mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
Changeling last resort (#43820)
* Changeling-LastResort-Stasis * Update changeling_catalog.yml * fix * Merge fix * fix * Update ChangelingLastResortSystem.cs * ConfirmableAction * fix 2 * Merge * Update ChangelingLastResortSystem.cs * review * sprite * Update icon.png * fix * NightVision * review * Interaction * review review * misc cleaning - Moved some components around - Lowered price of biodegrade and voice mimic - Updated store locale to make the warning more clear - Unpredicted "Take Over Body" - Made cloning copy over entity descriptions * abstract * fix * stuff * move to API * fix MobLing * review * docs --------- Co-authored-by: ScarKy0 <scarky0@onet.eu>
This commit is contained in:
parent
964aebb031
commit
951b2a4e3d
23 changed files with 410 additions and 5 deletions
|
|
@ -0,0 +1,5 @@
|
|||
using Content.Shared.Changeling.Systems;
|
||||
|
||||
namespace Content.Client.Changeling.Systems;
|
||||
|
||||
public sealed partial class ChangelingLastResortSystem : SharedChangelingLastResortSystem;
|
||||
|
|
@ -497,4 +497,26 @@ public sealed partial class AntagSelectionSystem
|
|||
GameTicker.StartGameRule(ruleEnt);
|
||||
return (ruleEnt, antag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns components to an entity based on a <see cref="AntagSpecifierPrototype"/>
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to give the components.</param>
|
||||
/// <param name="antag">The prototype to apply the components from.</param>
|
||||
[PublicAPI]
|
||||
public void AssignAntagComponents(EntityUid entity, ProtoId<AntagSpecifierPrototype> 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);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="AssignAntagComponents(EntityUid,ProtoId{AntagSpecifierPrototype})"/>
|
||||
[PublicAPI]
|
||||
public void AssignAntagComponents(EntityUid entity, AntagSpecifierPrototype antag)
|
||||
{
|
||||
EntityManager.AddComponents(entity, antag.Components);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<AntagSelection
|
|||
$"Game rule {ToPrettyString(gameRule)}, failed to pre-assign {player.Name} to antag {prototype.ID}");
|
||||
|
||||
// The following is where we apply components, equipment, and other changes to our antagonist entity.
|
||||
EntityManager.AddComponents(antag, prototype.Components);
|
||||
AssignAntagComponents(antag, prototype);
|
||||
|
||||
// Equip the entity's RoleLoadout and LoadoutGroup
|
||||
List<ProtoId<StartingGearPrototype>> gear = new();
|
||||
|
|
|
|||
109
Content.Server/Changeling/Systems/ChangelingLastResortSystem.cs
Normal file
109
Content.Server/Changeling/Systems/ChangelingLastResortSystem.cs
Normal file
|
|
@ -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<AntagSpecifierPrototype> 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<ChangelingSlugComponent> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a changeling slug can take over the <paramref name="target"/> body.
|
||||
/// </summary>
|
||||
private bool CanTakeOver(EntityUid user, EntityUid target, bool showPopups = true)
|
||||
{
|
||||
if (!HasComp<HumanoidProfileComponent>(target))
|
||||
return false;
|
||||
|
||||
if (HasComp<ChangelingIdentityComponent>(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<ChangelingSlugComponent> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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}");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Allows a changeling to gib their current body and escape as a head slug.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class ChangelingLastResortAbilityComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The prototype ID of the slug to spawn.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId SlugPrototype = "MobHeadSlug";
|
||||
|
||||
/// <summary>
|
||||
/// The sound to play when the changeling gibbs.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier Sound = new SoundCollectionSpecifier("gib", AudioParams.Default.WithVariation(0.025f));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action event for Last Resort.
|
||||
/// </summary>
|
||||
public sealed partial class ChangelingLastResortActionEvent : InstantActionEvent;
|
||||
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Allows a changeling slug to take over a corpse and become a full changeling again.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ChangelingSlugComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The action granted for taking over a corpse.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId? Action = "ActionChangelingTakeOverCorpse";
|
||||
|
||||
/// <summary>
|
||||
/// The action entity associated with taking over a corpse.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? ActionEntity;
|
||||
|
||||
/// <summary>
|
||||
/// How long it takes to take over a corpse.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan TakeOverDuration = TimeSpan.FromSeconds(5);
|
||||
|
||||
/// <summary>
|
||||
/// The sound to play when starting the takeover.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Effects/Fluids/splat.ogg");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action event for taking over a corpse.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public sealed partial class ChangelingTakeOverCorpseActionEvent : EntityTargetActionEvent;
|
||||
|
||||
/// <summary>
|
||||
/// DoAfter event for the takeover process.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class ChangelingTakeOverCorpseDoAfterEvent : SimpleDoAfterEvent;
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<ChangelingSlugComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
_actions.AddAction(ent, ref ent.Comp.ActionEntity, ent.Comp.Action);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnTakeOverShutdown(Entity<ChangelingSlugComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (ent.Comp.ActionEntity != null)
|
||||
_actions.RemoveAction(ent.Owner, ent.Comp.ActionEntity);
|
||||
}
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnLastResortAction(Entity<ChangelingLastResortAbilityComponent> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)}!
|
||||
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ]
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@
|
|||
id: Changeling
|
||||
parent: [BaseGameRule, BaseRoundstartAntagRule]
|
||||
components:
|
||||
- type: ChangelingRule
|
||||
- type: GameRule
|
||||
minPlayers: 25
|
||||
- type: AntagSelection
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Resources/Textures/Mobs/Animals/headslug.rsi/icon.png
Normal file
BIN
Resources/Textures/Mobs/Animals/headslug.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 445 B |
21
Resources/Textures/Mobs/Animals/headslug.rsi/meta.json
Normal file
21
Resources/Textures/Mobs/Animals/headslug.rsi/meta.json
Normal file
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/Mobs/Animals/headslug.rsi/slug.png
Normal file
BIN
Resources/Textures/Mobs/Animals/headslug.rsi/slug.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Resources/Textures/Mobs/Animals/headslug.rsi/slug_dead.png
Normal file
BIN
Resources/Textures/Mobs/Animals/headslug.rsi/slug_dead.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 530 B |
Loading…
Add table
Reference in a new issue