Compare commits

...

1 Commits

Author SHA1 Message Date
9f9ef72390 Refactor identifiers and add subtitle UI 2026-05-17 11:56:08 +01:00
25 changed files with 276 additions and 6871 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -27,6 +27,14 @@ mainly on vines and thorns.
11. **Workflow** - You're not to make any code changes until you've shown me the proposed changes, I'll then either approve, deny, or modify them before you make the change. 11. **Workflow** - You're not to make any code changes until you've shown me the proposed changes, I'll then either approve, deny, or modify them before you make the change.
12. **Events** - We use C# events, actions, and delegates rather than UnityEvents, except when dealing with raw/stock ui components. 12. **Events** - We use C# events, actions, and delegates rather than UnityEvents, except when dealing with raw/stock ui components.
## Semantics
1. **Access** - All methods, properties, and fields, should always be the minimum required access.
2. **Const** - All const fields and variables should be ALL_CAP_UNDERSCORED for names.
3. **Variable Ordering** - Const variables followed by Unity serialized fields, followed by private/protected variables, followed by public access.
4. **Method Ordering** - vContainer injection method, followed by private Unity Methods (Awake, Start, Update, etc), followed by public methods, then protected, then followed by private methods.
## Documentation ## Documentation
UniTask - https://github.com/Cysharp/UniTask UniTask - https://github.com/Cysharp/UniTask

View File

@@ -13,7 +13,7 @@ namespace BriarQueen.Data.IO.Saves
[MemoryPackable] [MemoryPackable]
public partial class SaveGame public partial class SaveGame
{ {
public string SaveVersion = "0.0.2-alpha"; public string SaveVersion;
public string SaveFileName; public string SaveFileName;
// Key Unlocks // Key Unlocks
@@ -115,12 +115,12 @@ namespace BriarQueen.Data.IO.Saves
// -------- Helper Methods -------- // -------- Helper Methods --------
public bool IsPuzzleCompleted(PuzzleKey puzzle) public bool IsPuzzleCompleted(PuzzleKey puzzle)
{ {
return PuzzleCompleted.TryGetValue(PuzzleIdentifiers.AllPuzzles[puzzle], out var completed) && completed; return PuzzleCompleted.TryGetValue(PuzzleIdentifiers.Get(puzzle), out var completed) && completed;
} }
public void SetPuzzleCompleted(PuzzleKey puzzle, bool completed = true) public void SetPuzzleCompleted(PuzzleKey puzzle, bool completed = true)
{ {
PuzzleCompleted[PuzzleIdentifiers.AllPuzzles[puzzle]] = completed; PuzzleCompleted[PuzzleIdentifiers.Get(puzzle)] = completed;
} }
public bool GetLevelFlag(LevelFlag flag) public bool GetLevelFlag(LevelFlag flag)
@@ -133,4 +133,4 @@ namespace BriarQueen.Data.IO.Saves
LevelFlags[flag] = value; LevelFlags[flag] = value;
} }
} }
} }

View File

@@ -2,10 +2,6 @@ namespace BriarQueen.Data.Identifiers
{ {
public enum AchievementID public enum AchievementID
{ {
WorkshopSafeUnlocked, AshwickGateKeypadUnlocked,
WorkshopPuzzleBoxSolved,
FountainGemPuzzleSolved,
FireplaceLockboxPuzzleBoxSolved,
LaxleyGrandfatherClockPuzzleSolved,
} }
} }

View File

