diff --git a/Content.Client/Changeling/Systems/ChangelingLastResortSystem.cs b/Content.Client/Changeling/Systems/ChangelingLastResortSystem.cs
new file mode 100644
index 0000000000..62560c4310
--- /dev/null
+++ b/Content.Client/Changeling/Systems/ChangelingLastResortSystem.cs
@@ -0,0 +1,5 @@
+using Content.Shared.Changeling.Systems;
+
+namespace Content.Client.Changeling.Systems;
+
+public sealed partial class ChangelingLastResortSystem : SharedChangelingLastResortSystem;
diff --git a/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs b/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs
index 46741d1978..4259916c77 100644
--- a/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs
+++ b/Content.Server/Antag/AntagSelectionSystem.API.Assignment.cs
@@ -497,4 +497,26 @@ public sealed partial class AntagSelectionSystem
GameTicker.StartGameRule(ruleEnt);
return (ruleEnt, antag);
}
+
+ ///
+ /// Assigns components to an entity based on a
+ ///
+ /// The entity to give the components.
+ /// The prototype to apply the components from.
+ [PublicAPI]
+ public void AssignAntagComponents(EntityUid entity, ProtoId antag)
+ {
+ // The following is where we apply components, equipment, and other changes to our antagonist entity.
+ if (!ProtoMan.Resolve(antag, out var antagPrototype))
+ return;
+
+ AssignAntagComponents(entity, antagPrototype);
+ }
+
+ ///
+ [PublicAPI]
+ public void AssignAntagComponents(EntityUid entity, AntagSpecifierPrototype antag)
+ {
+ EntityManager.AddComponents(entity, antag.Components);
+ }
}
diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs
index 0ec6e2603c..8ca6c70e6e 100644
--- a/Content.Server/Antag/AntagSelectionSystem.cs
+++ b/Content.Server/Antag/AntagSelectionSystem.cs
@@ -26,6 +26,7 @@ using Content.Shared.GameTicking.Components;
using Content.Shared.Random.Helpers;
using Content.Shared.Roles;
using Content.Shared.Whitelist;
+using JetBrains.Annotations;
using Robust.Server.Audio;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@@ -780,7 +781,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem> gear = new();
diff --git a/Content.Server/Changeling/Systems/ChangelingLastResortSystem.cs b/Content.Server/Changeling/Systems/ChangelingLastResortSystem.cs
new file mode 100644
index 0000000000..dbfbf6df57
--- /dev/null
+++ b/Content.Server/Changeling/Systems/ChangelingLastResortSystem.cs
@@ -0,0 +1,109 @@
+using Content.Server.Antag;
+using Content.Shared.Administration.Systems;
+using Content.Shared.Antag;
+using Content.Shared.Changeling.Components;
+using Content.Shared.Changeling.Systems;
+using Content.Shared.DoAfter;
+using Content.Shared.Humanoid;
+using Content.Shared.Mind;
+using Content.Shared.Mobs.Systems;
+using Content.Shared.Popups;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Changeling.Systems;
+
+public sealed partial class ChangelingLastResortSystem : SharedChangelingLastResortSystem
+{
+ private static readonly ProtoId ChangelingAntag = "Changeling";
+
+ [Dependency] private RejuvenateSystem _rejuvenate = default!;
+ [Dependency] private SharedMindSystem _mind = default!;
+ [Dependency] private MobStateSystem _mobState = default!;
+ [Dependency] private SharedPopupSystem _popup = default!;
+ [Dependency] private SharedDoAfterSystem _doAfter = default!;
+ [Dependency] private AntagSelectionSystem _antag = default!;
+
+ [SubscribeLocalEvent]
+ private void OnTakeOverCorpseAction(Entity ent,
+ ref ChangelingTakeOverCorpseActionEvent args)
+ {
+ // CanTakeOver checks for the existence of ChangelingIdentityComponent on the target.
+ // As such it cannot be predicted as that component is not networked to sessions other than the owner
+ // Unless we do fucky networking magic
+ if (args.Handled || !CanTakeOver(ent.Owner, args.Target))
+ return;
+
+ args.Handled = true;
+
+ Audio.PlayPvs(ent.Comp.Sound, ent.Owner);
+ _popup.PopupEntity(Loc.GetString("changeling-takeover-start-others", ("user", ent.Owner)),
+ ent.Owner,
+ PopupType.MediumCaution);
+
+ var doAfter = new DoAfterArgs(EntityManager,
+ ent.Owner,
+ ent.Comp.TakeOverDuration,
+ new ChangelingTakeOverCorpseDoAfterEvent(),
+ ent,
+ target: args.Target)
+ {
+ BreakOnDamage = true,
+ BreakOnMove = true,
+ DuplicateCondition = DuplicateConditions.None,
+ RequireCanInteract = false,
+ };
+
+ _doAfter.TryStartDoAfter(doAfter);
+ }
+
+ ///
+ /// Checks whether a changeling slug can take over the body.
+ ///
+ private bool CanTakeOver(EntityUid user, EntityUid target, bool showPopups = true)
+ {
+ if (!HasComp(target))
+ return false;
+
+ if (HasComp(target))
+ {
+ if (showPopups)
+ _popup.PopupEntity(Loc.GetString("changeling-takeover-is-changeling"), user);
+ return false;
+ }
+
+ if (_mobState.IsDead(target))
+ return true;
+
+ if (showPopups)
+ _popup.PopupEntity(Loc.GetString("changeling-takeover-not-dead"), user);
+ return false;
+ }
+
+ [SubscribeLocalEvent]
+ private void OnTakeOverCorpseDoAfter(Entity ent,
+ ref ChangelingTakeOverCorpseDoAfterEvent args)
+ {
+ args.Handled = true;
+
+ if (args.Cancelled || args.Target is not { } target || !CanTakeOver(args.User, target, showPopups: false))
+ return;
+
+ if (!_mind.TryGetMind(args.User, out var mindId, out var mind))
+ return;
+
+ TakeOverCorpse(args.User, target, mindId, mind);
+
+ _popup.PopupEntity(Loc.GetString("changeling-takeover-success-self"), target, target, PopupType.Large);
+ }
+
+ private void TakeOverCorpse(EntityUid user, EntityUid target, EntityUid mindId, MindComponent mind)
+ {
+ // TODO: delete this after adding the stasis.
+ _rejuvenate.PerformRejuvenate(target);
+ _mind.TransferTo(mindId, target, mind: mind);
+
+ _antag.AssignAntagComponents(target, ChangelingAntag);
+
+ QueueDel(user);
+ }
+}
diff --git a/Content.Server/Cloning/CloningSystem.cs b/Content.Server/Cloning/CloningSystem.cs
index eef5ac02a7..2abf6f7e25 100644
--- a/Content.Server/Cloning/CloningSystem.cs
+++ b/Content.Server/Cloning/CloningSystem.cs
@@ -88,6 +88,7 @@ public sealed partial class CloningSystem : SharedCloningSystem
// Set the clone's name. The raised events will also adjust their PDA and ID card names.
_metaData.SetEntityName(clone.Value, originalName, raiseEvents: settings.RaiseEntityRenamedEvent);
+ _metaData.SetEntityDescription(clone.Value, Description(original));
_identity.QueueIdentityUpdate(clone.Value); // We have to manually refresh the identity in case we did not raise events.
_adminLogger.Add(LogType.Chat, LogImpact.Medium, $"The body of {original:player} was cloned as {clone.Value:player}");
diff --git a/Content.Shared/Changeling/Components/ChangelingLastResortAbilityComponent.cs b/Content.Shared/Changeling/Components/ChangelingLastResortAbilityComponent.cs
new file mode 100644
index 0000000000..73ed0dcf13
--- /dev/null
+++ b/Content.Shared/Changeling/Components/ChangelingLastResortAbilityComponent.cs
@@ -0,0 +1,30 @@
+using Content.Shared.Actions;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Changeling.Components;
+
+///
+/// Allows a changeling to gib their current body and escape as a head slug.
+///
+[RegisterComponent, NetworkedComponent]
+public sealed partial class ChangelingLastResortAbilityComponent : Component
+{
+ ///
+ /// The prototype ID of the slug to spawn.
+ ///
+ [DataField]
+ public EntProtoId SlugPrototype = "MobHeadSlug";
+
+ ///
+ /// The sound to play when the changeling gibbs.
+ ///
+ [DataField]
+ public SoundSpecifier Sound = new SoundCollectionSpecifier("gib", AudioParams.Default.WithVariation(0.025f));
+}
+
+///
+/// Action event for Last Resort.
+///
+public sealed partial class ChangelingLastResortActionEvent : InstantActionEvent;
diff --git a/Content.Shared/Changeling/Components/ChangelingSlugComponent.cs b/Content.Shared/Changeling/Components/ChangelingSlugComponent.cs
new file mode 100644
index 0000000000..96dfdb3f7b
--- /dev/null
+++ b/Content.Shared/Changeling/Components/ChangelingSlugComponent.cs
@@ -0,0 +1,51 @@
+using Content.Shared.Actions;
+using Content.Shared.DoAfter;
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Changeling.Components;
+
+///
+/// Allows a changeling slug to take over a corpse and become a full changeling again.
+///
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class ChangelingSlugComponent : Component
+{
+ ///
+ /// The action granted for taking over a corpse.
+ ///
+ [DataField]
+ public EntProtoId? Action = "ActionChangelingTakeOverCorpse";
+
+ ///
+ /// The action entity associated with taking over a corpse.
+ ///
+ [DataField, AutoNetworkedField]
+ public EntityUid? ActionEntity;
+
+ ///
+ /// How long it takes to take over a corpse.
+ ///
+ [DataField]
+ public TimeSpan TakeOverDuration = TimeSpan.FromSeconds(5);
+
+ ///
+ /// The sound to play when starting the takeover.
+ ///
+ [DataField]
+ public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Effects/Fluids/splat.ogg");
+}
+
+///
+/// Action event for taking over a corpse.
+///
+[ByRefEvent]
+public sealed partial class ChangelingTakeOverCorpseActionEvent : EntityTargetActionEvent;
+
+///
+/// DoAfter event for the takeover process.
+///
+[Serializable, NetSerializable]
+public sealed partial class ChangelingTakeOverCorpseDoAfterEvent : SimpleDoAfterEvent;
diff --git a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs
index cb78adc77f..4124c524a8 100644
--- a/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs
+++ b/Content.Shared/Changeling/Systems/ChangelingTransformSystem.cs
@@ -195,6 +195,7 @@ public sealed partial class ChangelingTransformSystem : EntitySystem
_adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(ent.Owner):player} successfully transformed into \"{Name(targetIdentity)}\"");
_metaData.SetEntityName(ent, Name(targetIdentity), raiseEvents: false); // Don't raise events because we don't want to rename the ID card.
+ _metaData.SetEntityDescription(ent, Description(targetIdentity));
_identity.QueueIdentityUpdate(ent); // We have to manually refresh the identity because we did not raise events.
Dirty(ent);
diff --git a/Content.Shared/Changeling/Systems/SharedChangelingLastResortSystem.cs b/Content.Shared/Changeling/Systems/SharedChangelingLastResortSystem.cs
new file mode 100644
index 0000000000..acfce30cf8
--- /dev/null
+++ b/Content.Shared/Changeling/Systems/SharedChangelingLastResortSystem.cs
@@ -0,0 +1,49 @@
+using Content.Shared.Mind;
+using Content.Shared.Actions;
+using Content.Shared.Changeling.Components;
+using Content.Shared.Gibbing;
+using Robust.Shared.Audio.Systems;
+using Robust.Shared.Network;
+
+namespace Content.Shared.Changeling.Systems;
+
+public abstract partial class SharedChangelingLastResortSystem : EntitySystem
+{
+ [Dependency] private INetManager _net = default!;
+ [Dependency] private GibbingSystem _gibbing = default!;
+ [Dependency] private SharedMindSystem _mind = default!;
+ [Dependency] private SharedActionsSystem _actions = default!;
+ [Dependency] protected SharedAudioSystem Audio = default!;
+
+ [SubscribeLocalEvent]
+ private void OnTakeOverMapInit(Entity ent, ref MapInitEvent args)
+ {
+ _actions.AddAction(ent, ref ent.Comp.ActionEntity, ent.Comp.Action);
+ }
+
+ [SubscribeLocalEvent]
+ private void OnTakeOverShutdown(Entity ent, ref ComponentShutdown args)
+ {
+ if (ent.Comp.ActionEntity != null)
+ _actions.RemoveAction(ent.Owner, ent.Comp.ActionEntity);
+ }
+
+ [SubscribeLocalEvent]
+ private void OnLastResortAction(Entity ent,
+ ref ChangelingLastResortActionEvent args)
+ {
+ if (args.Handled || !_mind.TryGetMind(args.Performer, out var mindId, out var mind))
+ return;
+
+ args.Handled = true;
+
+ Audio.PlayPredicted(ent.Comp.Sound, args.Performer, args.Performer);
+
+ if (!_net.IsServer)
+ return; // Transfer Mind is unpredictable.
+
+ var slug = PredictedSpawnAtPosition(ent.Comp.SlugPrototype, Transform(args.Performer).Coordinates);
+ _mind.TransferTo(mindId, slug, mind: mind);
+ _gibbing.Gib(args.Performer);
+ }
+}
diff --git a/Resources/Locale/en-US/changeling/changeling.ftl b/Resources/Locale/en-US/changeling/changeling.ftl
index 52daca4783..02636a33e5 100644
--- a/Resources/Locale/en-US/changeling/changeling.ftl
+++ b/Resources/Locale/en-US/changeling/changeling.ftl
@@ -42,6 +42,12 @@ changeling-flesh-clothing-alert-desc = Whether clothing transformation is enable
changeling-biodegrade-used-popup = {CAPITALIZE(THE($user))} vomits acid over {POSS-ADJ($user)} {$restraint}!
changeling-biodegrade-used-popup-self = We vomit acid over our {$restraint}!
+# last resort
+changeling-takeover-not-dead = This body yet lives! We cannot infest it alive.
+changeling-takeover-is-changeling = This body rejects our attempts to take over!
+changeling-takeover-start-others = {CAPITALIZE(THE($user))} begins to crawl inside the corpse!
+changeling-takeover-success-self = We have successfully infested the body and assumed its form.
+
# stings
changeling-sting-success = We silently sting {THE($target)}!
diff --git a/Resources/Locale/en-US/store/changeling-catalog.ftl b/Resources/Locale/en-US/store/changeling-catalog.ftl
index d42415b1fd..25133ba334 100644
--- a/Resources/Locale/en-US/store/changeling-catalog.ftl
+++ b/Resources/Locale/en-US/store/changeling-catalog.ftl
@@ -24,3 +24,8 @@ changeling-catalog-lethal-sting-desc = Causes very slow damage to the target. Us
changeling-catalog-hallucinogenic-sting-name = Hallucinogenic Sting
changeling-catalog-hallucinogenic-sting-desc = Causes the target to get high and have difficulty speaking. Causes confusion among the crew. Can be used on self.
+
+changeling-catalog-last-resort-name = Last Resort
+changeling-catalog-last-resort-desc = Gib your current body and escape as a weak head slug. If you infest a humanoid corpse, you can return to a full changeling body.
+
+ Warning! This resets your progress as a changeling, removing your store purchases and absorbed identities!
diff --git a/Resources/Prototypes/Actions/changeling.yml b/Resources/Prototypes/Actions/changeling.yml
index 0ebb7bdbed..b68dc9fc36 100644
--- a/Resources/Prototypes/Actions/changeling.yml
+++ b/Resources/Prototypes/Actions/changeling.yml
@@ -202,3 +202,39 @@
- !type:AddReagentToBloodstream
reagent: Cryptobiolin
quantity: 10 # About 20s of your speech being scrambled
+
+- type: entity
+ parent: BaseAction
+ id: ActionChangelingLastResort
+ name: "[color=red]Last Resort[/color]"
+ description: We sacrifice our current body in a moment of need, violently expanding to break through obstacles and reforming as a headslug.
+ components:
+ - type: ConfirmableAction
+ popup: suicide-action-popup
+ - type: Action
+ raiseOnAction: true
+ checkCanInteract: false # You can transform if you are killed
+ checkConsciousness: false
+ itemIconStyle: BigAction
+ icon:
+ sprite: Interface/Actions/changeling2.rsi
+ state: last_resort
+ - type: InstantAction
+ event: !type:ChangelingLastResortActionEvent
+ - type: ChangelingLastResortAbility
+
+- type: entity
+ parent: BaseAction
+ id: ActionChangelingTakeOverCorpse
+ name: Take Over Corpse
+ description: Infest a corpse to return to your true form.
+ components:
+ - type: Action
+ useDelay: 10
+ itemIconStyle: BigAction
+ icon:
+ sprite: Interface/Actions/changeling2.rsi
+ state: take_over_corpse
+ - type: EntityTargetAction
+ event: !type:ChangelingTakeOverCorpseActionEvent
+ - type: TargetAction
diff --git a/Resources/Prototypes/Catalog/changeling_catalog.yml b/Resources/Prototypes/Catalog/changeling_catalog.yml
index 1477569e8b..c83f07fb36 100644
--- a/Resources/Prototypes/Catalog/changeling_catalog.yml
+++ b/Resources/Prototypes/Catalog/changeling_catalog.yml
@@ -34,7 +34,7 @@
description: changeling-catalog-voice-mimic-desc
icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: mimicry}
cost:
- ChangelingDNA: 20
+ ChangelingDNA: 10
categories:
- ChangelingStoreUtility
conditions:
@@ -49,7 +49,7 @@
icon: { sprite: /Textures/Interface/Actions/changeling2.rsi, state: biodegrade }
applyToMob: true
cost:
- ChangelingDNA: 20
+ ChangelingDNA: 10
categories:
- ChangelingStoreUtility
conditions:
@@ -130,3 +130,17 @@
- !type:ListingLimitedStockCondition
stock: 1
productAction: ActionChangelingStingHallucinogenic
+
+- type: listing
+ id: ChangelingLastResort
+ name: changeling-catalog-last-resort-name
+ description: changeling-catalog-last-resort-desc
+ applyToMob: true
+ cost:
+ ChangelingDNA: 20
+ categories:
+ - ChangelingStoreUtility
+ conditions:
+ - !type:ListingLimitedStockCondition
+ stock: 1
+ productAction: ActionChangelingLastResort
diff --git a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml
index 8ece41546e..ffa7f94b8c 100644
--- a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml
+++ b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml
@@ -14,6 +14,53 @@
balance:
ChangelingDNA: 60
+- type: entity
+ parent: [ SimpleSpaceMobBase, MobNightVision ]
+ id: MobHeadSlug
+ name: headslug
+ description: A small, slug-like creature with a large, gaping maw. It's covered in a thick, slimy mucus.
+ components:
+ - type: Fixtures
+ fixtures:
+ fix1:
+ shape:
+ !type:PhysShapeCircle
+ radius: 0.2
+ density: 15
+ mask:
+ - SmallMobMask
+ layer:
+ - SmallMobLayer
+ - type: Sprite
+ drawdepth: SmallMobs
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: slug
+ sprite: Mobs/Animals/headslug.rsi
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: slug
+ Dead:
+ Base: slug_dead
+ - type: MobThresholds
+ thresholds:
+ 0: Alive
+ 50: Dead
+ - type: MovementSpeedModifier # Slightly faster than regular mobs
+ baseWalkSpeed: 3
+ baseSprintSpeed: 5
+ - type: MeleeWeapon
+ altDisarm: false
+ damage:
+ types:
+ Blunt: 5
+ Structural: 15 # to destroy lockers in which bodies could be hidden
+ - type: ChangelingSlug
+ - type: Tag # Removes DoorBumpOpener
+ tags:
+ []
+
- type: entity # dummy prototype for the store listing
id: ChangelingFleshClothingAbilityStoreDummy
categories: [ HideSpawnMenu ]
diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml
index ef4bb40b76..6320d33417 100644
--- a/Resources/Prototypes/GameRules/roundstart.yml
+++ b/Resources/Prototypes/GameRules/roundstart.yml
@@ -209,6 +209,7 @@
id: Changeling
parent: [BaseGameRule, BaseRoundstartAntagRule]
components:
+ - type: ChangelingRule
- type: GameRule
minPlayers: 25
- type: AntagSelection
diff --git a/Resources/Prototypes/Roles/Antags/changeling.yml b/Resources/Prototypes/Roles/Antags/changeling.yml
index 76df0c6069..c16e5be244 100644
--- a/Resources/Prototypes/Roles/Antags/changeling.yml
+++ b/Resources/Prototypes/Roles/Antags/changeling.yml
@@ -13,7 +13,7 @@
text: changeling-role-greeting
color: Red
sound: /Audio/Ambience/Antag/changeling_start.ogg
- components:
+ components: # When updating components, remember to copy the changes over to MobLing !!!!!
- type: ChangelingDevour
- type: ChangelingIdentity
- type: ChangelingTransform
diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/last_resort.png b/Resources/Textures/Interface/Actions/changeling2.rsi/last_resort.png
new file mode 100644
index 0000000000..5df2d4b692
Binary files /dev/null and b/Resources/Textures/Interface/Actions/changeling2.rsi/last_resort.png differ
diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json b/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json
index c8544d759c..691fc0fd9e 100644
--- a/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json
+++ b/Resources/Textures/Interface/Actions/changeling2.rsi/meta.json
@@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "Made by ketufaispikinut from a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (scientist suit), a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (hydro suit) and the changeling ability border/background sprites created by TiniestShark. Biodegrade, Mimicry and Extract Dna On/Off, Blind, Mute, Neurodepressant, Cryogenic, Lethal and Hallucination sting by ketufaispikinut, based on TiniestShark's textures. Shop icon by ketufaispikinut, based on TiniestShark's textures.",
+ "copyright": "Made by ketufaispikinut from a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (scientist suit), a sprite taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 (hydro suit) and the changeling ability border/background sprites created by TiniestShark. Biodegrade, Mimicry and Extract Dna On/Off, Blind, Mute, Neurodepressant, Cryogenic, Lethal and Hallucination sting by ketufaispikinut, based on TiniestShark's textures. Shop icon by ketufaispikinut, based on TiniestShark's textures. last_resort taken from https://github.com/tgstation/tgstation/blob/5c90546a27a1e5ea59b9f127ae274d7341acc70b/icons/mob/actions/actions_changeling.dmi and modified by Pok27 (GitHub). take_over_corpse by Pok27 (GitHub).",
"size": {
"x": 32,
"y": 32
@@ -45,6 +45,12 @@
},
{
"name": "shop"
+ },
+ {
+ "name": "last_resort"
+ },
+ {
+ "name": "take_over_corpse"
}
]
}
diff --git a/Resources/Textures/Interface/Actions/changeling2.rsi/take_over_corpse.png b/Resources/Textures/Interface/Actions/changeling2.rsi/take_over_corpse.png
new file mode 100644
index 0000000000..82027a9c0e
Binary files /dev/null and b/Resources/Textures/Interface/Actions/changeling2.rsi/take_over_corpse.png differ
diff --git a/Resources/Textures/Mobs/Animals/headslug.rsi/icon.png b/Resources/Textures/Mobs/Animals/headslug.rsi/icon.png
new file mode 100644
index 0000000000..6620e232e4
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/headslug.rsi/icon.png differ
diff --git a/Resources/Textures/Mobs/Animals/headslug.rsi/meta.json b/Resources/Textures/Mobs/Animals/headslug.rsi/meta.json
new file mode 100644
index 0000000000..64666f2c04
--- /dev/null
+++ b/Resources/Textures/Mobs/Animals/headslug.rsi/meta.json
@@ -0,0 +1,21 @@
+{
+ "version": 1,
+ "license": "CC-BY-4.0",
+ "copyright": "Made by ketufaispikinut",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "slug",
+ "directions": 4
+ },
+ {
+ "name": "slug_dead"
+ },
+ {
+ "name": "icon"
+ }
+ ]
+}
diff --git a/Resources/Textures/Mobs/Animals/headslug.rsi/slug.png b/Resources/Textures/Mobs/Animals/headslug.rsi/slug.png
new file mode 100644
index 0000000000..b2f3472328
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/headslug.rsi/slug.png differ
diff --git a/Resources/Textures/Mobs/Animals/headslug.rsi/slug_dead.png b/Resources/Textures/Mobs/Animals/headslug.rsi/slug_dead.png
new file mode 100644
index 0000000000..55e6a49a9e
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/headslug.rsi/slug_dead.png differ