diff --git a/Content.Client/_White/FluffColorForClothing/FluffColorForClothingSystem.cs b/Content.Client/_White/FluffColorForClothing/FluffColorForClothingSystem.cs new file mode 100644 index 0000000000..a17cd1b50e --- /dev/null +++ b/Content.Client/_White/FluffColorForClothing/FluffColorForClothingSystem.cs @@ -0,0 +1,32 @@ +using Content.Shared.Clothing.Components; +using Content.Shared.Clothing.EntitySystems; +using Content.Shared.Item; +using Robust.Client.GameObjects; + +namespace Content.Shared._White.FluffColorForClothing; + +public sealed class FluffColorForClothingSystem : SharedFluffColorForClothingSystem +{ + [Dependency] private readonly ClothingSystem _clothingSystem = default!; + [Dependency] private readonly SharedItemSystem _itemSystem = default!; + + protected override void UpdateVisuals(EntityUid uid, FluffColorForClothingComponent component) + { + if (!TryComp(uid, out SpriteComponent? sprite)) + return; + + var state = sprite.LayerGetState(0).Name; + if (state == null) + return; + + var prefix = state.Substring(0, state.IndexOf('_')); + sprite.LayerSetState(0, $"{prefix}_{component.CurrentColor}"); + + if (TryComp(uid, out var clothingComp)) + _clothingSystem.SetEquippedPrefix(uid, component.CurrentColor, clothingComp); + + if (TryComp(uid, out var itemComp)) + _itemSystem.SetHeldPrefix(uid, component.CurrentColor, false, itemComp); + } + +} diff --git a/Content.Server/_White/FluffColorForClothing/FluffColorForClothingSystem.cs b/Content.Server/_White/FluffColorForClothing/FluffColorForClothingSystem.cs new file mode 100644 index 0000000000..536ac5a427 --- /dev/null +++ b/Content.Server/_White/FluffColorForClothing/FluffColorForClothingSystem.cs @@ -0,0 +1,57 @@ +using System.Linq; +using Content.Shared.Inventory; +using Robust.Shared.Containers; + +namespace Content.Shared._White.FluffColorForClothing; + +public sealed class FluffColorForClothingSystem : SharedFluffColorForClothingSystem +{ + [Dependency] private readonly InventorySystem _inventory = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + + private string GetNextColor(FluffColorForClothingComponent component) + { + var index = component.Colors.IndexOf(component.CurrentColor); + var count = component.Colors.Count; + if (index < count - 1) + index++; + else + index = 0; + + var newColor = component.Colors[index]; + + return newColor; + } + + protected override void ChangeColor(EntityUid uid, FluffColorForClothingComponent component) + { + if (component.User != null && _inventory.TryGetContainerSlotEnumerator((EntityUid) component.User, out var containerSlotEnumerator)) + { + while (containerSlotEnumerator.NextItem(out var item, out var _)) + { + if (TryComp(item, out var comp) && !comp.MainItem) + { + comp.CurrentColor = GetNextColor(comp); + Dirty(item, comp); + } + } + } + ChangeCompInside(component); + component.CurrentColor = GetNextColor(component); + Dirty(uid, component); + } + + private void ChangeCompInside(FluffColorForClothingComponent component) + { + if (_container.TryGetContainer(component.Owner, "toggleable-clothing", out var container) && container.ContainedEntities.Any()) + { + var content = container.ContainedEntities.First(); + if (TryComp(content, out var contentComp) && component.Specifier == contentComp.Specifier) + { + contentComp.CurrentColor = GetNextColor(contentComp); + Dirty(contentComp.Owner, contentComp); + } + + } + } +} diff --git a/Content.Shared/_White/FluffColorForClothing/FluffColorForClothingComponent.cs b/Content.Shared/_White/FluffColorForClothing/FluffColorForClothingComponent.cs new file mode 100644 index 0000000000..d08ec90560 --- /dev/null +++ b/Content.Shared/_White/FluffColorForClothing/FluffColorForClothingComponent.cs @@ -0,0 +1,39 @@ +using Content.Shared.Inventory; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared._White.FluffColorForClothing; + +[RegisterComponent, NetworkedComponent] +[AutoGenerateComponentState(true)] +public sealed partial class FluffColorForClothingComponent : Component +{ + [DataField, AutoNetworkedField] + public EntProtoId Action = "ActionFluffColorForClothing"; + + [DataField, AutoNetworkedField] + public EntityUid? ActionEntity; + + [DataField] + [AutoNetworkedField] + public string CurrentColor = "white"; + + [DataField] + public List Colors = new() { "white" }; + + [DataField] + public string VerbText = "Поменять цвет"; + + [DataField] + public string Specifier = "default"; + + [DataField] + public bool MainItem = false; + + [DataField] + public EntityUid? User; + + [DataField("requiredSlot"), AutoNetworkedField] + public SlotFlags RequiredFlags = SlotFlags.NECK; + +} diff --git a/Content.Shared/_White/FluffColorForClothing/SharedFluffColorForClothingSystem.cs b/Content.Shared/_White/FluffColorForClothing/SharedFluffColorForClothingSystem.cs new file mode 100644 index 0000000000..1737584e16 --- /dev/null +++ b/Content.Shared/_White/FluffColorForClothing/SharedFluffColorForClothingSystem.cs @@ -0,0 +1,104 @@ +using Content.Shared.Actions; +using Content.Shared.Inventory.Events; +using Content.Shared.Verbs; +using Robust.Shared.Utility; + +namespace Content.Shared._White.FluffColorForClothing; + +public abstract class SharedFluffColorForClothingSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + [Dependency] private readonly ActionContainerSystem _actionContainer = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent>(OnAddVerb); + SubscribeLocalEvent(OnAfterHandleState); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnequipped); + SubscribeLocalEvent(OnEvent); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnGetActions); + SubscribeLocalEvent(OnRemove); + } + + private void OnRemove(Entity ent, ref ComponentRemove args) + { + _actionsSystem.RemoveAction(ent.Comp.ActionEntity); + } + + private void OnGetActions(Entity ent, ref GetItemActionsEvent args) + { + if (ent.Comp.ActionEntity != null && args.SlotFlags == ent.Comp.RequiredFlags) + args.AddAction(ent.Comp.ActionEntity.Value); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (_actionContainer.EnsureAction(ent.Owner, ref ent.Comp.ActionEntity, out var action, ent.Comp.Action)) + _actionsSystem.SetEntityIcon(ent.Comp.ActionEntity.Value, ent.Owner, action); + } + + private void OnEvent(Entity ent, ref FluffColorForClothingEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + ChangeColor(ent.Owner, ent.Comp); + } + + private void OnUnequipped(EntityUid uid, FluffColorForClothingComponent component, GotUnequippedEvent args) + { + component.User = null; + } + + private void OnEquipped(EntityUid uid, FluffColorForClothingComponent component, GotEquippedEvent args) + { + component.User = args.Equipee; + } + + private void OnAfterHandleState(EntityUid uid, FluffColorForClothingComponent component, ref AfterAutoHandleStateEvent args) + { + UpdateVisuals(uid, component); + } + + private void OnInit(EntityUid uid, FluffColorForClothingComponent component, ComponentInit args) + { + UpdateVisuals(uid, component); + } + + private void OnAddVerb(EntityUid uid, FluffColorForClothingComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || args.Hands == null || component.Colors.Count < 2 || !component.MainItem) + return; + + AlternativeVerb verb = new() + { + EventTarget = uid, + ExecutionEventArgs = new FluffColorForClothingEvent() { Performer = args.User }, + Text = component.VerbText, + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/rotate_cw.svg.192dpi.png")), + Priority = 0, + }; + + args.Verbs.Add(verb); + } + + protected virtual void UpdateVisuals(EntityUid uid, FluffColorForClothingComponent component) + { + // See client system + } + + protected virtual void ChangeColor(EntityUid uid, FluffColorForClothingComponent component) + { + // See server system + } +} + +public sealed partial class FluffColorForClothingEvent : InstantActionEvent +{ +} diff --git a/Resources/Prototypes/_White/Fluff/vkuser.yml b/Resources/Prototypes/_White/Fluff/vkuser.yml new file mode 100644 index 0000000000..89de8781d0 --- /dev/null +++ b/Resources/Prototypes/_White/Fluff/vkuser.yml @@ -0,0 +1,66 @@ +- type: entity + parent: ClothingNeckBase + id: ClothingNeckCloakRaincoat + name: прародительский плащ + suffix: fluff + components: + - type: ToggleableClothing + clothingPrototype: ClothingHeadHatHoodRaincoat + requiredSlot: NECK + - type: ContainerContainer + containers: + toggleable-clothing: !type:ContainerSlot {} + storagebase: !type:Container + ents: [] + slot: head + - type: Clothing + sprite: White/Fluff/vkuser/raincoat.rsi + - type: Sprite + sprite: White/Fluff/vkuser/raincoat.rsi + state: icon_green + - type: Appearance + - type: FluffColorForClothing + mainItem: true + specifier: Raincoat + currentColor: green + colors: + - green + - red + - type: Tag + tags: + - ClothMade + +- type: entity + parent: ClothingHeadBase + id: ClothingHeadHatHoodRaincoat + noSpawn: true + name: прародительский капюшон + suffix: fluff + components: + - type: Sprite + sprite: White/Fluff/vkuser/hoodraincoat.rsi + state: icon_green + - type: Clothing + sprite: White/Fluff/vkuser/hoodraincoat.rsi + - type: Tag + tags: [] # ignore "WhitelistChameleon" tag + - type: HideLayerClothing + slots: + - Hair + - type: FluffColorForClothing + specifier: Raincoat + currentColor: green + colors: + - green + - red + +- type: entity + id: ActionFluffColorForClothing + name: Поменять цвет + description: Меняет цвет вашей экипировки. + noSpawn: true + components: + - type: InstantAction + itemIconStyle: BigItem + useDelay: 1 + event: !type:FluffColorForClothingEvent diff --git a/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/green-equipped-HELMET.png b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/green-equipped-HELMET.png new file mode 100644 index 0000000000..5a715fbfb1 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/green-equipped-HELMET.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/icon_green.png b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/icon_green.png new file mode 100644 index 0000000000..3cbcacbc86 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/icon_green.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/icon_red.png b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/icon_red.png new file mode 100644 index 0000000000..215aa4b15e Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/icon_red.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/meta.json b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/meta.json new file mode 100644 index 0000000000..eeb91813c4 --- /dev/null +++ b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/meta.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "license": "CC-BY-SA-4.0", + "copyright": "Archestratigus АКА Заступник", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon_green" + }, + { + "name": "icon_red" + }, + { + "name": "green-equipped-HELMET", + "directions": 4 + }, + { + "name": "red-equipped-HELMET", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/red-equipped-HELMET.png b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/red-equipped-HELMET.png new file mode 100644 index 0000000000..f69eee0855 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/hoodraincoat.rsi/red-equipped-HELMET.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-equipped-NECK.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-equipped-NECK.png new file mode 100644 index 0000000000..8c13c0420e Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-equipped-NECK.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-inhand-left.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-inhand-left.png new file mode 100644 index 0000000000..ca08a6997a Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-inhand-left.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-inhand-right.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-inhand-right.png new file mode 100644 index 0000000000..23a29aa671 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/green-inhand-right.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/icon_green.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/icon_green.png new file mode 100644 index 0000000000..975bd8a9d0 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/icon_green.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/icon_red.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/icon_red.png new file mode 100644 index 0000000000..9f5ae23938 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/icon_red.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/meta.json b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/meta.json new file mode 100644 index 0000000000..a439ebed3a --- /dev/null +++ b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/meta.json @@ -0,0 +1,173 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Archestratigus АКА Заступник", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "green-inhand-left", + "directions": 4 + }, + { + "name": "red-inhand-left", + "directions": 4 + }, + { + "name": "green-inhand-right", + "directions": 4 + }, + { + "name": "red-inhand-right", + "directions": 4 + }, + { + "name": "icon_green" + }, + { + "name": "icon_red" + }, + { + "name": "red-equipped-NECK", + "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 + ] + ] + }, + { + "name": "green-equipped-NECK", + "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 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-equipped-NECK.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-equipped-NECK.png new file mode 100644 index 0000000000..347940d405 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-equipped-NECK.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-inhand-left.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-inhand-left.png new file mode 100644 index 0000000000..a142ee02c9 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-inhand-left.png differ diff --git a/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-inhand-right.png b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-inhand-right.png new file mode 100644 index 0000000000..4c9995dfb4 Binary files /dev/null and b/Resources/Textures/White/Fluff/vkuser/raincoat.rsi/red-inhand-right.png differ