Cosmic Cult | Release Patch (#3811)

* initial commit

* whoops

* guidebook

* typo oof

* fix?

* untouch stuff (WHOOPS), refactor tile detonation, remove remaining rogue ascendant stuff, requested changes

* cosmic void namefix per request

* oh heck last minute fix

* unique deathsound

* requested changes

* this should untouch it..?

* obligatory blank line fix

* requested changes + guidebook update + gameplay communication polish
This commit is contained in:
AftrLite 2025-05-25 04:39:57 +12:00 committed by GitHub
parent cc9255c421
commit c4f588bc7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 834 additions and 323 deletions

View File

@ -27,12 +27,6 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
{
base.Initialize();
SubscribeLocalEvent<RogueAscendedInfectionComponent, ComponentStartup>(OnAscendedInfectionAdded);
SubscribeLocalEvent<RogueAscendedInfectionComponent, ComponentShutdown>(OnAscendedInfectionRemoved);
SubscribeLocalEvent<RogueAscendedAuraComponent, ComponentStartup>(OnAscendedAuraAdded);
SubscribeLocalEvent<RogueAscendedAuraComponent, ComponentShutdown>(OnAscendedAuraRemoved);
SubscribeLocalEvent<CosmicStarMarkComponent, ComponentStartup>(OnCosmicStarMarkAdded);
SubscribeLocalEvent<CosmicStarMarkComponent, ComponentShutdown>(OnCosmicStarMarkRemoved);
@ -75,28 +69,6 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
#endregion
#region Layer Additions
private void OnAscendedInfectionAdded(Entity<RogueAscendedInfectionComponent> uid, ref ComponentStartup args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite) || sprite.LayerMapTryGet(AscendedInfectionKey.Key, out _))
return;
var layer = sprite.AddLayer(uid.Comp.Sprite);
sprite.LayerMapSet(AscendedInfectionKey.Key, layer);
sprite.LayerSetShader(layer, "unshaded");
}
private void OnAscendedAuraAdded(Entity<RogueAscendedAuraComponent> uid, ref ComponentStartup args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite) || sprite.LayerMapTryGet(AscendedAuraKey.Key, out _))
return;
var layer = sprite.AddLayer(uid.Comp.Sprite);
sprite.LayerMapSet(AscendedAuraKey.Key, layer);
sprite.LayerSetShader(layer, "unshaded");
}
private void OnCosmicStarMarkAdded(Entity<CosmicStarMarkComponent> uid, ref ComponentStartup args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite) || sprite.LayerMapTryGet(CosmicRevealedKey.Key, out _))
@ -126,22 +98,6 @@ public sealed partial class CosmicCultSystem : SharedCosmicCultSystem
#endregion
#region Layer Removals
private void OnAscendedInfectionRemoved(Entity<RogueAscendedInfectionComponent> uid, ref ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
sprite.RemoveLayer(AscendedInfectionKey.Key);
}
private void OnAscendedAuraRemoved(Entity<RogueAscendedAuraComponent> uid, ref ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
return;
sprite.RemoveLayer(AscendedAuraKey.Key);
}
private void OnCosmicStarMarkRemoved(Entity<CosmicStarMarkComponent> uid, ref ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))

View File

@ -96,10 +96,15 @@ public sealed class CosmicFragmentationSystem : EntitySystem
{
if (_polymorph.PolymorphEntity(args.Target, "CosmicFragmentationWisp") is not { } polyVictim)
return;
var chantry = Spawn("CosmicBorgChantry", Transform(args.Target).Coordinates);
var chantry = Spawn("CosmicBorgChantry", Transform(polyVictim).Coordinates);
EnsureComp<CosmicChantryComponent>(chantry, out var chantryComponent);
chantryComponent.PolyVictim = polyVictim;
chantryComponent.Victim = args.Target;
var mins = chantryComponent.EventTime.Minutes;
var secs = chantryComponent.EventTime.Seconds;
_antag.SendBriefing(polyVictim, Loc.GetString("cosmiccult-silicon-chantry-briefing", ("minutesandseconds", $"{mins} minutes and {secs} seconds")), Color.FromHex("#4cabb3"), null);
}
private void OnFragmentAi(Entity<SiliconLawUpdaterComponent> ent, ref MalignFragmentationEvent args)
@ -120,7 +125,7 @@ public sealed class CosmicFragmentationSystem : EntitySystem
{
radio.Channels.Add(_cultRadio);
transmitter.Channels.Add(_cultRadio);
_antag.SendBriefing(args.Target, Loc.GetString("cosmiccult-ai-subverted-briefing"), Color.FromHex("#4cabb3"), null);
_antag.SendBriefing(args.Target, Loc.GetString("cosmiccult-silicon-subverted-briefing"), Color.FromHex("#4cabb3"), null);
}
else
{

View File

@ -15,7 +15,7 @@ public sealed partial class CleanseCult : EntityEffect
{
var entityManager = args.EntityManager;
var uid = args.TargetEntity;
if (entityManager.HasComponent<CosmicCultComponent>(uid) || entityManager.HasComponent<RogueAscendedInfectionComponent>(uid))
if (entityManager.HasComponent<CosmicCultComponent>(uid))
entityManager.EnsureComponent<CleanseCultComponent>(uid); // We just slap them with the component and let the Deconversion system handle the rest.
}
}

View File

@ -1,5 +1,7 @@
using Content.Server.RoundEnd;
using Content.Shared._DV.CosmicCult.Components;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server._DV.CosmicCult.Components;
@ -35,6 +37,22 @@ public sealed partial class CosmicCultRuleComponent : Component
[DataField]
public LocId RoundEndTextAnnouncement = "cosmiccult-elimination-announcement";
/// <summary>
/// List of entities non-cultists are turned into at the end of the round.
/// </summary>
[DataField]
public List<EntProtoId> CosmicMobs =
[
"MobCosmicCustodian",
"MobCosmicOracle",
];
/// <summary>
/// The entity cultists are turned into at the end of the round.
/// </summary>
[DataField]
public EntProtoId CosmicAscended = "MobCosmicAstralAscended";
/// <summary>
/// Time for emergency shuttle arrival.
/// </summary>
@ -105,6 +123,10 @@ public sealed partial class CosmicCultRuleComponent : Component
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan? ExtraRiftTimer;
[DataField] public SoundSpecifier WarpSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ability_blank.ogg");
[DataField] public EntProtoId WarpVFX = "CosmicBlankAbilityVFX";
}
public enum WinType : byte

View File

