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:
@@ -1,9 +1,9 @@
|
||||
<controls:FancyWindow
|
||||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'anomaly-scanner-ui-title'}"
|
||||
MinSize="350 260"
|
||||
SetSize="350 260">
|
||||
MinSize="350 400"
|
||||
SetSize="350 400">
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True" Margin="10 0 10 10">
|
||||
<RichTextLabel Name="TextDisplay"></RichTextLabel>
|
||||
</BoxContainer>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.Anomaly.Components;
|
||||
using Content.Server.Anomaly.Components;
|
||||
using Content.Shared.Anomaly;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
@@ -21,6 +21,7 @@ public sealed partial class AnomalySystem
|
||||
|
||||
SubscribeLocalEvent<AnomalySeverityChangedEvent>(OnScannerAnomalySeverityChanged);
|
||||
SubscribeLocalEvent<AnomalyHealthChangedEvent>(OnScannerAnomalyHealthChanged);
|
||||
SubscribeLocalEvent<AnomalyBehaviorChangedEvent>(OnScannerAnomalyBehaviorChanged);
|
||||
}
|
||||
|
||||
private void OnScannerAnomalyShutdown(ref AnomalyShutdownEvent args)
|
||||
@@ -67,6 +68,17 @@ public sealed partial class AnomalySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScannerAnomalyBehaviorChanged(ref AnomalyBehaviorChangedEvent args)
|
||||
{
|
||||
var query = EntityQueryEnumerator<AnomalyScannerComponent>();
|
||||
while (query.MoveNext(out var uid, out var component))
|
||||
{
|
||||
if (component.ScannedAnomaly != args.Anomaly)
|
||||
continue;
|
||||
UpdateScannerUi(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScannerUiOpened(EntityUid uid, AnomalyScannerComponent component, BoundUIOpenedEvent args)
|
||||
{
|
||||
UpdateScannerUi(uid, component);
|
||||
@@ -132,8 +144,20 @@ public sealed partial class AnomalySystem
|
||||
return msg;
|
||||
}
|
||||
|
||||
TryComp<SecretDataAnomalyComponent>(anomaly, out var secret);
|
||||
|
||||
//Severity
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.Severity))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-severity-percentage", ("percent", anomalyComp.Severity.ToString("P"))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Stability
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.Stability))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-stability-unknown"));
|
||||
else
|
||||
{
|
||||
string stateLoc;
|
||||
if (anomalyComp.Stability < anomalyComp.DecayThreshold)
|
||||
stateLoc = Loc.GetString("anomaly-scanner-stability-low");
|
||||
@@ -142,19 +166,73 @@ public sealed partial class AnomalySystem
|
||||
else
|
||||
stateLoc = Loc.GetString("anomaly-scanner-stability-medium");
|
||||
msg.AddMarkup(stateLoc);
|
||||
}
|
||||
msg.PushNewline();
|
||||
|
||||
//Point output
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.OutputPoint))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-point-output", ("point", GetAnomalyPointValue(anomaly, anomalyComp))));
|
||||
msg.PushNewline();
|
||||
msg.PushNewline();
|
||||
|
||||
//Particles title
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-readout"));
|
||||
msg.PushNewline();
|
||||
|
||||
//Danger
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleDanger))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-danger", ("type", GetParticleLocale(anomalyComp.SeverityParticleType))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Unstable
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleUnstable))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-unstable", ("type", GetParticleLocale(anomalyComp.DestabilizingParticleType))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Containment
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleContainment))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-containment", ("type", GetParticleLocale(anomalyComp.WeakeningParticleType))));
|
||||
msg.PushNewline();
|
||||
|
||||
//Transformation
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.ParticleTransformation))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation-unknown"));
|
||||
else
|
||||
msg.AddMarkup(Loc.GetString("anomaly-scanner-particle-transformation", ("type", GetParticleLocale(anomalyComp.TransformationParticleType))));
|
||||
|
||||
|
||||
//Behavior
|
||||
msg.PushNewline();
|
||||
msg.PushNewline();
|
||||
msg.AddMarkup(Loc.GetString("anomaly-behavior-title"));
|
||||
msg.PushNewline();
|
||||
|
||||
if (secret != null && secret.Secret.Contains(AnomalySecretData.Behavior))
|
||||
msg.AddMarkup(Loc.GetString("anomaly-behavior-unknown"));
|
||||
else
|
||||
{
|
||||
if (anomalyComp.CurrentBehavior != null)
|
||||
{
|
||||
var behavior = _prototype.Index(anomalyComp.CurrentBehavior.Value);
|
||||
|
||||
msg.AddMarkup("- " + Loc.GetString(behavior.Description));
|
||||
msg.PushNewline();
|
||||
var mod = Math.Floor((behavior.EarnPointModifier) * 100);
|
||||
msg.AddMarkup("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod)));
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.AddMarkup(Loc.GetString("anomaly-behavior-balanced"));
|
||||
}
|
||||
}
|
||||
|
||||
//The timer at the end here is actually added in the ui itself.
|
||||
return msg;
|
||||
|
||||
@@ -8,13 +8,18 @@ using Content.Server.Radio.EntitySystems;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Anomaly;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Content.Shared.Anomaly.Prototypes;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Server.Anomaly;
|
||||
|
||||
@@ -33,13 +38,20 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
[Dependency] private readonly SharedPointLightSystem _pointLight = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly RadioSystem _radio = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly RadiationSystem _radiation = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly IComponentFactory _componentFactory = default!;
|
||||
[Dependency] private readonly ISerializationManager _serialization = default!;
|
||||
[Dependency] private readonly IEntityManager _entity = default!;
|
||||
|
||||
public const float MinParticleVariation = 0.8f;
|
||||
public const float MaxParticleVariation = 1.2f;
|
||||
|
||||
[ValidatePrototypeId<WeightedRandomPrototype>]
|
||||
const string WeightListProto = "AnomalyBehaviorList";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -54,25 +66,34 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
InitializeCommands();
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, AnomalyComponent component, MapInitEvent args)
|
||||
private void OnMapInit(Entity<AnomalyComponent> anomaly, ref MapInitEvent args)
|
||||
{
|
||||
component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * 3; // longer the first time
|
||||
ChangeAnomalyStability(uid, Random.NextFloat(component.InitialStabilityRange.Item1 , component.InitialStabilityRange.Item2), component);
|
||||
ChangeAnomalySeverity(uid, Random.NextFloat(component.InitialSeverityRange.Item1, component.InitialSeverityRange.Item2), component);
|
||||
anomaly.Comp.NextPulseTime = Timing.CurTime + GetPulseLength(anomaly.Comp) * 3; // longer the first time
|
||||
ChangeAnomalyStability(anomaly, Random.NextFloat(anomaly.Comp.InitialStabilityRange.Item1 , anomaly.Comp.InitialStabilityRange.Item2), anomaly.Comp);
|
||||
ChangeAnomalySeverity(anomaly, Random.NextFloat(anomaly.Comp.InitialSeverityRange.Item1, anomaly.Comp.InitialSeverityRange.Item2), anomaly.Comp);
|
||||
|
||||
ShuffleParticlesEffect(anomaly.Comp);
|
||||
anomaly.Comp.Continuity = _random.NextFloat(anomaly.Comp.MinContituty, anomaly.Comp.MaxContituty);
|
||||
SetBehavior(anomaly, GetRandomBehavior());
|
||||
}
|
||||
|
||||
public void ShuffleParticlesEffect(AnomalyComponent anomaly)
|
||||
{
|
||||
var particles = new List<AnomalousParticleType>
|
||||
{ AnomalousParticleType.Delta, AnomalousParticleType.Epsilon, AnomalousParticleType.Zeta };
|
||||
component.SeverityParticleType = Random.PickAndTake(particles);
|
||||
component.DestabilizingParticleType = Random.PickAndTake(particles);
|
||||
component.WeakeningParticleType = Random.PickAndTake(particles);
|
||||
{ AnomalousParticleType.Delta, AnomalousParticleType.Epsilon, AnomalousParticleType.Zeta, AnomalousParticleType.Sigma };
|
||||
|
||||
anomaly.SeverityParticleType = Random.PickAndTake(particles);
|
||||
anomaly.DestabilizingParticleType = Random.PickAndTake(particles);
|
||||
anomaly.WeakeningParticleType = Random.PickAndTake(particles);
|
||||
anomaly.TransformationParticleType = Random.PickAndTake(particles);
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, AnomalyComponent component, ComponentShutdown args)
|
||||
private void OnShutdown(Entity<AnomalyComponent> anomaly, ref ComponentShutdown args)
|
||||
{
|
||||
EndAnomaly(uid, component);
|
||||
EndAnomaly(anomaly);
|
||||
}
|
||||
|
||||
private void OnStartCollide(EntityUid uid, AnomalyComponent component, ref StartCollideEvent args)
|
||||
private void OnStartCollide(Entity<AnomalyComponent> anomaly, ref StartCollideEvent args)
|
||||
{
|
||||
if (!TryComp<AnomalousParticleComponent>(args.OtherEntity, out var particle))
|
||||
return;
|
||||
@@ -80,21 +101,33 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
if (args.OtherFixtureId != particle.FixtureId)
|
||||
return;
|
||||
|
||||
var behaviorMod = 1f;
|
||||
if (anomaly.Comp.CurrentBehavior != null)
|
||||
{
|
||||
var b = _prototype.Index(anomaly.Comp.CurrentBehavior.Value);
|
||||
behaviorMod = b.ParticleSensivity;
|
||||
}
|
||||
// small function to randomize because it's easier to read like this
|
||||
float VaryValue(float v) => v * Random.NextFloat(MinParticleVariation, MaxParticleVariation);
|
||||
float VaryValue(float v) => v * behaviorMod * Random.NextFloat(MinParticleVariation, MaxParticleVariation);
|
||||
|
||||
if (particle.ParticleType == component.DestabilizingParticleType || particle.DestabilzingOverride)
|
||||
if (particle.ParticleType == anomaly.Comp.DestabilizingParticleType || particle.DestabilzingOverride)
|
||||
{
|
||||
ChangeAnomalyStability(uid, VaryValue(particle.StabilityPerDestabilizingHit), component);
|
||||
ChangeAnomalyStability(anomaly, VaryValue(particle.StabilityPerDestabilizingHit), anomaly.Comp);
|
||||
}
|
||||
if (particle.ParticleType == component.SeverityParticleType || particle.SeverityOverride)
|
||||
if (particle.ParticleType == anomaly.Comp.SeverityParticleType || particle.SeverityOverride)
|
||||
{
|
||||
ChangeAnomalySeverity(uid, VaryValue(particle.SeverityPerSeverityHit), component);
|
||||
ChangeAnomalySeverity(anomaly, VaryValue(particle.SeverityPerSeverityHit), anomaly.Comp);
|
||||
}
|
||||
if (particle.ParticleType == component.WeakeningParticleType || particle.WeakeningOverride)
|
||||
if (particle.ParticleType == anomaly.Comp.WeakeningParticleType || particle.WeakeningOverride)
|
||||
{
|
||||
ChangeAnomalyHealth(uid, VaryValue(particle.HealthPerWeakeningeHit), component);
|
||||
ChangeAnomalyStability(uid, VaryValue(particle.StabilityPerWeakeningeHit), component);
|
||||
ChangeAnomalyHealth(anomaly, VaryValue(particle.HealthPerWeakeningeHit), anomaly.Comp);
|
||||
ChangeAnomalyStability(anomaly, VaryValue(particle.StabilityPerWeakeningeHit), anomaly.Comp);
|
||||
}
|
||||
if (particle.ParticleType == anomaly.Comp.TransformationParticleType || particle.TransmutationOverride)
|
||||
{
|
||||
ChangeAnomalySeverity(anomaly, VaryValue(particle.SeverityPerSeverityHit), anomaly.Comp);
|
||||
if (_random.Prob(anomaly.Comp.Continuity))
|
||||
SetBehavior(anomaly, GetRandomBehavior());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +149,13 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
//penalty of up to 50% based on health
|
||||
multiplier *= MathF.Pow(1.5f, component.Health) - 0.5f;
|
||||
|
||||
//Apply behavior modifier
|
||||
if (component.CurrentBehavior != null)
|
||||
{
|
||||
var behavior = _prototype.Index(component.CurrentBehavior.Value);
|
||||
multiplier *= behavior.EarnPointModifier;
|
||||
}
|
||||
|
||||
var severityValue = 1 / (1 + MathF.Pow(MathF.E, -7 * (component.Severity - 0.5f)));
|
||||
|
||||
return (int) ((component.MaxPointsPerSecond - component.MinPointsPerSecond) * severityValue * multiplier) + component.MinPointsPerSecond;
|
||||
@@ -133,6 +173,7 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
AnomalousParticleType.Delta => Loc.GetString("anomaly-particles-delta"),
|
||||
AnomalousParticleType.Epsilon => Loc.GetString("anomaly-particles-epsilon"),
|
||||
AnomalousParticleType.Zeta => Loc.GetString("anomaly-particles-zeta"),
|
||||
AnomalousParticleType.Sigma => Loc.GetString("anomaly-particles-sigma"),
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
@@ -144,4 +185,40 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
UpdateGenerator();
|
||||
UpdateVessels();
|
||||
}
|
||||
|
||||
#region Behavior
|
||||
private string GetRandomBehavior()
|
||||
{
|
||||
var weightList = _prototype.Index<WeightedRandomPrototype>(WeightListProto);
|
||||
return weightList.Pick(_random);
|
||||
}
|
||||
|
||||
private void SetBehavior(Entity<AnomalyComponent> anomaly, ProtoId<AnomalyBehaviorPrototype> behaviorProto)
|
||||
{
|
||||
if (anomaly.Comp.CurrentBehavior == behaviorProto)
|
||||
return;
|
||||
|
||||
if (anomaly.Comp.CurrentBehavior != null)
|
||||
RemoveBehavior(anomaly, anomaly.Comp.CurrentBehavior.Value);
|
||||
|
||||
//event broadcast
|
||||
var ev = new AnomalyBehaviorChangedEvent(anomaly, anomaly.Comp.CurrentBehavior, behaviorProto);
|
||||
anomaly.Comp.CurrentBehavior = behaviorProto;
|
||||
RaiseLocalEvent(anomaly, ref ev, true);
|
||||
|
||||
var behavior = _prototype.Index(behaviorProto);
|
||||
|
||||
EntityManager.AddComponents(anomaly, behavior.Components);
|
||||
}
|
||||
|
||||
private void RemoveBehavior(Entity<AnomalyComponent> anomaly, ProtoId<AnomalyBehaviorPrototype> behaviorProto)
|
||||
{
|
||||
if (anomaly.Comp.CurrentBehavior == null)
|
||||
return;
|
||||
|
||||
var behavior = _prototype.Index(anomaly.Comp.CurrentBehavior.Value);
|
||||
|
||||
EntityManager.RemoveComponents(anomaly, behavior.Components);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -13,58 +13,64 @@ public sealed partial class AnomalousParticleComponent : Component
|
||||
/// The type of particle that the projectile
|
||||
/// imbues onto the anomaly on contact.
|
||||
/// </summary>
|
||||
[DataField("particleType", required: true)]
|
||||
[DataField(required: true)]
|
||||
public AnomalousParticleType ParticleType;
|
||||
|
||||
/// <summary>
|
||||
/// The fixture that's checked on collision.
|
||||
/// </summary>
|
||||
[DataField("fixtureId")]
|
||||
[DataField]
|
||||
public string FixtureId = "projectile";
|
||||
|
||||
/// <summary>
|
||||
/// The amount that the <see cref="AnomalyComponent.Severity"/> increases by when hit
|
||||
/// of an anomalous particle of <seealso cref="AnomalyComponent.SeverityParticleType"/>.
|
||||
/// </summary>
|
||||
[DataField("severityPerSeverityHit")]
|
||||
[DataField]
|
||||
public float SeverityPerSeverityHit = 0.025f;
|
||||
|
||||
/// <summary>
|
||||
/// The amount that the <see cref="AnomalyComponent.Stability"/> increases by when hit
|
||||
/// of an anomalous particle of <seealso cref="AnomalyComponent.DestabilizingParticleType"/>.
|
||||
/// </summary>
|
||||
[DataField("stabilityPerDestabilizingHit")]
|
||||
[DataField]
|
||||
public float StabilityPerDestabilizingHit = 0.04f;
|
||||
|
||||
/// <summary>
|
||||
/// The amount that the <see cref="AnomalyComponent.Stability"/> increases by when hit
|
||||
/// of an anomalous particle of <seealso cref="AnomalyComponent.DestabilizingParticleType"/>.
|
||||
/// </summary>
|
||||
[DataField("healthPerWeakeningeHit")]
|
||||
[DataField]
|
||||
public float HealthPerWeakeningeHit = -0.05f;
|
||||
|
||||
/// <summary>
|
||||
/// The amount that the <see cref="AnomalyComponent.Stability"/> increases by when hit
|
||||
/// of an anomalous particle of <seealso cref="AnomalyComponent.DestabilizingParticleType"/>.
|
||||
/// </summary>
|
||||
[DataField("stabilityPerWeakeningeHit")]
|
||||
[DataField]
|
||||
public float StabilityPerWeakeningeHit = -0.1f;
|
||||
|
||||
/// <summary>
|
||||
/// If this is true then the particle will always affect the stability of the anomaly.
|
||||
/// </summary>
|
||||
[DataField("destabilzingOverride")]
|
||||
[DataField]
|
||||
public bool DestabilzingOverride = false;
|
||||
|
||||
/// <summary>
|
||||
/// If this is true then the particle will always affect the weakeness of the anomaly.
|
||||
/// </summary>
|
||||
[DataField("weakeningOverride")]
|
||||
[DataField]
|
||||
public bool WeakeningOverride = false;
|
||||
|
||||
/// <summary>
|
||||
/// If this is true then the particle will always affect the severity of the anomaly.
|
||||
/// </summary>
|
||||
[DataField("severityOverride")]
|
||||
[DataField]
|
||||
public bool SeverityOverride = false;
|
||||
|
||||
/// <summary>
|
||||
/// If this is true then the particle will always affect the behaviour.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool TransmutationOverride = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using Content.Server.Anomaly.Effects;
|
||||
|
||||
namespace Content.Server.Anomaly.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Hides some information about the anomaly when scanning it
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(SecretDataAnomalySystem), typeof(AnomalySystem))]
|
||||
public sealed partial class SecretDataAnomalyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimum hidden data elements on MapInit
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int RandomStartSecretMin = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum hidden data elements on MapInit
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int RandomStartSecretMax = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Current secret data
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<AnomalySecretData> Secret = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enum with secret data field variants
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public enum AnomalySecretData : byte
|
||||
{
|
||||
Severity,
|
||||
Stability,
|
||||
OutputPoint,
|
||||
ParticleDanger,
|
||||
ParticleUnstable,
|
||||
ParticleContainment,
|
||||
ParticleTransformation,
|
||||
Behavior,
|
||||
Default
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Content.Server.Anomaly.Effects;
|
||||
|
||||
namespace Content.Server.Anomaly.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Shuffle Particle types in some situations
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(ShuffleParticlesAnomalySystem))]
|
||||
public sealed partial class ShuffleParticlesAnomalyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Prob() chance to randomize particle types after Anomaly pulation
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool ShuffleOnPulse = false;
|
||||
|
||||
/// <summary>
|
||||
/// Prob() chance to randomize particle types after APE or CHIMP projectile
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool ShuffleOnParticleHit = false;
|
||||
|
||||
/// <summary>
|
||||
/// Chance to random particles
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float Prob = 0.5f;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Anomaly.Components;
|
||||
using Content.Shared.Administration.Logs;
|
||||
@@ -33,7 +33,7 @@ public sealed class BluespaceAnomalySystem : EntitySystem
|
||||
{
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
var xform = xformQuery.GetComponent(uid);
|
||||
var range = component.MaxShuffleRadius * args.Severity;
|
||||
var range = component.MaxShuffleRadius * args.Severity * args.PowerModifier;
|
||||
var mobs = new HashSet<Entity<MobStateComponent>>();
|
||||
_lookup.GetEntitiesInRange(xform.Coordinates, range, mobs);
|
||||
var allEnts = new ValueList<EntityUid>(mobs.Select(m => m.Owner)) { uid };
|
||||
@@ -56,7 +56,7 @@ public sealed class BluespaceAnomalySystem : EntitySystem
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var mapPos = _xform.GetWorldPosition(xform);
|
||||
var radius = component.SupercriticalTeleportRadius;
|
||||
var radius = component.SupercriticalTeleportRadius * args.PowerModifier;
|
||||
var gridBounds = new Box2(mapPos - new Vector2(radius, radius), mapPos + new Vector2(radius, radius));
|
||||
var mobs = new HashSet<Entity<MobStateComponent>>();
|
||||
_lookup.GetEntitiesInRange(xform.Coordinates, component.MaxShuffleRadius, mobs);
|
||||
|
||||
@@ -28,7 +28,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem
|
||||
|
||||
private void OnPulse(Entity<ElectricityAnomalyComponent> anomaly, ref AnomalyPulseEvent args)
|
||||
{
|
||||
var range = anomaly.Comp.MaxElectrocuteRange * args.Stability;
|
||||
var range = anomaly.Comp.MaxElectrocuteRange * args.Stability * args.PowerModifier;
|
||||
|
||||
int boltCount = (int)MathF.Floor(MathHelper.Lerp((float)anomaly.Comp.MinBoltCount, (float)anomaly.Comp.MaxBoltCount, args.Severity));
|
||||
|
||||
@@ -37,7 +37,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem
|
||||
|
||||
private void OnSupercritical(Entity<ElectricityAnomalyComponent> anomaly, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
var range = anomaly.Comp.MaxElectrocuteRange * 3;
|
||||
var range = anomaly.Comp.MaxElectrocuteRange * 3 * args.PowerModifier;
|
||||
|
||||
_emp.EmpPulse(_transform.GetMapCoordinates(anomaly), range, anomaly.Comp.EmpEnergyConsumption, anomaly.Comp.EmpDisabledDuration);
|
||||
_lightning.ShootRandomLightnings(anomaly, range, anomaly.Comp.MaxBoltCount * 3, arcDepth: 3);
|
||||
|
||||
@@ -35,7 +35,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem
|
||||
if (!entry.Settings.SpawnOnPulse)
|
||||
continue;
|
||||
|
||||
SpawnEntities(component, entry, args.Stability, args.Severity);
|
||||
SpawnEntities(component, entry, args.Stability, args.Severity, args.PowerModifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem
|
||||
if (!entry.Settings.SpawnOnSuperCritical)
|
||||
continue;
|
||||
|
||||
SpawnEntities(component, entry, 1, 1);
|
||||
SpawnEntities(component, entry, 1, 1, args.PowerModifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem
|
||||
if (!entry.Settings.SpawnOnShutdown || args.Supercritical)
|
||||
continue;
|
||||
|
||||
SpawnEntities(component, entry, 1, 1);
|
||||
SpawnEntities(component, entry, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem
|
||||
if (!entry.Settings.SpawnOnStabilityChanged)
|
||||
continue;
|
||||
|
||||
SpawnEntities(component, entry, args.Stability, args.Severity);
|
||||
SpawnEntities(component, entry, args.Stability, args.Severity, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,17 +79,17 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem
|
||||
if (!entry.Settings.SpawnOnSeverityChanged)
|
||||
continue;
|
||||
|
||||
SpawnEntities(component, entry, args.Stability, args.Severity);
|
||||
SpawnEntities(component, entry, args.Stability, args.Severity, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnEntities(Entity<EntitySpawnAnomalyComponent> anomaly, EntitySpawnSettingsEntry entry, float stability, float severity)
|
||||
private void SpawnEntities(Entity<EntitySpawnAnomalyComponent> anomaly, EntitySpawnSettingsEntry entry, float stability, float severity, float powerMod)
|
||||
{
|
||||
var xform = Transform(anomaly);
|
||||
if (!TryComp(xform.GridUid, out MapGridComponent? grid))
|
||||
return;
|
||||
|
||||
var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings);
|
||||
var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings, powerMod);
|
||||
if (tiles == null)
|
||||
return;
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ public sealed class InjectionAnomalySystem : EntitySystem
|
||||
|
||||
private void OnPulse(Entity<InjectionAnomalyComponent> entity, ref AnomalyPulseEvent args)
|
||||
{
|
||||
PulseScalableEffect(entity, entity.Comp.InjectRadius, entity.Comp.MaxSolutionInjection * args.Severity);
|
||||
PulseScalableEffect(entity, entity.Comp.InjectRadius * args.PowerModifier, entity.Comp.MaxSolutionInjection * args.Severity * args.PowerModifier);
|
||||
}
|
||||
|
||||
private void OnSupercritical(Entity<InjectionAnomalyComponent> entity, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
PulseScalableEffect(entity, entity.Comp.SuperCriticalInjectRadius, entity.Comp.SuperCriticalSolutionInjection);
|
||||
PulseScalableEffect(entity, entity.Comp.SuperCriticalInjectRadius * args.PowerModifier, entity.Comp.SuperCriticalSolutionInjection * args.PowerModifier);
|
||||
}
|
||||
|
||||
private void PulseScalableEffect(Entity<InjectionAnomalyComponent> entity, float injectRadius, float maxInject)
|
||||
|
||||
@@ -31,12 +31,12 @@ public sealed class ProjectileAnomalySystem : EntitySystem
|
||||
|
||||
private void OnPulse(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||
{
|
||||
ShootProjectilesAtEntities(uid, component, args.Severity);
|
||||
ShootProjectilesAtEntities(uid, component, args.Severity * args.PowerModifier);
|
||||
}
|
||||
|
||||
private void OnSupercritical(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
ShootProjectilesAtEntities(uid, component, 1.0f);
|
||||
ShootProjectilesAtEntities(uid, component, args.PowerModifier);
|
||||
}
|
||||
|
||||
private void ShootProjectilesAtEntities(EntityUid uid, ProjectileAnomalyComponent component, float severity)
|
||||
|
||||
@@ -25,9 +25,10 @@ public sealed class PuddleCreateAnomalySystem : EntitySystem
|
||||
return;
|
||||
|
||||
var xform = Transform(entity.Owner);
|
||||
var puddleSol = _solutionContainer.SplitSolution(sol.Value, entity.Comp.MaxPuddleSize * args.Severity);
|
||||
var puddleSol = _solutionContainer.SplitSolution(sol.Value, entity.Comp.MaxPuddleSize * args.Severity * args.PowerModifier);
|
||||
_puddle.TrySplashSpillAt(entity.Owner, xform.Coordinates, puddleSol, out _);
|
||||
}
|
||||
|
||||
private void OnSupercritical(Entity<PuddleCreateAnomalyComponent> entity, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
if (!_solutionContainer.TryGetSolution(entity.Owner, entity.Comp.Solution, out _, out var sol))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.Components;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Content.Shared.Anomaly.Effects.Components;
|
||||
@@ -24,14 +24,14 @@ public sealed class PyroclasticAnomalySystem : EntitySystem
|
||||
private void OnPulse(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var ignitionRadius = component.MaximumIgnitionRadius * args.Stability;
|
||||
var ignitionRadius = component.MaximumIgnitionRadius * args.Stability * args.PowerModifier;
|
||||
IgniteNearby(uid, xform.Coordinates, args.Severity, ignitionRadius);
|
||||
}
|
||||
|
||||
private void OnSupercritical(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
IgniteNearby(uid, xform.Coordinates, 1, component.MaximumIgnitionRadius * 2);
|
||||
IgniteNearby(uid, xform.Coordinates, 1, component.MaximumIgnitionRadius * 2 * args.PowerModifier);
|
||||
}
|
||||
|
||||
public void IgniteNearby(EntityUid uid, EntityCoordinates coordinates, float severity, float radius)
|
||||
|
||||
40
Content.Server/Anomaly/Effects/SecretDataAnomalySystem.cs
Normal file
40
Content.Server/Anomaly/Effects/SecretDataAnomalySystem.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Content.Server.Anomaly.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Anomaly.Effects;
|
||||
|
||||
public sealed class SecretDataAnomalySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
private readonly List<AnomalySecretData> _deita = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<SecretDataAnomalyComponent, MapInitEvent>(OnMapInit);
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, SecretDataAnomalyComponent anomaly, MapInitEvent args)
|
||||
{
|
||||
RandomizeSecret(uid,_random.Next(anomaly.RandomStartSecretMin, anomaly.RandomStartSecretMax), anomaly);
|
||||
}
|
||||
|
||||
public void RandomizeSecret(EntityUid uid, int count, SecretDataAnomalyComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
component.Secret.Clear();
|
||||
|
||||
// I also considered just adding all the enum values and pruning but that seems more wasteful.
|
||||
_deita.Clear();
|
||||
_deita.AddRange(Enum.GetValues<AnomalySecretData>());
|
||||
var actualCount = Math.Min(count, _deita.Count);
|
||||
|
||||
for (int i = 0; i < actualCount; i++)
|
||||
{
|
||||
component.Secret.Add(_random.PickAndTake(_deita));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using Content.Server.Anomaly.Components;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Anomaly.Effects;
|
||||
public sealed class ShuffleParticlesAnomalySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AnomalySystem _anomaly = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<ShuffleParticlesAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
||||
SubscribeLocalEvent<ShuffleParticlesAnomalyComponent, StartCollideEvent>(OnStartCollide);
|
||||
}
|
||||
|
||||
private void OnStartCollide(EntityUid uid, ShuffleParticlesAnomalyComponent shuffle, StartCollideEvent args)
|
||||
{
|
||||
if (!TryComp<AnomalyComponent>(uid, out var anomaly))
|
||||
return;
|
||||
|
||||
if (shuffle.ShuffleOnParticleHit && _random.Prob(shuffle.Prob))
|
||||
_anomaly.ShuffleParticlesEffect(anomaly);
|
||||
|
||||
if (!TryComp<AnomalousParticleComponent>(args.OtherEntity, out var particle))
|
||||
return;
|
||||
}
|
||||
|
||||
private void OnPulse(EntityUid uid, ShuffleParticlesAnomalyComponent shuffle, AnomalyPulseEvent args)
|
||||
{
|
||||
if (!TryComp<AnomalyComponent>(uid, out var anomaly))
|
||||
return;
|
||||
|
||||
if (shuffle.ShuffleOnPulse && _random.Prob(shuffle.Prob))
|
||||
{
|
||||
_anomaly.ShuffleParticlesEffect(anomaly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem
|
||||
if (!entry.Settings.SpawnOnPulse)
|
||||
continue;
|
||||
|
||||
SpawnTiles(component, entry, args.Stability, args.Severity);
|
||||
SpawnTiles(component, entry, args.Stability, args.Severity, args.PowerModifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem
|
||||
if (!entry.Settings.SpawnOnSuperCritical)
|
||||
continue;
|
||||
|
||||
SpawnTiles(component, entry, 1, 1);
|
||||
SpawnTiles(component, entry, 1, 1, args.PowerModifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem
|
||||
if (!entry.Settings.SpawnOnShutdown || args.Supercritical)
|
||||
continue;
|
||||
|
||||
SpawnTiles(component, entry, 1, 1);
|
||||
SpawnTiles(component, entry, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem
|
||||
if (!entry.Settings.SpawnOnStabilityChanged)
|
||||
continue;
|
||||
|
||||
SpawnTiles(component, entry, args.Stability, args.Severity);
|
||||
SpawnTiles(component, entry, args.Stability, args.Severity, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,17 +78,17 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem
|
||||
if (!entry.Settings.SpawnOnSeverityChanged)
|
||||
continue;
|
||||
|
||||
SpawnTiles(component, entry, args.Stability, args.Severity);
|
||||
SpawnTiles(component, entry, args.Stability, args.Severity, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnTiles(Entity<TileSpawnAnomalyComponent> anomaly, TileSpawnSettingsEntry entry, float stability, float severity)
|
||||
private void SpawnTiles(Entity<TileSpawnAnomalyComponent> anomaly, TileSpawnSettingsEntry entry, float stability, float severity, float powerMod)
|
||||
{
|
||||
var xform = Transform(anomaly);
|
||||
if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||
return;
|
||||
|
||||
var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings);
|
||||
var tiles = _anomaly.GetSpawningPoints(anomaly, stability, severity, entry.Settings, powerMod);
|
||||
if (tiles == null)
|
||||
return;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -33,6 +33,7 @@ public enum AnomalousParticleType : byte
|
||||
Delta,
|
||||
Epsilon,
|
||||
Zeta,
|
||||
Sigma,
|
||||
Default
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -277,7 +301,16 @@ public abstract class SharedAnomalySystem : EntitySystem
|
||||
{
|
||||
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 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(
|
||||
|
||||
@@ -8,20 +8,29 @@ anomaly-particles-delta = Delta particles
|
||||
anomaly-particles-epsilon = Epsilon particles
|
||||
anomaly-particles-zeta = Zeta particles
|
||||
anomaly-particles-omega = Omega particles
|
||||
anomaly-particles-sigma = Sigma particles
|
||||
|
||||
anomaly-scanner-component-scan-complete = Scan complete!
|
||||
|
||||
anomaly-scanner-ui-title = anomaly scanner
|
||||
anomaly-scanner-no-anomaly = No anomaly currently scanned.
|
||||
anomaly-scanner-severity-percentage = Current severity: [color=gray]{$percent}[/color]
|
||||
anomaly-scanner-severity-percentage-unknown = Current severity: [color=red]ERROR[/color]
|
||||
anomaly-scanner-stability-low = Current anomaly state: [color=gold]Decaying[/color]
|
||||
anomaly-scanner-stability-medium = Current anomaly state: [color=forestgreen]Stable[/color]
|
||||
anomaly-scanner-stability-high = Current anomaly state: [color=crimson]Growing[/color]
|
||||
anomaly-scanner-stability-unknown = Current anomaly state: [color=red]ERROR[/color]
|
||||
anomaly-scanner-point-output = Point output: [color=gray]{$point}[/color]
|
||||
anomaly-scanner-point-output-unknown = Point output: [color=red]ERROR[/color]
|
||||
anomaly-scanner-particle-readout = Particle Reaction Analysis:
|
||||
anomaly-scanner-particle-danger = - [color=crimson]Danger type:[/color] {$type}
|
||||
anomaly-scanner-particle-unstable = - [color=plum]Unstable type:[/color] {$type}
|
||||
anomaly-scanner-particle-containment = - [color=goldenrod]Containment type:[/color] {$type}
|
||||
anomaly-scanner-particle-transformation = - [color=#6b75fa]Transformation type:[/color] {$type}
|
||||
anomaly-scanner-particle-danger-unknown = - [color=crimson]Danger type:[/color] [color=red]ERROR[/color]
|
||||
anomaly-scanner-particle-unstable-unknown = - [color=plum]Unstable type:[/color] [color=red]ERROR[/color]
|
||||
anomaly-scanner-particle-containment-unknown = - [color=goldenrod]Containment type:[/color] [color=red]ERROR[/color]
|
||||
anomaly-scanner-particle-transformation-unknown = - [color=#6b75fa]Transformation type:[/color] [color=red]ERROR[/color]
|
||||
anomaly-scanner-pulse-timer = Time until next pulse: [color=gray]{$time}[/color]
|
||||
|
||||
anomaly-gorilla-core-slot-name = Anomaly core
|
||||
@@ -65,3 +74,23 @@ anomaly-command-supercritical = Makes a target anomaly go supercritical
|
||||
# Flavor text on the footer
|
||||
anomaly-generator-flavor-left = Anomaly may spawn inside the operator.
|
||||
anomaly-generator-flavor-right = v1.1
|
||||
|
||||
anomaly-behavior-unknown = [color=red]ERROR. Cannot be read.[/color]
|
||||
|
||||
anomaly-behavior-title = behavior deviation analysis:
|
||||
anomaly-behavior-point =[color=gold]Anomaly produces {$mod}% of the points[/color]
|
||||
|
||||
anomaly-behavior-safe = [color=forestgreen]The anomaly is extremely stable. Extremely rare pulsations.[/color]
|
||||
anomaly-behavior-slow = [color=forestgreen]The frequency of pulsations is much less frequent.[/color]
|
||||
anomaly-behavior-light = [color=forestgreen]Pulsation power is significantly reduced.[/color]
|
||||
anomaly-behavior-balanced = No behavior deviations detected.
|
||||
anomaly-behavior-delayed-force = The frequency of pulsations is greatly reduced, but their power is increased.
|
||||
anomaly-behavior-rapid = The frequency of the pulsation is much higher, but its strength is attenuated.
|
||||
anomaly-behavior-reflect = A protective coating was detected.
|
||||
anomaly-behavior-nonsensivity = A weak reaction to particles was detected.
|
||||
anomaly-behavior-sensivity = Amplified reaction to particles was detected.
|
||||
anomaly-behavior-secret = Interference detected. Some data cannot be read
|
||||
anomaly-behavior-inconstancy = [color=crimson]Impermanence has been detected. Particle types can change over time.[/color]
|
||||
anomaly-behavior-fast = [color=crimson]The pulsation frequency is strongly increased.[/color]
|
||||
anomaly-behavior-strenght = [color=crimson]The pulsation power is significantly increased.[/color]
|
||||
anomaly-behavior-moving = [color=crimson]Coordinate instability was detected.[/color]
|
||||
@@ -70,6 +70,9 @@ signal-port-description-set-particle-epsilon = Sets the type of particle this de
|
||||
signal-port-name-set-particle-zeta = Set particle type: zeta
|
||||
signal-port-description-set-particle-zeta = Sets the type of particle this device emits to zeta.
|
||||
|
||||
signal-port-name-set-particle-sigma = Set particle type: sigma
|
||||
signal-port-description-set-particle-sigma = Sets the type of particle this device emits to sigma.
|
||||
|
||||
signal-port-name-logic-input-a = Input A
|
||||
signal-port-description-logic-input-a = First input of a logic gate.
|
||||
|
||||
|
||||
208
Resources/Prototypes/Anomaly/behaviours.yml
Normal file
208
Resources/Prototypes/Anomaly/behaviours.yml
Normal file
@@ -0,0 +1,208 @@
|
||||
- type: weightedRandom
|
||||
id: AnomalyBehaviorList
|
||||
weights:
|
||||
#safe
|
||||
Slow: 0.5
|
||||
Light: 0.5
|
||||
FullSafe: 0.1
|
||||
#balanced
|
||||
Balanced: 3
|
||||
DelayedForce: 1
|
||||
Rapid: 1
|
||||
BalancedSecret: 1
|
||||
Reflect: 1
|
||||
NonSensivity: 1
|
||||
Sensivity: 1
|
||||
#Hard
|
||||
Fast: 0.5
|
||||
Strenght: 0.5
|
||||
Inconstancy: 0.5
|
||||
InconstancyParticle: 0.5
|
||||
FullUnknown: 0.5
|
||||
Jumping: 0.3
|
||||
Moving: 0.1
|
||||
#Complex
|
||||
FastUnknown: 0.2
|
||||
JumpingUnknown: 0.1
|
||||
InconstancyParticleUnknown: 0.1
|
||||
|
||||
|
||||
# Easy x0.5 point production
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: FullSafe
|
||||
pulseFrequencyModifier: 3
|
||||
pulsePowerModifier: 0.5
|
||||
earnPointModifier: 0.05
|
||||
description: anomaly-behavior-safe
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Slow
|
||||
pulseFrequencyModifier: 2
|
||||
earnPointModifier: 0.5
|
||||
description: anomaly-behavior-slow
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Light
|
||||
pulsePowerModifier: 0.5
|
||||
earnPointModifier: 0.5
|
||||
description: anomaly-behavior-light
|
||||
|
||||
# Balanced x1 point production
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Balanced
|
||||
earnPointModifier: 1
|
||||
description: anomaly-behavior-balanced
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: DelayedForce
|
||||
earnPointModifier: 1.15
|
||||
description: anomaly-behavior-delayed-force
|
||||
pulseFrequencyModifier: 0.5
|
||||
pulsePowerModifier: 2
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Rapid
|
||||
earnPointModifier: 1.15
|
||||
description: anomaly-behavior-rapid
|
||||
pulseFrequencyModifier: 2
|
||||
pulsePowerModifier: 0.5
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: BalancedSecret
|
||||
earnPointModifier: 1.2
|
||||
description: anomaly-behavior-secret
|
||||
components:
|
||||
- type: SecretDataAnomaly
|
||||
randomStartSecretMin: 2
|
||||
randomStartSecretMax: 3
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Reflect
|
||||
earnPointModifier: 1.1
|
||||
particleSensivity: 0.5
|
||||
description: anomaly-behavior-reflect
|
||||
components:
|
||||
- type: Reflect
|
||||
reflectProb: 0.5
|
||||
reflects:
|
||||
- Energy
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: NonSensivity
|
||||
earnPointModifier: 0.8
|
||||
particleSensivity: 0.5
|
||||
description: anomaly-behavior-nonsensivity
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Sensivity
|
||||
earnPointModifier: 1.2
|
||||
particleSensivity: 1.5
|
||||
description: anomaly-behavior-sensivity
|
||||
|
||||
# Hard x2 point production
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Fast
|
||||
earnPointModifier: 1.9
|
||||
pulseFrequencyModifier: 0.5
|
||||
description: anomaly-behavior-fast
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Strenght
|
||||
pulsePowerModifier: 1.5
|
||||
earnPointModifier: 1.4
|
||||
description: anomaly-behavior-strenght
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Inconstancy
|
||||
earnPointModifier: 1.7
|
||||
description: anomaly-behavior-inconstancy
|
||||
components:
|
||||
- type: ShuffleParticlesAnomaly
|
||||
shuffleOnPulse: true
|
||||
prob: 1
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: InconstancyParticle
|
||||
earnPointModifier: 1.8
|
||||
description: anomaly-behavior-inconstancy
|
||||
components:
|
||||
- type: ShuffleParticlesAnomaly
|
||||
shuffleOnParticleHit: true
|
||||
prob: 0.8
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Moving
|
||||
earnPointModifier: 2.2
|
||||
description: anomaly-behavior-moving
|
||||
components:
|
||||
- type: RandomWalk
|
||||
minSpeed: 0
|
||||
maxSpeed: 0.3
|
||||
- type: CanMoveInAir
|
||||
- type: Physics
|
||||
bodyType: Dynamic
|
||||
bodyStatus: InAir
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: Jumping
|
||||
earnPointModifier: 1.8
|
||||
description: anomaly-behavior-moving
|
||||
components:
|
||||
- type: ChaoticJump
|
||||
jumpMinInterval: 15
|
||||
jumpMaxInterval: 25
|
||||
rangeMin: 1
|
||||
rangeMax: 4
|
||||
effect: PuddleSparkle
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: FullUnknown
|
||||
earnPointModifier: 1.9
|
||||
description: anomaly-behavior-secret
|
||||
components:
|
||||
- type: SecretDataAnomaly
|
||||
randomStartSecretMin: 4
|
||||
randomStartSecretMax: 6
|
||||
|
||||
# Complex Effects
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: JumpingUnknown
|
||||
earnPointModifier: 1.9
|
||||
description: anomaly-behavior-moving
|
||||
components:
|
||||
- type: ChaoticJump
|
||||
jumpMinInterval: 15
|
||||
jumpMaxInterval: 25
|
||||
rangeMin: 1
|
||||
rangeMax: 1
|
||||
effect: PuddleSparkle
|
||||
- type: SecretDataAnomaly
|
||||
randomStartSecretMin: 3
|
||||
randomStartSecretMax: 5
|
||||
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: FastUnknown
|
||||
earnPointModifier: 1.9
|
||||
pulseFrequencyModifier: 0.5
|
||||
description: anomaly-behavior-fast
|
||||
components:
|
||||
- type: SecretDataAnomaly
|
||||
randomStartSecretMin: 3
|
||||
randomStartSecretMax: 5
|
||||
|
||||
- type: anomalyBehavior
|
||||
id: InconstancyParticleUnknown
|
||||
earnPointModifier: 1.95
|
||||
description: anomaly-behavior-inconstancy
|
||||
components:
|
||||
- type: ShuffleParticlesAnomaly
|
||||
shuffleOnParticleHit: true
|
||||
prob: 0.5
|
||||
- type: SecretDataAnomaly
|
||||
randomStartSecretMin: 3
|
||||
randomStartSecretMax: 5
|
||||
@@ -107,3 +107,8 @@
|
||||
id: SetParticleZeta
|
||||
name: signal-port-name-set-particle-zeta
|
||||
description: signal-port-description-set-particle-zeta
|
||||
|
||||
- type: sinkPort
|
||||
id: SetParticleSigma
|
||||
name: signal-port-name-set-particle-sigma
|
||||
description: signal-port-description-set-particle-sigma
|
||||
|
||||
@@ -643,6 +643,7 @@
|
||||
- type: Clothing
|
||||
sprite: Objects/Weapons/Guns/Revolvers/chimp.rsi
|
||||
- type: Gun
|
||||
projectileSpeed: 4
|
||||
fireRate: 1.5
|
||||
soundGunshot:
|
||||
path: /Audio/Weapons/Guns/Gunshots/taser2.ogg
|
||||
@@ -657,6 +658,8 @@
|
||||
fireCost: 100
|
||||
- proto: AnomalousParticleZetaStrong
|
||||
fireCost: 100
|
||||
- proto: AnomalousParticleSigmaStrong
|
||||
fireCost: 100
|
||||
- type: Construction
|
||||
graph: UpgradeWeaponPistolCHIMP
|
||||
node: start
|
||||
@@ -679,6 +682,8 @@
|
||||
fireCost: 100
|
||||
- proto: AnomalousParticleZetaStrong
|
||||
fireCost: 100
|
||||
- proto: AnomalousParticleSigmaStrong
|
||||
fireCost: 100
|
||||
|
||||
- type: entity
|
||||
name: eye of a behonker
|
||||
|
||||
@@ -487,6 +487,11 @@
|
||||
name: delta particles
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
color: "#c2385d"
|
||||
radius: 2.0
|
||||
energy: 7.0
|
||||
- type: AnomalousParticle
|
||||
particleType: Delta
|
||||
- type: Sprite
|
||||
@@ -513,6 +518,9 @@
|
||||
Heat: 5
|
||||
- type: TimedDespawn
|
||||
lifetime: 3
|
||||
- type: Reflective
|
||||
reflective:
|
||||
- Energy
|
||||
|
||||
|
||||
- type: entity
|
||||
@@ -533,6 +541,11 @@
|
||||
name: epsilon particles
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
color: "#38c296"
|
||||
radius: 2.0
|
||||
energy: 7.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: magicm_cyan
|
||||
@@ -558,6 +571,11 @@
|
||||
name: zeta particles
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
color: "#b9c238"
|
||||
radius: 2.0
|
||||
energy: 7.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: magicm_yellow
|
||||
@@ -583,6 +601,11 @@
|
||||
name: omega particles
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
color: "#38c24f"
|
||||
radius: 2.0
|
||||
energy: 7.0
|
||||
- type: Sprite
|
||||
sprite: Objects/Weapons/Guns/Projectiles/magic.rsi
|
||||
layers:
|
||||
@@ -601,6 +624,33 @@
|
||||
types:
|
||||
Heat: 20
|
||||
|
||||
- type: entity
|
||||
parent: AnomalousParticleDelta
|
||||
id: AnomalousParticleSigma
|
||||
name: sigma particles
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
color: "#8d38c2"
|
||||
radius: 2.0
|
||||
energy: 7.0
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: magicm
|
||||
shader: unshaded
|
||||
- type: AnomalousParticle
|
||||
particleType: Sigma
|
||||
|
||||
- type: entity
|
||||
parent: AnomalousParticleSigma
|
||||
id: AnomalousParticleSigmaStrong
|
||||
name: sigma particles
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: AnomalousParticle
|
||||
particleType: Sigma
|
||||
|
||||
# Launcher projectiles (grenade / rocket)
|
||||
- type: entity
|
||||
id: BulletRocket
|
||||
|
||||
@@ -172,10 +172,12 @@
|
||||
- AnomalousParticleDelta
|
||||
- AnomalousParticleEpsilon
|
||||
- AnomalousParticleZeta
|
||||
- AnomalousParticleSigma
|
||||
setTypePorts:
|
||||
SetParticleDelta: AnomalousParticleDelta
|
||||
SetParticleEpsilon: AnomalousParticleEpsilon
|
||||
SetParticleZeta: AnomalousParticleZeta
|
||||
SetParticleSigma: AnomalousParticleSigma
|
||||
fireBurstSize: 1
|
||||
fireBurstDelayMin: 2
|
||||
fireBurstDelayMax: 6
|
||||
@@ -185,6 +187,7 @@
|
||||
guides:
|
||||
- APE
|
||||
- type: Gun
|
||||
projectileSpeed: 4
|
||||
fireRate: 10 #just has to be fast enough to keep up with upgrades
|
||||
showExamineText: false
|
||||
selectedMode: SemiAuto
|
||||
@@ -219,6 +222,7 @@
|
||||
- SetParticleDelta
|
||||
- SetParticleEpsilon
|
||||
- SetParticleZeta
|
||||
- SetParticleSigma
|
||||
|
||||
- type: entity
|
||||
id: MachineAnomalyGenerator
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
anchored: false
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
bodyStatus: InAir
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
@@ -47,6 +48,9 @@
|
||||
- type: EmitSoundOnSpawn
|
||||
sound:
|
||||
path: /Audio/Effects/teleport_arrival.ogg
|
||||
- type: SecretDataAnomaly
|
||||
randomStartSecretMin: 0
|
||||
randomStartSecretMax: 2
|
||||
|
||||
- type: entity
|
||||
id: AnomalyPyroclastic
|
||||
@@ -598,7 +602,7 @@
|
||||
color: "#6270bb"
|
||||
- type: Anomaly
|
||||
animationTime: 6
|
||||
offset: 0.05, 0
|
||||
offset: 0, 0
|
||||
corePrototype: AnomalyCoreFlora
|
||||
coreInertPrototype: AnomalyCoreFloraInert
|
||||
anomalyContactDamage:
|
||||
|
||||
Reference in New Issue
Block a user