Prettier window breaking (#2368)

* Put the damage in the windows

* add crack overlays

* Window cracking

* glass related sounds

* let's use a valid state

* run optipng on these for posterity

* Examine damage descriptions

* add "Constructible" to dictionary

* Downmix stereo effects to mono

* breaking and knocking

* Add shard etc. sprites

* shard inhands

* more sprite wrangling

* Expand destructiblecomponent drop system + implement it for windows

* Shard descriptions

* Random sprite component

* no nullbabby

* Random destroysounds

* random offset on destructible drops

* fix fucked yaml

* sound collections

* random pitch for knocking

* Localization

* hascomponent

* better spawnondestroy

* missed one
This commit is contained in:
Peter Wedder
2020-10-29 21:42:11 +02:00
committed by GitHub
parent 68078e626a
commit bd4f2b41df
86 changed files with 1447 additions and 61 deletions

View File

@@ -1,4 +1,5 @@
using Content.Client.GameObjects.EntitySystems;
using System.Diagnostics.CodeAnalysis;
using Content.Client.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components;
using Robust.Client.GameObjects;
using Robust.Client.Interfaces.GameObjects.Components;
@@ -34,14 +35,33 @@ namespace Content.Client.GameObjects.Components
Owner.EntityManager.EventBus.RaiseEvent(EventSource.Local, new WindowSmoothDirtyEvent(Owner));
var state0 = $"{_stateBase}0";
const string cracksRSIPath = "/Textures/Constructible/Structures/Windows/cracks.rsi";
_sprite.LayerMapSet(CornerLayers.SE, _sprite.AddLayerState(state0));
_sprite.LayerSetDirOffset(CornerLayers.SE, SpriteComponent.DirectionOffset.None);
_sprite.LayerMapSet(WindowDamageLayers.DamageSE, _sprite.AddLayerState("0_1", cracksRSIPath));
_sprite.LayerSetShader(WindowDamageLayers.DamageSE, "unshaded");
_sprite.LayerSetVisible(WindowDamageLayers.DamageSE, false);
_sprite.LayerMapSet(CornerLayers.NE, _sprite.AddLayerState(state0));
_sprite.LayerSetDirOffset(CornerLayers.NE, SpriteComponent.DirectionOffset.CounterClockwise);
_sprite.LayerMapSet(WindowDamageLayers.DamageNE, _sprite.AddLayerState("0_1", cracksRSIPath));
_sprite.LayerSetDirOffset(WindowDamageLayers.DamageNE, SpriteComponent.DirectionOffset.CounterClockwise);
_sprite.LayerSetShader(WindowDamageLayers.DamageNE, "unshaded");
_sprite.LayerSetVisible(WindowDamageLayers.DamageNE, false);
_sprite.LayerMapSet(CornerLayers.NW, _sprite.AddLayerState(state0));
_sprite.LayerSetDirOffset(CornerLayers.NW, SpriteComponent.DirectionOffset.Flip);
_sprite.LayerMapSet(WindowDamageLayers.DamageNW, _sprite.AddLayerState("0_1", cracksRSIPath));
_sprite.LayerSetDirOffset(WindowDamageLayers.DamageNW, SpriteComponent.DirectionOffset.Flip);
_sprite.LayerSetShader(WindowDamageLayers.DamageNW, "unshaded");
_sprite.LayerSetVisible(WindowDamageLayers.DamageNW, false);
_sprite.LayerMapSet(CornerLayers.SW, _sprite.AddLayerState(state0));
_sprite.LayerSetDirOffset(CornerLayers.SW, SpriteComponent.DirectionOffset.Clockwise);
_sprite.LayerMapSet(WindowDamageLayers.DamageSW, _sprite.AddLayerState("0_1", cracksRSIPath));
_sprite.LayerSetDirOffset(WindowDamageLayers.DamageSW, SpriteComponent.DirectionOffset.Clockwise);
_sprite.LayerSetShader(WindowDamageLayers.DamageSW, "unshaded");
_sprite.LayerSetVisible(WindowDamageLayers.DamageSW, false);
}
/// <inheritdoc />
@@ -91,4 +111,13 @@ namespace Content.Client.GameObjects.Components
serializer.DataField(ref _stateBase, "base", null);
}
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
public enum WindowDamageLayers
{
DamageSE,
DamageNE,
DamageNW,
DamageSW
}
}

