SettlementInteractionCompleteFix.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. /// <summary>
  4. /// Comprehensive fix for settlement interaction detection and UI updates
  5. /// This component forces the settlement detection system to work properly
  6. /// </summary>
  7. public class SettlementInteractionCompleteFix : MonoBehaviour
  8. {
  9. [Header("Complete Settlement Interaction Fix")]
  10. [Tooltip("Enable comprehensive settlement detection fix")]
  11. public bool enableFix = true;
  12. [Tooltip("Force UI updates even when manager doesn't detect settlements")]
  13. public bool forceUIUpdates = true;
  14. [Tooltip("Debug output level")]
  15. public bool verboseDebug = false;
  16. private SettlementInteractionManager manager;
  17. private SettlementInteractionUI settlementUI;
  18. private Transform teamMarker;
  19. private MapMaker2 mapMaker;
  20. private Settlement lastDetectedSettlement;
  21. void Start()
  22. {
  23. if (!enableFix) return;
  24. // Find all components
  25. manager = FindFirstObjectByType<SettlementInteractionManager>();
  26. settlementUI = FindFirstObjectByType<SettlementInteractionUI>();
  27. teamMarker = GameObject.Find("TeamMarker")?.transform;
  28. mapMaker = FindFirstObjectByType<MapMaker2>();
  29. }
  30. void Update()
  31. {
  32. if (!enableFix || manager == null || teamMarker == null || mapMaker?.GetMapData() == null)
  33. return;
  34. // Manual settlement detection that actually works
  35. Settlement currentSettlement = DetectNearbySettlement();
  36. // Check if settlement detection changed
  37. if (currentSettlement != lastDetectedSettlement)
  38. {
  39. if (lastDetectedSettlement != null)
  40. {
  41. LogDebug($"Left settlement: {lastDetectedSettlement.name}");
  42. // Force trigger OnSettlementLeft event
  43. if (forceUIUpdates && settlementUI != null)
  44. {
  45. settlementUI.ForceHideUI();
  46. }
  47. // Try to trigger manager's event
  48. try
  49. {
  50. manager.OnSettlementLeft?.Invoke();
  51. }
  52. catch (System.Exception e)
  53. {
  54. LogDebug($"Error invoking OnSettlementLeft: {e.Message}");
  55. }
  56. }
  57. lastDetectedSettlement = currentSettlement;
  58. if (currentSettlement != null)
  59. {
  60. LogDebug($"Detected settlement: {currentSettlement.name} ({currentSettlement.Type})");
  61. // Force trigger OnSettlementDetected event
  62. if (forceUIUpdates && settlementUI != null)
  63. {
  64. // Update UI manually
  65. UpdateSettlementUI(currentSettlement);
  66. }
  67. // Try to trigger manager's event
  68. try
  69. {
  70. manager.OnSettlementDetected?.Invoke(currentSettlement);
  71. }
  72. catch (System.Exception e)
  73. {
  74. LogDebug($"Error invoking OnSettlementDetected: {e.Message}");
  75. }
  76. }
  77. }
  78. // Handle input manually if manager doesn't
  79. if (currentSettlement != null && Input.GetKeyDown(KeyCode.E))
  80. {
  81. LogDebug($"Manual E key detection - entering {currentSettlement.name}");
  82. manager.EnterSettlement(currentSettlement);
  83. }
  84. }
  85. private Settlement DetectNearbySettlement()
  86. {
  87. Vector3 teamPos = teamMarker.position;
  88. Vector2Int mapPos = new Vector2Int(
  89. Mathf.RoundToInt(teamPos.x),
  90. Mathf.RoundToInt(teamPos.z)
  91. );
  92. var mapData = mapMaker.GetMapData();
  93. if (mapData == null) return null;
  94. // Check current position and surrounding area
  95. for (int dx = -2; dx <= 2; dx++)
  96. {
  97. for (int dy = -2; dy <= 2; dy++)
  98. {
  99. Vector2Int checkPos = new Vector2Int(mapPos.x + dx, mapPos.y + dy);
  100. var settlement = mapData.GetSettlementAt(checkPos, 0.5f);
  101. if (settlement != null)
  102. {
  103. float distance = Vector2Int.Distance(mapPos, settlement.position);
  104. if (distance <= 2f) // Within interaction range
  105. {
  106. return settlement;
  107. }
  108. }
  109. }
  110. }
  111. return null;
  112. }
  113. private void UpdateSettlementUI(Settlement settlement)
  114. {
  115. if (settlementUI == null) return;
  116. // Force show UI
  117. settlementUI.ForceShowUI();
  118. // Try to update UI elements directly
  119. try
  120. {
  121. var uiDoc = settlementUI.GetComponent<UIDocument>();
  122. if (uiDoc != null)
  123. {
  124. var root = uiDoc.rootVisualElement;
  125. var nameLabel = root.Q<UnityEngine.UIElements.Label>("SettlementName");
  126. if (nameLabel != null)
  127. {
  128. nameLabel.text = settlement.name;
  129. LogDebug($"Updated settlement name to: {settlement.name}");
  130. }
  131. var instructionLabel = root.Q<UnityEngine.UIElements.Label>("InteractionInstruction");
  132. if (instructionLabel != null)
  133. {
  134. string settlementType = settlement.Type == SettlementType.Town ? "Town" : "Village";
  135. instructionLabel.text = $"Press E to enter {settlementType}";
  136. LogDebug($"Updated instruction text");
  137. }
  138. var container = root.Q<UnityEngine.UIElements.VisualElement>("SettlementPrompt");
  139. if (container != null)
  140. {
  141. container.style.display = UnityEngine.UIElements.DisplayStyle.Flex;
  142. }
  143. }
  144. }
  145. catch (System.Exception e)
  146. {
  147. LogDebug($"Error updating UI: {e.Message}");
  148. }
  149. }
  150. private void LogDebug(string message)
  151. {
  152. if (verboseDebug)
  153. {
  154. Debug.Log($"[SettlementFix] {message}");
  155. }
  156. }
  157. [ContextMenu("Force Detect Settlement Now")]
  158. public void ForceDetectNow()
  159. {
  160. var settlement = DetectNearbySettlement();
  161. if (settlement != null)
  162. {
  163. LogDebug($"Force detected: {settlement.name}");
  164. UpdateSettlementUI(settlement);
  165. }
  166. else
  167. {
  168. LogDebug("No settlement detected at current position");
  169. if (settlementUI != null)
  170. {
  171. settlementUI.ForceHideUI();
  172. }
  173. }
  174. }
  175. void OnGUI()
  176. {
  177. if (!enableFix) return;
  178. GUILayout.BeginArea(new Rect(10, 300, 350, 120));
  179. GUILayout.BeginVertical("box");
  180. GUILayout.Label("Settlement Complete Fix", new GUIStyle(GUI.skin.label) { fontSize = 12, fontStyle = FontStyle.Bold });
  181. if (GUILayout.Button("Force Detect Settlement"))
  182. {
  183. ForceDetectNow();
  184. }
  185. if (lastDetectedSettlement != null)
  186. {
  187. GUILayout.Label($"Current: {lastDetectedSettlement.name}", new GUIStyle(GUI.skin.label) { fontSize = 10 });
  188. }
  189. else
  190. {
  191. GUILayout.Label("No settlement detected", new GUIStyle(GUI.skin.label) { fontSize = 10 });
  192. }
  193. if (teamMarker != null)
  194. {
  195. Vector3 pos = teamMarker.position;
  196. GUILayout.Label($"Position: ({pos.x:F0}, {pos.z:F0})", new GUIStyle(GUI.skin.label) { fontSize = 10 });
  197. }
  198. GUILayout.EndVertical();
  199. GUILayout.EndArea();
  200. }
  201. }