From 9063cfe454263e2616d4d948648d6c73cbc039f9 Mon Sep 17 00:00:00 2001 From: Morb <14136326+Morb0@users.noreply.github.com> Date: Sun, 14 Jan 2024 10:52:07 +0300 Subject: [PATCH] Tail wagging (#19573) * MVP * Uncomment animated prototypes * Disable wagging on death * Move component to server * Looped tail animation * Apply front tail template * Disable animated markings globally * Add emote sending * Update documentation * Move locale * Use static instantAction & remove action on comp del * Use fluent POSS-ADJ * Update docs * Add copyright * Update copyright * Update license & copyright * Move to main directory & format meta.json * Fix path * Change namespace * Remove empty meta.json * Update * REMOVE unnecessary IsNullOrWhiteSpace check Co-authored-by: DrSmugleaf * Move animated markings to main file * Use emotes * new * fix * fix * Tests, pls * fix dixel * Remove networked from wagging comp * Remove unused import * Remove unused imports * Move wagging comp to shared * Revert the emotes If we're getting it the action is better. --------- Co-authored-by: DrSmugleaf Co-authored-by: metalgearsloth --- Content.Server/Wagging/WaggingSystem.cs | 110 ++++++ Content.Shared/Actions/SharedActionsSystem.cs | 2 +- Content.Shared/Wagging/WaggingComponent.cs | 33 ++ .../Locale/en-US/actions/actions/wagging.ftl | 5 + Resources/Prototypes/Actions/types.yml | 12 + .../Mobs/Customization/Markings/reptilian.yml | 39 ++- .../Entities/Mobs/Species/reptilian.yml | 1 + Resources/Prototypes/Voice/tail_emotes.yml | 14 + .../reptilian_parts.rsi/meta.json | 314 +++++++++++++++++- .../tail_dtiger_wagging.png | Bin 0 -> 5311 bytes .../tail_ltiger_wagging.png | Bin 0 -> 5283 bytes .../tail_smooth_wagging.png | Bin 0 -> 4655 bytes .../tail_spikes_wagging.png | Bin 0 -> 5335 bytes 13 files changed, 527 insertions(+), 3 deletions(-) create mode 100644 Content.Server/Wagging/WaggingSystem.cs create mode 100644 Content.Shared/Wagging/WaggingComponent.cs create mode 100644 Resources/Locale/en-US/actions/actions/wagging.ftl create mode 100644 Resources/Prototypes/Voice/tail_emotes.yml create mode 100644 Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_dtiger_wagging.png create mode 100644 Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_ltiger_wagging.png create mode 100644 Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_smooth_wagging.png create mode 100644 Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_spikes_wagging.png diff --git a/Content.Server/Wagging/WaggingSystem.cs b/Content.Server/Wagging/WaggingSystem.cs new file mode 100644 index 0000000000..5d4163fa65 --- /dev/null +++ b/Content.Server/Wagging/WaggingSystem.cs @@ -0,0 +1,110 @@ +using Content.Server.Actions; +using Content.Server.Chat.Systems; +using Content.Server.Humanoid; +using Content.Shared.Humanoid; +using Content.Shared.Humanoid.Markings; +using Content.Shared.Mobs; +using Content.Shared.Toggleable; +using Content.Shared.Wagging; +using Robust.Shared.Prototypes; + +namespace Content.Server.Wagging; + +/// +/// Adds an action to toggle wagging animation for tails markings that supporting this +/// +public sealed class WaggingSystem : EntitySystem +{ + [Dependency] private readonly ActionsSystem _actions = default!; + [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearance = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnWaggingMapInit); + SubscribeLocalEvent(OnWaggingShutdown); + SubscribeLocalEvent(OnWaggingToggle); + SubscribeLocalEvent(OnMobStateChanged); + } + + private void OnWaggingMapInit(EntityUid uid, WaggingComponent component, MapInitEvent args) + { + _actions.AddAction(uid, ref component.ActionEntity, component.Action, uid); + } + + private void OnWaggingShutdown(EntityUid uid, WaggingComponent component, ComponentShutdown args) + { + _actions.RemoveAction(uid, component.ActionEntity); + } + + private void OnWaggingToggle(EntityUid uid, WaggingComponent component, ref ToggleActionEvent args) + { + if (args.Handled) + return; + + TryToggleWagging(uid, wagging: component); + } + + private void OnMobStateChanged(EntityUid uid, WaggingComponent component, MobStateChangedEvent args) + { + if (args.NewMobState != MobState.Dead) + return; + + if (component.Wagging) + TryToggleWagging(uid, wagging: component); + } + + public bool TryToggleWagging(EntityUid uid, WaggingComponent? wagging = null, HumanoidAppearanceComponent? humanoid = null) + { + if (!Resolve(uid, ref wagging, ref humanoid)) + return false; + + if (!humanoid.MarkingSet.Markings.TryGetValue(MarkingCategories.Tail, out var markings)) + return false; + + if (markings.Count == 0) + return false; + + wagging.Wagging = !wagging.Wagging; + + for (var idx = 0; idx < markings.Count; idx++) // Animate all possible tails + { + var currentMarkingId = markings[idx].MarkingId; + string newMarkingId; + + if (wagging.Wagging) + { + newMarkingId = $"{currentMarkingId}{wagging.Suffix}"; + } + else + { + if (currentMarkingId.EndsWith(wagging.Suffix)) + { + newMarkingId = currentMarkingId[..^wagging.Suffix.Length]; + } + else + { + newMarkingId = currentMarkingId; + Log.Warning($"Unable to revert wagging for {currentMarkingId}"); + } + } + + if (!_prototype.HasIndex(newMarkingId)) + { + Log.Warning($"{ToPrettyString(uid)} tried toggling wagging but {newMarkingId} marking doesn't exist"); + continue; + } + + _humanoidAppearance.SetMarkingId(uid, MarkingCategories.Tail, idx, newMarkingId, + humanoid: humanoid); + } + + var emoteText = Loc.GetString(wagging.Wagging ? "wagging-emote-start" : "wagging-emote-stop", ("ent", uid)); + _chat.TrySendInGameICMessage(uid, emoteText, InGameICChatType.Emote, ChatTransmitRange.Normal); // Ok while emotes dont have radial menu + + return true; + } +} diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 4323a46114..fc7af4a408 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -562,7 +562,7 @@ public abstract class SharedActionsSystem : EntitySystem /// Action entity to add /// The 's action component of /// The action entity prototype id to use if is invalid. - /// The entity that contains/enables this action (e.g., flashlight).. + /// The entity that contains/enables this action (e.g., flashlight). public bool AddAction(EntityUid performer, [NotNullWhen(true)] ref EntityUid? actionId, string? actionPrototypeId, diff --git a/Content.Shared/Wagging/WaggingComponent.cs b/Content.Shared/Wagging/WaggingComponent.cs new file mode 100644 index 0000000000..76881827dd --- /dev/null +++ b/Content.Shared/Wagging/WaggingComponent.cs @@ -0,0 +1,33 @@ +using Content.Shared.Chat.Prototypes; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Wagging; + +/// +/// An emoting wag for markings. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class WaggingComponent : Component +{ + [DataField] + public EntProtoId Action = "ActionToggleWagging"; + + [DataField] + public EntityUid? ActionEntity; + + [DataField] + public ProtoId EmoteId = "WagTail"; + + /// + /// Suffix to add to get the animated marking. + /// + public string Suffix = "Animated"; + + /// + /// Is the entity currently wagging. + /// + [DataField] + public bool Wagging = false; +} diff --git a/Resources/Locale/en-US/actions/actions/wagging.ftl b/Resources/Locale/en-US/actions/actions/wagging.ftl new file mode 100644 index 0000000000..2fbcb676f4 --- /dev/null +++ b/Resources/Locale/en-US/actions/actions/wagging.ftl @@ -0,0 +1,5 @@ +action-name-toggle-wagging = Wagging Tail +action-description-toggle-wagging = Start or stop wagging tail. + +wagging-emote-start = starts wagging {POSS-ADJ($ent)} tail. +wagging-emote-stop = stops wagging {POSS-ADJ($ent)} tail. \ No newline at end of file diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml index f301589879..3c7597f14e 100644 --- a/Resources/Prototypes/Actions/types.yml +++ b/Resources/Prototypes/Actions/types.yml @@ -315,3 +315,15 @@ event: !type:ToggleEyesActionEvent useDelay: 1 # so u cant give yourself and observers eyestrain by rapidly spamming the action +- type: entity + id: ActionToggleWagging + name: action-name-toggle-wagging + description: action-description-toggle-wagging + noSpawn: true + components: + - type: InstantAction + icon: { sprite: Mobs/Customization/reptilian_parts.rsi, state: tail_smooth_behind } + iconOn: { sprite: Mobs/Customization/reptilian_parts.rsi, state: tail_smooth_behind } + itemIconStyle: NoItem + useDelay: 1 # emote spam + event: !type:ToggleActionEvent diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml index 81827adb8d..7183472596 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml @@ -280,7 +280,7 @@ sprites: - sprite: Mobs/Customization/reptilian_parts.rsi state: horns_kobold_ears - + - type: marking id: LizardHornsFloppyKoboldEars bodyPart: HeadSide @@ -307,3 +307,40 @@ sprites: - sprite: Mobs/Customization/reptilian_parts.rsi state: body_backspikes + +# Animated +- type: marking + id: LizardTailSmoothAnimated + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [] + sprites: + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_smooth_wagging + +- type: marking + id: LizardTailSpikesAnimated + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [] + sprites: + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_spikes_wagging + +- type: marking + id: LizardTailLTigerAnimated + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [] + sprites: + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_ltiger_wagging + +- type: marking + id: LizardTailDTigerAnimated + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [] + sprites: + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_dtiger_wagging diff --git a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml index 48204ca7c4..604f6411fe 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/reptilian.yml @@ -59,6 +59,7 @@ heatDamage: types: Heat : 1.5 #per second, scales with temperature & other constants + - type: Wagging - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Voice/tail_emotes.yml b/Resources/Prototypes/Voice/tail_emotes.yml new file mode 100644 index 0000000000..610a2ea801 --- /dev/null +++ b/Resources/Prototypes/Voice/tail_emotes.yml @@ -0,0 +1,14 @@ +- type: emote + id: WagTail + chatMessages: [wags tail] + chatTriggers: + - wag + - wag. + - wags + - wags. + - wagging + - wagging. + - wag tail + - wag tail. + - wags tail + - wags tail. diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json index 763e212529..1c4c1a2fbc 100644 --- a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json +++ b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "https://github.com/Skyrat-SS13/Skyrat-tg/tree/40e3cdbb15b8bc0d5ef2fb46133adf805bda5297, while Argali, Ayrshire, Myrsore and Bighorn are drawn by Ubaser, and Kobold Ears are drawn by Pigeonpeas. Body_underbelly made by Nairod(github) for SS14. Large is drawn by Ubaser.", + "copyright": "https://github.com/Skyrat-SS13/Skyrat-tg/tree/40e3cdbb15b8bc0d5ef2fb46133adf805bda5297, while Argali, Ayrshire, Myrsore and Bighorn are drawn by Ubaser, and Kobold Ears are drawn by Pigeonpeas. Body_underbelly made by Nairod(github) for SS14. Large drawn by Ubaser. Wagging tail by SonicDC.", "size": { "x": 32, "y": 32 @@ -67,6 +67,318 @@ "name": "tail_ltiger", "directions": 4 }, + { + "name": "tail_smooth_wagging", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "tail_dtiger_wagging", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "tail_ltiger_wagging", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "tail_spikes_wagging", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, { "name": "snout_round", "directions": 4 diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_dtiger_wagging.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_dtiger_wagging.png new file mode 100644 index 0000000000000000000000000000000000000000..889b0078dcadddcca71fd89e15e1455d99f2477f GIT binary patch literal 5311 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 UA6x^sQV(8cm#-Ta8@fIE9~hkv4gdfE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_ltiger_wagging.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_ltiger_wagging.png new file mode 100644 index 0000000000000000000000000000000000000000..87ec63ed3a3276d2ee5a447d6a05624c19094aec GIT binary patch literal 5283 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 Dicn-+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_spikes_wagging.png b/Resources/Textures/Mobs/Customization/reptilian_parts.rsi/tail_spikes_wagging.png new file mode 100644 index 0000000000000000000000000000000000000000..faad0cf6a9f056498fd5193941fa4e644b9ec2f8 GIT binary patch literal 5335 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 literal 0 HcmV?d00001 -- 2.51.2