Skip to content

Commit

Permalink
Station Goals (#10)
Browse files Browse the repository at this point in the history
# Description

- [x] Station goals
#2

# Media


![изображение](https://github.com/Simple-Station/Parkstation-Friendly-Chainsaw/assets/42233446/6e9a3a84-88be-489e-8095-6cd40f7c026f)

![изображение](https://github.com/Simple-Station/Parkstation-Friendly-Chainsaw/assets/42233446/fe44948e-766b-4fb0-8b5d-fe0957c94255)

![изображение](https://github.com/Simple-Station/Parkstation-Friendly-Chainsaw/assets/42233446/9c56b9bb-f3fd-4bd5-9436-c6e397a4622f)

# Changelog

:cl: DEATHB4DEFEAT
- add: Added station goals that get sent to the Command fax machine at
the start of every shift

---------

Co-authored-by: DEATHB4DEFEAT <[email protected]>
Co-authored-by: DEATHB4DEFEAT <[email protected]>
  • Loading branch information
3 people committed Dec 17, 2023
1 parent 3b76be7 commit 8b6f1d2
Show file tree
Hide file tree
Showing 16 changed files with 576 additions and 2 deletions.
1 change: 1 addition & 0 deletions Content.Client/Entry/EntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public override void Init()
_prototypeManager.RegisterIgnore("wireLayout");
_prototypeManager.RegisterIgnore("alertLevels");
_prototypeManager.RegisterIgnore("nukeopsRole");
_prototypeManager.RegisterIgnore("stationGoal"); // Corvax-StationGoal

_componentFactory.GenerateNetIds();
_adminManager.Initialize();
Expand Down
13 changes: 13 additions & 0 deletions Content.Server/Corvax/GameTicking/RoundEndedEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Content.Server.Corvax.GameTicking;

public sealed class RoundEndedEvent : EntityEventArgs
{
public int RoundId { get; }
public TimeSpan RoundDuration { get; }

public RoundEndedEvent(int roundId, TimeSpan roundDuration)
{
RoundId = roundId;
RoundDuration = roundDuration;
}
}
11 changes: 11 additions & 0 deletions Content.Server/Corvax/GameTicking/RoundStartedEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Content.Server.Corvax.GameTicking;

public sealed class RoundStartedEvent : EntityEventArgs
{
public int RoundId { get; }

public RoundStartedEvent(int roundId)
{
RoundId = roundId;
}
}
55 changes: 55 additions & 0 deletions Content.Server/Corvax/StationGoal/StationGoalCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.Linq;
using Content.Server.Administration;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;

namespace Content.Server.Corvax.StationGoal
{
[AdminCommand(AdminFlags.Fun)]
public sealed class StationGoalCommand : IConsoleCommand
{
public string Command => "sendstationgoal";
public string Description => Loc.GetString("send-station-goal-command-description");
public string Help => Loc.GetString("send-station-goal-command-help-text", ("command", Command));

public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
shell.WriteError(Loc.GetString("shell-need-exactly-one-argument"));
return;
}

var protoId = args[0];
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
if (!prototypeManager.TryIndex<StationGoalPrototype>(protoId, out var proto))
{
shell.WriteError(Loc.GetString("send-station-goal-command-error-no-goal-proto", ("id", protoId)));
return;
}

var stationGoalPaper = IoCManager.Resolve<IEntityManager>().System<StationGoalPaperSystem>();
if (!stationGoalPaper.SendStationGoal(proto))
{
shell.WriteError(Loc.GetString("send-station-goal-command-error-couldnt-fax"));
return;
}
}

public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length == 1)
{
var options = IoCManager.Resolve<IPrototypeManager>()
.EnumeratePrototypes<StationGoalPrototype>()
.OrderBy(p => p.ID)
.Select(p => new CompletionOption(p.ID));

return CompletionResult.FromHintOptions(options, Loc.GetString("send-station-goal-command-arg-id"));
}

return CompletionResult.Empty;
}
}
}
11 changes: 11 additions & 0 deletions Content.Server/Corvax/StationGoal/StationGoalPaperComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Content.Server.Corvax.StationGoal
{
/// <summary>
/// Paper with a written station goal in it.
/// </summary>
[RegisterComponent]
public sealed partial class StationGoalPaperComponent : Component
{
}
}

113 changes: 113 additions & 0 deletions Content.Server/Corvax/StationGoal/StationGoalPaperSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using System.Data;
using System.Text.RegularExpressions;
using Content.Server.Corvax.GameTicking;
using Content.Server.Fax;
using Content.Server.Station.Systems;
using Content.Shared.Corvax.CCCVars;
using Content.Shared.Random;
using Content.Shared.Random.Helpers;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;

namespace Content.Server.Corvax.StationGoal;

/// <summary>
/// System for station goals
/// </summary>
public sealed class StationGoalPaperSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly FaxSystem _fax = default!;
[Dependency] private readonly IConfigurationManager _config = default!;
[Dependency] private readonly StationSystem _station = default!;

private static readonly Regex StationIdRegex = new(@".*-(\d+)$");

private const string RandomPrototype = "StationGoals";


public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<RoundStartedEvent>(OnRoundStarted);
}


private void OnRoundStarted(RoundStartedEvent ev)
{
if (_config.GetCVar(CCCVars.StationGoalsEnabled))
SendRandomGoal();
}

