More anomalies (#13766)
@@ -1,4 +1,5 @@
|
||||
using Content.Shared.Anomaly;
|
||||
using Content.Client.Gravity;
|
||||
using Content.Shared.Anomaly;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Timing;
|
||||
@@ -8,6 +9,7 @@ namespace Content.Client.Anomaly;
|
||||
public sealed class AnomalySystem : SharedAnomalySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly FloatingVisualizerSystem _floating = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -15,6 +17,20 @@ public sealed class AnomalySystem : SharedAnomalySystem
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<AnomalyComponent, AppearanceChangeEvent>(OnAppearanceChanged);
|
||||
SubscribeLocalEvent<AnomalyComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<AnomalyComponent, AnimationCompletedEvent>(OnAnimationComplete);
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, AnomalyComponent component, ComponentStartup args)
|
||||
{
|
||||
_floating.FloatAnimation(uid, component.FloatingOffset, component.AnimationKey, component.AnimationTime);
|
||||
}
|
||||
|
||||
private void OnAnimationComplete(EntityUid uid, AnomalyComponent component, AnimationCompletedEvent args)
|
||||
{
|
||||
if (args.Key != component.AnimationKey)
|
||||
return;
|
||||
_floating.FloatAnimation(uid, component.FloatingOffset, component.AnimationKey, component.AnimationTime);
|
||||
}
|
||||
|
||||
private void OnAppearanceChanged(EntityUid uid, AnomalyComponent component, ref AppearanceChangeEvent args)
|
||||
|
||||
@@ -4,7 +4,10 @@ using Content.Server.Power.EntitySystems;
|
||||
using Content.Shared.Anomaly;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Materials;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
|
||||
namespace Content.Server.Anomaly;
|
||||
|
||||
@@ -91,12 +94,32 @@ public sealed partial class AnomalySystem
|
||||
var randomY = Random.Next((int) gridBounds.Bottom, (int)gridBounds.Top);
|
||||
|
||||
var tile = new Vector2i(randomX, randomY);
|
||||
if (_atmosphere.IsTileSpace(grid, xform.MapUid, tile,
|
||||
mapGridComp: gridComp) || _atmosphere.IsTileAirBlocked(grid, tile, mapGridComp: gridComp))
|
||||
|
||||
// no air-blocked areas.
|
||||
if (_atmosphere.IsTileSpace(grid, xform.MapUid, tile, mapGridComp: gridComp) ||
|
||||
_atmosphere.IsTileAirBlocked(grid, tile, mapGridComp: gridComp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't spawn inside of solid objects
|
||||
var physQuery = GetEntityQuery<PhysicsComponent>();
|
||||
var valid = true;
|
||||
foreach (var ent in gridComp.GetAnchoredEntities(tile))
|
||||
{
|
||||
if (!physQuery.TryGetComponent(ent, out var body))
|
||||
continue;
|
||||
if (body.BodyType != BodyType.Static ||
|
||||
!body.Hard ||
|
||||
(body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
|
||||
continue;
|
||||
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
if (!valid)
|
||||
continue;
|
||||
|
||||
targetCoords = gridComp.GridTileToLocal(tile);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly ExplosionSystem _explosion = default!;
|
||||
[Dependency] private readonly MaterialStorageSystem _material = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
|
||||
public const float MinParticleVariation = 0.8f;
|
||||
@@ -100,13 +99,13 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
|
||||
var multiplier = 1f;
|
||||
if (component.Stability > component.GrowthThreshold)
|
||||
multiplier = component.GrowingPointMultiplier; //more points for unstable
|
||||
else if (component.Stability < component.DecayThreshold)
|
||||
multiplier = component.DecayingPointMultiplier; //less points if it's dying
|
||||
|
||||
//penalty of up to 50% based on health
|
||||
multiplier *= MathF.Pow(1.5f, component.Health) - 0.5f;
|
||||
|
||||
return (int) ((component.MaxPointsPerSecond - component.MinPointsPerSecond) * component.Severity * multiplier);
|
||||
var severityValue = 1 / (1 + MathF.Pow(MathF.E, -7 * (component.Severity - 0.5f)));
|
||||
|
||||
return (int) ((component.MaxPointsPerSecond - component.MinPointsPerSecond) * severityValue * multiplier) + component.MinPointsPerSecond;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -6,11 +6,13 @@ using Content.Shared.Anomaly.Effects.Components;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Anomaly.Effects;
|
||||
|
||||
public sealed class ElectricityAnomalySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly LightningSystem _lightning = default!;
|
||||
[Dependency] private readonly ElectrocutionSystem _electrocution = default!;
|
||||
@@ -25,16 +27,12 @@ public sealed class ElectricityAnomalySystem : EntitySystem
|
||||
|
||||
private void OnPulse(EntityUid uid, ElectricityAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||
{
|
||||
var range = component.MaxElectrocuteRange * args.Stabiltiy;
|
||||
var damage = (int) (component.MaxElectrocuteDamage * args.Severity);
|
||||
var duration = component.MaxElectrocuteDuration * args.Severity;
|
||||
|
||||
var range = component.MaxElectrocuteRange * args.Stability;
|
||||
var xform = Transform(uid);
|
||||
foreach (var comp in _lookup.GetComponentsInRange<StatusEffectsComponent>(xform.MapPosition, range))
|
||||
foreach (var comp in _lookup.GetComponentsInRange<MobStateComponent>(xform.MapPosition, range))
|
||||
{
|
||||
var ent = comp.Owner;
|
||||
|
||||
_electrocution.TryDoElectrocution(ent, uid, damage, duration, true, statusEffects: comp, ignoreInsulation: true);
|
||||
_lightning.ShootLightning(uid, ent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +46,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem
|
||||
if (mobQuery.HasComponent(ent))
|
||||
validEnts.Add(ent);
|
||||
|
||||
if (_random.Prob(0.1f) && poweredQuery.HasComponent(ent))
|
||||
if (_random.Prob(0.2f) && poweredQuery.HasComponent(ent))
|
||||
validEnts.Add(ent);
|
||||
}
|
||||
|
||||
@@ -58,4 +56,32 @@ public sealed class ElectricityAnomalySystem : EntitySystem
|
||||
_lightning.ShootLightning(uid, ent);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var (elec, anom, xform) in EntityQuery<ElectricityAnomalyComponent, AnomalyComponent, TransformComponent>())
|
||||
{
|
||||
if (_timing.CurTime < elec.NextSecond)
|
||||
continue;
|
||||
elec.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1);
|
||||
|
||||
var owner = xform.Owner;
|
||||
|
||||
if (!_random.Prob(elec.PassiveElectrocutionChance * anom.Stability))
|
||||
continue;
|
||||
|
||||
var range = elec.MaxElectrocuteRange * anom.Stability;
|
||||
var damage = (int) (elec.MaxElectrocuteDamage * anom.Severity);
|
||||
var duration = elec.MaxElectrocuteDuration * anom.Severity;
|
||||
|
||||
foreach (var comp in _lookup.GetComponentsInRange<StatusEffectsComponent>(xform.MapPosition, range))
|
||||
{
|
||||
var ent = comp.Owner;
|
||||
|
||||
_electrocution.TryDoElectrocution(ent, owner, damage, duration, true, statusEffects: comp, ignoreInsulation: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
97
Content.Server/Anomaly/Effects/FleshAnomalySystem.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Maps;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Content.Shared.Anomaly.Effects.Components;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Anomaly.Effects;
|
||||
|
||||
public sealed class FleshAnomalySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IMapManager _map = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly ITileDefinitionManager _tiledef = default!;
|
||||
[Dependency] private readonly TileSystem _tile = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<FleshAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
||||
SubscribeLocalEvent<FleshAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
|
||||
SubscribeLocalEvent<FleshAnomalyComponent, AnomalyStabilityChangedEvent>(OnSeverityChanged);
|
||||
}
|
||||
|
||||
private void OnPulse(EntityUid uid, FleshAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||
{
|
||||
var range = component.SpawnRange * args.Stability;
|
||||
var amount = (int) (component.MaxSpawnAmount * args.Severity + 0.5f);
|
||||
|
||||
var xform = Transform(uid);
|
||||
SpawnMonstersOnOpenTiles(component, xform, amount, range);
|
||||
}
|
||||
|
||||
private void OnSupercritical(EntityUid uid, FleshAnomalyComponent component, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
SpawnMonstersOnOpenTiles(component, xform, component.MaxSpawnAmount, component.SpawnRange);
|
||||
Spawn(component.SupercriticalSpawn, xform.Coordinates);
|
||||
}
|
||||
|
||||
private void OnSeverityChanged(EntityUid uid, FleshAnomalyComponent component, ref AnomalyStabilityChangedEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
if (!_map.TryGetGrid(xform.GridUid, out var grid))
|
||||
return;
|
||||
|
||||
var radius = component.SpawnRange * args.Stability;
|
||||
var fleshTile = (ContentTileDefinition) _tiledef[component.FleshTileId];
|
||||
var localpos = xform.Coordinates.Position;
|
||||
var tilerefs = grid.GetLocalTilesIntersecting(
|
||||
new Box2(localpos + (-radius, -radius), localpos + (radius, radius)));
|
||||
foreach (var tileref in tilerefs)
|
||||
{
|
||||
if (!_random.Prob(0.33f))
|
||||
continue;
|
||||
_tile.ReplaceTile(tileref, fleshTile);
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnMonstersOnOpenTiles(FleshAnomalyComponent component, TransformComponent xform, int amount, float radius)
|
||||
{
|
||||
if (!_map.TryGetGrid(xform.GridUid, out var grid))
|
||||
return;
|
||||
|
||||
var localpos = xform.Coordinates.Position;
|
||||
var tilerefs = grid.GetLocalTilesIntersecting(
|
||||
new Box2(localpos + (-radius, -radius), localpos + (radius, radius))).ToArray();
|
||||
_random.Shuffle(tilerefs);
|
||||
var physQuery = GetEntityQuery<PhysicsComponent>();
|
||||
var amountCounter = 0;
|
||||
foreach (var tileref in tilerefs)
|
||||
{
|
||||
var valid = true;
|
||||
foreach (var ent in grid.GetAnchoredEntities(tileref.GridIndices))
|
||||
{
|
||||
if (!physQuery.TryGetComponent(ent, out var body))
|
||||
continue;
|
||||
if (body.BodyType != BodyType.Static ||
|
||||
!body.Hard ||
|
||||
(body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
|
||||
continue;
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
if (!valid)
|
||||
continue;
|
||||
amountCounter++;
|
||||
Spawn(_random.Pick(component.Spawns), tileref.GridIndices.ToEntityCoordinates(xform.GridUid.Value, _map));
|
||||
if (amountCounter >= amount)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public sealed class PyroclasticAnomalySystem : EntitySystem
|
||||
private void OnPulse(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var ignitionRadius = component.MaximumIgnitionRadius * args.Stabiltiy;
|
||||
var ignitionRadius = component.MaximumIgnitionRadius * args.Stability;
|
||||
IgniteNearby(xform.Coordinates, args.Severity, ignitionRadius);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Server.Decals;
|
||||
using Content.Shared.Decals;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Maps;
|
||||
@@ -54,6 +55,28 @@ public sealed class TileSystem : EntitySystem
|
||||
return DeconstructTile(tileRef);
|
||||
}
|
||||
|
||||
public bool ReplaceTile(TileRef tileref, ContentTileDefinition replacementTile)
|
||||
{
|
||||
if (!TryComp<MapGridComponent>(tileref.GridUid, out var grid))
|
||||
return false;
|
||||
return ReplaceTile(tileref, replacementTile, tileref.GridUid, grid);
|
||||
}
|
||||
|
||||
public bool ReplaceTile(TileRef tileref, ContentTileDefinition replacementTile, EntityUid grid, MapGridComponent? component = null)
|
||||
{
|
||||
if (!Resolve(grid, ref component))
|
||||
return false;
|
||||
|
||||
var variant = _robustRandom.Pick(replacementTile.PlacementVariants);
|
||||
var decals = _decal.GetDecalsInRange(tileref.GridUid, tileref.GridPosition().SnapToGrid(EntityManager, _mapManager).Position, 0.5f);
|
||||
foreach (var (id, _) in decals)
|
||||
{
|
||||
_decal.RemoveDecal(tileref.GridUid, id);
|
||||
}
|
||||
component.SetTile(tileref.GridIndices, new Tile(replacementTile.TileId, 0, variant));
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DeconstructTile(TileRef tileRef)
|
||||
{
|
||||
var indices = tileRef.GridIndices;
|
||||
|
||||
@@ -62,7 +62,7 @@ public sealed class AnomalyComponent : Component
|
||||
/// The amount of health lost when the stability is below the <see cref="DecayThreshold"/>
|
||||
/// </summary>
|
||||
[DataField("healthChangePerSecond"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float HealthChangePerSecond = -0.05f;
|
||||
public float HealthChangePerSecond = -0.01f;
|
||||
#endregion
|
||||
|
||||
#region Growth
|
||||
@@ -208,21 +208,14 @@ public sealed class AnomalyComponent : Component
|
||||
/// This doesn't include the point bonus for being unstable.
|
||||
/// </summary>
|
||||
[DataField("maxPointsPerSecond")]
|
||||
public int MaxPointsPerSecond = 65;
|
||||
public int MaxPointsPerSecond = 100;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier applied to the point value for the
|
||||
/// anomaly being above the <see cref="GrowthThreshold"/>
|
||||
/// </summary>
|
||||
[DataField("growingPointMultiplier")]
|
||||
public float GrowingPointMultiplier = 1.2f;
|
||||
|
||||
/// <summary>
|
||||
/// The multiplier applied to the point value for the
|
||||
/// anomaly being below the <see cref="DecayThreshold"/>
|
||||
/// </summary>
|
||||
[DataField("decayingPointMultiplier")]
|
||||
public float DecayingPointMultiplier = 0.75f;
|
||||
public float GrowingPointMultiplier = 1.5f;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -238,6 +231,24 @@ public sealed class AnomalyComponent : Component
|
||||
/// </summary>
|
||||
[DataField("anomalyContactDamageSound")]
|
||||
public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
|
||||
|
||||
#region Floating Animation
|
||||
/// <summary>
|
||||
/// How long it takes to go from the bottom of the animation to the top.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("animationTime")]
|
||||
public readonly float AnimationTime = 2f;
|
||||
|
||||
/// <summary>
|
||||
/// How far it goes in any direction.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("offset")]
|
||||
public readonly Vector2 FloatingOffset = (0, 0.15f);
|
||||
|
||||
public readonly string AnimationKey = "anomalyfloat";
|
||||
#endregion
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
@@ -260,14 +271,10 @@ public sealed class AnomalyComponentState : ComponentState
|
||||
/// <summary>
|
||||
/// Event raised at regular intervals on an anomaly to do whatever its effect is.
|
||||
/// </summary>
|
||||
/// <param name="Stabiltiy"></param>
|
||||
/// <param name="Stability"></param>
|
||||
/// <param name="Severity"></param>
|
||||
[ByRefEvent]
|
||||
public readonly record struct AnomalyPulseEvent(float Stabiltiy, float Severity)
|
||||
{
|
||||
public readonly float Stabiltiy = Stabiltiy;
|
||||
public readonly float Severity = Severity;
|
||||
}
|
||||
public readonly record struct AnomalyPulseEvent(float Stability, float Severity);
|
||||
|
||||
/// <summary>
|
||||
/// Event raised on an anomaly when it reaches a supercritical point.
|
||||
|
||||
73
Content.Shared/Anomaly/Effects/BluespaceAnomalySystem.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Anomaly.Components;
|
||||
using Content.Shared.Anomaly.Effects.Components;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Teleportation.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared.Anomaly.Effects;
|
||||
|
||||
public sealed class BluespaceAnomalySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xform = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<BluespaceAnomalyComponent, AnomalyPulseEvent>(OnPulse);
|
||||
SubscribeLocalEvent<BluespaceAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
|
||||
SubscribeLocalEvent<BluespaceAnomalyComponent, AnomalySeverityChangedEvent>(OnSeverityChanged);
|
||||
}
|
||||
|
||||
private void OnPulse(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalyPulseEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var range = component.MaxShuffleRadius * args.Severity;
|
||||
var allEnts = _lookup.GetComponentsInRange<MobStateComponent>(xform.Coordinates, range)
|
||||
.Select(x => x.Owner).ToList();
|
||||
allEnts.Add(uid);
|
||||
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
var coords = new List<EntityCoordinates>();
|
||||
foreach (var ent in allEnts)
|
||||
{
|
||||
if (xformQuery.TryGetComponent(ent, out var xf))
|
||||
coords.Add(xf.Coordinates);
|
||||
}
|
||||
|
||||
_random.Shuffle(coords);
|
||||
for (var i = 0; i < allEnts.Count; i++)
|
||||
{
|
||||
_xform.SetCoordinates(allEnts[i], coords[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSupercritical(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalySupercriticalEvent args)
|
||||
{
|
||||
var xform = Transform(uid);
|
||||
var mapPos = _xform.GetWorldPosition(xform);
|
||||
var radius = component.SupercriticalTeleportRadius;
|
||||
var gridBounds = new Box2(mapPos - (radius, radius), mapPos + (radius, radius));
|
||||
foreach (var comp in _lookup.GetComponentsInRange<MobStateComponent>(xform.Coordinates, component.MaxShuffleRadius))
|
||||
{
|
||||
var ent = comp.Owner;
|
||||
var randomX = _random.NextFloat(gridBounds.Left, gridBounds.Right);
|
||||
var randomY = _random.NextFloat(gridBounds.Bottom, gridBounds.Top);
|
||||
|
||||
var pos = new Vector2(randomX, randomY);
|
||||
_xform.SetWorldPosition(ent, pos);
|
||||
_audio.PlayPvs(component.TeleportSound, ent);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSeverityChanged(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalySeverityChangedEvent args)
|
||||
{
|
||||
if (!TryComp<PortalComponent>(uid, out var portal))
|
||||
return;
|
||||
portal.MaxRandomRadius = (component.MaxPortalRadius - component.MinPortalRadius) * args.Severity + component.MinPortalRadius;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Anomaly.Effects.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(BluespaceAnomalySystem))]
|
||||
public sealed class BluespaceAnomalyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum radius that the shuffle effect will extend for
|
||||
/// scales with stability
|
||||
/// </summary>
|
||||
[DataField("maxShuffleRadius"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MaxShuffleRadius = 10;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum MAX distance the portal this anomaly is tied to can teleport you.
|
||||
/// </summary>
|
||||
[DataField("maxPortalRadius"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MaxPortalRadius = 25;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum MAX distance the portal this anomaly is tied to can teleport you.
|
||||
/// </summary>
|
||||
[DataField("minPortalRadius"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MinPortalRadius = 10;
|
||||
|
||||
/// <summary>
|
||||
/// How far the supercritical event can teleport you
|
||||
/// </summary>
|
||||
[DataField("superCriticalTeleportRadius"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float SupercriticalTeleportRadius = 50f;
|
||||
|
||||
/// <summary>
|
||||
/// The sound played after players are shuffled/teleported around
|
||||
/// </summary>
|
||||
[DataField("teleportSound"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg");
|
||||
}
|
||||
@@ -1,14 +1,41 @@
|
||||
namespace Content.Shared.Anomaly.Effects.Components;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Anomaly.Effects.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class ElectricityAnomalyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum radius of the passive electrocution effect
|
||||
/// scales with stability
|
||||
/// </summary>
|
||||
[DataField("maxElectrocutionRange"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MaxElectrocuteRange = 6f;
|
||||
public float MaxElectrocuteRange = 7f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of damage the electrocution can do
|
||||
/// scales with severity
|
||||
/// </summary>
|
||||
[DataField("maxElectrocuteDamage"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float MaxElectrocuteDamage = 20f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of time the electrocution lasts
|
||||
/// scales with severity
|
||||
/// </summary>
|
||||
[DataField("maxElectrocuteDuration"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan MaxElectrocuteDuration = TimeSpan.FromSeconds(8);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum chance that each second, when in range of the anomaly, you will be electrocuted.
|
||||
/// scales with stability
|
||||
/// </summary>
|
||||
[DataField("passiveElectrocutionChance"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float PassiveElectrocutionChance = 0.05f;
|
||||
|
||||
/// <summary>
|
||||
/// Used for tracking seconds, so that we can shock people in a non-tick-dependent way.
|
||||
/// </summary>
|
||||
[DataField("nextSecond", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan NextSecond = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
|
||||
|
||||
namespace Content.Shared.Anomaly.Effects.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed class FleshAnomalyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of entities that are random picked to be spawned on each pulse
|
||||
/// </summary>
|
||||
[DataField("spawns", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
|
||||
public List<string> Spawns = new();
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of entities that spawn per pulse
|
||||
/// scales with severity.
|
||||
/// </summary>
|
||||
[DataField("maxSpawnAmount"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public int MaxSpawnAmount = 8;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum radius the entities will spawn in.
|
||||
/// Also governs the maximum reach of flesh tiles
|
||||
/// scales with stability
|
||||
/// </summary>
|
||||
[DataField("spawnRange"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public float SpawnRange = 4f;
|
||||
|
||||
/// <summary>
|
||||
/// The tile that is spawned by the anomaly's effect
|
||||
/// </summary>
|
||||
[DataField("fleshTileId", customTypeSerializer: typeof(PrototypeIdSerializer<ContentTileDefinition>)), ViewVariables(VVAccess.ReadWrite)]
|
||||
public string FleshTileId = "FloorFlesh";
|
||||
|
||||
/// <summary>
|
||||
/// The entity spawned when the anomaly goes supercritical
|
||||
/// </summary>
|
||||
[DataField("superCriticalSpawn", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
|
||||
public string SupercriticalSpawn = "FleshKudzu";
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
namespace Content.Shared.Anomaly.Effects.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
[RegisterComponent]
|
||||
namespace Content.Shared.Anomaly.Effects.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed class GravityAnomalyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -13,7 +13,7 @@ public sealed class PyroclasticAnomalyComponent : Component
|
||||
/// I have no clue if this is balanced.
|
||||
/// </remarks>
|
||||
[DataField("heatPerSecond")]
|
||||
public float HeatPerSecond = 50;
|
||||
public float HeatPerSecond = 25;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum distance from which you can be ignited by the anomaly.
|
||||
@@ -50,5 +50,5 @@ public sealed class PyroclasticAnomalyComponent : Component
|
||||
/// The amount of gas released when the anomaly goes supercritical
|
||||
/// </summary>
|
||||
[DataField("supercriticalMoleAmount")]
|
||||
public float SupercriticalMoleAmount = 50f;
|
||||
public float SupercriticalMoleAmount = 75f;
|
||||
}
|
||||
|
||||
@@ -29,9 +29,8 @@ public abstract class SharedGravityAnomalySystem : EntitySystem
|
||||
foreach (var ent in lookup)
|
||||
{
|
||||
var tempXform = Transform(ent);
|
||||
|
||||
var foo = tempXform.MapPosition.Position - xform.MapPosition.Position;
|
||||
_throwing.TryThrow(ent, foo.Normalized * 10, strength, uid, 0);
|
||||
_throwing.TryThrow(ent, foo * 10, strength, uid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +53,6 @@ public abstract class SharedGravityAnomalySystem : EntitySystem
|
||||
var tempXform = Transform(ent);
|
||||
|
||||
var foo = tempXform.MapPosition.Position - xform.MapPosition.Position;
|
||||
Logger.Debug($"{ToPrettyString(ent)}: {foo}: {foo.Normalized}: {foo.Normalized * 10}");
|
||||
_throwing.TryThrow(ent, foo * 5, strength, uid, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,9 @@ public abstract class SharedAnomalySystem : EntitySystem
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
if (!Timing.IsFirstTimePredicted)
|
||||
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;
|
||||
@@ -173,6 +176,10 @@ public abstract class SharedAnomalySystem : EntitySystem
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
if (!Timing.IsFirstTimePredicted)
|
||||
return;
|
||||
|
||||
Audio.PlayPvs(component.SupercriticalSound, uid);
|
||||
|
||||
var ev = new AnomalySupercriticalEvent();
|
||||
|
||||
@@ -82,6 +82,7 @@ tiles-asteroid-ironsand-pebbles = asteroid ironsand pebbles
|
||||
tiles-asteroid-ironsand-rock = asteroid ironsand rock
|
||||
tiles-cave = cave
|
||||
tiles-cave-drought = cave drought
|
||||
tiles-flesh-floor = flesh floor
|
||||
tiles-techmaint3-floor = grated maintenance floor
|
||||
tiles-techmaint2-floor = steel maintenance floor
|
||||
tiles-wood2 = wood pattern floor
|
||||
|
||||
@@ -13,4 +13,6 @@
|
||||
- AnomalyPyroclastic
|
||||
- AnomalyGravity
|
||||
- AnomalyElectricity
|
||||
- AnomalyFlesh
|
||||
- AnomalyBluespace
|
||||
chance: 1
|
||||
|
||||
160
Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml
Normal file
@@ -0,0 +1,160 @@
|
||||
- type: entity
|
||||
parent: SimpleMobBase
|
||||
id: BaseMobFlesh
|
||||
name: aberrant flesh
|
||||
description: A shambling mass of flesh, animated through anomalous energy.
|
||||
abstract: true
|
||||
components:
|
||||
- type: HTN
|
||||
rootTask: SimpleHostileCompound
|
||||
- type: Faction
|
||||
factions:
|
||||
- SimpleHostile
|
||||
- type: Tag
|
||||
tags:
|
||||
- DoorBumpOpener
|
||||
- Flesh
|
||||
- type: Sprite
|
||||
drawdepth: Mobs
|
||||
sprite: Mobs/Aliens/flesh.rsi
|
||||
- type: MovementAlwaysTouching
|
||||
- type: MovementSpeedModifier
|
||||
baseWalkSpeed: 1
|
||||
baseSprintSpeed: 1.5
|
||||
- type: MobState
|
||||
allowedStates:
|
||||
- Alive
|
||||
- Dead
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
75: Dead
|
||||
- type: Stamina
|
||||
excess: 50
|
||||
- type: Appearance
|
||||
- type: Butcherable
|
||||
spawned:
|
||||
- id: FoodMeat
|
||||
amount: 1
|
||||
- type: Bloodstream
|
||||
bloodMaxVolume: 500
|
||||
- type: CombatMode
|
||||
disarmAction:
|
||||
enabled: false
|
||||
autoPopulate: false
|
||||
name: action-name-disarm
|
||||
- type: MeleeWeapon
|
||||
hidden: true
|
||||
soundHit:
|
||||
path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
|
||||
angle: 0
|
||||
animation: WeaponArcClaw
|
||||
damage:
|
||||
types:
|
||||
Slash: 3
|
||||
- type: ReplacementAccent
|
||||
accent: genericAggressive
|
||||
|
||||
- type: entity
|
||||
parent: BaseMobFlesh
|
||||
id: MobFleshJared
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
state: jared
|
||||
- type: DamageStateVisuals
|
||||
states:
|
||||
Alive:
|
||||
Base: jared
|
||||
Critical:
|
||||
Base: dead
|
||||
Dead:
|
||||
Base: dead
|
||||
- type: MeleeWeapon
|
||||
hidden: true
|
||||
soundHit:
|
||||
path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
|
||||
angle: 0
|
||||
animation: WeaponArcClaw
|
||||
damage:
|
||||
types:
|
||||
Slash: 5
|
||||
|
||||
- type: entity
|
||||
parent: BaseMobFlesh
|
||||
id: MobFleshGolem
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
state: golem
|
||||
- type: DamageStateVisuals
|
||||
states:
|
||||
Alive:
|
||||
Base: golem
|
||||
Critical:
|
||||
Base: dead
|
||||
Dead:
|
||||
Base: dead
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
50: Dead
|
||||
- type: MeleeWeapon
|
||||
hidden: true
|
||||
soundHit:
|
||||
path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
|
||||
angle: 0
|
||||
animation: WeaponArcClaw
|
||||
damage:
|
||||
types:
|
||||
Slash: 5
|
||||
|
||||
- type: entity
|
||||
parent: BaseMobFlesh
|
||||
id: MobFleshClamp
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
state: clamp
|
||||
- type: DamageStateVisuals
|
||||
states:
|
||||
Alive:
|
||||
Base: clamp
|
||||
Critical:
|
||||
Base: dead
|
||||
Dead:
|
||||
Base: dead
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
30: Dead
|
||||
- type: MovementSpeedModifier
|
||||
baseWalkSpeed: 2
|
||||
baseSprintSpeed: 2.5
|
||||
|
||||
- type: entity
|
||||
parent: BaseMobFlesh
|
||||
id: MobFleshLover
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
state: lover
|
||||
- type: DamageStateVisuals
|
||||
states:
|
||||
Alive:
|
||||
Base: lover
|
||||
Critical:
|
||||
Base: dead
|
||||
Dead:
|
||||
Base: dead
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
30: Dead
|
||||
- type: MovementSpeedModifier
|
||||
baseWalkSpeed: 2
|
||||
baseSprintSpeed: 2.5
|
||||
@@ -14,6 +14,7 @@
|
||||
"/Audio/Weapons/slash.ogg"
|
||||
- type: Sprite
|
||||
sprite: Objects/Misc/kudzu.rsi
|
||||
color: "#ff0000"
|
||||
state: kudzu_11
|
||||
drawdepth: Overdoors
|
||||
netsync: false
|
||||
@@ -77,3 +78,55 @@
|
||||
- type: SlowContacts
|
||||
walkSpeedModifier: 0.2
|
||||
sprintSpeedModifier: 0.2
|
||||
|
||||
- type: entity
|
||||
id: FleshKudzu
|
||||
name: tendons
|
||||
description: A rapidly growing cluster of meaty tendons. WHY ARE YOU STOPPING TO LOOK AT IT?!
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
snap:
|
||||
- Wall
|
||||
components:
|
||||
- type: MeleeSound
|
||||
soundGroups:
|
||||
Brute:
|
||||
path:
|
||||
"/Audio/Weapons/slash.ogg"
|
||||
- type: Sprite
|
||||
sprite: Objects/Misc/fleshkudzu.rsi
|
||||
state: base
|
||||
drawdepth: Overdoors
|
||||
netsync: false
|
||||
- type: Appearance
|
||||
- type: Clickable
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Physics
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
- hard: false
|
||||
density: 7
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.5,-0.5,0.5,0.5"
|
||||
layer:
|
||||
- MidImpassable
|
||||
- type: Damageable
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 10
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- type: Spreader
|
||||
growthResult: FleshKudzu
|
||||
chance: 1
|
||||
- type: SlowContacts
|
||||
walkSpeedModifier: 0.2
|
||||
sprintSpeedModifier: 0.2
|
||||
ignoreWhitelist:
|
||||
tags:
|
||||
- Flesh
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
- type: entity
|
||||
id: FleshBlocker
|
||||
parent: BaseStructure
|
||||
name: flesh clump
|
||||
description: An annoying clump of flesh.
|
||||
components:
|
||||
- type: InteractionOutline
|
||||
- type: Sprite
|
||||
noRot: true
|
||||
sprite: Structures/Decoration/flesh_decoration.rsi
|
||||
layers:
|
||||
- state: closed
|
||||
map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
- shape:
|
||||
!type:PhysShapeCircle
|
||||
radius: 0.3
|
||||
density: 190
|
||||
mask:
|
||||
- MachineMask
|
||||
layer:
|
||||
- Impassable
|
||||
- type: RandomSprite
|
||||
available:
|
||||
- enum.DamageStateVisualLayers.Base:
|
||||
closed: ""
|
||||
- enum.DamageStateVisualLayers.Base:
|
||||
ajar: ""
|
||||
- enum.DamageStateVisualLayers.Base:
|
||||
open: ""
|
||||
- type: Damageable
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 25
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
@@ -33,12 +33,14 @@
|
||||
- MobLayer
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
drawdepth: Items
|
||||
noRot: true
|
||||
drawdepth: Effects #it needs to draw over stuff.
|
||||
sprite: Structures/Specific/anomaly.rsi
|
||||
- type: InteractionOutline
|
||||
- type: Clickable
|
||||
- type: Damageable
|
||||
- type: Appearance
|
||||
- type: AnimationPlayer
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- AnomalousResearch
|
||||
@@ -71,7 +73,6 @@
|
||||
suffix: Gravity
|
||||
components:
|
||||
- type: Sprite
|
||||
drawdepth: Effects #it needs to draw over stuff.
|
||||
layers:
|
||||
- state: anom2
|
||||
map: ["enum.AnomalyVisualLayers.Base"]
|
||||
@@ -106,3 +107,75 @@
|
||||
castShadows: false
|
||||
- type: ElectricityAnomaly
|
||||
- type: Electrified
|
||||
|
||||
- type: entity
|
||||
id: AnomalyFlesh
|
||||
parent: BaseAnomaly
|
||||
suffix: Flesh
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: anom5
|
||||
map: ["enum.AnomalyVisualLayers.Base"]
|
||||
- state: anom5-pulse
|
||||
map: ["enum.AnomalyVisualLayers.Animated"]
|
||||
visible: false
|
||||
- type: PointLight
|
||||
radius: 2.0
|
||||
energy: 7.5
|
||||
color: "#cb5b7e"
|
||||
castShadows: false
|
||||
- type: FleshAnomaly
|
||||
spawns:
|
||||
- MobFleshJared
|
||||
- MobFleshGolem
|
||||
- MobFleshClamp
|
||||
- MobFleshLover
|
||||
- FleshBlocker
|
||||
|
||||
- type: entity
|
||||
id: AnomalyBluespace
|
||||
parent: BaseAnomaly
|
||||
suffix: Bluespace
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: anom4
|
||||
map: ["enum.AnomalyVisualLayers.Base"]
|
||||
- state: anom4-pulse
|
||||
map: ["enum.AnomalyVisualLayers.Animated"]
|
||||
visible: false
|
||||
- type: PointLight
|
||||
radius: 2.0
|
||||
energy: 7.5
|
||||
color: "#00ccff"
|
||||
castShadows: false
|
||||
- type: BluespaceAnomaly
|
||||
- type: Portal
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
- shape:
|
||||
!type:PhysShapeCircle
|
||||
radius: 0.35
|
||||
density: 50
|
||||
mask:
|
||||
- MobMask
|
||||
layer:
|
||||
- MobLayer
|
||||
- id: portalFixture
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.25,-0.48,0.25,0.48"
|
||||
mask:
|
||||
- FullTileMask
|
||||
layer:
|
||||
- WallLayer
|
||||
hard: false
|
||||
- type: Anomaly
|
||||
pulseSound:
|
||||
collection: RadiationPulse
|
||||
params:
|
||||
volume: 5
|
||||
anomalyContactDamage:
|
||||
types:
|
||||
Radiation: 10
|
||||
|
||||
@@ -1367,6 +1367,22 @@
|
||||
thermalConductivity: 0.04
|
||||
heatCapacity: 10000
|
||||
|
||||
- type: tile
|
||||
id: FloorFlesh
|
||||
name: tiles-flesh-floor
|
||||
sprite: /Textures/Tiles/meat.png
|
||||
variants: 4
|
||||
placementVariants: [0, 1, 2, 3]
|
||||
baseTurfs:
|
||||
- Plating
|
||||
isSubfloor: false
|
||||
canCrowbar: true
|
||||
footstepSounds:
|
||||
collection: BarestepCarpet
|
||||
friction: 0.20 #slippy
|
||||
thermalConductivity: 0.04
|
||||
heatCapacity: 10000
|
||||
|
||||
- type: tile
|
||||
id: FloorTechMaint2
|
||||
name: tiles-techmaint2-floor
|
||||
|
||||
@@ -216,6 +216,9 @@
|
||||
- type: Tag
|
||||
id: FireAxe
|
||||
|
||||
- type: Tag
|
||||
id: Flesh
|
||||
|
||||
- type: Tag
|
||||
id: WhitelistChameleon
|
||||
|
||||
|
||||
BIN
Resources/Textures/Mobs/Aliens/flesh.rsi/clamp.png
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
Resources/Textures/Mobs/Aliens/flesh.rsi/dead.png
Normal file
|
After Width: | Height: | Size: 311 B |
BIN
Resources/Textures/Mobs/Aliens/flesh.rsi/golem.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
Resources/Textures/Mobs/Aliens/flesh.rsi/jared.png
Normal file
|
After Width: | Height: | Size: 741 B |
BIN
Resources/Textures/Mobs/Aliens/flesh.rsi/lover.png
Normal file
|
After Width: | Height: | Size: 723 B |
27
Resources/Textures/Mobs/Aliens/flesh.rsi/meta.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Created by EmoGarbage404 (github) for space-station-14, credit to Aleksh#7552 (discord) for original concepts and designs",
|
||||
"states": [
|
||||
{
|
||||
"name": "clamp"
|
||||
},
|
||||
{
|
||||
"name": "dead"
|
||||
},
|
||||
{
|
||||
"name": "golem",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "jared"
|
||||
},
|
||||
{
|
||||
"name": "lover"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/Objects/Misc/fleshkudzu.rsi/base.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
14
Resources/Textures/Objects/Misc/fleshkudzu.rsi/meta.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC0-1.0",
|
||||
"copyright": "Created by EmoGarbage404 (github) for space-station-14",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "base"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 508 B |
|
After Width: | Height: | Size: 505 B |
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 1,
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Created by Aleksh#7552 (discord) for space-station-14",
|
||||
"states": [
|
||||
{
|
||||
"name": "ajar"
|
||||
},
|
||||
{
|
||||
"name": "closed"
|
||||
},
|
||||
{
|
||||
"name": "open"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 436 B |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Resources/Textures/Structures/Specific/anomaly.rsi/anom5.png
Normal file
|
After Width: | Height: | Size: 429 B |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC0-1.0",
|
||||
"copyright": "Created by EmoGarbage; anom3, anom3-pulse, anom4, anom4-pulse are CC-BY-SA-3.0 at https://github.com/ParadiseSS13/Paradise/blob/master/icons/effects/effects.dmi",
|
||||
"copyright": "Created by EmoGarbage; anom3, anom3-pulse, anom4, anom4-pulse are CC-BY-SA-3.0 at https://github.com/ParadiseSS13/Paradise/blob/master/icons/effects/effects.dmi; anom5, anom5-pulse are CC-BY-SA-3.0 by Aleksh#7552 (discord) for space-station-14",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
@@ -92,6 +92,20 @@
|
||||
0.15
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "anom5"
|
||||
},
|
||||
{
|
||||
"name": "anom5-pulse",
|
||||
"delays": [
|
||||
[
|
||||
0.25,
|
||||
0.25,
|
||||
0.25,
|
||||
0.25
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -56,3 +56,7 @@
|
||||
copyright: "by brainfood for space-station-14, ."
|
||||
source: "https://github.com/space-wizards/space-station-14/pull/12193"
|
||||
|
||||
- files: ["meat.png"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Created by EmoGarbage404 (github) for space-station-14."
|
||||
source: "https://github.com/space-wizards/space-station-14/pull/13766"
|
||||
|
||||
BIN
Resources/Textures/Tiles/meat.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |