Move files and folders to new repo format to enable multi-project format
This commit is contained in:
30
Zennysoft.Game.Ma/src/game/DialogueController.cs
Normal file
30
Zennysoft.Game.Ma/src/game/DialogueController.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using DialogueManagerRuntime;
|
||||
using Godot;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class DialogueController : Node
|
||||
{
|
||||
public static PackedScene DialogueBalloon { get; set; }
|
||||
|
||||
private static Node _currentlyActiveDialogue { get; set; } = new Node();
|
||||
|
||||
private static Resource _currentDialogue { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
DialogueBalloon = GD.Load<PackedScene>("res://src/ui/dialogue/DialogueBalloon.tscn");
|
||||
}
|
||||
|
||||
public static void ShowDialogue(Resource dialogueResource, string dialogueTitle)
|
||||
{
|
||||
Interrupt();
|
||||
_currentlyActiveDialogue = DialogueManager.ShowDialogueBalloonScene(DialogueBalloon, dialogueResource, dialogueTitle);
|
||||
}
|
||||
|
||||
public static void Interrupt()
|
||||
{
|
||||
if (IsInstanceValid(_currentlyActiveDialogue))
|
||||
_currentlyActiveDialogue.QueueFree();
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/DialogueController.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/DialogueController.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://daphxl6vvsbjm
|
||||
16
Zennysoft.Game.Ma/src/game/ElementType.cs
Normal file
16
Zennysoft.Game.Ma/src/game/ElementType.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public enum ElementType
|
||||
{
|
||||
None,
|
||||
Aeolic,
|
||||
Telluric,
|
||||
Hydric,
|
||||
Igneous,
|
||||
Ferrum
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(ElementType))]
|
||||
public partial class ElementTypeEnumContext : JsonSerializerContext;
|
||||
1
Zennysoft.Game.Ma/src/game/ElementType.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/ElementType.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d2jmqna6ogv8t
|
||||
493
Zennysoft.Game.Ma/src/game/Game.cs
Normal file
493
Zennysoft.Game.Ma/src/game/Game.cs
Normal file
@@ -0,0 +1,493 @@
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Collections;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.SaveFileBuilder;
|
||||
using Chickensoft.Serialization;
|
||||
using Chickensoft.Serialization.Godot;
|
||||
using Zennysoft.Game.Ma.src.items;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.IO.Abstractions;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
using static Zennysoft.Game.Ma.GameLogic.State;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Game : Node3D, IGame
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
IGameRepo IProvide<IGameRepo>.Value() => GameRepo;
|
||||
|
||||
IGame IProvide<IGame>.Value() => this;
|
||||
|
||||
IPlayer IProvide<IPlayer>.Value() => Player;
|
||||
|
||||
IGameEventDepot IProvide<IGameEventDepot>.Value() => GameEventDepot;
|
||||
|
||||
public IInstantiator Instantiator { get; set; } = default!;
|
||||
|
||||
public IGameLogic GameLogic { get; set; } = default!;
|
||||
|
||||
public IGameEventDepot GameEventDepot { get; set; } = default!;
|
||||
|
||||
public IGameRepo GameRepo { get; set; } = default!;
|
||||
|
||||
public GameLogic.IBinding GameBinding { get; set; } = default!;
|
||||
|
||||
[Signal]
|
||||
public delegate void StatRaisedAlertEventHandler(string statRaisedAlert);
|
||||
|
||||
[Dependency] public IAppRepo AppRepo => this.DependOn<IAppRepo>();
|
||||
|
||||
#region Nodes
|
||||
[Node] private IMap Map { get; set; } = default!;
|
||||
|
||||
[Node] private InGameUI InGameUI { get; set; } = default!;
|
||||
|
||||
[Node] private IFloorClearMenu FloorClearMenu { get; set; } = default!;
|
||||
|
||||
[Node] private DeathMenu DeathMenu { get; set; } = default!;
|
||||
|
||||
[Node] private IPauseMenu PauseMenu { get; set; } = default!;
|
||||
|
||||
[Node] private InGameAudio InGameAudio { get; set; } = default!;
|
||||
|
||||
[Node] private Timer DoubleEXPTimer { get; set; } = default!;
|
||||
|
||||
[Node] private IPlayer Player { get; set; } = default!;
|
||||
#endregion
|
||||
|
||||
#region Save
|
||||
public JsonSerializerOptions JsonOptions { get; set; } = default!;
|
||||
|
||||
public const string SAVE_FILE_NAME = "game.json";
|
||||
|
||||
public IFileSystem FileSystem { get; set; } = default!;
|
||||
|
||||
public string SaveFilePath { get; set; } = default!;
|
||||
|
||||
public ISaveFile<GameData> SaveFile { get; set; } = default!;
|
||||
|
||||
public ISaveChunk<GameData> GameChunk { get; set; } = default!;
|
||||
|
||||
ISaveChunk<GameData> IProvide<ISaveChunk<GameData>>.Value() => GameChunk;
|
||||
|
||||
[Signal]
|
||||
public delegate void SaveFileLoadedEventHandler();
|
||||
#endregion
|
||||
|
||||
public RescuedItemDatabase RescuedItems { get; set; } = default!;
|
||||
|
||||
private EffectService _effectService;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
FileSystem = new FileSystem();
|
||||
|
||||
SaveFilePath = FileSystem.Path.Join(OS.GetUserDataDir(), SAVE_FILE_NAME);
|
||||
|
||||
GameRepo = new GameRepo();
|
||||
GameLogic = new GameLogic();
|
||||
GameEventDepot = new GameEventDepot();
|
||||
GameLogic.Set(GameRepo);
|
||||
GameLogic.Set(AppRepo);
|
||||
GameLogic.Set(GameEventDepot);
|
||||
GameLogic.Set(Player);
|
||||
GameLogic.Set(Map);
|
||||
Instantiator = new Instantiator(GetTree());
|
||||
RescuedItems = new RescuedItemDatabase();
|
||||
|
||||
var resolver = new SerializableTypeResolver();
|
||||
GodotSerialization.Setup();
|
||||
Serializer.AddConverter(new Texture2DConverter());
|
||||
|
||||
var upgradeDependencies = new Blackboard();
|
||||
|
||||
JsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
Converters = {
|
||||
new SerializableTypeConverter(upgradeDependencies)
|
||||
},
|
||||
TypeInfoResolver = JsonTypeInfoResolver.Combine(resolver, WeaponTagEnumContext.Default, ItemTagEnumContext.Default, ElementTypeEnumContext.Default, AccessoryTagEnumContext.Default, ThrowableItemTagEnumContext.Default, UsableItemTagEnumContext.Default, BoxItemTagEnumContext.Default),
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
GameChunk = new SaveChunk<GameData>(
|
||||
(chunk) =>
|
||||
{
|
||||
var gameData = new GameData()
|
||||
{
|
||||
PlayerData = new PlayerData()
|
||||
{
|
||||
PlayerStats = new PlayerStats()
|
||||
{
|
||||
CurrentHP = Player.Stats.CurrentHP.Value,
|
||||
MaximumHP = Player.Stats.MaximumHP.Value,
|
||||
CurrentVT = Player.Stats.CurrentVT.Value,
|
||||
MaximumVT = Player.Stats.MaximumVT.Value,
|
||||
CurrentAttack = Player.Stats.CurrentAttack.Value,
|
||||
BonusAttack = Player.Stats.BonusAttack.Value,
|
||||
MaxAttack = Player.Stats.MaxAttack.Value,
|
||||
CurrentDefense = Player.Stats.CurrentDefense.Value,
|
||||
BonusDefense = Player.Stats.BonusDefense.Value,
|
||||
MaxDefense = Player.Stats.MaxDefense.Value,
|
||||
CurrentExp = Player.Stats.CurrentExp.Value,
|
||||
CurrentLevel = Player.Stats.CurrentLevel.Value,
|
||||
ExpToNextLevel = Player.Stats.ExpToNextLevel.Value,
|
||||
Luck = Player.Stats.Luck.Value
|
||||
},
|
||||
Inventory = Player.Inventory
|
||||
},
|
||||
MapData = new MapData()
|
||||
{
|
||||
FloorScenes = Map.FloorScenes
|
||||
},
|
||||
RescuedItems = new RescuedItemDatabase() { Items = RescuedItems.Items }
|
||||
};
|
||||
|
||||
return gameData;
|
||||
},
|
||||
onLoad: (chunk, data) =>
|
||||
{
|
||||
RescuedItems = data.RescuedItems;
|
||||
chunk.LoadChunkSaveData(data.PlayerData);
|
||||
chunk.LoadChunkSaveData(data.MapData);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
SaveFile = new SaveFile<GameData>(
|
||||
root: GameChunk,
|
||||
onSave: async (GameData data) =>
|
||||
{
|
||||
// Save the game data to disk.
|
||||
var json = JsonSerializer.Serialize(data, JsonOptions);
|
||||
await FileSystem.File.WriteAllTextAsync(SaveFilePath, json);
|
||||
},
|
||||
onLoad: async () =>
|
||||
{
|
||||
// Load the game data from disk.
|
||||
if (!FileSystem.File.Exists(SaveFilePath))
|
||||
{
|
||||
GD.Print("No save file to load");
|
||||
return null;
|
||||
}
|
||||
|
||||
var json = await FileSystem.File.ReadAllTextAsync(SaveFilePath);
|
||||
return JsonSerializer.Deserialize<GameData>(json, JsonOptions);
|
||||
}
|
||||
);
|
||||
|
||||
GameBinding = GameLogic.Bind();
|
||||
GameBinding
|
||||
.Handle((in GameLogic.Output.StartGame _) =>
|
||||
{
|
||||
GameRepo.Resume();
|
||||
InGameUI.Show();
|
||||
})
|
||||
.Handle((in GameLogic.Output.GoToOverworld _) =>
|
||||
{
|
||||
GameEventDepot.OnOverworldEntered();
|
||||
})
|
||||
.Handle((in GameLogic.Output.SetPauseMode output) => CallDeferred(nameof(SetPauseMode), output.IsPaused))
|
||||
.Handle((in GameLogic.Output.ShowPauseMenu _) =>
|
||||
{
|
||||
PauseMenu.Show();
|
||||
PauseMenu.FadeIn();
|
||||
Input.MouseMode = Input.MouseModeEnum.Visible;
|
||||
PauseMenu.SetProcessUnhandledInput(true);
|
||||
})
|
||||
.Handle((in GameLogic.Output.LoadNextFloor _) => { Map.SpawnNextFloor(); })
|
||||
.Handle((in GameLogic.Output.HidePauseMenu _) => { PauseMenu.Hide(); })
|
||||
.Handle((in GameLogic.Output.ExitPauseMenu _) => { PauseMenu.FadeOut(); Input.MouseMode = Input.MouseModeEnum.Visible; PauseMenu.SetProcessUnhandledInput(false); })
|
||||
.Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); })
|
||||
.Handle((in GameLogic.Output.ExitFloorClearMenu _) => { FloorClearMenu.FadeOut(); })
|
||||
.Handle((in GameLogic.Output.OpenInventory _) => { InGameUI.ShowInventoryScreen(); InGameUI.InventoryMenu.SetProcessInput(true); })
|
||||
.Handle((in GameLogic.Output.HideInventory _) => { InGameUI.HideInventoryScreen(); InGameUI.InventoryMenu.SetProcessInput(false); })
|
||||
.Handle((in GameLogic.Output.ShowMiniMap _) => { InGameUI.ShowMiniMap(); })
|
||||
.Handle((in GameLogic.Output.HideMiniMap _) => { InGameUI.HideMiniMap(); })
|
||||
.Handle((in GameLogic.Output.ShowAskForTeleport _) => { GameRepo.Pause(); InGameUI.UseTeleportPrompt.FadeIn(); InGameUI.SetProcessInput(true); })
|
||||
.Handle((in GameLogic.Output.HideAskForTeleport _) => { GameRepo.Resume(); InGameUI.UseTeleportPrompt.FadeOut(); InGameUI.SetProcessInput(false); })
|
||||
.Handle((in GameLogic.Output.ShowLostScreen _) => { DeathMenu.Show(); DeathMenu.FadeIn(); })
|
||||
.Handle((in GameLogic.Output.ExitLostScreen _) => { DeathMenu.FadeOut(); })
|
||||
.Handle((in GameLogic.Output.SaveGame _) =>
|
||||
{
|
||||
SaveFile.Save();
|
||||
AppRepo.OnExitGame();
|
||||
GetTree().Quit();
|
||||
// Back to title screen
|
||||
});
|
||||
GameLogic.Start();
|
||||
|
||||
GameLogic.Input(new GameLogic.Input.Initialize());
|
||||
|
||||
this.Provide();
|
||||
|
||||
PauseMenu.TransitionCompleted += OnPauseMenuTransitioned;
|
||||
PauseMenu.UnpauseButtonPressed += PauseMenu_UnpauseButtonPressed;
|
||||
InGameUI.InventoryMenu.ClosedMenu += InventoryMenu_CloseInventory;
|
||||
InGameUI.MinimapButtonReleased += Player_MinimapButtonReleased;
|
||||
|
||||
InGameUI.UseTeleportPrompt.TeleportToNextFloor += UseTeleportPrompt_TeleportToNextFloor;
|
||||
InGameUI.UseTeleportPrompt.CloseTeleportPrompt += UseTeleportPrompt_CloseTeleportPrompt;
|
||||
|
||||
FloorClearMenu.GoToNextFloor += FloorClearMenu_GoToNextFloor;
|
||||
FloorClearMenu.SaveAndExit += FloorClearMenu_SaveAndExit;
|
||||
FloorClearMenu.TransitionCompleted += FloorClearMenu_TransitionCompleted;
|
||||
|
||||
GameEventDepot.RestorativePickedUp += GameEventDepot_RestorativePickedUp;
|
||||
|
||||
DoubleEXPTimer.Timeout += DoubleEXPTimer_Timeout;
|
||||
|
||||
_effectService = new EffectService(this, Player);
|
||||
}
|
||||
|
||||
public void LoadExistingGame()
|
||||
{
|
||||
SaveFile.Load()
|
||||
.ContinueWith((_) => CallDeferred(nameof(FinishedLoadingSaveFile)));
|
||||
}
|
||||
|
||||
public void TogglePause()
|
||||
{
|
||||
if (GameLogic.Value is Paused)
|
||||
GameLogic.Input(new GameLogic.Input.UnpauseGame());
|
||||
else
|
||||
GameLogic.Input(new GameLogic.Input.PauseGame());
|
||||
}
|
||||
|
||||
public void ToggleInventory()
|
||||
{
|
||||
if (GameLogic.Value is InventoryOpened)
|
||||
GameLogic.Input(new GameLogic.Input.CloseInventory());
|
||||
else
|
||||
GameLogic.Input(new GameLogic.Input.OpenInventory());
|
||||
}
|
||||
|
||||
public void ToggleMinimap()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.MiniMapButtonPressed());
|
||||
}
|
||||
|
||||
public void FloorExitReached()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.AskForTeleport());
|
||||
GameEventDepot.OnTeleportEntered();
|
||||
}
|
||||
|
||||
public void UseItem(InventoryItem item)
|
||||
{
|
||||
if (item is ConsumableItem consumableItem)
|
||||
{
|
||||
if (Player.Stats.CurrentHP == Player.Stats.MaximumHP && consumableItem.RaiseHPAmount > 0)
|
||||
Player.RaiseHP(consumableItem.RaiseHPAmount);
|
||||
if (Player.Stats.CurrentVT == Player.Stats.MaximumVT && consumableItem.RaiseVTAmount > 0)
|
||||
Player.RaiseVT(consumableItem.RaiseVTAmount);
|
||||
|
||||
if (consumableItem.HealHPAmount > 0 && Player.Stats.CurrentHP != Player.Stats.MaximumHP)
|
||||
Player.HealHP(consumableItem.HealHPAmount);
|
||||
if (consumableItem.HealVTAmount > 0 && Player.Stats.CurrentVT != Player.Stats.MaximumVT)
|
||||
Player.HealVT(consumableItem.HealVTAmount);
|
||||
}
|
||||
if (item is EffectItem effectItem)
|
||||
{
|
||||
switch (effectItem.UsableItemTag)
|
||||
{
|
||||
case UsableItemTag.DoubleEXP:
|
||||
DoubleEXP(TimeSpan.FromSeconds(30));
|
||||
break;
|
||||
case UsableItemTag.TeleportAllEnemiesToRoom:
|
||||
_effectService.TeleportEnemiesToCurrentRoom();
|
||||
break;
|
||||
case UsableItemTag.KillHalfEnemiesInRoom:
|
||||
_effectService.KillHalfEnemiesInRoom();
|
||||
break;
|
||||
case UsableItemTag.TurnAllEnemiesIntoHealingItem:
|
||||
_effectService.TurnAllEnemiesInRoomIntoHealingItem();
|
||||
break;
|
||||
case UsableItemTag.HealsAllInRoomToMaxHP:
|
||||
_effectService.HealAllEnemiesAndPlayerInRoomToFull();
|
||||
break;
|
||||
case UsableItemTag.AbsorbHPFromAllEnemiesInRoom:
|
||||
_effectService.AbsorbHPFromAllEnemiesInRoom();
|
||||
break;
|
||||
case UsableItemTag.DealElementalDamageToAllEnemiesInRoom:
|
||||
_effectService.DealElementalDamageToAllEnemiesInRoom(ElementType.Hydric);
|
||||
break;
|
||||
case UsableItemTag.SwapHPAndVT:
|
||||
_effectService.SwapHPandVT();
|
||||
break;
|
||||
case UsableItemTag.RaiseCurrentWeaponAttack:
|
||||
_effectService.RaiseCurrentWeaponAttack();
|
||||
break;
|
||||
case UsableItemTag.RaiseCurrentDefenseArmor:
|
||||
_effectService.RaiseCurrentArmorDefense();
|
||||
break;
|
||||
case UsableItemTag.RaiseLevel:
|
||||
_effectService.RaiseLevel();
|
||||
break;
|
||||
case UsableItemTag.RandomEffect:
|
||||
_effectService.RandomEffect(effectItem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item is ThrowableItem throwableItem)
|
||||
{
|
||||
if (throwableItem.HealHPAmount > 0)
|
||||
Player.HealHP(throwableItem.HealHPAmount);
|
||||
if (throwableItem.HealVTAmount > 0)
|
||||
Player.HealVT(throwableItem.HealVTAmount);
|
||||
|
||||
if (throwableItem.ThrowableItemTag == ThrowableItemTag.TeleportToRandomLocation)
|
||||
_effectService.TeleportToRandomRoom(Player);
|
||||
|
||||
if (throwableItem.ThrowableItemTag == ThrowableItemTag.CanChangeAffinity)
|
||||
_effectService.ChangeAffinity(throwableItem);
|
||||
|
||||
if (throwableItem.ThrowableItemTag == ThrowableItemTag.WarpToExitIfFound)
|
||||
_effectService.WarpToExit(Player);
|
||||
}
|
||||
}
|
||||
|
||||
public void DropItem(InventoryItem item)
|
||||
{
|
||||
var droppedScene = GD.Load<PackedScene>("res://src/items/dropped/DroppedItem.tscn");
|
||||
var dropped = droppedScene.Instantiate<DroppedItem>();
|
||||
dropped.Item = item;
|
||||
AddChild(dropped);
|
||||
dropped.Drop();
|
||||
}
|
||||
|
||||
public void ThrowItem(InventoryItem item)
|
||||
{
|
||||
var thrownScene = GD.Load<PackedScene>("res://src/items/thrown/ThrownItem.tscn");
|
||||
var thrown = thrownScene.Instantiate<ThrownItem>();
|
||||
thrown.ItemThatIsThrown = item;
|
||||
AddChild(thrown);
|
||||
thrown.Position += new Vector3(0, 1.5f, 0);
|
||||
thrown.Throw(_effectService);
|
||||
}
|
||||
|
||||
public void AnnounceMessageOnInventoryScreen(string message)
|
||||
{
|
||||
InGameUI.InventoryMenu.ShowMessage(message);
|
||||
}
|
||||
|
||||
public void AnnounceMessageOnMainScreen(string message)
|
||||
{
|
||||
InGameUI.PlayerInfoUI.DisplayMessage(message);
|
||||
}
|
||||
|
||||
public IDungeonFloor CurrentFloor => Map.CurrentFloor;
|
||||
|
||||
public void EnemyDefeated(Vector3 defeatedLocation, EnemyStatResource resource)
|
||||
{
|
||||
Player.GainExp(resource.ExpFromDefeat * GameRepo.EXPRate);
|
||||
}
|
||||
|
||||
private void DropRestorative(Vector3 vector)
|
||||
{
|
||||
var restorativeScene = GD.Load<PackedScene>("res://src/items/restorative/Restorative.tscn");
|
||||
var restorative = restorativeScene.Instantiate<Restorative>();
|
||||
AddChild(restorative);
|
||||
restorative.GlobalPosition = vector;
|
||||
}
|
||||
|
||||
private void UseTeleportPrompt_CloseTeleportPrompt()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.HideAskForTeleport());
|
||||
}
|
||||
|
||||
private void UseTeleportPrompt_TeleportToNextFloor()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.FloorExitReached());
|
||||
GameEventDepot.OnDungeonAThemeAreaEntered();
|
||||
}
|
||||
|
||||
private void PauseMenu_UnpauseButtonPressed()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.UnpauseGame());
|
||||
}
|
||||
|
||||
private void Player_PauseButtonPressed()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.PauseGame());
|
||||
}
|
||||
|
||||
private void Player_MinimapButtonReleased()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.MiniMapButtonReleased());
|
||||
}
|
||||
|
||||
private void FloorClearMenu_TransitionCompleted()
|
||||
{
|
||||
GameRepo.Resume();
|
||||
if (Player.EquippedWeapon.Value.ItemTag == ItemTag.BreaksOnChange)
|
||||
Player.Unequip(Player.EquippedWeapon.Value);
|
||||
if (Player.EquippedArmor.Value.ItemTag == ItemTag.BreaksOnChange)
|
||||
Player.Unequip(Player.EquippedArmor.Value);
|
||||
if (Player.EquippedAccessory.Value.ItemTag == ItemTag.BreaksOnChange)
|
||||
Player.Unequip(Player.EquippedAccessory.Value);
|
||||
}
|
||||
|
||||
private void FloorClearMenu_GoToNextFloor()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.GoToNextFloor());
|
||||
}
|
||||
|
||||
private void FloorClearMenu_SaveAndExit()
|
||||
{
|
||||
// Save
|
||||
GameLogic.Input(new GameLogic.Input.SaveGame());
|
||||
}
|
||||
|
||||
private void GameEventDepot_RestorativePickedUp(Restorative obj)
|
||||
=> Player.Stats.SetCurrentVT(Player.Stats.CurrentVT.Value + obj.VTRestoreAmount);
|
||||
|
||||
private void SetPauseMode(bool isPaused)
|
||||
{
|
||||
if (GetTree() != null)
|
||||
GetTree().Paused = isPaused;
|
||||
}
|
||||
|
||||
public async void DoubleEXP(TimeSpan lengthOfEffect)
|
||||
{
|
||||
ToggleInventory();
|
||||
AnnounceMessageOnMainScreen("Experience points temporarily doubled.");
|
||||
DoubleEXPTimer.Start(lengthOfEffect.Seconds);
|
||||
GameRepo.EXPRate = 2;
|
||||
}
|
||||
|
||||
private void DoubleEXPTimer_Timeout()
|
||||
{
|
||||
DoubleEXPTimer.Stop();
|
||||
GameRepo.EXPRate = 1;
|
||||
AnnounceMessageOnMainScreen("Experience points effect wore off.");
|
||||
}
|
||||
|
||||
private void InventoryMenu_CloseInventory() => GameLogic.Input(new GameLogic.Input.CloseInventory());
|
||||
|
||||
public void NextFloorLoaded()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.HideFloorClearMenu());
|
||||
}
|
||||
|
||||
private void OnPauseMenuTransitioned()
|
||||
{
|
||||
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
|
||||
}
|
||||
|
||||
public void OnStart() =>
|
||||
GameLogic.Input(new GameLogic.Input.StartGame());
|
||||
|
||||
private void FinishedLoadingSaveFile()
|
||||
{
|
||||
EmitSignal(SignalName.SaveFileLoaded);
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/Game.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/Game.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://chftlu4proh3d
|
||||
86
Zennysoft.Game.Ma/src/game/Game.tscn
Normal file
86
Zennysoft.Game.Ma/src/game/Game.tscn
Normal file
@@ -0,0 +1,86 @@
|
||||
[gd_scene load_steps=13 format=3 uid="uid://33ek675mfb5n"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://chftlu4proh3d" path="res://src/game/Game.cs" id="1_ytcii"]
|
||||
[ext_resource type="Shader" uid="uid://dmjxo4k2rx1an" path="res://src/app/App.gdshader" id="2_6ifxs"]
|
||||
[ext_resource type="PackedScene" uid="uid://by67pn7fdsg1m" path="res://src/map/Map.tscn" id="3_d8awv"]
|
||||
[ext_resource type="PackedScene" uid="uid://cfecvvav8kkp6" path="res://src/player/Player.tscn" id="3_kk6ly"]
|
||||
[ext_resource type="PackedScene" uid="uid://b1muxus5qdbeu" path="res://src/ui/in_game_ui/InGameUI.tscn" id="5_lxtnp"]
|
||||
[ext_resource type="PackedScene" uid="uid://b16ejcwanod72" path="res://src/audio/InGameAudio.tscn" id="6_qc71l"]
|
||||
[ext_resource type="Script" uid="uid://daphxl6vvsbjm" path="res://src/game/DialogueController.cs" id="10_58pbt"]
|
||||
[ext_resource type="Script" uid="uid://cbal5oeaha4nx" path="res://src/ui/pause_menu/PauseMenu.cs" id="11_5ng8c"]
|
||||
[ext_resource type="PackedScene" uid="uid://pu6gp8de3ck4" path="res://src/ui/floor_clear/FloorClearMenu.tscn" id="11_rya1n"]
|
||||
[ext_resource type="PackedScene" uid="uid://dbtfgrtgpr4qg" path="res://src/ui/death_menu/DeathMenu.tscn" id="11_wypid"]
|
||||
[ext_resource type="PackedScene" uid="uid://blbqgw3wosc1w" path="res://src/ui/pause_menu/PauseMenu.tscn" id="12_yev8k"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_e75a2"]
|
||||
shader = ExtResource("2_6ifxs")
|
||||
shader_parameter/change_color_depth = false
|
||||
shader_parameter/target_color_depth = 7
|
||||
shader_parameter/dithering = false
|
||||
shader_parameter/scale_resolution = false
|
||||
shader_parameter/target_resolution_scale = 4
|
||||
shader_parameter/enable_recolor = false
|
||||
|
||||
[node name="Game" type="Node3D"]
|
||||
process_mode = 3
|
||||
script = ExtResource("1_ytcii")
|
||||
|
||||
[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
|
||||
material = SubResource("ShaderMaterial_e75a2")
|
||||
custom_minimum_size = Vector2(1280, 960)
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
stretch = true
|
||||
|
||||
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
|
||||
transparent_bg = true
|
||||
handle_input_locally = false
|
||||
size = Vector2i(1280, 960)
|
||||
render_target_update_mode = 4
|
||||
|
||||
[node name="PauseContainer" type="Node3D" parent="SubViewportContainer/SubViewport"]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 1
|
||||
|
||||
[node name="Player" parent="SubViewportContainer/SubViewport/PauseContainer" instance=ExtResource("3_kk6ly")]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 1
|
||||
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, -3, 0)
|
||||
|
||||
[node name="Map" parent="SubViewportContainer/SubViewport/PauseContainer" instance=ExtResource("3_d8awv")]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 1
|
||||
|
||||
[node name="StatusEffectTimers" type="Node" parent="SubViewportContainer/SubViewport/PauseContainer"]
|
||||
|
||||
[node name="DoubleEXPTimer" type="Timer" parent="SubViewportContainer/SubViewport/PauseContainer/StatusEffectTimers"]
|
||||
unique_name_in_owner = true
|
||||
wait_time = 30.0
|
||||
|
||||
[node name="InGameUI" parent="." instance=ExtResource("5_lxtnp")]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
|
||||
[node name="InGameAudio" parent="." instance=ExtResource("6_qc71l")]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="DialogueController" type="Node" parent="."]
|
||||
unique_name_in_owner = true
|
||||
process_mode = 3
|
||||
script = ExtResource("10_58pbt")
|
||||
|
||||
[node name="DeathMenu" parent="." instance=ExtResource("11_wypid")]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
|
||||
[node name="FloorClearMenu" parent="." instance=ExtResource("11_rya1n")]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
|
||||
[node name="PauseMenu" parent="." instance=ExtResource("12_yev8k")]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
script = ExtResource("11_5ng8c")
|
||||
17
Zennysoft.Game.Ma/src/game/GameData.cs
Normal file
17
Zennysoft.Game.Ma/src/game/GameData.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[Meta, Id("game_data")]
|
||||
public partial record GameData
|
||||
{
|
||||
[Save("player_data")]
|
||||
public required PlayerData PlayerData { get; init; }
|
||||
|
||||
[Save("map_data")]
|
||||
public required MapData MapData { get; init; }
|
||||
|
||||
[Save("rescued_items")]
|
||||
public required RescuedItemDatabase RescuedItems { get; init; }
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameData.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameData.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://x6xknnr3wpkv
|
||||
80
Zennysoft.Game.Ma/src/game/GameEventDepot.cs
Normal file
80
Zennysoft.Game.Ma/src/game/GameEventDepot.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public interface IGameEventDepot : IDisposable
|
||||
{
|
||||
event Action? OverworldEntered;
|
||||
public void OnOverworldEntered();
|
||||
|
||||
event Action? DungeonAThemeAreaEntered;
|
||||
public void OnDungeonAThemeAreaEntered();
|
||||
|
||||
event Action? DungeonBThemeAreaEntered;
|
||||
public void OnDungeonBThemeAreaEntered();
|
||||
|
||||
event Action? DungeonCThemeAreaEntered;
|
||||
public void OnDungeonCThemeAreaEntered();
|
||||
|
||||
event Action? TeleportEntered;
|
||||
public void OnTeleportEntered();
|
||||
|
||||
event Action? MenuScrolled;
|
||||
public void OnMenuScrolled();
|
||||
|
||||
event Action? MenuBackedOut;
|
||||
public void OnMenuBackedOut();
|
||||
|
||||
event Action? InventorySorted;
|
||||
public void OnInventorySorted();
|
||||
|
||||
event Action<ConsumableItemStats>? HealingItemConsumed;
|
||||
public void OnHealingItemConsumed(ConsumableItemStats item);
|
||||
|
||||
event Action<Vector3, EnemyStatResource>? EnemyDefeated;
|
||||
public void OnEnemyDefeated(Vector3 position, EnemyStatResource enemyStatResource);
|
||||
|
||||
event Action<Restorative>? RestorativePickedUp;
|
||||
public void OnRestorativePickedUp(Restorative restorative);
|
||||
}
|
||||
|
||||
public class GameEventDepot : IGameEventDepot
|
||||
{
|
||||
|
||||
public event Action? OverworldEntered;
|
||||
public event Action? DungeonAThemeAreaEntered;
|
||||
public event Action? DungeonBThemeAreaEntered;
|
||||
public event Action? DungeonCThemeAreaEntered;
|
||||
|
||||
public event Action? TeleportEntered;
|
||||
|
||||
public event Action? MenuScrolled;
|
||||
public event Action? MenuBackedOut;
|
||||
public event Action? InventorySorted;
|
||||
public event Action<ConsumableItemStats>? HealingItemConsumed;
|
||||
public event Action<Restorative>? RestorativePickedUp;
|
||||
|
||||
public event Action<Vector3, EnemyStatResource>? EnemyDefeated;
|
||||
|
||||
public void OnOverworldEntered() => OverworldEntered?.Invoke();
|
||||
public void OnDungeonAThemeAreaEntered() => DungeonAThemeAreaEntered?.Invoke();
|
||||
public void OnDungeonBThemeAreaEntered() => DungeonBThemeAreaEntered?.Invoke();
|
||||
public void OnDungeonCThemeAreaEntered() => DungeonCThemeAreaEntered?.Invoke();
|
||||
|
||||
public void OnTeleportEntered() => TeleportEntered?.Invoke();
|
||||
|
||||
public void OnMenuScrolled() => MenuScrolled?.Invoke();
|
||||
public void OnMenuBackedOut() => MenuBackedOut?.Invoke();
|
||||
|
||||
public void OnInventorySorted() => InventorySorted?.Invoke();
|
||||
public void OnHealingItemConsumed(ConsumableItemStats item) => HealingItemConsumed?.Invoke(item);
|
||||
public void OnRestorativePickedUp(Restorative restorative) => RestorativePickedUp?.Invoke(restorative);
|
||||
|
||||
public void OnEnemyDefeated(Vector3 position, EnemyStatResource enemyStatResource) => EnemyDefeated?.Invoke(position, enemyStatResource);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameEventDepot.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameEventDepot.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b7t5vaa72dluj
|
||||
40
Zennysoft.Game.Ma/src/game/GameLogic.Input.cs
Normal file
40
Zennysoft.Game.Ma/src/game/GameLogic.Input.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public static class Input
|
||||
{
|
||||
public readonly record struct StartGame;
|
||||
|
||||
public readonly record struct Initialize;
|
||||
|
||||
public readonly record struct GoToOverworld;
|
||||
|
||||
public readonly record struct SaveGame;
|
||||
|
||||
public readonly record struct OpenInventory;
|
||||
|
||||
public readonly record struct CloseInventory;
|
||||
|
||||
public readonly record struct MiniMapButtonPressed;
|
||||
|
||||
public readonly record struct MiniMapButtonReleased;
|
||||
|
||||
public readonly record struct FloorExitReached;
|
||||
public readonly record struct HideFloorClearMenu;
|
||||
|
||||
public readonly record struct GameOver;
|
||||
|
||||
public readonly record struct GoToNextFloor;
|
||||
|
||||
public readonly record struct PauseGame;
|
||||
|
||||
public readonly record struct UnpauseGame;
|
||||
|
||||
public readonly record struct PauseMenuTransitioned;
|
||||
|
||||
public readonly record struct AskForTeleport;
|
||||
|
||||
public readonly record struct HideAskForTeleport;
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameLogic.Input.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameLogic.Input.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c5bupugjtove2
|
||||
43
Zennysoft.Game.Ma/src/game/GameLogic.Output.cs
Normal file
43
Zennysoft.Game.Ma/src/game/GameLogic.Output.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public static class Output
|
||||
{
|
||||
public readonly record struct StartGame;
|
||||
|
||||
public readonly record struct ShowPauseMenu;
|
||||
|
||||
public readonly record struct HidePauseMenu;
|
||||
|
||||
public readonly record struct ExitPauseMenu;
|
||||
|
||||
public readonly record struct OpenInventory();
|
||||
|
||||
public readonly record struct HideInventory;
|
||||
|
||||
public readonly record struct SetPauseMode(bool IsPaused);
|
||||
|
||||
public readonly record struct ShowMiniMap;
|
||||
|
||||
public readonly record struct HideMiniMap;
|
||||
|
||||
public readonly record struct ShowLostScreen;
|
||||
|
||||
public readonly record struct ExitLostScreen;
|
||||
|
||||
public readonly record struct LoadNextFloor;
|
||||
|
||||
public readonly record struct ShowFloorClearMenu;
|
||||
|
||||
public readonly record struct ExitFloorClearMenu;
|
||||
|
||||
public readonly record struct ShowAskForTeleport;
|
||||
|
||||
public readonly record struct HideAskForTeleport;
|
||||
|
||||
public readonly record struct GoToOverworld;
|
||||
|
||||
public readonly record struct SaveGame;
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameLogic.Output.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameLogic.Output.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://canjbp5frcnep
|
||||
27
Zennysoft.Game.Ma/src/game/GameLogic.State.cs
Normal file
27
Zennysoft.Game.Ma/src/game/GameLogic.State.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
[Meta]
|
||||
public abstract partial record State : StateLogic<State>
|
||||
{
|
||||
protected State()
|
||||
{
|
||||
OnAttach(() =>
|
||||
{
|
||||
var gameRepo = Get<IGameRepo>();
|
||||
gameRepo.IsPaused.Sync += OnIsPaused;
|
||||
});
|
||||
OnDetach(() =>
|
||||
{
|
||||
var gameRepo = Get<IGameRepo>();
|
||||
gameRepo.IsPaused.Sync -= OnIsPaused;
|
||||
});
|
||||
}
|
||||
|
||||
public void OnIsPaused(bool isPaused) => Output(new Output.SetPauseMode(isPaused));
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameLogic.State.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameLogic.State.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://biqpnjkv83rwx
|
||||
13
Zennysoft.Game.Ma/src/game/GameLogic.cs
Normal file
13
Zennysoft.Game.Ma/src/game/GameLogic.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public interface IGameLogic : ILogicBlock<GameLogic.State>;
|
||||
|
||||
[Meta]
|
||||
[LogicBlock(typeof(State), Diagram = true)]
|
||||
public partial class GameLogic : LogicBlock<GameLogic.State>, IGameLogic
|
||||
{
|
||||
public override Transition GetInitialState() => To<State.MenuBackdrop>();
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameLogic.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameLogic.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cy056a5d12tfj
|
||||
48
Zennysoft.Game.Ma/src/game/GameLogic.g.puml
Normal file
48
Zennysoft.Game.Ma/src/game/GameLogic.g.puml
Normal file
@@ -0,0 +1,48 @@
|
||||
@startuml GameLogic
|
||||
state "GameLogic State" as Zennysoft_Game_Ma_GameLogic_State {
|
||||
state "MenuBackdrop" as Zennysoft_Game_Ma_GameLogic_State_MenuBackdrop
|
||||
state "Playing" as Zennysoft_Game_Ma_GameLogic_State_Playing {
|
||||
state "AskForTeleport" as Zennysoft_Game_Ma_GameLogic_State_AskForTeleport
|
||||
state "FloorClearedDecisionState" as Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState
|
||||
state "InventoryOpened" as Zennysoft_Game_Ma_GameLogic_State_InventoryOpened
|
||||
state "MinimapOpen" as Zennysoft_Game_Ma_GameLogic_State_MinimapOpen
|
||||
state "Paused" as Zennysoft_Game_Ma_GameLogic_State_Paused
|
||||
state "Resuming" as Zennysoft_Game_Ma_GameLogic_State_Resuming
|
||||
}
|
||||
state "Quit" as Zennysoft_Game_Ma_GameLogic_State_Quit
|
||||
}
|
||||
|
||||
Zennysoft_Game_Ma_GameLogic_State_AskForTeleport --> Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState : FloorExitReached
|
||||
Zennysoft_Game_Ma_GameLogic_State_AskForTeleport --> Zennysoft_Game_Ma_GameLogic_State_Playing : HideAskForTeleport
|
||||
Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState --> Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState : GoToNextFloor
|
||||
Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState --> Zennysoft_Game_Ma_GameLogic_State_Playing : HideFloorClearMenu
|
||||
Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState --> Zennysoft_Game_Ma_GameLogic_State_Playing : SaveGame
|
||||
Zennysoft_Game_Ma_GameLogic_State_InventoryOpened --> Zennysoft_Game_Ma_GameLogic_State_Playing : CloseInventory
|
||||
Zennysoft_Game_Ma_GameLogic_State_MenuBackdrop --> Zennysoft_Game_Ma_GameLogic_State_MenuBackdrop : Initialize
|
||||
Zennysoft_Game_Ma_GameLogic_State_MenuBackdrop --> Zennysoft_Game_Ma_GameLogic_State_Playing : StartGame
|
||||
Zennysoft_Game_Ma_GameLogic_State_MinimapOpen --> Zennysoft_Game_Ma_GameLogic_State_Playing : MiniMapButtonReleased
|
||||
Zennysoft_Game_Ma_GameLogic_State_Paused --> Zennysoft_Game_Ma_GameLogic_State_Resuming : UnpauseGame
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing --> Zennysoft_Game_Ma_GameLogic_State_AskForTeleport : AskForTeleport
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing --> Zennysoft_Game_Ma_GameLogic_State_InventoryOpened : OpenInventory
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing --> Zennysoft_Game_Ma_GameLogic_State_MinimapOpen : MiniMapButtonPressed
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing --> Zennysoft_Game_Ma_GameLogic_State_Paused : PauseGame
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing --> Zennysoft_Game_Ma_GameLogic_State_Playing : GoToOverworld
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing --> Zennysoft_Game_Ma_GameLogic_State_Quit : GameOver
|
||||
Zennysoft_Game_Ma_GameLogic_State_Resuming --> Zennysoft_Game_Ma_GameLogic_State_Playing : PauseMenuTransitioned
|
||||
|
||||
Zennysoft_Game_Ma_GameLogic_State : OnIsPaused() → SetPauseMode
|
||||
Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState : OnGoToNextFloor → LoadNextFloor
|
||||
Zennysoft_Game_Ma_GameLogic_State_FloorClearedDecisionState : OnSaveGame → SaveGame
|
||||
Zennysoft_Game_Ma_GameLogic_State_InventoryOpened : OnEnter → OpenInventory
|
||||
Zennysoft_Game_Ma_GameLogic_State_InventoryOpened : OnExit → HideInventory
|
||||
Zennysoft_Game_Ma_GameLogic_State_MinimapOpen : OnEnter → ShowMiniMap
|
||||
Zennysoft_Game_Ma_GameLogic_State_MinimapOpen : OnExit → HideMiniMap
|
||||
Zennysoft_Game_Ma_GameLogic_State_Paused : OnEnter → ShowPauseMenu
|
||||
Zennysoft_Game_Ma_GameLogic_State_Paused : OnExit → ExitPauseMenu
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing : None → StartGame
|
||||
Zennysoft_Game_Ma_GameLogic_State_Playing : OnGoToOverworld → GoToOverworld
|
||||
Zennysoft_Game_Ma_GameLogic_State_Quit : OnEnter → ShowLostScreen
|
||||
Zennysoft_Game_Ma_GameLogic_State_Resuming : OnExit → HidePauseMenu
|
||||
|
||||
[*] --> Zennysoft_Game_Ma_GameLogic_State_MenuBackdrop
|
||||
@enduml
|
||||
87
Zennysoft.Game.Ma/src/game/GameRepo.cs
Normal file
87
Zennysoft.Game.Ma/src/game/GameRepo.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Chickensoft.Collections;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public interface IGameRepo : IDisposable
|
||||
{
|
||||
void Pause();
|
||||
|
||||
void Resume();
|
||||
|
||||
IAutoProp<bool> IsPaused { get; }
|
||||
|
||||
void SetPlayerGlobalTransform(Transform3D playerGlobalTransform);
|
||||
|
||||
public int MaxItemSize { get; }
|
||||
|
||||
public int EXPRate { get; set; }
|
||||
|
||||
public int CurrentFloor { get; set; }
|
||||
}
|
||||
|
||||
public class GameRepo : IGameRepo
|
||||
{
|
||||
public event Action? Ended;
|
||||
|
||||
public IAutoProp<Transform3D> PlayerGlobalTransform => _playerGlobalTransform;
|
||||
private readonly AutoProp<Transform3D> _playerGlobalTransform;
|
||||
|
||||
public IAutoProp<bool> IsPaused => _isPaused;
|
||||
private readonly AutoProp<bool> _isPaused;
|
||||
|
||||
public int MaxItemSize => 20;
|
||||
|
||||
public int EXPRate { get; set; } = 1;
|
||||
|
||||
private bool _disposedValue;
|
||||
|
||||
public int CurrentFloor { get; set; } = 0;
|
||||
|
||||
public GameRepo()
|
||||
{
|
||||
_isPaused = new AutoProp<bool>(true);
|
||||
_playerGlobalTransform = new AutoProp<Transform3D>(Transform3D.Identity);
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
_isPaused.OnNext(true);
|
||||
GD.Print("Paused");
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
_isPaused.OnNext(false);
|
||||
GD.Print("Resume");
|
||||
}
|
||||
|
||||
public void SetPlayerGlobalTransform(Transform3D playerGlobalTransform) => _playerGlobalTransform.OnNext(playerGlobalTransform);
|
||||
|
||||
public void OnGameEnded()
|
||||
{
|
||||
Pause();
|
||||
Ended?.Invoke();
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_isPaused.OnCompleted();
|
||||
_isPaused.Dispose();
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/GameRepo.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/GameRepo.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://2n7h2jneaihr
|
||||
45
Zennysoft.Game.Ma/src/game/IGame.cs
Normal file
45
Zennysoft.Game.Ma/src/game/IGame.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Chickensoft.SaveFileBuilder;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public interface IGame : IProvide<IGameRepo>, IProvide<IGameEventDepot>, IProvide<IGame>, IProvide<IPlayer>, IProvide<ISaveChunk<GameData>>, INode3D
|
||||
{
|
||||
void LoadExistingGame();
|
||||
|
||||
event Game.SaveFileLoadedEventHandler? SaveFileLoaded;
|
||||
|
||||
event Game.StatRaisedAlertEventHandler StatRaisedAlert;
|
||||
|
||||
public RescuedItemDatabase RescuedItems { get; }
|
||||
|
||||
public IDungeonFloor CurrentFloor { get; }
|
||||
|
||||
public void UseItem(InventoryItem item);
|
||||
|
||||
public void DropItem(InventoryItem item);
|
||||
|
||||
public void ThrowItem(InventoryItem item);
|
||||
|
||||
public void DoubleEXP(TimeSpan lengthOfEffect);
|
||||
|
||||
public void ToggleInventory();
|
||||
|
||||
public void ToggleMinimap();
|
||||
|
||||
public void AnnounceMessageOnInventoryScreen(string message);
|
||||
|
||||
public void AnnounceMessageOnMainScreen(string message);
|
||||
|
||||
public void FloorExitReached();
|
||||
|
||||
public void NextFloorLoaded();
|
||||
|
||||
public void EnemyDefeated(Vector3 defeatedLocation, EnemyStatResource enemyStatResource);
|
||||
|
||||
public void TogglePause();
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/game/IGame.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/game/IGame.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cql33235m74q7
|
||||
@@ -0,0 +1,26 @@
|
||||
using Chickensoft.Introspection;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record AskForTeleport : Playing, IGet<Input.FloorExitReached>, IGet<Input.HideAskForTeleport>
|
||||
{
|
||||
public AskForTeleport()
|
||||
{
|
||||
this.OnAttach(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowAskForTeleport()); });
|
||||
this.OnDetach(() => { Output(new Output.HideAskForTeleport()); });
|
||||
}
|
||||
|
||||
public Transition On(in Input.FloorExitReached input) => To<FloorClearedDecisionState>();
|
||||
|
||||
public Transition On(in Input.HideAskForTeleport input)
|
||||
{
|
||||
return To<Playing>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://boai3f4vwgree
|
||||
@@ -0,0 +1,36 @@
|
||||
using Chickensoft.Introspection;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record FloorClearedDecisionState : Playing, IGet<Input.GoToNextFloor>, IGet<Input.SaveGame>, IGet<Input.HideFloorClearMenu>
|
||||
{
|
||||
public FloorClearedDecisionState()
|
||||
{
|
||||
this.OnAttach(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); });
|
||||
this.OnDetach(() => { Output(new Output.ExitFloorClearMenu()); });
|
||||
}
|
||||
|
||||
public Transition On(in Input.GoToNextFloor input)
|
||||
{
|
||||
Output(new Output.LoadNextFloor());
|
||||
return ToSelf();
|
||||
}
|
||||
|
||||
public Transition On(in Input.HideFloorClearMenu input)
|
||||
{
|
||||
return To<Playing>();
|
||||
}
|
||||
|
||||
public Transition On(in Input.SaveGame input)
|
||||
{
|
||||
Output(new Output.SaveGame());
|
||||
return To<Playing>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dw1wcux7lcpqy
|
||||
@@ -0,0 +1 @@
|
||||
uid://cpu75lmblmbj4
|
||||
@@ -0,0 +1,25 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record InventoryOpened : Playing, IGet<Input.CloseInventory>
|
||||
{
|
||||
public InventoryOpened()
|
||||
{
|
||||
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.OpenInventory()); });
|
||||
this.OnExit(() => { Get<IGameRepo>().Resume(); Output(new Output.HideInventory()); });
|
||||
}
|
||||
|
||||
public Transition On(in Input.CloseInventory input)
|
||||
{
|
||||
return To<Playing>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://dmbireek8b68t
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
using Chickensoft.Introspection;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record MenuBackdrop : State, IGet<Input.StartGame>, IGet<Input.Initialize>
|
||||
{
|
||||
public MenuBackdrop()
|
||||
{
|
||||
OnAttach(() => Get<IAppRepo>().GameEntered += OnGameEntered);
|
||||
OnDetach(() => Get<IAppRepo>().GameEntered -= OnGameEntered);
|
||||
}
|
||||
|
||||
public void OnGameEntered() => Input(new Input.StartGame());
|
||||
|
||||
public Transition On(in Input.StartGame input)
|
||||
{
|
||||
Get<IMap>().LoadMap();
|
||||
return To<Playing>();
|
||||
}
|
||||
|
||||
public Transition On(in Input.Initialize input)
|
||||
{
|
||||
return ToSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://lwjsht36v6ut
|
||||
@@ -0,0 +1,22 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record MinimapOpen : Playing, IGet<Input.MiniMapButtonReleased>
|
||||
{
|
||||
public MinimapOpen()
|
||||
{
|
||||
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowMiniMap()); });
|
||||
this.OnExit(() => { Get<IGameRepo>().Resume(); Output(new Output.HideMiniMap()); });
|
||||
}
|
||||
|
||||
public Transition On(in Input.MiniMapButtonReleased input) => To<Playing>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://nlpm8t4dege2
|
||||
@@ -0,0 +1,26 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record Paused : Playing, IGet<Input.UnpauseGame>
|
||||
{
|
||||
public Paused()
|
||||
{
|
||||
this.OnEnter(() =>
|
||||
{
|
||||
Get<IGameRepo>().Pause();
|
||||
Output(new Output.ShowPauseMenu());
|
||||
});
|
||||
this.OnExit(() => Output(new Output.ExitPauseMenu()));
|
||||
}
|
||||
|
||||
public virtual Transition On(in Input.UnpauseGame input) => To<Resuming>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://c46publoqhqsn
|
||||
@@ -0,0 +1,43 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record Playing : State,
|
||||
IGet<Input.OpenInventory>,
|
||||
IGet<Input.MiniMapButtonPressed>,
|
||||
IGet<Input.GameOver>,
|
||||
IGet<Input.AskForTeleport>,
|
||||
IGet<Input.PauseGame>,
|
||||
IGet<Input.GoToOverworld>
|
||||
{
|
||||
public Playing()
|
||||
{
|
||||
OnAttach(() => Output(new Output.StartGame()));
|
||||
}
|
||||
|
||||
public void OnEnded() => Input(new Input.GameOver());
|
||||
|
||||
public Transition On(in Input.OpenInventory input) => To<InventoryOpened>();
|
||||
|
||||
public Transition On(in Input.MiniMapButtonPressed input) => To<MinimapOpen>();
|
||||
|
||||
public Transition On(in Input.GameOver input) => To<Quit>();
|
||||
|
||||
public Transition On(in Input.AskForTeleport input) => To<AskForTeleport>();
|
||||
|
||||
public Transition On(in Input.PauseGame input) => To<Paused>();
|
||||
|
||||
public Transition On(in Input.GoToOverworld input)
|
||||
{
|
||||
Output(new Output.GoToOverworld());
|
||||
return ToSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://i54nvesmcliy
|
||||
@@ -0,0 +1,19 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record Quit : State
|
||||
{
|
||||
public Quit()
|
||||
{
|
||||
this.OnEnter(() => Output(new Output.ShowLostScreen()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://cq37bi3y07rxa
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.LogicBlocks;
|
||||
|
||||
public partial class GameLogic
|
||||
{
|
||||
public partial record State
|
||||
{
|
||||
[Meta]
|
||||
public partial record Resuming : Playing, IGet<Input.PauseMenuTransitioned>
|
||||
{
|
||||
public Resuming()
|
||||
{
|
||||
this.OnEnter(() => Get<IGameRepo>().Resume());
|
||||
this.OnExit(() => Output(new Output.HidePauseMenu()));
|
||||
}
|
||||
|
||||
public Transition On(in Input.PauseMenuTransitioned input) =>
|
||||
To<Playing>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://clh8ucurjwuvh
|
||||
Reference in New Issue
Block a user