diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index 10a001be8b..c0f660d216 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -18,6 +18,7 @@ using Content.Server.Storage.Components; using Content.Server.Storage.EntitySystems; using Content.Server.Tabletop; using Content.Server.Tabletop.Components; +using Content.Server.Terminator.Systems; using Content.Shared.Administration; using Content.Shared.Administration.Components; using Content.Shared.Body.Components; @@ -30,6 +31,7 @@ using Content.Shared.Database; using Content.Shared.Electrocution; using Content.Shared.Interaction.Components; using Content.Shared.Inventory; +using Content.Shared.Mind.Components; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; @@ -72,6 +74,7 @@ public sealed partial class AdminVerbSystem [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly TabletopSystem _tabletopSystem = default!; + [Dependency] private readonly TerminatorSystem _terminator = default!; [Dependency] private readonly VomitSystem _vomitSystem = default!; [Dependency] private readonly WeldableSystem _weldableSystem = default!; [Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!; @@ -793,6 +796,7 @@ public sealed partial class AdminVerbSystem Message = Loc.GetString("admin-smite-super-speed-description"), }; args.Verbs.Add(superSpeed); + //Bonk Verb superBonkLite = new() { @@ -820,5 +824,27 @@ public sealed partial class AdminVerbSystem Impact = LogImpact.Extreme, }; args.Verbs.Add(superBonk); + + Verb terminate = new() + { + Text = "Terminate", + Category = VerbCategory.Smite, + Icon = new SpriteSpecifier.Rsi(new ("Mobs/Species/Terminator/parts.rsi"), "skull_icon"), + Act = () => + { + if (!TryComp(args.Target, out var mindContainer) || mindContainer.Mind == null) + return; + + var coords = Transform(args.Target).Coordinates; + var mindId = mindContainer.Mind.Value; + _terminator.CreateSpawner(coords, mindId); + + _popupSystem.PopupEntity(Loc.GetString("admin-smite-terminate-prompt"), args.Target, + args.Target, PopupType.LargeCaution); + }, + Impact = LogImpact.Extreme, + Message = Loc.GetString("admin-smite-terminate-description") + }; + args.Verbs.Add(terminate); } } diff --git a/Content.Server/Destructible/Thresholds/Behaviors/PopupBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/PopupBehavior.cs new file mode 100644 index 0000000000..59589c19aa --- /dev/null +++ b/Content.Server/Destructible/Thresholds/Behaviors/PopupBehavior.cs @@ -0,0 +1,30 @@ +using Content.Shared.Popups; + +namespace Content.Server.Destructible.Thresholds.Behaviors; + +/// +/// Shows a popup for everyone. +/// +[DataDefinition] +public sealed partial class PopupBehavior : IThresholdBehavior +{ + /// + /// Locale id of the popup message. + /// + [DataField("popup", required: true)] + public string Popup; + + /// + /// Type of popup to show. + /// + [DataField("popupType")] + public PopupType PopupType; + + public void Execute(EntityUid uid, DestructibleSystem system, EntityUid? cause = null) + { + var popup = system.EntityManager.System(); + // popup is placed at coords since the entity could be deleted after, no more popup then + var coords = system.EntityManager.GetComponent(uid).Coordinates; + popup.PopupCoordinates(Loc.GetString(Popup), coords, PopupType); + } +} diff --git a/Content.Server/Objectives/Components/TerminatorTargetOverrideComponent.cs b/Content.Server/Objectives/Components/TerminatorTargetOverrideComponent.cs new file mode 100644 index 0000000000..c66ff55f05 --- /dev/null +++ b/Content.Server/Objectives/Components/TerminatorTargetOverrideComponent.cs @@ -0,0 +1,12 @@ +using Content.Server.Objectives.Systems; + +namespace Content.Server.Objectives.Components; + +/// +/// Sets this objective's target to the exterminator's target override, if it has one. +/// If not it will be random. +/// +[RegisterComponent, Access(typeof(TerminatorTargetOverrideSystem))] +public sealed partial class TerminatorTargetOverrideComponent : Component +{ +} diff --git a/Content.Server/Objectives/Systems/TerminatorTargetOverrideSystem.cs b/Content.Server/Objectives/Systems/TerminatorTargetOverrideSystem.cs new file mode 100644 index 0000000000..0a81c2810e --- /dev/null +++ b/Content.Server/Objectives/Systems/TerminatorTargetOverrideSystem.cs @@ -0,0 +1,41 @@ +using Content.Server.Objectives.Components; +using Content.Server.Terminator.Components; +using Content.Shared.Mind; +using Content.Shared.Objectives.Components; + +namespace Content.Server.Objectives.Systems; + +/// +/// Handles copying the exterminator's target override to this objective. +/// +public sealed class TerminatorTargetOverrideSystem : EntitySystem +{ + [Dependency] private readonly TargetObjectiveSystem _target = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAssigned); + } + + private void OnAssigned(EntityUid uid, TerminatorTargetOverrideComponent comp, ref ObjectiveAssignedEvent args) + { + if (args.Mind.OwnedEntity == null) + { + args.Cancelled = true; + return; + } + + var user = args.Mind.OwnedEntity.Value; + if (!TryComp(user, out var terminator)) + { + args.Cancelled = true; + return; + } + + // this exterminator has a target override so set its objective target accordingly + if (terminator.Target != null) + _target.SetTarget(uid, terminator.Target.Value); + } +} diff --git a/Content.Server/Roles/RoleSystem.cs b/Content.Server/Roles/RoleSystem.cs index c53fa1cf9e..f7a5177357 100644 --- a/Content.Server/Roles/RoleSystem.cs +++ b/Content.Server/Roles/RoleSystem.cs @@ -15,6 +15,7 @@ public sealed class RoleSystem : SharedRoleSystem SubscribeAntagEvents(); SubscribeAntagEvents(); SubscribeAntagEvents(); + SubscribeAntagEvents(); SubscribeAntagEvents(); SubscribeAntagEvents(); SubscribeAntagEvents(); diff --git a/Content.Server/Roles/TerminatorRoleComponent.cs b/Content.Server/Roles/TerminatorRoleComponent.cs new file mode 100644 index 0000000000..4154e8ab69 --- /dev/null +++ b/Content.Server/Roles/TerminatorRoleComponent.cs @@ -0,0 +1,8 @@ +using Content.Shared.Roles; + +namespace Content.Server.Roles; + +[RegisterComponent] +public sealed partial class TerminatorRoleComponent : AntagonistRoleComponent +{ +} diff --git a/Content.Server/Terminator/Components/TerminatorComponent.cs b/Content.Server/Terminator/Components/TerminatorComponent.cs new file mode 100644 index 0000000000..9427f95eed --- /dev/null +++ b/Content.Server/Terminator/Components/TerminatorComponent.cs @@ -0,0 +1,19 @@ +using Content.Server.Terminator.Systems; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; + +namespace Content.Server.Terminator.Components; + +/// +/// Main terminator component, handles the target, if any, and objectives. +/// +[RegisterComponent, Access(typeof(TerminatorSystem))] +public sealed partial class TerminatorComponent : Component +{ + /// + /// Used to force the terminate objective's target. + /// If null it will be a random person. + /// + [DataField("target")] + public EntityUid? Target; +} diff --git a/Content.Server/Terminator/Components/TerminatorTargetComponent.cs b/Content.Server/Terminator/Components/TerminatorTargetComponent.cs new file mode 100644 index 0000000000..786cbd1167 --- /dev/null +++ b/Content.Server/Terminator/Components/TerminatorTargetComponent.cs @@ -0,0 +1,16 @@ +using Content.Server.Terminator.Systems; + +namespace Content.Server.Terminator.Components; + +/// +/// Sets after the ghost role spawns. +/// +[RegisterComponent, Access(typeof(TerminatorSystem))] +public sealed partial class TerminatorTargetComponent : Component +{ + /// + /// The target to set after the ghost role spawns. + /// + [DataField("target")] + public EntityUid? Target; +} diff --git a/Content.Server/Terminator/Systems/TerminatorSystem.cs b/Content.Server/Terminator/Systems/TerminatorSystem.cs new file mode 100644 index 0000000000..b669935277 --- /dev/null +++ b/Content.Server/Terminator/Systems/TerminatorSystem.cs @@ -0,0 +1,66 @@ +using Content.Server.Body.Components; +using Content.Server.GenericAntag; +using Content.Server.Ghost.Roles.Events; +using Content.Server.Roles; +using Content.Server.Terminator.Components; +using Content.Shared.Roles; +using Robust.Shared.Map; + +namespace Content.Server.Terminator.Systems; + +public sealed class TerminatorSystem : EntitySystem +{ + [Dependency] private readonly SharedRoleSystem _role = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnSpawned); + SubscribeLocalEvent(OnCreated); + } + + private void OnMapInit(EntityUid uid, TerminatorComponent comp, MapInitEvent args) + { + // cyborg doesn't need to breathe + RemComp(uid); + } + + private void OnSpawned(EntityUid uid, TerminatorComponent comp, GhostRoleSpawnerUsedEvent args) + { + if (!TryComp(args.Spawner, out var target)) + return; + + comp.Target = target.Target; + } + + private void OnCreated(EntityUid uid, TerminatorComponent comp, ref GenericAntagCreatedEvent args) + { + var mindId = args.MindId; + var mind = args.Mind; + + _role.MindAddRole(mindId, new RoleBriefingComponent + { + Briefing = Loc.GetString("terminator-role-briefing") + }, mind); + _role.MindAddRole(mindId, new TerminatorRoleComponent(), mind); + } + + /// + /// Create a spawner at a position and return it. + /// + /// Coordinates to create the spawner at + /// Optional target mind to force the terminator to target + public EntityUid CreateSpawner(EntityCoordinates coords, EntityUid? target) + { + var uid = Spawn("SpawnPointGhostTerminator", coords); + if (target != null) + { + var comp = EnsureComp(uid); + comp.Target = target; + } + + return uid; + } +} diff --git a/Resources/Locale/en-US/administration/smites.ftl b/Resources/Locale/en-US/administration/smites.ftl index e6b0f92b7a..fe8077a550 100644 --- a/Resources/Locale/en-US/administration/smites.ftl +++ b/Resources/Locale/en-US/administration/smites.ftl @@ -12,7 +12,8 @@ admin-smite-turned-ash-other = {CAPITALIZE($name)} turns into a pile of ash! admin-smite-stomach-removal-self = Your stomach feels hollow... admin-smite-run-walk-swap-prompt = You have to press shift to run! admin-smite-super-speed-prompt = You move at mach 0.8! -admin-smite-lung-removal-self = You can't breath! +admin-smite-lung-removal-self = You can't breathe! +admin-smite-terminate-prompt = I'll be back ## Smite descriptions @@ -57,6 +58,7 @@ admin-smite-disarm-prone-description = Makes them get disarmed 100% of the time admin-smite-garbage-can-description = Turn them into a garbage bin to emphasize what they remind you of. admin-smite-super-bonk-description = Slams them on every single table on the Station and beyond. admin-smite-super-bonk-lite-description= Slams them on every single table on the Station and beyond. Stops when the target is dead. +admin-smite-terminate-description = Creates a Terminator ghost role with the sole objective of killing them. ## Tricks descriptions diff --git a/Resources/Locale/en-US/game-ticking/game-rules/rule-terminator.ftl b/Resources/Locale/en-US/game-ticking/game-rules/rule-terminator.ftl new file mode 100644 index 0000000000..41237a5c10 --- /dev/null +++ b/Resources/Locale/en-US/game-ticking/game-rules/rule-terminator.ftl @@ -0,0 +1,14 @@ +terminator-round-end-agent-name = nt-800 + +objective-issuer-susnet = [color=#d64119]Susnet[/color] + +terminator-role-greeting = + You are the exterminator, a relentless assassin sent into the past to secure our future. + We need you to eliminate {$target}, {$job}. + Use any means at your disposal to complete the mission. + Glory to Cybersun. + +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! diff --git a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl index 25e334181b..45e25fe391 100644 --- a/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl +++ b/Resources/Locale/en-US/ghost/roles/ghost-role-component.ftl @@ -207,3 +207,7 @@ ghost-role-information-BreadDog-rules = You're an edible dog made of bread. Your ghost-role-information-Shiva-name = Shiva ghost-role-information-Shiva-description = Shiva, the stations first defender. Help the Head of Security in their work ghost-role-information-Shiva-rules = Protect security staff and the crew from danger. Stay with Security staff or around the Security department, try to disable criminals and not kill them if the situation allows for it. + +ghost-role-information-exterminator-name = Exterminator +ghost-role-information-exterminator-description = You been been sent back in time to terminate a target with high importance to the future. +ghost-role-information-exterminator-rules = You are an antagonist and may kill anyone that tries to stop you, but killing the target is always your top priority. 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 0000000000..c88c7b14da --- /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/en-US/prototypes/roles/antags.ftl b/Resources/Locale/en-US/prototypes/roles/antags.ftl index 2848300c19..1502a30208 100644 --- a/Resources/Locale/en-US/prototypes/roles/antags.ftl +++ b/Resources/Locale/en-US/prototypes/roles/antags.ftl @@ -29,4 +29,7 @@ roles-antag-space-ninja-name = Space Ninja roles-antag-space-ninja-objective = Use your stealth to sabotage the station, nom on electrical wires. roles-antag-thief-name = Thief -roles-antag-thief-objective = Add some NT property to your personal collection without using violence. \ No newline at end of file +roles-antag-thief-objective = Add some NT property to your personal collection without using violence. + +roles-antag-terminator-name = Terminator +roles-antag-terminator-objective = Kill the target at all costs, the future depends on it. diff --git a/Resources/Prototypes/Body/Parts/terminator.yml b/Resources/Prototypes/Body/Parts/terminator.yml new file mode 100644 index 0000000000..dec0c99f7c --- /dev/null +++ b/Resources/Prototypes/Body/Parts/terminator.yml @@ -0,0 +1,157 @@ +- type: entity + abstract: true + parent: BaseItem + id: PartTerminator + name: nt-800 body part + components: + - type: Sprite + sprite: Mobs/Species/Terminator/parts.rsi + - type: Icon + sprite: Mobs/Species/Terminator/parts.rsi + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Cybernetic + - type: BodyPart + - type: ContainerContainer + containers: + bodypart: !type:Container + ents: [] + - type: StaticPrice + price: 200 + +- type: entity + parent: PartTerminator + id: TorsoTerminator + name: nt-800 torso + components: + - type: Sprite + state: torso_m + - type: Icon + state: torso_m + - type: BodyPart + partType: Torso + +- type: entity + parent: PartTerminator + id: HeadTerminator + name: nt-800 skull + description: Its red eyes have powered down... for now. + components: + - type: Sprite + state: skull_icon + - type: Icon + state: skull_icon + - type: BodyPart + partType: Head + # killing a terminators worth big bucks + - type: StaticPrice + price: 2000 + - type: Tag + tags: + - Head + +- type: entity + parent: PartTerminator + id: LeftArmTerminator + name: left nt-800 arm + components: + - type: Sprite + state: l_arm + - type: Icon + state: l_arm + - type: BodyPart + partType: Arm + symmetry: Left + +- type: entity + parent: PartTerminator + id: RightArmTerminator + name: right nt-800 arm + components: + - type: Sprite + state: r_arm + - type: Icon + state: r_arm + - type: BodyPart + partType: Arm + symmetry: Right + +- type: entity + parent: PartTerminator + id: LeftHandTerminator + name: left nt-800 hand + components: + - type: Sprite + state: l_hand + - type: Icon + state: l_hand + - type: BodyPart + partType: Hand + symmetry: Left + +- type: entity + parent: PartTerminator + id: RightHandTerminator + name: right nt-800 hand + components: + - type: Sprite + state: r_hand + - type: Icon + state: r_hand + - type: BodyPart + partType: Hand + symmetry: Right + +- type: entity + parent: PartTerminator + id: LeftLegTerminator + name: left nt-800 leg + components: + - type: Sprite + state: l_leg + - type: Icon + state: l_leg + - type: BodyPart + partType: Leg + symmetry: Left + - type: MovementBodyPart + +- type: entity + parent: PartTerminator + id: RightLegTerminator + name: right nt-800 leg + components: + - type: Sprite + state: r_leg + - type: Icon + state: r_leg + - type: BodyPart + partType: Leg + symmetry: Right + - type: MovementBodyPart + +- type: entity + parent: PartTerminator + id: LeftFootTerminator + name: left nt-800 foot + components: + - type: Sprite + state: l_foot + - type: Icon + state: l_foot + - type: BodyPart + partType: Foot + symmetry: Left + +- type: entity + parent: PartTerminator + id: RightFootTerminator + name: right nt-800 foot + components: + - type: Sprite + state: r_foot + - type: Icon + state: r_foot + - type: BodyPart + partType: Foot + symmetry: Right diff --git a/Resources/Prototypes/Body/Prototypes/terminator.yml b/Resources/Prototypes/Body/Prototypes/terminator.yml new file mode 100644 index 0000000000..c271a89d86 --- /dev/null +++ b/Resources/Prototypes/Body/Prototypes/terminator.yml @@ -0,0 +1,85 @@ +# not quite human... +- type: body + id: TerminatorFlesh + name: exterminator + root: torso + slots: + head: + part: HeadHuman + connections: + - torso + organs: + brain: MobTerminatorEndoskeleton + torso: + part: TorsoHuman + connections: + - left arm + - right arm + - left leg + - right 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 + +# TODO: terminator body parts +- type: body + id: TerminatorEndoskeleton + name: terminatorEndoskeleton + root: torso + slots: + head: + part: HeadTerminator + connections: + - torso + torso: + part: TorsoTerminator + connections: + - left arm + - right arm + - left leg + - right leg + right arm: + part: RightArmTerminator + connections: + - right hand + left arm: + part: LeftArmTerminator + connections: + - left hand + right hand: + part: RightHandTerminator + left hand: + part: LeftHandTerminator + right leg: + part: RightLegTerminator + connections: + - right foot + left leg: + part: LeftLegTerminator + connections: + - left foot + right foot: + part: RightFootTerminator + left foot: + part: LeftFootTerminator diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 26904bc276..c56d7326b1 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -249,3 +249,41 @@ Cellular: 0.0 Heat: 2.5 Caustic: 0.0 + +# terminator's flesh damage set +- type: damageModifierSet + id: CyberneticFlesh + coefficients: + Blunt: 0.2 + Slash: 0.2 + Piercing: 0.1 + # fire and lasers burn it good + Heat: 1.0 + # zap + Shock: 1.5 + Cold: 0.25 + Caustic: 0.25 + # doesnt have organs to poison + Poison: 0.0 + Cellular: 0.0 + +# terminator's endoskeleton damage set +- type: damageModifierSet + id: Cybernetic + coefficients: + # bonk + Blunt: 1.0 + # alloy too hard to cut or shoot + Slash: 0.0 + Piercing: 0.0 + # no burning anymore + Heat: 0.0 + # zap zap + Shock: 2.5 + Cold: 0.0 + Caustic: 0.0 + Poison: 0.0 + Cellular: 0.0 + flatReductions: + # can't punch the endoskeleton to death + Blunt: 5 diff --git a/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml b/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml index 7e282cb98e..c7af6c8ab5 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/ghost_roles.yml @@ -136,3 +136,20 @@ - state: green - sprite: Objects/Weapons/Melee/energykatana.rsi state: icon + +- type: entity + parent: MarkerBase + id: SpawnPointGhostTerminator + name: terminator spawn point + components: + - type: GhostRole + name: ghost-role-information-exterminator-name + description: ghost-role-information-exterminator-description + rules: ghost-role-information-exterminator-rules + - type: GhostRoleMobSpawner + prototype: MobHumanTerminator + - type: Sprite + layers: + - state: green + - sprite: Mobs/Species/Terminator/parts.rsi + state: full diff --git a/Resources/Prototypes/Entities/Mobs/Player/terminator.yml b/Resources/Prototypes/Entities/Mobs/Player/terminator.yml new file mode 100644 index 0000000000..0867419f8b --- /dev/null +++ b/Resources/Prototypes/Entities/Mobs/Player/terminator.yml @@ -0,0 +1,183 @@ +- type: entity + parent: MobHuman + id: MobHumanTerminator + # uses random name generator dont worry + name: exterminator + components: + - type: Terminator + - type: GenericAntag + rule: Exterminator + # reduced barotrauma damage + - type: Barotrauma + damage: + types: + Blunt: 0.1 + # 4x stamina, faster recovery + - type: Stamina + decay: 6 + cooldown: 1 + critThreshold: 400 + # immune to space drugs, pax, temporary blindness + - type: StatusEffects + allowed: + - Stun + - KnockedDown + - SlowedDown + - Stutter + - Electrocution + - Drunk + - SlurredSpeech + - RatvarianLanguage + - PressureImmunity + - Muted + - ForcedSleep + - StaminaModifier + - type: MobState + allowedStates: + - Alive + - Dead + # endoskeleton need it + - type: TransferMindOnGib + - type: MobThresholds + thresholds: + 0: Alive + # used for health display its not possible to actually fall into crit + 200: Dead + # fire!!!! + - type: Flammable + damage: + types: + Heat: 2.0 + # slightly wider thresholds + - type: Temperature + heatDamageThreshold: 390 + coldDamageThreshold: 240 + # take terminator flesh damage + - type: Damageable + damageModifierSet: CyberneticFlesh + # only organ is an endoskeleton, which is transferred when flesh dies + - type: Body + prototype: TerminatorFlesh + # endoskeleton transformation when either you would get burned to crit or killed by any damage + # you will become an endoskeleton as your last chance to kill the target + - type: Destructible + thresholds: + # the burn trigger is first incase of a bombing or nuking, it might well do over 200 damage but 100 heat is more important + - 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 + # faster than humans when damaged + - type: SlowOnDamage + speedModifierThresholds: + 70: 0.8 + 90: 0.6 + # arnold is very strong + - type: MeleeWeapon + damage: + types: + Blunt: 10 + Structural: 10 + - type: RandomHumanoidAppearance + +- type: entity + parent: + - BaseMob + - MobCombat + - MobDamageable + - MobSiliconBase + id: MobTerminatorEndoskeleton + # you are now valid + name: nt-800 "exterminator" endoskeleton + description: The inner powerhouse of Susnet's infiltrator androids. Ridiculously hard alloy on the inside, unassuming flesh on the outside. + components: + - type: HumanoidAppearance + species: Terminator + - type: MovementSpeedModifier + baseWalkSpeed: 1.5 + baseSprintSpeed: 3.0 + - type: Sprite + sprite: Mobs/Species/Terminator/parts.rsi + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.35 + # he heavy + density: 500 + mask: + - MobMask + layer: + - MobLayer + - type: MobThresholds + thresholds: + 0: Alive + # gibbed at 200 so cant go crit + 200: Dead + # incase some weird stuff happens and the crew adopts a terminator + - type: Repairable + doAfterDelay: 15 + allowSelfRepair: false + - type: Body + prototype: TerminatorEndoskeleton + # lets it sit in the terminator flesh's brain slot + - type: Organ + - type: Brain + - type: TypingIndicator + proto: robot # beep boop borp + - type: Speech + speechSounds: Pai + - type: Damageable + damageModifierSet: Cybernetic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:PlaySoundBehavior + # endoSKELETON + sound: /Audio/Effects/bone_rattle.ogg + # a keepsake or a gift for cargo + - !type:SpawnEntitiesBehavior + spawn: + HeadTerminator: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + # for fire spreading around, the endoskeleton cannot burn + - type: Flammable + fireSpread: true + canResistFire: true + damage: + types: + Heat: 0 + # now his only weapon, but it is stronger + - type: MeleeWeapon + damage: + types: + Blunt: 15 + Structural: 5 + - type: Puller + needsHands: false + - type: Tag + tags: + - DoorBumpOpener + - ShoesRequiredStepTriggerImmune + # let mind transfer on gib work + - MindTransferTarget diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 57e83b6af5..3a0a993a38 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -260,6 +260,19 @@ lightBreakChancePerSecond: 0.0003 doorToggleChancePerSecond: 0.001 +# - type: entity +# parent: BaseGameRule +# id: TerminatorSpawn +# noSpawn: true +# components: +# - type: StationEvent +# weight: 8 +# duration: 1 +# earliestStart: 30 +# minimumPlayers: 20 +# - type: RandomSpawnRule +# prototype: SpawnPointGhostTerminator + - type: entity id: VentClog parent: BaseGameRule diff --git a/Resources/Prototypes/GameRules/midround.yml b/Resources/Prototypes/GameRules/midround.yml index 241ee931bb..28767e2c18 100644 --- a/Resources/Prototypes/GameRules/midround.yml +++ b/Resources/Prototypes/GameRules/midround.yml @@ -34,4 +34,15 @@ parent: BaseGameRule noSpawn: true components: - - type: ThiefRule \ No newline at end of file + - type: ThiefRule + +- type: entity + noSpawn: true + parent: BaseGameRule + id: Exterminator + components: + - type: GenericAntagRule + agentName: terminator-round-end-agent-name + objectives: + - TerminateObjective + - ShutDownObjective diff --git a/Resources/Prototypes/Objectives/terminator.yml b/Resources/Prototypes/Objectives/terminator.yml new file mode 100644 index 0000000000..1b569599a7 --- /dev/null +++ b/Resources/Prototypes/Objectives/terminator.yml @@ -0,0 +1,40 @@ +- type: entity + abstract: true + parent: BaseObjective + id: BaseTerminatorObjective + components: + - type: Objective + difficulty: 1 + issuer: susnet + - type: RoleRequirement + roles: + components: + - TerminatorRole + +- type: entity + noSpawn: true + parent: [BaseTerminatorObjective, BaseKillObjective] + id: TerminateObjective + description: Follow your programming and terminate the target. + components: + - type: Objective + unique: false + - type: TargetObjective + title: objective-terminate-title + - type: PickRandomPerson + - type: TerminatorTargetOverride + - type: KillPersonCondition + requireDead: true + +- type: entity + noSpawn: true + parent: BaseTerminatorObjective + id: ShutDownObjective + name: Shut down + description: Once the mission is complete die to prevent our technology from being stolen. + components: + - type: Objective + icon: + sprite: Mobs/Species/Terminator/parts.rsi + state: skull_icon + - type: DieCondition diff --git a/Resources/Prototypes/Roles/Antags/terminator.yml b/Resources/Prototypes/Roles/Antags/terminator.yml new file mode 100644 index 0000000000..ef1f176b8d --- /dev/null +++ b/Resources/Prototypes/Roles/Antags/terminator.yml @@ -0,0 +1,6 @@ +- type: antag + id: Terminator + name: roles-antag-terminator-name + antagonist: true + setPreference: false + objective: roles-antag-terminator-objective diff --git a/Resources/Prototypes/Species/terminator.yml b/Resources/Prototypes/Species/terminator.yml new file mode 100644 index 0000000000..cfc5a7107c --- /dev/null +++ b/Resources/Prototypes/Species/terminator.yml @@ -0,0 +1,110 @@ +- type: species + id: Terminator + name: Terminator + roundStart: false + prototype: MobTerminatorEndoskeleton + sprites: MobTerminatorSprites + defaultSkinTone: "#fff9e2" + markingLimits: MobHumanMarkingLimits + maleFirstNames: skeletonNamesFirst + femaleFirstNames: skeletonNamesFirst + dollPrototype: MobSkeletonPersonDummy + skinColoration: TintedHues + +- type: speciesBaseSprites + id: MobTerminatorSprites + sprites: + Head: MobTerminatorHead + Chest: MobTerminatorTorso + LArm: MobTerminatorLArm + RArm: MobTerminatorRArm + LHand: MobTerminatorLHand + RHand: MobTerminatorRHand + LLeg: MobTerminatorLLeg + RLeg: MobTerminatorRLeg + LFoot: MobTerminatorLFoot + RFoot: MobTerminatorRFoot + +- type: humanoidBaseSprite + id: MobTerminatorHead + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobTerminatorHeadMale + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: head_m + +- type: humanoidBaseSprite + id: MobTerminatorHeadFemale + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: head_f + +- type: humanoidBaseSprite + id: MobTerminatorTorso + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobTerminatorTorsoMale + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: torso_m + +- type: humanoidBaseSprite + id: MobTerminatorTorsoFemale + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: torso_f + +- type: humanoidBaseSprite + id: MobTerminatorLLeg + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: l_leg + +- type: humanoidBaseSprite + id: MobTerminatorLArm + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: l_arm + +- type: humanoidBaseSprite + id: MobTerminatorLHand + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: l_hand + +- type: humanoidBaseSprite + id: MobTerminatorLFoot + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: l_foot + +- type: humanoidBaseSprite + id: MobTerminatorRLeg + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: r_leg + +- type: humanoidBaseSprite + id: MobTerminatorRArm + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: r_arm + +- type: humanoidBaseSprite + id: MobTerminatorRHand + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: r_hand + +- type: humanoidBaseSprite + id: MobTerminatorRFoot + baseSprite: + sprite: Mobs/Species/Terminator/parts.rsi + state: r_foot diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/full.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/full.png new file mode 100644 index 0000000000..44e3df3e91 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/full.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/head_f.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/head_f.png new file mode 100644 index 0000000000..dada5727bf Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/head_f.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/head_m.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/head_m.png new file mode 100644 index 0000000000..dada5727bf Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/head_m.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_arm.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_arm.png new file mode 100644 index 0000000000..bb7425405c Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_arm.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_foot.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_foot.png new file mode 100644 index 0000000000..8e0b3f1507 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_foot.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_hand.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_hand.png new file mode 100644 index 0000000000..cf93432a5e Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_hand.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_leg.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_leg.png new file mode 100644 index 0000000000..d693b3696d Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/l_leg.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json new file mode 100644 index 0000000000..688877a32d --- /dev/null +++ b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/meta.json @@ -0,0 +1,66 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by ps3moira#9488 (discord) for SS14.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "full" + }, + { + "name": "head_f", + "directions": 4 + }, + { + "name": "head_m", + "directions": 4 + }, + { + "name": "l_arm", + "directions": 4 + }, + { + "name": "l_foot", + "directions": 4 + }, + { + "name": "l_hand", + "directions": 4 + }, + { + "name": "l_leg", + "directions": 4 + }, + { + "name": "r_arm", + "directions": 4 + }, + { + "name": "r_foot", + "directions": 4 + }, + { + "name": "r_hand", + "directions": 4 + }, + { + "name": "r_leg", + "directions": 4 + }, + { + "name": "skull_icon", + "directions": 1 + }, + { + "name": "torso_f", + "directions": 4 + }, + { + "name": "torso_m", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_arm.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_arm.png new file mode 100644 index 0000000000..51f05a4773 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_arm.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_foot.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_foot.png new file mode 100644 index 0000000000..19ac240da3 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_foot.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_hand.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_hand.png new file mode 100644 index 0000000000..6cd2eb37cc Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_hand.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_leg.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_leg.png new file mode 100644 index 0000000000..e1ea113ca3 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/r_leg.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/skull_icon.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/skull_icon.png new file mode 100644 index 0000000000..6d0ea66780 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/skull_icon.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/torso_f.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/torso_f.png new file mode 100644 index 0000000000..2bcb3cc9eb Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/torso_f.png differ diff --git a/Resources/Textures/Mobs/Species/Terminator/parts.rsi/torso_m.png b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/torso_m.png new file mode 100644 index 0000000000..2bcb3cc9eb Binary files /dev/null and b/Resources/Textures/Mobs/Species/Terminator/parts.rsi/torso_m.png differ