Status effects fix. Refresh the status effect cooldown. (#5708)

This commit is contained in:
pointer-to-null
2021-12-07 09:18:07 +03:00
committed by GitHub
parent 4688c74d43
commit 090e74792c
26 changed files with 111 additions and 62 deletions

View File

@@ -73,7 +73,7 @@ namespace Content.IntegrationTests.Tests
Assert.That(inventory.TryGetSlotItem(Slots.INNERCLOTHING, out ItemComponent uniform));
Assert.That(uniform.Owner.Prototype != null && uniform.Owner.Prototype.ID == "InventoryJumpsuitJanitorDummy");
EntitySystem.Get<StunSystem>().TryStun(human.Uid, TimeSpan.FromSeconds(1f));
EntitySystem.Get<StunSystem>().TryStun(human.Uid, TimeSpan.FromSeconds(1f), true);
// Since the mob is stunned, they can't equip this.
Assert.That(inventory.SpawnItemInSlot(Slots.IDCARD, "InventoryIDCardDummy", true), Is.False);

View File

@@ -180,7 +180,7 @@ namespace Content.Server.Atmos.EntitySystems
flammable.Resisting = true;
flammable.Owner.PopupMessage(Loc.GetString("flammable-component-resist-message"));
_stunSystem.TryParalyze(uid, TimeSpan.FromSeconds(2f), alerts: alerts);
_stunSystem.TryParalyze(uid, TimeSpan.FromSeconds(2f), true, alerts: alerts);
// TODO FLAMMABLE: Make this not use TimerComponent...
flammable.Owner.SpawnTimer(2000, () =>

View File

@@ -15,12 +15,17 @@ public class Electrocute : ReagentEffect
[DataField("electrocuteDamageScale")] public int ElectrocuteDamageScale = 5;
/// <remarks>
/// true - refresh electrocute time, false - accumulate electrocute time
/// </remarks>
[DataField("refresh")] public bool Refresh = true;
public override bool ShouldLog => true;
public override void Effect(ReagentEffectArgs args)
{
EntitySystem.Get<ElectrocutionSystem>().TryDoElectrocution(args.SolutionEntity, null,
Math.Max((args.Quantity * ElectrocuteDamageScale).Int(), 1), TimeSpan.FromSeconds(ElectrocuteTime));
Math.Max((args.Quantity * ElectrocuteDamageScale).Int(), 1), TimeSpan.FromSeconds(ElectrocuteTime), Refresh);
args.Source?.RemoveReagent(args.Reagent.ID, args.Quantity);
}

View File

@@ -30,6 +30,12 @@ namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
[DataField("time")]
public float Time = 2.0f;
/// <remarks>
/// true - refresh status effect time, false - accumulate status effect time
/// </remarks>
[DataField("refresh")]
public bool Refresh = true;
/// <summary>
/// Should this effect add the status effect, remove time from it, or set its cooldown?
/// </summary>
@@ -41,7 +47,7 @@ namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
var statusSys = args.EntityManager.EntitySysManager.GetEntitySystem<StatusEffectsSystem>();
if (Type == StatusEffectMetabolismType.Add && Component != String.Empty)
{
statusSys.TryAddStatusEffect(args.SolutionEntity, Key, TimeSpan.FromSeconds(Time), Component);
statusSys.TryAddStatusEffect(args.SolutionEntity, Key, TimeSpan.FromSeconds(Time), Refresh, Component);
}
else if (Type == StatusEffectMetabolismType.Remove)
{

View File

@@ -23,10 +23,16 @@ namespace Content.Server.Chemistry.ReagentEffects.StatusEffects
[DataField("time")]
public float Time = 2.0f;
/// <remarks>
/// true - refresh jitter time, false - accumulate jitter time
/// </remarks>
[DataField("refresh")]
public bool Refresh = true;
public override void Effect(ReagentEffectArgs args)
{
args.EntityManager.EntitySysManager.GetEntitySystem<SharedJitteringSystem>()
.DoJitter(args.SolutionEntity, TimeSpan.FromSeconds(Time), Amplitude, Frequency);
.DoJitter(args.SolutionEntity, TimeSpan.FromSeconds(Time), Refresh, Amplitude, Frequency);
}
}
}

View File

