Skip to content

Commit

Permalink
Update HealthBars
Browse files Browse the repository at this point in the history
- Can now show all active effects
- Minor code improvements
  • Loading branch information
Lacyway committed Jul 16, 2024
1 parent cc0ed89 commit a7f2432
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 17 deletions.
Binary file modified Fika.Core/Bundles/Files/playerui.bundle
Binary file not shown.
170 changes: 164 additions & 6 deletions Fika.Core/Coop/Custom/FikaHealthBar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
using Comfort.Common;
using EFT;
using EFT.Animations;
using EFT.HealthSystem;
using EFT.UI;
using Fika.Core.Bundles;
using Fika.Core.Coop.Players;
using Fika.Core.Utils;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

Expand All @@ -23,11 +26,15 @@ public class FikaHealthBar : MonoBehaviour
private CoopPlayer mainPlayer;
private PlayerPlateUI playerPlate;
private float screenScale = 1f;
private Dictionary<Type, Sprite> effectIcons;
private List<HealthBarEffect> effects;

protected void Awake()
{
currentPlayer = GetComponent<ObservedCoopPlayer>();
mainPlayer = (CoopPlayer)Singleton<GameWorld>.Instance.MainPlayer;
effectIcons = EFTHardSettings.Instance.StaticIcons.EffectIcons.EffectIcons;
effects = [];
CreateHealthBar();
}

Expand Down Expand Up @@ -172,24 +179,118 @@ private void CreateHealthBar()
SetPlayerPlateHealthVisibility(FikaPlugin.HideHealthBar.Value);
playerPlate.gameObject.SetActive(FikaPlugin.UseNamePlates.Value);

if (FikaPlugin.ShowEffects.Value)
{
currentPlayer.HealthController.EffectAddedEvent += HealthController_EffectAddedEvent;
currentPlayer.HealthController.EffectRemovedEvent += HealthController_EffectRemovedEvent;
}

FikaPlugin.UsePlateFactionSide.SettingChanged += UsePlateFactionSide_SettingChanged;
FikaPlugin.HideHealthBar.SettingChanged += HideHealthBar_SettingChanged;
FikaPlugin.UseNamePlates.SettingChanged += UseNamePlates_SettingChanged;
FikaPlugin.UseHealthNumber.SettingChanged += UseHealthNumber_SettingChanged;
FikaPlugin.ShowEffects.SettingChanged += ShowEffects_SettingChanged;

currentPlayer.HealthController.HealthChangedEvent += HealthController_HealthChangedEvent;
currentPlayer.HealthController.BodyPartDestroyedEvent += HealthController_BodyPartDestroyedEvent;
currentPlayer.HealthController.BodyPartRestoredEvent += HealthController_BodyPartRestoredEvent;
currentPlayer.HealthController.DiedEvent += HealthController_DiedEvent;

playerPlate.SetHealthNumberText("100%");

UpdateHealth();
}

#region events
private void UseHealthNumber_SettingChanged(object sender, EventArgs e)
{
UpdateHealth();
}

private void HealthController_EffectRemovedEvent(IEffect effect)
{
for (int i = 0; i < effects.Count; i++)
{
HealthBarEffect currentEffect = effects[i];
if (currentEffect.effectType == effect.Type)
{
currentEffect.DecreaseAmount();
if (currentEffect.GetAmount() == 0)
{
currentEffect.Remove();
effects.Remove(currentEffect);
}
break;
}
}
}

private void HealthController_EffectAddedEvent(IEffect effect)
{
AddEffect(effect);
}

private void AddEffect(IEffect effect)
{
bool found = false;
foreach (HealthBarEffect currentEffect in effects)
{
if (currentEffect.effectType == effect.Type)
{
currentEffect.IncreaseAmount();
found = true;
}
}

if (found)
{
return;
}

if (effectIcons.TryGetValue(effect.Type, out Sprite effectSprite))
{
GameObject newEffect = Instantiate(playerPlate.EffectImageTemplate, playerPlate.EffectsBackground.transform);
HealthBarEffect healthBarEffect = new();
healthBarEffect.Init(newEffect, effect, effectSprite);
effects.Add(healthBarEffect);
}
}

