diff --git a/Content.Client/Entry/IgnoredComponents.cs b/Content.Client/Entry/IgnoredComponents.cs index 82ae23c20f..9278d9f23e 100644 --- a/Content.Client/Entry/IgnoredComponents.cs +++ b/Content.Client/Entry/IgnoredComponents.cs @@ -350,6 +350,7 @@ namespace Content.Client.Entry "RandomArtifactSprite", "EnergySword", "MeleeSound", + "RangedDamageSound", "DoorRemote", "InteractionPopup", "HealthAnalyzer", diff --git a/Content.Server/Projectiles/Components/HitscanComponent.cs b/Content.Server/Projectiles/Components/HitscanComponent.cs index 545b16dd79..a16fd6ca1b 100644 --- a/Content.Server/Projectiles/Components/HitscanComponent.cs +++ b/Content.Server/Projectiles/Components/HitscanComponent.cs @@ -1,3 +1,4 @@ +using Content.Server.Weapon.Ranged; using Content.Shared.Damage; using Content.Shared.Physics; using Content.Shared.Sound; @@ -38,8 +39,12 @@ namespace Content.Server.Projectiles.Components private string? _muzzleFlash; [DataField("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) { @@ -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, () => { if (!_entMan.Deleted(Owner)) diff --git a/Content.Server/Projectiles/Components/ProjectileComponent.cs b/Content.Server/Projectiles/Components/ProjectileComponent.cs index 6e3013aef3..da5ba7a442 100644 --- a/Content.Server/Projectiles/Components/ProjectileComponent.cs +++ b/Content.Server/Projectiles/Components/ProjectileComponent.cs @@ -17,7 +17,9 @@ namespace Content.Server.Projectiles.Components // Get that juicy FPS hit sound [DataField("soundHit")] public SoundSpecifier? SoundHit; - [DataField("soundHitSpecies")] public SoundSpecifier? SoundHitSpecies; + + [DataField("soundForce")] + public bool ForceSound = false; public bool DamagedEntity; diff --git a/Content.Server/Projectiles/SharedProjectileSystem.cs b/Content.Server/Projectiles/SharedProjectileSystem.cs index f1da327f5a..dd4a8c6b87 100644 --- a/Content.Server/Projectiles/SharedProjectileSystem.cs +++ b/Content.Server/Projectiles/SharedProjectileSystem.cs @@ -1,5 +1,8 @@ using Content.Server.Administration.Logs; 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.Camera; using Content.Shared.Damage; @@ -10,6 +13,7 @@ using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Physics.Dynamics; using Robust.Shared.Player; +using Robust.Shared.Prototypes; namespace Content.Server.Projectiles { @@ -19,6 +23,7 @@ namespace Content.Server.Projectiles [Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly AdminLogSystem _adminLogSystem = default!; [Dependency] private readonly CameraRecoilSystem _cameraRecoil = default!; + [Dependency] private readonly GunSystem _guns = default!; public override void Initialize() { @@ -36,42 +41,27 @@ namespace Content.Server.Projectiles var otherEntity = args.OtherFixture.Body.Owner; - var coordinates = EntityManager.GetComponent(args.OtherFixture.Body.Owner).Coordinates; - var playerFilter = Filter.Pvs(coordinates, entityMan: EntityManager); + var modifiedDamage = _damageableSystem.TryChangeDamage(otherEntity, component.Damage); + component.DamagedEntity = true; - if (!EntityManager.GetComponent(otherEntity).EntityDeleted && component.SoundHitSpecies != null && - EntityManager.HasComponent(otherEntity)) + if (modifiedDamage is not null && EntityManager.EntityExists(component.Shooter)) { - SoundSystem.Play(playerFilter, component.SoundHitSpecies.GetSound(), coordinates); - } - else - { - var soundHit = component.SoundHit?.GetSound(); - - if (!string.IsNullOrEmpty(soundHit)) - SoundSystem.Play(playerFilter, soundHit, coordinates); + _adminLogSystem.Add(LogType.BulletHit, + HasComp(otherEntity) ? LogImpact.Extreme : LogImpact.High, + $"Projectile {ToPrettyString(component.Owner):projectile} shot by {ToPrettyString(component.Shooter):user} hit {ToPrettyString(otherEntity):target} and dealt {modifiedDamage.Total:damage} damage"); } - if (!EntityManager.GetComponent(otherEntity).EntityDeleted) - { - var dmg = _damageableSystem.TryChangeDamage(otherEntity, component.Damage); - component.DamagedEntity = true; - - if (dmg is not null && EntityManager.EntityExists(component.Shooter)) - _adminLogSystem.Add(LogType.BulletHit, - HasComp(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"); - } + _guns.PlaySound(otherEntity, modifiedDamage, component.SoundHit, component.ForceSound); // Damaging it can delete it - if (!Deleted(otherEntity) && HasComp(otherEntity)) + if (HasComp(otherEntity)) { var direction = args.OurFixture.Body.LinearVelocity.Normalized; _cameraRecoil.KickCamera(otherEntity, direction); } if (component.DeleteOnCollide) - EntityManager.QueueDeleteEntity(uid); + QueueDel(uid); } public override void Update(float frameTime) diff --git a/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs index 98f1ed2f2e..18f4a74732 100644 --- a/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs @@ -33,7 +33,7 @@ namespace Content.Server.Weapon.Melee [Dependency] private readonly AdminLogSystem _logSystem = default!; [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; - private const float DamagePitchVariation = 0.15f; + public const float DamagePitchVariation = 0.15f; 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"); } - PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, comp.HitSound); + PlayHitSound(target, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, comp.HitSound); } } else @@ -165,7 +165,7 @@ namespace Content.Server.Weapon.Melee var target = entities.First(); TryComp(target, out var meleeWeapon); - PlayHitSound(target, GetHighestDamageSound(modifiedDamage), hitEvent.HitSoundOverride, meleeWeapon?.HitSound); + PlayHitSound(target, GetHighestDamageSound(modifiedDamage, _protoManager), hitEvent.HitSoundOverride, meleeWeapon?.HitSound); } else { @@ -196,9 +196,9 @@ namespace Content.Server.Weapon.Melee 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. if (groups.Count == 1) diff --git a/Content.Server/Weapon/Ranged/GunSystem.Guns.cs b/Content.Server/Weapon/Ranged/GunSystem.Guns.cs index 63195d9da5..64c20a9304 100644 --- a/Content.Server/Weapon/Ranged/GunSystem.Guns.cs +++ b/Content.Server/Weapon/Ranged/GunSystem.Guns.cs @@ -3,12 +3,16 @@ using Content.Server.CombatMode; using Content.Server.Hands.Components; using Content.Server.Interaction.Components; using Content.Server.Projectiles.Components; +using Content.Server.Weapon.Melee; using Content.Server.Weapon.Ranged.Ammunition.Components; using Content.Server.Weapon.Ranged.Barrels.Components; +using Content.Shared.Audio; using Content.Shared.Camera; +using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Interaction.Events; using Content.Shared.Popups; +using Content.Shared.Sound; using Robust.Shared.Audio; using Robust.Shared.Map; using Robust.Shared.Physics; @@ -239,10 +243,12 @@ public sealed partial class GunSystem var result = rayCastResults[0]; var distance = result.Distance; hitscan.FireEffects(shooter, distance, angle, result.HitEntity); - var dmg = _damageable.TryChangeDamage(result.HitEntity, hitscan.Damage); - if (dmg != null) + var modifiedDamage = _damageable.TryChangeDamage(result.HitEntity, hitscan.Damage); + if (modifiedDamage != null) _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 { @@ -251,4 +257,46 @@ public sealed partial class GunSystem } #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(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 } diff --git a/Content.Server/Weapon/Ranged/GunSystem.cs b/Content.Server/Weapon/Ranged/GunSystem.cs index b4633ec6ea..5a97b9efc8 100644 --- a/Content.Server/Weapon/Ranged/GunSystem.cs +++ b/Content.Server/Weapon/Ranged/GunSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Hands.Components; using Content.Server.PowerCell; using Content.Server.Stunnable; +using Content.Server.Weapon.Melee; using Content.Server.Weapon.Ranged.Ammunition.Components; using Content.Server.Weapon.Ranged.Barrels.Components; using Content.Shared.ActionBlocker; @@ -22,6 +23,7 @@ using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Player; +using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Timing; @@ -30,6 +32,7 @@ namespace Content.Server.Weapon.Ranged; public sealed partial class GunSystem : EntitySystem { [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ActionBlockerSystem _blocker = 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 SharedHandsSystem _handsSystem = default!; + public const float DamagePitchVariation = MeleeWeaponSystem.DamagePitchVariation; + /// /// How many sounds are allowed to be played on ejecting multiple casings. /// diff --git a/Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs b/Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs new file mode 100644 index 0000000000..39303a5210 --- /dev/null +++ b/Content.Server/Weapon/Ranged/RangedDamageSoundComponent.cs @@ -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; + +/// +/// Plays the specified sound upon receiving damage of that type. +/// +[RegisterComponent] +public sealed class RangedDamageSoundComponent : Component +{ + // TODO: Limb damage changing sound type. + + /// + /// Specified sounds to apply when the entity takes damage with the specified group. + /// Will fallback to defaults if none specified. + /// + [ViewVariables, DataField("soundGroups", + customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + public Dictionary? SoundGroups; + + /// + /// Specified sounds to apply when the entity takes damage with the specified type. + /// Will fallback to defaults if none specified. + /// + [ViewVariables, DataField("soundTypes", + customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + public Dictionary? SoundTypes; +} diff --git a/Resources/Audio/Weapons/Guns/Hits/bullet_meat1.ogg b/Resources/Audio/Weapons/Guns/Hits/bullet_meat1.ogg new file mode 100644 index 0000000000..9dec73fa01 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/bullet_meat1.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/bullet_meat2.ogg b/Resources/Audio/Weapons/Guns/Hits/bullet_meat2.ogg new file mode 100644 index 0000000000..075e4b8770 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/bullet_meat2.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/bullet_meat3.ogg b/Resources/Audio/Weapons/Guns/Hits/bullet_meat3.ogg new file mode 100644 index 0000000000..1207121608 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/bullet_meat3.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/bullet_meat4.ogg b/Resources/Audio/Weapons/Guns/Hits/bullet_meat4.ogg new file mode 100644 index 0000000000..c6723318a1 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/bullet_meat4.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/energy_meat1.ogg b/Resources/Audio/Weapons/Guns/Hits/energy_meat1.ogg new file mode 100644 index 0000000000..e82535a53d Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/energy_meat1.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/energy_meat2.ogg b/Resources/Audio/Weapons/Guns/Hits/energy_meat2.ogg new file mode 100644 index 0000000000..4f0194facf Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/energy_meat2.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/energy_metal1.ogg b/Resources/Audio/Weapons/Guns/Hits/energy_metal1.ogg new file mode 100644 index 0000000000..b8394657c7 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/energy_metal1.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/energy_metal2.ogg b/Resources/Audio/Weapons/Guns/Hits/energy_metal2.ogg new file mode 100644 index 0000000000..9c2849ceb1 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/energy_metal2.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/licenses.txt b/Resources/Audio/Weapons/Guns/Hits/licenses.txt new file mode 100644 index 0000000000..a7a335fb4a --- /dev/null +++ b/Resources/Audio/Weapons/Guns/Hits/licenses.txt @@ -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 \ No newline at end of file diff --git a/Resources/Audio/Weapons/Guns/Hits/ric1.ogg b/Resources/Audio/Weapons/Guns/Hits/ric1.ogg new file mode 100644 index 0000000000..b7f7bd99ca Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/ric1.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/ric2.ogg b/Resources/Audio/Weapons/Guns/Hits/ric2.ogg new file mode 100644 index 0000000000..dcd44b0732 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/ric2.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/ric3.ogg b/Resources/Audio/Weapons/Guns/Hits/ric3.ogg new file mode 100644 index 0000000000..c538a97e35 Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/ric3.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/ric4.ogg b/Resources/Audio/Weapons/Guns/Hits/ric4.ogg new file mode 100644 index 0000000000..ac872734be Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/ric4.ogg differ diff --git a/Resources/Audio/Weapons/Guns/Hits/ric5.ogg b/Resources/Audio/Weapons/Guns/Hits/ric5.ogg new file mode 100644 index 0000000000..2c946c457d Binary files /dev/null and b/Resources/Audio/Weapons/Guns/Hits/ric5.ogg differ diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml index 0173bfe171..162481cb8d 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/human.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml @@ -6,6 +6,15 @@ description: A miserable pile of secrets. noSpawn: true components: + - type: RangedDamageSound + soundGroups: + Brute: + collection: + MeatBulletImpact + soundTypes: + Heat: + collection: + MeatLaserImpact - type: Tag tags: - CanPilot diff --git a/Resources/Prototypes/Entities/Mobs/Species/slime.yml b/Resources/Prototypes/Entities/Mobs/Species/slime.yml index 478f2ddc8a..6ab29a46f8 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/slime.yml @@ -5,148 +5,148 @@ description: A miserable pile of slime. abstract: true components: - - type: Icon - sprite: Mobs/Species/Slime/parts.rsi - state: full - - type: Sprite - netsync: false - drawdepth: Mobs - layers: - - map: [ "enum.HumanoidVisualLayers.Chest" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: torso_m - - map: [ "enum.HumanoidVisualLayers.Head" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: head_m - - map: [ "enum.HumanoidVisualLayers.Eyes" ] - color: "#008800" - sprite: Mobs/Customization/eyes.rsi - state: eyes - - map: [ "enum.HumanoidVisualLayers.RArm" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: r_arm - - map: [ "enum.HumanoidVisualLayers.LArm" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: l_arm - - map: [ "enum.HumanoidVisualLayers.RLeg" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: r_leg - - map: [ "enum.HumanoidVisualLayers.LLeg" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: l_leg - - shader: StencilClear - sprite: Mobs/Species/Slime/parts.rsi - state: l_leg - - shader: StencilMask - map: [ "enum.HumanoidVisualLayers.StencilMask" ] - sprite: Mobs/Customization/masking_helpers.rsi - state: female_full - visible: false - - map: [ "jumpsuit" ] - shader: StencilDraw - - map: [ "enum.HumanoidVisualLayers.LHand" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: l_hand - - map: [ "enum.HumanoidVisualLayers.RHand" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: r_hand - - map: [ "enum.HumanoidVisualLayers.LFoot" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: l_foot - - map: [ "enum.HumanoidVisualLayers.RFoot" ] - color: "#b8b8b8" - sprite: Mobs/Species/Slime/parts.rsi - state: r_foot - - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] - color: "#ffffff" - sprite: Objects/Misc/handcuffs.rsi - state: body-overlay-2 - visible: false - - map: [ "id" ] - - map: [ "gloves" ] - - map: [ "shoes" ] - - map: [ "ears" ] - - map: [ "outerClothing" ] - - map: [ "eyes" ] - - map: [ "belt" ] - - map: [ "neck" ] - - map: [ "back" ] - - map: [ "enum.HumanoidVisualLayers.FacialHair" ] - state: shaved - sprite: Mobs/Customization/human_facial_hair.rsi - - map: [ "enum.HumanoidVisualLayers.Hair" ] - state: bald - sprite: Mobs/Customization/human_hair.rsi - - map: [ "mask" ] - - map: [ "head" ] - - map: [ "pocket1" ] - - map: [ "pocket2" ] - - type: Markings - layerPoints: - Legs: - points: 2 - required: false - Arms: - points: 4 - required: false - - type: Body - template: HumanoidTemplate - preset: SlimePreset - - type: HumanoidAppearance - hairMatchesSkin: true - hairAlpha: 0.5 - - type: Damageable - damageContainer: Biological - damageModifierSet: Slime - - type: Bloodstream - bloodReagent: Slime # TODO Color slime blood based on their slime color or smth - bloodlossDamage: - types: - Bloodloss: - 1 - bloodlossHealDamage: - types: - Bloodloss: - -0.25 - - type: Barotrauma - damage: - types: - Blunt: 1.4 #per second, scales with pressure and other constants. Twice as much as humans. - - type: Reactive - groups: - Flammable: [ Touch ] - Extinguish: [ Touch ] - reactions: - - reagents: [ Water, SpaceCleaner ] - methods: [ Touch ] - effects: - - !type:WashCreamPieReaction - - reagents: [ Water ] - methods: [ Touch ] - effects: - - !type:HealthChange - scaled: true - damage: - types: - Heat: 2 - - !type:PopupMessage - type: Local - messages: [ "slime-hurt-by-water-popup" ] - probability: 0.25 - - type: Butcherable - butcheringType: Spike - spawned: - - id: FoodMeatSlime - amount: 5 + - type: Icon + sprite: Mobs/Species/Slime/parts.rsi + state: full + - type: Sprite + netsync: false + drawdepth: Mobs + layers: + - map: [ "enum.HumanoidVisualLayers.Chest" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: torso_m + - map: [ "enum.HumanoidVisualLayers.Head" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: head_m + - map: [ "enum.HumanoidVisualLayers.Eyes" ] + color: "#008800" + sprite: Mobs/Customization/eyes.rsi + state: eyes + - map: [ "enum.HumanoidVisualLayers.RArm" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: r_arm + - map: [ "enum.HumanoidVisualLayers.LArm" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: l_arm + - map: [ "enum.HumanoidVisualLayers.RLeg" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: r_leg + - map: [ "enum.HumanoidVisualLayers.LLeg" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: l_leg + - shader: StencilClear + sprite: Mobs/Species/Slime/parts.rsi + state: l_leg + - shader: StencilMask + map: [ "enum.HumanoidVisualLayers.StencilMask" ] + sprite: Mobs/Customization/masking_helpers.rsi + state: female_full + visible: false + - map: [ "jumpsuit" ] + shader: StencilDraw + - map: [ "enum.HumanoidVisualLayers.LHand" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: l_hand + - map: [ "enum.HumanoidVisualLayers.RHand" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: r_hand + - map: [ "enum.HumanoidVisualLayers.LFoot" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: l_foot + - map: [ "enum.HumanoidVisualLayers.RFoot" ] + color: "#b8b8b8" + sprite: Mobs/Species/Slime/parts.rsi + state: r_foot + - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] + color: "#ffffff" + sprite: Objects/Misc/handcuffs.rsi + state: body-overlay-2 + visible: false + - map: [ "id" ] + - map: [ "gloves" ] + - map: [ "shoes" ] + - map: [ "ears" ] + - map: [ "outerClothing" ] + - map: [ "eyes" ] + - map: [ "belt" ] + - map: [ "neck" ] + - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.FacialHair" ] + state: shaved + sprite: Mobs/Customization/human_facial_hair.rsi + - map: [ "enum.HumanoidVisualLayers.Hair" ] + state: bald + sprite: Mobs/Customization/human_hair.rsi + - map: [ "mask" ] + - map: [ "head" ] + - map: [ "pocket1" ] + - map: [ "pocket2" ] + - type: Markings + layerPoints: + Legs: + points: 2 + required: false + Arms: + points: 4 + required: false + - type: Body + template: HumanoidTemplate + preset: SlimePreset + - type: HumanoidAppearance + hairMatchesSkin: true + hairAlpha: 0.5 + - type: Damageable + damageContainer: Biological + damageModifierSet: Slime + - type: Bloodstream + bloodReagent: Slime # TODO Color slime blood based on their slime color or smth + bloodlossDamage: + types: + Bloodloss: + 1 + bloodlossHealDamage: + types: + Bloodloss: + -0.25 + - type: Barotrauma + damage: + types: + Blunt: 1.4 #per second, scales with pressure and other constants. Twice as much as humans. + - type: Reactive + groups: + Flammable: [ Touch ] + Extinguish: [ Touch ] + reactions: + - reagents: [ Water, SpaceCleaner ] + methods: [ Touch ] + effects: + - !type:WashCreamPieReaction + - reagents: [ Water ] + methods: [ Touch ] + effects: + - !type:HealthChange + scaled: true + damage: + types: + Heat: 2 + - !type:PopupMessage + type: Local + messages: [ "slime-hurt-by-water-popup" ] + probability: 0.25 + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatSlime + amount: 5 - type: entity save: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 927bd14281..60bea83152 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -147,6 +147,7 @@ Heat: 5 soundHit: path: "/Audio/Weapons/Guns/Hits/taser_hit.ogg" + soundForce: true - type: StunOnCollide stunAmount: 5 knockdownAmount: 5 diff --git a/Resources/Prototypes/Entities/Structures/Walls/base_structurewalls.yml b/Resources/Prototypes/Entities/Structures/Walls/base_structurewalls.yml index 8efa6b0ac5..83dc62c30a 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/base_structurewalls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/base_structurewalls.yml @@ -9,6 +9,15 @@ snap: - Wall components: + - type: RangedDamageSound + soundGroups: + Brute: + collection: + MetalBulletImpact + soundTypes: + Heat: + collection: + MetalLaserImpact - type: Tag tags: - Wall diff --git a/Resources/Prototypes/SoundCollections/impacts.yml b/Resources/Prototypes/SoundCollections/impacts.yml new file mode 100644 index 0000000000..beec871215 --- /dev/null +++ b/Resources/Prototypes/SoundCollections/impacts.yml @@ -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" +