From d12a6bd9cffd572ee434f4f63af5b253464bef80 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Thu, 25 Jun 2020 01:43:58 +1000 Subject: [PATCH] Add xenos (#1204) * Add xenos for stress test Pretty hacky and not how I'd do it long-term * Remove claws * Add in unarmed combat behaviors * Cleanuppppp Co-authored-by: Metal Gear Sloth --- .../{ => Melee}/SwingMeleeWeaponOperator.cs | 12 ++- .../Combat/Melee/UnarmedCombatOperator.cs | 88 ++++++++++++++++++ ...ckEntity.cs => MeleeWeaponAttackEntity.cs} | 5 +- .../Combat/Melee/UnarmedAttackEntity.cs | 78 ++++++++++++++++ Content.Server/AI/Utility/AiLogic/Mimic.cs | 18 ++++ Content.Server/AI/Utility/AiLogic/Xeno.cs | 19 ++++ .../UnarmedAttackPlayersBehaviorSet.cs | 17 ++++ .../Combat/Melee/CanUnarmedCombatCon.cs | 17 ++++ .../Melee/MeleeAttackNearbyPlayerExp.cs | 2 +- .../Melee/MeleeAttackNearbySpeciesExp.cs | 2 +- .../Melee/UnarmedAttackNearbyPlayerExp.cs | 36 +++++++ .../Entities/Effects/weapon_arc.yml | 2 + .../Mobs/{npcs.yml => NPCs/human.yml} | 0 .../Prototypes/Entities/Mobs/NPCs/mimic.yml | 59 ++++++++++++ .../Prototypes/Entities/Mobs/NPCs/xeno.yml | 59 ++++++++++++ .../Prototypes/Entities/Mobs/Player/human.yml | 20 ++++ Resources/Prototypes/Entities/Mobs/human.yml | 22 +---- Resources/Textures/Mob/xeno.rsi/meta.json | 19 ++++ Resources/Textures/Mob/xeno.rsi/running.png | Bin 0 -> 8050 bytes Resources/Textures/Mob/xeno.rsi/standing.png | Bin 0 -> 10554 bytes .../Objects/Melee/xeno_claw.rsi/icon.png | Bin 0 -> 309 bytes .../Melee/xeno_claw.rsi/inhand-left.png | Bin 0 -> 1863 bytes .../Melee/xeno_claw.rsi/inhand-right.png | Bin 0 -> 1865 bytes .../Objects/Melee/xeno_claw.rsi/meta.json | 23 +++++ 24 files changed, 471 insertions(+), 27 deletions(-) rename Content.Server/AI/Operators/Combat/{ => Melee}/SwingMeleeWeaponOperator.cs (86%) create mode 100644 Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs rename Content.Server/AI/Utility/Actions/Combat/Melee/{MeleeAttackEntity.cs => MeleeWeaponAttackEntity.cs} (93%) create mode 100644 Content.Server/AI/Utility/Actions/Combat/Melee/UnarmedAttackEntity.cs create mode 100644 Content.Server/AI/Utility/AiLogic/Mimic.cs create mode 100644 Content.Server/AI/Utility/AiLogic/Xeno.cs create mode 100644 Content.Server/AI/Utility/BehaviorSets/UnarmedAttackPlayersBehaviorSet.cs create mode 100644 Content.Server/AI/Utility/Considerations/Combat/Melee/CanUnarmedCombatCon.cs create mode 100644 Content.Server/AI/Utility/ExpandableActions/Combat/Melee/UnarmedAttackNearbyPlayerExp.cs rename Resources/Prototypes/Entities/Mobs/{npcs.yml => NPCs/human.yml} (100%) create mode 100644 Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml create mode 100644 Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml create mode 100644 Resources/Prototypes/Entities/Mobs/Player/human.yml create mode 100644 Resources/Textures/Mob/xeno.rsi/meta.json create mode 100644 Resources/Textures/Mob/xeno.rsi/running.png create mode 100644 Resources/Textures/Mob/xeno.rsi/standing.png create mode 100644 Resources/Textures/Objects/Melee/xeno_claw.rsi/icon.png create mode 100644 Resources/Textures/Objects/Melee/xeno_claw.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Melee/xeno_claw.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Melee/xeno_claw.rsi/meta.json diff --git a/Content.Server/AI/Operators/Combat/SwingMeleeWeaponOperator.cs b/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs similarity index 86% rename from Content.Server/AI/Operators/Combat/SwingMeleeWeaponOperator.cs rename to Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs index d4c5ade0d6..38065d5973 100644 --- a/Content.Server/AI/Operators/Combat/SwingMeleeWeaponOperator.cs +++ b/Content.Server/AI/Operators/Combat/Melee/SwingMeleeWeaponOperator.cs @@ -5,7 +5,7 @@ using Content.Server.GameObjects.EntitySystems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; -namespace Content.Server.AI.Operators.Combat +namespace Content.Server.AI.Operators.Combat.Melee { public class SwingMeleeWeaponOperator : AiOperator { @@ -41,6 +41,15 @@ namespace Content.Server.AI.Operators.Combat return true; } + + public override void Shutdown(Outcome outcome) + { + base.Shutdown(outcome); + if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) + { + combatModeComponent.IsInCombatMode = false; + } + } public override Outcome Execute(float frameTime) { @@ -70,5 +79,4 @@ namespace Content.Server.AI.Operators.Combat return Outcome.Continuing; } } - } diff --git a/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs b/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs new file mode 100644 index 0000000000..5fc0332351 --- /dev/null +++ b/Content.Server/AI/Operators/Combat/Melee/UnarmedCombatOperator.cs @@ -0,0 +1,88 @@ +using Content.Server.GameObjects; +using Content.Server.GameObjects.Components.Mobs; +using Content.Server.GameObjects.Components.Weapon.Melee; +using Content.Server.GameObjects.EntitySystems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; + +namespace Content.Server.AI.Operators.Combat.Melee +{ + public sealed class UnarmedCombatOperator : AiOperator + { + private float _burstTime; + private float _elapsedTime; + + private readonly IEntity _owner; + private readonly IEntity _target; + private UnarmedCombatComponent _unarmedCombat; + + public UnarmedCombatOperator(IEntity owner, IEntity target, float burstTime = 1.0f) + { + _owner = owner; + _target = target; + _burstTime = burstTime; + } + + public override bool TryStartup() + { + if (!base.TryStartup()) + { + return true; + } + + if (!_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) + { + return false; + } + + if (!combatModeComponent.IsInCombatMode) + { + combatModeComponent.IsInCombatMode = true; + } + + if (_owner.TryGetComponent(out UnarmedCombatComponent unarmedCombatComponent)) + { + _unarmedCombat = unarmedCombatComponent; + } + else + { + return false; + } + + return true; + } + + public override void Shutdown(Outcome outcome) + { + base.Shutdown(outcome); + if (_owner.TryGetComponent(out CombatModeComponent combatModeComponent)) + { + combatModeComponent.IsInCombatMode = false; + } + } + + public override Outcome Execute(float frameTime) + { + if (_burstTime <= _elapsedTime) + { + return Outcome.Success; + } + + if (_unarmedCombat.Deleted) + { + return Outcome.Failed; + } + + if ((_target.Transform.GridPosition.Position - _owner.Transform.GridPosition.Position).Length > + _unarmedCombat.Range) + { + return Outcome.Failed; + } + + var interactionSystem = IoCManager.Resolve().GetEntitySystem(); + interactionSystem.UseItemInHand(_owner, _target.Transform.GridPosition, _target.Uid); + _elapsedTime += frameTime; + return Outcome.Continuing; + } + } +} \ No newline at end of file diff --git a/Content.Server/AI/Utility/Actions/Combat/Melee/MeleeAttackEntity.cs b/Content.Server/AI/Utility/Actions/Combat/Melee/MeleeWeaponAttackEntity.cs similarity index 93% rename from Content.Server/AI/Utility/Actions/Combat/Melee/MeleeAttackEntity.cs rename to Content.Server/AI/Utility/Actions/Combat/Melee/MeleeWeaponAttackEntity.cs index 25f329fdc1..2da20091a1 100644 --- a/Content.Server/AI/Utility/Actions/Combat/Melee/MeleeAttackEntity.cs +++ b/Content.Server/AI/Utility/Actions/Combat/Melee/MeleeWeaponAttackEntity.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Content.Server.AI.Operators; using Content.Server.AI.Operators.Combat; +using Content.Server.AI.Operators.Combat.Melee; using Content.Server.AI.Operators.Movement; using Content.Server.AI.Utility.Considerations; using Content.Server.AI.Utility.Considerations.Combat; @@ -17,11 +18,11 @@ using Robust.Shared.Interfaces.GameObjects; namespace Content.Server.AI.Utility.Actions.Combat.Melee { - public sealed class MeleeAttackEntity : UtilityAction + public sealed class MeleeWeaponAttackEntity : UtilityAction { private IEntity _entity; - public MeleeAttackEntity(IEntity owner, IEntity entity, float weight) : base(owner) + public MeleeWeaponAttackEntity(IEntity owner, IEntity entity, float weight) : base(owner) { _entity = entity; Bonus = weight; diff --git a/Content.Server/AI/Utility/Actions/Combat/Melee/UnarmedAttackEntity.cs b/Content.Server/AI/Utility/Actions/Combat/Melee/UnarmedAttackEntity.cs new file mode 100644 index 0000000000..6883b294bf --- /dev/null +++ b/Content.Server/AI/Utility/Actions/Combat/Melee/UnarmedAttackEntity.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using Content.Server.AI.Operators; +using Content.Server.AI.Operators.Combat.Melee; +using Content.Server.AI.Operators.Movement; +using Content.Server.AI.Utility.Considerations; +using Content.Server.AI.Utility.Considerations.Combat; +using Content.Server.AI.Utility.Considerations.Combat.Melee; +using Content.Server.AI.Utility.Considerations.Movement; +using Content.Server.AI.Utility.Curves; +using Content.Server.AI.WorldState; +using Content.Server.AI.WorldState.States; +using Content.Server.AI.WorldState.States.Combat; +using Content.Server.AI.WorldState.States.Movement; +using Content.Server.GameObjects.Components.Weapon.Melee; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.AI.Utility.Actions.Combat.Melee +{ + public sealed class UnarmedAttackEntity : UtilityAction + { + private IEntity _entity; + + public UnarmedAttackEntity(IEntity owner, IEntity entity, float weight) : base(owner) + { + _entity = entity; + Bonus = weight; + } + + public override void SetupOperators(Blackboard context) + { + MoveToEntityOperator moveOperator; + if (Owner.TryGetComponent(out UnarmedCombatComponent unarmedCombatComponent)) + { + moveOperator = new MoveToEntityOperator(Owner, _entity, unarmedCombatComponent.Range - 0.01f); + } + // I think it's possible for this to happen given planning is time-sliced? + // TODO: At this point we should abort + else + { + moveOperator = new MoveToEntityOperator(Owner, _entity); + } + + ActionOperators = new Queue(new AiOperator[] + { + moveOperator, + new UnarmedCombatOperator(Owner, _entity), + }); + } + + protected override void UpdateBlackboard(Blackboard context) + { + base.UpdateBlackboard(context); + context.GetState().SetValue(_entity); + context.GetState().SetValue(_entity); + // Can just set ourselves as entity given unarmed just inherits from meleeweapon + context.GetState().SetValue(Owner); + } + + protected override Consideration[] Considerations { get; } = { + new CanUnarmedCombatCon( + new BoolCurve()), + // Don't attack a dead target + new TargetIsDeadCon( + new InverseBoolCurve()), + // Deprioritise a target in crit + new TargetIsCritCon( + new QuadraticCurve(-0.8f, 1.0f, 1.0f, 0.0f)), + // Somewhat prioritise distance + new DistanceCon( + new QuadraticCurve(-1.0f, 1.0f, 1.02f, 0.0f)), + // Prefer weaker targets + new TargetHealthCon( + new QuadraticCurve(1.0f, 0.4f, 0.0f, -0.02f)), + // TODO: Consider our Speed and Damage to compare this to using a weapon + // Also need to unequip our weapon if we have one (xenos can't hold one so no issue for now) + }; + } +} \ No newline at end of file diff --git a/Content.Server/AI/Utility/AiLogic/Mimic.cs b/Content.Server/AI/Utility/AiLogic/Mimic.cs new file mode 100644 index 0000000000..bc8ecb9f28 --- /dev/null +++ b/Content.Server/AI/Utility/AiLogic/Mimic.cs @@ -0,0 +1,18 @@ +using Content.Server.AI.Utility.BehaviorSets; +using JetBrains.Annotations; +using Robust.Server.AI; + +namespace Content.Server.AI.Utility.AiLogic +{ + [AiLogicProcessor("Mimic")] + [UsedImplicitly] + public sealed class Mimic : UtilityAi + { + public override void Setup() + { + base.Setup(); + AddBehaviorSet(new UnarmedAttackPlayersBehaviorSet(SelfEntity), false); + SortActions(); + } + } +} \ No newline at end of file diff --git a/Content.Server/AI/Utility/AiLogic/Xeno.cs b/Content.Server/AI/Utility/AiLogic/Xeno.cs new file mode 100644 index 0000000000..b658d0cfb0 --- /dev/null +++ b/Content.Server/AI/Utility/AiLogic/Xeno.cs @@ -0,0 +1,19 @@ +using Content.Server.AI.Utility.BehaviorSets; +using JetBrains.Annotations; +using Robust.Server.AI; + +namespace Content.Server.AI.Utility.AiLogic +{ + [AiLogicProcessor("Xeno")] + [UsedImplicitly] + public sealed class Xeno : UtilityAi + { + public override void Setup() + { + base.Setup(); + AddBehaviorSet(new IdleBehaviorSet(SelfEntity), false); + AddBehaviorSet(new UnarmedAttackPlayersBehaviorSet(SelfEntity), false); + SortActions(); + } + } +} \ No newline at end of file diff --git a/Content.Server/AI/Utility/BehaviorSets/UnarmedAttackPlayersBehaviorSet.cs b/Content.Server/AI/Utility/BehaviorSets/UnarmedAttackPlayersBehaviorSet.cs new file mode 100644 index 0000000000..6b479b87e9 --- /dev/null +++ b/Content.Server/AI/Utility/BehaviorSets/UnarmedAttackPlayersBehaviorSet.cs @@ -0,0 +1,17 @@ +using Content.Server.AI.Utility.Actions; +using Content.Server.AI.Utility.ExpandableActions.Combat.Melee; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.AI.Utility.BehaviorSets +{ + public sealed class UnarmedAttackPlayersBehaviorSet : BehaviorSet + { + public UnarmedAttackPlayersBehaviorSet(IEntity owner) : base(owner) + { + Actions = new IAiUtility[] + { + new UnarmedAttackNearbyPlayerExp(), + }; + } + } +} \ No newline at end of file diff --git a/Content.Server/AI/Utility/Considerations/Combat/Melee/CanUnarmedCombatCon.cs b/Content.Server/AI/Utility/Considerations/Combat/Melee/CanUnarmedCombatCon.cs new file mode 100644 index 0000000000..f77e6ce5c4 --- /dev/null +++ b/Content.Server/AI/Utility/Considerations/Combat/Melee/CanUnarmedCombatCon.cs @@ -0,0 +1,17 @@ +using Content.Server.AI.Utility.Curves; +using Content.Server.AI.WorldState; +using Content.Server.AI.WorldState.States; +using Content.Server.GameObjects.Components.Weapon.Melee; + +namespace Content.Server.AI.Utility.Considerations.Combat.Melee +{ + public sealed class CanUnarmedCombatCon : Consideration + { + public CanUnarmedCombatCon(IResponseCurve curve) : base(curve) {} + + public override float GetScore(Blackboard context) + { + return context.GetState().GetValue().HasComponent() ? 1.0f : 0.0f; + } + } +} \ No newline at end of file diff --git a/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbyPlayerExp.cs b/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbyPlayerExp.cs index e70dba6c86..adab7f24cd 100644 --- a/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbyPlayerExp.cs +++ b/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbyPlayerExp.cs @@ -28,7 +28,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee { if (entity.HasComponent() && entity != owner) { - yield return new MeleeAttackEntity(owner, entity, Bonus); + yield return new MeleeWeaponAttackEntity(owner, entity, Bonus); } } } diff --git a/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbySpeciesExp.cs b/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbySpeciesExp.cs index ad00223233..617252184e 100644 --- a/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbySpeciesExp.cs +++ b/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/MeleeAttackNearbySpeciesExp.cs @@ -16,7 +16,7 @@ namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee var owner = context.GetState().GetValue(); foreach (var entity in context.GetState().GetValue()) { - yield return new MeleeAttackEntity(owner, entity, Bonus); + yield return new MeleeWeaponAttackEntity(owner, entity, Bonus); } } } diff --git a/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/UnarmedAttackNearbyPlayerExp.cs b/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/UnarmedAttackNearbyPlayerExp.cs new file mode 100644 index 0000000000..e168116431 --- /dev/null +++ b/Content.Server/AI/Utility/ExpandableActions/Combat/Melee/UnarmedAttackNearbyPlayerExp.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using Content.Server.AI.Utility.Actions; +using Content.Server.AI.Utility.Actions.Combat.Melee; +using Content.Server.AI.Utils; +using Content.Server.AI.WorldState; +using Content.Server.AI.WorldState.States; +using Content.Server.GameObjects; +using Content.Server.GameObjects.Components.Movement; +using Robust.Server.GameObjects; + +namespace Content.Server.AI.Utility.ExpandableActions.Combat.Melee +{ + public sealed class UnarmedAttackNearbyPlayerExp : ExpandableUtilityAction + { + public override float Bonus => UtilityAction.CombatBonus; + + public override IEnumerable GetActions(Blackboard context) + { + var owner = context.GetState().GetValue(); + if (!owner.TryGetComponent(out AiControllerComponent controller)) + { + throw new InvalidOperationException(); + } + + foreach (var entity in Visibility.GetEntitiesInRange(owner.Transform.GridPosition, typeof(SpeciesComponent), + controller.VisionRadius)) + { + if (entity.HasComponent() && entity != owner) + { + yield return new UnarmedAttackEntity(owner, entity, Bonus); + } + } + } + } +} \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Effects/weapon_arc.yml b/Resources/Prototypes/Entities/Effects/weapon_arc.yml index 2653321b72..10e70bb4fd 100644 --- a/Resources/Prototypes/Entities/Effects/weapon_arc.yml +++ b/Resources/Prototypes/Entities/Effects/weapon_arc.yml @@ -12,6 +12,8 @@ - type: entity id: WeaponTGArc + save: false + abstract: true parent: WeaponArc components: - type: Sprite diff --git a/Resources/Prototypes/Entities/Mobs/npcs.yml b/Resources/Prototypes/Entities/Mobs/NPCs/human.yml similarity index 100% rename from Resources/Prototypes/Entities/Mobs/npcs.yml rename to Resources/Prototypes/Entities/Mobs/NPCs/human.yml diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml new file mode 100644 index 0000000000..3ecbbd0322 --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml @@ -0,0 +1,59 @@ +# Hacky for the stress test so don't even consider adding to this +- type: entity + save: false + name: Mimic + id: MimicMob_Content + description: Surprise. # When this gets a proper write this should use the object's actual description >:) + drawdepth: Mobs + suffix: AI + components: + - type: AiController + logic: Mimic + - type: Hands + hands: + - left + - right + - type: MovementSpeedModifier + - type: InteractionOutline + - type: Sprite + netsync: false + drawdepth: Mobs + sprite: Buildings/VendingMachines/cola.rsi + state: normal + - type: Icon + sprite: Buildings/VendingMachines/cola.rsi + state: normal + - type: Physics + mass: 85 + - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" + mask: + - Impassable + - MobImpassable + - VaultImpassable + - SmallImpassable + layer: + - Opaque + - MobImpassable + - type: Species + Template: Human + HeatResistance: 323 + - type: BodyManager + BaseTemplate: bodyTemplate.Humanoid + BasePreset: bodyPreset.BasicHuman + - type: HeatResistance + - type: Damageable + - type: CombatMode + - type: Teleportable + - type: CharacterInfo + - type: FootstepSound + - type: HumanoidAppearance + - type: Stunnable + - type: AnimationPlayer + - type: UnarmedCombat + range: 1.5 + arcwidth: 0 + arc: fist + damage: 90 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml new file mode 100644 index 0000000000..6203b61bb2 --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -0,0 +1,59 @@ +# Hacky for the stress test so don't even consider adding to this +- type: entity + save: false + name: Xeno + id: XenoMob_Content + description: They mostly come at night. Mostly. + drawdepth: Mobs + suffix: AI + components: + - type: AiController + logic: Xeno + - type: Hands + hands: + - left + - right + - type: MovementSpeedModifier + # Organs + - type: InteractionOutline + - type: Sprite + drawdepth: Mobs + sprite: Mob/xeno.rsi + state: running + - type: Icon + sprite: Mob/xeno.rsi + state: running + - type: Physics + mass: 85 + - type: Collidable + shapes: + - !type:PhysShapeAabb + bounds: "-0.35,-0.35,0.35,0.35" + mask: + - Impassable + - MobImpassable + - VaultImpassable + - SmallImpassable + layer: + - Opaque + - MobImpassable + - type: Species + Template: Human + HeatResistance: 323 + - type: BodyManager + BaseTemplate: bodyTemplate.Humanoid + BasePreset: bodyPreset.BasicHuman + - type: HeatResistance + - type: Damageable + - type: CombatMode + - type: Teleportable + - type: CharacterInfo + - type: FootstepSound + - type: HumanoidAppearance + - type: Stunnable + - type: AnimationPlayer + - type: UnarmedCombat + range: 1.5 + arcwidth: 0 + arc: claw + damage: 90 diff --git a/Resources/Prototypes/Entities/Mobs/Player/human.yml b/Resources/Prototypes/Entities/Mobs/Player/human.yml new file mode 100644 index 0000000000..8995218961 --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Player/human.yml @@ -0,0 +1,20 @@ +- type: entity + save: false + name: Urist McHands + parent: BaseHumanMob_Content + abstract: true + id: HumanMob_Content + description: A miserable pile of secrets + drawdepth: Mobs + components: + - type: Mind + show_examine_info: true + - type: Input + context: "human" + - type: StatusEffectsUI + - type: OverlayEffectsUI + - type: Eye + zoom: 0.5, 0.5 + - type: CameraRecoil + - type: Examiner + - type: HumanInventoryController \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Mobs/human.yml b/Resources/Prototypes/Entities/Mobs/human.yml index 44f5752f16..c12cd79d92 100644 --- a/Resources/Prototypes/Entities/Mobs/human.yml +++ b/Resources/Prototypes/Entities/Mobs/human.yml @@ -1,5 +1,5 @@ # Both humans and NPCs inherit from this. -# Anything human specific (e.g. UI, input) goes under HumanMob_Content +# Anything player specific (e.g. UI, input) goes under HumanMob_Content - type: entity save: false name: Urist McHands @@ -138,26 +138,6 @@ arcwidth: 30 arc: fist -- type: entity - save: false - name: Urist McHands - parent: BaseHumanMob_Content - id: HumanMob_Content - description: A miserable pile of secrets - drawdepth: Mobs - components: - - type: Mind - show_examine_info: true - - type: Input - context: "human" - - type: StatusEffectsUI - - type: OverlayEffectsUI - - type: Eye - zoom: 0.5, 0.5 - - type: CameraRecoil - - type: Examiner - - type: HumanInventoryController - - type: entity save: false name: Urist McHands diff --git a/Resources/Textures/Mob/xeno.rsi/meta.json b/Resources/Textures/Mob/xeno.rsi/meta.json new file mode 100644 index 0000000000..b6ea7da0c2 --- /dev/null +++ b/Resources/Textures/Mob/xeno.rsi/meta.json @@ -0,0 +1,19 @@ +{ + "version": 1, + "size": { + "x": 64, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/discordia-space/CEV-Eris/raw/7344da18b5e3dd0b1994a84e9c9c0774d71b93a5/icons/mob/alien.dmi", + "states": [ + { + "name": "running", + "directions": 4 + }, + { + "name": "standing", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Mob/xeno.rsi/running.png b/Resources/Textures/Mob/xeno.rsi/running.png new file mode 100644 index 0000000000000000000000000000000000000000..b2ca1b8d4f07e24dba07e5c0797d2a672614b801 GIT binary patch literal 8050 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�ul0Za6fBx}z#N%OGuJBF!KFwAysDpQJpVRT- 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 DK5c2! literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Melee/xeno_claw.rsi/meta.json b/Resources/Textures/Objects/Melee/xeno_claw.rsi/meta.json new file mode 100644 index 0000000000..bce8d4e9b0 --- /dev/null +++ b/Resources/Textures/Objects/Melee/xeno_claw.rsi/meta.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/discordia-space/CEV-Eris/raw/7344da18b5e3dd0b1994a84e9c9c0774d71b93a5/icons/mob/alien.dmi", + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "inhand-left", + "directions": 1 + }, + { + "name": "inhand-right", + "directions": 1 + } + ] +} \ No newline at end of file