View File

@@ -0,0 +1,60 @@
using System;
using Content.Shared.GameObjects.Components;
using Content.Shared.Utility;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Interfaces.GameObjects;
namespace Content.Client.GameObjects.Components
{
[UsedImplicitly]
public sealed class WindowVisualizer : AppearanceVisualizer
{
public override void OnChangeData(AppearanceComponent component)
{
base.OnChangeData(component);
var sprite = component.Owner.GetComponent<ISpriteComponent>();
var snapGrid = component.Owner.GetComponent<SnapGridComponent>();
var lowWall = FindLowWall(snapGrid);
if (lowWall == null) return;
if (component.TryGetData(WindowVisuals.Damage, out float fraction))
{
var level = Math.Min(ContentHelpers.RoundToLevels(fraction, 1, 7), 5);
if (level == 0)
{
foreach (WindowDamageLayers val in Enum.GetValues(typeof(WindowDamageLayers)))
{
sprite.LayerSetVisible(val, false);
}
return;
}
foreach (WindowDamageLayers val in Enum.GetValues(typeof(WindowDamageLayers)))
{
sprite.LayerSetVisible(val, true);
}
sprite.LayerSetState(WindowDamageLayers.DamageNE, $"{(int) lowWall.LastCornerNE}_{level}");
sprite.LayerSetState(WindowDamageLayers.DamageSE, $"{(int) lowWall.LastCornerSE}_{level}");
sprite.LayerSetState(WindowDamageLayers.DamageSW, $"{(int) lowWall.LastCornerSW}_{level}");
sprite.LayerSetState(WindowDamageLayers.DamageNW, $"{(int) lowWall.LastCornerNW}_{level}");
}
}
private static LowWallComponent FindLowWall(SnapGridComponent snapGrid)
{
foreach (var entity in snapGrid.GetLocal())
{
if (entity.TryGetComponent(out LowWallComponent lowWall))
{
return lowWall;
}
}
return null;
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Content.Shared.Audio;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects.EntitySystems;
@@ -7,6 +8,7 @@ using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Random;
namespace Content.Server.GameObjects.Components.Damage
@@ -65,11 +67,6 @@ namespace Content.Server.GameObjects.Components.Damage
protected override void DestructionBehavior()
{
_actSystem.HandleBreakage(Owner);
if (!Owner.Deleted && DestroySound != string.Empty)
{
var pos = Owner.Transform.Coordinates;
EntitySystem.Get<AudioSystem>().PlayAtCoords(DestroySound, pos);
}
}
}
}

View File

@@ -1,10 +1,13 @@
using Content.Shared.GameObjects.Components.Damage;
using System.Collections.Generic;
using Content.Server.GameObjects.Components.Stack;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.EntitySystems;
using Robust.Server.GameObjects.EntitySystems;
using Content.Shared.Utility;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components.Damage
@@ -17,6 +20,8 @@ namespace Content.Server.GameObjects.Components.Damage
public class DestructibleComponent : RuinableComponent, IDestroyAct
{
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
protected ActSystem ActSystem;
@@ -24,22 +29,51 @@ namespace Content.Server.GameObjects.Components.Damage
public override string Name => "Destructible";
/// <summary>
/// Entity spawned upon destruction.
/// Entities spawned on destruction plus the min and max amount spawned.
/// </summary>
public string SpawnOnDestroy { get; private set; }
public Dictionary<string, MinMax> SpawnOnDestroy { get; private set; }
void IDestroyAct.OnDestroy(DestructionEventArgs eventArgs)
{
if (!string.IsNullOrWhiteSpace(SpawnOnDestroy) && eventArgs.IsSpawnWreck)
if (SpawnOnDestroy == null || !eventArgs.IsSpawnWreck) return;
foreach (var (key, value) in SpawnOnDestroy)
{
Owner.EntityManager.SpawnEntity(SpawnOnDestroy, Owner.Transform.Coordinates);
int count;
if (value.Min >= value.Max)
{
count = value.Min;
}
else
{
count = _random.Next(value.Min, value.Max + 1);
}
if (count == 0) continue;
if (EntityPrototypeHelpers.HasComponent<StackComponent>(key))
{
var spawned = Owner.EntityManager.SpawnEntity(key, Owner.Transform.Coordinates);
var stack = spawned.GetComponent<StackComponent>();
stack.Count = count;
spawned.RandomOffset(0.5f);
}
else
{
for (var i = 0; i < count; i++)
{
var spawned = Owner.EntityManager.SpawnEntity(key, Owner.Transform.Coordinates);
spawned.RandomOffset(0.5f);
}
}
}
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(this, d => d.SpawnOnDestroy, "spawnOnDestroy", string.Empty);
serializer.DataField(this, d => d.SpawnOnDestroy, "spawnOnDestroy", null);
}
public override void Initialize()
@@ -56,11 +90,13 @@ namespace Content.Server.GameObjects.Components.Damage
var pos = Owner.Transform.Coordinates;
ActSystem.HandleDestruction(Owner,
true); //This will call IDestroyAct.OnDestroy on this component (and all other components on this entity)
if (DestroySound != string.Empty)
}
}
public struct MinMax
{
EntitySystem.Get<AudioSystem>().PlayAtCoords(DestroySound, pos);
}
}
public int Min;
public int Max;
}
}
}

