diff --git a/Content.Shared/Stealth/Components/StealthComponent.cs b/Content.Shared/Stealth/Components/StealthComponent.cs
index 58cf1cdde6..1a8a647768 100644
--- a/Content.Shared/Stealth/Components/StealthComponent.cs
+++ b/Content.Shared/Stealth/Components/StealthComponent.cs
@@ -19,6 +19,12 @@ public sealed partial class StealthComponent : Component
[DataField("enabled")]
public bool Enabled = true;
+ ///
+ /// The creature will continue invisible at death.
+ ///
+ [DataField("enabledOnDeath")]
+ public bool EnabledOnDeath = true;
+
///
/// Whether or not the entity previously had an interaction outline prior to cloaking.
///
diff --git a/Content.Shared/Stealth/SharedStealthSystem.cs b/Content.Shared/Stealth/SharedStealthSystem.cs
index 67858c1942..aeb42453ca 100644
--- a/Content.Shared/Stealth/SharedStealthSystem.cs
+++ b/Content.Shared/Stealth/SharedStealthSystem.cs
@@ -1,4 +1,6 @@
using Content.Shared.Examine;
+using Content.Shared.Mobs;
+using Content.Shared.Mobs.Systems;
using Content.Shared.Stealth.Components;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
@@ -8,6 +10,7 @@ namespace Content.Shared.Stealth;
public abstract class SharedStealthSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly MobStateSystem _mobState = default!;
public override void Initialize()
{
@@ -22,6 +25,7 @@ public abstract class SharedStealthSystem : EntitySystem
SubscribeLocalEvent(OnInit);
SubscribeLocalEvent(OnExamineAttempt);
SubscribeLocalEvent(OnExamined);
+ SubscribeLocalEvent(OnMobStateChanged);
}
private void OnExamineAttempt(EntityUid uid, StealthComponent component, ExamineAttemptEvent args)
@@ -55,20 +59,34 @@ public abstract class SharedStealthSystem : EntitySystem
return;
component.Enabled = value;
- Dirty(component);
+ Dirty(uid, component);
+ }
+
+ private void OnMobStateChanged(EntityUid uid, StealthComponent component, MobStateChangedEvent args)
+ {
+ if (args.NewMobState == MobState.Dead)
+ {
+ component.Enabled = component.EnabledOnDeath;
+ }
+ else
+ {
+ component.Enabled = true;
+ }
+
+ Dirty(uid, component);
}
private void OnPaused(EntityUid uid, StealthComponent component, ref EntityPausedEvent args)
{
component.LastVisibility = GetVisibility(uid, component);
component.LastUpdated = null;
- Dirty(component);
+ Dirty(uid, component);
}
private void OnUnpaused(EntityUid uid, StealthComponent component, ref EntityUnpausedEvent args)
{
component.LastUpdated = _timing.CurTime;
- Dirty(component);
+ Dirty(uid, component);
}
protected virtual void OnInit(EntityUid uid, StealthComponent component, ComponentInit args)
@@ -128,7 +146,7 @@ public abstract class SharedStealthSystem : EntitySystem
}
component.LastVisibility = Math.Clamp(component.LastVisibility + delta, component.MinVisibility, component.MaxVisibility);
- Dirty(component);
+ Dirty(uid, component);
}
///
@@ -144,7 +162,7 @@ public abstract class SharedStealthSystem : EntitySystem
if (component.LastUpdated != null)
component.LastUpdated = _timing.CurTime;
- Dirty(component);
+ Dirty(uid, component);
}
///
diff --git a/Resources/Audio/Effects/Footsteps/attributions.yml b/Resources/Audio/Effects/Footsteps/attributions.yml
index 1718620864..ef91a34d36 100644
--- a/Resources/Audio/Effects/Footsteps/attributions.yml
+++ b/Resources/Audio/Effects/Footsteps/attributions.yml
@@ -33,6 +33,14 @@
copyright: "Taken and modified from tgstation (clownstep 1 and 2) by brainfood1183 (github)"
source: "https://github.com/tgstation/tgstation/tree/f8ee37afc00bce1ad421615eaa0e4cbddd5eea90/sound/effects"
+- files:
+ - snake1.ogg
+ - snake2.ogg
+ - snake3.ogg
+ license: "Custom"
+ copyright: "Taken from https://zvukipro.com/"
+ source: "https://zvukipro.com/jivotnie/21-zvuki-zmej.html"
+
- files:
- bells1.ogg
- bells2.ogg
diff --git a/Resources/Audio/Effects/Footsteps/snake1.ogg b/Resources/Audio/Effects/Footsteps/snake1.ogg
new file mode 100644
index 0000000000..0304b356b4
Binary files /dev/null and b/Resources/Audio/Effects/Footsteps/snake1.ogg differ
diff --git a/Resources/Audio/Effects/Footsteps/snake2.ogg b/Resources/Audio/Effects/Footsteps/snake2.ogg
new file mode 100644
index 0000000000..46f7ea5e58
Binary files /dev/null and b/Resources/Audio/Effects/Footsteps/snake2.ogg differ
diff --git a/Resources/Audio/Effects/Footsteps/snake3.ogg b/Resources/Audio/Effects/Footsteps/snake3.ogg
new file mode 100644
index 0000000000..a1640b2be5
Binary files /dev/null and b/Resources/Audio/Effects/Footsteps/snake3.ogg differ
diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
index c9caa79cc9..d3f447ae47 100644
--- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
+++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl
@@ -103,6 +103,12 @@ ghost-role-information-space-spider-description = Space spiders are just as agg
ghost-role-information-salvage-spider-name = Space spider on salvage wreck
ghost-role-information-salvage-spider-description = Space spiders are just as aggressive as regular spiders, feed.
+ghost-role-information-space-cobra-name = Space cobra
+ghost-role-information-space-cobra-description = Space cobras really don't like guests, and will always snack on a visitor.
+
+ghost-role-information-salvage-cobra-name = Space cobra on salvage wreck
+ghost-role-information-salvage-cobra-description = Space cobras really don't like guests, and will always snack on a visitor.
+
ghost-role-information-guardian-name = Guardian
ghost-role-information-guardian-description = Listen to your owner. Don't tank damage. Punch people hard.
diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl
index 383c0f58c8..3f2a23d30d 100644
--- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl
+++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl
@@ -29,6 +29,7 @@ petting-success-dragon = Dodging teeth, claws, and flames, you pet {THE($target)
petting-success-hamster = You pet {THE($target)} on {POSS-ADJ($target)} fluffy little head.
petting-success-bear = You reluctantly pet {THE($target)} on {POSS-ADJ($target)} mystical head.
petting-success-slimes = You pet {THE($target)} on {POSS-ADJ($target)} mucous surface.
+petting-success-snake = You pet {THE($target)} on {POSS-ADJ($target)} scaly large head.
petting-failure-generic = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} aloof towards you.
diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml b/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml
index 4373f5076d..ee1708caef 100644
--- a/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml
+++ b/Resources/Prototypes/Entities/Clothing/Shoes/misc.yml
@@ -70,6 +70,18 @@
- type: Clothing
sprite: Clothing/Shoes/Misc/damedaneshoes.rsi
+- type: entity
+ parent: ClothingShoesBase
+ id: ClothingShoesSnakeskinBoots
+ name: snakeskin boots
+ description: Boots made of high-class snakeskin, everyone around you will be jealous.
+ components:
+ - type: Sprite
+ sprite: Clothing/Shoes/Misc/snakeskin.rsi
+ - type: Clothing
+ sprite: Clothing/Shoes/Misc/snakeskin.rsi
+ - type: NoSlip
+
- type: entity
parent: [ClothingShoesBase, PowerCellSlotSmallItem]
id: ClothingShoesBootsSpeed
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/salvage.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/salvage.yml
index 80e3aa9460..71f09021ce 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/salvage.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/salvage.yml
@@ -238,6 +238,22 @@
- type: Sprite
layers:
- state: green
+ - state: spacespider
+ sprite: Mobs/Animals/spacespider.rsi
- type: ConditionalSpawner
prototypes:
- MobSpiderSpaceSalvage
+
+- type: entity
+ name: Salvage Space Cobra Spawner
+ id: SpawnMobCobraSalvage
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: green
+ - state: spacecobra
+ sprite: Mobs/Animals/spacecobra.rsi
+ - type: ConditionalSpawner
+ prototypes:
+ - MobCobraSpaceSalvage
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml b/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml
index 542198fd24..0766fc18d8 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml
@@ -372,7 +372,8 @@
- type: Sprite
layers:
- state: green
- - state: ai
+ - state: shiva
+ sprite: Mobs/Pets/shiva.rsi
- type: ConditionalSpawner
prototypes:
- MobSpiderShiva
@@ -427,11 +428,26 @@
- type: Sprite
layers:
- state: green
- - state: ai
+ - state: spacespider
+ sprite: Mobs/Animals/spacespider.rsi
- type: ConditionalSpawner
prototypes:
- MobSpiderSpace
+- type: entity
+ name: Space Cobra Spawner
+ id: SpawnMobSpaceCobra
+ parent: MarkerBase
+ components:
+ - type: Sprite
+ layers:
+ - state: green
+ - state: spacecobra
+ sprite: Mobs/Animals/spacecobra.rsi
+ - type: ConditionalSpawner
+ prototypes:
+ - MobCobraSpace
+
- type: entity
name: Slimes Spawner Blue
id: SpawnMobAdultSlimesBlue
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
index d784f5c162..9d63f47171 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
@@ -254,16 +254,16 @@
damage:
types:
Piercing: 6
- Poison: 2
+ Poison: 4
- type: SolutionContainerManager
solutions:
melee:
reagents:
- ReagentId: ChloralHydrate
- Quantity: 60
+ Quantity: 80
- type: MeleeChemicalInjector
solution: melee
- transferAmount: 3
+ transferAmount: 4
- type: ReplacementAccent
accent: xeno
- type: InteractionPopup
@@ -293,3 +293,108 @@
name: ghost-role-information-salvage-spider-name
description: ghost-role-information-salvage-spider-description
- type: SalvageMobRestrictions
+
+- type: entity
+ name: space cobra
+ id: MobCobraSpace
+ parent: MobSpaceBasic
+ description: Long fangs and a glowing hood, and the alluring look begs to come closer.
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Animals/spacecobra.rsi
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: spacecobra
+ - map: [ "enum.DamageStateVisualLayers.BaseUnshaded" ]
+ state: glow
+ shader: unshaded
+ - type: FootstepModifier
+ footstepSoundCollection:
+ collection: FootstepSnake
+ - type: MobThresholds
+ thresholds:
+ 0: Alive
+ 100: Dead
+ - type: Stamina
+ critThreshold: 150
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: spacecobra
+ BaseUnshaded: glow
+ Dead:
+ Base: dead_spacecobra
+ - type: Butcherable
+ spawned:
+ - id: FoodMeatSnake
+ amount: 2
+ - id: UraniumOre1
+ amount: 1
+ - id: ClothingShoesSnakeskinBoots
+ amount: 1
+ prob: 0.3
+ - type: Bloodstream
+ bloodMaxVolume: 200
+ bloodReagent: Cryoxadone
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeCircle
+ radius: 0.40
+ density: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+ - type: MeleeWeapon
+ hidden: true
+ soundHit:
+ path: /Audio/Effects/bite.ogg
+ angle: 0
+ animation: WeaponArcBite
+ damage:
+ types:
+ Piercing: 6
+ Poison: 4
+ - type: SolutionContainerManager
+ solutions:
+ melee:
+ reagents:
+ - ReagentId: NorepinephricAcid
+ Quantity: 90
+ - type: MeleeChemicalInjector
+ solution: melee
+ transferAmount: 6
+ - type: ReplacementAccent
+ accent: xeno
+ - type: InteractionPopup
+ successChance: 0.2
+ interactSuccessString: petting-success-snake
+ interactFailureString: petting-failure-generic
+ - type: PointLight
+ radius: 1.1
+ energy: 1.5
+ color: "#4faffb"
+ - type: GhostRole
+ prob: 0.25
+ name: ghost-role-information-space-cobra-name
+ description: ghost-role-information-space-cobra-description
+ - type: Stealth
+ enabledOnDeath: false
+ maxVisibility: 1.2
+ - type: StealthOnMove
+ passiveVisibilityRate: -0.25
+ movementVisibilityRate: 0.25
+
+- type: entity
+ id: MobCobraSpaceSalvage
+ parent: MobCobraSpace
+ suffix: "Salvage Ruleset"
+ components:
+ - type: GhostRole
+ prob: 0.25
+ name: ghost-role-information-salvage-cobra-name
+ description: ghost-role-information-salvage-cobra-description
+ - type: SalvageMobRestrictions
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
index 1626a1bc81..01ff223689 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
@@ -416,7 +416,14 @@
- MobMask
layer:
- MobLayer
-
+ - type: FootstepModifier
+ footstepSoundCollection:
+ collection: FootstepSnake
+ - type: Tag
+ tags:
+ - DoorBumpOpener
+ - FootstepSound
+
- type: entity
name: space adder
parent: MobPurpleSnake
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
index 2b7c9d6e16..c807263f84 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
@@ -507,6 +507,26 @@
- ReagentId: UncookedAnimalProteins
Quantity: 1
+- type: entity
+ name: raw snake meat
+ parent: FoodMeatBase
+ id: FoodMeatSnake
+ description: A long piece of snake meat, hopefully not poisonous.
+ components:
+ - type: Tag
+ tags:
+ - Raw
+ - type: Sprite
+ state: snake
+ - type: SolutionContainerManager
+ solutions:
+ food:
+ reagents:
+ - ReagentId: UncookedAnimalProteins
+ Quantity: 10
+ - ReagentId: Toxin
+ Quantity: 2
+
- type: entity
name: raw xeno meat
# not raw since acid kills bacteria or something, same as xeno
diff --git a/Resources/Prototypes/SoundCollections/footsteps.yml b/Resources/Prototypes/SoundCollections/footsteps.yml
index f0a273ec3a..e5b7210262 100644
--- a/Resources/Prototypes/SoundCollections/footsteps.yml
+++ b/Resources/Prototypes/SoundCollections/footsteps.yml
@@ -159,6 +159,13 @@
- /Audio/Effects/Footsteps/clownspiderstep1.ogg
- /Audio/Effects/Footsteps/clownspiderstep2.ogg
+- type: soundCollection
+ id: FootstepSnake
+ files:
+ - /Audio/Effects/Footsteps/snake1.ogg
+ - /Audio/Effects/Footsteps/snake2.ogg
+ - /Audio/Effects/Footsteps/snake3.ogg
+
- type: soundCollection
id: FootstepBells
files:
diff --git a/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/equipped-FEET.png b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/equipped-FEET.png
new file mode 100644
index 0000000000..7b2f287cca
Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/equipped-FEET.png differ
diff --git a/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/icon.png b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/icon.png
new file mode 100644
index 0000000000..103c20e1dd
Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/icon.png differ
diff --git a/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/inhand-left.png b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/inhand-left.png
new file mode 100644
index 0000000000..14c685192e
Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/inhand-left.png differ
diff --git a/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/inhand-right.png b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/inhand-right.png
new file mode 100644
index 0000000000..fa9453602d
Binary files /dev/null and b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/inhand-right.png differ
diff --git a/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/meta.json b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/meta.json
new file mode 100644
index 0000000000..f478e93982
--- /dev/null
+++ b/Resources/Textures/Clothing/Shoes/Misc/snakeskin.rsi/meta.json
@@ -0,0 +1,26 @@
+{
+ "version": 1,
+ "license": "CC-BY-NC-3.0",
+ "copyright": "Made by Nimfar11 (GitHub) for Space Station 14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "equipped-FEET",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ }
+ ]
+}
diff --git a/Resources/Textures/Mobs/Animals/spacecobra.rsi/dead_spacecobra.png b/Resources/Textures/Mobs/Animals/spacecobra.rsi/dead_spacecobra.png
new file mode 100644
index 0000000000..a88564d310
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/spacecobra.rsi/dead_spacecobra.png differ
diff --git a/Resources/Textures/Mobs/Animals/spacecobra.rsi/glow.png b/Resources/Textures/Mobs/Animals/spacecobra.rsi/glow.png
new file mode 100644
index 0000000000..950dc02a36
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/spacecobra.rsi/glow.png differ
diff --git a/Resources/Textures/Mobs/Animals/spacecobra.rsi/meta.json b/Resources/Textures/Mobs/Animals/spacecobra.rsi/meta.json
new file mode 100644
index 0000000000..86f542aee9
--- /dev/null
+++ b/Resources/Textures/Mobs/Animals/spacecobra.rsi/meta.json
@@ -0,0 +1,34 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Sprited by Nimfar11 (Github) for Space Station 14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "spacecobra",
+ "directions": 4,
+ "delays": [
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3],
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3],
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3],
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3]
+ ]
+ },
+ {
+ "name": "glow",
+ "directions": 4,
+ "delays": [
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3],
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3],
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3],
+ [0.3,0.2,0.2,0.4,0.2,0.2,0.3]
+ ]
+ },
+ {
+ "name": "dead_spacecobra"
+ }
+ ]
+}
diff --git a/Resources/Textures/Mobs/Animals/spacecobra.rsi/spacecobra.png b/Resources/Textures/Mobs/Animals/spacecobra.rsi/spacecobra.png
new file mode 100644
index 0000000000..fdaec29aa3
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/spacecobra.rsi/spacecobra.png differ
diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json b/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json
index f1aa4d3446..2bb20f1eb5 100644
--- a/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json
+++ b/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json
@@ -156,6 +156,9 @@
{
"name": "slime"
},
+ {
+ "name": "snake"
+ },
{
"name": "spider"
},
diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/snake.png b/Resources/Textures/Objects/Consumable/Food/meat.rsi/snake.png
new file mode 100644
index 0000000000..a16189e6ee
Binary files /dev/null and b/Resources/Textures/Objects/Consumable/Food/meat.rsi/snake.png differ