diff --git a/Content.Server/_Maid/Terminator/Components/HeatOverTimeComponent.cs b/Content.Server/_Maid/Terminator/Components/HeatOverTimeComponent.cs new file mode 100644 index 00000000000..3f6aac59788 --- /dev/null +++ b/Content.Server/_Maid/Terminator/Components/HeatOverTimeComponent.cs @@ -0,0 +1,32 @@ +using Content.Server._Maid.Terminator.EntitySystems; +using Robust.Shared.Serialization.TypeSerializers.Implementations; + +namespace Content.Server._Maid.Terminator.Components; + +[RegisterComponent, Access(typeof(HeatOverTimeSystem))] +public sealed partial class HeatOverTimeComponent : Component +{ + [DataField(required: true)] + public float Heat { get; set; } + + [DataField] + public float FireStacks { get; set; } + + [DataField(customTypeSerializer: typeof(TimespanSerializer))] + public TimeSpan Interval = TimeSpan.FromSeconds(1); + + [DataField] + public TimeSpan NextTickTime = TimeSpan.Zero; + + [DataField] + public bool IgnoreHeatResistance { get; set; } = false; + + [DataField] + public float MultiplierIncrease { get; set; } + + [DataField] + public float Multiplier { get; set; } = 1f; + + [DataField] + public float FireProtectionPenetration { get; set; } +} diff --git a/Content.Server/_Maid/Terminator/Components/SpawnOnGibComponent.cs b/Content.Server/_Maid/Terminator/Components/SpawnOnGibComponent.cs new file mode 100644 index 00000000000..9c6f18de3a6 --- /dev/null +++ b/Content.Server/_Maid/Terminator/Components/SpawnOnGibComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Prototypes; + +namespace Content.Server._Maid.Terminator.Components; + +[RegisterComponent] +public sealed partial class SpawnOnGibComponent : Component +{ + [DataField] public EntProtoId? Prototype; + [DataField] public bool TransferMind = false; +} \ No newline at end of file diff --git a/Content.Server/_Maid/Terminator/EntitySystems/HeatOverTimeSystem.cs b/Content.Server/_Maid/Terminator/EntitySystems/HeatOverTimeSystem.cs new file mode 100644 index 00000000000..e81a88ff9e8 --- /dev/null +++ b/Content.Server/_Maid/Terminator/EntitySystems/HeatOverTimeSystem.cs @@ -0,0 +1,56 @@ + +using Content.Server._Maid.Terminator.Components; +using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; +using Content.Server.Temperature.Systems; +using Content.Shared.Atmos.Components; +using Robust.Shared.Timing; + +namespace Content.Server._Maid.Terminator.EntitySystems; + +public sealed class HeatOverTimeSystem : EntitySystem +{ + [Dependency] private readonly FlammableSystem _flammable = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly TemperatureSystem _temperature = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnStartup); + } + + private void OnStartup(EntityUid uid, HeatOverTimeComponent component, ref ComponentStartup args) + { + if (component.NextTickTime == TimeSpan.Zero) + component.NextTickTime = _timing.CurTime; + } + + public override void Update(float frameTime) + { + var currentTime = _timing.CurTime; + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var uid, out var heatOverTimeComponent, out var flammableComponent)) + { + if (heatOverTimeComponent.Interval <= TimeSpan.Zero) + continue; + + while (currentTime >= heatOverTimeComponent.NextTickTime) + { + _temperature.ChangeHeat(uid, heatOverTimeComponent.Heat * heatOverTimeComponent.Multiplier, heatOverTimeComponent.IgnoreHeatResistance); + if (heatOverTimeComponent.FireStacks > 0f) + { + _flammable.AdjustFireStacks(uid, + heatOverTimeComponent.FireStacks * heatOverTimeComponent.Multiplier, + null, + true, + heatOverTimeComponent.FireProtectionPenetration); + } + + heatOverTimeComponent.Multiplier += heatOverTimeComponent.MultiplierIncrease; + heatOverTimeComponent.NextTickTime += heatOverTimeComponent.Interval; + } + } + } +} diff --git a/Content.Server/_Maid/Terminator/EntitySystems/SpawnOnGibSystem.cs b/Content.Server/_Maid/Terminator/EntitySystems/SpawnOnGibSystem.cs new file mode 100644 index 00000000000..58cda75f646 --- /dev/null +++ b/Content.Server/_Maid/Terminator/EntitySystems/SpawnOnGibSystem.cs @@ -0,0 +1,32 @@ +using Content.Server._Maid.Terminator.Components; +using Content.Server.Mind; +using Content.Shared.Body.Events; + +namespace Content.Server._Maid.Terminator.EntitySystems; + +// SpawnOnDespawnSystem will not do the trick cause no easy way to transfer mind without changing SpawnOnDespawnSystem itself +public sealed class SpawnOnGibSystem : EntitySystem +{ + [Dependency] private MindSystem _mindSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGibbed); + } + + private void OnGibbed(Entity ent, ref BeingGibbedEvent args) + { + if (!TryComp(ent, out TransformComponent? xform)) return; + + if (ent.Comp.Prototype == null) return; + + var spawned = Spawn(ent.Comp.Prototype, xform.Coordinates); + + if (ent.Comp.TransferMind && _mindSystem.TryGetMind(ent, out var mindId, out var mindComponent)) + { + _mindSystem.TransferTo(mindId, spawned); + } + } +} \ No newline at end of file diff --git a/Content.Server/_Maid/Terminator/GameTicking/Rules/TerminatorRuleComponent.cs b/Content.Server/_Maid/Terminator/GameTicking/Rules/TerminatorRuleComponent.cs new file mode 100644 index 00000000000..2db7f5f7c12 --- /dev/null +++ b/Content.Server/_Maid/Terminator/GameTicking/Rules/TerminatorRuleComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Whitelist; +using Robust.Shared.Audio; + +namespace Content.Server._Maid.Terminator.GameTicking.Rules; + +[RegisterComponent] +public sealed partial class TerminatorRuleComponent : Component +{ + [DataField] + public SoundSpecifier? BriefingSound; + + [DataField] + public EntityWhitelist? TargetBlacklist; + + [DataField] + public EntityUid? Target; +} diff --git a/Content.Server/_Maid/Terminator/GameTicking/Rules/TerminatorRuleSystem.cs b/Content.Server/_Maid/Terminator/GameTicking/Rules/TerminatorRuleSystem.cs new file mode 100644 index 00000000000..bad3580c6b4 --- /dev/null +++ b/Content.Server/_Maid/Terminator/GameTicking/Rules/TerminatorRuleSystem.cs @@ -0,0 +1,57 @@ +using Content.Server._Maid.Terminator.Roles; +using Content.Server.Antag; +using Content.Server.Body.Components; +using Content.Server.GameTicking.Rules; +using Content.Server.Mind; +using Content.Server.Objectives.Components; +using Content.Server.Roles; +using Content.Shared.GameTicking.Components; +using Content.Shared.Roles; +using Content.Shared.Roles.Jobs; +using Content.Shared.Whitelist; +using Robust.Shared.Random; + +namespace Content.Server._Maid.Terminator.GameTicking.Rules; + +public sealed class TerminatorRuleSystem : GameRuleSystem +{ + [Dependency] private readonly AntagSelectionSystem _antag = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + [Dependency] private readonly SharedJobSystem _jobs = default!; + [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedRoleSystem _role = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAntagSelectEntity); + SubscribeLocalEvent(AfterAntagSelected); + } + + private void OnAntagSelectEntity(Entity ent, ref AntagSelectEntityEvent args) + { + var allAliveHumanoids = _mind.GetAliveHumans(); + allAliveHumanoids.RemoveWhere(human => _whitelist.IsBlacklistPass(ent.Comp.TargetBlacklist, human)); + + if (allAliveHumanoids.Count == 0) + { + Log.Warning("Could not find any alive players to create a terminator for!"); + return; + } + + // pick a random player + var randomHumanoidMind = _random.Pick(allAliveHumanoids); + + ent.Comp.Target = randomHumanoidMind; + } + + private void AfterAntagSelected(Entity ent, ref AfterAntagEntitySelectedEvent args) + { + var targetComp = EnsureComp(args.EntityUid); + targetComp.Target = ent.Comp.Target; + + RemComp(args.EntityUid); + } +} diff --git a/Content.Server/_Maid/Terminator/Roles/TerminatorRoleComponent.cs b/Content.Server/_Maid/Terminator/Roles/TerminatorRoleComponent.cs new file mode 100644 index 00000000000..f9a84eca7a1 --- /dev/null +++ b/Content.Server/_Maid/Terminator/Roles/TerminatorRoleComponent.cs @@ -0,0 +1,9 @@ +using Content.Shared.Roles; + +namespace Content.Server._Maid.Terminator.Roles; + +[RegisterComponent] +public sealed partial class TerminatorRoleComponent : BaseMindRoleComponent +{ + +} diff --git a/Content.Server/_Maid/Triggers/Components/PopupOnTriggerComponent.cs b/Content.Server/_Maid/Triggers/Components/PopupOnTriggerComponent.cs new file mode 100644 index 00000000000..e2936a14676 --- /dev/null +++ b/Content.Server/_Maid/Triggers/Components/PopupOnTriggerComponent.cs @@ -0,0 +1,16 @@ +using Content.Shared.Popups; + +namespace Content.Server._Maid.Triggers.Components; + +/// +/// Displays a popup on a target entity when this entity is triggered. +/// +[RegisterComponent] +public sealed partial class PopupOnTriggerComponent : Component +{ + [DataField(required: true)] + public string Popup = string.Empty; + + [DataField] + public PopupType PopupType = PopupType.MediumCaution; +} diff --git a/Content.Server/_Maid/Triggers/EntitySystems/PopupOnTriggerSystem.cs b/Content.Server/_Maid/Triggers/EntitySystems/PopupOnTriggerSystem.cs new file mode 100644 index 00000000000..6110838c0a9 --- /dev/null +++ b/Content.Server/_Maid/Triggers/EntitySystems/PopupOnTriggerSystem.cs @@ -0,0 +1,27 @@ +using Content.Server.Explosion.EntitySystems; +using Content.Shared.Implants.Components; +using Content.Shared.Popups; +using Content.Shared.Trigger; + +namespace Content.Server._Maid.Triggers.EntitySystems; + +public sealed class PopupOnTriggerSystem : EntitySystem +{ + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnPopupTrigger); + } + + private void OnPopupTrigger(EntityUid uid, Components.PopupOnTriggerComponent component, ref TriggerEvent args) + { + if (!TryComp(uid, out SubdermalImplantComponent? implant) || implant.ImplantedEntity is null) + return; + + _popup.PopupEntity(Loc.GetString(component.Popup), implant.ImplantedEntity.Value, component.PopupType); + args.Handled = true; + } +} diff --git a/Resources/Locale/en-US/_Maid/Terminator/terminator.ftl b/Resources/Locale/en-US/_Maid/Terminator/terminator.ftl new file mode 100644 index 00000000000..29b9c7ff96d --- /dev/null +++ b/Resources/Locale/en-US/_Maid/Terminator/terminator.ftl @@ -0,0 +1,23 @@ +terminator-round-end-agent-name = nt-800 + +objective-issuer-susnet = [color=#d64119]Susnet[/color] + +terminator-role-greeting = + You are the Terminator, a relentless assassin sent into the past to secure our future. + Eliminate the target while minimizing changes to the timeline. + +terminator-role-briefing = Kill the target at all costs. + +terminator-endoskeleton-gib-popup = All the battered flesh falls apart, revealing a titanium endoskeleton! +terminator-endoskeleton-burn-popup = The seared flesh is burned to a crisp, revealing a titanium endoskeleton! + +ghost-role-information-exterminator-name = Terminator +ghost-role-information-exterminator-description = You have been sent back in time to terminate a target with high importance to the future. +ghost-role-information-exterminator-rules = + You are an antagonist who must kill your target to preserve the future. + You must also minimize changes to the timeline by avoiding unnecessary casualties and station damage. + +roles-antag-terminator-name = Terminator +roles-antag-terminator-objective = Kill the target while minimizing changes to the timeline. The future depends on it. + +terminator-overheat-popup = Your internal systems start to overheat! diff --git a/Resources/Locale/en-US/_Maid/mind/role-types.ftl b/Resources/Locale/en-US/_Maid/mind/role-types.ftl new file mode 100644 index 00000000000..7259663bebc --- /dev/null +++ b/Resources/Locale/en-US/_Maid/mind/role-types.ftl @@ -0,0 +1 @@ +role-subtype-terminator = Terminator diff --git a/Resources/Locale/en-US/objectives/conditions/terminate.ftl b/Resources/Locale/en-US/objectives/conditions/terminate.ftl new file mode 100644 index 00000000000..c88c7b14dae --- /dev/null +++ b/Resources/Locale/en-US/objectives/conditions/terminate.ftl @@ -0,0 +1 @@ +objective-terminate-title = Terminate {$targetName}, {CAPITALIZE($job)} diff --git a/Resources/Locale/ru-RU/_Maid/Terminator/terminator.ftl b/Resources/Locale/ru-RU/_Maid/Terminator/terminator.ftl new file mode 100644 index 00000000000..4be9a18d0c2 --- /dev/null +++ b/Resources/Locale/ru-RU/_Maid/Terminator/terminator.ftl @@ -0,0 +1,23 @@ +terminator-round-end-agent-name = nt-800 + +objective-issuer-susnet = [color=#d64119]Susnet[/color] + +terminator-role-greeting = + Вы - терминатор, безжалостный убийца, отправленный в прошлое, чтобы обеспечить наше будущее. + Устраните цель минимизируя изменения таймлайна. + +terminator-role-briefing = Убейте цель любой ценой. + +terminator-endoskeleton-gib-popup = Избитая плоть разваливается, обнажая титановый эндоскелет! +terminator-endoskeleton-burn-popup = Обугленная плоть сгорает дотла, обнажая титановый эндоскелет! + +ghost-role-information-exterminator-name = Терминатор +ghost-role-information-exterminator-description = Вас отправили назад во времени, чтобы устранить цель, крайне важную для будущего. +ghost-role-information-exterminator-rules = + Вы антагонист, которому необходимо убить вашу цель для сохранения будущего. + Вам также необходимо минимизировать изменения таймлайна, избегая лишних жертв и порчи станции. + +roles-antag-terminator-name = Терминатор +roles-antag-terminator-objective = Убейте цель, минимизируя изменения в таймлайне, от этого зависит будущее. + +terminator-overheat-popup = Ваши внутренности начинают нагреваться! diff --git a/Resources/Locale/ru-RU/_Maid/mind/role-types.ftl b/Resources/Locale/ru-RU/_Maid/mind/role-types.ftl new file mode 100644 index 00000000000..3d330210b85 --- /dev/null +++ b/Resources/Locale/ru-RU/_Maid/mind/role-types.ftl @@ -0,0 +1 @@ +role-subtype-terminator = Терминатор diff --git a/Resources/Locale/ru-RU/_Maid/prototypes/actions/terminator.ftl b/Resources/Locale/ru-RU/_Maid/prototypes/actions/terminator.ftl new file mode 100644 index 00000000000..8d51b268f72 --- /dev/null +++ b/Resources/Locale/ru-RU/_Maid/prototypes/actions/terminator.ftl @@ -0,0 +1,2 @@ +ent-ActionActivateTerminatorOverheat = Активировать имплант перегрева + .desc = Активирует ваш внутренний имплант перегрева, быстро повышая внутреннюю температуру тела сверх безопасных пределов. diff --git a/Resources/Locale/ru-RU/_Maid/prototypes/entities/body/terminator.ftl b/Resources/Locale/ru-RU/_Maid/prototypes/entities/body/terminator.ftl new file mode 100644 index 00000000000..8637099dd9c --- /dev/null +++ b/Resources/Locale/ru-RU/_Maid/prototypes/entities/body/terminator.ftl @@ -0,0 +1,15 @@ +ent-PartTerminatorBase = часть тела nt-800 +ent-ChestTerminator = грудная клетка nt-800 +ent-GroinTerminator = пах nt-800 +ent-HeadTerminator = череп nt-800 + .desc = Его красные глаза погасли... пока что. +ent-LeftArmTerminator = левая рука nt-800 +ent-RightArmTerminator = правая рука nt-800 +ent-LeftHandTerminator = левая кисть nt-800 +ent-RightHandTerminator = правая кисть nt-800 +ent-LeftLegTerminator = левая нога nt-800 +ent-RightLegTerminator = правая нога nt-800 +ent-LeftFootTerminator = левая стопа nt-800 +ent-RightFootTerminator = правая стопа nt-800 +ent-MobTerminatorEndoskeleton = эндоскелет nt-800 «Терминатор» + .desc = Внутреннее ядро андроидов-инфильтраторов Susnet. diff --git a/Resources/Locale/ru-RU/_Maid/prototypes/entities/objects/implants/terminator.ftl b/Resources/Locale/ru-RU/_Maid/prototypes/entities/objects/implants/terminator.ftl new file mode 100644 index 00000000000..984a9e2c035 --- /dev/null +++ b/Resources/Locale/ru-RU/_Maid/prototypes/entities/objects/implants/terminator.ftl @@ -0,0 +1,4 @@ +ent-TerminatorOverheatImplant = имплант перегрева + .desc = Этот имплант быстро перегревает тело пользователя при активации. +ent-TerminatorSelfExplodeImplant = имплант микробомбы + .desc = Этот имплант взрывает пользователя при активации или после смерти. diff --git a/Resources/Locale/ru-RU/_Maid/prototypes/objectives/terminator.ftl b/Resources/Locale/ru-RU/_Maid/prototypes/objectives/terminator.ftl new file mode 100644 index 00000000000..66d5a9049a6 --- /dev/null +++ b/Resources/Locale/ru-RU/_Maid/prototypes/objectives/terminator.ftl @@ -0,0 +1,4 @@ +ent-TerminateObjective = { ent-BaseObjective } + .desc = Следуйте своей программе и устраните цель. +ent-ShutDownObjective = Отключение. + .desc = После завершения миссии умрите, чтобы экипаж не смог завладеть технологиями будущего. diff --git a/Resources/Locale/ru-RU/objectives/conditions/terminate.ftl b/Resources/Locale/ru-RU/objectives/conditions/terminate.ftl new file mode 100644 index 00000000000..a444501bbbc --- /dev/null +++ b/Resources/Locale/ru-RU/objectives/conditions/terminate.ftl @@ -0,0 +1 @@ +objective-terminate-title = Устранить {$targetName}, {CAPITALIZE($job)} diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 271c85bb141..c12eb44c3cb 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -203,6 +203,8 @@ # - id: SlasherSpawn # Goobstation - The Slasher #Maid - id: SpacePirates # Goobstation - you probably can read whom this rule spawns #- id: WraithMidround # Goobstation - Wraith + - id: TerminatorSpawn # Maid - Terminator + #TODO When Slasher is Ready - id: SlasherSpawn # Goobstation - The Slasher #TODO when midrounds are "reviewed" by the chudmins add them back - type: entity diff --git a/Resources/Prototypes/_Maid/Body/Prototypes/terminator.yml b/Resources/Prototypes/_Maid/Body/Prototypes/terminator.yml new file mode 100644 index 00000000000..f75a07d45ea --- /dev/null +++ b/Resources/Prototypes/_Maid/Body/Prototypes/terminator.yml @@ -0,0 +1,45 @@ +- type: body + id: TerminatorFlesh + name: exterminator + root: chest + slots: + head: + part: HeadHuman + connections: + - chest + chest: + part: ChestHuman + connections: + - groin + - right arm + - left arm + - head + groin: + part: GroinHuman + connections: + - right leg + - left leg + right arm: + part: RightArmHuman + connections: + - right hand + left arm: + part: LeftArmHuman + connections: + - left hand + right hand: + part: RightHandHuman + left hand: + part: LeftHandHuman + right leg: + part: RightLegHuman + connections: + - right foot + left leg: + part: LeftLegHuman + connections: + - left foot + right foot: + part: RightFootHuman + left foot: + part: LeftFootHuman \ No newline at end of file diff --git a/Resources/Prototypes/_Maid/Damage/modifier_sets.yml b/Resources/Prototypes/_Maid/Damage/modifier_sets.yml new file mode 100644 index 00000000000..8d6a7bb4d85 --- /dev/null +++ b/Resources/Prototypes/_Maid/Damage/modifier_sets.yml @@ -0,0 +1,25 @@ +- type: damageModifierSet + id: TerminatorFlesh + coefficients: + Blunt: 1.0 + Slash: 1.0 + Piercing: 1.0 + Heat: 1.0 + Shock: 1.0 + Cold: 1.0 + Caustic: 1.0 + Poison: 0.0 + Cellular: 0.0 + +- type: damageModifierSet + id: TerminatorCybernetic + coefficients: + Blunt: 0.8 + Slash: 0.3 + Piercing: 0.3 + Heat: 0.3 + Shock: 2.5 + Cold: 0.0 + Caustic: 0.0 + Poison: 0.0 + Cellular: 0.0 diff --git a/Resources/Prototypes/_Maid/GameRules/midround.yml b/Resources/Prototypes/_Maid/GameRules/midround.yml new file mode 100644 index 00000000000..a131233298a --- /dev/null +++ b/Resources/Prototypes/_Maid/GameRules/midround.yml @@ -0,0 +1,46 @@ +# Terminator +- type: entity + parent: BaseGameRule + id: TerminatorSpawn + components: + - type: StationEvent + weight: 8 + earliestStart: 30 + minimumPlayers: 15 + maxOccurrences: 1 + duration: null + chaos: + Hostile: 120 + Combat: 120 + Death: 180 + Medical: 180 + eventType: HostilesSpawn + - type: GameRule + chaosScore: 300 + - type: AntagSpawner + prototype: MobHumanTerminator + - type: AntagRandomSpawn + - type: AntagObjectives + objectives: + - TerminateObjective + - ShutDownObjective + - type: TerminatorRule + targetBlacklist: + components: + - AntagImmune + - BorgBrain + - type: AntagSelection + agentName: terminator-round-end-agent-name + definitions: + - spawnerPrototype: SpawnPointGhostTerminator + min: 1 + max: 1 + pickPlayer: false + mindRoles: + - MindRoleTerminator + briefing: + text: terminator-role-greeting + color: red + - type: Tag + tags: + - MidroundAntag diff --git a/Resources/Prototypes/_Maid/Terminator/actions.yml b/Resources/Prototypes/_Maid/Terminator/actions.yml new file mode 100644 index 00000000000..523c3074c21 --- /dev/null +++ b/Resources/Prototypes/_Maid/Terminator/actions.yml @@ -0,0 +1,11 @@ +- type: entity + parent: [BaseSuicideAction, BaseImplantAction] + id: ActionActivateTerminatorOverheat + name: Activate Overheat Implant + description: Activates your internal overheat implant, rapidly driving your internal temperature beyond safe limits. + categories: [ HideSpawnMenu ] + components: + - type: Action + itemIconStyle: BigAction + priority: -20 + icon: Interface/Actions/firestarter.png diff --git a/Resources/Prototypes/_Maid/Terminator/implants.yml b/Resources/Prototypes/_Maid/Terminator/implants.yml new file mode 100644 index 00000000000..0159c0dcfed --- /dev/null +++ b/Resources/Prototypes/_Maid/Terminator/implants.yml @@ -0,0 +1,55 @@ +- type: entity + parent: BaseSubdermalImplant + id: TerminatorOverheatImplant + name: overheat implant + description: This implant rapidly overheats the user's body upon activation or upon death. + categories: [ HideSpawnMenu ] + components: + - type: SubdermalImplant + implantationTimeMultiplier: 4 + permanent: true + implantAction: ActionActivateTerminatorOverheat + - type: TriggerOnActivateImplant + - type: AddComponentsOnTrigger + removeExisting: false + targetUser: true + components: + - type: HeatOverTime + heat: 500 + fireStacks: 0.5 + interval: 1 + ignoreHeatResistance: true + fireProtectionPenetration: 1 + multiplierIncrease: 1 + - type: PopupOnTrigger + popup: terminator-overheat-popup + - type: Tag + tags: + - SubdermalImplant + - HideContextMenu + +# Copy of MicroBombImplant, but decreased damage and no explosion on gib +- type: entity + parent: BaseSubdermalImplant + id: TerminatorSelfExplodeImplant + name: micro-bomb implant + description: This implant detonates the user upon activation or upon death. + categories: [ HideSpawnMenu ] + components: + - type: SubdermalImplant + implantationTimeMultiplier: 4 + permanent: true + implantAction: ActionActivateMicroBomb + - type: TriggerOnActivateImplant + - type: ExplodeOnTrigger + - type: Explosive + explosionType: MicroBomb + totalIntensity: 120 + intensitySlope: 5 + maxIntensity: 30 + canCreateVacuum: false + - type: Tag + tags: + - SubdermalImplant + - HideContextMenu + - MicroBomb diff --git a/Resources/Prototypes/_Maid/Terminator/mobs.yml b/Resources/Prototypes/_Maid/Terminator/mobs.yml new file mode 100644 index 00000000000..1875e0e4b6d --- /dev/null +++ b/Resources/Prototypes/_Maid/Terminator/mobs.yml @@ -0,0 +1,218 @@ +- type: entity + abstract: true + id: MobTerminatorBase + components: + - type: ZombieImmune + - type: FlashImmunity + +- type: entity + parent: [MobHuman, MobTerminatorBase] + id: MobHumanTerminator + name: exterminator + components: + - type: AutoImplant + implants: + - TerminatorOverheatImplant + - type: Barotrauma + damage: + types: + Blunt: 0.1 + - type: Stamina + decay: 6 + cooldown: 1 + critThreshold: 400 + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - Stutter + - BloodLoss + - Electrocution + - SlurredSpeech + - RatvarianLanguage + - PressureImmunity + - Muted + - ForcedSleep + - StaminaModifier + - RadiationProtection + - type: MobState + allowedStates: + - Alive + - Dead + - type: SpawnOnGib + prototype: MobTerminatorEndoskeleton + transferMind: true + - type: MobThresholds + thresholds: + 0: Alive + 200: Dead + - type: Flammable + damage: + types: + Heat: 6.0 + - type: Temperature + heatDamageThreshold: 390 + coldDamageThreshold: 240 + - type: Damageable + damageModifierSet: TerminatorFlesh + - type: Body + prototype: TerminatorFlesh + requiredLegs: 2 + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Heat + damage: 100 + behaviors: + - !type:PopupBehavior + popup: terminator-endoskeleton-burn-popup + popupType: LargeCaution + - !type:GibBehavior + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:PopupBehavior + popup: terminator-endoskeleton-gib-popup + popupType: LargeCaution + - !type:GibBehavior + - type: SlowOnDamage + speedModifierThresholds: + 70: 0.8 + 90: 0.6 + - type: MeleeWeapon + damage: + types: + Blunt: 10 + Structural: 10 + - type: RandomHumanoidAppearance + - type: Tag + tags: + - CanPilot + - FootstepSound + - DoorBumpOpener + - Unimplantable + +- type: entity + parent: + - MobCombat + - MobDamageable + - MobSiliconBase + - MobTerminatorBase + id: MobTerminatorEndoskeleton + name: nt-800 "exterminator" endoskeleton + description: The inner powerhouse of Susnet's infiltrator androids. + components: + - type: StatusEffects + allowed: + - Stutter + - Electrocution + - StaminaModifier + - RadiationProtection + - type: FloatingVisuals + - type: Grabbable + - type: AutoImplant + implants: + - TerminatorSelfExplodeImplant + - type: MovementSpeedModifier + baseWalkSpeed: 2.0 + baseSprintSpeed: 3.2 + - type: Sprite + drawdepth: Mobs + layers: + - map: [ "movement" ] + state: full + sprite: Mobs/Species/Terminator/parts.rsi + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.35 + density: 500 + mask: + - MobMask + layer: + - MobLayer + - type: MobThresholds + thresholds: + 0: Alive + 100: Dead + - type: Repairable + doAfterDelay: 15 + allowSelfRepair: false + - type: TypingIndicator + proto: robot + - type: Speech + speechSounds: Pai + - type: Damageable + damageModifierSet: TerminatorCybernetic + - type: Explosive + explosionType: Minibomb + totalIntensity: 20 + intensitySlope: 5 + maxIntensity: 10 + canCreateVacuum: false + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:ExplodeBehavior + - !type:PlaySoundBehavior + sound: /Audio/Effects/bone_rattle.ogg + - !type:SpawnEntitiesBehavior + spawn: + HeadTerminator: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Flammable + fireSpread: false + canResistFire: true + damage: + types: + Heat: 0 + - type: MeleeWeapon + animation: WeaponArcPunch + wideAnimation: WeaponArcThrust + altDisarm: false + angle: 20 + damage: + types: + Blunt: 15 + Structural: 5 + - type: Puller + needsHands: false + - type: Prying + pryPowered: true + force: true + - type: Tag + tags: + - DoorBumpOpener + - MindTransferTarget + - Unimplantable + + +- type: entity + parent: BaseItem + id: HeadTerminator + name: nt-800 skull + description: Its red eyes have powered down... for now. + components: + - type: Sprite + sprite: Mobs/Species/Terminator/parts.rsi + state: skull_icon + - type: Icon + sprite: Mobs/Species/Terminator/parts.rsi + state: skull_icon + - type: StaticPrice + price: 4000 + - type: Tag + tags: + - MindTransferTarget + - Head \ No newline at end of file diff --git a/Resources/Prototypes/_Maid/Terminator/objectives.yml b/Resources/Prototypes/_Maid/Terminator/objectives.yml new file mode 100644 index 00000000000..e4548a83c91 --- /dev/null +++ b/Resources/Prototypes/_Maid/Terminator/objectives.yml @@ -0,0 +1,37 @@ +- type: entity + abstract: true + parent: BaseObjective + id: BaseTerminatorObjective + components: + - type: Objective + difficulty: 1 + issuer: objective-issuer-susnet + - type: RoleRequirement + roles: + - TerminatorRole + +- type: entity + parent: [BaseTerminatorObjective, BaseKillObjective] + id: TerminateObjective + name: Terminate the target. + description: Follow your programming and terminate the target. + components: + - type: Objective + unique: false + - type: PickSpecificPerson + - type: TargetObjective + title: objective-terminate-title + - type: KillPersonCondition + requireDead: true + +- type: entity + parent: BaseTerminatorObjective + id: ShutDownObjective + name: Shut down. + description: Once the mission is complete, die to prevent the crew from stealing future technology. + components: + - type: Objective + icon: + sprite: Mobs/Species/Terminator/parts.rsi + state: skull_icon + - type: DieCondition diff --git a/Resources/Prototypes/_Maid/Terminator/roles.yml b/Resources/Prototypes/_Maid/Terminator/roles.yml new file mode 100644 index 00000000000..d5dce91984c --- /dev/null +++ b/Resources/Prototypes/_Maid/Terminator/roles.yml @@ -0,0 +1,35 @@ +- type: entity + parent: BaseMindRoleAntag + id: MindRoleTerminator + name: Terminator Role + components: + - type: MindRole + antagPrototype: Terminator + exclusiveAntag: true + roleType: SoloAntagonist + subtype: role-subtype-terminator + - type: TerminatorRole + +- type: antag + id: Terminator + name: roles-antag-terminator-name + antagonist: true + setPreference: false + objective: roles-antag-terminator-objective + +- type: entity + categories: [ HideSpawnMenu, Spawner ] + parent: BaseAntagSpawner + id: SpawnPointGhostTerminator + components: + - type: GhostRole + name: ghost-role-information-exterminator-name + description: ghost-role-information-exterminator-description + rules: ghost-role-information-exterminator-rules + mindRoles: + - MindRoleGhostRoleSoloAntagonist + - type: Sprite + layers: + - state: green + - sprite: Mobs/Species/Terminator/parts.rsi + state: full diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json index b146ad203f9..aa0c23be55c 100644 --- a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json +++ b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json @@ -8,7 +8,8 @@ }, "states": [ { - "name": "full" + "name": "full", + "directions": 4 }, { "name": "head_f",