Cosmic Cult | Patch 1.1.0 (#3905)

* initial commit

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* my whitespace so trailing

* Merge branch 'coscult-tweakandfix' of https://github.com/AftrLite/Delta-v into coscult-tweakandfix

* tweaks

* 2nd content commit

* linter oopsie

* my yml so linter

* ubuntu build test fail my beloathed

* weighting tune

* requested changes + audio changes for licensing

* using begone

* tweak

* begone spawnmenu entry

* yml fix, nyano code tweak, effigy tweak

* review commit

* testfail nonsense begone

* requested changes from a review that doesn't even exist yet

* emote change
This commit is contained in:
AftrLite 2025-06-13 21:51:31 +12:00 committed by GitHub
parent d41b55e733
commit 409cd39883
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
125 changed files with 1893 additions and 347 deletions

View File

@ -1,4 +1,5 @@
using Content.Server.Abilities.Psionics;
using Content.Shared._DV.CosmicCult;
using Content.Shared.Anomaly;
using Content.Shared.Anomaly.Components;
using Robust.Shared.Random;
@ -17,6 +18,8 @@ public sealed partial class AnomalySystem
//Nyano - Summary: gives dispellable behavior to Anomalies.
private void OnDispelled(Entity<AnomalyComponent> ent, ref DispelledEvent args)
{
if (HasComp<CosmicCultExamineComponent>(ent)) // begone nyanocode interference with cosmic cult
return;
_dispel.DealDispelDamage(ent);
ChangeAnomalyHealth(ent, 0 - _random.NextFloat(0.4f, 0.8f), ent.Comp);
args.Handled = true;

View File

@ -0,0 +1,96 @@
using System.Numerics;
using Content.Server.Actions;
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.Maps;
using Content.Shared.Mind;
using Content.Shared.Warps;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
namespace Content.Server._DV.CosmicCult.Abilities;
public sealed class CosmicEffigySystem : EntitySystem
{
[Dependency] private readonly ActionsSystem _actions = default!;
[Dependency] private readonly CodeConditionSystem _codeCondition = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly ITileDefinitionManager _tileDef = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusEffigy>(OnColossusEffigy);
}
private void OnColossusEffigy(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusEffigy args)
{
if (!VerifyPlacement(ent, out var pos))
return;
_actions.RemoveAction(ent, ent.Comp.EffigyPlaceActionEntity);
_codeCondition.SetCompleted(ent.Owner, ent.Comp.EffigyObjective);
Spawn(ent.Comp.EffigyPrototype, pos);
ent.Comp.Timed = false;
}
private bool VerifyPlacement(Entity<CosmicColossusComponent> ent, out EntityCoordinates outPos)
{
// MAKE SURE WE'RE STANDING ON A GRID
var xform = Transform(ent);
outPos = new EntityCoordinates();
if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
{
_popup.PopupEntity(Loc.GetString("ghost-role-colossus-effigy-error-grid"), ent, ent);
return false;
}
var localTile = _map.GetTileRef(xform.GridUid.Value, grid, xform.Coordinates);
var targetIndices = localTile.GridIndices + new Vector2i(0, 2);
var pos = _map.ToCenterCoordinates(xform.GridUid.Value, targetIndices, grid);
outPos = pos;
var box = new Box2(pos.Position + new Vector2(-1.4f, -0.4f), pos.Position + new Vector2(1.4f, 0.4f));
// CHECK IF IT'S BEING PLACED CHEESILY CLOSE TO SPACE
var spaceDistance = 2;
var worldPos = _transform.GetWorldPosition(xform);
foreach (var tile in _map.GetTilesIntersecting(xform.GridUid.Value, grid, new Circle(worldPos, spaceDistance)))
{
if (tile.IsSpace(_tileDef))
{
_popup.PopupEntity(Loc.GetString("ghost-role-colossus-effigy-error-space", ("DISTANCE", spaceDistance)), ent, ent);
return false;
}
}
// CHECK FOR ENTITY AND ENVIRONMENTAL INTERSECTIONS
if (_lookup.AnyLocalEntitiesIntersecting(xform.GridUid.Value, box, LookupFlags.Dynamic | LookupFlags.Static, ent))
{
_popup.PopupEntity(Loc.GetString("ghost-role-colossus-effigy-error-intersection"), ent, ent);
return false;
}
// IF THE OBJECTIVE OR LOCATION IS MISSING, PLACE IT ANYWHERE
if (!_mind.TryGetObjectiveComp<CosmicEffigyConditionComponent>(ent, out var obj) || obj.EffigyTarget == null)
return true;
var targetXform = Transform(obj.EffigyTarget.Value);
if (xform.MapID != targetXform.MapID || (_transform.GetWorldPosition(xform) - _transform.GetWorldPosition(targetXform)).LengthSquared() > 15 * 15)
{
if (TryComp<WarpPointComponent>(obj.EffigyTarget, out var warp) && warp.Location is not null)
_popup.PopupEntity(Loc.GetString("ghost-role-colossus-effigy-error-location", ("LOCATION", warp.Location)), ent, ent);
return false;
}
return true;
}
}

View File

@ -0,0 +1,42 @@
using Content.Server.Popups;
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Robust.Shared.Timing;
namespace Content.Server._DV.CosmicCult.Abilities;
public sealed class CosmicHibernateSystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusHibernate>(OnColossusHibernate);
}
private void OnColossusHibernate(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusHibernate args)
{
if (ent.Comp.Attacking || ent.Comp.Hibernating || !_transform.AnchorEntity(ent))
return;
args.Handled = true;
var comp = ent.Comp;
comp.Hibernating = true;
comp.HibernationTimer = comp.HibernationWait + _timing.CurTime;
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Action);
_appearance.SetData(ent, ColossusVisuals.Hibernation, ColossusAction.Running);
_stun.TryStun(ent, comp.HibernationWait, true);
_popup.PopupCoordinates(
Loc.GetString("ghost-role-colossus-hibernate"),
Transform(ent).Coordinates,
PopupType.LargeCaution);
}
}

View File

@ -0,0 +1,37 @@
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Robust.Shared.Timing;
namespace Content.Server._DV.CosmicCult.Abilities;
public sealed class CosmicSunderSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusSunder>(OnColossusSunder);
}
private void OnColossusSunder(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusSunder args)
{
args.Handled = true;
var comp = ent.Comp;
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Action);
_transform.SetCoordinates(ent, args.Target);
_transform.AnchorEntity(ent);
comp.Attacking = true;
comp.AttackHoldTimer = comp.AttackWait + _timing.CurTime;
Spawn(comp.Attack1Vfx, args.Target);
var detonator = Spawn(comp.TileDetonations, args.Target);
EnsureComp<CosmicTileDetonatorComponent>(detonator, out var detonateComp);
detonateComp.DetonationTimer = _timing.CurTime;
}
}

View File

@ -68,14 +68,6 @@ public sealed class CosmicConversionSystem : EntitySystem
_stun.TryStun(target, TimeSpan.FromSeconds(4f), false);
_damageable.TryChangeDamage(target, uid.Comp.ConversionHeal * -1);
_cultRule.CosmicConversion(uid, target);
var finaleQuery = EntityQueryEnumerator<CosmicFinaleComponent>(); // Enumerator for The Monument's Finale
while (finaleQuery.MoveNext(out var monument, out var comp) && comp.CurrentState == FinaleState.ActiveBuffer)
{
if (comp.BufferTimer - _timing.CurTime < comp.ConversionSpeedup) // don't speed up if there's less than the speedup left.
return;
comp.BufferTimer -= comp.ConversionSpeedup;
_popup.PopupCoordinates(Loc.GetString("cosmiccult-finale-speedup"), Transform(monument).Coordinates, PopupType.Large);
}
}
}
}

View File

@ -1,5 +1,4 @@
using System.Linq;
using Content.Server._EE.Silicon.WeldingHealable;
using Content.Server.Bible.Components;
using Content.Server.Flash;
using Content.Server.Light.Components;
@ -7,10 +6,12 @@ using Content.Server.Light.EntitySystems;
using Content.Server.Stunnable;
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared._EE.Silicon.Components;
using Content.Shared.Effects;
using Content.Shared.Interaction;
using Content.Shared.Mobs.Components;
using Content.Shared.Physics;
using Content.Shared.Silicons.Borgs.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
@ -69,7 +70,7 @@ public sealed class CosmicGlareSystem : EntitySystem
_flash.Flash(targetEnt, uid, args.Action, (float)uid.Comp.CosmicGlareDuration.TotalMilliseconds, uid.Comp.CosmicGlarePenalty, false, false, uid.Comp.CosmicGlareStun);
if (HasComp<WeldingHealableComponent>(targetEnt)) //This component is used exclusively by IPCs and borgs, so we use it here to target 'em specifically.
if (HasComp<BorgChassisComponent>(targetEnt) || HasComp<SiliconComponent>(targetEnt)) //For paralyzing borgs and IPCs specifically.
{
_stun.TryParalyze(targetEnt, uid.Comp.CosmicGlareDuration / 2, true);
}

View File

@ -1,6 +1,7 @@
using Content.Server.Doors.Systems;
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared.DoAfter;
using Content.Shared.Doors.Components;
using Robust.Shared.Audio.Systems;
@ -11,12 +12,16 @@ public sealed class CosmicIngressSystem : EntitySystem
[Dependency] private readonly CosmicCultSystem _cult = default!;
[Dependency] private readonly DoorSystem _door = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicCultComponent, EventCosmicIngress>(OnCosmicIngress);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusIngress>(OnColossusIngress);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusIngressDoAfter>(OnColossusIngressDoAfter);
}
private void OnCosmicIngress(Entity<CosmicCultComponent> uid, ref EventCosmicIngress args)
@ -33,4 +38,33 @@ public sealed class CosmicIngressSystem : EntitySystem
Spawn(uid.Comp.AbsorbVFX, Transform(target).Coordinates);
_cult.MalignEcho(uid);
}
private void OnColossusIngress(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusIngress args)
{
var doargs = new DoAfterArgs(EntityManager, ent, ent.Comp.IngressDoAfter, new EventCosmicColossusIngressDoAfter(), ent, args.Target)
{
DistanceThreshold = 2f,
Hidden = false,
BreakOnMove = true,
};
args.Handled = true;
_audio.PlayPvs(ent.Comp.DoAfterSfx, ent);
_doAfter.TryStartDoAfter(doargs);
}
private void OnColossusIngressDoAfter(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusIngressDoAfter args)
{
if (args.Args.Target is not { } target)
return;
if (args.Cancelled || args.Handled)
return;
args.Handled = true;
var comp = ent.Comp;
if (TryComp<DoorBoltComponent>(target, out var doorBolt))
_door.SetBoltsDown((target, doorBolt), false);
_door.StartOpening(target);
_audio.PlayPvs(comp.IngressSfx, ent);
Spawn(comp.CultVfx, Transform(target).Coordinates);
}
}

View File

@ -0,0 +1,11 @@
namespace Content.Server.Objectives.Components;
[RegisterComponent]
public sealed partial class CosmicConversionConditionComponent : Component
{
/// <summary>
/// The amount of cultists this objective would like to be converted
/// </summary>
[DataField]
public int Converted;
}

View File

@ -45,6 +45,7 @@ public sealed partial class CosmicCultRuleComponent : Component
[
"MobCosmicCustodian",
"MobCosmicOracle",
"MobCosmicLodestar",
];
/// <summary>
@ -62,9 +63,18 @@ public sealed partial class CosmicCultRuleComponent : Component
[DataField]
public HashSet<EntityUid> Cultists = [];
/// <summary>
/// When true, prevents the wincondition state of Cosmic Cult from being changed.
/// </summary>
[DataField]
public bool WinLocked;
/// <summary>
/// When true, Malign Rifts are unable to spawn.
/// </summary>
[DataField]
public bool RiftStop;
[DataField]
public WinType WinType = WinType.CrewMinor;

View File

