Skip to content

Commit

Permalink
zero appreciation for my work, part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
MilonPL committed Oct 25, 2024
1 parent 318aa45 commit 94610ed
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Content.Server.Objectives.Components;

/// <summary>
/// Use this to mark a player as immune to any target objectives, useful for ghost roles or events.
/// </summary>
[RegisterComponent]
public sealed partial class TargetObjectiveImmuneComponent : Component
{
}
60 changes: 25 additions & 35 deletions Content.Server/Objectives/Systems/KillPersonConditionSystem.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using Content.Server.Objectives.Components;
using Content.Server.Revolutionary.Components;
using Content.Server.Shuttles.Systems;
Expand Down Expand Up @@ -25,9 +26,7 @@ public override void Initialize()
base.Initialize();

SubscribeLocalEvent<KillPersonConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress);

SubscribeLocalEvent<PickRandomPersonComponent, ObjectiveAssignedEvent>(OnPersonAssigned);

SubscribeLocalEvent<PickRandomHeadComponent, ObjectiveAssignedEvent>(OnHeadAssigned);
}

Expand All @@ -41,29 +40,15 @@ private void OnGetProgress(EntityUid uid, KillPersonConditionComponent comp, ref

private void OnPersonAssigned(EntityUid uid, PickRandomPersonComponent comp, ref ObjectiveAssignedEvent args)
{
// invalid objective prototype
if (!TryComp<TargetObjectiveComponent>(uid, out var target))
{
args.Cancelled = true;
return;
}

// target already assigned
if (target.Target != null)
return;

// no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId);
if (allHumans.Count == 0)
{
args.Cancelled = true;
return;
}

_target.SetTarget(uid, _random.Pick(allHumans), target);
AssignRandomTarget(uid, args, _ => true);
}

private void OnHeadAssigned(EntityUid uid, PickRandomHeadComponent comp, ref ObjectiveAssignedEvent args)
{
AssignRandomTarget(uid, args, mind => HasComp<CommandStaffComponent>(uid));
}

private void AssignRandomTarget(EntityUid uid, ObjectiveAssignedEvent args, Predicate<EntityUid> filter, bool fallbackToAny = true)
{
// invalid prototype
if (!TryComp<TargetObjectiveComponent>(uid, out var target))
Expand All @@ -76,25 +61,30 @@ private void OnHeadAssigned(EntityUid uid, PickRandomHeadComponent comp, ref Obj
if (target.Target != null)
return;

// no other humans to kill
var allHumans = _mind.GetAliveHumansExcept(args.MindId);
if (allHumans.Count == 0)
// Get all alive humans, filter out any with TargetObjectiveImmuneComponent
var allHumans = _mind.GetAliveHumansExcept(args.MindId)
.Where(mindId =>
{
if (!TryComp<MindComponent>(mindId, out var mindComp) || mindComp.OwnedEntity == null)
return false;
return !HasComp<TargetObjectiveImmuneComponent>(mindComp.OwnedEntity.Value);
})
.ToList();

// Filter out targets based on the filter
var filteredHumans = allHumans.Where(mind => filter(mind)).ToList();

// There's no humans and we can't fall back to any other target
if (filteredHumans.Count == 0 && !fallbackToAny)
{
args.Cancelled = true;
return;
}

var allHeads = new List<EntityUid>();
foreach (var person in allHumans)
{
if (TryComp<MindComponent>(person, out var mind) && mind.OwnedEntity is { } ent && HasComp<CommandStaffComponent>(ent))
allHeads.Add(person);
}

if (allHeads.Count == 0)
allHeads = allHumans; // fallback to non-head target
// Pick between humans matching our filter or fall back to all humans alive
var selectedHumans = filteredHumans.Count > 0 ? filteredHumans : allHumans;

_target.SetTarget(uid, _random.Pick(allHeads), target);
_target.SetTarget(uid, _random.Pick(selectedHumans), target);
}

private float GetProgress(EntityUid target, bool requireDead)
Expand Down

0 comments on commit 94610ed

Please sign in to comment.