Cluster grenades for uplink and security (#22029)
* clustergrenades go boom * Small tweaks * Some tweaks and soaplet * clustergrenadesystem changes and launcher types * small tweaks * typo * whitespace * rsi edit * another typo * add containers * Some changes related to merge * Forgot to change name * Made changes based on review * Removed new china lake ammo based on feedback in other PR * Unneeded nested loop moment * Nested loop needed after all moment
@@ -1,7 +1,6 @@
|
|||||||
using Content.Server.Explosion.EntitySystems;
|
using Content.Server.Explosion.EntitySystems;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
|
|
||||||
namespace Content.Server.Explosion.Components
|
namespace Content.Server.Explosion.Components
|
||||||
{
|
{
|
||||||
@@ -13,8 +12,8 @@ namespace Content.Server.Explosion.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// What we fill our prototype with if we want to pre-spawn with grenades.
|
/// What we fill our prototype with if we want to pre-spawn with grenades.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("fillPrototype", customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
|
[DataField("fillPrototype")]
|
||||||
public string? FillPrototype;
|
public EntProtoId? FillPrototype;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If we have a pre-fill how many more can we spawn.
|
/// If we have a pre-fill how many more can we spawn.
|
||||||
@@ -28,20 +27,91 @@ namespace Content.Server.Explosion.Components
|
|||||||
public int MaxGrenades = 3;
|
public int MaxGrenades = 3;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How long until our grenades are shot out and armed.
|
/// Maximum delay in seconds between individual grenade triggers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)] [DataField("delay")]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float Delay = 1;
|
[DataField("grenadeTriggerIntervalMax")]
|
||||||
|
public float GrenadeTriggerIntervalMax = 0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Max distance grenades can be thrown.
|
/// Minimum delay in seconds between individual grenade triggers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)] [DataField("distance")]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float ThrowDistance = 50;
|
[DataField("grenadeTriggerIntervalMin")]
|
||||||
|
public float GrenadeTriggerIntervalMin = 0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum delay in seconds before any grenades start to be triggered.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("baseTriggerDelay")]
|
||||||
|
public float BaseTriggerDelay = 1.0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decides if grenades trigger after getting launched
|
||||||
|
/// </summary>
|
||||||
|
[DataField("triggerGrenades")]
|
||||||
|
public bool TriggerGrenades = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does the cluster grenade shoot or throw
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("grenadeType")]
|
||||||
|
public Enum GrenadeType = Components.GrenadeType.Throw;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The speed at which grenades get thrown
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("velocity")]
|
||||||
|
public float Velocity = 5;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the spread be random
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("randomSpread")]
|
||||||
|
public bool RandomSpread = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should the angle be random
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("randomAngle")]
|
||||||
|
public bool RandomAngle = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Static distance grenades will be thrown to.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("distance")]
|
||||||
|
public float Distance = 1f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Max distance grenades should randomly be thrown to.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("maxSpreadDistance")]
|
||||||
|
public float MaxSpreadDistance = 2.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimal distance grenades should randomly be thrown to.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("minSpreadDistance")]
|
||||||
|
public float MinSpreadDistance = 0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the end.
|
/// This is the end.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CountDown;
|
public bool CountDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum GrenadeType
|
||||||
|
{
|
||||||
|
Throw,
|
||||||
|
Shoot
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ using Content.Shared.Interaction.Events;
|
|||||||
using Content.Shared.Throwing;
|
using Content.Shared.Throwing;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
using Content.Server.Weapons.Ranged.Systems;
|
||||||
|
using System.Numerics;
|
||||||
|
using Robust.Server.Containers;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
|
||||||
namespace Content.Server.Explosion.EntitySystems;
|
namespace Content.Server.Explosion.EntitySystems;
|
||||||
|
|
||||||
@@ -13,9 +17,11 @@ public sealed class ClusterGrenadeSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||||
[Dependency] private readonly TriggerSystem _trigger = default!;
|
|
||||||
[Dependency] private readonly ThrowingSystem _throwingSystem = default!;
|
[Dependency] private readonly ThrowingSystem _throwingSystem = default!;
|
||||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
|
[Dependency] private readonly GunSystem _gun = default!;
|
||||||
|
[Dependency] private readonly TransformSystem _transformSystem = default!;
|
||||||
|
[Dependency] private readonly ContainerSystem _containerSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -23,12 +29,12 @@ public sealed class ClusterGrenadeSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<ClusterGrenadeComponent, ComponentInit>(OnClugInit);
|
SubscribeLocalEvent<ClusterGrenadeComponent, ComponentInit>(OnClugInit);
|
||||||
SubscribeLocalEvent<ClusterGrenadeComponent, ComponentStartup>(OnClugStartup);
|
SubscribeLocalEvent<ClusterGrenadeComponent, ComponentStartup>(OnClugStartup);
|
||||||
SubscribeLocalEvent<ClusterGrenadeComponent, InteractUsingEvent>(OnClugUsing);
|
SubscribeLocalEvent<ClusterGrenadeComponent, InteractUsingEvent>(OnClugUsing);
|
||||||
SubscribeLocalEvent<ClusterGrenadeComponent, UseInHandEvent>(OnClugUse);
|
SubscribeLocalEvent<ClusterGrenadeComponent, TriggerEvent>(OnClugTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClugInit(EntityUid uid, ClusterGrenadeComponent component, ComponentInit args)
|
private void OnClugInit(EntityUid uid, ClusterGrenadeComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
component.GrenadesContainer = _container.EnsureContainer<Container>(uid, "cluster-flash");
|
component.GrenadesContainer = _container.EnsureContainer<Container>(uid, "cluster-payload");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClugStartup(Entity<ClusterGrenadeComponent> clug, ref ComponentStartup args)
|
private void OnClugStartup(Entity<ClusterGrenadeComponent> clug, ref ComponentStartup args)
|
||||||
@@ -53,64 +59,97 @@ public sealed class ClusterGrenadeSystem : EntitySystem
|
|||||||
!HasComp<FlashOnTriggerComponent>(args.Used))
|
!HasComp<FlashOnTriggerComponent>(args.Used))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
component.GrenadesContainer.Insert(args.Used);
|
_containerSystem.Insert(args.Used, component.GrenadesContainer);
|
||||||
UpdateAppearance(clug);
|
UpdateAppearance(clug);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClugUse(EntityUid uid, ClusterGrenadeComponent component, UseInHandEvent args)
|
private void OnClugTrigger(Entity<ClusterGrenadeComponent> clug, ref TriggerEvent args)
|
||||||
{
|
{
|
||||||
if (component.CountDown || (component.GrenadesContainer.ContainedEntities.Count + component.UnspawnedCount) <= 0)
|
var component = clug.Comp;
|
||||||
return;
|
component.CountDown = true;
|
||||||
|
|
||||||
// TODO: Should be an Update loop
|
|
||||||
uid.SpawnTimer((int) (component.Delay * 1000), () =>
|
|
||||||
{
|
|
||||||
if (Deleted(uid))
|
|
||||||
return;
|
|
||||||
|
|
||||||
component.CountDown = true;
|
|
||||||
var delay = 20;
|
|
||||||
var grenadesInserted = component.GrenadesContainer.ContainedEntities.Count + component.UnspawnedCount;
|
|
||||||
var thrownCount = 0;
|
|
||||||
var segmentAngle = 360 / grenadesInserted;
|
|
||||||
while (TryGetGrenade((uid, component), out var grenade))
|
|
||||||
{
|
|
||||||
var angleMin = segmentAngle * thrownCount;
|
|
||||||
var angleMax = segmentAngle * (thrownCount + 1);
|
|
||||||
var angle = Angle.FromDegrees(_random.Next(angleMin, angleMax));
|
|
||||||
// var distance = random.NextFloat() * _throwDistance;
|
|
||||||
|
|
||||||
delay += _random.Next(550, 900);
|
|
||||||
thrownCount++;
|
|
||||||
|
|
||||||
// TODO: Suss out throw strength
|
|
||||||
_throwingSystem.TryThrow(grenade, angle.ToVec().Normalized() * component.ThrowDistance);
|
|
||||||
|
|
||||||
grenade.SpawnTimer(delay, () =>
|
|
||||||
{
|
|
||||||
if ((!EntityManager.EntityExists(grenade) ? EntityLifeStage.Deleted : MetaData(grenade).EntityLifeStage) >= EntityLifeStage.Deleted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_trigger.Trigger(grenade, args.User);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityManager.DeleteEntity(uid);
|
|
||||||
});
|
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetGrenade(Entity<ClusterGrenadeComponent> ent, out EntityUid grenade)
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
var query = EntityQueryEnumerator<ClusterGrenadeComponent>();
|
||||||
|
|
||||||
|
while (query.MoveNext(out var uid, out var clug))
|
||||||
|
{
|
||||||
|
if (clug.CountDown && clug.UnspawnedCount > 0)
|
||||||
|
{
|
||||||
|
var grenadesInserted = clug.GrenadesContainer.ContainedEntities.Count + clug.UnspawnedCount;
|
||||||
|
var thrownCount = 0;
|
||||||
|
var segmentAngle = 360 / grenadesInserted;
|
||||||
|
var grenadeDelay = 0f;
|
||||||
|
|
||||||
|
while (TryGetGrenade(uid, clug, out var grenade))
|
||||||
|
{
|
||||||
|
// var distance = random.NextFloat() * _throwDistance;
|
||||||
|
var angleMin = segmentAngle * thrownCount;
|
||||||
|
var angleMax = segmentAngle * (thrownCount + 1);
|
||||||
|
var angle = Angle.FromDegrees(_random.Next(angleMin, angleMax));
|
||||||
|
if (clug.RandomAngle)
|
||||||
|
angle = _random.NextAngle();
|
||||||
|
thrownCount++;
|
||||||
|
|
||||||
|
switch (clug.GrenadeType)
|
||||||
|
{
|
||||||
|
case GrenadeType.Shoot:
|
||||||
|
ShootProjectile(grenade, angle, clug, uid);
|
||||||
|
break;
|
||||||
|
case GrenadeType.Throw:
|
||||||
|
ThrowGrenade(grenade, angle, clug);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// give an active timer trigger to the contained grenades when they get launched
|
||||||
|
if (clug.TriggerGrenades)
|
||||||
|
{
|
||||||
|
grenadeDelay += _random.NextFloat(clug.GrenadeTriggerIntervalMin, clug.GrenadeTriggerIntervalMax);
|
||||||
|
var grenadeTimer = EnsureComp<ActiveTimerTriggerComponent>(grenade);
|
||||||
|
grenadeTimer.TimeRemaining = (clug.BaseTriggerDelay + grenadeDelay);
|
||||||
|
var ev = new ActiveTimerTriggerEvent(grenade, uid);
|
||||||
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// delete the empty shell of the clusterbomb
|
||||||
|
Del(uid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShootProjectile(EntityUid grenade, Angle angle, ClusterGrenadeComponent clug, EntityUid clugUid)
|
||||||
|
{
|
||||||
|
var direction = angle.ToVec().Normalized();
|
||||||
|
|
||||||
|
if (clug.RandomSpread)
|
||||||
|
direction = _random.NextVector2().Normalized();
|
||||||
|
|
||||||
|
_gun.ShootProjectile(grenade, direction, Vector2.One.Normalized(), clugUid);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowGrenade(EntityUid grenade, Angle angle, ClusterGrenadeComponent clug)
|
||||||
|
{
|
||||||
|
var direction = angle.ToVec().Normalized() * clug.Distance;
|
||||||
|
|
||||||
|
if (clug.RandomSpread)
|
||||||
|
direction = angle.ToVec().Normalized() * _random.NextFloat(clug.MinSpreadDistance, clug.MaxSpreadDistance);
|
||||||
|
|
||||||
|
_throwingSystem.TryThrow(grenade, direction, clug.Velocity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetGrenade(EntityUid clugUid, ClusterGrenadeComponent component, out EntityUid grenade)
|
||||||
{
|
{
|
||||||
grenade = default;
|
grenade = default;
|
||||||
var component = ent.Comp;
|
|
||||||
|
|
||||||
if (component.UnspawnedCount > 0)
|
if (component.UnspawnedCount > 0)
|
||||||
{
|
{
|
||||||
component.UnspawnedCount--;
|
component.UnspawnedCount--;
|
||||||
grenade = EntityManager.SpawnEntity(component.FillPrototype, Transform(ent).MapPosition);
|
grenade = Spawn(component.FillPrototype, _transformSystem.GetMapCoordinates(clugUid));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,12 +167,12 @@ public sealed class ClusterGrenadeSystem : EntitySystem
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateAppearance(Entity<ClusterGrenadeComponent> ent)
|
private void UpdateAppearance(Entity<ClusterGrenadeComponent> clug)
|
||||||
{
|
{
|
||||||
var component = ent.Comp;
|
var component = clug.Comp;
|
||||||
if (!TryComp<AppearanceComponent>(ent, out var appearance))
|
if (!TryComp<AppearanceComponent>(clug, out var appearance))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_appearance.SetData(ent, ClusterGrenadeVisuals.GrenadesCounter, component.GrenadesContainer.ContainedEntities.Count + component.UnspawnedCount, appearance);
|
_appearance.SetData(clug, ClusterGrenadeVisuals.GrenadesCounter, component.GrenadesContainer.ContainedEntities.Count + component.UnspawnedCount, appearance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Content.Shared.Database;
|
|||||||
using Content.Shared.Projectiles;
|
using Content.Shared.Projectiles;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Physics.Events;
|
using Robust.Shared.Physics.Events;
|
||||||
|
using Content.Shared.Mobs.Components;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
namespace Content.Server.Projectiles;
|
namespace Content.Server.Projectiles;
|
||||||
@@ -70,7 +71,18 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
|||||||
|
|
||||||
component.DamagedEntity = true;
|
component.DamagedEntity = true;
|
||||||
|
|
||||||
if (component.DeleteOnCollide)
|
if (component.DeleteOnCollide )
|
||||||
|
{
|
||||||
|
QueueDel(uid);
|
||||||
|
}
|
||||||
|
if (component.CanPenetrate)
|
||||||
|
{
|
||||||
|
component.DamagedEntity = false;
|
||||||
|
|
||||||
|
if (!TryComp<MobStateComponent>(target, out var mobState))
|
||||||
|
QueueDel(uid);
|
||||||
|
}
|
||||||
|
else if (component.DeleteOnCollide && !component.CanPenetrate)
|
||||||
{
|
{
|
||||||
QueueDel(uid);
|
QueueDel(uid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public sealed partial class ProjectileComponent : Component
|
|||||||
[DataField("deleteOnCollide")]
|
[DataField("deleteOnCollide")]
|
||||||
public bool DeleteOnCollide = true;
|
public bool DeleteOnCollide = true;
|
||||||
|
|
||||||
|
[DataField("canPenetrate")]
|
||||||
|
public bool CanPenetrate = false;
|
||||||
|
|
||||||
[DataField("ignoreResistances")]
|
[DataField("ignoreResistances")]
|
||||||
public bool IgnoreResistances = false;
|
public bool IgnoreResistances = false;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ uplink-gloves-north-star-desc = A pair of gloves that reduce your punching coold
|
|||||||
|
|
||||||
# Explosives
|
# Explosives
|
||||||
uplink-explosive-grenade-name = Explosive Grenade
|
uplink-explosive-grenade-name = Explosive Grenade
|
||||||
uplink-explosive-grenade-desc = A simplistic grenade with a ten-second fuse that is geared towards injuring personnel. Causes minimal hull damage.
|
uplink-explosive-grenade-desc = A simplistic grenade with a three-and-a-half-second long fuse that is geared towards injuring personnel. Causes minimal hull damage.
|
||||||
|
|
||||||
uplink-flash-grenade-name = Flashbang
|
uplink-flash-grenade-name = Flashbang
|
||||||
uplink-flash-grenade-desc = A standard-issue flashbang, capable of blinding and slowing down anyone without proper protection. This, of course, includes you; make sure you're properly equipped before using it.
|
uplink-flash-grenade-desc = A standard-issue flashbang, capable of blinding and slowing down anyone without proper protection. This, of course, includes you; make sure you're properly equipped before using it.
|
||||||
@@ -63,6 +63,15 @@ uplink-exploding-pen-desc = A class IV explosive device contained within a stand
|
|||||||
uplink-exploding-syndicate-bomb-name = Syndicate Bomb
|
uplink-exploding-syndicate-bomb-name = Syndicate Bomb
|
||||||
uplink-exploding-syndicate-bomb-desc = A big, anchored bomb that can create a huge explosion if not defused in time. Useful as a distraction. Has an adjustable timer with a minimum setting of 120 seconds.
|
uplink-exploding-syndicate-bomb-desc = A big, anchored bomb that can create a huge explosion if not defused in time. Useful as a distraction. Has an adjustable timer with a minimum setting of 120 seconds.
|
||||||
|
|
||||||
|
uplink-cluster-grenade-name = Cluster Grenade
|
||||||
|
uplink-cluster-grenade-desc = Three explosive grenades bundled together, the grenades get launched after the 3.5 second timer runs out.
|
||||||
|
|
||||||
|
uplink-incendiary-grenade-name = Incendiary Grenade
|
||||||
|
uplink-incendiary-grenade-desc = Releases a spray of incendiary fragments, igniting anyone near the detonation area.
|
||||||
|
|
||||||
|
uplink-shrapnel-grenade-name = Shrapnel Grenade
|
||||||
|
uplink-shrapnel-grenade-desc = Launches a spray of sharp fragments dealing great damage against unarmored targets.
|
||||||
|
|
||||||
# Ammo
|
# Ammo
|
||||||
uplink-pistol-magazine-name = Pistol Magazine (.35 auto)
|
uplink-pistol-magazine-name = Pistol Magazine (.35 auto)
|
||||||
uplink-pistol-magazine-desc = Pistol magazine with 10 catridges. Compatible with the Viper.
|
uplink-pistol-magazine-desc = Pistol magazine with 10 catridges. Compatible with the Viper.
|
||||||
@@ -240,6 +249,9 @@ uplink-proximity-mine-desc = A mine disguised as a wet floor sign.
|
|||||||
uplink-disposable-turret-name = Disposable Ballistic Turret
|
uplink-disposable-turret-name = Disposable Ballistic Turret
|
||||||
uplink-disposable-turret-desc = Looks and functions like a normal electrical toolbox. Upon hitting the toolbox it will transform into a ballistic turret, theoretically shooting at anyone except members of the syndicate. Can be turned back into a toolbox using a screwdriver and repaired using a wrench.
|
uplink-disposable-turret-desc = Looks and functions like a normal electrical toolbox. Upon hitting the toolbox it will transform into a ballistic turret, theoretically shooting at anyone except members of the syndicate. Can be turned back into a toolbox using a screwdriver and repaired using a wrench.
|
||||||
|
|
||||||
|
uplink-cluster-banana-peel-name = Cluster Banana
|
||||||
|
uplink-cluster-banana-peel-desc = Splits into 6 explosive banana peels after being thrown, the peels detonate automatically after 20 seconds if nobody slips on them.
|
||||||
|
|
||||||
# Armor
|
# Armor
|
||||||
uplink-chameleon-name = Chameleon Kit
|
uplink-chameleon-name = Chameleon Kit
|
||||||
uplink-chameleon-desc = A backpack full of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!
|
uplink-chameleon-desc = A backpack full of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more!
|
||||||
@@ -308,6 +320,9 @@ uplink-syndicate-segway-crate-desc = Be an enemy of the corporation, in style!
|
|||||||
uplink-syndicate-sponge-box-name = Syndicate Sponge Box
|
uplink-syndicate-sponge-box-name = Syndicate Sponge Box
|
||||||
uplink-syndicate-sponge-box-desc = A box containing 6 syndicate sponges disguised as monkey cubes, these cubes turn into a variety of angry wildlife after coming into contact with water.
|
uplink-syndicate-sponge-box-desc = A box containing 6 syndicate sponges disguised as monkey cubes, these cubes turn into a variety of angry wildlife after coming into contact with water.
|
||||||
|
|
||||||
|
uplink-slipocalypse-clustersoap-name = Slipocalypse Clustersoap
|
||||||
|
uplink-slipocalypse-clustersoap-desc = Scatters arounds small pieces of syndicate-brand soap after being thrown, these pieces of soap evaporate after 60 seconds.
|
||||||
|
|
||||||
# Pointless
|
# Pointless
|
||||||
uplink-revolver-cap-gun-name = Cap Gun
|
uplink-revolver-cap-gun-name = Cap Gun
|
||||||
uplink-revolver-cap-gun-desc = Looks almost like the real thing! Ages 8 and up.
|
uplink-revolver-cap-gun-desc = Looks almost like the real thing! Ages 8 and up.
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
startingInventory:
|
startingInventory:
|
||||||
Handcuffs: 8
|
Handcuffs: 8
|
||||||
GrenadeFlashBang: 4
|
GrenadeFlashBang: 4
|
||||||
|
ClusterBangFull: 2
|
||||||
|
GrenadeStinger: 4
|
||||||
Flash: 5
|
Flash: 5
|
||||||
FlashlightSeclite: 5
|
FlashlightSeclite: 5
|
||||||
ClothingEyesGlassesSunglasses: 2
|
ClothingEyesGlassesSunglasses: 2
|
||||||
|
|||||||
@@ -250,6 +250,36 @@
|
|||||||
- UplinkExplosives
|
- UplinkExplosives
|
||||||
restockTime: 30
|
restockTime: 30
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkClusterGrenade
|
||||||
|
name: uplink-cluster-grenade-name
|
||||||
|
description: uplink-cluster-grenade-desc
|
||||||
|
productEntity: ClusterGrenade
|
||||||
|
cost:
|
||||||
|
Telecrystal: 8
|
||||||
|
categories:
|
||||||
|
- UplinkExplosives
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkGrenadeShrapnel
|
||||||
|
name: uplink-shrapnel-grenade-name
|
||||||
|
description: uplink-shrapnel-grenade-desc
|
||||||
|
productEntity: GrenadeShrapnel
|
||||||
|
cost:
|
||||||
|
Telecrystal: 4
|
||||||
|
categories:
|
||||||
|
- UplinkExplosives
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkGrenadeIncendiary
|
||||||
|
name: uplink-incendiary-grenade-name
|
||||||
|
description: uplink-incendiary-grenade-desc
|
||||||
|
productEntity: GrenadeIncendiary
|
||||||
|
cost:
|
||||||
|
Telecrystal: 4
|
||||||
|
categories:
|
||||||
|
- UplinkExplosives
|
||||||
|
|
||||||
# Ammo
|
# Ammo
|
||||||
|
|
||||||
- type: listing
|
- type: listing
|
||||||
@@ -956,6 +986,20 @@
|
|||||||
whitelist:
|
whitelist:
|
||||||
- Clown
|
- Clown
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkClusterBananaPeel
|
||||||
|
name: uplink-cluster-banana-peel-name
|
||||||
|
description: uplink-cluster-banana-peel-desc
|
||||||
|
productEntity: ClusterBananaPeel
|
||||||
|
cost:
|
||||||
|
Telecrystal: 6
|
||||||
|
categories:
|
||||||
|
- UplinkJob
|
||||||
|
conditions:
|
||||||
|
- !type:BuyerJobCondition
|
||||||
|
whitelist:
|
||||||
|
- Clown
|
||||||
|
|
||||||
- type: listing
|
- type: listing
|
||||||
id: UplinkHoloclownKit
|
id: UplinkHoloclownKit
|
||||||
name: uplink-holoclown-kit-name
|
name: uplink-holoclown-kit-name
|
||||||
@@ -1186,6 +1230,16 @@
|
|||||||
categories:
|
categories:
|
||||||
- UplinkMisc
|
- UplinkMisc
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: UplinkSlipocalypseClusterSoap
|
||||||
|
name: uplink-slipocalypse-clustersoap-name
|
||||||
|
description: uplink-slipocalypse-clustersoap-desc
|
||||||
|
productEntity: SlipocalypseClusterSoap
|
||||||
|
cost:
|
||||||
|
Telecrystal: 3
|
||||||
|
categories:
|
||||||
|
- UplinkMisc
|
||||||
|
|
||||||
- type: listing
|
- type: listing
|
||||||
id: UplinkUltrabrightLantern
|
id: UplinkUltrabrightLantern
|
||||||
name: uplink-ultrabright-lantern-name
|
name: uplink-ultrabright-lantern-name
|
||||||
|
|||||||
@@ -128,6 +128,46 @@
|
|||||||
- clean
|
- clean
|
||||||
- punishment
|
- punishment
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: soaplet
|
||||||
|
id: SoapletSyndie
|
||||||
|
noSpawn: true
|
||||||
|
parent: Soap
|
||||||
|
description: A tiny piece of syndicate soap.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
layers:
|
||||||
|
- state: syndie-soaplet
|
||||||
|
- type: Slippery
|
||||||
|
paralyzeTime: 5
|
||||||
|
launchForwardsMultiplier: 2.5
|
||||||
|
- type: StepTrigger
|
||||||
|
intersectRatio: 0.04
|
||||||
|
- type: Item
|
||||||
|
heldPrefix: syndie
|
||||||
|
- type: Fixtures
|
||||||
|
fixtures:
|
||||||
|
slips:
|
||||||
|
shape:
|
||||||
|
!type:PhysShapeAabb
|
||||||
|
bounds: "-0.08,-0.06,0.08,0.06"
|
||||||
|
layer:
|
||||||
|
- SlipLayer
|
||||||
|
hard: false
|
||||||
|
fix1:
|
||||||
|
shape:
|
||||||
|
!type:PhysShapeAabb
|
||||||
|
bounds: "-0.08,-0.06,0.08,0.06"
|
||||||
|
density: 1
|
||||||
|
mask:
|
||||||
|
- ItemMask
|
||||||
|
- type: DeleteOnTrigger
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Effects/Fluids/splat.ogg"
|
||||||
|
params:
|
||||||
|
volume: -20
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: soap
|
name: soap
|
||||||
id: SoapHomemade
|
id: SoapHomemade
|
||||||
|
|||||||
@@ -83,11 +83,23 @@
|
|||||||
- type: ExplodeOnTrigger
|
- type: ExplodeOnTrigger
|
||||||
- type: Explosive
|
- type: Explosive
|
||||||
explosionType: Default
|
explosionType: Default
|
||||||
maxIntensity: 2
|
maxIntensity: 3.4
|
||||||
totalIntensity: 10
|
intensitySlope: 3
|
||||||
|
totalIntensity: 20
|
||||||
canCreateVacuum: false
|
canCreateVacuum: false
|
||||||
- type: DeleteOnTrigger
|
- type: DeleteOnTrigger
|
||||||
- type: AnimationPlayer
|
- type: AnimationPlayer
|
||||||
|
- type: Damageable
|
||||||
|
damageContainer: Inorganic
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTrigger
|
||||||
|
damage: 10
|
||||||
|
behaviors:
|
||||||
|
- !type:TriggerBehavior
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: ["Destruction"]
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
- type: entity
|
||||||
|
id: PelletClusterRubber
|
||||||
|
name: pellet (ball, Rubber)
|
||||||
|
noSpawn: true
|
||||||
|
parent: BaseBullet
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi
|
||||||
|
state: buckshot
|
||||||
|
- type: Projectile
|
||||||
|
deleteOnCollide: false
|
||||||
|
canPenetrate: true
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 4
|
||||||
|
- type: StaminaDamageOnCollide
|
||||||
|
damage: 55
|
||||||
|
- type: TimedDespawn
|
||||||
|
lifetime: 0.25
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: PelletClusterLethal
|
||||||
|
name: pellet (ball, Lethal)
|
||||||
|
noSpawn: true
|
||||||
|
parent: BaseBullet
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi
|
||||||
|
state: buckshot
|
||||||
|
- type: Projectile
|
||||||
|
deleteOnCollide: false
|
||||||
|
canPenetrate: true
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Piercing: 45
|
||||||
|
- type: TimedDespawn
|
||||||
|
lifetime: 0.25
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: PelletClusterIncendiary
|
||||||
|
name: pellet (ball, incendiary)
|
||||||
|
noSpawn: true
|
||||||
|
parent: BaseBulletIncendiary
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Guns/Projectiles/projectiles2.rsi
|
||||||
|
state: buckshot-flare
|
||||||
|
- type: Projectile
|
||||||
|
deleteOnCollide: false
|
||||||
|
canPenetrate: true
|
||||||
|
damage:
|
||||||
|
groups:
|
||||||
|
Burn: 4
|
||||||
|
- type: IgniteOnCollide
|
||||||
|
fireStacks: 3
|
||||||
|
count: 10
|
||||||
|
- type: TimedDespawn
|
||||||
|
lifetime: 0.25
|
||||||
@@ -641,6 +641,11 @@
|
|||||||
- state: grenade
|
- state: grenade
|
||||||
- type: FlashOnTrigger
|
- type: FlashOnTrigger
|
||||||
range: 7
|
range: 7
|
||||||
|
- type: SpawnOnTrigger
|
||||||
|
proto: GrenadeFlashEffect
|
||||||
|
- type: ActiveTimerTrigger
|
||||||
|
timeRemaining: 0.3
|
||||||
|
- type: DeleteOnTrigger
|
||||||
|
|
||||||
# This is supposed to spawn shrapnel and stuff so uhh... TODO?
|
# This is supposed to spawn shrapnel and stuff so uhh... TODO?
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -11,16 +11,233 @@
|
|||||||
- type: ClusterGrenadeVisuals
|
- type: ClusterGrenadeVisuals
|
||||||
state: base
|
state: base
|
||||||
- type: ClusterGrenade
|
- type: ClusterGrenade
|
||||||
|
- type: OnUseTimerTrigger
|
||||||
|
delay: 3.5
|
||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
containers:
|
containers:
|
||||||
cluster-flash: !type:Container
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClusterBang
|
parent: GrenadeBase
|
||||||
id: ClusterBangFull
|
id: ClusterBangFull
|
||||||
|
name: ClusterBang
|
||||||
|
description: Launches three flashbangs after the timer runs out.
|
||||||
suffix: Full
|
suffix: Full
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
state: base-3
|
sprite: Objects/Weapons/Grenades/clusterbang.rsi
|
||||||
|
layers:
|
||||||
|
- state: icon
|
||||||
|
map: ["enum.TriggerVisualLayers.Base"]
|
||||||
- type: ClusterGrenade
|
- type: ClusterGrenade
|
||||||
fillPrototype: GrenadeFlashBang
|
fillPrototype: GrenadeFlashBang
|
||||||
|
distance: 7
|
||||||
|
velocity: 7
|
||||||
|
- type: TimerTriggerVisuals
|
||||||
|
primingSound:
|
||||||
|
path: /Audio/Effects/countdown.ogg
|
||||||
|
- type: GenericVisualizer
|
||||||
|
visuals:
|
||||||
|
enum.Trigger.TriggerVisuals.VisualState:
|
||||||
|
enum.ConstructionVisuals.Layer:
|
||||||
|
Primed: { state: primed }
|
||||||
|
Unprimed: { state: icon }
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Machines/door_lock_off.ogg"
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: GrenadeBase
|
||||||
|
id: ClusterGrenade
|
||||||
|
name: clustergrenade
|
||||||
|
description: Why use one grenade when you can use three at once!
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Grenades/clusterbomb.rsi
|
||||||
|
layers:
|
||||||
|
- state: icon
|
||||||
|
map: ["enum.TriggerVisualLayers.Base"]
|
||||||
|
- type: ClusterGrenade
|
||||||
|
fillPrototype: ExGrenade
|
||||||
|
velocity: 3.5
|
||||||
|
distance: 5
|
||||||
|
- type: OnUseTimerTrigger
|
||||||
|
beepSound:
|
||||||
|
path: "/Audio/Effects/beep1.ogg"
|
||||||
|
params:
|
||||||
|
volume: 5
|
||||||
|
initialBeepDelay: 0
|
||||||
|
beepInterval: 0.5
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Machines/door_lock_off.ogg"
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: ClusterBananaPeel
|
||||||
|
name: cluster banana peel
|
||||||
|
description: Splits into 6 explosive banana peels after throwing, guaranteed fun!
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Hydroponics/banana.rsi
|
||||||
|
state: produce
|
||||||
|
- type: Appearance
|
||||||
|
- type: ClusterGrenade
|
||||||
|
fillPrototype: TrashBananaPeelExplosive
|
||||||
|
maxGrenadesCount: 6
|
||||||
|
baseTriggerDelay: 20
|
||||||
|
- type: DamageOnLand
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 10
|
||||||
|
- type: Damageable
|
||||||
|
damageContainer: Inorganic
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Items/bikehorn.ogg"
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTrigger
|
||||||
|
damage: 10
|
||||||
|
behaviors:
|
||||||
|
- !type:TriggerBehavior
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: ["Destruction"]
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: GrenadeBase
|
||||||
|
id: GrenadeStinger
|
||||||
|
name: stinger grenade
|
||||||
|
description: Nothing to see here, please disperse.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Grenades/stingergrenade.rsi
|
||||||
|
layers:
|
||||||
|
- state: icon
|
||||||
|
map: ["enum.TriggerVisualLayers.Base"]
|
||||||
|
- type: ClusterGrenade
|
||||||
|
fillPrototype: PelletClusterRubber
|
||||||
|
maxGrenadesCount: 30
|
||||||
|
grenadeType: enum.GrenadeType.Shoot
|
||||||
|
- type: FlashOnTrigger
|
||||||
|
range: 7
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Effects/flash_bang.ogg"
|
||||||
|
- type: SpawnOnTrigger
|
||||||
|
proto: GrenadeFlashEffect
|
||||||
|
- type: TimerTriggerVisuals
|
||||||
|
primingSound:
|
||||||
|
path: /Audio/Effects/countdown.ogg
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: GrenadeBase
|
||||||
|
id: GrenadeIncendiary
|
||||||
|
name: incendiary grenade
|
||||||
|
description: Guaranteed to light up the mood.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Grenades/pyrogrenade.rsi
|
||||||
|
layers:
|
||||||
|
- state: icon
|
||||||
|
map: ["enum.TriggerVisualLayers.Base"]
|
||||||
|
- type: ClusterGrenade
|
||||||
|
fillPrototype: PelletClusterIncendiary
|
||||||
|
maxGrenadesCount: 15
|
||||||
|
grenadeType: enum.GrenadeType.Shoot
|
||||||
|
- type: OnUseTimerTrigger
|
||||||
|
beepSound:
|
||||||
|
path: "/Audio/Effects/beep1.ogg"
|
||||||
|
params:
|
||||||
|
volume: 5
|
||||||
|
initialBeepDelay: 0
|
||||||
|
beepInterval: 2
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Weapons/Guns/Gunshots/batrifle.ogg"
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: GrenadeBase
|
||||||
|
id: GrenadeShrapnel
|
||||||
|
name: shrapnel grenade
|
||||||
|
description: Releases a deadly spray of shrapnel that causes severe bleeding.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Weapons/Grenades/shrapnelgrenade.rsi
|
||||||
|
layers:
|
||||||
|
- state: icon
|
||||||
|
map: ["enum.TriggerVisualLayers.Base"]
|
||||||
|
- type: ClusterGrenade
|
||||||
|
fillPrototype: PelletClusterLethal
|
||||||
|
maxGrenadesCount: 30
|
||||||
|
grenadeType: enum.GrenadeType.Shoot
|
||||||
|
- type: OnUseTimerTrigger
|
||||||
|
beepSound:
|
||||||
|
path: "/Audio/Effects/beep1.ogg"
|
||||||
|
params:
|
||||||
|
volume: 5
|
||||||
|
initialBeepDelay: 0
|
||||||
|
beepInterval: 2
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Weapons/Guns/Gunshots/batrifle.ogg"
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: SoapSyndie
|
||||||
|
id: SlipocalypseClusterSoap
|
||||||
|
name: slipocalypse clustersoap
|
||||||
|
description: Spreads small pieces of syndicate soap over an area upon landing on the floor.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Janitorial/soap.rsi
|
||||||
|
layers:
|
||||||
|
- state: syndie-4
|
||||||
|
- type: Appearance
|
||||||
|
- type: ClusterGrenade
|
||||||
|
fillPrototype: SoapletSyndie
|
||||||
|
maxGrenadesCount: 30
|
||||||
|
grenadeTriggerIntervalMax: 0
|
||||||
|
grenadeTriggerIntervalMin: 0
|
||||||
|
baseTriggerDelay: 60
|
||||||
|
randomSpread: true
|
||||||
|
velocity: 3
|
||||||
|
- type: DamageOnLand
|
||||||
|
damage:
|
||||||
|
types:
|
||||||
|
Blunt: 10
|
||||||
|
- type: EmitSoundOnTrigger
|
||||||
|
sound:
|
||||||
|
path: "/Audio/Effects/flash_bang.ogg"
|
||||||
|
- type: Damageable
|
||||||
|
damageContainer: Inorganic
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTrigger
|
||||||
|
damage: 10
|
||||||
|
behaviors:
|
||||||
|
- !type:TriggerBehavior
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: ["Destruction"]
|
||||||
|
- type: ContainerContainer
|
||||||
|
containers:
|
||||||
|
cluster-payload: !type:Container
|
||||||
|
|||||||
@@ -29,7 +29,12 @@
|
|||||||
acts: ["Destruction"]
|
acts: ["Destruction"]
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: AnimationPlayer
|
- type: AnimationPlayer
|
||||||
- type: TimerTriggerVisuals
|
- type: GenericVisualizer
|
||||||
|
visuals:
|
||||||
|
enum.Trigger.TriggerVisuals.VisualState:
|
||||||
|
enum.ConstructionVisuals.Layer:
|
||||||
|
Primed: { state: primed }
|
||||||
|
Unprimed: { state: icon }
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: explosive grenade
|
name: explosive grenade
|
||||||
|
|||||||
@@ -79,6 +79,9 @@
|
|||||||
{
|
{
|
||||||
"name": "syndie-4"
|
"name": "syndie-4"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "syndie-soaplet"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "inhand-left",
|
"name": "inhand-left",
|
||||||
"directions": 4
|
"directions": 4
|
||||||
|
|||||||
|
After Width: | Height: | Size: 157 B |
|
After Width: | Height: | Size: 459 B |
@@ -22,6 +22,19 @@
|
|||||||
{
|
{
|
||||||
"name": "base-3",
|
"name": "base-3",
|
||||||
"directions": 1
|
"directions": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "icon",
|
||||||
|
"directions": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "primed",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 680 B |
|
After Width: | Height: | Size: 467 B |
|
After Width: | Height: | Size: 502 B |
|
After Width: | Height: | Size: 476 B |
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Taken from tgstation and modified by Swept at https://github.com/tgstation/tgstation/commit/29c0ed1b000619cb5398ef921000a8d4502ba0b6 and modified by Swept",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "base-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "base-2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "primed",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 667 B |
|
After Width: | Height: | Size: 234 B |
|
After Width: | Height: | Size: 290 B |
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/b13d244d761a07e200a9a41730bd446e776020d5",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "primed",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-BELT",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 349 B |
|
After Width: | Height: | Size: 233 B |
|
After Width: | Height: | Size: 293 B |
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/b13d244d761a07e200a9a41730bd446e776020d5",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "primed",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-BELT",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 351 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 312 B |
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/b13d244d761a07e200a9a41730bd446e776020d5",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "primed",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "equipped-BELT",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 377 B |
@@ -29,4 +29,4 @@
|
|||||||
"name": "spent"
|
"name": "spent"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||