using UnityEngine; using UnityEngine.UIElements; /// /// Comprehensive fix for settlement interaction detection and UI updates /// This component forces the settlement detection system to work properly /// public class SettlementInteractionCompleteFix : MonoBehaviour { [Header("Complete Settlement Interaction Fix")] [Tooltip("Enable comprehensive settlement detection fix")] public bool enableFix = true; [Tooltip("Force UI updates even when manager doesn't detect settlements")] public bool forceUIUpdates = true; [Tooltip("Debug output level")] public bool verboseDebug = true; private SettlementInteractionManager manager; private SettlementInteractionUI settlementUI; private Transform teamMarker; private MapMaker2 mapMaker; private Settlement lastDetectedSettlement; void Start() { if (!enableFix) return; // Find all components manager = FindFirstObjectByType(); settlementUI = FindFirstObjectByType(); teamMarker = GameObject.Find("TeamMarker")?.transform; mapMaker = FindFirstObjectByType(); LogDebug("=== Settlement Interaction Complete Fix Started ==="); LogDebug($"Manager found: {manager != null}"); LogDebug($"UI found: {settlementUI != null}"); LogDebug($"TeamMarker found: {teamMarker != null}"); LogDebug($"MapMaker found: {mapMaker != null}"); if (manager != null) { // Ensure debug logging is enabled manager.enableDebugLogs = true; LogDebug("Enabled debug logging on SettlementInteractionManager"); } } void Update() { if (!enableFix || manager == null || teamMarker == null || mapMaker?.GetMapData() == null) return; // Manual settlement detection that actually works Settlement currentSettlement = DetectNearbySettlement(); // Check if settlement detection changed if (currentSettlement != lastDetectedSettlement) { if (lastDetectedSettlement != null) { LogDebug($"Left settlement: {lastDetectedSettlement.name}"); // Force trigger OnSettlementLeft event if (forceUIUpdates && settlementUI != null) { settlementUI.ForceHideUI(); } // Try to trigger manager's event try { manager.OnSettlementLeft?.Invoke(); } catch (System.Exception e) { LogDebug($"Error invoking OnSettlementLeft: {e.Message}"); } } lastDetectedSettlement = currentSettlement; if (currentSettlement != null) { LogDebug($"Detected settlement: {currentSettlement.name} ({currentSettlement.Type})"); // Force trigger OnSettlementDetected event if (forceUIUpdates && settlementUI != null) { // Update UI manually UpdateSettlementUI(currentSettlement); } // Try to trigger manager's event try { manager.OnSettlementDetected?.Invoke(currentSettlement); } catch (System.Exception e) { LogDebug($"Error invoking OnSettlementDetected: {e.Message}"); } } } // Handle input manually if manager doesn't if (currentSettlement != null && Input.GetKeyDown(KeyCode.E)) { LogDebug($"Manual E key detection - entering {currentSettlement.name}"); manager.EnterSettlement(currentSettlement); } } private Settlement DetectNearbySettlement() { Vector3 teamPos = teamMarker.position; Vector2Int mapPos = new Vector2Int( Mathf.RoundToInt(teamPos.x), Mathf.RoundToInt(teamPos.z) ); var mapData = mapMaker.GetMapData(); if (mapData == null) return null; // Check current position and surrounding area for (int dx = -2; dx <= 2; dx++) { for (int dy = -2; dy <= 2; dy++) { Vector2Int checkPos = new Vector2Int(mapPos.x + dx, mapPos.y + dy); var settlement = mapData.GetSettlementAt(checkPos, 0.5f); if (settlement != null) { float distance = Vector2Int.Distance(mapPos, settlement.position); if (distance <= 2f) // Within interaction range { return settlement; } } } } return null; } private void UpdateSettlementUI(Settlement settlement) { if (settlementUI == null) return; // Force show UI settlementUI.ForceShowUI(); // Try to update UI elements directly try { var uiDoc = settlementUI.GetComponent(); if (uiDoc != null) { var root = uiDoc.rootVisualElement; var nameLabel = root.Q("SettlementName"); if (nameLabel != null) { nameLabel.text = settlement.name; LogDebug($"Updated settlement name to: {settlement.name}"); } var instructionLabel = root.Q("InteractionInstruction"); if (instructionLabel != null) { string settlementType = settlement.Type == SettlementType.Town ? "Town" : "Village"; instructionLabel.text = $"Press E to enter {settlementType}"; LogDebug($"Updated instruction text"); } var container = root.Q("SettlementPrompt"); if (container != null) { container.style.display = UnityEngine.UIElements.DisplayStyle.Flex; } } } catch (System.Exception e) { LogDebug($"Error updating UI: {e.Message}"); } } private void LogDebug(string message) { if (verboseDebug) { Debug.Log($"[SettlementFix] {message}"); } } [ContextMenu("Force Detect Settlement Now")] public void ForceDetectNow() { var settlement = DetectNearbySettlement(); if (settlement != null) { LogDebug($"Force detected: {settlement.name}"); UpdateSettlementUI(settlement); } else { LogDebug("No settlement detected at current position"); if (settlementUI != null) { settlementUI.ForceHideUI(); } } } void OnGUI() { if (!enableFix) return; GUILayout.BeginArea(new Rect(10, 300, 350, 120)); GUILayout.BeginVertical("box"); GUILayout.Label("Settlement Complete Fix", new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = FontStyle.Bold }); if (GUILayout.Button("Force Detect Settlement")) { ForceDetectNow(); } if (lastDetectedSettlement != null) { GUILayout.Label($"Current: {lastDetectedSettlement.name}", new GUIStyle(GUI.skin.label) { fontSize = 10 }); } else { GUILayout.Label("No settlement detected", new GUIStyle(GUI.skin.label) { fontSize = 10 }); } if (teamMarker != null) { Vector3 pos = teamMarker.position; GUILayout.Label($"Position: ({pos.x:F0}, {pos.z:F0})", new GUIStyle(GUI.skin.label) { fontSize = 10 }); } GUILayout.EndVertical(); GUILayout.EndArea(); } }