Makes thieving gloves sneakier (#21398)
* Hidden DoAfters * Fix formatting warnings * Hide progress bar and pickup animation * Copy Hidden field in copy constructor
This commit is contained in:
@@ -4,6 +4,7 @@ using Robust.Client.GameObjects;
|
|||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.Graphics;
|
using Robust.Shared.Graphics;
|
||||||
|
using Robust.Client.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -14,6 +15,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||||||
{
|
{
|
||||||
private readonly IEntityManager _entManager;
|
private readonly IEntityManager _entManager;
|
||||||
private readonly IGameTiming _timing;
|
private readonly IGameTiming _timing;
|
||||||
|
private readonly IPlayerManager _player;
|
||||||
private readonly SharedTransformSystem _transform;
|
private readonly SharedTransformSystem _transform;
|
||||||
private readonly MetaDataSystem _meta;
|
private readonly MetaDataSystem _meta;
|
||||||
|
|
||||||
@@ -31,13 +33,14 @@ public sealed class DoAfterOverlay : Overlay
|
|||||||
|
|
||||||
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
|
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
|
||||||
|
|
||||||
public DoAfterOverlay(IEntityManager entManager, IPrototypeManager protoManager, IGameTiming timing)
|
public DoAfterOverlay(IEntityManager entManager, IPrototypeManager protoManager, IGameTiming timing, IPlayerManager player)
|
||||||
{
|
{
|
||||||
_entManager = entManager;
|
_entManager = entManager;
|
||||||
_timing = timing;
|
_timing = timing;
|
||||||
|
_player = player;
|
||||||
_transform = _entManager.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
|
_transform = _entManager.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
|
||||||
_meta = _entManager.EntitySysManager.GetEntitySystem<MetaDataSystem>();
|
_meta = _entManager.EntitySysManager.GetEntitySystem<MetaDataSystem>();
|
||||||
var sprite = new SpriteSpecifier.Rsi(new ("/Textures/Interface/Misc/progress_bar.rsi"), "icon");
|
var sprite = new SpriteSpecifier.Rsi(new("/Textures/Interface/Misc/progress_bar.rsi"), "icon");
|
||||||
_barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite);
|
_barTexture = _entManager.EntitySysManager.GetEntitySystem<SpriteSystem>().Frame0(sprite);
|
||||||
|
|
||||||
_shader = protoManager.Index<ShaderPrototype>("unshaded").Instance();
|
_shader = protoManager.Index<ShaderPrototype>("unshaded").Instance();
|
||||||
@@ -58,6 +61,7 @@ public sealed class DoAfterOverlay : Overlay
|
|||||||
var curTime = _timing.CurTime;
|
var curTime = _timing.CurTime;
|
||||||
|
|
||||||
var bounds = args.WorldAABB.Enlarged(5f);
|
var bounds = args.WorldAABB.Enlarged(5f);
|
||||||
|
var localEnt = _player.LocalSession?.AttachedEntity;
|
||||||
|
|
||||||
var metaQuery = _entManager.GetEntityQuery<MetaDataComponent>();
|
var metaQuery = _entManager.GetEntityQuery<MetaDataComponent>();
|
||||||
var enumerator = _entManager.AllEntityQueryEnumerator<ActiveDoAfterComponent, DoAfterComponent, SpriteComponent, TransformComponent>();
|
var enumerator = _entManager.AllEntityQueryEnumerator<ActiveDoAfterComponent, DoAfterComponent, SpriteComponent, TransformComponent>();
|
||||||
@@ -88,6 +92,17 @@ public sealed class DoAfterOverlay : Overlay
|
|||||||
|
|
||||||
foreach (var doAfter in comp.DoAfters.Values)
|
foreach (var doAfter in comp.DoAfters.Values)
|
||||||
{
|
{
|
||||||
|
// Hide some DoAfters from other players for stealthy actions (ie: thieving gloves)
|
||||||
|
var alpha = 1f;
|
||||||
|
if (doAfter.Args.Hidden)
|
||||||
|
{
|
||||||
|
if (uid != localEnt)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Hints to the local player that this do-after is not visible to other players.
|
||||||
|
alpha = 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
// Use the sprite itself if we know its bounds. This means short or tall sprites don't get overlapped
|
// Use the sprite itself if we know its bounds. This means short or tall sprites don't get overlapped
|
||||||
// by the bar.
|
// by the bar.
|
||||||
float yOffset = sprite.Bounds.Height / 2f + 0.05f;
|
float yOffset = sprite.Bounds.Height / 2f + 0.05f;
|
||||||
@@ -108,15 +123,15 @@ public sealed class DoAfterOverlay : Overlay
|
|||||||
{
|
{
|
||||||
var elapsed = doAfter.CancelledTime.Value - doAfter.StartTime;
|
var elapsed = doAfter.CancelledTime.Value - doAfter.StartTime;
|
||||||
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||||
var cancelElapsed = (time - doAfter.CancelledTime.Value).TotalSeconds;
|
var cancelElapsed = (time - doAfter.CancelledTime.Value).TotalSeconds;
|
||||||
var flash = Math.Floor(cancelElapsed / FlashTime) % 2 == 0;
|
var flash = Math.Floor(cancelElapsed / FlashTime) % 2 == 0;
|
||||||
color = new Color(1f, 0f, 0f, flash ? 1f : 0f);
|
color = new Color(1f, 0f, 0f, flash ? alpha : 0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var elapsed = time - doAfter.StartTime;
|
var elapsed = time - doAfter.StartTime;
|
||||||
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
elapsedRatio = (float) Math.Min(1, elapsed.TotalSeconds / doAfter.Args.Delay.TotalSeconds);
|
||||||
color = GetProgressColor(elapsedRatio);
|
color = GetProgressColor(elapsedRatio, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
var xProgress = (EndX - StartX) * elapsedRatio + StartX;
|
var xProgress = (EndX - StartX) * elapsedRatio + StartX;
|
||||||
@@ -131,14 +146,14 @@ public sealed class DoAfterOverlay : Overlay
|
|||||||
handle.SetTransform(Matrix3.Identity);
|
handle.SetTransform(Matrix3.Identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Color GetProgressColor(float progress)
|
public static Color GetProgressColor(float progress, float alpha = 1f)
|
||||||
{
|
{
|
||||||
if (progress >= 1.0f)
|
if (progress >= 1.0f)
|
||||||
{
|
{
|
||||||
return new Color(0f, 1f, 0f);
|
return new Color(0f, 1f, 0f, alpha);
|
||||||
}
|
}
|
||||||
// lerp
|
// lerp
|
||||||
var hue = (5f / 18f) * progress;
|
var hue = (5f / 18f) * progress;
|
||||||
return Color.FromHsv((hue, 1f, 0.75f, 1f));
|
return Color.FromHsv((hue, 1f, 0.75f, alpha));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public sealed class DoAfterSystem : SharedDoAfterSystem
|
|||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
_overlay.AddOverlay(new DoAfterOverlay(EntityManager, _prototype, GameTiming));
|
_overlay.AddOverlay(new DoAfterOverlay(EntityManager, _prototype, GameTiming, _player));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
public override void Shutdown()
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ namespace Content.Server.Strip
|
|||||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: held)
|
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: held)
|
||||||
{
|
{
|
||||||
ExtraCheck = Check,
|
ExtraCheck = Check,
|
||||||
|
Hidden = ev.Stealth,
|
||||||
AttemptFrequency = AttemptFrequency.EveryTick,
|
AttemptFrequency = AttemptFrequency.EveryTick,
|
||||||
BreakOnDamage = true,
|
BreakOnDamage = true,
|
||||||
BreakOnTargetMove = true,
|
BreakOnTargetMove = true,
|
||||||
@@ -294,6 +295,7 @@ namespace Content.Server.Strip
|
|||||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: held)
|
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: held)
|
||||||
{
|
{
|
||||||
ExtraCheck = Check,
|
ExtraCheck = Check,
|
||||||
|
Hidden = ev.Stealth,
|
||||||
AttemptFrequency = AttemptFrequency.EveryTick,
|
AttemptFrequency = AttemptFrequency.EveryTick,
|
||||||
BreakOnDamage = true,
|
BreakOnDamage = true,
|
||||||
BreakOnTargetMove = true,
|
BreakOnTargetMove = true,
|
||||||
@@ -308,7 +310,7 @@ namespace Content.Server.Strip
|
|||||||
if (result != DoAfterStatus.Finished) return;
|
if (result != DoAfterStatus.Finished) return;
|
||||||
|
|
||||||
_handsSystem.TryDrop(user, checkActionBlocker: false, handsComp: userHands);
|
_handsSystem.TryDrop(user, checkActionBlocker: false, handsComp: userHands);
|
||||||
_handsSystem.TryPickup(target, held, handName, checkActionBlocker: false, animateUser: true, handsComp: hands);
|
_handsSystem.TryPickup(target, held, handName, checkActionBlocker: false, animateUser: !ev.Stealth, animate: !ev.Stealth, handsComp: hands);
|
||||||
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has placed the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s hands");
|
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has placed the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s hands");
|
||||||
// hand update will trigger strippable update
|
// hand update will trigger strippable update
|
||||||
}
|
}
|
||||||
@@ -354,6 +356,7 @@ namespace Content.Server.Strip
|
|||||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: item)
|
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: item)
|
||||||
{
|
{
|
||||||
ExtraCheck = Check,
|
ExtraCheck = Check,
|
||||||
|
Hidden = ev.Stealth,
|
||||||
AttemptFrequency = AttemptFrequency.EveryTick,
|
AttemptFrequency = AttemptFrequency.EveryTick,
|
||||||
BreakOnDamage = true,
|
BreakOnDamage = true,
|
||||||
BreakOnTargetMove = true,
|
BreakOnTargetMove = true,
|
||||||
@@ -389,7 +392,7 @@ namespace Content.Server.Strip
|
|||||||
// Raise a dropped event, so that things like gas tank internals properly deactivate when stripping
|
// Raise a dropped event, so that things like gas tank internals properly deactivate when stripping
|
||||||
RaiseLocalEvent(item, new DroppedEvent(user), true);
|
RaiseLocalEvent(item, new DroppedEvent(user), true);
|
||||||
|
|
||||||
_handsSystem.PickupOrDrop(user, item);
|
_handsSystem.PickupOrDrop(user, item, animateUser: !ev.Stealth, animate: !ev.Stealth);
|
||||||
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}");
|
_adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -430,6 +433,7 @@ namespace Content.Server.Strip
|
|||||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: item)
|
var doAfterArgs = new DoAfterArgs(EntityManager, user, ev.Time, new AwaitedDoAfterEvent(), null, target: target, used: item)
|
||||||
{
|
{
|
||||||
ExtraCheck = Check,
|
ExtraCheck = Check,
|
||||||
|
Hidden = ev.Stealth,
|
||||||
AttemptFrequency = AttemptFrequency.EveryTick,
|
AttemptFrequency = AttemptFrequency.EveryTick,
|
||||||
BreakOnDamage = true,
|
BreakOnDamage = true,
|
||||||
BreakOnTargetMove = true,
|
BreakOnTargetMove = true,
|
||||||
@@ -439,7 +443,7 @@ namespace Content.Server.Strip
|
|||||||
DuplicateCondition = DuplicateConditions.SameTool
|
DuplicateCondition = DuplicateConditions.SameTool
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Check() && _handsSystem.TryGetHand(target, handName, out var handSlot, hands) && handSlot.HeldEntity != null)
|
if (!ev.Stealth && Check() && _handsSystem.TryGetHand(target, handName, out var handSlot, hands) && handSlot.HeldEntity != null)
|
||||||
{
|
{
|
||||||
_popup.PopupEntity(
|
_popup.PopupEntity(
|
||||||
Loc.GetString("strippable-component-alert-owner",
|
Loc.GetString("strippable-component-alert-owner",
|
||||||
@@ -456,7 +460,7 @@ namespace Content.Server.Strip
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_handsSystem.TryDrop(target, item, checkActionBlocker: false, handsComp: hands);
|
_handsSystem.TryDrop(target, item, checkActionBlocker: false, handsComp: hands);
|
||||||
_handsSystem.PickupOrDrop(user, item, handsComp: userHands);
|
_handsSystem.PickupOrDrop(user, item, animateUser: !ev.Stealth, animate: !ev.Stealth, handsComp: userHands);
|
||||||
// hand update will trigger strippable update
|
// hand update will trigger strippable update
|
||||||
_adminLogger.Add(LogType.Stripping, LogImpact.Medium,
|
_adminLogger.Add(LogType.Stripping, LogImpact.Medium,
|
||||||
$"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}");
|
$"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}");
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ public sealed partial class DoAfterArgs
|
|||||||
|
|
||||||
public NetEntity? NetUsed;
|
public NetEntity? NetUsed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the progress bar for this DoAfter should be hidden from other players.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public bool Hidden;
|
||||||
|
|
||||||
#region Event options
|
#region Event options
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The event that will get raised when the DoAfter has finished. If null, this will simply raise a <see cref="SimpleDoAfterEvent"/>
|
/// The event that will get raised when the DoAfter has finished. If null, this will simply raise a <see cref="SimpleDoAfterEvent"/>
|
||||||
@@ -239,6 +245,7 @@ public sealed partial class DoAfterArgs
|
|||||||
Delay = other.Delay;
|
Delay = other.Delay;
|
||||||
Target = other.Target;
|
Target = other.Target;
|
||||||
Used = other.Used;
|
Used = other.Used;
|
||||||
|
Hidden = other.Hidden;
|
||||||
EventTarget = other.EventTarget;
|
EventTarget = other.EventTarget;
|
||||||
Broadcast = other.Broadcast;
|
Broadcast = other.Broadcast;
|
||||||
NeedHand = other.NeedHand;
|
NeedHand = other.NeedHand;
|
||||||
|
|||||||
Reference in New Issue
Block a user