using System; using System.Collections.Generic; using System.Linq; using DistantLands.Cozy; using DistantLands.Cozy.Data; using Sirenix.OdinInspector; using UnityEngine; using Random = UnityEngine.Random; // ReSharper disable once CheckNamespace namespace BlueWaterProject { public enum WeatherType { NONE = -1, SUNNY, RAIN, SNOW, FOG } public class CozyManager : Singleton { /*********************************************************************** * Definitions ***********************************************************************/ #region Definitions [Serializable] public class ForecastProfileRatio { [field: SerializeField] public WeatherInfo WeatherInfo { get; set; } [field: Range(0f, 10f)] [field: SerializeField] public float Ratio { get; set; } [field: DisableIf("@true")] [field: SerializeField] public float Percent { get; set; } } [Serializable] public class WeatherInfo { [field: SerializeField] public ForecastProfile ForecastProfile { get; set; } [field: SerializeField] public WeatherType WeatherType { get; set; } [field: SerializeField] public Sprite Sprite { get; set; } public WeatherInfo(ForecastProfile forecastProfile, WeatherType weatherType, Sprite sprite = null) { ForecastProfile = forecastProfile; WeatherType = weatherType; Sprite = sprite; } public WeatherInfo(WeatherInfo weatherInfo) { ForecastProfile = weatherInfo.ForecastProfile; WeatherType = weatherInfo.WeatherType; Sprite = weatherInfo.Sprite; } } #endregion /*********************************************************************** * Variables ***********************************************************************/ #region Variables // 날씨 [TitleGroup("날씨")] // 기본값 [BoxGroup("날씨/기본값")] [SerializeField] private ForecastProfileRatio[] forecastProfileRatioRatios; [BoxGroup("날씨/기본값")] [SerializeField, Required] private WeatherInfo defaultWeatherInfo; // 일기예보 [BoxGroup("날씨/일기예보")] [SerializeField] private int forecastWeatherCount = 7; [BoxGroup("날씨/일기예보")] [SerializeField] private List weatherInfoList; // 실시간 데이터 [TitleGroup("실시간 데이터"), BoxGroup("실시간 데이터/실시간 데이터", false)] [Tooltip("날씨가 변경되는데 걸리는 시간")] [SerializeField] private float changeWeatherTime; public WeatherInfo CurrentWeatherInfo => weatherInfoList[0]; public WeatherType CurrentWeatherType => weatherInfoList[0].WeatherType; public MeridiemTime CurrentTime => CozyWeather.instance.timeModule.currentTime; private float totalRatio; private float previousTimeMovementSpeed; #endregion /*********************************************************************** * Unity Events ***************************************************************m********/ #region Unity Events private void Start() { InitStart(); } private void Update() { changeWeatherTime = CozyWeather.instance.weatherModule.ecosystem.weatherTimer; } #endregion /*********************************************************************** * Init Methods ***********************************************************************/ #region Init Methods private void InitStart() { if (weatherInfoList == null || weatherInfoList.Count != 0) return; weatherInfoList = new List(forecastWeatherCount); for (var i = 0; i < forecastWeatherCount; i++) { var newWeatherInfo = new WeatherInfo(GetWeatherInfo()); weatherInfoList.Add(newWeatherInfo); } SetForecastProfile(weatherInfoList?[0].ForecastProfile); } #endregion /*********************************************************************** * Methods ***********************************************************************/ #region Methods [Button("날짜 변경")] public void SetCurrentDay(int day) => CozyWeather.instance.timeModule.currentDay = day; [Button("현재 시간 변경")] public void SetCurrentTime(int hour, int minute) { CozyWeather.instance.timeModule.SetHour(hour); CozyWeather.instance.timeModule.SetMinute(minute); } [Button("다음 날로 변경")] public void SetWeatherAndDate() { CozyWeather.instance.timeModule.currentDay += 1; CozyWeather.instance.timeModule.SetHour(9); CozyWeather.instance.timeModule.SetMinute(0); weatherInfoList.RemoveAt(0); var newWeatherInfo = new WeatherInfo(GetWeatherInfo()); weatherInfoList.Add(newWeatherInfo); SetForecastProfile(weatherInfoList[0].ForecastProfile); } [Button("다음 날씨")] public void SetNextWeather() { var remainWeatherTimer = CozyWeather.instance.weatherModule.ecosystem.weatherTimer; CozyWeather.instance.weatherModule.ecosystem.SetNextWeather(); CozyWeather.instance.weatherModule.ecosystem.SkipTicks(remainWeatherTimer); //CozyWeather.instance.weatherModule.ecosystem.SetWeather(CozyWeather.instance.weatherModule.ecosystem.currentWeather, 0f); //CozyWeather.instance.weatherModule.ecosystem.currentWeather.SetWeatherWeight(0); } private void SetForecastProfile(ForecastProfile newForecastProfile) { CozyWeather.instance.weatherModule.ecosystem.currentForecast.Clear(); CozyWeather.instance.weatherModule.ecosystem.forecastProfile = newForecastProfile; foreach (var profile in CozyWeather.instance.weatherModule.ecosystem.forecastProfile.profilesToForecast) { foreach (var fx in profile.FX) fx?.InitializeEffect(CozyWeather.instance); } CozyWeather.instance.weatherModule.ecosystem.SetupEcosystem(); //CozyWeather.instance.weatherModule.ecosystem.SetWeather(CozyWeather.instance.weatherModule.ecosystem.currentWeather, 0f); CozyWeather.instance.weatherModule.ecosystem.currentWeather.SetWeatherWeight(0); } [Button("비율 재계산"), GUIColor(0, 1, 0)] private void CalculateForecastProfileRatio() { totalRatio = forecastProfileRatioRatios.Sum(element => element.Ratio); foreach (var element in forecastProfileRatioRatios) { element.Percent = element.Ratio / totalRatio * 100f; } } private WeatherInfo GetWeatherInfo() { CalculateForecastProfileRatio(); var randomValue = Random.Range(0f, totalRatio); var cumulativeRatio = 0f; foreach (var element in forecastProfileRatioRatios) { cumulativeRatio += element.Ratio; if (randomValue <= cumulativeRatio) { return element.WeatherInfo; } } print("미리 설정된 날씨 정보가 없습니다."); return defaultWeatherInfo; } [Button("시간 정지")] public void PauseTime() { previousTimeMovementSpeed = CozyWeather.instance.perennialProfile.timeMovementSpeed; CozyWeather.instance.perennialProfile.pauseTime = true; CozyWeather.instance.perennialProfile.timeMovementSpeed = 0f; } [Button("시간 재시작")] public void ResumeTime() { CozyWeather.instance.perennialProfile.pauseTime = true; CozyWeather.instance.perennialProfile.timeMovementSpeed = previousTimeMovementSpeed; } #endregion } }