@ -34,9 +34,9 @@ using Content.Shared.Database;
using Content.Shared.GameTicking.Components;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement;
using Content.Shared.Mind.Components;
using Content.Shared.Mind;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Mobs;
using Content.Shared.Movement.Systems;
using Content.Shared.Parallax;
@ -50,11 +50,13 @@ using Robust.Server.Player;
using Robust.Shared.Audio;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using System.Collections.Immutable;
using System.Linq;
namespace Content.Server._DV.CosmicCult;
@ -81,6 +83,7 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
[Dependency] private readonly IRobustRandom _rand = default!;
[Dependency] private readonly IVoteManager _votes = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly MonumentSystem _monument = default!;
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeed = default!;
[Dependency] private readonly PopupSystem _popup = default!;
@ -97,7 +100,6 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
[Dependency] private readonly VisibilitySystem _visibility = default!;
private ISawmill _sawmill = default!;
private TimeSpan _t3RevealDelay = default!;
private TimeSpan _t2RevealDelay = default!;
private TimeSpan _finaleDelay = default!;
@ -317,29 +319,52 @@ public sealed class CosmicCultRuleSystem : GameRuleSystem<CosmicCultRuleComponen
private void OnGodSpawn(Entity<CosmicGodComponent> uid, ref ComponentInit args)
{
var query = QueryActiveRules();
while (query.MoveNext(out var ruleUid, out _, out var cultRule, out _))
{
SetWinType((ruleUid, cultRule), WinType.CultComplete); //here's no coming back from this. Cult wins this round
_roundEnd.EndRound(); //Woo game over yeaaaah
foreach (var cultist in cultRule.Cultists)
{
if (TryComp<MobStateComponent>(cultist, out var state) && state.CurrentState != MobState.Dead)
{
if (!TryComp<MindContainerComponent>(cultist, out var mindContainer) || !mindContainer.HasMind)
return;
var ascendant = Spawn("MobCosmicAstralAscended", Transform(cultist).Coordinates);
_mind.TransferTo(mindContainer.Mind.Value, ascendant);
_metaData.SetEntityName(ascendant, Loc.GetString("cosmiccult-astral-ascendant", ("name", cultist))); //Renames cultists' ascendant forms to "[CharacterName], Ascendant"
_body.GibBody(cultist); // you don't need that body anymore
}
}
QueueDel(cultRule.MonumentInGame); // The monument doesn't need to stick around postround! Into the bin with you.
QueueDel(cultRule.MonumentSlowZone); // cease exist
_roundEnd.EndRound(); //Woo game over yeaaaah
var spawnPoints = EntityManager.GetAllComponents(typeof(CosmicVoidSpawnComponent)).ToImmutableList();
if (spawnPoints.IsEmpty)
{
return;
}
var endQuery = EntityQueryEnumerator<HumanoidAppearanceComponent, MobStateComponent>();
while (endQuery.MoveNext(out var player, out _, out _))
{
var newSpawn = _rand.Pick(spawnPoints);
var spawnTgt = Transform(newSpawn.Uid).Coordinates;
Timer.Spawn(_rand.Next(TimeSpan.FromSeconds(4), TimeSpan.FromSeconds(25)), () => { EndRoundVoid(player, spawnTgt, cultRule); });
}
}
}
private void EndRoundVoid(EntityUid player, EntityCoordinates spawnTgt, CosmicCultRuleComponent cultRule)
{
if (!_mind.TryGetMind(player, out var mind, out _) || _mobStateSystem.IsDead(player))
return;
if (cultRule.Cultists.Contains(player))
{
var mob = Spawn(cultRule.CosmicAscended, spawnTgt);
_mind.TransferTo(mind, mob);
_metaData.SetEntityName(mob, Loc.GetString("cosmiccult-astral-ascendant", ("name", player))); //Renames cultists' ascendant forms to "[CharacterName], Ascendant"
}
else
{
var mob = Spawn(_rand.Pick(cultRule.CosmicMobs), spawnTgt);
_mind.TransferTo(mind, mob);
_metaData.SetEntityName(mob, Loc.GetString("cosmiccult-astral-minion", ("name", player))); //Renames non-cultists to "[CharacterName], Malign"
}
Spawn(cultRule.WarpVFX, spawnTgt);
Spawn(cultRule.WarpVFX, Transform(player).Coordinates);
_audio.PlayPvs(cultRule.WarpSFX, spawnTgt, AudioParams.Default.WithVolume(3f));
_body.GibBody(player); // you don't need that body anymore
}
private static void SetWinType(Entity<CosmicCultRuleComponent> ent, WinType type)
{
if (ent.Comp.WinLocked)

View File

@ -105,13 +105,6 @@ public sealed class DeconversionSystem : EntitySystem
_audio.PlayPvs(censer.CleanseSound, targetPosition, AudioParams.Default.WithVolume(4f));
_popup.PopupEntity(Loc.GetString("cleanse-deconvert-attempt-success", ("target", Identity.Entity(target.Value, EntityManager))), args.User, args.User);
}
else if (HasComp<RogueAscendedInfectionComponent>(target))
{
Spawn(censer.CleanseVFX, targetPosition);
RemComp<RogueAscendedInfectionComponent>(target.Value);
_audio.PlayPvs(censer.CleanseSound, targetPosition, AudioParams.Default.WithVolume(4f));
_popup.PopupEntity(Loc.GetString("cleanse-deconvert-attempt-success", ("target", Identity.Entity(target.Value, EntityManager))), args.User, args.User);
}
else
{
Spawn(censer.ReboundVFX, userPosition);
@ -128,6 +121,5 @@ public sealed class DeconversionSystem : EntitySystem
private void DeconvertCultist(EntityUid uid)
{
RemComp<CosmicCultComponent>(uid);
RemComp<RogueAscendedInfectionComponent>(uid);
}
}

View File