@ -0,0 +1,8 @@
namespace Content.Server.Objectives.Components;
[RegisterComponent]
public sealed partial class CosmicEffigyConditionComponent : Component
{
[DataField]
public EntityUid? EffigyTarget;
}

View File

@ -16,6 +16,12 @@ public sealed partial class CosmicFinaleComponent : Component
[DataField]
public bool FinaleActive = false;
/// <summary>
/// Bool used for the final announcement message at the finale's 2 minutes remaining mark.
/// </summary>
[DataField]
public bool FinaleAnnounceCheck = false;
[DataField]
public bool Occupied = false;
@ -29,13 +35,10 @@ public sealed partial class CosmicFinaleComponent : Component
public TimeSpan CultistsCheckTimer = default!;
[DataField, AutoNetworkedField]
public TimeSpan BufferRemainingTime = TimeSpan.FromSeconds(360);
public TimeSpan FinaleRemainingTime = TimeSpan.FromSeconds(362);
[DataField, AutoNetworkedField]
public TimeSpan FinaleRemainingTime = TimeSpan.FromSeconds(126);
[DataField, AutoNetworkedField]
public TimeSpan ConversionSpeedup = TimeSpan.FromSeconds(20);
public TimeSpan VisualsThreshold = TimeSpan.FromSeconds(240);
[DataField, AutoNetworkedField]
public TimeSpan CheckWait = TimeSpan.FromSeconds(5);
@ -53,13 +56,10 @@ public sealed partial class CosmicFinaleComponent : Component
public SoundSpecifier? SelectedSong;
[DataField]
public TimeSpan InteractionTime = TimeSpan.FromSeconds(14);
public TimeSpan InteractionTime = TimeSpan.FromSeconds(30);
[DataField]
public SoundSpecifier BufferMusic = new SoundPathSpecifier("/Audio/_DV/CosmicCult/premonition.ogg");
[DataField]
public SoundSpecifier FinaleMusic = new SoundPathSpecifier("/Audio/_DV/CosmicCult/a_new_dawn.ogg");
public SoundSpecifier FinaleMusic = new SoundPathSpecifier("/Audio/_DV/CosmicCult/finale.ogg");
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? SongTimer;
@ -84,9 +84,7 @@ public sealed partial class CosmicFinaleComponent : Component
public enum FinaleState : byte
{
Unavailable,
ReadyBuffer,
ReadyFinale,
ActiveBuffer,
ActiveFinale,
Victory,
}

View File

@ -1,26 +1,81 @@
using Content.Server.Objectives.Components;
using Content.Shared._DV.Roles;
using Content.Shared.Ninja.Components;
using Content.Shared.Objectives.Components;
using Content.Shared.Roles;
using Content.Shared.Warps;
using Robust.Shared.Random;
namespace Content.Server.Objectives.Systems;
public sealed class CosmicCultObjectiveSystem : EntitySystem
{
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly NumberObjectiveSystem _number = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedRoleSystem _roles = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicEffigyConditionComponent, RequirementCheckEvent>(OnEffigyRequirementCheck);
SubscribeLocalEvent<CosmicEffigyConditionComponent, ObjectiveAfterAssignEvent>(OnEffigyAfterAssign);
SubscribeLocalEvent<CosmicEntropyConditionComponent, ObjectiveGetProgressEvent>(OnGetEntropyProgress);
SubscribeLocalEvent<CosmicConversionConditionComponent, ObjectiveGetProgressEvent>(OnGetConversionProgress);
SubscribeLocalEvent<CosmicTierConditionComponent, ObjectiveGetProgressEvent>(OnGetTierProgress);
SubscribeLocalEvent<CosmicVictoryConditionComponent, ObjectiveGetProgressEvent>(OnGetVictoryProgress);
}
private void OnEffigyRequirementCheck(EntityUid uid, CosmicEffigyConditionComponent comp, ref RequirementCheckEvent args)
{
if (args.Cancelled || !_roles.MindHasRole<CosmicColossusRoleComponent>(args.MindId))
return;
var warps = new List<EntityUid>();
var query = EntityQueryEnumerator<BombingTargetComponent, WarpPointComponent>();
while (query.MoveNext(out var warpUid, out _, out var warp))
{
if (warp.Location != null)
{
warps.Add(warpUid);
}
}
if (warps.Count <= 0)
{
args.Cancelled = true;
return;
}
comp.EffigyTarget = _random.Pick(warps);
}
private void OnEffigyAfterAssign(EntityUid uid, CosmicEffigyConditionComponent comp, ref ObjectiveAfterAssignEvent args)
{
string description;
if (comp.EffigyTarget == null || !TryComp<WarpPointComponent>(comp.EffigyTarget, out var warp) || warp.Location == null)
{
// this should never really happen but eh
description = Loc.GetString("objective-condition-effigy-no-target");
}
else
{
description = Loc.GetString("objective-condition-effigy", ("location", warp.Location));
}
_metaData.SetEntityDescription(uid, description, args.Meta);
}
private void OnGetEntropyProgress(Entity<CosmicEntropyConditionComponent> ent, ref ObjectiveGetProgressEvent args)
{
args.Progress = Progress(ent.Comp.Siphoned, _number.GetTarget(ent.Owner));
}
private void OnGetConversionProgress(Entity<CosmicConversionConditionComponent> ent, ref ObjectiveGetProgressEvent args)
{
args.Progress = Progress(ent.Comp.Converted, _number.GetTarget(ent.Owner));
}
private void OnGetTierProgress(Entity<CosmicTierConditionComponent> ent, ref ObjectiveGetProgressEvent args)
{
args.Progress = Progress(ent.Comp.Tier, _number.GetTarget(ent.Owner));

View File

@ -103,6 +103,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
private TimeSpan _t3RevealDelay = default!;
private TimeSpan _t2RevealDelay = default!;
private TimeSpan _finaleDelay = default!;
private TimeSpan _voteDelay = default!;
private TimeSpan _voteTimer = default!;
private readonly SoundSpecifier _briefingSound = new SoundPathSpecifier("/Audio/_DV/CosmicCult/antag_cosmic_briefing.ogg");
@ -147,12 +148,16 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
DCCVars.CosmicCultStewardVoteTimer,
value => _voteTimer = TimeSpan.FromSeconds(value),
true);
Subs.CVar(_config,
DCCVars.CosmicCultStewardVoteDelayTimer,
value => _voteDelay = TimeSpan.FromSeconds(value),
true);
}
#region Starting Events
protected override void Started(EntityUid uid, CosmicCultRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
component.StewardVoteTimer = _timing.CurTime + TimeSpan.FromSeconds(10);
component.StewardVoteTimer = _timing.CurTime + _voteDelay;
}
protected override void ActiveTick(EntityUid uid, CosmicCultRuleComponent component, GameRuleComponent gameRule, float frameTime)
@ -162,13 +167,10 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
component.StewardVoteTimer = null;
StewardVote();
}
if (component.ExtraRiftTimer is { } riftTimer && _timing.CurTime >= riftTimer)
if (component.ExtraRiftTimer is { } riftTimer && _timing.CurTime >= riftTimer && !component.RiftStop)
{
component.ExtraRiftTimer = _timing.CurTime + _rand.Next(TimeSpan.FromSeconds(230), TimeSpan.FromSeconds(360)); //3min50 to 6min between new rifts. Seconds instead of minutes for granularity.
if (TryFindRandomTile(out var _, out var _, out var _, out var coords))
{
Spawn("CosmicMalignRift", coords);
}
SpawnRift();
}
if (component.PrepareFinaleTimer is { } finalePrepTimer && _timing.CurTime >= finalePrepTimer)
{
@ -195,7 +197,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
var sender = Loc.GetString("cosmiccult-announcement-sender");
var mapData = _map.GetMap(_transform.GetMapId(component.MonumentInGame.Owner.ToCoordinates()));
_chatSystem.DispatchStationAnnouncement(component.MonumentInGame, Loc.GetString("cosmiccult-announce-tier3-progress"), null, false, null, Color.FromHex("#4cabb3"));
_chatSystem.DispatchStationAnnouncement(component.MonumentInGame, Loc.GetString("cosmiccult-announce-tier3-progress"), sender, false, null, Color.FromHex("#4cabb3"));
_chatSystem.DispatchStationAnnouncement(component.MonumentInGame, Loc.GetString("cosmiccult-announce-tier3-warning"), null, false, null, Color.FromHex("#cae8e8"));
_audio.PlayGlobal(_tier3Sound, Filter.Broadcast(), false, AudioParams.Default);
@ -238,16 +240,13 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
//do spooky effects
var sender = Loc.GetString("cosmiccult-announcement-sender");
var mapData = _map.GetMap(_transform.GetMapId(component.MonumentInGame.Owner.ToCoordinates()));
_chatSystem.DispatchStationAnnouncement(component.MonumentInGame, Loc.GetString("cosmiccult-announce-tier2-progress"), null, false, null, Color.FromHex("#4cabb3"));
_chatSystem.DispatchStationAnnouncement(component.MonumentInGame, Loc.GetString("cosmiccult-announce-tier2-progress"), sender, false, null, Color.FromHex("#4cabb3"));
_chatSystem.DispatchStationAnnouncement(component.MonumentInGame, Loc.GetString("cosmiccult-announce-tier2-warning"), null, false, null, Color.FromHex("#cae8e8"));
_audio.PlayGlobal(_tier2Sound, Filter.Broadcast(), false, AudioParams.Default);
for (var i = 0; i < Convert.ToInt16(component.TotalCrew / 6); i++) // spawn # malign rifts equal to 16.67% of the playercount
{
if (TryFindRandomTile(out var _, out var _, out var _, out var coords))
{
Spawn("CosmicMalignRift", coords);
}
SpawnRift();
}
var lights = EntityQueryEnumerator<PoweredLightComponent>();
@ -277,7 +276,6 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
var options = new VoteOptions
{
DisplayVotes = false,
Title = Loc.GetString("cosmiccult-vote-steward-title"),
InitiatorText = Loc.GetString("cosmiccult-vote-steward-initiator"),
Duration = _voteTimer,
@ -308,6 +306,14 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
};
}
private void SpawnRift()
{
if (TryFindRandomTile(out var _, out var _, out var _, out var coords))
{
Spawn("CosmicMalignRift", coords);
}
}
private void OnAntagSelect(Entity<CosmicCultRuleComponent> uid, ref AfterAntagEntitySelectedEvent args)
{
TryStartCult(args.EntityUid, uid);
@ -446,6 +452,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
_roundEnd.DoRoundEndBehavior(ent.Comp.RoundEndBehavior, ent.Comp.EvacShuttleTime, ent.Comp.RoundEndTextSender, ent.Comp.RoundEndTextShuttleCall, ent.Comp.RoundEndTextAnnouncement);
ent.Comp.RoundEndBehavior = RoundEndBehavior.Nothing; // prevent this being called multiple times.
ent.Comp.RiftStop = true; // rifts can stop spawning now.
var gameruleMonument = ent.Comp.MonumentInGame;
if (TryComp<CosmicFinaleComponent>(gameruleMonument, out var finComp))
@ -491,6 +498,15 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
entropyComp.Siphoned = cult.Comp.EntropySiphoned;
}
}
public void AdjustCultObjectiveConversion(int value)
{
var query = EntityQueryEnumerator<CosmicConversionConditionComponent>();
while (query.MoveNext(out _, out var conversionComp))
{
conversionComp.Converted += value;
}
}
#endregion
public void OnStartMonument(Entity<MonumentComponent> ent)
@ -714,6 +730,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
_mind.TryAddObjective(mindId, mind, "CosmicFinalityObjective");
_mind.TryAddObjective(mindId, mind, "CosmicMonumentObjective");
_mind.TryAddObjective(mindId, mind, "CosmicConversionObjective");
_mind.TryAddObjective(mindId, mind, "CosmicEntropyObjective");
_euiMan.OpenEui(new CosmicConvertedEui(), session);
@ -723,6 +740,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
cult.Comp.TotalCult++;
cult.Comp.Cultists.Add(uid);
AdjustCultObjectiveConversion(1);
UpdateCultData(cult.Comp.MonumentInGame);
}
@ -763,6 +781,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
_alerts.ClearAlert(uid, uid.Comp.EntropyAlert);
cosmicGamerule.TotalCult--;
cosmicGamerule.Cultists.Remove(uid);
AdjustCultObjectiveConversion(-1);
UpdateCultData(cosmicGamerule.MonumentInGame);
_movementSpeed.RefreshMovementSpeedModifiers(uid);
}

