From 52c4ee954c09371d37f39364dbcdfe86da704bf1 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sat, 29 Mar 2025 12:35:04 +0100 Subject: [PATCH] [April Fools] Leggy (#36133) * leggy * shader * fix visuals for other clients * static --- .../StationAi/StationAiVisualizerSystem.cs | 173 ++++++++++++++++++ .../StationAi/SharedStationAiSystem.Held.cs | 46 ++++- .../StationAi/SharedStationAiSystem.cs | 24 +++ .../StationAi/StationAiCoreComponent.cs | 12 ++ Resources/Prototypes/Actions/station_ai.yml | 30 +++ .../Entities/Mobs/Player/silicon.yml | 78 ++++++-- .../Interface/Actions/actions_ai.rsi/leg.png | Bin 0 -> 2060 bytes .../Actions/actions_ai.rsi/meta.json | 5 +- .../Mobs/Silicon/leggy.rsi/ai_down.png | Bin 0 -> 3401 bytes .../Mobs/Silicon/leggy.rsi/ai_high.png | Bin 0 -> 6565 bytes .../Textures/Mobs/Silicon/leggy.rsi/ai_up.png | Bin 0 -> 2221 bytes .../Mobs/Silicon/leggy.rsi/base_high.png | Bin 0 -> 2135 bytes .../Textures/Mobs/Silicon/leggy.rsi/down.png | Bin 0 -> 2268 bytes .../Textures/Mobs/Silicon/leggy.rsi/meta.json | 96 ++++++++++ .../Textures/Mobs/Silicon/leggy.rsi/up.png | Bin 0 -> 1763 bytes 15 files changed, 447 insertions(+), 17 deletions(-) create mode 100644 Content.Client/Silicons/StationAi/StationAiVisualizerSystem.cs create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/leg.png create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/ai_down.png create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/ai_high.png create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/ai_up.png create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/base_high.png create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/down.png create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/meta.json create mode 100644 Resources/Textures/Mobs/Silicon/leggy.rsi/up.png diff --git a/Content.Client/Silicons/StationAi/StationAiVisualizerSystem.cs b/Content.Client/Silicons/StationAi/StationAiVisualizerSystem.cs new file mode 100644 index 0000000000..475e31d91f --- /dev/null +++ b/Content.Client/Silicons/StationAi/StationAiVisualizerSystem.cs @@ -0,0 +1,173 @@ +using Content.Shared.Silicons.StationAi; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; + +namespace Content.Client.Silicons.StationAi; + +public sealed partial class StationAiVisualizerSystem : VisualizerSystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnAnimationCompleted); + } + + private static readonly Animation CoreUpAnimation = new() + { + Length = TimeSpan.FromSeconds(0.8f), + AnimationTracks = + { + new AnimationTrackSpriteFlick + { + LayerKey = StationAiVisualLayers.CoreStanding, + KeyFrames = + { + new AnimationTrackSpriteFlick.KeyFrame(new RSI.StateId("up"), 0f) + } + }, + new AnimationTrackSpriteFlick + { + LayerKey = StationAiVisualLayers.ScreenStanding, + KeyFrames = + { + new AnimationTrackSpriteFlick.KeyFrame(new RSI.StateId("ai_up"), 0f) + } + } + } + }; + + private static readonly Animation CoreDownAnimation = new() + { + Length = TimeSpan.FromSeconds(0.8f), + AnimationTracks = + { + new AnimationTrackSpriteFlick + { + LayerKey = StationAiVisualLayers.CoreStanding, + KeyFrames = + { + new AnimationTrackSpriteFlick.KeyFrame(new RSI.StateId("down"), 0f) + } + }, + new AnimationTrackSpriteFlick + { + LayerKey = StationAiVisualLayers.ScreenStanding, + KeyFrames = + { + new AnimationTrackSpriteFlick.KeyFrame(new RSI.StateId("ai_down"), 0f) + } + } + } + }; + + protected override void OnAppearanceChange(EntityUid uid, StationAiCoreComponent component, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + if (!TryComp(uid, out var animPlayer)) + return; + + if (!AppearanceSystem.TryGetData(uid, StationAiVisualState.Key, out var state, args.Component)) + state = StationAiState.Empty; + + UpdateVisuals(uid, state, component, args.Sprite, animPlayer); + } + + private void OnAnimationCompleted(EntityUid uid, StationAiCoreComponent comp, AnimationCompletedEvent args) + { + if (args.Key != StationAiCoreComponent.AnimationKey) + return; + if (!TryComp(uid, out var sprite)) + return; + if (!TryComp(uid, out var animPlayer)) + return; + + if (!AppearanceSystem.TryGetData(uid, StationAiVisualState.Key, out var state)) + state = comp.CurrentState; + + // Convert to finished state + StationAiState targetState; + switch (state) + { + case StationAiState.Up: + targetState = StationAiState.Standing; + break; + case StationAiState.Down: + targetState = StationAiState.Occupied; + break; + default: + targetState = state; + break; + } + + UpdateVisuals(uid, targetState, comp, sprite, animPlayer); + } + + private void UpdateVisuals(EntityUid uid, StationAiState state, StationAiCoreComponent comp, SpriteComponent sprite, AnimationPlayerComponent? animPlayer = null) + { + if (state == comp.CurrentState) + return; + if (!Resolve(uid, ref animPlayer)) + return; + if (AnimationSystem.HasRunningAnimation(uid, animPlayer, StationAiCoreComponent.AnimationKey)) + return; + + var targetState = state; + if (comp.CurrentState == StationAiState.Occupied && state == StationAiState.Standing) + targetState = StationAiState.Up; // play standing up animation first + else if (comp.CurrentState == StationAiState.Standing && state == StationAiState.Occupied) + targetState = StationAiState.Down; // play sitting down animation first + + comp.CurrentState = targetState; + + switch (targetState) + { + case StationAiState.Empty: + sprite.LayerSetVisible(StationAiVisualLayers.Core, true); + sprite.LayerSetVisible(StationAiVisualLayers.Screen, true); + sprite.LayerSetVisible(StationAiVisualLayers.CoreStanding, false); + sprite.LayerSetVisible(StationAiVisualLayers.ScreenStanding, false); + sprite.LayerSetState(StationAiVisualLayers.Screen, new RSI.StateId("ai_empty")); + break; + case StationAiState.Occupied: + sprite.LayerSetVisible(StationAiVisualLayers.Core, true); + sprite.LayerSetVisible(StationAiVisualLayers.Screen, true); + sprite.LayerSetVisible(StationAiVisualLayers.CoreStanding, false); + sprite.LayerSetVisible(StationAiVisualLayers.ScreenStanding, false); + sprite.LayerSetState(StationAiVisualLayers.Screen, new RSI.StateId("ai")); + break; + case StationAiState.Dead: + sprite.LayerSetVisible(StationAiVisualLayers.Core, true); + sprite.LayerSetVisible(StationAiVisualLayers.Screen, true); + sprite.LayerSetVisible(StationAiVisualLayers.CoreStanding, false); + sprite.LayerSetVisible(StationAiVisualLayers.ScreenStanding, false); + sprite.LayerSetState(StationAiVisualLayers.Screen, new RSI.StateId("ai_dead")); + break; + case StationAiState.Up: + sprite.LayerSetVisible(StationAiVisualLayers.Core, false); + sprite.LayerSetVisible(StationAiVisualLayers.Screen, false); + sprite.LayerSetVisible(StationAiVisualLayers.CoreStanding, true); + sprite.LayerSetVisible(StationAiVisualLayers.ScreenStanding, true); + AnimationSystem.Play((uid, animPlayer), CoreUpAnimation, StationAiCoreComponent.AnimationKey); + break; + case StationAiState.Down: + sprite.LayerSetVisible(StationAiVisualLayers.Core, false); + sprite.LayerSetVisible(StationAiVisualLayers.Screen, false); + sprite.LayerSetVisible(StationAiVisualLayers.CoreStanding, true); + sprite.LayerSetVisible(StationAiVisualLayers.ScreenStanding, true); + AnimationSystem.Play((uid, animPlayer), CoreDownAnimation, StationAiCoreComponent.AnimationKey); + break; + case StationAiState.Standing: + sprite.LayerSetVisible(StationAiVisualLayers.Core, false); + sprite.LayerSetVisible(StationAiVisualLayers.Screen, false); + sprite.LayerSetVisible(StationAiVisualLayers.CoreStanding, true); + sprite.LayerSetVisible(StationAiVisualLayers.ScreenStanding, true); + sprite.LayerSetState(StationAiVisualLayers.CoreStanding, new RSI.StateId("base_high")); + sprite.LayerSetState(StationAiVisualLayers.ScreenStanding, new RSI.StateId("ai_high")); + break; + default: + break; + } + } +} diff --git a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs index 8acfb56376..bd19f300db 100644 --- a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs +++ b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Actions.Events; using Content.Shared.IdentityManagement; using Content.Shared.Interaction.Events; +using Content.Shared.Mind.Components; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Serialization; @@ -27,6 +28,8 @@ public abstract partial class SharedStationAiSystem SubscribeLocalEvent(OnHeldInteraction); SubscribeLocalEvent(OnHeldRelay); SubscribeLocalEvent(OnCoreJump); + SubscribeLocalEvent(OnCoreVisit); + SubscribeLocalEvent(OnCoreUnVisit); SubscribeLocalEvent(OnTryGetIdentityShortInfo); } @@ -50,7 +53,46 @@ public abstract partial class SharedStationAiSystem if (!TryGetCore(ent.Owner, out var core) || core.Comp?.RemoteEntity == null) return; - _xforms.DropNextTo(core.Comp.RemoteEntity.Value, core.Owner) ; + _xforms.DropNextTo(core.Comp.RemoteEntity.Value, core.Owner); + } + + private void OnCoreVisit(Entity ent, ref VisitCoreEvent args) + { + if (!TryGetCore(ent.Owner, out var core) || core.Comp?.RemoteEntity == null) + return; + + if (!_mind.TryGetMind(ent.Owner, out var mindId, out var mind)) + return; + + // move the player's mind to the core + _mind.Visit(mindId, core, mind); + _xforms.Unanchor(core); + + if (!TryComp(core, out var app)) + return; + + _appearance.SetData(core, StationAiVisualState.Key, StationAiState.Standing, app); + } + + private void OnCoreUnVisit(Entity ent, ref UnVisitCoreEvent args) + { + if (!Transform(ent.Owner).Anchored && !_xforms.AnchorEntity(ent.Owner)) + return; + + // move the player's mind back to the camera + if (ent.Comp.MindId != null) + _mind.UnVisit(ent.Comp.MindId.Value); + + if (!TryComp(ent.Owner, out StationAiCoreComponent? coreComp) || coreComp.RemoteEntity == null) + return; + + // move the camera back to the core + _xforms.DropNextTo(coreComp.RemoteEntity.Value, ent.Owner); + + if (!TryComp(ent.Owner, out var app)) + return; + + _appearance.SetData(ent.Owner, StationAiVisualState.Key, StationAiState.Occupied, app); } /// @@ -164,7 +206,7 @@ public abstract partial class SharedStationAiSystem var verb = new AlternativeVerb { Text = isOpen ? Loc.GetString("ai-close") : Loc.GetString("ai-open"), - Act = () => + Act = () => { // no need to show menu if device is not powered. if (!PowerReceiver.IsPowered(ent.Owner)) diff --git a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs index 4cf36f560e..47a520be13 100644 --- a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs +++ b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs @@ -460,6 +460,9 @@ public abstract partial class SharedStationAiSystem : EntitySystem private void OnAiRemove(Entity ent, ref EntRemovedFromContainerMessage args) { + if (args.Container.ID != StationAiCoreComponent.Container) + return; + if (_timing.ApplyingState) return; @@ -538,6 +541,16 @@ public sealed partial class JumpToCoreEvent : InstantActionEvent } +public sealed partial class VisitCoreEvent : InstantActionEvent +{ + +} + +public sealed partial class UnVisitCoreEvent : InstantActionEvent +{ + +} + [Serializable, NetSerializable] public sealed partial class IntellicardDoAfterEvent : SimpleDoAfterEvent; @@ -548,10 +561,21 @@ public enum StationAiVisualState : byte Key, } +public enum StationAiVisualLayers : byte +{ + Core, + Screen, + CoreStanding, + ScreenStanding, +} + [Serializable, NetSerializable] public enum StationAiState : byte { Empty, Occupied, Dead, + Up, + Down, + Standing, } diff --git a/Content.Shared/Silicons/StationAi/StationAiCoreComponent.cs b/Content.Shared/Silicons/StationAi/StationAiCoreComponent.cs index e97e7626b8..1a76076c51 100644 --- a/Content.Shared/Silicons/StationAi/StationAiCoreComponent.cs +++ b/Content.Shared/Silicons/StationAi/StationAiCoreComponent.cs @@ -39,4 +39,16 @@ public sealed partial class StationAiCoreComponent : Component public EntProtoId? PhysicalEntityProto = "StationAiHoloLocal"; public const string Container = "station_ai_mind_slot"; + + /// + /// The key used to index the leggy animation. + /// + [ViewVariables] + public const string AnimationKey = "leggy_animation"; + + /// + /// The current visual state of the core. + /// + [ViewVariables] + public StationAiState CurrentState = StationAiState.Empty; } diff --git a/Resources/Prototypes/Actions/station_ai.yml b/Resources/Prototypes/Actions/station_ai.yml index 67d5626219..3d70c012b9 100644 --- a/Resources/Prototypes/Actions/station_ai.yml +++ b/Resources/Prototypes/Actions/station_ai.yml @@ -12,6 +12,36 @@ state: ai_core event: !type:JumpToCoreEvent +- type: entity + id: ActionVisitCore + name: Leggy + description: Move around using your legs. + components: + - type: InstantAction + priority: -20 + itemIconStyle: BigAction + icon: + sprite: Interface/Actions/actions_ai.rsi + state: leg + event: !type:VisitCoreEvent + useDelay: 2 + startDelay: true + +- type: entity + id: ActionUnVisitCore + name: No Leggy + description: Return back to the remote. + components: + - type: InstantAction + priority: -20 + itemIconStyle: BigAction + icon: + sprite: Interface/Actions/actions_ai.rsi + state: leg + event: !type:UnVisitCoreEvent + useDelay: 2 + startDelay: true + - type: entity id: ActionSurvCameraLights name: Toggle camera lights diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 0769972512..440789ee4a 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -34,6 +34,7 @@ - type: ActionGrant actions: - ActionJumpToCore + - ActionVisitCore - ActionSurvCameraLights - ActionAIViewLaws - type: UserInterface @@ -325,10 +326,13 @@ name: AI Core description: The latest in Artificial Intelligences. parent: + - BaseMob - BaseStructure - AiHolder suffix: Empty components: + - type: Transform + noRot: true - type: WarpPoint - type: ContainerComp proto: AiHeld @@ -350,25 +354,77 @@ - type: StationAiVision - type: InteractionOutline - type: Sprite - sprite: Mobs/Silicon/station_ai.rsi + noRot: true layers: - state: base + sprite: Mobs/Silicon/station_ai.rsi + map: ["enum.StationAiVisualLayers.Core"] - state: ai_empty - map: ["unshaded"] + sprite: Mobs/Silicon/station_ai.rsi shader: unshaded + map: ["enum.StationAiVisualLayers.Screen"] + - state: base_high + sprite: Mobs/Silicon/leggy.rsi + map: ["enum.StationAiVisualLayers.CoreStanding"] + offset: "0.0,0.5" + visible: false + - state: ai_high + sprite: Mobs/Silicon/leggy.rsi + shader: unshaded + map: ["enum.StationAiVisualLayers.ScreenStanding"] + offset: "0.0,0.5" + visible: false - type: Appearance + - type: AnimationPlayer + - type: ActionGrant + actions: + - ActionUnVisitCore + - type: Anchorable + flags: + - None + - type: Physics + bodyType: Static + - type: Tag + tags: + - DoorBumpOpener + - FootstepSound + - Structure + - type: Access + groups: + - AllAccess + - type: IntrinsicRadioReceiver + - type: IntrinsicRadioTransmitter + channels: + - Binary + - Common + - Command + - Engineering + - Medical + - Science + - Security + - Service + - Supply + - type: ActiveRadio + channels: + - Binary + - Common + - Command + - Engineering + - Medical + - Science + - Security + - Service + - Supply + - type: ShowJobIcons + - type: Speech + speechVerb: Robotic + speechSounds: Borg - type: InteractionPopup interactSuccessString: petting-success-station-ai interactFailureString: petting-failure-station-ai messagePerceivedByOthers: petting-success-station-ai-others # Otherwise AI cannot tell its being pet as It's just a brain inside of the core, not the core itself. interactSuccessSound: path: /Audio/Ambience/Objects/periodic_beep.ogg - - type: GenericVisualizer - visuals: - enum.StationAiVisualState.Key: - unshaded: - Empty: { state: ai_empty } - Occupied: { state: ai } - type: Telephone compatibleRanges: - Grid @@ -396,12 +452,6 @@ - type: ContainerSpawnPoint containerId: station_ai_mind_slot job: StationAi - - type: Sprite - sprite: Mobs/Silicon/station_ai.rsi - layers: - - state: base - - state: ai - shader: unshaded # The actual brain inside the core - type: entity diff --git a/Resources/Textures/Interface/Actions/actions_ai.rsi/leg.png b/Resources/Textures/Interface/Actions/actions_ai.rsi/leg.png new file mode 100644 index 0000000000000000000000000000000000000000..13bcfcbe33be00f1cb6266bf6791fde714aa2c39 GIT binary patch literal 2060 zcmb_dU1%Id9A7;!F-`lRwK09rWvgP*xt-nHkK46pNbl0*Fn1o8!$hB)+nKvtbGN(h zZgQ7^w2i*lysC|*4)l7PLd(ZA3hGDiRM-o|Dv%%LLqW{D@N6ymfxy)#8h}N`(LZR-iuD-rL z2w_)x>f%c1@*ln3<1csNH~U{W%FTWtzIJ~2biMZNRez~o{jPrSr~3T-{3|Q<6Tj6L z7Z+DoSJ(cm(?Y4%7UZj^U#g#f{m0{TYqbA>pG}W3!Q__ZN_4kMk#{>I&w32A?cU(K zgE@Bmeula03o|$2Poze5!>)u8w(}%ht2h+RF#85-4l*W*&*n+dv|`+^pPk`Y6UVr5 zIR#TroRrLwS(l8>rgO&Zq@iJM;7N90O{WAE;v=?JDO;Xii*XHJowkEvo?{yje=^1m z1_s%QRECY)E@7201O|j6t7>6Ekt78^&WcckJd}As1cIVNNf%VMRXA$R#RWZ^IMA|1 zdoix$`;N}@)oL|djf8Et$P1dL@lfPN5l{s1W-K4ofaUFJGbD&-xTfQqw#5dFC~r^s zF^(#2x=?XCw3gQj6Ac(&Lk=&5Vc=2&h>Z@;nR3ewS>oAKu0e*TsmwirH;x{63G!_> zXWQlWMrGQPSy2d!?4#qRh3%@hcijS#Kt73abk`&x2td$sP|#&j7q!P|1HvXWWn;52 zvk@vraxkI`+VxPHG8p;jreJL71>3D4>abZsMZ!B)kz+ey)Z=#9cB$b&-TLulJf3mw zf?1{$UUqmtn;eQOf~F`y3=0jpsg$0yJReyGNhV?(4NllJv5qiAQXZ;6mS6-#Ba#46 zG_L^KQ%GJGRRhcI^$FXU3Q{0g-#iW2HYmrx@(NO36AJ9;ld+(x0LxJf)Pf{~D8VYwWTa^-5=0awLE1MmNgpvi zy2mrEgEU57Y_-ZJ+ejWA8Ns25aYm301aqxnbCY=7lI7O=YKc(N8)Qk-x@Q;sDsstS zk;d+(S;%iC-b2$jmM)5gJc&pOP@)(DB`+Bus>liu2u7kHMUkwKw(I|uF48+m7hyZW zZ%2A7EJg`gMM7^_p1XZ#ZY?jHDmOZ_$r1ejoZ*9uwV7f3^~u+mTXzZ5jcg3jn>}cD zo)p^YJW9l(adPRC^VRzc@6qQ9CliCY=!Kt`p4f2+_J%T-zx?H|ljkliD~Hqf%^epKtemof_c1w?PJFok`MG}pojI`? literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/actions_ai.rsi/meta.json b/Resources/Textures/Interface/Actions/actions_ai.rsi/meta.json index 434b9052e0..0f33441961 100644 --- a/Resources/Textures/Interface/Actions/actions_ai.rsi/meta.json +++ b/Resources/Textures/Interface/Actions/actions_ai.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/blob/c473a8bcc28fbd80827dfca5660d81ca6e833e2c/icons/hud/screen_ai.dmi , some sprites updated by ScarKy0(Discord), door actions by ScarKy0(Discord) and @Max_tanuki(Twitter)", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/blob/c473a8bcc28fbd80827dfca5660d81ca6e833e2c/icons/hud/screen_ai.dmi , some sprites updated by ScarKy0(Discord), door actions by ScarKy0(Discord) and @Max_tanuki(Twitter), leg made by muburu_ (Dicord) and adjusted by slarticodefast", "size": { "x": 32, "y": 32 @@ -48,6 +48,9 @@ }, { "name": "door_overcharge_off" + }, + { + "name": "leg" } ] } diff --git a/Resources/Textures/Mobs/Silicon/leggy.rsi/ai_down.png b/Resources/Textures/Mobs/Silicon/leggy.rsi/ai_down.png new file mode 100644 index 0000000000000000000000000000000000000000..04fea304649a7685a843143400e67ad50aeae358 GIT binary patch literal 3401 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/leggy.rsi/ai_up.png b/Resources/Textures/Mobs/Silicon/leggy.rsi/ai_up.png new file mode 100644 index 0000000000000000000000000000000000000000..54e1fb8d912d9c2667d32a7ebb406f5438650af8 GIT binary patch literal 2221 zcmZ`)c{JPG7XIO?)U2j9sF_Nyp;|+3aLJ2mQZf>%w=YPb|d zO|7|Nih4Ci4I$E^4MMeu`?%}9Kkr#-^z_FR z(aRp6kArpcZGXQ<(B^x7oTHTfaQ|o2cZ~m|Dqffj9~cZCvXPLG@Ek8T?jt`iL31qZ zx5`tZBd-J5Ew3t*zuDDwrPRa@y#GA5yi5w_k8XTo0EO*^Pd2P-lX=kwzEOD|z4`4; z8?peZjyZd!`C;Ym{=QX_MPVdrIFVVoIs#7!v1PM+c0_4l(io6RuC7X}m$#cb-ABQU z=%Anp6u(2rvBxNhg!hFCusUzeBN4$gw;q4$TOVgP7W6f~_7kZ7%JQN?+60H8t_;grBhPyRW1@Tl#M4D#z(s1hT3pB=lwwLnEBlSv>*+ zL*AVSHr_v(bZMI$_2`C4?^j-(%6(?;Uf9M|jl0miNEju{x&6U$USV2VTi0<|>d5>}XoYeI09)uopXv+zW?TjO{cAcW23iuC*{ z&)Mc+yFoFbPlfoB7TYU{+KgGoA!RcedGL)MqmDi2$T>sm^)x#br$B!k_D0^f!g??# z1P#7GgMF+NK`nfrBHM;ALPt7!Di~WR*P1Qc7-pD-z}w*xo#nZ#MnHXjzV4LiS3hz) zJ1R$~#nRjC4(eY{Z?OF7aY1ZLJ*UiBa<`I-Vb?&N?+4!`BH8TXVPu}zygnhtdcsm; zTMv6#ST-BZuZ?62kO&j;td(C^CERk9+$>I-Y9g43n{n!aH6+ikZ%J#hk8mF*JWGJC zn>x%}?5*aT;yUWWAACj%vXT0277uF{V01?a%{jcagZS-E#XLtz>b+S07Xgrc_%?MO zrs+2onVZXuC>`v!?33!$O(Jr&=}Yw2V1jlG+xHJ>9=ZF(T;}3zZJka{<&vH`u0sDq z2*3LSaj`=y;7O$F*%>j)PK=F?xaahDpSdHmah-KPiJ712oz}avPsfa?B1=OEP+3Mo z@W7Z6slSf@r(VpIW$E<7*K$=@Dotzu+ZN1`FaDB?2{5$${{{}sD!GX`&CG5FvBl<2 zUwtclLrEuLM^`9IffK*7#Cm=dP(}AAyS0z>MCOJqs+21aRj3#y)q3Q>GLM`b%|mzF zEc?o_9p*R-ZfJ|oQK-w)wiWu#EiZC!1tJXyCxXWJ3{Qp~Q>VIz!e0PODuCzjUEK<9 zxViR4@WSc&6%{y!=EP>+O$oc`vO_gq+@F!tUD8YMDP9IqI-EW&2+qGiP z-s}W_ZL=MVMlmT7zJq2HF`Suy4@Q>_KN);o9-xKE;ck<={rvr7lFbFdLK^6?ZeBP2|+-g6o?X|!F)ewi$Y`Z2%qylgBiO%^r9 z(cg^3bF+`9wP@FU)o7Otg0RKm3DQSFudC8=(e{4|2_)i0G7<|OCGJfPR+rGmrq!aJ z&agEx!5kZXPau|{)Mk}&_0uAw>TdAu|xTD}I17EsKtb{+_%zt{F@+ph%2_~S2GAG*XA=d_3(epK8<$q52&>m74>_RV=O zqUvkaK&}!ygMPy?rhu!ex-!)7Q;2g3+opNuzYCH!)GT{G&@}zemIaLZ71YipnK=!W zM(YUb@?XdDX5=Vw7%6MOW+rZA83C@p^blzRQI>z_a^iG z=?gI;Uds?Q9<&^QYLT<9j0Y|)XIYf-vKQiR!U>ugsp{zET5dF4%>bvzgB~(ed-p#) z)V@Mf5b*r;!t^zF=&g#|N+$tr^;)%`RJd5xZcVkCpQV}srpZsLdG~^hIHT}HbCoJj zs{Y$ciC5w5I}+f8cg>Gj-HNSYrLqwhR*eeDgDH=cfH?|KX%fV^Q zndqV+FOJq9=PY=pGuBM=Mj?9MJ$J6wNJuJ*eCe={5=(@vut54M0@~!7@ zl=4Joz&2zu3o};CJR7hra}C%zh-G3641t#KvCM`c)3V|}%P;=(x8C*G5b+mBCPyOF SS@%Dhr#z&w8KM^M6#ri&7bX}0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/leggy.rsi/base_high.png b/Resources/Textures/Mobs/Silicon/leggy.rsi/base_high.png new file mode 100644 index 0000000000000000000000000000000000000000..135ea9b994b2744cc4bb8881e14f030dedb82dfc GIT binary patch literal 2135 zcmb_dTWl0n7#>=s1zR655hPJ3gYgoaoy*S7?2KIyc2~OEt?PCTST*U{IcK^2f?QDmCU*^>*s0K5Axg^w3+S}VZJ35vw zUCQ%(NB`)tGwmlYb#<=a(t+Q-YvbF@_#Scl(RBx_mCrBw$E)RUsxP0eZrir)l{3|k zeyPsP%$z-YcJ{9-6o8t2Cvx%NOVy)0PEAeDLjN8=+dn`BlUFUjN0%#Lxyb2##-pg) z?g+jG)Xu486t(b>ncLuRNcU;FT?!#==Siqia=@CRdRA8)q>m7v&XZx&iZSO89A;<} z$C&kzG@o|jq+s@ryJTRzKc|n6=qhGbucCV@8UU1tkLXINXn9&C#?){%Xa~a_L)T3F zkr=Zka7b@RXXv=?5?T)Ntj_Zyt*9YEmL!>fm=<}F=lBRGh^!!Myrc;V-6#xrbFrai z6OT1~K`+J>eBaSHu3RpM%Hfdh4s(L4svIwJqR4^;>y24Hs<4)~qKS|op6;5CZ`u|e zAfmiI>c<#hS`VS*v|uf-ktRqOS3wRZg!mw&njzL(cFw3#0ml{s5xHHBBCa$E1|*j zby6Lo*vOFJII!PsB3?wIHnpjgX(uHs|!bZbt zn3WXCU{yU2%dj8`ii#v`$j$W$TOSQ15Uj7C25jqq@h?4$`Miws0vk3kW>r-}tQrZ6 zfD29x9L-~dn`lqECLBmqoQoQ;!hjf#s1YnE3X3CA%qoTi{0LS645_Mu1QA6^Ap4q< zv|iJLJsxWuqyh3mqg6ENns_v%2ZtiY=z$stFsKik^W@`(JU7;t3j{!~p^~~A&o=xr za><%u$lY~S$X$)Rhc;cCx+ofX5|(6Ej$)pb^ODX+<%rA*1S3(9q9`JhX6RQ^2h}Q? z$TwAcGt?Vt(F@2LCUC=Y%*_XLW4f%foHv-cNAUj(h6^s%y27~simx^|=MsjEtPR1< z9yD7|3UpeJ60smpE<8D(KL0}ko~wPS#F||1k)Mt~b^8{+bK%f)zut2HNLQsgVtxI1 zN%?HafloTB4`f#-S4@AmsH=Zy>%IFYCyYs|%g9XkOuiv3=;>kxsnaX1q4w!N7QNN| z{-y5e-N}7-o;dj<&)+?vT=@A^W%n6&-+{lE47wlgjU3thUiRrjZ5z)WZu@il&e^uZ zZBx{<6Tj`+x_|n@o5e4lxb?)IWcTaz(SdI#PLJ&xd?Yk+@!SU=pWnRdzR|A=$J|-! X%VlYPCimj^!Bd+`_9ynP9h&?HR;SeG literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/leggy.rsi/down.png b/Resources/Textures/Mobs/Silicon/leggy.rsi/down.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9f3e98bbf835dde364400d197f45c20528c582 GIT binary patch literal 2268 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