From 54e453628790ea2fbdc4ad7d0e8b10ef32a9201d Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Mon, 20 Jan 2025 20:33:21 +0100 Subject: [PATCH 01/14] Allow sorting into teams --- .../NpcFactionSpriteStateSetterSystem.cs | 28 ++++++++ .../NPC/Systems/NpcFactionSystem.cs | 6 ++ .../NPC/Events/NpcFactionChangedEvent.cs | 25 ++++++++ .../NPC/NpcFactionSelectorComponent.cs | 14 ++++ .../NPC/NpcFactionSelectorSystem.cs | 60 ++++++++++++++++++ .../NpcFactionSpriteStateSetterComponent.cs | 7 ++ Content.Shared/Verbs/VerbCategory.cs | 2 + Resources/Locale/en-US/npc/factions.ftl | 1 + Resources/Locale/en-US/verbs/verb-system.ftl | 2 + .../Prototypes/Recipes/Crafting/bots.yml | 2 +- Resources/Prototypes/ai_factions.yml | 37 +++++++++++ .../Bots/gladiabot.rsi/GladiabotBlue.png | Bin 0 -> 1218 bytes .../{gladiabot.png => GladiabotFFA.png} | Bin .../Bots/gladiabot.rsi/GladiabotGreen.png | Bin 0 -> 1218 bytes .../Bots/gladiabot.rsi/GladiabotRed.png | Bin 0 -> 1218 bytes .../Bots/gladiabot.rsi/GladiabotYellow.png | Bin 0 -> 1218 bytes .../Mobs/Silicon/Bots/gladiabot.rsi/meta.json | 38 ++++++++++- 17 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs create mode 100644 Content.Shared/NPC/Events/NpcFactionChangedEvent.cs create mode 100644 Content.Shared/NPC/NpcFactionSelectorComponent.cs create mode 100644 Content.Shared/NPC/NpcFactionSelectorSystem.cs create mode 100644 Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs create mode 100644 Resources/Locale/en-US/npc/factions.ftl create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotBlue.png rename Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/{gladiabot.png => GladiabotFFA.png} (100%) create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotGreen.png create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotRed.png create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotYellow.png diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs new file mode 100644 index 00000000000..1e57d917bec --- /dev/null +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -0,0 +1,28 @@ + +using Content.Shared.NPC.Components; +using Content.Shared.NPC.Events; +using Robust.Client.GameObjects; +using Robust.Shared.Reflection; + +namespace Content.Client.NPC.Systems; +public sealed partial class NpcFactionSpriteStateSetterSystem : EntitySystem +{ + [Dependency] private readonly SpriteSystem _spriteSystem = default!; + [Dependency] private readonly EntityManager _entityManager = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent<NpcFactionMemberComponent, NpcFactionAddedEvent>(OnFactionAdded); + } + + private void OnFactionAdded(Entity<NpcFactionMemberComponent > entity, ref NpcFactionAddedEvent args) + { + if (!_entityManager.HasComponent(entity, typeof(NpcFactionSpriteStateSetterComponent))) + return; + + SpriteComponent spriteComponent = _entityManager.GetComponent<SpriteComponent>(entity); + spriteComponent.LayerSetState(0, new Robust.Client.Graphics.RSI.StateId(args.FactionID)); + } +} diff --git a/Content.Server/NPC/Systems/NpcFactionSystem.cs b/Content.Server/NPC/Systems/NpcFactionSystem.cs index 663dbac9c77..a8a5121b250 100644 --- a/Content.Server/NPC/Systems/NpcFactionSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.NPC.Events; using System.Collections.Frozen; using System.Linq; using Content.Server.NPC.Components; @@ -76,6 +77,8 @@ public void AddFaction(EntityUid uid, string faction, bool dirty = true) if (!comp.Factions.Add(faction)) return; + RaiseLocalEvent(ent.Owner, new NpcFactionAddedEvent(faction)); + if (dirty) { RefreshFactions(comp); @@ -99,6 +102,9 @@ public void RemoveFaction(EntityUid uid, string faction, bool dirty = true) if (!component.Factions.Remove(faction)) return; + RaiseLocalEvent(ent.Owner, new NpcFactionRemovedEvent(faction)); + + if (dirty) { RefreshFactions(component); diff --git a/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs b/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs new file mode 100644 index 00000000000..dc43017af68 --- /dev/null +++ b/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs @@ -0,0 +1,25 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.NPC.Events; + +/// <summary> +/// Raised from client to server to notify a faction was added to an NPC. +/// </summary> +[Serializable, NetSerializable] +public sealed class NpcFactionAddedEvent : EntityEventArgs +{ + public string FactionID; + + public NpcFactionAddedEvent(string factionId) => FactionID = factionId; +} + +/// <summary> +/// Raised from client to server to notify a faction was removed from an NPC. +/// </summary> +[Serializable, NetSerializable] +public sealed class NpcFactionRemovedEvent : EntityEventArgs +{ + public string FactionID; + + public NpcFactionRemovedEvent(string factionId) => FactionID = factionId; +} diff --git a/Content.Shared/NPC/NpcFactionSelectorComponent.cs b/Content.Shared/NPC/NpcFactionSelectorComponent.cs new file mode 100644 index 00000000000..7eb5701373b --- /dev/null +++ b/Content.Shared/NPC/NpcFactionSelectorComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.NPC.Systems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Shared.NPC.Components; + +[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSelectorSystem))] +public sealed partial class NpcFactionSelectorComponent : Component +{ + [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))] + public List<string> SelectableFactions = new(); +} + diff --git a/Content.Shared/NPC/NpcFactionSelectorSystem.cs b/Content.Shared/NPC/NpcFactionSelectorSystem.cs new file mode 100644 index 00000000000..c3fef47da47 --- /dev/null +++ b/Content.Shared/NPC/NpcFactionSelectorSystem.cs @@ -0,0 +1,60 @@ +using Content.Shared.Database; +using Content.Shared.NPC.Components; +using Content.Shared.NPC.Prototypes; +using Content.Shared.Popups; +using Content.Shared.Verbs; +using Robust.Shared.Prototypes; +using System.Linq; + +namespace Content.Shared.NPC.Systems; +public sealed partial class NpcFactionSelectorSystem : EntitySystem +{ + + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly NpcFactionSystem _factionSystem = default!; + [Dependency] private readonly EntityManager _entityManager = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent<NpcFactionSelectorComponent, GetVerbsEvent<Verb>>(OnGetVerb); + } + + private void OnGetVerb(Entity<NpcFactionSelectorComponent> entity, ref GetVerbsEvent<Verb> args) + { + if (!args.CanAccess || !args.CanInteract || args.Hands == null) + return; + + NpcFactionSelectorComponent factionSelectorComponent = _entityManager.GetComponent<NpcFactionSelectorComponent>(entity); + + if (factionSelectorComponent.SelectableFactions.Count < 2) + return; + + foreach (var type in factionSelectorComponent.SelectableFactions) + { + var proto = _prototype.Index<NpcFactionPrototype>(type); + + var v = new Verb + { + Priority = 1, + Category = VerbCategory.SelectFaction, + Text = proto.ID, + Impact = LogImpact.Medium, + DoContactInteraction = true, + Act = () => + { + _popup.PopupPredicted(Loc.GetString("npcfaction-component-faction-set", ("faction", proto.ID)), entity.Owner, null); + foreach (var type in factionSelectorComponent.SelectableFactions) + { + _factionSystem.RemoveFaction(entity.Owner, type); + } + + _factionSystem.AddFaction(entity.Owner, proto.ID); + } + }; + args.Verbs.Add(v); + } + } +} diff --git a/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs b/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs new file mode 100644 index 00000000000..ec5d66ff03e --- /dev/null +++ b/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs @@ -0,0 +1,7 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.NPC.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class NpcFactionSpriteStateSetterComponent : Component {} + diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index 2d2a6044dfc..97ddb5c5cde 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -84,6 +84,8 @@ public VerbCategory(string text, string? icon, bool iconsOnly = false) public static readonly VerbCategory SelectType = new("verb-categories-select-type", null); + public static readonly VerbCategory SelectFaction = new("verb-categories-select-faction", null); + public static readonly VerbCategory PowerLevel = new("verb-categories-power-level", null); public static readonly VerbCategory Interaction = new("verb-categories-interaction", null); diff --git a/Resources/Locale/en-US/npc/factions.ftl b/Resources/Locale/en-US/npc/factions.ftl new file mode 100644 index 00000000000..8aaa2b6e8f3 --- /dev/null +++ b/Resources/Locale/en-US/npc/factions.ftl @@ -0,0 +1 @@ +npcfaction-component-faction-set = Faction set to: {$faction} diff --git a/Resources/Locale/en-US/verbs/verb-system.ftl b/Resources/Locale/en-US/verbs/verb-system.ftl index dfb4e621dca..d579f045c5f 100644 --- a/Resources/Locale/en-US/verbs/verb-system.ftl +++ b/Resources/Locale/en-US/verbs/verb-system.ftl @@ -26,9 +26,11 @@ verb-categories-set-sensor = Sensor verb-categories-timer = Set Delay verb-categories-lever = Lever verb-categories-select-type = Select Type +verb-categories-select-faction = Select Faction verb-categories-fax = Set Destination verb-categories-power-level = Power Level verb-categories-interaction = Interact +verb-categories-blood-cult = Blood Cult verb-common-toggle-light = Toggle light verb-common-close = Close diff --git a/Resources/Prototypes/Recipes/Crafting/bots.yml b/Resources/Prototypes/Recipes/Crafting/bots.yml index 64106f663f1..8f67905b85b 100644 --- a/Resources/Prototypes/Recipes/Crafting/bots.yml +++ b/Resources/Prototypes/Recipes/Crafting/bots.yml @@ -87,4 +87,4 @@ description: This bot fights for honour and glory! icon: sprite: Mobs/Silicon/Bots/gladiabot.rsi - state: gladiabot + state: GladiabotFFA diff --git a/Resources/Prototypes/ai_factions.yml b/Resources/Prototypes/ai_factions.yml index 0e66069f15d..fef9c2bd7f8 100644 --- a/Resources/Prototypes/ai_factions.yml +++ b/Resources/Prototypes/ai_factions.yml @@ -131,3 +131,40 @@ id: GladiabotFFA hostile: - GladiabotFFA + - GladiabotRed + - GladiabotGreen + - GladiabotBlue + - GladiabotYellow + +- type: npcFaction + id: GladiabotRed + hostile: + - GladiabotFFA + - GladiabotGreen + - GladiabotBlue + - GladiabotYellow + +- type: npcFaction + id: GladiabotGreen + hostile: + - GladiabotFFA + - GladiabotRed + - GladiabotBlue + - GladiabotYellow + +- type: npcFaction + id: GladiabotBlue + hostile: + - GladiabotFFA + - GladiabotRed + - GladiabotGreen + - GladiabotYellow + +- type: npcFaction + id: GladiabotYellow + hostile: + - GladiabotFFA + - GladiabotRed + - GladiabotGreen + - GladiabotBlue + diff --git a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotBlue.png b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotBlue.png new file mode 100644 index 0000000000000000000000000000000000000000..800edcb860771b5198492675364c8834177e7c08 GIT binary patch literal 1218 zcmeAS@N?(olHy`uVBq!ia0vp^3P9|@!3-pQ0$S%VFfg`eIy(n=Iy)-_6y>L7=A<$( zXq=xq(c0s1fJoc_WnD_4g4P`+Cj#c`bm+^dcDZf{xW%>BYQ~)}tiDo{M8w?>Zhi0| zdE=`GkJhYiUai1k=WvHr-Bn!k<DDfJltMlncv|=8`#<~V^SC*-3SC~)SLkp#*I01s zk&?8~H&w0twGszRoQyX2L=+jeZu?s5zkTI9B^&PltK&?w4G*Xboi{wZrPI74-7L5H zvt8i?(Uhq_=2V<n!qzFjb6v%sW0vnX9WZWA(=zmzQ4#yByJm}l_6(_yB83rGOHPSj zl3P7zyG8a=uIw)-<0VeK()L_;nM<)t^@u<_2dk(^U{f#0TPsa5p%T5VANhCxv)Cz8 zBzo|~#s(vk6YJ#v@YkKccFNbU!jqBnMNQ$He!&IV;w!>spZ~s5_)5LuzvPZfv;P(G z&iJdc_tup|?hgOW3JULDnPU5(h+U$}C?&W|)m~R|I`h5rFJ>DZc%XY>^Ru&S3;Qm! zE4Xfs+Q-Pp*Lcw;b^Z3r^77Yr{_S~uj{g$>My{d*+D{*YVkk4fC&X1s)>K)|-NmcZ z!lvNyyUz<Z?=PJ&GqGuAK==Y5FRy8nTi3RP+`e_bEID~$W8<_UPjd@14V}Q5C0;Y9 zPN}FY+rE8!xwQ1nn>RZ%oXexFtR2dqJ$u%aY+n#+mf>%#YZz^3XID^|2ej?T2QCR9 zrCbu^7yO?fU`W$!o(5FTS>O>_%)r2R1cVu<YV%101tm&cBT9nv(@M${i&7Z^5;OBk z^!!{y6ioFD^^AV+VcrH*(~}zEnda%K#lQjNurf$7vNA9NSzbUa4P}GEK!cGPEY1XE z8!|F62mt9QAkJ)O0gGn=*&x7E&dBfrn3!QSnxzat{S(+3Sb!=GjEoH!7eGw?{~xTG zK{Hb^=d9rEN?<N%_H=O!@$h~-<#t(<fq<(q+by>I3tFKUl0N^JziDi2=zAjQ_pNn# zF->R8IHwyQvwy(P)h6VmDthLSn$DIfTvNDJ)Ym(OhL*RkS~ve4XXsxYCpV>xyO+J$ zEX7;gUfadQAJI*8h%miTp|EM%wbx(Mn)PLNKMiADw|&L-l$G5RO4q+T`%+|e+4Wy# z?%Qs=?{axi|9->93*X-_c>jH_wTy5h@0vu3z$xb~c3f5zwFx`e#KXXP=;IVl2ls$u z2Y2Ogv1LEdWMI+x6vHK=$N0d={#=#3l1c4-j!nXe9We%%U4j|d)$F=YEDq<3vC}`< zH<Qy&Bx$bz*FV;$?M&{|>sy|ywCq3Sx2XGZ^j}4n&t<#hxfaH8{qb_l$U2*MQ{LiU z+u^leH`y2L;cb`RD4f`~Wcu<9iy1mk{wi`Yu+8|+-npI2;J_Yxk3G!~N?W$rE9{YZ zzxu$Fzl_-)%LG3CV`zLF+qa<Oz{hi~YwRERi8)=9f3&&d%<twoKCPAY7bbs_{jv1# a!Qc9s5=WA6nR6w9BFEF!&t;ucLK6U?SonMZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/gladiabot.png b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotFFA.png similarity index 100% rename from Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/gladiabot.png rename to Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotFFA.png diff --git a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotGreen.png b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotGreen.png new file mode 100644 index 0000000000000000000000000000000000000000..3e82302e6cfbf6a25805042be647351adddffbc7 GIT binary patch literal 1218 zcmeAS@N?(olHy`uVBq!ia0vp^3P9|@!3-pQ0$S%VFfg`eIy(n=Iy)-_6y>L7=A<$( zXq=xq(c0s1fJoc_WnD_4g4P`+Cj#c`bm+^dcDZf{xW%>BYQ~)}tiDo{M8w?>Zhi0| zdE=`GkJhYiUai1k=WvHr-Bn!k<DDfJltMlncv|=8`#<~V^SC*-3SC~)SLkp#*I01s zk&?8~H&w0twGszRoQyX2L=+jeZu?s5zkTI9B^&PltK&?w4G*Xboi{wZrPI74-7L5H zvt8i?(Uhq_=2V<n!qzFjb6v%sW0vnX9WZWA(=zmzQ4#yByJm}l_6(_yB83rGOHPSj zl3P7zyG8a=uIw)-<0VeK()L_;nM<)t^@u<_2dk(^U{f#0TPsa5p%T5VANhCxv)Cz8 zBzo|~#s(vk6YJ#v@YkKccFNbU!jqBnMNQ$He!&IV;w!>spZ~s5_)5LuzvPZfv;P(G z&iJdc_tup|?hgOW3JULDnPU5(h+U$}C?&W|)m~R|I`h5rFJ>DZc%XY>^Ru&S3;Qm! zE4Xfs+Q-Pp*Lcw;b^Z3r^77Yr{_S~uj{g$>My{d*+D{*YVkk4fC&X3CR94wt&85@J zqQK_yyUz<Z?=PJ&GqGuAz=CieFRy8nTi3RP+`e_bEID~$W8<_UPjd@1jX<55C0;Y9 zPN}FY+rE8!xwQ1nn>RZ%oXexFtjisqJ$u%aY+n#+mf>%#8*ON3XID^|2egeZ#oZf7 zDVGHK1^*`q7}7MGrva677I;J!12rE3VaBQ2e9}Nci4xa{lHmNblJdl&REB`W%)Amk zKi3ciQ$0gHqu+a&w*l4kq(*qAd3tIwZ~!^13{s4&42(dQ7Z6KB*`P4cU}Of1GXdF# zj7$syKspMDGuv6f;#oj82=J6MGQ0pLW*CiTDFaad1a<}%ph^QHV*|zo5L5sE2Ww`~ z%v8)dD|ovSm<yUcT^vI^yx&f_UDjkE;A+fvi!J|xR_KMK&;R9b8XFt>o(TGVYh7MU z(-||)>Bh(GAMkUv2|1~Xo;jqZvt<g`6mAvu^-iIo<*lpM&40%k`d7!vO)2B<Wp6f1 z@fNq&b}{isbQ2vSOm9>uY?^lM_1Cm!eVN@)!&ujCU$H%9W%q>A_3zHU6j@z%{a2a$ zw%hKzTprZF->~t*_xB6lf1hhDBizWlCQ%}A%6W?&mlZ{A!VWg^Ft8r_IEB-}J>b~E zT{&EA*$*@sSad$caEa(KJ}|OBS0%4xQhT3clW<~3jKO7>U<P(IyY3T<!}((D^iTH9 z<g^n>+AF~IkM(Igll%1gmgg!h`%n2T>V6#kSJCBj*)Dmmg>hVeyc{#K&gR{ex474K zc<t9s_62)*+od-OC$=q_zC6QXhR&0}id+nAGrqHTZs#&Mu*cqGPxFJ)mM!)Qdt~0P zKJer(W46aKflvP!8Xw2@E$BG#@m%W~`v-nvPS@lgZSFYpyLpaJYi0d~$)99@Ed6`% Zw|=I?k>p$ETuGqF@pScbS?83{1OR)$_o@H@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotRed.png b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotRed.png new file mode 100644 index 0000000000000000000000000000000000000000..68d0e24929bd221076c1154b9d8d2449a3a5afac GIT binary patch literal 1218 zcmeAS@N?(olHy`uVBq!ia0vp^3P9|@!3-pQ0$S%VFfg`eIy(n=Iy)-_6y>L7=A<$( zXq=xq(c0s1fJoc_WnD_4g4P`+Cj#c`bm+^dcDZf{xW%>BYQ~)}tiDo{M8w?>Zhi0| zdE=`GkJhYiUai1k=WvHr-Bn!k<DDfJltMlncv|=8`#<~V^SC*-3SC~)SLkp#*I01s zk&?8~H&w0twGszRoQyX2L=+jeZu?s5zkTI9B^&PltK&?w4G*Xboi{wZrPI74-7L5H zvt8i?(Uhq_=2V<n!qzFjb6v%sW0vnX9WZWA(=zmzQ4#yByJm}l_6(_yB83rGOHPSj zl3P7zyG8a=uIw)-<0VeK()L_;nM<)t^@u<_2dk(^U{f#0TPsa5p%T5VANhCxv)Cz8 zBzo|~#s(vk6YJ#v@YkKccFNbU!jqBnMNQ$He!&IV;w!>spZ~s5_)5LuzvPZfv;P(G z&iJdc_tup|?hgOW3JULDnPU5(h+U$}C?&W|)m~R|I`h5rFJ>DZc%XY>^Ru&S3;Qm! zE4Xfs+Q-Pp*Lcw;b^Z3r^77Yr{_S~uj{g$>My{d*+D{*YVkk4fC&blMO3GbXxzoj^ zz{2A3yUz<Z?=PJ&GqGvrf`9-YFRy8nTi3RP+`e_bEID~$W8<_UPjd^iKn;zVC0;Y9 zPN}FY+rE8!xwQ1nn>RZ%oXexF%B`)RJ$u%aY+n#+mf>$4t*dKiXID^|2ehr*Tay(? zDVGHK1^*`q7}7MGrva677I;J!GcfQS0b$0e+I-SLL5ULAh?3y^w370~qEv=}#LT=B zJwMkF1yemkJ)_@yn70Ad^rS|3rg?g5F>nAmtPE0&tPG4mmKP99L)oA(&|qW+i!%Y) zhKx)M0zf(nh%?(+z~WgzHVE*PGcvpYCT19oW+?+u{{(gh7NAN4BVz-`1rSsJ{|9Sk z(9BfKIV*U(5||5`JzX3_JiOmdxn0&|AmD1uc8e|lf>!8-q|g85ZyFmL`kn~-eQRA_ zOw$=N&gsU->>u!RwFx<?ik>;7rn6-V*A#9Q_4Q7nq2;Zs*3Ey%8Twbp$xSKa?qzQ_ zOYs)B*LE@SM|2Y%B1~^oC~TT`?e*8RW__96Ps3Q(ZC|lHWo7q-()I7oz7$zqcKuhG z`?lNeyIdaBzu&O&!uR(J-hZEKEhF5>yCzX0aLRd$9hVhFZNd&V@i4F+`Z$Ht!9C#E z!Cg6AY}pSq8CY~a#c+w}F+MP|KUXEMWKw&dW0P=VM~uN`mtY2VHM{N;i^KV1?DS9e z&E&KbN!lyG^^f&wJCpnL`j+P^E&EUTE$V(8{a4ZDbJ;F=u7z=2f4m$svd-q+l()Fo zc6jaAP4)$Qc-y5n3MaNLnZ7*3VusF>zlvN8Y%{*IcW&o0IIzdwV^8yg(v~gu3VUSU zuRiePFJrdHGJ#M37#bhP_ATf*@bO&h8v6%+VoulOA8qb9^SgPDPitlUg~^{}e=Plb a@V9=Z#F6A%=3Ggj$nkXbb6Mw<&;$S$ZTE%% literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotYellow.png b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotYellow.png new file mode 100644 index 0000000000000000000000000000000000000000..abdef3b926ff71c930310a9fa66e1cdf0dc41d26 GIT binary patch literal 1218 zcmeAS@N?(olHy`uVBq!ia0vp^3P9|@!3-pQ0$S%VFfg`eIy(n=Iy)-_6y>L7=A<$( zXq=xq(c0s1fJoc_WnD_4g4P`+Cj#c`bm+^dcDZf{xW%>BYQ~)}tiDo{M8w?>Zhi0| zdE=`GkJhYiUai1k=WvHr-Bn!k<DDfJltMlncv|=8`#<~V^SC*-3SC~)SLkp#*I01s zk&?8~H&w0twGszRoQyX2L=+jeZu?s5zkTI9B^&PltK&?w4G*Xboi{wZrPI74-7L5H zvt8i?(Uhq_=2V<n!qzFjb6v%sW0vnX9WZWA(=zmzQ4#yByJm}l_6(_yB83rGOHPSj zl3P7zyG8a=uIw)-<0VeK()L_;nM<)t^@u<_2dk(^U{f#0TPsa5p%T5VANhCxv)Cz8 zBzo|~#s(vk6YJ#v@YkKccFNbU!jqBnMNQ$He!&IV;w!>spZ~s5_)5LuzvPZfv;P(G z&iJdc_tup|?hgOW3JULDnPU5(h+U$}C?&W|)m~R|I`h5rFJ>DZc%XY>^Ru&S3;Qm! zE4Xfs+Q-Pp*Lcw;b^Z3r^77Yr{_S~uj{g$>My{d*+D{*YVkk4fC&bm%Sjyc+xwF}& zAlu^cyUz<Z?=PJ&GqGvrf|&t6US88Cx2|moxqa(=S#t8i#>Qzyp5_*2fqoh@OT1=I zol;R*wtf5da%t(CH*a=kIG0CTl^0n*d-kj;*}fpuEW_V8I$YPz&aR*^4`|!^)U9$r zO1UJ+FZe$}z>ucdJPoLvv%n*=n1O-s2naJy)#j513QCl?MwA5Sr<If^7Ns%-BxdH7 z==r&ZD46OQ>KXms!@LcsrYAMRGtJXei-7~kVP%kFWMyCkvb=y;8p;NRfd(TpSeyyS zHe_UC5CGCqK%Cjm0v68#vO$2SoRQ%LFfqeuG)ozP`X{h6umDvW7#SNdE`XT&|36qW zgJz~;&RN0RmB3uk?CIhd;^F;v%I&fy0|8fKwp(oZ7qmhzBz^ubf7965(Dy{p?_2Bg zVw%pFaZWcrX8(Ynt4+vBRrJguHJvR}xTbKcsIPYl4J~h7wQl}9&d|R)PHsvWcQ1Rh zS&Fx~y|#;qKcbuH5Mg?wLSfUiYp=hiHS5dlej3KQZu^SuDJ#1tl&*hw_NB<`vg^Of z+_&9!-{tb4{{4oH7rwt=@c#Q;YZ>82-ZhC5fm6;~?6|BbY7=&_iHCvp(8np94(<WR z4(`g~V#|J@$-tuXDTYf#kMV(#{kbZ6C6n6w9Gip_J7Nqjy96_^tJ!s*SRBq5W2b+z zZziXmNYY*bu79jg+nL;_*S9=ZY1x0uZ&CN-=)a0CpUZa1b1jVH`s3x8k##ojro6?y zw!>?`Zn7`f!`m*sQ8=+}$@JwJ7Bh67{8i*)V4Lxsy>mO4!GS&Y9($S}l(uZKSJ)%- ze)WMTe;KnqmI-|N$I$pVwr@elfsf}}*VsSs6LY#I|7df^ncvNGd|E5(FHHU<`(x?f agTM7NC5|NDGUrMHMUJPdpUXO@geCyAmHFiW literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/meta.json b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/meta.json index cc898e53cd6..d3ac6b30cf6 100644 --- a/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/meta.json +++ b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/meta.json @@ -8,7 +8,43 @@ "copyright": "Tim Falken", "states": [ { - "name": "gladiabot", + "name": "GladiabotFFA", + "delays": [ + [ + 0.5, + 0.2 + ] + ] + }, + { + "name": "GladiabotRed", + "delays": [ + [ + 0.5, + 0.2 + ] + ] + }, + { + "name": "GladiabotGreen", + "delays": [ + [ + 0.5, + 0.2 + ] + ] + }, + { + "name": "GladiabotBlue", + "delays": [ + [ + 0.5, + 0.2 + ] + ] + }, + { + "name": "GladiabotYellow", "delays": [ [ 0.5, From ddb30d711b922b158622e524df5baa51eeab6078 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Mon, 20 Jan 2025 21:11:54 +0100 Subject: [PATCH 02/14] Use another component to subscribe to the event --- .../NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index 1e57d917bec..376590abc71 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -14,10 +14,10 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent<NpcFactionMemberComponent, NpcFactionAddedEvent>(OnFactionAdded); + SubscribeLocalEvent<NpcFactionSelectorComponent, NpcFactionAddedEvent>(OnFactionAdded); } - private void OnFactionAdded(Entity<NpcFactionMemberComponent > entity, ref NpcFactionAddedEvent args) + private void OnFactionAdded(Entity<NpcFactionSelectorComponent> entity, ref NpcFactionAddedEvent args) { if (!_entityManager.HasComponent(entity, typeof(NpcFactionSpriteStateSetterComponent))) return; From ebbf1683fc55f20c975a327f9cb2114238b92b67 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Mon, 20 Jan 2025 21:12:48 +0100 Subject: [PATCH 03/14] removed using which won't work in Floof copied form EE but the Floof implementation of the NpcFactionSystem seems to be slightly outdated --- Content.Shared/NPC/NpcFactionSelectorSystem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Content.Shared/NPC/NpcFactionSelectorSystem.cs b/Content.Shared/NPC/NpcFactionSelectorSystem.cs index c3fef47da47..a1889605564 100644 --- a/Content.Shared/NPC/NpcFactionSelectorSystem.cs +++ b/Content.Shared/NPC/NpcFactionSelectorSystem.cs @@ -1,6 +1,5 @@ using Content.Shared.Database; using Content.Shared.NPC.Components; -using Content.Shared.NPC.Prototypes; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Prototypes; From 00c302297ac960830075ab355227954e275ae6f8 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Mon, 20 Jan 2025 22:21:42 +0100 Subject: [PATCH 04/14] Move faction selector to Server --- .../Systems/NpcFactionSpriteStateSetterSystem.cs | 4 ++-- .../NPC/Components/NpcFactionSelectorComponent.cs | 12 ++++++++++++ .../NPC/Systems}/NpcFactionSelectorSystem.cs | 8 ++++---- Content.Server/NPC/Systems/NpcFactionSystem.cs | 4 ++-- Content.Shared/NPC/NpcFactionSelectorComponent.cs | 14 -------------- 5 files changed, 20 insertions(+), 22 deletions(-) create mode 100644 Content.Server/NPC/Components/NpcFactionSelectorComponent.cs rename {Content.Shared/NPC => Content.Server/NPC/Systems}/NpcFactionSelectorSystem.cs (87%) delete mode 100644 Content.Shared/NPC/NpcFactionSelectorComponent.cs diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index 376590abc71..e409436b695 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -14,10 +14,10 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent<NpcFactionSelectorComponent, NpcFactionAddedEvent>(OnFactionAdded); + SubscribeLocalEvent<NpcFactionSpriteStateSetterComponent, NpcFactionAddedEvent>(OnFactionAdded); } - private void OnFactionAdded(Entity<NpcFactionSelectorComponent> entity, ref NpcFactionAddedEvent args) + private void OnFactionAdded(Entity<NpcFactionSpriteStateSetterComponent> entity, ref NpcFactionAddedEvent args) { if (!_entityManager.HasComponent(entity, typeof(NpcFactionSpriteStateSetterComponent))) return; diff --git a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs b/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs new file mode 100644 index 00000000000..ff12f8c77cd --- /dev/null +++ b/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs @@ -0,0 +1,12 @@ +using Content.Server.NPC.Systems; +using Robust.Shared.GameStates; + +namespace Content.Server.NPC.Components; + +[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSelectorSystem))] +public sealed partial class NpcFactionSelectorComponent : Component +{ + [DataField] + public List<string> SelectableFactions = new(); +} + diff --git a/Content.Shared/NPC/NpcFactionSelectorSystem.cs b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs similarity index 87% rename from Content.Shared/NPC/NpcFactionSelectorSystem.cs rename to Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs index a1889605564..29c9fd11713 100644 --- a/Content.Shared/NPC/NpcFactionSelectorSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs @@ -1,11 +1,11 @@ +using Content.Server.NPC.Components; using Content.Shared.Database; -using Content.Shared.NPC.Components; using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Prototypes; using System.Linq; -namespace Content.Shared.NPC.Systems; +namespace Content.Server.NPC.Systems; public sealed partial class NpcFactionSelectorSystem : EntitySystem { @@ -18,10 +18,10 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent<NpcFactionSelectorComponent, GetVerbsEvent<Verb>>(OnGetVerb); + SubscribeLocalEvent<NpcFactionMemberComponent, GetVerbsEvent<Verb>>(OnGetVerb); } - private void OnGetVerb(Entity<NpcFactionSelectorComponent> entity, ref GetVerbsEvent<Verb> args) + private void OnGetVerb(Entity<NpcFactionMemberComponent> entity, ref GetVerbsEvent<Verb> args) { if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; diff --git a/Content.Server/NPC/Systems/NpcFactionSystem.cs b/Content.Server/NPC/Systems/NpcFactionSystem.cs index a8a5121b250..864ad5a4980 100644 --- a/Content.Server/NPC/Systems/NpcFactionSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSystem.cs @@ -77,7 +77,7 @@ public void AddFaction(EntityUid uid, string faction, bool dirty = true) if (!comp.Factions.Add(faction)) return; - RaiseLocalEvent(ent.Owner, new NpcFactionAddedEvent(faction)); + RaiseLocalEvent(uid, new NpcFactionAddedEvent(faction)); if (dirty) { @@ -102,7 +102,7 @@ public void RemoveFaction(EntityUid uid, string faction, bool dirty = true) if (!component.Factions.Remove(faction)) return; - RaiseLocalEvent(ent.Owner, new NpcFactionRemovedEvent(faction)); + RaiseLocalEvent(uid, new NpcFactionRemovedEvent(faction)); if (dirty) diff --git a/Content.Shared/NPC/NpcFactionSelectorComponent.cs b/Content.Shared/NPC/NpcFactionSelectorComponent.cs deleted file mode 100644 index 7eb5701373b..00000000000 --- a/Content.Shared/NPC/NpcFactionSelectorComponent.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Content.Shared.NPC.Systems; -using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; - -namespace Content.Shared.NPC.Components; - -[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSelectorSystem))] -public sealed partial class NpcFactionSelectorComponent : Component -{ - [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>))] - public List<string> SelectableFactions = new(); -} - From 622aabd9262abf9ddf9317820b9987b5ca94a6d0 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Tue, 21 Jan 2025 19:21:57 +0100 Subject: [PATCH 05/14] remove networked attributes where they're not neede --- Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 2 -- Content.Server/NPC/Components/NpcFactionSelectorComponent.cs | 2 +- Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index e409436b695..11e9d326d35 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -2,12 +2,10 @@ using Content.Shared.NPC.Components; using Content.Shared.NPC.Events; using Robust.Client.GameObjects; -using Robust.Shared.Reflection; namespace Content.Client.NPC.Systems; public sealed partial class NpcFactionSpriteStateSetterSystem : EntitySystem { - [Dependency] private readonly SpriteSystem _spriteSystem = default!; [Dependency] private readonly EntityManager _entityManager = default!; public override void Initialize() diff --git a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs b/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs index ff12f8c77cd..b5572db4db1 100644 --- a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs +++ b/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs @@ -3,7 +3,7 @@ namespace Content.Server.NPC.Components; -[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSelectorSystem))] +[RegisterComponent] public sealed partial class NpcFactionSelectorComponent : Component { [DataField] diff --git a/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs b/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs index ec5d66ff03e..4c90340fb84 100644 --- a/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs +++ b/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs @@ -2,6 +2,6 @@ namespace Content.Shared.NPC.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent] public sealed partial class NpcFactionSpriteStateSetterComponent : Component {} From c30fdf3fafcb6d29b8ed5ca040d420e494878826 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Tue, 21 Jan 2025 19:21:57 +0100 Subject: [PATCH 06/14] remove networked attributes where they're not neede --- .../NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 2 -- Content.Server/NPC/Components/NpcFactionSelectorComponent.cs | 5 +---- Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index e409436b695..11e9d326d35 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -2,12 +2,10 @@ using Content.Shared.NPC.Components; using Content.Shared.NPC.Events; using Robust.Client.GameObjects; -using Robust.Shared.Reflection; namespace Content.Client.NPC.Systems; public sealed partial class NpcFactionSpriteStateSetterSystem : EntitySystem { - [Dependency] private readonly SpriteSystem _spriteSystem = default!; [Dependency] private readonly EntityManager _entityManager = default!; public override void Initialize() diff --git a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs b/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs index ff12f8c77cd..cf42f186226 100644 --- a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs +++ b/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs @@ -1,9 +1,6 @@ -using Content.Server.NPC.Systems; -using Robust.Shared.GameStates; - namespace Content.Server.NPC.Components; -[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSelectorSystem))] +[RegisterComponent] public sealed partial class NpcFactionSelectorComponent : Component { [DataField] diff --git a/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs b/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs index ec5d66ff03e..4c90340fb84 100644 --- a/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs +++ b/Content.Shared/NPC/NpcFactionSpriteStateSetterComponent.cs @@ -2,6 +2,6 @@ namespace Content.Shared.NPC.Components; -[RegisterComponent, NetworkedComponent] +[RegisterComponent] public sealed partial class NpcFactionSpriteStateSetterComponent : Component {} From 33eb9e446b7601699218dfb402521437c96aae0e Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Tue, 21 Jan 2025 20:00:47 +0100 Subject: [PATCH 07/14] Update prototype --- Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml b/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml index 2ad231acb6c..78faa6f6cb6 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml @@ -6,7 +6,7 @@ components: - type: Sprite sprite: Mobs/Silicon/Bots/gladiabot.rsi - state: gladiabot + state: GladiabotFFA - type: Inventory templateId: gladiabot - type: InventorySlots @@ -26,6 +26,14 @@ - type: NpcFactionMember factions: - GladiabotFFA + - type: NpcFactionSelector + selectableFactions: + - GladiabotFFA + - GladiabotRed + - GladiabotBlue + - GladiabotGreen + - GladiabotYellow + - type: NpcFactionSpriteStateSetter - type: CombatMode - type: MeleeWeapon altDisarm: false From 9ff0a3323b44c102f87e87a764325608cd23c7c4 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Tue, 21 Jan 2025 22:03:12 +0100 Subject: [PATCH 08/14] Fix events between server and client so the bot changes colour --- .../NpcFactionSpriteStateSetterSystem.cs | 15 +++++++++------ Content.Server/NPC/Systems/NpcFactionSystem.cs | 9 +++++---- .../NPC/Events/NpcFactionChangedEvent.cs | 18 ++++++++++++++---- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index 11e9d326d35..8a6e08ae28a 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -12,15 +12,18 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent<NpcFactionSpriteStateSetterComponent, NpcFactionAddedEvent>(OnFactionAdded); + SubscribeNetworkEvent<NpcFactionAddedEvent>(OnFactionAdded); } - private void OnFactionAdded(Entity<NpcFactionSpriteStateSetterComponent> entity, ref NpcFactionAddedEvent args) + private void OnFactionAdded(NpcFactionAddedEvent ev) { - if (!_entityManager.HasComponent(entity, typeof(NpcFactionSpriteStateSetterComponent))) - return; + if (_entityManager.TryGetEntity(ev.EntityUid, out var entity)) + { + if (!_entityManager.HasComponent(entity.Value, typeof(NpcFactionSpriteStateSetterComponent))) + return; - SpriteComponent spriteComponent = _entityManager.GetComponent<SpriteComponent>(entity); - spriteComponent.LayerSetState(0, new Robust.Client.Graphics.RSI.StateId(args.FactionID)); + SpriteComponent spriteComponent = _entityManager.GetComponent<SpriteComponent>(entity.Value); + spriteComponent.LayerSetState(0, new Robust.Client.Graphics.RSI.StateId(ev.FactionID)); + } } } diff --git a/Content.Server/NPC/Systems/NpcFactionSystem.cs b/Content.Server/NPC/Systems/NpcFactionSystem.cs index 864ad5a4980..faa72d1e6fe 100644 --- a/Content.Server/NPC/Systems/NpcFactionSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSystem.cs @@ -9,7 +9,7 @@ namespace Content.Server.NPC.Systems; /// <summary> /// Outlines faction relationships with each other. -/// part of psionics rework was making this a partial class. Should've already been handled upstream, based on the linter. +/// part of psionics rework was making this a partial class. Should've already been handled upstream, based on the linter. /// </summary> public sealed partial class NpcFactionSystem : EntitySystem { @@ -77,7 +77,8 @@ public void AddFaction(EntityUid uid, string faction, bool dirty = true) if (!comp.Factions.Add(faction)) return; - RaiseLocalEvent(uid, new NpcFactionAddedEvent(faction)); + if(_lookup.TryGetNetEntity(uid, out var netEntity)) + RaiseNetworkEvent(new NpcFactionAddedEvent(netEntity.Value, faction)); if (dirty) { @@ -102,8 +103,8 @@ public void RemoveFaction(EntityUid uid, string faction, bool dirty = true) if (!component.Factions.Remove(faction)) return; - RaiseLocalEvent(uid, new NpcFactionRemovedEvent(faction)); - + if(_lookup.TryGetNetEntity(uid, out var netEntity)) + RaiseNetworkEvent(new NpcFactionRemovedEvent(netEntity.Value, faction)); if (dirty) { diff --git a/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs b/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs index dc43017af68..4b85345f326 100644 --- a/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs +++ b/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs @@ -8,9 +8,14 @@ namespace Content.Shared.NPC.Events; [Serializable, NetSerializable] public sealed class NpcFactionAddedEvent : EntityEventArgs { - public string FactionID; + public readonly string FactionID; + public readonly NetEntity EntityUid; - public NpcFactionAddedEvent(string factionId) => FactionID = factionId; + public NpcFactionAddedEvent(NetEntity entity, string factionId) + { + FactionID = factionId; + EntityUid = entity; + } } /// <summary> @@ -19,7 +24,12 @@ public sealed class NpcFactionAddedEvent : EntityEventArgs [Serializable, NetSerializable] public sealed class NpcFactionRemovedEvent : EntityEventArgs { - public string FactionID; + public readonly string FactionID; + public readonly NetEntity EntityUid; - public NpcFactionRemovedEvent(string factionId) => FactionID = factionId; + public NpcFactionRemovedEvent(NetEntity entity, string factionId) + { + FactionID = factionId; + EntityUid = entity; + } } From 785eb3b38bd2367185134f0003c7ce004553fbdf Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Wed, 22 Jan 2025 00:00:26 +0100 Subject: [PATCH 09/14] Don't crash when selecting NPC's that don't have the factionselector component --- Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs index 29c9fd11713..de026b5db61 100644 --- a/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs @@ -18,10 +18,10 @@ public override void Initialize() { base.Initialize(); - SubscribeLocalEvent<NpcFactionMemberComponent, GetVerbsEvent<Verb>>(OnGetVerb); + SubscribeLocalEvent<NpcFactionSelectorComponent, GetVerbsEvent<Verb>>(OnGetVerb); } - private void OnGetVerb(Entity<NpcFactionMemberComponent> entity, ref GetVerbsEvent<Verb> args) + private void OnGetVerb(Entity<NpcFactionSelectorComponent> entity, ref GetVerbsEvent<Verb> args) { if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; From e3499c48bd0a1ae45a9f160b98fbdc1d0a2c08d2 Mon Sep 17 00:00:00 2001 From: Timfa <timfalken@hotmail.com> Date: Wed, 22 Jan 2025 00:20:49 +0100 Subject: [PATCH 10/14] Apply suggestions from code review Co-authored-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> --- .../NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 11 +++-------- .../NPC/Systems/NpcFactionSelectorSystem.cs | 4 +--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index 8a6e08ae28a..328c2622b11 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -6,7 +6,6 @@ namespace Content.Client.NPC.Systems; public sealed partial class NpcFactionSpriteStateSetterSystem : EntitySystem { - [Dependency] private readonly EntityManager _entityManager = default!; public override void Initialize() { @@ -17,13 +16,9 @@ public override void Initialize() private void OnFactionAdded(NpcFactionAddedEvent ev) { - if (_entityManager.TryGetEntity(ev.EntityUid, out var entity)) - { - if (!_entityManager.HasComponent(entity.Value, typeof(NpcFactionSpriteStateSetterComponent))) - return; + if (!TryGetEntity(ev.EntityUid, out var entity) || !TryComp<SpriteComponent>(entity.Value, out var sprite)) + return; - SpriteComponent spriteComponent = _entityManager.GetComponent<SpriteComponent>(entity.Value); - spriteComponent.LayerSetState(0, new Robust.Client.Graphics.RSI.StateId(ev.FactionID)); - } + sprite.LayerSetState(0, new Robust.Client.Graphics.RSI.State(0, new Robust.Client.Graphics.RSI.StateId(ev.FactionID)); } } diff --git a/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs index de026b5db61..4d8eec1374b 100644 --- a/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs @@ -26,9 +26,7 @@ private void OnGetVerb(Entity<NpcFactionSelectorComponent> entity, ref GetVerbsE if (!args.CanAccess || !args.CanInteract || args.Hands == null) return; - NpcFactionSelectorComponent factionSelectorComponent = _entityManager.GetComponent<NpcFactionSelectorComponent>(entity); - - if (factionSelectorComponent.SelectableFactions.Count < 2) + if (!TryComp<NpcFactionSelectorComponent>(entity, out var factionSelectorComponent) || factionSelectorComponent.SelectableFactions.Count < 2) return; foreach (var type in factionSelectorComponent.SelectableFactions) From be337147cb0ae02c6cdada4a26adcb9b628805bc Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Wed, 22 Jan 2025 00:46:12 +0100 Subject: [PATCH 11/14] Apply //Floofstation comments --- Content.Server/NPC/Systems/NpcFactionSystem.cs | 2 +- Content.Shared/Verbs/VerbCategory.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Server/NPC/Systems/NpcFactionSystem.cs b/Content.Server/NPC/Systems/NpcFactionSystem.cs index faa72d1e6fe..5af25647155 100644 --- a/Content.Server/NPC/Systems/NpcFactionSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSystem.cs @@ -77,7 +77,7 @@ public void AddFaction(EntityUid uid, string faction, bool dirty = true) if (!comp.Factions.Add(faction)) return; - if(_lookup.TryGetNetEntity(uid, out var netEntity)) + if(TryGetNetEntity(uid, out var netEntity)) // Floofstation RaiseNetworkEvent(new NpcFactionAddedEvent(netEntity.Value, faction)); if (dirty) diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index 97ddb5c5cde..72580d7a086 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -84,12 +84,12 @@ public VerbCategory(string text, string? icon, bool iconsOnly = false) public static readonly VerbCategory SelectType = new("verb-categories-select-type", null); - public static readonly VerbCategory SelectFaction = new("verb-categories-select-faction", null); - public static readonly VerbCategory PowerLevel = new("verb-categories-power-level", null); public static readonly VerbCategory Interaction = new("verb-categories-interaction", null); public static readonly VerbCategory Vore = new("verb-categories-vore", null); // Floofstation + + public static readonly VerbCategory SelectFaction = new("verb-categories-select-faction", null); // Floofstation } } From b1a22daf7bb0a7a0b5911a9551e7e5f5d4f1ebd9 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Wed, 22 Jan 2025 00:46:39 +0100 Subject: [PATCH 12/14] Fix accidentally using an internal constructor that didn't seem to be necessary --- Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index 328c2622b11..73eb69a7004 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -19,6 +19,6 @@ private void OnFactionAdded(NpcFactionAddedEvent ev) if (!TryGetEntity(ev.EntityUid, out var entity) || !TryComp<SpriteComponent>(entity.Value, out var sprite)) return; - sprite.LayerSetState(0, new Robust.Client.Graphics.RSI.State(0, new Robust.Client.Graphics.RSI.StateId(ev.FactionID)); + sprite.LayerSetState(0, new (ev.FactionID)); } } From 45ac05ab1589d2332892ab4d62e1e5ed003aff06 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Wed, 22 Jan 2025 02:35:11 +0100 Subject: [PATCH 13/14] ensure we're only applying the event on entities with the setter component --- Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index 73eb69a7004..c897a332cb5 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -16,7 +16,7 @@ public override void Initialize() private void OnFactionAdded(NpcFactionAddedEvent ev) { - if (!TryGetEntity(ev.EntityUid, out var entity) || !TryComp<SpriteComponent>(entity.Value, out var sprite)) + if (!TryGetEntity(ev.EntityUid, out var entity) || !TryComp<SpriteComponent>(entity.Value, out var sprite) || !TryComp<NpcFactionSpriteStateSetterComponent>(entity.Value, out var _)) return; sprite.LayerSetState(0, new (ev.FactionID)); From 8b764d456f0f798a6e4638c46fd0614013a6cfb8 Mon Sep 17 00:00:00 2001 From: Tim <timfalken@hotmail.com> Date: Wed, 22 Jan 2025 17:10:20 +0100 Subject: [PATCH 14/14] Ensure a set faction is relevant to an entity that will change its sprite because of it --- .../NPC/Systems/NpcFactionSpriteStateSetterSystem.cs | 5 +++-- Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs | 2 ++ .../NPC}/NpcFactionSelectorComponent.cs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) rename {Content.Server/NPC/Components => Content.Shared/NPC}/NpcFactionSelectorComponent.cs (79%) diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs index c897a332cb5..9767c87bf0d 100644 --- a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs +++ b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs @@ -16,9 +16,10 @@ public override void Initialize() private void OnFactionAdded(NpcFactionAddedEvent ev) { - if (!TryGetEntity(ev.EntityUid, out var entity) || !TryComp<SpriteComponent>(entity.Value, out var sprite) || !TryComp<NpcFactionSpriteStateSetterComponent>(entity.Value, out var _)) + if (!TryGetEntity(ev.EntityUid, out var entity) || !TryComp<SpriteComponent>(entity.Value, out var sprite) || !TryComp<NpcFactionSpriteStateSetterComponent>(entity.Value, out var _)|| !TryComp<NpcFactionSelectorComponent>(entity.Value, out var factionSelector)) return; - sprite.LayerSetState(0, new (ev.FactionID)); + if(factionSelector.SelectableFactions.Contains(ev.FactionID)) + sprite.LayerSetState(0, new (ev.FactionID)); } } diff --git a/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs index 4d8eec1374b..c17207028a0 100644 --- a/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs +++ b/Content.Server/NPC/Systems/NpcFactionSelectorSystem.cs @@ -4,6 +4,8 @@ using Content.Shared.Verbs; using Robust.Shared.Prototypes; using System.Linq; +using Content.Shared.NPC.Components; + namespace Content.Server.NPC.Systems; public sealed partial class NpcFactionSelectorSystem : EntitySystem diff --git a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs b/Content.Shared/NPC/NpcFactionSelectorComponent.cs similarity index 79% rename from Content.Server/NPC/Components/NpcFactionSelectorComponent.cs rename to Content.Shared/NPC/NpcFactionSelectorComponent.cs index cf42f186226..4e59d2a26fc 100644 --- a/Content.Server/NPC/Components/NpcFactionSelectorComponent.cs +++ b/Content.Shared/NPC/NpcFactionSelectorComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.NPC.Components; +namespace Content.Shared.NPC.Components; [RegisterComponent] public sealed partial class NpcFactionSelectorComponent : Component