Files
CityBuilder/Assets/Scripts/City.cs
SHOUTING_PIRATE 1c91215efd initial commit
2025-07-07 20:59:04 +01:00

236 lines
8.3 KiB
C#

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
public int money;
//public int day;
public int curPopulation;
public int curJobs;
public int curFood;
public int maxPopulation;
public int maxJobs;
public int incomePerJob;
public TextMeshProUGUI moneyTxt;
public TextMeshProUGUI dayText;
public TextMeshProUGUI populationTxt;
public TextMeshProUGUI jobsTxt;
public TextMeshProUGUI foodTxt;
public List<Building> buildings = new List<Building>();
// 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
money -= building.preset.cost;
maxPopulation += building.preset.population;
maxJobs += building.preset.jobs;
//add the building to the list of buildings
buildings.Add(building);
//update the stats text
UpdateStats();
}
//called when bulldozing a building
public void OnRemoveBuilding(Building building)
{
//apply the building preset stats
maxPopulation -= building.preset.population;
maxJobs -= building.preset.jobs;
//remove the building from the list of buildings
buildings.Remove(building);
//destroy the building game object
Destroy(building.gameObject);
//update the stats text
UpdateStats();
}
//update the stats text
void UpdateStats()
{
moneyTxt.text = "$" + money;
populationTxt.text = curPopulation + " / " + maxPopulation;
jobsTxt.text = curJobs + " / " + maxJobs;
foodTxt.text = curFood.ToString();
}
//called when clicking "End Turn" button
public void EndDay()
{
//calculate the updated stats
CalculateMoney();
CalculatePopulation();
CalculateJobs();
CalculateFood();
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];
}
}
void CalculateMoney()
{
money += curJobs * incomePerJob;
foreach (Building building in buildings)
{
money -= building.preset.costPerTurn;
}
}
void CalculatePopulation()
{
if (curFood >= curPopulation && curPopulation < maxPopulation)
{
curFood -= curPopulation / 4;
curPopulation = Mathf.Min(curPopulation + (curFood / 4), maxPopulation);
}
else if (curFood < curPopulation)
{
curPopulation = curFood;
}
}
void CalculateJobs()
{
curJobs = Mathf.Min(curPopulation, maxJobs);
}
void CalculateFood()
{
curFood = 0;
foreach (Building building in buildings)
{
curFood += building.preset.food;
}
}
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);
#if UNITY_EDITOR
Debug.Log($"Sunrise period - Time: {curTime:F0}, Intensity: {intensity:F2}");
#endif
}
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);
#if UNITY_EDITOR
Debug.Log($"Sunset period - Time: {curTime:F0}, Intensity: {intensity:F2}");
#endif
}
}
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;
#if UNITY_EDITOR
Debug.Log($"Night cycle active - Time: {curTime:F0}, Intensity: {intensity:F2}");
#endif
}
// Move the sun target and apply light intensity
sunlight.transform.position = sunPosition;
sunlight.intensity = intensity;
}
}