144 lines
4.5 KiB
C#
144 lines
4.5 KiB
C#
using Content.Shared.Chemistry.Components;
|
|
using Content.Shared.Chemistry.EntitySystems;
|
|
using Content.Shared._DV.Paper;
|
|
using Content.Shared._DV.Roles;
|
|
using Content.Shared.Hands;
|
|
using Content.Shared.Interaction.Events;
|
|
using Content.Shared.Mind;
|
|
using Content.Shared.Mindshield.Components;
|
|
using Content.Shared.NPC.Systems;
|
|
using Content.Shared.Popups;
|
|
using Content.Shared.Roles;
|
|
using Content.Shared.Whitelist;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Shared._DV.Recruiter;
|
|
|
|
/// <summary>
|
|
/// Handles finger pricking and signing for the recruiter pen.
|
|
/// </summary>
|
|
public abstract class SharedRecruiterPenSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
[Dependency] private readonly NpcFactionSystem _faction = default!;
|
|
[Dependency] protected readonly SharedMindSystem Mind = default!;
|
|
[Dependency] protected readonly SharedPopupSystem Popup = default!;
|
|
[Dependency] private readonly SharedRoleSystem _role = default!;
|
|
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
|
|
|
|
private EntityQuery<MindShieldComponent> _shieldQuery;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
_shieldQuery = GetEntityQuery<MindShieldComponent>();
|
|
|
|
SubscribeLocalEvent<RecruiterPenComponent, HandSelectedEvent>(OnHandSelected);
|
|
SubscribeLocalEvent<RecruiterPenComponent, UseInHandEvent>(OnPrick);
|
|
SubscribeLocalEvent<RecruiterPenComponent, SignAttemptEvent>(OnSignAttempt);
|
|
}
|
|
|
|
private void OnHandSelected(Entity<RecruiterPenComponent> ent, ref HandSelectedEvent args)
|
|
{
|
|
var (uid, comp) = ent;
|
|
if (comp.RecruiterMind != null)
|
|
return;
|
|
|
|
// mind isnt networked properly so the popup is only done on server
|
|
var user = args.User;
|
|
if (!Mind.TryGetMind(user, out var mind, out _))
|
|
return;
|
|
|
|
if (!_role.MindHasRole<RecruiterRoleComponent>(mind))
|
|
return;
|
|
|
|
Popup.PopupEntity(Loc.GetString("recruiter-pen-bound", ("pen", uid)), user, user);
|
|
|
|
comp.RecruiterMind = mind;
|
|
comp.Bound = true;
|
|
Dirty(uid, comp);
|
|
}
|
|
|
|
private void OnPrick(Entity<RecruiterPenComponent> ent, ref UseInHandEvent args)
|
|
{
|
|
var (uid, comp) = ent;
|
|
if (args.Handled || !comp.Bound)
|
|
return;
|
|
|
|
if (!_solution.TryGetSolution(uid, comp.Solution, out var dest, true))
|
|
return;
|
|
|
|
args.Handled = true;
|
|
|
|
// sec would never defect, silly recruiter
|
|
var user = args.User;
|
|
if (CheckBlacklist(ent, user, "prick"))
|
|
return;
|
|
|
|
DrawBlood(ent, dest.Value, user);
|
|
}
|
|
|
|
private void OnSignAttempt(Entity<RecruiterPenComponent> ent, ref SignAttemptEvent args)
|
|
{
|
|
var (uid, comp) = ent;
|
|
if (args.Cancelled || !_timing.IsFirstTimePredicted)
|
|
return;
|
|
|
|
args.Cancelled = true;
|
|
|
|
if (!_solution.TryGetSolution(uid, comp.Solution, out var blood, true))
|
|
return;
|
|
|
|
var user = args.User;
|
|
if (!comp.Bound)
|
|
{
|
|
Popup.PopupClient(Loc.GetString("recruiter-pen-locked", ("pen", uid)), user, user);
|
|
return;
|
|
}
|
|
|
|
if (CheckBlacklist(ent, user, "sign"))
|
|
return;
|
|
|
|
if (blood.Value.Comp.Solution.AvailableVolume > 0)
|
|
{
|
|
Popup.PopupClient(Loc.GetString("recruiter-pen-empty", ("pen", uid)), user, user);
|
|
return;
|
|
}
|
|
|
|
_solution.RemoveAllSolution(blood.Value);
|
|
Recruit(ent, user);
|
|
|
|
// all checks passed, let it be signed!
|
|
args.Cancelled = false;
|
|
}
|
|
|
|
private bool CheckBlacklist(Entity<RecruiterPenComponent> ent, EntityUid user, string action)
|
|
{
|
|
var (uid, comp) = ent;
|
|
if (_whitelist.IsBlacklistPass(comp.Blacklist, user) || _faction.IsMemberOfAny(user, ent.Comp.FactionBlacklist))
|
|
{
|
|
Popup.PopupPredicted(Loc.GetString($"recruiter-pen-{action}-forbidden", ("pen", uid)), user, user);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to draw blood from the user into the pen.
|
|
/// Returns true if there was a popup.
|
|
/// </summary>
|
|
protected virtual void DrawBlood(EntityUid uid, Entity<SolutionComponent> dest, EntityUid user)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle greentext if the user is signing something for the first time.
|
|
/// </summary>
|
|
protected virtual void Recruit(Entity<RecruiterPenComponent> ent, EntityUid user)
|
|
{
|
|
}
|
|
}
|