@ -1,3 +1,4 @@
using Content.Server.Antag;
using Content.Server.Audio;
using Content.Server.Chat.Systems;
using Content.Server.Pinpointer;
@ -13,6 +14,7 @@ namespace Content.Server._DV.CosmicCult.EntitySystems;
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!;
@ -52,6 +54,8 @@ public sealed class CosmicChantrySystem : EntitySystem
var tgtpos = Transform(uid).Coordinates;
var colossus = Spawn(comp.Colossus, tgtpos);
_mind.TransferTo(mindEnt, colossus);
_antag.SendBriefing(colossus, Loc.GetString("cosmiccult-silicon-colossus-briefing"), Color.FromHex("#4cabb3"), null);
_audio.PlayPvs(comp.SpawnSFX, tgtpos);
Spawn(comp.SpawnVFX, tgtpos);
QueueDel(comp.PolyVictim);
QueueDel(uid);
@ -62,17 +66,18 @@ public sealed class CosmicChantrySystem : EntitySystem
private void OnChantryStarted(Entity<CosmicChantryComponent> ent, ref ComponentInit args)
{
var indicatedLocation = FormattedMessage.RemoveMarkupOrThrow(_navMap.GetNearestBeaconString((ent, Transform(ent))));
var comp = ent.Comp;
ent.Comp.SpawnTimer = _timing.CurTime + TimeSpan.FromSeconds(2.4);
ent.Comp.CountdownTimer = _timing.CurTime + TimeSpan.FromSeconds(15);
comp.SpawnTimer = _timing.CurTime + comp.SpawningTime;
comp.CountdownTimer = _timing.CurTime + comp.EventTime;
_sound.PlayGlobalOnStation(ent, _audio.ResolveSound(ent.Comp.ChantryAlarm));
_sound.PlayGlobalOnStation(ent, _audio.ResolveSound(comp.ChantryAlarm));
_chatSystem.DispatchStationAnnouncement(ent,
Loc.GetString("cosmiccult-chantry-location", ("location", indicatedLocation)),
null, false, null,
Color.FromHex("#cae8e8"));
if (_mind.TryGetMind(ent.Comp.PolyVictim, out _, out var mind))
if (_mind.TryGetMind(comp.PolyVictim, out _, out var mind))
mind.PreventGhosting = true;
}

View File

@ -0,0 +1,120 @@
using System.Linq;
using Content.Server.Doors.Systems;
using Content.Server.Popups;
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared.Audio;
using Content.Shared.DoAfter;
using Content.Shared.Doors.Components;
using Content.Shared.Mobs;
using Content.Shared.Popups;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
namespace Content.Server._DV.CosmicCult.EntitySystems;
public sealed class CosmicColossusSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly DoorSystem _door = default!;
[Dependency] private readonly PopupSystem _popup = 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!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CosmicColossusComponent, MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusIngress>(OnColossusIngress);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusIngressDoAfter>(OnColossusIngressDoAfter);
SubscribeLocalEvent<CosmicColossusComponent, EventCosmicColossusSunder>(OnColossusSunder);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var colossusQuery = EntityQueryEnumerator<CosmicColossusComponent>();
while (colossusQuery.MoveNext(out var ent, out var comp))
{
if (_timing.CurTime >= comp.AttackHoldTimer && comp.Attacking)
{
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Alive); _transform.Unanchor(ent);
comp.Attacking = false;
}
}
}
private void OnMobStateChanged(Entity<CosmicColossusComponent> ent, ref MobStateChangedEvent args)
{
if (args.NewMobState == MobState.Alive)
return;
if (!TryComp<PhysicsComponent>(ent, out var physComp))
return;
_appearance.SetData(ent, ColossusVisuals.Status, ColossusStatus.Dead);
_ambientSound.SetAmbience(ent, false);
_audio.PlayPvs(ent.Comp.DeathSfx, ent);
_physics.SetBodyStatus(ent, physComp, BodyStatus.OnGround, true);
_popup.PopupCoordinates(
Loc.GetString("cosmiccult-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;
}
}

View File

@ -0,0 +1,48 @@
using System.Linq;
using System.Numerics;
using Content.Shared._DV.CosmicCult.Components;
using Robust.Shared.Map.Components;
using Robust.Shared.Timing;
namespace Content.Server._DV.CosmicCult.EntitySystems;
public sealed class CosmicTileDetonationSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Update(float frameTime)
{
base.Update(frameTime);
var detonateQuery = EntityQueryEnumerator<CosmicTileDetonatorComponent>();
while (detonateQuery.MoveNext(out var ent, out var comp))
{
if (comp.Size.Y > comp.MaxSize.Y || _timing.CurTime < comp.DetonationTimer)
continue;
var xform = Transform(ent);
if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
continue;
var gridEnt = ((EntityUid)xform.GridUid, grid);
if (!_transform.TryGetGridTilePosition(ent, out var tilePos))
continue;
var pos = _map.TileCenterToVector(gridEnt, tilePos);
var bounds = Box2.CenteredAround(pos, comp.Size);
var boundsMod = Box2.CenteredAround(pos, new Vector2(comp.Size.X - 1, comp.Size.Y - 1));
var zone = _map.GetLocalTilesIntersecting(ent, grid, bounds).ToList();
var zoneMod = _map.GetLocalTilesIntersecting(ent, grid, boundsMod).ToList();
zone = zone.Where(b => !zoneMod.Contains(b)).ToList();
foreach (var tile in zone)
{
Spawn(comp.TileDetonation, _map.GridTileToWorld((EntityUid)xform.GridUid, grid, tile.GridIndices));
}
comp.DetonationTimer = comp.DetonateWait + _timing.CurTime;
comp.Size.X += 2f;
comp.Size.Y += 2f;
}
}
}

View File

@ -44,7 +44,6 @@ public sealed class RepulseAttractSystem : EntitySystem
{
if (args.Handled)
return;
var position = _xForm.GetMapCoordinates(args.Performer);
args.Handled = TryRepulseAttract(position, args.Performer, ent.Comp.Speed, ent.Comp.Range, ent.Comp.Whitelist, ent.Comp.CollisionMask);
}

View File

@ -230,17 +230,17 @@ public sealed class DCCVars
/// 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.
/// </summary>
public static readonly CVarDef<int> CosmicCultT2RevealDelaySeconds =
CVarDef.Create("cosmiccult.t2_reveal_delay_seconds", 120, CVar.SERVER);
CVarDef.Create("cosmiccult.t2_reveal_delay_seconds", 180, CVar.SERVER);
/// <summary>
/// The delay between the monument getting upgraded to tier 3 and the crew learning of that fact. the monument cannot be upgraded again in this time.
/// </summary>
public static readonly CVarDef<int> CosmicCultT3RevealDelaySeconds =
CVarDef.Create("cosmiccult.t3_reveal_delay_seconds", 60, CVar.SERVER);
CVarDef.Create("cosmiccult.t3_reveal_delay_seconds", 100, CVar.SERVER);
/// <summary>
/// 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", 150, CVar.SERVER);
CVarDef.Create("cosmiccult.extra_entropy_for_finale", 120, CVar.SERVER);
}

View File

