entities requirements
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -25,6 +25,11 @@
|
||||
nextPhases:
|
||||
"Hello": CP14RitualPhaseTest2
|
||||
"Blya": CP14RitualPhaseTest3
|
||||
- type: CP14RitualRequirementEntities
|
||||
visualEffect: CP14ImpactEffectShadowGrab
|
||||
consumeResource: true
|
||||
requiredEntities:
|
||||
CP14FoodCucumber: 3
|
||||
|
||||
- type: entity
|
||||
parent: CP14BaseRitualPhase
|
||||
|
||||
Reference in New Issue
Block a user