static bool Prefix(CombatHUDStatusPanel __instance, AbstractActor actor, AbilityDef.SpecialRules specialRulesFilter, Vector3 worldPos, Dictionary <string, CombatHUDStatusIndicator> ___effectDict) { Mod.Log.Debug?.Write($"Updating StatusEffect Panel for actor: {CombatantUtils.Label(actor)}"); try { List <EffectData> effectsOnActor = new List <EffectData>(); foreach (Effect effect in ModState.Combat.EffectManager.GetAllEffectsTargeting(actor)) { if (effect == null || effect.EffectData == null) { Mod.Log.Warn?.Write($"Effect with id: {effect?.id} has no effectData! Effect is from creatorGUID: {effect?.creatorGUID} creatorID: {effect?.creatorID} " + $"with targetId: {effect?.targetID}"); continue; } if (effect.EffectData.targetingData.specialRules != AbilityDef.SpecialRules.Aura && (effect.EffectData.targetingData.effectTriggerType != EffectTriggerType.OnDamaged || effect.triggerCount != 0) ) { Mod.Log.Debug?.Write($"Adding effectId: {effect?.EffectData?.Description?.Id} with name: {effect?.EffectData?.Description?.Name}"); effectsOnActor.Add(effect.EffectData); } } if (specialRulesFilter == AbilityDef.SpecialRules.Aura) { if (actor.AuraCache == null) { Mod.Log.Warn?.Write($"Actor: {CombatantUtils.Label(actor)} has a null aura cache. This should not happen!"); } else { Dictionary <string, List <EffectData> > dictionary = actor.AuraCache.PreviewAurasAffectingMe(actor, worldPos, null); foreach (string key in dictionary.Keys) { List <EffectData> collection = dictionary[key]; Mod.Log.Debug?.Write("Adding collection from aura."); effectsOnActor.AddRange(collection); } } } Traverse shouldShowEffectT = Traverse.Create(__instance).Method("ShouldShowEffect", new Type[] { typeof(EffectData), typeof(AbilityDef.SpecialRules) }); Traverse showDebuffT = Traverse.Create(__instance).Method("ShowBuff", new Type[] { typeof(string), typeof(Text), typeof(Text), typeof(Vector3), typeof(bool) }); Traverse showBuffT = Traverse.Create(__instance).Method("ShowDebuff", new Type[] { typeof(string), typeof(Text), typeof(Text), typeof(Vector3), typeof(bool) }); if (shouldShowEffectT == null || showDebuffT == null || showBuffT == null) { Mod.Log.Error?.Write("Failed to traverse necessary methods! Notify FrostRaptor - this should not happen!"); return(false); } ___effectDict.Clear(); for (int i = 0; i < effectsOnActor.Count; i++) { EffectData effectData = effectsOnActor[i]; if (effectData == null || effectData.Description == null || effectData.Description.Id == null || effectData.Description.Name == null) { Mod.Log.Error?.Write($"EffectData {effectData?.Description?.Name} has no description, id, or name! Cannot process, skipping!"); continue; } if (string.IsNullOrEmpty(effectData?.Description?.Icon)) { continue; // No icon to display, skip. } bool shouldShowEffect = shouldShowEffectT.GetValue <bool>(new object[] { effectData, specialRulesFilter }); bool alreadyShown = ___effectDict.ContainsKey(effectData.Description.Id); Mod.Log.Debug?.Write($" -- Effect with name: {effectData?.Description?.Name} and Id: {effectData?.Description?.Id} has shouldShowEffect: {shouldShowEffect} and alreadyShown: {alreadyShown}"); string effectId = effectData.Description.Id; if (shouldShowEffect && !alreadyShown) { Mod.Log.Debug?.Write($" -- Adding effect with name: {effectData?.Description?.Name} and Id: {effectData?.Description?.Id} to buff list."); int num = effectsOnActor.FindAll((EffectData x) => x.Description.Id == effectId).Count; if (effectData.statisticData != null && effectData.statisticData.targetCollection == StatisticEffectData.TargetCollection.Weapon && effectData.statisticData.targetWeaponSubType != WeaponSubType.Melee) { num = ((num > 1) ? (num / actor.Weapons.Count) : num); } Text text = CombatHUDStatusPanel.ProcessDetailString(effectData, (num > 0) ? num : 1); CombatHUDStatusIndicator combatHUDStatusIndicator; if (effectsOnActor[i].nature == EffectNature.Debuff) { combatHUDStatusIndicator = showDebuffT.GetValue <CombatHUDStatusIndicator>(new object[] { effectData.Description.Icon, new Text(effectData.Description.Name, Array.Empty <object>()), text, __instance.effectIconScale, false }); } else { combatHUDStatusIndicator = showBuffT.GetValue <CombatHUDStatusIndicator>(new object[] { effectData.Description.Icon, new Text(effectData.Description.Name, Array.Empty <object>()), text, __instance.effectIconScale, false }); } if (combatHUDStatusIndicator != null) { combatHUDStatusIndicator.AddTooltipString(text, effectsOnActor[i].nature); ___effectDict[effectId] = combatHUDStatusIndicator; } } } } catch (Exception e) { Mod.Log.Error?.Write(e, $"Failed to log status effects for actor: {CombatantUtils.Label(actor)} at position: {worldPos}"); } return(false); }