View File

@ -26,7 +26,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
{
if (!HasComp<HumanoidAppearanceComponent>(args.User))
return; // humanoids only!
if (!EntityIsCultist(args.User) && !args.Handled && ent.Comp.FinaleActive)
if (!EntityIsCultist(args.User) && !args.Handled && !ent.Comp.Occupied && ent.Comp.FinaleActive)
{
ent.Comp.Occupied = true;
var doargs = new DoAfterArgs(EntityManager, args.User, ent.Comp.InteractionTime, new CancelFinaleDoAfterEvent(), ent, ent)
@ -37,7 +37,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
_doAfter.TryStartDoAfter(doargs);
args.Handled = true;
}
else if (EntityIsCultist(args.User) && !args.Handled && !ent.Comp.FinaleActive && ent.Comp.CurrentState != FinaleState.Unavailable)
else if (EntityIsCultist(args.User) && !args.Handled && !ent.Comp.Occupied && !ent.Comp.FinaleActive && ent.Comp.CurrentState != FinaleState.Unavailable)
{
ent.Comp.Occupied = true;
var doargs = new DoAfterArgs(EntityManager, args.User, ent.Comp.InteractionTime, new StartFinaleDoAfterEvent(), ent, ent)
@ -70,35 +70,17 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
if (!TryComp<MonumentComponent>(uid, out var monument) || !TryComp<CosmicCorruptingComponent>(uid, out var corruptingComp))
return;
if (uid.Comp.CurrentState == FinaleState.ReadyBuffer)
{
_corrupting.SetCorruptionTime((uid, corruptingComp), TimeSpan.FromSeconds(3));
_appearance.SetData(uid, MonumentVisuals.FinaleReached, 2);
comp.BufferTimer = _timing.CurTime + comp.BufferRemainingTime;
comp.SelectedSong = comp.BufferMusic;
_sound.DispatchStationEventMusic(uid, comp.SelectedSong, StationEventMusicType.CosmicCult);
comp.FinaleTimer = _timing.CurTime + comp.FinaleRemainingTime;
comp.SelectedSong = comp.FinaleMusic;
uid.Comp.CurrentState = FinaleState.ActiveFinale;
_chatSystem.DispatchStationAnnouncement(uid,
Loc.GetString("cosmiccult-finale-location", ("location", indicatedLocation)),
null, false, null,
Color.FromHex("#cae8e8"));
uid.Comp.CurrentState = FinaleState.ActiveBuffer;
}
else
{
_corrupting.SetCorruptionTime((uid, corruptingComp), TimeSpan.FromSeconds(1));
_appearance.SetData(uid, MonumentVisuals.FinaleReached, 3);
comp.FinaleTimer = _timing.CurTime + comp.FinaleRemainingTime;
comp.SelectedSong = comp.FinaleMusic;
_sound.DispatchStationEventMusic(uid, comp.SelectedSong, StationEventMusicType.CosmicCult);
_chatSystem.DispatchStationAnnouncement(uid,
Loc.GetString("cosmiccult-finale-location", ("location", indicatedLocation)),
null, false, null,
Color.FromHex("#cae8e8"));
uid.Comp.CurrentState = FinaleState.ActiveFinale;
}
_corrupting.SetCorruptionTime((uid, corruptingComp), TimeSpan.FromSeconds(1));
_appearance.SetData(uid, MonumentVisuals.FinaleReached, 2);
_sound.DispatchStationEventMusic(uid, comp.SelectedSong, StationEventMusicType.CosmicCult);
_chatSystem.DispatchStationAnnouncement(uid,
Loc.GetString("cosmiccult-finale-location", ("location", indicatedLocation)),
null, false, null,
Color.FromHex("#cae8e8"));
var stationUid = _station.GetStationInMap(Transform(uid).MapID);
if (stationUid != null)
@ -111,6 +93,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
_monument.Enable((uid, monument));
comp.FinaleActive = true;
comp.FinaleAnnounceCheck = true;
Dirty(uid, monument);
_ui.SetUiState(uid.Owner, MonumentKey.Key, new MonumentBuiState(monument));
@ -132,16 +115,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
_sound.PlayGlobalOnStation(uid, _audio.ResolveSound(comp.CancelEventSound));
_sound.StopStationEventMusic(uid, StationEventMusicType.CosmicCult);
if (uid.Comp.CurrentState == FinaleState.ActiveBuffer)
{
uid.Comp.CurrentState = FinaleState.ReadyBuffer;
comp.BufferRemainingTime = comp.BufferTimer - _timing.CurTime + TimeSpan.FromSeconds(15);
}
else if (uid.Comp.CurrentState == FinaleState.ActiveFinale)
{
uid.Comp.CurrentState = FinaleState.ReadyFinale;
}
uid.Comp.CurrentState = FinaleState.ReadyFinale;
if (TryComp<CosmicCorruptingComponent>(uid, out var corruptingComp))
_corrupting.SetCorruptionTime((uid, corruptingComp), TimeSpan.FromSeconds(6));
@ -160,6 +134,7 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
_monument.Disable((uid, monument));
comp.FinaleActive = false;
comp.FinaleAnnounceCheck = false;
Dirty(target, monument);
_ui.SetUiState(uid.Owner, MonumentKey.Key, new MonumentBuiState(monument));

View File

@ -2,11 +2,12 @@ using Content.Server.Antag;
using Content.Server.Audio;
using Content.Server.Chat.Systems;
using Content.Server.Pinpointer;
using Content.Server.Polymorph.Systems;
using Content.Server.Popups;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared.Mind;
using Content.Shared.Roles;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@ -17,14 +18,18 @@ public sealed class CosmicChantrySystem : EntitySystem
[Dependency] private readonly AntagSelectionSystem _antag = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly PolymorphSystem _polymorph = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ServerGlobalSoundSystem _sound = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedRoleSystem _role = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
/// <summary>
/// Mind role to add to colossi.
/// </summary>
public static readonly EntProtoId MindRole = "MindRoleCosmicColossus";
public override void Initialize()
{
base.Initialize();
@ -54,8 +59,9 @@ public sealed class CosmicChantrySystem : EntitySystem
var tgtpos = Transform(uid).Coordinates;
var colossus = Spawn(comp.Colossus, tgtpos);
_mind.TransferTo(mindEnt, colossus);
_mind.TryAddObjective(mindEnt, mind, "CosmicFinalityObjective");
_role.MindAddRole(mindEnt, MindRole, mind, true);
_antag.SendBriefing(colossus, Loc.GetString("cosmiccult-silicon-colossus-briefing"), Color.FromHex("#4cabb3"), null);
_audio.PlayPvs(comp.SpawnSFX, tgtpos);
Spawn(comp.SpawnVFX, tgtpos);
QueueDel(comp.InternalVictim);
QueueDel(uid);

View File

@ -1,12 +1,16 @@
using Content.Server.Doors.Systems;
using Content.Server._DV.CosmicCult.Components;
using Content.Server.Actions;
using Content.Server.Popups;
using Content.Shared._DV.CosmicCult;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared.Audio;
using Content.Shared.DoAfter;
using Content.Shared.Doors.Components;
using Content.Shared.Damage;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems;
using Content.Shared.Popups;
using Content.Shared.Throwing;
using Content.Shared.Warps;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Physics.Components;
@ -17,25 +21,24 @@ namespace Content.Server._DV.CosmicCult.EntitySystems;
public sealed class CosmicColossusSystem : EntitySystem
{
[Dependency] private readonly ActionsSystem _actions = default!;
[Dependency] private readonly DamageableSystem _damage = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly DoorSystem _door = default!;
[Dependency] private readonly MobThresholdSystem _threshold = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly StationSystem _station = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedAmbientSoundSystem _ambientSound = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly ThrowingSystem _throw = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicColossusComponent, ComponentInit>(OnSpawn);
SubscribeLocalEvent<CosmicColossusComponent, MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusIngress>(OnColossusIngress);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusIngressDoAfter>(OnColossusIngressDoAfter);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusSunder>(OnColossusSunder);
}
public override void Update(float frameTime)
@ -45,75 +48,69 @@ public sealed class CosmicColossusSystem : EntitySystem
var colossusQuery = EntityQueryEnumerator<CosmicColossusComponent>();
while (colossusQuery.MoveNext(out var ent, out var comp))
{
if (_timing.CurTime >= comp.AttackHoldTimer && comp.Attacking)
if (comp.Attacking && _timing.CurTime >= comp.AttackHoldTimer)
{
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Alive); _transform.Unanchor(ent);
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Alive);
_appearance.SetData(ent, ColossusVisuals.Sunder, ColossusAction.Stopped);
_transform.Unanchor(ent);
comp.Attacking = false;
}
if (comp.Hibernating && _timing.CurTime >= comp.HibernationTimer)
{
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Alive);
_appearance.SetData(ent, ColossusVisuals.Hibernation, ColossusAction.Stopped);
_transform.Unanchor(ent);
_audio.PlayPvs(comp.ReawakenSfx, ent);
comp.Hibernating = false;
Spawn(comp.CultBigVfx, Transform(ent).Coordinates);
if (!TryComp<DamageableComponent>(ent, out var damageable))
continue;
_damage.TryChangeDamage(ent, damageable.Damage / 2 * -1, true);
}
if (comp.Timed && _timing.CurTime >= comp.DeathTimer)
{
if (!_threshold.TryGetThresholdForState(ent, MobState.Dead, out var damage))
return;
DamageSpecifier dspec = new();
dspec.DamageDict.Add("Heat", damage.Value);
_damage.TryChangeDamage(ent, dspec, true);
}
}
}
private void OnSpawn(Entity<CosmicColossusComponent> ent, ref ComponentInit args) // I WANT THIS BIG GUY HURLED TOWARDS THE STATION
{
ent.Comp.DeathTimer = _timing.CurTime + ent.Comp.DeathWait;
var station = _station.GetStationInMap(Transform(ent).MapID);
if (TryComp<StationDataComponent>(station, out var stationData))
{
var stationGrid = _station.GetLargestGrid(stationData);
_throw.TryThrow(ent, Transform(stationGrid!.Value).Coordinates, baseThrowSpeed: 30, null, 0, 0, false, false, false, false, false);
}
if (ent.Comp.Timed)
_actions.AddAction(ent, ref ent.Comp.EffigyPlaceActionEntity, ent.Comp.EffigyPlaceAction, ent);
}
private void OnMobStateChanged(Entity<CosmicColossusComponent> ent, ref MobStateChangedEvent args)
{
if (args.NewMobState == MobState.Alive)
return;
if (!TryComp<PhysicsComponent>(ent, out var physComp))
return;
ent.Comp.Hibernating = false;
ent.Comp.Attacking = false;
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Dead);
_appearance.SetData(ent, ColossusVisuals.Hibernation, ColossusAction.Stopped);
_appearance.SetData(ent, ColossusVisuals.Sunder, ColossusAction.Stopped);
_ambientSound.SetAmbience(ent, false);
_audio.PlayPvs(ent.Comp.DeathSfx, ent);
_physics.SetBodyStatus(ent, physComp, BodyStatus.OnGround, true);
_popup.PopupCoordinates(
Loc.GetString("cosmiccult-colossus-death"),
Loc.GetString("ghost-role-colossus-death"),
Transform(ent).Coordinates,
PopupType.Large);
RemComp<PointLightComponent>(ent);
}
private void OnColossusIngress(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusIngress args)
{
var doargs = new DoAfterArgs(EntityManager, ent, ent.Comp.IngressDoAfter, new EventCosmicColossusIngressDoAfter(), ent, args.Target)
{
DistanceThreshold = 2f,
Hidden = false,
BreakOnMove = true,
};
args.Handled = true;
_audio.PlayPvs(ent.Comp.DoAfterSfx, ent);
_doAfter.TryStartDoAfter(doargs);
}
private void OnColossusIngressDoAfter(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusIngressDoAfter args)
{
if (args.Args.Target is not { } target)
return;
if (args.Cancelled || args.Handled)
return;
args.Handled = true;
var comp = ent.Comp;
if (TryComp<DoorBoltComponent>(target, out var doorBolt))
_door.SetBoltsDown((target, doorBolt), false);
_door.StartOpening(target);
_audio.PlayPvs(comp.IngressSfx, ent);
Spawn(comp.CultVfx, Transform(target).Coordinates);
}
private void OnColossusSunder(Entity<CosmicColossusComponent> ent, ref EventCosmicColossusSunder args)
{
args.Handled = true;
var comp = ent.Comp;
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Attacking);
_transform.SetCoordinates(ent, args.Target);
_transform.AnchorEntity(ent);
comp.Attacking = true;
comp.AttackHoldTimer = comp.AttackWait + _timing.CurTime;
Spawn(comp.Attack1Vfx, args.Target);
var detonator = Spawn(comp.TileDetonations, args.Target);
EnsureComp<CosmicTileDetonatorComponent>(detonator, out var detonateComp);
detonateComp.DetonationTimer = _timing.CurTime;
RemComp<WarpPointComponent>(ent);
RemComp<CosmicCorruptingComponent>(ent);
}
}

