From 0df12ec24ab73786604f173296f95aaa950e5c88 Mon Sep 17 00:00:00 2001 From: Timfa Date: Tue, 21 Jan 2025 15:56:35 +0100 Subject: [PATCH] Gladiabot (#1548) Co-authored-by: stellar-novas Co-authored-by: RedFoxIV <38788538+RedFoxIV@users.noreply.github.com> (cherry picked from commit 01d1ec4d4b04f6d76f239ec0da0970dc705736ef) --- .../NpcFactionSpriteStateSetterSystem.cs | 28 ++++++ .../NPC/Systems/NPCCombatSystem.Melee.cs | 5 + .../Components/NpcFactionSelectorComponent.cs | 11 +++ .../NpcFactionSpriteStateSetterComponent.cs | 7 ++ .../NPC/Events/NpcFactionChangedEvent.cs | 25 +++++ .../NPC/Prototypes/NpcFactionPrototype.cs | 3 + .../NPC/Systems/NpcFactionSelectorSystem.cs | 60 ++++++++++++ .../NPC/Systems/NpcFactionSystem.cs | 17 +++- Content.Shared/Verbs/VerbCategory.cs | 2 + .../interaction-popup-component.ftl | 2 + Resources/Locale/en-US/npc/factions.ftl | 1 + Resources/Locale/en-US/verbs/verb-system.ftl | 1 + .../Entities/Mobs/NPCs/gladiabot.yml | 90 ++++++++++++++++++ .../gladiabot_inventory_template.yml | 10 ++ Resources/Prototypes/NPCs/gladiabot.yml | 12 +++ .../Crafting/Graphs/bots/gladiabot.yml | 25 +++++ .../Prototypes/Recipes/Crafting/bots.yml | 13 +++ Resources/Prototypes/ai_factions.yml | 41 ++++++++ .../Bots/gladiabot.rsi/GladiabotBlue.png | Bin 0 -> 1218 bytes .../Bots/gladiabot.rsi/GladiabotFFA.png | Bin 0 -> 2372 bytes .../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 | 56 +++++++++++ 24 files changed, 407 insertions(+), 2 deletions(-) create mode 100644 Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs create mode 100644 Content.Shared/NPC/Components/NpcFactionSelectorComponent.cs create mode 100644 Content.Shared/NPC/Components/NpcFactionSpriteStateSetterComponent.cs create mode 100644 Content.Shared/NPC/Events/NpcFactionChangedEvent.cs create mode 100644 Content.Shared/NPC/Systems/NpcFactionSelectorSystem.cs create mode 100644 Resources/Locale/en-US/npc/factions.ftl create mode 100644 Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml create mode 100644 Resources/Prototypes/InventoryTemplates/gladiabot_inventory_template.yml create mode 100644 Resources/Prototypes/NPCs/gladiabot.yml create mode 100644 Resources/Prototypes/Recipes/Crafting/Graphs/bots/gladiabot.yml create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotBlue.png create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/GladiabotFFA.png 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 create mode 100644 Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/meta.json diff --git a/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs b/Content.Client/NPC/Systems/NpcFactionSpriteStateSetterSystem.cs new file mode 100644 index 0000000000..1e57d917be --- /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(OnFactionAdded); + } + + private void OnFactionAdded(Entity entity, ref NpcFactionAddedEvent args) + { + if (!_entityManager.HasComponent(entity, typeof(NpcFactionSpriteStateSetterComponent))) + return; + + SpriteComponent spriteComponent = _entityManager.GetComponent(entity); + spriteComponent.LayerSetState(0, new Robust.Client.Graphics.RSI.StateId(args.FactionID)); + } +} diff --git a/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs b/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs index 2ae20817e2..a5279ae857 100644 --- a/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs +++ b/Content.Server/NPC/Systems/NPCCombatSystem.Melee.cs @@ -1,5 +1,6 @@ using System.Numerics; using Content.Server.NPC.Components; +using Content.Server.NPC.HTN; using Content.Shared.CombatMode; using Content.Shared.NPC; using Robust.Shared.Map; @@ -10,6 +11,7 @@ namespace Content.Server.NPC.Systems; public sealed partial class NPCCombatSystem { + [Dependency] private readonly IRobustRandom _rng = default!; private const float TargetMeleeLostRange = 14f; private void InitializeMelee() @@ -114,5 +116,8 @@ public sealed partial class NPCCombatSystem { _melee.AttemptLightAttack(uid, weaponUid, weapon, component.Target); } + + if (Comp(uid).Blackboard.TryGetValue("AttackDelayDeviation", out var dev, EntityManager)) + weapon.NextAttack += TimeSpan.FromSeconds(_rng.NextFloat(-dev, dev)); } } diff --git a/Content.Shared/NPC/Components/NpcFactionSelectorComponent.cs b/Content.Shared/NPC/Components/NpcFactionSelectorComponent.cs new file mode 100644 index 0000000000..fcc40e9b60 --- /dev/null +++ b/Content.Shared/NPC/Components/NpcFactionSelectorComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.NPC.Systems; +using Robust.Shared.GameStates; + +namespace Content.Shared.NPC.Components; + +[RegisterComponent, NetworkedComponent, Access(typeof(NpcFactionSelectorSystem))] +public sealed partial class NpcFactionSelectorComponent : Component +{ + [DataField] + public List SelectableFactions = new(); +} diff --git a/Content.Shared/NPC/Components/NpcFactionSpriteStateSetterComponent.cs b/Content.Shared/NPC/Components/NpcFactionSpriteStateSetterComponent.cs new file mode 100644 index 0000000000..ec5d66ff03 --- /dev/null +++ b/Content.Shared/NPC/Components/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/NPC/Events/NpcFactionChangedEvent.cs b/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs new file mode 100644 index 0000000000..dc43017af6 --- /dev/null +++ b/Content.Shared/NPC/Events/NpcFactionChangedEvent.cs @@ -0,0 +1,25 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.NPC.Events; + +/// +/// Raised from client to server to notify a faction was added to an NPC. +/// +[Serializable, NetSerializable] +public sealed class NpcFactionAddedEvent : EntityEventArgs +{ + public string FactionID; + + public NpcFactionAddedEvent(string factionId) => FactionID = factionId; +} + +/// +/// Raised from client to server to notify a faction was removed from an NPC. +/// +[Serializable, NetSerializable] +public sealed class NpcFactionRemovedEvent : EntityEventArgs +{ + public string FactionID; + + public NpcFactionRemovedEvent(string factionId) => FactionID = factionId; +} diff --git a/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs b/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs index 1dcdd751c8..5a7b403814 100644 --- a/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs +++ b/Content.Shared/NPC/Prototypes/NpcFactionPrototype.cs @@ -24,6 +24,9 @@ public sealed partial class NpcFactionPrototype : IPrototype /// public record struct FactionData { + [ViewVariables] + public bool IsHostileToSelf; + [ViewVariables] public HashSet> Friendly; diff --git a/Content.Shared/NPC/Systems/NpcFactionSelectorSystem.cs b/Content.Shared/NPC/Systems/NpcFactionSelectorSystem.cs new file mode 100644 index 0000000000..c3fef47da4 --- /dev/null +++ b/Content.Shared/NPC/Systems/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>(OnGetVerb); + } + + private void OnGetVerb(Entity entity, ref GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || args.Hands == null) + return; + + NpcFactionSelectorComponent factionSelectorComponent = _entityManager.GetComponent(entity); + + if (factionSelectorComponent.SelectableFactions.Count < 2) + return; + + foreach (var type in factionSelectorComponent.SelectableFactions) + { + var proto = _prototype.Index(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/Systems/NpcFactionSystem.cs b/Content.Shared/NPC/Systems/NpcFactionSystem.cs index 448c7eeaec..62de929864 100644 --- a/Content.Shared/NPC/Systems/NpcFactionSystem.cs +++ b/Content.Shared/NPC/Systems/NpcFactionSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.NPC.Components; +using Content.Shared.NPC.Events; using Content.Shared.NPC.Prototypes; using Robust.Shared.Prototypes; using System.Collections.Frozen; @@ -106,6 +107,8 @@ public sealed partial class NpcFactionSystem : EntitySystem if (!ent.Comp.Factions.Add(faction)) return; + RaiseLocalEvent(ent.Owner, new NpcFactionAddedEvent(faction)); + if (dirty) RefreshFactions((ent, ent.Comp)); } @@ -125,6 +128,8 @@ public sealed partial class NpcFactionSystem : EntitySystem continue; } + RaiseLocalEvent(ent.Owner, new NpcFactionAddedEvent(faction)); + ent.Comp.Factions.Add(faction); } @@ -149,6 +154,8 @@ public sealed partial class NpcFactionSystem : EntitySystem if (!ent.Comp.Factions.Remove(faction)) return; + RaiseLocalEvent(ent.Owner, new NpcFactionRemovedEvent(faction)); + if (dirty) RefreshFactions((ent, ent.Comp)); } @@ -217,7 +224,12 @@ public sealed partial class NpcFactionSystem : EntitySystem if (!Resolve(ent, ref ent.Comp, false) || !Resolve(other, ref other.Comp, false)) return false; - return ent.Comp.Factions.Overlaps(other.Comp.Factions) || ent.Comp.FriendlyFactions.Overlaps(other.Comp.Factions); + var intersect = ent.Comp.Factions.Intersect(other.Comp.Factions); // factions which have both ent and other as members + foreach (var faction in intersect) + if (_factions[faction].IsHostileToSelf) + return false; + + return intersect.Count() > 0 || ent.Comp.FriendlyFactions.Overlaps(other.Comp.Factions); } public bool IsFactionFriendly(string target, string with) @@ -301,8 +313,9 @@ public sealed partial class NpcFactionSystem : EntitySystem { _factions = _proto.EnumeratePrototypes().ToFrozenDictionary( faction => faction.ID, - faction => new FactionData + faction => new FactionData { + IsHostileToSelf = faction.Hostile.Contains(faction.ID), Friendly = faction.Friendly.ToHashSet(), Hostile = faction.Hostile.ToHashSet() }); diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index 38ec881a7c..be35479a36 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -100,6 +100,8 @@ namespace Content.Shared.Verbs public static readonly VerbCategory SelectType = new("verb-categories-select-type"); + public static readonly VerbCategory SelectFaction = new("verb-categories-select-faction"); + public static readonly VerbCategory PowerLevel = new("verb-categories-power-level"); public static readonly VerbCategory Interaction = new("verb-categories-interaction"); diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl index 40d9975a46..aced542aaf 100644 --- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl @@ -72,6 +72,7 @@ petting-success-syndicate-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} petting-success-derelict-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} rusty metal head. petting-success-recycler = You pet {THE($target)} on {POSS-ADJ($target)} mildly threatening steel exterior. petting-success-station-ai = You pet {THE($target)} on {POSS-ADJ($target)} cold, square screen. +petting-success-gladiabot = You pet {THE($target)} on {POSS-ADJ($target)} vicious cardboard head. petting-failure-honkbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} honks in refusal! petting-failure-cleanbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy mopping! @@ -87,6 +88,7 @@ petting-failure-service-cyborg = You reach out to pet {THE($target)}, but {SUBJE petting-failure-syndicate-cyborg = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} treacherous affiliation makes you reconsider. petting-failure-derelict-cyborg = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} rusty and jagged exterior makes you reconsider. petting-failure-station-ai = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BASIC($target, "zap", "zaps")} your hand away. +petting-failure-gladiabot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} only wants to fight! petting-success-station-ai-others = { CAPITALIZE(THE($user)) } pets {THE($target)} on {POSS-ADJ($target)} cold, square screen. diff --git a/Resources/Locale/en-US/npc/factions.ftl b/Resources/Locale/en-US/npc/factions.ftl new file mode 100644 index 0000000000..8aaa2b6e8f --- /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 c99f9987cb..d579f045c5 100644 --- a/Resources/Locale/en-US/verbs/verb-system.ftl +++ b/Resources/Locale/en-US/verbs/verb-system.ftl @@ -26,6 +26,7 @@ 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 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml b/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml new file mode 100644 index 0000000000..78faa6f6cb --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/NPCs/gladiabot.yml @@ -0,0 +1,90 @@ +- type: entity + parent: MobSiliconBase + id: MobGladiaBot + name: gladiabot + description: For glory! + components: + - type: Sprite + sprite: Mobs/Silicon/Bots/gladiabot.rsi + state: GladiabotFFA + - type: Inventory + templateId: gladiabot + - type: InventorySlots + - type: UserInterface + interfaces: + enum.StrippingUiKey.Key: + type: StrippableBoundUserInterface + - type: Construction + graph: GladiaBot + node: bot + - type: Stripping + - type: Strippable + - type: SentienceTarget + flavorKind: station-event-random-sentience-flavor-mechanical + - type: UseDelay + delay: 1 + - type: NpcFactionMember + factions: + - GladiabotFFA + - type: NpcFactionSelector + selectableFactions: + - GladiabotFFA + - GladiabotRed + - GladiabotBlue + - GladiabotGreen + - GladiabotYellow + - type: NpcFactionSpriteStateSetter + - type: CombatMode + - type: MeleeWeapon + altDisarm: false + soundHit: + path: /Audio/Weapons/bladeslice.ogg + angle: 0 + animation: WeaponArcPunch + damage: + types: + Slash: 3 + - type: MobThresholds + thresholds: + 0: Alive + 40: Dead + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 30 + behaviors: + - !type:TriggerBehavior + - trigger: + !type:DamageTrigger + damage: 40 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ProximitySensor: + min: 1 + max: 1 + - !type:SpawnEntitiesBehavior + spawn: + MaterialCloth1: + min: 1 + max: 1 + - !type:EmptyContainersBehaviour + containers: + - head + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: MovementSpeedModifier + baseWalkSpeed: 2 + baseSprintSpeed: 3 + - type: HTN + rootTask: + task: GladiabotCompound + blackboard: + AttackDelayDeviation: !type:Single + 0.3 + - type: InteractionPopup + interactSuccessString: petting-success-gladiabot + interactFailureString: petting-failure-gladiabot + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg diff --git a/Resources/Prototypes/InventoryTemplates/gladiabot_inventory_template.yml b/Resources/Prototypes/InventoryTemplates/gladiabot_inventory_template.yml new file mode 100644 index 0000000000..c7f0e44fe3 --- /dev/null +++ b/Resources/Prototypes/InventoryTemplates/gladiabot_inventory_template.yml @@ -0,0 +1,10 @@ +- type: inventoryTemplate + id: gladiabot + slots: + - name: head + slotTexture: head + slotFlags: HEAD + uiWindowPos: 0,1 + strippingWindowPos: 0,0 + displayName: Head + offset: 0.1, -0.15 diff --git a/Resources/Prototypes/NPCs/gladiabot.yml b/Resources/Prototypes/NPCs/gladiabot.yml new file mode 100644 index 0000000000..5e7170ee27 --- /dev/null +++ b/Resources/Prototypes/NPCs/gladiabot.yml @@ -0,0 +1,12 @@ +- type: htnCompound + id: GladiabotCompound + branches: + - tasks: + - !type:HTNPrimitiveTask + operator: !type:UtilityOperator + proto: NearbyMeleeTargets + - !type:HTNCompoundTask + task: MeleeAttackTargetCompound + - tasks: + - !type:HTNCompoundTask + task: IdleCompound diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/bots/gladiabot.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/bots/gladiabot.yml new file mode 100644 index 0000000000..ddcfceaef4 --- /dev/null +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/bots/gladiabot.yml @@ -0,0 +1,25 @@ +- type: constructionGraph + id: GladiaBot + start: start + graph: + - node: start + edges: + - to: bot + steps: + - material: Cardboard + amount: 1 + doAfter: 2 + - tag: ProximitySensor + icon: + sprite: Objects/Misc/proximity_sensor.rsi + state: icon + name: proximity sensor + doAfter: 2 + - tag: Shiv + icon: + sprite: Objects/Weapons/Melee/shiv.rsi + state: icon + name: shiv + doAfter: 2 + - node: bot + entity: MobGladiaBot diff --git a/Resources/Prototypes/Recipes/Crafting/bots.yml b/Resources/Prototypes/Recipes/Crafting/bots.yml index 3031f4a780..8f67905b85 100644 --- a/Resources/Prototypes/Recipes/Crafting/bots.yml +++ b/Resources/Prototypes/Recipes/Crafting/bots.yml @@ -75,3 +75,16 @@ icon: sprite: Mobs/Silicon/Bots/supplybot.rsi state: supplybot + +- type: construction + name: gladiabot + id: gladiabot + graph: GladiaBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This bot fights for honour and glory! + icon: + sprite: Mobs/Silicon/Bots/gladiabot.rsi + state: GladiabotFFA diff --git a/Resources/Prototypes/ai_factions.yml b/Resources/Prototypes/ai_factions.yml index c0f7c7da6a..4cbfc73f8e 100644 --- a/Resources/Prototypes/ai_factions.yml +++ b/Resources/Prototypes/ai_factions.yml @@ -107,3 +107,44 @@ - type: npcFaction id: AnimalFriend + +- type: npcFaction + 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 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 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!kspZ~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{2A3yUzRZ%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;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!kspZ~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^cyUzQzyp5_*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?MwA5SrKXms!@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(?`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 new file mode 100644 index 0000000000..d3ac6b30cf --- /dev/null +++ b/Resources/Textures/Mobs/Silicon/Bots/gladiabot.rsi/meta.json @@ -0,0 +1,56 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Tim Falken", + "states": [ + { + "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, + 0.2 + ] + ] + } + ] +}