Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Content.Client/_DV/CosmicCult/CosmicGlyphSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Content.Shared._DV.CosmicCult;

namespace Content.Client._DV.CosmicCult;

public sealed class CosmicGlyphSystem : SharedCosmicGlyphSystem
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared._DV.CosmicCult;
using Content.Shared.Damage;
using Content.Shared.Mind;
using Content.Shared.Mindshield.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Popups;
Expand All @@ -22,15 +23,17 @@ public sealed class CosmicConversionSystem : EntitySystem
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SharedCosmicCultSystem _cosmicCult = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<CosmicGlyphConversionComponent, TryActivateGlyphEvent>(OnConversionGlyph);
SubscribeLocalEvent<CosmicGlyphConversionComponent, CheckGlyphConditionsEvent>(OnCheckGlyphConditions);
}

private void OnConversionGlyph(Entity<CosmicGlyphConversionComponent> uid, ref TryActivateGlyphEvent args)
private void OnCheckGlyphConditions(Entity<CosmicGlyphConversionComponent> uid, ref CheckGlyphConditionsEvent args)
{
var possibleTargets = _cosmicGlyph.GetTargetsNearGlyph(uid, uid.Comp.ConversionRange, entity => _cosmicCult.EntityIsCultist(entity));
if (possibleTargets.Count == 0)
Expand All @@ -45,6 +48,28 @@ private void OnConversionGlyph(Entity<CosmicGlyphConversionComponent> uid, ref T
args.Cancel();
return;
}
foreach (var target in possibleTargets)
{
if (!_mind.TryGetMind(target, out _, out _))
{
_popup.PopupEntity(Loc.GetString("cult-glyph-target-mindless"), uid, args.User);
args.Cancel();
return;
}
}
}

