diff --git a/Dungeon_The Ritual/Src/AttachPuzzle.cs b/Dungeon_The Ritual/Src/AttachPuzzle.cs index 91cab53..c2528d3 100644 --- a/Dungeon_The Ritual/Src/AttachPuzzle.cs +++ b/Dungeon_The Ritual/Src/AttachPuzzle.cs @@ -1,17 +1,17 @@ -using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using HarmonyLib; using Jotunn; -using Mono.Security; using UnityEngine; -using UnityEngine.PlayerLoop; -using Random = UnityEngine.Random; namespace Underground_Ruins; public class AttachPuzzle : MonoBehaviour { + private const string PuzzleInitializedKey = "BFD_puzzleInitialized"; + private const string PuzzleSolvedKey = "BFD_puzzleSolved"; + public List puzzleItemStandList = new List(); public List puzzleSolutionPickableList = new List(); public List puzzleSolution = new List(); @@ -24,76 +24,89 @@ public class AttachPuzzle : MonoBehaviour public void Awake() { - zNetView = this.gameObject.GetComponent(); - zNetView.m_zdo.GetBool("BFD_puzzleInitialized", out bool value); + zNetView = gameObject.GetComponent(); + if (zNetView == null || zNetView.m_zdo == null) + { + return; + } + + zNetView.m_zdo.GetBool(PuzzleInitializedKey, out bool value); initialized = value; } public void Initialize() { - if (initialized) - { - Debug.Log("Dungeon puzzle in position " + this.gameObject.transform.position + " has already been initialized."); - return; - } - GetItemStands(); GetPickables(); - - GameObject targetDoorPrefab = FindGameObjectInSector("PuzzleSecretDoor",this.gameObject.transform.position); + + GameObject targetDoorPrefab = FindGameObjectInSector("PuzzleSecretDoor", gameObject.transform.position); if (targetDoorPrefab != null) { targetDoor = targetDoorPrefab.GetComponent(); } - - GameObject puzzleSwitchPrefab = FindGameObjectInSector("PuzzleLever",this.gameObject.transform.position); + + GameObject puzzleSwitchPrefab = FindGameObjectInSector("PuzzleLever", gameObject.transform.position); if (puzzleSwitchPrefab != null) { puzzleSwitch = puzzleSwitchPrefab.GetComponentInChildren(); - } - + } + if (puzzleSwitch != null) { puzzleSwitch.m_onUse = OnSwitchUse; + puzzleSwitch.m_onHover = null; + puzzleSwitch.m_hoverText = "[$KEY_Use] Submit Offering"; + if (string.IsNullOrEmpty(puzzleSwitch.m_name)) + { + puzzleSwitch.m_name = "Hidden Door Mechanism"; + } } - - GenerateSolution(); - - zNetView.m_zdo.Set("BFD_puzzleInitialized", true); + + if (IsPuzzleSolved(targetDoor)) + { + targetDoor.Open(Vector3.forward); + } + else + { + GenerateSolution(); + ResetDoorState(); + } + + if (!initialized && zNetView != null && zNetView.m_zdo != null) + { + zNetView.m_zdo.Set(PuzzleInitializedKey, true); + } + + initialized = true; } - + public IEnumerator DelayedPuzzleInit(Vector3 pos) { while (!ZNetScene.instance.IsAreaReady(pos)) { yield return null; } - + Initialize(); } - public GameObject FindGameObjectInSector(string prefabName, Vector3 position) { int prefabHash = prefabName.GetStableHashCode(); - + Vector2i sector = ZoneSystem.GetZone(position); - int sectorIndex = ZDOMan.instance.SectorToIndex(sector); - + if (sectorIndex >= 0 && sectorIndex < ZDOMan.instance.m_objectsBySector.Length) { List sectorList = ZDOMan.instance.m_objectsBySector[sectorIndex]; - if (sectorList != null) { foreach (ZDO zdo in sectorList) { int zdoPrefabHash = zdo.GetPrefab(); - if (zdoPrefabHash == prefabHash) { - GameObject instance = ZNetScene.instance.FindInstance(zdo)?.gameObject; if (instance != null) { @@ -103,158 +116,205 @@ public GameObject FindGameObjectInSector(string prefabName, Vector3 position) } } } + return null; } - + public void GetItemStands() { + puzzleItemStandList.Clear(); + for (int i = 0; i < countPuzzleStands; i++) { - string prefabName = string.Concat(i.ToString(),"_PuzzleStand"); - - GameObject puzzleStandPrefab = FindGameObjectInSector(prefabName, this.gameObject.transform.position); + string prefabName = string.Concat(i.ToString(), "_PuzzleStand"); + GameObject puzzleStandPrefab = FindGameObjectInSector(prefabName, gameObject.transform.position); if (puzzleStandPrefab == null) { - // Debug.Log("Can not find puzzle stand with name " + prefabName + " in scene"); continue; } - - PuzzleStand puzzleStand = new PuzzleStand() + + PuzzleStand puzzleStand = new PuzzleStand { PuzzleStandGameObject = puzzleStandPrefab, puzzleStand = true, puzzlePickable = false, puzzlePosition = i }; - + puzzleItemStandList.Add(puzzleStand); } } - + public void GetPickables() { + puzzleSolutionPickableList.Clear(); + for (int i = 0; i < countPuzzleStands; i++) { - string prefabName = string.Concat(i.ToString(),"_PuzzlePickable"); - GameObject puzzleStandPrefab = FindGameObjectInSector(prefabName, this.gameObject.transform.position); + string prefabName = string.Concat(i.ToString(), "_PuzzlePickable"); + GameObject puzzleStandPrefab = FindGameObjectInSector(prefabName, gameObject.transform.position); if (puzzleStandPrefab == null) { - // Debug.Log("Can not find puzzle pickable with name " + prefabName + " in scene"); continue; } - - PuzzleStand puzzleStand = new PuzzleStand() + + PuzzleStand puzzleStand = new PuzzleStand { PuzzleStandGameObject = puzzleStandPrefab, puzzleStand = false, puzzlePickable = true, puzzlePosition = i }; - + puzzleSolutionPickableList.Add(puzzleStand); } } - + public bool OnSwitchUse(Switch caller, Humanoid user, ItemDrop.ItemData item) { - if (CheckSolution()) + if (!CheckSolution()) { - targetDoor.Open(Vector3.forward); - Debug.Log("Puzzle solved! Door is opening."); - return true; + Debug.Log("Puzzle solution is incorrect."); + return false; } - Debug.Log("Puzzle solution is incorrect."); - return false; - + + SetPuzzleSolved(targetDoor, true); + targetDoor.Open(Vector3.forward); + Debug.Log("Puzzle solved! Door is opening."); + return true; } public void GenerateSolution() { - Debug.Log("Generating solution"); - if (puzzleSolutionPickableList.Count > 0 && puzzleSolutionPickableList != null) + puzzleSolution = Enumerable.Repeat(1, countPuzzleStands).ToList(); + + if (puzzleSolutionPickableList == null || puzzleSolutionPickableList.Count == 0) { - puzzleSolution.Clear(); - - for (int i = 0; i < countPuzzleStands; i++) + return; + } + + foreach (PuzzleStand puzzlePickable in puzzleSolutionPickableList) + { + if (puzzlePickable == null || puzzlePickable.PuzzleStandGameObject == null) { - puzzleSolution.Add(0); + continue; } - - for (int i = 0; i < countPuzzleStands; i++) + + Pickable pickable = puzzlePickable.PuzzleStandGameObject.GetComponent(); + if (pickable != null) { - int answer = Random.Range(0, 2); - int.TryParse(puzzleSolutionPickableList[i].PuzzleStandGameObject.name[0].ToString(), out int position); - if (position >= 0 && position < puzzleSolution.Count) - { - puzzleSolution[position] = answer; - if (answer == 0) - { - puzzleSolutionPickableList[i].PuzzleStandGameObject.GetComponent().SetPicked(true); - } - } + pickable.SetPicked(false); } } } public bool CheckSolution() - { + { List tempPuzzleSolution = Enumerable.Repeat(0, countPuzzleStands).ToList(); - - if (puzzleItemStandList == null || targetDoor == null) + + if (puzzleItemStandList == null || targetDoor == null || puzzleSolution == null || puzzleSolution.Count != countPuzzleStands) { return false; } - - + foreach (PuzzleStand puzzleStand in puzzleItemStandList) { - if (puzzleStand == null) + if (puzzleStand == null || puzzleStand.PuzzleStandGameObject == null) { continue; } ItemStand itemStand = puzzleStand.PuzzleStandGameObject.GetComponent(); - - if (itemStand == null) - { - continue; - } - - if (itemStand.m_nview == null) - { - continue; - } - - if (itemStand.m_nview.GetZDO() == null) + if (itemStand == null || itemStand.m_nview == null || itemStand.m_nview.GetZDO() == null) { continue; } string attachItemName = itemStand.m_visualName; - Debug.Log("Checking solution. Item attached has name " + attachItemName); - - if (int.TryParse(puzzleStand.PuzzleStandGameObject.name[0].ToString(), out int position)) + int position = puzzleStand.puzzlePosition; + if (position >= 0 && position < tempPuzzleSolution.Count) { - if (position >= 0 && position < tempPuzzleSolution.Count) - { - tempPuzzleSolution[position] = attachItemName == solutionItemName ? 1 : 0; - } - else - { - Debug.LogWarning("Position " + position + " is out of bounds for temp puzzle solution."); - } + tempPuzzleSolution[position] = attachItemName == solutionItemName ? 1 : 0; } - else + } + + return tempPuzzleSolution.SequenceEqual(puzzleSolution); + } + + public void ResetDoorState() + { + if (targetDoor == null) + { + return; + } + + SetPuzzleSolved(targetDoor, false); + + ZNetView doorZNetView = targetDoor.GetComponent(); + if (doorZNetView == null || doorZNetView.GetZDO() == null) + { + return; + } + + doorZNetView.GetZDO().Set(ZDOVars.s_state, 0); + } + + public static bool IsPuzzleDoor(Door door) + { + if (door == null || door.gameObject == null) + { + return false; + } + + return door.gameObject.name.Contains("PuzzleSecretDoor"); + } + + public static bool IsPuzzleSolved(Door door) + { + if (door == null) + { + return false; + } + + ZNetView doorZNetView = door.GetComponent(); + if (doorZNetView == null || doorZNetView.GetZDO() == null) + { + return false; + } + + return doorZNetView.GetZDO().GetBool(PuzzleSolvedKey, false); + } + + public static void SetPuzzleSolved(Door door, bool solved) + { + if (door == null) + { + return; + } + + ZNetView doorZNetView = door.GetComponent(); + if (doorZNetView == null || doorZNetView.GetZDO() == null) + { + return; + } + + doorZNetView.GetZDO().Set(PuzzleSolvedKey, solved); + } + + [HarmonyPatch(typeof(Door), nameof(Door.Interact))] + public static class PuzzleDoorInteractPatch + { + public static bool Prefix(Door __instance) + { + if (!IsPuzzleDoor(__instance)) { - Debug.LogError("Failed to parse position from GameObject name: " + itemStand.gameObject.name); + return true; } + + return IsPuzzleSolved(__instance); } - - bool isCorrectSolution = tempPuzzleSolution.SequenceEqual(puzzleSolution); - Debug.Log("Checking solution. Provided answer is: " + string.Join(",", tempPuzzleSolution)); - return isCorrectSolution; } public class PuzzleStand @@ -265,4 +325,3 @@ public class PuzzleStand public int puzzlePosition = new int(); } } -