From 9a3bbdbe893405ce546fae79efd13618e24059e6 Mon Sep 17 00:00:00 2001 From: fishbait Date: Sat, 22 Feb 2025 07:33:06 +0100 Subject: [PATCH] Bingle (#1519) * init * yupp * stuff for tonigth * death sprite * cleanup * added speech and passive regen * more cleanup * that if for today * stuff * fixed falling animation * yml split, and localisation * moved scale to serverside, linked bingle to pit for upgrade * Apply suggestions from durk Co-authored-by: Aiden * fixes * added upgrade sprite, added combat indicator * pit animation * added check for spawning in nullspace * trying to fix check error * test * Revert "test" * test 2 --------- Co-authored-by: unknown Co-authored-by: Fishbait Co-authored-by: Aiden (cherry picked from commit 6608e6eb74a870a882288ecd2af1cea6dcfc7a1a) --- .../Bingle/BingleFallingVisualsSystem.cs | 80 ++++++++ .../_Goobstation/Bingle/BingleSystem.cs | 43 +++++ .../_Goobstation/Bingle/BinglePitSystem.cs | 177 ++++++++++++++++++ .../_Goobstation/Bingle/BingleSystem.cs | 64 +++++++ .../_Goobstation/Bingle/BingleComponent.cs | 31 +++ .../_Goobstation/Bingle/BinglePitComponent.cs | 45 +++++ .../Bingle/BinglePitFallingComponent.cs | 40 ++++ .../en-US/_Goobstation/bingle/bingle.ftl | 20 ++ .../Structures/Specific/Binglepit.yml | 62 ++++++ .../Accents/full_replacements.yml | 21 +++ .../Entities/Markers/Spawners/bingle.yml | 28 +++ .../Entities/Mobs/Player/bingle.yml | 104 ++++++++++ .../_Goobstation/GameRules/bingleEvent.yml | 14 ++ .../_Goobstation/Voice/speech_verbs.yml | 33 ++++ .../Mobs/Bingle/bingle.rsi/Upgraded.png | Bin 0 -> 6359 bytes .../Mobs/Bingle/bingle.rsi/alive.png | Bin 0 -> 2080 bytes .../Mobs/Bingle/bingle.rsi/combat.png | Bin 0 -> 4435 bytes .../Mobs/Bingle/bingle.rsi/dead.png | Bin 0 -> 1076 bytes .../Mobs/Bingle/bingle.rsi/icon.png | Bin 0 -> 745 bytes .../Mobs/Bingle/bingle.rsi/meta.json | 39 ++++ .../Mobs/Bingle/bingle.rsi/pit.png | Bin 0 -> 2117 bytes 21 files changed, 801 insertions(+) create mode 100644 Content.Client/_Goobstation/Bingle/BingleFallingVisualsSystem.cs create mode 100644 Content.Client/_Goobstation/Bingle/BingleSystem.cs create mode 100644 Content.Server/_Goobstation/Bingle/BinglePitSystem.cs create mode 100644 Content.Server/_Goobstation/Bingle/BingleSystem.cs create mode 100644 Content.Shared/_Goobstation/Bingle/BingleComponent.cs create mode 100644 Content.Shared/_Goobstation/Bingle/BinglePitComponent.cs create mode 100644 Content.Shared/_Goobstation/Bingle/BinglePitFallingComponent.cs create mode 100644 Resources/Locale/en-US/_Goobstation/bingle/bingle.ftl create mode 100644 Resources/Prototypes/Entities/Structures/Specific/Binglepit.yml create mode 100644 Resources/Prototypes/_Goobstation/Accents/full_replacements.yml create mode 100644 Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/bingle.yml create mode 100644 Resources/Prototypes/_Goobstation/Entities/Mobs/Player/bingle.yml create mode 100644 Resources/Prototypes/_Goobstation/GameRules/bingleEvent.yml create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/Upgraded.png create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/alive.png create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/combat.png create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/dead.png create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/icon.png create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/meta.json create mode 100644 Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/pit.png diff --git a/Content.Client/_Goobstation/Bingle/BingleFallingVisualsSystem.cs b/Content.Client/_Goobstation/Bingle/BingleFallingVisualsSystem.cs new file mode 100644 index 0000000000..c310b308b2 --- /dev/null +++ b/Content.Client/_Goobstation/Bingle/BingleFallingVisualsSystem.cs @@ -0,0 +1,80 @@ +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Shared.Animations; +using Content.Shared._Goobstation.Bingle; + +namespace Content.Client._Goobstation.Bingle; + +/// +/// Handles the falling animation for entities that fall into a Binglepit. shamlesly copied from chasm +/// +public sealed class BingleFallingVisualsSystem : EntitySystem +{ + [Dependency] private readonly AnimationPlayerSystem _anim = default!; + + private readonly string _chasmFallAnimationKey = "chasm_fall"; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnComponentRemove); + } + + private void OnComponentInit(EntityUid uid, BinglePitFallingComponent component, ComponentInit args) + { + if (!TryComp(uid, out var sprite) || + TerminatingOrDeleted(uid)) + { + return; + } + + component.OriginalScale = sprite.Scale; + + var player = EnsureComp(uid); + if (_anim.HasRunningAnimation(player, _chasmFallAnimationKey)) + return; + + _anim.Play((uid, player), GetFallingAnimation(component), _chasmFallAnimationKey); + } + + private void OnComponentRemove(EntityUid uid, BinglePitFallingComponent component, ComponentRemove args) + { + if (!TryComp(uid, out var sprite) || TerminatingOrDeleted(uid)) + return; + + if (!TryComp(uid, out var player)) + return; + + //var player = EnsureComp(uid); + if (_anim.HasRunningAnimation(player, _chasmFallAnimationKey)) + _anim.Stop(player, _chasmFallAnimationKey); + + sprite.Scale = component.OriginalScale; + } + + private Animation GetFallingAnimation(BinglePitFallingComponent component) + { + var length = component.AnimationTime; + + return new Animation() + { + Length = length, + AnimationTracks = + { + new AnimationTrackComponentProperty() + { + ComponentType = typeof(SpriteComponent), + Property = nameof(SpriteComponent.Scale), + KeyFrames = + { + new AnimationTrackProperty.KeyFrame(component.OriginalScale, 0.0f), + new AnimationTrackProperty.KeyFrame(component.AnimationScale, length.Seconds), + }, + InterpolationMode = AnimationInterpolationMode.Cubic + } + } + }; + } +} diff --git a/Content.Client/_Goobstation/Bingle/BingleSystem.cs b/Content.Client/_Goobstation/Bingle/BingleSystem.cs new file mode 100644 index 0000000000..48364e049d --- /dev/null +++ b/Content.Client/_Goobstation/Bingle/BingleSystem.cs @@ -0,0 +1,43 @@ +using Robust.Client.GameObjects; +using Content.Shared._Goobstation.Bingle; +using Content.Shared.CombatMode; + +namespace Content.Client._Goobstation.Bingle; + +/// +/// handles the upgrade apperance from normal bingle to upgraded bingle +/// +public sealed class BingleSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeNetworkEvent(OnUpgradeChange); + SubscribeLocalEvent(OnCombatToggle); + } + + //make eyse glow red when combat mode engaged. + private void OnCombatToggle(EntityUid uid, BingleComponent component, ToggleCombatActionEvent args) + { + if (!TryComp(uid, out var sprite)) + return; + if (!TryComp(uid, out var combat)) + return; + if (!sprite.LayerMapTryGet(BingleVisual.Combat, out var layer)) + return; + + sprite.LayerSetVisible(layer, combat.IsInCombatMode); + } + + private void OnUpgradeChange(BingleUpgradeEntityMessage args) + { + var uid = GetEntity(args.Bingle); + + if (!TryComp(uid, out var sprite)) + return; + if (!sprite.LayerMapTryGet(BingleVisual.Upgraded, out var layer)) + return; + + sprite.LayerSetVisible(layer, true); + } +} diff --git a/Content.Server/_Goobstation/Bingle/BinglePitSystem.cs b/Content.Server/_Goobstation/Bingle/BinglePitSystem.cs new file mode 100644 index 0000000000..cea0ac3199 --- /dev/null +++ b/Content.Server/_Goobstation/Bingle/BinglePitSystem.cs @@ -0,0 +1,177 @@ +using System.Numerics; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Timing; +using Robust.Server.GameObjects; +using Content.Server.Stunnable; +using Content.Shared.Ghost.Roles.Components; +using Content.Shared.StepTrigger.Systems; +using Content.Shared.Mobs.Components; +using Content.Shared.Destructible; +using Content.Shared.Stunnable; +using Content.Shared.Humanoid; +using Content.Shared.Weapons.Melee.Events; +using Content.Shared.Movement.Events; +using Content.Shared._Goobstation.Bingle; +using Content.Shared.Popups; +using Content.Shared.Movement.Pulling.Components; +using Content.Shared.Movement.Pulling.Systems; + +namespace Content.Server._Goobstation.Bingle; + +public sealed class BinglePitSystem : EntitySystem +{ + [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly BingleSystem _bingleSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly StunSystem _stun = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly PullingSystem _pulling = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStepTriggered); + SubscribeLocalEvent(OnStepTriggerAttempt); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnDestruction); + SubscribeLocalEvent(OnAttacked); + SubscribeLocalEvent(OnUpdateCanMove); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var falling)) + { + if (_timing.CurTime < falling.NextDeletionTime) + continue; + + _containerSystem.Insert(uid, falling.Pit.Pit); + EnsureComp(uid); // used stuned to prevent any funny being done inside the pit + RemCompDeferred(uid, falling); + } + } + + private void OnInit(EntityUid uid, BinglePitComponent component, MapInitEvent args) + { + if (!Transform(uid).Coordinates.IsValid(EntityManager)) + QueueDel(uid); + component.Pit = _containerSystem.EnsureContainer(uid, "pit"); + } + + private void OnStepTriggered(EntityUid uid, BinglePitComponent component, ref StepTriggeredOffEvent args) + { + // dont swallow bingles + if (HasComp(args.Tripper)) + return; + // need to be at levl 2 or above to swallow anything alive + if (HasComp(args.Tripper) && component.Level < 2) + return; + if (HasComp(args.Tripper)) + return; + + StartFalling(uid, component, args.Tripper); + + if (component.BinglePoints >= component.SpawnNewAt) + { + SpawnBingle(uid, component); + component.BinglePoints -= component.SpawnNewAt; + } + } + + public void StartFalling(EntityUid uid, BinglePitComponent component, EntityUid tripper, bool playSound = true) + { + component.BinglePoints += HasComp(tripper) + ? component.PointsForAlive + (HasComp(tripper) + ? component.AdditionalPointsForHuman : 0) : 1; + + if (TryComp(tripper, out var pullable) && pullable.BeingPulled) + _pulling.TryStopPull(tripper, pullable); + + var fall = EnsureComp(tripper); + fall.Pit = component; + fall.NextDeletionTime = _timing.CurTime + fall.DeletionTime; + _stun.TryKnockdown(tripper, fall.DeletionTime, false); + + if (playSound) + _audio.PlayPvs(component.FallingSound, uid); + + } + + private void OnStepTriggerAttempt(EntityUid uid, BinglePitComponent component, ref StepTriggerAttemptEvent args) + => args.Continue = true; + + public void SpawnBingle(EntityUid uid, BinglePitComponent component) + { + Spawn(component.GhostRoleToSpawn, Transform(uid).Coordinates); + + component.MinionsMade++; + if (component.MinionsMade >= component.UpgradeMinionsAfter) + { + component.MinionsMade = 0; + component.Level++; + UpgradeBingles(uid, component); + } + } + + public void UpgradeBingles(EntityUid uid, BinglePitComponent component) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var queryUid, out var queryBingleComp)) + if (queryBingleComp.MyPit != null && queryBingleComp.MyPit.Value == uid) + _bingleSystem.UpgradeBingle(queryUid, queryBingleComp); + if (component.Level <= component.MaxSize) + ScaleUpPit(uid, component); + + _popup.PopupEntity(Loc.GetString("bingle-pit-grow"), uid); + } + + private void OnDestruction(EntityUid uid, BinglePitComponent component, DestructionEventArgs args) + { + if (component.Pit != null) + foreach (var pitUid in _containerSystem.EmptyContainer(component.Pit)) + { + RemComp(pitUid); + _stun.TryKnockdown(pitUid, TimeSpan.FromSeconds(2), false); + } + + RemoveAllBingleGhostRoles(uid, component);//remove all unclaimed ghostroles when pit is destroyed + + //Remove all falling when pit is destroyed, in the small chance somone is inbetween start and insert + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var fallingUid, out var fallingComp)) + RemCompDeferred(fallingUid, fallingComp); + } + + public void RemoveAllBingleGhostRoles(EntityUid uid, BinglePitComponent component) + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var queryGRMSUid, out var queryGRMScomp)) + if (queryGRMScomp.Prototype == "MobBingle") + if (Transform(uid).Coordinates == Transform(queryGRMSUid).Coordinates) + QueueDel(queryGRMSUid); // remove any unspawned bngle when pit is destroyed + } + private void OnAttacked(EntityUid uid, BinglePitComponent component, AttackedEvent args) + { + if (_containerSystem.ContainsEntity(uid, args.User)) + EnsureComp(args.User); + } + + private void OnUpdateCanMove(EntityUid uid, BinglePitFallingComponent component, UpdateCanMoveEvent args) + => args.Cancel(); + + private void ScaleUpPit(EntityUid uid, BinglePitComponent component) + { + if (!TryComp(uid, out var appearanceComponent)) + appearanceComponent = _entityManager.EnsureComponent(uid); + var appearance = _entityManager.System(); + _entityManager.EnsureComponent(uid); + + appearance.SetData(uid, ScaleVisuals.Scale, Vector2.One * component.Level, appearanceComponent); + } +} diff --git a/Content.Server/_Goobstation/Bingle/BingleSystem.cs b/Content.Server/_Goobstation/Bingle/BingleSystem.cs new file mode 100644 index 0000000000..c272529934 --- /dev/null +++ b/Content.Server/_Goobstation/Bingle/BingleSystem.cs @@ -0,0 +1,64 @@ +using Content.Shared.Weapons.Melee; +using Content.Shared.Interaction.Events; +using Content.Shared.Popups; +using Content.Shared._Goobstation.Bingle; +using Robust.Shared.Map; +using System.Numerics; + +namespace Content.Server._Goobstation.Bingle; + +public sealed class BingleSystem : EntitySystem +{ + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnAttackAttempt); + } + + private void OnMapInit(EntityUid uid, BingleComponent component, MapInitEvent args) + { + var cords = Transform(uid).Coordinates; + if (!cords.IsValid(EntityManager) || cords.Position == Vector2.Zero) + return; + if (MapId.Nullspace == Transform(uid).MapID) + return; + + if (component.Prime) + component.MyPit = Spawn("BinglePit", cords); + else + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var queryUid, out var _)) + if (cords == Transform(queryUid).Coordinates) + component.MyPit = queryUid; + } + } + + //ran by the pit to upgrade bingle damage + public void UpgradeBingle(EntityUid uid, BingleComponent component) + { + if (component.Upgraded) + return; + if (!TryComp(uid, out var weponComp)) + return; + + weponComp.Damage = component.UpgradeDamage; + component.Upgraded = true; + Dirty(uid, weponComp); + + _popup.PopupEntity(Loc.GetString("bingle-upgrade-success"), uid, uid); + + RaiseNetworkEvent(new BingleUpgradeEntityMessage(GetNetEntity(uid))); + } + + private void OnAttackAttempt(EntityUid uid, BingleComponent component, AttackAttemptEvent args) + { + //Prevent Friendly Bingle fire + if (HasComp(args.Target) || HasComp(args.Target)) + args.Cancel(); + } +} + diff --git a/Content.Shared/_Goobstation/Bingle/BingleComponent.cs b/Content.Shared/_Goobstation/Bingle/BingleComponent.cs new file mode 100644 index 0000000000..903bb7e265 --- /dev/null +++ b/Content.Shared/_Goobstation/Bingle/BingleComponent.cs @@ -0,0 +1,31 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +using Content.Shared.Damage; +using Robust.Shared.Network; + +namespace Content.Shared._Goobstation.Bingle; + +[RegisterComponent, NetworkedComponent] +public sealed partial class BingleComponent : Component +{ + [DataField] + public bool Upgraded = false; + [DataField] + public DamageSpecifier UpgradeDamage = default!; + [DataField] + public bool Prime = false; + + public EntityUid? MyPit; +} +[Serializable, NetSerializable] +public sealed class BingleUpgradeEntityMessage(NetEntity bingle) : EntityEventArgs +{ + public NetEntity Bingle = bingle; +} + +[Serializable, NetSerializable] +public enum BingleVisual : byte +{ + Upgraded, + Combat +} diff --git a/Content.Shared/_Goobstation/Bingle/BinglePitComponent.cs b/Content.Shared/_Goobstation/Bingle/BinglePitComponent.cs new file mode 100644 index 0000000000..6e99b0ae5a --- /dev/null +++ b/Content.Shared/_Goobstation/Bingle/BinglePitComponent.cs @@ -0,0 +1,45 @@ +using Robust.Shared.Containers; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Shared._Goobstation.Bingle; + +[RegisterComponent] +public sealed partial class BinglePitComponent : Component +{ + /// + /// ammount of stored + /// + [DataField] + public float BinglePoints = 0f; + public float PointsForAlive = 5f; + public float AdditionalPointsForHuman = 5f; + /// + /// amount of Bingle Points needed for a new bingle + /// + [DataField] + public float SpawnNewAt = 10f; + + /// + /// amount bingles needed to evolve / gain a level / expand the ... THE FACTORY MUST GROW + /// + [DataField] + public float MinionsMade = 0f; + + [DataField] + public float UpgradeMinionsAfter = 12f; + + /// + /// the Bingle pit's level + /// + [DataField] + public float Level = 1f; + /// + /// Where the entities go when it falls into the pit, empties when it is destroyed. + /// + public Container Pit = default!; + [DataField] + public float MaxSize = 3f; + public SoundSpecifier FallingSound = new SoundPathSpecifier("/Audio/Effects/falling.ogg"); + public EntProtoId GhostRoleToSpawn = "SpawnPointGhostBingle"; +} diff --git a/Content.Shared/_Goobstation/Bingle/BinglePitFallingComponent.cs b/Content.Shared/_Goobstation/Bingle/BinglePitFallingComponent.cs new file mode 100644 index 0000000000..f0a96b01fc --- /dev/null +++ b/Content.Shared/_Goobstation/Bingle/BinglePitFallingComponent.cs @@ -0,0 +1,40 @@ +using System.Numerics; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; + +namespace Content.Shared._Goobstation.Bingle; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentPause] +public sealed partial class BinglePitFallingComponent : Component +{ + /// + /// Time it should take for the falling animation (scaling down) to complete. + /// + [DataField("animationTime")] + public TimeSpan AnimationTime = TimeSpan.FromSeconds(1.5f); + + /// + /// Time it should take in seconds for the entity to actually delete + /// + [DataField("deletionTime")] + public TimeSpan DeletionTime = TimeSpan.FromSeconds(1.8f); + + [DataField("nextDeletionTime", customTypeSerializer:typeof(TimeOffsetSerializer))] + [AutoPausedField] + public TimeSpan NextDeletionTime = TimeSpan.Zero; + + /// + /// Original scale of the object so it can be restored if the component is removed in the middle of the animation + /// + public Vector2 OriginalScale = Vector2.Zero; + + /// + /// Scale that the animation should bring entities to. + /// + public Vector2 AnimationScale = new Vector2(0.01f, 0.01f); + + /// + /// the pit your about to fall into + /// + public BinglePitComponent Pit = new BinglePitComponent(); +} diff --git a/Resources/Locale/en-US/_Goobstation/bingle/bingle.ftl b/Resources/Locale/en-US/_Goobstation/bingle/bingle.ftl new file mode 100644 index 0000000000..b0595e478c --- /dev/null +++ b/Resources/Locale/en-US/_Goobstation/bingle/bingle.ftl @@ -0,0 +1,20 @@ + +bingle-accent-1 = Bingle +bingle-accent-2 = Bing +bingle-accent-3 = Bongle +bingle-accent-4 = Bong +bingle-accent-5 = BINGLE + +chat-speech-verb-name-bingle = Bingle +bingle-verb-1 = Croaks +bingle-verb-2 = Mumbles +bingle-verb-3 = Harks +bingle-verb-4 = Grumbles + +bingle-station-announcement = Bingle Bingle Bingle + +ghost-role-information-bingle-name = Bingle +ghost-role-information-bingle-description = The Pit is love. The Pit is life. The Pit must grow + +bingle-upgrade-success = You feel stronger +bingle-pit-grow = The pit grows larger diff --git a/Resources/Prototypes/Entities/Structures/Specific/Binglepit.yml b/Resources/Prototypes/Entities/Structures/Specific/Binglepit.yml new file mode 100644 index 0000000000..e7adc03a2e --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Specific/Binglepit.yml @@ -0,0 +1,62 @@ +- type: entity + id: BinglePit + name: binglepit + description: Looks Hungry + placement: + mode: SnapgridCenter + components: + - type: BinglePit + - type: StepTrigger + requiredTriggeredSpeed: 0 + intersectRatio: 0.4 + blacklist: + tags: + - Catwalk + triggerGroups: + types: + - Chasm + - type: Transform + anchored: true + - type: Physics + bodyType: Static + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - WallLayer + mask: + - ItemMask + density: 1000 + hard: false + - type: Sprite + drawdepth: FloorTiles + layers: + - sprite: _Goobstation/Mobs/Bingle/bingle.rsi + state: pit + - type: InteractionOutline + - type: Clickable + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Metallic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 256 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: EmitSoundOnSpawn + sound: + path: /Audio/Weapons/Guns/Gunshots/rocket_launcher.ogg + - type: RequireProjectileTarget + - type: SolutionContainerManager + solutions: + drainBuffer: + maxVol: 1000 + - type: Drain + unitsPerSecond: 10 + unitsDestroyedPerSecond: 10 diff --git a/Resources/Prototypes/_Goobstation/Accents/full_replacements.yml b/Resources/Prototypes/_Goobstation/Accents/full_replacements.yml new file mode 100644 index 0000000000..e8e46d0d01 --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Accents/full_replacements.yml @@ -0,0 +1,21 @@ +# Accents that work off of full replacements rather than word replacements. + +- type: accent + id: gondola + fullReplacements: + - accent-words-gondola-1 + +- type: accent + id: bingle + fullReplacements: + - bingle-accent-1 # for the odds + - bingle-accent-1 + - bingle-accent-1 + - bingle-accent-1 + - bingle-accent-1 + - bingle-accent-1 + - bingle-accent-1 + - bingle-accent-2 + - bingle-accent-3 + - bingle-accent-4 + - bingle-accent-5 diff --git a/Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/bingle.yml b/Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/bingle.yml new file mode 100644 index 0000000000..72195d1b5f --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Markers/Spawners/bingle.yml @@ -0,0 +1,28 @@ +- type: entity + id: SpawnPointGhostBingle + name: ghost role spawn point + suffix: Bingle + parent: MarkerBase + components: + - type: GhostRole + name: ghost-role-information-bingle-name + description: ghost-role-information-bingle-description + rules: ghost-role-information-freeagent-rules + raffle: + settings: short + - type: GhostRoleMobSpawner + prototype: MobBingle + - type: Sprite + sprite: Markers/jobs.rsi + layers: + - state: green + - sprite: _Goobstation/Mobs/Bingle/bingle.rsi + state: icon + +- type: entity + id: SpawnPointGhostBinglePrime + parent: SpawnPointGhostBingle + suffix: Prime + components: + - type: GhostRoleMobSpawner + prototype: MobBinglePrime diff --git a/Resources/Prototypes/_Goobstation/Entities/Mobs/Player/bingle.yml b/Resources/Prototypes/_Goobstation/Entities/Mobs/Player/bingle.yml new file mode 100644 index 0000000000..7153c49a5f --- /dev/null +++ b/Resources/Prototypes/_Goobstation/Entities/Mobs/Player/bingle.yml @@ -0,0 +1,104 @@ +- type: entity + name: bingle + id: MobBingle + parent: MobSpaceBasic + description: bingle + components: + - type: Bingle + upgradeDamage: + types: + Blunt: 14 + Structural: 28 + - type: GhostTakeoverAvailable + - type: GhostRole + name: ghost-role-information-bingle-name + description: ghost-role-information-bingle-description + rules: ghost-role-information-freeagent-rules + raffle: + settings: short + - type: Sprite + drawdepth: Mobs + sprite: _Goobstation/Mobs/Bingle/bingle.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base", "movement"] + state: alive + - map: ["enum.BingleVisual.Upgraded"] + state: Upgraded + visible: false + - map: ["enum.BingleVisual.Combat"] + state: combat + visible: false + - type: MobThresholds + thresholds: + 0: Alive + 140: Dead # by request + - type: MobState + allowedStates: + - Alive + - Dead + - type: DamageStateVisuals + rotate: true + states: + Alive: + Base: alive + Dead: + Base: dead + - type: Bloodstream + bloodMaxVolume: 100 + bloodReagent: Nitrogen # by request + - type: MeleeWeapon + soundHit: + path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg + angle: 0 + wideAnimationRotation: 0 + animation: WeaponArcSlash + damage: + types: + Blunt: 7 + Structural: 14 # breaks down the walls and airlocks in 10 hits + bluntStaminaDamageFactor: 2.0 + - type: MovementSpeedModifier + baseWalkSpeed : 2 # same as slime + baseSprintSpeed : 4 + - type: Stamina + critThreshold: 120 + - type: StaminaDamageOnHit # from stunbaton + damage: 15 + overtime: 40 + sound: /Audio/Weapons/egloves.ogg + - type: Damageable + damageContainer: OrganicPart # unsure if this is the right type + damageModifierSet: Bingle + - type: FootstepModifier + footstepSoundCollection: + path: /Audio/Effects/Footsteps/slime1.ogg + params: + volume: 3 + - type: TypingIndicator + proto: alien + - type: Speech + speechVerb: Bingle + speechSounds: Slime + - type: ReplacementAccent # prevent talking + accent: bingle + - type: PassiveDamage #passive Healing + allowedStates: + - Alive + damage: + types: + Poison: -0.1 + groups: + Brute: -0.1 + Burn: -0.1 + - type: NightVision + color: "#008080" + activateSound: null + deactivateSound: null + +- type: entity + id: MobBinglePrime + parent: MobBingle + suffix: Prime + components: + - type: Bingle + prime: true diff --git a/Resources/Prototypes/_Goobstation/GameRules/bingleEvent.yml b/Resources/Prototypes/_Goobstation/GameRules/bingleEvent.yml new file mode 100644 index 0000000000..087cba6897 --- /dev/null +++ b/Resources/Prototypes/_Goobstation/GameRules/bingleEvent.yml @@ -0,0 +1,14 @@ +- type: entity + id: BingleSpawn + parent: BaseStationEventShortDelay + components: + - type: StationEvent + startAnnouncement: bingle-station-announcement + startAudio: + path: /Audio/Announcements/attention.ogg + earliestStart: 20 + weight: 6 + duration: 50 + minimumPlayers: 15 + - type: RandomSpawnRule + prototype: SpawnPointGhostBinglePrime diff --git a/Resources/Prototypes/_Goobstation/Voice/speech_verbs.yml b/Resources/Prototypes/_Goobstation/Voice/speech_verbs.yml index 52a8d0d40e..ebce1c50be 100644 --- a/Resources/Prototypes/_Goobstation/Voice/speech_verbs.yml +++ b/Resources/Prototypes/_Goobstation/Voice/speech_verbs.yml @@ -6,3 +6,36 @@ path: /Audio/Machines/beep.ogg exclaimSound: path: /Audio/Machines/beep.ogg + +- type: speechVerb + id: Dead + name: chat-speech-verb-name-dead + speechVerbStrings: + - chat-speech-verb-dead-1 + - chat-speech-verb-dead-2 + - chat-speech-verb-dead-3 + - chat-speech-verb-dead-4 + - chat-speech-verb-dead-5 + - chat-speech-verb-dead-6 + - chat-speech-verb-dead-7 + - chat-speech-verb-dead-8 + - chat-speech-verb-dead-9 + +- type: speechVerb + id: VoiceModulator + name: chat-speech-verb-VoiceModulator-name + speechVerbStrings: + - chat-speech-verb-VoiceModulator-1 + - chat-speech-verb-VoiceModulator-2 + - chat-speech-verb-VoiceModulator-3 + - chat-speech-verb-VoiceModulator-4 + - chat-speech-verb-VoiceModulator-5 + +- type: speechVerb + id: Bingle + name: chat-speech-verb-name-bingle + speechVerbStrings: + - bingle-verb-1 + - bingle-verb-2 + - bingle-verb-3 + - bingle-verb-4 diff --git a/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/Upgraded.png b/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/Upgraded.png new file mode 100644 index 0000000000000000000000000000000000000000..6877c80670a70f6f4be8964fdd42633933f1090f GIT binary patch literal 6359 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 R0;def*}={J?3!)6{|`G16L|mt literal 0 HcmV?d00001 diff --git a/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/alive.png b/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/alive.png new file mode 100644 index 0000000000000000000000000000000000000000..8684a63ceeee094322a7afb3f84d0038ae1c1431 GIT binary patch literal 2080 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/dead.png b/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/dead.png new file mode 100644 index 0000000000000000000000000000000000000000..82d1c47d3f60617643833c854fb811af77119bb0 GIT binary patch literal 1076 zcmV-41k3x0P)EX>4Tx04R}tkv&MmP!xqvQ%glEf_4yb2vVKwq9Tr^ibb$c+6t{Yn7s54nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~E;uQ=NQw6)g%&Yhc)XAE?m4`7A0RZVOf`FAfT~$W zIuRFh`BgFa3LgRh1~DcvQ%`0Vv+%61d+MgTi}Eb*zCWv9DVPlKiNrCc8y4{f@$9Ch zbKWNov$CWRpA%0SbV1@ruFEdJaV|M5@XWB0P0tgDiN#VE%U#UMhDtm`98pw_@`aqs z3g<1(YPHVV_v9}O6||KM*J+I+fh8o7f(RLPR8WP5DD4_4Cem~s_wbK6{uH@na#g^{ zv49#>NRA);4}QLYkeQevU6TtrrTxlJDtqIJ1lHTZO zkt1MW8@RacX!0I#xdRM8>5?HilAo4PECTOm^i6qS=oaW(bLZAR$LRx*rCBZC00)P_ zM2WK3J>K2hJ-2^*+VlGXP~UQyU7p^x00006VoOIv0RI600RN!9r;`8x010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>Y`*6gcsXR-*s_02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00In2L_t(o!|hhTYui8=eYPZYS57i<<=P$$5u}|$vXyr5 zm^rim!p@yLcI#4VG#2clp%E>06p5UKB$UD2aSGNCm$Xo-2gc~`xO?CG-aQHE(WA%z zjzQC;yIhs(^XB8b!CxcbE>|U+ok24QiYx&D#5Z4`oP^#qsTl-xJjZUk2AjIj41&e$ z>rywLwQk&%=%B9p(c&CBW&6s54NgukknsrV-A`mZ0ss(u0y>_{=Q!9P4Fil8=LmhT z6B)gYp+T*KW2Wr@08DHD&wqUfo4O$O1flOiEdW4SM?|la&t0y{=da$#F;Tr{5V^5I zEu_(2kz3z`qpVjIm|b4g5@}Q*=W#`a$A=4IIggPiksM>QGu(b#!~gVtpdLKCyu!_w z50x{9O(qI`Pm;)atV)WEN3!>HJcsl0ZNL!RDODpk=ngc=EmE2vf@qz9meOdD!LsFMkcEJ4m=7}P?M uB}c!K+t#*j^i&@uVxK?pQPZQxzl{eb?;_dE13-TO0000X&cN7jkND~n_qf)dAaZ2f`gI+FZbho{m!}Po*R)djWh7SWuUsWdWz3Bu9U5y zZgh9+^+Z&U{GzuYscar>1tLyX*BvsXGck`bEC=5{DKQ#{%(XiYrQO&asORUZ(miTQ z`)5rkH(+WLV+LS2KYv@&)3fKskM@-+oe><@Z#LGXR4PfOQjxnW>jDq}V4^D~CU}!m z8RZzP~kBwd^nI^S4Zl3Xq)p65xeRuimyopzFWNdyptQR~L*^}1UB z+WR7z>Fde?#-}g0q}6JP@B3;GYv?ACu?CQ0LeT_XSp=pe8L;cS`SZ0V+)bdJ?N_Wqm%s%9G7AH@IsHqn0K5uk#*hYi7p zsPO5LE6@EOW&^h&mCos`k@G|V&;*EH_qRGzL`X-Nlcur-HN}l_Au9kdh=>q99MDMM5b1b`N1!@iHBK%}U6WWrl~tk~S6Y|`ii z09O%&ERax?OgVc4Y*Yki8lC%q$=GFhP5?%Az{@zMjuQYX*^DUCXr09ASrs7+ z&EH>+(;wRF*M{}K;>7nF9`r~?72gn&@y5TBfio~q4xIJ!__qK601jnXNoGw=04e|g b00;m8000000Mb*F00000NkvXXu0mjfmwihc literal 0 HcmV?d00001 diff --git a/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/meta.json b/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/meta.json new file mode 100644 index 0000000000..f9b9f4472d --- /dev/null +++ b/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/meta.json @@ -0,0 +1,39 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Brainrot HQ", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "alive", + "directions": 4 + }, + { + "name": "pit", + "delays": [ + [ + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "icon" + }, + { + "name": "dead" + }, + { + "name": "Upgraded", + "directions": 4 + }, + { + "name": "combat", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/pit.png b/Resources/Textures/_Goobstation/Mobs/Bingle/bingle.rsi/pit.png new file mode 100644 index 0000000000000000000000000000000000000000..8c9e88cc4498fbc71680fae42d289912e86cc31b GIT binary patch literal 2117 zcmV-L2)g%)P)|*ghFE^t9_rLn)b?gtdAASFAtGlUQUVqbdHq`^a z8cKqLG7o~mn%a83CddN7}PE;D`Me-EEi7D`x2#C&VT&`=5j_F06 z8VM3Gwhp$$wX|(aFX}}6n=Bx>i&@{g^RCTOzk2qx)MH>ZJ$0fXEyprCgX@S*UBgFz6Z|RxaiM6K&N_Df z>q%+8eemJppVLPzDSi6tala??+s}2>hj=cqDG(3V;it!K6grL!ks0-iQu>JaRRT;x z>an09&)CJ2pB6a%{OoiA2`|omTfDx!EJo4K`sl>5vAhsvi2$)B0W8Y-ql{MtW#a~6_@ZNE$?c+SeQ2KTuf)~LRKEOBH*m>}kjp5$ZFJ#b6cyE*OXXmluCG{r498M@{H8(Qy0V{UWEVzM(IPjG0`W_lwXFKC+VV z(ec-d-%q~l;A0n&2sVYjWe9&X0z7|(`6~c+0Ou_@PvLAK7Yoj2hvQe#C|hfbFZsye zJfvI7QEWEk#@^oA_@e~GGl+xiKH!JwXAsIMEfrNMt`*yYnk9>&FdR(4=)x^gp zNFqws!C(3!M5xxzkKyNe*J%vl7*Lpl1a<;rA_+xcg^yM7&mTW*R|B6Y;36+bLMt%P zs763MuTdALOgxP1IAky$=b|3%cn;%jD9h2$_!7y^MvRP46p#lfChXE_KKk&NB0z;) z<2(rlmOXz)0fvwiNrJbJJ}wUAD2h9~P7c71lJOho*;()@U`Bk#I37kH{aE_&s}T?t zNkSB}tIkK6*k%VJ+i`A_w)h@F@M|`d4QR+`qbNCw`mhHHh{>yjU$YCIH5W7)(kHaJ zwpB7d>xwT45uc;tMy+bY5&=1MS;#ZUE&$AZnBp1y;K7$A{M%h>3>hjzIbaB%HNnOP zh|qb)IDX*gJ3!5jh`&St3bhdC9KLh+ez}kVFeapfPaZJ5lzhry`iMK5rb@RDALqC& zQrraEIBw+SFrU8|Wu01|DD*3?=Nv*P^qCVs zk}!r}2=Mo~z&dL`)*c7O0M-~CMAuzXk1^N8d5v;@6@1qOpGzle_+q*K5dO-yL9($% zP-hUqsLkAQEVloA_(S#4c$CTQ8h)Q0>)>|?h`ZyCx?9Y-uyr;v_tjw6jB*$pOHIZ#qTH%&b$5whB>+Idhm6%>W%DjWP$p?;J?E|ye~AFY5F=JK zUL75Xdj3Lm&fAs!T)WnF;kU2GFl6XC9foITG``QN+IN01$olHWdJ6oiA<-z?n;72b zsB5lMPmRBht#6cUCjy2-FnbkucT>H*<`n&w0G#MM%Vv8FG{MDufF3f=4LMTF3q$g| zo?9XyI@dc9RavSX1eedrQ;eCG0*_xg@kqFnFvhI8j&`1o5PUtw}V-B!J zlxH2TIL112DIEedO6N6t%xU$gm6c4^aJ?uumv)taXq*oDOVBxg5an^^nNv?9)SFw~ zc^;tA7|G7r&rUMu?{S=^&qbl1<;%oOKSrMj=}dH#kmhNS&j4xXbFSV@{cg>w65wvO zQdbS0#P}GDAs$IV0#9YO`Tu~7yUTu+fSj}?QAASYijU9xA`8N%E=vUD+nEO96eRdgE=B;asE7(=YA+{TV~+I_0T>y> zH5yGMkOLsW_j1hhX9dQ%GjQG|A?h;jx( zO_#A4S#MMhAOTYH5n#+?;IUwA+y4(>&0Utky8y|{EZ%1KtAA+Vw2rg;9)VpNyNk7# zjzGR=18PPu*}ZX`SJOCc*z^AY&Oc|HOZh&7=ad7g5n#fKWRL(&ZrmCR3C);aka%4V zK_y8xzZr(goNkLt5zuG285~l`3lO67>PQfC7M+b`daRV0vMvOy@_t?;V|cUMT(Llu zWH}zka9&cJpR%qVfto?=y1((MYfh@?ox^^vH~D`+USnJR4gqm@3|V)JIUTbeGeTYD zTyIS0y5~CtWN>#G4DTauPLB5Z_8+1` vzG<$L{-gi^01jnXNoGw=04e|g00;m8000000Mb*F00000NkvXXu0mjf+5h)6 literal 0 HcmV?d00001