Skip to content

Commit

Permalink
Fugitive, rough but functional
Browse files Browse the repository at this point in the history
  • Loading branch information
VMSolidus committed Jan 22, 2024
1 parent b88d3c3 commit 47586c3
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 17 deletions.
14 changes: 14 additions & 0 deletions Content.Server/Nyanotrasen/Fugitive/FugitiveComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Robust.Shared.Audio;

namespace Content.Server.Fugitive
{
[RegisterComponent]
public sealed partial class FugitiveComponent : Component
{
[DataField("spawnSound")]
public SoundSpecifier SpawnSoundPath = new SoundPathSpecifier("/Audio/Effects/clang.ogg");

[DataField("firstMindAdded")]
public bool FirstMindAdded = false;
}
}
11 changes: 11 additions & 0 deletions Content.Server/Nyanotrasen/Fugitive/FugitiveCountdownComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Content.Server.Fugitive
{
[RegisterComponent]
public sealed partial class FugitiveCountdownComponent : Component
{
public TimeSpan? AnnounceTime = null;

[DataField("AnnounceCD")]
public TimeSpan AnnounceCD = TimeSpan.FromMinutes(5);
}
}
158 changes: 158 additions & 0 deletions Content.Server/Nyanotrasen/Fugitive/FugitiveSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using System.Linq;
using System.Text;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Server.Ghost.Roles.Events;
using Content.Server.Traitor;
using Content.Server.Objectives;
using Content.Server.Chat.Systems;
using Content.Server.Communications;
using Content.Server.Paper;
using Content.Server.Humanoid;
using Content.Server.Popups;
using Content.Server.Stunnable;
using Content.Server.Ghost.Components;
using Content.Server.Roles;
using Content.Server.GameTicking;
using Content.Shared.Roles;
using Content.Shared.Movement.Systems;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Humanoid;
using Content.Shared.Random.Helpers;
using Content.Shared.Examine;
using Content.Shared.Preferences;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Audio;
using Robust.Shared.Utility;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Server.GameObjects;
using Robust.Server.Audio;
using static Content.Shared.Examine.ExamineSystemShared;

