Merge branch 'Transfer/Engi' into EngiTransfer
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared._White._Engi.BucketHelmet;
|
||||
|
||||
namespace Content.Server._White._Engi.BucketHelmet;
|
||||
|
||||
/// <summary>
|
||||
/// WD.
|
||||
/// This handles placemet of PreventStrippingFromEarsComponent when bucket helmet is in use.
|
||||
/// </summary>
|
||||
public sealed class BucketHelmetSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<BucketHelmetComponent, GotEquippedEvent>(OnGotEquipped);
|
||||
SubscribeLocalEvent<BucketHelmetComponent, GotUnequippedEvent>(OnGotUnequipped);
|
||||
}
|
||||
|
||||
|
||||
public void OnGotUnequipped(EntityUid uid, BucketHelmetComponent component, GotUnequippedEvent args)
|
||||
{
|
||||
RemComp<PreventStrippingFromEarsComponent>(args.Equipee);
|
||||
}
|
||||
|
||||
public void OnGotEquipped(EntityUid uid, BucketHelmetComponent component, GotEquippedEvent args)
|
||||
{
|
||||
if (args.Slot == "head")
|
||||
EnsureComp<PreventStrippingFromEarsComponent>(args.Equipee);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server._White._Engi.PacifiedOnChaplainAction
|
||||
{
|
||||
/// <summary>
|
||||
/// WD.
|
||||
/// Adds verb for chaplain to pacify entity.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class PacifiedOnChaplainActionComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public SoundSpecifier ActionSound = new SoundPathSpecifier("/Audio/Effects/holy.ogg");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Server.Popups;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Server.Bible.Components;
|
||||
using Content.Shared.Timing;
|
||||
using Content.Shared.CombatMode.Pacification;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
|
||||
namespace Content.Server._White._Engi.PacifiedOnChaplainAction
|
||||
{
|
||||
/// <summary>
|
||||
/// WD
|
||||
/// </summary>
|
||||
public sealed class PacifiedOnChaplainAction : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly UseDelaySystem _delay = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<PacifiedOnChaplainActionComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
SubscribeLocalEvent<PacifiedOnChaplainActionComponent, GetVerbsEvent<AlternativeVerb>>(AddPacifiedOnChaplainVerb);
|
||||
}
|
||||
|
||||
private void Action(PacifiedOnChaplainActionComponent component, EntityUid target, EntityUid user)
|
||||
{
|
||||
var popup = "";
|
||||
|
||||
if (HasComp<PacifiedComponent>(target))
|
||||
{
|
||||
popup = "unpacified-by-chaplain";
|
||||
RemComp<PacifiedComponent>(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
popup = "pacified-by-chaplain";
|
||||
EnsureComp<PacifiedComponent>(target);
|
||||
}
|
||||
|
||||
_adminLogger.Add(LogType.Verb,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(target):target} {popup} {ToPrettyString(user):user}");
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString(popup, ("target", target)), user, user);
|
||||
|
||||
_audio.PlayPvs(component.ActionSound, user);
|
||||
|
||||
}
|
||||
|
||||
private void OnAfterInteract(EntityUid uid, PacifiedOnChaplainActionComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (!args.CanReach)
|
||||
return;
|
||||
|
||||
if (!TryComp(uid, out UseDelayComponent? useDelay) || _delay.IsDelayed((uid, useDelay)))
|
||||
return;
|
||||
|
||||
if (args.Target == null)
|
||||
return;
|
||||
|
||||
if (!HasComp<BibleUserComponent>(args.User))
|
||||
return;
|
||||
|
||||
Action(component, (EntityUid) args.Target, args.User);
|
||||
|
||||
_delay.TryResetDelay((uid, useDelay));
|
||||
|
||||
return;
|
||||
}
|
||||
private void AddPacifiedOnChaplainVerb(EntityUid uid, PacifiedOnChaplainActionComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (!args.CanInteract || !args.CanAccess)
|
||||
return;
|
||||
|
||||
if (!HasComp<BibleUserComponent>(args.User))
|
||||
return;
|
||||
|
||||
if (!_blocker.CanInteract(args.User, uid))
|
||||
return;
|
||||
|
||||
var verbName = "";
|
||||
|
||||
if (HasComp<PacifiedComponent>(args.Target))
|
||||
verbName = Loc.GetString("unpacify-by-chaplain");
|
||||
else
|
||||
verbName = Loc.GetString("pacify-by-chaplain");
|
||||
|
||||
AlternativeVerb verb = new()
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
if (!TryComp(uid, out UseDelayComponent? useDelay) || _delay.IsDelayed((uid, useDelay)))
|
||||
return;
|
||||
|
||||
Action(component, args.Target, args.User);
|
||||
|
||||
_delay.TryResetDelay((uid, useDelay));
|
||||
},
|
||||
Text = verbName,
|
||||
Priority = 2
|
||||
};
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.Commands;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._White._Engi.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 != 2)
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-wrong-arguments-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
shell.WriteError($"No station goal found with ID {protoId}!");
|
||||
return;
|
||||
}
|
||||
|
||||
var stationGoalPaper = IoCManager.Resolve<IEntityManager>().System<StationGoalPaperSystem>();
|
||||
if (!stationGoalPaper.SendStationGoal(euid, protoId))
|
||||
{
|
||||
shell.WriteError("Station goal was not sent");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
switch (args.Length)
|
||||
{
|
||||
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.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._White._Engi.StationGoal
|
||||
{
|
||||
/// <summary>
|
||||
/// WD.
|
||||
/// 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Content.Server._White._Engi.StationGoal
|
||||
{
|
||||
/// <summary>
|
||||
/// WD.
|
||||
/// Paper with a written station goal in it.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class StationGoalPaperComponent : Component
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using Content.Server.Fax;
|
||||
using Content.Server.GameTicking.Events;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Fax.Components;
|
||||
using Content.Shared.Paper;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Server.RandomMetadata;
|
||||
|
||||
namespace Content.Server._White._Engi.StationGoal
|
||||
{
|
||||
/// <summary>
|
||||
/// WD.
|
||||
/// System to spawn paper with station goal.
|
||||
/// </summary>
|
||||
public sealed class StationGoalPaperSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly FaxSystem _fax = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly RandomMetadataSystem _randomMeta = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStarting);
|
||||
}
|
||||
|
||||
private void OnRoundStarting(RoundStartingEvent ev)
|
||||
{
|
||||
var playerCount = _playerManager.PlayerCount;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (selGoal is null)
|
||||
return;
|
||||
|
||||
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 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(EntityUid? ent, StationGoalPrototype goal)
|
||||
{
|
||||
if (ent is null)
|
||||
return false;
|
||||
|
||||
if (!TryComp<StationDataComponent>(ent, out var stationData))
|
||||
return false;
|
||||
|
||||
var today = DateTime.Today.ToString("dd.MM");
|
||||
var namesList = new List<string>
|
||||
{
|
||||
"names_first_male",
|
||||
"names_last_male"
|
||||
};
|
||||
var operatorName = _randomMeta.GetRandomFromSegments(namesList, " ");
|
||||
|
||||
var faxContent = Loc.GetString("engi-station-goal-form",
|
||||
("station", MetaData(ent.Value).EntityName),
|
||||
("date", today),
|
||||
("operator", operatorName),
|
||||
("text", Loc.GetString(goal.Text)));
|
||||
|
||||
var printout = new FaxPrintout(
|
||||
faxContent,
|
||||
Loc.GetString("engi-station-goal-fax-paper-name"),
|
||||
null,
|
||||
null,
|
||||
"paper_stamp-centcom",
|
||||
new List<StampDisplayInfo>
|
||||
{
|
||||
new() { StampedName = Loc.GetString("stamp-component-stamped-name-centcom"), StampedColor = Color.FromHex("#006600") },
|
||||
});
|
||||
|
||||
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)
|
||||
{
|
||||
_fax.Receive(faxUid, printout, null, fax);
|
||||
foreach (var spawnEnt in goal.Spawns)
|
||||
{
|
||||
SpawnAtPosition(spawnEnt, Transform(faxUid).Coordinates);
|
||||
}
|
||||
wasSent = true;
|
||||
}
|
||||
}
|
||||
return wasSent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._White._Engi.StationGoal
|
||||
{
|
||||
/// <summary>
|
||||
/// WD
|
||||
/// </summary>
|
||||
[Serializable, Prototype("stationGoal")]
|
||||
public sealed class StationGoalPrototype : IPrototype
|
||||
{
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
[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.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntProtoId> Spawns = new();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user