diff --git a/Content.Shared/Item/ItemToggle/ComponentTogglerSystem.cs b/Content.Shared/Item/ItemToggle/ComponentTogglerSystem.cs index f483b8a2ee2..4d7ed9de33a 100644 --- a/Content.Shared/Item/ItemToggle/ComponentTogglerSystem.cs +++ b/Content.Shared/Item/ItemToggle/ComponentTogglerSystem.cs @@ -1,12 +1,15 @@ using Content.Shared.Item.ItemToggle.Components; +using Robust.Shared.Timing; namespace Content.Shared.Item.ItemToggle; /// /// Handles component manipulation. /// -public sealed class ComponentTogglerSystem : EntitySystem +public sealed partial class ComponentTogglerSystem : EntitySystem { + [Dependency] private IGameTiming _timing = default!; // LuaM: predict err fix + public override void Initialize() { base.Initialize(); @@ -22,14 +25,32 @@ private void OnToggled(Entity ent, ref ItemToggledEve // Goobstation - Make this system more flexible public void ToggleComponent(EntityUid uid, bool activate) { - if (!TryComp(uid, out var component)) + if (!_timing.IsFirstTimePredicted) // LuaM: predict err fix return; - var target = component.Parent ? Transform(uid).ParentUid : uid; + if (!TryComp(uid, out var component)) + return; + // LuaM-start: add target for the correct remove component, in o.w. - wizden logic if (activate) + { + var target = component.Parent ? Transform(uid).ParentUid : uid; + if (TerminatingOrDeleted(target)) + return; + + component.Target = target; EntityManager.AddComponents(target, component.Components); + } else - EntityManager.RemoveComponents(target, component.RemoveComponents ?? component.Components); + { + if (component.Target == null) + return; + + if (TerminatingOrDeleted(component.Target.Value)) + return; + + EntityManager.RemoveComponents(component.Target.Value, component.RemoveComponents ?? component.Components); + } + // LuaM-end } } diff --git a/Content.Shared/Item/ItemToggle/Components/ComponentTogglerComponent.cs b/Content.Shared/Item/ItemToggle/Components/ComponentTogglerComponent.cs index 20ef0a02315..cecdb4dc772 100644 --- a/Content.Shared/Item/ItemToggle/Components/ComponentTogglerComponent.cs +++ b/Content.Shared/Item/ItemToggle/Components/ComponentTogglerComponent.cs @@ -29,4 +29,10 @@ public sealed partial class ComponentTogglerComponent : Component /// [DataField] public bool Parent; + + // + // It holds the entity that the component gave the component to, so it can remove from it even if it changes parent. + // + [DataField] + public EntityUid? Target; } diff --git a/Content.Shared/_Goobstation/Clothing/Systems/ClothingGrantingSystem.cs b/Content.Shared/_Goobstation/Clothing/Systems/ClothingGrantingSystem.cs index c8661b8ddd2..8534badc6a7 100644 --- a/Content.Shared/_Goobstation/Clothing/Systems/ClothingGrantingSystem.cs +++ b/Content.Shared/_Goobstation/Clothing/Systems/ClothingGrantingSystem.cs @@ -3,13 +3,16 @@ using Content.Shared.Inventory.Events; using Content.Shared.Tag; using Robust.Shared.Serialization.Manager; +using Robust.Shared.Timing; // LuaM using YamlDotNet.Core.Tokens; namespace Content.Shared._Goobstation.Clothing.Systems; + public sealed partial class ClothingGrantingSystem : EntitySystem { [Dependency] private ISerializationManager _serializationManager = default!; [Dependency] private TagSystem _tagSystem = default!; + [Dependency] private IGameTiming _timing = default!; // LuaM: predict err fix public override void Initialize() { @@ -25,6 +28,9 @@ public override void Initialize() // Monolith Cleanup - Below private void OnCompEquip(EntityUid uid, ClothingGrantComponentComponent component, GotEquippedEvent args) { + if (!_timing.IsFirstTimePredicted) // LuaM: predict err fix + return; + if (!TryComp(uid, out var clothing)) return; @@ -33,7 +39,7 @@ private void OnCompEquip(EntityUid uid, ClothingGrantComponentComponent componen foreach (var (name, data) in component.Components) { - var newComp = (Component) Factory.GetComponent(name); + var newComp = (Component)Factory.GetComponent(name); if (HasComp(args.Equipee, newComp.GetType())) continue; @@ -48,12 +54,15 @@ private void OnCompEquip(EntityUid uid, ClothingGrantComponentComponent componen private void OnCompUnequip(EntityUid uid, ClothingGrantComponentComponent component, GotUnequippedEvent args) { + if (!_timing.IsFirstTimePredicted) // LuaM: predict err fix + return; + foreach (var (name, _) in component.Components) { if (!component.Active.TryGetValue(name, out _)) continue; - var newComp = (Component) Factory.GetComponent(name); + var newComp = (Component)Factory.GetComponent(name); RemComp(args.Equipee, newComp.GetType()); component.Active[name] = false; @@ -63,6 +72,9 @@ private void OnCompUnequip(EntityUid uid, ClothingGrantComponentComponent compon private void OnTagEquip(EntityUid uid, ClothingGrantTagComponent component, GotEquippedEvent args) { + if (!_timing.IsFirstTimePredicted) // LuaM: predict err fix + return; + if (!TryComp(uid, out var clothing)) return; @@ -77,6 +89,9 @@ private void OnTagEquip(EntityUid uid, ClothingGrantTagComponent component, GotE private void OnTagUnequip(EntityUid uid, ClothingGrantTagComponent component, GotUnequippedEvent args) { + if (!_timing.IsFirstTimePredicted) // LuaM: predict err fix + return; + if (!component.IsActive) return; diff --git a/Content.Shared/_LuaM/Containers/OutOfContainerGrantComponent.cs b/Content.Shared/_LuaM/Containers/OutOfContainerGrantComponent.cs new file mode 100644 index 00000000000..897cca0bc60 --- /dev/null +++ b/Content.Shared/_LuaM/Containers/OutOfContainerGrantComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared._LuaM.Container.Components +{ + /// + /// Grants the listed components to entity if it NOT inside any container + /// for example: brain has Blip if he not in the containers (other words, brain in space) + /// + [RegisterComponent] + public sealed partial class OutOfContainerGrantComponent : Component + { + [DataField(required: true)] + [AlwaysPushInheritance] + public ComponentRegistry Components { get; private set; } = new(); + + [ViewVariables(VVAccess.ReadWrite)] + public Dictionary Active = new(); + } +} diff --git a/Content.Shared/_LuaM/Containers/OutOfContainerGrantSystem.cs b/Content.Shared/_LuaM/Containers/OutOfContainerGrantSystem.cs new file mode 100644 index 00000000000..a2e7b41a4c3 --- /dev/null +++ b/Content.Shared/_LuaM/Containers/OutOfContainerGrantSystem.cs @@ -0,0 +1,78 @@ +using Content.Shared._LuaM.Container.Components; +using Robust.Shared.Containers; +using Robust.Shared.Serialization.Manager; + +namespace Content.Shared._LuaM.Container.Systems; // idk how name that. + +// A simple system that add components to entity if he not inside a container +// Following the example of goob +public sealed partial class OutOfContainerGrantSystem : EntitySystem // this name is suck, i know +{ + [Dependency] private readonly ISerializationManager _serializationManager = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + + SubscribeLocalEvent(OnContainerChanged); + SubscribeLocalEvent(OnContainerChanged); + } + + private void OnStartup(EntityUid uid, OutOfContainerGrantComponent component, ComponentStartup args) + { + UpdateComp(uid, component); + } + + private void OnContainerChanged(EntityUid uid, OutOfContainerGrantComponent component, EntityEventArgs args) + { + UpdateComp(uid, component); + } + + private void UpdateComp(EntityUid uid, OutOfContainerGrantComponent component) + { + if (_container.IsEntityInContainer(uid)) + RemoveComp(uid, component); + else + AddComp(uid, component); + } + + private void AddComp(EntityUid uid, OutOfContainerGrantComponent component) + { + foreach (var (name, data) in component.Components) + { + if (component.Active.TryGetValue(name, out var active) && active) + continue; + + var newComp = (Component)Factory.GetComponent(name); + + if (HasComp(uid, newComp.GetType())) + { + component.Active[name] = true; + continue; + } + + object? temp = newComp; + _serializationManager.CopyTo(data.Component, ref temp); + EntityManager.AddComponent(uid, (Component)temp!); + + component.Active[name] = true; + } + } + + private void RemoveComp(EntityUid uid, OutOfContainerGrantComponent component) + { + foreach (var (name, _) in component.Components) + { + if (!component.Active.TryGetValue(name, out var active) || !active) + continue; + + var newComp = (Component)Factory.GetComponent(name); + RemComp(uid, newComp.GetType()); + + component.Active[name] = false; + } + } +} diff --git a/Resources/Prototypes/Body/Organs/diona.yml b/Resources/Prototypes/Body/Organs/diona.yml index 1f0a2821089..0b843b3074d 100644 --- a/Resources/Prototypes/Body/Organs/diona.yml +++ b/Resources/Prototypes/Body/Organs/diona.yml @@ -55,6 +55,21 @@ reagents: - ReagentId: GreyMatter Quantity: 5 + - type: OutOfContainerGrant # LuaM + components: + - type: RadarBlip + radarColor: "#E0FFFF" + scale: 3 + shape: Star + maxDistance: 512 + requireNoGrid: true + visibleFromOtherGrids: true + gridConfig: + color: "#E0FFFF" + shape: Star + respectZoom: true + rotate: true + bounds: "-0.5,-0.5,0.5,0.5" - type: entity id: OrganDionaEyes diff --git a/Resources/Prototypes/Body/Organs/human.yml b/Resources/Prototypes/Body/Organs/human.yml index 06cfeb643f7..3bca1602744 100644 --- a/Resources/Prototypes/Body/Organs/human.yml +++ b/Resources/Prototypes/Body/Organs/human.yml @@ -97,17 +97,21 @@ - type: Item size: Small heldPrefix: brain -# - type: RadarBlip # LuaM -# radarColor: "#E0FFFF" -# scale: 6 -# shape: Star -# visibleFromOtherGrids: true -# gridConfig: -# color: "#E0FFFF" -# shape: Star -# respectZoom: true -# rotate: true -# bounds: "-0.5,-0.5,0.5,0.5" + - type: OutOfContainerGrant # LuaM + components: + - type: RadarBlip + radarColor: "#E0FFFF" + scale: 3 + shape: Star + maxDistance: 512 + requireNoGrid: true + visibleFromOtherGrids: true + gridConfig: + color: "#E0FFFF" + shape: Star + respectZoom: true + rotate: true + bounds: "-0.5,-0.5,0.5,0.5" - type: entity id: OrganHumanEyes