Use conditions to store progress for Ninja objectives (#20254)

* TryGetObjectiveComp

* helper function to get objective

* store N of jacked doors in condition

* store called in threat bool in condition

* store techs in steal research condition

* fix access

* remove unused transform system

* use popup from shared system

* fix formatting

* condition => obj everywhere

* i fogror to remove downloaded nodes from role

* change signature

* use query

* View Variables

* spider charge detonated => condition
This commit is contained in:
Slava0135
2023-10-10 09:32:10 +03:00
committed by GitHub
parent c35a018cad
commit 6f8c2b7e52
11 changed files with 76 additions and 88 deletions

View File

@@ -1,16 +1,10 @@
using Content.Server.Communications;
using Content.Server.DoAfter;
using Content.Server.Mind;
using Content.Server.Ninja.Events;
using Content.Server.Power.Components;
using Content.Server.Roles;
using Content.Server.Objectives.Components;
using Content.Shared.Communications;
using Content.Shared.DoAfter;
using Content.Shared.Interaction.Components;
using Content.Shared.Interaction.Events;
using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems;
using Content.Shared.Popups;
using Content.Shared.Research.Components;
using Content.Shared.Toggleable;
@@ -94,7 +88,7 @@ public sealed class NinjaGlovesSystem : SharedNinjaGlovesSystem
EnsureComp<ResearchStealerComponent>(user);
// prevent calling in multiple threats by toggling gloves after
if (_mind.TryGetRole<NinjaRoleComponent>(user, out var role) && !role.CalledInThreat)
if (_mind.TryGetObjectiveComp<TerrorConditionComponent>(user, out var obj) && !obj.CalledInThreat)
{
var hacker = EnsureComp<CommsHackerComponent>(user);
var rule = _ninja.NinjaRule(user);

View File

@@ -1,12 +1,8 @@
using Content.Server.Administration.Commands;
using Content.Server.Communications;
using Content.Server.Chat.Managers;
using Content.Server.StationEvents.Components;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Ghost.Roles.Events;
using Content.Server.Objectives;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.PowerCell;
@@ -23,16 +19,12 @@ using Content.Shared.Mind.Components;
using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems;
using Content.Shared.Popups;
using Content.Shared.Roles;
using Content.Shared.PowerCell.Components;
using Content.Shared.Rounding;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Shared.Random;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Objectives.Components;
namespace Content.Server.Ninja.Systems;
@@ -57,8 +49,6 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
[Dependency] private readonly RoleSystem _role = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly StealthClothingSystem _stealthClothing = default!;
public override void Initialize()
@@ -85,12 +75,12 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
/// </summary>
private int Download(EntityUid uid, List<string> ids)
{
if (!_mind.TryGetRole<NinjaRoleComponent>(uid, out var role))
if (!_mind.TryGetObjectiveComp<StealResearchConditionComponent>(uid, out var obj))
return 0;
var oldCount = role.DownloadedNodes.Count;
role.DownloadedNodes.UnionWith(ids);
var newCount = role.DownloadedNodes.Count;
var oldCount = obj.DownloadedNodes.Count;
obj.DownloadedNodes.UnionWith(ids);
var newCount = obj.DownloadedNodes.Count;
return newCount - oldCount;
}
@@ -124,7 +114,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
if (GetNinjaBattery(uid, out _, out var battery))
{
var severity = ContentHelpers.RoundToLevels(MathF.Max(0f, battery.CurrentCharge), battery.MaxCharge, 8);
var severity = ContentHelpers.RoundToLevels(MathF.Max(0f, battery.CurrentCharge), battery.MaxCharge, 8);
_alerts.ShowAlert(uid, AlertType.SuitPower, (short) severity);
}
else
@@ -205,7 +195,7 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
if (ninja.Suit == null)
return;
float wattage = _suit.SuitWattage(ninja.Suit.Value);
float wattage = Suit.SuitWattage(ninja.Suit.Value);
SetSuitPowerAlert(uid, ninja);
if (!TryUseCharge(uid, wattage * frameTime))
@@ -225,11 +215,11 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
return;
// this popup is serverside since door emag logic is serverside (power funnies)
_popup.PopupEntity(Loc.GetString("ninja-doorjack-success", ("target", Identity.Entity(args.Target, EntityManager))), uid, uid, PopupType.Medium);
Popup.PopupEntity(Loc.GetString("ninja-doorjack-success", ("target", Identity.Entity(args.Target, EntityManager))), uid, uid, PopupType.Medium);
// handle greentext
if (_mind.TryGetRole<NinjaRoleComponent>(uid, out var role))
role.DoorsJacked++;
if (_mind.TryGetObjectiveComp<DoorjackConditionComponent>(uid, out var obj))
obj.DoorsJacked++;
}
/// <summary>
@@ -242,14 +232,14 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
? Loc.GetString("ninja-research-steal-fail")
: Loc.GetString("ninja-research-steal-success", ("count", gained), ("server", args.Target));
_popup.PopupEntity(str, uid, uid, PopupType.Medium);
Popup.PopupEntity(str, uid, uid, PopupType.Medium);
}
private void OnThreatCalledIn(EntityUid uid, SpaceNinjaComponent comp, ref ThreatCalledInEvent args)
{
if (_mind.TryGetRole<NinjaRoleComponent>(uid, out var role))
if (_mind.TryGetObjectiveComp<TerrorConditionComponent>(uid, out var obj))
{
role.CalledInThreat = true;
obj.CalledInThreat = true;
}
}
}

