More robust bullet impact sounds (#8325)
This commit is contained in:
@@ -350,6 +350,7 @@ namespace Content.Client.Entry
|
|||||||
"RandomArtifactSprite",
|
"RandomArtifactSprite",
|
||||||
"EnergySword",
|
"EnergySword",
|
||||||
"MeleeSound",
|
"MeleeSound",
|
||||||
|
"RangedDamageSound",
|
||||||
"DoorRemote",
|
"DoorRemote",
|
||||||
"InteractionPopup",
|
"InteractionPopup",
|
||||||
"HealthAnalyzer",
|
"HealthAnalyzer",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Weapon.Ranged;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Physics;
|
using Content.Shared.Physics;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
@@ -38,8 +39,12 @@ namespace Content.Server.Projectiles.Components
|
|||||||
private string? _muzzleFlash;
|
private string? _muzzleFlash;
|
||||||
[DataField("impactFlash")]
|
[DataField("impactFlash")]
|
||||||
private string? _impactFlash;
|
private string? _impactFlash;
|
||||||
[DataField("soundHitWall")]
|
|
||||||
private SoundSpecifier _soundHitWall = new SoundPathSpecifier("/Audio/Weapons/Guns/Hits/laser_sear_wall.ogg");
|
[DataField("soundHit")]
|
||||||
|
public SoundSpecifier? SoundHit;
|
||||||
|
|
||||||
|
[DataField("soundForce")]
|
||||||
|
public bool ForceSound = false;
|
||||||
|
|
||||||
public void FireEffects(EntityUid user, float distance, Angle angle, EntityUid? hitEntity = null)
|
public void FireEffects(EntityUid user, float distance, Angle angle, EntityUid? hitEntity = null)
|
||||||
{
|
{
|
||||||
@@ -80,14 +85,6 @@ namespace Content.Server.Projectiles.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hitEntity != null && _soundHitWall != null)
|
|
||||||
{
|
|
||||||
// TODO: No wall component so ?
|
|
||||||
var offset = localAngle.ToVec().Normalized / 2;
|
|
||||||
var coordinates = localCoordinates.Offset(offset);
|
|
||||||
SoundSystem.Play(Filter.Pvs(coordinates), _soundHitWall.GetSound(), coordinates);
|
|
||||||
}
|
|
||||||
|
|
||||||
Owner.SpawnTimer((int) _deathTime.TotalMilliseconds, () =>
|
Owner.SpawnTimer((int) _deathTime.TotalMilliseconds, () =>
|
||||||
{
|
{
|
||||||
if (!_entMan.Deleted(Owner))
|
if (!_entMan.Deleted(Owner))
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ namespace Content.Server.Projectiles.Components
|
|||||||
|
|
||||||
// Get that juicy FPS hit sound
|
// Get that juicy FPS hit sound
|
||||||
[DataField("soundHit")] public SoundSpecifier? SoundHit;
|
[DataField("soundHit")] public SoundSpecifier? SoundHit;
|
||||||
[DataField("soundHitSpecies")] public SoundSpecifier? SoundHitSpecies;
|
|
||||||
|
[DataField("soundForce")]
|
||||||
|
public bool ForceSound = false;
|
||||||
|
|
||||||
public bool DamagedEntity;
|
public bool DamagedEntity;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.Projectiles.Components;
|
using Content.Server.Projectiles.Components;
|
||||||
|
using Content.Server.Weapon.Melee;
|
||||||
|
using Content.Server.Weapon.Ranged;
|
||||||
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Body.Components;
|
using Content.Shared.Body.Components;
|
||||||
using Content.Shared.Camera;
|
using Content.Shared.Camera;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
@@ -10,6 +13,7 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Server.Projectiles
|
namespace Content.Server.Projectiles
|
||||||
{
|
{
|
||||||
@@ -19,6 +23,7 @@ namespace Content.Server.Projectiles
|
|||||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||||
[Dependency] private readonly AdminLogSystem _adminLogSystem = default!;
|
[Dependency] private readonly AdminLogSystem _adminLogSystem = default!;
|
||||||
[Dependency] private readonly CameraRecoilSystem _cameraRecoil = default!;
|
[Dependency] private readonly CameraRecoilSystem _cameraRecoil = default!;
|
||||||
|
[Dependency] private readonly GunSystem _guns = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -36,42 +41,27 @@ namespace Content.Server.Projectiles
|
|||||||
|
|
||||||
var otherEntity = args.OtherFixture.Body.Owner;
|
var otherEntity = args.OtherFixture.Body.Owner;
|
||||||
|
|
||||||
var coordinates = EntityManager.GetComponent<TransformComponent>(args.OtherFixture.Body.Owner).Coordinates;
|
var modifiedDamage = _damageableSystem.TryChangeDamage(otherEntity, component.Damage);
|
||||||
var playerFilter = Filter.Pvs(coordinates, entityMan: EntityManager);
|
component.DamagedEntity = true;
|
||||||
|
|
||||||
if (!EntityManager.GetComponent<MetaDataComponent>(otherEntity).EntityDeleted && component.SoundHitSpecies != null &&
|
if (modifiedDamage is not null && EntityManager.EntityExists(component.Shooter))
|
||||||
EntityManager.HasComponent<SharedBodyComponent>(otherEntity))
|
|
||||||
{
|
{
|
||||||
SoundSystem.Play(playerFilter, component.SoundHitSpecies.GetSound(), coordinates);
|
_adminLogSystem.Add(LogType.BulletHit,
|
||||||
}
|
HasComp<ActorComponent>(otherEntity) ? LogImpact.Extreme : LogImpact.High,
|
||||||
else
|
$"Projectile {ToPrettyString(component.Owner):projectile} shot by {ToPrettyString(component.Shooter):user} hit {ToPrettyString(otherEntity):target} and dealt {modifiedDamage.Total:damage} damage");
|
||||||
{
|
|
||||||
var soundHit = component.SoundHit?.GetSound();
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(soundHit))
|
|
||||||
SoundSystem.Play(playerFilter, soundHit, coordinates);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EntityManager.GetComponent<MetaDataComponent>(otherEntity).EntityDeleted)
|
_guns.PlaySound(otherEntity, modifiedDamage, component.SoundHit, component.ForceSound);
|
||||||
{
|
|
||||||
var dmg = _damageableSystem.TryChangeDamage(otherEntity, component.Damage);
|
|
||||||
component.DamagedEntity = true;
|
|
||||||
|
|
||||||
if (dmg is not null && EntityManager.EntityExists(component.Shooter))
|
|
||||||
_adminLogSystem.Add(LogType.BulletHit,
|
|
||||||
HasComp<ActorComponent>(otherEntity) ? LogImpact.Extreme : LogImpact.High,
|
|
||||||
$"Projectile {ToPrettyString(component.Owner):projectile} shot by {ToPrettyString(component.Shooter):user} hit {ToPrettyString(otherEntity):target} and dealt {dmg.Total:damage} damage");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Damaging it can delete it
|
// Damaging it can delete it
|
||||||
if (!Deleted(otherEntity) && HasComp<CameraRecoilComponent>(otherEntity))
|
if (HasComp<CameraRecoilComponent>(otherEntity))
|
||||||
{
|
{
|
||||||
var direction = args.OurFixture.Body.LinearVelocity.Normalized;
|
var direction = args.OurFixture.Body.LinearVelocity.Normalized;
|
||||||
_cameraRecoil.KickCamera(otherEntity, direction);
|
_cameraRecoil.KickCamera(otherEntity, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.DeleteOnCollide)
|
if (component.DeleteOnCollide)
|
||||||
EntityManager.QueueDeleteEntity(uid);
|
QueueDel(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Content.Server.Weapon.Melee
|
|||||||
[Dependency] private readonly AdminLogSystem _logSystem = default!;
|
[Dependency] private readonly AdminLogSystem _logSystem = default!;
|
||||||
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
|
[Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
|
||||||
|
|
||||||
private const float DamagePitchVariation = 0.15f;
|
public const float DamagePitchVariation = 0.15f;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -107,7 +107,7 @@ namespace Content.Server.Weapon.Melee
|
|||||||
$"{ToPrettyString(args.User):user} melee attacked {ToPrettyString(args.Target.Value):target} using {ToPrettyString(args.Used):used} and dealt {damageResult.Total:damage} damage");
|
$"{ToPrettyString(args.User):user} melee attacked {ToPrettyString(args.Target.Value):target} using {ToPrettyString(args.Used):used} and dealt {damageResult.Total:damage} damage");
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, comp.HitSound);
|
PlayHitSound(target, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, comp.HitSound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -165,7 +165,7 @@ namespace Content.Server.Weapon.Melee
|
|||||||
var target = entities.First();
|
var target = entities.First();
|
||||||
TryComp<MeleeWeaponComponent>(target, out var meleeWeapon);
|
TryComp<MeleeWeaponComponent>(target, out var meleeWeapon);
|
||||||
|
|
||||||
PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, meleeWeapon?.HitSound);
|
PlayHitSound(target, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, meleeWeapon?.HitSound);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -196,9 +196,9 @@ namespace Content.Server.Weapon.Melee
|
|||||||
RaiseLocalEvent(owner, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false);
|
RaiseLocalEvent(owner, new RefreshItemCooldownEvent(comp.LastAttackTime, comp.CooldownEnd), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string? GetHighestDamageSound(DamageSpecifier modifiedDamage)
|
public static string? GetHighestDamageSound(DamageSpecifier modifiedDamage, IPrototypeManager protoManager)
|
||||||
{
|
{
|
||||||
var groups = modifiedDamage.GetDamagePerGroup(_protoManager);
|
var groups = modifiedDamage.GetDamagePerGroup(protoManager);
|
||||||
|
|
||||||
// Use group if it's exclusive, otherwise fall back to type.
|
// Use group if it's exclusive, otherwise fall back to type.
|
||||||
if (groups.Count == 1)
|
if (groups.Count == 1)
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ using Content.Server.CombatMode;
|
|||||||
using Content.Server.Hands.Components;
|
using Content.Server.Hands.Components;
|
||||||
using Content.Server.Interaction.Components;
|
using Content.Server.Interaction.Components;
|
||||||
using Content.Server.Projectiles.Components;
|
using Content.Server.Projectiles.Components;
|
||||||
|
using Content.Server.Weapon.Melee;
|
||||||
using Content.Server.Weapon.Ranged.Ammunition.Components;
|
using Content.Server.Weapon.Ranged.Ammunition.Components;
|
||||||
using Content.Server.Weapon.Ranged.Barrels.Components;
|
using Content.Server.Weapon.Ranged.Barrels.Components;
|
||||||
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Camera;
|
using Content.Shared.Camera;
|
||||||
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Interaction.Events;
|
using Content.Shared.Interaction.Events;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Sound;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
@@ -239,10 +243,12 @@ public sealed partial class GunSystem
|
|||||||
var result = rayCastResults[0];
|
var result = rayCastResults[0];
|
||||||
var distance = result.Distance;
|
var distance = result.Distance;
|
||||||
hitscan.FireEffects(shooter, distance, angle, result.HitEntity);
|
hitscan.FireEffects(shooter, distance, angle, result.HitEntity);
|
||||||
var dmg = _damageable.TryChangeDamage(result.HitEntity, hitscan.Damage);
|
var modifiedDamage = _damageable.TryChangeDamage(result.HitEntity, hitscan.Damage);
|
||||||
if (dmg != null)
|
if (modifiedDamage != null)
|
||||||
_logs.Add(LogType.HitScanHit,
|
_logs.Add(LogType.HitScanHit,
|
||||||
$"{EntityManager.ToPrettyString(shooter):user} hit {EntityManager.ToPrettyString(result.HitEntity):target} using {EntityManager.ToPrettyString(hitscan.Owner):used} and dealt {dmg.Total:damage} damage");
|
$"{EntityManager.ToPrettyString(shooter):user} hit {EntityManager.ToPrettyString(result.HitEntity):target} using {EntityManager.ToPrettyString(hitscan.Owner):used} and dealt {modifiedDamage.Total:damage} damage");
|
||||||
|
|
||||||
|
PlaySound(rayCastResults[0].HitEntity, modifiedDamage, hitscan.SoundHit, hitscan.ForceSound);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -251,4 +257,46 @@ public sealed partial class GunSystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Impact sounds
|
||||||
|
|
||||||
|
public void PlaySound(EntityUid otherEntity, DamageSpecifier? modifiedDamage, SoundSpecifier? weaponSound, bool forceWeaponSound)
|
||||||
|
{
|
||||||
|
// Like projectiles and melee,
|
||||||
|
// 1. Entity specific sound
|
||||||
|
// 2. Ammo's sound
|
||||||
|
// 3. Nothing
|
||||||
|
var playedSound = false;
|
||||||
|
|
||||||
|
if (!forceWeaponSound && modifiedDamage != null && modifiedDamage.Total > 0 && TryComp<RangedDamageSoundComponent>(otherEntity, out var rangedSound))
|
||||||
|
{
|
||||||
|
var type = MeleeWeaponSystem.GetHighestDamageSound(modifiedDamage, _protoManager);
|
||||||
|
|
||||||
|
if (type != null && rangedSound.SoundTypes?.TryGetValue(type, out var damageSoundType) == true)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(
|
||||||
|
Filter.Pvs(otherEntity, entityManager: EntityManager),
|
||||||
|
damageSoundType!.GetSound(),
|
||||||
|
otherEntity,
|
||||||
|
AudioHelpers.WithVariation(DamagePitchVariation));
|
||||||
|
|
||||||
|
playedSound = true;
|
||||||
|
}
|
||||||
|
else if (type != null && rangedSound.SoundGroups?.TryGetValue(type, out var damageSoundGroup) == true)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(
|
||||||
|
Filter.Pvs(otherEntity, entityManager: EntityManager),
|
||||||
|
damageSoundGroup!.GetSound(),
|
||||||
|
otherEntity,
|
||||||
|
AudioHelpers.WithVariation(DamagePitchVariation));
|
||||||
|
|
||||||
|
playedSound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!playedSound && weaponSound != null)
|
||||||
|
SoundSystem.Play(Filter.Pvs(otherEntity, entityManager: EntityManager), weaponSound.GetSound(), otherEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Server.Atmos.EntitySystems;
|
|||||||
using Content.Server.Hands.Components;
|
using Content.Server.Hands.Components;
|
||||||
using Content.Server.PowerCell;
|
using Content.Server.PowerCell;
|
||||||
using Content.Server.Stunnable;
|
using Content.Server.Stunnable;
|
||||||
|
using Content.Server.Weapon.Melee;
|
||||||
using Content.Server.Weapon.Ranged.Ammunition.Components;
|
using Content.Server.Weapon.Ranged.Ammunition.Components;
|
||||||
using Content.Server.Weapon.Ranged.Barrels.Components;
|
using Content.Server.Weapon.Ranged.Barrels.Components;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
@@ -22,6 +23,7 @@ using Robust.Shared.Containers;
|
|||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ namespace Content.Server.Weapon.Ranged;
|
|||||||
public sealed partial class GunSystem : EntitySystem
|
public sealed partial class GunSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
||||||
[Dependency] private readonly AdminLogSystem _logs = default!;
|
[Dependency] private readonly AdminLogSystem _logs = default!;
|
||||||
@@ -44,6 +47,8 @@ public sealed partial class GunSystem : EntitySystem
|
|||||||
[Dependency] private readonly StunSystem _stun = default!;
|
[Dependency] private readonly StunSystem _stun = default!;
|
||||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||||
|
|
||||||
|
public const float DamagePitchVariation = MeleeWeaponSystem.DamagePitchVariation;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How many sounds are allowed to be played on ejecting multiple casings.
|
/// How many sounds are allowed to be played on ejecting multiple casings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
30
Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs
Normal file
30
Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Content.Shared.Damage.Prototypes;
|
||||||
|
using Content.Shared.Sound;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||||
|
|
||||||
|
namespace Content.Server.Weapon.Ranged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Plays the specified sound upon receiving damage of that type.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class RangedDamageSoundComponent : Component
|
||||||
|
{
|
||||||
|
// TODO: Limb damage changing sound type.
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specified sounds to apply when the entity takes damage with the specified group.
|
||||||
|
/// Will fallback to defaults if none specified.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables, DataField("soundGroups",
|
||||||
|
customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageGroupPrototype>))]
|
||||||
|
public Dictionary<string, SoundSpecifier>? SoundGroups;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specified sounds to apply when the entity takes damage with the specified type.
|
||||||
|
/// Will fallback to defaults if none specified.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables, DataField("soundTypes",
|
||||||
|
customTypeSerializer: typeof(PrototypeIdDictionarySerializer<SoundSpecifier, DamageTypePrototype>))]
|
||||||
|
public Dictionary<string, SoundSpecifier>? SoundTypes;
|
||||||
|
}
|
||||||
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat1.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat2.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat3.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat3.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat4.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/bullet_meat4.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/energy_meat1.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/energy_meat1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/energy_meat2.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/energy_meat2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/energy_metal1.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/energy_metal1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/energy_metal2.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/energy_metal2.ogg
Normal file
Binary file not shown.
16
Resources/Audio/Weapons/Guns/Hits/licenses.txt
Normal file
16
Resources/Audio/Weapons/Guns/Hits/licenses.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Taken from https://github.com/Citadel-Station-13/Citadel-Station-13-RP/tree/cc701aedb633d83eae8339a8b3712ad8ad99cca0/sound licensed under CC BY-SA 3.0. Remixed to mono where it was stereo by metalgearsloth:
|
||||||
|
- bullet_meat1.ogg
|
||||||
|
- bullet_meat2.ogg
|
||||||
|
- bullet_meat3.ogg
|
||||||
|
- bullet_meat4.ogg
|
||||||
|
- energy_meat1.ogg
|
||||||
|
- energy_meat2.ogg
|
||||||
|
- energy_metal1.ogg
|
||||||
|
- energy_metal2.ogg
|
||||||
|
|
||||||
|
Taken from https://github.com/tgstation/tgstation/tree/7501504b0ea029d2cf1c0336d09db5c0959aa412/sound/weapons/effects CC BY-SA 3.0.
|
||||||
|
- ric1.ogg
|
||||||
|
- ric2.ogg
|
||||||
|
- ric3.ogg
|
||||||
|
- ric4.ogg
|
||||||
|
- ric5.ogg
|
||||||
BIN
Resources/Audio/Weapons/Guns/Hits/ric1.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/ric1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/ric2.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/ric2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/ric3.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/ric3.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/ric4.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/ric4.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Weapons/Guns/Hits/ric5.ogg
Normal file
BIN
Resources/Audio/Weapons/Guns/Hits/ric5.ogg
Normal file
Binary file not shown.
@@ -6,6 +6,15 @@
|
|||||||
description: A miserable pile of secrets.
|
description: A miserable pile of secrets.
|
||||||
noSpawn: true
|
noSpawn: true
|
||||||
components:
|
components:
|
||||||
|
- type: RangedDamageSound
|
||||||
|
soundGroups:
|
||||||
|
Brute:
|
||||||
|
collection:
|
||||||
|
MeatBulletImpact
|
||||||
|
soundTypes:
|
||||||
|
Heat:
|
||||||
|
collection:
|
||||||
|
MeatLaserImpact
|
||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- CanPilot
|
- CanPilot
|
||||||
|
|||||||
@@ -5,148 +5,148 @@
|
|||||||
description: A miserable pile of slime.
|
description: A miserable pile of slime.
|
||||||
abstract: true
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: Icon
|
- type: Icon
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: full
|
state: full
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
netsync: false
|
netsync: false
|
||||||
drawdepth: Mobs
|
drawdepth: Mobs
|
||||||
layers:
|
layers:
|
||||||
- map: [ "enum.HumanoidVisualLayers.Chest" ]
|
- map: [ "enum.HumanoidVisualLayers.Chest" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: torso_m
|
state: torso_m
|
||||||
- map: [ "enum.HumanoidVisualLayers.Head" ]
|
- map: [ "enum.HumanoidVisualLayers.Head" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: head_m
|
state: head_m
|
||||||
- map: [ "enum.HumanoidVisualLayers.Eyes" ]
|
- map: [ "enum.HumanoidVisualLayers.Eyes" ]
|
||||||
color: "#008800"
|
color: "#008800"
|
||||||
sprite: Mobs/Customization/eyes.rsi
|
sprite: Mobs/Customization/eyes.rsi
|
||||||
state: eyes
|
state: eyes
|
||||||
- map: [ "enum.HumanoidVisualLayers.RArm" ]
|
- map: [ "enum.HumanoidVisualLayers.RArm" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: r_arm
|
state: r_arm
|
||||||
- map: [ "enum.HumanoidVisualLayers.LArm" ]
|
- map: [ "enum.HumanoidVisualLayers.LArm" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: l_arm
|
state: l_arm
|
||||||
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
|
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: r_leg
|
state: r_leg
|
||||||
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
|
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: l_leg
|
state: l_leg
|
||||||
- shader: StencilClear
|
- shader: StencilClear
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: l_leg
|
state: l_leg
|
||||||
- shader: StencilMask
|
- shader: StencilMask
|
||||||
map: [ "enum.HumanoidVisualLayers.StencilMask" ]
|
map: [ "enum.HumanoidVisualLayers.StencilMask" ]
|
||||||
sprite: Mobs/Customization/masking_helpers.rsi
|
sprite: Mobs/Customization/masking_helpers.rsi
|
||||||
state: female_full
|
state: female_full
|
||||||
visible: false
|
visible: false
|
||||||
- map: [ "jumpsuit" ]
|
- map: [ "jumpsuit" ]
|
||||||
shader: StencilDraw
|
shader: StencilDraw
|
||||||
- map: [ "enum.HumanoidVisualLayers.LHand" ]
|
- map: [ "enum.HumanoidVisualLayers.LHand" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: l_hand
|
state: l_hand
|
||||||
- map: [ "enum.HumanoidVisualLayers.RHand" ]
|
- map: [ "enum.HumanoidVisualLayers.RHand" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: r_hand
|
state: r_hand
|
||||||
- map: [ "enum.HumanoidVisualLayers.LFoot" ]
|
- map: [ "enum.HumanoidVisualLayers.LFoot" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: l_foot
|
state: l_foot
|
||||||
- map: [ "enum.HumanoidVisualLayers.RFoot" ]
|
- map: [ "enum.HumanoidVisualLayers.RFoot" ]
|
||||||
color: "#b8b8b8"
|
color: "#b8b8b8"
|
||||||
sprite: Mobs/Species/Slime/parts.rsi
|
sprite: Mobs/Species/Slime/parts.rsi
|
||||||
state: r_foot
|
state: r_foot
|
||||||
- map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
|
- map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
|
||||||
color: "#ffffff"
|
color: "#ffffff"
|
||||||
sprite: Objects/Misc/handcuffs.rsi
|
sprite: Objects/Misc/handcuffs.rsi
|
||||||
state: body-overlay-2
|
state: body-overlay-2
|
||||||
visible: false
|
visible: false
|
||||||
- map: [ "id" ]
|
- map: [ "id" ]
|
||||||
- map: [ "gloves" ]
|
- map: [ "gloves" ]
|
||||||
- map: [ "shoes" ]
|
- map: [ "shoes" ]
|
||||||
- map: [ "ears" ]
|
- map: [ "ears" ]
|
||||||
- map: [ "outerClothing" ]
|
- map: [ "outerClothing" ]
|
||||||
- map: [ "eyes" ]
|
- map: [ "eyes" ]
|
||||||
- map: [ "belt" ]
|
- map: [ "belt" ]
|
||||||
- map: [ "neck" ]
|
- map: [ "neck" ]
|
||||||
- map: [ "back" ]
|
- map: [ "back" ]
|
||||||
- map: [ "enum.HumanoidVisualLayers.FacialHair" ]
|
- map: [ "enum.HumanoidVisualLayers.FacialHair" ]
|
||||||
state: shaved
|
state: shaved
|
||||||
sprite: Mobs/Customization/human_facial_hair.rsi
|
sprite: Mobs/Customization/human_facial_hair.rsi
|
||||||
- map: [ "enum.HumanoidVisualLayers.Hair" ]
|
- map: [ "enum.HumanoidVisualLayers.Hair" ]
|
||||||
state: bald
|
state: bald
|
||||||
sprite: Mobs/Customization/human_hair.rsi
|
sprite: Mobs/Customization/human_hair.rsi
|
||||||
- map: [ "mask" ]
|
- map: [ "mask" ]
|
||||||
- map: [ "head" ]
|
- map: [ "head" ]
|
||||||
- map: [ "pocket1" ]
|
- map: [ "pocket1" ]
|
||||||
- map: [ "pocket2" ]
|
- map: [ "pocket2" ]
|
||||||
- type: Markings
|
- type: Markings
|
||||||
layerPoints:
|
layerPoints:
|
||||||
Legs:
|
Legs:
|
||||||
points: 2
|
points: 2
|
||||||
required: false
|
required: false
|
||||||
Arms:
|
Arms:
|
||||||
points: 4
|
points: 4
|
||||||
required: false
|
required: false
|
||||||
- type: Body
|
- type: Body
|
||||||
template: HumanoidTemplate
|
template: HumanoidTemplate
|
||||||
preset: SlimePreset
|
preset: SlimePreset
|
||||||
- type: HumanoidAppearance
|
- type: HumanoidAppearance
|
||||||
hairMatchesSkin: true
|
hairMatchesSkin: true
|
||||||
hairAlpha: 0.5
|
hairAlpha: 0.5
|
||||||
- type: Damageable
|
- type: Damageable
|
||||||
damageContainer: Biological
|
damageContainer: Biological
|
||||||
damageModifierSet: Slime
|
damageModifierSet: Slime
|
||||||
- type: Bloodstream
|
- type: Bloodstream
|
||||||
bloodReagent: Slime # TODO Color slime blood based on their slime color or smth
|
bloodReagent: Slime # TODO Color slime blood based on their slime color or smth
|
||||||
bloodlossDamage:
|
bloodlossDamage:
|
||||||
types:
|
types:
|
||||||
Bloodloss:
|
Bloodloss:
|
||||||
1
|
1
|
||||||
bloodlossHealDamage:
|
bloodlossHealDamage:
|
||||||
types:
|
types:
|
||||||
Bloodloss:
|
Bloodloss:
|
||||||
-0.25
|
-0.25
|
||||||
- type: Barotrauma
|
- type: Barotrauma
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Blunt: 1.4 #per second, scales with pressure and other constants. Twice as much as humans.
|
Blunt: 1.4 #per second, scales with pressure and other constants. Twice as much as humans.
|
||||||
- type: Reactive
|
- type: Reactive
|
||||||
groups:
|
groups:
|
||||||
Flammable: [ Touch ]
|
Flammable: [ Touch ]
|
||||||
Extinguish: [ Touch ]
|
Extinguish: [ Touch ]
|
||||||
reactions:
|
reactions:
|
||||||
- reagents: [ Water, SpaceCleaner ]
|
- reagents: [ Water, SpaceCleaner ]
|
||||||
methods: [ Touch ]
|
methods: [ Touch ]
|
||||||
effects:
|
effects:
|
||||||
- !type:WashCreamPieReaction
|
- !type:WashCreamPieReaction
|
||||||
- reagents: [ Water ]
|
- reagents: [ Water ]
|
||||||
methods: [ Touch ]
|
methods: [ Touch ]
|
||||||
effects:
|
effects:
|
||||||
- !type:HealthChange
|
- !type:HealthChange
|
||||||
scaled: true
|
scaled: true
|
||||||
damage:
|
damage:
|
||||||
types:
|
types:
|
||||||
Heat: 2
|
Heat: 2
|
||||||
- !type:PopupMessage
|
- !type:PopupMessage
|
||||||
type: Local
|
type: Local
|
||||||
messages: [ "slime-hurt-by-water-popup" ]
|
messages: [ "slime-hurt-by-water-popup" ]
|
||||||
probability: 0.25
|
probability: 0.25
|
||||||
- type: Butcherable
|
- type: Butcherable
|
||||||
butcheringType: Spike
|
butcheringType: Spike
|
||||||
spawned:
|
spawned:
|
||||||
- id: FoodMeatSlime
|
- id: FoodMeatSlime
|
||||||
amount: 5
|
amount: 5
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
save: false
|
save: false
|
||||||
|
|||||||
@@ -147,6 +147,7 @@
|
|||||||
Heat: 5
|
Heat: 5
|
||||||
soundHit:
|
soundHit:
|
||||||
path: "/Audio/Weapons/Guns/Hits/taser_hit.ogg"
|
path: "/Audio/Weapons/Guns/Hits/taser_hit.ogg"
|
||||||
|
soundForce: true
|
||||||
- type: StunOnCollide
|
- type: StunOnCollide
|
||||||
stunAmount: 5
|
stunAmount: 5
|
||||||
knockdownAmount: 5
|
knockdownAmount: 5
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
snap:
|
snap:
|
||||||
- Wall
|
- Wall
|
||||||
components:
|
components:
|
||||||
|
- type: RangedDamageSound
|
||||||
|
soundGroups:
|
||||||
|
Brute:
|
||||||
|
collection:
|
||||||
|
MetalBulletImpact
|
||||||
|
soundTypes:
|
||||||
|
Heat:
|
||||||
|
collection:
|
||||||
|
MetalLaserImpact
|
||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- Wall
|
- Wall
|
||||||
|
|||||||
29
Resources/Prototypes/SoundCollections/impacts.yml
Normal file
29
Resources/Prototypes/SoundCollections/impacts.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
- type: soundCollection
|
||||||
|
id: MeatBulletImpact
|
||||||
|
files:
|
||||||
|
- "/Audio/Weapons/Guns/Hits/bullet_meat1.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/bullet_meat2.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/bullet_meat3.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/bullet_meat4.ogg"
|
||||||
|
|
||||||
|
- type: soundCollection
|
||||||
|
id: MeatLaserImpact
|
||||||
|
files:
|
||||||
|
- "/Audio/Weapons/Guns/Hits/energy_meat1.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/energy_meat2.ogg"
|
||||||
|
|
||||||
|
- type: soundCollection
|
||||||
|
id: MetalBulletImpact
|
||||||
|
files:
|
||||||
|
- "/Audio/Weapons/Guns/Hits/ric1.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/ric2.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/ric3.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/ric4.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/ric5.ogg"
|
||||||
|
|
||||||
|
- type: soundCollection
|
||||||
|
id: MetalLaserImpact
|
||||||
|
files:
|
||||||
|
- "/Audio/Weapons/Guns/Hits/energy_metal1.ogg"
|
||||||
|
- "/Audio/Weapons/Guns/Hits/energy_metal2.ogg"
|
||||||
|
|
||||||
Reference in New Issue
Block a user