| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- using System.Linq;
- using Content.Shared.Damage;
- using Content.Shared.Damage.Prototypes;
- using Content.Shared.FixedPoint;
- using Robust.Client.GameObjects;
- using Robust.Shared.Prototypes;
- using Robust.Shared.Utility;
- namespace Content.Client.Damage;
- /// <summary>
- /// A simple visualizer for any entity with a DamageableComponent
- /// to display the status of how damaged it is.
- ///
- /// Can either be an overlay for an entity, or target multiple
- /// layers on the same entity.
- ///
- /// This can be disabled dynamically by passing into SetData,
- /// key DamageVisualizerKeys.Disabled, value bool
- /// (DamageVisualizerKeys lives in Content.Shared.Damage)
- ///
- /// Damage layers, if targeting layers, can also be dynamically
- /// disabled if needed by passing into SetData, the name/enum
- /// of the sprite layer, and then passing in a bool value
- /// (true to enable, false to disable).
- /// </summary>
- public sealed class DamageVisualsSystem : VisualizerSystem<DamageVisualsComponent>
- {
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<DamageVisualsComponent, ComponentInit>(InitializeEntity);
- }
- private void InitializeEntity(EntityUid entity, DamageVisualsComponent comp, ComponentInit args)
- {
- VerifyVisualizerSetup(entity, comp);
- if (!comp.Valid)
- {
- RemCompDeferred<DamageVisualsComponent>(entity);
- return;
- }
- InitializeVisualizer(entity, comp);
- }
- private void VerifyVisualizerSetup(EntityUid entity, DamageVisualsComponent damageVisComp)
- {
- if (damageVisComp.Thresholds.Count < 1)
- {
- Log.Error($"ThresholdsLookup were invalid for entity {entity}. ThresholdsLookup: {damageVisComp.Thresholds}");
- damageVisComp.Valid = false;
- return;
- }
- if (damageVisComp.Divisor == 0)
- {
- Log.Error($"Divisor for {entity} is set to zero.");
- damageVisComp.Valid = false;
- return;
- }
- if (damageVisComp.Overlay)
- {
- if (damageVisComp.DamageOverlayGroups == null && damageVisComp.DamageOverlay == null)
- {
- Log.Error($"Enabled overlay without defined damage overlay sprites on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- if (damageVisComp.TrackAllDamage && damageVisComp.DamageOverlay == null)
- {
- Log.Error($"Enabled all damage tracking without a damage overlay sprite on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- if (!damageVisComp.TrackAllDamage && damageVisComp.DamageOverlay != null)
- {
- Log.Warning($"Disabled all damage tracking with a damage overlay sprite on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- if (damageVisComp.TrackAllDamage && damageVisComp.DamageOverlayGroups != null)
- {
- Log.Warning($"Enabled all damage tracking with damage overlay groups on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- }
- else if (!damageVisComp.Overlay)
- {
- if (damageVisComp.TargetLayers == null)
- {
- Log.Error($"Disabled overlay without target layers on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- if (damageVisComp.DamageOverlayGroups != null || damageVisComp.DamageOverlay != null)
- {
- Log.Error($"Disabled overlay with defined damage overlay sprites on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- if (damageVisComp.DamageGroup == null)
- {
- Log.Error($"Disabled overlay without defined damage group on {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- }
- if (damageVisComp.DamageOverlayGroups != null && damageVisComp.DamageGroup != null)
- {
- Log.Warning($"Damage overlay sprites and damage group are both defined on {entity}.");
- }
- if (damageVisComp.DamageOverlay != null && damageVisComp.DamageGroup != null)
- {
- Log.Warning($"Damage overlay sprites and damage group are both defined on {entity}.");
- }
- }
- private void InitializeVisualizer(EntityUid entity, DamageVisualsComponent damageVisComp)
- {
- if (!TryComp(entity, out SpriteComponent? spriteComponent)
- || !TryComp<DamageableComponent>(entity, out var damageComponent)
- || !HasComp<AppearanceComponent>(entity))
- return;
- damageVisComp.Thresholds.Add(FixedPoint2.Zero);
- damageVisComp.Thresholds.Sort();
- if (damageVisComp.Thresholds[0] != 0)
- {
- Log.Error($"ThresholdsLookup were invalid for entity {entity}. ThresholdsLookup: {damageVisComp.Thresholds}");
- damageVisComp.Valid = false;
- return;
- }
- // If the damage container on our entity's DamageableComponent
- // is not null, we can try to check through its groups.
- if (damageComponent.DamageContainerID != null
- && _prototypeManager.TryIndex<DamageContainerPrototype>(damageComponent.DamageContainerID, out var damageContainer))
- {
- // Are we using damage overlay sprites by group?
- // Check if the container matches the supported groups,
- // and start caching the last threshold.
- if (damageVisComp.DamageOverlayGroups != null)
- {
- foreach (var damageType in damageVisComp.DamageOverlayGroups.Keys)
- {
- if (!damageContainer.SupportedGroups.Contains(damageType))
- {
- Log.Error($"Damage key {damageType} was invalid for entity {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- damageVisComp.LastThresholdPerGroup.Add(damageType, FixedPoint2.Zero);
- }
- }
- // Are we tracking a single damage group without overlay instead?
- // See if that group is in our entity's damage container.
- else if (!damageVisComp.Overlay && damageVisComp.DamageGroup != null)
- {
- if (!damageContainer.SupportedGroups.Contains(damageVisComp.DamageGroup))
- {
- Log.Error($"Damage keys were invalid for entity {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- damageVisComp.LastThresholdPerGroup.Add(damageVisComp.DamageGroup, FixedPoint2.Zero);
- }
- }
- // Ditto above, but instead we go through every group.
- else // oh boy! time to enumerate through every single group!
- {
- var damagePrototypeIdList = _prototypeManager.EnumeratePrototypes<DamageGroupPrototype>()
- .Select((p, _) => p.ID)
- .ToList();
- if (damageVisComp.DamageOverlayGroups != null)
- {
- foreach (var damageType in damageVisComp.DamageOverlayGroups.Keys)
- {
- if (!damagePrototypeIdList.Contains(damageType))
- {
- Log.Error($"Damage keys were invalid for entity {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- damageVisComp.LastThresholdPerGroup.Add(damageType, FixedPoint2.Zero);
- }
- }
- else if (damageVisComp.DamageGroup != null)
- {
- if (!damagePrototypeIdList.Contains(damageVisComp.DamageGroup))
- {
- Log.Error($"Damage keys were invalid for entity {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- damageVisComp.LastThresholdPerGroup.Add(damageVisComp.DamageGroup, FixedPoint2.Zero);
- }
- }
- // If we're targeting any layers, and the amount of
- // layers is greater than zero, we start reserving
- // all the layers needed to track damage groups
- // on the entity.
- if (damageVisComp.TargetLayers is { Count: > 0 })
- {
- // This should ensure that the layers we're targeting
- // are valid for the visualizer's use.
- //
- // If the layer doesn't have a base state, or
- // the layer key just doesn't exist, we skip it.
- foreach (var key in damageVisComp.TargetLayers)
- {
- if (!spriteComponent.LayerMapTryGet(key, out var index))
- {
- Log.Warning($"Layer at key {key} was invalid for entity {entity}.");
- continue;
- }
- damageVisComp.TargetLayerMapKeys.Add(key);
- }
- // Similar to damage overlay groups, if none of the targeted
- // sprite layers could be used, we display an error and
- // invalidate the visualizer without crashing.
- if (damageVisComp.TargetLayerMapKeys.Count == 0)
- {
- Log.Error($"Target layers were invalid for entity {entity}.");
- damageVisComp.Valid = false;
- return;
- }
- // Otherwise, we start reserving layers. Since the filtering
- // loop above ensures that all of these layers are not null,
- // and have valid state IDs, there should be no issues.
- foreach (var layer in damageVisComp.TargetLayerMapKeys)
- {
- var layerCount = spriteComponent.AllLayers.Count();
- var index = spriteComponent.LayerMapGet(layer);
- // var layerState = spriteComponent.LayerGetState(index).ToString()!;
- if (index + 1 != layerCount)
- {
- index += 1;
- }
- damageVisComp.LayerMapKeyStates.Add(layer, layer.ToString());
- // If we're an overlay, and we're targeting groups,
- // we reserve layers per damage group.
- if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
- {
- foreach (var (group, sprite) in damageVisComp.DamageOverlayGroups)
- {
- AddDamageLayerToSprite(spriteComponent,
- sprite,
- $"{layer}_{group}_{damageVisComp.Thresholds[1]}",
- $"{layer}{group}",
- index);
- }
- damageVisComp.DisabledLayers.Add(layer, false);
- }
- // If we're not targeting groups, and we're still
- // using an overlay, we instead just add a general
- // overlay that reflects on how much damage
- // was taken.
- else if (damageVisComp.DamageOverlay != null)
- {
- AddDamageLayerToSprite(spriteComponent,
- damageVisComp.DamageOverlay,
- $"{layer}_{damageVisComp.Thresholds[1]}",
- $"{layer}trackDamage",
- index);
- damageVisComp.DisabledLayers.Add(layer, false);
- }
- }
- }
- // If we're not targeting layers, however,
- // we should ensure that we instead
- // reserve it as an overlay.
- else
- {
- if (damageVisComp.DamageOverlayGroups != null)
- {
- foreach (var (group, sprite) in damageVisComp.DamageOverlayGroups)
- {
- AddDamageLayerToSprite(spriteComponent,
- sprite,
- $"DamageOverlay_{group}_{damageVisComp.Thresholds[1]}",
- $"DamageOverlay{group}");
- damageVisComp.TopMostLayerKey = $"DamageOverlay{group}";
- }
- }
- else if (damageVisComp.DamageOverlay != null)
- {
- AddDamageLayerToSprite(spriteComponent,
- damageVisComp.DamageOverlay,
- $"DamageOverlay_{damageVisComp.Thresholds[1]}",
- "DamageOverlay");
- damageVisComp.TopMostLayerKey = $"DamageOverlay";
- }
- }
- }
- /// <summary>
- /// Adds a damage tracking layer to a given sprite component.
- /// </summary>
- private void AddDamageLayerToSprite(SpriteComponent spriteComponent, DamageVisualizerSprite sprite, string state, string mapKey, int? index = null)
- {
- var newLayer = spriteComponent.AddLayer(
- new SpriteSpecifier.Rsi(
- new (sprite.Sprite), state
- ), index);
- spriteComponent.LayerMapSet(mapKey, newLayer);
- if (sprite.Color != null)
- spriteComponent.LayerSetColor(newLayer, Color.FromHex(sprite.Color));
- spriteComponent.LayerSetVisible(newLayer, false);
- }
- protected override void OnAppearanceChange(EntityUid uid, DamageVisualsComponent damageVisComp, ref AppearanceChangeEvent args)
- {
- // how is this still here?
- if (!damageVisComp.Valid)
- return;
- // If this was passed into the component, we update
- // the data to ensure that the current disabled
- // bool matches.
- if (AppearanceSystem.TryGetData<bool>(uid, DamageVisualizerKeys.Disabled, out var disabledStatus, args.Component))
- damageVisComp.Disabled = disabledStatus;
- if (damageVisComp.Disabled)
- return;
- HandleDamage(uid, args.Component, damageVisComp);
- }
- private void HandleDamage(EntityUid uid, AppearanceComponent component, DamageVisualsComponent damageVisComp)
- {
- if (!TryComp(uid, out SpriteComponent? spriteComponent)
- || !TryComp(uid, out DamageableComponent? damageComponent))
- return;
- if (damageVisComp.TargetLayers != null && damageVisComp.DamageOverlayGroups != null)
- UpdateDisabledLayers(uid, spriteComponent, component, damageVisComp);
- if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null && damageVisComp.TargetLayers == null)
- CheckOverlayOrdering(spriteComponent, damageVisComp);
- if (AppearanceSystem.TryGetData<bool>(uid, DamageVisualizerKeys.ForceUpdate, out var update, component)
- && update)
- {
- ForceUpdateLayers(damageComponent, spriteComponent, damageVisComp);
- return;
- }
- if (damageVisComp.TrackAllDamage)
- {
- UpdateDamageVisuals(damageComponent, spriteComponent, damageVisComp);
- return;
- }
- if (!AppearanceSystem.TryGetData<DamageVisualizerGroupData>(uid, DamageVisualizerKeys.DamageUpdateGroups,
- out var data, component))
- {
- data = new DamageVisualizerGroupData(Comp<DamageableComponent>(uid).DamagePerGroup.Keys.ToList());
- }
- UpdateDamageVisuals(data.GroupList, damageComponent, spriteComponent, damageVisComp);
- }
- /// <summary>
- /// Checks if any layers were disabled in the last
- /// data update. Disabled layers mean that the
- /// layer will no longer be visible, or obtain
- /// any damage updates.
- /// </summary>
- private void UpdateDisabledLayers(EntityUid uid, SpriteComponent spriteComponent, AppearanceComponent component, DamageVisualsComponent damageVisComp)
- {
- foreach (var layer in damageVisComp.TargetLayerMapKeys)
- {
- // I assume this gets set by something like body system if limbs are missing???
- // TODO is this actually used by anything anywhere?
- AppearanceSystem.TryGetData(uid, layer, out bool disabled, component);
- if (damageVisComp.DisabledLayers[layer] == disabled)
- continue;
- damageVisComp.DisabledLayers[layer] = disabled;
- if (damageVisComp.TrackAllDamage)
- {
- spriteComponent.LayerSetVisible($"{layer}trackDamage", !disabled);
- continue;
- }
- if (damageVisComp.DamageOverlayGroups == null)
- continue;
- foreach (var damageGroup in damageVisComp.DamageOverlayGroups.Keys)
- {
- spriteComponent.LayerSetVisible($"{layer}{damageGroup}", !disabled);
- }
- }
- }
- /// <summary>
- /// Checks the overlay ordering on the current
- /// sprite component, compared to the
- /// data for the visualizer. If the top
- /// most layer doesn't match, the sprite
- /// layers are recreated and placed on top.
- /// </summary>
- private void CheckOverlayOrdering(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
- {
- if (spriteComponent[damageVisComp.TopMostLayerKey] != spriteComponent[spriteComponent.AllLayers.Count() - 1])
- {
- if (!damageVisComp.TrackAllDamage && damageVisComp.DamageOverlayGroups != null)
- {
- foreach (var (damageGroup, sprite) in damageVisComp.DamageOverlayGroups)
- {
- var threshold = damageVisComp.LastThresholdPerGroup[damageGroup];
- ReorderOverlaySprite(spriteComponent,
- damageVisComp,
- sprite,
- $"DamageOverlay{damageGroup}",
- $"DamageOverlay_{damageGroup}",
- threshold);
- }
- }
- else if (damageVisComp.TrackAllDamage && damageVisComp.DamageOverlay != null)
- {
- ReorderOverlaySprite(spriteComponent,
- damageVisComp,
- damageVisComp.DamageOverlay,
- $"DamageOverlay",
- $"DamageOverlay",
- damageVisComp.LastDamageThreshold);
- }
- }
- }
- private void ReorderOverlaySprite(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, DamageVisualizerSprite sprite, string key, string statePrefix, FixedPoint2 threshold)
- {
- spriteComponent.LayerMapTryGet(key, out var spriteLayer);
- var visibility = spriteComponent[spriteLayer].Visible;
- spriteComponent.RemoveLayer(spriteLayer);
- if (threshold == FixedPoint2.Zero) // these should automatically be invisible
- threshold = damageVisComp.Thresholds[1];
- spriteLayer = spriteComponent.AddLayer(
- new SpriteSpecifier.Rsi(
- new (sprite.Sprite),
- $"{statePrefix}_{threshold}"
- ),
- spriteLayer);
- spriteComponent.LayerMapSet(key, spriteLayer);
- spriteComponent.LayerSetVisible(spriteLayer, visibility);
- // this is somewhat iffy since it constantly reallocates
- damageVisComp.TopMostLayerKey = key;
- }
- /// <summary>
- /// Updates damage visuals without tracking
- /// any damage groups.
- /// </summary>
- private void UpdateDamageVisuals(DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
- {
- if (!CheckThresholdBoundary(damageComponent.TotalDamage, damageVisComp.LastDamageThreshold, damageVisComp, out var threshold))
- return;
- damageVisComp.LastDamageThreshold = threshold;
- if (damageVisComp.TargetLayers != null)
- {
- foreach (var layerMapKey in damageVisComp.TargetLayerMapKeys)
- {
- UpdateTargetLayer(spriteComponent, damageVisComp, layerMapKey, threshold);
- }
- }
- else
- {
- UpdateOverlay(spriteComponent, threshold);
- }
- }
- /// <summary>
- /// Updates damage visuals by damage group,
- /// according to the list of damage groups
- /// passed into it.
- /// </summary>
- private void UpdateDamageVisuals(List<string> delta, DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
- {
- foreach (var damageGroup in delta)
- {
- if (!damageVisComp.Overlay && damageGroup != damageVisComp.DamageGroup)
- continue;
- if (!_prototypeManager.TryIndex<DamageGroupPrototype>(damageGroup, out var damageGroupPrototype)
- || !damageComponent.Damage.TryGetDamageInGroup(damageGroupPrototype, out var damageTotal))
- continue;
- if (!damageVisComp.LastThresholdPerGroup.TryGetValue(damageGroup, out var lastThreshold)
- || !CheckThresholdBoundary(damageTotal, lastThreshold, damageVisComp, out var threshold))
- continue;
- damageVisComp.LastThresholdPerGroup[damageGroup] = threshold;
- if (damageVisComp.TargetLayers != null)
- {
- foreach (var layerMapKey in damageVisComp.TargetLayerMapKeys)
- {
- UpdateTargetLayer(spriteComponent, damageVisComp, layerMapKey, damageGroup, threshold);
- }
- }
- else
- {
- UpdateOverlay(spriteComponent, damageVisComp, damageGroup, threshold);
- }
- }
- }
- /// <summary>
- /// Checks if a threshold boundary was passed.
- /// </summary>
- private bool CheckThresholdBoundary(FixedPoint2 damageTotal, FixedPoint2 lastThreshold, DamageVisualsComponent damageVisComp, out FixedPoint2 threshold)
- {
- threshold = FixedPoint2.Zero;
- damageTotal = damageTotal / damageVisComp.Divisor;
- var thresholdIndex = damageVisComp.Thresholds.BinarySearch(damageTotal);
- if (thresholdIndex < 0)
- {
- thresholdIndex = ~thresholdIndex;
- threshold = damageVisComp.Thresholds[thresholdIndex - 1];
- }
- else
- {
- threshold = damageVisComp.Thresholds[thresholdIndex];
- }
- if (threshold == lastThreshold)
- return false;
- return true;
- }
- /// <summary>
- /// This is the entry point for
- /// forcing an update on all damage layers.
- /// Does different things depending on
- /// the configuration of the visualizer.
- /// </summary>
- private void ForceUpdateLayers(DamageableComponent damageComponent, SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp)
- {
- if (damageVisComp.DamageOverlayGroups != null)
- {
- UpdateDamageVisuals(damageVisComp.DamageOverlayGroups.Keys.ToList(), damageComponent, spriteComponent, damageVisComp);
- }
- else if (damageVisComp.DamageGroup != null)
- {
- UpdateDamageVisuals(new List<string>(){ damageVisComp.DamageGroup }, damageComponent, spriteComponent, damageVisComp);
- }
- else if (damageVisComp.DamageOverlay != null)
- {
- UpdateDamageVisuals(damageComponent, spriteComponent, damageVisComp);
- }
- }
- /// <summary>
- /// Updates a target layer. Without a damage group passed in,
- /// it assumes you're updating a layer that is tracking all
- /// damage.
- /// </summary>
- private void UpdateTargetLayer(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, object layerMapKey, FixedPoint2 threshold)
- {
- if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
- {
- if (!damageVisComp.DisabledLayers[layerMapKey])
- {
- var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
- spriteComponent.LayerMapTryGet($"{layerMapKey}trackDamage", out var spriteLayer);
- UpdateDamageLayerState(spriteComponent,
- spriteLayer,
- $"{layerState}",
- threshold);
- }
- }
- else if (!damageVisComp.Overlay)
- {
- var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
- spriteComponent.LayerMapTryGet(layerMapKey, out var spriteLayer);
- UpdateDamageLayerState(spriteComponent,
- spriteLayer,
- $"{layerState}",
- threshold);
- }
- }
- /// <summary>
- /// Updates a target layer by damage group.
- /// </summary>
- private void UpdateTargetLayer(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, object layerMapKey, string damageGroup, FixedPoint2 threshold)
- {
- if (damageVisComp.Overlay && damageVisComp.DamageOverlayGroups != null)
- {
- if (damageVisComp.DamageOverlayGroups.ContainsKey(damageGroup) && !damageVisComp.DisabledLayers[layerMapKey])
- {
- var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
- spriteComponent.LayerMapTryGet($"{layerMapKey}{damageGroup}", out var spriteLayer);
- UpdateDamageLayerState(spriteComponent,
- spriteLayer,
- $"{layerState}_{damageGroup}",
- threshold);
- }
- }
- else if (!damageVisComp.Overlay)
- {
- var layerState = damageVisComp.LayerMapKeyStates[layerMapKey];
- spriteComponent.LayerMapTryGet(layerMapKey, out var spriteLayer);
- UpdateDamageLayerState(spriteComponent,
- spriteLayer,
- $"{layerState}_{damageGroup}",
- threshold);
- }
- }
- /// <summary>
- /// Updates an overlay that is tracking all damage.
- /// </summary>
- private void UpdateOverlay(SpriteComponent spriteComponent, FixedPoint2 threshold)
- {
- spriteComponent.LayerMapTryGet($"DamageOverlay", out var spriteLayer);
- UpdateDamageLayerState(spriteComponent,
- spriteLayer,
- $"DamageOverlay",
- threshold);
- }
- /// <summary>
- /// Updates an overlay based on damage group.
- /// </summary>
- private void UpdateOverlay(SpriteComponent spriteComponent, DamageVisualsComponent damageVisComp, string damageGroup, FixedPoint2 threshold)
- {
- if (damageVisComp.DamageOverlayGroups != null)
- {
- if (damageVisComp.DamageOverlayGroups.ContainsKey(damageGroup))
- {
- spriteComponent.LayerMapTryGet($"DamageOverlay{damageGroup}", out var spriteLayer);
- UpdateDamageLayerState(spriteComponent,
- spriteLayer,
- $"DamageOverlay_{damageGroup}",
- threshold);
- }
- }
- }
- /// <summary>
- /// Updates a layer on the sprite by what
- /// prefix it has (calculated by whatever
- /// function calls it), and what threshold
- /// was passed into it.
- /// </summary>
- private void UpdateDamageLayerState(SpriteComponent spriteComponent, int spriteLayer, string statePrefix, FixedPoint2 threshold)
- {
- if (threshold == 0)
- {
- spriteComponent.LayerSetVisible(spriteLayer, false);
- }
- else
- {
- if (!spriteComponent[spriteLayer].Visible)
- {
- spriteComponent.LayerSetVisible(spriteLayer, true);
- }
- spriteComponent.LayerSetState(spriteLayer, $"{statePrefix}_{threshold}");
- }
- }
- }
|