View File

@ -10,6 +10,7 @@ using Content.Shared._DV.CCVars;
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared._DV.CosmicCult.Prototypes;
using Content.Shared._DV.CustomObjectiveSummary;
using Content.Shared.Audio;
using Content.Shared.Damage;
using Content.Shared.Interaction;
@ -53,6 +54,7 @@ public sealed class MonumentSystem : SharedMonumentSystem
{
base.Initialize();
SubscribeLocalEvent<EvacShuttleLeftEvent>(OnShuttleEvac); // for no more finale once the evac shuttle leaves
SubscribeLocalEvent<MonumentComponent, InteractUsingEvent>(OnInfuseHeldEntropy);
SubscribeLocalEvent<MonumentComponent, ActivateInWorldEvent>(OnInfuseEntropy);
}
@ -72,6 +74,7 @@ public sealed class MonumentSystem : SharedMonumentSystem
foreach (var entity in entities) _damage.TryChangeDamage(entity, monuComp.MonumentHealing * -1);
monuComp.CheckTimer = _timing.CurTime + monuComp.CheckWait;
}
if (comp.SongTimer is { } time && _timing.CurTime >= time)
{
comp.SongTimer = null;
@ -79,19 +82,14 @@ public sealed class MonumentSystem : SharedMonumentSystem
_sound.DispatchStationEventMusic(uid, song, StationEventMusicType.CosmicCult);
}
if (comp.CurrentState == FinaleState.ActiveBuffer && _timing.CurTime >= comp.BufferTimer) // swap everything over when buffer timer runs out
if (comp.CurrentState == FinaleState.ActiveFinale && comp.FinaleAnnounceCheck && comp.FinaleTimer - _timing.CurTime < comp.VisualsThreshold)
{
comp.CurrentState = FinaleState.ActiveFinale;
comp.FinaleTimer = _timing.CurTime + comp.FinaleRemainingTime;
comp.SelectedSong = comp.FinaleMusic;
_sound.StopStationEventMusic(uid, StationEventMusicType.CosmicCult);
_appearance.SetData(uid, MonumentVisuals.FinaleReached, 3);
_chatSystem.DispatchStationAnnouncement(uid, Loc.GetString("cosmiccult-announce-finale-warning"), null, false, null, Color.FromHex("#cae8e8"));
comp.SongTimer = _timing.CurTime + TimeSpan.FromSeconds(1);
comp.FinaleAnnounceCheck = false;
}
else if (comp.CurrentState == FinaleState.ActiveFinale && _timing.CurTime >= comp.FinaleTimer) // trigger wincondition on time runout
if (comp.CurrentState == FinaleState.ActiveFinale && _timing.CurTime >= comp.FinaleTimer) // trigger wincondition on time runout
{
var victoryQuery = EntityQueryEnumerator<CosmicVictoryConditionComponent>();
while (victoryQuery.MoveNext(out _, out var victoryComp))
@ -99,7 +97,6 @@ public sealed class MonumentSystem : SharedMonumentSystem
victoryComp.Victory = true;
}
_sound.StopStationEventMusic(uid, StationEventMusicType.CosmicCult);
Spawn(CosmicGod, Transform(uid).Coordinates);
comp.CurrentState = FinaleState.Victory;
}
@ -126,6 +123,30 @@ public sealed class MonumentSystem : SharedMonumentSystem
}
}
/// <summary>
/// on shuttle evac, disable the monument's UI, disable it from being activated, and stop the finale music if it was playing
/// </summary>
private void OnShuttleEvac(EvacShuttleLeftEvent args)
{
var evacQuery = EntityQueryEnumerator<MonumentComponent, CosmicFinaleComponent>();
while (evacQuery.MoveNext(out var ent, out var monuComp, out var finaleComp))
{
Disable((ent, monuComp));
finaleComp.Occupied = true;
_sound.StopStationEventMusic(ent, StationEventMusicType.CosmicCult);
if (TryComp<ActivatableUIComponent>(ent, out var uiComp))
{
if (TryComp<UserInterfaceComponent>(ent, out var uiComp2)) //close the UI for everyone who has it open
{
_ui.CloseUi((ent, uiComp2), MonumentKey.Key);
}
uiComp.Key = null; //kazne called this the laziest way to disable a UI ever
}
}
}
private void OnMonumentPhaseOut(Entity<MonumentComponent> ent)
{
//todo check if anything gets messed up by doing this to the monument?
@ -441,7 +462,7 @@ public sealed class MonumentSystem : SharedMonumentSystem
uiComp.Key = null; //kazne called this the laziest way to disable a UI ever
}
finaleComp.CurrentState = FinaleState.ReadyBuffer;
finaleComp.CurrentState = FinaleState.ReadyFinale;
uid.Comp.Enabled = false;
uid.Comp.TargetProgress = uid.Comp.CurrentProgress;

View File

@ -224,7 +224,13 @@ public sealed partial class DCCVars
/// How long the timer for the cult's stewardship vote lasts.
/// </summary>
public static readonly CVarDef<int> CosmicCultStewardVoteTimer =
CVarDef.Create("cosmiccult.steward_vote_timer", 40, CVar.SERVER);
CVarDef.Create("cosmiccult.steward_vote_timer", 80, CVar.SERVER);
/// <summary>
/// How long we wait before starting the stewardship vote.
/// </summary>
public static readonly CVarDef<int> CosmicCultStewardVoteDelayTimer =
CVarDef.Create("cosmiccult.steward_vote_delay", 25, CVar.SERVER);
/// <summary>
/// The delay between the monument getting upgraded to tier 2 and the crew learning of that fact. the monument cannot be upgraded again in this time.
@ -242,5 +248,5 @@ public sealed partial class DCCVars
/// The delay between the monument getting upgraded to tier 3 and the finale starting.
/// </summary>
public static readonly CVarDef<int> CosmicCultFinaleDelaySeconds =
CVarDef.Create("cosmiccult.extra_entropy_for_finale", 120, CVar.SERVER);
CVarDef.Create("cosmiccult.extra_entropy_for_finale", 110, CVar.SERVER);
}

View File

@ -33,8 +33,6 @@ public sealed partial class CosmicChantryComponent : Component
[DataField] public SoundSpecifier ChantryAlarm = new SoundPathSpecifier("/Audio/_DV/CosmicCult/chantry_alarm.ogg");
[DataField] public SoundSpecifier SpawnSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/colossus_spawn.ogg");
[DataField] public EntProtoId Colossus = "MobCosmicColossus";
[DataField] public EntProtoId SpawnVFX = "CosmicGlareAbilityVFX";

View File

@ -1,6 +1,5 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
@ -17,6 +16,14 @@ public sealed partial class CosmicColossusComponent : Component
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan AttackHoldTimer = default!;
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan HibernationTimer = default!;
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan DeathTimer = default!;
[DataField] public SoundSpecifier ReawakenSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/colossus_spawn.ogg");
[DataField] public SoundSpecifier DeathSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/colossus_death.ogg");
[DataField] public SoundSpecifier IngressSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ability_ingress.ogg");
@ -25,21 +32,41 @@ public sealed partial class CosmicColossusComponent : Component
[DataField] public EntProtoId CultVfx = "CosmicGenericVFX";
[DataField] public EntProtoId CultBigVfx = "CosmicGlareAbilityVFX";
[DataField] public EntProtoId Attack1Vfx = "CosmicColossusAttack1Vfx";
[DataField] public EntProtoId TileDetonations = "MobTileDamageZone";
[DataField] public TimeSpan IngressDoAfter = TimeSpan.FromSeconds(7);
[DataField] public EntProtoId EffigyPrototype = "CosmicEffigy";
[DataField] public EntProtoId EffigyObjective = "ColossusEffigyObjective";
[DataField] public EntProtoId EffigyPlaceAction = "ActionCosmicColossusEffigy";
[DataField] public EntityUid? EffigyPlaceActionEntity;
[DataField] public TimeSpan IngressDoAfter = TimeSpan.FromSeconds(4);
[DataField] public TimeSpan AttackWait = TimeSpan.FromSeconds(1.5);
[DataField] public TimeSpan HibernationWait = TimeSpan.FromSeconds(20);
[DataField] public TimeSpan DeathWait = TimeSpan.FromMinutes(15);
[DataField] public bool Attacking;
[DataField] public bool Hibernating;
[DataField] public bool Timed;
}
[Serializable, NetSerializable]
public enum ColossusVisuals : byte
{
Status,
Hibernation,
Sunder,
}
[Serializable, NetSerializable]
@ -47,5 +74,12 @@ public enum ColossusStatus : byte
{
Alive,
Dead,
Attacking,
Action,
}
[Serializable, NetSerializable]
public enum ColossusAction : byte
{
Running,
Stopped,
}

View File

@ -20,3 +20,5 @@ public sealed partial class EventCosmicFragmentation : EntityTargetActionEvent;
// COLOSSUS ACTIONS
public sealed partial class EventCosmicColossusSunder : WorldTargetActionEvent;
public sealed partial class EventCosmicColossusIngress : EntityTargetActionEvent;
public sealed partial class EventCosmicColossusHibernate : InstantActionEvent;
public sealed partial class EventCosmicColossusEffigy : InstantActionEvent;

View File

@ -0,0 +1,9 @@
using Content.Shared.Roles;
namespace Content.Shared._DV.Roles;
/// <summary>
/// Added to mind role entities to tag that they are using the cosmic colossus systems.
/// </summary>
[RegisterComponent]
public sealed partial class CosmicColossusRoleComponent : BaseMindRoleComponent;

View File

