using UnityEngine; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine.UI; using System; using Unity.VisualScripting; using System.Numerics; using Vector3 = UnityEngine.Vector3; using UnityEditor.Rendering; public class City : MonoBehaviour { public static City Instance { get; private set; } void Awake() { Instance = this; } private string[] weekDay = new string[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; public string curDay; public float curTime; private bool timeSpeedUp = false; // Flag to check if time is sped up private float timeMultiplier = 1f; // Multiplier for time speed private float sunriseTime = 21600f; // 6:00 AM in seconds (6 * 3600) [SerializeField] GameObject sunriseTarget; // Reference to the sunrise target object for rotation private float sunsetTime = 72000f; // 8:00 PM in seconds (20 * 3600) [SerializeField] GameObject sunsetTarget; // Reference to the sunset target object for rotation private float noonTime = 43200f; // 12:00 PM in seconds (12 * 3600) [SerializeField] GameObject noonTarget; // Reference to the noon target object for rotation private float minIntensity = 0.1f; // Minimum light intensity (night) private float maxIntensity = 2f; // Maximum light intensity (noon) [SerializeField] private Light sunlight; // Reference to the sunlight light source [SerializeField] private GameObject sunTarget; // Reference to the sun target object for rotation // Removed legacy fields: maxPopulation, maxJobs, incomePerJob, faithPerChurch public TextMeshProUGUI moneyTxt; public TextMeshProUGUI dayText; public TextMeshProUGUI populationTxt; public TextMeshProUGUI jobsTxt; public TextMeshProUGUI foodTxt; public TextMeshProUGUI woodTxt; public TextMeshProUGUI steelTxt; public TextMeshProUGUI faithTxt; public TextMeshProUGUI waterTxt; public List buildings = new List(); // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { UpdateWeekDay(); // Initialize curDay with the correct day name UpdateStats(); timeSpeedUp = false; // Initialize timeSpeedUp to false } void Update() { // Set the time multiplier based on whether time is sped up timeMultiplier = timeSpeedUp ? 48f : 12f; // Update the current time UpdateCurrentTime(); // Update the day cycle DayCycle(); // Make the sunlight always aim at the moving sun target if (sunlight != null && sunTarget != null) { sunlight.transform.LookAt(sunTarget.transform.position); } } //called when placing a building public void OnPlaceBuilding(Building building) { // Apply the building preset stats buildings.Add(building); var preset = building.preset; // Loop through all resource types and add if value is not zero foreach (ResourceManager.ResourceTypes type in Enum.GetValues(typeof(ResourceManager.ResourceTypes))) { int value = GetResourceValueFromPreset(preset, type); if (value != 0) { ResourceManager.Instance.AddResource(type, value); } } UpdateStats(); } // Helper method to get the value for a resource type from the preset private int GetResourceValueFromPreset(BuildingPreset preset, ResourceManager.ResourceTypes type) { switch (type) { case ResourceManager.ResourceTypes.Population: return preset.population; case ResourceManager.ResourceTypes.Jobs: return preset.jobs; case ResourceManager.ResourceTypes.Faith: return preset.faith; case ResourceManager.ResourceTypes.Food: return preset.food; case ResourceManager.ResourceTypes.Wood: return preset.wood; case ResourceManager.ResourceTypes.Steel: return preset.steel; case ResourceManager.ResourceTypes.Water: return preset.water; case ResourceManager.ResourceTypes.Money: return preset.cost; // Add more as needed default: return 0; } } //called when bulldozing a building public void OnRemoveBuilding(Building building) { // Subtract the building preset stats from resources var preset = building.preset; foreach (ResourceManager.ResourceTypes type in Enum.GetValues(typeof(ResourceManager.ResourceTypes))) { int value = GetResourceValueFromPreset(preset, type); if (value != 0) { ResourceManager.Instance.AddResource(type, -value); } } // Remove the building from the list and destroy it buildings.Remove(building); Destroy(building.gameObject); UpdateStats(); } //update the stats text void UpdateStats() { moneyTxt.text = "$" + ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Money).resourceAmount; populationTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Population).resourceAmount.ToString(); jobsTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Jobs).resourceAmount.ToString(); foodTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Food).resourceAmount.ToString(); woodTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Wood).resourceAmount.ToString(); steelTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Steel).resourceAmount.ToString(); faithTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Faith).resourceAmount.ToString(); waterTxt.text = ResourceManager.Instance.GetResourceAmount(ResourceManager.ResourceTypes.Water).resourceAmount.ToString(); } //called when clicking "End Turn" button public void EndDay() { // Apply all per-day resource changes using ResourceManager ResourceManager.Instance.ApplyDailyResourceChanges(); UpdateStats(); UpdateWeekDay(); // Update the current day of the week } private void UpdateWeekDay() { if (curDay == null) { curDay = weekDay[0]; // Initialize with Sunday } else { int currentIndex = Array.IndexOf(weekDay, curDay); int nextIndex = (currentIndex + 1) % weekDay.Length; // Loop back to the start after Saturday curDay = weekDay[nextIndex]; } } private float UpdateCurrentTime() { // Always use the current timeMultiplier based on timeSpeedUp float currentMultiplier = timeSpeedUp ? 48f : 12f; curTime += Time.deltaTime * 60 * currentMultiplier; // Update current time in seconds // Check if a full day has passed (86400 seconds) if (curTime >= 86400f) // 24 hours * 60 minutes * 60 seconds { curTime = 0f; // Reset the timer EndDay(); // Call the EndTurn method to process the end of the day } // Display the current time in hours and minutes int hours = (int)(curTime / 3600); int minutes = (int)((curTime % 3600) / 60); string currentDayName = curDay; // Use the current day name dayText.text = $"{currentDayName}\n{hours:D2}:{minutes:D2}"; return curTime; } public void SpeedUpTime() { // Toggle the time speed up flag timeSpeedUp = !timeSpeedUp; } private void DayCycle() { if (sunlight == null || sunTarget == null) return; float intensity = minIntensity; Vector3 sunPosition = sunriseTarget.transform.position; // Default to sunrise if (curTime >= sunriseTime && curTime <= sunsetTime) { // Daytime period (6 AM to 8 PM) if (curTime <= noonTime) { // Sunrise to noon - intensity increases, sun moves from sunrise to noon position float t = (curTime - sunriseTime) / (noonTime - sunriseTime); intensity = Mathf.Lerp(minIntensity, maxIntensity, t); sunPosition = Vector3.Lerp(sunriseTarget.transform.position, noonTarget.transform.position, t); } else { // Noon to sunset - intensity decreases, sun moves from noon to sunset position float t = (curTime - noonTime) / (sunsetTime - noonTime); intensity = Mathf.Lerp(maxIntensity, minIntensity, t); sunPosition = Vector3.Lerp(noonTarget.transform.position, sunsetTarget.transform.position, t); } } else { // Nighttime period (8 PM to 6 AM) intensity = minIntensity; // During night, keep the sun at sunset position (sun is "below horizon") sunPosition = sunsetTarget.transform.position; } // Move the sun target and apply light intensity sunlight.transform.position = sunPosition; sunlight.intensity = intensity; } }