diff --git a/Assets/KSH/DungeonLogic.cs b/Assets/KSH/DungeonLogic.cs index 1bc28af7..ee321abf 100644 --- a/Assets/KSH/DungeonLogic.cs +++ b/Assets/KSH/DungeonLogic.cs @@ -15,10 +15,6 @@ public class DungeonLogic : MonoBehaviour private PlayerController _player; private EnemyController _enemy; - - // 던전 결과 이벤트 - public event Action OnDungeonSuccess; - public event Action OnDungeonFailure; private void Awake() { diff --git a/Assets/KSH/PlayerStats.cs b/Assets/KSH/PlayerStats.cs index ea614d58..3f23bcb1 100644 --- a/Assets/KSH/PlayerStats.cs +++ b/Assets/KSH/PlayerStats.cs @@ -50,6 +50,7 @@ public class PlayerStats : MonoBehaviour private SpeechBubbleFollower _speechBubbleFollower; private bool _isActiveBubble; private bool _hasShownBubbleToday; // 하루에 말풍선 하나만 표시하기 + private InteractionAnimationPanelController _interactionAnimation; // 상호작용 패널 Active 여부 확인 private int _mealCount; public int MealCount => _mealCount; @@ -142,8 +143,7 @@ public class PlayerStats : MonoBehaviour ShowBubble(); } } - - private InteractionAnimationPanelController _interactionAnimation; + public void SetInteractionPanelController(InteractionAnimationPanelController panelController) { _interactionAnimation = panelController; @@ -151,7 +151,7 @@ public class PlayerStats : MonoBehaviour public void ShowBubble() { - if (_interactionAnimation.IsPanelActive()) return; + if (_interactionAnimation != null && _interactionAnimation.IsPanelActive()) return; if(_isActiveBubble) _speechBubbleFollower.ShowMessage(); @@ -296,11 +296,6 @@ public class PlayerStats : MonoBehaviour // 하루가 실제로 종료된 경우에만 이벤트 발생 if (isDayEnded) { - // 결근 관련 변수 초기화 - _hasWorkedToday = false; - _hasCheckedAbsenceToday = false; - _hasShownBubbleToday = false; - // 식사 횟수 초기화 _mealCount = 0; @@ -333,6 +328,13 @@ public class PlayerStats : MonoBehaviour { EndDay(time, actionType); } + + if (TimeStat >= 8.0f && TimeStat < 9.0f) + { + _hasWorkedToday = false; + _hasCheckedAbsenceToday = false; + _hasShownBubbleToday = false; + } CheckBubble(); } diff --git a/Assets/LIN/Scripts/DailyRoutine/InteractionController.cs b/Assets/LIN/Scripts/DailyRoutine/InteractionController.cs index 28ec589e..951ad303 100644 --- a/Assets/LIN/Scripts/DailyRoutine/InteractionController.cs +++ b/Assets/LIN/Scripts/DailyRoutine/InteractionController.cs @@ -28,7 +28,7 @@ public class InteractionController : MonoBehaviour { housingCanvasController.ShowNpcInteractionButton(() => { - GameManager.Instance.StartNPCDialogue(GamePhase.Gameplay); + GameManager.Instance.DirectStartDialogue(); }); } diff --git a/Assets/Resources/Dialogues/dialogue.json b/Assets/Resources/Dialogues/dialogue.json index 38b6326c..b228cdb7 100644 --- a/Assets/Resources/Dialogues/dialogue.json +++ b/Assets/Resources/Dialogues/dialogue.json @@ -46,6 +46,97 @@ "id": "player_intro_3", "name": "주인공", "text": "할 수 밖에 없잖아...!!", + "nextId": "fairy_intro_5", + "phase": "intro" + }, + { + "id": "fairy_intro_5", + "name": "냉장고 요정", + "text": "아, 추가로 설명을 하자면!", + "nextId": "player_intro_4", + "phase": "intro" + }, + { + "id": "player_intro_4", + "name": "냉장고 요정", + "text": "시간 아래의 바가 보이지? 상단은 너의 회사 평판, 하단은 체력 바야.", + "nextId": "fairy_intro_6", + "phase": "intro" + }, + { + "id": "fairy_intro_6", + "name": "냉장고 요정", + "text": "던전은 냉장고를 통해 진입할 수 있어. 일주일 내에 스테이지 2개를 깨주기 바라!", + "nextId": "player_intro_5", + "phase": "intro" + }, + { + "id": "player_intro_5", + "name": "주인공", + "text": "(앞으로 중고 거래를 안해야겠어.) 그래. 그런데 평판이나 체력이 0이 되면 뭐가... 돼?", + "nextId": "fairy_intro_7", + "phase": "intro" + }, + { + "id": "fairy_intro_7", + "name": "냉장고 요정", + "text": "평판이 0이 되면 굉장한 일이 벌어지지...", + "nextId": "player_intro_6", + "phase": "intro" + }, + { + "id": "player_intro_6", + "name": "주인공", + "text": "설마 용사로 전직-", + "nextId": "fairy_intro_8", + "phase": "intro" + }, + { + "id": "fairy_intro_8", + "name": "냉장고 요정", + "text": "너가 회사에서 짤려.", + "nextId": "player_intro_7", + "phase": "intro" + }, + { + "id": "player_intro_7", + "name": "주인공", + "text": "...........?", + "nextId": "fairy_intro_9", + "phase": "intro" + }, + { + "id": "fairy_intro_9", + "name": "냉장고 요정", + "text": "그리고 체력 0이 되면 지쳐서 기절할 거야.", + "nextId": "player_intro_8", + "phase": "intro" + }, + { + "id": "player_intro_8", + "name": "주인공", + "text": "...........................", + "nextId": "fairy_intro_10", + "phase": "intro" + }, + { + "id": "fairy_intro_10", + "name": "냉장고 요정", + "text": "관리를 잘 하는 게 좋겠지?", + "nextId": "player_intro_9", + "phase": "intro" + }, + { + "id": "player_intro_9", + "name": "주인공", + "text": "이래서 감자 온도가 -99도, 아니 알려줘서 참으로 고맙다.", + "nextId": "fairy_intro_11", + "phase": "intro" + }, + { + "id": "fairy_intro_11", + "name": "냉장고 요정", + "text": "별 말씀을!", "nextId": "", "phase": "intro" }, @@ -73,14 +164,14 @@ { "id": "fairy_gameplay_3", "name": "냉장고 요정", - "text": "던전은 총 2스테이지까지 있으며 모두 클리어한다면...", + "text": "같은 스테이지를 3번이나 시도하면... 굉장한 일이 벌어지지.", "nextId": "player_gameplay_3", "phase": "gameplay" }, { "id": "player_gameplay_3", "name": "주인공", - "text": "한다면... 뭐지?", + "text": "(안좋은 일이겠지)", "nextId": "", "phase": "gameplay" }, @@ -195,6 +286,69 @@ "text": "그 날 서울시 어느 동네에서, 한 34세의 남성의 절규 소리가 울려퍼졌다.", "nextId": "", "phase": "zero" + }, + { + "id": "fairy_fail_1", + "name": "냉장고 요정", + "text": "...이야. \n같은 스테이지를 몇 번이나 도전하는 거야?", + "nextId": "player_fail_1", + "phase": "fail" + }, + { + "id": "player_fail_1", + "name": "주인공", + "text": "못 할 수도 있지...", + "nextId": "fairy_fail_2", + "phase": "fail" + }, + { + "id": "fairy_fail_2", + "name": "냉장고 요정", + "text": "음, 축하해!", + "nextId": "player_fail_2", + "phase": "fail" + }, + { + "id": "player_fail_2", + "name": "주인공", + "text": "(불안하다...)", + "nextId": "fairy_fail_3", + "phase": "fail" + }, + { + "id": "fairy_fail_3", + "name": "냉장고 요정", + "text": "던전이 제대로 잠재워지지 않아서 곧 세상은 멸망할 거야!", + "nextId": "player_fail_4", + "phase": "fail" + }, + { + "id": "player_fail_4", + "name": "주인공", + "text": "뭐?????", + "nextId": "fairy_fail_4", + "phase": "fail" + }, + { + "id": "fairy_fail_4", + "name": "냉장고 요정", + "text": "출근하기 싫다고 했지? 이제 안해도 돼!", + "nextId": "player_fail_5", + "phase": "fail" + }, + { + "id": "player_fail_5", + "name": "주인공", + "text": "안돼!!!!!!", + "nextId": "fairy_fail_5", + "phase": "fail" + }, + { + "id": "fairy_fail_5", + "name": " ", + "text": "그렇게 세상은 멸망했다. 끝.", + "nextId": "", + "phase": "fail" } ] } \ No newline at end of file diff --git a/Assets/Scripts/Common/Dialogue/ChatWindowController.cs b/Assets/Scripts/Common/Dialogue/ChatWindowController.cs index 428cd556..8e4c61be 100644 --- a/Assets/Scripts/Common/Dialogue/ChatWindowController.cs +++ b/Assets/Scripts/Common/Dialogue/ChatWindowController.cs @@ -35,8 +35,9 @@ public enum GamePhase // 단계별로 출력되는 대화가 달라짐 { Intro, // 인트로 설명문 Gameplay, // 게임 진행 팁? 등 - End, // 엔딩 대화 - ZeroEnd + End, // 회고 엔딩 + ZeroEnd, // 평판 0 엔딩 + FailEnd // 같은 스테이지 3회 실패 엔딩 } public class ChatWindowController : MonoBehaviour, IPointerClickHandler diff --git a/Assets/Scripts/Common/Dialogue/FairyDialogueManager.cs b/Assets/Scripts/Common/Dialogue/FairyDialogueManager.cs index 65fc370e..ad16eb22 100644 --- a/Assets/Scripts/Common/Dialogue/FairyDialogueManager.cs +++ b/Assets/Scripts/Common/Dialogue/FairyDialogueManager.cs @@ -90,7 +90,11 @@ public class FairyDialogueManager else if (phase == GamePhase.ZeroEnd) { StartPhaseDialogue("zero"); - } + } + else if (phase == GamePhase.FailEnd) + { + StartPhaseDialogue("fail"); + } } // 단계별 시작 대화 찾기 및 시작 diff --git a/Assets/Scripts/Common/GameManager.cs b/Assets/Scripts/Common/GameManager.cs index 871d1795..b9f8f710 100644 --- a/Assets/Scripts/Common/GameManager.cs +++ b/Assets/Scripts/Common/GameManager.cs @@ -13,6 +13,9 @@ public partial class GameManager : Singleton private int stageLevel = 1; // 스테이지 정보 public int StageLevel => stageLevel; + + private int tryStageCount = 0; + public int TryStageCount => tryStageCount; // 날짜 변경 이벤트, 추후에 UI 상의 날짜를 변경할 때 사용 public event Action OnDayChanged; @@ -40,15 +43,24 @@ public partial class GameManager : Singleton public void StartNPCDialogue(GamePhase phase) // intro, gameplay, end 존재 { - if(chatWindowController == null) - SetChatWindowController(); - - chatWindowController.SetGamePhase(phase); + StartCoroutine(StartNPCDialogueCoroutine(phase)); } - private void SetChatWindowController() + private IEnumerator StartNPCDialogueCoroutine(GamePhase phase) { - chatWindowController = FindObjectOfType(); + if (chatWindowController == null) + { + yield return new WaitForSeconds(0.5f); // 씬 전환 대기 + chatWindowController = FindObjectOfType(); + } + + chatWindowController.SetGamePhase(phase); + } + + public void DirectStartDialogue() + { + if (chatWindowController == null) chatWindowController = FindObjectOfType(); + chatWindowController.SetGamePhase(GamePhase.Gameplay); } #endregion @@ -79,6 +91,7 @@ public partial class GameManager : Singleton public void ChangeToGameScene() { + tryStageCount++; // 던전 시도 횟수 증가 SceneManager.LoadScene("ReDungeon"); // 던전 Scene HandleSceneAudio("Dungeon"); } @@ -87,6 +100,8 @@ public partial class GameManager : Singleton { SceneManager.LoadScene("ReHousing"); // Home Scene HandleSceneAudio("Housing"); + + if (tryStageCount >= 3) FailEnd(); // 엔딩 } // TODO: Open Setting Panel 등 Panel 처리 diff --git a/Assets/Scripts/Common/GameUtility/EndingLogic.cs b/Assets/Scripts/Common/GameUtility/EndingLogic.cs index 8e77c8a8..9e144159 100644 --- a/Assets/Scripts/Common/GameUtility/EndingLogic.cs +++ b/Assets/Scripts/Common/GameUtility/EndingLogic.cs @@ -16,51 +16,24 @@ public partial class GameManager public void ClearStage() { + tryStageCount = 0; // 시도 횟수 초기화 stageLevel++; } - private void ZeroReputationEnd() + private void ZeroReputationEnd() // 평판 0 엔딩 { - // npc와의 대화 출력, Phase = zero StartNPCDialogue(GamePhase.ZeroEnd); } + + private void FailEnd() // 같은 스테이지 3회 도전 실패 엔딩 + { + StartNPCDialogue(GamePhase.FailEnd); + } - // 엔딩 관련 메서드. 7일차에 실행 + // 회고 엔딩. 7일차에 실행 private void TriggerTimeEnding() { // npc와의 마지막 대화 출력 StartNPCDialogue(GamePhase.End); - - // 플레이어 상태에 따라 엔딩 판별 - // EndingType endingType = DetermineEnding(); - - // 엔딩 타입에 따라 다른 씬이나 UI 표시 - /*switch (endingType) - { - case EndingType.Normal: - Debug.Log("던전 공략 성공"); - // TODO: 엔딩 관련 패널 띄우기 - break; - case EndingType.Bad: - Debug.Log("던전 공략 실패"); - - break; - case EndingType.Happy: - Debug.Log("던전 공략 성공과 훌륭한 평판 작"); - - break; - }*/ - } - - // 던전 스테이지와 평판 수치로 엔딩 판별 - private EndingType DetermineEnding() - { - if (stageLevel < GameConstants.maxStage) // 현재 스테이지 1 혹은 2 - return EndingType.Bad; - - if (PlayerStats.Instance.ReputationStat >= happyEndReputation) // 평판이 일정 수치 이상 - return EndingType.Happy; - - return EndingType.Normal; } } \ No newline at end of file