diff --git a/Assets/KSH/GameConstants.cs b/Assets/KSH/GameConstants.cs index 065d0426..d42c6808 100644 --- a/Assets/KSH/GameConstants.cs +++ b/Assets/KSH/GameConstants.cs @@ -5,15 +5,12 @@ using UnityEngine; // 행동 타입 public enum ActionType { - NotSleep, // 5시간 미만 취침 - LessSleep, // 5시간 취침 - SleepWell, // 8시간 취침 - ForcedSleep, // 강제 수면(10시간) - Sleep, + Sleep, // 8시 기상 + OverSlept, // 결근-늦잠 + ForcedSleep, // 탈진(체력 0) Eat, Work, Dungeon, - // 보너스 스테이지 제외 Housework, // 집안일 OvertimeWork, // 야근 TeamDinner, // 회식 @@ -32,7 +29,16 @@ public class GameConstants public float maxTime = 24f; public float maxReputation = 10f; - // 강제 값 + // 체력 회복 한계 값 + public float limitRecover = 8.0f; + + // 기상 시간 + public float wakeUpTime = 8.0f; + + // 오전 8시 기상 값 + public float wakeUpAtEight = 888f; + + // 강제 값 (탈진, 결근-늦잠) public float forcedValue = 999f; // 날짜 한계 값 diff --git a/Assets/KSH/GameManager.cs b/Assets/KSH/GameManager.cs index 2281a049..8082bc57 100644 --- a/Assets/KSH/GameManager.cs +++ b/Assets/KSH/GameManager.cs @@ -15,7 +15,7 @@ public class GameManager : Singleton public int CurrentDay => currentDay; private int maxDays = GameConstants.maxDays; - // 날짜 변경 이벤트 + // 날짜 변경 이벤트, 추후에 UI 상의 날짜를 변경할 때 사용 public event Action OnDayChanged; private void Start() diff --git a/Assets/KSH/PlayerStats.cs b/Assets/KSH/PlayerStats.cs index ea693331..be92e15b 100644 --- a/Assets/KSH/PlayerStats.cs +++ b/Assets/KSH/PlayerStats.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using UnityEngine; +using Random = UnityEngine.Random; public class PlayerStats : MonoBehaviour { @@ -13,6 +14,11 @@ public class PlayerStats : MonoBehaviour public float ReputationStat { get; private set; } public event Action OnDayEnded; + public event Action Exhaustion; // 탈진 + public event Action Overslept; // 결근(늦잠) + public event Action ZeroReputation; // 평판 0 이벤트 + + private float previousAddHealth = 0f; private void Start() { @@ -47,7 +53,7 @@ public class PlayerStats : MonoBehaviour ActionEffect effect = _valueByAction.GetActionEffect(actionType); // 스탯 변경 적용 - ModifyTime(effect.timeChange); + ModifyTime(effect.timeChange, actionType); ModifyHealth(effect.healthChange); ModifyReputation(effect.reputationChange); } @@ -62,48 +68,106 @@ public class PlayerStats : MonoBehaviour } // 하루 종료 처리 - private void EndDay(bool isForced) //bool isForced? 해서 true면 강제 수면이라 8시에 깨는 + private void EndDay(float time, ActionType actionType) //bool isForced? 해서 true면 강제 수면이라 8시에 깨는 { - // 하루 종료 이벤트 발생 - OnDayEnded?.Invoke(); - - // 시간 리셋 - if (isForced) + bool isDayEnded = false; + + // 수면 행동 처리 + if (actionType == ActionType.Sleep) // 다음 날 오전 8시 기상 { - TimeStat = _gameConstants.baseTime; // 강제 수면일 시 아침 8시 기상 고정 + // 다음 날 오전 8시 - 현재 시간 값 + float nowTime = TimeStat - time; + float remainTime = CalculateTimeToWakeUp(nowTime); + + TimeStat = _gameConstants.baseTime; // 아침 8시 기상 + + // 체력 회복 + ModifyHealth(remainTime); + + // 일반 수면의 경우, 시간이 8시 이후일 때만 하루가 종료된 것으로 판단 + isDayEnded = nowTime >= 8.0f; + + // 회복량이 8 이하면 늦잠 이벤트 발동 + if (remainTime < _gameConstants.limitRecover) + { + Debug.Log($"수면이 8시간 미만입니다. 수면 시간: {remainTime}"); + Overslept?.Invoke(); // 늦잠 이벤트 + } + } + else if (actionType == ActionType.OverSlept) // 늦잠, 오전 8시에 행동을 결정하기에 하루 지남 X + { + // 다음 날 오후 3~6시 사이 기상, 추가 체력 회복 + float randomWakeUpTime = Random.Range(15, 18); + TimeStat = randomWakeUpTime; + + // 추가 체력 회복 + float remainHealth = _gameConstants.limitRecover - previousAddHealth; // 체력 회복 총량 8 - 이전 회복 값 = 총 8회복 + ModifyHealth(remainHealth); + } + else if (actionType == ActionType.ForcedSleep) // 탈진 + { + // 오전 0~8시 사이에 잠들면 하루가 지나지 않은 것으로 처리 + float nowTime = TimeStat - time; + bool isEarlyMorning = nowTime >= 0 && nowTime < 8; + isDayEnded = !isEarlyMorning; + + // 다음 날 오후 3~6시 사이 기상 + float randomWakeUpTime = Random.Range(15, 18); + TimeStat = randomWakeUpTime; + } + else // 수면 이외의 행동 + { + isDayEnded = true; + TimeStat -= _gameConstants.maxTime; + } + + // 하루가 실제로 종료된 경우에만 이벤트 발생 + if (isDayEnded) + { + OnDayEnded?.Invoke(); + } + } + + public float CalculateTimeToWakeUp(float timeStat) + { + float wakeUpTime = _gameConstants.wakeUpTime; + if (timeStat < wakeUpTime) // 현재 시간이 0~7시 사이인 경우 + { + // 당일 오전 8시까지 남은 시간 + return wakeUpTime - timeStat; } else { - TimeStat -= _gameConstants.maxTime; + return ( wakeUpTime + 24f ) - timeStat; // 다음 날 오전 8시까지 남은 시간 } } // 행동에 따른 내부 스탯 변경 메서드 - public void ModifyTime(float time) + public void ModifyTime(float time, ActionType actionType) { TimeStat += time; if (TimeStat >= _gameConstants.maxTime) { - if (time == _gameConstants.forcedValue) - { - EndDay(true); - } - else - { - EndDay(false); - } + EndDay(time, actionType); } } public void ModifyHealth(float health) { + previousAddHealth = health; // 이전 회복량 저장 HealthStat += health; // 혹시 모를 음수 값 처리 - if (HealthStat < 0) + if (HealthStat <= 0) { HealthStat = 0.0f; + // 현재는 0 되자마자 발생하도록 처리하였는데 다른 방식으로의 처리가 필요하다면 말씀해주십시오. + // 동작 이후에 스탯을 깎는다는 기준하에 작성하였습니다. (동작 전에는 CanPerformByHealth()를 통해 행동 가능 여부 판단) + + // 탈진 이벤트 발생 + Debug.Log("탈진! 체력 0"); + Exhaustion?.Invoke(); } if (HealthStat > _gameConstants.maxHealth) @@ -116,8 +180,10 @@ public class PlayerStats : MonoBehaviour { ReputationStat += reputation; - if (ReputationStat < 0) + if (ReputationStat <= 0) { + Debug.Log("당신의 평판은 0입니다..;"); + ZeroReputation?.Invoke(); ReputationStat = 0.0f; } diff --git a/Assets/KSH/ValueByAction.cs b/Assets/KSH/ValueByAction.cs index 3d7796e3..7e66a79a 100644 --- a/Assets/KSH/ValueByAction.cs +++ b/Assets/KSH/ValueByAction.cs @@ -33,14 +33,15 @@ public class ValueByAction actionEffects = new Dictionary { // 기본 액션들, 효과(시간, 체력, 평판 순) - { ActionType.Sleep, new ActionEffect(_gameConstants.forcedValue, 0, 0) }, // 8시 강제 기상 - { ActionType.ForcedSleep, new ActionEffect(+10.0f, +4.0f, 0) }, // 체력 0 + { ActionType.Sleep, new ActionEffect(_gameConstants.wakeUpAtEight, 0, 0) }, // 8시 강제 기상 + { ActionType.OverSlept, new ActionEffect(_gameConstants.forcedValue, 0, 0) }, // 결근 (오후 3~6시 기상) + { ActionType.ForcedSleep, new ActionEffect(_gameConstants.forcedValue, 4, 0) }, // 탈진 { ActionType.Eat, new ActionEffect(+1.0f, +1.0f, 0) }, { ActionType.Work, new ActionEffect(+10.0f, -3.0f, +0.2f) }, // 8to6: 10시간 { ActionType.Dungeon, new ActionEffect(+3.0f, -3.0f, 0) }, { ActionType.Housework, new ActionEffect(+1.0f, -1.0f, +0.2f) }, { ActionType.OvertimeWork, new ActionEffect(+4.0f, -5.0f, +1.0f) }, - { ActionType.TeamDinner, new ActionEffect(_gameConstants.forcedValue, _gameConstants.forcedValue, 0) }, // 수면 강제(8시 기상) 후 최대 체력 + { ActionType.TeamDinner, new ActionEffect(_gameConstants.wakeUpAtEight, _gameConstants.forcedValue, 0) }, // 수면 강제(8시 기상) 후 최대 체력 { ActionType.Absence, new ActionEffect(0, 0, -3.0f) } }; }