using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.Linq;
///
/// Displays active fights in the UI with zoom buttons
/// Shows runner vs monster fights, sorted by fight intensity (participants in room)
///
public class ActiveFightsUIPanel : MonoBehaviour
{
[Header("Settings")]
[SerializeField] private float updateInterval = 0.5f;
private VisualElement root;
private VisualElement fightsList;
private Dictionary fightEntries = new();
private float lastUpdateTime = 0f;
void Start()
{
InitializeUI();
}
private void InitializeUI()
{
// Find or create UIDocument
var uiDocument = FindAnyObjectByType();
if (uiDocument == null)
{
var docGO = new GameObject("UIDocument");
uiDocument = docGO.AddComponent();
}
root = uiDocument.rootVisualElement;
// Create the fights panel container
var panelContainer = new VisualElement();
panelContainer.name = "ActiveFightsPanel";
panelContainer.style.position = Position.Absolute;
panelContainer.style.left = 20; // Left side instead of right
panelContainer.style.top = 20;
panelContainer.style.width = 350;
// Limit height so the list scrolls instead of growing off-screen
panelContainer.style.maxHeight = new StyleLength(new Length(85, LengthUnit.Percent));
panelContainer.style.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.8f);
panelContainer.style.borderBottomLeftRadius = 5;
panelContainer.style.borderBottomRightRadius = 5;
panelContainer.style.borderTopLeftRadius = 5;
panelContainer.style.borderTopRightRadius = 5;
panelContainer.style.paddingBottom = 10;
panelContainer.style.paddingTop = 10;
panelContainer.style.paddingLeft = 10;
panelContainer.style.paddingRight = 10;
panelContainer.style.flexDirection = FlexDirection.Column;
// Title
var title = new Label("Active Fights");
title.style.fontSize = 16;
title.style.color = Color.white;
title.style.marginBottom = 10;
title.style.unityFontStyleAndWeight = FontStyle.Bold;
title.style.flexShrink = 0;
panelContainer.Add(title);
// Scrollable container so the list doesn't overflow the screen
var scrollView = new ScrollView(ScrollViewMode.Vertical);
scrollView.name = "FightsScrollView";
scrollView.style.flexGrow = 1;
scrollView.style.flexShrink = 1;
scrollView.horizontalScrollerVisibility = ScrollerVisibility.Hidden;
scrollView.verticalScrollerVisibility = ScrollerVisibility.Auto;
// Fights list container (lives inside the ScrollView)
fightsList = new VisualElement();
fightsList.name = "FightsList";
fightsList.style.flexDirection = FlexDirection.Column;
scrollView.Add(fightsList);
panelContainer.Add(scrollView);
root.Add(panelContainer);
}
void Update()
{
if (FightTracker.Instance == null) return;
if (fightsList == null) return;
if (Time.time - lastUpdateTime < updateInterval) return;
lastUpdateTime = Time.time;
RefreshFightsList();
}
///
/// Updates the list of displayed fights
///
private void RefreshFightsList()
{
var fights = FightTracker.Instance.GetDisplayFights();
var currentFightIds = new HashSet();
// Update or create entries for current fights
foreach (var fight in fights)
{
string fightId = $"{fight.runnerId}_{fight.monster.GetHashCode()}";
currentFightIds.Add(fightId);
if (fightEntries.ContainsKey(fightId))
{
// Update existing entry
UpdateFightEntry(fightEntries[fightId], fight);
}
else
{
// Create new entry
var entryElement = CreateFightEntry(fight, fightId);
fightEntries[fightId] = entryElement;
fightsList.Add(entryElement);
}
}
// Remove entries for fights that are no longer active
var entriesToRemove = fightEntries.Keys.Where(id => !currentFightIds.Contains(id)).ToList();
foreach (var id in entriesToRemove)
{
if (fightEntries[id] != null)
{
fightEntries[id].RemoveFromHierarchy();
}
fightEntries.Remove(id);
}
}
///
/// Creates a single fight entry UI element
///
private VisualElement CreateFightEntry(FightData fight, string fightId)
{
var entryContainer = new VisualElement();
entryContainer.name = $"FightEntry_{fightId}";
entryContainer.style.flexDirection = FlexDirection.Row;
entryContainer.style.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.9f);
entryContainer.style.borderBottomLeftRadius = 3;
entryContainer.style.borderBottomRightRadius = 3;
entryContainer.style.borderTopLeftRadius = 3;
entryContainer.style.borderTopRightRadius = 3;
entryContainer.style.paddingBottom = 5;
entryContainer.style.paddingTop = 5;
entryContainer.style.paddingLeft = 8;
entryContainer.style.paddingRight = 8;
entryContainer.style.marginBottom = 5;
entryContainer.style.alignItems = Align.Center;
// Status indicator
var statusDot = new VisualElement();
statusDot.style.width = 12;
statusDot.style.height = 12;
statusDot.style.borderBottomLeftRadius = 6;
statusDot.style.borderBottomRightRadius = 6;
statusDot.style.borderTopLeftRadius = 6;
statusDot.style.borderTopRightRadius = 6;
statusDot.style.backgroundColor = fight.isActive ? Color.red : new Color(1f, 0.5f, 0f);
statusDot.style.marginRight = 8;
entryContainer.Add(statusDot);
// Fight text
var fightText = new Label(fight.GetDisplayText());
fightText.style.color = Color.white;
fightText.style.fontSize = 12;
fightText.style.flexGrow = 1;
entryContainer.Add(fightText);
// Zoom button
var zoomButton = new Button(() => ZoomToFight(fight));
zoomButton.text = "Zoom";
zoomButton.style.width = 60;
zoomButton.style.height = 25;
zoomButton.style.backgroundColor = new Color(0.2f, 0.5f, 0.9f, 0.9f);
zoomButton.style.color = Color.white;
zoomButton.style.fontSize = 11;
zoomButton.style.marginLeft = 8;
entryContainer.Add(zoomButton);
return entryContainer;
}
///
/// Updates an existing fight entry
///
private void UpdateFightEntry(VisualElement entryElement, FightData fight)
{
if (entryElement == null) return;
// Update status dot color
var statusDot = entryElement.Q(null, "unity-content-container")?.Children().FirstOrDefault() as VisualElement;
if (statusDot != null)
{
statusDot.style.backgroundColor = fight.isActive ? Color.red : new Color(1f, 0.5f, 0f);
}
}
///
/// Zooms the camera to the room where the fight is happening
///
private void ZoomToFight(FightData fight)
{
var cameraController = FindAnyObjectByType();
if (cameraController != null)
{
cameraController.ZoomToRoom(fight.room, 1.3f, 0.5f);
}
}
}