| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- using UnityEngine;
- using System.Collections.Generic;
- using System.Collections;
- public class HotelManager : MonoBehaviour
- {
- public static HotelManager Instance { get; private set; }
- [Header("Hotel Settings")]
- [SerializeField] private int maxGuestsPerDay = 20;
- [SerializeField] private float guestArrivalInterval = 30f; // seconds
- [SerializeField] private Transform guestSpawnPoint;
- [Header("Guest Prefabs")]
- [SerializeField] private GameObject[] guestPrefabs;
- [SerializeField] private GameObject defaultGuestPrefab;
- [Header("Hotel Stats")]
- [SerializeField] private float hotelRating = 3f; // 1 to 5 stars
- [SerializeField] private int totalRooms = 0;
- [SerializeField] private int availableRooms = 0;
- private List<Room> hotelRooms = new List<Room>();
- private List<Guest> currentGuests = new List<Guest>();
- private List<Guest> waitingGuests = new List<Guest>();
- private bool isHotelOpen = false;
- private int guestsArrivedToday = 0;
- private float timeUntilNextGuest = 0f;
- // Events
- public System.Action<Guest> OnGuestArrived;
- public System.Action<Guest> OnGuestLeft;
- public System.Action<Guest> OnGuestAssignedRoom;
- public System.Action<Room> OnRoomAdded;
- private void Awake()
- {
- if (Instance != null && Instance != this)
- {
- Destroy(this.gameObject);
- return;
- }
- Instance = this;
- }
- private void Start()
- {
- SubscribeToEvents();
- SetupSpawnPoint();
- // Wait for hotel to open before spawning guests
- if (GameManager.Instance != null)
- {
- GameManager.OnHotelOpened += OnHotelOpened;
- }
- }
- private void OnDestroy()
- {
- UnsubscribeFromEvents();
- }
- private void Update()
- {
- if (isHotelOpen)
- {
- HandleGuestArrivals();
- UpdateHotelStats();
- }
- }
- #region Hotel Operations
- private void OnHotelOpened()
- {
- isHotelOpen = true;
- Debug.Log("Hotel is now open! Guests will start arriving.");
- // Start spawning guests
- timeUntilNextGuest = guestArrivalInterval;
- }
- private void HandleGuestArrivals()
- {
- if (!isHotelOpen) return;
- timeUntilNextGuest -= Time.deltaTime;
- if (timeUntilNextGuest <= 0 && guestsArrivedToday < maxGuestsPerDay)
- {
- SpawnGuest();
- // Calculate next arrival time (with some randomness)
- float randomFactor = UnityEngine.Random.Range(0.5f, 1.5f);
- timeUntilNextGuest = guestArrivalInterval * randomFactor;
- // Adjust based on hotel rating (higher rating = more guests)
- timeUntilNextGuest /= (hotelRating / 3f);
- }
- }
- private void SpawnGuest()
- {
- if (guestSpawnPoint == null)
- {
- Debug.LogWarning("No guest spawn point set!");
- return;
- }
- // Choose guest type based on hotel rating
- Guest.GuestType guestType = ChooseGuestType();
- GameObject guestPrefab = ChooseGuestPrefab(guestType);
- if (guestPrefab == null)
- {
- Debug.LogWarning("No guest prefab available!");
- return;
- }
- GameObject guestObj = Instantiate(guestPrefab, guestSpawnPoint.position, guestSpawnPoint.rotation);
- Guest guest = guestObj.GetComponent<Guest>();
- if (guest == null)
- {
- guest = guestObj.AddComponent<Guest>();
- }
- // Set guest properties
- guest.GuestName = GenerateGuestName();
- // Set guest type based on hotel rating
- SetGuestType(guest, guestType);
- guestsArrivedToday++;
- Debug.Log($"Guest {guest.GuestName} ({guestType}) has arrived!");
- }
- private Guest.GuestType ChooseGuestType()
- {
- // Higher rated hotels get more high-profile guests
- float rand = UnityEngine.Random.value;
- if (hotelRating >= 4.5f && rand < 0.1f)
- return Guest.GuestType.Celebrity;
- else if (hotelRating >= 4f && rand < 0.2f)
- return Guest.GuestType.VIP;
- else if (rand < 0.3f)
- return Guest.GuestType.Business;
- else if (rand < 0.5f)
- return Guest.GuestType.Family;
- else
- return Guest.GuestType.Regular;
- }
- private GameObject ChooseGuestPrefab(Guest.GuestType guestType)
- {
- // For now, use default prefab. Later can be expanded for specific types
- if (defaultGuestPrefab != null)
- return defaultGuestPrefab;
- if (guestPrefabs != null && guestPrefabs.Length > 0)
- return guestPrefabs[UnityEngine.Random.Range(0, guestPrefabs.Length)];
- return CreateDefaultGuestPrefab();
- }
- private GameObject CreateDefaultGuestPrefab()
- {
- // Create a simple guest prefab if none is provided
- GameObject guest = GameObject.CreatePrimitive(PrimitiveType.Capsule);
- guest.name = "Guest";
- // Add NavMeshAgent
- guest.AddComponent<UnityEngine.AI.NavMeshAgent>();
- // Add Guest script
- guest.AddComponent<Guest>();
- // Set color
- guest.GetComponent<Renderer>().material.color = Color.blue;
- return guest;
- }
- private void SetGuestType(Guest guest, Guest.GuestType guestType)
- {
- // This would be expanded to set specific properties based on type
- // For now, just log the type
- Debug.Log($"Setting guest type to: {guestType}");
- }
- private string GenerateGuestName()
- {
- string[] firstNames = { "Alex", "Jamie", "Casey", "Jordan", "Riley", "Morgan", "Quinn", "Blake", "Drew", "Sage" };
- string[] lastNames = { "Parker", "Reed", "Blake", "Gray", "Stone", "Fox", "Lane", "Cross", "Vale", "Knox" };
- return $"{firstNames[UnityEngine.Random.Range(0, firstNames.Length)]} {lastNames[UnityEngine.Random.Range(0, lastNames.Length)]}";
- }
- #endregion
- #region Room Management
- public void AddRoom(Room room)
- {
- if (room != null)
- {
- hotelRooms.Add(room);
- totalRooms++;
- availableRooms++;
- OnRoomAdded?.Invoke(room);
- UpdateHotelStats();
- Debug.Log($"Room added. Total rooms: {totalRooms}, Available: {availableRooms}");
- }
- }
- public Room GetAvailableRoom(Guest guest)
- {
- // Find an available room that matches guest preferences
- foreach (Room room in hotelRooms)
- {
- if (room.isComplete && !room.IsOccupied())
- {
- // For now, assign any available room
- // Later can be expanded to match guest preferences
- room.SetOccupied(true, guest);
- availableRooms--;
- Debug.Log($"Assigned room to {guest.GuestName}");
- return room;
- }
- }
- Debug.Log($"No available rooms for {guest.GuestName}");
- return null;
- }
- public void ReleaseRoom(Room room)
- {
- if (room != null && room.IsOccupied())
- {
- room.SetOccupied(false);
- availableRooms++;
- Debug.Log($"Room released. Available rooms: {availableRooms}");
- }
- }
- public List<Room> GetAllRooms()
- {
- return new List<Room>(hotelRooms);
- }
- public int GetAvailableRoomCount()
- {
- return availableRooms;
- }
- #endregion
- #region Guest Management
- private void SubscribeToEvents()
- {
- Guest.OnGuestArrived += OnGuestArrivedHandler;
- Guest.OnGuestLeft += OnGuestLeftHandler;
- Guest.OnGuestAssignedRoom += OnGuestAssignedRoomHandler;
- }
- private void UnsubscribeFromEvents()
- {
- Guest.OnGuestArrived -= OnGuestArrivedHandler;
- Guest.OnGuestLeft -= OnGuestLeftHandler;
- Guest.OnGuestAssignedRoom -= OnGuestAssignedRoomHandler;
- }
- private void OnGuestArrivedHandler(Guest guest)
- {
- currentGuests.Add(guest);
- OnGuestArrived?.Invoke(guest);
- Debug.Log($"Hotel Manager: {guest.GuestName} has arrived. Current guests: {currentGuests.Count}");
- }
- private void OnGuestLeftHandler(Guest guest)
- {
- currentGuests.Remove(guest);
- waitingGuests.Remove(guest);
- // Release room if guest had one
- if (guest.AssignedRoom != null)
- {
- ReleaseRoom(guest.AssignedRoom);
- }
- OnGuestLeft?.Invoke(guest);
- Debug.Log($"Hotel Manager: {guest.GuestName} has left. Current guests: {currentGuests.Count}");
- }
- private void OnGuestAssignedRoomHandler(Guest guest)
- {
- waitingGuests.Remove(guest);
- OnGuestAssignedRoom?.Invoke(guest);
- Debug.Log($"Hotel Manager: {guest.GuestName} has been assigned a room");
- }
- public List<Guest> GetCurrentGuests()
- {
- return new List<Guest>(currentGuests);
- }
- public List<Guest> GetWaitingGuests()
- {
- return new List<Guest>(waitingGuests);
- }
- #endregion
- #region Hotel Statistics
- private void UpdateHotelStats()
- {
- // Calculate hotel rating based on guest satisfaction
- if (currentGuests.Count > 0)
- {
- float totalSatisfaction = 0f;
- int guestsWithFeedback = 0;
- foreach (Guest guest in currentGuests)
- {
- if (guest.AssignedRoom != null) // Only count guests who have checked in
- {
- totalSatisfaction += guest.SatisfactionLevel;
- guestsWithFeedback++;
- }
- }
- if (guestsWithFeedback > 0)
- {
- float averageSatisfaction = totalSatisfaction / guestsWithFeedback;
- // Slowly adjust hotel rating based on satisfaction
- float targetRating = 1f + (averageSatisfaction * 4f); // Convert 0-1 to 1-5 scale
- hotelRating = Mathf.Lerp(hotelRating, targetRating, Time.deltaTime * 0.1f);
- hotelRating = Mathf.Clamp(hotelRating, 1f, 5f);
- }
- }
- }
- public float GetHotelRating()
- {
- return hotelRating;
- }
- public int GetTotalGuests()
- {
- return currentGuests.Count;
- }
- public float GetOccupancyRate()
- {
- if (totalRooms == 0) return 0f;
- return (float)(totalRooms - availableRooms) / totalRooms;
- }
- #endregion
- #region Utility Methods
- private void SetupSpawnPoint()
- {
- if (guestSpawnPoint == null)
- {
- // Create a default spawn point
- GameObject spawnObj = new GameObject("Guest Spawn Point");
- spawnObj.transform.position = new Vector3(0, 0, -15f); // Outside the initial room
- guestSpawnPoint = spawnObj.transform;
- spawnObj.transform.SetParent(this.transform);
- }
- }
- public bool IsHotelOpen()
- {
- return isHotelOpen;
- }
- private void OnDrawGizmosSelected()
- {
- if (guestSpawnPoint != null)
- {
- Gizmos.color = Color.green;
- Gizmos.DrawWireSphere(guestSpawnPoint.position, 1f);
- Gizmos.DrawWireCube(guestSpawnPoint.position + Vector3.up, Vector3.one * 0.5f);
- }
- }
- #endregion
- }
- // Extension methods for Room class
- public static class RoomExtensions
- {
- private static Dictionary<Room, Guest> roomOccupancy = new Dictionary<Room, Guest>();
- public static bool IsOccupied(this Room room)
- {
- return roomOccupancy.ContainsKey(room) && roomOccupancy[room] != null;
- }
- public static void SetOccupied(this Room room, bool occupied, Guest guest = null)
- {
- if (occupied && guest != null)
- {
- roomOccupancy[room] = guest;
- }
- else
- {
- roomOccupancy.Remove(room);
- }
- }
- public static Guest GetOccupant(this Room room)
- {
- return roomOccupancy.ContainsKey(room) ? roomOccupancy[room] : null;
- }
- }
|