entities requirements

This commit is contained in:
Ed
2024-09-29 23:15:16 +03:00
parent d8707735d6
commit 4b5080b90d
6 changed files with 122 additions and 26 deletions

View File

@@ -1,5 +1,7 @@
using Content.Server._CP14.MagicRituals.Components.Requirements;
using Content.Shared._CP14.MagicRitual;
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals;
@@ -7,15 +9,92 @@ public sealed partial class CP14RitualSystem
{
[Dependency] private readonly EntityLookupSystem _lookup = default!;
private EntityQuery<MetaDataComponent> _metaQuery;
private EntityQuery<StackComponent> _stackQuery;
private void InitializeRequirements()
{
SubscribeLocalEvent<CP14RitualRequirementEntitiesComponent, CP14RitualTriggerAttempt>(OnResourceRequirementCheck);
}
private void OnResourceRequirementCheck(Entity<CP14RitualRequirementEntitiesComponent> ent, ref CP14RitualTriggerAttempt args)
private void OnResourceRequirementCheck(Entity<CP14RitualRequirementEntitiesComponent> requirement, ref CP14RitualTriggerAttempt args)
{
var entitiesAround = _lookup.GetEntitiesInRange(ent, ent.Comp.CheckRange, LookupFlags.Uncontained);
var entitiesAround = _lookup.GetEntitiesInRange(requirement, requirement.Comp.CheckRange, LookupFlags.Uncontained);
var passed = true;
foreach (var reqEnt in requirement.Comp.RequiredEntities)
{
var requiredCount = reqEnt.Value;
foreach (var entity in entitiesAround)
{
var entProto = MetaData(entity).EntityPrototype;
if (entProto is null)
continue;
if (entProto.ID == reqEnt.Key && requiredCount > 0)
{
Spawn(requirement.Comp.VisualEffect, Transform(entity).Coordinates);
requiredCount--;
if (requirement.Comp.ConsumeResource)
Del(entity);
}
}
if (requiredCount > 0)
passed = false;
}
foreach (var reqStack in requirement.Comp.RequiredStack)
{
var requiredCount = reqStack.Value;
foreach (var entity in entitiesAround)
{
if (!_stackQuery.TryGetComponent(entity, out var stack))
continue;
if (stack.StackTypeId != reqStack.Key)
continue;
var count = (int)MathF.Min(requiredCount, stack.Count);
requiredCount -= count;
Spawn(requirement.Comp.VisualEffect, Transform(entity).Coordinates);
if (requirement.Comp.ConsumeResource)
{
if (stack.Count - count <= 0)
Del(entity);
else
_stack.SetCount(entity, stack.Count - count, stack);
}
}
if (requiredCount > 0)
passed = false;
}
if (!passed)
args.Cancel();
}
private Dictionary<EntProtoId, int> IndexIngredients(HashSet<EntityUid> ingredients)
{
var indexedIngredients = new Dictionary<EntProtoId, int>();
foreach (var ingredient in ingredients)
{
var protoId = _metaQuery.GetComponent(ingredient).EntityPrototype?.ID;
if (protoId == null)
continue;
if (indexedIngredients.ContainsKey(protoId))
indexedIngredients[protoId]++;
else
indexedIngredients[protoId] = 1;
}
return indexedIngredients;
}
}

View File

@@ -1,7 +1,10 @@
using Content.Server._CP14.MagicRituals.Components;
using Content.Server._CP14.MagicRituals.Components.Triggers;
using Content.Server.Speech;
using Content.Server.Speech.Components;
using Content.Shared._CP14.MagicRitual;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals;
@@ -20,6 +23,18 @@ public sealed partial class CP14RitualSystem
TimerUpdate();
}
private void TriggerRitualPhase(Entity<CP14MagicRitualPhaseComponent> ent, EntProtoId nextPhase)
{
var ev = new CP14RitualTriggerAttempt();
RaiseLocalEvent(ent, ev);
if (ev.Cancelled)
return;
var evConfirmed = new CP14RitualTriggerEvent(nextPhase);
RaiseLocalEvent(ent, evConfirmed);
}
#region Trigger timer
private void OnTimerMapInit(Entity<CP14RitualTriggerTimerComponent> ent, ref MapInitEvent args)
@@ -29,16 +44,15 @@ public sealed partial class CP14RitualSystem
private void TimerUpdate()
{
var query = EntityQueryEnumerator<CP14RitualTriggerTimerComponent>();
while (query.MoveNext(out var uid, out var timer))
var query = EntityQueryEnumerator<CP14RitualTriggerTimerComponent, CP14MagicRitualPhaseComponent>();
while (query.MoveNext(out var uid, out var timer, out var phase))
{
if (_timing.CurTime < timer.TriggerTime)
continue;
timer.TriggerTime += TimeSpan.FromSeconds(timer.Time.Next(_random));
var ev = new CP14RitualTriggerAttempt(timer.NextPhase);
RaiseLocalEvent(uid, ev);
TriggerRitualPhase((uid, phase), timer.NextPhase);
}
}
@@ -53,6 +67,9 @@ public sealed partial class CP14RitualSystem
private void OnListen(Entity<CP14RitualTriggerVoiceComponent> ent, ref ListenEvent args)
{
if (!TryComp<CP14MagicRitualPhaseComponent>(ent, out var phase))
return;
var message = args.Message.Trim();
var triggered = false;
@@ -61,8 +78,7 @@ public sealed partial class CP14RitualSystem
if (trigger.Key != message)
continue;
var triggerEv = new CP14RitualTriggerAttempt(trigger.Value);
RaiseLocalEvent(ent, triggerEv);
TriggerRitualPhase((ent.Owner,phase), trigger.Value);
triggered = true;
break;
}
@@ -75,8 +91,7 @@ public sealed partial class CP14RitualSystem
if (!(ent.Comp.FailAttempts <= 0))
return;
var failEv = new CP14RitualTriggerAttempt(ent.Comp.FailedPhase.Value);
RaiseLocalEvent(ent, failEv);
TriggerRitualPhase((ent.Owner,phase), ent.Comp.FailedPhase.Value);
}
#endregion
}