@@ -49,9 +49,9 @@ namespace BriarQueen.Data.Identifiers
ClockTower, ClockTower,
} }
public static class AudioNameIdentifiers public static class AudioNameIdentifiers
{ {
public static readonly IReadOnlyDictionary<MusicKey, string> Music = private static readonly IReadOnlyDictionary<MusicKey, string> _music =
new ReadOnlyDictionary<MusicKey, string>( new ReadOnlyDictionary<MusicKey, string>(
new Dictionary<MusicKey, string> new Dictionary<MusicKey, string>
{ {
@@ -59,7 +59,7 @@ namespace BriarQueen.Data.Identifiers
// { MusicKey.SomeTrack, "Music:SomeTrack" } // { MusicKey.SomeTrack, "Music:SomeTrack" }
}); });
public static readonly IReadOnlyDictionary<SFXKey, string> SFX = private static readonly IReadOnlyDictionary<SFXKey, string> _sfx =
new ReadOnlyDictionary<SFXKey, string>( new ReadOnlyDictionary<SFXKey, string>(
new Dictionary<SFXKey, string> new Dictionary<SFXKey, string>
{ {
@@ -68,7 +68,7 @@ namespace BriarQueen.Data.Identifiers
{ SFXKey.AshwickGateOpening, "SFX:Level:AshwickOutskirts:GateOpening" }, { SFXKey.AshwickGateOpening, "SFX:Level:AshwickOutskirts:GateOpening" },
}); });
public static readonly IReadOnlyDictionary<UIFXKey, string> UIFX = private static readonly IReadOnlyDictionary<UIFXKey, string> _uifx =
new ReadOnlyDictionary<UIFXKey, string>( new ReadOnlyDictionary<UIFXKey, string>(
new Dictionary<UIFXKey, string> new Dictionary<UIFXKey, string>
{ {
@@ -76,14 +76,14 @@ namespace BriarQueen.Data.Identifiers
{ UIFXKey.CodexEntryUnlocked, "UIFX:General:CodexEntryUnlocked" }, { UIFXKey.CodexEntryUnlocked, "UIFX:General:CodexEntryUnlocked" },
}); });
public static readonly IReadOnlyDictionary<AmbienceKey, string> Ambience = private static readonly IReadOnlyDictionary<AmbienceKey, string> _ambience =
new ReadOnlyDictionary<AmbienceKey, string>( new ReadOnlyDictionary<AmbienceKey, string>(
new Dictionary<AmbienceKey, string> new Dictionary<AmbienceKey, string>
{ {
// Add ambience mappings here // Add ambience mappings here
}); });
public static readonly IReadOnlyDictionary<VoiceKey, string> Voice = private static readonly IReadOnlyDictionary<VoiceKey, string> _voice =
new ReadOnlyDictionary<VoiceKey, string>( new ReadOnlyDictionary<VoiceKey, string>(
new Dictionary<VoiceKey, string> new Dictionary<VoiceKey, string>
{ {
@@ -106,27 +106,27 @@ namespace BriarQueen.Data.Identifiers
public static string Get(MusicKey key) public static string Get(MusicKey key)
{ {
return Music.TryGetValue(key, out var value) ? value : string.Empty; return _music.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(SFXKey key) public static string Get(SFXKey key)
{ {
return SFX.TryGetValue(key, out var value) ? value : string.Empty; return _sfx.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(UIFXKey key) public static string Get(UIFXKey key)
{ {
return UIFX.TryGetValue(key, out var value) ? value : string.Empty; return _uifx.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(AmbienceKey key) public static string Get(AmbienceKey key)
{ {
return Ambience.TryGetValue(key, out var value) ? value : string.Empty; return _ambience.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(VoiceKey key) public static string Get(VoiceKey key)
{ {
return Voice.TryGetValue(key, out var value) ? value : string.Empty; return _voice.TryGetValue(key, out var value) ? value : string.Empty;
} }
} }
} }

View File

@@ -22,25 +22,25 @@ namespace BriarQueen.Data.Identifiers
public static class CodexEntryIDs public static class CodexEntryIDs
{ {
private const string DOCUMENT_PREFIX = "Codex:Document:"; private const string DOCUMENT_PREFIX = "Codex:Document";
private const string CLUE_PREFIX = "Codex:Clue:"; private const string CLUE_PREFIX = "Codex:Clue";
private const string PHOTO_PREFIX = "Codex:Photo:"; private const string PHOTO_PREFIX = "Codex:Photo";
public static readonly IReadOnlyDictionary<DocumentEntryID, string> Documents = private static readonly IReadOnlyDictionary<DocumentEntryID, string> _documents =
new ReadOnlyDictionary<DocumentEntryID, string>( new ReadOnlyDictionary<DocumentEntryID, string>(
new Dictionary<DocumentEntryID, string> new Dictionary<DocumentEntryID, string>
{ {
{ DocumentEntryID.C1CarNewspaper, GetDocumentIdentifier(DocumentEntryID.C1CarNewspaper) }, { DocumentEntryID.C1CarNewspaper, GetDocumentIdentifier(DocumentEntryID.C1CarNewspaper) },
}); });
public static readonly IReadOnlyDictionary<ClueEntryID, string> Clues = private static readonly IReadOnlyDictionary<ClueEntryID, string> _clues =
new ReadOnlyDictionary<ClueEntryID, string>( new ReadOnlyDictionary<ClueEntryID, string>(
new Dictionary<ClueEntryID, string> new Dictionary<ClueEntryID, string>
{ {
{ ClueEntryID.JasonsNote, $"{PHOTO_PREFIX}:AshwickMarketGate" }, { ClueEntryID.JasonsNote, GetClueIdentifier(ClueEntryID.JasonsNote) },
}); });
public static readonly IReadOnlyDictionary<PhotoEntryID, string> Photos = private static readonly IReadOnlyDictionary<PhotoEntryID, string> _photos =
new ReadOnlyDictionary<PhotoEntryID, string>( new ReadOnlyDictionary<PhotoEntryID, string>(
new Dictionary<PhotoEntryID, string> new Dictionary<PhotoEntryID, string>
{ {
@@ -48,32 +48,32 @@ namespace BriarQueen.Data.Identifiers
public static string Get(DocumentEntryID id) public static string Get(DocumentEntryID id)
{ {
return Documents.TryGetValue(id, out var value) ? value : string.Empty; return _documents.TryGetValue(id, out var value) ? value : string.Empty;
} }
public static string Get(ClueEntryID id) public static string Get(ClueEntryID id)
{ {
return Clues.TryGetValue(id, out var value) ? value : string.Empty; return _clues.TryGetValue(id, out var value) ? value : string.Empty;
} }
public static string Get(PhotoEntryID id) public static string Get(PhotoEntryID id)
{ {
return Photos.TryGetValue(id, out var value) ? value : string.Empty; return _photos.TryGetValue(id, out var value) ? value : string.Empty;
} }
private static string GetDocumentIdentifier(DocumentEntryID id) private static string GetDocumentIdentifier(DocumentEntryID id)
{ {
return $"{DOCUMENT_PREFIX}{id}"; return $"{DOCUMENT_PREFIX}:{id}";
} }
private static string GetClueIdentifier(ClueEntryID id) private static string GetClueIdentifier(ClueEntryID id)
{ {
return $"{CLUE_PREFIX}{id}"; return $"{CLUE_PREFIX}:{id}";
} }
private static string GetPhotoIdentifier(PhotoEntryID id) private static string GetPhotoIdentifier(PhotoEntryID id)
{ {
return $"{PHOTO_PREFIX}{id}"; return $"{PHOTO_PREFIX}:{id}";
} }
} }
} }

View File

@@ -40,7 +40,7 @@ namespace BriarQueen.Data.Identifiers
public static class InteractEventIDs public static class InteractEventIDs
{ {
public static readonly IReadOnlyDictionary<ItemInteractKey, string> ItemInteractions = private static readonly IReadOnlyDictionary<ItemInteractKey, string> _itemInteractions =
new ReadOnlyDictionary<ItemInteractKey, string>( new ReadOnlyDictionary<ItemInteractKey, string>(
new Dictionary<ItemInteractKey, string> new Dictionary<ItemInteractKey, string>
{ {
@@ -54,13 +54,13 @@ namespace BriarQueen.Data.Identifiers
}); });
public static readonly IReadOnlyDictionary<LevelInteractKey, string> LevelInteractions = private static readonly IReadOnlyDictionary<LevelInteractKey, string> _levelInteractions =
new ReadOnlyDictionary<LevelInteractKey, string>( new ReadOnlyDictionary<LevelInteractKey, string>(
new Dictionary<LevelInteractKey, string> new Dictionary<LevelInteractKey, string>
{ {
}); });
public static readonly IReadOnlyDictionary<EnvironmentInteractKey, string> EnvironmentInteractions = private static readonly IReadOnlyDictionary<EnvironmentInteractKey, string> _environmentInteractions =
new ReadOnlyDictionary<EnvironmentInteractKey, string>( new ReadOnlyDictionary<EnvironmentInteractKey, string>(
new Dictionary<EnvironmentInteractKey, string> new Dictionary<EnvironmentInteractKey, string>
{ {
@@ -73,7 +73,7 @@ namespace BriarQueen.Data.Identifiers
{ EnvironmentInteractKey.ClockTower, "Even from here, something about that clock tower feels wrong."} { EnvironmentInteractKey.ClockTower, "Even from here, something about that clock tower feels wrong."}
}); });
public static readonly IReadOnlyDictionary<UIInteractKey, string> UIInteractions = private static readonly IReadOnlyDictionary<UIInteractKey, string> _uiInteractions =
new ReadOnlyDictionary<UIInteractKey, string>( new ReadOnlyDictionary<UIInteractKey, string>(
new Dictionary<UIInteractKey, string> new Dictionary<UIInteractKey, string>
{ {
@@ -82,22 +82,22 @@ namespace BriarQueen.Data.Identifiers
public static string Get(ItemInteractKey key) public static string Get(ItemInteractKey key)
{ {
return ItemInteractions.TryGetValue(key, out var value) ? value : string.Empty; return _itemInteractions.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(LevelInteractKey key) public static string Get(LevelInteractKey key)
{ {
return LevelInteractions.TryGetValue(key, out var value) ? value : string.Empty; return _levelInteractions.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(EnvironmentInteractKey key) public static string Get(EnvironmentInteractKey key)
{ {
return EnvironmentInteractions.TryGetValue(key, out var value) ? value : string.Empty; return _environmentInteractions.TryGetValue(key, out var value) ? value : string.Empty;
} }
public static string Get(UIInteractKey key) public static string Get(UIInteractKey key)
{ {
return UIInteractions.TryGetValue(key, out var value) ? value : string.Empty; return _uiInteractions.TryGetValue(key, out var value) ? value : string.Empty;
} }
} }
} }

View File

@@ -25,19 +25,19 @@ namespace BriarQueen.Data.Identifiers
public static class ItemIDs public static class ItemIDs
{ {
public static readonly IReadOnlyDictionary<PuzzleSlotKey, string> PuzzleSlots = private static readonly IReadOnlyDictionary<PuzzleSlotKey, string> _puzzleSlots =
new ReadOnlyDictionary<PuzzleSlotKey, string>( new ReadOnlyDictionary<PuzzleSlotKey, string>(
new Dictionary<PuzzleSlotKey, string> new Dictionary<PuzzleSlotKey, string>
{ {
}); });
public static readonly IReadOnlyDictionary<EnvironmentKey, string> Environment = private static readonly IReadOnlyDictionary<EnvironmentKey, string> _environment =
new ReadOnlyDictionary<EnvironmentKey, string>( new ReadOnlyDictionary<EnvironmentKey, string>(
new Dictionary<EnvironmentKey, string> new Dictionary<EnvironmentKey, string>
{ {
}); });
public static readonly IReadOnlyDictionary<ItemKey, string> Pickups = private static readonly IReadOnlyDictionary<ItemKey, string> _pickups =
new ReadOnlyDictionary<ItemKey, string>( new ReadOnlyDictionary<ItemKey, string>(
new Dictionary<ItemKey, string> new Dictionary<ItemKey, string>
{ {
@@ -48,37 +48,37 @@ namespace BriarQueen.Data.Identifiers
public static string Get(ItemKey key) public static string Get(ItemKey key)
{ {
return Pickups.TryGetValue(key, out var id) ? id : string.Empty; return _pickups.TryGetValue(key, out var id) ? id : string.Empty;
} }
public static string Get(EnvironmentKey key) public static string Get(EnvironmentKey key)
{ {
return Environment.TryGetValue(key, out var id) ? id : string.Empty; return _environment.TryGetValue(key, out var id) ? id : string.Empty;
} }
public static string Get(PuzzleSlotKey key) public static string Get(PuzzleSlotKey key)
{ {
return PuzzleSlots.TryGetValue(key, out var id) ? id : string.Empty; return _puzzleSlots.TryGetValue(key, out var id) ? id : string.Empty;
} }
public static bool TryGet(ItemKey key, out string id) public static bool TryGet(ItemKey key, out string id)
{ {
return Pickups.TryGetValue(key, out id); return _pickups.TryGetValue(key, out id);
} }
public static bool TryGet(EnvironmentKey key, out string id) public static bool TryGet(EnvironmentKey key, out string id)
{ {
return Environment.TryGetValue(key, out id); return _environment.TryGetValue(key, out id);
} }
public static bool TryGet(PuzzleSlotKey key, out string id) public static bool TryGet(PuzzleSlotKey key, out string id)
{ {
return PuzzleSlots.TryGetValue(key, out id); return _puzzleSlots.TryGetValue(key, out id);
} }
public static IEnumerable<string> GetAllItemIDs() public static IEnumerable<string> GetAllItemIDs()
{ {
return Pickups.Values; return _pickups.Values;
} }
} }
} }

View File

@@ -1,23 +1,30 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace BriarQueen.Data.Identifiers namespace BriarQueen.Data.Identifiers
{ {
public enum PuzzleKey public enum PuzzleKey
{ {
AshwickMarketGate, AshwickOutskirtsGate,
} }
public static class PuzzleIdentifiers public static class PuzzleIdentifiers
{ {
public static readonly Dictionary<PuzzleKey, string> AllPuzzles = new() private static readonly IReadOnlyDictionary<PuzzleKey, string> _allPuzzles =
{ new ReadOnlyDictionary<PuzzleKey, string>(
{ PuzzleKey.AshwickMarketGate, "CH1:Puzzle:AshwickMarketGate" }, new Dictionary<PuzzleKey, string>
}; {
{ PuzzleKey.AshwickOutskirtsGate, "CH1:Puzzle:AshwickOutskirtsGate" },
});
public static string Get(PuzzleKey key)
{
return _allPuzzles.TryGetValue(key, out var value) ? value : string.Empty;
}
// Optional helper to get all puzzle IDs
public static IEnumerable<string> GetAllPuzzleIDs() public static IEnumerable<string> GetAllPuzzleIDs()
{ {
return AllPuzzles.Values; return _allPuzzles.Values;
} }
} }
} }

View File

@@ -25,7 +25,7 @@ namespace BriarQueen.Data.Identifiers
public static class SubtitleIdentifiers public static class SubtitleIdentifiers
{ {
public static readonly IReadOnlyDictionary<SubtitleKey, SubtitleEntry> Subtitles = private static readonly IReadOnlyDictionary<SubtitleKey, SubtitleEntry> _subtitles =
new ReadOnlyDictionary<SubtitleKey, SubtitleEntry>( new ReadOnlyDictionary<SubtitleKey, SubtitleEntry>(
new Dictionary<SubtitleKey, SubtitleEntry> new Dictionary<SubtitleKey, SubtitleEntry>
{ {
@@ -34,22 +34,22 @@ namespace BriarQueen.Data.Identifiers
public static bool TryGet(SubtitleKey key, out SubtitleEntry entry) public static bool TryGet(SubtitleKey key, out SubtitleEntry entry)
{ {
return Subtitles.TryGetValue(key, out entry); return _subtitles.TryGetValue(key, out entry);
} }
public static string GetText(SubtitleKey key) public static string GetText(SubtitleKey key)
{ {
return Subtitles.TryGetValue(key, out var entry) ? entry.Text : string.Empty; return _subtitles.TryGetValue(key, out var entry) ? entry.Text : string.Empty;
} }
public static float GetPreferredDuration(SubtitleKey key) public static float GetPreferredDuration(SubtitleKey key)
{ {
return Subtitles.TryGetValue(key, out var entry) ? entry.PreferredDurationSeconds : 0f; return _subtitles.TryGetValue(key, out var entry) ? entry.PreferredDurationSeconds : 0f;
} }
public static IEnumerable<SubtitleKey> GetAllKeys() public static IEnumerable<SubtitleKey> GetAllKeys()
{ {
return Subtitles.Keys; return _subtitles.Keys;
} }
} }
} }

View File

@@ -6,8 +6,6 @@ namespace BriarQueen.Data.Identifiers
{ {
[DisplayName("Empty Hands")] [DisplayName("Empty Hands")]
None = 0, None = 0,
[DisplayName("Sharpened Knife")]
Knife = 1,
} }

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace BriarQueen.Data.Identifiers namespace BriarQueen.Data.Identifiers
{ {
@@ -21,63 +22,77 @@ namespace BriarQueen.Data.Identifiers
public static class TutorialPopupTexts public static class TutorialPopupTexts
{ {
public static readonly Dictionary<TutorialPopupID, string> AllPopups = new() private static readonly IReadOnlyDictionary<TutorialPopupID, string> _allPopups =
new ReadOnlyDictionary<TutorialPopupID, string>(
new Dictionary<TutorialPopupID, string>
{
{
TutorialPopupID.ReturnToPreviousLevel,
"Click the lower corners to return to the previous area."
},
{
TutorialPopupID.UsingItemsTogether,
"Select one item, then click another to use them together."
},
{
TutorialPopupID.HideHUD,
"Press '{Hide_HUD}' to hide the HUD."
},
{
TutorialPopupID.MultipleUseItems,
"Some items can be used more than once, but they may wear out."
},
{
TutorialPopupID.DarkRooms,
"Dark rooms can hide important details. Use light to reveal them."
},
{
TutorialPopupID.Codex,
"Documents you find are stored in the Codex. Press '{Codex}' to open it."
},
{
TutorialPopupID.HiddenItems,
"Some items are hidden. Search carefully."
},
{
TutorialPopupID.ResetPuzzles,
"Some puzzles can be reset if you get stuck."
},
{
TutorialPopupID.LeavingPuzzles,
"When you leave a puzzle, your progress is saved."
},
{
TutorialPopupID.Tools,
"You'll find tools as you explore. Try them on different objects. Press '{Show_Tools}' to open your tools."
},
{
TutorialPopupID.ItemsAway,
"Press '{Right_Click}' to put away the selected item."
},
{
TutorialPopupID.ItemCycling,
"Press '{Previous_Item}' or '{Next_Item}' to cycle through the items in your backpack."
},
{
TutorialPopupID.ToolCycling,
"Press '{Previous_Tool}' or '{Next_Tool}' to cycle through your tools."
},
});
public static bool TryGet(TutorialPopupID id, out string text)
{ {
{ return _allPopups.TryGetValue(id, out text);
TutorialPopupID.ReturnToPreviousLevel, }
"Click the lower corners to return to the previous area."
},
{
TutorialPopupID.UsingItemsTogether,
"Select one item, then click another to use them together."
},
{
TutorialPopupID.HideHUD,
"Press '{Hide_HUD}' to hide the HUD."
},
{
TutorialPopupID.MultipleUseItems,
"Some items can be used more than once, but they may wear out."
},
{
TutorialPopupID.DarkRooms,
"Dark rooms can hide important details. Use light to reveal them."
},
{
TutorialPopupID.Codex,
"Documents you find are stored in the Codex. Press '{Codex}' to open it."
},
{
TutorialPopupID.HiddenItems,
"Some items are hidden. Search carefully."
},
{
TutorialPopupID.ResetPuzzles,
"Some puzzles can be reset if you get stuck."
},
{
TutorialPopupID.LeavingPuzzles,
"When you leave a puzzle, your progress is saved."
},
{ public static string Get(TutorialPopupID id)
TutorialPopupID.Tools, {
"You'll find tools as you explore. Try them on different objects. Press '{Show_Tools}' to open your tools." return _allPopups.TryGetValue(id, out var value) ? value : string.Empty;
}, }
{
TutorialPopupID.ItemsAway,
"Press '{Right_Click}' to put away the selected item."
},
{
TutorialPopupID.ItemCycling,
"Press '{Previous_Item}' or '{Next_Item}' to cycle through the items in your backpack."
},
{
TutorialPopupID.ToolCycling,
"Press '{Previous_Tool}' or '{Next_Tool}' to cycle through your tools."
},
};
public static IEnumerable<string> GetAllTexts() => AllPopups.Values; public static IEnumerable<string> GetAllTexts()
{
return _allPopups.Values;
}
} }
} }

View File

@@ -208,7 +208,7 @@ namespace BriarQueen.Framework.Managers.IO
CurrentSave = new SaveGame CurrentSave = new SaveGame
{ {
SaveFileName = saveFileName, SaveFileName = saveFileName,
SaveVersion = "0.0.1a", SaveVersion = Application.version,
OpeningCinematicPlayed = false OpeningCinematicPlayed = false
}; };
IsGameLoaded = true; IsGameLoaded = true;

View File

@@ -62,7 +62,7 @@ namespace BriarQueen.Framework.Services.Tutorials
/// </summary> /// </summary>
public string ResolveText(TutorialPopupID id) public string ResolveText(TutorialPopupID id)
{ {
if (!TutorialPopupTexts.AllPopups.TryGetValue(id, out var template)) if (!TutorialPopupTexts.TryGet(id, out var template))
return string.Empty; return string.Empty;
return ResolveText(template); return ResolveText(template);
@@ -101,4 +101,4 @@ namespace BriarQueen.Framework.Services.Tutorials
return string.IsNullOrWhiteSpace(displayString) ? string.Empty : displayString; return string.IsNullOrWhiteSpace(displayString) ? string.Empty : displayString;
} }
} }
} }

View File

@@ -97,8 +97,8 @@ namespace BriarQueen.Game.Cinematics
private Sequence _skipTextSequence; private Sequence _skipTextSequence;
protected EventCoordinator EventCoordinator; protected EventCoordinator _eventCoordinator;
protected InputManager InputManager; protected InputManager _inputManager;
protected virtual void Awake() protected virtual void Awake()
{ {
@@ -116,7 +116,7 @@ namespace BriarQueen.Game.Cinematics
{ {
if (!_isPlaying) return; if (!_isPlaying) return;
if (!_allowKeyboardEscapeSkipFallback) return; if (!_allowKeyboardEscapeSkipFallback) return;
if (InputManager != null) return; if (_inputManager != null) return;
var kb = Keyboard.current; var kb = Keyboard.current;
if (kb != null && kb.escapeKey.wasPressedThisFrame) if (kb != null && kb.escapeKey.wasPressedThisFrame)
@@ -247,14 +247,14 @@ namespace BriarQueen.Game.Cinematics
protected virtual void BindSkipAction() protected virtual void BindSkipAction()
{ {
if (InputManager == null) if (_inputManager == null)
return; return;
InputManager.BindPauseForSkip(OnSkipPerformed); _inputManager.BindPauseForSkip(OnSkipPerformed);
if (_skipText != null) if (_skipText != null)
{ {
var inputType = InputManager.DeviceInputType; var inputType = _inputManager.DeviceInputType;
switch (inputType) switch (inputType)
{ {
case DeviceInputType.KeyboardAndMouse: case DeviceInputType.KeyboardAndMouse:
@@ -278,10 +278,10 @@ namespace BriarQueen.Game.Cinematics
protected virtual void UnbindSkipAction() protected virtual void UnbindSkipAction()
{ {
if (InputManager == null) if (_inputManager == null)
return; return;
InputManager.ResetPauseBind(OnSkipPerformed); _inputManager.ResetPauseBind(OnSkipPerformed);
} }
private void OnSkipPerformed(InputAction.CallbackContext _) private void OnSkipPerformed(InputAction.CallbackContext _)
@@ -535,7 +535,7 @@ namespace BriarQueen.Game.Cinematics
{ {
StopSkipTextTween(); StopSkipTextTween();
if (EventCoordinator != null) if (_eventCoordinator != null)
{ {
if (_cinematicCanvasGroup != null) if (_cinematicCanvasGroup != null)
{ {
@@ -544,7 +544,7 @@ namespace BriarQueen.Game.Cinematics
_cinematicCanvasGroup.alpha = 1f; _cinematicCanvasGroup.alpha = 1f;
} }
EventCoordinator.PublishImmediate(new FadeEvent(false, 1f)); _eventCoordinator.PublishImmediate(new FadeEvent(false, 1f));
return; return;
} }
@@ -679,8 +679,8 @@ namespace BriarQueen.Game.Cinematics
[Inject] [Inject]
public void Construct(EventCoordinator eventCoordinator, InputManager inputManager) public void Construct(EventCoordinator eventCoordinator, InputManager inputManager)
{ {
EventCoordinator = eventCoordinator; _eventCoordinator = eventCoordinator;
InputManager = inputManager; _inputManager = inputManager;
} }
} }
} }

View File

@@ -39,12 +39,12 @@ namespace BriarQueen.Game.Items.HoverZones
[SerializeField] [SerializeField]
private SFXKey _soundEffectOnClick; private SFXKey _soundEffectOnClick;
protected EventCoordinator EventCoordinator; protected EventCoordinator _eventCoordinator;
protected LevelManager LevelManager; protected LevelManager _levelManager;
protected SaveManager SaveManager; protected SaveManager _saveManager;
protected AudioManager AudioManager; protected AudioManager _audioManager;
protected TutorialService TutorialService; protected TutorialService _tutorialService;
public CanvasGroup CanvasGroup; public CanvasGroup CanvasGroup;
@@ -76,13 +76,13 @@ namespace BriarQueen.Game.Items.HoverZones
var message = !string.IsNullOrEmpty(_lockedInteractText) ? _lockedInteractText var message = !string.IsNullOrEmpty(_lockedInteractText) ? _lockedInteractText
: InteractEventIDs.Get(EnvironmentInteractKey.Locked); : InteractEventIDs.Get(EnvironmentInteractKey.Locked);
EventCoordinator.Publish(new DisplayInteractEvent(message)); _eventCoordinator.Publish(new DisplayInteractEvent(message));
return; return;
} }
if (item != null) if (item != null)
{ {
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.CantUseItem))); _eventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.CantUseItem)));
return; return;
} }
@@ -90,17 +90,17 @@ namespace BriarQueen.Game.Items.HoverZones
if (_soundEffectOnClick != SFXKey.None) if (_soundEffectOnClick != SFXKey.None)
{ {
AudioManager.Play(AudioNameIdentifiers.Get(_soundEffectOnClick)); _audioManager.Play(AudioNameIdentifiers.Get(_soundEffectOnClick));
} }
var loaded = await LevelManager.LoadLevel(levelId); var loaded = await _levelManager.LoadLevel(levelId);
if (!loaded) if (!loaded)
{ {
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(EnvironmentInteractKey.CantGoThere))); _eventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(EnvironmentInteractKey.CantGoThere)));
} }
TutorialService.DisplayTutorial(TutorialPopupID.ReturnToPreviousLevel); _tutorialService.DisplayTutorial(TutorialPopupID.ReturnToPreviousLevel);
} }
public virtual UniTask EnterHover() public virtual UniTask EnterHover()
@@ -127,11 +127,11 @@ namespace BriarQueen.Game.Items.HoverZones
public void Construct(LevelManager levelManager, EventCoordinator eventCoordinator, public void Construct(LevelManager levelManager, EventCoordinator eventCoordinator,
SaveManager saveManager, AudioManager audioManager, TutorialService tutorialService) SaveManager saveManager, AudioManager audioManager, TutorialService tutorialService)
{ {
LevelManager = levelManager; _levelManager = levelManager;
EventCoordinator = eventCoordinator; _eventCoordinator = eventCoordinator;
SaveManager = saveManager; _saveManager = saveManager;
AudioManager = audioManager; _audioManager = audioManager;
TutorialService = tutorialService; _tutorialService = tutorialService;
} }
} }
} }

View File

@@ -16,6 +16,7 @@ using PrimeTween;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI; using UnityEngine.UI;
using VContainer; using VContainer;
@@ -29,8 +30,8 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
public class AshwickGateKeypadPuzzle : BasePuzzle, IPuzzleStateful, IUIWindow, IUIBackHandler, IUIOverlayHost public class AshwickGateKeypadPuzzle : BasePuzzle, IPuzzleStateful, IUIWindow, IUIBackHandler, IUIOverlayHost
{ {
private const string CorrectCode = "312"; private const string CORRECT_CODE = "312";
private const int RequiredDigits = 3; private const int REQUIRED_DIGITS = 3;
[Header("Scene References")] [Header("Scene References")]
[SerializeField] private AshwickOutskirts _outskirts; [SerializeField] private AshwickOutskirts _outskirts;
@@ -50,7 +51,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
[SerializeField] private TweenSettings _panelFadeTweenSettings = new() [SerializeField] private TweenSettings _panelFadeTweenSettings = new()
{ {
duration = 1.5f, duration = 0.8f,
ease = Ease.OutQuad, ease = Ease.OutQuad,
useUnscaledTime = true useUnscaledTime = true
}; };
@@ -71,7 +72,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
private TutorialService _tutorialService; private TutorialService _tutorialService;
private UIManager _uiManager; private UIManager _uiManager;
public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.AshwickMarketGate]; public override string PuzzleID => PuzzleIdentifiers.Get(PuzzleKey.AshwickOutskirtsGate);
public bool IsCompleted => _isCompleted || SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen); public bool IsCompleted => _isCompleted || SaveManager.GetLevelFlag(LevelFlag.AshwickGateOpen);
public WindowType WindowType => WindowType.AshwickGateKeypadWindow; public WindowType WindowType => WindowType.AshwickGateKeypadWindow;
public UIPauseBehavior PauseBehavior => UIPauseBehavior.OpenPauseOverlay; public UIPauseBehavior PauseBehavior => UIPauseBehavior.OpenPauseOverlay;
@@ -161,11 +162,12 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
var restored = MemoryPackSerializer.Deserialize<AshwickGateKeypadPuzzleState>(state); var restored = MemoryPackSerializer.Deserialize<AshwickGateKeypadPuzzleState>(state);
_currentDigits = restored?.Digits ?? string.Empty; _currentDigits = restored?.Digits ?? string.Empty;
if (_currentDigits.Length > RequiredDigits) if (_currentDigits.Length > REQUIRED_DIGITS)
_currentDigits = _currentDigits[..RequiredDigits]; _currentDigits = _currentDigits[..REQUIRED_DIGITS];
} }
SyncDisplay(); SyncDisplay();
ResetFeedbackState();
return UniTask.CompletedTask; return UniTask.CompletedTask;
} }
@@ -178,7 +180,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
_currentDigits = string.Empty; _currentDigits = string.Empty;
SyncDisplay(); SyncDisplay();
SaveManager.SetPuzzleCompleted(PuzzleKey.AshwickMarketGate, true, requestSave: false); SaveManager.SetPuzzleCompleted(PuzzleKey.AshwickOutskirtsGate, true, requestSave: false);
_skipSaveOnHide = true; _skipSaveOnHide = true;
_uiManager?.CloseWindow(WindowType); _uiManager?.CloseWindow(WindowType);
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.AshwickGateOpening)); AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.AshwickGateOpening));
@@ -195,6 +197,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
SetPanelState(0f, false, true); SetPanelState(0f, false, true);
SyncDisplay(); SyncDisplay();
ResetFeedbackState();
EnsureExclusiveRaycaster(); EnsureExclusiveRaycaster();
try try
@@ -229,6 +232,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
_isOpen = false; _isOpen = false;
ResetPanelTween(); ResetPanelTween();
ResetFeedbackState();
if (_panelGroup != null) if (_panelGroup != null)
{ {
@@ -349,13 +353,16 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
private void OnDigitPressed(int digit) private void OnDigitPressed(int digit)
{ {
if (_isEvaluating || IsCompleted || !_isOpen || _currentDigits.Length >= RequiredDigits) if (_isEvaluating || IsCompleted || !_isOpen || _currentDigits.Length >= REQUIRED_DIGITS)
return; return;
if (_currentDigits.Length == 0)
ResetFeedbackState();
_currentDigits += digit.ToString(); _currentDigits += digit.ToString();
SyncDisplay(); SyncDisplay();
if (_currentDigits.Length == RequiredDigits) if (_currentDigits.Length == REQUIRED_DIGITS)
EvaluateCode().Forget(); EvaluateCode().Forget();
} }
@@ -366,7 +373,7 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
if (_panelGroup != null) if (_panelGroup != null)
_panelGroup.interactable = false; _panelGroup.interactable = false;
if (_currentDigits == CorrectCode) if (_currentDigits == CORRECT_CODE)
{ {
if (_statusGlow != null) if (_statusGlow != null)
{ {
@@ -438,6 +445,21 @@ namespace BriarQueen.Game.Puzzles.ChapterOne.AshwickHallow
_displayField.text = _currentDigits; _displayField.text = _currentDigits;
} }
private void ResetFeedbackState()
{
_statusGlow?.TurnOff().Forget();
ResetCloseButtonSelection();
}
private void ResetCloseButtonSelection()
{
if (_closeButton == null || EventSystem.current == null)
return;
if (EventSystem.current.currentSelectedGameObject == _closeButton.gameObject)
EventSystem.current.SetSelectedGameObject(null);
}
private void SetPanelState(float alpha, bool interactable, bool blocksRaycasts) private void SetPanelState(float alpha, bool interactable, bool blocksRaycasts)
{ {
if (_panelGroup == null) if (_panelGroup == null)

View File

@@ -270,7 +270,6 @@ namespace BriarQueen.UI.HUD
return toolID switch return toolID switch
{ {
ToolID.None => string.Empty, ToolID.None => string.Empty,
ToolID.Knife => "Knife",
_ => toolID.ToString() _ => toolID.ToString()
}; };
} }

View File

@@ -12,7 +12,7 @@ PlayerSettings:
targetDevice: 2 targetDevice: 2
useOnDemandResources: 0 useOnDemandResources: 0
accelerometerFrequency: 60 accelerometerFrequency: 60
companyName: DefaultCompany companyName: Porta Interactive
productName: BriarQueen productName: BriarQueen
defaultCursor: {fileID: 0} defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0} cursorHotspot: {x: 0, y: 0}
@@ -144,7 +144,7 @@ PlayerSettings:
loadStoreDebugModeEnabled: 0 loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0 visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0 tvOSBundleVersion: 1.0
bundleVersion: 0.1.0 bundleVersion: 0.2.0-build
preloadedAssets: preloadedAssets:
- {fileID: 0} - {fileID: 0}
- {fileID: 11400000, guid: 1d6ed6270200a436ab407f74dc7890af, type: 2} - {fileID: 11400000, guid: 1d6ed6270200a436ab407f74dc7890af, type: 2}