@@ -61,7 +61,7 @@ namespace Content.Server.Conveyor
signal != TwoWayLeverSignal.Middle)
{
args.Cancel();
_stunSystem.TryParalyze(uid, TimeSpan.FromSeconds(2f));
_stunSystem.TryParalyze(uid, TimeSpan.FromSeconds(2f), true);
component.Owner.PopupMessage(args.Attemptee, Loc.GetString("conveyor-component-failed-link"));
}
}

View File

@@ -51,7 +51,7 @@ namespace Content.Server.Damage.Systems
component.LastHit = _gameTiming.CurTime;
if (_robustRandom.Prob(component.StunChance))
_stunSystem.TryStun(uid, TimeSpan.FromSeconds(component.StunSeconds));
_stunSystem.TryStun(uid, TimeSpan.FromSeconds(component.StunSeconds), true);
var damageScale = (speed / component.MinimumSpeed) * component.Factor;

View File

@@ -585,7 +585,7 @@ namespace Content.Server.Doors.Components
if (e.Owner.HasComponent<DamageableComponent>())
EntitySystem.Get<DamageableSystem>().TryChangeDamage(e.Owner.Uid, CrushDamage);
EntitySystem.Get<StunSystem>().TryParalyze(e.Owner.Uid, TimeSpan.FromSeconds(DoorStunTime));
EntitySystem.Get<StunSystem>().TryParalyze(e.Owner.Uid, TimeSpan.FromSeconds(DoorStunTime), true);
}
// If we hit someone, open up after stun (opens right when stun ends)

View File

@@ -52,7 +52,7 @@ namespace Content.Server.Electrocution
}
entityManager.EntitySysManager.GetEntitySystem<ElectrocutionSystem>()
.TryDoElectrocution(uid, null, damage, TimeSpan.FromSeconds(seconds));
.TryDoElectrocution(uid, null, damage, TimeSpan.FromSeconds(seconds), true);
}
}
}

View File