View File

@@ -1,11 +1,15 @@
using System.Collections.Generic;
using Content.Shared.Audio;
using Content.Shared.GameObjects.Components.Damage;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using Logger = Robust.Shared.Log.Logger;
namespace Content.Server.GameObjects.Components.Damage
{
@@ -16,12 +20,19 @@ namespace Content.Server.GameObjects.Components.Damage
[ComponentReference(typeof(IDamageableComponent))]
public abstract class RuinableComponent : DamageableComponent
{
[Dependency] private IRobustRandom _random = default!;
/// <summary>
/// Sound played upon destruction.
/// </summary>
[ViewVariables]
protected string DestroySound { get; private set; }
/// <summary>
/// Used instead of <see cref="DestroySound"/> if specified.
/// </summary>
[ViewVariables]
protected string DestroySoundCollection { get; private set; }
public override List<DamageState> SupportedDamageStates =>
new List<DamageState> {DamageState.Alive, DamageState.Dead};
@@ -44,6 +55,7 @@ namespace Content.Server.GameObjects.Components.Damage
() => Thresholds.TryGetValue(DamageState.Dead, out var value) ? value : (int?) null);
serializer.DataField(this, ruinable => ruinable.DestroySound, "destroySound", string.Empty);
serializer.DataField(this, ruinable => ruinable.DestroySoundCollection, "destroySoundCollection", string.Empty);
}
protected override void EnterState(DamageState state)
@@ -65,10 +77,24 @@ namespace Content.Server.GameObjects.Components.Damage
{
CurrentState = DamageState.Dead;
if (!Owner.Deleted && DestroySound != string.Empty)
if (!Owner.Deleted)
{
var pos = Owner.Transform.Coordinates;
EntitySystem.Get<AudioSystem>().PlayAtCoords(DestroySound, pos);
string sound = string.Empty;
if (DestroySoundCollection != string.Empty)
{
sound = AudioHelpers.GetRandomFileFromSoundCollection(DestroySoundCollection);
}
else if (DestroySound != string.Empty)
{
sound = DestroySound;
}
if (sound != string.Empty)
{
Logger.Debug("Playing destruction sound");
EntitySystem.Get<AudioSystem>().PlayAtCoords(sound, pos, AudioHelpers.WithVariation(0.125f));
}
}
DestructionBehavior();

View File

@@ -0,0 +1,36 @@
using System.Collections.Generic;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Random;
using Robust.Shared.Serialization;
namespace Content.Server.GameObjects.Components
{
[RegisterComponent]
public class RandomSpriteStateComponent : Component
{
[Dependency] private readonly IRobustRandom _random = default!;
public override string Name => "RandomSpriteState";
private List<string> _spriteStates;
private int _spriteLayer;
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(ref _spriteStates, "spriteStates", null);
serializer.DataField(ref _spriteLayer, "spriteLayer", 0);
}
public override void Initialize()
{
base.Initialize();
if (_spriteStates == null) return;
if (!Owner.TryGetComponent(out SpriteComponent spriteComponent)) return;
spriteComponent.LayerSetState(_spriteLayer, _random.Pick(_spriteStates));
}
}
}

