Skip to content

Commit

Permalink
Merge pull request #1387 from Werzet/pick-station-goals
Browse files Browse the repository at this point in the history
Cherry-pick upgrade station goal system
  • Loading branch information
DexlerXD authored Jul 19, 2024
2 parents b8ab5a6 + d2ff5f8 commit 978949d
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 75 deletions.
34 changes: 23 additions & 11 deletions Content.Server/Corvax/StationGoal/StationGoalCommand.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.Administration;
using Content.Server.Commands;
using Content.Shared.Administration;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;
Expand All @@ -9,19 +10,27 @@ namespace Content.Server.Corvax.StationGoal
[AdminCommand(AdminFlags.Fun)]
public sealed class StationGoalCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entManager = default!;

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)
if (args.Length != 2)
{
shell.WriteError(Loc.GetString("shell-need-exactly-one-argument"));
shell.WriteError(Loc.GetString("shell-wrong-arguments-number"));
return;
}

var protoId = args[0];
if (!NetEntity.TryParse(args[0], out var euidNet) || !_entManager.TryGetEntity(euidNet, out var euid))
{
shell.WriteError($"Failed to parse euid '{args[0]}'.");
return;
}

var protoId = args[1];
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
if (!prototypeManager.TryIndex<StationGoalPrototype>(protoId, out var proto))
{
Expand All @@ -30,24 +39,27 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
}

var stationGoalPaper = IoCManager.Resolve<IEntityManager>().System<StationGoalPaperSystem>();
if (!stationGoalPaper.SendStationGoal(proto))
if (!stationGoalPaper.SendStationGoal(euid, protoId))
{
shell.WriteError("Station goal was not sent");
return;
}
}

public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
{
if (args.Length == 1)
switch (args.Length)
{
var options = IoCManager.Resolve<IPrototypeManager>()
.EnumeratePrototypes<StationGoalPrototype>()
.Select(p => new CompletionOption(p.ID));
case 1:
var stations = ContentCompletionHelper.StationIds(_entManager);
return CompletionResult.FromHintOptions(stations, "[StationId]");
case 2:
var options = IoCManager.Resolve<IPrototypeManager>()
.EnumeratePrototypes<StationGoalPrototype>()
.Select(p => new CompletionOption(p.ID));

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

return CompletionResult.Empty;
}
}
Expand Down
14 changes: 14 additions & 0 deletions Content.Server/Corvax/StationGoal/StationGoalComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Robust.Shared.Prototypes;

namespace Content.Server.Corvax.StationGoal
{
/// <summary>
/// if attached to a station prototype, will send the station a random goal from the list
/// </summary>
[RegisterComponent]
public sealed partial class StationGoalComponent : Component
{
[DataField]
public List<ProtoId<StationGoalPrototype>> Goals = new();
}
}
132 changes: 86 additions & 46 deletions Content.Server/Corvax/StationGoal/StationGoalPaperSystem.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System.Linq;
using Content.Server.Fax;
using Content.Server.GameTicking.Events;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Server.Paper;
using Content.Shared.Fax.Components;
using Content.Shared.GameTicking;
Expand All @@ -8,6 +11,7 @@
using Content.Shared.SS220.Photocopier;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Server.Player;

namespace Content.Server.Corvax.StationGoal
{
Expand All @@ -16,75 +20,111 @@ namespace Content.Server.Corvax.StationGoal
/// </summary>
public sealed class StationGoalPaperSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly FaxSystem _faxSystem = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly StationSystem _station = default!;

public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundStartedEvent>(OnRoundStarted);
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStarting);
}

private void OnRoundStarted(RoundStartedEvent ev)
private void OnRoundStarting(RoundStartingEvent ev)
{
SendRandomGoal();
}
var playerCount = _playerManager.PlayerCount;

public bool SendRandomGoal()
{
var availableGoals = _prototypeManager.EnumeratePrototypes<StationGoalPrototype>().ToList();
var goal = _random.Pick(availableGoals);
return SendStationGoal(goal);
}
public static string Random_planet_name()
{
var rand = new Random();
string name = $"{(char)rand.Next(65, 90)}-";
var query = EntityQueryEnumerator<StationGoalComponent>();
while (query.MoveNext(out var uid, out var station))
{
var tempGoals = new List<ProtoId<StationGoalPrototype>>(station.Goals);
StationGoalPrototype? selGoal = null;
while (tempGoals.Count > 0)
{
var goalId = _random.Pick(tempGoals);
var goalProto = _proto.Index(goalId);

if (playerCount > goalProto.MaxPlayers ||
playerCount < goalProto.MinPlayers)
{
tempGoals.Remove(goalId);
continue;
}

selGoal = goalProto;
break;
}

for (var i = 1; i <= 5; i++)
name += $"{rand.Next(0, 9)}{(i != 5 ? "-" : "")}";
if (selGoal is null)
return;

return name;
if (SendStationGoal(uid, selGoal))
{
Log.Info($"Goal {selGoal.ID} has been sent to station {MetaData(uid).EntityName}");
}
}
}

