Ion storm event (#20277)
* ion storm event prototype + locale * add lawsets * use lawsets, make borgs ion storm targets * ion storm rule and ion storm target * lawset prototype * use lawsets * update silicon law system to use lawsets and support ion storm event * new toys * fix * more fix * fixy * ion storm admin logging * assigning laws makes borg provide its own laws, other stuff * 1h reoccurence * 50% chance * better call saul * emagLaws is required * add announcment audio * fixy * family friendly gaming * fixy * address reviews * fixy * more fixy and no erp * pro --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
@@ -1,12 +1,11 @@
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Laws.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for an entity that grants a special "obey" law when emagge.d
|
||||
/// This is used for an entity that grants a special "obey" law when emagged.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedSiliconLawSystem))]
|
||||
public sealed partial class EmagSiliconLawComponent : Component
|
||||
@@ -14,31 +13,39 @@ public sealed partial class EmagSiliconLawComponent : Component
|
||||
/// <summary>
|
||||
/// The name of the person who emagged this law provider.
|
||||
/// </summary>
|
||||
[DataField("ownerName"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? OwnerName;
|
||||
|
||||
/// <summary>
|
||||
/// Does the panel need to be open to EMAG this law provider.
|
||||
/// </summary>
|
||||
[DataField("requireOpenPanel"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool RequireOpenPanel = true;
|
||||
|
||||
/// <summary>
|
||||
/// The laws that the borg is given when emagged.
|
||||
/// The laws that the borg is given when emagged.
|
||||
/// Law 0 is prepended to this, so this can only include the static laws.
|
||||
/// </summary>
|
||||
[DataField("emagLaws", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<SiliconLawPrototype>))]
|
||||
public List<string> EmagLaws = new();
|
||||
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||
public ProtoId<SiliconLawsetPrototype> EmagLaws = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// How long the borg is stunned when it's emagged. Setting to 0 will disable it.
|
||||
/// Lawset created from the prototype id and law 0.
|
||||
/// Cached when getting laws and only modified during an ion storm event.
|
||||
/// </summary>
|
||||
[DataField("stunTime"), ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public SiliconLawset? Lawset;
|
||||
|
||||
/// <summary>
|
||||
/// How long the borg is stunned when it's emagged. Setting to 0 will disable it.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan StunTime = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// A role given to entities with this component when they are emagged.
|
||||
/// Mostly just for admin purposes.
|
||||
/// </summary>
|
||||
[DataField("antagonistRole", customTypeSerializer: typeof(PrototypeIdSerializer<AntagPrototype>))]
|
||||
public string? AntagonistRole = "SubvertedSilicon";
|
||||
[DataField]
|
||||
public ProtoId<AntagPrototype>? AntagonistRole = "SubvertedSilicon";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using Content.Shared.Random;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Laws.Components;
|
||||
|
||||
/// <summary>
|
||||
/// During the ion storm event, this entity will have <see cref="IonStormLawsEvent"/> raised on it if it has laws.
|
||||
/// New laws can be modified in multiple ways depending on the fields below.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class IonStormTargetComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="WeightedRandomPrototype"/> for a random lawset to possibly replace the old one with.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public ProtoId<WeightedRandomPrototype> RandomLawsets = "IonStormLawsets";
|
||||
|
||||
/// <summary>
|
||||
/// Chance for this borg to be affected at all.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float Chance = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Chance to replace the lawset with a random one
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float RandomLawsetChance = 0.25f;
|
||||
|
||||
/// <summary>
|
||||
/// Chance to remove a random law.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float RemoveChance = 0.1f;
|
||||
|
||||
/// <summary>
|
||||
/// Chance to replace a random law with the new one, rather than have it be a glitched-order law.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ReplaceChance = 0.1f;
|
||||
|
||||
/// <summary>
|
||||
/// Chance to shuffle laws after everything is done.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ShuffleChance = 0.1f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an ion storm target to modify its laws.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct IonStormLawsEvent(SiliconLawset Lawset);
|
||||
@@ -1,7 +1,6 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared.Silicons.Laws.Components;
|
||||
|
||||
@@ -14,19 +13,19 @@ public sealed partial class SiliconLawBoundComponent : Component
|
||||
/// <summary>
|
||||
/// The sidebar action that toggles the laws screen.
|
||||
/// </summary>
|
||||
[DataField("viewLawsAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string ViewLawsAction = "ActionViewLaws";
|
||||
[DataField]
|
||||
public EntProtoId ViewLawsAction = "ActionViewLaws";
|
||||
|
||||
/// <summary>
|
||||
/// The action for toggling laws. Stored here so we can remove it later.
|
||||
/// </summary>
|
||||
[DataField("viewLawsActionEntity")]
|
||||
[DataField]
|
||||
public EntityUid? ViewLawsActionEntity;
|
||||
|
||||
/// <summary>
|
||||
/// The last entity that provided laws to this entity.
|
||||
/// </summary>
|
||||
[DataField("lastLawProvider")]
|
||||
[DataField]
|
||||
public EntityUid? LastLawProvider;
|
||||
}
|
||||
|
||||
@@ -43,7 +42,7 @@ public record struct GetSiliconLawsEvent(EntityUid Entity)
|
||||
{
|
||||
public EntityUid Entity = Entity;
|
||||
|
||||
public readonly List<SiliconLaw> Laws = new();
|
||||
public SiliconLawset Laws = new();
|
||||
|
||||
public bool Handled = false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Laws.Components;
|
||||
|
||||
@@ -9,8 +9,15 @@ namespace Content.Shared.Silicons.Laws.Components;
|
||||
public sealed partial class SiliconLawProviderComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The laws that are provided.
|
||||
/// The id of the lawset that is being provided.
|
||||
/// </summary>
|
||||
[DataField("laws", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<SiliconLawPrototype>))]
|
||||
public List<string> Laws = new();
|
||||
[DataField(required: true)]
|
||||
public ProtoId<SiliconLawsetPrototype> Laws = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Lawset created from the prototype id.
|
||||
/// Cached when getting laws and only modified during an ion storm event.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public SiliconLawset? Lawset;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ public partial class SiliconLaw : IComparable<SiliconLaw>
|
||||
/// <summary>
|
||||
/// A locale string which is the actual text of the law.
|
||||
/// </summary>
|
||||
[DataField("lawString", required: true)]
|
||||
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||
public string LawString = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
@@ -22,13 +22,13 @@ public partial class SiliconLaw : IComparable<SiliconLaw>
|
||||
/// This is a fixedpoint2 only for the niche case of supporting laws that go between 0 and 1.
|
||||
/// Funny.
|
||||
/// </remarks>
|
||||
[DataField("order", required: true)]
|
||||
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||
public FixedPoint2 Order;
|
||||
|
||||
/// <summary>
|
||||
/// An identifier that overrides <see cref="Order"/> in the law menu UI.
|
||||
/// </summary>
|
||||
[DataField("lawIdentifierOverride")]
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public string? LawIdentifierOverride;
|
||||
|
||||
public int CompareTo(SiliconLaw? other)
|
||||
@@ -38,6 +38,19 @@ public partial class SiliconLaw : IComparable<SiliconLaw>
|
||||
|
||||
return Order.CompareTo(other.Order);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a shallow clone of this law.
|
||||
/// </summary>
|
||||
public SiliconLaw ShallowClone()
|
||||
{
|
||||
return new SiliconLaw()
|
||||
{
|
||||
LawString = LawString,
|
||||
Order = Order,
|
||||
LawIdentifierOverride = LawIdentifierOverride
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -50,6 +63,4 @@ public sealed class SiliconLawPrototype : SiliconLaw, IPrototype
|
||||
/// <inheritdoc/>
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
|
||||
}
|
||||
|
||||
69
Content.Shared/Silicons/Laws/SiliconLawsetPrototype.cs
Normal file
69
Content.Shared/Silicons/Laws/SiliconLawsetPrototype.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Silicons.Laws;
|
||||
|
||||
/// <summary>
|
||||
/// Lawset data used internally.
|
||||
/// </summary>
|
||||
[DataDefinition, Serializable, NetSerializable]
|
||||
public sealed partial class SiliconLawset
|
||||
{
|
||||
/// <summary>
|
||||
/// List of laws in this lawset.
|
||||
/// </summary>
|
||||
[DataField(required: true), ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<SiliconLaw> Laws = new();
|
||||
|
||||
/// <summary>
|
||||
/// A single line used in logging laws.
|
||||
/// </summary>
|
||||
public string LoggingString()
|
||||
{
|
||||
var laws = new List<string>(Laws.Count);
|
||||
foreach (var law in Laws)
|
||||
{
|
||||
laws.Add($"{law.Order}: {Loc.GetString(law.LawString)}");
|
||||
}
|
||||
|
||||
return string.Join(" / ", laws);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Do a clone of this lawset.
|
||||
/// It will have unique laws but their strings are still shared.
|
||||
/// </summary>
|
||||
public SiliconLawset Clone()
|
||||
{
|
||||
var laws = new List<SiliconLaw>(Laws.Count);
|
||||
foreach (var law in Laws)
|
||||
{
|
||||
laws.Add(law.ShallowClone());
|
||||
}
|
||||
|
||||
return new SiliconLawset()
|
||||
{
|
||||
Laws = laws
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a prototype for a <see cref="SiliconLawPrototype"/> list.
|
||||
/// Cannot be used directly since it is a list of prototype ids rather than List<Siliconlaw>.
|
||||
/// </summary>
|
||||
[Prototype("siliconLawset"), Serializable, NetSerializable]
|
||||
public sealed partial class SiliconLawsetPrototype : IPrototype
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// List of law prototype ids in this lawset.
|
||||
/// </summary>
|
||||
[DataField(required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<SiliconLawPrototype>))]
|
||||
public List<string> Laws = new();
|
||||
}
|
||||
Reference in New Issue
Block a user