private void UpdateOnTargetChange() { var target = m_LinkedCharacter.TargetingSystem.LockedCharacter; m_infoboxName.text = target.Name; // only update status immunities when we change targets. List <string> immunityTags = new List <string>(); var statusNaturalImmunities = At.GetValue(typeof(CharacterStats), target.Stats, "m_statusEffectsNaturalImmunity") as TagSourceSelector[]; foreach (TagSourceSelector tagSelector in statusNaturalImmunities) { immunityTags.Add(tagSelector.Tag.TagName); } var statusImmunities = At.GetValue(typeof(CharacterStats), target.Stats, "m_statusEffectsImmunity") as Dictionary <Tag, List <string> >; foreach (KeyValuePair <Tag, List <string> > entry in statusImmunities) { if (entry.Value.Count > 0) { immunityTags.Add(entry.Key.TagName); } } if (immunityTags.Count > 0) { m_infoboxNoImmuneText.gameObject.SetActive(false); float offset = 0f; var pos = m_infoboxNoImmuneText.rectTransform.position; if (immunityTags.Contains("Bleeding")) { m_infoboxBleedingSprite.gameObject.SetActive(true); m_infoboxBleedingSprite.rectTransform.position = new Vector3(pos.x, pos.y - 2f, 0); offset += CombatHUD.Rel(22f); } else { m_infoboxBleedingSprite.gameObject.SetActive(false); } if (immunityTags.Contains("Burning")) { m_infoboxBurningSprite.gameObject.SetActive(true); m_infoboxBurningSprite.rectTransform.position = new Vector3(pos.x + offset, pos.y - 2f, 0); offset += CombatHUD.Rel(22f); } else { m_infoboxBurningSprite.gameObject.SetActive(false); } if (immunityTags.Contains("Poison")) { m_infoboxPoisonSprite.gameObject.SetActive(true); m_infoboxPoisonSprite.rectTransform.position = new Vector3(pos.x + offset, pos.y - 2f, 0); } else { m_infoboxPoisonSprite.gameObject.SetActive(false); } } else { m_infoboxNoImmuneText.gameObject.SetActive(true); m_infoboxBurningSprite.gameObject.SetActive(false); m_infoboxBleedingSprite.gameObject.SetActive(false); m_infoboxPoisonSprite.gameObject.SetActive(false); } }
private void UpdateStatuses(Character target) { // update status icons float offset = 0f; float offsetInterval = CombatHUD.Rel(30f, true); var barPos = RectTransformUtility.WorldToScreenPoint(m_LinkedCharacter.CharacterCamera.CameraScript, target.UIBarPosition); var pos = barPos + new Vector2(CombatHUD.Rel(225f), 0); for (int i = 0; i < m_StatusHolder.transform.childCount; i++) { var obj = m_StatusHolder.transform.GetChild(i).gameObject; string identifier = obj.name; var status = target.StatusEffectMngr.Statuses.Find(x => x.IdentifierName == identifier); if (!status) { obj.SetActive(false); } else { var parentRect = obj.GetComponent <RectTransform>(); parentRect.position = new Vector3(pos.x, pos.y + offset); var text = parentRect.transform.Find("Text").GetComponent <Text>(); if ((bool)CombatHUD.config.GetValue(Settings.EnemyStatusTimers)) { TimeSpan t = TimeSpan.FromSeconds(status.RemainingLifespan); var s = string.Format("{0}:{1}", t.Minutes, t.Seconds.ToString("00")); text.text = s; text.color = Color.white; if (!text.gameObject.activeSelf) { text.gameObject.SetActive(true); } if (!obj.activeSelf) { obj.SetActive(true); } offset -= offsetInterval; } else if (text.gameObject.activeSelf) { text.gameObject.SetActive(false); } } } // buildups if ((bool)CombatHUD.config.GetValue(Settings.EnemyBuildup)) { var m_statusBuildup = At.GetValue(typeof(StatusEffectManager), target.StatusEffectMngr, "m_statusBuildUp") as IDictionary; IDictionary dict = m_statusBuildup as IDictionary; FieldInfo buildupField = m_statusBuildup.GetType().GetGenericArguments()[1].GetField("BuildUp"); foreach (string name in dict.Keys) { //GameObject holder = null; if (m_StatusHolder.transform.Find(name) is Transform t) { var holder = t.gameObject; if (holder.activeSelf) { // status is already active (ie. its 100%) continue; } float value = (float)buildupField.GetValue(dict[name]); if (value > 0 && value < 100) { var parentRect = holder.GetComponent <RectTransform>(); parentRect.position = new Vector3(pos.x, pos.y + offset); offset -= offsetInterval; var text = holder.GetComponentInChildren <Text>(); text.text = Math.Round(value) + "%"; text.color = new Color(1.0f, 0.5f, 0.5f, value * 0.01f + 0.25f); if (!holder.activeSelf) { holder.SetActive(true); } } } } } }
private void UpdatePlayerStatuses(int splitID, ref List <StatusEffectInfo> statusInfos) { var player = SplitScreenManager.Instance.LocalPlayers[splitID]; if (player == null || !player.AssignedCharacter) { return; } var effectsManager = player.AssignedCharacter.StatusEffectMngr; var panel = player.CharUI.GetComponentInChildren <StatusEffectPanel>(); if (!panel || !effectsManager) { Debug.LogError("Could not find status effect managers for " + player.AssignedCharacter.Name); return; } var activeIcons = At.GetField(panel, "m_statusIcons") as Dictionary <string, StatusEffectIcon>; foreach (var entry in activeIcons) { if (!entry.Value.gameObject.activeSelf) { continue; } float remainingLifespan = 0f; StatusEffect status = effectsManager.Statuses.Find((s => s.IdentifierName == entry.Key)); if (status) { remainingLifespan = status.RemainingLifespan; } else { // some statuses use an identifier tag instead of their own status name for the icon... switch (entry.Key.ToLower()) { case "imbuemainweapon": remainingLifespan = panel.LocalCharacter.CurrentWeapon.FirstImbue.RemainingLifespan; break; case "imbueoffweapon": remainingLifespan = panel.LocalCharacter.LeftHandWeapon.FirstImbue.RemainingLifespan; break; case "summonweapon": remainingLifespan = panel.LocalCharacter.CurrentWeapon.SummonedEquipment.RemainingLifespan; break; case "summonghost": remainingLifespan = panel.LocalCharacter.CurrentSummon.RemainingLifespan; break; case "129": // marsh poison uses "129" for its tag, I think that's its effect preset ID? if (effectsManager.Statuses.Find((it => it.IdentifierName.Equals("Hallowed Marsh Poison Lvl1"))) is StatusEffect marshpoison) { remainingLifespan = marshpoison.RemainingLifespan; } break; default: //Debug.Log("[CombatHUD] Unhandled Status Identifier! Key: " + entry.Key); continue; } } if (remainingLifespan > 0f && entry.Value) { statusInfos.Add(new StatusEffectInfo { TimeRemaining = remainingLifespan, LinkedIcon = entry.Value }); } } }
internal void Update() { //cleanup dead labels first var maxLifespan = (float)CombatHUD.config.GetValue(Settings.LabelLifespan); for (int z = 0; z < ActiveLabels.Count; z++) { if (Time.time - ActiveLabels[z].CreationTime > maxLifespan || !ActiveLabels[z].Target) { ActiveLabels.RemoveAt(z); z--; } } float ceiling = (float)CombatHUD.config.GetValue(Settings.DamageCeiling); int minsize = (int)(float)CombatHUD.config.GetValue(Settings.MinFontSize); int maxsize = (int)(float)CombatHUD.config.GetValue(Settings.MaxFontSize); if (maxsize < minsize) { maxsize = minsize; } var m_hideUI = (bool)At.GetValue(typeof(Global), Global.Instance, "m_hideUI"); var m_playerShowHUD = (bool[])At.GetValue(typeof(OptionManager), null, "m_playerShowHUD"); for (int i = 0; i < SplitScreenManager.Instance.LocalPlayerCount; i++) { var player = SplitScreenManager.Instance.LocalPlayers[i]; if (!player.AssignedCharacter) { continue; } // dont show damage labels if player is in menu bool disable = false; if (m_hideUI || !m_playerShowHUD[i] || MenuManager.Instance.IsMapDisplayed || (player.AssignedCharacter.CharacterUI.GetCurrentMenu() is MenuPanel panel && panel.IsDisplayed)) { disable = true; } var camera = player.CameraScript; int offset = i * 30; for (int j = 0 + offset; j < LabelHolders.Count; j++) { if (disable || j - offset >= ActiveLabels.Count) { if (LabelHolders[j].activeSelf) { LabelHolders[j].SetActive(false); } } else { var labelInfo = ActiveLabels[j - offset]; var labelHolder = LabelHolders[j]; var pos = (bool)CombatHUD.config.GetValue(Settings.LabelsStayAtHitPos) ? labelInfo.HitWorldPos : labelInfo.Target.CenterPosition; float damageStrength = (float)((decimal)labelInfo.Damage / (decimal)ceiling); // set damage "strength" float time = Time.time - labelInfo.CreationTime; var timeOffset = Mathf.Lerp(0.3f, 0.07f, damageStrength) * time; var screenPos = camera.WorldToViewportPoint(pos + new Vector3(0, timeOffset)); float distance = Vector3.Distance(player.AssignedCharacter.transform.position, pos); if (IsScreenPosVisible(ref screenPos, i) && distance < (float)CombatHUD.config.GetValue(Settings.MaxDistance)) { screenPos += new Vector3 ( CombatHUD.Rel(labelInfo.ranXpos), CombatHUD.Rel(labelInfo.ranYpos, true) ); labelHolder.GetComponent <RectTransform>().position = screenPos; var text = labelHolder.GetComponent <Text>(); text.text = Math.Round(labelInfo.Damage).ToString(); text.fontSize = (int)Mathf.Lerp(minsize, maxsize, damageStrength); text.color = labelInfo.TextColor; if (!LabelHolders[j].activeSelf) { LabelHolders[j].SetActive(true); } } else if (LabelHolders[j].activeSelf) { LabelHolders[j].SetActive(false); } } } } }
private void UpdateStatuses(Character target) { // update status icons float offset = 0f; float offsetInterval = CombatHUD.Rel(30f, true); var barPos = RectTransformUtility.WorldToScreenPoint(m_LinkedCharacter.CharacterCamera.CameraScript, target.UIBarPosition); var pos = barPos + new Vector2(CombatHUD.Rel(225f), 0); var statuses = target.StatusEffectMngr.Statuses; // Key: Status Identifier, float: Buildup / opacity var displayDict = new Dictionary <string, float>(); foreach (var status in statuses) { if (!displayDict.ContainsKey(status.IdentifierName)) { displayDict.Add(status.IdentifierName, 100f); } } if (HUDConfig.Enemy_StatusBuildup.Value) { var buildupDict = (IDictionary)At.GetField(target.StatusEffectMngr, "m_statusBuildUp"); foreach (string name in buildupDict.Keys) { if (displayDict.ContainsKey(name) || buildupDict[name] == null) { continue; } if (s_buildupField == null) { s_buildupField = buildupDict[name].GetType().GetField("BuildUp"); } float value = (float)s_buildupField.GetValue(buildupDict[name]); if (value > 0 && value < 100) { displayDict.Add(name, value); } } } for (int i = 0; i < m_statusHolder.transform.childCount; i++) { var holder = m_statusHolder.transform.GetChild(i); if (i >= displayDict.Count) { if (holder.gameObject.activeSelf) { holder.gameObject.SetActive(false); } } else { var entry = displayDict.ElementAt(i); if (!s_statusIcons.ContainsKey(entry.Key)) { var status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(entry.Key); if (!status) { s_statusIcons.Add(entry.Key, null); continue; } var icon = status.OverrideIcon ?? status.StatusIcon; s_statusIcons.Add(entry.Key, icon); } var sprite = s_statusIcons[entry.Key]; if (!sprite) { continue; } if (s_cachedImages == null) { s_cachedImages = new Image[m_statusHolder.transform.childCount]; for (int j = 0; j < m_statusHolder.transform.childCount; j++) { s_cachedImages[j] = m_statusHolder.transform.GetChild(j).Find("Image").GetComponent <Image>(); } } if (s_cachedImages[i].sprite != sprite) { s_cachedImages[i].sprite = sprite; } holder.position = new Vector3(pos.x, pos.y + offset); var text = holder.Find("Text").GetComponent <Text>(); if (!holder.gameObject.activeSelf) { holder.gameObject.SetActive(true); } if (displayDict[entry.Key] >= 100f) { if (HUDConfig.Enemy_StatusTimers.Value) { var status = statuses.Find(it => it.IdentifierName == entry.Key); TimeSpan t = TimeSpan.FromSeconds(status.RemainingLifespan); var s = $"{t.Minutes}:{t.Seconds:00}"; text.text = s; text.color = Color.white; if (!text.gameObject.activeSelf) { text.gameObject.SetActive(true); } offset -= offsetInterval; } else if (text.gameObject.activeSelf) { text.gameObject.SetActive(false); } } else { var parentRect = holder.GetComponent <RectTransform>(); parentRect.position = new Vector3(pos.x, pos.y + offset); offset -= offsetInterval; var buildupTxt = holder.GetComponentInChildren <Text>(); buildupTxt.text = Math.Round(displayDict[entry.Key]) + "%"; buildupTxt.color = new Color(1.0f, 0.5f, 0.5f, displayDict[entry.Key] * 0.01f + 0.25f); if (!text.gameObject.activeSelf) { text.gameObject.SetActive(true); } } } } }
internal void Update() { if (NetworkLevelLoader.Instance.IsGameplayLoading || NetworkLevelLoader.Instance.IsGameplayPaused) { if (!wasInMenu) { for (int i = 0; i < m_labelHolders.Count; i++) { if (m_labelHolders[i].activeSelf) { m_labelHolders[i].SetActive(false); } } wasInMenu = true; } return; } wasInMenu = false; List <StatusEffectInfo> statusInfos = new List <StatusEffectInfo>(); var m_hideUI = (bool)At.GetValue(typeof(Global), Global.Instance, "m_hideUI"); var m_playerShowHUD = (bool[])At.GetValue(typeof(OptionManager), null, "m_playerShowHUD"); for (int i = 0; i < SplitScreenManager.Instance.LocalPlayers.Count; i++) { var player = SplitScreenManager.Instance.LocalPlayers[i].AssignedCharacter; if (player == null || !m_playerShowHUD[i] || m_hideUI) { continue; } UpdateVitalText(player); if ((bool)CombatHUD.config.GetValue(Settings.PlayerStatusTimers)) { try { UpdatePlayerStatuses(i, ref statusInfos); } catch //(Exception e) { //Debug.LogError("Error updating statuses: " + e.Message); } } } // update text holders for (int i = 0; i < m_labelHolders.Count; i++) { if (i >= statusInfos.Count || !(bool)CombatHUD.config.GetValue(Settings.PlayerStatusTimers)) { if (m_labelHolders[i].activeSelf) { m_labelHolders[i].SetActive(false); } } else { var text = m_labelHolders[i].GetComponent <Text>(); var iconRect = statusInfos[i].LinkedIcon.RectTransform; var posOffset = new Vector3(0, CombatHUD.Rel(25f, true), 0); text.GetComponent <RectTransform>().position = iconRect.position + posOffset; TimeSpan t = TimeSpan.FromSeconds(statusInfos[i].TimeRemaining); text.text = t.Minutes + ":" + t.Seconds.ToString("00"); if (statusInfos[i].TimeRemaining < 15) { text.color = Color.red; } else { text.color = Color.white; } if (!m_labelHolders[i].activeSelf) { m_labelHolders[i].SetActive(true); } } } }