From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sun, 18 Aug 2024 16:22:36 +0000 (-0400) Subject: Goliath mob (#30839) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=a540b8840e7ad2493217c85037f8e719b38cdd3d;p=space-station-14.git Goliath mob (#30839) * Goliath mob * Update asteroid.yml * mcfuck yourself * add cloak * fixes * Update materials.yml --- diff --git a/Content.Server/Actions/ActionOnInteractSystem.cs b/Content.Server/Actions/ActionOnInteractSystem.cs index 36e5920b32..a1f02ed1ec 100644 --- a/Content.Server/Actions/ActionOnInteractSystem.cs +++ b/Content.Server/Actions/ActionOnInteractSystem.cs @@ -154,21 +154,6 @@ public sealed class ActionOnInteractSystem : EntitySystem args.Handled = true; } - private bool ValidAction(BaseActionComponent action, bool canReach = true) - { - if (!action.Enabled) - return false; - - if (action.Charges.HasValue && action.Charges <= 0) - return false; - - var curTime = _timing.CurTime; - if (action.Cooldown.HasValue && action.Cooldown.Value.End > curTime) - return false; - - return canReach || action is BaseTargetActionComponent { CheckCanAccess: false }; - } - private List<(EntityUid Id, T Comp)> GetValidActions(List? actions, bool canReach = true) where T : BaseActionComponent { var valid = new List<(EntityUid Id, T Comp)>(); @@ -180,7 +165,7 @@ public sealed class ActionOnInteractSystem : EntitySystem { if (!_actions.TryGetActionData(id, out var baseAction) || baseAction as T is not { } action || - !ValidAction(action, canReach)) + !_actions.ValidAction(action, canReach)) { continue; } diff --git a/Content.Server/NPC/Components/NPCUseActionOnTargetComponent.cs b/Content.Server/NPC/Components/NPCUseActionOnTargetComponent.cs new file mode 100644 index 0000000000..f022a45ecc --- /dev/null +++ b/Content.Server/NPC/Components/NPCUseActionOnTargetComponent.cs @@ -0,0 +1,27 @@ +using Content.Server.NPC.Systems; +using Content.Shared.Actions; +using Robust.Shared.Prototypes; + +namespace Content.Server.NPC.Components; + +/// +/// This is used for an NPC that constantly tries to use an action on a given target. +/// +[RegisterComponent, Access(typeof(NPCUseActionOnTargetSystem))] +public sealed partial class NPCUseActionOnTargetComponent : Component +{ + /// + /// HTN blackboard key for the target entity + /// + [DataField] + public string TargetKey = "Target"; + + /// + /// Action that's going to attempt to be used. + /// + [DataField(required: true)] + public EntProtoId ActionId; + + [DataField] + public EntityUid? ActionEnt; +} diff --git a/Content.Server/NPC/NPCBlackboard.cs b/Content.Server/NPC/NPCBlackboard.cs index 322ff0f85b..ffdb55045d 100644 --- a/Content.Server/NPC/NPCBlackboard.cs +++ b/Content.Server/NPC/NPCBlackboard.cs @@ -34,6 +34,7 @@ public sealed partial class NPCBlackboard : IEnumerable @@ -269,6 +270,13 @@ public sealed partial class NPCBlackboard : IEnumerable("Target", out _, entMan) + ? AggroVisionRadius + : VisionRadius; + } + // I Ummd and Ahhd about using strings vs enums and decided on tags because // if a fork wants to do their own thing they don't need to touch the enum. @@ -317,9 +325,11 @@ public sealed partial class NPCBlackboard : IEnumerable /// A configurable "order" enum that can be given to an NPC from an external source. /// diff --git a/Content.Server/NPC/Systems/NPCUseActionOnTargetSystem.cs b/Content.Server/NPC/Systems/NPCUseActionOnTargetSystem.cs new file mode 100644 index 0000000000..f6cc2d1468 --- /dev/null +++ b/Content.Server/NPC/Systems/NPCUseActionOnTargetSystem.cs @@ -0,0 +1,68 @@ +using Content.Server.NPC.Components; +using Content.Server.NPC.HTN; +using Content.Shared.Actions; +using Robust.Shared.Timing; + +namespace Content.Server.NPC.Systems; + +public sealed class NPCUseActionOnTargetSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + ent.Comp.ActionEnt = _actions.AddAction(ent, ent.Comp.ActionId); + } + + public bool TryUseTentacleAttack(Entity user, EntityUid target) + { + if (!Resolve(user, ref user.Comp, false)) + return false; + + if (!TryComp(user.Comp.ActionEnt, out var action)) + return false; + + if (!_actions.ValidAction(action)) + return false; + + if (action.Event != null) + { + action.Event.Performer = user; + action.Event.Action = user.Comp.ActionEnt.Value; + action.Event.Coords = Transform(target).Coordinates; + } + + _actions.PerformAction(user, + null, + user.Comp.ActionEnt.Value, + action, + action.BaseEvent, + _timing.CurTime, + false); + return true; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // Tries to use the attack on the current target. + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var comp, out var htn)) + { + if (!htn.Blackboard.TryGetValue(comp.TargetKey, out var target, EntityManager)) + continue; + + TryUseTentacleAttack((uid, comp), target); + } + } +} diff --git a/Content.Server/NPC/Systems/NPCUtilitySystem.cs b/Content.Server/NPC/Systems/NPCUtilitySystem.cs index 5e1823227a..a2fb285ac1 100644 --- a/Content.Server/NPC/Systems/NPCUtilitySystem.cs +++ b/Content.Server/NPC/Systems/NPCUtilitySystem.cs @@ -264,7 +264,7 @@ public sealed class NPCUtilitySystem : EntitySystem } case TargetDistanceCon: { - var radius = blackboard.GetValueOrDefault(NPCBlackboard.VisionRadius, EntityManager); + var radius = blackboard.GetValueOrDefault(blackboard.GetVisionRadiusKey(EntityManager), EntityManager); if (!TryComp(targetUid, out TransformComponent? targetXform) || !TryComp(owner, out TransformComponent? xform)) @@ -309,13 +309,13 @@ public sealed class NPCUtilitySystem : EntitySystem } case TargetInLOSCon: { - var radius = blackboard.GetValueOrDefault(NPCBlackboard.VisionRadius, EntityManager); + var radius = blackboard.GetValueOrDefault(blackboard.GetVisionRadiusKey(EntityManager), EntityManager); return _examine.InRangeUnOccluded(owner, targetUid, radius + 0.5f, null) ? 1f : 0f; } case TargetInLOSOrCurrentCon: { - var radius = blackboard.GetValueOrDefault(NPCBlackboard.VisionRadius, EntityManager); + var radius = blackboard.GetValueOrDefault(blackboard.GetVisionRadiusKey(EntityManager), EntityManager); const float bufferRange = 0.5f; if (blackboard.TryGetValue("Target", out var currentTarget, EntityManager) && @@ -375,7 +375,7 @@ public sealed class NPCUtilitySystem : EntitySystem private void Add(NPCBlackboard blackboard, HashSet entities, UtilityQuery query) { var owner = blackboard.GetValue(NPCBlackboard.Owner); - var vision = blackboard.GetValueOrDefault(NPCBlackboard.VisionRadius, EntityManager); + var vision = blackboard.GetValueOrDefault(blackboard.GetVisionRadiusKey(EntityManager), EntityManager); switch (query) { diff --git a/Content.Shared/Abilities/Goliath/GoliathSummonTentacleAction.cs b/Content.Shared/Abilities/Goliath/GoliathSummonTentacleAction.cs new file mode 100644 index 0000000000..abdb0d5e10 --- /dev/null +++ b/Content.Shared/Abilities/Goliath/GoliathSummonTentacleAction.cs @@ -0,0 +1,31 @@ +using Content.Shared.Actions; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Abilities.Goliath; + +public sealed partial class GoliathSummonTentacleAction : EntityWorldTargetActionEvent +{ + /// + /// The ID of the entity that is spawned. + /// + [DataField] + public EntProtoId EntityId = "EffectGoliathTentacleSpawn"; + + /// + /// Directions determining where the entities will spawn. + /// + [DataField] + public List OffsetDirections = new() + { + Direction.North, + Direction.South, + Direction.East, + Direction.West, + }; + + /// + /// How many entities will spawn beyond the original one at the target location? + /// + [DataField] + public int ExtraSpawns = 3; +}; diff --git a/Content.Shared/Abilities/Goliath/GoliathTentacleSystem.cs b/Content.Shared/Abilities/Goliath/GoliathTentacleSystem.cs new file mode 100644 index 0000000000..98dbc5e18a --- /dev/null +++ b/Content.Shared/Abilities/Goliath/GoliathTentacleSystem.cs @@ -0,0 +1,69 @@ +using Content.Shared.Directions; +using Content.Shared.Maps; +using Content.Shared.Physics; +using Content.Shared.Popups; +using Content.Shared.Stunnable; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Network; +using Robust.Shared.Random; + +namespace Content.Shared.Abilities.Goliath; + +public sealed class GoliathTentacleSystem : EntitySystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly SharedMapSystem _map = default!; + [Dependency] private readonly SharedStunSystem _stun = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly TurfSystem _turf = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnSummonAction); + } + + private void OnSummonAction(GoliathSummonTentacleAction args) + { + if (args.Handled || args.Coords is not { } coords) + return; + + // TODO: animation + + _popup.PopupPredicted(Loc.GetString("tentacle-ability-use-popup", ("entity", args.Performer)), args.Performer, args.Performer, type: PopupType.SmallCaution); + _stun.TryStun(args.Performer, TimeSpan.FromSeconds(0.8f), false); + + List spawnPos = new(); + spawnPos.Add(coords); + + var dirs = new List(); + dirs.AddRange(args.OffsetDirections); + + for (var i = 0; i < 3; i++) + { + var dir = _random.PickAndTake(dirs); + spawnPos.Add(coords.Offset(dir)); + } + + if (_transform.GetGrid(coords) is not { } grid || !TryComp(grid, out var gridComp)) + return; + + foreach (var pos in spawnPos) + { + if (!_map.TryGetTileRef(grid, gridComp, pos, out var tileRef) || + tileRef.IsSpace() || + _turf.IsTileBlocked(tileRef, CollisionGroup.Impassable)) + { + continue; + } + + if (_net.IsServer) + Spawn(args.EntityId, pos); + } + + args.Handled = true; + } +} diff --git a/Content.Shared/Actions/SharedActionsSystem.cs b/Content.Shared/Actions/SharedActionsSystem.cs index 635d78b8dd..fb9415096f 100644 --- a/Content.Shared/Actions/SharedActionsSystem.cs +++ b/Content.Shared/Actions/SharedActionsSystem.cs @@ -958,6 +958,21 @@ public abstract class SharedActionsSystem : EntitySystem // See client-side system for UI code. } + public bool ValidAction(BaseActionComponent action, bool canReach = true) + { + if (!action.Enabled) + return false; + + if (action.Charges.HasValue && action.Charges <= 0) + return false; + + var curTime = GameTiming.CurTime; + if (action.Cooldown.HasValue && action.Cooldown.Value.End > curTime) + return false; + + return canReach || action is BaseTargetActionComponent { CheckCanAccess: false }; + } + #endregion #region EquipHandlers diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index 092da8fe5a..8f828131f5 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -14,16 +14,22 @@ using Content.Shared.Movement.Systems; using Content.Shared.Standing; using Content.Shared.StatusEffect; using Content.Shared.Throwing; +using Content.Shared.Whitelist; using Robust.Shared.Audio.Systems; +using Robust.Shared.Physics.Components; +using Robust.Shared.Physics.Events; +using Robust.Shared.Physics.Systems; namespace Content.Shared.Stunnable; public abstract class SharedStunSystem : EntitySystem { [Dependency] private readonly ActionBlockerSystem _blocker = default!; + [Dependency] private readonly SharedBroadphaseSystem _broadphase = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly EntityWhitelistSystem _entityWhitelist = default!; [Dependency] private readonly StandingStateSystem _standingState = default!; [Dependency] private readonly StatusEffectsSystem _statusEffect = default!; @@ -45,6 +51,9 @@ public abstract class SharedStunSystem : EntitySystem SubscribeLocalEvent(UpdateCanMove); SubscribeLocalEvent(UpdateCanMove); + SubscribeLocalEvent(OnStunOnContactStartup); + SubscribeLocalEvent(OnStunOnContactCollide); + // helping people up if they're knocked down SubscribeLocalEvent(OnInteractHand); SubscribeLocalEvent(OnRefreshMovespeed); @@ -104,6 +113,27 @@ public abstract class SharedStunSystem : EntitySystem _blocker.UpdateCanMove(uid); } + private void OnStunOnContactStartup(Entity ent, ref ComponentStartup args) + { + if (TryComp(ent, out var body)) + _broadphase.RegenerateContacts(ent, body); + } + + private void OnStunOnContactCollide(Entity ent, ref StartCollideEvent args) + { + if (args.OurFixtureId != ent.Comp.FixtureId) + return; + + if (_entityWhitelist.IsBlacklistPass(ent.Comp.Blacklist, args.OtherEntity)) + return; + + if (!TryComp(args.OtherEntity, out var status)) + return; + + TryStun(args.OtherEntity, ent.Comp.Duration, true, status); + TryKnockdown(args.OtherEntity, ent.Comp.Duration, true, status); + } + private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args) { _standingState.Down(uid); diff --git a/Content.Shared/Stunnable/StunOnContactComponent.cs b/Content.Shared/Stunnable/StunOnContactComponent.cs new file mode 100644 index 0000000000..cc4af53b3b --- /dev/null +++ b/Content.Shared/Stunnable/StunOnContactComponent.cs @@ -0,0 +1,23 @@ +using Content.Shared.Whitelist; +using Robust.Shared.GameStates; + +namespace Content.Shared.Stunnable; + +[RegisterComponent, NetworkedComponent, Access(typeof(SharedStunSystem))] +public sealed partial class StunOnContactComponent : Component +{ + /// + /// The fixture the entity must collide with to be stunned + /// + [DataField] + public string FixtureId = "fix"; + + /// + /// The duration of the stun. + /// + [DataField] + public TimeSpan Duration = TimeSpan.FromSeconds(5); + + [DataField] + public EntityWhitelist Blacklist = new(); +} diff --git a/Resources/Locale/en-US/abilities/goliath.ftl b/Resources/Locale/en-US/abilities/goliath.ftl new file mode 100644 index 0000000000..953d32a5c6 --- /dev/null +++ b/Resources/Locale/en-US/abilities/goliath.ftl @@ -0,0 +1 @@ +tentacle-ability-use-popup = {CAPITALIZE(THE($entity))} digs its tentacles under the ground! diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml new file mode 100644 index 0000000000..8cbd40b5cc --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml @@ -0,0 +1,182 @@ +- type: entity + id: BaseMobAsteroid + parent: + - BaseMob + - MobDamageable + - MobAtmosExposed + - MobCombat + abstract: true + components: + - type: Reactive + groups: + Flammable: [Touch] + Extinguish: [Touch] + Acidic: [Touch, Ingestion] + - type: Body + prototype: Animal + - type: Climbing + - type: NameIdentifier + group: GenericNumber + - type: StatusEffects + allowed: + - SlowedDown + - Stutter + - Stun + - Electrocution + - TemporaryBlindness + - RadiationProtection + - Drowsiness + - type: StandingState + - type: Tag + tags: + - DoorBumpOpener + +- type: entity + id: MobGoliath + parent: BaseMobAsteroid + name: goliath + description: A massive beast that uses long tentacles to ensnare its prey, threatening them is not advised under any conditions. + components: + - type: Sprite + sprite: Mobs/Aliens/Asteroid/goliath.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: goliath + - type: DamageStateVisuals + states: + Alive: + Base: goliath + Dead: + Base: goliath_dead + - type: MovementSpeedModifier + baseWalkSpeed : 2.50 + baseSprintSpeed : 2.50 + - type: MobThresholds + thresholds: + 0: Alive + 300: Dead + - type: MeleeWeapon + soundHit: + path: "/Audio/Weapons/smash.ogg" + angle: 0 + attackRate: 0.75 + animation: WeaponArcPunch + damage: + types: + Slash: 15 + Piercing: 10 + - type: NpcFactionMember + factions: + - SimpleHostile + - type: HTN + rootTask: + task: GoliathCompound + blackboard: + VisionRadius: !type:Single + 6 + AggroVisionRadius: !type:Single + 10 + - type: NPCUseActionOnTarget + actionId: ActionGoliathTentacle + - type: Tag + tags: + - CannotSuicide + - Goliath + - FootstepSound + - type: NoSlip + - type: Butcherable + spawned: + - id: FoodMeatGoliath + amount: 3 + - id: MaterialGoliathHide1 + +- type: entity + id: ActionGoliathTentacle + name: "[color=red]Tentacle Slam[/color]" + description: Use your tentacles to grab and stun a target player! + components: + - type: EntityWorldTargetAction + raiseOnUser: true + icon: + sprite: Mobs/Aliens/Asteroid/goliath.rsi + state: goliath_tentacle_spawn + iconOn: + sprite: Mobs/Aliens/Asteroid/goliath.rsi + state: goliath_tentacle_wiggle + sound: + path: "/Audio/Weapons/slash.ogg" + event: !type:GoliathSummonTentacleAction + useDelay: 8 + range: 10 + +- type: entity + id: GoliathTentacle + name: tentacle + components: + - type: Transform + anchored: True + - type: Physics + bodyType: Static + canCollide: true + - type: InteractionOutline + - type: Sprite + sprite: Mobs/Aliens/Asteroid/goliath.rsi + layers: + - state: goliath_tentacle_wiggle + - type: StunOnContact + blacklist: + tags: + - Goliath + - type: Fixtures + fixtures: + fix: + shape: + !type:PhysShapeAabb + bounds: "-0.45,-0.45,0.45,0.45" + mask: + - Impassable + layer: + - Impassable + hard: false + - type: TimedDespawn #do this shit by hand because of fucking course. + lifetime: 0.4 + - type: SpawnOnDespawn + prototype: EffectGoliathTentacleRetract + +- type: entity + id: BaseEffectGoliathTentacleSpawn + categories: [ HideSpawnMenu ] + name: tentacle + abstract: true + components: + - type: Transform + anchored: True + - type: Physics + bodyType: Static + canCollide: false + - type: Sprite + sprite: Mobs/Aliens/Asteroid/goliath.rsi + - type: InteractionOutline + - type: TimedDespawn + lifetime: 0.7 + +- type: entity + id: EffectGoliathTentacleSpawn + parent: BaseEffectGoliathTentacleSpawn + categories: [ HideSpawnMenu ] + name: tentacle + components: + - type: Sprite + state: goliath_tentacle_spawn + - type: SpawnOnDespawn + prototype: GoliathTentacle + +- type: entity + id: EffectGoliathTentacleRetract + parent: BaseEffectGoliathTentacleSpawn + categories: [ HideSpawnMenu ] + components: + - type: Sprite + state: goliath_tentacle_retract + - type: EffectVisuals + - type: AnimationPlayer diff --git a/Resources/Prototypes/Entities/Objects/Materials/materials.yml b/Resources/Prototypes/Entities/Objects/Materials/materials.yml index e00f3e65d3..867b83f9ff 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/materials.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/materials.yml @@ -510,7 +510,7 @@ flavors: - banana - type: Food - trash: + trash: - TrashBananiumPeel - type: BadFood - type: SolutionContainerManager @@ -654,3 +654,40 @@ Gunpowder: 100 - type: Item size: Tiny + +- type: entity + parent: MaterialBase + id: MaterialGoliathHide + name: goliath hide plates + description: Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna. + suffix: Full + components: + - type: Sprite + sprite: Objects/Materials/hide.rsi + layers: + - state: goliath_hide + map: [ "base" ] + - type: StaticPrice + price: 0 + - type: StackPrice + price: 1500 + - type: Appearance + - type: Stack + stackType: GoliathHide + baseLayer: base + layerStates: + - goliath_hide + - goliath_hide_2 + - goliath_hide_3 + - type: Item + size: Large + shape: + - 0,0,2,2 + +- type: entity + parent: MaterialGoliathHide + id: MaterialGoliathHide1 + suffix: 1 + components: + - type: Stack + count: 1 diff --git a/Resources/Prototypes/NPCs/goliath.yml b/Resources/Prototypes/NPCs/goliath.yml new file mode 100644 index 0000000000..0befc5d581 --- /dev/null +++ b/Resources/Prototypes/NPCs/goliath.yml @@ -0,0 +1,75 @@ +- type: htnCompound + id: GoliathCompound + branches: + - tasks: + - !type:HTNCompoundTask + task: GoliathMeleeCombatPrecondition + - tasks: + - !type:HTNCompoundTask + task: IdleCompound + +- type: htnCompound + id: GoliathMeleeCombatPrecondition + branches: + - preconditions: + - !type:BuckledPrecondition + isBuckled: true + tasks: + - !type:HTNPrimitiveTask + operator: !type:UnbuckleOperator + shutdownState: TaskFinished + + - preconditions: + - !type:InContainerPrecondition + isInContainer: true + tasks: + - !type:HTNCompoundTask + task: EscapeCompound + + - preconditions: + - !type:PulledPrecondition + isPulled: true + tasks: + - !type:HTNPrimitiveTask + operator: !type:UnPullOperator + shutdownState: TaskFinished + + - tasks: + - !type:HTNPrimitiveTask + operator: !type:UtilityOperator + proto: NearbyMeleeTargets + - !type:HTNCompoundTask + task: GoliathAttackTargetCompound + +- type: htnCompound + id: GoliathAttackTargetCompound + branches: + - preconditions: + - !type:KeyExistsPrecondition + key: Target + tasks: + - !type:HTNPrimitiveTask + operator: !type:MoveToOperator + shutdownState: PlanFinished + pathfindInPlanning: true + removeKeyOnFinish: false + targetKey: TargetCoordinates + pathfindKey: TargetPathfind + rangeKey: MeleeRange + - !type:HTNPrimitiveTask + operator: !type:JukeOperator + jukeType: AdjacentTile + - !type:HTNPrimitiveTask + operator: !type:MeleeOperator + targetKey: Target + preconditions: + - !type:KeyExistsPrecondition + key: Target + - !type:TargetInRangePrecondition + targetKey: Target + rangeKey: MeleeRange + services: + - !type:UtilityService + id: MeleeService + proto: NearbyMeleeTargets + key: Target diff --git a/Resources/Prototypes/Procedural/vgroid.yml b/Resources/Prototypes/Procedural/vgroid.yml index 4371e9cad5..315f908fad 100644 --- a/Resources/Prototypes/Procedural/vgroid.yml +++ b/Resources/Prototypes/Procedural/vgroid.yml @@ -145,7 +145,7 @@ minCount: 5 maxCount: 8 groups: - - id: MobXeno + - id: MobGoliath amount: 1 #- type: dungeonConfig @@ -175,7 +175,7 @@ minCount: 20 maxCount: 30 groups: - - id: MobXeno + - id: MobGoliath amount: 1 #- type: dungeonConfig diff --git a/Resources/Prototypes/Stacks/Materials/materials.yml b/Resources/Prototypes/Stacks/Materials/materials.yml index 1157dc3f00..049f538bcc 100644 --- a/Resources/Prototypes/Stacks/Materials/materials.yml +++ b/Resources/Prototypes/Stacks/Materials/materials.yml @@ -88,3 +88,10 @@ icon: { sprite: /Textures/Objects/Misc/reagent_fillings.rsi, state: powderpile } spawn: MaterialGunpowder maxCount: 60 + +- type: stack + id: GoliathHide + name: goliath hide + icon: { sprite: /Textures/Objects/Materials/hide.rsi, state: goliath_hide } + spawn: MaterialGoliathHide1 + maxCount: 30 diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 5e1b5cbe4d..1e3ae71958 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -656,6 +656,9 @@ - type: Tag id: Goat +- type: Tag + id: Goliath + - type: Tag id: GPS diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath.png new file mode 100644 index 0000000000..5839a35796 Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_alert.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_alert.png new file mode 100644 index 0000000000..c4c0b8efbe Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_alert.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_dead.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_dead.png new file mode 100644 index 0000000000..e6978b2890 Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_dead.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_preattack.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_preattack.png new file mode 100644 index 0000000000..743e9f35be Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_preattack.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_retract.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_retract.png new file mode 100644 index 0000000000..d0895ccd15 Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_retract.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_spawn.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_spawn.png new file mode 100644 index 0000000000..9172b0099c Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_spawn.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_wiggle.png b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_wiggle.png new file mode 100644 index 0000000000..f762213403 Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/goliath_tentacle_wiggle.png differ diff --git a/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/meta.json new file mode 100644 index 0000000000..b9d3f2bd7f --- /dev/null +++ b/Resources/Textures/Mobs/Aliens/Asteroid/goliath.rsi/meta.json @@ -0,0 +1,111 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from Paradise at https://github.com/ParadiseSS13/Paradise/blob/5a68c5f6d3b60ee82c06e0287d1eb8108d2e1fe2/icons/mob/lavaland/lavaland_monsters.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "goliath", + "directions": 4 + }, + { + "name": "goliath_alert", + "directions": 4, + "delays": [ + [ + 1, + 0.2, + 1, + 0.5 + ], + [ + 1, + 0.2, + 1, + 0.5 + ], + [ + 1, + 0.2, + 1, + 0.5 + ], + [ + 1, + 0.2, + 1, + 0.5 + ] + ] + }, + { + "name": "goliath_preattack", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "goliath_dead" + }, + { + "name": "goliath_tentacle_spawn", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.1 + ] + ] + }, + { + "name": "goliath_tentacle_wiggle", + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "goliath_tentacle_retract", + "delays": [ + [ + 0.1, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide.png b/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide.png new file mode 100644 index 0000000000..04526a2dac Binary files /dev/null and b/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide.png differ diff --git a/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide_2.png b/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide_2.png new file mode 100644 index 0000000000..9b03018487 Binary files /dev/null and b/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide_2.png differ diff --git a/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide_3.png b/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide_3.png new file mode 100644 index 0000000000..c9a53d76f2 Binary files /dev/null and b/Resources/Textures/Objects/Materials/hide.rsi/goliath_hide_3.png differ diff --git a/Resources/Textures/Objects/Materials/hide.rsi/meta.json b/Resources/Textures/Objects/Materials/hide.rsi/meta.json new file mode 100644 index 0000000000..0ec2b25480 --- /dev/null +++ b/Resources/Textures/Objects/Materials/hide.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from Paradise at https://github.com/ParadiseSS13/Paradise/blob/88d236d5c91e9a57e103957555c2e9a8c63b68fa/icons/obj/stacks/organic.dmi", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "goliath_hide" + }, + { + "name": "goliath_hide_2" + }, + { + "name": "goliath_hide_3" + } + ] +} \ No newline at end of file