Fix some mispredict reconciliation issues. (#6319)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -76,7 +76,7 @@ internal class ClientAlertsSystem : AlertsSystem
|
|||||||
if (componentAlerts == null) return;
|
if (componentAlerts == null) return;
|
||||||
|
|
||||||
//TODO: Do we really want to send alerts for non-attached entity?
|
//TODO: Do we really want to send alerts for non-attached entity?
|
||||||
component.Alerts = componentAlerts;
|
component.Alerts = new(componentAlerts);
|
||||||
if (!CurControlled(component.Owner, _playerManager)) return;
|
if (!CurControlled(component.Owner, _playerManager)) return;
|
||||||
|
|
||||||
SyncAlerts?.Invoke(this, componentAlerts);
|
SyncAlerts?.Invoke(this, componentAlerts);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ namespace Content.Client.Atmos.Visualizers
|
|||||||
if (!component.TryGetData(PipeColorVisuals.Color, out Color color))
|
if (!component.TryGetData(PipeColorVisuals.Color, out Color color))
|
||||||
color = Color.White;
|
color = Color.White;
|
||||||
|
|
||||||
if (!component.TryGetData(PipeVisuals.VisualState, out PipeVisualState state))
|
if (!component.TryGetData(PipeVisuals.VisualState, out PipeDirection connectedDirections))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(!component.TryGetData(SubFloorVisuals.SubFloor, out bool subfloor))
|
if(!component.TryGetData(SubFloorVisuals.SubFloor, out bool subfloor))
|
||||||
@@ -84,7 +84,7 @@ namespace Content.Client.Atmos.Visualizers
|
|||||||
{
|
{
|
||||||
var layer = sprite.LayerMapGet(layerKey);
|
var layer = sprite.LayerMapGet(layerKey);
|
||||||
var dir = (PipeDirection) layerKey;
|
var dir = (PipeDirection) layerKey;
|
||||||
var visible = subfloor && state.ConnectedDirections.HasDirection(dir);
|
var visible = subfloor && connectedDirections.HasDirection(dir);
|
||||||
sprite.LayerSetVisible(layer, visible);
|
sprite.LayerSetVisible(layer, visible);
|
||||||
|
|
||||||
if (!visible) continue;
|
if (!visible) continue;
|
||||||
|
|||||||
@@ -58,12 +58,18 @@ namespace Content.Client.Botany
|
|||||||
|
|
||||||
var sprite = IoCManager.Resolve<IEntityManager>().GetComponent<ISpriteComponent>(component.Owner);
|
var sprite = IoCManager.Resolve<IEntityManager>().GetComponent<ISpriteComponent>(component.Owner);
|
||||||
|
|
||||||
if (component.TryGetData<SpriteSpecifier>(PlantHolderVisuals.Plant, out var specifier))
|
if (component.TryGetData<string>(PlantHolderVisuals.PlantRsi, out var rsi)
|
||||||
|
&& component.TryGetData<string>(PlantHolderVisuals.PlantState, out var state))
|
||||||
{
|
{
|
||||||
var valid = !specifier.Equals(SpriteSpecifier.Invalid);
|
var valid = !string.IsNullOrWhiteSpace(state);
|
||||||
|
|
||||||
sprite.LayerSetVisible(PlantHolderLayers.Plant, valid);
|
sprite.LayerSetVisible(PlantHolderLayers.Plant, valid);
|
||||||
|
|
||||||
if(valid)
|
if(valid)
|
||||||
sprite.LayerSetSprite(PlantHolderLayers.Plant, specifier);
|
{
|
||||||
|
sprite.LayerSetRSI(PlantHolderLayers.Plant, rsi);
|
||||||
|
sprite.LayerSetState(PlantHolderLayers.Plant, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.TryGetData<bool>(PlantHolderVisuals.HealthLight, out var health))
|
if (component.TryGetData<bool>(PlantHolderVisuals.HealthLight, out var health))
|
||||||
|
|||||||
@@ -548,9 +548,9 @@ namespace Content.Client.Damage
|
|||||||
{
|
{
|
||||||
UpdateDamageVisuals(damageComponent, spriteComponent, damageData);
|
UpdateDamageVisuals(damageComponent, spriteComponent, damageData);
|
||||||
}
|
}
|
||||||
else if (component.TryGetData<List<string>>(DamageVisualizerKeys.DamageUpdateGroups, out List<string>? delta))
|
else if (component.TryGetData(DamageVisualizerKeys.DamageUpdateGroups, out DamageVisualizerGroupData data))
|
||||||
{
|
{
|
||||||
UpdateDamageVisuals(delta, damageComponent, spriteComponent, damageData);
|
UpdateDamageVisuals(data.GroupList, damageComponent, spriteComponent, damageData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Shared.Rotation;
|
using Content.Shared.Rotation;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.Animations;
|
using Robust.Client.Animations;
|
||||||
@@ -17,17 +17,17 @@ namespace Content.Client.Rotation
|
|||||||
{
|
{
|
||||||
base.OnChangeData(component);
|
base.OnChangeData(component);
|
||||||
|
|
||||||
if (component.TryGetData<RotationState>(RotationVisuals.RotationState, out var state))
|
// if TryGet fails, state defaults to RotationState.Vertical.
|
||||||
|
component.TryGetData<RotationState>(RotationVisuals.RotationState, out var state);
|
||||||
|
|
||||||
|
switch (state)
|
||||||
{
|
{
|
||||||
switch (state)
|
case RotationState.Vertical:
|
||||||
{
|
SetRotation(component, 0);
|
||||||
case RotationState.Vertical:
|
break;
|
||||||
SetRotation(component, 0);
|
case RotationState.Horizontal:
|
||||||
break;
|
SetRotation(component, Angle.FromDegrees(90));
|
||||||
case RotationState.Horizontal:
|
break;
|
||||||
SetRotation(component, Angle.FromDegrees(90));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -592,30 +592,31 @@ namespace Content.Server.Botany.Components
|
|||||||
|
|
||||||
if (Dead)
|
if (Dead)
|
||||||
{
|
{
|
||||||
appearanceComponent.SetData(PlantHolderVisuals.Plant,
|
appearanceComponent.SetData(PlantHolderVisuals.PlantRsi, Seed.PlantRsi.ToString());
|
||||||
new SpriteSpecifier.Rsi(Seed.PlantRsi, "dead"));
|
appearanceComponent.SetData(PlantHolderVisuals.PlantState, "dead");
|
||||||
}
|
}
|
||||||
else if (Harvest)
|
else if (Harvest)
|
||||||
{
|
{
|
||||||
appearanceComponent.SetData(PlantHolderVisuals.Plant,
|
appearanceComponent.SetData(PlantHolderVisuals.PlantRsi, Seed.PlantRsi.ToString());
|
||||||
new SpriteSpecifier.Rsi(Seed.PlantRsi, "harvest"));
|
appearanceComponent.SetData(PlantHolderVisuals.PlantState, "harvest");
|
||||||
}
|
}
|
||||||
else if (Age < Seed.Maturation)
|
else if (Age < Seed.Maturation)
|
||||||
{
|
{
|
||||||
var growthStage = Math.Max(1, (int) ((Age * Seed.GrowthStages) / Seed.Maturation));
|
var growthStage = Math.Max(1, (int) ((Age * Seed.GrowthStages) / Seed.Maturation));
|
||||||
appearanceComponent.SetData(PlantHolderVisuals.Plant,
|
|
||||||
new SpriteSpecifier.Rsi(Seed.PlantRsi, $"stage-{growthStage}"));
|
appearanceComponent.SetData(PlantHolderVisuals.PlantRsi, Seed.PlantRsi.ToString());
|
||||||
|
appearanceComponent.SetData(PlantHolderVisuals.PlantState, $"stage-{growthStage}");
|
||||||
_lastProduce = Age;
|
_lastProduce = Age;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
appearanceComponent.SetData(PlantHolderVisuals.Plant,
|
appearanceComponent.SetData(PlantHolderVisuals.PlantRsi, Seed.PlantRsi.ToString());
|
||||||
new SpriteSpecifier.Rsi(Seed.PlantRsi, $"stage-{Seed.GrowthStages}"));
|
appearanceComponent.SetData(PlantHolderVisuals.PlantState, $"stage-{Seed.GrowthStages}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
appearanceComponent.SetData(PlantHolderVisuals.Plant, SpriteSpecifier.Invalid);
|
appearanceComponent.SetData(PlantHolderVisuals.PlantState, "");
|
||||||
appearanceComponent.SetData(PlantHolderVisuals.HealthLight, false);
|
appearanceComponent.SetData(PlantHolderVisuals.HealthLight, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ namespace Content.Server.NodeContainer.Nodes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
appearance.SetData(PipeVisuals.VisualState, new PipeVisualState(netConnectedDirections));
|
appearance.SetData(PipeVisuals.VisualState, netConnectedDirections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,19 +11,6 @@ namespace Content.Shared.Atmos
|
|||||||
VisualState
|
VisualState
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public class PipeVisualState
|
|
||||||
{
|
|
||||||
// TODO ATMOS: Make this not a class and just be the field below...
|
|
||||||
[ViewVariables]
|
|
||||||
public readonly PipeDirection ConnectedDirections;
|
|
||||||
|
|
||||||
public PipeVisualState(PipeDirection connectedDirections)
|
|
||||||
{
|
|
||||||
ConnectedDirections = connectedDirections;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public enum PipeDirection
|
public enum PipeDirection
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ namespace Content.Shared.Botany
|
|||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public enum PlantHolderVisuals
|
public enum PlantHolderVisuals
|
||||||
{
|
{
|
||||||
Plant,
|
PlantRsi,
|
||||||
|
PlantState,
|
||||||
HealthLight,
|
HealthLight,
|
||||||
WaterLight,
|
WaterLight,
|
||||||
NutritionLight,
|
NutritionLight,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Content.Shared.Chemistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class SolutionContainerVisualState
|
public class SolutionContainerVisualState : ICloneable
|
||||||
{
|
{
|
||||||
public readonly Color Color;
|
public readonly Color Color;
|
||||||
|
|
||||||
@@ -33,6 +33,11 @@ namespace Content.Shared.Chemistry
|
|||||||
Color = color;
|
Color = color;
|
||||||
FilledVolumeFraction = (byte) (byte.MaxValue * filledVolumeFraction);
|
FilledVolumeFraction = (byte) (byte.MaxValue * filledVolumeFraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
return new SolutionContainerVisualState(Color, FilledVolumeFraction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SolutionContainerLayers : byte
|
public enum SolutionContainerLayers : byte
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Damage
|
namespace Content.Shared.Damage
|
||||||
@@ -11,4 +12,20 @@ namespace Content.Shared.Damage
|
|||||||
DamageUpdateGroups,
|
DamageUpdateGroups,
|
||||||
ForceUpdate
|
ForceUpdate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class DamageVisualizerGroupData : ICloneable
|
||||||
|
{
|
||||||
|
public List<string> GroupList;
|
||||||
|
|
||||||
|
public DamageVisualizerGroupData(List<string> groupList)
|
||||||
|
{
|
||||||
|
GroupList = groupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
return new DamageVisualizerGroupData(new List<string>(GroupList));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,10 @@ namespace Content.Shared.Damage
|
|||||||
component.Dirty();
|
component.Dirty();
|
||||||
|
|
||||||
if (EntityManager.TryGetComponent<AppearanceComponent>(component.Owner, out var appearance) && damageDelta != null)
|
if (EntityManager.TryGetComponent<AppearanceComponent>(component.Owner, out var appearance) && damageDelta != null)
|
||||||
appearance.SetData(DamageVisualizerKeys.DamageUpdateGroups, damageDelta.GetDamagePerGroup().Keys.ToList());
|
{
|
||||||
|
var data = new DamageVisualizerGroupData(damageDelta.GetDamagePerGroup().Keys.ToList());
|
||||||
|
appearance.SetData(DamageVisualizerKeys.DamageUpdateGroups, data);
|
||||||
|
}
|
||||||
RaiseLocalEvent(component.Owner, new DamageChangedEvent(component, damageDelta, interruptsDoAfters), false);
|
RaiseLocalEvent(component.Owner, new DamageChangedEvent(component, damageDelta, interruptsDoAfters), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +201,7 @@ namespace Content.Shared.Damage
|
|||||||
component.DamageModifierSetId = state.ModifierSetId;
|
component.DamageModifierSetId = state.ModifierSetId;
|
||||||
|
|
||||||
// Has the damage actually changed?
|
// Has the damage actually changed?
|
||||||
DamageSpecifier newDamage = new() { DamageDict = state.DamageDict };
|
DamageSpecifier newDamage = new() { DamageDict = new(state.DamageDict) };
|
||||||
var delta = component.Damage - newDamage;
|
var delta = component.Damage - newDamage;
|
||||||
delta.TrimZeros();
|
delta.TrimZeros();
|
||||||
|
|
||||||
|
|||||||
@@ -718,7 +718,7 @@ namespace Content.Shared.Hands.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class HandsVisualState
|
public class HandsVisualState : ICloneable
|
||||||
{
|
{
|
||||||
public List<HandVisualState> Hands { get; } = new();
|
public List<HandVisualState> Hands { get; } = new();
|
||||||
|
|
||||||
@@ -726,10 +726,15 @@ namespace Content.Shared.Hands.Components
|
|||||||
{
|
{
|
||||||
Hands = hands;
|
Hands = hands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
return new HandsVisualState(new List<HandVisualState>(Hands));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class HandVisualState
|
public struct HandVisualState
|
||||||
{
|
{
|
||||||
public string RsiPath { get; }
|
public string RsiPath { get; }
|
||||||
public string? EquippedPrefix { get; }
|
public string? EquippedPrefix { get; }
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace Content.Shared.StatusEffect
|
|||||||
foreach (var state in status.ActiveEffects.ToArray())
|
foreach (var state in status.ActiveEffects.ToArray())
|
||||||
{
|
{
|
||||||
// if we're past the end point of the effect
|
// if we're past the end point of the effect
|
||||||
if (_gameTiming.CurTime > state.Value.Cooldown.Item2)
|
if (curTime > state.Value.Cooldown.Item2)
|
||||||
{
|
{
|
||||||
TryRemoveStatusEffect(status.Owner, state.Key, status);
|
TryRemoveStatusEffect(status.Owner, state.Key, status);
|
||||||
}
|
}
|
||||||
@@ -53,24 +53,33 @@ namespace Content.Shared.StatusEffect
|
|||||||
|
|
||||||
private void OnHandleState(EntityUid uid, StatusEffectsComponent component, ref ComponentHandleState args)
|
private void OnHandleState(EntityUid uid, StatusEffectsComponent component, ref ComponentHandleState args)
|
||||||
{
|
{
|
||||||
if (args.Current is StatusEffectsComponentState state)
|
if (args.Current is not StatusEffectsComponentState state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
component.AllowedEffects = new(state.AllowedEffects);
|
||||||
|
|
||||||
|
// Remove non-existent effects.
|
||||||
|
foreach (var effect in component.ActiveEffects.Keys)
|
||||||
{
|
{
|
||||||
component.AllowedEffects = state.AllowedEffects;
|
if (!state.ActiveEffects.ContainsKey(effect))
|
||||||
|
|
||||||
foreach (var effect in state.ActiveEffects)
|
|
||||||
{
|
{
|
||||||
// don't bother with anything if we already have it
|
TryRemoveStatusEffect(uid, effect, component);
|
||||||
if (component.ActiveEffects.ContainsKey(effect.Key))
|
|
||||||
{
|
|
||||||
component.ActiveEffects[effect.Key] = effect.Value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var time = effect.Value.Cooldown.Item2 - effect.Value.Cooldown.Item1;
|
|
||||||
//TODO: Not sure how to handle refresh here.
|
|
||||||
TryAddStatusEffect(uid, effect.Key, time, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var effect in state.ActiveEffects)
|
||||||
|
{
|
||||||
|
// don't bother with anything if we already have it
|
||||||
|
if (component.ActiveEffects.ContainsKey(effect.Key))
|
||||||
|
{
|
||||||
|
component.ActiveEffects[effect.Key] = effect.Value;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var time = effect.Value.Cooldown.Item2 - effect.Value.Cooldown.Item1;
|
||||||
|
//TODO: Not sure how to handle refresh here.
|
||||||
|
TryAddStatusEffect(uid, effect.Key, time, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -187,7 +196,7 @@ namespace Content.Shared.StatusEffect
|
|||||||
_alertsSystem.ShowAlert(uid, proto.Alert.Value, null, cooldown1);
|
_alertsSystem.ShowAlert(uid, proto.Alert.Value, null, cooldown1);
|
||||||
}
|
}
|
||||||
|
|
||||||
status.Dirty();
|
Dirty(status);
|
||||||
// event?
|
// event?
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -261,7 +270,7 @@ namespace Content.Shared.StatusEffect
|
|||||||
|
|
||||||
status.ActiveEffects.Remove(key);
|
status.ActiveEffects.Remove(key);
|
||||||
|
|
||||||
status.Dirty();
|
Dirty(status);
|
||||||
// event?
|
// event?
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -285,6 +294,7 @@ namespace Content.Shared.StatusEffect
|
|||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dirty(status);
|
||||||
return failed;
|
return failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,6 +362,7 @@ namespace Content.Shared.StatusEffect
|
|||||||
_alertsSystem.ShowAlert(uid, proto.Alert.Value, null, cooldown);
|
_alertsSystem.ShowAlert(uid, proto.Alert.Value, null, cooldown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dirty(status);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,6 +398,7 @@ namespace Content.Shared.StatusEffect
|
|||||||
_alertsSystem.ShowAlert(uid, proto.Alert.Value, null, cooldown);
|
_alertsSystem.ShowAlert(uid, proto.Alert.Value, null, cooldown);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dirty(status);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +418,8 @@ namespace Content.Shared.StatusEffect
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
status.ActiveEffects[key].Cooldown = (_gameTiming.CurTime, _gameTiming.CurTime + time);
|
status.ActiveEffects[key].Cooldown = (_gameTiming.CurTime, _gameTiming.CurTime + time);
|
||||||
|
|
||||||
|
Dirty(status);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Content.Shared.Storage.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public class ShowLayerData
|
public class ShowLayerData : ICloneable
|
||||||
{
|
{
|
||||||
public IReadOnlyList<string> QueuedEntities { get; internal set; }
|
public IReadOnlyList<string> QueuedEntities { get; internal set; }
|
||||||
|
|
||||||
@@ -33,14 +33,14 @@ namespace Content.Shared.Storage.Components
|
|||||||
QueuedEntities = new List<string>();
|
QueuedEntities = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShowLayerData(IReadOnlyList<string> other)
|
public ShowLayerData(IEnumerable<string> other)
|
||||||
{
|
{
|
||||||
QueuedEntities = other;
|
QueuedEntities = new List<string>(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShowLayerData(ShowLayerData other)
|
public object Clone()
|
||||||
{
|
{
|
||||||
QueuedEntities = other.QueuedEntities;
|
return new ShowLayerData(QueuedEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user