Cult update (#220)
* - tweak: Cult door not bump openable. * - tweak: Better summoning and Narsie * - tweak: Construct update. * - tweak: Eldrich blade fits in suit storage. * - tweak: More spell limit. * - fix: Fix pylon desc. * - tweak: Teleport works on cuffed targets. * - tweak: More popups if target is holy. * - fix: No rune drawing using fingers. * - tweak: Better pylon placement & less pylon healing range. * - tweak: More blood rites charge. * - fix: Fix max spell amount. * - tweak: Less cult door and wall health. * - fix: Constructs are dead IC. * - add: Revive rune now notifies player. * - add: Narsie summon rune eui. * - fix: Fix narsie summon sound not playing for reapers. * - tweak: Whatever. * - add: Conceal presence spell. * - tweak: Tweakz. * - add: Blood spear. * - add: Blood boil barrage. * - tweak: Artificer flies. * - tweak: Blood bolt color tweaks. * - tweak: Runic door is bump openable again. * - fix: Fix concealed door outline. * - add: Update concealable name and desc. * - tweak: Remove the unremoveable. * - tweak: Gift ignore. * - add: Organs regenerate on rejuvenate. * - tweak: Brainless cultist is fine. * - add: Added more fun. * - add: Add rune descriptions. * - fix: Fixes. * - tweak: Blood rites now uses verb. * - tweak: Bring it back.
This commit is contained in:
@@ -62,13 +62,14 @@ public sealed partial class CultRuleComponent : Component
|
||||
|
||||
public List<ConstructComponent> Constructs = new();
|
||||
|
||||
public CultWinCondition WinCondition;
|
||||
public CultWinCondition WinCondition = CultWinCondition.CultDraw;
|
||||
}
|
||||
|
||||
public enum CultWinCondition : byte
|
||||
{
|
||||
CultDraw,
|
||||
CultWin,
|
||||
CultFailure
|
||||
CultFailure,
|
||||
}
|
||||
|
||||
public sealed class CultNarsieSummoned : EntityEventArgs
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System.Linq;
|
||||
using Content.Server._Miracle.Components;
|
||||
using Content.Server._Miracle.GulagSystem;
|
||||
using Content.Server.Actions;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.NPC.Systems;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.Roles.Jobs;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Storage.EntitySystems;
|
||||
using Content.Shared.Body.Systems;
|
||||
using Content.Shared.Humanoid;
|
||||
@@ -25,6 +26,7 @@ using Robust.Shared.Random;
|
||||
using Content.Shared._White;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared.Mind;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
|
||||
@@ -47,6 +49,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||
[Dependency] private readonly GulagSystem _gulag = default!;
|
||||
[Dependency] private readonly BloodSpearSystem _bloodSpear = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
|
||||
@@ -69,6 +72,13 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
SubscribeLocalEvent<CultistComponent, ComponentInit>(OnCultistComponentInit);
|
||||
SubscribeLocalEvent<CultistComponent, ComponentRemove>(OnCultistComponentRemoved);
|
||||
SubscribeLocalEvent<CultistComponent, MobStateChangedEvent>(OnCultistsStateChanged);
|
||||
|
||||
SubscribeLocalEvent<CultistRoleComponent, GetBriefingEvent>(OnGetBriefing);
|
||||
}
|
||||
|
||||
private void OnGetBriefing(Entity<CultistRoleComponent> ent, ref GetBriefingEvent args)
|
||||
{
|
||||
args.Append(Loc.GetString("cult-role-briefing-short"));
|
||||
}
|
||||
|
||||
private void OnCultistsStateChanged(EntityUid uid, CultistComponent component, MobStateChangedEvent ev)
|
||||
@@ -130,7 +140,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
if (!TryComp<MobStateComponent>(owner, out var mobState))
|
||||
continue;
|
||||
|
||||
if (_mobStateSystem.IsAlive(owner, mobState))
|
||||
if (!_mobStateSystem.IsDead(owner, mobState))
|
||||
{
|
||||
aliveCultists++;
|
||||
}
|
||||
@@ -140,7 +150,10 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
return;
|
||||
|
||||
cultistsRule.WinCondition = CultWinCondition.CultFailure;
|
||||
_roundEndSystem.EndRound();
|
||||
|
||||
// Check for all in once gamemode
|
||||
if (!GameTicker.GetActiveGameRules().Where(HasComp<RampingStationEventSchedulerComponent>).Any())
|
||||
_roundEndSystem.EndRound();
|
||||
}
|
||||
|
||||
private void OnCultistComponentInit(EntityUid uid, CultistComponent component, ComponentInit args)
|
||||
@@ -165,6 +178,8 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
}
|
||||
|
||||
UpdateCultistsAppearance(cultistsRule);
|
||||
|
||||
component.OriginalMind = (mindComponent.Mind.Value, Comp<MindComponent>(mindComponent.Mind.Value));
|
||||
}
|
||||
|
||||
private void OnCultistComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args)
|
||||
@@ -177,6 +192,8 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
|
||||
cultistsRule.CurrentCultists.Remove(component);
|
||||
|
||||
_bloodSpear.DetachSpearFromUser((uid, component));
|
||||
|
||||
foreach (var empower in component.SelectedEmpowers)
|
||||
{
|
||||
_actions.RemoveAction(uid, GetEntity(empower));
|
||||
@@ -438,7 +455,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
PrototypeId = cultistRule.CultistRolePrototype
|
||||
};
|
||||
|
||||
_roleSystem.MindAddRole(mindId, cultistComponent);
|
||||
_roleSystem.MindAddRole(mindId, cultistComponent, mind);
|
||||
EnsureComp<CultistComponent>(playerEntity);
|
||||
|
||||
_factionSystem.RemoveFaction(playerEntity, "NanoTrasen", false);
|
||||
@@ -478,19 +495,27 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
|
||||
|
||||
_roundEndSystem.EndRound();
|
||||
|
||||
var query = EntityQueryEnumerator<MobStateComponent, MindContainerComponent, CultistComponent>();
|
||||
var query =
|
||||
EntityQueryEnumerator<MobStateComponent, MindContainerComponent, CultistComponent, TransformComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out _, out var mindContainer, out _))
|
||||
List<Entity<MindContainerComponent, TransformComponent>> cultists = new();
|
||||
|
||||
while (query.MoveNext(out var uid, out _, out var mindContainer, out _, out var transform))
|
||||
{
|
||||
if (!mindContainer.HasMind || mindContainer.Mind is null)
|
||||
cultists.Add((uid, mindContainer, transform));
|
||||
}
|
||||
|
||||
foreach (var ent in cultists)
|
||||
{
|
||||
if (ent.Comp1.Mind is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var reaper = Spawn(CultRuleComponent.ReaperPrototype, Transform(uid).Coordinates);
|
||||
_mindSystem.TransferTo(mindContainer.Mind.Value, reaper);
|
||||
var reaper = Spawn(CultRuleComponent.ReaperPrototype, ent.Comp2.Coordinates);
|
||||
_mindSystem.TransferTo(ent.Comp1.Mind.Value, reaper);
|
||||
|
||||
_bodySystem.GibBody(uid);
|
||||
_bodySystem.GibBody(ent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ using Content.Shared.Popups;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Pylon;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Audio;
|
||||
@@ -40,6 +41,8 @@ public sealed class PylonSystem : EntitySystem
|
||||
[Dependency] private readonly BloodstreamSystem _blood = default!;
|
||||
[Dependency] private readonly TurfSystem _turf = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly PointLightSystem _pointLight = default!;
|
||||
[Dependency] private readonly PhysicsSystem _physics = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -47,6 +50,15 @@ public sealed class PylonSystem : EntitySystem
|
||||
|
||||
SubscribeLocalEvent<SharedPylonComponent, InteractHandEvent>(OnInteract);
|
||||
SubscribeLocalEvent<SharedPylonComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<SharedPylonComponent, ConcealEvent>(OnConceal);
|
||||
}
|
||||
|
||||
private void OnConceal(Entity<SharedPylonComponent> ent, ref ConcealEvent args)
|
||||
{
|
||||
ent.Comp.Activated = !args.Conceal;
|
||||
UpdateAppearance(ent, ent.Comp);
|
||||
_pointLight.SetEnabled(ent, !args.Conceal);
|
||||
_physics.SetCanCollide(ent, !args.Conceal);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, SharedPylonComponent component, ComponentInit args)
|
||||
@@ -172,7 +184,7 @@ public sealed class PylonSystem : EntitySystem
|
||||
if (player.AttachedEntity is not { Valid: true } playerEntity)
|
||||
continue;
|
||||
|
||||
if (!EntityManager.TryGetComponent<CultistComponent>(playerEntity, out _))
|
||||
if (!HasComp<CultistComponent>(playerEntity) && !HasComp<ConstructComponent>(playerEntity))
|
||||
continue;
|
||||
|
||||
if (_mobStateSystem.IsDead(playerEntity))
|
||||
@@ -221,12 +233,7 @@ public sealed class PylonSystem : EntitySystem
|
||||
|
||||
UpdateAppearance(uid, comp);
|
||||
|
||||
if (!TryComp<PointLightComponent>(uid, out var light))
|
||||
return;
|
||||
|
||||
#pragma warning disable RA0002
|
||||
light.Enabled = comp.Activated;
|
||||
#pragma warning restore RA0002
|
||||
_pointLight.SetEnabled(uid, comp.Activated);
|
||||
|
||||
var toggleMsg = Loc.GetString(comp.Activated ? "pylon-toggle-on" : "pylon-toggle-off");
|
||||
_popupSystem.PopupEntity(toggleMsg, uid);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.UserInterface;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._White.Cult;
|
||||
|
||||
@@ -11,5 +12,5 @@ public sealed partial class RuneDrawerProviderComponent : Component
|
||||
public Enum UserInterfaceKey = ListViewSelectorUiKey.Key;
|
||||
|
||||
[DataField("runePrototypes")]
|
||||
public List<string> RunePrototypes = new();
|
||||
public List<EntProtoId> RunePrototypes = new();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Emp;
|
||||
using Content.Server.EUI;
|
||||
using Content.Server._White.Cult.UI;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
@@ -17,12 +19,19 @@ using Content.Shared.Stacks;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared._White.Cult.Actions;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Mindshield.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Player;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
|
||||
@@ -36,6 +45,13 @@ public partial class CultSystem
|
||||
[Dependency] private readonly EuiManager _euiManager = default!;
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly MapSystem _mapSystem = default!;
|
||||
[Dependency] private readonly TileSystem _tile = default!;
|
||||
[Dependency] private readonly BloodSpearSystem _bloodSpear = default!;
|
||||
[Dependency] private readonly PhysicsSystem _physics = default!;
|
||||
|
||||
private const string TileId = "CultFloor";
|
||||
private const string ConcealedTileId = "CultFloorConcealed";
|
||||
|
||||
public void InitializeActions()
|
||||
{
|
||||
@@ -44,8 +60,10 @@ public partial class CultSystem
|
||||
SubscribeLocalEvent<CultistComponent, CultShadowShacklesTargetActionEvent>(OnShadowShackles);
|
||||
SubscribeLocalEvent<CultistComponent, CultElectromagneticPulseInstantActionEvent>(OnElectromagneticPulse);
|
||||
SubscribeLocalEvent<CultistComponent, CultSummonCombatEquipmentTargetActionEvent>(OnSummonCombatEquipment);
|
||||
SubscribeLocalEvent<CultistComponent, CultConcealPresenceWorldActionEvent>(OnConcealPresence);
|
||||
SubscribeLocalEvent<CultistComponent, CultConcealInstantActionEvent>(OnConcealPresence);
|
||||
SubscribeLocalEvent<CultistComponent, CultRevealInstantActionEvent>(OnConcealPresence);
|
||||
SubscribeLocalEvent<CultistComponent, CultBloodRitesInstantActionEvent>(OnBloodRites);
|
||||
SubscribeLocalEvent<CultistComponent, CultBloodSpearRecallInstantActionEvent>(OnBloodSpearRecall);
|
||||
SubscribeLocalEvent<CultistComponent, CultTeleportTargetActionEvent>(OnTeleport);
|
||||
SubscribeLocalEvent<CultistComponent, CultStunTargetActionEvent>(OnStunTarget);
|
||||
SubscribeLocalEvent<CultistComponent, ActionGettingRemovedEvent>(OnActionRemoved);
|
||||
@@ -74,9 +92,15 @@ public partial class CultSystem
|
||||
private void OnStunTarget(EntityUid uid, CultistComponent component, CultStunTargetActionEvent args)
|
||||
{
|
||||
if (args.Target == uid || !TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) ||
|
||||
HasComp<HolyComponent>(args.Target) || !TryComp<StatusEffectsComponent>(args.Target, out var status))
|
||||
!TryComp<StatusEffectsComponent>(args.Target, out var status))
|
||||
return;
|
||||
|
||||
if (HasComp<HolyComponent>(args.Target))
|
||||
{
|
||||
_popupSystem.PopupEntity("Священная сила препятствует магии.", args.Performer, args.Performer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasComp<MindShieldComponent>(args.Target))
|
||||
{
|
||||
_popupSystem.PopupEntity("Он имплантирован чипом защиты разума.", args.Performer, args.Performer);
|
||||
@@ -94,14 +118,23 @@ public partial class CultSystem
|
||||
|
||||
private void OnTeleport(EntityUid uid, CultistComponent component, CultTeleportTargetActionEvent args)
|
||||
{
|
||||
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) || !TryComp<ActorComponent>(uid, out var actor))
|
||||
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) ||
|
||||
!TryComp<ActorComponent>(uid, out var actor))
|
||||
return;
|
||||
|
||||
if (!TryComp<CultistComponent>(args.Target, out _) &&
|
||||
!(TryComp<MobStateComponent>(args.Target, out var mobStateComponent) &&
|
||||
mobStateComponent.CurrentState is not MobState.Alive))
|
||||
if (HasComp<HolyComponent>(args.Target))
|
||||
{
|
||||
_popupSystem.PopupEntity("Цель должна быть культистом или лежать.", args.Performer, args.Performer);
|
||||
_popupSystem.PopupEntity("Священная сила препятствует магии.", args.Performer, args.Performer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasComp<CultistComponent>(args.Target) && !HasComp<ConstructComponent>(args.Target) &&
|
||||
(!TryComp<MobStateComponent>(args.Target, out var mobStateComponent) ||
|
||||
mobStateComponent.CurrentState is MobState.Alive) &&
|
||||
(!TryComp<CuffableComponent>(args.Target, out var cuffable) || cuffable.Container.Count == 0))
|
||||
{
|
||||
_popupSystem.PopupEntity("Цель должна быть культистом, быть связанной или лежать.", args.Performer,
|
||||
args.Performer);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -147,25 +180,28 @@ public partial class CultSystem
|
||||
|
||||
totalBloodAmount += solutionContent.Quantity;
|
||||
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, solutionContent.Quantity / 6f);
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, solutionContent.Quantity / 6f, bloodstreamComponent);
|
||||
_solutionSystem.RemoveReagent((Entity<SolutionComponent>) solution, "Blood", FixedPoint2.MaxValue);
|
||||
|
||||
if (GetMissingBloodValue(bloodstreamComponent) == 0)
|
||||
/*if (GetMissingBloodValue(bloodstreamComponent) == 0)
|
||||
{
|
||||
breakLoop = true;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
if (totalBloodAmount == 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
component.RitesBloodAmount += totalBloodAmount;
|
||||
|
||||
_audio.PlayPvs("/Audio/White/Cult/enter_blood.ogg", uid, AudioParams.Default);
|
||||
_damageableSystem.TryChangeDamage(uid, new DamageSpecifier(bruteDamageGroup, -20));
|
||||
_damageableSystem.TryChangeDamage(uid, new DamageSpecifier(burnDamageGroup, -20));
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString("verb-blood-rites-message", ("blood", component.RitesBloodAmount)), uid,
|
||||
uid);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -174,10 +210,163 @@ public partial class CultSystem
|
||||
return bloodstreamComponent.BloodMaxVolume - bloodstreamComponent.BloodSolution!.Value.Comp.Solution.Volume;
|
||||
}
|
||||
|
||||
private void OnConcealPresence(EntityUid uid, CultistComponent component, CultConcealPresenceWorldActionEvent args)
|
||||
private void OnBloodSpearRecall(Entity<CultistComponent> ent, ref CultBloodSpearRecallInstantActionEvent args)
|
||||
{
|
||||
if (!TryComp<BloodstreamComponent>(args.Performer, out _))
|
||||
if (ent.Comp.BloodSpear == null)
|
||||
{
|
||||
_bloodSpear.DetachSpearFromUser(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
var spear = ent.Comp.BloodSpear.Value;
|
||||
var xform = Transform(spear);
|
||||
var coords = _transform.GetWorldPosition(xform);
|
||||
var userCoords = _transform.GetWorldPosition(ent);
|
||||
var distance = (userCoords - coords).Length();
|
||||
if (distance > 10f)
|
||||
{
|
||||
_popupSystem.PopupEntity("Копьё слишком далеко!", ent, ent);
|
||||
return;
|
||||
}
|
||||
|
||||
TryComp<PhysicsComponent>(spear, out var physics);
|
||||
_physics.SetBodyType(spear, BodyType.Dynamic, body: physics, xform: xform);
|
||||
_transform.AttachToGridOrMap(spear, xform);
|
||||
_transform.SetWorldPosition(xform, userCoords);
|
||||
_handsSystem.TryPickupAnyHand(ent, spear, animate: false);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnConcealPresence(EntityUid uid, CultistComponent component, CultConcealPresenceInstantActionEvent args)
|
||||
{
|
||||
if (!TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) ||
|
||||
!TryComp<TransformComponent>(args.Performer, out var xform))
|
||||
return;
|
||||
|
||||
var conceal = args is CultConcealInstantActionEvent;
|
||||
|
||||
var concealableQuery = GetEntityQuery<ConcealableComponent>();
|
||||
var appearanceQuery = GetEntityQuery<AppearanceComponent>();
|
||||
|
||||
const float radius = 5f;
|
||||
|
||||
var entitiesInRange = _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(xform), radius);
|
||||
|
||||
var success = false;
|
||||
|
||||
// Conceal/Reveal runes and structures
|
||||
foreach (var ent in entitiesInRange)
|
||||
{
|
||||
if (!concealableQuery.TryGetComponent(ent, out var concealable) ||
|
||||
!appearanceQuery.TryGetComponent(ent, out var appearance) ||
|
||||
!EntityManager.MetaQuery.TryGetComponent(ent, out var meta))
|
||||
continue;
|
||||
|
||||
if (concealable.Concealed == conceal)
|
||||
continue;
|
||||
|
||||
_appearanceSystem.SetData(ent, ConcealableAppearance.Concealed, conceal, appearance);
|
||||
|
||||
concealable.Concealed = conceal;
|
||||
|
||||
RaiseLocalEvent(ent, new ConcealEvent(conceal));
|
||||
|
||||
if (concealable.ChangeMeta)
|
||||
{
|
||||
if (conceal)
|
||||
{
|
||||
_metaDataSystem.SetEntityName(ent, concealable.ConcealedName, meta);
|
||||
_metaDataSystem.SetEntityDescription(ent, concealable.ConcealedDesc, meta);
|
||||
}
|
||||
else
|
||||
{
|
||||
_metaDataSystem.SetEntityName(ent, concealable.RevealedName, meta);
|
||||
_metaDataSystem.SetEntityDescription(ent, concealable.RevealedDesc, meta);
|
||||
}
|
||||
}
|
||||
|
||||
Dirty(ent, concealable, meta);
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
var gridUid = xform.GridUid;
|
||||
var pos = xform.Coordinates;
|
||||
|
||||
var cultTileDef = (ContentTileDefinition) _tileDefinition[TileId];
|
||||
var concealedTileDef = (ContentTileDefinition) _tileDefinition[ConcealedTileId];
|
||||
|
||||
// Conceal/Reveal tiles
|
||||
if (TryComp(gridUid, out MapGridComponent? mapGrid))
|
||||
{
|
||||
var tileRefs = _mapSystem.GetLocalTilesIntersecting(gridUid.Value, mapGrid,
|
||||
new Box2(pos.Position + new Vector2(-radius, -radius), pos.Position + new Vector2(radius, radius)));
|
||||
|
||||
foreach (var tile in tileRefs)
|
||||
{
|
||||
var tilePos = _turf.GetTileCenter(tile);
|
||||
|
||||
if (!pos.InRange(EntityManager, _transform, tilePos, radius))
|
||||
continue;
|
||||
|
||||
if (conceal)
|
||||
{
|
||||
if (tile.Tile.TypeId != cultTileDef.TileId)
|
||||
continue;
|
||||
|
||||
_tile.ReplaceTile(tile, concealedTileDef);
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tile.Tile.TypeId != concealedTileDef.TileId)
|
||||
continue;
|
||||
|
||||
_tile.ReplaceTile(tile, cultTileDef);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
_audio.PlayPvs(conceal ? "/Audio/White/Cult/smoke.ogg" : "/Audio/White/Cult/enter_blood.ogg", uid,
|
||||
AudioParams.Default.WithMaxDistance(2f));
|
||||
_bloodstreamSystem.TryModifyBloodLevel(uid, -2, bloodstream, createPuddle: false);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
var spellQuery = GetEntityQuery<ConcealPresenceSpellComponent>();
|
||||
var actionQuery = GetEntityQuery<InstantActionComponent>();
|
||||
|
||||
// Alter spell concealing/revealing state
|
||||
foreach (var empower in component.SelectedEmpowers)
|
||||
{
|
||||
if (empower == null)
|
||||
continue;
|
||||
|
||||
var ent = GetEntity(empower.Value);
|
||||
|
||||
if (!spellQuery.TryGetComponent(ent, out var spell) ||
|
||||
!actionQuery.TryGetComponent(ent, out var action))
|
||||
continue;
|
||||
|
||||
if (conceal)
|
||||
{
|
||||
spell.Revealing = true;
|
||||
action.Icon = spell.RevealIcon;
|
||||
action.Event = spell.RevealEvent;
|
||||
}
|
||||
else
|
||||
{
|
||||
spell.Revealing = false;
|
||||
action.Icon = spell.ConcealIcon;
|
||||
action.Event = spell.ConcealEvent;
|
||||
}
|
||||
|
||||
Dirty(ent, action);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSummonCombatEquipment(
|
||||
@@ -300,7 +489,7 @@ public partial class CultSystem
|
||||
var xform = Transform(args.Performer).Coordinates;
|
||||
var dagger = _entityManager.SpawnEntity(RitualDaggerPrototypeId, xform);
|
||||
|
||||
_bloodstreamSystem.TryModifyBloodLevel(args.Performer, -20, bloodstreamComponent, false);
|
||||
_bloodstreamSystem.TryModifyBloodLevel(args.Performer, -10, bloodstreamComponent, false);
|
||||
_handsSystem.TryPickupAnyHand(args.Performer, dagger);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@ using Content.Server.Hands.Systems;
|
||||
using Content.Server.Weapons.Ranged.Systems;
|
||||
using Content.Server._White.Cult.GameRule;
|
||||
using Content.Server._White.Cult.Runes.Comps;
|
||||
using Content.Server._White.Cult.UI;
|
||||
using Content.Server.Bible.Components;
|
||||
using Content.Server.Chemistry.Components;
|
||||
using Content.Server.Chemistry.Containers.EntitySystems;
|
||||
using Content.Server.Fluids.Components;
|
||||
using Content.Server.Ghost;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
@@ -36,10 +38,13 @@ using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Runes;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Content.Shared.Cuffs;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Mindshield.Components;
|
||||
using Content.Shared.Pulling;
|
||||
using Content.Shared.UserInterface;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Components;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics.Events;
|
||||
@@ -92,7 +97,8 @@ public sealed partial class CultSystem : EntitySystem
|
||||
SubscribeLocalEvent<CultEmpowerComponent, ActivateInWorldEvent>(OnActiveInWorld);
|
||||
|
||||
// UI
|
||||
SubscribeLocalEvent<RuneDrawerProviderComponent, UseInHandEvent>(OnRuneDrawerUseInHand);
|
||||
SubscribeLocalEvent<RuneDrawerProviderComponent, ActivatableUIOpenAttemptEvent>(OnRuneDrawAttempt);
|
||||
SubscribeLocalEvent<RuneDrawerProviderComponent, BeforeActivatableUIOpenEvent>(BeforeRuneDraw);
|
||||
SubscribeLocalEvent<RuneDrawerProviderComponent, ListViewItemSelectedMessage>(OnRuneSelected);
|
||||
SubscribeLocalEvent<CultTeleportRuneProviderComponent, TeleportRunesListWindowItemSelectedMessage>(
|
||||
OnTeleportRuneSelected);
|
||||
@@ -107,6 +113,8 @@ public sealed partial class CultSystem : EntitySystem
|
||||
SubscribeLocalEvent<CultRuneBaseComponent, CultEraseEvent>(OnErase);
|
||||
SubscribeLocalEvent<CultRuneBaseComponent, StartCollideEvent>(HandleCollision);
|
||||
|
||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
||||
|
||||
InitializeBuffSystem();
|
||||
InitializeNarsie();
|
||||
InitializeSoulShard();
|
||||
@@ -134,30 +142,30 @@ public sealed partial class CultSystem : EntitySystem
|
||||
|
||||
private readonly SoundPathSpecifier _magic = new("/Audio/White/Cult/magic.ogg");
|
||||
|
||||
private readonly SoundPathSpecifier _apocRuneStartDrawing = new("/Audio/White/Cult/startdraw.ogg");
|
||||
private readonly SoundPathSpecifier _apocRuneEndDrawing = new("/Audio/White/Cult/finisheddraw.ogg");
|
||||
private readonly SoundPathSpecifier _narsie40Sec = new("/Audio/White/Cult/40sec.ogg");
|
||||
|
||||
private Entity<AudioComponent>? _narsieSummonningAudio = null;
|
||||
|
||||
private void OnRoundRestart(RoundRestartCleanupEvent ev)
|
||||
{
|
||||
CultRuneReviveComponent.ChargesLeft = 3;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rune draw start ----
|
||||
*/
|
||||
|
||||
private void OnRuneDrawerUseInHand(EntityUid uid, RuneDrawerProviderComponent component, UseInHandEvent args)
|
||||
private void OnRuneDrawAttempt(Entity<RuneDrawerProviderComponent> ent, ref ActivatableUIOpenAttemptEvent args)
|
||||
{
|
||||
if (!_ui.TryGetUi(uid, component.UserInterfaceKey, out _))
|
||||
return;
|
||||
|
||||
if (!TryComp<ActorComponent>(args.User, out var actorComponent))
|
||||
return;
|
||||
|
||||
if (!HasComp<CultistComponent>(args.User))
|
||||
return;
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
if (_ui.TryGetUi(uid, ListViewSelectorUiKey.Key, out var bui))
|
||||
{
|
||||
_ui.SetUiState(bui, new ListViewBUIState(component.RunePrototypes, false));
|
||||
_ui.OpenUi(bui, actorComponent.PlayerSession);
|
||||
}
|
||||
private void BeforeRuneDraw(Entity<RuneDrawerProviderComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
if (_ui.TryGetUi(ent, ListViewSelectorUiKey.Key, out var bui))
|
||||
_ui.SetUiState(bui, new ListViewBUIState(ent.Comp.RunePrototypes, true));
|
||||
}
|
||||
|
||||
private void OnRuneSelected(EntityUid uid, RuneDrawerProviderComponent component, ListViewItemSelectedMessage args)
|
||||
@@ -185,16 +193,20 @@ public sealed partial class CultSystem : EntitySystem
|
||||
if (HasComp<CultBuffComponent>(whoCalled))
|
||||
_timeToDraw /= 2;
|
||||
|
||||
if (runePrototype == ApocalypseRunePrototypeId)
|
||||
{
|
||||
_timeToDraw = 120.0f;
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-started-drawing-rune-end"), "CULT", true,
|
||||
_apocRuneStartDrawing, colorOverride: Color.DarkRed);
|
||||
}
|
||||
|
||||
if (!IsAllowedToDraw(whoCalled))
|
||||
return false;
|
||||
|
||||
if (runePrototype == ApocalypseRunePrototypeId)
|
||||
{
|
||||
if (!_mindSystem.TryGetMind(whoCalled, out _, out var mind) ||
|
||||
mind.Session is not { } playerSession)
|
||||
return false;
|
||||
|
||||
_euiManager.OpenEui(new ApocalypseRuneEui(whoCalled, _entityManager), playerSession);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var ev = new CultDrawEvent
|
||||
{
|
||||
Rune = runePrototype
|
||||
@@ -769,7 +781,7 @@ public sealed partial class CultSystem : EntitySystem
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-ritual-started"), "CULT", false,
|
||||
colorOverride: Color.DarkRed);
|
||||
|
||||
_audio.PlayGlobal(_narsie40Sec, Filter.Broadcast(), false, AudioParams.Default.WithLoop(true).WithVolume(0.15f));
|
||||
_narsieSummonningAudio = _audio.PlayGlobal(_narsie40Sec, Filter.Broadcast(), false, AudioParams.Default.WithLoop(true).WithVolume(0.15f));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -778,6 +790,8 @@ public sealed partial class CultSystem : EntitySystem
|
||||
{
|
||||
_doAfterAlreadyStarted = false;
|
||||
|
||||
_audio.Stop(_narsieSummonningAudio?.Owner, _narsieSummonningAudio?.Comp);
|
||||
|
||||
if (args.Cancelled)
|
||||
{
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-ritual-prevented"), "CULT", false,
|
||||
@@ -790,13 +804,13 @@ public sealed partial class CultSystem : EntitySystem
|
||||
if (transform == null)
|
||||
return;
|
||||
|
||||
_entityManager.SpawnEntity(NarsiePrototypeId, transform.Value);
|
||||
|
||||
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-narsie-summoned"), "CULT", true, _apocRuneEndDrawing,
|
||||
colorOverride: Color.DarkRed);
|
||||
|
||||
var ev = new CultNarsieSummoned();
|
||||
RaiseLocalEvent(ev);
|
||||
|
||||
_entityManager.SpawnEntity(NarsiePrototypeId, transform.Value);
|
||||
|
||||
//_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-narsie-summoned"), "CULT", true, _apocRuneEndDrawing,
|
||||
// colorOverride: Color.DarkRed);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -852,6 +866,27 @@ public sealed partial class CultSystem : EntitySystem
|
||||
CultRuneReviveComponent.ChargesLeft--;
|
||||
|
||||
_entityManager.EventBus.RaiseLocalEvent(target, new RejuvenateEvent());
|
||||
|
||||
EntityUid? transferTo = null;
|
||||
|
||||
if (!_mindSystem.TryGetMind(target, out var mindId, out var mind))
|
||||
{
|
||||
if (!TryComp<CultistComponent>(target, out var cultist) || cultist.OriginalMind == null)
|
||||
return true;
|
||||
|
||||
(mindId, mind) = cultist.OriginalMind.Value;
|
||||
|
||||
transferTo = target;
|
||||
}
|
||||
|
||||
if (mind.Session is not { } playerSession)
|
||||
return true;
|
||||
|
||||
// notify them they're being revived.
|
||||
if (mind.CurrentEntity != target)
|
||||
{
|
||||
_euiManager.OpenEui(new ReturnToBodyEui(mind, _mindSystem, mindId, transferTo), playerSession);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1258,6 +1293,8 @@ public sealed partial class CultSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
var damage = 10;
|
||||
|
||||
if (rune == ApocalypseRunePrototypeId)
|
||||
{
|
||||
if (!_entityManager.TryGetComponent(uid, out TransformComponent? transComp))
|
||||
@@ -1265,6 +1302,7 @@ public sealed partial class CultSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
damage = 40;
|
||||
var pos = transComp.MapPosition;
|
||||
var x = (int) pos.X;
|
||||
var y = (int) pos.Y;
|
||||
@@ -1273,7 +1311,7 @@ public sealed partial class CultSystem : EntitySystem
|
||||
"CULT", true, _apocRuneEndDrawing, colorOverride: Color.DarkRed);
|
||||
}
|
||||
|
||||
var damageSpecifier = new DamageSpecifier(_prototypeManager.Index<DamageTypePrototype>("Slash"), 10);
|
||||
var damageSpecifier = new DamageSpecifier(_prototypeManager.Index<DamageTypePrototype>("Slash"), damage);
|
||||
_damageableSystem.TryChangeDamage(uid, damageSpecifier, true, false);
|
||||
|
||||
_xform.AttachToGridOrMap(_entityManager.SpawnEntity(rune, transform.Value));
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Linq;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Player;
|
||||
@@ -16,6 +17,7 @@ public sealed partial class CultSystem
|
||||
SubscribeLocalEvent<CultistComponent, CultEmpowerSelectedBuiMessage>(OnCultistEmpowerSelected);
|
||||
SubscribeLocalEvent<CultistComponent, CultEmpowerRemoveBuiMessage>(OnCultistEmpowerRemove);
|
||||
SubscribeLocalEvent<CultistComponent, SpellCreatedEvent>(OnSpellCreated);
|
||||
SubscribeLocalEvent<CultistComponent, CultistFactoryItemSelectedMessage>(OnBloodRitesSelected);
|
||||
}
|
||||
|
||||
private void OnCultistEmpowerRemove(Entity<CultistComponent> ent, ref CultEmpowerRemoveBuiMessage args)
|
||||
@@ -28,7 +30,7 @@ public sealed partial class CultSystem
|
||||
|
||||
private void OnSpellCreated(EntityUid ent, CultistComponent comp, SpellCreatedEvent args)
|
||||
{
|
||||
if (args.Cancelled || comp.SelectedEmpowers.Count >= 1)
|
||||
if (args.Cancelled || comp.SelectedEmpowers.Count >= 2)
|
||||
return;
|
||||
|
||||
var action = CultistComponent.CultistActions.FirstOrDefault(x => x.Equals(args.Spell));
|
||||
@@ -55,7 +57,7 @@ public sealed partial class CultSystem
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
if (comp.SelectedEmpowers.Count >= 1)
|
||||
if (comp.SelectedEmpowers.Count >= 2)
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("verb-spell-create-too-much"), ent, ent);
|
||||
return;
|
||||
@@ -98,8 +100,24 @@ public sealed partial class CultSystem
|
||||
}
|
||||
};
|
||||
|
||||
var bloodRitesVerb = new Verb
|
||||
{
|
||||
Text = Loc.GetString("verb-blood-rites-text"),
|
||||
Message = Loc.GetString("verb-blood-rites-message", ("blood", ent.Comp.RitesBloodAmount)),
|
||||
Category = VerbCategory.Cult,
|
||||
Act = () =>
|
||||
{
|
||||
if (!_ui.TryGetUi(ent, BloodRitesUi.Key, out var bui))
|
||||
return;
|
||||
|
||||
_ui.SetUiState(bui, new CultistFactoryBUIState(ent.Comp.BloodRites));
|
||||
_ui.OpenUi(bui, actor.PlayerSession);
|
||||
}
|
||||
};
|
||||
|
||||
args.Verbs.Add(createSpellVerb);
|
||||
args.Verbs.Add(removeSpellVerb);
|
||||
args.Verbs.Add(bloodRitesVerb);
|
||||
}
|
||||
|
||||
private void RemoveSpell(Entity<CultistComponent> ent, ICommonSession session)
|
||||
@@ -112,4 +130,36 @@ public sealed partial class CultSystem
|
||||
|
||||
_ui.TryOpen(ent, CultEmpowerRemoveUiKey.Key, session);
|
||||
}
|
||||
|
||||
private void OnBloodRitesSelected(Entity<CultistComponent> ent, ref CultistFactoryItemSelectedMessage args)
|
||||
{
|
||||
if (!_prototypeManager.TryIndex<CultistFactoryProductionPrototype>(args.Item, out var prototype))
|
||||
return;
|
||||
|
||||
if (ent.Comp.RitesBloodAmount < prototype.BloodCost)
|
||||
{
|
||||
var message = Loc.GetString("verb-blood-rites-no-blood", ("required", prototype.BloodCost),
|
||||
("blood", ent.Comp.RitesBloodAmount));
|
||||
_popupSystem.PopupEntity(message, ent, ent);
|
||||
return;
|
||||
}
|
||||
|
||||
var success = false;
|
||||
foreach (var item in prototype.Item)
|
||||
{
|
||||
var entity = Spawn(item, Transform(ent).Coordinates);
|
||||
if (_handsSystem.TryPickupAnyHand(ent, entity))
|
||||
{
|
||||
success = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString("verb-blood-rites-no-hand"), ent, ent);
|
||||
QueueDel(entity);
|
||||
break;
|
||||
}
|
||||
|
||||
if (success)
|
||||
ent.Comp.RitesBloodAmount -= prototype.BloodCost;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Server.Cuffs;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Shared._White.Chaplain;
|
||||
using Content.Shared.Doors;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Components;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Weapons.Melee.Components;
|
||||
using Content.Shared.Weapons.Melee.Events;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
|
||||
|
||||
@@ -19,6 +25,9 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly OccluderSystem _occluder = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly CuffableSystem _cuffable = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -27,6 +36,31 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
|
||||
SubscribeLocalEvent<RunicDoorComponent, BeforeDoorClosedEvent>(OnBeforeDoorClosed);
|
||||
SubscribeLocalEvent<RunicDoorComponent, AttackedEvent>(OnGetAttacked);
|
||||
SubscribeLocalEvent<RunicDoorComponent, ConcealEvent>(OnConceal);
|
||||
}
|
||||
|
||||
private void OnConceal(Entity<RunicDoorComponent> ent, ref ConcealEvent args)
|
||||
{
|
||||
if (!TryComp(ent, out MetaDataComponent? meta))
|
||||
return;
|
||||
|
||||
if (TryComp(ent, out PhysicsComponent? physics))
|
||||
_occluder.SetEnabled(ent, args.Conceal && physics.CanCollide, meta: meta);
|
||||
|
||||
if (TryComp(ent, out DoorComponent? door))
|
||||
{
|
||||
door.Occludes = args.Conceal;
|
||||
Dirty(ent, door, meta);
|
||||
}
|
||||
|
||||
if (!TryComp(ent, out MeleeSoundComponent? meleeSound) || meleeSound.SoundGroups == null)
|
||||
return;
|
||||
|
||||
meleeSound.SoundGroups["Brute"] = args.Conceal
|
||||
? new SoundPathSpecifier("/Audio/Weapons/smash.ogg")
|
||||
: new SoundCollectionSpecifier("GlassSmash");
|
||||
|
||||
Dirty(ent, meleeSound, meta);
|
||||
}
|
||||
|
||||
private void OnGetAttacked(Entity<RunicDoorComponent> ent, ref AttackedEvent args)
|
||||
@@ -79,7 +113,8 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
|
||||
_doorSystem.Deny(airlock);
|
||||
|
||||
if (!HasComp<HumanoidAppearanceComponent>(user) || HasComp<HolyComponent>(user))
|
||||
if (!HasComp<HumanoidAppearanceComponent>(user) || HasComp<HolyComponent>(user) ||
|
||||
TryComp(airlock, out ConcealableComponent? concealable) && concealable.Concealed)
|
||||
return false;
|
||||
|
||||
var direction = Transform(user).MapPosition.Position - Transform(airlock).MapPosition.Position;
|
||||
@@ -90,4 +125,11 @@ public sealed class RunicDoorSystem : EntitySystem
|
||||
_stunSystem.TryParalyze(user, TimeSpan.FromSeconds(3), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanBumpOpen(EntityUid uid, EntityUid otherUid)
|
||||
{
|
||||
return !HasComp<RunicDoorComponent>(uid) || !HasComp<ConstructComponent>(otherUid) &&
|
||||
(!HasComp<CultistComponent>(otherUid) || !_mobState.IsAlive(otherUid) ||
|
||||
TryComp(otherUid, out CuffableComponent? cuffable) && _cuffable.GetAllCuffs(cuffable).Count > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Shared.Interaction;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared._White.Cult;
|
||||
using Content.Shared._White.Cult.Structures;
|
||||
using Content.Shared._White.Cult.Systems;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -28,6 +29,7 @@ public sealed class CultistFactorySystem : EntitySystem
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly PhysicsSystem _physics = default!;
|
||||
|
||||
private const string RitualDaggerPrototypeId = "RitualDagger";
|
||||
|
||||
@@ -42,6 +44,12 @@ public sealed class CultistFactorySystem : EntitySystem
|
||||
SubscribeLocalEvent<CultistFactoryComponent, InteractUsingEvent>(TryToggleAnchor);
|
||||
SubscribeLocalEvent<CultistFactoryComponent, CultAnchorDoAfterEvent>(OnAnchorDoAfter);
|
||||
SubscribeLocalEvent<CultistFactoryComponent, ExaminedEvent>(OnExamine);
|
||||
SubscribeLocalEvent<CultistFactoryComponent, ConcealEvent>(OnConceal);
|
||||
}
|
||||
|
||||
private void OnConceal(Entity<CultistFactoryComponent> ent, ref ConcealEvent args)
|
||||
{
|
||||
_physics.SetCanCollide(ent, !args.Conceal);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
||||
61
Content.Server/_White/Cult/UI/ApocalypseRuneEui.cs
Normal file
61
Content.Server/_White/Cult/UI/ApocalypseRuneEui.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.EUI;
|
||||
using Content.Shared._White.Cult.Runes;
|
||||
using Content.Shared._White.Cult.UI;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Eui;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server._White.Cult.UI;
|
||||
|
||||
public sealed class ApocalypseRuneEui : BaseEui
|
||||
{
|
||||
private readonly SoundPathSpecifier _apocRuneStartDrawing = new("/Audio/White/Cult/startdraw.ogg");
|
||||
private const string ApocalypseRunePrototypeId = "ApocalypseRune";
|
||||
|
||||
private readonly EntityUid _whoCalled;
|
||||
private readonly IEntityManager _entityManager;
|
||||
|
||||
public ApocalypseRuneEui(EntityUid whoCalled, IEntityManager entityManager)
|
||||
{
|
||||
_whoCalled = whoCalled;
|
||||
_entityManager = entityManager;
|
||||
}
|
||||
|
||||
public override void HandleMessage(EuiMessageBase msg)
|
||||
{
|
||||
base.HandleMessage(msg);
|
||||
|
||||
if (msg is not ApocalypseRuneDrawMessage {Accepted: true})
|
||||
{
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
var ev = new CultDrawEvent
|
||||
{
|
||||
Rune = ApocalypseRunePrototypeId
|
||||
};
|
||||
|
||||
var argsDoAfterEvent = new DoAfterArgs(_entityManager, _whoCalled, 120f, ev, _whoCalled)
|
||||
{
|
||||
BreakOnUserMove = true,
|
||||
NeedHand = true
|
||||
};
|
||||
|
||||
if (!_entityManager.System<DoAfterSystem>().TryStartDoAfter(argsDoAfterEvent))
|
||||
{
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
_entityManager.System<ChatSystem>().DispatchGlobalAnnouncement(Loc.GetString("cult-started-drawing-rune-end"),
|
||||
"CULT", true, _apocRuneStartDrawing, colorOverride: Color.DarkRed);
|
||||
|
||||
_entityManager.System<AudioSystem>().PlayPvs("/Audio/White/Cult/butcher.ogg", _whoCalled,
|
||||
AudioParams.Default.WithMaxDistance(2f));
|
||||
Close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user