Anomalies behaviours (#24683)

* Added new anomaly particle

* Add basic anomaly behaviour

* +2 parametres

* add functional to new particle

* add components to behaviours

* big content

* add shuffle, moved thing to server

* clean up

* fixes

* random pick redo

* bonjour behavioUr

* fix AJCM

* fix

* add some new behaviours

* power modifier behaviour

* rmeove timer

* new event for update ui fix

* refactor!

* fixes

* enum

* Fix mapinit

* Minor touches

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
Ed
2024-04-01 11:29:13 +03:00
committed by GitHub
parent de8b788856
commit a4ec01d471
29 changed files with 832 additions and 91 deletions

View File

@@ -1,4 +1,5 @@
using System.Numerics;
using Content.Shared.Anomaly.Prototypes;
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
@@ -166,6 +167,12 @@ public sealed partial class AnomalyComponent : Component
[DataField]
public AnomalousParticleType WeakeningParticleType;
/// <summary>
/// The particle type that change anomaly behaviour.
/// </summary>
[DataField]
public AnomalousParticleType TransformationParticleType;
#region Points and Vessels
/// <summary>
/// The vessel that the anomaly is connceted to. Stored so that multiple
@@ -185,7 +192,7 @@ public sealed partial class AnomalyComponent : Component
/// This doesn't include the point bonus for being unstable.
/// </summary>
[DataField("maxPointsPerSecond")]
public int MaxPointsPerSecond = 80;
public int MaxPointsPerSecond = 70;
/// <summary>
/// The multiplier applied to the point value for the
@@ -221,6 +228,31 @@ public sealed partial class AnomalyComponent : Component
[DataField, ViewVariables(VVAccess.ReadWrite)]
public EntProtoId? CoreInertPrototype;
#region Behavior Deviations
[DataField]
public ProtoId<AnomalyBehaviorPrototype>? CurrentBehavior;
/// <summary>
/// Presumption of anomaly to change behavior. The higher the number, the higher the chance that the anomaly will change its behavior.
/// </summary>
[DataField]
public float Continuity = 0f;
/// <summary>
/// Minimum contituty probability chance, that can be selected by anomaly on MapInit
/// </summary>
[DataField]
public float MinContituty = 0.1f;
/// <summary>
/// Maximum contituty probability chance, that can be selected by anomaly on MapInit
/// </summary>
[DataField]
public float MaxContituty = 1.0f;
#endregion
#region Floating Animation
/// <summary>
/// How long it takes to go from the bottom of the animation to the top.
@@ -247,13 +279,13 @@ public sealed partial class AnomalyComponent : Component
/// <param name="Stability"></param>
/// <param name="Severity"></param>
[ByRefEvent]
public readonly record struct AnomalyPulseEvent(EntityUid Anomaly, float Stability, float Severity);
public readonly record struct AnomalyPulseEvent(EntityUid Anomaly, float Stability, float Severity, float PowerModifier);
/// <summary>
/// Event raised on an anomaly when it reaches a supercritical point.
/// </summary>
[ByRefEvent]
public readonly record struct AnomalySupercriticalEvent(EntityUid Anomaly);
public readonly record struct AnomalySupercriticalEvent(EntityUid Anomaly, float PowerModifier);
/// <summary>
/// Event broadcast after an anomaly goes supercritical
@@ -282,3 +314,9 @@ public readonly record struct AnomalyStabilityChangedEvent(EntityUid Anomaly, fl
/// <param name="Anomaly">The anomaly being changed</param>
[ByRefEvent]
public readonly record struct AnomalyHealthChangedEvent(EntityUid Anomaly, float Health);
/// <summary>
/// Event broadcast when an anomaly's behavior is changed.
/// </summary>
[ByRefEvent]
public readonly record struct AnomalyBehaviorChangedEvent(EntityUid Anomaly, ProtoId<AnomalyBehaviorPrototype>? Old, ProtoId<AnomalyBehaviorPrototype>? New);

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using Content.Shared.Anomaly.Components;
using Content.Shared.Anomaly.Effects.Components;
using Content.Shared.Ghost;
@@ -27,8 +27,8 @@ public abstract class SharedGravityAnomalySystem : EntitySystem
private void OnAnomalyPulse(EntityUid uid, GravityAnomalyComponent component, ref AnomalyPulseEvent args)
{
var xform = Transform(uid);
var range = component.MaxThrowRange * args.Severity;
var strength = component.MaxThrowStrength * args.Severity;
var range = component.MaxThrowRange * args.Severity * args.PowerModifier;
var strength = component.MaxThrowStrength * args.Severity * args.PowerModifier;
var lookup = _lookup.GetEntitiesInRange(uid, range, LookupFlags.Dynamic | LookupFlags.Sundries);
var xformQuery = GetEntityQuery<TransformComponent>();
var worldPos = _xform.GetWorldPosition(xform, xformQuery);
@@ -61,8 +61,8 @@ public abstract class SharedGravityAnomalySystem : EntitySystem
var tiles = tileref.Select(t => (t.GridIndices, Tile.Empty)).ToList();
_mapSystem.SetTiles(xform.GridUid.Value, grid, tiles);
var range = component.MaxThrowRange * 2;
var strength = component.MaxThrowStrength * 2;
var range = component.MaxThrowRange * 2 * args.PowerModifier;
var strength = component.MaxThrowStrength * 2 * args.PowerModifier;
var lookup = _lookup.GetEntitiesInRange(uid, range, LookupFlags.Dynamic | LookupFlags.Sundries);
var xformQuery = GetEntityQuery<TransformComponent>();
var physQuery = GetEntityQuery<PhysicsComponent>();

View File

@@ -0,0 +1,45 @@
using Robust.Shared.Prototypes;
namespace Content.Shared.Anomaly.Prototypes;
[Prototype]
public sealed partial class AnomalyBehaviorPrototype : IPrototype
{
[IdDataField] public string ID { get; private set; } = default!;
/// <summary>
/// Description for anomaly scanner
/// </summary>
[DataField]
public string Description = string.Empty;
/// <summary>
/// modification of the number of points earned from an anomaly
/// </summary>
[DataField]
public float EarnPointModifier = 1f;
/// <summary>
/// deceleration or acceleration of the pulsation frequency of the anomaly
/// </summary>
[DataField]
public float PulseFrequencyModifier = 1f;
/// <summary>
/// pulse and supercrit power modifier
/// </summary>
[DataField]
public float PulsePowerModifier = 1f;
/// <summary>
/// how much the particles will affect the anomaly
/// </summary>
[DataField]
public float ParticleSensivity = 1f;
/// <summary>
/// Components that are added to the anomaly when this behavior is selected, and removed when another behavior is selected.
/// </summary>
[DataField(serverOnly: true)]
public ComponentRegistry Components = new();
}

View File

@@ -33,6 +33,7 @@ public enum AnomalousParticleType : byte
Delta,
Epsilon,
Zeta,
Sigma,
Default
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Administration.Logs;
using Content.Shared.Anomaly.Components;
using Content.Shared.Anomaly.Prototypes;
using Content.Shared.Damage;
using Content.Shared.Database;
using Content.Shared.Interaction;
@@ -14,6 +15,7 @@ using Robust.Shared.Network;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -33,6 +35,7 @@ public abstract class SharedAnomalySystem : EntitySystem
[Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] protected readonly SharedPopupSystem Popup = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IRobustRandom _random = default!;
public override void Initialize()
@@ -90,8 +93,7 @@ public abstract class SharedAnomalySystem : EntitySystem
return;
DebugTools.Assert(component.MinPulseLength > TimeSpan.FromSeconds(3)); // this is just to prevent lagspikes mispredicting pulses
var variation = Random.NextFloat(-component.PulseVariation, component.PulseVariation) + 1;
component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * variation;
RefreshPulseTimer(uid, component);
if (_net.IsServer)
Log.Info($"Performing anomaly pulse. Entity: {ToPrettyString(uid)}");
@@ -115,10 +117,25 @@ public abstract class SharedAnomalySystem : EntitySystem
pulse.EndTime = Timing.CurTime + pulse.PulseDuration;
Appearance.SetData(uid, AnomalyVisuals.IsPulsing, true);
var ev = new AnomalyPulseEvent(uid, component.Stability, component.Severity);
var powerMod = 1f;
if (component.CurrentBehavior != null)
{
var beh = _prototype.Index<AnomalyBehaviorPrototype>(component.CurrentBehavior);
powerMod = beh.PulsePowerModifier;
}
var ev = new AnomalyPulseEvent(uid, component.Stability, component.Severity, powerMod);
RaiseLocalEvent(uid, ref ev, true);
}
public void RefreshPulseTimer(EntityUid uid, AnomalyComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
var variation = Random.NextFloat(-component.PulseVariation, component.PulseVariation) + 1;
component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * variation;
}
/// <summary>
/// Begins the animation for going supercritical
/// </summary>
@@ -159,7 +176,14 @@ public abstract class SharedAnomalySystem : EntitySystem
if (_net.IsServer)
Log.Info($"Raising supercritical event. Entity: {ToPrettyString(uid)}");
var ev = new AnomalySupercriticalEvent(uid);
var powerMod = 1f;
if (component.CurrentBehavior != null)
{
var beh = _prototype.Index<AnomalyBehaviorPrototype>(component.CurrentBehavior);
powerMod = beh.PulsePowerModifier;
}
var ev = new AnomalySupercriticalEvent(uid, powerMod);
RaiseLocalEvent(uid, ref ev, true);
EndAnomaly(uid, component, true);
@@ -276,8 +300,17 @@ public abstract class SharedAnomalySystem : EntitySystem
public TimeSpan GetPulseLength(AnomalyComponent component)
{
DebugTools.Assert(component.MaxPulseLength > component.MinPulseLength);
var modifier = Math.Clamp((component.Stability - component.GrowthThreshold) / component.GrowthThreshold, 0, 1);
return (component.MaxPulseLength - component.MinPulseLength) * modifier + component.MinPulseLength;
var modifier = Math.Clamp((component.Stability - component.GrowthThreshold) / component.GrowthThreshold, 0, 1);
var lenght = (component.MaxPulseLength - component.MinPulseLength) * modifier + component.MinPulseLength;
//Apply behavior modifier
if (component.CurrentBehavior != null)
{
var behavior = _prototype.Index(component.CurrentBehavior.Value);
lenght *= behavior.PulseFrequencyModifier;
}
return lenght;
}
/// <summary>
@@ -335,14 +368,14 @@ public abstract class SharedAnomalySystem : EntitySystem
/// <summary>
/// Gets random points around the anomaly based on the given parameters.
/// </summary>
public List<TileRef>? GetSpawningPoints(EntityUid uid, float stability, float severity, AnomalySpawnSettings settings)
public List<TileRef>? GetSpawningPoints(EntityUid uid, float stability, float severity, AnomalySpawnSettings settings, float powerModifier = 1f)
{
var xform = Transform(uid);
if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
return null;
var amount = (int) (MathHelper.Lerp(settings.MinAmount, settings.MaxAmount, severity * stability) + 0.5f);
var amount = (int) (MathHelper.Lerp(settings.MinAmount, settings.MaxAmount, severity * stability * powerModifier) + 0.5f);
var localpos = xform.Coordinates.Position;
var tilerefs = grid.GetLocalTilesIntersecting(