| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- using UnityEngine;
- using UnityEngine.UIElements;
- using System.Linq;
- /// <summary>
- /// Controls the travel UI and integrates with TeamTravelSystem for route planning and execution.
- /// Uses the existing travel UI elements from MapWithTravelUI.uxml
- /// </summary>
- [RequireComponent(typeof(UIDocument))]
- public class TravelUIController : MonoBehaviour
- {
- [Header("UI References")]
- public UIDocument uiDocument;
- [Header("Settings")]
- public bool showDebugLogs = false;
- // UI Elements
- private VisualElement travelContainer;
- private VisualElement travelPanel;
- private Button closeButton;
- private Label distanceLabel;
- private Label timeLabel;
- private Label specialCostsLabel;
- private Button startTravelButton;
- // Route selection (if available)
- private VisualElement routeOptionsContainer;
- private RadioButtonGroup routeSelection;
- // System references
- private TeamTravelSystem travelSystem;
- private SimpleTeamPlacement teamPlacement;
- // Current state
- private TravelRoute selectedRoute;
- private bool isUIVisible = false;
- void Awake()
- {
- if (uiDocument == null)
- uiDocument = GetComponent<UIDocument>();
- }
- void Start()
- {
- // Find system references
- travelSystem = TeamTravelSystem.Instance;
- teamPlacement = SimpleTeamPlacement.Instance;
- if (travelSystem == null)
- {
- Debug.LogError("❌ TeamTravelSystem not found! TravelUIController requires it.");
- return;
- }
- // Setup UI
- SetupUIElements();
- SetupEventHandlers();
- // Hide UI initially
- HideTravelUI();
- }
- void Update()
- {
- // Monitor for travel planning
- if (travelSystem != null && travelSystem.GetPlannedDestination().HasValue && !isUIVisible)
- {
- ShowTravelUI();
- }
- else if (travelSystem != null && !travelSystem.GetPlannedDestination().HasValue && isUIVisible)
- {
- HideTravelUI();
- }
- }
- /// <summary>
- /// Sets up references to UI elements
- /// </summary>
- private void SetupUIElements()
- {
- if (uiDocument?.rootVisualElement == null)
- {
- Debug.LogError("❌ UIDocument root not available");
- return;
- }
- var root = uiDocument.rootVisualElement;
- // Find main UI elements
- travelContainer = root.Q("TravelContainer");
- travelPanel = root.Q("TravelPanel");
- closeButton = root.Q<Button>("CloseButton");
- distanceLabel = root.Q<Label>("DistanceLabel");
- timeLabel = root.Q<Label>("TimeLabel");
- specialCostsLabel = root.Q<Label>("SpecialCostsLabel");
- startTravelButton = root.Q<Button>("StartTravelButton");
- // Optional route selection elements
- routeOptionsContainer = root.Q("RouteOptions");
- routeSelection = root.Q<RadioButtonGroup>("RouteSelection");
- }
- /// <summary>
- /// Sets up event handlers for UI interactions
- /// </summary>
- private void SetupEventHandlers()
- {
- // Close button
- if (closeButton != null)
- {
- closeButton.clicked += OnCloseButtonClicked;
- }
- // Start travel button
- if (startTravelButton != null)
- {
- startTravelButton.clicked += OnStartTravelClicked;
- }
- // Route selection (if available)
- if (routeSelection != null)
- {
- routeSelection.RegisterValueChangedCallback(OnRouteSelectionChanged);
- }
- if (showDebugLogs)
- {
- }
- }
- /// <summary>
- /// Shows the travel UI and updates it with current route information
- /// </summary>
- public void ShowTravelUI()
- {
- if (travelContainer == null) return;
- travelContainer.style.display = DisplayStyle.Flex;
- isUIVisible = true;
- // Update UI with current travel information
- UpdateTravelInformation();
- if (showDebugLogs)
- {
- }
- }
- /// <summary>
- /// Hides the travel UI
- /// </summary>
- public void HideTravelUI()
- {
- if (travelContainer == null) return;
- travelContainer.style.display = DisplayStyle.None;
- isUIVisible = false;
- if (showDebugLogs)
- {
- }
- }
- /// <summary>
- /// Updates the travel information display with current route data
- /// </summary>
- private void UpdateTravelInformation()
- {
- if (travelSystem == null) return;
- var routes = travelSystem.GetAvailableRoutes();
- if (routes.Count == 0)
- {
- ShowNoRoutesMessage();
- return;
- }
- // Select the best route by default (lowest cost)
- selectedRoute = routes.OrderBy(r => r.totalCost).First();
- // Update basic information
- UpdateBasicRouteInfo(selectedRoute);
- // Update route options if available
- UpdateRouteOptions(routes);
- // Update start button
- UpdateStartButton(selectedRoute);
- }
- /// <summary>
- /// Updates the basic route information display
- /// </summary>
- private void UpdateBasicRouteInfo(TravelRoute route)
- {
- if (distanceLabel != null)
- {
- distanceLabel.text = $"Distance: {route.totalDistance:F1} leagues";
- }
- if (timeLabel != null)
- {
- distanceLabel.text = $"Travel Time: {route.estimatedTime:F1} hours";
- }
- if (specialCostsLabel != null)
- {
- if (route.specialCosts.Count > 0)
- {
- var costStrings = route.specialCosts.Select(kvp => $"{kvp.Value} {kvp.Key}");
- specialCostsLabel.text = $"Special Costs: {string.Join(", ", costStrings)}";
- specialCostsLabel.style.color = new StyleColor(Color.yellow);
- }
- else
- {
- specialCostsLabel.text = "Special Costs: None";
- specialCostsLabel.style.color = new StyleColor(Color.white);
- }
- }
- }
- /// <summary>
- /// Updates route selection options if multiple routes are available
- /// </summary>
- private void UpdateRouteOptions(System.Collections.Generic.List<TravelRoute> routes)
- {
- if (routeOptionsContainer == null || routes.Count <= 1)
- {
- // Hide route options if not available or only one route
- if (routeOptionsContainer != null)
- routeOptionsContainer.style.display = DisplayStyle.None;
- return;
- }
- routeOptionsContainer.style.display = DisplayStyle.Flex;
- // TODO: Implement route selection UI if needed
- // For now, we'll just use the best route automatically
- }
- /// <summary>
- /// Updates the start travel button with appropriate text and state
- /// </summary>
- private void UpdateStartButton(TravelRoute route)
- {
- if (startTravelButton == null) return;
- // Check if player can afford the route
- bool canAfford = CanAffordRoute(route);
- startTravelButton.SetEnabled(canAfford);
- if (canAfford)
- {
- if (route.specialCosts.Count > 0)
- {
- var totalCost = route.specialCosts.Values.Sum();
- startTravelButton.text = $"Start Journey ({totalCost} gold)";
- }
- else
- {
- startTravelButton.text = "Start Journey (Free)";
- }
- }
- else
- {
- startTravelButton.text = "Insufficient Resources";
- }
- }
- /// <summary>
- /// Checks if the player can afford the selected route
- /// </summary>
- private bool CanAffordRoute(TravelRoute route)
- {
- // TODO: Implement player resource checking
- // For now, assume player can always afford free routes
- return route.specialCosts.Count == 0 || route.specialCosts.Values.Sum() <= 100; // Placeholder
- }
- /// <summary>
- /// Shows a message when no routes are available
- /// </summary>
- private void ShowNoRoutesMessage()
- {
- if (distanceLabel != null)
- distanceLabel.text = "Distance: No route available";
- if (timeLabel != null)
- timeLabel.text = "Travel Time: --";
- if (specialCostsLabel != null)
- specialCostsLabel.text = "Cannot reach destination";
- if (startTravelButton != null)
- {
- startTravelButton.text = "No Route Available";
- startTravelButton.SetEnabled(false);
- }
- }
- /// <summary>
- /// Event handler for close button
- /// </summary>
- private void OnCloseButtonClicked()
- {
- if (travelSystem != null)
- {
- travelSystem.CancelTravelPlanning();
- }
- HideTravelUI();
- if (showDebugLogs)
- {
- }
- }
- /// <summary>
- /// Event handler for start travel button
- /// </summary>
- private void OnStartTravelClicked()
- {
- if (selectedRoute == null || travelSystem == null)
- {
- Debug.LogWarning("Cannot start travel: no route selected or travel system unavailable");
- return;
- }
- if (!CanAffordRoute(selectedRoute))
- {
- Debug.LogWarning("Cannot start travel: insufficient resources");
- return;
- }
- // Start the travel
- travelSystem.StartTravel(selectedRoute);
- // Hide UI
- HideTravelUI();
- if (showDebugLogs)
- {
- }
- }
- /// <summary>
- /// Event handler for route selection changes
- /// </summary>
- private void OnRouteSelectionChanged(ChangeEvent<int> evt)
- {
- if (travelSystem == null) return;
- var routes = travelSystem.GetAvailableRoutes();
- if (evt.newValue >= 0 && evt.newValue < routes.Count)
- {
- selectedRoute = routes[evt.newValue];
- UpdateBasicRouteInfo(selectedRoute);
- UpdateStartButton(selectedRoute);
- if (showDebugLogs)
- {
- }
- }
- }
- /// <summary>
- /// Public methods for external control
- /// </summary>
- public bool IsUIVisible() => isUIVisible;
- public TravelRoute GetSelectedRoute() => selectedRoute;
- /// <summary>
- /// Context menu methods for debugging
- /// </summary>
- [ContextMenu("Show Travel UI (Test)")]
- public void TestShowTravelUI()
- {
- ShowTravelUI();
- }
- [ContextMenu("Hide Travel UI (Test)")]
- public void TestHideTravelUI()
- {
- HideTravelUI();
- }
- }
|