private void ShowEffects_SettingChanged(object sender, EventArgs e)
{
if (FikaPlugin.ShowEffects.Value)
{
currentPlayer.HealthController.EffectAddedEvent += HealthController_EffectAddedEvent;
currentPlayer.HealthController.EffectRemovedEvent += HealthController_EffectRemovedEvent;

IEnumerable<IEffect> currentEffects = currentPlayer.HealthController.GetAllActiveEffects();
foreach (IEffect effect in currentEffects)
{
AddEffect(effect);
}
}
else
{
currentPlayer.HealthController.EffectAddedEvent -= HealthController_EffectAddedEvent;
currentPlayer.HealthController.EffectRemovedEvent -= HealthController_EffectRemovedEvent;

List<HealthBarEffect> tempList = new(effects);
foreach (HealthBarEffect effect in tempList)
{
effect.Remove();
}
effects.Clear();
tempList.Clear();
tempList = null;
}
}

private void HealthController_DiedEvent(EDamageType obj)
{
Destroy(this);
}

private void HealthController_BodyPartRestoredEvent(EBodyPart arg1, EFT.HealthSystem.ValueStruct arg2)
private void HealthController_BodyPartRestoredEvent(EBodyPart arg1, ValueStruct arg2)
{
UpdateHealth();
}
Expand All @@ -208,6 +309,7 @@ private void UsePlateFactionSide_SettingChanged(object sender, EventArgs e)
{
SetPlayerPlateFactionVisibility(FikaPlugin.UsePlateFactionSide.Value);
}

private void HideHealthBar_SettingChanged(object sender, EventArgs e)
{
SetPlayerPlateHealthVisibility(FikaPlugin.HideHealthBar.Value);
Expand All @@ -216,7 +318,8 @@ private void HideHealthBar_SettingChanged(object sender, EventArgs e)
private void UseNamePlates_SettingChanged(object sender, EventArgs e)
{
playerPlate.gameObject.SetActive(FikaPlugin.UseNamePlates.Value);
}
}
#endregion

/// <summary>
/// Updates the health on the HealthBar, this is invoked from events on the healthcontroller
Expand All @@ -229,8 +332,7 @@ private void UpdateHealth()
{
if (!playerPlate.healthNumberBackgroundScreen.gameObject.activeSelf)
{
playerPlate.healthNumberBackgroundScreen.gameObject.SetActive(true);
playerPlate.healthBarBackgroundScreen.gameObject.SetActive(false);
SetPlayerPlateHealthVisibility(false);
}
int healthNumberPercentage = (int)Math.Round(currentHealth / maxHealth * 100);
playerPlate.SetHealthNumberText($"{healthNumberPercentage}%");
Expand All @@ -239,8 +341,7 @@ private void UpdateHealth()
{
if (!playerPlate.healthBarBackgroundScreen.gameObject.activeSelf)
{
playerPlate.healthNumberBackgroundScreen.gameObject.SetActive(false);
playerPlate.healthBarBackgroundScreen.gameObject.SetActive(true);
SetPlayerPlateHealthVisibility(false);
}

float normalizedHealth = Mathf.Clamp01(currentHealth / maxHealth);
Expand Down Expand Up @@ -302,14 +403,71 @@ protected void OnDestroy()
FikaPlugin.UsePlateFactionSide.SettingChanged -= UsePlateFactionSide_SettingChanged;
FikaPlugin.HideHealthBar.SettingChanged -= HideHealthBar_SettingChanged;
FikaPlugin.UseNamePlates.SettingChanged -= UseNamePlates_SettingChanged;
FikaPlugin.UseHealthNumber.SettingChanged -= UseHealthNumber_SettingChanged;
FikaPlugin.ShowEffects.SettingChanged -= ShowEffects_SettingChanged;

currentPlayer.HealthController.HealthChangedEvent -= HealthController_HealthChangedEvent;
currentPlayer.HealthController.BodyPartDestroyedEvent -= HealthController_BodyPartDestroyedEvent;
currentPlayer.HealthController.BodyPartRestoredEvent -= HealthController_BodyPartRestoredEvent;
currentPlayer.HealthController.DiedEvent -= HealthController_DiedEvent;
currentPlayer.HealthController.EffectAddedEvent -= HealthController_EffectAddedEvent;
currentPlayer.HealthController.EffectRemovedEvent -= HealthController_EffectRemovedEvent;

playerPlate.gameObject.SetActive(false);
Destroy(this);
}

private class HealthBarEffect
{
public Type effectType;
private int amount;
private GameObject effectObject;
private Image effectImage;
private TextMeshProUGUI tmpText;

public void Init(GameObject initObject, IEffect effect, Sprite effectSprite)
{
effectObject = initObject;
effectObject.SetActive(true);
effectImage = effectObject.transform.GetChild(0).GetComponent<Image>();
effectImage.sprite = effectSprite;
tmpText = effectObject.transform.GetChild(1).GetComponent<TextMeshProUGUI>();
amount = 1;
tmpText.text = amount.ToString();
effectType = effect.Type;
}

public void Remove()
{
Destroy(effectImage);
Destroy(tmpText);
Destroy(effectObject);
}

public int GetAmount()
{
return amount;
}

public void IncreaseAmount()
{
amount++;
tmpText.text = amount.ToString();
}

public void DecreaseAmount()
{
amount = Math.Max(0, amount - 1);
if (amount == 0)
{
Remove();
return;
}
else
{
tmpText.text = amount.ToString();
}
}
}
}
}
2 changes: 1 addition & 1 deletion Fika.Core/Coop/Custom/PlayerPlateUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class PlayerPlateUI : MonoBehaviour
[SerializeField]
public GameObject EffectsBackground;
[SerializeField]
public Image EffectImageTemplate;
public GameObject EffectImageTemplate;