private void OnConversionGlyph(Entity<CosmicGlyphConversionComponent> uid, ref TryActivateGlyphEvent args)
{
var ev = new CheckGlyphConditionsEvent(args.User, args.Cultists);
RaiseLocalEvent(uid, ref ev);
if (ev.Cancelled)
{
args.Cancel();
return;
}

var possibleTargets = _cosmicGlyph.GetTargetsNearGlyph(uid, uid.Comp.ConversionRange, entity => _cosmicCult.EntityIsCultist(entity));

foreach (var target in possibleTargets)
{
Expand Down
18 changes: 16 additions & 2 deletions Content.Server/_DV/CosmicCult/Abilities/CosmicTransmuteSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,32 @@ public override void Initialize()
base.Initialize();

SubscribeLocalEvent<CosmicGlyphTransmuteComponent, TryActivateGlyphEvent>(OnTransmuteGlyph);
SubscribeLocalEvent<CosmicGlyphTransmuteComponent, CheckGlyphConditionsEvent>(OnCheckGlyphConditions);
}

private void OnTransmuteGlyph(Entity<CosmicGlyphTransmuteComponent> uid, ref TryActivateGlyphEvent args)
private void OnCheckGlyphConditions(Entity<CosmicGlyphTransmuteComponent> uid, ref CheckGlyphConditionsEvent args)
{
var tgtpos = Transform(uid).Coordinates;
var possibleTargets = GatherEntities(uid);
if (possibleTargets.Count == 0)
{
_popup.PopupEntity(Loc.GetString("cult-glyph-conditions-not-met"), uid, args.User);
args.Cancel();
return;
}
}

private void OnTransmuteGlyph(Entity<CosmicGlyphTransmuteComponent> uid, ref TryActivateGlyphEvent args)
{
var ev = new CheckGlyphConditionsEvent(args.User, args.Cultists);
RaiseLocalEvent(uid, ref ev);
if (ev.Cancelled)
{
args.Cancel();
return;
}

var tgtpos = Transform(uid).Coordinates;
var possibleTargets = GatherEntities(uid);
var target = _random.Pick(possibleTargets);
if (!TryComp<CosmicTransmutableComponent>(target, out var comp)) return;
Spawn(comp.TransmutesTo, tgtpos);
Expand Down
6 changes: 1 addition & 5 deletions Content.Server/_DV/CosmicCult/CosmicCultSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Content.Server._EE.Radio;
using Content.Shared.Alert;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Eye;
using Content.Shared.Hands;
using Content.Shared.Inventory.Events;
Expand All @@ -29,6 +28,7 @@
using Content.Shared.Popups;
using Content.Shared.Radio;
using Content.Server.Radio.Components;
using Content.Shared.Examine;

namespace Content.Server._DV.CosmicCult;

Expand Down Expand Up @@ -85,8 +85,6 @@ public override void Initialize()
SubscribeLocalEvent<CosmicImposingComponent, ComponentRemove>(OnEndImposition);
SubscribeLocalEvent<CosmicImposingComponent, RefreshMovementSpeedModifiersEvent>(OnImpositionMoveSpeed);

SubscribeLocalEvent<CosmicCultExamineComponent, ExaminedEvent>(OnCosmicCultExamined);

SubscribeLocalEvent<CosmicCultComponent, EncryptionChannelsChangedEvent>(OnTransmitterChannelsChangedCult, after: new[] { typeof(IntrinsicRadioKeySystem) });

SubscribeFinale(); //Hook up the cosmic cult finale system
Expand Down Expand Up @@ -191,12 +189,10 @@ private void OnEndInfluenceStride(Entity<InfluenceStrideComponent> uid, ref Comp
private void OnStartImposition(Entity<CosmicImposingComponent> uid, ref ComponentInit args) // these functions just make sure
{
_movementSpeed.RefreshMovementSpeedModifiers(uid);
EnsureComp<CosmicCultExamineComponent>(uid).CultistText = "cosmic-examine-text-malignecho";
}
private void OnEndImposition(Entity<CosmicImposingComponent> uid, ref ComponentRemove args) // as various cosmic cult effects get added and removed
{
_movementSpeed.RefreshMovementSpeedModifiers(uid);
RemComp<CosmicCultExamineComponent>(uid);
}

private void OnRefreshMoveSpeed(EntityUid uid, InfluenceStrideComponent comp, RefreshMovementSpeedModifiersEvent args)
Expand Down
94 changes: 77 additions & 17 deletions Content.Server/_DV/CosmicCult/CosmicGlyphSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
using Robust.Server.Audio;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.Timing;

namespace Content.Server._DV.CosmicCult;

public sealed class CosmicGlyphSystem : EntitySystem
public sealed class CosmicGlyphSystem : SharedCosmicGlyphSystem
{
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
Expand All @@ -22,35 +23,55 @@ public sealed class CosmicGlyphSystem : EntitySystem
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedCosmicCultSystem _cosmicCult = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly IGameTiming _timing = default!;

private readonly HashSet<Entity<CosmicCultComponent>> _cultists = [];
private readonly HashSet<Entity<HumanoidAppearanceComponent>> _humanoids = [];

public override void Initialize()
{
SubscribeLocalEvent<CosmicGlyphComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<CosmicGlyphComponent, ActivateInWorldEvent>(OnUseGlyph);
SubscribeLocalEvent<CosmicGlyphComponent, ComponentStartup>(OnGlyphCreated);
}

#region Base trigger

private void OnExamine(Entity<CosmicGlyphComponent> uid, ref ExaminedEvent args)
private void OnGlyphCreated(Entity<CosmicGlyphComponent> ent, ref ComponentStartup args)
{
if (_cosmicCult.EntityIsCultist(args.Examiner))
{
args.PushMarkup(Loc.GetString("cosmic-examine-glyph-cultcount", ("COUNT", uid.Comp.RequiredCultists)));
}
else
ent.Comp.Timer = _timing.CurTime + ent.Comp.SpawnTime;
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var glyphQuery = EntityQueryEnumerator<CosmicGlyphComponent>();
while (glyphQuery.MoveNext(out var uid, out var comp))
{
args.PushMarkup(Loc.GetString("cosmic-examine-text-glyphs"));
if (_timing.CurTime < comp.Timer) continue;
if (comp.State == GlyphStatus.Spawning || comp.State == GlyphStatus.Cooldown)
{
_appearance.SetData(uid, GlyphVisuals.Status, GlyphStatus.Ready);
comp.State = GlyphStatus.Ready;
return;
}
if (comp.State == GlyphStatus.Active)
{
ActivateGlyph(new Entity<CosmicGlyphComponent>(uid, comp));
}
if (comp.State == GlyphStatus.Despawning)
{
QueueDel(uid);
}
}
}

private void OnUseGlyph(Entity<CosmicGlyphComponent> uid, ref ActivateInWorldEvent args)
{
var tgtpos = Transform(uid).Coordinates;
var userCoords = Transform(args.User).Coordinates;
if (args.Handled || !userCoords.TryDistance(EntityManager, tgtpos, out var distance) || distance > uid.Comp.ActivationRange || !_cosmicCult.EntityIsCultist(args.User))
if (args.Handled || !userCoords.TryDistance(EntityManager, tgtpos, out var distance) || distance > uid.Comp.ActivationRange || !_cosmicCult.EntityIsCultist(args.User) || uid.Comp.State != GlyphStatus.Ready)
return;
var cultists = GatherCultists(uid, uid.Comp.ActivationRange);
if (cultists.Count < uid.Comp.RequiredCultists)
Expand All @@ -59,21 +80,60 @@ private void OnUseGlyph(Entity<CosmicGlyphComponent> uid, ref ActivateInWorldEve
return;
}

var ev = new CheckGlyphConditionsEvent(args.User, cultists);
RaiseLocalEvent(uid, ref ev);
if (ev.Cancelled) return;

args.Handled = true;
var tryInvokeEv = new TryActivateGlyphEvent(args.User, cultists);
RaiseLocalEvent(uid, tryInvokeEv);
if (tryInvokeEv.Cancelled)
uid.Comp.User = args.User;
if (uid.Comp.ActivationTime > TimeSpan.FromSeconds(0))
{
_appearance.SetData(uid, GlyphVisuals.Status, GlyphStatus.Active);
uid.Comp.State = GlyphStatus.Active;
uid.Comp.Timer = _timing.CurTime + uid.Comp.ActivationTime;
_audio.PlayPvs(uid.Comp.ChargeSFX, Transform(uid).Coordinates);
}
else ActivateGlyph(uid);
}

private void ActivateGlyph(Entity<CosmicGlyphComponent> ent)
{
if (ent.Comp.EraseOnUse)
{
EraseGlyph(ent);
}
else if (ent.Comp.CooldownTime > TimeSpan.FromSeconds(0))
{
_appearance.SetData(ent, GlyphVisuals.Status, GlyphStatus.Cooldown);
ent.Comp.State = GlyphStatus.Cooldown;
ent.Comp.Timer = _timing.CurTime + ent.Comp.CooldownTime;
}
else
{
_appearance.SetData(ent, GlyphVisuals.Status, GlyphStatus.Ready);
ent.Comp.State = GlyphStatus.Ready;
}

if (ent.Comp.User is not { } user) return;
var cultists = GatherCultists(ent, ent.Comp.ActivationRange);
var tryInvokeEv = new TryActivateGlyphEvent(user, cultists);
RaiseLocalEvent(ent, ref tryInvokeEv);
var tgtpos = Transform(ent).Coordinates;
if (tryInvokeEv.Cancelled || cultists.Count < ent.Comp.RequiredCultists)
{
_audio.PlayPvs(ent.Comp.FailSFX, tgtpos);
return;
}

var damage = uid.Comp.ActivationDamage / cultists.Count;
var damage = ent.Comp.ActivationDamage / cultists.Count;
foreach (var cultist in cultists)
{
_damageable.TryChangeDamage(cultist, damage, true);
}

_audio.PlayPvs(uid.Comp.GylphSFX, tgtpos, AudioParams.Default.WithVolume(+1f));
Spawn(uid.Comp.GylphVFX, tgtpos);
QueueDel(uid);
_audio.PlayPvs(ent.Comp.TriggerSFX, tgtpos, AudioParams.Default.WithVolume(+1f));
Spawn(ent.Comp.GlyphVFX, tgtpos);
ent.Comp.User = null;
}
#endregion

Expand Down
55 changes: 49 additions & 6 deletions Content.Shared/_DV/CosmicCult/Components/CosmicGlyphComponent.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using Content.Shared.Damage;
using Robust.Shared.GameStates;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;

namespace Content.Shared._DV.CosmicCult.Components;

[RegisterComponent]
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause]
public sealed partial class CosmicGlyphComponent : Component
{
[DataField] public int RequiredCultists = 1;
Expand All @@ -15,12 +19,51 @@ public sealed partial class CosmicGlyphComponent : Component
/// </summary>
[DataField] public DamageSpecifier ActivationDamage = new();
[DataField] public bool CanBeErased = true;
[DataField] public EntProtoId GylphVFX = "CosmicGenericVFX";
[DataField] public SoundSpecifier GylphSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/glyph_trigger.ogg");
[DataField] public bool EraseOnUse = false;
[DataField] public EntProtoId GlyphVFX = "CosmicGenericVFX";
[DataField] public SoundSpecifier TriggerSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/glyph_trigger.ogg");
[DataField] public SoundSpecifier ChargeSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/glyph_charge.ogg");
[DataField] public SoundSpecifier FailSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/glyph_fail.ogg");
[DataField] public GlyphStatus State = GlyphStatus.Spawning;
[DataField] public EntityUid? User = null;
[DataField] public TimeSpan SpawnTime = TimeSpan.FromSeconds(1.2);
[DataField] public TimeSpan DespawnTime = TimeSpan.FromSeconds(0.6);
[DataField] public TimeSpan ActivationTime = TimeSpan.FromSeconds(0);
[DataField] public TimeSpan CooldownTime = TimeSpan.FromSeconds(3.0);
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan Timer = default!;
}

public sealed class TryActivateGlyphEvent(EntityUid user, HashSet<Entity<CosmicCultComponent>> cultists) : CancellableEntityEventArgs
[ByRefEvent]
public record struct TryActivateGlyphEvent(EntityUid User, HashSet<Entity<CosmicCultComponent>> Cultists, bool Cancelled = false)
{
public EntityUid User = user;
public HashSet<Entity<CosmicCultComponent>> Cultists = cultists;
public void Cancel()
{
Cancelled = true;
}
}

[ByRefEvent]
public record struct CheckGlyphConditionsEvent(EntityUid User, HashSet<Entity<CosmicCultComponent>> Cultists, bool Cancelled = false)
{
public void Cancel()
{
Cancelled = true;
}
}

[Serializable, NetSerializable]
public enum GlyphVisuals : byte
{
Status,
}

[Serializable, NetSerializable]
public enum GlyphStatus : byte
{
Spawning,
Despawning,
Ready,
Active,
Cooldown
}
12 changes: 10 additions & 2 deletions Content.Shared/_DV/CosmicCult/SharedCosmicCultSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Content.Shared.Antag;
using Content.Shared.Examine;
using Content.Shared.Ghost;
using Content.Shared.IdentityManagement.Components;
using Content.Shared.Mind;
using Content.Shared.Roles;
using Content.Shared.Verbs;
Expand All @@ -28,10 +29,12 @@ public override void Initialize()
SubscribeLocalEvent<CosmicCultLeadComponent, ComponentGetStateAttemptEvent>(OnCosmicCultCompGetStateAttempt);
SubscribeLocalEvent<CosmicCultComponent, ComponentStartup>(DirtyCosmicCultComps);
SubscribeLocalEvent<CosmicCultLeadComponent, ComponentStartup>(DirtyCosmicCultComps);
SubscribeLocalEvent<CosmicTransmutableComponent, GetVerbsEvent<ExamineVerb>>(OnDetailedExamine);

SubscribeLocalEvent<CosmicTransmutableComponent, GetVerbsEvent<ExamineVerb>>(OnTransmutableExamined);
SubscribeLocalEvent<CosmicCultExamineComponent, ExaminedEvent>(OnCosmicCultExamined);
}

private void OnDetailedExamine(Entity<CosmicTransmutableComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
private void OnTransmutableExamined(Entity<CosmicTransmutableComponent> ent, ref GetVerbsEvent<ExamineVerb> args)
{
if (ent.Comp.TransmutesTo == "" || ent.Comp.RequiredGlyphType == "") return;
if (!EntityIsCultist(args.User)) //non-cultists don't need to know this anyway
Expand All @@ -48,6 +51,11 @@ private void OnDetailedExamine(Entity<CosmicTransmutableComponent> ent, ref GetV
"/Textures/_DV/CosmicCult/Interface/transmute_inspect.png");
}

private void OnCosmicCultExamined(Entity<CosmicCultExamineComponent> ent, ref ExaminedEvent args)
{
args.PushMarkup(Loc.GetString(EntitySeesCult(args.Examiner) ? ent.Comp.CultistText : ent.Comp.OthersText));
}

public bool EntityIsCultist(EntityUid user)
{
if (!_mind.TryGetMind(user, out var mind, out _))
Expand Down
Loading
Loading