@ -9,6 +9,7 @@
- files:
- a_new_dawn.ogg
- premonition.ogg
- finale.ogg
license: "CC-BY-SA-3.0"
copyright: "Custom music composed by Nahu Pyrope for Cosmic Cult."
source: "https://linktr.ee/nahupyrope"
@ -20,6 +21,7 @@
- insert_entropy.ogg
- tier2.ogg
- tier3.ogg
- tile_detonate.ogg
- spire_draining.ogg
- monument_spawn.ogg
- monument_relocation.ogg
@ -27,6 +29,9 @@
- god_spawn.ogg
- god_ambient.ogg
- glyph_trigger.ogg
- effigy_supercritical.ogg
- effigy_pulse.ogg
- effigy_ambience.ogg
- door_open.ogg
- door_close.ogg
- chantry_alarm.ogg
@ -64,3 +69,12 @@
license: "CC-BY-SA-3.0"
copyright: "By widgetbeck & AftrLite(GitHub) for Cosmic Cult. Made using a combination of (Creative Commons 0) samples from freesound.org and personally-recorded foley."
source: "https://freesound.org/"
- files:
- colossus_ask.ogg
- colossus_exclaim.ogg
- colossus_say.ogg
- colossus_scream.ogg
license: "CC-BY-SA-3.0"
copyright: "By widgetbeck for Cosmic Cult. Made using a combination of (Creative Commons 0) samples from freesound.org."
source: "https://freesound.org/"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -17,6 +17,7 @@ psionic-power-precognition-bureaucratic-error-result-message = You see a vision
psionic-power-precognition-clerical-error-result-message = You see faces you once knew being obscured in a fog of static, identities lost.
psionic-power-precognition-closet-skeleton-result-message = You hear a crackling laugh echo and clinking bones in the dusty recesses of the station.
psionic-power-precognition-dragon-spawn-result-message = Reality around you bulges and breaks as a great beast cries for war. The smell of salty sea and blood fills the air.
psionic-power-precognition-colossus-spawn-result-message = You see the vast shadow of a monstrosity so large that it casts all beneath it into darkness. The noösphere shifts precariously in its wake.
psionic-power-precognition-ninja-spawn-result-message = You see a vision of shadows brought to life, hounds of war howling their cries as they chase it through dark corners of the station.
psionic-power-precognition-revenant-spawn-result-message = The shadows around you grow threefold taller and threefold darker. Something lurks within them, a predator stalking you in the darkness.
psionic-power-precognition-gas-leak-result-message = For but a moment, it feels as if you cannot breathe. With a blink, everything returns to normal.

View File

@ -13,5 +13,6 @@ cosmiccolossus-titles-lone-dataset-1 = Herculean
cosmiccolossus-titles-lone-dataset-2 = Mythical
cosmiccolossus-titles-lone-dataset-3 = Apocryphal
cosmiccolossus-titles-lone-dataset-4 = Gargantuan
cosmiccolossus-titles-lone-dataset-5 = Monumental
name-format-colossus = {$part0}, {$part1}

View File