View File

@@ -1,11 +1,104 @@
using Content.Shared.GameObjects.Components;
using System;
using Content.Server.Utility;
using Content.Shared.Audio;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Interfaces.GameObjects.Components;
using Content.Shared.Utility;
using Robust.Server.GameObjects;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Localization;
using Robust.Shared.Utility;
namespace Content.Server.GameObjects.Components
{
[RegisterComponent]
[ComponentReference(typeof(SharedWindowComponent))]
public class WindowComponent : SharedWindowComponent
public class WindowComponent : SharedWindowComponent, IExamine, IInteractHand
{
private int? Damage
{
get
{
if (!Owner.TryGetComponent(out IDamageableComponent damageableComponent)) return null;
return damageableComponent.TotalDamage;
}
}
private int? MaxDamage
{
get
{
if (!Owner.TryGetComponent(out IDamageableComponent damageableComponent)) return null;
return damageableComponent.Thresholds[DamageState.Dead];
}
}
public override void Initialize()
{
base.Initialize();
if (Owner.TryGetComponent(out IDamageableComponent damageableComponent))
{
damageableComponent.HealthChangedEvent += OnDamage;
}
}
private void OnDamage(HealthChangedEventArgs eventArgs)
{
int current = eventArgs.Damageable.TotalDamage;
int max = eventArgs.Damageable.Thresholds[DamageState.Dead];
if (eventArgs.Damageable.CurrentState == DamageState.Dead) return;
UpdateVisuals(current, max);
}
private void UpdateVisuals(int currentDamage, int maxDamage)
{
if (Owner.TryGetComponent(out AppearanceComponent appearance))
{
appearance.SetData(WindowVisuals.Damage, (float) currentDamage / maxDamage);
}
}
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
{
int? damage = Damage;
int? maxDamage = MaxDamage;
if (damage == null || maxDamage == null) return;
float fraction = ((damage == 0 || maxDamage == 0) ? 0f : (float) damage / maxDamage) ?? 0f;
int level = Math.Min(ContentHelpers.RoundToLevels(fraction, 1, 7), 5);
switch (level)
{
case 0:
message.AddText(Loc.GetString("It looks fully intact."));
break;
case 1:
message.AddText(Loc.GetString("It has a few scratches."));
break;
case 2:
message.AddText(Loc.GetString("It has a few small cracks."));
break;
case 3:
message.AddText(Loc.GetString("It has several big cracks running along its surface."));
break;
case 4:
message.AddText(Loc.GetString("It has deep cracks across multiple layers."));
break;
case 5:
message.AddText(Loc.GetString("It is extremely badly cracked and on the verge of shattering."));
break;
}
}
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
{
EntitySystem.Get<AudioSystem>()
.PlayAtCoords("/Audio/Effects/glass_knock.ogg", eventArgs.Target.Transform.Coordinates, AudioHelpers.WithVariation(0.05f));
eventArgs.Target.PopupMessageEveryone(Loc.GetString("*knock knock*"));
return true;
}
}
}

View File

