using System; using UnityEngine; namespace Jovian.Calendar { /// /// ScriptableObject defining the rules of an in-game calendar: day length, hours, minutes, /// month structure, month names, week length, and starting date. Create via /// Assets > Create > Jovian > Calendar > Calendar Settings. /// [CreateAssetMenu(fileName = "CalendarSettings", menuName = "Jovian/Calendar/Calendar Settings")] public class CalendarSettings : ScriptableObject { /// How many real-time seconds one full 0 to 1 float cycle represents. public float secondsPerFullDay; /// How many in-world hours per day (e.g. 24, or 16 for a shorter day). public int hoursPerDay; /// How many in-world minutes per hour (e.g. 60). public int minutesPerHour; /// /// Days in each month, in order. Length of this array defines months per year. /// E.g. { 30, 28, 31 } = 3 months with different lengths. /// public int[] daysPerMonth; /// /// Custom month names. Must match daysPerMonth.Length. /// public string[] monthNames; /// Optional: days per week for week-tracking. 0 to disable. public int daysPerWeek; // --- Starting date --- public int startYear; public int startMonth; // 0-indexed public int startDay; // 0-indexed public int startHour; public int startMinute; /// Number of months in a year, derived from daysPerMonth array length. public int MonthsPerYear => daysPerMonth?.Length ?? 0; /// Total days in one full year. public int TotalDaysInYear { get { var total = 0; if(daysPerMonth == null) { return 0; } foreach(var t in daysPerMonth) { total += t; } return total; } } /// Total in-world minutes in a single day. public int MinutesPerDay => hoursPerDay * minutesPerHour; /// Validates all calendar parameters. Throws ArgumentException on invalid configuration. public void Validate() { if(secondsPerFullDay <= 0f) { throw new ArgumentException("SecondsPerFullDay must be > 0"); } if(hoursPerDay <= 0) { throw new ArgumentException("HoursPerDay must be > 0"); } if(minutesPerHour <= 0) { throw new ArgumentException("MinutesPerHour must be > 0"); } if(daysPerMonth == null || daysPerMonth.Length == 0) { throw new ArgumentException("DaysPerMonth must have at least one entry"); } if(monthNames == null || monthNames.Length != daysPerMonth.Length) { throw new ArgumentException("MonthNames length must match DaysPerMonth length"); } for(var i = 0; i < daysPerMonth.Length; i++) { if(daysPerMonth[i] <= 0) { throw new ArgumentException($"DaysPerMonth[{i}] must be > 0"); } } if(startMonth < 0 || startMonth >= daysPerMonth.Length) { throw new ArgumentException("StartMonth out of range"); } if(startDay < 0 || startDay >= daysPerMonth[startMonth]) { throw new ArgumentException("StartDay out of range for StartMonth"); } if(startHour < 0 || startHour >= hoursPerDay) { throw new ArgumentException("StartHour out of range"); } if(startMinute < 0 || startMinute >= minutesPerHour) { throw new ArgumentException("StartMinute out of range"); } } } }