|
|
@@ -0,0 +1,1045 @@
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.UIElements;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Collections;
|
|
|
+using System.Linq;
|
|
|
+
|
|
|
+public class TownShopManager : MonoBehaviour
|
|
|
+{
|
|
|
+ [Header("Shop Configuration")]
|
|
|
+ public TownShop[] allShops;
|
|
|
+
|
|
|
+ [Header("UI References")]
|
|
|
+ public UIDocument townUI;
|
|
|
+
|
|
|
+ private Dictionary<string, TownShop> shopLookup = new Dictionary<string, TownShop>();
|
|
|
+ private Dictionary<string, EventCallback<ClickEvent>> clickCallbacks = new Dictionary<string, EventCallback<ClickEvent>>();
|
|
|
+ private VisualElement rootElement;
|
|
|
+
|
|
|
+ // Singleton pattern to prevent multiple instances
|
|
|
+ private static TownShopManager instance;
|
|
|
+ public static TownShopManager Instance => instance;
|
|
|
+
|
|
|
+ // Prevent multiple shop UI creation
|
|
|
+ private bool isShopUIOpen = false;
|
|
|
+
|
|
|
+ void Awake()
|
|
|
+ {
|
|
|
+ Debug.Log($"TownShopManager.Awake() called on {gameObject.name}");
|
|
|
+
|
|
|
+ // Check if another instance already exists
|
|
|
+ if (instance != null)
|
|
|
+ {
|
|
|
+ if (instance == this)
|
|
|
+ {
|
|
|
+ Debug.Log($"TownShopManager: Same instance re-awakening on {gameObject.name}");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning($"Duplicate TownShopManager detected! Existing: {instance.gameObject.name}, New: {gameObject.name}");
|
|
|
+
|
|
|
+ // Before destroying, transfer any UI reference to the existing instance
|
|
|
+ if (townUI != null && instance.townUI == null)
|
|
|
+ {
|
|
|
+ Debug.Log("Transferring UI reference to existing singleton");
|
|
|
+ instance.townUI = townUI;
|
|
|
+
|
|
|
+ // Also transfer rootElement if available
|
|
|
+ if (instance.rootElement == null && townUI != null)
|
|
|
+ {
|
|
|
+ instance.rootElement = townUI.rootVisualElement;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.LogWarning($"Destroying duplicate on {gameObject.name}");
|
|
|
+ Destroy(gameObject);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ instance = this;
|
|
|
+ Debug.Log($"TownShopManager singleton established on {gameObject.name}");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Configure shops immediately in Awake to ensure they're ready before Start()
|
|
|
+ StartCoroutine(ConfigureShopsEarly());
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator ConfigureShopsEarly()
|
|
|
+ {
|
|
|
+ Debug.Log($"ConfigureShopsEarly starting on {gameObject.name}");
|
|
|
+
|
|
|
+ // Wait a few frames for SettlementContext to be available and TownShop components to start
|
|
|
+ yield return null;
|
|
|
+ yield return null;
|
|
|
+ yield return null;
|
|
|
+
|
|
|
+ Debug.Log($"TownShopManager: Configuring shops early in Awake on {gameObject.name}");
|
|
|
+
|
|
|
+ // Always create default shops first (creates the GameObjects)
|
|
|
+ if (allShops == null || allShops.Length == 0)
|
|
|
+ {
|
|
|
+ Debug.Log($"Creating default shops on {gameObject.name}");
|
|
|
+ CreateDefaultShops();
|
|
|
+ Debug.Log($"After CreateDefaultShops: allShops.Length = {allShops?.Length ?? 0}");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.Log($"Shops already exist: {allShops.Length} shops");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Wait another frame for shops to finish their Start() methods
|
|
|
+ yield return null;
|
|
|
+
|
|
|
+ // Then configure them based on SettlementContext if available
|
|
|
+ if (SettlementContext.Instance != null)
|
|
|
+ {
|
|
|
+ Debug.Log($"=== SETTLEMENT DEBUG on {gameObject.name} ===");
|
|
|
+ Debug.Log($"Settlement Name: {SettlementContext.Instance.settlementName}");
|
|
|
+ Debug.Log($"Settlement Type: {SettlementContext.Instance.settlementType}");
|
|
|
+ Debug.Log($"Settlement Seed: {SettlementContext.Instance.settlementSeed}");
|
|
|
+ Debug.Log($"=== Configuring shops for {SettlementContext.Instance.settlementType} ===");
|
|
|
+ ConfigureShopsFromSettlement();
|
|
|
+ UpdateAllBuildingNames();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning("TownShopManager: SettlementContext.Instance is NULL in Awake - shops will use default names");
|
|
|
+ // Configure with default names when no SettlementContext (for testing)
|
|
|
+ ConfigureShopsWithDefaults();
|
|
|
+ }
|
|
|
+
|
|
|
+ // Build the shop lookup table BEFORE setting up UI
|
|
|
+ Debug.Log($"ConfigureShopsEarly: Building shop lookup table for {allShops?.Length ?? 0} shops");
|
|
|
+ shopLookup.Clear();
|
|
|
+ if (allShops != null)
|
|
|
+ {
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null)
|
|
|
+ {
|
|
|
+ string elementName = GetUIElementNameForShop(shop);
|
|
|
+ shopLookup[elementName] = shop;
|
|
|
+ Debug.Log($"Added to lookup: {shop.buildingName} -> {elementName}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // NOW setup UI after shops are properly configured AND lookup is built
|
|
|
+ Debug.Log($"ConfigureShopsEarly: Setting up UI with {allShops?.Length ?? 0} shops, lookup: {shopLookup.Count}");
|
|
|
+ if (rootElement != null && allShops != null && allShops.Length > 0 && shopLookup.Count > 0)
|
|
|
+ {
|
|
|
+ SetupUIClickHandlers();
|
|
|
+ UpdateMoneyDisplay();
|
|
|
+ UpdateBuildingVisibility();
|
|
|
+ UpdateAllBuildingNames();
|
|
|
+ Debug.Log("ConfigureShopsEarly: UI setup completed");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning($"ConfigureShopsEarly: Cannot setup UI - rootElement: {rootElement != null}, allShops: {allShops?.Length ?? 0}, lookup: {shopLookup.Count}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ConfigureShopsWithDefaults()
|
|
|
+ {
|
|
|
+ Debug.Log("TownShopManager: Using default shop configuration");
|
|
|
+
|
|
|
+ if (allShops == null) return;
|
|
|
+
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null)
|
|
|
+ {
|
|
|
+ // Use shop type as default name if not already set properly
|
|
|
+ string defaultName = $"{shop.shopType} Shop";
|
|
|
+ string defaultKeeper = "Merchant";
|
|
|
+
|
|
|
+ shop.UpdateNames(defaultName, defaultKeeper);
|
|
|
+ Debug.Log($"Set default name: {shop.buildingName}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnDestroy()
|
|
|
+ {
|
|
|
+ // Clear singleton reference when destroyed
|
|
|
+ if (instance == this)
|
|
|
+ {
|
|
|
+ instance = null;
|
|
|
+ Debug.Log("TownShopManager singleton cleared");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void Start()
|
|
|
+ {
|
|
|
+ Debug.Log($"TownShopManager.Start() called on {gameObject.name}, instance == this: {instance == this}");
|
|
|
+ Debug.Log($"Current singleton instance: {(instance != null ? instance.gameObject.name : "NULL")}");
|
|
|
+
|
|
|
+ // Only start if this is the active instance
|
|
|
+ if (instance == this)
|
|
|
+ {
|
|
|
+ Debug.Log($"TownShopManager.Start() - Active instance on {gameObject.name}");
|
|
|
+ Debug.Log($"allShops status: {(allShops != null ? $"Array with {allShops.Length} items" : "NULL")}");
|
|
|
+
|
|
|
+ // Check if townUI is assigned
|
|
|
+ if (townUI == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("TownShopManager: townUI is not assigned in the inspector!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get root element from townUI
|
|
|
+ rootElement = townUI.rootVisualElement;
|
|
|
+ if (rootElement == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("TownShopManager: Could not get rootVisualElement from townUI!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log($"TownShopManager: UI initialized - townUI: {townUI != null}, rootElement: {rootElement != null}");
|
|
|
+
|
|
|
+ // NOTE: Shop configuration and UI setup will happen in ConfigureShopsEarly coroutine
|
|
|
+ // Don't setup UI here since shops might not be ready yet
|
|
|
+ Debug.Log("TownShopManager: Waiting for ConfigureShopsEarly to complete before setting up UI");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning($"TownShopManager.Start() - Inactive instance on {gameObject.name}, skipping initialization");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Public method to reinitialize shops and UI (for testing)
|
|
|
+ /// </summary>
|
|
|
+ public void ReinitializeShopsAndUI()
|
|
|
+ {
|
|
|
+ Debug.Log("Reinitializing shops and UI...");
|
|
|
+
|
|
|
+ // Clear existing UI event handlers to prevent duplicates
|
|
|
+ ClearUIClickHandlers();
|
|
|
+
|
|
|
+ // Reinitialize shops
|
|
|
+ InitializeShops();
|
|
|
+
|
|
|
+ // Setup UI again
|
|
|
+ SetupUIClickHandlers();
|
|
|
+ UpdateMoneyDisplay();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Clear all UI click handlers to prevent duplicates
|
|
|
+ /// </summary>
|
|
|
+ private void ClearUIClickHandlers()
|
|
|
+ {
|
|
|
+ if (rootElement == null) return;
|
|
|
+
|
|
|
+ // Clear stored callbacks first
|
|
|
+ foreach (var kvp in clickCallbacks)
|
|
|
+ {
|
|
|
+ var element = rootElement.Q<VisualElement>(kvp.Key);
|
|
|
+ if (element != null)
|
|
|
+ {
|
|
|
+ element.UnregisterCallback<ClickEvent>(kvp.Value);
|
|
|
+ Debug.Log($"Cleared stored callback for {kvp.Key}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ clickCallbacks.Clear();
|
|
|
+
|
|
|
+ // Also clear any OnAnyShopClicked callbacks as fallback
|
|
|
+ var shopElements = new string[] { "WeaponShop", "ArmorShop", "PotionShop", "GeneralStore" };
|
|
|
+ foreach (var elementName in shopElements)
|
|
|
+ {
|
|
|
+ var element = rootElement.Q<VisualElement>(elementName);
|
|
|
+ if (element != null)
|
|
|
+ {
|
|
|
+ element.UnregisterCallback<ClickEvent>(OnAnyShopClicked);
|
|
|
+ Debug.Log($"Cleared fallback callbacks for {elementName}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void InitializeShops()
|
|
|
+ {
|
|
|
+ shopLookup.Clear();
|
|
|
+
|
|
|
+ // Ensure shops exist before trying to initialize them
|
|
|
+ if (allShops == null || allShops.Length == 0)
|
|
|
+ {
|
|
|
+ Debug.LogWarning("TownShopManager.InitializeShops() - allShops is null or empty, creating default shops");
|
|
|
+ CreateDefaultShops();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (allShops == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("TownShopManager.InitializeShops() - Failed to create shops, cannot continue");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shops should already be configured by ConfigureShopsEarly() in Awake
|
|
|
+ Debug.Log($"TownShopManager.InitializeShops() - Building shop lookup table for {allShops.Length} shops");
|
|
|
+
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null)
|
|
|
+ {
|
|
|
+ // Map shop to UI element by name
|
|
|
+ string elementName = GetUIElementNameForShop(shop);
|
|
|
+ shopLookup[elementName] = shop;
|
|
|
+
|
|
|
+ Debug.Log($"Registered shop: {shop.buildingName} -> {elementName}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CreateDefaultShops()
|
|
|
+ {
|
|
|
+ Debug.Log($"Creating default shops on {gameObject.name}...");
|
|
|
+ var setupHelper = GetComponent<TownSetupHelper>();
|
|
|
+ if (setupHelper == null)
|
|
|
+ {
|
|
|
+ setupHelper = gameObject.AddComponent<TownSetupHelper>();
|
|
|
+ Debug.Log($"Added TownSetupHelper to {gameObject.name}");
|
|
|
+ }
|
|
|
+
|
|
|
+ setupHelper.SetupSampleTown();
|
|
|
+
|
|
|
+ // Collect the created shops
|
|
|
+ List<TownShop> shopList = new List<TownShop>();
|
|
|
+ if (setupHelper.weaponShop != null) shopList.Add(setupHelper.weaponShop);
|
|
|
+ if (setupHelper.armorShop != null) shopList.Add(setupHelper.armorShop);
|
|
|
+ if (setupHelper.potionShop != null) shopList.Add(setupHelper.potionShop);
|
|
|
+ if (setupHelper.generalStore != null) shopList.Add(setupHelper.generalStore);
|
|
|
+
|
|
|
+ allShops = shopList.ToArray();
|
|
|
+ Debug.Log($"CreateDefaultShops completed on {gameObject.name}: {allShops.Length} shops created");
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ Debug.Log($" - {shop.buildingName} ({shop.shopType}) on {shop.gameObject.name}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ConfigureShopsFromSettlement()
|
|
|
+ {
|
|
|
+ if (SettlementContext.Instance == null || allShops == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("ConfigureShopsFromSettlement: Missing SettlementContext or allShops!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var settlementType = SettlementContext.Instance.settlementType;
|
|
|
+ var settlementName = SettlementContext.Instance.settlementName;
|
|
|
+ var mapPosition = SettlementContext.Instance.mapPosition;
|
|
|
+
|
|
|
+ Debug.Log($"=== CONFIGURE SHOPS DEBUG ===");
|
|
|
+ Debug.Log($"Settlement: {settlementName} ({settlementType})");
|
|
|
+ Debug.Log($"Total shops to configure: {allShops.Length}");
|
|
|
+
|
|
|
+ // First, randomize all shop names based on settlement
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null)
|
|
|
+ {
|
|
|
+ string newBuildingName = ShopNameGenerator.GenerateUniqueShopName(shop.shopType, settlementName, mapPosition);
|
|
|
+ string newShopkeeperName = ShopNameGenerator.GenerateUniqueShopkeeperName(shop.shopType, settlementName, mapPosition);
|
|
|
+
|
|
|
+ // Update names using the shop's UpdateNames method
|
|
|
+ shop.UpdateNames(newBuildingName, newShopkeeperName);
|
|
|
+
|
|
|
+ Debug.Log($"Configured shop: {shop.buildingName} run by {shop.shopkeeperName} (GameObject: {shop.gameObject.name}, Active: {shop.gameObject.activeInHierarchy})");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // For villages, disable some shops
|
|
|
+ if (settlementType == SettlementType.Village)
|
|
|
+ {
|
|
|
+ Debug.Log($"=== VILLAGE CONFIGURATION START ===");
|
|
|
+ Debug.Log($"Configuring for village: {settlementName}");
|
|
|
+ Debug.Log($"Total shops before: {allShops?.Length ?? 0}");
|
|
|
+
|
|
|
+ // Count shops that are actually active before we start
|
|
|
+ int activeShopsBefore = 0;
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null && shop.gameObject.activeInHierarchy)
|
|
|
+ {
|
|
|
+ activeShopsBefore++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Debug.Log($"Active shops before village config: {activeShopsBefore}");
|
|
|
+
|
|
|
+ // First, disable all shops
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null)
|
|
|
+ {
|
|
|
+ bool wasPreviouslyActive = shop.gameObject.activeInHierarchy;
|
|
|
+ shop.gameObject.SetActive(false);
|
|
|
+ Debug.Log($"Village: Disabled {shop.buildingName} ({shop.shopType}) - Was active: {wasPreviouslyActive}, Now active: {shop.gameObject.activeInHierarchy}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Count shops that are actually disabled after we disable them
|
|
|
+ int activeShopsAfterDisable = 0;
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null && shop.gameObject.activeInHierarchy)
|
|
|
+ {
|
|
|
+ activeShopsAfterDisable++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Debug.Log($"Active shops after disabling all: {activeShopsAfterDisable}");
|
|
|
+
|
|
|
+ var random = new System.Random(SettlementContext.Instance.settlementSeed);
|
|
|
+ Debug.Log($"Using village seed: {SettlementContext.Instance.settlementSeed}");
|
|
|
+
|
|
|
+ // Always keep general store
|
|
|
+ var generalStore = allShops.FirstOrDefault(s => s != null && s.shopType == ShopType.General);
|
|
|
+ if (generalStore != null)
|
|
|
+ {
|
|
|
+ bool wasActive = generalStore.gameObject.activeInHierarchy;
|
|
|
+ generalStore.gameObject.SetActive(true);
|
|
|
+ Debug.Log($"Village: Enabled General Store - Was active: {wasActive}, Now active: {generalStore.gameObject.activeInHierarchy}, Building: {generalStore.buildingName}");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogError("Village: No General Store found!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Maybe keep one other shop (60% chance)
|
|
|
+ double randomValue = random.NextDouble();
|
|
|
+ Debug.Log($"Village: Random value for second shop: {randomValue} (>0.4 = keep second shop)");
|
|
|
+
|
|
|
+ if (randomValue > 0.4)
|
|
|
+ {
|
|
|
+ var eligibleShops = allShops.Where(s => s != null && s.shopType != ShopType.General).ToArray();
|
|
|
+ Debug.Log($"Village: Found {eligibleShops.Length} eligible shops for second shop");
|
|
|
+
|
|
|
+ if (eligibleShops.Length > 0)
|
|
|
+ {
|
|
|
+ var selectedShop = eligibleShops[random.Next(eligibleShops.Length)];
|
|
|
+ bool wasActive = selectedShop.gameObject.activeInHierarchy;
|
|
|
+ selectedShop.gameObject.SetActive(true);
|
|
|
+ Debug.Log($"Village: Also enabled {selectedShop.buildingName} ({selectedShop.shopType}) - Was active: {wasActive}, Now active: {selectedShop.gameObject.activeInHierarchy}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.Log("Village: Only keeping General Store (random value <= 0.4)");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Final count of active shops
|
|
|
+ int finalActiveShops = 0;
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null && shop.gameObject.activeInHierarchy)
|
|
|
+ {
|
|
|
+ finalActiveShops++;
|
|
|
+ Debug.Log($"Village Final: {shop.buildingName} ({shop.shopType}) is ACTIVE");
|
|
|
+ }
|
|
|
+ else if (shop != null)
|
|
|
+ {
|
|
|
+ Debug.Log($"Village Final: {shop.buildingName} ({shop.shopType}) is DISABLED");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Debug.Log($"=== VILLAGE CONFIGURATION END - Final active shops: {finalActiveShops} ===");
|
|
|
+ }
|
|
|
+ else // Town
|
|
|
+ {
|
|
|
+ Debug.Log("Configuring for town - enabling all shops");
|
|
|
+ // Towns have all shops available
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null)
|
|
|
+ {
|
|
|
+ shop.gameObject.SetActive(true);
|
|
|
+ Debug.Log($"Town: Enabling {shop.buildingName}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ UpdateAllBuildingNames();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateBuildingVisibility()
|
|
|
+ {
|
|
|
+ if (rootElement == null)
|
|
|
+ {
|
|
|
+ Debug.LogWarning("UpdateBuildingVisibility: rootElement is null!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log("=== UPDATE BUILDING VISIBILITY START ===");
|
|
|
+
|
|
|
+ // Check if allShops is null or empty
|
|
|
+ if (allShops == null || allShops.Length == 0)
|
|
|
+ {
|
|
|
+ Debug.LogWarning("UpdateBuildingVisibility: allShops is null or empty!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get all shop types that are available and active
|
|
|
+ var availableShopTypes = new System.Collections.Generic.HashSet<ShopType>();
|
|
|
+ foreach (var shop in allShops)
|
|
|
+ {
|
|
|
+ if (shop != null && shop.gameObject.activeInHierarchy)
|
|
|
+ {
|
|
|
+ availableShopTypes.Add(shop.shopType);
|
|
|
+ Debug.Log($"Available shop type: {shop.shopType} ({shop.buildingName})");
|
|
|
+ }
|
|
|
+ else if (shop != null)
|
|
|
+ {
|
|
|
+ Debug.Log($"Unavailable shop type: {shop.shopType} ({shop.buildingName}) - GameObject active: {shop.gameObject.activeInHierarchy}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log($"Total available shop types: {availableShopTypes.Count}");
|
|
|
+
|
|
|
+ // Show/hide buildings based on what's available
|
|
|
+ var allShopElements = new string[] { "WeaponShop", "ArmorShop", "PotionShop", "GeneralStore" };
|
|
|
+ var correspondingTypes = new ShopType[] { ShopType.Weapons, ShopType.Armor, ShopType.Potions, ShopType.General };
|
|
|
+
|
|
|
+ for (int i = 0; i < allShopElements.Length; i++)
|
|
|
+ {
|
|
|
+ var element = rootElement.Q<VisualElement>(allShopElements[i]);
|
|
|
+ if (element != null)
|
|
|
+ {
|
|
|
+ bool shouldShow = availableShopTypes.Contains(correspondingTypes[i]);
|
|
|
+ var previousDisplay = element.style.display.value;
|
|
|
+
|
|
|
+ if (shouldShow)
|
|
|
+ {
|
|
|
+ element.style.display = DisplayStyle.Flex;
|
|
|
+ UpdateBuildingNameDisplay(element, correspondingTypes[i]);
|
|
|
+ Debug.Log($"UI Element {allShopElements[i]} ({correspondingTypes[i]}): SHOWING (was {previousDisplay})");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ element.style.display = DisplayStyle.None;
|
|
|
+ Debug.Log($"UI Element {allShopElements[i]} ({correspondingTypes[i]}): HIDING (was {previousDisplay})");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning($"UI Element {allShopElements[i]} not found in root element!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Handle Harbor visibility based on settlement context
|
|
|
+ var harborElement = rootElement.Q<VisualElement>("Harbor");
|
|
|
+ if (harborElement != null)
|
|
|
+ {
|
|
|
+ bool shouldShowHarbor = true; // Default to show
|
|
|
+
|
|
|
+ if (SettlementContext.Instance != null)
|
|
|
+ {
|
|
|
+ shouldShowHarbor = SettlementContext.Instance.hasHarbor;
|
|
|
+ Debug.Log($"Harbor visibility: {shouldShowHarbor} (hasHarbor: {SettlementContext.Instance.hasHarbor})");
|
|
|
+ }
|
|
|
+
|
|
|
+ harborElement.style.display = shouldShowHarbor ? DisplayStyle.Flex : DisplayStyle.None;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateAllBuildingNames()
|
|
|
+ {
|
|
|
+ if (rootElement == null) return;
|
|
|
+
|
|
|
+ var allShopElements = new string[] { "WeaponShop", "ArmorShop", "PotionShop", "GeneralStore" };
|
|
|
+ var correspondingTypes = new ShopType[] { ShopType.Weapons, ShopType.Armor, ShopType.Potions, ShopType.General };
|
|
|
+
|
|
|
+ for (int i = 0; i < allShopElements.Length; i++)
|
|
|
+ {
|
|
|
+ var element = rootElement.Q<VisualElement>(allShopElements[i]);
|
|
|
+ if (element != null)
|
|
|
+ {
|
|
|
+ UpdateBuildingNameDisplay(element, correspondingTypes[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log("Updated all building names to match shop data");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateBuildingNameDisplay(VisualElement buildingElement, ShopType shopType)
|
|
|
+ {
|
|
|
+ // Check if allShops is available
|
|
|
+ if (allShops == null || allShops.Length == 0)
|
|
|
+ {
|
|
|
+ Debug.LogWarning($"UpdateBuildingNameDisplay: allShops is null or empty for {shopType}");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Find the shop with this type
|
|
|
+ var shop = allShops.FirstOrDefault(s => s != null && s.shopType == shopType && s.gameObject.activeInHierarchy);
|
|
|
+ if (shop == null) return;
|
|
|
+
|
|
|
+ // Look for various possible label elements that might contain the building name
|
|
|
+ var possibleLabelSelectors = new string[]
|
|
|
+ {
|
|
|
+ "building-name",
|
|
|
+ "shop-name",
|
|
|
+ "label",
|
|
|
+ "name-label",
|
|
|
+ "title"
|
|
|
+ };
|
|
|
+
|
|
|
+ bool nameUpdated = false;
|
|
|
+ foreach (var selector in possibleLabelSelectors)
|
|
|
+ {
|
|
|
+ var nameLabel = buildingElement.Q<Label>(selector);
|
|
|
+ if (nameLabel != null)
|
|
|
+ {
|
|
|
+ string oldText = nameLabel.text;
|
|
|
+ nameLabel.text = shop.buildingName;
|
|
|
+ Debug.Log($"Updated building display name: {selector} '{oldText}' -> '{shop.buildingName}'");
|
|
|
+ nameUpdated = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Try to find any Label element within the building element
|
|
|
+ if (!nameUpdated)
|
|
|
+ {
|
|
|
+ var allLabels = buildingElement.Query<Label>().ToList();
|
|
|
+ foreach (var label in allLabels)
|
|
|
+ {
|
|
|
+ // Skip if label text looks like it might be something else (like "WEAPONS", "ARMOR", etc)
|
|
|
+ if (!string.IsNullOrEmpty(label.text) &&
|
|
|
+ !label.text.ToUpper().Contains("WEAPON") &&
|
|
|
+ !label.text.ToUpper().Contains("ARMOR") &&
|
|
|
+ !label.text.ToUpper().Contains("POTION") &&
|
|
|
+ !label.text.ToUpper().Contains("GENERAL"))
|
|
|
+ {
|
|
|
+ string oldText = label.text;
|
|
|
+ label.text = shop.buildingName;
|
|
|
+ Debug.Log($"Updated building label: '{oldText}' -> '{shop.buildingName}'");
|
|
|
+ nameUpdated = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // If still no update, log the building structure for debugging
|
|
|
+ if (!nameUpdated)
|
|
|
+ {
|
|
|
+ Debug.Log($"Could not find name label for {shopType} building (shop: {shop.buildingName})");
|
|
|
+ LogBuildingStructure(buildingElement, shopType);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LogBuildingStructure(VisualElement buildingElement, ShopType shopType)
|
|
|
+ {
|
|
|
+ Debug.Log($"=== Building Structure for {shopType} ===");
|
|
|
+ Debug.Log($"Element name: {buildingElement.name}");
|
|
|
+
|
|
|
+ var labels = buildingElement.Query<Label>().ToList();
|
|
|
+ Debug.Log($"Found {labels.Count} labels:");
|
|
|
+ for (int i = 0; i < labels.Count; i++)
|
|
|
+ {
|
|
|
+ Debug.Log($" Label {i}: name='{labels[i].name}', text='{labels[i].text}'");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetUIElementNameForShop(TownShop shop)
|
|
|
+ {
|
|
|
+ switch (shop.shopType)
|
|
|
+ {
|
|
|
+ case ShopType.Weapons: return "WeaponShop";
|
|
|
+ case ShopType.Armor: return "ArmorShop";
|
|
|
+ case ShopType.Potions: return "PotionShop";
|
|
|
+ case ShopType.General: return "GeneralStore";
|
|
|
+ default: return shop.buildingName.Replace(" ", "");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetupUIClickHandlers()
|
|
|
+ {
|
|
|
+ if (townUI == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("TownUI is null!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ rootElement = townUI.rootVisualElement;
|
|
|
+
|
|
|
+ if (rootElement == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("Root element is null!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log($"Setting up click handlers for {shopLookup.Count} shops");
|
|
|
+
|
|
|
+ // Setup click handlers for each shop
|
|
|
+ foreach (var kvp in shopLookup)
|
|
|
+ {
|
|
|
+ var shopElement = rootElement.Q<VisualElement>(kvp.Key);
|
|
|
+ if (shopElement != null)
|
|
|
+ {
|
|
|
+ // Create and store the callback so we can unregister it later
|
|
|
+ var shop = kvp.Value;
|
|
|
+ EventCallback<ClickEvent> callback = evt => OnShopClicked(shop);
|
|
|
+
|
|
|
+ // Store the callback for later cleanup
|
|
|
+ clickCallbacks[kvp.Key] = callback;
|
|
|
+
|
|
|
+ // Register the callback
|
|
|
+ shopElement.RegisterCallback<ClickEvent>(callback);
|
|
|
+
|
|
|
+ // Add visual feedback for interactable elements
|
|
|
+ shopElement.AddToClassList("interactable-building");
|
|
|
+
|
|
|
+ Debug.Log($"✓ Setup click handler for {kvp.Key} -> {shop.buildingName}");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning($"✗ Could not find UI element: {kvp.Key}");
|
|
|
+
|
|
|
+ // List all available elements for debugging
|
|
|
+ DebugListChildElements(rootElement, kvp.Key);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Setup other building click handlers
|
|
|
+ SetupSpecialBuildingHandlers();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void DebugListChildElements(VisualElement parent, string searchName)
|
|
|
+ {
|
|
|
+ Debug.Log($"Looking for '{searchName}' in available elements:");
|
|
|
+ foreach (var child in parent.Children())
|
|
|
+ {
|
|
|
+ Debug.Log($" - Found element: {child.name} (type: {child.GetType().Name})");
|
|
|
+ if (child.childCount > 0)
|
|
|
+ {
|
|
|
+ DebugListChildElementsRecursive(child, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void DebugListChildElementsRecursive(VisualElement parent, int depth)
|
|
|
+ {
|
|
|
+ string indent = new string(' ', depth * 4);
|
|
|
+ foreach (var child in parent.Children())
|
|
|
+ {
|
|
|
+ Debug.Log($"{indent}- {child.name} (type: {child.GetType().Name})");
|
|
|
+ if (child.childCount > 0 && depth < 3) // Limit recursion
|
|
|
+ {
|
|
|
+ DebugListChildElementsRecursive(child, depth + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // This method handles all shop clicks to avoid closure issues
|
|
|
+ private void OnAnyShopClicked(ClickEvent evt)
|
|
|
+ {
|
|
|
+ var element = evt.target as VisualElement;
|
|
|
+ if (element != null && shopLookup.ContainsKey(element.name))
|
|
|
+ {
|
|
|
+ OnShopClicked(shopLookup[element.name]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetupSpecialBuildingHandlers()
|
|
|
+ {
|
|
|
+ // Adventurer's Guild
|
|
|
+ var guild = rootElement.Q<VisualElement>("AdventurersGuild");
|
|
|
+ if (guild != null)
|
|
|
+ {
|
|
|
+ guild.RegisterCallback<ClickEvent>(evt => OnAdventurersGuildClicked());
|
|
|
+ guild.AddToClassList("interactable-building");
|
|
|
+ Debug.Log("✓ Setup Adventurer's Guild click handler");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning("✗ Could not find AdventurersGuild element");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Harbor
|
|
|
+ var harbor = rootElement.Q<VisualElement>("Harbor");
|
|
|
+ if (harbor != null)
|
|
|
+ {
|
|
|
+ harbor.RegisterCallback<ClickEvent>(evt => OnHarborClicked());
|
|
|
+ harbor.AddToClassList("interactable-building");
|
|
|
+ Debug.Log("✓ Setup Harbor click handler");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning("✗ Could not find Harbor element");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Inn
|
|
|
+ var inn = rootElement.Q<VisualElement>("Inn");
|
|
|
+ if (inn != null)
|
|
|
+ {
|
|
|
+ inn.RegisterCallback<ClickEvent>(evt => OnInnClicked());
|
|
|
+ inn.AddToClassList("interactable-building");
|
|
|
+ Debug.Log("✓ Setup Inn click handler");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning("✗ Could not find Inn element");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Map button
|
|
|
+ var mapButton = rootElement.Q<Button>("MapButton");
|
|
|
+ if (mapButton != null)
|
|
|
+ {
|
|
|
+ mapButton.clicked += OnReturnToMapClicked;
|
|
|
+ Debug.Log("✓ Setup Map button click handler");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning("✗ Could not find MapButton element");
|
|
|
+ }
|
|
|
+
|
|
|
+ // Inventory button
|
|
|
+ var inventoryButton = rootElement.Q<Button>("InventoryButton");
|
|
|
+ if (inventoryButton != null)
|
|
|
+ {
|
|
|
+ inventoryButton.clicked += OnInventoryClicked;
|
|
|
+ Debug.Log("✓ Setup Inventory button click handler");
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning("✗ Could not find InventoryButton element");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnShopClicked(TownShop shop)
|
|
|
+ {
|
|
|
+ // Prevent multiple shop UIs from opening simultaneously
|
|
|
+ if (isShopUIOpen)
|
|
|
+ {
|
|
|
+ Debug.Log($"Shop UI already open, ignoring click on {shop.buildingName}");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Debug.Log($"=== SHOP CLICK DEBUG ===");
|
|
|
+ Debug.Log($"Clicked shop: {shop.buildingName} ({shop.shopType})");
|
|
|
+ Debug.Log($"Shop keeper: {shop.shopkeeperName}");
|
|
|
+ Debug.Log($"GameObject name: {shop.gameObject.name}");
|
|
|
+ Debug.Log($"=== Opening shop UI ===");
|
|
|
+
|
|
|
+ // Handle shop opening directly in TownShopManager
|
|
|
+ // Don't delegate to TownManager to avoid duplicate UI creation
|
|
|
+ OpenShopUI(shop);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OpenShopUI(TownShop shop)
|
|
|
+ {
|
|
|
+ // Set flag to prevent multiple openings
|
|
|
+ isShopUIOpen = true;
|
|
|
+
|
|
|
+ // Close any existing shop UIs first
|
|
|
+ var existingShopUIs = FindObjectsByType<TownShopUI>(FindObjectsSortMode.None);
|
|
|
+ foreach (var existingUI in existingShopUIs)
|
|
|
+ {
|
|
|
+ if (existingUI.gameObject != null)
|
|
|
+ {
|
|
|
+ Debug.Log($"Closing existing shop UI: {existingUI.gameObject.name}");
|
|
|
+ Destroy(existingUI.gameObject);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create shop UI GameObject as a separate top-level object
|
|
|
+ var shopUIObject = new GameObject("TownShopUI");
|
|
|
+
|
|
|
+ // Add UIDocument component and load the UXML
|
|
|
+ var uiDocument = shopUIObject.AddComponent<UIDocument>();
|
|
|
+
|
|
|
+ // Copy settings from town UI document if available
|
|
|
+ if (townUI != null)
|
|
|
+ {
|
|
|
+ uiDocument.panelSettings = townUI.panelSettings;
|
|
|
+ uiDocument.sortingOrder = townUI.sortingOrder + 100; // Ensure it's on top
|
|
|
+ }
|
|
|
+
|
|
|
+ uiDocument.visualTreeAsset = Resources.Load<VisualTreeAsset>("UI/TownShopUI");
|
|
|
+
|
|
|
+ Debug.Log($"Loaded UXML asset: {uiDocument.visualTreeAsset != null}");
|
|
|
+
|
|
|
+ // If not found in Resources, try direct path
|
|
|
+ if (uiDocument.visualTreeAsset == null)
|
|
|
+ {
|
|
|
+#if UNITY_EDITOR
|
|
|
+ uiDocument.visualTreeAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/UI/TownShopUI.uxml");
|
|
|
+ Debug.Log($"Loaded UXML from Assets: {uiDocument.visualTreeAsset != null}");
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uiDocument.visualTreeAsset == null)
|
|
|
+ {
|
|
|
+ Debug.LogError("Failed to load TownShopUI UXML!");
|
|
|
+ Destroy(shopUIObject);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add TownShopUI component
|
|
|
+ var shopUI = shopUIObject.AddComponent<TownShopUI>();
|
|
|
+
|
|
|
+ // Set the UI document reference
|
|
|
+ shopUI.uiDocument = uiDocument;
|
|
|
+
|
|
|
+ // Wait for proper initialization then set shop data
|
|
|
+ StartCoroutine(InitializeShopUIDelayed(shopUI, shop));
|
|
|
+
|
|
|
+ // Reset flag when this specific shop UI is destroyed
|
|
|
+ StartCoroutine(WatchForShopUIDestruction(shopUIObject));
|
|
|
+
|
|
|
+ Debug.Log($"Opened shop UI for {shop.buildingName} with sortOrder: {uiDocument.sortingOrder}");
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator InitializeShopUIDelayed(TownShopUI shopUI, TownShop shop)
|
|
|
+ {
|
|
|
+ // Wait a frame to ensure Start() is called
|
|
|
+ yield return null;
|
|
|
+
|
|
|
+ // Now set the shop data and open
|
|
|
+ shopUI.SetShop(shop);
|
|
|
+ shopUI.OpenShop();
|
|
|
+
|
|
|
+ Debug.Log($"Shop UI initialization completed for {shop.buildingName}");
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator WatchForShopUIDestruction(GameObject shopUIObject)
|
|
|
+ {
|
|
|
+ while (shopUIObject != null)
|
|
|
+ {
|
|
|
+ yield return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shop UI was destroyed, reset flag
|
|
|
+ isShopUIOpen = false;
|
|
|
+ Debug.Log("Shop UI closed - ready for new shop");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnAdventurersGuildClicked()
|
|
|
+ {
|
|
|
+ Debug.Log("Adventurer's Guild clicked - Quest system not implemented yet");
|
|
|
+ ShowNotImplementedMessage("Adventurer's Guild", "Quest and job board system");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnHarborClicked()
|
|
|
+ {
|
|
|
+ Debug.Log("Harbor clicked - Travel system not implemented yet");
|
|
|
+ ShowNotImplementedMessage("Harbor", "Sea travel and shipping");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnInnClicked()
|
|
|
+ {
|
|
|
+ Debug.Log("Inn clicked - Rest system not implemented yet");
|
|
|
+ ShowNotImplementedMessage("The Wanderer's Rest", "Rest, heal, and save progress");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnReturnToMapClicked()
|
|
|
+ {
|
|
|
+ Debug.Log("Returning to map");
|
|
|
+ UnityEngine.SceneManagement.SceneManager.LoadScene("MapScene2");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnInventoryClicked()
|
|
|
+ {
|
|
|
+ Debug.Log("Team inventory clicked - not implemented yet");
|
|
|
+ ShowNotImplementedMessage("Team Inventory", "View and manage party equipment");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ShowNotImplementedMessage(string buildingName, string description)
|
|
|
+ {
|
|
|
+ // Create a simple popup message
|
|
|
+ var popup = new VisualElement();
|
|
|
+ popup.style.position = Position.Absolute;
|
|
|
+ popup.style.width = Length.Percent(100);
|
|
|
+ popup.style.height = Length.Percent(100);
|
|
|
+ popup.style.backgroundColor = new Color(0, 0, 0, 0.7f);
|
|
|
+ popup.style.justifyContent = Justify.Center;
|
|
|
+ popup.style.alignItems = Align.Center;
|
|
|
+
|
|
|
+ var messageBox = new VisualElement();
|
|
|
+ messageBox.style.width = 400;
|
|
|
+ messageBox.style.height = 200;
|
|
|
+ messageBox.style.backgroundColor = new Color(0.9f, 0.9f, 0.9f);
|
|
|
+ messageBox.style.borderLeftWidth = 2;
|
|
|
+ messageBox.style.borderRightWidth = 2;
|
|
|
+ messageBox.style.borderTopWidth = 2;
|
|
|
+ messageBox.style.borderBottomWidth = 2;
|
|
|
+ messageBox.style.borderLeftColor = Color.black;
|
|
|
+ messageBox.style.borderRightColor = Color.black;
|
|
|
+ messageBox.style.borderTopColor = Color.black;
|
|
|
+ messageBox.style.borderBottomColor = Color.black;
|
|
|
+ messageBox.style.borderTopLeftRadius = 10;
|
|
|
+ messageBox.style.borderTopRightRadius = 10;
|
|
|
+ messageBox.style.borderBottomLeftRadius = 10;
|
|
|
+ messageBox.style.borderBottomRightRadius = 10;
|
|
|
+ messageBox.style.paddingLeft = 20;
|
|
|
+ messageBox.style.paddingRight = 20;
|
|
|
+ messageBox.style.paddingTop = 20;
|
|
|
+ messageBox.style.paddingBottom = 20;
|
|
|
+ messageBox.style.justifyContent = Justify.Center;
|
|
|
+ messageBox.style.alignItems = Align.Center;
|
|
|
+
|
|
|
+ var titleLabel = new Label(buildingName);
|
|
|
+ titleLabel.style.fontSize = 20;
|
|
|
+ titleLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
|
|
|
+ titleLabel.style.color = Color.black;
|
|
|
+ titleLabel.style.marginBottom = 10;
|
|
|
+
|
|
|
+ var descLabel = new Label($"Coming Soon!\n\n{description}");
|
|
|
+ descLabel.style.fontSize = 14;
|
|
|
+ descLabel.style.color = new Color(0.3f, 0.3f, 0.3f);
|
|
|
+ descLabel.style.whiteSpace = WhiteSpace.Normal;
|
|
|
+ descLabel.style.unityTextAlign = TextAnchor.MiddleCenter;
|
|
|
+ descLabel.style.marginBottom = 20;
|
|
|
+
|
|
|
+ var closeButton = new Button { text = "Close" };
|
|
|
+ closeButton.style.width = 100;
|
|
|
+ closeButton.style.height = 30;
|
|
|
+ closeButton.clicked += () => rootElement.Remove(popup);
|
|
|
+
|
|
|
+ messageBox.Add(titleLabel);
|
|
|
+ messageBox.Add(descLabel);
|
|
|
+ messageBox.Add(closeButton);
|
|
|
+ popup.Add(messageBox);
|
|
|
+
|
|
|
+ rootElement.Add(popup);
|
|
|
+
|
|
|
+ // Auto-close after 3 seconds
|
|
|
+ StartCoroutine(ClosePopupAfterDelay(popup, 3f));
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator ClosePopupAfterDelay(VisualElement popup, float delay)
|
|
|
+ {
|
|
|
+ yield return new WaitForSeconds(delay);
|
|
|
+ if (popup.parent != null)
|
|
|
+ rootElement.Remove(popup);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void UpdateMoneyDisplay()
|
|
|
+ {
|
|
|
+ var moneyAmount = rootElement?.Q<Label>("MoneyAmount");
|
|
|
+ if (moneyAmount != null)
|
|
|
+ {
|
|
|
+ var townManager = FindFirstObjectByType<TownManager>();
|
|
|
+ if (townManager?.currentTeam?[0] != null)
|
|
|
+ {
|
|
|
+ var character = townManager.currentTeam[0];
|
|
|
+ string moneyText = "";
|
|
|
+ if (character.gold > 0) moneyText += $"{character.gold}g ";
|
|
|
+ if (character.silver > 0) moneyText += $"{character.silver}s ";
|
|
|
+ if (character.copper > 0) moneyText += $"{character.copper}c";
|
|
|
+
|
|
|
+ moneyAmount.text = moneyText.Trim();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void Update()
|
|
|
+ {
|
|
|
+ // Update money display periodically (could be optimized with events)
|
|
|
+ if (Time.frameCount % 60 == 0) // Update once per second at 60fps
|
|
|
+ {
|
|
|
+ UpdateMoneyDisplay();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|