View File

@@ -1,5 +1,6 @@
using Content.Server.Explosion.EntitySystems;
using Content.Server.Mind;
using Content.Server.Objectives.Components;
using Content.Server.Popups;
using Content.Server.Roles;
using Content.Server.Sticky.Events;
@@ -69,10 +70,10 @@ public sealed class SpiderChargeSystem : EntitySystem
/// </summary>
private void OnExplode(EntityUid uid, SpiderChargeComponent comp, TriggerEvent args)
{
if (comp.Planter == null || !_mind.TryGetRole<NinjaRoleComponent>(comp.Planter.Value, out var role))
if (comp.Planter == null || !_mind.TryGetObjectiveComp<SpiderChargeConditionComponent>(comp.Planter.Value, out var obj))
return;
// assumes the target was destroyed, that the charge wasn't moved somehow
role.SpiderChargeDetonated = true;
obj.SpiderChargeDetonated = true;
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server.Objectives.Systems;
using Content.Shared.Ninja.Systems;
namespace Content.Server.Objectives.Components;
@@ -6,7 +7,9 @@ namespace Content.Server.Objectives.Components;
/// Objective condition that requires the player to be a ninja and have doorjacked at least a random number of airlocks.
/// Requires <see cref="NumberObjectiveComponent"/> to function.
/// </summary>
[RegisterComponent, Access(typeof(NinjaConditionsSystem))]
[RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SharedSpaceNinjaSystem))]
public sealed partial class DoorjackConditionComponent : Component
{
[DataField("doorsJacked"), ViewVariables(VVAccess.ReadWrite)]
public int DoorsJacked;
}

View File

@@ -1,3 +1,4 @@
using Content.Server.Ninja.Systems;
using Content.Server.Objectives.Systems;
namespace Content.Server.Objectives.Components;
@@ -5,7 +6,9 @@ namespace Content.Server.Objectives.Components;
/// <summary>
/// Requires that the player is a ninja and blew up their spider charge at its target location.
/// </summary>
[RegisterComponent, Access(typeof(NinjaConditionsSystem))]
[RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SpiderChargeSystem))]
public sealed partial class SpiderChargeConditionComponent : Component
{
[DataField("spiderChargeDetonated"), ViewVariables(VVAccess.ReadWrite)]
public bool SpiderChargeDetonated;
}

View File

