491 lines
13 KiB
C#
491 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using RoR2.ConVar;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering.PostProcessing;
|
|
|
|
namespace RoR2.UI;
|
|
|
|
[RequireComponent(typeof(MPEventSystemProvider))]
|
|
[RequireComponent(typeof(Canvas))]
|
|
public class HUD : MonoBehaviour
|
|
{
|
|
public delegate void ShouldHudDisplayDelegate(HUD hud, ref bool shouldDisplay);
|
|
|
|
private static List<HUD> instancesList;
|
|
|
|
private static bool lockInstancesList;
|
|
|
|
private static List<GameObject> instancesToReenableList;
|
|
|
|
public static readonly ReadOnlyCollection<HUD> readOnlyInstanceList;
|
|
|
|
private bool shouldForceScoreboardToggle;
|
|
|
|
public GameObject oldTarget;
|
|
|
|
private LocalUser _localUserViewer;
|
|
|
|
[Header("Main")]
|
|
[Tooltip("Immediate child of this object which contains all other UI.")]
|
|
public GameObject mainContainer;
|
|
|
|
private Canvas _mainContainerCanvas;
|
|
|
|
[NonSerialized]
|
|
public CameraRigController cameraRigController;
|
|
|
|
public GameObject scoreboardPanel;
|
|
|
|
public InspectPanelController inspectPanelController;
|
|
|
|
public GameObject mainUIPanel;
|
|
|
|
public GameObject cinematicPanel;
|
|
|
|
public CombatHealthBarViewer combatHealthBarViewer;
|
|
|
|
public ContextManager contextManager;
|
|
|
|
public AllyCardManager allyCardManager;
|
|
|
|
public Transform gameModeUiRoot;
|
|
|
|
[Header("Character")]
|
|
public HealthBar healthBar;
|
|
|
|
public ExpBar expBar;
|
|
|
|
public LevelText levelText;
|
|
|
|
public BuffDisplay buffDisplay;
|
|
|
|
public MoneyText moneyText;
|
|
|
|
public GameObject lunarCoinContainer;
|
|
|
|
public MoneyText lunarCoinText;
|
|
|
|
public GameObject voidCoinContainer;
|
|
|
|
public MoneyText voidCoinText;
|
|
|
|
public SkillIcon[] skillIcons;
|
|
|
|
public EquipmentIcon[] equipmentIcons;
|
|
|
|
public ItemInventoryDisplay itemInventoryDisplay;
|
|
|
|
[Header("Debug")]
|
|
public HUDSpeedometer speedometer;
|
|
|
|
private MPEventSystemProvider eventSystemProvider;
|
|
|
|
private Canvas canvas;
|
|
|
|
private EScoreboardDeactivateReturnContext scoreboardDeactivateReturnContext;
|
|
|
|
private GameObject previousTargetBodyObject;
|
|
|
|
public static readonly BoolConVar cvHudEnable;
|
|
|
|
public GameObject targetBodyObject
|
|
{
|
|
get
|
|
{
|
|
if (!targetMaster)
|
|
{
|
|
return null;
|
|
}
|
|
return targetMaster.GetBodyObject();
|
|
}
|
|
}
|
|
|
|
public CharacterMaster targetMaster { get; set; }
|
|
|
|
public LocalUser localUserViewer
|
|
{
|
|
get
|
|
{
|
|
return _localUserViewer;
|
|
}
|
|
set
|
|
{
|
|
if (_localUserViewer != value)
|
|
{
|
|
_localUserViewer = value;
|
|
eventSystemProvider.eventSystem = _localUserViewer.eventSystem;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Canvas mainContainerCanvas
|
|
{
|
|
get
|
|
{
|
|
if (_mainContainerCanvas == null)
|
|
{
|
|
_mainContainerCanvas = mainContainer.GetComponent<Canvas>();
|
|
}
|
|
return _mainContainerCanvas;
|
|
}
|
|
set
|
|
{
|
|
}
|
|
}
|
|
|
|
public PostProcessVolume scoreboardPostProcessVolume { get; private set; }
|
|
|
|
public GameObject gameModeUiInstance { get; private set; }
|
|
|
|
public static event Action<HUD> onHudTargetChangedGlobal;
|
|
|
|
public static event ShouldHudDisplayDelegate shouldHudDisplay;
|
|
|
|
static HUD()
|
|
{
|
|
instancesList = new List<HUD>();
|
|
lockInstancesList = false;
|
|
instancesToReenableList = new List<GameObject>();
|
|
readOnlyInstanceList = instancesList.AsReadOnly();
|
|
cvHudEnable = new BoolConVar("hud_enable", ConVarFlags.Archive, "1", "Enable/disable the HUD.");
|
|
}
|
|
|
|
private static void OnUICameraPreRender(UICamera uiCamera)
|
|
{
|
|
CameraRigController cameraRigController = uiCamera.cameraRigController;
|
|
if (!cameraRigController)
|
|
{
|
|
return;
|
|
}
|
|
LocalUser localUser = (cameraRigController.viewer ? cameraRigController.viewer.localUser : null);
|
|
if (localUser == null)
|
|
{
|
|
return;
|
|
}
|
|
lockInstancesList = true;
|
|
for (int i = 0; i < instancesList.Count; i++)
|
|
{
|
|
HUD hUD = instancesList[i];
|
|
if (hUD.localUserViewer == localUser)
|
|
{
|
|
hUD.canvas.worldCamera = uiCamera.camera;
|
|
continue;
|
|
}
|
|
GameObject gameObject = hUD.gameObject;
|
|
instancesToReenableList.Add(gameObject);
|
|
gameObject.SetActive(value: false);
|
|
}
|
|
lockInstancesList = false;
|
|
}
|
|
|
|
private static void OnUICameraPostRender(UICamera uiCamera)
|
|
{
|
|
lockInstancesList = true;
|
|
for (int i = 0; i < instancesToReenableList.Count; i++)
|
|
{
|
|
instancesToReenableList[i].SetActive(value: true);
|
|
}
|
|
instancesToReenableList.Clear();
|
|
lockInstancesList = false;
|
|
}
|
|
|
|
public static bool SetScoreboardActive(LocalUser localUser, bool isActive, EScoreboardDeactivateReturnContext returnContext, bool shouldForceScoreboardToggle = false)
|
|
{
|
|
if (localUser == null)
|
|
{
|
|
return false;
|
|
}
|
|
CameraRigController cameraRigController = localUser.cameraRigController;
|
|
if (!cameraRigController)
|
|
{
|
|
return false;
|
|
}
|
|
HUD hud = cameraRigController.hud;
|
|
hud.SetScoreboardState(isActive);
|
|
if (isActive)
|
|
{
|
|
hud.shouldForceScoreboardToggle = shouldForceScoreboardToggle;
|
|
hud.scoreboardDeactivateReturnContext = returnContext;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static bool IsScoreboardActive(LocalUser localUser)
|
|
{
|
|
if (localUser == null)
|
|
{
|
|
return false;
|
|
}
|
|
CameraRigController cameraRigController = localUser.cameraRigController;
|
|
if (!cameraRigController)
|
|
{
|
|
return false;
|
|
}
|
|
return cameraRigController.hud.scoreboardPanel.activeSelf;
|
|
}
|
|
|
|
public void OnEnable()
|
|
{
|
|
if (!lockInstancesList)
|
|
{
|
|
instancesList.Add(this);
|
|
UpdateHudVisibility();
|
|
}
|
|
}
|
|
|
|
public void OnDisable()
|
|
{
|
|
if (!lockInstancesList)
|
|
{
|
|
instancesList.Remove(this);
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
eventSystemProvider = GetComponent<MPEventSystemProvider>();
|
|
canvas = GetComponent<Canvas>();
|
|
if ((bool)scoreboardPanel)
|
|
{
|
|
scoreboardPostProcessVolume = scoreboardPanel.GetComponentInChildren<PostProcessVolume>();
|
|
scoreboardPanel.SetActive(value: false);
|
|
}
|
|
mainUIPanel.SetActive(value: false);
|
|
if ((bool)Run.instance)
|
|
{
|
|
gameModeUiInstance = Run.instance.InstantiateUi(gameModeUiRoot);
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if ((bool)Run.instance)
|
|
{
|
|
Run.instance.UnregisterUi(gameModeUiInstance);
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
NetworkUser networkUser = ((!targetMaster) ? null : targetMaster.GetComponent<PlayerCharacterMasterController>()?.networkUser);
|
|
PlayerCharacterMasterController playerCharacterMasterController = (targetMaster ? targetMaster.GetComponent<PlayerCharacterMasterController>() : null);
|
|
Inventory inventory = (targetMaster ? targetMaster.inventory : null);
|
|
GameObject gameObject = targetBodyObject;
|
|
CharacterBody characterBody = (gameObject ? gameObject.GetComponent<CharacterBody>() : null);
|
|
if ((bool)healthBar && (bool)targetBodyObject && gameObject != oldTarget)
|
|
{
|
|
healthBar.source = targetBodyObject.GetComponent<HealthComponent>();
|
|
healthBar.InitializeHealthBar();
|
|
}
|
|
oldTarget = gameObject;
|
|
if ((bool)expBar)
|
|
{
|
|
expBar.source = targetMaster;
|
|
}
|
|
if ((bool)levelText)
|
|
{
|
|
levelText.source = characterBody;
|
|
}
|
|
if ((bool)moneyText)
|
|
{
|
|
moneyText.targetValue = (int)(targetMaster ? targetMaster.money : 0);
|
|
}
|
|
if ((bool)lunarCoinContainer)
|
|
{
|
|
bool flag = localUserViewer != null && localUserViewer.userProfile.totalCollectedCoins != 0;
|
|
uint targetValue = (networkUser ? networkUser.lunarCoins : 0u);
|
|
lunarCoinContainer.SetActive(flag);
|
|
if (flag && (bool)lunarCoinText)
|
|
{
|
|
lunarCoinText.targetValue = (int)targetValue;
|
|
}
|
|
}
|
|
if ((bool)voidCoinContainer)
|
|
{
|
|
int num = (int)(targetMaster ? targetMaster.voidCoins : 0);
|
|
bool flag2 = num > 0;
|
|
voidCoinContainer.SetActive(flag2);
|
|
if (flag2 && (bool)voidCoinText)
|
|
{
|
|
voidCoinText.targetValue = num;
|
|
}
|
|
}
|
|
if ((bool)itemInventoryDisplay)
|
|
{
|
|
itemInventoryDisplay.SetSubscribedInventory(inventory);
|
|
}
|
|
if ((bool)targetBodyObject)
|
|
{
|
|
SkillLocator component = targetBodyObject.GetComponent<SkillLocator>();
|
|
if ((bool)component)
|
|
{
|
|
if (skillIcons.Length != 0 && (bool)skillIcons[0])
|
|
{
|
|
skillIcons[0].targetSkillSlot = SkillSlot.Primary;
|
|
skillIcons[0].targetSkill = component.primary;
|
|
skillIcons[0].playerCharacterMasterController = playerCharacterMasterController;
|
|
}
|
|
if (skillIcons.Length > 1 && (bool)skillIcons[1])
|
|
{
|
|
skillIcons[1].targetSkillSlot = SkillSlot.Secondary;
|
|
skillIcons[1].targetSkill = component.secondary;
|
|
skillIcons[1].playerCharacterMasterController = playerCharacterMasterController;
|
|
}
|
|
if (skillIcons.Length > 2 && (bool)skillIcons[2])
|
|
{
|
|
skillIcons[2].targetSkillSlot = SkillSlot.Utility;
|
|
skillIcons[2].targetSkill = component.utility;
|
|
skillIcons[2].playerCharacterMasterController = playerCharacterMasterController;
|
|
}
|
|
if (skillIcons.Length > 3 && (bool)skillIcons[3])
|
|
{
|
|
skillIcons[3].targetSkillSlot = SkillSlot.Special;
|
|
skillIcons[3].targetSkill = component.special;
|
|
skillIcons[3].playerCharacterMasterController = playerCharacterMasterController;
|
|
}
|
|
}
|
|
}
|
|
EquipmentIcon[] array = equipmentIcons;
|
|
foreach (EquipmentIcon obj in array)
|
|
{
|
|
obj.targetInventory = inventory;
|
|
obj.targetEquipmentSlot = (targetBodyObject ? targetBodyObject.GetComponent<EquipmentSlot>() : null);
|
|
obj.playerCharacterMasterController = (targetMaster ? targetMaster.GetComponent<PlayerCharacterMasterController>() : null);
|
|
}
|
|
if ((bool)buffDisplay)
|
|
{
|
|
buffDisplay.SetSource(characterBody);
|
|
}
|
|
if ((bool)allyCardManager)
|
|
{
|
|
allyCardManager.sourceGameObject = targetBodyObject;
|
|
}
|
|
if ((bool)scoreboardPanel)
|
|
{
|
|
bool flag3 = localUserViewer.userProfile.useToggleScoreboard || shouldForceScoreboardToggle;
|
|
bool flag4 = localUserViewer != null && localUserViewer.inputPlayer != null && localUserViewer.inputPlayer.GetButton("info");
|
|
if (((flag4 && localUserViewer.inputPlayer.GetButtonDown("info")) || !flag3) && (bool)targetBodyObject)
|
|
{
|
|
bool activeSelf = scoreboardPanel.activeSelf;
|
|
bool flag5 = (flag3 ? (!activeSelf) : flag4);
|
|
if (flag5 != activeSelf && !PauseManager.PauseScreenIsOpen())
|
|
{
|
|
SetScoreboardState(flag5);
|
|
}
|
|
}
|
|
}
|
|
if ((bool)speedometer)
|
|
{
|
|
speedometer.targetTransform = (targetBodyObject ? targetBodyObject.transform : null);
|
|
}
|
|
if ((bool)combatHealthBarViewer)
|
|
{
|
|
combatHealthBarViewer.viewerBody = characterBody;
|
|
combatHealthBarViewer.viewerBodyObject = targetBodyObject;
|
|
combatHealthBarViewer.viewerTeamIndex = TeamComponent.GetObjectTeam(targetBodyObject);
|
|
}
|
|
if ((object)targetBodyObject != previousTargetBodyObject)
|
|
{
|
|
previousTargetBodyObject = targetBodyObject;
|
|
HUD.onHudTargetChangedGlobal?.Invoke(this);
|
|
}
|
|
int j = 0;
|
|
for (int num2 = base.transform.childCount - 1; j < num2; j++)
|
|
{
|
|
base.transform.GetChild(j).gameObject.SetActive(value: false);
|
|
}
|
|
if (base.transform.childCount > 0)
|
|
{
|
|
base.transform.GetChild(base.transform.childCount - 1).gameObject.SetActive(value: true);
|
|
}
|
|
UpdateHudVisibility();
|
|
}
|
|
|
|
public void SetScoreboardState(bool newState)
|
|
{
|
|
if (newState != scoreboardPanel.activeSelf)
|
|
{
|
|
if (newState)
|
|
{
|
|
ActivateScoreboard();
|
|
}
|
|
else
|
|
{
|
|
DeactivateScoreboard();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ActivateScoreboard()
|
|
{
|
|
PauseManager.ClosePauseScreen(shouldResume: false);
|
|
scoreboardPanel.SetActive(value: true);
|
|
scoreboardPanel.GetComponent<ScoreboardController>()?.SelectFirstScoreboardStrip();
|
|
if (!localUserViewer.userProfile.useInspectFeature)
|
|
{
|
|
return;
|
|
}
|
|
InteractionDriver component = targetBodyObject.GetComponent<InteractionDriver>();
|
|
if (!(component.currentInteractable != null))
|
|
{
|
|
return;
|
|
}
|
|
IInspectable component2 = component.currentInteractable.GetComponent<IInspectable>();
|
|
if (component2 != null)
|
|
{
|
|
IInspectInfoProvider inspectInfoProvider = component2.GetInspectInfoProvider();
|
|
if (inspectInfoProvider != null && inspectInfoProvider.CanBeInspected())
|
|
{
|
|
inspectPanelController.Show(component2.GetInspectInfoProvider().GetInfo(), WithSidecar: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DeactivateScoreboard()
|
|
{
|
|
scoreboardPanel.SetActive(value: false);
|
|
if (RoR2Application.isInSinglePlayer)
|
|
{
|
|
EScoreboardDeactivateReturnContext eScoreboardDeactivateReturnContext = scoreboardDeactivateReturnContext;
|
|
if (eScoreboardDeactivateReturnContext != 0 && eScoreboardDeactivateReturnContext == EScoreboardDeactivateReturnContext.Pause)
|
|
{
|
|
PauseManager.TogglePauseScreen();
|
|
}
|
|
else
|
|
{
|
|
PauseStopController.instance?.Pause(shouldPause: false);
|
|
}
|
|
}
|
|
else if ((bool)PauseStopController.instance && PauseStopController.instance.isPaused)
|
|
{
|
|
switch (scoreboardDeactivateReturnContext)
|
|
{
|
|
case EScoreboardDeactivateReturnContext.Pause:
|
|
PauseManager.TogglePauseScreen();
|
|
break;
|
|
case EScoreboardDeactivateReturnContext.Game:
|
|
PauseManager.OpenMinimalPauseScreen();
|
|
break;
|
|
}
|
|
}
|
|
scoreboardDeactivateReturnContext = EScoreboardDeactivateReturnContext.Game;
|
|
shouldForceScoreboardToggle = false;
|
|
}
|
|
|
|
private void UpdateHudVisibility()
|
|
{
|
|
if (mainContainer.activeInHierarchy)
|
|
{
|
|
bool shouldDisplay = cameraRigController?.isHudAllowed ?? false;
|
|
HUD.shouldHudDisplay?.Invoke(this, ref shouldDisplay);
|
|
bool flag = cvHudEnable.value && shouldDisplay;
|
|
if (mainUIPanel.activeSelf != flag)
|
|
{
|
|
mainUIPanel.SetActive(flag);
|
|
}
|
|
}
|
|
}
|
|
}
|