@ -8,11 +8,13 @@ cosmic-examine-text-abilitylapse = [color=#4cabb3]They look like they're seeing
cosmic-examine-text-malignecho = [color=#4cabb3]An echo in the membrane of realspace — it appears to be fading quickly. Something is amiss aboard the station![/color]
cosmic-examine-text-imposition = [color=#4cabb3]A barrier of astral power wards them from injury![/color]
cosmic-examine-text-chantry = [color=#4cabb3]You get the horrific feeling that there's somebody trapped inside![/color]
cosmic-examine-text-effigy = [color=#4cabb3]It radiates unstable anomalous energy![/color]
cosmic-examine-text-god = [color=#4cabb3]the end is the end is the end is the end is the end is the end is the end is the end is the end is the end is[/color]
## CULTIST EXAMINES
cosmic-examine-text-forthecult = [color=#4cabb3]This is our doing. As things should be.[/color]
cosmic-examine-text-cultentity = [color=#4cabb3]A powerful ally.[/color]
cosmic-examine-text-culteffigy = [color=#4cabb3]This may prove useful.[/color]
## GLYPH EXAMINES
cosmic-examine-glyph-cultcount = {$COUNT ->

View File

@ -1,3 +1,46 @@
# THE UNKNOWN
ghost-role-information-theunknown-name = The Unknown
ghost-role-information-theunknown-description = The Cosmic Cult has won. An fragment of cosmic power extrudes into realspace.
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-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.
ghost-role-colossus-charactermenu = You must usher in the end of all things. Wreak untold havoc upon all before you.
ghost-role-colossus-objective = Call forth an Effigy of Entropy and persist until the end of all things.
ghost-role-colossus-briefing =
You are an Entropic Colossus!
Your objectives are listed in the character menu.
Read more about your role in the guidebook entry.
ghost-role-colossus-death = The colossus collapses, its light extinguished.
ghost-role-colossus-hibernate = The colossus begins drawing in energy!
ghost-role-colossus-effigy-confirm = If placement is valid, press again to Beckon an Effigy.
ghost-role-colossus-effigy-error-grid = Invalid location! An Effigy must be beckoned upon a stable surface.
ghost-role-colossus-effigy-error-location = Invalid location! The Effigy must be beckoned near {$LOCATION}.
ghost-role-colossus-effigy-error-intersection = Too crowded! An Effigy requires an empty 3x1 area to be beckoned.
ghost-role-colossus-effigy-error-space = Too close to space! An Effigy must be be at least {$DISTANCE}m away.
objective-condition-effigy-no-target = Beckon an Effigy wherever you desire.
objective-condition-effigy = Beckon an Effigy near "{$location}".
# MINDSINK (Positronic Brain)
ghost-role-mindsink-installed = Whispers hum from its surface!
ghost-role-mindsink-off = It lies dormant.
ghost-role-mindsink-still-searching = It is drawing upon the noösphere...
ghost-role-mindsink-searching = It has started drawing upon the noösphere...
ghost-role-mindsink-role-name = Malign Mindsink
ghost-role-mindsink-role-description = Serve the station crew, despite your unusual origins.
ghost-role-mindsink-wipe-device-verb-text = Erase Mind
ghost-role-mindsink-wiped-device = The mind was snuffed out.
ghost-role-mindsink-stop-searching-verb-text = Stop Seeking
ghost-role-mindsink-stopped-searching = Noöspheric resonance halted.
ghost-role-mindsink-slot-component-slot-name-brain = Brain

View File

@ -2,3 +2,5 @@ guide-entry-cosmiccult = Cosmic Cult
guide-entry-cosmiccult-monument = The Monument
guide-entry-cosmiccult-influences = Influences
guide-entry-cosmiccult-deconversion = Deconversion
guide-entry-cosmiccolossus = Entropic Colossus

View File

@ -18,7 +18,7 @@ cosmiccult-vote-steward-briefing =
Ensure that The Monument is placed in a secure location, and organize the cult to ensure your collective victory.
You are not permitted to instruct cultists on how to use or spend their Entropy.
cosmiccult-finale-autocall-briefing = The Monument activates {$minutesandseconds}! Gather yourselves, and prepare for the end.
cosmiccult-finale-autocall-briefing = The Monument activates in {$minutesandseconds}! Gather yourselves, and prepare for the end.
cosmiccult-finale-ready = A terrifying light surges forth from The Monument!
cosmiccult-finale-speedup = The beckoning quickens! Energy surges through the surroundings...
@ -123,11 +123,10 @@ cosmiccult-rift-absorb = {$NAME} absorbs the rift, and malign light empowers the
cosmiccult-rift-purge = {$NAME} purges the malign rift from reality!
## COLOSSUS & CHANTRY
## CHANTRY
cosmiccult-chantry-location = A dangerous increase in Λ-CDM has been detected {$location}! Intercept and intervene immediately.
cosmiccult-chantry-powerup = The vacuous chantry flares to life!
cosmiccult-colossus-death = The colossus collapses, its light extinguished.
## UI / BASE POPUP
@ -163,6 +162,8 @@ objective-issuer-cosmiccult = [bold][color=#cae8e8]The Unknown[/color][/bold]
objective-cosmiccult-charactermenu = You must usher in the end of all things. Complete your tasks to advance the cult's progress.
objective-cosmiccult-steward-charactermenu = You must direct the cult to usher in the end of all things. Oversee and ensure the cult's progress.
objective-condition-conversion-title = CONVERT CREW
objective-condition-conversion-desc = Collectively bring at least {$count} crew into the fold.
objective-condition-entropy-title = SIPHON ENTROPY
objective-condition-entropy-desc = Collectively siphon at least {$count} entropy from the crew.
objective-condition-culttier-title = EMPOWER THE MONUMENT

View File

@ -1,2 +1,2 @@
role-subtype-cultist = Cultist
role-subtype-rogue-ascended = Rogue Ascended
role-subtype-colossus = Colossus

View File

@ -72,3 +72,10 @@
- Airloss
- Genetic
- Metaphysical
- type: damageContainer # DeltaV edits begin
id: InorganicMetaphysical
supportedGroups:
- Brute
- Burn
- Metaphysical # DeltaV edits end

View File

@ -18,7 +18,7 @@
requiredLegs: 2
gibSound: /Audio/Effects/bone_rattle.ogg
- type: Damageable
damageContainer: BiologicalMetaphysical # DeltaV
damageContainer: InorganicMetaphysical # DeltaV
damageModifierSet: Skeleton
- type: DamageVisuals
damageOverlayGroups:

View File

@ -35,6 +35,7 @@
tableId: BasicAntagEventsTableDeltaV
- id: ClosetSkeleton
- id: DragonSpawn
- id: ColossusSpawn # DeltaV
#- id: KingRatMigration # DeltaV - disabled
- id: NinjaSpawn
- id: ParadoxCloneSpawn

View File

@ -6,6 +6,7 @@
- Traitors
- Thieves
- CosmicCult # DeltaV - Cosmic Cult
- CosmicColossus # DeltaV - Entropic Colossus
- Revolutionaries
- NuclearOperatives
- SpaceNinja

View File

@ -199,7 +199,7 @@
description: Warp to the target location and unleash a cascading detonation of malign energy.
components:
- type: WorldTargetAction
useDelay: 20
useDelay: 18
range: 7
itemIconStyle: NoItem
icon:
@ -213,7 +213,7 @@
description: Use your colossal strength to force open a doorway.
components:
- type: EntityTargetAction
useDelay: 10
useDelay: 8
range: 2
whitelist:
components:
@ -223,3 +223,32 @@
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: ingress
event: !type:EventCosmicColossusIngress
- type: entity
id: ActionCosmicColossusHibernate
name: Slumber Shell
description: Slumber your body for a period of time to regenerate integrity. Must be done on stable ground.
components:
- type: LimitedCharges
maxCharges: 2
- type: InstantAction
useDelay: 120
checkCanInteract: false
itemIconStyle: NoItem
icon:
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: slumber
event: !type:EventCosmicColossusHibernate {}
- type: entity
id: ActionCosmicColossusEffigy
name: Beckon an Effigy
description: Draw out an Effigy of Entropy into realspace.
components:
- type: InstantAction
useDelay: 999
itemIconStyle: NoItem
icon:
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: nova
event: !type:EventCosmicColossusEffigy {}

View File

@ -82,7 +82,8 @@
- type: BatterySelfRecharger
autoRecharge: true
autoRechargeRate: 5
- type: TypingIndicatorClothing
proto: CosmicTyping
# COSMIC CULT HARDSUIT HELMET
- type: entity

View File

@ -41,9 +41,9 @@
- type: TimedDespawn
lifetime: 0.5
- type: Transform
noRot: true
anchored: true
- type: Sprite
snapCardinals: true
layers:
- sprite: _DV/CosmicCult/Effects/tile_spawn.rsi
state: floorglow
@ -357,9 +357,11 @@
components:
- type: Transform
anchored: true
noRot: true
- type: TimedDespawn
lifetime: 1.5
- type: Sprite
snapCardinals: true
layers:
- sprite: _DV/CosmicCult/Effects/colossus_attack.rsi
state: attack1

View File

@ -21,3 +21,8 @@
id: CosmicCultDeconversion
name: guide-entry-cosmiccult-deconversion
text: "/ServerInfo/_DV/Guidebook/Antagonist/CosmicCultDeconversion.xml"
- type: guideEntry
id: CosmicColossus
name: guide-entry-cosmiccolossus
text: "/ServerInfo/_DV/Guidebook/Antagonist/CosmicColossus.xml"

View File

@ -63,7 +63,7 @@
layer: 2 #ghost vis layer
- type: entity
parent: [ BaseSimpleMob, FlyingMobBase ]
parent: [ BaseSimpleMob ]
id: MobCosmicAstralAscended
name: astral ascended
description: Transcendant, ascendant.
@ -92,13 +92,18 @@
shader: unshaded
- state: ascended-body
shader: unshaded
- type: Physics
bodyStatus: InAir
- type: NoSlip
- type: CanMoveInAir
- type: Eye
drawFov: true
- type: ContentEye
maxZoom: 1.2, 1.2
- type: Speech
speechVerb: Ghost
- type: TypingIndicator
proto: CosmicTyping
- type: PointLight
color: "#42a4ae"
radius: 2
@ -122,7 +127,7 @@
parent: MobCosmicAstralAscended
id: MobCosmicCustodian
name: malign custodian
description: Twisted beyond recognition.
description: An abomination wrought of malign mass. It floats with a weightless, unnerving grace.
components:
- type: MovementSpeedModifier
baseWalkSpeed: 3
@ -131,15 +136,25 @@
- type: Sprite
sprite: _DV/CosmicCult/Mobs/custodian.rsi
layers:
- state: custodian
- state: custodian_unshaded
- map: [ "enum.DamageStateVisualLayers.Base" ]
state: custodian
- map: [ "enum.DamageStateVisualLayers.BaseUnshaded" ]
state: custodian_unshaded
shader: unshaded
- type: DamageStateVisuals
states:
Alive:
Base: custodian
BaseUnshaded: custodian_unshaded
Dead:
Base: dead
BaseUnshaded: dead_unshaded
- type: entity
parent: MobCosmicAstralAscended
id: MobCosmicOracle
name: malign oracle
description: Twisted beyond recognition.
description: An abomination wrought of malign mass. Its gaze seeks relentlessly.
components:
- type: MovementSpeedModifier
baseWalkSpeed: 3
@ -148,6 +163,39 @@
- type: Sprite
sprite: _DV/CosmicCult/Mobs/oracle.rsi
layers:
- state: oracle
- state: oracle_unshaded
- map: [ "enum.DamageStateVisualLayers.Base" ]
state: oracle
- map: [ "enum.DamageStateVisualLayers.BaseUnshaded" ]
state: oracle_unshaded
shader: unshaded
- type: DamageStateVisuals
states:
Alive:
Base: oracle
BaseUnshaded: oracle_unshaded
Dead:
Base: dead
BaseUnshaded: dead_unshaded
- type: entity
parent: MobCosmicAstralAscended
id: MobCosmicLodestar
name: malign lodestar
description: An abomination wrought of malign mass. A searing light glimmers within.
components:
- type: Sprite
sprite: _DV/CosmicCult/Mobs/lodestar.rsi
layers:
- map: [ "enum.DamageStateVisualLayers.Base" ]
state: lodestar
- map: [ "enum.DamageStateVisualLayers.BaseUnshaded" ]
state: lodestar_unshaded
shader: unshaded
- type: DamageStateVisuals
states:
Alive:
Base: lodestar
BaseUnshaded: lodestar_unshaded
Dead:
Base: dead
BaseUnshaded: dead_unshaded

View File

@ -1,17 +1,11 @@
- type: entity
parent: [ BaseSimpleMob, FlyingMobBase ]
id: MobCosmicColossus
abstract: true
id: MobCosmicColossusBase
name: entropic colossus
description: A colossal monstrosity of malign plating and dendritic infestation.
components:
- type: FTLSmashImmune
- type: BodyEmotes
- type: RandomMetadata
nameSegments:
- ColossusNames
- ColossusTitlesBase
nameFormat: name-format-colossus
- type: CosmicColossus
- type: CosmicCultExamine
cultistText: cosmic-examine-text-cultentity
othersText: cosmic-examine-text-entities
@ -35,6 +29,10 @@
shader: unshaded
visible: false
map: ["attack"]
- state: hibernate
shader: unshaded
visible: false
map: ["hibernating"]
- type: Appearance
- type: GenericVisualizer
visuals:
@ -42,23 +40,32 @@
underlay:
Alive: { visible: true }
Dead: { visible: false }
Attacking: { visible: false }
Action: { visible: false }
base:
Alive: { visible: true }
Dead: { visible: false }
Attacking: { visible: false }
Action: { visible: false }
corpse:
Alive: { visible: false }
Dead: { visible: true }
Attacking: { visible: false }
Action: { visible: false }
overlay:
Alive: { visible: true }
Dead: { visible: false }
Attacking: { visible: false }
Action: { visible: false }
attack:
Alive: { visible: false }
Dead: { visible: false }
Attacking: { visible: true }
Action: { visible: true }
enum.ColossusVisuals.Hibernation:
hibernating:
Running: { visible: true }
Stopped: { visible: false }
enum.ColossusVisuals.Sunder:
sunder:
Running: { visible: true }
Stopped: { visible: false }
- type: Physics
bodyType: KinematicController
- type: Fixtures
@ -75,13 +82,14 @@
- type: WarpPoint
follow: true
- type: Body
prototype: Animal
requiredLegs: 0
- type: Emoting
- type: Speech
speechSounds: Bass
speechSounds: ColossusSpeech
speechVerb: Robotic
allowedEmotes: []
- type: TypingIndicator
proto: robot
proto: CosmicTyping
- type: Grammar
attributes:
proper: true
@ -90,11 +98,17 @@
- type: MovementSpeedModifier
baseWalkSpeed: 2
baseSprintSpeed: 3
baseWeightlessModifier: 1
weightlessAcceleration: 1.5
weightlessFriction: 1
- type: AmbientSound
volume: +8
range: 18
sound:
path: /Audio/_DV/CosmicCult/colossus_ambience.ogg
- type: EmitSoundOnSpawn
sound:
path: /Audio/_DV/CosmicCult/colossus_spawn.ogg
- type: Tag
tags:
- CannotSuicide
@ -103,16 +117,33 @@
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: Metallic
- type: Bloodstream
bloodMaxVolume: 650
maxBleedAmount: 0.1
bleedReductionAmount: 0.1
bloodReagent: Entropy
bloodlossDamage:
types:
Bloodloss:
0
bloodlossHealDamage:
types:
Bloodloss:
0
- type: MobState
- type: MobThresholds
thresholds:
0: Alive
500: Dead
allowedStates:
- Alive
- Dead
- type: Butcherable
butcherDelay: 16
spawned:
- id: CosmicCultMindSink
amount: 1
- type: PointLight
color: "#42a4ae"
radius: 4
energy: 4
softness: 1
castShadows: true
- type: LightBehaviour
behaviours:
- !type:FadeBehaviour
@ -125,9 +156,12 @@
enabled: true
isLooped: true
reverseWhenFinished: true
- type: ContentEye
maxZoom: 1.2, 1.2
- type: StatusEffects
allowed:
- Stutter
- Stun
- type: IntrinsicRadioReceiver
- type: IntrinsicRadioTransmitter
channels:
@ -148,17 +182,18 @@
type: SiliconLawBoundUserInterface
requireInputValidation: false
- type: SiliconLawBound
- type: ActionGrant
actions:
- ActionViewLaws
- ActionCosmicColossusSunder
- ActionCosmicColossusIngress
- type: SiliconLawProvider
laws: CosmicCultLaws
- type: NoSlip
- type: Puller
needsHands: false
- type: CombatMode
- type: ActionGrant
actions:
- ActionViewLaws
- ActionCosmicColossusSunder
- ActionCosmicColossusIngress
- ActionCosmicColossusHibernate
- type: MeleeWeapon
altDisarm: false
animation: WeaponArcCosmic
@ -191,6 +226,63 @@
params:
variation: 0.2
volume: -6
- type: GhostRole
name: ghost-role-information-colossus-name
description: ghost-role-information-colossus-description
rules: ghost-role-information-colossus-rules
mindRoles:
- MindRoleCosmicColossus
raffle:
settings: default
- type: GhostTakeoverAvailable
- type: GuideHelp
guides:
- CosmicColossus
- type: entity
parent: [ MobCosmicColossusBase ]
categories: [ HideSpawnMenu ]
id: MobCosmicColossusLone
suffix: MidRoundAntag
description: An ancient monstrosity of malign plating and dendritic infestation.
components:
- type: RandomMetadata
nameSegments:
- ColossusNames
- ColossusTitlesLone
nameFormat: name-format-colossus
- type: MobThresholds
thresholds:
0: Alive
450: Dead
- type: CosmicCorrupting
mobile: true
autoDisable: false
corruptionReduction: 0
- type: entity
parent: [ MobCosmicColossusBase ]
id: MobCosmicColossus
components:
- type: RandomMetadata
nameSegments:
- ColossusNames
- ColossusTitlesBase
nameFormat: name-format-colossus
- type: MobThresholds
thresholds:
0: Alive
400: Dead
- type: CosmicColossus
- type: speechSounds
id: ColossusSpeech
saySound:
path: /Audio/_DV/CosmicCult/colossus_say.ogg
askSound:
path: /Audio/_DV/CosmicCult/colossus_ask.ogg
exclaimSound:
path: /Audio/_DV/CosmicCult/colossus_exclaim.ogg
- type: entity
categories: [ HideSpawnMenu ]
@ -221,6 +313,7 @@
- type: Transform
anchored: true
- type: Sprite
snapCardinals: true
sprite: _DV/CosmicCult/Effects/tile_attacks.rsi
offset: 0,0.27
layers:
@ -241,12 +334,14 @@
- Wall
components:
- type: Sprite
snapCardinals: true
sprite: _DV/CosmicCult/Effects/tile_attacks.rsi
offset: 0,0.27
layers:
- state: tiledamage_end
shader: unshaded
- type: Transform
noRot: true
anchored: true
- type: TimedDespawn
lifetime: 1
@ -269,8 +364,6 @@
intersectRatio: 0.1
ignoreWeightless: true
blacklist:
components:
- CosmicCult
tags:
- Catwalk
- type: TileEntityEffect
@ -278,4 +371,4 @@
- !type:HealthChange
damage:
types:
Cold: 10
Cold: 12.5

View File

@ -0,0 +1,149 @@
- type: entity
parent: [ BaseSimpleMob, FlyingMobBase ]
id: BaseMobCosmicHostile
suffix: Hostile
abstract: true
components:
- type: MovementSpeedModifier
baseWalkSpeed: 3
baseSprintSpeed: 3
weightlessModifier: 1
- type: HTN
rootTask:
task: SimpleHostileCompound
blackboard:
NavClimb: !type:Bool
true
NavSmash: !type:Bool
true
- type: NpcFactionMember
factions:
- SimpleHostile
- type: Tag
tags:
- DoorBumpOpener
- type: MobState
allowedStates:
- Alive
- Dead
- type: MobThresholds
thresholds:
0: Alive
50: Dead
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: Metallic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 70
behaviors:
- !type:SpawnEntitiesBehavior
spawn:
CosmicLapseAbilityVFX:
min: 1
max: 1
- !type:DoActsBehavior
acts: [ "Destruction" ]
- !type:PlaySoundBehavior
sound:
path: /Audio/_DV/CosmicCult/ability_lapse.ogg
- type: Bloodstream
bloodMaxVolume: 100
maxBleedAmount: 10.75
bleedReductionAmount: 0.1
bloodReagent: Entropy
bloodlossDamage:
types:
Bloodloss:
0
bloodlossHealDamage:
types:
Bloodloss:
0
- type: CombatMode
- type: MeleeWeapon
altDisarm: false
animation: WeaponArcCosmic
damage:
types:
Asphyxiation: 5
Cold: 5
soundHit:
path: /Audio/_DV/CosmicCult/cosmiclance_hit.ogg
params:
variation: 0.2
volume: 1
soundSwing:
path: /Audio/_DV/CosmicCult/cosmicweapon_swing.ogg
params:
variation: 0.125
volume: -4
- type: TypingIndicator
proto: CosmicTyping
- type: PointLight
color: "#42a4ae"
radius: 2
energy: 2
softness: 1
castShadows: false
- type: ZombieImmune
- type: GhostTakeoverAvailable
- type: LightBehaviour
behaviours:
- !type:FadeBehaviour
interpolate: Linear
minDuration: 5.5
maxDuration: 5.5
startValue: 0.5
endValue: 2
property: Energy
enabled: true
isLooped: true
reverseWhenFinished: true
- type: entity
parent: [ BaseMobCosmicHostile, MobCosmicCustodian ]
id: MobCosmicCustodianHostile
components:
- type: Physics
bodyStatus: OnGround
- type: entity
parent: [ BaseMobCosmicHostile, MobCosmicOracle ]
id: MobCosmicOracleHostile
components:
- type: Physics
bodyStatus: OnGround
- type: entity
parent: [ BaseMobCosmicHostile, MobCosmicLodestar ]
id: MobCosmicLodestarHostile
components:
- type: Physics
bodyStatus: OnGround
- type: HTN
rootTask:
task: SimpleRangedHostileCompound
blackboard:
NavClimb: !type:Bool
true
NavSmash: !type:Bool
true
- type: Gun
projectileSpeed: 12
soundGunshot: /Audio/_DV/CosmicCult/projectile_razor.ogg
soundEmpty: null
fireRate: 1
useKey: false
- type: RechargeBasicEntityAmmo
rechargeCooldown: 1.8
rechargeSound:
path: /Audio/_DV/CosmicCult/projectile_razor_reload.ogg
params:
volume: -99
- type: BasicEntityAmmoProvider
proto: ProjectileCosmic
capacity: 1
count: 1

View File

@ -187,7 +187,7 @@
groups:
Brute: -10
- type: Gun
projectileSpeed: 14
projectileSpeed: 15
soundGunshot: /Audio/_DV/CosmicCult/projectile_razor.ogg
soundEmpty: null
fireRate: 1
@ -196,6 +196,8 @@
rechargeCooldown: 1.8
rechargeSound:
path: /Audio/_DV/CosmicCult/projectile_razor_reload.ogg
params:
variation: 0.08
- type: BasicEntityAmmoProvider
proto: ProjectileCosmicRazor
capacity: 1
@ -221,21 +223,13 @@
soundSwing:
path: /Audio/_DV/CosmicCult/cosmicweapon_swing.ogg
params:
variation: 0.125
variation: 0.124
volume: -4
soundNoDamage:
path: /Audio/_DV/CosmicCult/cosmicsword_glance.ogg
params:
variation: 0.2
volume: -11
- type: Reflect
reflectProb: .21
spread: 120
soundOnReflect:
path: /Audio/_DV/CosmicCult/cosmicsword_glance.ogg
params:
variation: 0.2
volume: -6
- type: Wieldable
wieldSound:
path: /Audio/_DV/CosmicCult/cosmic_wield.ogg

View File

@ -26,9 +26,6 @@
sprite: _DV/CosmicCult/Objects/entropymote.rsi
size: Small
- type: CosmicEntropyMote
- type: Tag
tags:
- Entropy
- type: Extractable
grindableSolutionName: grind
- type: SolutionContainerManager

View File

@ -2,7 +2,7 @@
id: CosmicCultLawBoard
parent: BaseElectronics
name: malign law board
description: An eerie circuit board, suited for slotting into an AI law upload console. Its circuitry is interwoven with phantasmal dendritic strands that twitch of their own accord.
description: An eerie circuit board, suited for slotting into an AI law upload console. Its circuitry is interwoven with dendritic strands that twitch of their own accord.
components:
- type: Sprite
sprite: _DV/CosmicCult/Objects/lawboard.rsi
@ -11,3 +11,45 @@
lawUploadSound: /Audio/_DV/CosmicCult/antag_cosmic_AI_briefing.ogg
subverted: true
laws: CosmicCultLaws
- type: entity
id: CosmicCultMindSink
parent: PositronicBrain
name: astral mindsink
description: A strange artifact. Though comprised of malign materials, it instills no feelings of discomfort.
components:
- type: Sprite
sprite: _DV/CosmicCult/Objects/mindsink.rsi
layers:
- state: base
- state: fg_idle
shader: unshaded
map: ["overlay"]
- type: GenericVisualizer
visuals:
enum.ToggleableGhostRoleVisuals.Status:
overlay:
Off: { state: fg_idle }
Searching: { state: fg_searching }
On: { state: fg_occupied }
- type: ToggleableGhostRole
mindRoles:
- MindRoleGhostRoleSilicon
examineTextMindPresent: ghost-role-mindsink-installed
examineTextMindSearching: ghost-role-mindsink-still-searching
examineTextNoMind: ghost-role-mindsink-off
beginSearchingText: ghost-role-mindsink-searching
roleName: ghost-role-mindsink-role-name
roleDescription: ghost-role-mindsink-role-description
roleRules: ghost-role-information-silicon-rules
wipeVerbText: ghost-role-mindsink-wipe-device-verb-text
wipeVerbPopup: ghost-role-mindsink-wiped-device
stopSearchVerbText: ghost-role-mindsink-stop-searching-verb-text
stopSearchVerbPopup: ghost-role-mindsink-stopped-searching
job: Borg
- type: TypingIndicator
proto: CosmicTyping
- type: Speech
speechSounds: ColossusSpeech
- type: NameIdentifier
group: CosmicPositronicBrain

View File

@ -0,0 +1,114 @@
##################### PILLAR
- type: entity
parent: BaseStructure
id: CosmicEffigy
name: effigy of entropy
description: An abhorrent malign anomaly. Raw entropy oozes forth, betraying its instability.
components:
- type: Sprite
sprite: _DV/CosmicCult/Tileset/cosmiceffigy.rsi
offset: 0, 0
layers:
- state: unshaded_bg
shader: unshaded
- state: base
- state: unshaded_fg
shader: unshaded
drawdepth: Mobs
- type: AmbientSound
volume: -5
range: 8
sound:
path: /Audio/_DV/CosmicCult/effigy_ambience.ogg
- type: CosmicCultExamine
cultistText: cosmic-examine-text-culteffigy
othersText: cosmic-examine-text-effigy
- type: CosmicCorrupting
corruptionReduction: 0.02
enabled: true
floodFillStarting: true
corruptionMaxTicks: 6
corruptionSpeed: 1.25
- type: InteractionOutline
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeCircle
radius: 0.5
density: 50
mask:
- FlyingMobMask
layer:
- FlyingMobLayer
- type: Clickable
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: Metallic
- type: DamageOnAttacked
damage:
types:
Cold: 10
- type: PointLight
color: "#42a4ae"
radius: 4
energy: 4
castShadows: true
- type: LightBehaviour
behaviours:
- !type:FadeBehaviour
interpolate: Linear
minDuration: 2.25
maxDuration: 2.25
startValue: 2
endValue: 5
property: Energy
enabled: true
isLooped: true
reverseWhenFinished: true
- type: GuideHelp
guides:
- AnomalousResearch
- CosmicCult
- type: Anomaly
pulseSound:
path: /Audio/_DV/CosmicCult/effigy_pulse.ogg
supercriticalSound:
path: /Audio/_DV/CosmicCult/effigy_supercritical.ogg
nextPulseTime: 1
minPulseLength: 60
maxPulseLength: 80
minContituty: 0.4
maxContituty: 0.8
growthThreshold: 0.35
- type: EntitySpawnAnomaly
entries:
- settings:
spawnOnPulse: true
minAmount: 2
maxAmount: 3
minRange: 3
maxRange: 4.5
spawns:
- MobCosmicCustodianHostile
- MobCosmicOracleHostile
- MobCosmicLodestarHostile
- settings:
spawnOnSuperCritical: true
minAmount: 4
maxAmount: 7
maxRange: 8
spawns:
- MobCosmicCustodianHostile
- MobCosmicOracleHostile
- MobCosmicLodestarHostile
- CosmicMalignRift
- settings:
spawnOnShutdown: true
minAmount: 1
maxAmount: 2
maxRange: 1
spawns:
- MobCosmicLodestarHostile
- type: WarpPoint
follow: true

View File

@ -137,7 +137,6 @@
base: decay
- type: Tag
tags:
- Entropy
- HideContextMenu
- type: TileEmission
color: "#42a4ae"

View File

@ -53,6 +53,9 @@
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
##################### CHAIR
@ -72,10 +75,13 @@
thresholds:
- trigger:
!type:DamageTrigger
damage: 600
damage: 200
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
##################### PILLAR
- type: entity
@ -108,10 +114,13 @@
thresholds:
- trigger:
!type:DamageTrigger
damage: 600
damage: 200
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
##################### THRUSTER
- type: entity
@ -173,6 +182,9 @@
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
##################### LAMP
- type: entity
@ -180,6 +192,8 @@
description: A mote of un-light shimmers within.
suffix: Always Powered
name: malign light
placement:
mode: SnapgridCenter
components:
- type: MeleeSound
soundGroups:
@ -212,15 +226,15 @@
thresholds:
- trigger:
!type:DamageTrigger
damage: 600
damage: 200
behaviors: #excess damage, don't spawn entities.
- !type:DoActsBehavior
acts: [ "Destruction" ]
- !type:PlaySoundBehavior
sound:
collection: GlassBreak
placement:
mode: SnapgridCenter
- type: entity
id: CosmicMalignRift
@ -279,7 +293,7 @@
shape:
!type:PhysShapeAabb
bounds: "-0.25,-0.375,0.25,0.4"
density: 100
density: 200
mask:
- LargeMobMask
layer:
@ -321,7 +335,7 @@
thresholds:
- trigger:
!type:DamageTrigger
damage: 400
damage: 300
behaviors: #excess damage, don't spawn entities.
- !type:DoActsBehavior
acts: [ "Destruction" ]
@ -367,7 +381,7 @@
sprite: _DV/CosmicCult/Tileset/cosmictable.rsi
state: full
- type: Damageable
damageContainer: StructuralInorganic
damageContainer: Inorganic
damageModifierSet: Metallic
- type: CosmicCultExamine
cultistText: cosmic-examine-text-forthecult

View File

@ -6,5 +6,11 @@
objective: roles-antag-cosmiccult-description
requirements:
- !type:OverallPlaytimeRequirement
time: 43200 # 12h
time: 86400 # 24h i really just want people to read the guidebook please please please
guides: [ CosmicCult ]
- type: antag
id: CosmicAntagColossus
name: ghost-role-information-colossus-name
antagonist: true
objective: ghost-role-colossus-objective

View File

@ -14,4 +14,4 @@
id: ColossusTitlesLone
values:
prefix: cosmiccolossus-titles-lone-dataset-
count: 4
count: 5

View File

@ -0,0 +1,35 @@
- type: entity
parent: BaseGameRule
id: ColossusSpawn
components:
- type: StationEvent
weight: 4.5
earliestStart: 30
reoccurrenceDelay: 20
minimumPlayers: 25
duration: null
- type: PrecognitionResult
message: psionic-power-precognition-colossus-spawn-result-message
- type: SpaceSpawnRule
- type: AntagSpawner
prototype: MobCosmicColossusLone
- type: AntagObjectives
objectives:
- ColossusSurviveObjective
- ColossusEffigyObjective
- type: AntagSelection
agentName: role-subtype-colossus
definitions:
- spawnerPrototype: SpawnPointCosmicColossus
min: 1
max: 1
pickPlayer: false
mindRoles:
- MindRoleCosmicColossus
briefing:
text: ghost-role-colossus-briefing
color: CadetBlue
sound: /Audio/_DV/CosmicCult/antag_cosmic_briefing.ogg
components:
- type: CosmicColossus
timed: true

View File

@ -0,0 +1,18 @@
- type: entity
categories: [ HideSpawnMenu, Spawner ]
parent: BaseAntagSpawner
id: SpawnPointCosmicColossus
components:
- type: GhostRole
name: ghost-role-information-colossus-name
description: ghost-role-information-colossus-description
rules: ghost-role-information-colossus-rules
makeSentient: true
allowSpeech: true
allowMovement: true
mindRoles:
- MindRoleGhostRoleTeamAntagonist
- type: Sprite
layers:
- sprite: _DV/CosmicCult/Mobs/colossus.rsi
state: colossus

View File

@ -11,3 +11,17 @@
- type: CosmicCultRole
- type: RoleBriefing
briefing: objective-cosmiccult-charactermenu
- type: entity
parent: BaseMindRoleAntag
id: MindRoleCosmicColossus
name: Colossus Role
components:
- type: MindRole
antagPrototype: CosmicAntagColossus
roleType: TeamAntagonist
subtype: role-subtype-colossus
exclusiveAntag: true
- type: CosmicColossusRole
- type: RoleBriefing
briefing: ghost-role-colossus-charactermenu

View File

@ -0,0 +1,5 @@
- type: nameIdentifierGroup
id: CosmicPositronicBrain
prefix: ASTRAL
minValue: 0
maxValue: 10

View File

@ -10,8 +10,35 @@
roles:
- CosmicCultRole
- type: entity
abstract: true
parent: BaseObjective
id: BaseCosmicColossusObjective
components:
- type: Objective
difficulty: 1.5
issuer: objective-issuer-cosmiccult
- type: RoleRequirement
roles:
- CosmicColossusRole
############################### COSMIC CULT'S OBJECTIVES
- type: entity
parent: BaseCosmicCultObjective
id: CosmicConversionObjective
components:
- type: Objective
icon:
sprite: _DV/CosmicCult/Icons/objectives.rsi
state: infection
- type: NumberObjective
min: 7
max: 14
title: objective-condition-conversion-title
description: objective-condition-conversion-desc
- type: CosmicConversionCondition
- type: entity
parent: BaseCosmicCultObjective
id: CosmicEntropyObjective
@ -21,8 +48,8 @@
sprite: _DV/CosmicCult/Icons/objectives.rsi
state: siphon
- type: NumberObjective
min: 40
max: 60
min: 70
max: 90
title: objective-condition-entropy-title
description: objective-condition-entropy-desc
- type: CosmicEntropyCondition
@ -56,3 +83,28 @@
title: objective-condition-victory-title
description: objective-condition-victory-desc
- type: CosmicVictoryCondition
############################### COLOSSI OBJECTIVES
- type: entity
parent: [BaseCosmicColossusObjective, BaseSurviveObjective]
id: ColossusSurviveObjective
name: PERSIST
description: Persist until the end of all things.
components:
- type: Objective
icon:
sprite: _DV/CosmicCult/Icons/objectives.rsi
state: colossus
- type: entity
parent: [BaseCosmicColossusObjective, BaseCodeObjective]
id: ColossusEffigyObjective
name: BECKON
description: Call forth an Effigy of Entropy.
components:
- type: Objective
icon:
sprite: _DV/CosmicCult/Icons/objectives.rsi
state: effigy
- type: CosmicEffigyCondition

View File

@ -45,8 +45,8 @@
mobile: true
- type: entity
id: ProjectileCosmicRazor
name: Astral Bolt
id: ProjectileCosmic
name: Malign Bolt
parent: BaseBullet
categories: [ HideSpawnMenu ]
description: Ouch.
@ -60,22 +60,15 @@
layers:
- state: razor
shader: unshaded
- type: DamageMarkerOnCollide
whitelist:
components:
- MobState
damage:
types:
Cold: 15
Asphyxiation: 10
- type: Projectile
impactEffect: BulletImpactEffectCosmic
damage:
types:
Cold: 10
Asphyxiation: 5
Cold: 12
soundHit:
path: /Audio/_DV/CosmicCult/projectile_razor_hit.ogg
params:
variation: 0.08
- type: Ammo
muzzleFlash: null
# Short lifespan
@ -101,6 +94,27 @@
enabled: true
reverseWhenFinished: true
- type: entity
id: ProjectileCosmicRazor
name: Astral Bolt
parent: ProjectileCosmic
categories: [ HideSpawnMenu ]
description: Ouch.
components:
- type: DamageMarkerOnCollide
whitelist:
components:
- MobState
damage:
types:
Cold: 15
Asphyxiation: 10
- type: Projectile
impactEffect: BulletImpactEffectCosmic
damage:
types:
Cold: 10
Asphyxiation: 5
- type: entity
id: BulletImpactEffectCosmic

View File

@ -12,6 +12,7 @@
objectives:
- CosmicFinalityObjective
- CosmicMonumentObjective
- CosmicConversionObjective
- CosmicEntropyObjective
- type: AntagSelection
definitions:

View File

@ -1,2 +0,0 @@
- type: Tag
id: Entropy

View File

@ -0,0 +1,7 @@
- type: typingIndicator
id: CosmicTyping
spritePath: /Textures/_DV/CosmicCult/Effects/speech.rsi
typingState: malign0
idleState: malign0
offset: -0.2, 0.1
shader: unshaded

View File

@ -14,3 +14,8 @@
id: Revenant
announcement: terror-revenant
rule: RevenantSpawn
- type: ninjaHackingThreat # DeltaV start
id: Colossus
announcement: terror-colossus
rule: ColossusSpawn # DeltaV end

View File

@ -8,7 +8,8 @@
## Various Antagonists
Antagonists can take many forms, like:
- [textlink="The Cosmic Cult" link="CosmicCult"], who seek to usher in the end of all things.
- [textlink="The Cosmic Cult" link="CosmicCult"], who seek to usher in the end of all things. <!-- DeltaV -->
- [textlink="Entropic Colossi" link="CosmicColossus"], towering monstrosities of malign plating. <!-- DeltaV -->
- [textlink="Traitors" link="Traitors"] amongst the crew who must assassinate, steal and decieve.
- [textlink="Thieves" link="Thieves"] driven by kleptomania, determined to get their fix using their special gloves.
- [textlink="Revolutionaries" link="Revolutionaries"] who are intent on taking control of the station from the inside.

View File

@ -0,0 +1,49 @@
<Document>
# Entropic Colossus
<Box>
[color=#999999][italic]"Neither ill will, nor impassioned desire. Neither malice, nor cruelty. Nothing."[/italic][/color]
</Box>
<Box>
[color=#999999][italic]"Just an end."[/italic][/color]
</Box>
<Box>
<GuideEntityEmbed Entity="MobCosmicColossus" Caption=""/>
</Box>
You are an Entropic Colossus, a towering monstrosity of malign plating and dendritic infestation. Your purpose is the same as that of the [color=#4cabb3]Cosmic Cult[/color]: The end of all things.
Some Colossi are remnants. Perhaps survivors of a conflict borne of The Unknown's influence, or the product of some strange Noospheric anomaly. These Colossi drift across the distal black of space until their energies deplete... Or until they impact civilization.
[textlink="For information on cult-created colossi, click here." link="CosmicCult"]
## Influences
Entropic Colossi are posessed of powerful [color=#4cabb3]Malign Influences[/color], with which a capable colossus may lay waste to its enemies.
- [color=#4cabb3][bold]Entropic Sunder:[/bold][/color] Warp to the target location and unleash a cascading detonation of malign energy. Careful - this will hurt allied cultists!
- [color=#4cabb3][bold]Colossal Ingress:[/bold][/color] Use your colossal strength to force open a doorway. Even securely bolted doorways will be torn open by your titanic power.
- [color=#4cabb3][bold]Slumber Shell:[/bold][/color] Slumber your body for a period of time to regenerate integrity. Must be done on stable ground. This will restore you for exactly half the damage you've taken.
Colossi that have encountered the station by happenstance also have this influence:
- [color=#4cabb3][bold]Colossal Ingress:[/bold][/color] Use your colossal strength to force open a doorway. Even securely bolted doorways will be torn open by your titanic power.
## Objectives
<Box>
<GuideEntityEmbed Entity="MobTileDamageArea" Caption=""/>
</Box>
Colossi that have encountered the station by happenstance:
- [color=#4cabb3][bold]Persist[/bold][/color] - Collectively siphon a certain amount of Entropy from the crew. The more entropy you siphon, the more you can empower the Monument!
- [color=#4cabb3][bold]Beckon[/bold][/color] - Call forth an Effigy of Entropy at a designated location aboard the station.
Colossi created from Cyborgs by the Cosmic Cult:
- [color=#4cabb3][bold]Usher In The End[/bold][/color] - Complete the final ritual to beckon the Unknown and destroy the station.
## Effigy of Entropy
<Box>
<GuideEntityEmbed Entity="CosmicEffigy" Caption=""/>
</Box>
Some Colossi may call forth an [color=#4cabb3]Effigy of Entropy[/color]. The effigy is a dangerously unstable malign anomaly, and should be dealt with by the Epistemics department immediately!
</Document>

View File

@ -86,6 +86,8 @@
If successfully unleashed, an Entropic Colossus will be a force to be reckoned with.
[textlink="For more on Entropic Colossi, click here." link="CosmicColossus"]
## Malign Law
<Box>
<GuideEntityEmbed Entity="StationAiUploadComputer" Caption=""/>

View File

@ -7,7 +7,7 @@
When mounting an effort to thwart the [color=#4cabb3]Cosmic Cult[/color], there are several methods the crew might employ to ensure their survival and safety. One of these methods is [color=Yellow]Deconversion[/color].
To [color=Yellow]Deconvert[/color] a cosmic cultist, a [bold]Censer[/bold] must be used. Censers are fueled with Holy Water, which can be procured from:
To [color=Yellow]Deconvert[/color] a cosmic cultist, an [bold]Ardent Censer[/bold] must be used. Censers are fueled with Holy Water, which can be procured from:
- Usage of a Bible by a Chaplain or Mystagogue on most containers of water will bless the water, turning it into Holy Water.
## Suppression Methods

View File

@ -27,8 +27,6 @@
Be prepared to defend the Monument during the Beckoning, as just one waylaid action from a single disruptive soul will bring this ritual to a sudden, unceremonious halt.
Converting additional crewmembers using a [color=#4cabb3]Glyph of Truth[/color] while the Beckoning is active will accelerate its speed, bringing the cult closer to total victory.
## Glyphs
Glyphs may be [color=#4cabb3]Scribed[/color] by interacting with the Monument. You may also [color=#4cabb3]Unscribe[/color] an unused Glyph in a similar manner at The Monument.

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

View File

@ -0,0 +1,85 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455, modified by Radezolid for SUITSTORAGE",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon",
"directions": 1
},
{
"name": "icon-on",
"directions": 1,
"delays": [
[
0.2,
0.2
]
]
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
},
{
"name": "equipped-BACKPACK",
"directions": 4
},
{
"name": "on-equipped-BACKPACK",
"directions": 4,
"delays": [
[
0.2,
0.2
],
[
0.2,
0.2
],
[
0.2,
0.2
],
[
0.2,
0.2
]
]
},
{
"name": "equipped-SUITSTORAGE",
"directions": 4
},
{
"name": "on-equipped-SUITSTORAGE",
"directions": 4,
"delays": [
[
0.2,
0.2
],
[
0.2,
0.2
],
[
0.2,
0.2
],
[
0.2,
0.2
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 681 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

View File

@ -0,0 +1,60 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "A custom item by AftrLite(Github)",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "malign0",
"delays": [
[
0.3,
0.3,
0.3,
0.4,
0.3
]
]
},
{
"name": "malign1",
"delays": [
[
0.1,
0.1,
0.1,
0.1,
0.1,
0.1
]
]
},
{
"name": "malign2",
"delays": [
[
0.1,
0.1,
0.1,
0.1,
0.1,
0.1
]
]
},
{
"name": "malign3",
"delays": [
[
0.3,
0.3,
0.3,
0.4
]
]
}
]
}

View File

@ -55,6 +55,9 @@
{
"name": "sunder"
},
{
"name": "slumber"
},
{
"name": "corruption"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

View File

@ -18,6 +18,12 @@
},
{
"name": "infection"
},
{
"name": "colossus"
},
{
"name": "effigy"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -163,6 +163,43 @@
},
{
"name": "attacking"
},
{
"name": "hibernate",
"delays": [
[
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075,
0.075
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

View File

@ -7,6 +7,12 @@
"y": 32
},
"states": [
{
"name": "dead"
},
{
"name": "dead_unshaded"
},
{
"name": "custodian",
"directions": 4,

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Some files were not shown because too many files have changed in this diff Show More