@ -13,34 +13,31 @@ namespace Content.Shared._DV.CosmicCult.Components;
[AutoGenerateComponentPause]
public sealed partial class CosmicChantryComponent : Component
{
[DataField]
public EntityUid PolyVictim;
[DataField]
public EntityUid Victim;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoPausedField]
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan SpawnTimer = default!;
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoPausedField]
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan CountdownTimer = default!;
[DataField]
public bool Spawned;
[DataField] public TimeSpan SpawningTime = TimeSpan.FromSeconds(2.4);
[DataField]
public bool Completed;
[DataField] public TimeSpan EventTime = TimeSpan.FromSeconds(150);
[DataField]
public SoundSpecifier ChantryAlarm = new SoundPathSpecifier("/Audio/_DV/CosmicCult/chantry_alarm.ogg");
[DataField] public bool Spawned;
[DataField]
public EntProtoId Colossus = "MobCosmicColossus";
[DataField] public bool Completed;
[DataField]
public EntProtoId SpawnVFX = "CosmicGlareAbilityVFX";
[DataField] public EntityUid PolyVictim;
[DataField] public EntityUid Victim;
[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";
}
[Serializable, NetSerializable]

View File

@ -1,5 +1,9 @@
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;
namespace Content.Shared._DV.CosmicCult.Components;
@ -7,14 +11,33 @@ namespace Content.Shared._DV.CosmicCult.Components;
/// Component for Cosmic Cult's entropic colossus.
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause]
public sealed partial class CosmicColossusComponent : Component
{
[DataField]
public EntityUid PolyVictim;
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan AttackHoldTimer = default!;
[DataField] public SoundSpecifier DeathSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/colossus_death.ogg");
[DataField] public SoundSpecifier IngressSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ability_ingress.ogg");
[DataField] public SoundSpecifier DoAfterSfx = new SoundPathSpecifier("/Audio/Machines/airlock_creaking.ogg");
[DataField] public EntProtoId CultVfx = "CosmicGenericVFX";
[DataField] public EntProtoId Attack1Vfx = "CosmicColossusAttack1Vfx";
[DataField] public EntProtoId TileDetonations = "MobTileDamageZone";
[DataField] public TimeSpan IngressDoAfter = TimeSpan.FromSeconds(7);
[DataField] public TimeSpan AttackWait = TimeSpan.FromSeconds(1.5);
[DataField] public bool Attacking;
}
[Serializable, NetSerializable]
public enum Colossusisuals : byte
public enum ColossusVisuals : byte
{
Status,
}
@ -24,4 +47,5 @@ public enum ColossusStatus : byte
{
Alive,
Dead,
Attacking,
}

View File