namespace Content.Server.Fugitive
{
public sealed class FugitiveSystem : EntitySystem
{
private const string FugitiveRole = "Fugitive";
private const string EscapeObjective = "EscapeShuttleObjectiveFugitive";

[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly PaperSystem _paperSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FugitiveComponent, GhostRoleSpawnerUsedEvent>(OnSpawned);
}

public override void Update(float frameTime)
{
base.Update(frameTime);
foreach (var (cd, _) in EntityQuery<FugitiveCountdownComponent, FugitiveComponent>())
{
if (cd.AnnounceTime != null && _timing.CurTime > cd.AnnounceTime)
{
_chat.DispatchGlobalAnnouncement(Loc.GetString("station-event-fugitive-hunt-announcement"), sender: Loc.GetString("fugitive-announcement-GALPOL"), colorOverride: Color.Yellow);

foreach (var console in EntityQuery<CommunicationsConsoleComponent>())
{
if (HasComp<GhostComponent>(console.Owner))
continue;

var paperEnt = Spawn("Paper", Transform(console.Owner).Coordinates);
var fugireport = Loc.GetString("fugi-report-ent-name", ("name", cd.Owner));
_metaData.SetEntityName(paperEnt, fugireport);

if (!TryComp<PaperComponent>(paperEnt, out var paper))
continue;

var report = GenerateFugiReport(cd.Owner);

_paperSystem.SetContent(paperEnt, report.ToMarkup(), paper);
}

RemCompDeferred<FugitiveCountdownComponent>(cd.Owner);
}
}
}

private void OnSpawned(EntityUid uid, FugitiveComponent component, GhostRoleSpawnerUsedEvent args)
{
if (!TryComp<HumanoidAppearanceComponent>(uid, out var humanoid))
return;

var pref = HumanoidCharacterProfile.Random();
var species = pref.Species;
_humanoidSystem.SetSpecies(uid, species, true, humanoid);
_humanoidSystem.LoadProfile(uid, pref);

if (TryComp<FugitiveCountdownComponent>(uid, out var cd))
cd.AnnounceTime = _timing.CurTime + cd.AnnounceCD;

_popupSystem.PopupEntity(Loc.GetString("fugitive-spawn", ("name", uid)), uid,
Filter.Pvs(uid).RemoveWhereAttachedEntity(entity => !ExamineSystemShared.InRangeUnOccluded(uid, entity, ExamineRange, null)), true, Shared.Popups.PopupType.LargeCaution);

_stun.TryParalyze(uid, TimeSpan.FromSeconds(2), false);
_audioSystem.PlayPvs(component.SpawnSoundPath, uid, AudioParams.Default.WithVolume(-6f));

var tile = Spawn("FloorTileItemSteel", Transform(uid).Coordinates);
}

private FormattedMessage GenerateFugiReport(EntityUid uid)
{
FormattedMessage report = new();
report.AddMarkup(Loc.GetString("fugi-report-title", ("name", uid)));
report.PushNewline();
report.PushNewline();
report.AddMarkup(Loc.GetString("fugitive-report-first-line", ("name", uid)));
report.PushNewline();
report.PushNewline();


if (!TryComp<HumanoidAppearanceComponent>(uid, out var humanoidComponent) ||
!_prototypeManager.TryIndex<SpeciesPrototype>(humanoidComponent.Species, out var species))
{
report.AddMarkup(Loc.GetString("fugitive-report-inhuman", ("name", uid)));
return report;
}

report.AddMarkup(Loc.GetString("fugitive-report-morphotype", ("species", Loc.GetString(species.Name))));
report.PushNewline();
report.AddMarkup(Loc.GetString("fugitive-report-age", ("age", humanoidComponent.Age)));
report.PushNewline();

string sexLine = string.Empty;
sexLine += humanoidComponent.Sex switch
{
Sex.Male => Loc.GetString("fugitive-report-sex-m"),
Sex.Female => Loc.GetString("fugitive-report-sex-f"),
_ => Loc.GetString("fugitive-report-sex-n")
};

report.AddMarkup(sexLine);

if (TryComp<PhysicsComponent>(uid, out var physics))
{
report.PushNewline();
report.AddMarkup(Loc.GetString("fugitive-report-weight", ("weight", Math.Round(physics.FixturesMass))));
}
report.PushNewline();
report.PushNewline();
report.AddMarkup(Loc.GetString("fugitive-report-last-line"));

return report;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public sealed partial class MidRoundAntagRuleComponent : Component
public IReadOnlyList<string> MidRoundAntags = new[]
{
"SpawnPointGhostRatKing",
"SpawnPointGhostVampSpider",
"SpawnPointGhostFugitive",
"MobEvilTwinSpawn"
//"SpawnPointGhostVampSpider",//Has Arachne as a prereq
"SpawnPointGhostFugitive", //Yea this is temporarily the Fugitive event until the others are working
//"MobEvilTwinSpawn"
};
}
1 change: 1 addition & 0 deletions Resources/Locale/en-US/nyanotrasen/job/job-description.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ job-description-mail-carrier = Deliver mail and other packages from and to logis
job-description-martialartist = Be honorable and disciplined, spar in the dojo, challenge security to CQC. Currently available on Shōkō.
job-description-prisoner = Sit in prison. Gamble with your cellmates. Talk to the warden. Write your memoirs.
job-description-mantis = Solve mysteries from the nature of the universe to the meaning of life. Be the main person to deal with Psionic beings.
job-description-fugitive = Escape the station alive.
1 change: 1 addition & 0 deletions Resources/Locale/en-US/nyanotrasen/job/job-names.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
job-name-gladiator = Gladiator
job-name-fugitive = fugitive
job-name-guard = Prison Guard
job-name-mail-carrier = Courier
job-name-martialartist = Martial Artist
Expand Down
2 changes: 2 additions & 0 deletions Resources/Locale/en-US/nyanotrasen/prototypes/antags.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
roles-antag-fugitive-name = Fugitive
roles-antag-fugitive-description = Survive. Escape.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
station-event-fugitive-hunt-announcement = Please check communications consoles for a sensitive message.
fugitive-spawn = {CAPITALIZE(THE($name))} falls from the ceiling!
fugitive-announcement-GALPOL = GALPOL
fugi-report-ent-name = FUGITIVE REPORT: {$name}
fugi-report-title = WANTED: {$name}
fugitive-report-first-line = Escaped fugitive {$name} has been spotted in the sector. They may be a stowaway on a station somewhere.
fugitive-report-inhuman = {CAPITALIZE(THE($name))} {CONJUGATE-BE($name)} inhuman. We have no further details.
fugitive-report-morphotype = MORPHOTYPE: {$species}
fugitive-report-sex-m = SEX: M
fugitive-report-sex-f = SEX: F
fugitive-report-sex-n = SEX: N/A
fugitive-report-weight = WEIGHT: {$weight} kg
fugitive-report-age = AGE: {$age}
fugitive-report-last-line = The above individual is wanted across the sector; preferably alive.
fugitive-round-end-result = {$fugitiveCount ->
[one] There was one fugitive.
*[other] There were {$fugitiveCount} fugitives.
}
fugitive-user-was-a-fugitive = [color=gray]{$user}[/color] was a fugitive.
fugitive-user-was-a-fugitive-named = [color=White]{$name}[/color] ([color=gray]{$user}[/color]) was a fugitive.
fugitive-was-a-fugitive-named = [color=White]{$name}[/color] was a fugitive.
fugitive-user-was-a-fugitive-with-objectives = [color=gray]{$user}[/color] was a fugitive who had the following objectives:
fugitive-user-was-a-fugitive-with-objectives-named = [color=White]{$name}[/color] ([color=gray]{$user}[/color]) was a fugitive who had the following objectives:
fugitive-was-a-fugitive-with-objectives-named = [color=White]{$name}[/color] was a fugitive who had the following objectives:
3 changes: 3 additions & 0 deletions Resources/Prototypes/DeltaV/Roles/play_time_trackers.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
- type: playTimeTracker
id: JobBrigmedic

- type: playTimeTracker
id: JobFugitive
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
parent: MarkerBase
noSpawn: true
components:
# - type: GhostRoleMobSpawner
# prototype: MobHumanFugitive # Todo
- type: GhostRoleMobSpawner
prototype: MobHumanFugitive
- type: GhostRole
name: Fugitive
description: You're an escaped prisoner. Make it out alive.
Expand All @@ -38,6 +38,7 @@
- state: green
- state: prisoner


- type: entity
id: SpawnPointLocationMidRoundAntag
name: possible spawn location
Expand All @@ -49,7 +50,8 @@
layers:
- state: green
- state: prisoner
# - type: MidRoundAntagSpawnLocation # When MidRoundAntag?
- type: MidRoundAntagSpawnLocation # When MidRoundAntag? Now is MidRoundAntag


# - type: entity
# id: SpawnPointGhostVampSpider
Expand Down
49 changes: 49 additions & 0 deletions Resources/Prototypes/Nyanotrasen/Entities/Mobs/NPCs/humanoid.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Unfortunate, isn't it, that these don't work for ghost roles?

# - type: entity
# id: RandomHumanoidSpawnerFugitive
# name: fugitive
# components:
# - type: Icon
# sprite: Mobs/Species/Human/parts.rsi
# state: full
# - type: RandomHumanoidSpawner
# settings: Fugitive

# - type: randomHumanoidSettings
# id: Fugitive
# components:
# - type: Loadout
# prototypes: [FugitiveStartingGear]

- type: entity
parent: MobHuman
id: MobHumanFugitive
name: Fugitive
noSpawn: true
components:
- type: Loadout
prototypes: [FugitiveStartingGear]
- type: Fugitive
- type: FugitiveCountdown
- type: RandomHumanoidAppearance

#- type: entity
# parent: MarkerBase
# id: MobEvilTwinSpawn
# name: paradox anomaly
# components:
# - type: EvilTwinSpawner
# - type: Sprite
# sprite: Markers/jobs.rsi
# layers:
# - state: green
# - sprite: Mobs/Ghosts/ghost_human.rsi
# state: icon
# - type: GhostRole
# name: paradox anomaly
# description: Replace your double, or befriend them.
# rules: |
# Try and replace your twin with this funny roleplay antag rather than
# plasma flooding the station or something. You can also just befriend them.
# - type: GhostTakeoverAvailable
22 changes: 11 additions & 11 deletions Resources/Prototypes/Nyanotrasen/GameRules/events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
- type: NoosphericStormRule

# Rat king, paradox anomaly, fugitive, oneiro, etc.
#- type: entity
# id: MidRoundAntag
# parent: BaseGameRule
# noSpawn: true
# components:
# - type: StationEvent
# weight: 7
# reoccurrenceDelay: 5
# minimumPlayers: 15
# earliestStart: 25
# - type: MidRoundAntagRule
- type: entity
id: MidRoundAntag
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 7
reoccurrenceDelay: 5
minimumPlayers: 15
earliestStart: 25
- type: MidRoundAntagRule

# Base glimmer event
- type: entity
Expand Down
26 changes: 26 additions & 0 deletions Resources/Prototypes/Nyanotrasen/Roles/Jobs/Antag/fugitive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
- type: job
id: Fugitive
name: job-name-fugitive
description: job-description-fugitive
playTimeTracker: JobFugitive
startingGear: FugitiveStartingGear
setPreference: false
icon: "Prisoner"

- type: antag
id: Fugitive
name: roles-antag-fugitive-name
antagonist: true
setPreference: false
objective: roles-antag-fugitive-objective

- type: startingGear
id: FugitiveStartingGear
equipment:
jumpsuit: ClothingUniformJumpsuitPrisoner
gloves: ClothingHandsGlovesColorYellow
back: ClothingBackpack
shoes: ClothingShoesColorBlack
inhand:
- ToolboxElectricalFilled
innerClothingSkirt: ClothingUniformJumpskirtPrisoner

0 comments on commit 47586c3

Please sign in to comment.