diff --git a/Content.Server/Anomaly/AnomalySystem.cs b/Content.Server/Anomaly/AnomalySystem.cs index 4955b4e3369..234ee777d21 100644 --- a/Content.Server/Anomaly/AnomalySystem.cs +++ b/Content.Server/Anomaly/AnomalySystem.cs @@ -87,7 +87,7 @@ public sealed partial class AnomalySystem : SharedAnomalySystem if (anomaly.Comp.CurrentBehavior is not null) RemoveBehavior(anomaly, anomaly.Comp.CurrentBehavior.Value); - EndAnomaly(anomaly, spawnCore: false); + EndAnomaly(anomaly, spawnCore: false, forced: true); } private void OnStartCollide(Entity anomaly, ref StartCollideEvent args) @@ -143,7 +143,7 @@ public sealed partial class AnomalySystem : SharedAnomalySystem return 0; var multiplier = 1f; - if (component.Stability > component.GrowthThreshold) + if (component.AlwaysGrow || component.Stability > component.GrowthThreshold) // DeltaV - Add AlwaysGrow multiplier = component.GrowingPointMultiplier; //more points for unstable //penalty of up to 50% based on health @@ -253,7 +253,11 @@ public sealed partial class AnomalySystem : SharedAnomalySystem else { string stateLoc; - if (anomalyComp.Stability < anomalyComp.DecayThreshold) + // DeltaV - Colossus Additions START + if (anomalyComp.AlwaysGrow) + stateLoc = Loc.GetString("anomaly-scanner-stability-high"); + // DeltaV - Colossus Additions END + else if (anomalyComp.Stability < anomalyComp.DecayThreshold) // DeltaV - Add else stateLoc = Loc.GetString("anomaly-scanner-stability-low"); else if (anomalyComp.Stability > anomalyComp.GrowthThreshold) stateLoc = Loc.GetString("anomaly-scanner-stability-high"); @@ -345,6 +349,15 @@ public sealed partial class AnomalySystem : SharedAnomalySystem msg.AddMarkupOrThrow(Loc.GetString("anomaly-behavior-unknown")); else { + // DeltaV - Colossus Additions START + if (anomalyComp.AlwaysGrow) + { + msg.AddMarkupOrThrow("- " + Loc.GetString("anomaly-behavior-always-grow")); + if (anomalyComp.CurrentBehavior != null) + msg.PushNewline(); + } + // DeltaV - Colossus Additions END + if (anomalyComp.CurrentBehavior != null) { var behavior = _prototype.Index(anomalyComp.CurrentBehavior.Value); @@ -354,7 +367,7 @@ public sealed partial class AnomalySystem : SharedAnomalySystem var mod = Math.Floor((behavior.EarnPointModifier) * 100); msg.AddMarkupOrThrow("- " + Loc.GetString("anomaly-behavior-point", ("mod", mod))); } - else + else if(!anomalyComp.AlwaysGrow) // DeltaV - Add condition, previously regular else { msg.AddMarkupOrThrow(Loc.GetString("anomaly-behavior-balanced")); } diff --git a/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicColossusBuffsSystem.cs b/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicColossusBuffsSystem.cs new file mode 100644 index 00000000000..123c642835e --- /dev/null +++ b/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicColossusBuffsSystem.cs @@ -0,0 +1,63 @@ +using Content.Server._DV.CosmicCult.Components; +using Content.Shared._DV.CosmicCult.Components; +using Content.Shared.Damage; +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Systems; +using Content.Shared.Weapons.Melee; +using Robust.Shared.Prototypes; + +namespace Content.Server._DV.CosmicCult.Abilities.Colossus; + +public sealed class CosmicColossusBuffsSystem : EntitySystem +{ + [Dependency] private readonly DamageableSystem _damage = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(HandleAttackRate); + SubscribeLocalEvent(HandleDamageBonus); + SubscribeLocalEvent(HandleCorruptingSpeed); + SubscribeLocalEvent(HandleHeal); + } + + private void HandleAttackRate(Entity ent, + ref CosmicColossusEffigySupercriticalEvent args) + { + if (TryComp(ent, out var weapon)) + { + weapon.AttackRate *= ent.Comp.Multiplier; + } + } + + private void HandleDamageBonus(Entity ent, + ref CosmicColossusEffigySupercriticalEvent args) + { + if (!TryComp(ent, out var colossusComp)) + return; + + colossusComp.BonusDamage += + new DamageSpecifier(_proto.Index(ent.Comp.BonusDamageType), ent.Comp.BonusDamage); + } + + private void HandleCorruptingSpeed(Entity ent, + ref CosmicColossusEffigySupercriticalEvent args) + { + if (TryComp(ent, out var corrupting)) + { + corrupting.CorruptionSpeed *= ent.Comp.Multiplier; + } + } + + private void HandleHeal(Entity ent, ref CosmicColossusEffigySupercriticalEvent args) + { + if (TryComp(ent, out var damageable)) + { + _damage.TryChangeDamage(ent.Owner, + -damageable.Damage * Math.Abs(ent.Comp.DamageFractionHealed), // just in case someone sets a negative value in YML + true); + } + } +} diff --git a/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicColossusEffigySupercriticalEvent.cs b/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicColossusEffigySupercriticalEvent.cs new file mode 100644 index 00000000000..bbf95809a98 --- /dev/null +++ b/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicColossusEffigySupercriticalEvent.cs @@ -0,0 +1,8 @@ +using Content.Server._DV.CosmicCult.Components; + +namespace Content.Server._DV.CosmicCult.Abilities.Colossus; + +[ByRefEvent] +public readonly record struct CosmicColossusEffigySupercriticalEvent( + Entity Effigy +); diff --git a/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicEffigySystem.cs b/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicEffigySystem.cs index 32a1cb0836b..2540c361699 100644 --- a/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicEffigySystem.cs +++ b/Content.Server/_DV/CosmicCult/Abilities/Colossus/CosmicEffigySystem.cs @@ -1,15 +1,24 @@ using System.Numerics; +using Content.Server._DV.CosmicCult.Abilities.Colossus; +using Content.Server._DV.CosmicCult.Components; using Content.Server.Actions; +using Content.Server.Chat.Managers; using Content.Server.Objectives.Components; using Content.Server.Objectives.Systems; using Content.Server.Popups; using Content.Shared._DV.CosmicCult; using Content.Shared._DV.CosmicCult.Components; +using Content.Shared.Anomaly.Components; using Content.Shared.Maps; using Content.Shared.Mind; +using Content.Shared.Popups; using Content.Shared.Warps; +using Robust.Server.Audio; +using Robust.Server.Player; using Robust.Shared.Map; using Robust.Shared.Map.Components; +using Robust.Shared.Player; +using Robust.Shared.Timing; namespace Content.Server._DV.CosmicCult.Abilities; @@ -23,12 +32,93 @@ public sealed class CosmicEffigySystem : EntitySystem [Dependency] private readonly SharedMapSystem _map = default!; [Dependency] private readonly SharedMindSystem _mind = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly AudioSystem _audio = default!; + [Dependency] private readonly CosmicCultObjectiveSystem _cultObjective = default!; + [Dependency] private readonly IGameTiming _time = default!; + [Dependency] private readonly IChatManager _chat = default!; + [Dependency] private readonly IPlayerManager _player = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnColossusEffigy); + SubscribeLocalEvent(OnSupercritical); + SubscribeLocalEvent(OnAnomShutdown); + } + + private void OnAnomShutdown(Entity ent, ref AnomalyShutdownEvent args) + { + if (args.Forced || args.Supercritical || !Exists(ent.Comp.Colossus) || !TryComp(ent.Comp.Colossus, out var colossusComp)) + return; + + colossusComp.DeathTimer = _time.CurTime; + colossusComp.Timed = true; + } + + private void OnSupercritical(Entity ent, ref AnomalySupercriticalEvent args) + { + if (!Exists(ent.Comp.Colossus) + || !TryComp(ent.Comp.Colossus, out var colossusComp) + || !_mind.TryGetMind(ent.Comp.Colossus.Value, out _, out var mind)) + return; + + var colossus = ent.Comp.Colossus.Value; + + var ev = new CosmicColossusEffigySupercriticalEvent(ent); + RaiseLocalEvent(colossus, ref ev); + + var transform = Transform(ent.Comp.Colossus.Value); + Spawn(colossusComp.BuffVfx, transform.Coordinates); + + if (colossusComp.CompletedEffigies == 0) + { + _audio.PlayStatic(colossusComp.ReawakenSfx, + Filter.BroadcastMap(transform.MapID), + transform.Coordinates, + true); + } + else + { + _audio.PlayPvs(colossusComp.ReawakenSfx, ent); + } + + colossusComp.CompletedEffigies += 1; + + if (colossusComp.CompletedEffigies >= colossusComp.MaxEffigies) + { + colossusComp.Timed = false; + _popup.PopupEntity(Loc.GetString("colossus-buff-final-popup"), colossus, PopupType.Large); + return; + } + + _popup.PopupEntity(Loc.GetString("colossus-buff-popup"), colossus, PopupType.Large); + + var objIndex = mind.Objectives.FindIndex(HasComp); + if (objIndex == -1 || + !TryComp(mind.Objectives[objIndex], out var conditionComp)) + { + Log.Error($"Failed to find effigy objective on {ToPrettyString(colossus)}!"); + return; + } + + var objective = mind.Objectives[objIndex]; + if (_cultObjective.RandomizeEffigyTarget(objective, conditionComp, setDescription: true) is not {} nextTarget) + { + Log.Error("Failed to randomize effigy objective location!"); + return; + } + + if (mind.UserId is { } userId) + { + _chat.DispatchServerMessage(_player.GetSessionById(userId), Loc.GetString("colossus-next-target", ("location", nextTarget))); + } + + _codeCondition.SetCompleted(objective, false); + + colossusComp.EffigyPlaceActionEntity = _actions.AddAction(colossus, colossusComp.EffigyPlaceAction); + colossusComp.DeathTimer = _time.CurTime + colossusComp.DeathWaitEffigy; + colossusComp.Timed = true; } private void OnColossusEffigy(Entity ent, ref EventCosmicColossusEffigy args) @@ -38,8 +128,16 @@ public sealed class CosmicEffigySystem : EntitySystem _actions.RemoveAction(ent.Owner, ent.Comp.EffigyPlaceActionEntity); _codeCondition.SetCompleted(ent.Owner, ent.Comp.EffigyObjective); - Spawn(ent.Comp.EffigyPrototype, pos); + var effigy = Spawn(ent.Comp.EffigyPrototype, pos); ent.Comp.Timed = false; + + if (!TryComp(effigy, out var effigyComp)) + { + Log.Error("Colossus tried to place Effigy prototype missing CosmicEffigyComponent!"); + return; + } + + effigyComp.Colossus = ent.Owner; } private bool VerifyPlacement(Entity ent, out EntityCoordinates outPos) diff --git a/Content.Server/_DV/CosmicCult/Components/CosmicColossusBuffComponents.cs b/Content.Server/_DV/CosmicCult/Components/CosmicColossusBuffComponents.cs new file mode 100644 index 00000000000..e5f52e27d8f --- /dev/null +++ b/Content.Server/_DV/CosmicCult/Components/CosmicColossusBuffComponents.cs @@ -0,0 +1,56 @@ +using Content.Shared.Damage.Prototypes; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; + +namespace Content.Server._DV.CosmicCult.Components; + +/// +/// The owning colossus's attack rate will be multiplied by +/// the given multiplier once its effigy goes supercritical. +/// Component meant to be applied to Cosmic Colossus. +/// +[RegisterComponent] +public sealed partial class MultiplyAttackRateOnSupercriticalComponent : Component +{ + [DataField] + public float Multiplier = 1.1f; +} + +/// +/// The owning colossus's corrupting speed will be multiplied by +/// the given multiplier once its effigy goes supercritical. +/// Component meant to be applied to Cosmic Colossus. +/// +[RegisterComponent] +public sealed partial class MultiplyCorruptingSpeedOnSupercriticalComponent : Component +{ + [DataField] + public float Multiplier = 0.9f; +} + +/// +/// The owning colossus will receive a flat bonus to +/// its melee attack damage once its effigy goes supercritical. +/// Component meant to be applied to Cosmic Colossus. +/// +[RegisterComponent] +public sealed partial class FlatAttackBonusOnSupercriticalComponent : Component +{ + [DataField] + public FixedPoint2 BonusDamage = 10; + + [DataField] + public ProtoId BonusDamageType = "Blunt"; +} + +/// +/// The owning colossus will be healed for `-CurrentDamage * Abs(DamageFractionHealed)` damage +/// once its effigy goes supercritical. +/// Component meant to be applied to Cosmic Colossus. +/// +[RegisterComponent] +public sealed partial class HealOnSupercriticalComponent : Component +{ + [DataField] + public float DamageFractionHealed = 1.0f; +} diff --git a/Content.Server/_DV/CosmicCult/Components/CosmicCorruptingComponent.cs b/Content.Server/_DV/CosmicCult/Components/CosmicCorruptingComponent.cs index f403587dd70..fd61cdf28e6 100644 --- a/Content.Server/_DV/CosmicCult/Components/CosmicCorruptingComponent.cs +++ b/Content.Server/_DV/CosmicCult/Components/CosmicCorruptingComponent.cs @@ -1,3 +1,4 @@ +using Content.Server._DV.CosmicCult.Abilities.Colossus; using Content.Server._DV.CosmicCult.EntitySystems; using Content.Shared.Maps; using Robust.Shared.Prototypes; @@ -5,7 +6,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Server._DV.CosmicCult.Components; -[RegisterComponent, Access(typeof(CosmicCorruptingSystem))] +[RegisterComponent, Access(typeof(CosmicCorruptingSystem), typeof(CosmicColossusBuffsSystem))] [AutoGenerateComponentPause] public sealed partial class CosmicCorruptingComponent : Component { diff --git a/Content.Server/_DV/CosmicCult/Components/CosmicEffigyComponent.cs b/Content.Server/_DV/CosmicCult/Components/CosmicEffigyComponent.cs new file mode 100644 index 00000000000..4b1312cff4a --- /dev/null +++ b/Content.Server/_DV/CosmicCult/Components/CosmicEffigyComponent.cs @@ -0,0 +1,19 @@ +using Content.Server._DV.CosmicCult.Abilities; +using Content.Server._DV.CosmicCult.EntitySystems; + +namespace Content.Server._DV.CosmicCult.Components; + +/// +/// Component for cosmic effigy anomalies, spawned by Cosmic Colossi. +/// +/// . +/// . +[RegisterComponent] +public sealed partial class CosmicEffigyComponent : Component +{ + /// + /// The colossus that placed this effigy. + /// + [DataField] + public EntityUid? Colossus; +} diff --git a/Content.Server/_DV/CosmicCult/CosmicCultObjectiveSystem.cs b/Content.Server/_DV/CosmicCult/CosmicCultObjectiveSystem.cs index fc6acaab934..50d29dcf87f 100644 --- a/Content.Server/_DV/CosmicCult/CosmicCultObjectiveSystem.cs +++ b/Content.Server/_DV/CosmicCult/CosmicCultObjectiveSystem.cs @@ -35,6 +35,12 @@ public sealed class CosmicCultObjectiveSystem : EntitySystem if (args.Cancelled || !_roles.MindHasRole(args.MindId)) return; + if (RandomizeEffigyTarget(uid, comp) is null) + args.Cancelled = true; + } + + public string? RandomizeEffigyTarget(EntityUid uid, CosmicEffigyConditionComponent comp, bool setDescription = false) + { var warps = new List(); var query = EntityQueryEnumerator(); var effigyBlacklist = comp.Blacklist; @@ -51,10 +57,22 @@ public sealed class CosmicCultObjectiveSystem : EntitySystem if (warps.Count <= 0) { - args.Cancelled = true; - return; + return null; } - comp.EffigyTarget = _random.Pick(warps); + + var newWarp = _random.Pick(warps); + var warpComp = Comp(newWarp); + + comp.EffigyTarget = newWarp; + + if (setDescription) + { + _metaData.SetEntityDescription(uid, + warpComp.Location != null + ? Loc.GetString("objective-condition-effigy", ("location", warpComp.Location)) + : Loc.GetString("objective-condition-effigy-no-target")); + } + return warpComp.Location; } private void OnEffigyAfterAssign(EntityUid uid, CosmicEffigyConditionComponent comp, ref ObjectiveAfterAssignEvent args) diff --git a/Content.Server/_DV/CosmicCult/EntitySystems/CosmicColossusSystem.cs b/Content.Server/_DV/CosmicCult/EntitySystems/CosmicColossusSystem.cs index d1cceeb15ea..e8013312d69 100644 --- a/Content.Server/_DV/CosmicCult/EntitySystems/CosmicColossusSystem.cs +++ b/Content.Server/_DV/CosmicCult/EntitySystems/CosmicColossusSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.Popups; using Content.Shared.Station.Components; using Content.Shared.Throwing; using Content.Shared.Warps; +using Content.Shared.Weapons.Melee.Events; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Physics.Components; @@ -41,6 +42,7 @@ public sealed class CosmicColossusSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnSpawn); SubscribeLocalEvent(OnMobStateChanged); + SubscribeLocalEvent(OnMeleeHit); } public override void Update(float frameTime) @@ -82,7 +84,7 @@ public sealed class CosmicColossusSystem : EntitySystem private void OnSpawn(Entity ent, ref ComponentInit args) // I WANT THIS BIG GUY HURLED TOWARDS THE STATION { - ent.Comp.DeathTimer = _timing.CurTime + ent.Comp.DeathWait; + ent.Comp.DeathTimer = _timing.CurTime + ent.Comp.DeathWaitSpawn; var station = _station.GetStationInMap(Transform(ent).MapID); if (TryComp(station, out var stationData)) { @@ -115,4 +117,9 @@ public sealed class CosmicColossusSystem : EntitySystem RemComp(ent); RemComp(ent); } + + private void OnMeleeHit(Entity colossus, ref MeleeHitEvent args) + { + args.BonusDamage += colossus.Comp.BonusDamage; + } } diff --git a/Content.Shared/Anomaly/Components/AnomalyComponent.cs b/Content.Shared/Anomaly/Components/AnomalyComponent.cs index e5fc4be7d11..8d5bb34e6b8 100644 --- a/Content.Shared/Anomaly/Components/AnomalyComponent.cs +++ b/Content.Shared/Anomaly/Components/AnomalyComponent.cs @@ -285,6 +285,11 @@ public sealed partial class AnomalyComponent : Component [DataField] public bool DeleteEntity = true; + + // DeltaV - Colossus additions START + [DataField] + public bool AlwaysGrow; + // DeltaV - Colossus additions END } /// @@ -308,7 +313,7 @@ public readonly record struct AnomalySupercriticalEvent(EntityUid Anomaly, float /// The anomaly being shut down. /// Whether or not the anomaly shut down passively or via a supercritical event. [ByRefEvent] -public readonly record struct AnomalyShutdownEvent(EntityUid Anomaly, bool Supercritical); +public readonly record struct AnomalyShutdownEvent(EntityUid Anomaly, bool Supercritical, bool Forced); // DeltaV - Add Forced /// /// Event broadcast when an anomaly's severity is changed. diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 92dcc860fd6..f55c4495d26 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -84,7 +84,7 @@ public abstract partial class SharedAnomalySystem : EntitySystem // DeltaV - Mad Log.Info($"Performing anomaly pulse. Entity: {ToPrettyString(uid)}"); // if we are above the growth threshold, then grow before the pulse - if (component.Stability > component.GrowthThreshold) + if (component.AlwaysGrow || component.Stability > component.GrowthThreshold) // DeltaV - Add AlwaysGrow { ChangeAnomalySeverity(uid, GetSeverityIncreaseFromGrowth(component), component); } @@ -192,7 +192,8 @@ public abstract partial class SharedAnomalySystem : EntitySystem // DeltaV - Mad /// Whether or not the anomaly ended via supercritical event /// Create anomaly cores based on the result of completing an anomaly? /// Whether or not the anomaly decaying/going supercritical is logged - public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool supercritical = false, bool spawnCore = true, bool logged = false) + /// Whether or not the anomaly shutdown was caused by component shutdown // DeltaV - Add forced + public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool supercritical = false, bool spawnCore = true, bool logged = false, bool forced = false) // DeltaV - Add forced { if (logged) { @@ -207,7 +208,7 @@ public abstract partial class SharedAnomalySystem : EntitySystem // DeltaV - Mad if (!Resolve(uid, ref component)) return; - var ev = new AnomalyShutdownEvent(uid, supercritical); + var ev = new AnomalyShutdownEvent(uid, supercritical, forced); // DeltaV - Add forced RaiseLocalEvent(uid, ref ev, true); if (Terminating(uid) || _net.IsClient) @@ -345,7 +346,7 @@ public abstract partial class SharedAnomalySystem : EntitySystem // DeltaV - Mad // if the stability is under the death threshold, // update it every second to start killing it slowly. - if (anomaly.Stability < anomaly.DecayThreshold) + if (!anomaly.AlwaysGrow && anomaly.Stability < anomaly.DecayThreshold) // DeltaV - Add AlwaysGrow { ChangeAnomalyHealth(ent, anomaly.HealthChangePerSecond * frameTime, anomaly); } @@ -479,6 +480,14 @@ public abstract partial class SharedAnomalySystem : EntitySystem // DeltaV - Mad if (!Resolve(ent, ref ent.Comp, logMissing: false)) return false; + // DeltaV - Colossus Additions START + if (ent.Comp.AlwaysGrow) + { + visual = AnomalyStabilityVisuals.Growing; + return true; + } + // DeltaV - Colossus Additions END + visual = AnomalyStabilityVisuals.Stable; if (ent.Comp.Stability <= ent.Comp.DecayThreshold) { diff --git a/Content.Shared/_DV/CosmicCult/Components/CosmicColossusComponent.cs b/Content.Shared/_DV/CosmicCult/Components/CosmicColossusComponent.cs index cad6a3eb986..8e654f22639 100644 --- a/Content.Shared/_DV/CosmicCult/Components/CosmicColossusComponent.cs +++ b/Content.Shared/_DV/CosmicCult/Components/CosmicColossusComponent.cs @@ -1,3 +1,5 @@ +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; @@ -36,6 +38,8 @@ public sealed partial class CosmicColossusComponent : Component [DataField] public EntProtoId Attack1Vfx = "CosmicColossusAttack1Vfx"; + [DataField] public EntProtoId BuffVfx = "ColossusBuffVfx"; + [DataField] public EntProtoId TileDetonations = "MobTileDamageZone"; [DataField] public EntProtoId EffigyPrototype = "CosmicEffigy"; @@ -52,13 +56,23 @@ public sealed partial class CosmicColossusComponent : Component [DataField] public TimeSpan HibernationWait = TimeSpan.FromSeconds(30); - [DataField] public TimeSpan DeathWait = TimeSpan.FromMinutes(15); + [DataField] public TimeSpan DeathWaitSpawn = TimeSpan.FromMinutes(15); + + [DataField] public TimeSpan DeathWaitEffigy = TimeSpan.FromMinutes(10); [DataField] public bool Attacking; [DataField] public bool Hibernating; [DataField] public bool Timed; + + [DataField] public short CompletedEffigies; + + [DataField] public short MaxEffigies = 3; + + [DataField] public DamageSpecifier BonusDamage = new(); + + } [Serializable, NetSerializable] diff --git a/Resources/Locale/en-US/_DV/anomaly/anomaly.ftl b/Resources/Locale/en-US/_DV/anomaly/anomaly.ftl new file mode 100644 index 00000000000..8691f64c4e9 --- /dev/null +++ b/Resources/Locale/en-US/_DV/anomaly/anomaly.ftl @@ -0,0 +1 @@ +anomaly-behavior-always-grow = [color=red]Anomaly never stops growing.[/color] diff --git a/Resources/Locale/en-US/_DV/cosmiccult/colossus.ftl b/Resources/Locale/en-US/_DV/cosmiccult/colossus.ftl new file mode 100644 index 00000000000..55f4f5d6425 --- /dev/null +++ b/Resources/Locale/en-US/_DV/cosmiccult/colossus.ftl @@ -0,0 +1,3 @@ +colossus-buff-popup = You grow stronger. Another space calls for you. +colossus-buff-final-popup = You have grown strong enough. The curtains must fall. +colossus-next-target = {$location} calls for you. Beckon your next effigy there. diff --git a/Resources/Locale/en-US/_DV/cosmiccult/ghostroles.ftl b/Resources/Locale/en-US/_DV/cosmiccult/ghostroles.ftl index 7273d5dc86b..a4f2027fa91 100644 --- a/Resources/Locale/en-US/_DV/cosmiccult/ghostroles.ftl +++ b/Resources/Locale/en-US/_DV/cosmiccult/ghostroles.ftl @@ -7,7 +7,7 @@ ghost-role-information-theunknown-rules = ... # COLOSSUS ghost-role-information-colossus-name = Entropic Colossus -ghost-role-information-colossus-description = Call upon an Effigy of Entropy to perpetuate your existence and accelerate the end of all things! You have 15 minutes to do so or your energies will be extinguished. +ghost-role-information-colossus-description = Call upon three Effigies of Entropy to grow in power and accelerate the end of all things, starting with the station! You have 15 minutes to place your first effigy. If you don't place one or your effigy decays, your energies will be extinguished. ghost-role-information-colossus-rules = You are a [color={role-type-team-antagonist-color}][bold]{role-type-team-antagonist-name}[/bold][/color] with any cosmic cultists that may be present. terror-colossus = Attention crew, it appears that someone on your station has drawn the attention of an enormous malign anomaly. diff --git a/Resources/Prototypes/_DV/CosmicCult/Effects/effects.yml b/Resources/Prototypes/_DV/CosmicCult/Effects/effects.yml index 57c5a553be5..0b6c8347c99 100644 --- a/Resources/Prototypes/_DV/CosmicCult/Effects/effects.yml +++ b/Resources/Prototypes/_DV/CosmicCult/Effects/effects.yml @@ -169,6 +169,36 @@ isLooped: true reverseWhenFinished: true +- type: entity + categories: [ HideSpawnMenu ] + parent: BaseCosmicVFX + id: ColossusBuffVfx + components: + - type: TimedDespawn + lifetime: 0.8 + - type: Sprite + layers: + - sprite: _DV/CosmicCult/Effects/colossus_buffvfx.rsi + state: vfx + shader: unshaded + - type: PointLight + color: "#a35d7b" + radius: 1.5 + energy: 2.5 + castShadows: false + - type: LightBehaviour + behaviours: + - !type:FadeBehaviour + interpolate: Linear + minDuration: 0.8 + maxDuration: 0.8 + startValue: 0.1 + endValue: 2 + property: Energy + enabled: true + isLooped: true + reverseWhenFinished: true + - type: entity categories: [ HideSpawnMenu ] parent: BaseCosmicVFX diff --git a/Resources/Prototypes/_DV/CosmicCult/Mobs/colossus.yml b/Resources/Prototypes/_DV/CosmicCult/Mobs/colossus.yml index b614e3ccadf..13744450819 100644 --- a/Resources/Prototypes/_DV/CosmicCult/Mobs/colossus.yml +++ b/Resources/Prototypes/_DV/CosmicCult/Mobs/colossus.yml @@ -275,6 +275,10 @@ groups: Brute: -1 Burn: -0.5 + - type: MultiplyAttackRateOnSupercritical + - type: MultiplyCorruptingSpeedOnSupercritical + - type: FlatAttackBonusOnSupercritical + - type: HealOnSupercritical - type: entity parent: [ MobCosmicColossusBase ] diff --git a/Resources/Prototypes/_DV/CosmicCult/Tileset/effigy.yml b/Resources/Prototypes/_DV/CosmicCult/Tileset/effigy.yml index 22f0154b776..8a3384cf4bf 100644 --- a/Resources/Prototypes/_DV/CosmicCult/Tileset/effigy.yml +++ b/Resources/Prototypes/_DV/CosmicCult/Tileset/effigy.yml @@ -23,6 +23,7 @@ - type: CosmicCultExamine cultistText: cosmic-examine-text-culteffigy othersText: cosmic-examine-text-effigy + - type: CosmicEffigy - type: CosmicCorrupting corruptionReduction: 0.02 enabled: true @@ -80,7 +81,7 @@ maxPulseLength: 80 minContituty: 0.4 maxContituty: 0.8 - growthThreshold: 0.35 + alwaysGrow: true - type: EntitySpawnAnomaly entries: - settings: diff --git a/Resources/Prototypes/_DV/CosmicCult/events.yml b/Resources/Prototypes/_DV/CosmicCult/events.yml index 1e06f3f4693..8e3476637b6 100644 --- a/Resources/Prototypes/_DV/CosmicCult/events.yml +++ b/Resources/Prototypes/_DV/CosmicCult/events.yml @@ -6,7 +6,7 @@ weight: 4.5 earliestStart: 45 reoccurrenceDelay: 20 - minimumPlayers: 25 + minimumPlayers: 35 duration: null - type: PrecognitionResult message: psionic-power-precognition-colossus-spawn-result-message diff --git a/Resources/Textures/_DV/CosmicCult/Effects/colossus_buffvfx.rsi/meta.json b/Resources/Textures/_DV/CosmicCult/Effects/colossus_buffvfx.rsi/meta.json new file mode 100644 index 00000000000..0b6078963eb --- /dev/null +++ b/Resources/Textures/_DV/CosmicCult/Effects/colossus_buffvfx.rsi/meta.json @@ -0,0 +1,39 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "by DisposableCrewmember42 on GitHub", + "size": { + "x": 61, + "y": 118 + }, + "states": [ + { + "name": "vfx", + "delays": [ + [ + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04, + 0.04 + ] + ] + } + ] +} diff --git a/Resources/Textures/_DV/CosmicCult/Effects/colossus_buffvfx.rsi/vfx.png b/Resources/Textures/_DV/CosmicCult/Effects/colossus_buffvfx.rsi/vfx.png new file mode 100644 index 00000000000..bd5e3737032 Binary files /dev/null and b/Resources/Textures/_DV/CosmicCult/Effects/colossus_buffvfx.rsi/vfx.png differ