@@ -1,4 +1,5 @@
using Content.Server.Objectives.Systems;
using Content.Shared.Ninja.Systems;
namespace Content.Server.Objectives.Components;
@@ -6,7 +7,9 @@ namespace Content.Server.Objectives.Components;
/// Objective condition that requires the player to be a ninja and have stolen at least a random number of technologies.
/// Requires <see cref="NumberObjectiveComponent"/> to function.
/// </summary>
[RegisterComponent, Access(typeof(NinjaConditionsSystem))]
[RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SharedSpaceNinjaSystem))]
public sealed partial class StealResearchConditionComponent : Component
{
[DataField("downloadedNodes"), ViewVariables(VVAccess.ReadWrite)]
public HashSet<string> DownloadedNodes = new();
}

View File

@@ -1,11 +1,17 @@
using Content.Server.Objectives.Systems;
using Content.Shared.Ninja.Systems;
namespace Content.Server.Objectives.Components;
/// <summary>
/// Requires that the player is a ninja and has called in a threat.
/// </summary>
[RegisterComponent, Access(typeof(NinjaConditionsSystem))]
[RegisterComponent, Access(typeof(NinjaConditionsSystem), typeof(SharedSpaceNinjaSystem))]
public sealed partial class TerrorConditionComponent : Component
{
/// <summary>
/// Whether the comms console has been hacked
/// </summary>
[DataField("calledInThreat"), ViewVariables(VVAccess.ReadWrite)]
public bool CalledInThreat;
}

View File

@@ -2,7 +2,6 @@ using Content.Server.Roles;
using Content.Server.Objectives.Components;
using Content.Server.Warps;
using Content.Shared.Objectives.Components;
using Robust.Shared.GameObjects;
namespace Content.Server.Objectives.Systems;
@@ -31,22 +30,16 @@ public sealed class NinjaConditionsSystem : EntitySystem
private void OnDoorjackGetProgress(EntityUid uid, DoorjackConditionComponent comp, ref ObjectiveGetProgressEvent args)
{
args.Progress = DoorjackProgress(args.MindId, _number.GetTarget(uid));
args.Progress = DoorjackProgress(comp, _number.GetTarget(uid));
}
private float DoorjackProgress(EntityUid mindId, int target)
private float DoorjackProgress(DoorjackConditionComponent comp, int target)
{
// prevent divide-by-zero
if (target == 0)
return 1f;
if (!TryComp<NinjaRoleComponent>(mindId, out var role))
return 0f;
if (role.DoorsJacked >= target)
return 1f;
return (float) role.DoorsJacked / (float) target;
return MathF.Min(comp.DoorsJacked / (float) target, 1f);
}
// spider charge
@@ -58,7 +51,7 @@ public sealed class NinjaConditionsSystem : EntitySystem
private void OnSpiderChargeGetProgress(EntityUid uid, SpiderChargeConditionComponent comp, ref ObjectiveGetProgressEvent args)
{
args.Progress = TryComp<NinjaRoleComponent>(args.MindId, out var role) && role.SpiderChargeDetonated ? 1f : 0f;
args.Progress = comp.SpiderChargeDetonated ? 1f : 0f;
}
private string SpiderChargeTitle(EntityUid mindId)
@@ -79,28 +72,20 @@ public sealed class NinjaConditionsSystem : EntitySystem
private void OnStealResearchGetProgress(EntityUid uid, StealResearchConditionComponent comp, ref ObjectiveGetProgressEvent args)
{
args.Progress = StealResearchProgress(args.MindId, _number.GetTarget(uid));
args.Progress = StealResearchProgress(comp, _number.GetTarget(uid));
}
private float StealResearchProgress(EntityUid mindId, int target)
private float StealResearchProgress(StealResearchConditionComponent comp, int target)
{
// prevent divide-by-zero
if (target == 0)
return 1f;
if (!TryComp<NinjaRoleComponent>(mindId, out var role))
return 0f;
if (role.DownloadedNodes.Count >= target)
return 1f;
return (float) role.DownloadedNodes.Count / (float) target;
return MathF.Min(comp.DownloadedNodes.Count / (float) target, 1f);
}
// terror
private void OnTerrorGetProgress(EntityUid uid, TerrorConditionComponent comp, ref ObjectiveGetProgressEvent args)
{
args.Progress = TryComp<NinjaRoleComponent>(args.MindId, out var role) && role.CalledInThreat ? 1f : 0f;
args.Progress = comp.CalledInThreat ? 1f : 0f;
}
}