/// <summary>
/// Send a random station goal to all faxes which are authorized to receive it
/// </summary>
/// <returns>If the fax was successful</returns>
/// <exception cref="ConstraintException">Raised when station goal types in the prototype is invalid</exception>
public bool SendRandomGoal()
{
// Get the random station goal list
if (!_prototype.TryIndex<WeightedRandomPrototype>(RandomPrototype, out var goals))
{
Log.Error($"StationGoalPaperSystem: Random station goal prototype '{RandomPrototype}' not found");
return false;
}

// Get a random goal
var goal = RecursiveRandom(goals);

// Send the goal
return SendStationGoal(goal);
}

private StationGoalPrototype RecursiveRandom(WeightedRandomPrototype random)
{
var goal = random.Pick(_random);

if (_prototype.TryIndex<StationGoalPrototype>(goal, out var goalPrototype))
return goalPrototype;

if (_prototype.TryIndex<WeightedRandomPrototype>(goal, out var goalRandom))
return RecursiveRandom(goalRandom);

throw new Exception($"StationGoalPaperSystem: Random station goal could not be found from origin prototype {RandomPrototype}");
}

/// <summary>
/// Send a station goal to all faxes which are authorized to receive it
/// </summary>
/// <returns>True if at least one fax received paper</returns>
public bool SendStationGoal(StationGoalPrototype goal)
{
var enumerator = EntityManager.EntityQueryEnumerator<FaxMachineComponent>();
var wasSent = false;

while (enumerator.MoveNext(out var uid, out var fax))
{
if (!fax.ReceiveStationGoal ||
!TryComp<MetaDataComponent>(_station.GetOwningStation(uid), out var meta))
continue;

var stationId = StationIdRegex.Match(meta.EntityName).Groups[1].Value;

var printout = new FaxPrintout(
Loc.GetString("station-goal-fax-paper-header",
("date", DateTime.Now.AddYears(1000).ToString("yyyy MMMM dd")),
("station", string.IsNullOrEmpty(stationId) ? "???" : stationId),
("content", goal.Text)
),
Loc.GetString("station-goal-fax-paper-name"),
"StationGoalPaper"
);

_fax.Receive(uid, printout, null, fax);

wasSent = true;
}

return wasSent;
}
}
12 changes: 12 additions & 0 deletions Content.Server/Corvax/StationGoal/StationGoalPrototype.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Robust.Shared.Prototypes;

namespace Content.Server.Corvax.StationGoal
{
[Serializable, Prototype("stationGoal")]
public sealed class StationGoalPrototype : IPrototype
{
[IdDataFieldAttribute] public string ID { get; } = default!;

public string Text => Loc.GetString($"station-goal-{ID.ToLower()}");
}
}
9 changes: 9 additions & 0 deletions Content.Server/Fax/FaxMachineComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ public sealed partial class FaxMachineComponent : Component
[DataField("receiveNukeCodes")]
public bool ReceiveNukeCodes { get; set; } = false;

// Corvax-StationGoal-Start
/// <summary>
/// Should that fax receive station goal info
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField("receiveStationGoal")]
public bool ReceiveStationGoal { get; set; } = false;
// Corvax-StationGoal-End

/// <summary>
/// Sound to play when fax has been emagged
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions Content.Server/GameTicking/GameTicker.RoundFlow.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.Announcements;
using Content.Server.Corvax.GameTicking;
using Content.Server.Discord;
using Content.Server.GameTicking.Events;
using Content.Server.Ghost;
Expand Down Expand Up @@ -252,6 +253,7 @@ public void StartRound(bool force = false)
AnnounceRound();
UpdateInfoText();
SendRoundStartedDiscordMessage();
RaiseLocalEvent(new RoundStartedEvent(RoundId)); // Corvax-RoundFlow

#if EXCEPTION_TOLERANCE
}
Expand Down Expand Up @@ -388,6 +390,7 @@ public void ShowRoundEndScoreboard(string text = "")
RaiseNetworkEvent(new RoundEndMessageEvent(gamemodeTitle, roundEndText, roundDuration, RoundId,
listOfPlayerInfoFinal.Length, listOfPlayerInfoFinal, LobbySong,
new SoundCollectionSpecifier("RoundEnd").GetSound()));
RaiseLocalEvent(new RoundEndedEvent(RoundId, roundDuration)); // Corvax-RoundFlow
}

private async void SendRoundEndDiscordMessage()
Expand Down
18 changes: 18 additions & 0 deletions Content.Shared/Corvax/CCVars/CCCVars.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Robust.Shared.Configuration;

namespace Content.Shared.Corvax.CCCVars;

[CVarDefs]
// ReSharper disable once InconsistentNaming
public sealed class CCCVars
{
/*
* Station Goals
*/

/// <summary>
/// Enables station goals
/// </summary>
public static readonly CVarDef<bool> StationGoalsEnabled =
CVarDef.Create("game.station_goals", false, CVar.SERVERONLY);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
send-station-goal-command-description = Sends the selected station target to all faxes that can receive it
send-station-goal-command-help-text = Usage: { $command } <Goal Prototype ID>
send-station-goal-command-arg-id = Goal Prototype ID
send-station-goal-command-error-no-goal-proto = No station goal found with ID {$id}
send-station-goal-command-error-couldnt-fax = Couldn't send station goal, probably due to a lack of fax machines that are able to recieve it
Loading

0 comments on commit 8b6f1d2

Please sign in to comment.