using UnityEngine;
using System;
using System.Collections;
using UnityEngine.Events;
public class ChildrenLoopManager : MonoBehaviour
{
[Header("Children Loops Setup")]
[Tooltip("Check if we're loading a saved game in the Children Loops section")]
[SerializeField] private Transform playerNewGameStartPosition;
public bool isLoadingChildrenLoops;
[Header("Puzzle Objects")]
[Tooltip("Reference to the puzzle GameObject if applicable")]
[SerializeField] private GameObject puzzleGameObject;
[Tooltip("Optional puzzle solved effects, if needed")]
[SerializeField] private GameObject puzzleSolvedEffects;
public ChildrenLoopsEventsData childrenLoopsEventsData;
public ChildrenLoopsPuzzlesData childrenLoopsPuzzlesData;
// 1. Define the loop states (8 loops + 1 puzzle)
public enum ChildrenLoopState
{
CheckLoad,
LongHallway,
Loop1,
Loop2,
Loop3,
Loop4,
Loop5,
Loop6,
Loop7,
Loop8,
Puzzle
}
// Current loop state
public ChildrenLoopState currentChildrenLoopState = ChildrenLoopState.Loop1;
private void Awake()
{
// Assign this manager to GameManager so it can be activated/deactivated appropriately
if (GameManager.GetInstance() != null)
{
GameManager.GetInstance().childrenLoopManager = this;
}
// If we are loading a saved game, mark accordingly
if (LoadManager.GetInstance() != null && LoadManager.GetInstance().LoadingGame)
{
isLoadingChildrenLoops = true;
}
}
public void Activate()
{
Logger.Log("Children Loops Manager Activated: Initializing Children Loops.");
//TryLoadSavedState();
UpdateStoryline();
}
public void Deactivate()
{
Logger.Log("Children Loops Manager Deactivated.");
StopAllCoroutines();
SaveStorylineState();
CleanupPlayerSettings();
// If you want to automatically progress upon deactivation, uncomment below:
// NotifyCompletion();
}
public void UpdateStoryline()
{
switch (currentChildrenLoopState)
{
case ChildrenLoopState.CheckLoad:
HandleCheckLoadState();
break;
case ChildrenLoopState.LongHallway:
Logger.Log("Children Loop Long Hallway activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLongHallwayLeadingToLoops.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop1:
Logger.Log("Children Loop 1 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop1Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop2:
Logger.Log("Children Loop 2 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop2Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop3:
Logger.Log("Children Loop 3 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
#region Light Switches Puzzle Related:
foreach (var lightSwitch in childrenLoopsPuzzlesData.ManageLightSwitchesInLoop3.lightSwitch)
{
lightSwitch.onLightSwitchTurnedOn += childrenLoopsPuzzlesData.lightsSwitchesPuzzleInLoop3.CheckPuzzleCombination;
lightSwitch.onLightSwitchTurnedOff += childrenLoopsPuzzlesData.lightsSwitchesPuzzleInLoop3.CheckPuzzleCombination;
}
//YOU NEED TO LATER UNSUBSCRIBE THE LIGHT SWITCHES!
#endregion
childrenLoopsEventsData.StartOfLoop3Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop4:
Logger.Log("Children Loop 4 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop4Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop5:
Logger.Log("Children Loop 5 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop5Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop6:
Logger.Log("Children Loop 6 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop6Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop7:
Logger.Log("Children Loop 7 activated.");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop7Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Loop8:
Logger.Log("Children Loop 8 activated (final loop before puzzle).");
if (isLoadingChildrenLoops)
{
isLoadingChildrenLoops = false;
}
childrenLoopsEventsData.StartOfLoop8Event.Invoke();
SaveStorylineState();
break;
case ChildrenLoopState.Puzzle:
Logger.Log("Children Loop Puzzle activated.");
HandlePuzzle();
SaveStorylineState();
break;
default:
Logger.LogWarning("Unhandled Children Loop State: " + currentChildrenLoopState);
break;
}
}
private void HandleCheckLoadState()
{
if (IsInitialCutscenePlayed())
{
Logger.Print("Try Load Saved State");
TryLoadSavedState();
}
else //If started new game for the first time:
{
Logger.Print("New game started");
PlayInitialCutscene();
SetupPlayer(playerNewGameStartPosition, enableCameraCarMovement: false, enablePlayerController: true,
pocketWatchIsObtained: true);
UpdateToNextLoopState();
}
}
private bool IsInitialCutscenePlayed() => GameProgressManager.GetInstance().initialCutscenePlayed;
private void PlayInitialCutscene()
{
Logger.Log("Playing initial cutscene...");
SetInitialCutscenePlayed(true);
var gameProgressManager = GameProgressManager.GetInstance();
gameProgressManager.playerControllerShouldBeEnabledOnGameLoad = false;
gameProgressManager.playerCameraControllerShouldBeEnabledOnGameLoad = true;
}
private void SetInitialCutscenePlayed(bool value) => GameProgressManager.GetInstance().initialCutscenePlayed = value;
private void SetupPlayer(Transform newPosition, bool enableCameraCarMovement, bool enablePlayerController, bool pocketWatchIsObtained)
{
var playerManager = PlayerManager.GetInstance();
if (playerManager == null)
{
Logger.LogError("PlayerManager instance is missing!");
return;
}
//playerManager.DisablePlayerMovement();
playerManager.playerGameObj.transform.position = newPosition.position;
playerManager.playerGameObj.transform.rotation = newPosition.rotation;
playerManager.playerGameObj.transform.SetParent(newPosition);
playerManager._cameraMovement.cameraCarMovement = enableCameraCarMovement;
var gameProgressManager = GameProgressManager.GetInstance();
gameProgressManager.playerControllerShouldBeEnabledOnGameLoad = enablePlayerController;
gameProgressManager.PocketWatchIsObtained = pocketWatchIsObtained;
InventoryManager.GetInstance().SaveTemporarilyPocketWatchInventoryItemData(true); //Obtained pocket watch so save temporarily.
}
///
/// Moves to the next loop/puzzle state, if available.
///
public void UpdateToNextLoopState()
{
ChildrenLoopState[] allStates = (ChildrenLoopState[])Enum.GetValues(typeof(ChildrenLoopState));
int currentIndex = Array.IndexOf(allStates, currentChildrenLoopState);
if (currentIndex < allStates.Length - 1)
{
// Move to the next state
currentChildrenLoopState = allStates[currentIndex + 1];
UpdateStoryline();
}
else
{
Logger.Log("All Children Loops and the puzzle are complete.");
NotifyCompletion();
}
}
///
/// Attempt to load the saved Children loop state from GameProgressManager.
///
private void TryLoadSavedState()
{
var gameProgressManager = GameProgressManager.GetInstance();
if (gameProgressManager == null) return;
if (Enum.TryParse(gameProgressManager.currentStorylineState, out ChildrenLoopState savedState))
{
currentChildrenLoopState = savedState;
Logger.Log("Loaded Children Loop State from save: " + savedState);
UpdateStoryline();
}
else
{
Logger.LogWarning("No valid saved Children Loop state found. Starting at Loop1.");
currentChildrenLoopState = ChildrenLoopState.LongHallway;
UpdateStoryline();
}
// After loading, no longer in a loading phase
isLoadingChildrenLoops = false;
}
///
/// Saves the current Children loop state to GameProgressManager.
///
private void SaveStorylineState()
{
var gameProgressManager = GameProgressManager.GetInstance();
if (gameProgressManager == null) return;
gameProgressManager.currentStorylineState = currentChildrenLoopState.ToString();
}
///
/// Performs any final logic, then notifies GameManager this section is complete.
///
private void NotifyCompletion()
{
// Let GameManager know this story section (ChildrenLoops) is done
GameManager.GetInstance().OnStorySectionComplete(GameManager.StoryState.ChildrenLoops);
}
///
/// Resets or cleans up player settings if needed.
///
private void CleanupPlayerSettings()
{
var playerManager = PlayerManager.GetInstance();
if (playerManager != null)
{
// Example: disable or reset player movement or camera
// playerManager.DisablePlayerMovement();
}
Logger.Log("Cleaned up settings specific to Children Loops.");
}
// ------------------------ Loop-Specific Handlers ------------------------
private void HandleLoop1()
{
/* Faint, childlike humming echoes around the corners
* They discover torn pieces of a child�s drawing pinned to various spots,
* depicting fragments like a clock reading �11:20.�
* Picking up the final piece triggers a jumpscare:
* a swift silhouette of a small child darts across the hallway intersection,
* accompanied by a sharp stinger of eerie music.
*The player reassembles the drawing,
* which reveals a clue�such as a clock time (�11:20�) or a cryptic phrase (�She won�t stop crying at 11:20�).
* If the player sets their watch to 11:20, the hallway flickers,
* momentarily transporting them to an earlier moment
* where distant cries from baby Emily are heard before abruptly cutting off.
* In the Kids� Bedroom, they also find notes �Emily�s cradle� and �Medea�s frustration"*/
}
private void HandleLoop2()
{
// Logic for loop 2
}
private void HandleLoop3()
{
// Logic for loop 3
}
private void HandleLoop4()
{
// Logic for loop 4
}
private void HandleLoop5()
{
// Logic for loop 5
}
private void HandleLoop6()
{
// Logic for loop 6
}
private void HandleLoop7()
{
// Logic for loop 7
}
private void HandleLoop8()
{
// Logic for loop 8 (the final loop before puzzle)
}
// ------------------------ Puzzle Handler ------------------------
private void HandlePuzzle()
{
// Activate puzzle elements
if (puzzleGameObject != null)
{
puzzleGameObject.SetActive(true);
}
// Optionally handle puzzle-solved scenario:
// puzzleSolvedEffects.SetActive(true); // if puzzle is solved
// Then call UpdateToNextLoopState() or NotifyCompletion() if final
}
}
[Serializable]
public class ChildrenLoopsEventsData
{
public UnityEvent StartOfLongHallwayLeadingToLoops;
public UnityEvent StartOfLoop1Event;
public UnityEvent StartOfLoop2Event;
public UnityEvent StartOfLoop3Event;
public UnityEvent StartOfLoop4Event;
public UnityEvent StartOfLoop5Event;
public UnityEvent StartOfLoop6Event;
public UnityEvent StartOfLoop7Event;
public UnityEvent StartOfLoop8Event;
}
[Serializable]
public class ChildrenLoopsPuzzlesData
{
public LightSwitchesPuzzle lightsSwitchesPuzzleInLoop3;
public ManageLightSwitchesInRoom ManageLightSwitchesInLoop3;
}