@@ -188,7 +188,7 @@ namespace Content.Server.Electrocution
entity,
uid,
(int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth)),
TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth)),
TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth)), true,
electrified.SiemensCoefficient);
}
@@ -224,7 +224,7 @@ namespace Content.Server.Electrocution
node,
(int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth) * damageMult),
TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth) *
timeMult),
timeMult), true,
electrified.SiemensCoefficient);
}
@@ -246,12 +246,12 @@ namespace Content.Server.Electrocution
/// <returns>Whether the entity <see cref="uid"/> was stunned by the shock.</returns>
public bool TryDoElectrocution(
EntityUid uid, EntityUid? sourceUid, int shockDamage, TimeSpan time, float siemensCoefficient = 1f,
EntityUid uid, EntityUid? sourceUid, int shockDamage, TimeSpan time, bool refresh, float siemensCoefficient = 1f,
StatusEffectsComponent? statusEffects = null,
SharedAlertsComponent? alerts = null)
{
if (!DoCommonElectrocutionAttempt(uid, sourceUid, ref siemensCoefficient)
|| !DoCommonElectrocution(uid, sourceUid, shockDamage, time, siemensCoefficient, statusEffects, alerts))
|| !DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects, alerts))
return false;
RaiseLocalEvent(uid, new ElectrocutedEvent(uid, sourceUid, siemensCoefficient));
@@ -265,6 +265,7 @@ namespace Content.Server.Electrocution
Node node,
int shockDamage,
TimeSpan time,
bool refresh,
float siemensCoefficient = 1f,
StatusEffectsComponent? statusEffects = null,
SharedAlertsComponent? alerts = null,
@@ -275,9 +276,9 @@ namespace Content.Server.Electrocution
// Coefficient needs to be higher than this to do a powered electrocution!
if(siemensCoefficient <= 0.5f)
return DoCommonElectrocution(uid, sourceUid, shockDamage, time, siemensCoefficient, statusEffects, alerts);
return DoCommonElectrocution(uid, sourceUid, shockDamage, time, refresh, siemensCoefficient, statusEffects, alerts);
if (!DoCommonElectrocution(uid, sourceUid, null, time, siemensCoefficient, statusEffects, alerts))
if (!DoCommonElectrocution(uid, sourceUid, null, time, refresh, siemensCoefficient, statusEffects, alerts))
return false;
if (!Resolve(sourceUid, ref sourceTransform)) // This shouldn't really happen, but just in case...
@@ -319,7 +320,7 @@ namespace Content.Server.Electrocution
}
private bool DoCommonElectrocution(EntityUid uid, EntityUid? sourceUid,
int? shockDamage, TimeSpan time, float siemensCoefficient = 1f,
int? shockDamage, TimeSpan time, bool refresh, float siemensCoefficient = 1f,
StatusEffectsComponent? statusEffects = null,
SharedAlertsComponent? alerts = null)
{
@@ -341,14 +342,14 @@ namespace Content.Server.Electrocution
!_statusEffectsSystem.CanApplyEffect(uid, StatusEffectKey, statusEffects))
return false;
if (!_statusEffectsSystem.TryAddStatusEffect<ElectrocutedComponent>(uid, StatusEffectKey, time,
if (!_statusEffectsSystem.TryAddStatusEffect<ElectrocutedComponent>(uid, StatusEffectKey, time, refresh,
statusEffects, alerts))
return false;
var shouldStun = siemensCoefficient > 0.5f;
if (shouldStun)
_stunSystem.TryParalyze(uid, time * ParalyzeTimeMultiplier, statusEffects, alerts);
_stunSystem.TryParalyze(uid, time * ParalyzeTimeMultiplier, refresh, statusEffects, alerts);
// TODO: Sparks here.
@@ -362,8 +363,8 @@ namespace Content.Server.Electrocution
$"{statusEffects.Owner} took {actual.Total} powered electrocution damage");
}
_stutteringSystem.DoStutter(uid, time * StutteringTimeMultiplier, statusEffects, alerts);
_jitteringSystem.DoJitter(uid, time * JitterTimeMultiplier, JitterAmplitude, JitterFrequency, true,
_stutteringSystem.DoStutter(uid, time * StutteringTimeMultiplier, refresh, statusEffects, alerts);
_jitteringSystem.DoJitter(uid, time * JitterTimeMultiplier, refresh, JitterAmplitude, JitterFrequency, true,
statusEffects, alerts);
_popupSystem.PopupEntity(Loc.GetString("electrocuted-component-mob-shocked-popup-player"), uid,

View File

@@ -131,7 +131,7 @@ namespace Content.Server.Flash
flashable.Dirty();
}
_stunSystem.TrySlowdown(target, TimeSpan.FromSeconds(flashDuration/1000f),
_stunSystem.TrySlowdown(target, TimeSpan.FromSeconds(flashDuration/1000f), true,
slowTo, slowTo);
if (displayPopup && user != null && target != user)

View File

@@ -158,7 +158,7 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
if (mob != null)
{
_stunSystem.TryParalyze(mob.Uid, TimeSpan.FromSeconds(1));
_stunSystem.TryParalyze(mob.Uid, TimeSpan.FromSeconds(1), true);
instrument.Owner.PopupMessage(mob, "instrument-component-finger-cramps-max-message");
}

View File

@@ -247,7 +247,7 @@ namespace Content.Server.PneumaticCannon
if(data.User.TryGetComponent<StatusEffectsComponent>(out var status)
&& comp.Power == PneumaticCannonPower.High)
{
_stun.TryParalyze(data.User.Uid, TimeSpan.FromSeconds(comp.HighPowerStunTime), status);
_stun.TryParalyze(data.User.Uid, TimeSpan.FromSeconds(comp.HighPowerStunTime), true, status);
data.User.PopupMessage(Loc.GetString("pneumatic-cannon-component-power-stun",
("cannon", comp.Owner)));
}

View File

@@ -28,13 +28,13 @@ namespace Content.Server.Speech.EntitySystems
SubscribeLocalEvent<StutteringAccentComponent, AccentGetEvent>(OnAccent);
}
public override void DoStutter(EntityUid uid, TimeSpan time, StatusEffectsComponent? status = null, SharedAlertsComponent? alerts = null)
public override void DoStutter(EntityUid uid, TimeSpan time, bool refresh, StatusEffectsComponent? status = null, SharedAlertsComponent? alerts = null)
{
if (!Resolve(uid, ref status, false))
return;
if (!_statusEffectsSystem.HasStatusEffect(uid, StutterKey, status))
_statusEffectsSystem.TryAddStatusEffect<StutteringAccentComponent>(uid, StutterKey, time, status, alerts);
_statusEffectsSystem.TryAddStatusEffect<StutteringAccentComponent>(uid, StutterKey, time, refresh, status, alerts);
else
_statusEffectsSystem.TryAddTime(uid, StutterKey, time, status);
}

View File

@@ -37,12 +37,12 @@ namespace Content.Server.Stunnable
// Let the actual methods log errors for these.
Resolve(otherUid, ref alerts, ref standingState, ref appearance, false);
_stunSystem.TryStun(otherUid, TimeSpan.FromSeconds(component.StunAmount), status, alerts);
_stunSystem.TryStun(otherUid, TimeSpan.FromSeconds(component.StunAmount), true, status, alerts);
_stunSystem.TryKnockdown(otherUid, TimeSpan.FromSeconds(component.KnockdownAmount),
_stunSystem.TryKnockdown(otherUid, TimeSpan.FromSeconds(component.KnockdownAmount), true,
status, alerts);
_stunSystem.TrySlowdown(otherUid, TimeSpan.FromSeconds(component.SlowdownAmount),
_stunSystem.TrySlowdown(otherUid, TimeSpan.FromSeconds(component.SlowdownAmount), true,
component.WalkSpeedMultiplier, component.RunSpeedMultiplier, status, alerts);
}
}

View File

@@ -34,7 +34,7 @@ namespace Content.Server.Stunnable
if (args.Handled || !_random.Prob(args.PushProbability))
return;
if (!TryParalyze(uid, TimeSpan.FromSeconds(4f), status))
if (!TryParalyze(uid, TimeSpan.FromSeconds(4f), true, status))
return;
var source = args.Source;

View File

@@ -129,21 +129,21 @@ namespace Content.Server.Stunnable
if (!EntityManager.HasComponent<SlowedDownComponent>(entity.Uid))
{
if (_robustRandom.Prob(comp.ParalyzeChanceNoSlowdown))
_stunSystem.TryParalyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), status);
_stunSystem.TryParalyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), true, status);
else
_stunSystem.TrySlowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), 0.5f, 0.5f, status);
_stunSystem.TrySlowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), true, 0.5f, 0.5f, status);
}
else
{
if (_robustRandom.Prob(comp.ParalyzeChanceWithSlowdown))
_stunSystem.TryParalyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), status);
_stunSystem.TryParalyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), true, status);
else
_stunSystem.TrySlowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), 0.5f, 0.5f, status);
_stunSystem.TrySlowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), true, 0.5f, 0.5f, status);
}
var slowdownTime = TimeSpan.FromSeconds(comp.SlowdownTime);
_jitterSystem.DoJitter(entity.Uid, slowdownTime, status:status);
_stutteringSystem.DoStutter(entity.Uid, slowdownTime, status);
_jitterSystem.DoJitter(entity.Uid, slowdownTime, true, status:status);
_stutteringSystem.DoStutter(entity.Uid, slowdownTime, true, status);
if (!comp.Owner.TryGetComponent<PowerCellSlotComponent>(out var slot) || slot.Cell == null || !(slot.Cell.CurrentCharge < comp.EnergyPerUse))
return;

