Laxley Grandfather Clock puzzle artwork done.
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
using System;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public abstract class DisplayNameAttribute : Attribute
|
||||
namespace BriarQueen.Data.Attributes
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public DisplayNameAttribute(string name)
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class DisplayNameAttribute : Attribute
|
||||
{
|
||||
Name = name;
|
||||
public string Name { get; }
|
||||
|
||||
public DisplayNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,9 @@ namespace BriarQueen.Data.IO.Saves
|
||||
VillageStreetVinesCut,
|
||||
LaxleyFireplaceExtinguished,
|
||||
LaxleyLockboxOpened,
|
||||
LaxleyClockSolved,
|
||||
LaxleyHourHandRetrieved,
|
||||
LaxleyMinuteHandRetrieved,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -6,5 +6,6 @@ namespace BriarQueen.Data.Identifiers
|
||||
WorkshopPuzzleBoxSolved,
|
||||
FountainGemPuzzleSolved,
|
||||
FireplaceLockboxPuzzleBoxSolved,
|
||||
LaxleyGrandfatherClockPuzzleSolved,
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,9 @@ namespace BriarQueen.Data.Identifiers
|
||||
ChapterOneVillageMarketSquareStatue,
|
||||
ChapterOneVillageMarketSquareFirepit,
|
||||
ChapterOneVillageEnd,
|
||||
ChapterOneVillageEndChurch
|
||||
ChapterOneVillageEndChurch,
|
||||
ChapterOneLaxleyHouseLockbox,
|
||||
ChapterOneLaxleyHouseUpstairsStudy,
|
||||
}
|
||||
|
||||
public enum AssetItemKey
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace BriarQueen.Data.Identifiers
|
||||
SharpenKnife,
|
||||
LockBoxNumberReel,
|
||||
LockboxOpening,
|
||||
ClockOpening,
|
||||
}
|
||||
|
||||
public enum UIFXKey
|
||||
@@ -63,6 +64,8 @@ namespace BriarQueen.Data.Identifiers
|
||||
{ SFXKey.ResetPuzzle, "SFX_ResetPuzzle" },
|
||||
{ SFXKey.SharpenKnife, "SFX_SharpenKnife"},
|
||||
{ SFXKey.LockBoxNumberReel, "SFX_LockBoxNumberReel" },
|
||||
{ SFXKey.LockboxOpening, "SFX_LockboxOpening" },
|
||||
{ SFXKey.ClockOpening, "SFX_ClockOpening" },
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<UIFXKey, string> UIFX =
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace BriarQueen.Data.Identifiers
|
||||
None = 0,
|
||||
WorkshopDiary = 1,
|
||||
LaxleyHouseBillOfSale = 2,
|
||||
GranddfatherClockPlaque = 3
|
||||
}
|
||||
|
||||
public enum ClueEntryID
|
||||
@@ -25,20 +26,15 @@ namespace BriarQueen.Data.Identifiers
|
||||
WorkshopFadedPhoto = 1
|
||||
}
|
||||
|
||||
public enum LocationEntryID
|
||||
{
|
||||
None = 0,
|
||||
Village = 1,
|
||||
Workshop = 2
|
||||
}
|
||||
|
||||
public static class CodexEntryIDs
|
||||
{
|
||||
public static readonly IReadOnlyDictionary<BookEntryID, string> Books =
|
||||
new ReadOnlyDictionary<BookEntryID, string>(
|
||||
new Dictionary<BookEntryID, string>
|
||||
{
|
||||
{ BookEntryID.WorkshopDiary, "BOOK_WorkshopDiary" }
|
||||
{ BookEntryID.WorkshopDiary, "BOOK_WorkshopDiary" },
|
||||
{ BookEntryID.LaxleyHouseBillOfSale, "BOOK_LaxleyHouseBillOfSale" },
|
||||
{ BookEntryID.GranddfatherClockPlaque, "BOOK_GranddfatherClockPlaque" },
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<ClueEntryID, string> Clues =
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace BriarQueen.Data.Identifiers
|
||||
RagFallsApart = 7,
|
||||
LooksImportant = 8,
|
||||
WrongTool = 9,
|
||||
RefillBucket = 10,
|
||||
CollectEndlessGoblets = 10,
|
||||
}
|
||||
|
||||
public enum LevelInteractKey
|
||||
@@ -50,7 +50,11 @@ namespace BriarQueen.Data.Identifiers
|
||||
PumpTurnOn = 16,
|
||||
FireHot = 17,
|
||||
ExtinguishFire = 18,
|
||||
CauldronBoiledAway = 19
|
||||
CauldronBoiledAway = 19,
|
||||
LaxleyHouseBrokenClock = 20,
|
||||
LaxleyGrandfatherClockMissingBothHands = 21,
|
||||
LaxleyGrandfatherClockMissingHourHand = 22,
|
||||
LaxleyGrandfatherClockMissingMinuteHand = 23,
|
||||
}
|
||||
|
||||
public enum UIInteractKey
|
||||
@@ -58,66 +62,72 @@ namespace BriarQueen.Data.Identifiers
|
||||
None = 0,
|
||||
EmptySlot = 1,
|
||||
}
|
||||
|
||||
|
||||
public static class InteractEventIDs
|
||||
{
|
||||
public static readonly IReadOnlyDictionary<ItemInteractKey, string> ItemInteractions =
|
||||
new ReadOnlyDictionary<ItemInteractKey, string>(
|
||||
new Dictionary<ItemInteractKey, string>
|
||||
{
|
||||
{ ItemInteractKey.EmptyHands, "I need to put my tools away." },
|
||||
{ ItemInteractKey.CantUseItem, "That won't work here." },
|
||||
{ ItemInteractKey.RustyKnife, "It's too blunt to be useful." },
|
||||
{ ItemInteractKey.SomethingMissing, "Something's missing." },
|
||||
{ ItemInteractKey.PliersSnapped, "The pliers snapped. They're no use now." },
|
||||
{ ItemInteractKey.CarefulInteract, "I need to be careful with this." },
|
||||
{ ItemInteractKey.RagFallsApart, "The rag fell apart." },
|
||||
{ ItemInteractKey.LooksImportant, "That looks important." },
|
||||
{ ItemInteractKey.WrongTool, "I need the proper tool for this."},
|
||||
{ ItemInteractKey.RefillBucket, "I need to refill this before I can use."}
|
||||
{ ItemInteractKey.EmptyHands, "My hands are too full for that." },
|
||||
{ ItemInteractKey.CantUseItem, "That won’t work here." },
|
||||
{ ItemInteractKey.RustyKnife, "Too dull to be of any use." },
|
||||
{ ItemInteractKey.SomethingMissing, "Something isn’t right." },
|
||||
{ ItemInteractKey.PliersSnapped, "The pliers snap. That’s the end of them." },
|
||||
{ ItemInteractKey.CarefulInteract, "I should take care with this." },
|
||||
{ ItemInteractKey.RagFallsApart, "It fell apart in my hands." },
|
||||
{ ItemInteractKey.LooksImportant, "This feels important." },
|
||||
{ ItemInteractKey.WrongTool, "This isn’t the right tool." },
|
||||
{ ItemInteractKey.CollectEndlessGoblets, "Faint symbols coil across the goblet’s surface." },
|
||||
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<LevelInteractKey, string> LevelInteractions =
|
||||
new ReadOnlyDictionary<LevelInteractKey, string>(
|
||||
new Dictionary<LevelInteractKey, string>
|
||||
{
|
||||
{ LevelInteractKey.WaterValve, "I've already turned the water on." },
|
||||
{ LevelInteractKey.ClearVinesOutside, "I need to clear the vines outside first." },
|
||||
{ LevelInteractKey.PumphouseChain, "There must be a key around here somewhere." },
|
||||
{ LevelInteractKey.CutVines, "I need something to cut through these." },
|
||||
{ LevelInteractKey.WorkshopLockedSafe, "It's locked tight." },
|
||||
{ LevelInteractKey.UnlockedPumphouse, "You used the Pumphouse Key."},
|
||||
{ LevelInteractKey.WaterValve, "The water is already flowing." },
|
||||
{ LevelInteractKey.ClearVinesOutside, "The vines still block the way outside." },
|
||||
{ LevelInteractKey.PumphouseChain, "It’s locked by something more than rust." },
|
||||
{ LevelInteractKey.CutVines, "These won’t give way by hand." },
|
||||
{ LevelInteractKey.WorkshopLockedSafe, "Sealed tight." },
|
||||
{ LevelInteractKey.UnlockedPumphouse, "The lock gives with a dull click." },
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<EnvironmentInteractKey, string> EnvironmentInteractions =
|
||||
new ReadOnlyDictionary<EnvironmentInteractKey, string>(
|
||||
new Dictionary<EnvironmentInteractKey, string>
|
||||
{
|
||||
{ EnvironmentInteractKey.BrokenLantern, "It's too broken to use." },
|
||||
{ EnvironmentInteractKey.WorkshopWriting, "It could be worse... it could be blood." },
|
||||
{ EnvironmentInteractKey.UseGrindstone, "I could sharpen something on this." },
|
||||
{ EnvironmentInteractKey.WorkshopBookDisintegrating, "It fell apart in my hands." },
|
||||
{ EnvironmentInteractKey.UsingKnife, "I should be careful cutting these." },
|
||||
{ EnvironmentInteractKey.AlreadySharpened, "That should be sharp enough now." },
|
||||
{ EnvironmentInteractKey.Locked, "It's locked." },
|
||||
{ EnvironmentInteractKey.CantGoThere, "I can't go that way." },
|
||||
{ EnvironmentInteractKey.DirtyWindow, "I can't see through all this grime." },
|
||||
{ EnvironmentInteractKey.WorkshopBagNoItems, "There's nothing left inside." },
|
||||
{ EnvironmentInteractKey.FindCandle, "I should look for the candle." },
|
||||
{ EnvironmentInteractKey.DoesntBelong, "That doesn't belong here." },
|
||||
{ EnvironmentInteractKey.SharpGlass, "Ow... that's sharp." },
|
||||
{ EnvironmentInteractKey.FreshAndCoolWater, "The water feels cool and refreshing." },
|
||||
{ EnvironmentInteractKey.WorkshopBooks, "The books are ancient and crumbling." },
|
||||
{ EnvironmentInteractKey.PumpTurnOn, "The water pumps splutter into life."},
|
||||
{ EnvironmentInteractKey.FireHot, "I should put the fire out first."},
|
||||
{ EnvironmentInteractKey.CauldronBoiledAway, "Whatever was in the cauldron, boiled away long ago."}
|
||||
{ EnvironmentInteractKey.BrokenLantern, "Beyond repair." },
|
||||
{ EnvironmentInteractKey.WorkshopWriting, "At least it isn’t blood." },
|
||||
{ EnvironmentInteractKey.UseGrindstone, "This could still sharpen an edge." },
|
||||
{ EnvironmentInteractKey.WorkshopBookDisintegrating, "It crumbles at a touch." },
|
||||
{ EnvironmentInteractKey.UsingKnife, "Careful… one slip." },
|
||||
{ EnvironmentInteractKey.AlreadySharpened, "That edge will do." },
|
||||
{ EnvironmentInteractKey.Locked, "Locked." },
|
||||
{ EnvironmentInteractKey.CantGoThere, "No way through." },
|
||||
{ EnvironmentInteractKey.DirtyWindow, "Nothing visible through the grime." },
|
||||
{ EnvironmentInteractKey.WorkshopBagNoItems, "Picked clean." },
|
||||
{ EnvironmentInteractKey.FindCandle, "I need the candle that goes here." },
|
||||
{ EnvironmentInteractKey.DoesntBelong, "This feels out of place." },
|
||||
{ EnvironmentInteractKey.SharpGlass, "Still sharp enough to bite." },
|
||||
{ EnvironmentInteractKey.FreshAndCoolWater, "Cool. Clean. Unexpected." },
|
||||
{ EnvironmentInteractKey.WorkshopBooks, "Time hasn’t been kind to these." },
|
||||
{ EnvironmentInteractKey.PumpTurnOn, "The pumps shudder back to life." },
|
||||
{ EnvironmentInteractKey.FireHot, "Too hot to get close." },
|
||||
{ EnvironmentInteractKey.CauldronBoiledAway, "Whatever it held is long gone." },
|
||||
{ EnvironmentInteractKey.ExtinguishFire, "The symbols begin to glow as the goblet fills." },
|
||||
{ EnvironmentInteractKey.LaxleyHouseBrokenClock, "The clock stopped at three-thirty-three." },
|
||||
{ EnvironmentInteractKey.LaxleyGrandfatherClockMissingBothHands, "It's missing both hands. "},
|
||||
{ EnvironmentInteractKey.LaxleyGrandfatherClockMissingHourHand, "The hour hand is missing."},
|
||||
{ EnvironmentInteractKey.LaxleyGrandfatherClockMissingMinuteHand, "The minute hand is missing."},
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<UIInteractKey, string> UIInteractions =
|
||||
new ReadOnlyDictionary<UIInteractKey, string>(
|
||||
new Dictionary<UIInteractKey, string>
|
||||
{
|
||||
{ UIInteractKey.EmptySlot, "Empty slot." },
|
||||
{ UIInteractKey.EmptySlot, "Empty." },
|
||||
});
|
||||
|
||||
public static string Get(ItemInteractKey key)
|
||||
|
||||
@@ -37,7 +37,10 @@ namespace BriarQueen.Data.Identifiers
|
||||
TornPage4 = 29,
|
||||
TornPage5 = 30,
|
||||
IncompleteBook = 31,
|
||||
CompleteBook = 32
|
||||
CompleteBook = 32,
|
||||
Stamp = 33,
|
||||
LaxleyClockHourHand = 34,
|
||||
LaxleyClockMinuteHand = 35,
|
||||
}
|
||||
|
||||
public enum EnvironmentKey
|
||||
@@ -56,6 +59,7 @@ namespace BriarQueen.Data.Identifiers
|
||||
WorkshopBrokenLantern = 11,
|
||||
WorkshopWriting = 12,
|
||||
StreetVines = 13,
|
||||
GrandfatherClockPlaque = 14,
|
||||
}
|
||||
|
||||
public enum PuzzleSlotKey
|
||||
@@ -64,7 +68,9 @@ namespace BriarQueen.Data.Identifiers
|
||||
WorkshopCandleSlot = 1,
|
||||
WorkshopPuzzleBoxSlot = 2,
|
||||
FountainGemSlot = 3,
|
||||
|
||||
FireplaceLockboxSlot = 4,
|
||||
GrandfatherClockFace = 5,
|
||||
GrandfatherClockHand = 6,
|
||||
}
|
||||
|
||||
public static class ItemIDs
|
||||
@@ -74,7 +80,11 @@ namespace BriarQueen.Data.Identifiers
|
||||
new Dictionary<PuzzleSlotKey, string>
|
||||
{
|
||||
{ PuzzleSlotKey.WorkshopCandleSlot, "PUZ_WorkshopCandleSlot" },
|
||||
{ PuzzleSlotKey.WorkshopPuzzleBoxSlot, "PUZ_WorkshopPuzzleBoxSlot" }
|
||||
{ PuzzleSlotKey.WorkshopPuzzleBoxSlot, "PUZ_WorkshopPuzzleBoxSlot" },
|
||||
{ PuzzleSlotKey.FountainGemSlot, "PUZ_FountainGemSlot" },
|
||||
{ PuzzleSlotKey.FireplaceLockboxSlot, "PUZ_FireplaceLockboxSlot" },
|
||||
{ PuzzleSlotKey.GrandfatherClockFace, "PUZ_GrandfatherClockFace" },
|
||||
{ PuzzleSlotKey.GrandfatherClockHand, "PUZ_GrandfatherClockHand" },
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<EnvironmentKey, string> Environment =
|
||||
@@ -94,37 +104,48 @@ namespace BriarQueen.Data.Identifiers
|
||||
{ EnvironmentKey.WorkshopBrokenLantern, "ENV_WorkshopBrokenLantern" },
|
||||
{ EnvironmentKey.WorkshopWriting, "ENV_WorkshopWriting" },
|
||||
{ EnvironmentKey.StreetVines, "ENV_StreetVines" },
|
||||
{ EnvironmentKey.GrandfatherClockPlaque, "ENV_GrandfatherClockPlaque" },
|
||||
});
|
||||
|
||||
public static readonly IReadOnlyDictionary<ItemKey, string> Pickups =
|
||||
new ReadOnlyDictionary<ItemKey, string>(
|
||||
new Dictionary<ItemKey, string>
|
||||
{
|
||||
{ ItemKey.RustedKnife, "00_RustedKnife" },
|
||||
{ ItemKey.SharpenedKnife, "01_SharpenedKnife" },
|
||||
{ ItemKey.EmeraldAmulet, "02_EmeraldAmulet" },
|
||||
{ ItemKey.DustyMirror, "03_DustyMirror" },
|
||||
{ ItemKey.SmallRag, "04_SmallRag" },
|
||||
{ ItemKey.GreenCandle, "05_GreenCandle" },
|
||||
{ ItemKey.IndigoCandle, "06_IndigoCandle" },
|
||||
{ ItemKey.DirtyMagnifyingGlass, "07_DirtyMagnifyingGlass" },
|
||||
{ ItemKey.PumphouseKey, "08_PumphouseKey" },
|
||||
{ ItemKey.RedCandle, "09_RedCandle" },
|
||||
{ ItemKey.OrangeCandle, "10_OrangeCandle" },
|
||||
{ ItemKey.YellowCandle, "11_YellowCandle" },
|
||||
{ ItemKey.BlueCandle, "12_BlueCandle" },
|
||||
{ ItemKey.VioletCandle, "13_VioletCandle" },
|
||||
{ ItemKey.Pliers, "14_Pliers" },
|
||||
{ ItemKey.Emerald, "15_Emerald" },
|
||||
{ ItemKey.Sapphire, "16_Sapphire" },
|
||||
{ ItemKey.Ruby, "17_Ruby" },
|
||||
{ ItemKey.RubyRing, "18_RubyRing" },
|
||||
{ ItemKey.SilverCoin, "19_SilverCoin" },
|
||||
{ ItemKey.GoldCoin, "20_GoldCoin" },
|
||||
{ ItemKey.GrindstoneAxlePin, "21_GrindstoneAxlePin" },
|
||||
{ ItemKey.Diamond, "22_Diamond" },
|
||||
{ ItemKey.DiamondTiara, "23_DiamondTiara" },
|
||||
{ ItemKey.DustySapphire, "24_DustySapphire" },
|
||||
{ ItemKey.RustedKnife, "01_RustedKnife" },
|
||||
{ ItemKey.SharpenedKnife, "02_SharpenedKnife" },
|
||||
{ ItemKey.EmeraldAmulet, "03_EmeraldAmulet" },
|
||||
{ ItemKey.DustyMirror, "04_DustyMirror" },
|
||||
{ ItemKey.SmallRag, "05_SmallRag" },
|
||||
{ ItemKey.GreenCandle, "06_GreenCandle" },
|
||||
{ ItemKey.IndigoCandle, "07_IndigoCandle" },
|
||||
{ ItemKey.DirtyMagnifyingGlass, "08_DirtyMagnifyingGlass" },
|
||||
{ ItemKey.PumphouseKey, "09_PumphouseKey" },
|
||||
{ ItemKey.RedCandle, "10_RedCandle" },
|
||||
{ ItemKey.OrangeCandle, "11_OrangeCandle" },
|
||||
{ ItemKey.YellowCandle, "12_YellowCandle" },
|
||||
{ ItemKey.BlueCandle, "13_BlueCandle" },
|
||||
{ ItemKey.VioletCandle, "14_VioletCandle" },
|
||||
{ ItemKey.Pliers, "15_Pliers" },
|
||||
{ ItemKey.Emerald, "16_Emerald" },
|
||||
{ ItemKey.Sapphire, "17_Sapphire" },
|
||||
{ ItemKey.Ruby, "18_Ruby" },
|
||||
{ ItemKey.RubyRing, "19_RubyRing" },
|
||||
{ ItemKey.SilverCoin, "20_SilverCoin" },
|
||||
{ ItemKey.GoldCoin, "21_GoldCoin" },
|
||||
{ ItemKey.GrindstoneAxlePin, "22_GrindstoneAxlePin" },
|
||||
{ ItemKey.Diamond, "23_Diamond" },
|
||||
{ ItemKey.DiamondTiara, "24_DiamondTiara" },
|
||||
{ ItemKey.DustySapphire, "25_DustySapphire" },
|
||||
{ ItemKey.TornPage1, "26_TornPage1" },
|
||||
{ ItemKey.TornPage2, "27_TornPage2" },
|
||||
{ ItemKey.TornPage3, "28_TornPage3" },
|
||||
{ ItemKey.TornPage4, "29_TornPage4" },
|
||||
{ ItemKey.TornPage5, "30_TornPage5" },
|
||||
{ ItemKey.IncompleteBook, "31_IncompleteBook" },
|
||||
{ ItemKey.CompleteBook, "32_CompleteBook" },
|
||||
{ ItemKey.Stamp, "33_Stamp" },
|
||||
{ ItemKey.LaxleyClockHourHand, "34_LaxleyClockHourHand" },
|
||||
{ ItemKey.LaxleyClockMinuteHand, "35_LaxleyClockMinuteHand" },
|
||||
});
|
||||
|
||||
public static string Get(ItemKey key)
|
||||
|
||||
@@ -6,5 +6,6 @@ namespace BriarQueen.Data.Identifiers
|
||||
Village = 1,
|
||||
Workshop = 2,
|
||||
LaxleyHouse = 3,
|
||||
Pumphouse = 4,
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace BriarQueen.Data.Identifiers
|
||||
WorkshopPuzzleBox,
|
||||
FountainGemPuzzle,
|
||||
FireplaceLockboxPuzzle,
|
||||
LaxleyClock
|
||||
}
|
||||
|
||||
public static class PuzzleIdentifiers
|
||||
@@ -18,6 +19,7 @@ namespace BriarQueen.Data.Identifiers
|
||||
{ PuzzleKey.WorkshopPuzzleBox, "CH1:Puzzle:WorkshopBox" },
|
||||
{ PuzzleKey.FountainGemPuzzle , "CH1:Puzzle:FountainGems" },
|
||||
{ PuzzleKey.FireplaceLockboxPuzzle, "CH1:Puzzle:FireplaceLockboxPuzzle" },
|
||||
{ PuzzleKey.LaxleyClock, "CH1:Puzzle:LaxleyClock" },
|
||||
};
|
||||
|
||||
// Optional helper to get all puzzle IDs
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
using BriarQueen.Data.Attributes;
|
||||
|
||||
namespace BriarQueen.Data.Identifiers
|
||||
{
|
||||
public enum ToolID
|
||||
{
|
||||
[DisplayName("Empty Hands")]
|
||||
None = 0,
|
||||
[DisplayName("Sharpened Knife")]
|
||||
Knife = 1,
|
||||
WaterBucket,
|
||||
[DisplayName("Water Goblet")]
|
||||
EndlessGoblet,
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -25,15 +25,15 @@ namespace BriarQueen.Data.Identifiers
|
||||
{
|
||||
{
|
||||
TutorialPopupID.ReturnToPreviousLevel,
|
||||
"Click the bottom corners to go back the way you came."
|
||||
"Click the bottom corners to return to the previous area."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.UsingItemsTogether,
|
||||
"Select an item, then click another to use it on that object."
|
||||
"Select one item, then click another to use them together."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.HideHUD,
|
||||
"Press 'H' to hide the HUD and see the world more clearly."
|
||||
"Press 'H' to hide the HUD."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.ExitItems,
|
||||
@@ -41,31 +41,31 @@ namespace BriarQueen.Data.Identifiers
|
||||
},
|
||||
{
|
||||
TutorialPopupID.MultipleUseItems,
|
||||
"Some items can be used more than once, but will eventually wear out."
|
||||
"Some items can be used multiple times, but they may wear out."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.DarkRooms,
|
||||
"Dark rooms hide what matters. Look carefully—light reveals what they conceal."
|
||||
"Dark rooms can hide important details. Use light to reveal them."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.Codex,
|
||||
"New discoveries are added to your codex. Press 'C' to review what you've gathered."
|
||||
"The Codex stores information you've discovered. Press 'C' to open it."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.HiddenItems,
|
||||
"Some things are hidden on purpose. Search carefully to uncover them."
|
||||
"Some items are hidden. Search carefully."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.ResetPuzzles,
|
||||
"Some puzzles can be reset if you make a mistake."
|
||||
"Some puzzles can be reset."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.Tools,
|
||||
"You'll find tools as you explore. Each has its own purpose—try them on different objects. Press 'Y' to view your tools."
|
||||
"You'll find tools as you explore. Try them on different objects. Press 'Y' to view your tools."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.ItemsAway,
|
||||
"Right-click to put away any items."
|
||||
"Right-click to put away the current item."
|
||||
},
|
||||
{
|
||||
TutorialPopupID.ItemCycling,
|
||||
|
||||
@@ -2,5 +2,5 @@ using BriarQueen.Framework.Events.System;
|
||||
|
||||
namespace BriarQueen.Framework.Events.Progression
|
||||
{
|
||||
public record RequestHintEvent : IEvent;
|
||||
public abstract record RequestHintEvent : IEvent;
|
||||
}
|
||||
@@ -11,5 +11,5 @@ namespace BriarQueen.Framework.Events.Progression
|
||||
/// By default stages are monotonic (only increase).
|
||||
/// Set Force=true to allow decreasing (e.g., reset/override).
|
||||
/// </summary>
|
||||
public record UpdateHintProgressEvent(string LevelID, int Stage, bool Force = false) : IEvent;
|
||||
public abstract record UpdateHintProgressEvent(string LevelID, int Stage, bool Force = false) : IEvent;
|
||||
}
|
||||
@@ -1,7 +1,22 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using BriarQueen.Data.Attributes;
|
||||
|
||||
namespace BriarQueen.Framework.Extensions
|
||||
{
|
||||
public class EnumExtensions
|
||||
public static class EnumExtensions
|
||||
{
|
||||
|
||||
public static string GetDisplayName(this Enum value)
|
||||
{
|
||||
var type = value.GetType();
|
||||
var field = type.GetField(value.ToString());
|
||||
|
||||
if (field == null)
|
||||
return value.ToString();
|
||||
|
||||
var attribute = field.GetCustomAttribute<DisplayNameAttribute>();
|
||||
|
||||
return attribute != null ? attribute.Name : value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace BriarQueen.Framework.Extensions
|
||||
{
|
||||
public class StringExtensions
|
||||
public static class StringExtensions
|
||||
{
|
||||
|
||||
private static readonly string[] Prefixes =
|
||||
{
|
||||
"ENV_",
|
||||
"PUZ_",
|
||||
"SUB_",
|
||||
"UI_",
|
||||
"SFX_",
|
||||
"BGM_",
|
||||
"BOOK_",
|
||||
"CLUE_",
|
||||
"PHOTO_"
|
||||
};
|
||||
|
||||
private static readonly IReadOnlyDictionary<string, string> Overrides =
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
{ "Pumphouse", "Pump House" },
|
||||
{ "Lockbox", "Lockbox" },
|
||||
{ "Codex", "Codex" },
|
||||
{ "UIFX", "UI FX" },
|
||||
{ "SFX", "SFX" },
|
||||
{ "BGM", "BGM" }
|
||||
};
|
||||
|
||||
public static string Prettify(this string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return string.Empty;
|
||||
|
||||
value = StripPrefix(value);
|
||||
value = value.Replace("_", " ");
|
||||
value = AddSpacing(value);
|
||||
value = Regex.Replace(value, @"\s+", " ").Trim();
|
||||
|
||||
if (value.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
var words = value.Split(' ');
|
||||
var sb = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < words.Length; i++)
|
||||
{
|
||||
var word = words[i];
|
||||
|
||||
if (string.IsNullOrWhiteSpace(word))
|
||||
continue;
|
||||
|
||||
string formatted = FormatWord(word);
|
||||
|
||||
sb.Append(formatted);
|
||||
|
||||
if (i < words.Length - 1)
|
||||
sb.Append(' ');
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string StripPrefix(string value)
|
||||
{
|
||||
foreach (var prefix in Prefixes)
|
||||
{
|
||||
if (value.StartsWith(prefix))
|
||||
return value.Substring(prefix.Length);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static string AddSpacing(string value)
|
||||
{
|
||||
value = Regex.Replace(value, "([a-z0-9])([A-Z])", "$1 $2");
|
||||
value = Regex.Replace(value, "([A-Z]+)([A-Z][a-z])", "$1 $2");
|
||||
value = Regex.Replace(value, "([a-zA-Z])([0-9])", "$1 $2");
|
||||
value = Regex.Replace(value, "([0-9])([a-zA-Z])", "$1 $2");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private static string FormatWord(string word)
|
||||
{
|
||||
if (Overrides.TryGetValue(word, out var overrideValue))
|
||||
return overrideValue;
|
||||
|
||||
if (word.Length > 1 && word.ToUpperInvariant() == word)
|
||||
return word;
|
||||
|
||||
return char.ToUpperInvariant(word[0]) + word.Substring(1).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Managers.Player;
|
||||
using NaughtyAttributes;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
@@ -10,15 +12,21 @@ namespace BriarQueen.Framework.Managers
|
||||
public class DebugManager : MonoBehaviour
|
||||
{
|
||||
private SaveManager _saveManager;
|
||||
private PlayerManager _playerManager;
|
||||
|
||||
[Header("Current Loaded Save")]
|
||||
[SerializeField, ReadOnly]
|
||||
private SaveGame _currentSave;
|
||||
|
||||
[Header("Interactive Debugging")]
|
||||
[SerializeField]
|
||||
private ItemKey _itemToGive;
|
||||
|
||||
[Inject]
|
||||
public void Construct(SaveManager saveManager)
|
||||
public void Construct(SaveManager saveManager, PlayerManager playerManager)
|
||||
{
|
||||
_saveManager = saveManager;
|
||||
_playerManager = playerManager;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
@@ -30,5 +38,14 @@ namespace BriarQueen.Framework.Managers
|
||||
{
|
||||
_currentSave = save;
|
||||
}
|
||||
|
||||
[Button]
|
||||
private void GiveItem()
|
||||
{
|
||||
if (_itemToGive == ItemKey.None)
|
||||
return;
|
||||
|
||||
_playerManager.CollectItem(ItemIDs.Get(_itemToGive));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.Save;
|
||||
using BriarQueen.Framework.Extensions;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using MemoryPack;
|
||||
using UnityEngine;
|
||||
@@ -418,5 +419,17 @@ namespace BriarQueen.Framework.Managers.IO
|
||||
|
||||
return CurrentSave.PersistentVariables.Game.GetLevelFlag(levelFlag);
|
||||
}
|
||||
|
||||
public bool HasCollectedItem(string uniqueIdentifier)
|
||||
{
|
||||
if (uniqueIdentifier == null)
|
||||
return false;
|
||||
|
||||
var collected = CurrentSave?.CollectedItems;
|
||||
if (collected == null)
|
||||
return false;
|
||||
|
||||
return collected.Any(x => x.UniqueIdentifier == uniqueIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,5 +14,6 @@ namespace BriarQueen.Framework.Managers.Interaction.Data
|
||||
|
||||
UniTask EnterHover();
|
||||
UniTask ExitHover();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -375,6 +375,7 @@ namespace BriarQueen.Framework.Managers.Interaction
|
||||
return;
|
||||
|
||||
if (_currentHovered != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _currentHovered.ExitHover();
|
||||
@@ -382,20 +383,19 @@ namespace BriarQueen.Framework.Managers.Interaction
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
_currentHovered = next;
|
||||
|
||||
_eventCoordinator.Publish(
|
||||
new HoverInteractableChangedEvent(_currentHovered));
|
||||
_eventCoordinator.Publish(new HoverInteractableChangedEvent(_currentHovered));
|
||||
|
||||
var cursor =
|
||||
_currentHovered?.ApplicableCursorStyle
|
||||
?? UICursorService.CursorStyle.Default;
|
||||
var cursor = _currentHovered?.ApplicableCursorStyle
|
||||
?? UICursorService.CursorStyle.Default;
|
||||
|
||||
_eventCoordinator.Publish(
|
||||
new CursorStyleChangeEvent(cursor));
|
||||
_eventCoordinator.Publish(new CursorStyleChangeEvent(cursor));
|
||||
|
||||
if (_currentHovered != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _currentHovered.EnterHover();
|
||||
@@ -403,6 +403,7 @@ namespace BriarQueen.Framework.Managers.Interaction
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask ClearHover()
|
||||
@@ -437,6 +438,7 @@ namespace BriarQueen.Framework.Managers.Interaction
|
||||
return;
|
||||
|
||||
_currentHovered.OnInteract(_selectedItem).Forget();
|
||||
|
||||
}
|
||||
|
||||
private void OnRightClickReceived(OnRightClickEvent obj)
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace BriarQueen.Framework.Managers.Levels.Data
|
||||
|
||||
public virtual string InteractableName =>
|
||||
!string.IsNullOrWhiteSpace(_interactableTooltip) ? _interactableTooltip : _itemData.ItemName;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Called when the item is interacted with. Defaults to Pickup.
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Extensions;
|
||||
using BriarQueen.Framework.Managers.Interaction;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Managers.UI.Base;
|
||||
@@ -222,16 +223,15 @@ namespace BriarQueen.Framework.Managers.UI
|
||||
private string GetToolbeltTextForEntry(ToolID toolID, bool lost)
|
||||
{
|
||||
if (lost)
|
||||
return $"You lost the {toolID.ToString()}.";
|
||||
return $"You lost the {toolID.GetDisplayName()}.";
|
||||
else
|
||||
return $"You gained the {toolID.ToString()}.";
|
||||
return $"You gained the {toolID.GetDisplayName()}.";
|
||||
}
|
||||
|
||||
private string GetCodexTextForEntry(CodexType codexType)
|
||||
{
|
||||
return codexType switch
|
||||
{
|
||||
CodexType.BookEntry => "You've acquired a new book entry.",
|
||||
CodexType.BookEntry => "You've acquired a new document.",
|
||||
CodexType.PuzzleClue => "You've acquired a new puzzle clue.",
|
||||
CodexType.Photo => "You've acquired a new photo.",
|
||||
_ => string.Empty
|
||||
|
||||
@@ -46,10 +46,30 @@ namespace BriarQueen.Game.Items.Environment.ChapterOne.VillageStreet
|
||||
|
||||
private void PublishFailureMessage()
|
||||
{
|
||||
var message = SettingsService.Game.AutoUseTools
|
||||
? InteractEventIDs.Get(LevelInteractKey.CutVines)
|
||||
: InteractEventIDs.Get(ItemInteractKey.WrongTool);
|
||||
var autoUseTools = SettingsService != null &&
|
||||
SettingsService.Game != null &&
|
||||
SettingsService.Game.AutoUseTools;
|
||||
|
||||
var equippedTool = PlayerManager.GetEquippedTool();
|
||||
|
||||
string message;
|
||||
|
||||
if (equippedTool == ToolID.None)
|
||||
{
|
||||
message = InteractEventIDs.Get(LevelInteractKey.CutVines);
|
||||
}
|
||||
else if (autoUseTools)
|
||||
{
|
||||
// In auto-use mode, reaching this point means the player does not have access
|
||||
// to the required tool at all, so this should still read like a generic failure.
|
||||
message = InteractEventIDs.Get(LevelInteractKey.CutVines);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto-use is disabled, and the player has some tool equipped that is not valid.
|
||||
message = InteractEventIDs.Get(ItemInteractKey.WrongTool);
|
||||
}
|
||||
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -14,6 +15,10 @@ namespace BriarQueen.Game.Items.Environment.General
|
||||
[SerializeField]
|
||||
private LevelFlag _levelFlag;
|
||||
|
||||
public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Interact;
|
||||
|
||||
|
||||
|
||||
public override async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (item != null)
|
||||
@@ -22,7 +27,7 @@ namespace BriarQueen.Game.Items.Environment.General
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PlayerManager.CanUseTool(ToolID.WaterBucket))
|
||||
if (!PlayerManager.CanUseTool(ToolID.EndlessGoblet))
|
||||
{
|
||||
PublishFailureMessage();
|
||||
return;
|
||||
|
||||
@@ -52,10 +52,30 @@ namespace BriarQueen.Game.Items.Environment.General
|
||||
|
||||
private void PublishFailureMessage()
|
||||
{
|
||||
var message = SettingsService.Game.AutoUseTools
|
||||
? InteractEventIDs.Get(LevelInteractKey.CutVines)
|
||||
: InteractEventIDs.Get(ItemInteractKey.WrongTool);
|
||||
var autoUseTools = SettingsService != null &&
|
||||
SettingsService.Game != null &&
|
||||
SettingsService.Game.AutoUseTools;
|
||||
|
||||
var equippedTool = PlayerManager.GetEquippedTool();
|
||||
|
||||
string message;
|
||||
|
||||
if (equippedTool == ToolID.None)
|
||||
{
|
||||
message = InteractEventIDs.Get(LevelInteractKey.CutVines);
|
||||
}
|
||||
else if (autoUseTools)
|
||||
{
|
||||
// In auto-use mode, reaching this point means the player does not have access
|
||||
// to the required tool at all, so this should still read like a generic failure.
|
||||
message = InteractEventIDs.Get(LevelInteractKey.CutVines);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Auto-use is disabled, and the player has some tool equipped that is not valid.
|
||||
message = InteractEventIDs.Get(ItemInteractKey.WrongTool);
|
||||
}
|
||||
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(message));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ namespace BriarQueen.Game.Items.HoverZones
|
||||
|
||||
public CanvasGroup CanvasGroup;
|
||||
|
||||
public bool CanInteract()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
if(CanvasGroup == null)
|
||||
|
||||
@@ -1,7 +1,60 @@
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Events.Gameplay;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace BriarQueen.Game.Items.Pickups.ChapterOne.LaxleyHouse
|
||||
{
|
||||
public class MantleClock
|
||||
public class MantleClock : BaseItem
|
||||
{
|
||||
|
||||
public override UICursorService.CursorStyle ApplicableCursorStyle =>
|
||||
HasRetrievedHourHand
|
||||
? UICursorService.CursorStyle.Inspect
|
||||
: UICursorService.CursorStyle.Pickup;
|
||||
|
||||
public override string InteractableName => "Broken Mantle Clock";
|
||||
|
||||
private bool HasRetrievedHourHand =>
|
||||
SaveManager.GetLevelFlag(LevelFlag.LaxleyHourHandRetrieved);
|
||||
|
||||
public override async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (!CheckEmptyHands())
|
||||
return;
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
EventCoordinator.Publish(
|
||||
new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.CantUseItem)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasRetrievedHourHand)
|
||||
{
|
||||
EventCoordinator.Publish(
|
||||
new DisplayInteractEvent(InteractEventIDs.Get(EnvironmentInteractKey.LaxleyHouseBrokenClock)));
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerManager.CollectItem(ItemIDs.Get(ItemKey.LaxleyClockHourHand));
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.LooksImportant)));
|
||||
EventCoordinator.Publish(new SelectedItemChangedEvent(null));
|
||||
|
||||
await OnInteracted();
|
||||
}
|
||||
|
||||
protected override UniTask OnInteracted()
|
||||
{
|
||||
if (!HasRetrievedHourHand)
|
||||
SaveManager.SetLevelFlag(LevelFlag.LaxleyHourHandRetrieved, true);
|
||||
|
||||
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,171 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Events.Progression;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Hints.Data;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Services.Puzzles.Base;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using MemoryPack;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Clock
|
||||
{
|
||||
public class LaxleyClockBasePuzzle
|
||||
[Serializable]
|
||||
[MemoryPackable]
|
||||
public partial struct LaxleyClockPuzzleState
|
||||
{
|
||||
|
||||
public bool HourHandPlaced;
|
||||
public bool MinuteHandPlaced;
|
||||
|
||||
public int HourHandRotationStep;
|
||||
public int MinuteHandRotationStep;
|
||||
|
||||
public bool IsSolved;
|
||||
}
|
||||
|
||||
public class LaxleyClockBasePuzzle : BasePuzzle, IPuzzleStateful
|
||||
{
|
||||
private const int SolvedHourStep = 6;
|
||||
private const int SolvedMinuteStep = 1;
|
||||
|
||||
[Header("Clock Face")]
|
||||
[SerializeField]
|
||||
private LaxleyClockFace _clockFace;
|
||||
|
||||
[Header("Puzzle State")]
|
||||
[SerializeField]
|
||||
private Image _background;
|
||||
|
||||
[SerializeField]
|
||||
private Sprite _clockOpenSprite;
|
||||
|
||||
[SerializeField]
|
||||
private List<BaseItem> _clockItems;
|
||||
|
||||
public override string PuzzleID => PuzzleIdentifiers.AllPuzzles[PuzzleKey.LaxleyClock];
|
||||
public override string LevelName => "Grandfather Clock";
|
||||
public override Dictionary<int, BaseHint> Hints { get; }
|
||||
|
||||
public bool IsCompleted => SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved);
|
||||
|
||||
protected override async UniTask PostLoadInternal()
|
||||
{
|
||||
_clockFace.Initialise(this);
|
||||
|
||||
if (SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved))
|
||||
{
|
||||
_clockFace.LockHands();
|
||||
await OpenClock(false);
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask NotifyClockStateChanged()
|
||||
{
|
||||
if (IsCompleted)
|
||||
return;
|
||||
|
||||
if (!_clockFace.AreBothHandsPlaced())
|
||||
return;
|
||||
|
||||
if (_clockFace.HourHandRotationStep == SolvedHourStep &&
|
||||
_clockFace.MinuteHandRotationStep == SolvedMinuteStep)
|
||||
{
|
||||
await CompletePuzzle();
|
||||
}
|
||||
}
|
||||
|
||||
public override async UniTask CompletePuzzle()
|
||||
{
|
||||
if (IsCompleted)
|
||||
return;
|
||||
|
||||
SaveManager.SetLevelFlag(LevelFlag.LaxleyClockSolved, true);
|
||||
SaveManager.SetPuzzleCompleted(PuzzleKey.LaxleyClock, true);
|
||||
|
||||
EventCoordinator.Publish(new FadeEvent(false, 0.5f));
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(0.5f));
|
||||
_clockFace.HideMechanism();
|
||||
_clockFace.LockHands();
|
||||
await OpenClock(true);
|
||||
EventCoordinator.Publish(new UnlockAchievementEvent(AchievementID.LaxleyGrandfatherClockPuzzleSolved));
|
||||
EventCoordinator.Publish(new FadeEvent(true, 0.5f));
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(0.5f));
|
||||
}
|
||||
|
||||
public UniTask<byte[]> CaptureState()
|
||||
{
|
||||
var state = new LaxleyClockPuzzleState
|
||||
{
|
||||
HourHandPlaced = _clockFace.HourHandPlaced,
|
||||
MinuteHandPlaced = _clockFace.MinuteHandPlaced,
|
||||
HourHandRotationStep = _clockFace.HourHandRotationStep,
|
||||
MinuteHandRotationStep = _clockFace.MinuteHandRotationStep,
|
||||
IsSolved = IsCompleted
|
||||
};
|
||||
|
||||
byte[] data = MemoryPackSerializer.Serialize(state);
|
||||
return UniTask.FromResult(data);
|
||||
}
|
||||
|
||||
public async UniTask RestoreState(byte[] state)
|
||||
{
|
||||
_clockFace.Initialise(this);
|
||||
|
||||
if (state == null || state.Length == 0)
|
||||
{
|
||||
if (SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved))
|
||||
{
|
||||
_clockFace.LockHands();
|
||||
await OpenClock(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LaxleyClockPuzzleState restored = MemoryPackSerializer.Deserialize<LaxleyClockPuzzleState>(state);
|
||||
|
||||
_clockFace.RestoreState(
|
||||
restored.HourHandPlaced,
|
||||
restored.MinuteHandPlaced,
|
||||
restored.HourHandRotationStep,
|
||||
restored.MinuteHandRotationStep,
|
||||
restored.IsSolved);
|
||||
|
||||
if (restored.IsSolved || SaveManager.GetLevelFlag(LevelFlag.LaxleyClockSolved))
|
||||
{
|
||||
_clockFace.LockHands();
|
||||
await OpenClock(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask OpenClock(bool playAudio = false)
|
||||
{
|
||||
_background.sprite = _clockOpenSprite;
|
||||
|
||||
if (playAudio)
|
||||
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.ClockOpening));
|
||||
|
||||
await UnlockItems();
|
||||
}
|
||||
|
||||
private UniTask UnlockItems()
|
||||
{
|
||||
foreach (var item in _clockItems)
|
||||
{
|
||||
if (SaveManager.CurrentSave.CollectedItems.All(x => x.UniqueIdentifier != item.ItemData.UniqueID))
|
||||
{
|
||||
item.CanvasGroup.blocksRaycasts = true;
|
||||
item.CanvasGroup.interactable = true;
|
||||
item.CanvasGroup.alpha = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,192 @@
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Clock
|
||||
{
|
||||
public class LaxleyClockFace
|
||||
public class LaxleyClockFace : BaseItem
|
||||
{
|
||||
|
||||
[Header("Hands")]
|
||||
[SerializeField]
|
||||
private LaxleyClockHand _hourHand;
|
||||
|
||||
[SerializeField]
|
||||
private LaxleyClockHand _minuteHand;
|
||||
|
||||
[SerializeField]
|
||||
private Image _hub;
|
||||
|
||||
private LaxleyClockBasePuzzle _owningPuzzle;
|
||||
private bool _locked;
|
||||
|
||||
public bool HourHandPlaced => _hourHand != null && _hourHand.Placed;
|
||||
public bool MinuteHandPlaced => _minuteHand != null && _minuteHand.Placed;
|
||||
|
||||
public int HourHandRotationStep => _hourHand != null ? _hourHand.CurrentRotationStep : 0;
|
||||
public int MinuteHandRotationStep => _minuteHand != null ? _minuteHand.CurrentRotationStep : 0;
|
||||
|
||||
public override string InteractableName => "Clock Face";
|
||||
public override UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Interact;
|
||||
|
||||
public void Initialise(LaxleyClockBasePuzzle owningPuzzle)
|
||||
{
|
||||
_owningPuzzle = owningPuzzle;
|
||||
_locked = false;
|
||||
|
||||
gameObject.SetActive(true);
|
||||
|
||||
if (_hub != null)
|
||||
_hub.gameObject.SetActive(true);
|
||||
|
||||
_hourHand?.Initialise(this, _owningPuzzle);
|
||||
_minuteHand?.Initialise(this, _owningPuzzle);
|
||||
|
||||
RefreshInteractionState();
|
||||
}
|
||||
|
||||
public override async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (!IsInteractable())
|
||||
return;
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
string message = string.Empty;
|
||||
|
||||
if (!HourHandPlaced && !MinuteHandPlaced)
|
||||
{
|
||||
message = InteractEventIDs.Get(EnvironmentInteractKey.LaxleyGrandfatherClockMissingBothHands);
|
||||
}
|
||||
else if (!HourHandPlaced && MinuteHandPlaced)
|
||||
{
|
||||
message = InteractEventIDs.Get(EnvironmentInteractKey.LaxleyGrandfatherClockMissingHourHand);
|
||||
}
|
||||
else if (HourHandPlaced && !MinuteHandPlaced)
|
||||
{
|
||||
message = InteractEventIDs.Get(EnvironmentInteractKey.LaxleyGrandfatherClockMissingMinuteHand);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(message));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool isHourHandItem = item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockHourHand);
|
||||
bool isMinuteHandItem = item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockMinuteHand);
|
||||
|
||||
if (!isHourHandItem && !isMinuteHandItem)
|
||||
{
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.CantUseItem)));
|
||||
return;
|
||||
}
|
||||
|
||||
await PlaceHand(item);
|
||||
}
|
||||
|
||||
public bool AreBothHandsPlaced()
|
||||
{
|
||||
return HourHandPlaced && MinuteHandPlaced;
|
||||
}
|
||||
|
||||
public void LockHands()
|
||||
{
|
||||
_locked = true;
|
||||
_hourHand?.Lock();
|
||||
_minuteHand?.Lock();
|
||||
RefreshInteractionState();
|
||||
}
|
||||
|
||||
public void HideMechanism()
|
||||
{
|
||||
_locked = true;
|
||||
|
||||
_hourHand?.Hide();
|
||||
_minuteHand?.Hide();
|
||||
|
||||
if (_hub != null)
|
||||
_hub.gameObject.SetActive(false);
|
||||
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void RestoreState(
|
||||
bool hourPlaced,
|
||||
bool minutePlaced,
|
||||
int hourRotationStep,
|
||||
int minuteRotationStep,
|
||||
bool solved)
|
||||
{
|
||||
_locked = solved;
|
||||
gameObject.SetActive(!solved);
|
||||
|
||||
if (solved)
|
||||
{
|
||||
_hourHand?.RestoreState(hourPlaced, hourRotationStep, true);
|
||||
_minuteHand?.RestoreState(minutePlaced, minuteRotationStep, true);
|
||||
HideMechanism();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_hub != null)
|
||||
_hub.gameObject.SetActive(true);
|
||||
|
||||
_hourHand?.RestoreState(hourPlaced, hourRotationStep, false);
|
||||
_minuteHand?.RestoreState(minutePlaced, minuteRotationStep, false);
|
||||
|
||||
RefreshInteractionState();
|
||||
}
|
||||
|
||||
internal async UniTask NotifyHandChanged()
|
||||
{
|
||||
RefreshInteractionState();
|
||||
|
||||
if (_owningPuzzle != null)
|
||||
await _owningPuzzle.NotifyClockStateChanged();
|
||||
}
|
||||
|
||||
private async UniTask PlaceHand(ItemDataSo item)
|
||||
{
|
||||
if (item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockHourHand))
|
||||
{
|
||||
await _hourHand.Place();
|
||||
}
|
||||
else if (item.UniqueID == ItemIDs.Get(ItemKey.LaxleyClockMinuteHand))
|
||||
{
|
||||
await _minuteHand.Place();
|
||||
}
|
||||
|
||||
PlayerManager.RemoveItem(item);
|
||||
|
||||
RefreshInteractionState();
|
||||
|
||||
if (_owningPuzzle != null)
|
||||
await _owningPuzzle.NotifyClockStateChanged();
|
||||
}
|
||||
|
||||
private void RefreshInteractionState()
|
||||
{
|
||||
bool bothPlaced = AreBothHandsPlaced();
|
||||
bool canPlaceHands = !_locked && !bothPlaced;
|
||||
|
||||
if (CanvasGroup != null)
|
||||
{
|
||||
CanvasGroup.blocksRaycasts = canPlaceHands;
|
||||
CanvasGroup.interactable = canPlaceHands;
|
||||
}
|
||||
|
||||
_hourHand?.SetCanRotate(!_locked && bothPlaced);
|
||||
_minuteHand?.SetCanRotate(!_locked && bothPlaced);
|
||||
}
|
||||
|
||||
private bool IsInteractable()
|
||||
{
|
||||
return !_locked && !AreBothHandsPlaced();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,316 @@
|
||||
using System.Threading;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PrimeTween;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Clock
|
||||
{
|
||||
public class LaxleyClockHand
|
||||
public class LaxleyClockHand : BaseItem
|
||||
{
|
||||
|
||||
[Header("State")]
|
||||
[SerializeField]
|
||||
private bool _placed;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0, 11)]
|
||||
private int _currentRotationStep;
|
||||
|
||||
[SerializeField]
|
||||
private bool _locked;
|
||||
|
||||
[SerializeField]
|
||||
private bool _isRotating;
|
||||
|
||||
[SerializeField]
|
||||
private bool _canRotate;
|
||||
|
||||
[Header("Rotation")]
|
||||
[SerializeField]
|
||||
private float[] _rotationSteps = new float[12]
|
||||
{
|
||||
0f, // 12
|
||||
-30f, // 1
|
||||
-60f, // 2
|
||||
-90f, // 3
|
||||
-120f, // 4
|
||||
-150f, // 5
|
||||
-180f, // 6
|
||||
-210f, // 7
|
||||
-240f, // 8
|
||||
-270f, // 9
|
||||
-300f, // 10
|
||||
-330f // 11
|
||||
};
|
||||
|
||||
[SerializeField]
|
||||
private float _rotateDuration = 0.15f;
|
||||
|
||||
[SerializeField]
|
||||
private Ease _rotateEase = Ease.Linear;
|
||||
|
||||
[Header("Placement")]
|
||||
[SerializeField]
|
||||
private float _placeDuration = 0.2f;
|
||||
|
||||
[SerializeField]
|
||||
private Ease _placeEase = Ease.OutSine;
|
||||
|
||||
[Header("Components")]
|
||||
[SerializeField]
|
||||
private GameObject _parentPivot;
|
||||
|
||||
[SerializeField]
|
||||
private CanvasGroup _parentCanvasGroup;
|
||||
|
||||
[Header("Placement Behaviour")]
|
||||
[SerializeField]
|
||||
private bool _randomiseRotationOnFirstPlace = true;
|
||||
|
||||
private Sequence _placeSequence;
|
||||
private Sequence _rotateSequence;
|
||||
|
||||
private CancellationTokenSource _placeCTS;
|
||||
private CancellationTokenSource _rotateCTS;
|
||||
|
||||
private LaxleyClockFace _clockFace;
|
||||
|
||||
public bool Placed => _placed;
|
||||
public int CurrentRotationStep => _currentRotationStep;
|
||||
|
||||
public void Initialise(LaxleyClockFace clockFace, LaxleyClockBasePuzzle owningPuzzle)
|
||||
{
|
||||
_clockFace = clockFace;
|
||||
_canRotate = false;
|
||||
|
||||
if (_placed)
|
||||
{
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(true);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 1f;
|
||||
|
||||
ApplyRotationImmediate(_currentRotationStep);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(false);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public override async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (!IsInteractable())
|
||||
return;
|
||||
|
||||
await RotateToNextStep();
|
||||
await _clockFace.NotifyHandChanged();
|
||||
}
|
||||
|
||||
public async UniTask Place()
|
||||
{
|
||||
if (_placed)
|
||||
return;
|
||||
|
||||
_placed = true;
|
||||
_locked = false;
|
||||
_canRotate = false;
|
||||
|
||||
CancelPlaceTween();
|
||||
|
||||
_placeCTS = new CancellationTokenSource();
|
||||
|
||||
if (_randomiseRotationOnFirstPlace)
|
||||
_currentRotationStep = Random.Range(0, _rotationSteps.Length);
|
||||
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(true);
|
||||
|
||||
ApplyRotationImmediate(_currentRotationStep);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
{
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
_parentCanvasGroup.blocksRaycasts = false;
|
||||
_parentCanvasGroup.interactable = false;
|
||||
}
|
||||
|
||||
_placeSequence.Stop();
|
||||
_placeSequence = Sequence.Create()
|
||||
.Group(Tween.Alpha(_parentCanvasGroup, 1f, _placeDuration, _placeEase));
|
||||
|
||||
try
|
||||
{
|
||||
await _placeSequence.ToUniTask(cancellationToken: _placeCTS.Token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void RestoreState(bool placed, int rotationStep, bool locked)
|
||||
{
|
||||
CancelPlaceTween();
|
||||
CancelRotateTween();
|
||||
|
||||
_placed = placed;
|
||||
_locked = locked;
|
||||
_isRotating = false;
|
||||
_canRotate = false;
|
||||
_currentRotationStep = Mathf.Clamp(rotationStep, 0, 11);
|
||||
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(_placed);
|
||||
|
||||
if (_placed)
|
||||
{
|
||||
ApplyRotationImmediate(_currentRotationStep);
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_parentCanvasGroup != null)
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void SetCanRotate(bool canRotate)
|
||||
{
|
||||
_canRotate = canRotate;
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void Lock()
|
||||
{
|
||||
_locked = true;
|
||||
_canRotate = false;
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
CancelPlaceTween();
|
||||
CancelRotateTween();
|
||||
|
||||
_canRotate = false;
|
||||
_isRotating = false;
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
{
|
||||
_parentCanvasGroup.blocksRaycasts = false;
|
||||
_parentCanvasGroup.interactable = false;
|
||||
_parentCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
if (_parentPivot != null)
|
||||
_parentPivot.SetActive(false);
|
||||
}
|
||||
|
||||
private async UniTask RotateToNextStep()
|
||||
{
|
||||
if (!IsInteractable())
|
||||
return;
|
||||
|
||||
_isRotating = true;
|
||||
RefreshVisualState();
|
||||
|
||||
CancelRotateTween();
|
||||
_rotateCTS = new CancellationTokenSource();
|
||||
|
||||
_currentRotationStep = (_currentRotationStep + 1) % 12;
|
||||
|
||||
Vector3 targetEuler = _parentPivot.transform.localEulerAngles;
|
||||
targetEuler.z = _rotationSteps[_currentRotationStep];
|
||||
|
||||
_rotateSequence.Stop();
|
||||
_rotateSequence = Sequence.Create()
|
||||
.Group(
|
||||
Tween.LocalRotation(
|
||||
_parentPivot.transform,
|
||||
Quaternion.Euler(targetEuler),
|
||||
_rotateDuration,
|
||||
_rotateEase));
|
||||
|
||||
try
|
||||
{
|
||||
await _rotateSequence.ToUniTask(cancellationToken: _rotateCTS.Token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
_isRotating = false;
|
||||
RefreshVisualState();
|
||||
}
|
||||
|
||||
private void ApplyRotationImmediate(int step)
|
||||
{
|
||||
if (_parentPivot == null)
|
||||
return;
|
||||
|
||||
Vector3 euler = _parentPivot.transform.localEulerAngles;
|
||||
euler.z = _rotationSteps[Mathf.Clamp(step, 0, 11)];
|
||||
_parentPivot.transform.localEulerAngles = euler;
|
||||
}
|
||||
|
||||
private void RefreshVisualState()
|
||||
{
|
||||
bool interactable = IsInteractable();
|
||||
|
||||
if (_parentCanvasGroup != null)
|
||||
{
|
||||
_parentCanvasGroup.blocksRaycasts = interactable;
|
||||
_parentCanvasGroup.interactable = interactable;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInteractable()
|
||||
{
|
||||
return _placed && !_locked && !_isRotating && _canRotate;
|
||||
}
|
||||
|
||||
private void CancelPlaceTween()
|
||||
{
|
||||
_placeSequence.Stop();
|
||||
|
||||
if (_placeCTS != null)
|
||||
{
|
||||
_placeCTS.Cancel();
|
||||
_placeCTS.Dispose();
|
||||
_placeCTS = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelRotateTween()
|
||||
{
|
||||
_rotateSequence.Stop();
|
||||
|
||||
if (_rotateCTS != null)
|
||||
{
|
||||
_rotateCTS.Cancel();
|
||||
_rotateCTS.Dispose();
|
||||
_rotateCTS = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
CancelPlaceTween();
|
||||
CancelRotateTween();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,18 @@ using System.Linq;
|
||||
using AYellowpaper.SerializedCollections;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Events.Progression;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Hints.Data;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Services.Puzzles.Base;
|
||||
using BriarQueen.Game.Levels.ChapterOne.LaxleyHouse.FireplaceLockbox;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using MemoryPack;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Fireplace.LockboxPuzzle
|
||||
{
|
||||
[Serializable]
|
||||
[MemoryPackable]
|
||||
@@ -94,6 +94,7 @@ namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
AudioManager.Play(AudioNameIdentifiers.Get(SFXKey.LockboxOpening));
|
||||
|
||||
await OpenLockbox();
|
||||
EventCoordinator.Publish(new UnlockAchievementEvent(AchievementID.FireplaceLockboxPuzzleBoxSolved));
|
||||
|
||||
EventCoordinator.Publish(new FadeEvent(true, 0.5f));
|
||||
}
|
||||
@@ -103,10 +104,10 @@ namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
if (_backgroundImage != null)
|
||||
_backgroundImage.sprite = _lockBoxOpenSprite;
|
||||
|
||||
await GenerateLockboxItems();
|
||||
await UnlockLockboxItems();
|
||||
}
|
||||
|
||||
private async UniTask GenerateLockboxItems()
|
||||
private async UniTask UnlockLockboxItems()
|
||||
{
|
||||
foreach (var item in _lockboxItems)
|
||||
{
|
||||
@@ -119,10 +120,6 @@ namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse
|
||||
item.CanvasGroup.blocksRaycasts = true;
|
||||
item.CanvasGroup.interactable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
await DestructionService.Destroy(item.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using PrimeTween;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.Game.Levels.ChapterOne.LaxleyHouse.FireplaceLockbox
|
||||
namespace BriarQueen.Game.Puzzles.ChapterOne.LaxleyHouse.Fireplace.LockboxPuzzle
|
||||
{
|
||||
public class LockboxSlot : BaseItem
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Extensions;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -82,10 +83,12 @@ namespace BriarQueen.UI.Codex
|
||||
Location = location;
|
||||
|
||||
if (_label != null)
|
||||
_label.text = string.IsNullOrWhiteSpace(displayText) ? location.ToString() : displayText;
|
||||
_label.text = string.IsNullOrWhiteSpace(displayText) ? location.ToString().Prettify() : displayText.Prettify();
|
||||
|
||||
RefreshVisuals();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void HandleClicked()
|
||||
{
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace BriarQueen.UI.HUD
|
||||
public UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.UseItem;
|
||||
public string InteractableName => Item.ItemName;
|
||||
|
||||
public bool CanInteract() => true;
|
||||
|
||||
public UniTask EnterHover()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
|
||||
Reference in New Issue
Block a user