ritual cucumber setup

This commit is contained in:
Ed
2024-09-29 21:55:28 +03:00
parent 3f94c73bdb
commit d8707735d6
10 changed files with 355 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
using Content.Server._CP14.MagicRituals.Components.Requirements;
using Content.Shared._CP14.MagicRitual;
namespace Content.Server._CP14.MagicRituals;
public sealed partial class CP14RitualSystem
{
[Dependency] private readonly EntityLookupSystem _lookup = default!;
private void InitializeRequirements()
{
SubscribeLocalEvent<CP14RitualRequirementEntitiesComponent, CP14RitualTriggerAttempt>(OnResourceRequirementCheck);
}
private void OnResourceRequirementCheck(Entity<CP14RitualRequirementEntitiesComponent> ent, ref CP14RitualTriggerAttempt args)
{
var entitiesAround = _lookup.GetEntitiesInRange(ent, ent.Comp.CheckRange, LookupFlags.Uncontained);
}
}

View File

@@ -0,0 +1,82 @@
using Content.Server._CP14.MagicRituals.Components.Triggers;
using Content.Server.Speech;
using Content.Server.Speech.Components;
using Content.Shared._CP14.MagicRitual;
namespace Content.Server._CP14.MagicRituals;
public sealed partial class CP14RitualSystem
{
private void InitializeTriggers()
{
SubscribeLocalEvent<CP14RitualTriggerVoiceComponent, ComponentInit>(OnVoiceInit);
SubscribeLocalEvent<CP14RitualTriggerVoiceComponent, ListenEvent>(OnListen);
SubscribeLocalEvent<CP14RitualTriggerTimerComponent, MapInitEvent>(OnTimerMapInit);
}
private void UpdateTriggers(float frameTime)
{
TimerUpdate();
}
#region Trigger timer
private void OnTimerMapInit(Entity<CP14RitualTriggerTimerComponent> ent, ref MapInitEvent args)
{
ent.Comp.TriggerTime = _timing.CurTime + TimeSpan.FromSeconds(ent.Comp.Time.Next(_random));
}
private void TimerUpdate()
{
var query = EntityQueryEnumerator<CP14RitualTriggerTimerComponent>();
while (query.MoveNext(out var uid, out var timer))
{
if (_timing.CurTime < timer.TriggerTime)
continue;
timer.TriggerTime += TimeSpan.FromSeconds(timer.Time.Next(_random));
var ev = new CP14RitualTriggerAttempt(timer.NextPhase);
RaiseLocalEvent(uid, ev);
}
}
#endregion
#region Trigger voice
private void OnVoiceInit(Entity<CP14RitualTriggerVoiceComponent> ent, ref ComponentInit args)
{
EnsureComp<ActiveListenerComponent>(ent).Range = ent.Comp.ListenRange;
}
private void OnListen(Entity<CP14RitualTriggerVoiceComponent> ent, ref ListenEvent args)
{
var message = args.Message.Trim();
var triggered = false;
foreach (var trigger in ent.Comp.NextPhases)
{
if (trigger.Key != message)
continue;
var triggerEv = new CP14RitualTriggerAttempt(trigger.Value);
RaiseLocalEvent(ent, triggerEv);
triggered = true;
break;
}
if (triggered || ent.Comp.FailAttempts is null || ent.Comp.FailedPhase is null)
return;
ent.Comp.FailAttempts -= 1;
if (!(ent.Comp.FailAttempts <= 0))
return;
var failEv = new CP14RitualTriggerAttempt(ent.Comp.FailedPhase.Value);
RaiseLocalEvent(ent, failEv);
}
#endregion
}

View File

@@ -0,0 +1,58 @@
using Content.Server._CP14.MagicRituals.Components;
using Content.Shared._CP14.MagicRitual;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Server._CP14.MagicRituals;
public partial class CP14RitualSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly TransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
InitializeTriggers();
InitializeRequirements();
SubscribeLocalEvent<CP14MagicRitualComponent, MapInitEvent>(OnRitualInit);
SubscribeLocalEvent<CP14MagicRitualPhaseComponent, CP14RitualTriggerAttempt>(OnPhaseTriggerAttempt);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
UpdateTriggers(frameTime);
}
private void OnRitualInit(Entity<CP14MagicRitualComponent> ritual, ref MapInitEvent args)
{
ChangePhase(ritual, ritual.Comp.StartPhase);
}
private void OnPhaseTriggerAttempt(Entity<CP14MagicRitualPhaseComponent> phase, ref CP14RitualTriggerAttempt args)
{
if (args.Cancelled || args.NextPhase is null || phase.Comp.Ritual is null)
return;
ChangePhase(phase.Comp.Ritual.Value, args.NextPhase.Value);
}
private void ChangePhase(Entity<CP14MagicRitualComponent> ritual, EntProtoId newPhase)
{
QueueDel(ritual.Comp.CurrentPhase);
var newPhaseEnt = Spawn(newPhase, Transform(ritual).Coordinates);
_transform.SetParent(newPhaseEnt, ritual);
var newPhaseComp = EnsureComp<CP14MagicRitualPhaseComponent>(newPhaseEnt);
ritual.Comp.CurrentPhase = (newPhaseEnt, newPhaseComp);
newPhaseComp.Ritual = ritual;
}
}