View File

@@ -8,33 +8,9 @@ namespace Content.Server.Roles;
[RegisterComponent]
public sealed partial class NinjaRoleComponent : AntagonistRoleComponent
{
/// <summary>
/// Number of doors that have been doorjacked, used for objective
/// </summary>
[DataField("doorsJacked")]
public int DoorsJacked;
/// <summary>
/// Research nodes that have been downloaded, used for objective
/// </summary>
[DataField("downloadedNodes")]
public HashSet<string> DownloadedNodes = new();
/// <summary>
/// Warp point that the spider charge has to target
/// </summary>
[DataField("spiderChargeTarget")]
public EntityUid? SpiderChargeTarget;
/// <summary>
/// Whether the spider charge has been detonated on the target, used for objective
/// </summary>
[DataField("spiderChargeDetonated")]
public bool SpiderChargeDetonated;
/// <summary>
/// Whether the comms console has been hacked, used for objective
/// </summary>
[DataField("calledInThreat")]
public bool CalledInThreat;
}

View File

@@ -292,6 +292,33 @@ public abstract class SharedMindSystem : EntitySystem
return true;
}
public bool TryGetObjectiveComp<T>(EntityUid uid, [NotNullWhen(true)] out T? objective) where T : Component
{
if (TryGetMind(uid, out var mindId, out var mind) && TryGetObjectiveComp(mindId, out objective, mind))
{
return true;
}
objective = default;
return false;
}
public bool TryGetObjectiveComp<T>(EntityUid mindId, [NotNullWhen(true)] out T? objective, MindComponent? mind = null) where T : Component
{
if (Resolve(mindId, ref mind))
{
var query = GetEntityQuery<T>();
foreach (var uid in mind.AllObjectives)
{
if (query.TryGetComponent(uid, out objective))
{
return true;
}
}
}
objective = default;
return false;
}
public bool TryGetSession(EntityUid? mindId, [NotNullWhen(true)] out ICommonSession? session)
{
session = null;

View File

@@ -11,8 +11,8 @@ namespace Content.Shared.Ninja.Systems;
/// </summary>
public abstract class SharedSpaceNinjaSystem : EntitySystem
{
[Dependency] protected readonly SharedNinjaSuitSystem _suit = default!;
[Dependency] protected readonly SharedPopupSystem _popup = default!;
[Dependency] protected readonly SharedNinjaSuitSystem Suit = default!;
[Dependency] protected readonly SharedPopupSystem Popup = default!;
public override void Initialize()
{
@@ -74,7 +74,7 @@ public abstract class SharedSpaceNinjaSystem : EntitySystem
{
if (comp.Suit != null && TryComp<StealthClothingComponent>(comp.Suit, out var stealthClothing) && stealthClothing.Enabled)
{
_suit.RevealNinja(comp.Suit.Value, uid, null, stealthClothing);
Suit.RevealNinja(comp.Suit.Value, uid, null, stealthClothing);
}
}
@@ -83,7 +83,7 @@ public abstract class SharedSpaceNinjaSystem : EntitySystem
/// </summary>
private void OnShotAttempted(EntityUid uid, SpaceNinjaComponent comp, ref ShotAttemptedEvent args)
{
_popup.PopupClient(Loc.GetString("gun-disabled"), uid, uid);
Popup.PopupClient(Loc.GetString("gun-disabled"), uid, uid);
args.Cancel();
}
}