public bool SendStationGoal(EntityUid? ent, ProtoId<StationGoalPrototype> goal)
{
return SendStationGoal(ent, _proto.Index(goal));
}
/// <summary>
/// Send a station goal to all faxes which are authorized to receive it.
/// Send a station goal on selected station 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)
public bool SendStationGoal(EntityUid? ent, StationGoalPrototype goal)
{
var faxes = EntityManager.EntityQueryEnumerator<FaxMachineComponent>();
var wasSent = false;
while (faxes.MoveNext(out var uid, out var fax))
{
if (!fax.ReceiveStationGoal) continue;
if (ent is null)
return false;

var dataToCopy = new Dictionary<Type, IPhotocopiedComponentData>();
var paperDataToCopy = new PaperPhotocopiedData()
{
Content = Loc.GetString(goal.Text, ("rand_planet_name", Random_planet_name())),
StampState = "paper_stamp-centcom",
StampedBy = new List<StampDisplayInfo>{
new(){
StampedName = Loc.GetString("stamp-component-stamped-name-centcom"),
StampedColor = Color.FromHex("#dca019") //SS220-CentcomFashion-Changed the stamp color
}
if (!TryComp<StationDataComponent>(ent, out var stationData))
return false;

var dataToCopy = new Dictionary<Type, IPhotocopiedComponentData>();
var paperDataToCopy = new PaperPhotocopiedData()
{
Content = Loc.GetString(goal.Text, ("station", MetaData(ent.Value).EntityName)),
StampState = "paper_stamp-centcom",
StampedBy = [
new()
{
StampedName = Loc.GetString("stamp-component-stamped-name-centcom"),
StampedColor = Color.FromHex("#dca019") //SS220-CentcomFashion-Changed the stamp color
}
};
dataToCopy.Add(typeof(PaperComponent), paperDataToCopy);
]
};
dataToCopy.Add(typeof(PaperComponent), paperDataToCopy);

var metaData = new PhotocopyableMetaData()
{
EntityName = Loc.GetString("station-goal-fax-paper-name"),
PrototypeId = "PaperNtFormCc"
};
var metaData = new PhotocopyableMetaData()
{
EntityName = Loc.GetString("station-goal-fax-paper-name"),
PrototypeId = "PaperNtFormCc"
};

var printout = new FaxPrintout(dataToCopy, metaData);
_faxSystem.Receive(uid, printout, null, fax);
var printout = new FaxPrintout(dataToCopy, metaData);

wasSent = true;
}
var wasSent = false;
var query = EntityQueryEnumerator<FaxMachineComponent>();
while (query.MoveNext(out var faxUid, out var fax))
{
if (!fax.ReceiveStationGoal)
continue;

var largestGrid = _station.GetLargestGrid(stationData);
var grid = Transform(faxUid).GridUid;
if (grid is not null && largestGrid == grid.Value)
{
_faxSystem.Receive(faxUid, printout, null, fax);
foreach (var spawnEnt in goal.Spawns)
{
SpawnAtPosition(spawnEnt, Transform(faxUid).Coordinates);
}
wasSent = true;
}
}
return wasSent;
}
}
Expand Down
16 changes: 15 additions & 1 deletion Content.Server/Corvax/StationGoal/StationGoalPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ public sealed class StationGoalPrototype : IPrototype
{
[IdDataFieldAttribute] public string ID { get; } = default!;

[DataField("text")] public string Text { get; set; } = string.Empty;
[DataField]
public string Text { get; set; } = string.Empty;

[DataField]
public int? MinPlayers;

[DataField]
public int? MaxPlayers;

/// <summary>
/// Goal may require certain items to complete. These items will appear near the receving fax machine at the start of the round.
/// TODO: They should be spun up at the tradepost instead of at the fax machine, but I'm too lazy to do that right now. Maybe in the future.
/// </summary>
[DataField]
public List<EntProtoId> Spawns = new();
}
}
Loading

0 comments on commit 978949d

Please sign in to comment.