Files
CityBuilder/Assets/Scripts/City.cs

221 lines
9.2 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
// 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<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
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;
}
}