public void SetNameText(string text)
{
Expand Down
23 changes: 13 additions & 10 deletions Fika.Core/FikaPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public class FikaPlugin : BaseUnityPlugin
public static ConfigEntry<float> MaxDistanceToShow { get; set; }
public static ConfigEntry<float> MinimumOpacity { get; set; }
public static ConfigEntry<float> MinimumNamePlateScale { get; set; }
public static ConfigEntry<bool> ShowEffects { get; set; }

// Coop | Quest Sharing
public static ConfigEntry<EQuestSharingTypes> QuestTypesToShareAndReceive { get; set; }
Expand Down Expand Up @@ -327,25 +328,27 @@ private void SetupConfig()

HideHealthBar = Config.Bind("Coop | Name Plates", "Hide Health Bar", false, new ConfigDescription("Completely hides the health bar.", tags: new ConfigurationManagerAttributes() { Order = 10 }));

UseHealthNumber = Config.Bind("Coop | Name Plates", "Show HP% instead of bar", false, new ConfigDescription("Shows health in % amount instead of using the bar.", tags: new ConfigurationManagerAttributes() { Order = 9 }));
UseHealthNumber = Config.Bind("Coop | Name Plates", "Show HP% instead of bar", false, new ConfigDescription("Shows health in % amount instead of using the bar.", tags: new ConfigurationManagerAttributes() { Order = 10 }));

UsePlateFactionSide = Config.Bind("Coop | Name Plates", "Show Player Faction Icon", true, new ConfigDescription("Shows the player faction icon next to the HP bar.", tags: new ConfigurationManagerAttributes() { Order = 8 }));
UsePlateFactionSide = Config.Bind("Coop | Name Plates", "Show Player Faction Icon", true, new ConfigDescription("Shows the player faction icon next to the HP bar.", tags: new ConfigurationManagerAttributes() { Order = 9 }));

HideNamePlateInOptic = Config.Bind("Coop | Name Plates", "Hide Name Plate in Optic", true, new ConfigDescription("Hides the name plate when viewing through PiP scopes.", tags: new ConfigurationManagerAttributes() { Order = 7 }));
HideNamePlateInOptic = Config.Bind("Coop | Name Plates", "Hide Name Plate in Optic", true, new ConfigDescription("Hides the name plate when viewing through PiP scopes.", tags: new ConfigurationManagerAttributes() { Order = 8 }));

NamePlateUseOpticZoom = Config.Bind("Coop | Name Plates", "Name Plates Use Optic Zoom", true, new ConfigDescription("If name plate location should be displayed using the PiP optic camera.", tags: new ConfigurationManagerAttributes() { Order = 6, IsAdvanced = true }));
NamePlateUseOpticZoom = Config.Bind("Coop | Name Plates", "Name Plates Use Optic Zoom", true, new ConfigDescription("If name plate location should be displayed using the PiP optic camera.", tags: new ConfigurationManagerAttributes() { Order = 7, IsAdvanced = true }));

DecreaseOpacityNotLookingAt = Config.Bind("Coop | Name Plates", "Decrease Opacity In Peripheral", true, new ConfigDescription("Decreases the opacity of the name plates when not looking at a player.", tags: new ConfigurationManagerAttributes() { Order = 5 }));
DecreaseOpacityNotLookingAt = Config.Bind("Coop | Name Plates", "Decrease Opacity In Peripheral", true, new ConfigDescription("Decreases the opacity of the name plates when not looking at a player.", tags: new ConfigurationManagerAttributes() { Order = 6 }));

NamePlateScale = Config.Bind("Coop | Name Plates", "Name Plate Scale", 0.22f, new ConfigDescription("Size of the name plates", new AcceptableValueRange<float>(0.05f, 1f), new ConfigurationManagerAttributes() { Order = 4 }));
NamePlateScale = Config.Bind("Coop | Name Plates", "Name Plate Scale", 0.22f, new ConfigDescription("Size of the name plates", new AcceptableValueRange<float>(0.05f, 1f), new ConfigurationManagerAttributes() { Order = 5 }));

OpacityInADS = Config.Bind("Coop | Name Plates", "Opacity in ADS", 0.75f, new ConfigDescription("The opacity of the name plates when aiming down sights.", new AcceptableValueRange<float>(0.1f, 1f), new ConfigurationManagerAttributes() { Order = 3 }));
OpacityInADS = Config.Bind("Coop | Name Plates", "Opacity in ADS", 0.75f, new ConfigDescription("The opacity of the name plates when aiming down sights.", new AcceptableValueRange<float>(0.1f, 1f), new ConfigurationManagerAttributes() { Order = 4 }));

MaxDistanceToShow = Config.Bind("Coop | Name Plates", "Max Distance to Show", 500f, new ConfigDescription("The maximum distance at which name plates will become invisible, starts to fade at half the input value.", new AcceptableValueRange<float>(10f, 1000f), new ConfigurationManagerAttributes() { Order = 2 }));
MaxDistanceToShow = Config.Bind("Coop | Name Plates", "Max Distance to Show", 500f, new ConfigDescription("The maximum distance at which name plates will become invisible, starts to fade at half the input value.", new AcceptableValueRange<float>(10f, 1000f), new ConfigurationManagerAttributes() { Order = 3 }));

MinimumOpacity = Config.Bind("Coop | Name Plates", "Minimum Opacity", 0.1f, new ConfigDescription("The minimum opacity of the name plates.", new AcceptableValueRange<float>(0.0f, 1f), new ConfigurationManagerAttributes() { Order = 1 }));
MinimumOpacity = Config.Bind("Coop | Name Plates", "Minimum Opacity", 0.1f, new ConfigDescription("The minimum opacity of the name plates.", new AcceptableValueRange<float>(0.0f, 1f), new ConfigurationManagerAttributes() { Order = 2 }));

MinimumNamePlateScale = Config.Bind("Coop | Name Plates", "Minimum Name Plate Scale", 0.01f, new ConfigDescription("The minimum scale of the name plates.", new AcceptableValueRange<float>(0.0f, 1f), new ConfigurationManagerAttributes() { Order = 0 }));
MinimumNamePlateScale = Config.Bind("Coop | Name Plates", "Minimum Name Plate Scale", 0.01f, new ConfigDescription("The minimum scale of the name plates.", new AcceptableValueRange<float>(0.0f, 1f), new ConfigurationManagerAttributes() { Order = 1 }));

ShowEffects = Config.Bind("Coop | Name Plates", "Show Effects", true, new ConfigDescription("If status effects should be display below the health bar.", tags: new ConfigurationManagerAttributes() { Order = 0 }));

// Coop | Quest Sharing

Expand Down

0 comments on commit a7f2432

Please sign in to comment.