View File

@@ -174,7 +174,7 @@ namespace Content.Server.Weapon.Ranged
{
//Wound them
EntitySystem.Get<DamageableSystem>().TryChangeDamage(user.Uid, ClumsyDamage);
EntitySystem.Get<StunSystem>().TryParalyze(user.Uid, TimeSpan.FromSeconds(3f));
EntitySystem.Get<StunSystem>().TryParalyze(user.Uid, TimeSpan.FromSeconds(3f), true);
// Apply salt to the wound ("Honk!")
SoundSystem.Play(

View File

@@ -53,12 +53,13 @@ namespace Content.Shared.Jittering
/// </remarks>
/// <param name="uid">Entity in question.</param>
/// <param name="time">For how much time to apply the effect.</param>
/// <param name="refresh">The status effect cooldown should be refreshed (true) or accumulated (false).</param>
/// <param name="amplitude">Jitteriness of the animation. See <see cref="MaxAmplitude"/> and <see cref="MinAmplitude"/>.</param>
/// <param name="frequency">Frequency for jittering. See <see cref="MaxFrequency"/> and <see cref="MinFrequency"/>.</param>
/// <param name="forceValueChange">Whether to change any existing jitter value even if they're greater than the ones we're setting.</param>
/// <param name="status">The status effects component to modify.</param>
/// <param name="alerts">The alerts component.</param>
public void DoJitter(EntityUid uid, TimeSpan time, float amplitude = 10f, float frequency = 4f, bool forceValueChange = false,
public void DoJitter(EntityUid uid, TimeSpan time, bool refresh, float amplitude = 10f, float frequency = 4f, bool forceValueChange = false,
StatusEffectsComponent? status = null,
SharedAlertsComponent? alerts = null)
{
@@ -68,7 +69,7 @@ namespace Content.Shared.Jittering
amplitude = Math.Clamp(amplitude, MinAmplitude, MaxAmplitude);
frequency = Math.Clamp(frequency, MinFrequency, MaxFrequency);
if (StatusEffects.TryAddStatusEffect<JitteringComponent>(uid, "Jitter", time, status, alerts))
if (StatusEffects.TryAddStatusEffect<JitteringComponent>(uid, "Jitter", time, refresh, status, alerts))
{
var jittering = EntityManager.GetComponent<JitteringComponent>(uid);

View File

@@ -68,7 +68,7 @@ namespace Content.Shared.Nutrition.EntitySystems
CreamedEntity(uid, creamPied, args);
_stunSystem.TryParalyze(uid, TimeSpan.FromSeconds(creamPie.ParalyzeTime));
_stunSystem.TryParalyze(uid, TimeSpan.FromSeconds(creamPie.ParalyzeTime), true);
}
protected virtual void CreamedEntity(EntityUid uid, CreamPiedComponent creamPied, ThrowHitByEvent args) {}

View File

@@ -64,7 +64,7 @@ namespace Content.Shared.Slippery
if (!component.Slippery
|| component.Owner.IsInContainer()
|| component.Slipped.Contains(uid)
|| !_statusEffectsSystem.CanApplyEffect(uid, "Stun"))
|| !_statusEffectsSystem.CanApplyEffect(uid, "Stun")) //Should be KnockedDown instead?
{
return false;
}
@@ -95,11 +95,17 @@ namespace Content.Shared.Slippery
otherBody.LinearVelocity *= component.LaunchForwardsMultiplier;
_stunSystem.TryParalyze(otherBody.OwnerUid, TimeSpan.FromSeconds(5));
bool playSound = !_statusEffectsSystem.HasStatusEffect(otherBody.OwnerUid, "KnockedDown");
_stunSystem.TryParalyze(otherBody.OwnerUid, TimeSpan.FromSeconds(component.ParalyzeTime), true);
component.Slipped.Add(otherBody.OwnerUid);
component.Dirty();
//Preventing from playing the slip sound when you are already knocked down.
if(playSound)
{
PlaySound(component);
}
_adminLog.Add(LogType.Slip, LogImpact.Low, $"{component.Owner} slipped on collision with {otherBody.Owner}");

View File

@@ -18,7 +18,7 @@ namespace Content.Shared.Slippery
{
public override string Name => "Slippery";
private float _paralyzeTime = 3f;
private float _paralyzeTime = 5f;
private float _intersectPercentage = 0.3f;
private float _requiredSlipSpeed = 5f;
private float _launchForwardsMultiplier = 1f;

View File

@@ -8,7 +8,7 @@ namespace Content.Shared.Speech.EntitySystems
public abstract class SharedStutteringSystem : EntitySystem
{
// For code in shared... I imagine we ain't getting accent prediction anytime soon so let's not bother.
public virtual void DoStutter(EntityUid uid, TimeSpan time, StatusEffectsComponent? status = null, SharedAlertsComponent? alerts = null)
public virtual void DoStutter(EntityUid uid, TimeSpan time, bool refresh, StatusEffectsComponent? status = null, SharedAlertsComponent? alerts = null)
{
}
}

View File

@@ -38,6 +38,13 @@ namespace Content.Shared.StatusEffect
[ViewVariables]
public (TimeSpan, TimeSpan) Cooldown;
/// <summary>
/// Specifies whether to refresh or accumulate the cooldown of the status effect.
/// true - refresh time, false - accumulate time.
/// </summary>
[ViewVariables]
public bool CooldownRefresh = true;
/// <summary>
/// The name of the relevant component that
/// was added alongside the effect, if any.
@@ -45,9 +52,10 @@ namespace Content.Shared.StatusEffect
[ViewVariables]
public string? RelevantComponent;
public StatusEffectState((TimeSpan, TimeSpan) cooldown, string? relevantComponent=null)
public StatusEffectState((TimeSpan, TimeSpan) cooldown, bool refresh, string? relevantComponent=null)
{
Cooldown = cooldown;
CooldownRefresh = refresh;
RelevantComponent = relevantComponent;
}
}

View File

@@ -64,7 +64,8 @@ namespace Content.Shared.StatusEffect
}
var time = effect.Value.Cooldown.Item2 - effect.Value.Cooldown.Item1;
TryAddStatusEffect(uid, effect.Key, time);
//TODO: Not sure how to handle refresh here.
TryAddStatusEffect(uid, effect.Key, time, true);
}
}
}
@@ -75,11 +76,12 @@ namespace Content.Shared.StatusEffect
/// <param name="uid">The entity to add the effect to.</param>
/// <param name="key">The status effect ID to add.</param>
/// <param name="time">How long the effect should last for.</param>
/// <param name="refresh">The status effect cooldown should be refreshed (true) or accumulated (false).</param>
/// <param name="status">The status effects component to change, if you already have it.</param>
/// <param name="alerts">The alerts component to modify, if the status effect has an alert.</param>
/// <returns>False if the effect could not be added or the component already exists, true otherwise.</returns>
/// <typeparam name="T">The component type to add and remove from the entity.</typeparam>
public bool TryAddStatusEffect<T>(EntityUid uid, string key, TimeSpan time,
public bool TryAddStatusEffect<T>(EntityUid uid, string key, TimeSpan time, bool refresh,
StatusEffectsComponent? status=null,
SharedAlertsComponent? alerts=null)
where T: Component, new()
@@ -89,7 +91,7 @@ namespace Content.Shared.StatusEffect
Resolve(uid, ref alerts, false);
if (TryAddStatusEffect(uid, key, time, status, alerts))
if (TryAddStatusEffect(uid, key, time, refresh, status, alerts))
{
// If they already have the comp, we just won't bother updating anything.
if (!EntityManager.HasComponent<T>(uid))
@@ -103,7 +105,7 @@ namespace Content.Shared.StatusEffect
return false;
}
public bool TryAddStatusEffect(EntityUid uid, string key, TimeSpan time, string component,
public bool TryAddStatusEffect(EntityUid uid, string key, TimeSpan time, bool refresh, string component,
StatusEffectsComponent? status = null,
SharedAlertsComponent? alerts = null)
{
@@ -112,7 +114,7 @@ namespace Content.Shared.StatusEffect
Resolve(uid, ref alerts, false);
if (TryAddStatusEffect(uid, key, time, status, alerts))
if (TryAddStatusEffect(uid, key, time, refresh, status, alerts))
{
// If they already have the comp, we just won't bother updating anything.
if (!EntityManager.HasComponent(uid, _componentFactory.GetRegistration(component).Type))
@@ -136,6 +138,7 @@ namespace Content.Shared.StatusEffect
/// <param name="uid">The entity to add the effect to.</param>
/// <param name="key">The status effect ID to add.</param>
/// <param name="time">How long the effect should last for.</param>
/// <param name="refresh">The status effect cooldown should be refreshed (true) or accumulated (false).</param>
/// <param name="status">The status effects component to change, if you already have it.</param>
/// <param name="alerts">The alerts component to modify, if the status effect has an alert.</param>
/// <returns>False if the effect could not be added, or if the effect already existed.</returns>
@@ -146,7 +149,7 @@ namespace Content.Shared.StatusEffect
/// If the effect already exists, it will simply replace the cooldown with the new one given.
/// If you want special 'effect merging' behavior, do it your own damn self!
/// </remarks>
public bool TryAddStatusEffect(EntityUid uid, string key, TimeSpan time,
public bool TryAddStatusEffect(EntityUid uid, string key, TimeSpan time, bool refresh,
StatusEffectsComponent? status=null,
SharedAlertsComponent? alerts=null)
{
@@ -163,14 +166,27 @@ namespace Content.Shared.StatusEffect
(TimeSpan, TimeSpan) cooldown = (_gameTiming.CurTime, _gameTiming.CurTime + time);
// If they already have this status effect, add the time onto it's cooldown rather than anything else.
if (HasStatusEffect(uid, key, status))
{
status.ActiveEffects[key].Cooldown.Item2 += time;
status.ActiveEffects[key].CooldownRefresh = refresh;
if(refresh)
{
//Making sure we don't reset a longer cooldown by applying a shorter one.
if((status.ActiveEffects[key].Cooldown.Item2 - _gameTiming.CurTime) < time)
{
//Refresh cooldown time.
status.ActiveEffects[key].Cooldown = cooldown;
}
}
else
{
status.ActiveEffects.Add(key, new StatusEffectState(cooldown, null));
//Accumulate cooldown time.
status.ActiveEffects[key].Cooldown.Item2 += time;
}
}
else
{
status.ActiveEffects.Add(key, new StatusEffectState(cooldown, refresh, null));
}
if (proto.Alert != null && alerts != null)

View File

@@ -118,7 +118,7 @@ namespace Content.Shared.Stunnable
/// <summary>
/// Stuns the entity, disallowing it from doing many interactions temporarily.
/// </summary>
public bool TryStun(EntityUid uid, TimeSpan time,
public bool TryStun(EntityUid uid, TimeSpan time, bool refresh,
StatusEffectsComponent? status = null,
SharedAlertsComponent? alerts = null)
{
@@ -130,13 +130,13 @@ namespace Content.Shared.Stunnable
Resolve(uid, ref alerts, false);
return _statusEffectSystem.TryAddStatusEffect<StunnedComponent>(uid, "Stun", time, alerts: alerts);
return _statusEffectSystem.TryAddStatusEffect<StunnedComponent>(uid, "Stun", time, refresh, alerts: alerts);
}
/// <summary>
/// Knocks down the entity, making it fall to the ground.
/// </summary>
public bool TryKnockdown(EntityUid uid, TimeSpan time,
public bool TryKnockdown(EntityUid uid, TimeSpan time, bool refresh,
StatusEffectsComponent? status = null,
SharedAlertsComponent? alerts = null)
{
@@ -148,13 +148,13 @@ namespace Content.Shared.Stunnable
Resolve(uid, ref alerts, false);
return _statusEffectSystem.TryAddStatusEffect<KnockedDownComponent>(uid, "KnockedDown", time, alerts: alerts);
return _statusEffectSystem.TryAddStatusEffect<KnockedDownComponent>(uid, "KnockedDown", time, refresh, alerts: alerts);
}
/// <summary>
/// Applies knockdown and stun to the entity temporarily.
/// </summary>
public bool TryParalyze(EntityUid uid, TimeSpan time,
public bool TryParalyze(EntityUid uid, TimeSpan time, bool refresh,
StatusEffectsComponent? status = null,
SharedAlertsComponent? alerts = null)
{
@@ -164,13 +164,13 @@ namespace Content.Shared.Stunnable
// Optional component.
Resolve(uid, ref alerts, false);
return TryKnockdown(uid, time, status, alerts) && TryStun(uid, time, status, alerts);
return TryKnockdown(uid, time, refresh, status, alerts) && TryStun(uid, time, refresh, status, alerts);
}
/// <summary>
/// Slows down the mob's walking/running speed temporarily
/// </summary>
public bool TrySlowdown(EntityUid uid, TimeSpan time,
public bool TrySlowdown(EntityUid uid, TimeSpan time, bool refresh,
float walkSpeedMultiplier = 1f, float runSpeedMultiplier = 1f,
StatusEffectsComponent? status = null,
SharedAlertsComponent? alerts = null)
@@ -184,7 +184,7 @@ namespace Content.Shared.Stunnable
if (time <= TimeSpan.Zero)
return false;
if (_statusEffectSystem.TryAddStatusEffect<SlowedDownComponent>(uid, "SlowedDown", time, status, alerts))
if (_statusEffectSystem.TryAddStatusEffect<SlowedDownComponent>(uid, "SlowedDown", time, refresh, status, alerts))
{
var slowed = EntityManager.GetComponent<SlowedDownComponent>(uid);
// Doesn't make much sense to have the "TrySlowdown" method speed up entities now does it?