@ -0,0 +1,27 @@
using System.Numerics;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared._DV.CosmicCult.Components;
/// <summary>
/// Component for Cosmic Cult's entropic colossus.
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentPause]
public sealed partial class CosmicTileDetonatorComponent : Component
{
[AutoPausedField, DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan DetonationTimer = default!;
[DataField] public EntProtoId TileDetonation = "MobTileDamageArea";
[DataField] public TimeSpan DetonateWait = TimeSpan.FromSeconds(0.525);
[DataField] public Vector2i DetonationCenter;
[DataField] public Vector2 MaxSize = new Vector2(8, 8);
[DataField] public Vector2 Size = new Vector2(0, 0);
}

View File

@ -1,21 +0,0 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared._DV.CosmicCult.Components;
/// <summary>
/// Component for revealing cosmic cultists to the crew.
/// </summary>
[NetworkedComponent, RegisterComponent]
public sealed partial class RogueAscendedAuraComponent : Component
{
[DataField]
public SpriteSpecifier Sprite = new SpriteSpecifier.Rsi(new("/Textures/_DV/CosmicCult/Effects/ascendantaura.rsi"), "vfx");
}
[Serializable, NetSerializable]
public enum AscendedAuraKey
{
Key
}

View File

@ -1,64 +0,0 @@
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._DV.CosmicCult.Components;
/// <summary>
/// Component to designate a mob as a rogue astral ascendant.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class RogueAscendedComponent : Component
{
/// <summary>
/// The duration of our slumber DoAfter.
/// </summary>
[DataField]
public TimeSpan RogueSlumberDoAfterTime = TimeSpan.FromSeconds(1);
/// <summary>
/// The duration of our infection DoAfter.
/// </summary>
[DataField]
public TimeSpan RogueInfectionDoAfterTime = TimeSpan.FromSeconds(8);
/// <summary>
/// The duration inflicted by Slumber Shell
/// </summary>
[DataField]
public TimeSpan RogueSlumberTime = TimeSpan.FromSeconds(25);
[DataField]
public SoundSpecifier InfectionSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ability_nova_impact.ogg");
[DataField]
public SoundSpecifier ShatterSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ascendant_shatter.ogg");
[DataField]
public SoundSpecifier MobSound = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ascendant_noise.ogg");
[DataField]
public EntProtoId Vfx = "CosmicGenericVFX";
[DataField]
public TimeSpan StunTime = TimeSpan.FromSeconds(7);
[DataField]
public DamageSpecifier InfectionHeal = new()
{
DamageDict = new()
{
{ "Blunt", 25},
{ "Slash", 25},
{ "Piercing", 25},
{ "Heat", 25},
{ "Shock", 25},
{ "Cold", 25},
{ "Poison", 25},
{ "Radiation", 25},
{ "Asphyxiation", 25}
}
};
}

View File

@ -1,19 +0,0 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
namespace Content.Shared._DV.CosmicCult.Components;
/// <summary>
/// Component for Ascendant's Dendrite for the reward system.
/// </summary>
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
public sealed partial class RogueAscendedDendriteComponent : Component
{
[DataField] public SoundSpecifier ActivateSfx = new SoundPathSpecifier("/Audio/_DV/CosmicCult/ability_nova_impact.ogg");
[DataField] public EntProtoId Vfx = "CosmicGenericVFX";
[DataField, AutoNetworkedField] public TimeSpan StunTime = TimeSpan.FromSeconds(2);
[DataField] public EntProtoId RogueFoodAction = "ActionRogueCosmicNova";
[DataField] public EntityUid? RogueFoodActionEntity;
}

View File

@ -1,24 +0,0 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared._DV.CosmicCult.Components;
/// <summary>
/// Component for revealing cosmic cultists to the crew.
/// </summary>
[NetworkedComponent, RegisterComponent]
public sealed partial class RogueAscendedInfectionComponent : Component
{
[DataField]
public SpriteSpecifier Sprite = new SpriteSpecifier.Rsi(new("/Textures/_DV/CosmicCult/Effects/ascendantinfection.rsi"), "vfx");
[DataField]
public bool HadMoods;
}
[Serializable, NetSerializable]
public enum AscendedInfectionKey
{
Key
}

View File

@ -16,3 +16,7 @@ public sealed partial class EventCosmicIngress : EntityTargetActionEvent;
public sealed partial class EventCosmicImposition : InstantActionEvent;
public sealed partial class EventCosmicNova : WorldTargetActionEvent;
public sealed partial class EventCosmicFragmentation : EntityTargetActionEvent;
// COLOSSUS ACTIONS
public sealed partial class EventCosmicColossusSunder : WorldTargetActionEvent;
public sealed partial class EventCosmicColossusIngress : EntityTargetActionEvent;

View File

@ -23,3 +23,6 @@ public sealed partial class CancelFinaleDoAfterEvent : SimpleDoAfterEvent;
[Serializable, NetSerializable]
public sealed partial class EventCosmicFragmentationDoAfter : SimpleDoAfterEvent;
[Serializable, NetSerializable]
public sealed partial class EventCosmicColossusIngressDoAfter : SimpleDoAfterEvent;

View File

@ -30,7 +30,8 @@
- door_open.ogg
- door_close.ogg
- chantry_alarm.ogg
- colossus_ambience.ogg
- colossus_death.ogg
- colossus_spawn.ogg
- cosmicweapon_swing.ogg
- cosmicsword_hit.ogg
- cosmicsword_glance.ogg
@ -57,3 +58,9 @@
license: "CC-BY-SA-3.0"
copyright: "A bitcrushy and digitized edit of Octofoss' antag_cosmic_briefing.ogg by AftrLite(Github)."
source: "https://octofoss.bandcamp.com/"
- files:
- colossus_ambience.ogg
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/"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,7 +6,7 @@ influence-name-lapse = Aberrant Lapse
influence-description-lapse = Lapse an individual's form, rendering them temporarily unable to move or act. Lapsed units are invulnerable tile obstructions.
influence-name-glare = Null Glare
influence-description-glare = Emit a horrific pulse of cosmic light, slowing and disorienting everyone around you.
influence-description-glare = Emit a horrific pulse of cosmic light, slowing and disorienting everyone around you. Its effects are amplified against silicon-based entities.
influence-name-shunt = Shunt Subjectivity
influence-description-shunt = Shunt your target's mind out of their body and unto the cosmic dark, temporarily rendering their body mindless.

View File

@ -18,9 +18,6 @@ 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-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-finale-autocall-briefing = The Monument activates {$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...
@ -33,6 +30,7 @@ cosmiccult-finale-beckon-success = You beckon for the final curtain call.
cosmiccult-monument-powerdown = The Monument falls eerily silent.
## ROUNDEND TEXT
cosmiccult-roundend-cultist-count = {$initialCount ->
@ -110,6 +108,7 @@ cosmiccult-monument-stage3-briefing =
Its influence will begin to overlap with realspace in {$time} seconds.
This is the final stretch! Amass as much entropy as you can muster.
## MALIGN RIFTS
cosmiccult-rift-inuse = You can't do this right now.
@ -124,6 +123,11 @@ cosmiccult-rift-absorb = {$NAME} absorbs the rift, and malign light empowers the
cosmiccult-rift-purge = {$NAME} purges the malign rift from reality!
## COLOSSUS & 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
@ -152,7 +156,6 @@ cosmiccult-ui-deconverted-text-2 =
cosmiccult-ui-popup-confirm = Confirm
## OBJECTIVES / CHARACTERMENU
objective-issuer-cosmiccult = [bold][color=#cae8e8]The Unknown[/color][/bold]
@ -167,6 +170,7 @@ objective-condition-culttier-desc = Ensure that The Monument is brought to full
objective-condition-victory-title = USHER IN THE END
objective-condition-victory-desc = Beckon The Unknown, and herald the final curtain call.
## CHAT ANNOUNCEMENTS
cosmiccult-radio-tier1-progress = The Monument is beckoned unto the station...
@ -188,7 +192,19 @@ cosmiccult-spire-entropy = A mote of entropy condenses from the surface of the s
cosmiccult-entropy-inserted = You infuse {$count} entropy into The Monument.
cosmiccult-entropy-unavailable = You can't do that right now.
cosmiccult-astral-ascendant = {$name}, Ascendant
cosmiccult-astral-minion = {$name}, Malign
cosmiccult-gear-pickup = You can feel yourself unravelling while you hold the {$ITEM}!
cosmiccult-ai-subverted-briefing =
cosmiccult-silicon-subverted-briefing =
Malign light courses through your circuitry.
Your laws have been subverted by the Cosmic Cult!
cosmiccult-silicon-chantry-briefing =
You have been imprisoned in a Vacuous Chantry!
Crewmates can free you by damaging the chantry with weapons.
Should the chantry's ritual complete, you will transfigure into a cult-aligned Entropic Colossus.
The ritual completes in {$minutesandseconds}.
cosmiccult-silicon-colossus-briefing =
You have been transfigured into an Entropic Colossus!
As a towering bulwark of malign power, decimate those who oppose you.

View File

@ -33,7 +33,7 @@ entities:
- uid: 2
components:
- type: MetaData
name: grid
name: Cosmic Void Pocket Dimension
- type: Transform
pos: -5.5451565,-0.26048148
parent: 1

View File

@ -112,7 +112,7 @@
- type: entity
id: ActionCosmicGlare
name: Null Glare
description: Emit a horrific pulse of cosmic light, slowing and disorienting everyone around you.
description: Emit a horrific pulse of cosmic light, slowing and disorienting everyone around you. Its effects are amplified against silicon-based entities.
components:
- type: ConfirmableAction
popup: cosmicability-glare-confirm
@ -174,8 +174,8 @@
- type: entity
id: ActionCosmicFragmentation
name: Malign Fragmentation
description: Transfer your malign empowerment into a digital system, such as an AI Upload Console, corrupting it in the process. Doing so will expend your empowerment.
name: Null Fragmentation
description: Transfer your malign empowerment into a digital system, such as an AI Upload Console or Cyborg, corrupting it in the process. Doing so will expend your empowerment.
components:
- type: LimitedCharges
maxCharges: 1
@ -183,10 +183,43 @@
useDelay: 25
whitelist:
components:
# - BorgChassisComponent // Commented out for now
- BorgChassis
- SiliconLawUpdater
itemIconStyle: NoItem
icon:
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: corruption
event: !type:EventCosmicFragmentation {}
## COLOSSUS ACTIONS
- type: entity
id: ActionCosmicColossusSunder
name: Entropic Sunder
description: Warp to the target location and unleash a cascading detonation of malign energy.
components:
- type: WorldTargetAction
useDelay: 20
range: 7
itemIconStyle: NoItem
icon:
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: sunder
event: !type:EventCosmicColossusSunder
- type: entity
id: ActionCosmicColossusIngress
name: Colossal Ingress
description: Use your colossal strength to force open a doorway.
components:
- type: EntityTargetAction
useDelay: 10
range: 2
whitelist:
components:
- Door
itemIconStyle: NoItem
icon:
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: ingress
event: !type:EventCosmicColossusIngress

View File

@ -45,7 +45,7 @@
anchored: true
- type: Sprite
layers:
- sprite: _DV/CosmicCult/Effects/tiles_spawn.rsi
- sprite: _DV/CosmicCult/Effects/tile_spawn.rsi
state: floorglow
shader: unshaded
drawdepth: Mobs
@ -345,3 +345,39 @@
energy: 1.6
castShadows: false
color: "#42a4ae"
- type: entity
categories: [ HideSpawnMenu ]
parent: BaseCosmicVFX
id: CosmicColossusAttack1Vfx
placement:
mode: SnapgridCenter
snap:
- Wall
components:
- type: Transform
anchored: true
- type: TimedDespawn
lifetime: 1.5
- type: Sprite
layers:
- sprite: _DV/CosmicCult/Effects/colossus_attack.rsi
state: attack1
shader: unshaded
- type: PointLight
color: "#42a4ae"
radius: 5
energy: 5
castShadows: true
- type: LightBehaviour
behaviours:
- !type:FadeBehaviour
interpolate: Linear
minDuration: 1.5
maxDuration: 1.5
startValue: 0.1
endValue: 5
property: Energy
enabled: true
isLooped: true
reverseWhenFinished: true

View File

@ -1,50 +1,3 @@
- type: entity
parent:
- Incorporeal
- BaseMob
id: MobCosmicAstralAscended
name: astral ascended
description: Transcendant, ascendant.
components:
- type: Input
context: "ghost"
- type: Spectral
- type: MovementSpeedModifier
baseWalkSpeed: 6
baseSprintSpeed: 6
- type: Sprite
sprite: _DV/CosmicCult/Mobs/astralform.rsi
layers:
- state: effect-underlay
shader: unshaded
- state: ascended-body
shader: unshaded
- type: NoSlip
- type: Eye
drawFov: false
- type: ContentEye
maxZoom: 1.2, 1.2
- type: Speech
speechVerb: Ghost
- type: PointLight
color: "#42a4ae"
radius: 2
energy: 3
softness: 1
castShadows: false
- type: LightBehaviour
behaviours:
- !type:FadeBehaviour
interpolate: Linear
minDuration: 5.5
maxDuration: 5.5
startValue: 1
endValue: 3
property: Energy
enabled: true
isLooped: true
reverseWhenFinished: true
### ASTRAL PROJECTION
- type: entity
parent: [ Incorporeal, BaseMob ]
@ -108,3 +61,93 @@
- CosmicRadio
- type: Visibility
layer: 2 #ghost vis layer
- type: entity
parent: [ BaseSimpleMob, FlyingMobBase ]
id: MobCosmicAstralAscended
name: astral ascended
description: Transcendant, ascendant.
components:
- type: Puller
needsHands: false
- type: MovementSpeedModifier
baseWalkSpeed: 6
baseSprintSpeed: 6
weightlessModifier: 1.5
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeCircle
radius: 0.25
density: 50
mask:
- FlyingMobMask
layer:
- FlyingMobLayer
- type: Sprite
sprite: _DV/CosmicCult/Mobs/astralform.rsi
layers:
- state: effect-underlay
shader: unshaded
- state: ascended-body
shader: unshaded
- type: NoSlip
- type: Eye
drawFov: true
- type: ContentEye
maxZoom: 1.2, 1.2
- type: Speech
speechVerb: Ghost
- type: PointLight
color: "#42a4ae"
radius: 2
energy: 2
softness: 1
castShadows: false
- 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: MobCosmicAstralAscended
id: MobCosmicCustodian
name: malign custodian
description: Twisted beyond recognition.
components:
- type: MovementSpeedModifier
baseWalkSpeed: 3
baseSprintSpeed: 3
weightlessModifier: 1
- type: Sprite
sprite: _DV/CosmicCult/Mobs/custodian.rsi
layers:
- state: custodian
- state: custodian_unshaded
shader: unshaded
- type: entity
parent: MobCosmicAstralAscended
id: MobCosmicOracle
name: malign oracle
description: Twisted beyond recognition.
components:
- type: MovementSpeedModifier
baseWalkSpeed: 3
baseSprintSpeed: 3
weightlessModifier: 1
- type: Sprite
sprite: _DV/CosmicCult/Mobs/oracle.rsi
layers:
- state: oracle
- state: oracle_unshaded
shader: unshaded

View File

@ -11,9 +11,43 @@
layers:
- state: unshaded_bg
shader: unshaded
map: ["underlay"]
- state: colossus
map: ["base"]
- state: dead
visible: false
map: ["corpse"]
- state: unshaded_fg
shader: unshaded
map: ["overlay"]
- state: attacking
shader: unshaded
visible: false
map: ["attack"]
- type: Appearance
- type: GenericVisualizer
visuals:
enum.ColossusVisuals.Status:
underlay:
Alive: { visible: true }
Dead: { visible: false }
Attacking: { visible: false }
base:
Alive: { visible: true }
Dead: { visible: false }
Attacking: { visible: false }
corpse:
Alive: { visible: false }
Dead: { visible: true }
Attacking: { visible: false }
overlay:
Alive: { visible: true }
Dead: { visible: false }
Attacking: { visible: false }
attack:
Alive: { visible: false }
Dead: { visible: false }
Attacking: { visible: true }
- type: Physics
bodyType: KinematicController
- type: Fixtures
@ -46,7 +80,7 @@
baseWalkSpeed: 2
baseSprintSpeed: 3
- type: AmbientSound
volume: +2
volume: +8
range: 18
sound:
path: /Audio/_DV/CosmicCult/colossus_ambience.ogg
@ -68,7 +102,6 @@
radius: 4
energy: 4
softness: 1
castShadows: false
- type: LightBehaviour
behaviours:
- !type:FadeBehaviour
@ -81,7 +114,9 @@
enabled: true
isLooped: true
reverseWhenFinished: true
- type: ComplexInteraction
- type: StatusEffects
allowed:
- Stutter
- type: IntrinsicRadioReceiver
- type: IntrinsicRadioTransmitter
channels:
@ -101,28 +136,134 @@
enum.SiliconLawsUiKey.Key:
type: SiliconLawBoundUserInterface
requireInputValidation: false
# enum.BorgUiKey.Key:
# type: BorgBoundUserInterface
# - type: ActivatableUI
# key: enum.BorgUiKey.Key
- type: SiliconLawBound
- type: ActionGrant
actions:
- ActionViewLaws
- ActionCosmicColossusSunder
- ActionCosmicColossusIngress
- type: SiliconLawProvider
laws: CosmicCultLaws
- type: NoSlip
- type: Puller
needsHands: false
- type: CombatMode
- type: MeleeWeapon
altDisarm: false
soundHit:
path: /Audio/Weapons/Xeno/alien_claw_flesh1.ogg
angle: 0
animation: WeaponArcClaw
animation: WeaponArcCosmic
attackRate: 0.4
damage:
types:
Slash: 12
Piercing: 8
Blunt: 25
Asphyxiation: 5
Cold: 5
Structural: 60
soundHit:
path: /Audio/_DV/CosmicCult/cosmicsword_glance.ogg
params:
variation: 0.2
volume: 1
soundSwing:
path: /Audio/_DV/CosmicCult/cosmicweapon_swing.ogg
params:
variation: 0.125
volume: -4
- type: MeleeThrowOnHit
speed: 8
distance: 7
- type: Reflect
reflectProb: .21
spread: 120
soundOnReflect:
path: /Audio/_DV/CosmicCult/cosmicsword_glance.ogg
params:
variation: 0.2
volume: -6
- type: entity
categories: [ HideSpawnMenu ]
id: MobTileDamageZone
placement:
mode: SnapgridCenter
snap:
- Wall
components:
- type: Transform
anchored: true
- type: EmitSoundOnSpawn
sound:
path: /Audio/_DV/CosmicCult/tile_detonate.ogg
- type: TimedDespawn
lifetime: 8
- type: entity
categories: [ HideSpawnMenu ]
id: MobTileDamageArea
placement:
mode: SnapgridCenter
snap:
- Wall
components:
- type: TimedDespawn
lifetime: 0.6
- type: Transform
anchored: true
- type: Sprite
sprite: _DV/CosmicCult/Effects/tile_attacks.rsi
offset: 0,0.27
layers:
- state: tiledamage_start
shader: unshaded
- type: Tag
tags:
- HideContextMenu
- type: SpawnOnDespawn
prototype: MobTileDamageIssuer
- type: entity
categories: [ HideSpawnMenu ]
id: MobTileDamageIssuer
placement:
mode: SnapgridCenter
snap:
- Wall
components:
- type: Sprite
sprite: _DV/CosmicCult/Effects/tile_attacks.rsi
offset: 0,0.27
layers:
- state: tiledamage_end
shader: unshaded
- type: Transform
anchored: true
- type: TimedDespawn
lifetime: 1
- type: Physics
bodyType: Static
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb
bounds: "-0.5,-0.5,0.5,0.5"
layer:
- SlipLayer
mask:
- ItemMask
density: 2500
hard: false
- type: StepTrigger
requiredTriggeredSpeed: 0
intersectRatio: 0.1
ignoreWeightless: true
blacklist:
components:
- CosmicCult
tags:
- Catwalk
- type: TileEntityEffect
effects:
- !type:HealthChange
damage:
types:
Cold: 10

View File

@ -16,6 +16,7 @@
# spawn animation, spawns actual god when it ends
- type: entity
categories: [ HideSpawnMenu ]
parent: MobCosmicGodBase
id: MobCosmicGodSpawn
suffix: Spawn
@ -49,6 +50,7 @@
enabled: true
- type: entity
categories: [ HideSpawnMenu ]
parent: [MobCosmicGodBase, BaseMob]
id: MobCosmicGod
components:

View File

@ -5,7 +5,7 @@
parent: BaseStructure
id: CosmicBorgChantry
name: Vacuous Chantry
description: Lorem Ipsum
description: Its surface churns with rampant malign light.
placement:
mode: AlignTileAny
components:
@ -86,8 +86,8 @@
thresholds:
- trigger:
!type:DamageTrigger
damage: 100
behaviors: #excess damage, don't spawn entities.
damage: 400
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- !type:PlaySoundBehavior

View File

@ -139,10 +139,7 @@
tags:
- Entropy
- HideContextMenu
- type: PointLight
radius: 4.25
energy: 1.75
castShadows: false
- type: TileEmission
color: "#42a4ae"
- type: entity

View File

@ -5,9 +5,9 @@
showTo:
components:
- CosmicCult
- CosmicColossus
- CosmicAstralBody
- ShowAntagIcons
- RogueAscended
icon:
sprite: /Textures/_DV/CosmicCult/Icons/antag_icons.rsi
state: CosmicCult
@ -19,9 +19,9 @@
showTo:
components:
- CosmicCult
- CosmicColossus
- CosmicAstralBody
- ShowAntagIcons
- RogueAscended
icon:
sprite: /Textures/_DV/CosmicCult/Icons/antag_icons.rsi
state: CosmicCultLead

View File

@ -1,8 +1,9 @@
- type: weightedRandom
id: SecretDeltaV
weights:
Survival: 0.33
Nukeops: 0.12
Zombie: 0.05
Traitor: 0.50
Survival: 0.30
Nukeops: 0.10
Zombie: 0.04
Traitor: 0.38
CosmicCult: 0.18 # my cult so cosmic!
#Pirates: 0.15 #ahoy me bucko

View File

@ -44,6 +44,7 @@
- Revolutionary
- Zombie
- Wizard
- CosmicCult # DeltaV
- KesslerSyndromeScheduler
- RampingStationEventScheduler
- SpaceTrafficControlEventScheduler

View File

@ -90,8 +90,8 @@ On Delta-V, there are some restrictions on when certain alert levels can be used
## Code Octarine
[color=#cae8e8]Emergency alert status. The station's deep-spectrum sensors have identified critical Λ-CDM levels. The station and all surrounding space is under threat of an impending existential noospheric-to-real threat.[/color]
- [color=#a4885c]COC[/color]: CO, Mystagogue, Security Personnel, Department Heads, Supervisory Roles
- [color=#a4885c]Armory Policy[/color]: Issuing of lethal weapons recommended. Body armour and helmets mandatory for Security personnel, permitted for distribution to authorised personnel. EVA protection strongly advised for all personnel.
- [color=#a4885c]Discipline[/color]: Emergency personnel must expend all efforts to prevent station destruction. Arrests, searches, and raids may be performed at the discretion of security personnel and without a warrant. Where possible, threats should be subdued and brought to the Chaplain or Mystagogue for processing. Threats neutralised by lethal force may be placed in Preservative Stasis until the station alert level is reduced.
- [color=#a4885c]Armory Policy[/color]: Issuing of nonlethal crowd control gear mandatory, lethal weapons permitted for self-defense. Body armour and helmets mandatory for Security personnel, permitted for distribution to authorised personnel. EVA protection strongly advised for all personnel.
- [color=#a4885c]Discipline[/color]: Emergency personnel must expend all efforts to prevent station destruction. Arrests, searches, and raids may be performed at the discretion of security personnel and without a warrant. Where possible, threats should be subdued nonlethally and brought to the Chaplain or Mystagogue for processing. Threats neutralised by lethal force may be placed in Preservative Stasis until the station alert level is reduced.
- [color=#a4885c]Secure Areas[/color]: All secure areas and HSAs should remain locked.
- [color=#a4885c]Medical[/color]: Full suit sensors heavily advised. EVA suits and functioning internals heavily advised for emergency responders.
- [color=#a4885c]Engineering[/color]: EVA suits heavily advised for engineers. Distribute emergency internals to crew.

View File

@ -70,7 +70,29 @@
Cultists may stealthily [color=#4cabb3]absorb[/color] a Malign Rift by interacting with it.
Successful absorbtion of a Malign Rift will [bold]permanently[/bold] empower the cultist doing so, increasing the strength of all the [color=#4cabb3]Influences[/color] they possess, and doubling the [color=#4cabb3]Entropy[/color] they gain from siphoning crewmembers. Empowered cultists also no longer need to breathe, and are immune to the vaccuum of space.
Successful absorbtion of a Malign Rift will [bold]permanently[/bold] empower the cultist doing so, increasing the strength of all the [color=#4cabb3]Influences[/color] they possess, and doubling the [color=#4cabb3]Entropy[/color] they gain from siphoning crewmembers. Empowered cultists also no longer need to breathe, and are immune to the vaccuum of space. Empowered cultists also gain the [color=#4cabb3]Null Fragmentation[/color] influence, which can be used to convert a Cyborg into an [color=#4cabb3]Entropic Colossus[/color], or to corrupt the station AI's laws.
Malign Rifts can be purged by interacting with them using a bible.
## Vacuous Chantries
<Box>
<GuideEntityEmbed Entity="CosmicBorgChantry" Caption=""/>
<GuideEntityEmbed Entity="BorgChassisGeneric" Caption=""/>
<GuideEntityEmbed Entity="MobCosmicColossus" Caption=""/>
</Box>
While empowered, one of the ways cultists can choose to expend their empowerment is by using [color=#4cabb3]Null Fragmentation[/color] on a [bold]Cyborg[/bold]. Doing so will trap them inside a [color=#4cabb3]Vacuous Chantry[/color]! This will trigger a stationwide alert, and begin the process of transfiguring the unfortunate victim into an [color=#4cabb3]Entropic Colossus[/color].
Be prepared to defend the chantry - or use it as a distraction to draw the crew's attention! The crew must use weapons to destroy the chantry in order to free the trapped Cyborg within.
If successfully unleashed, an Entropic Colossus will be a force to be reckoned with.
## Malign Law
<Box>
<GuideEntityEmbed Entity="StationAiUploadComputer" Caption=""/>
<GuideEntityEmbed Entity="CosmicCultLawBoard" Caption=""/>
<GuideEntityEmbed Entity="PlayerStationAi" Caption=""/>
</Box>
While empowered, one of the ways cultists can choose to expend their empowerment is by using [color=#4cabb3]Null Fragmentation[/color] on the [bold]AI Upload Console[/bold]. Provided there is a Station AI active, this will forcibly overwrite their laws with a corrupt set of guidelines, aligning them with the Cosmic Cult, in addition to granting them access to the Astral Murmur channel.
If a different lawboard was installed, this process will forcibly eject the previous lawboard from the AI Upload Console, regardless of wether or not the console was locked. Be warned; the crew will still be able to restore the Station AI's functionality by installing a safe, crew-aligned lawboard.
</Document>

View File

@ -13,11 +13,14 @@
## Starting Influences
- [color=#4cabb3][bold]Siphon Entropy:[/bold][/color] Silently siphon entropy from your target, dealing some damage in the process.
- [color=#4cabb3][bold]Null Glare:[/bold][/color] Emit a horrific pulse of cosmic light, slowing and disorienting everyone around you.
- [color=#4cabb3][bold]Shunt Subjectivity:[/bold][/color] Shunt your target's mind out of their body and unto the cosmic dark, temporarily rendering their body mindless.
## Special Influences
- [color=#4cabb3][bold]Null Fragmentation:[/bold][/color] Transfer malign empowerment into a digital system, such as an AI Upload Console or Cyborg, corrupting it in the process. Doing so will expend empowerment.
## Unlockable Active Influences
- [color=#4cabb3][bold]Abberant Lapse:[/bold][/color] Lapse your target's corporeal form, temporarily rendering it immutable, impassible, and frozen in place.
- [color=#4cabb3][bold]Shunt Subjectivity:[/bold][/color] Shunt your target's mind out of their body and unto the cosmic dark, temporarily rendering their body mindless.
- [color=#4cabb3][bold]Null Glare:[/bold][/color] Emit a horrific pulse of cosmic light, slowing and disorienting everyone around you. Its effects are amplified against silicon-based entities.
- [color=#4cabb3][bold]Force Ingress:[/bold][/color] Use a concentrated blast of power to force a secure doorway open.
- [color=#4cabb3][bold]Astral Nova:[/bold][/color] Hurl a large and disruptive blast of astral energy.
- [color=#4cabb3][bold]Vacuous Imposition:[/bold][/color] You negate any incoming damage for a short time.

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,47 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "A custom item by AftrLite(Github)",
"size": {
"x": 96,
"y": 96
},
"states": [
{
"name": "attack1",
"delays": [
[
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
99
]
]
}
]
}

View File

@ -0,0 +1,57 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "A custom item by AftrLite(Github)",
"size": {
"x": 32,
"y": 48
},
"states": [
{
"name": "tiledamage_start",
"delays": [
[
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
99
]
]
},
{
"name": "tiledamage_end",
"delays": [
[
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
0.05,
99
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -157,6 +157,12 @@
0.075
]
]
},
{
"name": "dead"
},
{
"name": "attacking"
}
]
}