@@ -1,4 +1,6 @@
using Robust.Shared.GameObjects;
using System;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization;
namespace Content.Shared.GameObjects.Components
{
@@ -6,4 +8,10 @@ namespace Content.Shared.GameObjects.Components
{
public override string Name => "Window";
}
[Serializable, NetSerializable]
public enum WindowVisuals
{
Damage
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -22,7 +22,10 @@
- type: Destructible
deadThreshold: 30
destroySound: /Audio/Effects/woodhit.ogg
spawnOnDestroy: WoodPlank
spawnOnDestroy:
WoodPlank:
Min: 1
Max: 1
resistances: metallicResistances
- type: Occluder
sizeX: 32

View File

@@ -21,7 +21,10 @@
- type: Destructible
deadThreshold: 30
destroySound: /Audio/Effects/metalbreak.ogg
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
resistances: metallicResistances
- type: entity
@@ -47,5 +50,8 @@
- type: Destructible
deadThreshold: 30
destroySound: /Audio/Effects/metalbreak.ogg
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
resistances: metallicResistances

View File

@@ -39,7 +39,10 @@
deadThreshold: 15
destroySound: /Audio/Effects/metalbreak.ogg
resistances: metallicResistances
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: entity
id: TableFrame
@@ -55,7 +58,10 @@
deadThreshold: 1
destroySound: /Audio/Effects/metalbreak.ogg
resistances: metallicResistances
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: entity
id: TableBar
@@ -71,7 +77,10 @@
deadThreshold: 1
destroySound: /Audio/Effects/metalbreak.ogg
resistances: metallicResistances
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: entity
id: TableMetal
@@ -87,7 +96,10 @@
deadThreshold: 15
destroySound: /Audio/Effects/metalbreak.ogg
resistances: metallicResistances
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: entity
id: TableR
@@ -103,7 +115,10 @@
deadThreshold: 75
destroySound: /Audio/Effects/metalbreak.ogg
resistances: metallicResistances
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: entity
id: TableGlass
@@ -117,8 +132,12 @@
sprite: Constructible/Structures/Tables/glass.rsi
- type: Destructible
deadThreshold: 5
destroySound: /Audio/Effects/glassbreak2.ogg
destroySound: /Audio/Effects/glass_break2.ogg
resistances: metallicResistances
spawnOnDestroy:
ShardGlass:
Min: 1
Max: 1
- type: entity
id: TableGlassR
@@ -132,8 +151,12 @@
sprite: Constructible/Structures/Tables/r_glass.rsi
- type: Destructible
deadThreshold: 20
destroySound: /Audio/Effects/glassbreak2.ogg
destroySound: /Audio/Effects/glass_break2.ogg
resistances: metallicResistances
spawnOnDestroy:
ShardGlass:
Min: 1
Max: 1
- type: entity
id: TableWood
@@ -149,7 +172,10 @@
deadThreshold: 15
destroySound: /Audio/Effects/woodhit.ogg
resistances: metallicResistances
spawnOnDestroy: WoodPlank
spawnOnDestroy:
WoodPlank:
Min: 1
Max: 1
- type: entity
id: TableCarpet
@@ -165,7 +191,10 @@
deadThreshold: 15
destroySound: /Audio/Effects/woodhit.ogg
resistances: metallicResistances
spawnOnDestroy: WoodPlank
spawnOnDestroy:
WoodPlank:
Min: 1
Max: 1
- type: entity
id: TableStone

View File

@@ -24,7 +24,10 @@
- type: Destructible
maxHP: 500
resistances: metallicResistances
spawnOnDestroy: AMEPart
spawnOnDestroy:
AMEPart:
Min: 1
Max: 1
- type: SnapGrid
offset: Center
- type: Airtight

View File

@@ -46,7 +46,10 @@
wireType: HighVoltage
- type: Destructible
resistances: metallicResistances
spawnOnDestroy: HVWireStack1
spawnOnDestroy:
HVWireStack1:
Min: 1
Max: 1
- type: entity
parent: WireBase
@@ -73,7 +76,10 @@
wireType: MediumVoltage
- type: Destructible
resistances: metallicResistances
spawnOnDestroy: MVWireStack1
spawnOnDestroy:
MVWireStack1:
Min: 1
Max: 1
- type: entity
parent: WireBase
@@ -102,4 +108,7 @@
wireType: Apc
- type: Destructible
resistances: metallicResistances
spawnOnDestroy: ApcExtensionCableStack1
spawnOnDestroy:
ApcExtensionCableStack1:
Min: 1
Max: 1

View File

@@ -32,7 +32,10 @@
offset: Center
- type: Destructible
deadThreshold: 50
spawnOnDestroy: chem_master_broken
spawnOnDestroy:
chem_master_broken:
Min: 1
Max: 1
- type: UserInterface
interfaces:
- key: enum.ChemMasterUiKey.Key
@@ -71,7 +74,10 @@
offset: Center
- type: Destructible
deadThreshold: 25
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: UserInterface
interfaces:
- key: enum.ChemMasterUiKey.Key

View File

@@ -31,7 +31,10 @@
- type: Destructible
deadThreshold: 50
resistances: metallicResistances
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
- type: SnapGrid
offset: Edge
placement:

View File

@@ -46,7 +46,10 @@
sprite: Constructible/Structures/Walls/brick.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -63,7 +66,10 @@
sprite: Constructible/Structures/Walls/clock.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -80,7 +86,10 @@
sprite: Constructible/Structures/Walls/clown.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -98,7 +107,10 @@
sprite: Constructible/Structures/Walls/cult.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -115,7 +127,10 @@
sprite: Constructible/Structures/Walls/debug.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -132,7 +147,10 @@
sprite: Constructible/Structures/Walls/diamond.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -150,7 +168,10 @@
sprite: Constructible/Structures/Walls/gold.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -167,7 +188,10 @@
sprite: Constructible/Structures/Walls/ice.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -184,7 +208,10 @@
sprite: Constructible/Structures/Walls/metal.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -201,7 +228,10 @@
sprite: Constructible/Structures/Walls/plasma.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -218,7 +248,10 @@
sprite: Constructible/Structures/Walls/plastic.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -262,7 +295,10 @@
sprite: Constructible/Structures/Walls/riveted.rsi
- type: Destructible
deadThreshold: 1000
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -279,7 +315,10 @@
sprite: Constructible/Structures/Walls/sandstone.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -296,7 +335,10 @@
sprite: Constructible/Structures/Walls/silver.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -335,7 +377,10 @@
sprite: Constructible/Structures/Walls/uranium.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls
@@ -352,7 +397,10 @@
sprite: Constructible/Structures/Walls/wood.rsi
- type: Destructible
deadThreshold: 300
spawnOnDestroy: Girder
spawnOnDestroy:
Girder:
Min: 1
Max: 1
resistances: metallicResistances
- type: IconSmooth
key: walls

View File

@@ -29,6 +29,11 @@
- type: Destructible
deadThreshold: 15
resistances: metallicResistances
destroySoundCollection: WindowBreak
spawnOnDestroy:
ShardGlass:
Min: 1
Max: 3
- type: SnapGrid
offset: Center
- type: Airtight
@@ -37,6 +42,9 @@
- type: Construction
graph: window
node: window
- type: Appearance
visuals:
- type: WindowVisualizer
- type: entity
id: ReinforcedWindow
@@ -75,3 +83,10 @@
- type: Construction
graph: window
node: phoronWindow
- type: soundCollection
id: WindowBreak
files:
- /Audio/Effects/glass_break1.ogg
- /Audio/Effects/glass_break2.ogg
- /Audio/Effects/glass_break3.ogg

View File

@@ -126,8 +126,11 @@
- type: Anchorable
- type: Destructible
deadThreshold: 10
spawnOnDestroy: FloodlightBroken
destroySound: /Audio/Effects/glassbreak1.ogg
spawnOnDestroy:
FloodlightBroken:
Min: 1
Max: 1
destroySound: /Audio/Effects/glass_break1.ogg
resistances: metallicResistances
- type: Appearance
visuals:
@@ -145,7 +148,10 @@
- type: Anchorable
- type: Destructible
deadThreshold: 20
spawnOnDestroy: SteelSheet1
spawnOnDestroy:
SteelSheet1:
Min: 1
Max: 1
destroySound: /Audio/Effects/metalbreak.ogg
resistances: metallicResistances
- type: Physics

View File

@@ -0,0 +1,53 @@
- type: entity
id: ShardBase
name: shard
description: It's a shard of some unknown material.
parent: BaseItem
abstract: true
components:
- type: Sprite
sprite: Objects/Materials/Shards/shard.rsi
state: shard1
- type: RandomSpriteState
spriteStates:
- shard1
- shard2
- shard3
- type: ItemCooldown
- type: MeleeWeapon
damageType: Slash
- type: Item
sprite: Objects/Materials/Shards/shard.rsi
- type: entity
id: ShardGlass
name: glass shard
description: A small piece of glass. It looks sharp, you wouldn't want to step on it barefoot.
parent: ShardBase
components:
- type: Sprite
color: "#bbeeff"
- type: Item
color: "#bbeeff"
- type: entity
id: ShardGlassReinforced
name: reinforced glass shard
description: A small piece of reinforced glass. It looks sharp, you wouldn't want to step on it barefoot.
parent: ShardBase
components:
- type: Sprite
color: "#96cdef"
- type: Item
color: "#96cdef"
- type: entity
id: ShardGlassPhoron
name: phoron glass shard
description: A small piece of phoron glass. It looks sharp, you wouldn't want to step on it barefoot.
parent: ShardBase
components:
- type: Sprite
color: "#f3b489"
- type: Item
color: "#f3b489"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -0,0 +1,731 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "brndd",
"states": [
{
"name": "0_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "0_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "0_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "0_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "0_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "1_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "1_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "1_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "1_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "1_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "2_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "2_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "2_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "2_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "2_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "3_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "3_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "3_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "3_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "3_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "4_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "4_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "4_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "4_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "4_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "5_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "5_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "5_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "5_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "5_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "6_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "6_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "6_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "6_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "6_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "7_1",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "7_2",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "7_3",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "7_4",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
},
{
"name": "7_5",
"directions": 4,
"delays": [
[
1
],
[
1
],
[
1
],
[
1
]
]
}
]
}

View File

@@ -0,0 +1,38 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "https://github.com/discordia-space/CEV-Eris/commit/b5b4edd4e46efc2ee2d3c1ce5aff82d80ddc461e",
"states": [
{
"name": "piecelarge",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "piecemedium",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "piecesmall",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,74 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "https://github.com/discordia-space/CEV-Eris/commit/b5b4edd4e46efc2ee2d3c1ce5aff82d80ddc461e",
"states": [
{
"name": "inhand-left",
"directions": 4,
"delays": [
[
1.0
],
[
1.0
],
[
1.0
],
[
1.0
]
]
},
{
"name": "inhand-right",
"directions": 4,
"delays": [
[
1.0
],
[
1.0
],
[
1.0
],
[
1.0
]
]
},
{
"name": "shard3",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "shard2",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "shard1",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

View File

@@ -0,0 +1,38 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "https://github.com/discordia-space/CEV-Eris/commit/b5b4edd4e46efc2ee2d3c1ce5aff82d80ddc461e",
"states": [
{
"name": "shrapnellarge",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "shrapnelmedium",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "shrapnelsmall",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

View File

@@ -0,0 +1,38 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA-3.0",
"copyright": "https://github.com/discordia-space/CEV-Eris/commit/b5b4edd4e46efc2ee2d3c1ce5aff82d80ddc461e",
"states": [
{
"name": "splinterslarge",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "splintersmedium",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "splinterssmall",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

View File

@@ -83,6 +83,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Collidable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Collidables/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=comms/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Constructible/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Cooldowns/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Diethylamine/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Firelock/@EntryIndexedValue">True</s:Boolean>