View File

@@ -0,0 +1,19 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals.Components;
/// <summary>
/// Ritual Behavior Controller. Creates and removes entities of magical phases
/// </summary>
[RegisterComponent, Access(typeof(CP14RitualSystem))]
public sealed partial class CP14MagicRitualComponent : Component
{
[DataField(required: true)]
public EntProtoId StartPhase;
/// <summary>
///
/// </summary>
[DataField]
public Entity<CP14MagicRitualPhaseComponent>? CurrentPhase;
}

View File

@@ -0,0 +1,14 @@
namespace Content.Server._CP14.MagicRituals.Components;
/// <summary>
/// Magical entity that reacts to world events
/// </summary>
[RegisterComponent, Access(typeof(CP14RitualSystem))]
public sealed partial class CP14MagicRitualPhaseComponent : Component
{
/// <summary>
///
/// </summary>
[DataField]
public Entity<CP14MagicRitualComponent>? Ritual;
}

View File

@@ -0,0 +1,38 @@
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals.Components.Requirements;
/// <summary>
///
/// </summary>
[RegisterComponent, Access(typeof(CP14RitualSystem))]
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();
/// <summary>
/// Effect appearing in place of used entities
/// </summary>
[DataField]
public EntProtoId? VisualEffect;
}

View File

@@ -0,0 +1,20 @@
using Content.Shared.Destructible.Thresholds;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals.Components.Triggers;
/// <summary>
///
/// </summary>
[RegisterComponent, Access(typeof(CP14RitualSystem))]
public sealed partial class CP14RitualTriggerTimerComponent : Component
{
[DataField(required: true)]
public MinMax Time = new MinMax(0, 1);
[DataField]
public TimeSpan TriggerTime = TimeSpan.Zero;
[DataField(required: true)]
public EntProtoId NextPhase;
}

View File

@@ -0,0 +1,26 @@
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.MagicRituals.Components.Triggers;
/// <summary>
///
/// </summary>
[RegisterComponent, Access(typeof(CP14RitualSystem))]
public sealed partial class CP14RitualTriggerVoiceComponent : Component
{
[DataField]
public float ListenRange = 5f;
[DataField(required: true)]
public Dictionary<string, EntProtoId> NextPhases = new();
/// <summary>
/// the number of errors (incorrect phrases) that can be said next to the ritual, before switching to FailedPhase.
/// set null, if you want an infinite number of tries
/// </summary>
[DataField]
public int? FailAttempts = null;
[DataField]
public EntProtoId? FailedPhase;
}

View File

@@ -0,0 +1,13 @@
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.MagicRitual;
public sealed class CP14RitualTriggerAttempt : CancellableEntityEventArgs
{
public EntProtoId? NextPhase;
public CP14RitualTriggerAttempt(EntProtoId phase)
{
NextPhase = phase;
}
}

View File

@@ -0,0 +1,64 @@
- type: entity
id: CP14BaseRitualPhase
abstract: true
components:
- type: CP14MagicRitualPhase
- type: Tag
tags:
- HideContextMenu
- type: entity
parent: CP14FoodCucumber
id: RitualCucumber
name: ritual cucumber
components:
- type: CP14MagicRitual
startPhase: CP14RitualPhaseTest1
- type: entity
parent: CP14BaseRitualPhase
id: CP14RitualPhaseTest1
components:
- type: PointLight
color: "#FFFF00"
- type: CP14RitualTriggerVoice
nextPhases:
"Hello": CP14RitualPhaseTest2
"Blya": CP14RitualPhaseTest3
- type: entity
parent: CP14BaseRitualPhase
id: CP14RitualPhaseTest2
components:
- type: PointLight
color: "#FF00FF"
- type: CP14RitualTriggerTimer
nextPhase: CP14RitualPhaseTest1
time:
min: 5
max: 10
- type: EmitSoundOnSpawn
sound:
path: /Audio/Effects/tesla_consume.ogg
params:
variation: 0.3
- type: entity
parent: CP14BaseRitualPhase
id: CP14RitualPhaseTest3
components:
- type: PointLight
color: "#00FFFF"
- type: CP14RitualTriggerVoice
nextPhases:
"Burbon": CP14RitualPhaseTest2
"Nazad": CP14RitualPhaseTest1
- type: CP14RitualTriggerTimer
nextPhase: CP14RitualPhaseTest1
time:
min: 5
max: 10
- type: RandomSpawner
deleteSpawnerAfterSpawn: false
prototypes:
- CP14DirtEffect