View File

@@ -1,4 +1,5 @@
using Content.Server._CP14.MagicRituals.Components;
using Content.Server.Stack;
using Content.Shared._CP14.MagicRitual;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
@@ -10,6 +11,7 @@ namespace Content.Server._CP14.MagicRituals;
public partial class CP14RitualSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly StackSystem _stack = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly TransformSystem _transform = default!;
@@ -21,7 +23,7 @@ public partial class CP14RitualSystem : EntitySystem
InitializeRequirements();
SubscribeLocalEvent<CP14MagicRitualComponent, MapInitEvent>(OnRitualInit);
SubscribeLocalEvent<CP14MagicRitualPhaseComponent, CP14RitualTriggerAttempt>(OnPhaseTriggerAttempt);
SubscribeLocalEvent<CP14MagicRitualPhaseComponent, CP14RitualTriggerEvent>(OnPhaseTriggerAttempt);
}
public override void Update(float frameTime)
@@ -36,9 +38,9 @@ public partial class CP14RitualSystem : EntitySystem
ChangePhase(ritual, ritual.Comp.StartPhase);
}
private void OnPhaseTriggerAttempt(Entity<CP14MagicRitualPhaseComponent> phase, ref CP14RitualTriggerAttempt args)
private void OnPhaseTriggerAttempt(Entity<CP14MagicRitualPhaseComponent> phase, ref CP14RitualTriggerEvent args)
{
if (args.Cancelled || args.NextPhase is null || phase.Comp.Ritual is null)
if (args.NextPhase is null || phase.Comp.Ritual is null)
return;
ChangePhase(phase.Comp.Ritual.Value, args.NextPhase.Value);

View File

@@ -12,27 +12,18 @@ public sealed partial class CP14RitualRequirementEntitiesComponent : Component
[DataField]
public float CheckRange = 1f;
/// <summary>
/// Entities that should be located nearby, but which will not be spent.
/// </summary>
[DataField]
public Dictionary<EntProtoId, int> RequiredEntities = new ();
/// <summary>
/// Entities to be placed next to each other, which will be spent.
/// </summary>
[DataField]
public Dictionary<EntProtoId, int> ConsumedEntities = new ();
[DataField]
public Dictionary<ProtoId<StackPrototype>, int> RequiredStack = new();
[DataField]
public Dictionary<ProtoId<StackPrototype>, int> ConsumedStack = new();
public bool ConsumeResource = false;
/// <summary>
/// Effect appearing in place of used entities
/// </summary>
[DataField]
public EntProtoId? VisualEffect;
public EntProtoId? VisualEffect = "CP14DustEffect";
}

View File

@@ -3,10 +3,14 @@ using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual;
public sealed class CP14RitualTriggerAttempt : CancellableEntityEventArgs
{
}
public sealed class CP14RitualTriggerEvent : EntityEventArgs
{
public EntProtoId? NextPhase;
public CP14RitualTriggerAttempt(EntProtoId phase)
public CP14RitualTriggerEvent(EntProtoId phase)
{
NextPhase = phase;
}

View File

@@ -25,6 +25,11 @@
nextPhases:
"Hello": CP14RitualPhaseTest2
"Blya": CP14RitualPhaseTest3
- type: CP14RitualRequirementEntities
visualEffect: CP14ImpactEffectShadowGrab
consumeResource: true
requiredEntities:
CP14FoodCucumber: 3
- type: entity
parent: CP14BaseRitualPhase