diff --git a/Content.Client/_White/Cult/Concealable/ConcealableVisualizer.cs b/Content.Client/_White/Cult/Concealable/ConcealableVisualizer.cs new file mode 100644 index 0000000000..fd5283af1e --- /dev/null +++ b/Content.Client/_White/Cult/Concealable/ConcealableVisualizer.cs @@ -0,0 +1,67 @@ +using System.Linq; +using Content.Client.IconSmoothing; +using Content.Client.Interactable.Components; +using Content.Shared._White.Cult.Components; +using Robust.Client.GameObjects; + +namespace Content.Client._White.Cult.Concealable; + +public sealed class ConcealableVisualizer : VisualizerSystem +{ + [Dependency] private readonly IconSmoothSystem _smooth = default!; + + protected override void OnAppearanceChange(EntityUid uid, ConcealableComponent component, ref AppearanceChangeEvent args) + { + base.OnAppearanceChange(uid, component, ref args); + + if (args.Sprite == null) + return; + + if (!AppearanceSystem.TryGetData(uid, ConcealableAppearance.Concealed, out var concealed, args.Component)) + return; + + if (component.IconSmooth) + _smooth.SetEnabled(uid, concealed); + + if (component.InteractionOutline) + { + if (concealed) + { + if (TryComp(uid, out InteractionOutlineComponent? outline)) + { + outline.OnMouseLeave(uid); + RemComp(uid); + } + } + else + EnsureComp(uid); + } + + if (concealed) + { + if (component.ConcealedSprite != null) + { + for (var i = 0; i < args.Sprite.AllLayers.Count(); i++) + { + args.Sprite.LayerSetRSI(i, component.ConcealedSprite.Value); + } + return; + } + + args.Sprite.Color = args.Sprite.Color.WithAlpha(0f); + } + else + { + if (component.RevealedSprite != null) + { + for (var i = 0; i < args.Sprite.AllLayers.Count(); i++) + { + args.Sprite.LayerSetRSI(i, component.RevealedSprite.Value); + } + return; + } + + args.Sprite.Color = args.Sprite.Color.WithAlpha(1f); + } + } +} diff --git a/Content.Client/_White/Cult/ShowCultHudSystem.cs b/Content.Client/_White/Cult/ShowCultHudSystem.cs index c5faa8f274..6c845f468d 100644 --- a/Content.Client/_White/Cult/ShowCultHudSystem.cs +++ b/Content.Client/_White/Cult/ShowCultHudSystem.cs @@ -1,4 +1,5 @@ using Content.Shared._White.Cult; +using Content.Shared._White.Cult.Components; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Player; @@ -20,10 +21,15 @@ public sealed class ShowCultHudSystem : EntitySystem SubscribeLocalEvent(OnPlayerAttached); SubscribeLocalEvent(OnPlayerDetached); + SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnComponentRemoved); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); + _overlay = new CultHudOverlay(EntityManager); } - private void OnComponentInit(EntityUid uid, CultistComponent component, ComponentInit args) + private void OnComponentInit(EntityUid uid, ShowCultHudComponent component, ComponentInit args) { if (_player.LocalSession?.AttachedEntity != uid) return; @@ -32,7 +38,7 @@ public sealed class ShowCultHudSystem : EntitySystem } - private void OnComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args) + private void OnComponentRemoved(EntityUid uid, ShowCultHudComponent component, ComponentRemove args) { if (_player.LocalSession?.AttachedEntity != uid) return; @@ -41,7 +47,7 @@ public sealed class ShowCultHudSystem : EntitySystem } - private void OnPlayerAttached(EntityUid uid, CultistComponent component, PlayerAttachedEvent args) + private void OnPlayerAttached(EntityUid uid, ShowCultHudComponent component, PlayerAttachedEvent args) { if (_player.LocalSession != args.Player) return; @@ -49,7 +55,7 @@ public sealed class ShowCultHudSystem : EntitySystem _overlayManager.AddOverlay(_overlay); } - private void OnPlayerDetached(EntityUid uid, CultistComponent component, PlayerDetachedEvent args) + private void OnPlayerDetached(EntityUid uid, ShowCultHudComponent component, PlayerDetachedEvent args) { if (_player.LocalSession != args.Player) return; diff --git a/Content.Client/_White/Cult/UI/ApocalypseRuneEui/ApocalypseRuneEui.cs b/Content.Client/_White/Cult/UI/ApocalypseRuneEui/ApocalypseRuneEui.cs new file mode 100644 index 0000000000..81f10759bb --- /dev/null +++ b/Content.Client/_White/Cult/UI/ApocalypseRuneEui/ApocalypseRuneEui.cs @@ -0,0 +1,45 @@ +using Content.Client.Eui; +using Content.Client.Ghost.UI; +using Content.Shared._White.Cult.UI; +using JetBrains.Annotations; +using Robust.Client.Graphics; + +namespace Content.Client._White.Cult.UI.ApocalypseRuneEui; + +[UsedImplicitly] +public sealed class ApocalypseRuneEui : BaseEui +{ + private readonly ApocalypseRuneMenu _menu; + + public ApocalypseRuneEui() + { + _menu = new ApocalypseRuneMenu(); + + _menu.DenyButton.OnPressed += _ => + { + SendMessage(new ApocalypseRuneDrawMessage(false)); + _menu.Close(); + }; + + _menu.AcceptButton.OnPressed += _ => + { + SendMessage(new ApocalypseRuneDrawMessage(true)); + _menu.Close(); + }; + } + + public override void Opened() + { + IoCManager.Resolve().RequestWindowAttention(); + _menu.OpenCentered(); + } + + public override void Closed() + { + base.Closed(); + + SendMessage(new ApocalypseRuneDrawMessage(false)); + _menu.Close(); + } + +} diff --git a/Content.Client/_White/Cult/UI/ApocalypseRuneEui/ApocalypseRuneMenu.cs b/Content.Client/_White/Cult/UI/ApocalypseRuneEui/ApocalypseRuneMenu.cs new file mode 100644 index 0000000000..57ad078780 --- /dev/null +++ b/Content.Client/_White/Cult/UI/ApocalypseRuneEui/ApocalypseRuneMenu.cs @@ -0,0 +1,60 @@ +using System.Numerics; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using static Robust.Client.UserInterface.Controls.BoxContainer; + +namespace Content.Client.Ghost.UI; + +public sealed class ApocalypseRuneMenu : DefaultWindow +{ + public readonly Button DenyButton; + public readonly Button AcceptButton; + + public ApocalypseRuneMenu() + { + Title = Loc.GetString("apocalypse-rune-title"); + + Contents.AddChild(new BoxContainer + { + Orientation = LayoutOrientation.Vertical, + Children = + { + new BoxContainer + { + Orientation = LayoutOrientation.Vertical, + Children = + { + (new Label() + { + Text = Loc.GetString("apocalypse-rune-text") + }), + new BoxContainer + { + Orientation = LayoutOrientation.Horizontal, + Align = AlignMode.Center, + Children = + { + (AcceptButton = new Button + { + Text = Loc.GetString("apocalypse-rune-accept-button"), + }), + + (new Control() + { + MinSize = new Vector2(20, 0) + }), + + (DenyButton = new Button + { + Text = Loc.GetString("apocalypse-rune-deny-button"), + }) + } + }, + } + }, + } + }); + } +} + diff --git a/Content.Client/_White/Cult/UI/CultistFactory/CultistFactoryBUI.cs b/Content.Client/_White/Cult/UI/CultistFactory/CultistFactoryBUI.cs index 8f9b0c90b8..74516d4ade 100644 --- a/Content.Client/_White/Cult/UI/CultistFactory/CultistFactoryBUI.cs +++ b/Content.Client/_White/Cult/UI/CultistFactory/CultistFactoryBUI.cs @@ -32,6 +32,8 @@ public sealed class CultistFactoryBUI : BoundUserInterface _radialContainer = new RadialContainer(); + _radialContainer.Closed += Close; + if (State != null) UpdateState(State); } diff --git a/Content.Client/_White/Cult/UI/ListViewSelector/ListViewSelectorWindow.xaml.cs b/Content.Client/_White/Cult/UI/ListViewSelector/ListViewSelectorWindow.xaml.cs index f440a56b7d..15e151b14a 100644 --- a/Content.Client/_White/Cult/UI/ListViewSelector/ListViewSelectorWindow.xaml.cs +++ b/Content.Client/_White/Cult/UI/ListViewSelector/ListViewSelectorWindow.xaml.cs @@ -1,4 +1,5 @@ -using Robust.Client.AutoGenerated; +using Content.Client.Lathe.UI; +using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Client.UserInterface.XAML; @@ -7,19 +8,21 @@ using Robust.Shared.Prototypes; namespace Content.Client._White.Cult.UI.ListViewSelector; [GenerateTypedNameReferences] -public partial class ListViewSelectorWindow : DefaultWindow +public sealed partial class ListViewSelectorWindow : DefaultWindow { public Action? ItemSelected; private readonly IPrototypeManager _prototypeManager; + public string TooltipText = string.Empty; + public ListViewSelectorWindow(IPrototypeManager prototypeManager) { RobustXamlLoader.Load(this); _prototypeManager = prototypeManager; } - public void PopulateList(List items, bool isPrototypes) + public void PopulateList(List items, bool isPrototypes) { ItemsContainer.RemoveAllChildren(); @@ -27,16 +30,16 @@ public partial class ListViewSelectorWindow : DefaultWindow { var button = new Button(); var itemName = Loc.GetString($"ent-{item}"); + var itemDesc = string.Empty; - if (isPrototypes) + if (isPrototypes && _prototypeManager.TryIndex(item, out var itemPrototype)) { - if (_prototypeManager.TryIndex(item, out var itemPrototype)) - { - itemName = itemPrototype.Name; - } + itemName = itemPrototype.Name; + itemDesc = itemPrototype.Description; } button.Text = itemName; + button.TooltipSupplier = _ => new RecipeTooltip(itemDesc); button.OnPressed += _ => ItemSelected?.Invoke(item, items.IndexOf(item)); diff --git a/Content.Client/_White/Cult/UI/StructureRadial/CultPylonPlacementHijack.cs b/Content.Client/_White/Cult/UI/StructureRadial/CultPylonPlacementHijack.cs new file mode 100644 index 0000000000..bf3f349560 --- /dev/null +++ b/Content.Client/_White/Cult/UI/StructureRadial/CultPylonPlacementHijack.cs @@ -0,0 +1,82 @@ +using System.Linq; +using Content.Client.Construction; +using Content.Shared.Construction.Prototypes; +using Content.Shared.Popups; +using Robust.Client.Placement; +using Robust.Client.Utility; +using Robust.Shared.Map; + +namespace Content.Client._White.Cult.UI.StructureRadial; + +public sealed class CultPylonPlacementHijack : PlacementHijack +{ + private readonly ConstructionSystem _constructionSystem; + private readonly IEntityManager _entMan; + private readonly ConstructionPrototype? _prototype; + private readonly EntityUid _player; + + public override bool CanRotate { get; } + + public CultPylonPlacementHijack(ConstructionPrototype? prototype, IEntityManager entMan, EntityUid player) + { + _prototype = prototype; + _entMan = entMan; + _player = player; + _constructionSystem = entMan.System(); + CanRotate = prototype?.CanRotate ?? true; + } + + /// + public override bool HijackPlacementRequest(EntityCoordinates coordinates) + { + if (_prototype == null) + return true; + + if (CheckForStructure(coordinates)) + { + var popup = _entMan.System(); + popup.PopupClient(Loc.GetString("cult-structure-craft-another-structure-nearby"), _player, _player); + return true; + } + + _constructionSystem.ClearAllGhosts(); + var dir = Manager.Direction; + _constructionSystem.SpawnGhost(_prototype, coordinates, dir); + + return true; + } + + private bool CheckForStructure(EntityCoordinates coordinates) + { + var lookupSystem = _entMan.System(); + var entities = lookupSystem.GetEntitiesInRange(coordinates, 10f); + foreach (var ent in entities) + { + if (!_entMan.TryGetComponent(ent, out var metadata)) + continue; + + if (metadata.EntityPrototype?.ID is "CultPylon") + return true; + } + + return false; + } + + /// + public override bool HijackDeletion(EntityUid entity) + { + if (IoCManager.Resolve().HasComponent(entity)) + { + _constructionSystem.ClearGhost(entity.GetHashCode()); + } + + return true; + } + + /// + public override void StartHijack(PlacementManager manager) + { + base.StartHijack(manager); + manager.CurrentTextures = _prototype?.Layers.Select(sprite => sprite.DirFrame0()).ToList(); + } +} diff --git a/Content.Client/_White/Cult/UI/StructureRadial/StructureCraftBoundUserInterface.cs b/Content.Client/_White/Cult/UI/StructureRadial/StructureCraftBoundUserInterface.cs index 78f070b843..d04ff37054 100644 --- a/Content.Client/_White/Cult/UI/StructureRadial/StructureCraftBoundUserInterface.cs +++ b/Content.Client/_White/Cult/UI/StructureRadial/StructureCraftBoundUserInterface.cs @@ -86,43 +86,23 @@ public sealed class StructureCraftBoundUserInterface : BoundUserInterface if (construct == null) return; - var player = _player.LocalPlayer?.ControlledEntity; + var player = _player.LocalEntity; if (player == null) return; - if (construct.ID == "CultPylon" && CheckForStructure(player, id)) - { - var popup = _entMan.System(); - popup.PopupClient(Loc.GetString("cult-structure-craft-another-structure-nearby"), player.Value, player.Value); - return; - } + PlacementHijack hijack; - var constructSystem = _systemManager.GetEntitySystem(); - var hijack = new ConstructionPlacementHijack(constructSystem, construct); + if (construct.ID == "CultPylon") + { + hijack = new CultPylonPlacementHijack(construct, _entMan, player.Value); + } + else + { + var constructSystem = _systemManager.GetEntitySystem(); + hijack = new ConstructionPlacementHijack(constructSystem, construct); + } _placement.BeginPlacing(newObj, hijack); } - - private bool CheckForStructure(EntityUid? uid, string id) - { - if (uid == null) - return false; - - if (!_entMan.TryGetComponent(uid, out var transform)) - return false; - - var lookupSystem = _entMan.System(); - var entities = lookupSystem.GetEntitiesInRange(transform.Coordinates, 15f); - foreach (var ent in entities) - { - if (!_entMan.TryGetComponent(ent, out var metadata)) - continue; - - if (metadata.EntityPrototype?.ID == id) - return true; - } - - return false; - } } diff --git a/Content.Server/Changeling/ChangelingRuleSystem.cs b/Content.Server/Changeling/ChangelingRuleSystem.cs index 32a68b8da2..ff97fe04a1 100644 --- a/Content.Server/Changeling/ChangelingRuleSystem.cs +++ b/Content.Server/Changeling/ChangelingRuleSystem.cs @@ -55,6 +55,13 @@ public sealed class ChangelingRuleSystem : GameRuleSystem(ClearUsedNames); SubscribeLocalEvent(OnObjectivesTextGetInfo); + + SubscribeLocalEvent(OnGetBriefing); + } + + private void OnGetBriefing(Entity ent, ref GetBriefingEvent args) + { + args.Append(Loc.GetString("changeling-role-briefing-short")); } protected override void ActiveTick( @@ -176,13 +183,6 @@ public sealed class ChangelingRuleSystem : GameRuleSystem).Any()) _roundEnd.DoRoundEndBehavior(RoundEndBehavior.ShuttleCall, component.ShuttleCallTime); else diff --git a/Content.Server/Ghost/ReturnToBodyEui.cs b/Content.Server/Ghost/ReturnToBodyEui.cs index 77b143f7df..d600fb9f37 100644 --- a/Content.Server/Ghost/ReturnToBodyEui.cs +++ b/Content.Server/Ghost/ReturnToBodyEui.cs @@ -11,12 +11,26 @@ public sealed class ReturnToBodyEui : BaseEui private readonly MindComponent _mind; + private readonly EntityUid _mindId; + + private readonly EntityUid? _transferTo; + public ReturnToBodyEui(MindComponent mind, SharedMindSystem mindSystem) { _mind = mind; _mindSystem = mindSystem; } + // WD START + public ReturnToBodyEui(MindComponent mind, SharedMindSystem mindSystem, EntityUid mindId, EntityUid? transferTo) + { + _mind = mind; + _mindSystem = mindSystem; + _mindId = mindId; + _transferTo = transferTo; + } + // WD END + public override void HandleMessage(EuiMessageBase msg) { base.HandleMessage(msg); @@ -28,6 +42,9 @@ public sealed class ReturnToBodyEui : BaseEui return; } + if (_transferTo != null) // WD + _mindSystem.TransferTo(_mindId, _transferTo, mind: _mind); + _mindSystem.UnVisit(_mind.Session); Close(); diff --git a/Content.Server/Hands/Systems/HandsSystem.cs b/Content.Server/Hands/Systems/HandsSystem.cs index d59291c362..11e70fcdb0 100644 --- a/Content.Server/Hands/Systems/HandsSystem.cs +++ b/Content.Server/Hands/Systems/HandsSystem.cs @@ -1,9 +1,11 @@ using System.Numerics; using Content.Server._White.Other.ChangeThrowForceSystem; +using Content.Server.Damage.Components; using Content.Server.Inventory; using Content.Server.Pulling; using Content.Server.Stack; using Content.Server.Stunnable; +using Content.Shared._White.Cult.Systems; using Content.Shared._White.MagGloves; using Content.Shared.ActionBlocker; using Content.Shared.Body.Part; @@ -40,6 +42,7 @@ namespace Content.Server.Hands.Systems [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly PullingSystem _pullingSystem = default!; [Dependency] private readonly ThrowingSystem _throwingSystem = default!; + [Dependency] private readonly CultItemSystem _cultItem = default!; public override void Initialize() { @@ -194,6 +197,11 @@ namespace Content.Server.Hands.Systems !_actionBlockerSystem.CanThrow(player, throwEnt)) return false; + // WD EDIT START + if (HasComp(throwEnt) && !_cultItem.CanThrow(player, throwEnt)) + return false; + // WD EDIT END + if (_timing.CurTime < hands.NextThrowTime) return false; hands.NextThrowTime = _timing.CurTime + hands.ThrowCooldown; diff --git a/Content.Server/Holosign/HolosignSystem.cs b/Content.Server/Holosign/HolosignSystem.cs index 33a08c0975..7f0952987f 100644 --- a/Content.Server/Holosign/HolosignSystem.cs +++ b/Content.Server/Holosign/HolosignSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Coordinates.Helpers; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Popups; +using Content.Shared.Storage; namespace Content.Server.Holosign; @@ -59,7 +60,7 @@ public sealed class HolosignSystem : EntitySystem return; } - if (args.Handled || !args.CanReach) + if (args.Handled || !args.CanReach || HasComp(args.Target)) return; if (component.Signs.Count >= component.Uses) // wd edit diff --git a/Content.Server/_White/Cult/GameRule/CultRuleComponent.cs b/Content.Server/_White/Cult/GameRule/CultRuleComponent.cs index 1e1e5a8d89..2c441c7c16 100644 --- a/Content.Server/_White/Cult/GameRule/CultRuleComponent.cs +++ b/Content.Server/_White/Cult/GameRule/CultRuleComponent.cs @@ -62,13 +62,14 @@ public sealed partial class CultRuleComponent : Component public List Constructs = new(); - public CultWinCondition WinCondition; + public CultWinCondition WinCondition = CultWinCondition.CultDraw; } public enum CultWinCondition : byte { + CultDraw, CultWin, - CultFailure + CultFailure, } public sealed class CultNarsieSummoned : EntityEventArgs diff --git a/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs b/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs index 2736fc7f54..5c0618ff9f 100644 --- a/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs +++ b/Content.Server/_White/Cult/GameRule/CultRuleSystem.cs @@ -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 [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 SubscribeLocalEvent(OnCultistComponentInit); SubscribeLocalEvent(OnCultistComponentRemoved); SubscribeLocalEvent(OnCultistsStateChanged); + + SubscribeLocalEvent(OnGetBriefing); + } + + private void OnGetBriefing(Entity 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 if (!TryComp(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 return; cultistsRule.WinCondition = CultWinCondition.CultFailure; - _roundEndSystem.EndRound(); + + // Check for all in once gamemode + if (!GameTicker.GetActiveGameRules().Where(HasComp).Any()) + _roundEndSystem.EndRound(); } private void OnCultistComponentInit(EntityUid uid, CultistComponent component, ComponentInit args) @@ -165,6 +178,8 @@ public sealed class CultRuleSystem : GameRuleSystem } UpdateCultistsAppearance(cultistsRule); + + component.OriginalMind = (mindComponent.Mind.Value, Comp(mindComponent.Mind.Value)); } private void OnCultistComponentRemoved(EntityUid uid, CultistComponent component, ComponentRemove args) @@ -177,6 +192,8 @@ public sealed class CultRuleSystem : GameRuleSystem 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 PrototypeId = cultistRule.CultistRolePrototype }; - _roleSystem.MindAddRole(mindId, cultistComponent); + _roleSystem.MindAddRole(mindId, cultistComponent, mind); EnsureComp(playerEntity); _factionSystem.RemoveFaction(playerEntity, "NanoTrasen", false); @@ -478,19 +495,27 @@ public sealed class CultRuleSystem : GameRuleSystem _roundEndSystem.EndRound(); - var query = EntityQueryEnumerator(); + var query = + EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _, out var mindContainer, out _)) + List> 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); } } diff --git a/Content.Server/_White/Cult/Pylon/PylonSystem.cs b/Content.Server/_White/Cult/Pylon/PylonSystem.cs index dc070a6231..1dc61c8b55 100644 --- a/Content.Server/_White/Cult/Pylon/PylonSystem.cs +++ b/Content.Server/_White/Cult/Pylon/PylonSystem.cs @@ -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(OnInteract); SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnConceal); + } + + private void OnConceal(Entity 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(playerEntity, out _)) + if (!HasComp(playerEntity) && !HasComp(playerEntity)) continue; if (_mobStateSystem.IsDead(playerEntity)) @@ -221,12 +233,7 @@ public sealed class PylonSystem : EntitySystem UpdateAppearance(uid, comp); - if (!TryComp(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); diff --git a/Content.Server/_White/Cult/Runes/Comps/RuneDrawerProviderComponent.cs b/Content.Server/_White/Cult/Runes/Comps/RuneDrawerProviderComponent.cs index 8a03b32ef8..eb143905b3 100644 --- a/Content.Server/_White/Cult/Runes/Comps/RuneDrawerProviderComponent.cs +++ b/Content.Server/_White/Cult/Runes/Comps/RuneDrawerProviderComponent.cs @@ -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 RunePrototypes = new(); + public List RunePrototypes = new(); } diff --git a/Content.Server/_White/Cult/Runes/Systems/CultSystem.Actions.cs b/Content.Server/_White/Cult/Runes/Systems/CultSystem.Actions.cs index 5cddd043be..134af2bfc6 100644 --- a/Content.Server/_White/Cult/Runes/Systems/CultSystem.Actions.cs +++ b/Content.Server/_White/Cult/Runes/Systems/CultSystem.Actions.cs @@ -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(OnShadowShackles); SubscribeLocalEvent(OnElectromagneticPulse); SubscribeLocalEvent(OnSummonCombatEquipment); - SubscribeLocalEvent(OnConcealPresence); + SubscribeLocalEvent(OnConcealPresence); + SubscribeLocalEvent(OnConcealPresence); SubscribeLocalEvent(OnBloodRites); + SubscribeLocalEvent(OnBloodSpearRecall); SubscribeLocalEvent(OnTeleport); SubscribeLocalEvent(OnStunTarget); SubscribeLocalEvent(OnActionRemoved); @@ -74,9 +92,15 @@ public partial class CultSystem private void OnStunTarget(EntityUid uid, CultistComponent component, CultStunTargetActionEvent args) { if (args.Target == uid || !TryComp(args.Performer, out var bloodstream) || - HasComp(args.Target) || !TryComp(args.Target, out var status)) + !TryComp(args.Target, out var status)) return; + if (HasComp(args.Target)) + { + _popupSystem.PopupEntity("Священная сила препятствует магии.", args.Performer, args.Performer); + return; + } + if (HasComp(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(args.Performer, out var bloodstream) || !TryComp(uid, out var actor)) + if (!TryComp(args.Performer, out var bloodstream) || + !TryComp(uid, out var actor)) return; - if (!TryComp(args.Target, out _) && - !(TryComp(args.Target, out var mobStateComponent) && - mobStateComponent.CurrentState is not MobState.Alive)) + if (HasComp(args.Target)) { - _popupSystem.PopupEntity("Цель должна быть культистом или лежать.", args.Performer, args.Performer); + _popupSystem.PopupEntity("Священная сила препятствует магии.", args.Performer, args.Performer); + return; + } + + if (!HasComp(args.Target) && !HasComp(args.Target) && + (!TryComp(args.Target, out var mobStateComponent) || + mobStateComponent.CurrentState is MobState.Alive) && + (!TryComp(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) 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 ent, ref CultBloodSpearRecallInstantActionEvent args) { - if (!TryComp(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(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(args.Performer, out var bloodstream) || + !TryComp(args.Performer, out var xform)) + return; + + var conceal = args is CultConcealInstantActionEvent; + + var concealableQuery = GetEntityQuery(); + var appearanceQuery = GetEntityQuery(); + + 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(); + var actionQuery = GetEntityQuery(); + + // 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; } diff --git a/Content.Server/_White/Cult/Runes/Systems/CultSystem.Rune.cs b/Content.Server/_White/Cult/Runes/Systems/CultSystem.Rune.cs index 740e086ff4..d1275eb638 100644 --- a/Content.Server/_White/Cult/Runes/Systems/CultSystem.Rune.cs +++ b/Content.Server/_White/Cult/Runes/Systems/CultSystem.Rune.cs @@ -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(OnActiveInWorld); // UI - SubscribeLocalEvent(OnRuneDrawerUseInHand); + SubscribeLocalEvent(OnRuneDrawAttempt); + SubscribeLocalEvent(BeforeRuneDraw); SubscribeLocalEvent(OnRuneSelected); SubscribeLocalEvent( OnTeleportRuneSelected); @@ -107,6 +113,8 @@ public sealed partial class CultSystem : EntitySystem SubscribeLocalEvent(OnErase); SubscribeLocalEvent(HandleCollision); + SubscribeLocalEvent(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? _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 ent, ref ActivatableUIOpenAttemptEvent args) { - if (!_ui.TryGetUi(uid, component.UserInterfaceKey, out _)) - return; - - if (!TryComp(args.User, out var actorComponent)) - return; - if (!HasComp(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 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(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(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("Slash"), 10); + var damageSpecifier = new DamageSpecifier(_prototypeManager.Index("Slash"), damage); _damageableSystem.TryChangeDamage(uid, damageSpecifier, true, false); _xform.AttachToGridOrMap(_entityManager.SpawnEntity(rune, transform.Value)); diff --git a/Content.Server/_White/Cult/Runes/Systems/CultSystem.Verb.cs b/Content.Server/_White/Cult/Runes/Systems/CultSystem.Verb.cs index 059fa77710..1f45cfaa9f 100644 --- a/Content.Server/_White/Cult/Runes/Systems/CultSystem.Verb.cs +++ b/Content.Server/_White/Cult/Runes/Systems/CultSystem.Verb.cs @@ -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(OnCultistEmpowerSelected); SubscribeLocalEvent(OnCultistEmpowerRemove); SubscribeLocalEvent(OnSpellCreated); + SubscribeLocalEvent(OnBloodRitesSelected); } private void OnCultistEmpowerRemove(Entity 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 ent, ICommonSession session) @@ -112,4 +130,36 @@ public sealed partial class CultSystem _ui.TryOpen(ent, CultEmpowerRemoveUiKey.Key, session); } + + private void OnBloodRitesSelected(Entity ent, ref CultistFactoryItemSelectedMessage args) + { + if (!_prototypeManager.TryIndex(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; + } } diff --git a/Content.Server/_White/Cult/Structures/RunicDoorSystem.cs b/Content.Server/_White/Cult/Structures/RunicDoorSystem.cs index 01e31df343..b92c799152 100644 --- a/Content.Server/_White/Cult/Structures/RunicDoorSystem.cs +++ b/Content.Server/_White/Cult/Structures/RunicDoorSystem.cs @@ -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(OnBeforeDoorOpened); SubscribeLocalEvent(OnBeforeDoorClosed); SubscribeLocalEvent(OnGetAttacked); + SubscribeLocalEvent(OnConceal); + } + + private void OnConceal(Entity 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 ent, ref AttackedEvent args) @@ -79,7 +113,8 @@ public sealed class RunicDoorSystem : EntitySystem _doorSystem.Deny(airlock); - if (!HasComp(user) || HasComp(user)) + if (!HasComp(user) || HasComp(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(uid) || !HasComp(otherUid) && + (!HasComp(otherUid) || !_mobState.IsAlive(otherUid) || + TryComp(otherUid, out CuffableComponent? cuffable) && _cuffable.GetAllCuffs(cuffable).Count > 0); + } } diff --git a/Content.Server/_White/Cult/TimedProduction/CultistFactorySystem.cs b/Content.Server/_White/Cult/TimedProduction/CultistFactorySystem.cs index d3dff143eb..31763ee9fd 100644 --- a/Content.Server/_White/Cult/TimedProduction/CultistFactorySystem.cs +++ b/Content.Server/_White/Cult/TimedProduction/CultistFactorySystem.cs @@ -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(TryToggleAnchor); SubscribeLocalEvent(OnAnchorDoAfter); SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnConceal); + } + + private void OnConceal(Entity ent, ref ConcealEvent args) + { + _physics.SetCanCollide(ent, !args.Conceal); } public override void Update(float frameTime) diff --git a/Content.Server/_White/Cult/UI/ApocalypseRuneEui.cs b/Content.Server/_White/Cult/UI/ApocalypseRuneEui.cs new file mode 100644 index 0000000000..1dee78d18a --- /dev/null +++ b/Content.Server/_White/Cult/UI/ApocalypseRuneEui.cs @@ -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().TryStartDoAfter(argsDoAfterEvent)) + { + Close(); + return; + } + + _entityManager.System().DispatchGlobalAnnouncement(Loc.GetString("cult-started-drawing-rune-end"), + "CULT", true, _apocRuneStartDrawing, colorOverride: Color.DarkRed); + + _entityManager.System().PlayPvs("/Audio/White/Cult/butcher.ogg", _whoCalled, + AudioParams.Default.WithMaxDistance(2f)); + Close(); + } +} diff --git a/Content.Shared/Changeling/SharedTentacleGun.cs b/Content.Shared/Changeling/SharedTentacleGun.cs index 358eed81b4..eba52ec191 100644 --- a/Content.Shared/Changeling/SharedTentacleGun.cs +++ b/Content.Shared/Changeling/SharedTentacleGun.cs @@ -123,10 +123,10 @@ public abstract class SharedTentacleGun : EntitySystem foreach (var activeItem in _handsSystem.EnumerateHeld(args.Embedded)) { if(!TryComp(activeItem, out var physicsComponent)) - return; + continue; var coords = Transform(args.Embedded).Coordinates; - _handsSystem.TryDrop(args.Embedded, coords); + _handsSystem.TryDrop(args.Embedded, activeItem, coords); var force = physicsComponent.Mass * 2.5f / 2; diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs index 32339eb03a..3a8f086ba2 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.Interactions.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Shared._White.Cult.Components; using Content.Shared.Examine; using Content.Shared.Hands.Components; using Content.Shared.IdentityManagement; @@ -7,12 +8,15 @@ using Content.Shared.Inventory.VirtualItem; using Content.Shared.Localizations; using Robust.Shared.Input.Binding; using Robust.Shared.Map; +using Robust.Shared.Network; using Robust.Shared.Player; namespace Content.Shared.Hands.EntitySystems; public abstract partial class SharedHandsSystem : EntitySystem { + [Dependency] private readonly INetManager _net = default!; // WD + private void InitializeInteractions() { SubscribeAllEvent(HandleSetHand); @@ -95,7 +99,17 @@ public abstract partial class SharedHandsSystem : EntitySystem private bool DropPressed(ICommonSession? session, EntityCoordinates coords, EntityUid netEntity) { if (TryComp(session?.AttachedEntity, out HandsComponent? hands) && hands.ActiveHand != null) + // WD EDIT START + { + if (HasComp(hands.ActiveHandEntity)) + { + if (_net.IsServer) + QueueDel(hands.ActiveHandEntity.Value); + return false; + } TryDrop(session.AttachedEntity.Value, hands.ActiveHand, coords, handsComp: hands); + } + // WD EDIT END // always send to server. return false; diff --git a/Content.Shared/Weapons/Melee/Components/MeleeSoundComponent.cs b/Content.Shared/Weapons/Melee/Components/MeleeSoundComponent.cs index ae467dc4ad..879a398655 100644 --- a/Content.Shared/Weapons/Melee/Components/MeleeSoundComponent.cs +++ b/Content.Shared/Weapons/Melee/Components/MeleeSoundComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.Damage.Prototypes; using Robust.Shared.Audio; +using Robust.Shared.GameStates; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary; namespace Content.Shared.Weapons.Melee.Components; @@ -8,6 +9,7 @@ namespace Content.Shared.Weapons.Melee.Components; /// Plays the specified sound upon receiving damage of the specified type. /// [RegisterComponent] +[NetworkedComponent, AutoGenerateComponentState] // WD public sealed partial class MeleeSoundComponent : Component { /// @@ -16,6 +18,7 @@ public sealed partial class MeleeSoundComponent : Component /// [DataField("soundGroups", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + [AutoNetworkedField] // WD public Dictionary? SoundGroups; /// @@ -24,10 +27,12 @@ public sealed partial class MeleeSoundComponent : Component /// [DataField("soundTypes", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] + [AutoNetworkedField] // WD public Dictionary? SoundTypes; /// /// Sound that plays if no damage is done. /// + [AutoNetworkedField] // WD [DataField("noDamageSound")] public SoundSpecifier? NoDamageSound; } diff --git a/Content.Shared/_White/Body/BodyRejuvenateSystem.cs b/Content.Shared/_White/Body/BodyRejuvenateSystem.cs new file mode 100644 index 0000000000..055855e8dc --- /dev/null +++ b/Content.Shared/_White/Body/BodyRejuvenateSystem.cs @@ -0,0 +1,48 @@ +using System.Linq; +using Content.Shared.Body.Components; +using Content.Shared.Body.Systems; +using Content.Shared.Rejuvenate; +using Robust.Shared.Containers; +using Robust.Shared.Prototypes; + +namespace Content.Shared._White.Body; + +public sealed class BodyRejuvenateSystem : EntitySystem +{ + [Dependency] private readonly SharedBodySystem _body = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnRejuvenate); + } + + private void OnRejuvenate(Entity ent, ref RejuvenateEvent args) + { + if (ent.Comp.Prototype == null) + return; + + var prototype = _prototypeManager.Index(ent.Comp.Prototype.Value); + var protoSlots = prototype.Slots.Values.ToList(); + + foreach (var (id, component) in _body.GetBodyChildren(ent.Owner, ent.Comp)) + { + foreach (var organSlot in component.Organs.Values) + { + if (!_container.TryGetContainer(id, SharedBodySystem.GetOrganContainerId(organSlot.Id), + out var container)) + continue; + + if (container.Count > 0) + continue; + + var organ = protoSlots.Where(x => x.Organs.ContainsKey(organSlot.Id)) + .Select(x => x.Organs[organSlot.Id]).FirstOrDefault(); + + TrySpawnInContainer(organ, id, SharedBodySystem.GetOrganContainerId(organSlot.Id), out _); + } + } + } +} diff --git a/Content.Shared/_White/Chemistry/NarcoticEffect.cs b/Content.Shared/_White/Chemistry/NarcoticEffect.cs new file mode 100644 index 0000000000..bb98352db7 --- /dev/null +++ b/Content.Shared/_White/Chemistry/NarcoticEffect.cs @@ -0,0 +1,99 @@ +using System.Threading; +using Content.Shared._White.Mood; +using Content.Shared.Chemistry.Components; +using Content.Shared.Damage.Systems; +using Content.Shared.Drunk; +using Content.Shared.Standing; +using Content.Shared.StatusEffect; +using Robust.Shared.Random; +using Timer = Robust.Shared.Timing.Timer; + +namespace Content.Shared._White.Chemistry; + +public sealed class NarcoticEffect : EntitySystem +{ + [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; + [Dependency] private readonly StaminaSystem _stamina = default!; + [Dependency] private readonly StandingStateSystem _standingStateSystem = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnRemove); + } + + private void OnInit(EntityUid uid, NarcoticEffectComponent component, ComponentInit args) + { + int index = _robustRandom.Next(0, Enum.GetNames(typeof(NarcoticEffects)).Length); + + Effects(uid, component, index); + } + + private void OnRemove(EntityUid uid, NarcoticEffectComponent component, ComponentRemove args) + { + if (TryComp(uid, out var movespeedModifierComponent)) + { + if (movespeedModifierComponent.ModifierTimer != TimeSpan.Zero) + Timer.Spawn(movespeedModifierComponent.ModifierTimer, () => component.CancelTokenSource.Cancel()); + return; + } + component.CancelTokenSource.Cancel(); + } + + private void Effects(EntityUid uid, NarcoticEffectComponent component, int index) + { + if(!TryComp(uid, out var standingComp)) + return; + + RaiseLocalEvent(uid, new MoodEffectEvent("Stimulator")); + CancellationToken token = component.CancelTokenSource.Token; + + TryComp(uid, out var statusEffectsComp); + + int timer = component.TimerInterval[_robustRandom.Next(0, component.TimerInterval.Count)]; + int slur = component.SlurTime[_robustRandom.Next(0, component.SlurTime.Count)]; + + switch (Enum.GetValues(typeof(NarcoticEffects)).GetValue(index)) + { + case NarcoticEffects.TremorAndShake when _statusEffectsSystem.HasStatusEffect(uid, "Drunk", statusEffectsComp): + Timer.SpawnRepeating(timer, () => _stamina.TakeStaminaDamage(uid, 15F), token); + _statusEffectsSystem.TryAddTime(uid, "Drunk", TimeSpan.FromSeconds(slur), statusEffectsComp); + break; + + case NarcoticEffects.Shake when _statusEffectsSystem.HasStatusEffect(uid, "Drunk", statusEffectsComp): + _statusEffectsSystem.TryAddTime(uid, "Drunk", TimeSpan.FromSeconds(slur), statusEffectsComp); + break; + + case NarcoticEffects.StunAndShake when _statusEffectsSystem.HasStatusEffect(uid, "Drunk", statusEffectsComp): + Timer.SpawnRepeating(timer, () => _standingStateSystem.TryLieDown(uid, standingComp), token); + _statusEffectsSystem.TryAddTime(uid, "Drunk", TimeSpan.FromSeconds(slur), statusEffectsComp); + break; + + case NarcoticEffects.Stun: + Timer.SpawnRepeating(timer, () => _standingStateSystem.TryLieDown(uid, standingComp), token); + break; + + case NarcoticEffects.TremorAndShake: + Timer.SpawnRepeating(timer, () => _stamina.TakeStaminaDamage(uid, 15F), token); + _statusEffectsSystem.TryAddStatusEffect(uid, "Drunk", TimeSpan.FromSeconds(slur), true, statusEffectsComp); + break; + + case NarcoticEffects.Tremor: + Timer.SpawnRepeating(timer, () => _stamina.TakeStaminaDamage(uid, 15F), token); + break; + + case NarcoticEffects.Shake: + _statusEffectsSystem.TryAddStatusEffect(uid, "Drunk", TimeSpan.FromSeconds(slur), true, statusEffectsComp); + break; + + case NarcoticEffects.StunAndShake: + Timer.SpawnRepeating(timer, () => _standingStateSystem.TryLieDown(uid, standingComp), token); + _statusEffectsSystem.TryAddStatusEffect(uid, "Drunk", TimeSpan.FromSeconds(slur), true, statusEffectsComp); + break; + } + } +} diff --git a/Content.Shared/_White/Chemistry/NarcoticEffectComponent.cs b/Content.Shared/_White/Chemistry/NarcoticEffectComponent.cs new file mode 100644 index 0000000000..f23182685e --- /dev/null +++ b/Content.Shared/_White/Chemistry/NarcoticEffectComponent.cs @@ -0,0 +1,30 @@ +using System.Threading; +using Robust.Shared.Serialization; + +namespace Content.Shared._White.Chemistry; + +/// +/// This is used for... +/// +[RegisterComponent] +public sealed partial class NarcoticEffectComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField] + public CancellationTokenSource CancelTokenSource = new(); + + [ViewVariables(VVAccess.ReadOnly), DataField] + public List TimerInterval = new() { 3000, 6000, 3800, 7000, 5000 }; + + [ViewVariables(VVAccess.ReadOnly), DataField] + public List SlurTime = new() { 35, 60, 80, 90, 45 }; +} + +[Serializable, NetSerializable] +public enum NarcoticEffects +{ + Stun, + Tremor, + Shake, + TremorAndShake, + StunAndShake +} diff --git a/Content.Shared/_White/Cult/Actions/CultActions.cs b/Content.Shared/_White/Cult/Actions/CultActions.cs index 4abc4b31f1..b3924e0046 100644 --- a/Content.Shared/_White/Cult/Actions/CultActions.cs +++ b/Content.Shared/_White/Cult/Actions/CultActions.cs @@ -30,10 +30,23 @@ public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityT { } -public sealed partial class CultConcealPresenceWorldActionEvent : WorldTargetActionEvent +[Virtual] +public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent +{ +} + +public sealed partial class CultConcealInstantActionEvent : CultConcealPresenceInstantActionEvent +{ +} + +public sealed partial class CultRevealInstantActionEvent : CultConcealPresenceInstantActionEvent { } public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent { } + +public sealed partial class CultBloodSpearRecallInstantActionEvent : InstantActionEvent +{ +} diff --git a/Content.Shared/_White/Cult/Components/BloodSpearComponent.cs b/Content.Shared/_White/Cult/Components/BloodSpearComponent.cs new file mode 100644 index 0000000000..c4f93b605a --- /dev/null +++ b/Content.Shared/_White/Cult/Components/BloodSpearComponent.cs @@ -0,0 +1,17 @@ +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Shared._White.Cult.Components; + +[RegisterComponent] +public sealed partial class BloodSpearComponent : Component +{ + [ViewVariables] + public Entity? User; + + [DataField] + public EntProtoId Action; + + [DataField] + public SoundSpecifier ShatterSound = new SoundCollectionSpecifier("GlassBreak"); +} diff --git a/Content.Shared/_White/Cult/Components/BoltBarrageComponent.cs b/Content.Shared/_White/Cult/Components/BoltBarrageComponent.cs new file mode 100644 index 0000000000..6070e62e73 --- /dev/null +++ b/Content.Shared/_White/Cult/Components/BoltBarrageComponent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared._White.Cult.Components; + +[RegisterComponent] +public sealed partial class BoltBarrageComponent : Component +{ + public bool Unremoveable = true; +} diff --git a/Content.Shared/_White/Cult/Components/ConcealPresenceSpellComponent.cs b/Content.Shared/_White/Cult/Components/ConcealPresenceSpellComponent.cs new file mode 100644 index 0000000000..6b59c4ca44 --- /dev/null +++ b/Content.Shared/_White/Cult/Components/ConcealPresenceSpellComponent.cs @@ -0,0 +1,23 @@ +using Content.Shared.Actions; +using Robust.Shared.Utility; + +namespace Content.Shared._White.Cult.Components; + +[RegisterComponent] +public sealed partial class ConcealPresenceSpellComponent : Component +{ + [ViewVariables] + public bool Revealing; + + [DataField(required: true), NonSerialized] + public InstantActionEvent? ConcealEvent; + + [DataField(required: true), NonSerialized] + public InstantActionEvent? RevealEvent; + + [DataField] + public SpriteSpecifier? ConcealIcon; + + [DataField] + public SpriteSpecifier? RevealIcon; +} diff --git a/Content.Shared/_White/Cult/Components/ConcealableComponent.cs b/Content.Shared/_White/Cult/Components/ConcealableComponent.cs new file mode 100644 index 0000000000..23807de31c --- /dev/null +++ b/Content.Shared/_White/Cult/Components/ConcealableComponent.cs @@ -0,0 +1,48 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; +using Robust.Shared.Utility; + +namespace Content.Shared._White.Cult.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ConcealableComponent : Component +{ + [ViewVariables, AutoNetworkedField] + public bool Concealed; + + [DataField] + public bool ExaminableWhileConcealed; + + [DataField] + public bool IconSmooth; + + [DataField] + public bool InteractionOutline; + + [DataField] + public ResPath? ConcealedSprite; + + [DataField] + public ResPath? RevealedSprite; + + [DataField] + public bool ChangeMeta; + + [DataField] + public string ConcealedName = string.Empty; + + [DataField] + public string ConcealedDesc = string.Empty; + + [DataField] + public string RevealedName = string.Empty; + + [DataField] + public string RevealedDesc = string.Empty; +} + +[Serializable, NetSerializable] +public enum ConcealableAppearance +{ + Concealed +} diff --git a/Content.Shared/_White/Cult/Components/CultEmpowerComponent.cs b/Content.Shared/_White/Cult/Components/CultEmpowerComponent.cs index aa2a378d21..970c2a8eda 100644 --- a/Content.Shared/_White/Cult/Components/CultEmpowerComponent.cs +++ b/Content.Shared/_White/Cult/Components/CultEmpowerComponent.cs @@ -9,8 +9,8 @@ public sealed partial class CultEmpowerComponent : Component [DataField("isRune")] public bool IsRune; - public int MaxAllowedCultistActions = 4; - public int MinRequiredCultistActions = 1; + public int MaxAllowedCultistActions = 5; + public int MinRequiredCultistActions = 2; } [Serializable, NetSerializable] diff --git a/Content.Shared/_White/Cult/Components/CultistComponent.cs b/Content.Shared/_White/Cult/Components/CultistComponent.cs index 0c822b41e6..758c61cd1c 100644 --- a/Content.Shared/_White/Cult/Components/CultistComponent.cs +++ b/Content.Shared/_White/Cult/Components/CultistComponent.cs @@ -1,6 +1,9 @@ using System.Threading; +using Content.Shared.FixedPoint; +using Content.Shared.Mind; using Robust.Shared.Audio; using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List; namespace Content.Shared._White.Cult.Components; @@ -8,7 +11,7 @@ namespace Content.Shared._White.Cult.Components; /// This is used for tagging a mob as a cultist. /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] -public sealed partial class CultistComponent : Component +public sealed partial class CultistComponent : ShowCultHudComponent { [DataField("greetSound", customTypeSerializer: typeof(SoundSpecifierTypeSerializer))] public SoundSpecifier? CultistGreetSound = new SoundPathSpecifier("/Audio/CultSounds/fart.ogg"); @@ -21,12 +24,17 @@ public sealed partial class CultistComponent : Component [AutoNetworkedField] public List SelectedEmpowers = new(); + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 RitesBloodAmount = FixedPoint2.Zero; + public static string SummonCultDaggerAction = "InstantActionSummonCultDagger"; public static string BloodRitesAction = "InstantActionBloodRites"; public static string EmpPulseAction = "InstantActionEmpPulse"; + public static string ConcealPresenceAction = "InstantActionConcealPresence"; + public static string CultTwistedConstructionAction = "ActionCultTwistedConstruction"; public static string CultTeleportAction = "ActionCultTeleport"; @@ -40,6 +48,22 @@ public sealed partial class CultistComponent : Component public static List CultistActions = new() { SummonCultDaggerAction, BloodRitesAction, CultTwistedConstructionAction, CultTeleportAction, - CultSummonCombatEquipmentAction, CultStunAction, EmpPulseAction, CultShadowShacklesAction + CultSummonCombatEquipmentAction, CultStunAction, EmpPulseAction, ConcealPresenceAction, CultShadowShacklesAction }; + + [DataField("bloodRites", customTypeSerializer: typeof(PrototypeIdListSerializer))] + public List BloodRites = new () + { + "FactoryCultBloodSpear", + "FactoryCultBloodBarrage" + }; + + [ViewVariables, NonSerialized] + public Entity? BloodSpear; + + [ViewVariables, NonSerialized] + public EntityUid? BloodSpearActionEntity; + + [ViewVariables, NonSerialized] + public Entity? OriginalMind; } diff --git a/Content.Shared/_White/Cult/Components/ShowCultHudComponent.cs b/Content.Shared/_White/Cult/Components/ShowCultHudComponent.cs new file mode 100644 index 0000000000..c03470bd80 --- /dev/null +++ b/Content.Shared/_White/Cult/Components/ShowCultHudComponent.cs @@ -0,0 +1,8 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._White.Cult.Components; + +[Virtual, RegisterComponent, NetworkedComponent] +public partial class ShowCultHudComponent : Component +{ +} diff --git a/Content.Shared/_White/Cult/CultistFactoryProductionPrototype.cs b/Content.Shared/_White/Cult/CultistFactoryProductionPrototype.cs index 8b000335c0..6066023d51 100644 --- a/Content.Shared/_White/Cult/CultistFactoryProductionPrototype.cs +++ b/Content.Shared/_White/Cult/CultistFactoryProductionPrototype.cs @@ -17,6 +17,9 @@ public sealed class CultistFactoryProductionPrototype : IPrototype [DataField("name", required: true)] public string Name = default!; + + [DataField] + public int BloodCost; } [Serializable, NetSerializable] diff --git a/Content.Shared/_White/Cult/Systems/BloodSpearSystem.cs b/Content.Shared/_White/Cult/Systems/BloodSpearSystem.cs new file mode 100644 index 0000000000..308be30e70 --- /dev/null +++ b/Content.Shared/_White/Cult/Systems/BloodSpearSystem.cs @@ -0,0 +1,80 @@ +using Content.Shared._White.Cult.Components; +using Content.Shared.Actions; +using Content.Shared.Hands; +using Content.Shared.StatusEffect; +using Content.Shared.Stunnable; +using Content.Shared.Throwing; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Network; + +namespace Content.Shared._White.Cult.Systems; + +public sealed class BloodSpearSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + [Dependency] private readonly SharedStunSystem _stunSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly INetManager _net = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRemove); + SubscribeLocalEvent(OnEquip); + SubscribeLocalEvent(OnThrowDoHit); + } + + private void OnThrowDoHit(Entity ent, ref ThrowDoHitEvent args) + { + if (!TryComp(args.Target, out StatusEffectsComponent? status)) + return; + + if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(6), true, status)) + return; + + if (_net.IsClient) + return; + + _audio.PlayPvs(ent.Comp.ShatterSound, Transform(ent).Coordinates); + QueueDel(ent); + } + + private void OnEquip(Entity ent, ref GotEquippedHandEvent args) + { + if (!TryComp(args.User, out CultistComponent? cultist)) + return; + + Entity user = (args.User, cultist); + + if (cultist.BloodSpear == ent && ent.Comp.User == user) + return; + + if (ent.Comp.User != null) + DetachSpearFromUser(ent.Comp.User.Value); + DetachSpearFromUser(user); + AttachSpearToUser(user, ent); + } + + public void DetachSpearFromUser(Entity user) + { + _actionsSystem.RemoveAction(user, user.Comp.BloodSpearActionEntity); + user.Comp.BloodSpearActionEntity = null; + if (user.Comp.BloodSpear != null) + user.Comp.BloodSpear.Value.Comp.User = null; + user.Comp.BloodSpear = null; + } + + public void AttachSpearToUser(Entity user, Entity spear) + { + _actionsSystem.AddAction(user, ref user.Comp.BloodSpearActionEntity, spear.Comp.Action); + user.Comp.BloodSpear = spear; + spear.Comp.User = user; + } + + private void OnRemove(Entity ent, ref ComponentRemove args) + { + if (ent.Comp.User != null) + DetachSpearFromUser(ent.Comp.User.Value); + } +} diff --git a/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs b/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs new file mode 100644 index 0000000000..e2fb4947a3 --- /dev/null +++ b/Content.Shared/_White/Cult/Systems/BoltBarrageSystem.cs @@ -0,0 +1,91 @@ +using System.Linq; +using Content.Shared._White.Cult.Components; +using Content.Shared.Ghost; +using Content.Shared.Hands; +using Content.Shared.Hands.Components; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Interaction.Events; +using Content.Shared.Weapons.Ranged.Events; +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Network; +using Robust.Shared.Timing; + +namespace Content.Shared._White.Cult.Systems; + +public sealed class BoltBarrageSystem : EntitySystem +{ + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly IGameTiming _timing = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnShootAttempt); + SubscribeLocalEvent(OnGunShot); + SubscribeLocalEvent(OnDrop); + SubscribeLocalEvent(OnUnequipHand); + SubscribeLocalEvent(OnRemoveAttempt); + SubscribeLocalEvent(OnEmptyShot); + } + + private void OnUnequipHand(Entity ent, ref UnequippedHandEvent args) + { + if (_net.IsServer && ent.Comp.Unremoveable) + QueueDel(ent); + } + + private void OnRemoveAttempt(Entity ent, ref ContainerGettingRemovedAttemptEvent args) + { + if (!_timing.ApplyingState && ent.Comp.Unremoveable) + args.Cancel(); + } + + private void OnEmptyShot(Entity ent, ref OnEmptyGunShotEvent args) + { + if (_net.IsServer) + QueueDel(ent); + } + + private void OnDrop(Entity ent, ref DroppedEvent args) + { + if (_net.IsServer) + QueueDel(ent); + } + + private void OnGunShot(Entity ent, ref GunShotEvent args) + { + if (!TryComp(args.User, out HandsComponent? hands)) + return; + + foreach (var hand in _hands.EnumerateHands(args.User, hands)) + { + if (!hand.IsEmpty) + continue; + + ent.Comp.Unremoveable = false; + _hands.SetActiveHand(args.User, hand, hands); + _hands.TryPickup(args.User, ent, hand, false, false, hands); + ent.Comp.Unremoveable = true; + return; + } + } + + private void OnShootAttempt(Entity ent, ref AttemptShootEvent args) + { + if (!HasComp(args.User) && !HasComp(args.User)) + { + args.Cancelled = true; + args.Message = Loc.GetString("bolt-barrage-component-not-cultist"); + return; + } + + if (_hands.EnumerateHands(args.User).Any(hand => hand.IsEmpty)) + return; + + args.Cancelled = true; + args.Message = Loc.GetString("bolt-barrage-component-no-empty-hand"); + } +} diff --git a/Content.Shared/_White/Cult/Systems/ConcealableSystem.cs b/Content.Shared/_White/Cult/Systems/ConcealableSystem.cs new file mode 100644 index 0000000000..68d4122178 --- /dev/null +++ b/Content.Shared/_White/Cult/Systems/ConcealableSystem.cs @@ -0,0 +1,38 @@ +using Content.Shared._White.Cult.Components; +using Content.Shared.Examine; +using Content.Shared.Interaction.Events; + +namespace Content.Shared._White.Cult.Systems; + +public sealed class ConcealableSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnInteract); + } + + private void OnInteract(Entity ent, ref InteractionAttemptEvent args) + { + if (ent.Comp is {Concealed: true, ExaminableWhileConcealed: false}) + args.Cancel(); + } + + private void OnExamine(Entity ent, ref ExamineAttemptEvent args) + { + if (ent.Comp is {Concealed: true, ExaminableWhileConcealed: false}) + args.Cancel(); + } +} + +public sealed class ConcealEvent : EntityEventArgs +{ + public bool Conceal; + + public ConcealEvent(bool conceal) + { + Conceal = conceal; + } +} diff --git a/Content.Shared/_White/Cult/Systems/CultItemSystem.cs b/Content.Shared/_White/Cult/Systems/CultItemSystem.cs index 67b75846f9..bc29cf60ed 100644 --- a/Content.Shared/_White/Cult/Systems/CultItemSystem.cs +++ b/Content.Shared/_White/Cult/Systems/CultItemSystem.cs @@ -49,6 +49,15 @@ public sealed class CultItemSystem : EntitySystem _popupSystem.PopupClient(Loc.GetString("cult-item-component-pickup-fail", ("name", Name(uid))), uid, args.User); } + public bool CanThrow(EntityUid player, EntityUid throwEnt) + { + if (!HasComp(throwEnt) || CanUse(player)) + return true; + + _popupSystem.PopupEntity(Loc.GetString("cult-item-component-throw-fail"), player, player); + return false; + } + private bool CanUse(EntityUid? uid) { return HasComp(uid) || HasComp(uid); diff --git a/Content.Shared/_White/Cult/UI/ApocalypseRuneDrawMessage.cs b/Content.Shared/_White/Cult/UI/ApocalypseRuneDrawMessage.cs new file mode 100644 index 0000000000..c91abcfac8 --- /dev/null +++ b/Content.Shared/_White/Cult/UI/ApocalypseRuneDrawMessage.cs @@ -0,0 +1,15 @@ +using Content.Shared.Eui; +using Robust.Shared.Serialization; + +namespace Content.Shared._White.Cult.UI; + +[Serializable, NetSerializable] +public sealed class ApocalypseRuneDrawMessage : EuiMessageBase +{ + public readonly bool Accepted; + + public ApocalypseRuneDrawMessage(bool accepted) + { + Accepted = accepted; + } +} diff --git a/Content.Shared/_White/Cult/UI/BloodRitesUi.cs b/Content.Shared/_White/Cult/UI/BloodRitesUi.cs new file mode 100644 index 0000000000..d43f80be9b --- /dev/null +++ b/Content.Shared/_White/Cult/UI/BloodRitesUi.cs @@ -0,0 +1,9 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared._White.Cult.UI; + +[Serializable, NetSerializable] +public enum BloodRitesUi +{ + Key +} diff --git a/Content.Shared/_White/Cult/UI/ListViewSelectorBUIState.cs b/Content.Shared/_White/Cult/UI/ListViewSelectorBUIState.cs index f57ec01a85..17120b3c58 100644 --- a/Content.Shared/_White/Cult/UI/ListViewSelectorBUIState.cs +++ b/Content.Shared/_White/Cult/UI/ListViewSelectorBUIState.cs @@ -12,10 +12,10 @@ public enum ListViewSelectorUiKey [Serializable, NetSerializable] public class ListViewBUIState : BoundUserInterfaceState { - public List Items { get; set; } + public List Items { get; set; } public bool IsUsingPrototypes { get; set; } - public ListViewBUIState(List items, bool isUsingPrototypes) + public ListViewBUIState(List items, bool isUsingPrototypes) { Items = items; IsUsingPrototypes = isUsingPrototypes; diff --git a/Resources/Audio/White/Cult/40sec.ogg b/Resources/Audio/White/Cult/40sec.ogg index 00416855f6..44572f8ed1 100644 Binary files a/Resources/Audio/White/Cult/40sec.ogg and b/Resources/Audio/White/Cult/40sec.ogg differ diff --git a/Resources/Audio/White/Cult/smoke.ogg b/Resources/Audio/White/Cult/smoke.ogg new file mode 100644 index 0000000000..0109e1947c Binary files /dev/null and b/Resources/Audio/White/Cult/smoke.ogg differ diff --git a/Resources/Audio/White/Cult/wand_teleport.ogg b/Resources/Audio/White/Cult/wand_teleport.ogg new file mode 100644 index 0000000000..e16d231ddd Binary files /dev/null and b/Resources/Audio/White/Cult/wand_teleport.ogg differ diff --git a/Resources/Changelog/ChangelogWhite.yml b/Resources/Changelog/ChangelogWhite.yml index b9b2f6eb0b..9d7909f987 100644 --- a/Resources/Changelog/ChangelogWhite.yml +++ b/Resources/Changelog/ChangelogWhite.yml @@ -2604,3 +2604,171 @@ id: 212 time: '2024-03-21T20:20:10.0000000+00:00' url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/228 +- author: Aviu + changes: + - message: "\u0417\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u0435 \u0441\u043E\ + \u043A\u0440\u044B\u0442\u0438\u044F \u043F\u0440\u0438\u0441\u0443\u0442\u0441\ + \u0442\u0432\u0438\u044F \u0434\u043B\u044F \u043A\u0443\u043B\u044C\u0442\u0430\ + ." + type: Add + - message: "\u0422\u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u043D\u043E\ + \ \u0441\u0434\u0435\u043B\u0430\u0442\u044C \u043A\u0440\u043E\u0432\u0430\u0432\ + \u043E\u0435 \u043A\u043E\u043F\u044C\u0435 \u0438 \u0437\u0430\u043B\u043F\ + \ \u043A\u0440\u043E\u0432\u0430\u0432\u044B\u0445 \u0441\u043D\u0430\u0440\u044F\ + \u0434\u043E\u0432, \u043A\u043B\u0438\u043A\u043D\u0443\u0432 \u041F\u041A\u041C\ + \ \u043F\u043E \u0441\u0435\u0431\u0435 -> \u041A\u0443\u043B\u044C\u0442 ->\ + \ \u041A\u0440\u043E\u0432\u0430\u0432\u044B\u0435 \u043E\u0431\u0440\u044F\u0434\ + \u044B." + type: Add + - message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E \u043E\u043F\u0438\ + \u0441\u0430\u043D\u0438\u0435 \u043A \u0440\u0443\u043D\u0430\u043C." + type: Add + - message: "\u041A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u044B \u043F\u043E\ + \u043B\u0443\u0447\u0438\u043B\u0438 \u043F\u0435\u0440\u0435\u043A\u043B\u044E\ + \u0447\u0430\u0435\u043C\u043E\u0435 \u043D\u043E\u0447\u043D\u043E\u0435 \u0437\ + \u0440\u0435\u043D\u0438\u0435." + type: Add + - message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u043F\u043E\u043F\ + \u0430\u043F\u044B \u043F\u0440\u0438 \u0432\u043E\u0441\u043A\u0440\u0435\u0448\ + \u0435\u043D\u0438\u0438\u0438 \u043D\u0430 \u0440\u0443\u043D\u0435 \u0438\ + \ \u043F\u0440\u0438 \u043F\u043E\u043F\u044B\u0442\u043A\u0435 \u043D\u0430\ + \u0447\u0435\u0440\u0442\u0438\u0442\u044C \u0440\u0438\u0442\u0443\u0430\u043B\ + \ \u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u0435\u043D\ + \u043D\u043E\u0433\u043E \u0440\u0430\u0437\u0440\u044B\u0432\u0430." + type: Add + - message: "\u041A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u044B \u0442\u0435\ + \u043F\u0435\u0440\u044C \u0432\u0438\u0434\u044F\u0442 \u0438\u043A\u043E\u043D\ + \u043A\u0438 \u043A\u0443\u043B\u044C\u0442\u0430." + type: Add + - message: "\u041A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u044B \u0442\u0435\ + \u043F\u0435\u0440\u044C \u043C\u043E\u0433\u0443\u0442 \u043B\u0435\u0447\u0438\ + \u0442\u044C\u0441\u044F \u043E\u0442 \u043F\u0438\u043B\u043E\u043D\u0430." + type: Add + - message: "\u0414\u0432\u0435\u0440\u044C \u043A\u0443\u043B\u044C\u0442\u0430\ + \ \u0442\u0435\u043F\u0435\u0440\u044C \u043C\u0433\u043D\u043E\u0432\u0435\u043D\ + \u043D\u043E \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044F\ + \ \u0440\u0438\u0442\u0443\u0430\u043B\u044C\u043D\u044B\u043C \u043A\u0438\u043D\ + \u0436\u0430\u043B\u043E\u043C." + type: Add + - message: "\u041A\u0443\u043B\u044C\u0442\u0438\u0441\u0442 \u0441 \u0432\u044B\ + \u0440\u0435\u0437\u0430\u043D\u043D\u044B\u043C \u043C\u043E\u0437\u0433\u043E\ + \u043C \u043C\u043E\u0436\u0435\u0442 \u0432\u0435\u0440\u043D\u0443\u0442\u044C\ + \u0441\u044F \u0432 \u0442\u0435\u043B\u043E \u043F\u0440\u0438 \u0432\u043E\ + \u0441\u043A\u0440\u0435\u0448\u0435\u043D\u0438\u0438 \u043D\u0430 \u0440\u0443\ + \u043D\u0435." + type: Add + - message: "\u0417\u0430\u0440\u044F\u0434\u044B \u0440\u0443\u043D\u044B \u0432\ + \u043E\u0441\u043A\u0440\u0435\u0448\u0435\u043D\u0438\u044F \u0431\u043E\u043B\ + \u044C\u0448\u0435 \u043D\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u044F\u044E\ + \u0442\u0441\u044F \u043C\u0435\u0436\u0434\u0443 \u0440\u0430\u0443\u043D\u0434\ + \u0430\u043C\u0438." + type: Fix + - message: "\u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\u043B\u044C\u0437\u044F\ + \ \u0447\u0435\u0440\u0442\u0438\u0442\u044C \u0440\u0443\u043D\u044B \u0431\ + \u0435\u0437 \u043A\u0438\u043D\u0436\u0430\u043B\u0430 \u0432 \u0440\u0443\u043A\ + \u0430\u0445." + type: Fix + - message: "\u0426\u0435\u043B\u044C \u043A\u0443\u043B\u044C\u0442\u0430 \u0431\ + \u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044C\u0441\u044F\ + \ \u043C\u0435\u0440\u0442\u0432\u043E\u0439, \u0435\u0441\u043B\u0438 \u043F\ + \u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044C \u0435\u0451 \u0432 \u043A\ + \u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442." + type: Fix + - message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D\u043E \u0445\u043F\ + \ \u0441\u0442\u0435\u043D\u0435 \u043A\u0443\u043B\u044C\u0442\u0430 \u0434\ + \u043E 300, \u0434\u0432\u0435\u0440\u0438 \u043A\u0443\u043B\u044C\u0442\u0430\ + \ \u0434\u043E 200." + type: Tweak + - message: "\u041A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u044B \u0442\u0435\ + \u043F\u0435\u0440\u044C \u0434\u0432\u0438\u0433\u0430\u044E\u0442\u0441\u044F\ + \ \u0438 \u0430\u0442\u0430\u043A\u0443\u044E\u0442 \u0431\u044B\u0441\u0442\ + \u0440\u0435\u0435." + type: Tweak + - message: "\u0424\u0430\u043D\u0442\u043E\u043C \u0442\u0435\u043F\u0435\u0440\u044C\ + \ \u043D\u0430\u043D\u043E\u0441\u0438\u0442 40 \u0441\u0442\u0440\u0443\u043A\ + \u0442\u0443\u0440\u043D\u043E\u0433\u043E \u0443\u0440\u043E\u043D\u0430." + type: Tweak + - message: "\u041C\u0430\u043A\u0441\u0438\u043C\u0443\u043C \u0437\u0430\u043A\u043B\ + \u0438\u043D\u0430\u043D\u0438\u0439 \u043A\u0440\u043E\u0432\u0438 \u0431\u0435\ + \u0437 \u0440\u0443\u043D\u044B \u043C\u043E\u0433\u0443\u0449\u0435\u0441\u0442\ + \u0432\u0430: 1 -> 2, \u0441 \u0440\u0443\u043D\u043E\u0439: 4 -> 5." + type: Tweak + - message: "\u0417\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u0435 \u0442\u0435\ + \u043B\u0435\u043F\u043E\u0440\u0442\u0430 \u0442\u0435\u043F\u0435\u0440\u044C\ + \ \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043D\u0430 \u0441\u0432\ + \u044F\u0437\u0430\u043D\u043D\u044B\u0445 \u0446\u0435\u043B\u0435\u0439." + type: Tweak + - message: "\u0416\u0443\u0442\u043A\u0438\u0439 \u043A\u043B\u0438\u043D\u043E\u043A\ + \ \u0442\u0435\u043F\u0435\u0440\u044C \u043C\u043E\u0436\u043D\u043E \u043F\ + \u043E\u0432\u0435\u0441\u0438\u0442\u044C \u043D\u0430 \u0431\u0440\u043E\u043D\ + \u044E." + type: Tweak + - message: "\u0414\u0432\u0435\u0440\u044C \u043A\u0443\u043B\u044C\u0442\u0430\ + \ \u0442\u0435\u043F\u0435\u0440\u044C \u043D\u0435 \u043E\u0442\u043A\u0440\ + \u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043F\u0440\u0438 \u043A\u043E\u043D\ + \u0442\u0430\u043A\u0442\u0435 \u0441 \u0436\u0438\u0432\u044B\u043C \u043D\u0435\ + \u0441\u0432\u044F\u0437\u0430\u043D\u043D\u044B\u043C \u043A\u0443\u043B\u044C\ + \u0442\u0438\u0441\u0442\u043E\u043C \u0438\u043B\u0438 \u043A\u043E\u043D\u0441\ + \u0442\u0440\u0443\u043A\u0442\u043E\u043C." + type: Tweak + id: 213 + time: '2024-03-22T08:23:33.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/220 +- author: ThereDrD + changes: + - message: "\u041F\u043E\u0444\u0438\u043A\u0448\u0435\u043D \u0434\u044E\u043F\ + \ \u0434\u0435\u043D\u0435\u0433 \u0432 \u043A\u0430\u0440\u0433\u043E" + type: Fix + id: 214 + time: '2024-03-24T02:10:19.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/234 +- author: ThereDrD + changes: + - message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u0437\u0430\u043F\ + \u043E\u043B\u043D\u0435\u043D\u043D\u044B\u0435 \u0432\u0435\u0440\u0441\u0438\ + \u0438 \u0448\u043A\u0430\u0444\u043E\u0432 \u043A\u043B\u043E\u0443\u043D\u0430\ + \ \u0438 \u043C\u0438\u043C\u0430" + type: Add + - message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u044B \u0440\u0430\u0437\ + \u043B\u0438\u0447\u043D\u044B\u0435 \u0436\u0438\u0432\u043E\u0442\u043D\u044B\ + \u0435 \u0432 \u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0435\ + \ \u0448\u043A\u0430\u0444\u044B. \u041A\u0430\u043A \u0430\u0433\u0440\u0435\ + \u0441\u0441\u0438\u0432\u043D\u044B\u0435, \u0441 \u043D\u0438\u0437\u043A\u0438\ + \u043C \u0448\u0430\u043D\u0441\u043E\u043C, \u0442\u0430\u043A \u0438 \u043C\ + \u0438\u0440\u043D\u044B\u0435." + type: Add + - message: "\u041F\u0435\u0440\u0435\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E\ + \ \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u0448\u043A\u0430\ + \u0444\u043E\u0432 \u0433\u043B\u0430\u0432. \u0412\u0441\u044F \u043E\u0434\ + \u0435\u0436\u0434\u0430 \u0442\u0435\u043F\u0435\u0440\u044C \u0445\u0440\u0430\ + \u043D\u0438\u0442\u0441\u044F \u0432 \u043A\u043E\u043C\u043E\u0434\u0430\u0445\ + ." + type: Tweak + - message: "\u041D\u0435\u043A\u043E\u0442\u043E\u0440\u044B\u0435 \u0448\u043A\u0430\ + \u0444\u044B \u0440\u043E\u043B\u0435\u0439 \u043F\u043E\u043F\u043E\u043B\u043D\ + \u0435\u043D\u044B \u043D\u043E\u0432\u044B\u043C\u0438 \u043F\u0440\u0435\u0434\ + \u043C\u0435\u0442\u0430\u043C\u0438" + type: Tweak + - message: "\u041F\u043E\u0444\u0438\u043A\u0448\u0435\u043D\u044B \u043F\u0443\u0441\ + \u0442\u044B\u0435 \u043F\u043E\u044F\u0441\u0430, \u0430\u043F\u0442\u0435\u0447\ + \u043A\u0438 \u0438 \u043F\u0440\u043E\u0447\u0438\u0435 \u043F\u0440\u0435\u0434\ + \u043C\u0435\u0442\u044B \u0432 \u0448\u043A\u0430\u0444\u0430\u0445." + type: Fix + id: 215 + time: '2024-03-24T03:21:27.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/193 +- author: CaypenNow + changes: + - message: "\u041F\u0435\u0440\u0435\u0434\u0435\u043B\u0430\u043D\u044B \u043D\u0435\ + \u0433\u0430\u0442\u0438\u0432\u043D\u044B\u0435 \u044D\u0444\u0444\u0435\u043A\ + \u0442\u044B \u0441\u0442\u0438\u043C\u0443\u043B\u044F\u0442\u043E\u0440\u043E\ + \u0432." + type: Add + - message: "\u0410\u0442\u043C\u043E\u0441 \u0433\u043E\u043B\u043E\u043F\u0440\u043E\ + \u0435\u043A\u0442\u043E\u0440 \u0441\u043D\u043E\u0432\u0430 \u043C\u043E\u0436\ + \u043D\u043E \u043F\u043E\u043B\u043E\u0436\u0438\u0442\u044C \u0432 \u0440\u044E\ + \u043A\u0437\u0430\u043A!" + type: Fix + id: 216 + time: '2024-03-24T08:59:57.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/227 diff --git a/Resources/Locale/ru-RU/White/cult.ftl b/Resources/Locale/ru-RU/White/cult.ftl index e0229b6cd4..e6d8326e9a 100644 --- a/Resources/Locale/ru-RU/White/cult.ftl +++ b/Resources/Locale/ru-RU/White/cult.ftl @@ -1,12 +1,15 @@ -cult-role-greeting = +cult-role-greeting = Вы - член культа! Ваши цели перечислены в меню персонажа. В ваш рюкзак были добавлены предметы, которые помогут вам. И помните - вы не единственный. Слава Нар`си! +cult-role-briefing-short = Используйте '^' для связи с другими членами культа. + cult-cond-cultwin = Культ одержал победу cult-cond-cultfailure = Экипаж уничтожил культ +cult-cond-cultdraw = Ничейный исход cultists-list-start = Культистами были: cultists-list-name = - [color=White]{ $name }[/color] ([color=gray]{ $user }[/color]) diff --git a/Resources/Locale/ru-RU/White/stuff.ftl/pylon.ftl b/Resources/Locale/ru-RU/White/stuff.ftl/pylon.ftl index b00cdb1f00..cc7dfd57fa 100644 --- a/Resources/Locale/ru-RU/White/stuff.ftl/pylon.ftl +++ b/Resources/Locale/ru-RU/White/stuff.ftl/pylon.ftl @@ -1,4 +1,4 @@ pylon-toggle-on = Кристалл воспаряет над пьедесталом, начиная пульсировать pylon-toggle-off = Кристалл перестаёт пульсировать, опускаясь на пьедестал ent-CultPylon = пилон - .desc = Мистический конструкция. + .desc = Мистическая конструкция. diff --git a/Resources/Locale/ru-RU/White/stuff.ftl/runes-entities.ftl b/Resources/Locale/ru-RU/White/stuff.ftl/runes-entities.ftl index 35a97e75af..cdea17ab9e 100644 --- a/Resources/Locale/ru-RU/White/stuff.ftl/runes-entities.ftl +++ b/Resources/Locale/ru-RU/White/stuff.ftl/runes-entities.ftl @@ -1,11 +1,28 @@ -ent-OfferingRune = руна предпонесения +ent-OfferingRune = руна предпонесения + .desc = Мгновенно превращает обычного члена экипажа в культиста, для чего требуется 2 культиста вокруг руны. Члена экипажа с имплантом защиты разума нельзя перевоплотить, можно только принести в жертву, для чего нужно 3 культиста, которые встанут вокруг руны. Если цель мертва, то она будет принесена в жертву, для чего требуется 1 культист. + ent-BuffRune = руна усиления + .desc = При активации усиливает вас, уменьшая затраты и ускоряя процесс подготовки заклинаний крови и черчения рун. + ent-EmpoweringRune = руна могущества + .desc = Позволяет культистам приготовить до 5 заклинаний крови. + ent-TeleportRune = руна телепортации + .desc = Эта руна при использовании переносит всё, что находится на ней, к другой руне телепортации. + ent-SummoningRune = руна призыва + .desc = Эта руна позволяет мгновенно призвать к руне любого несвязанного культиста. Для использования требуются 2 культиста, стоящих вокруг руны. + ent-ReviveRune = руна воскрешения + .desc = Каждый раз, когда кого-то приносят в жертву на Руне Преподнесения, этой руне добавляется один глобальный заряд. Размещение трупа культиста на руне и её активация вернет его к жизни, расходуя при этом заряд. + ent-BarrierRune = руна барьера + .desc = При активации на создаёт барьер, блокирующую проход. Может быть повторно активирована, чтобы отменить заклинание. + ent-BloodBoilRune = руна кипящей крови + .desc = При активации отнимает у призывателей некоторое количество крови, чтобы отправить несколько разрушительных импульсов любому не-культисту поблизости. Когда эффект закончится, руна ненадолго подожжет все, что находится вокруг нее. Для активации требуются 3 культиста, стоящих вокруг руны. + ent-ApocalypseRune = ритуал пространственного разрыва + .desc = Руна призыва Нар'Си. runes-window-title = Руны diff --git a/Resources/Locale/ru-RU/_white/implants/mindshield.ftl b/Resources/Locale/ru-RU/_white/implants/mindshield.ftl new file mode 100644 index 0000000000..883602d583 --- /dev/null +++ b/Resources/Locale/ru-RU/_white/implants/mindshield.ftl @@ -0,0 +1,2 @@ +ent-BoxMindshield = коробка имплантов + .desc = Хранит набор имплантов защиты разума. diff --git a/Resources/Locale/ru-RU/_white/mobs/angry.ftl b/Resources/Locale/ru-RU/_white/mobs/angry.ftl new file mode 100644 index 0000000000..73ead46448 --- /dev/null +++ b/Resources/Locale/ru-RU/_white/mobs/angry.ftl @@ -0,0 +1,3 @@ +ent-MobMonkeyAngry = { ent-MobMonkey } +.desc = { ent-MobMonkey.desc } +.suffix = Агрессивная diff --git a/Resources/Locale/ru-RU/cult/abilities.ftl b/Resources/Locale/ru-RU/cult/abilities.ftl index 0575e85db3..1fd0c0b66f 100644 --- a/Resources/Locale/ru-RU/cult/abilities.ftl +++ b/Resources/Locale/ru-RU/cult/abilities.ftl @@ -35,3 +35,9 @@ ent-ActionCultShadowShackles = Теневые Узы ent-InstantActionEmpPulse = Электромагнитный Импульс .desc = Большое заклинание, которое позволяет пользователю направлять темную энергию в ЭМИ. + +ent-InstantActionConcealPresence = Сокрытие Присутствия + .desc = Многофункциональное заклинание, чередующееся между скрытием и обнаружением ближайших рун и структур культа. + +ent-InstantActionRecallBloodSpear = Призвать Кровавое Копьё + .desc = Призывает кровавое копье в вашу руку. diff --git a/Resources/Locale/ru-RU/cult/bolt-barrage.ftl b/Resources/Locale/ru-RU/cult/bolt-barrage.ftl new file mode 100644 index 0000000000..b6e870093d --- /dev/null +++ b/Resources/Locale/ru-RU/cult/bolt-barrage.ftl @@ -0,0 +1,2 @@ +bolt-barrage-component-no-empty-hand = Вам нужно иметь свободную руку, чтобы стрелять. +bolt-barrage-component-not-cultist = Вы не умеете пользоваться магией. diff --git a/Resources/Locale/ru-RU/cult/cult-item.ftl b/Resources/Locale/ru-RU/cult/cult-item.ftl index 21ee937641..593e64950a 100644 --- a/Resources/Locale/ru-RU/cult/cult-item.ftl +++ b/Resources/Locale/ru-RU/cult/cult-item.ftl @@ -1,3 +1,4 @@ cult-item-component-pickup-fail = Вы не можете подобрать {$name} cult-item-component-attack-fail = Оружие не позволяет вам атаковать cult-item-component-equip-fail = Вы не можете это надеть +cult-item-component-throw-fail = Оружие не позволяет вам его бросить diff --git a/Resources/Locale/ru-RU/cult/cultist-factory.ftl b/Resources/Locale/ru-RU/cult/cultist-factory.ftl index 7be764e835..ed06221a46 100644 --- a/Resources/Locale/ru-RU/cult/cultist-factory.ftl +++ b/Resources/Locale/ru-RU/cult/cultist-factory.ftl @@ -9,3 +9,9 @@ ent-CultMirrorShield = зеркальный щит .desc = Щит с зеркалом на лицевой стороне, на котором изображен какой-то религиозный знак. ent-CultOuterArmor = бронированная мантия .desc = С первого взгляда кажется, что это простая мантия, но на ней имеется элементы брони. +ent-ShadowShackles = теневые оковы + .desc = Оковы, сковывающие запястья с помощью зловещей магии. +ent-BloodSpear = кровавое копьё + .desc = Ужасающее копьё, полностью состоящее из кристаллизованной крови. +ent-BloodBarrage = залп кровавых снарядов + .desc = Кровь за кровь. diff --git a/Resources/Locale/ru-RU/cult/gui.ftl b/Resources/Locale/ru-RU/cult/gui.ftl new file mode 100644 index 0000000000..92bd1fa53e --- /dev/null +++ b/Resources/Locale/ru-RU/cult/gui.ftl @@ -0,0 +1,4 @@ +apocalypse-rune-title = Вы готовы к финальной битве? +apocalypse-rune-text = Это последний шаг к вызову Нар'Си; это долгий, болезненный ритуал, и экипаж будет предупрежден о вашем присутствии. +apocalypse-rune-accept-button = Жизнь за Нар'Си! +apocalypse-rune-deny-button = Нет diff --git a/Resources/Locale/ru-RU/cult/pylon.ftl b/Resources/Locale/ru-RU/cult/pylon.ftl index b00cdb1f00..cc7dfd57fa 100644 --- a/Resources/Locale/ru-RU/cult/pylon.ftl +++ b/Resources/Locale/ru-RU/cult/pylon.ftl @@ -1,4 +1,4 @@ pylon-toggle-on = Кристалл воспаряет над пьедесталом, начиная пульсировать pylon-toggle-off = Кристалл перестаёт пульсировать, опускаясь на пьедестал ent-CultPylon = пилон - .desc = Мистический конструкция. + .desc = Мистическая конструкция. diff --git a/Resources/Locale/ru-RU/cult/verb.ftl b/Resources/Locale/ru-RU/cult/verb.ftl index 0721351b41..08f35fca69 100644 --- a/Resources/Locale/ru-RU/cult/verb.ftl +++ b/Resources/Locale/ru-RU/cult/verb.ftl @@ -1,9 +1,14 @@ verb-categories-cult = Культ verb-spell-create-text = Создать заклинание крови -verb-spell-create-message = Вы можете создать одно заклинание крови без руны могущества. -verb-spell-create-too-much = Начертите руну могущества, чтобы создать больше одного заклинания крови. +verb-spell-create-message = Вы можете создать два заклинания крови без руны могущества. +verb-spell-create-too-much = Начертите руну могущества, чтобы создать больше двух заклинаний крови. verb-spell-remove-text = Удалить заклинание крови verb-spell-remove-message = Убрать любое из созданных заклинаний крови. verb-spell-remove-no-spells = Заклинания крови отсутствуют. + +verb-blood-rites-text = Кровавые обряды +verb-blood-rites-message = Всего высосано крови: { $blood }. +verb-blood-rites-no-blood = Для обряда необходимо высосать { $required } крови с помощью заклинания Кровавые Обряды. Всего высосано: { $blood }. +verb-blood-rites-no-hand = Вам нужна свободная рука для обряда. diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/lockers/service.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/lockers/service.ftl index cb93a112f5..cf19227ad5 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/lockers/service.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/catalog/fills/lockers/service.ftl @@ -16,3 +16,9 @@ ent-LockerBotanistFilled = { ent-LockerBotanist } ent-LockerBotanistLoot = { ent-LockerBotanist } .suffix = Лут .desc = { ent-LockerBotanist.desc } +ent-LockerClownFilled = { ent-LockerClown } + .suffix = Заполненный + .desc = { ent-LockerClown.desc } +ent-LockerMimeFilled = { ent-LockerMime } + .suffix = Заполненный + .desc = { ent-LockerMime.desc } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/lockers/lockers.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/lockers/lockers.ftl index 51e9379864..a9c29274d6 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/lockers/lockers.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/lockers/lockers.ftl @@ -73,3 +73,9 @@ ent-LockerSyndicatePersonal = оружейный шкаф ent-LockerInspector = шкаф инспектора .desc = Содержит уникальный гардероб по последнему слову моды. .suffix = { "" } +ent-LockerMime = шкаф клоуна + .desc = Содержит рабочую экипировку станционного клоуна. Для хранения смешного + .suffix = { "" } +ent-LockerClown = шкаф мима + .desc = Содержит рабочую экипировку станционного мима. + .suffix = { "" } diff --git a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/wardrobe.ftl b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/wardrobe.ftl index 95e6004281..577f774bf4 100644 --- a/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/wardrobe.ftl +++ b/Resources/Locale/ru-RU/ss14-ru/prototypes/entities/structures/storage/closets/wardrobe.ftl @@ -34,8 +34,8 @@ ent-WardrobeSecurity = гардероб службы безопасности ent-WardrobeAtmospherics = гардероб атмосферного снаряжения .desc = { ent-WardrobeBase.desc } .suffix = { "" } -ent-ClosetJanitor = шкаф уборщика - .desc = Здесь хранится санитарно-технические одежда и оборудование . +ent-ClosetJanitor = шкаф оборудования уборщика + .desc = Здесь хранится санитарно-техническое оборудование. .suffix = { "" } ent-WardrobeFormal = официально-деловой гардероб .desc = Хранилище одежды строгого стиля. diff --git a/Resources/Locale/ru-RU/white/gamemodes/cult.ftl b/Resources/Locale/ru-RU/white/gamemodes/cult.ftl deleted file mode 100644 index 642b777e87..0000000000 --- a/Resources/Locale/ru-RU/white/gamemodes/cult.ftl +++ /dev/null @@ -1,7 +0,0 @@ -cult-cond-cultwin = Экипаж пососал -cult-cond-cultfailure = Экипаж не пососал -cultists-list-start = Культистами были: -cultists-list-name = - [color=White]{ $name }[/color] ([color=gray]{ $user }[/color]) -soul-shard-name = Душа { $soul } -soul-shard-description = В этом камне заключена душа { $soul } -cult-too-much-empowers = Слишком много способностей diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml b/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml index 4df6e9e761..9ab6cd8192 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_atmospherics.yml @@ -138,6 +138,6 @@ sprite: Structures/Storage/canister.rsi state: darkblue product: PluoxiumCanister - cost: 3500 + cost: 12000 category: Atmospherics group: market diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml b/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml index f2e71e43c8..43c1b3207e 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_vending.yml @@ -33,7 +33,7 @@ sprite: Objects/Specific/Service/vending_machine_restock.rsi state: base product: CrateVendingMachineRestockClothesFilled - cost: 10500 + cost: 14000 category: Service group: market diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml index 9e45d72f63..d7838745c7 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml @@ -14,6 +14,11 @@ - id: ClothingHandsGlovesCaptain - id: ClothingNeckMantleCap - id: ClothingEyesGlassesSunglasses + - id: ClothingOuterArmorCaptainCarapace + - id: ClothingHeadsetAltCommand + - id: ClothingMaskGasCaptain + - id: ClothingUniformJumpskirtCaptain + - id: ClothingOuterWinterCap - type: entity id: DresserChiefEngineerFilled @@ -27,6 +32,11 @@ - id: ClothingUniformJumpskirtChiefEngineerTurtle - id: ClothingNeckCloakCe - id: ClothingHeadHatBeretEngineering + - id: ClothingEyesGlassesMeson + - id: ClothingHeadsetAltEngineering + - id: ClothingHeadHatHardhatWhite + - id: ClothingHandsGlovesColorYellow + - id: ClothingShoesBootsMagAdv - type: entity id: DresserChiefMedicalOfficerFilled @@ -35,10 +45,18 @@ components: - type: StorageFill contents: + - id: ClothingUniformJumpsuitCMO + - id: ClothingUniformJumpskirtCMO + - id: ClothingOuterWinterCMO + - id: ClothingOuterCoatLabCmo - id: ClothingNeckMantleCMO - id: ClothingCloakCmo - - id: ClothingOuterCoatLabCmo - id: ClothingHeadHatBeretCmo + - id: ClothingHandsGlovesNitrile + - id: ClothingEyesHudMedical + - id: ClothingHeadsetAltMedical + - id: ClothingMaskSterile + - id: ClothingEyesEyepatchHudMedical - type: entity id: DresserHeadOfPersonnelFilled @@ -52,6 +70,10 @@ - id: ClothingHeadHatHopcap - id: ClothingOuterWinterHoP - id: ClothingHandsGlovesHop + - id: ClothingNeckGoldmedal + - id: ClothingShoesLeather + - id: ClothingUniformJumpsuitHoP + - id: ClothingUniformJumpskirtHoP - type: entity id: DresserHeadOfSecurityFilled @@ -70,6 +92,10 @@ - id: ClothingUniformJumpsuitHosFormal - id: ClothingMaskNeckGaiter - id: ClothingHandsGlovesCombat + - id: ClothingShoesBootsJack + - id: ClothingEyesGlassesSecurity + - id: ClothingHeadsetAltSecurity + - id: ClothingMaskGasSwat - type: entity id: DresserQuarterMasterFilled @@ -86,6 +112,11 @@ - id: ClothingUniformJumpskirtQMTurtleneck - id: ClothingHandsGlovesColorBrown - id: ClothingNeckMantleQM + - id: ClothingHeadsetAltCargo + - id: ClothingOuterWinterQM + - id: ClothingUniformJumpsuitQM + - id: ClothingUniformJumpskirtQM + - id: ClothingHeadHatQMsoft - type: entity id: DresserResearchDirectorFilled @@ -99,6 +130,10 @@ - id: ClothingHeadHatBeretRND - id: ClothingHandsGlovesColorPurple - id: ClothingHeadsetAltScience + - id: ClothingUniformJumpskirtResearchDirector + - id: ClothingUniformJumpsuitResearchDirector + - id: ClothingOuterWinterRD + - id: ClothingOuterCoatRD - type: entity id: DresserWardenFilled @@ -109,3 +144,11 @@ contents: - id: ClothingHeadHatWarden - id: ClothingHeadHatBeretWarden + - id: ClothingEyesGlassesSecurity + - id: ClothingHeadsetAltSecurity + - id: ClothingHandsGlovesCombat + - id: ClothingShoesBootsJack + - id: ClothingOuterCoatWarden + - id: ClothingOuterWinterWarden + - id: ClothingUniformJumpsuitWarden + - id: ClothingUniformJumpskirtWarden diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml b/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml index e685377234..b8f4e3f112 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml @@ -92,6 +92,8 @@ - id: DoorRemoteFirefight - id: ClothingBeltUtilityEngineering - id: ClothingEyesGlassesMeson + - id: ClothingShoesBootsMag + - id: ClothingHandsGlovesColorYellow - type: entity id: LockerAtmosphericsFilled @@ -109,6 +111,8 @@ - id: DoorRemoteFirefight - id: ClothingBeltUtilityEngineering - id: ClothingEyesGlassesMeson + - id: ClothingShoesBootsMag + - id: ClothingHandsGlovesColorYellow - type: entity id: LockerEngineerFilledHardsuit diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index 550f0b8fdc..77cbaff856 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -11,12 +11,10 @@ - id: CargoShuttleConsoleCircuitboard - id: SalvageShuttleConsoleCircuitboard - id: CargoBountyComputerCircuitboard - - id: CigPackGreen - prob: 0.50 - id: DoorRemoteCargo - id: RubberStampQm - - id: ClothingHeadsetAltCargo - id: BoxEncryptionKeyCargo + - id: BoxFolderClipboard - type: entity id: LockerCaptainFilledHardsuit @@ -25,19 +23,13 @@ components: - type: StorageFill contents: - - id: ClothingOuterArmorCaptainCarapace + - id: WeaponEgun - id: NukeDisk - id: PinpointerNuclear - id: CaptainIDCard - - id: ClothingOuterHardsuitCap - - id: ClothingMaskGasCaptain - - id: WeaponEgun - id: CommsComputerCircuitboard - - id: ClothingHeadsetAltCommand - id: PlushieNuke prob: 0.1 - - id: CigarGoldCase - prob: 0.25 - id: ClothingBeltSheathFilled - id: DoorRemoteCommand - id: RubberStampCaptain @@ -46,6 +38,9 @@ - id: MedalCase - id: CommandBudgetCard - id: CommandBudgetPinPaper + - id: MedalCase + - id: ClothingOuterHardsuitCap + - id: OxygenTankFilled - type: entity id: LockerCaptainFilled @@ -54,25 +49,22 @@ components: - type: StorageFill contents: - - id: ClothingOuterArmorCaptainCarapace - - id: NukeDisk - - id: PinpointerNuclear - - id: CaptainIDCard - - id: WeaponDisabler - - id: CommsComputerCircuitboard - - id: ClothingHeadsetAltCommand - - id: PlushieNuke - prob: 0.1 - - id: CigarGoldCase - prob: 0.25 - - id: ClothingBeltSheathFilled - - id: DoorRemoteCommand - - id: RubberStampCaptain - - id: WeaponAntiqueLaser - - id: JetpackCaptainFilled - - id: MedalCase - - id: CommandBudgetCard - - id: CommandBudgetPinPaper + - id: WeaponEgun + - id: NukeDisk + - id: PinpointerNuclear + - id: CaptainIDCard + - id: CommsComputerCircuitboard + - id: PlushieNuke + prob: 0.1 + - id: ClothingBeltSheathFilled + - id: DoorRemoteCommand + - id: RubberStampCaptain + - id: WeaponAntiqueLaser + - id: JetpackCaptainFilled + - id: MedalCase + - id: CommandBudgetCard + - id: CommandBudgetPinPaper + - id: MedalCase - type: entity id: LockerCaptainFilledNoLaser @@ -81,23 +73,22 @@ components: - type: StorageFill contents: - - id: ClothingOuterArmorCaptainCarapace - - id: NukeDisk - - id: PinpointerNuclear - - id: CaptainIDCard - - id: WeaponDisabler - - id: CommsComputerCircuitboard - - id: ClothingHeadsetAltCommand - - id: SpaceCash1000 - - id: PlushieNuke - prob: 0.1 - - id: CigarGoldCase - prob: 0.25 - - id: ClothingBeltSheathFilled - - id: DoorRemoteCommand - - id: RubberStampCaptain - - id: JetpackCaptainFilled - - id: MedalCase + - id: WeaponEgun + - id: NukeDisk + - id: PinpointerNuclear + - id: CaptainIDCard + - id: WeaponDisabler + - id: CommsComputerCircuitboard + - id: PlushieNuke + prob: 0.1 + - id: ClothingBeltSheathFilled + - id: DoorRemoteCommand + - id: RubberStampCaptain + - id: JetpackCaptainFilled + - id: MedalCase + - id: CommandBudgetCard + - id: CommandBudgetPinPaper + - id: MedalCase - type: entity id: LockerHeadOfPersonnelFilled @@ -113,18 +104,35 @@ - id: BoxHeadset - id: IDComputerCircuitboard - id: WeaponEgun - - id: CigarGoldCase - prob: 0.25 - # Fuck the HoP they don't deserve fucking cigars. - # Yes they do fuck you. - id: DoorRemoteService - id: ClothingNeckGoldmedal - id: RubberStampHop - id: BoxEncryptionKeyPassenger - id: BoxEncryptionKeyService - - id: ClothingBackpackIan - prob: 0.5 - - id: AccessConfigurator + - id: BoxFolderClipboard + +- type: entity + id: LockerHeadOfPersonnelFilledHardsuit + suffix: Filled, Hardsuit + parent: LockerHeadOfPersonnel + components: + - type: StorageFill + contents: + - id: HoPIDCard + - id: ClothingHeadsetCommand + - id: BoxPDA + - id: BoxID + - id: BoxHeadset + - id: IDComputerCircuitboard + - id: WeaponEgun + - id: DoorRemoteService + - id: ClothingNeckGoldmedal + - id: RubberStampHop + - id: BoxEncryptionKeyPassenger + - id: BoxEncryptionKeyService + - id: BoxFolderClipboard + - id: ClothingOuterHardsuitHOP + - id: OxygenTankFilled - type: entity id: LockerChiefEngineerFilledHardsuit @@ -133,24 +141,18 @@ components: - type: StorageFill contents: - - id: ClothingOuterHardsuitEngineeringWhite - - id: ClothingMaskBreath - - id: OxygenTankFilled - - id: NitrogenTankFilled - - id: ClothingEyesGlassesMeson - id: ClothingBeltChiefEngineerFilled - - id: ClothingShoesBootsMagAdv - - id: ClothingHandsGlovesColorYellow - - id: CigarCase - prob: 0.15 - id: DoorRemoteEngineering - id: RubberStampCE - - id: JetpackVoidFilled - - id: ClothingHeadsetAltEngineering - id: BoxEncryptionKeyEngineering - id: AccessConfigurator - id: RCD - id: RCDAmmo + amount: 2 + - id: HolofanProjector + - id: ClothingOuterHardsuitEngineeringWhite + - id: ClothingMaskBreath + - id: OxygenTankFilled - type: entity id: LockerChiefEngineerFilled @@ -159,19 +161,15 @@ components: - type: StorageFill contents: - - id: ClothingEyesGlassesMeson - - id: ClothingBeltChiefEngineerFilled - - id: ClothingHandsGlovesColorYellow - - id: CigarCase - prob: 0.15 - - id: DoorRemoteEngineering - - id: RubberStampCE - - id: ClothingHeadsetAltEngineering - - id: BoxEncryptionKeyEngineering - - id: AccessConfigurator - - id: RCD - - id: RCDAmmo - - id: ClothingHeadHatHardhatWhite + - id: ClothingBeltChiefEngineerFilled + - id: DoorRemoteEngineering + - id: RubberStampCE + - id: BoxEncryptionKeyEngineering + - id: AccessConfigurator + - id: RCD + - id: RCDAmmo + amount: 2 + - id: HolofanProjector - type: entity id: LockerChiefMedicalOfficerFilledHardsuit @@ -181,15 +179,6 @@ - type: StorageFill contents: - id: MedkitFilled - - id: ClothingHandsGlovesNitrile - - id: ClothingEyesHudMedical - - id: ClothingHeadsetAltMedical - - id: ClothingCloakCmo - - id: ClothingBackpackDuffelSurgeryFilled - - id: ClothingOuterCoatLabCmo - - id: ClothingMaskSterile - - id: ClothingHeadHatBeretCmo - - id: ClothingOuterHardsuitMedical - id: Hypospray - id: HandheldCrewMonitor - id: DoorRemoteMedical @@ -197,7 +186,10 @@ - id: MedicalTechFabCircuitboard - id: BoxEncryptionKeyMedical - id: Eftpos - - id: ClothingBeltMedical + - id: ClothingBeltMedicalFilled + - id: MedkitFilled + - id: ClothingOuterHardsuitMedical + - id: OxygenTankFilled - type: entity id: LockerChiefMedicalOfficerFilled @@ -207,11 +199,6 @@ - type: StorageFill contents: - id: MedkitFilled - - id: ClothingHandsGlovesNitrile - - id: ClothingEyesHudMedical - - id: ClothingHeadsetAltMedical - - id: ClothingBackpackDuffelSurgeryFilled - - id: ClothingMaskSterile - id: Hypospray - id: HandheldCrewMonitor - id: DoorRemoteMedical @@ -219,7 +206,7 @@ - id: MedicalTechFabCircuitboard - id: BoxEncryptionKeyMedical - id: Eftpos - - id: ClothingBeltMedical + - id: ClothingBeltMedicalFilled - type: entity id: LockerResearchDirectorFilledHardsuit @@ -261,28 +248,24 @@ - type: entity id: LockerHeadOfSecurityFilledHardsuit suffix: Filled, Hardsuit - parent: LockerHeadOfSecurity + parent: LockerHeadOfSecurityFilled components: - type: StorageFill contents: - - id: WeaponDisabler - - id: ClothingOuterCoatHoSTrench - - id: ClothingOuterHardsuitSecurityRed - - id: ClothingMaskGasSwat - - id: ClothingBeltSecurityFilled - - id: ClothingHeadsetAltSecurity - - id: ClothingEyesGlassesSecurity - - id: ClothingShoesBootsJack - - id: CigarGoldCase - prob: 0.50 + - id: WeaponEgun + - id: ClothingBeltAssaultFilled - id: DoorRemoteSecurity - id: RubberStampHos - id: SecurityTechFabCircuitboard - - id: JetpackSecurityFilled - id: BoxEncryptionKeySecurity - id: HoloprojectorSecurity - id: BookSecretDocuments - id: WeaponPistolMk58Nonlethal + - id: MagazinePistol + - id: BoxMindshield + - id: ClothingOuterHardsuitSecurityRed + - id: JetpackSecurityFilled + - id: OxygenTankFilled - type: entity id: LockerHeadOfSecurityFilled @@ -292,16 +275,7 @@ - type: StorageFill contents: - id: WeaponEgun - - id: ClothingHeadHatBeretHoS - - id: ClothingHeadHatHoshat - - id: ClothingNeckCloakHos - - id: ClothingOuterCoatHoSTrench - - id: ClothingBeltSecurityFilled - - id: ClothingHeadsetAltSecurity - - id: ClothingEyesGlassesSecurity - - id: ClothingShoesBootsJack - - id: CigarGoldCase - prob: 0.50 + - id: ClothingBeltAssaultFilled - id: DoorRemoteSecurity - id: RubberStampHos - id: SecurityTechFabCircuitboard @@ -310,6 +284,7 @@ - id: BookSecretDocuments - id: WeaponPistolMk58Nonlethal - id: MagazinePistol + - id: BoxMindshield - type: entity id: LockerFreezerVaultFilled diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml b/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml index 754eb95435..ce6c913669 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml @@ -15,6 +15,9 @@ - id: Bloodpack amount: 2 - id: Gauze + - id: MedkitFilled + - id: BoxPillCanister + - id: BoxBottle - type: entity id: LockerWallMedicalFilled @@ -34,6 +37,7 @@ - id: Bloodpack amount: 2 - id: Gauze + - id: MedkitFilled - type: entity @@ -44,7 +48,6 @@ - type: StorageFill contents: - id: HandheldHealthAnalyzer - prob: 0.6 - id: ClothingHandsGlovesLatex - id: ClothingHeadsetMedical - id: ClothingEyesHudMedical @@ -58,6 +61,8 @@ - id: ClothingHeadHatSurgcapBlue prob: 0.90 orGroup: Surgcaps + - id: ClothingUniformJumpsuitMedicalDoctor + - id: ClothingUniformJumpskirtMedicalDoctor - id: UniformScrubsColorBlue prob: 0.5 orGroup: Surgshrubs @@ -78,7 +83,6 @@ - type: StorageFill contents: - id: HandheldHealthAnalyzer - prob: 0.6 - id: ClothingHandsGlovesLatex - id: ClothingHeadsetMedical - id: ClothingEyesHudMedical @@ -92,6 +96,8 @@ - id: ClothingHeadHatSurgcapBlue prob: 0.90 orGroup: Surgcaps + - id: ClothingUniformJumpsuitMedicalDoctor + - id: ClothingUniformJumpskirtMedicalDoctor - id: UniformScrubsColorBlue prob: 0.5 orGroup: Surgshrubs @@ -149,5 +155,6 @@ - id: ClothingMaskSterile - id: HandheldGPSBasic - id: MedkitFilled - prob: 0.3 - id: Eftpos + - id: ClothingBeltMedicalEMTFilled + - id: HandheldCrewMonitor diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml index 8408d49cfe..5ce21d6abd 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/misc.yml @@ -63,7 +63,7 @@ orGroup: EmergencyNitrogenOrRegularNitrogen - id: EmergencyNitrogenTankFilled prob: 0.20 - orGroup: EmergencyNitrogenOrRegularNitrogen + orGroup: EmergencyNitrogenOrRegularNitrogen - id: ToolboxEmergencyFilled prob: 0.4 - id: MedkitOxygenFilled @@ -191,8 +191,37 @@ prob: 0.005 orGroup: syndiemaintloot - id: WeaponSniperMosin - prob: 0.0010 + prob: 0.001 orGroup: syndiemaintloot + # Angry animals + - id: null + prob: 0.95 + orGroup: angryanimalsmaintloot + - id: MobCarp + prob: 0.05 + orGroup: angryanimalsmaintloot + - id: MobGiantSpiderAngry + prob: 0.05 + orGroup: angryanimalsmaintloot + - id: MobAngryBee + prob: 0.05 + orGroup: angryanimalsmaintloot + - id: MobMonkeyAngry + prob: 0.05 + orGroup: angryanimalsmaintloot + # Animals + - id: null + prob: 0.7 + orGroup: animalsmaintloot + - id: MobMouse + prob: 0.1 + orGroup: animalsmaintloot + - id: MobMouse1 + prob: 0.1 + orGroup: animalsmaintloot + - id: MobMouse2 + prob: 0.1 + orGroup: animalsmaintloot - type: entity id: ClosetWallMaintenanceFilledRandom @@ -284,3 +313,32 @@ - id: WeaponSniperMosin prob: 0.0010 orGroup: syndiemaintloot + # Angry animals + - id: null + prob: 0.95 + orGroup: angryanimalsmaintloot + - id: MobCarp + prob: 0.005 + orGroup: angryanimalsmaintloot + - id: MobGiantSpiderAngry + prob: 0.005 + orGroup: angryanimalsmaintloot + - id: MobAngryBee + prob: 0.005 + orGroup: angryanimalsmaintloot + - id: MobMonkeyAngry + prob: 0.005 + orGroup: angryanimalsmaintloot + # Animals + - id: null + prob: 0.7 + orGroup: animalsmaintloot + - id: MobMouse + prob: 0.1 + orGroup: animalsmaintloot + - id: MobMouse1 + prob: 0.1 + orGroup: animalsmaintloot + - id: MobMouse2 + prob: 0.1 + orGroup: animalsmaintloot diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index 5fea75ab0e..0bca462d2a 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -7,23 +7,17 @@ contents: - id: FlashlightSeclite - id: WeaponDisabler - prob: 0.3 - id: ClothingBeltSecurityFilled - id: Flash - - id: ClothingEyesGlassesSecurity - - id: ClothingHeadsetAltSecurity - - id: ClothingHandsGlovesCombat - - id: ClothingShoesBootsJack - - id: ClothingOuterCoatWarden - - id: ClothingHeadHatWarden - - id: ClothingOuterWinterWarden - id: RubberStampWarden - id: DoorRemoteArmory - - id: ClothingOuterHardsuitWarden - id: HoloprojectorSecurity - id: BoxBodyCamera - id: WeaponPistolMk58Nonlethal - id: MagazinePistol + - id: BoxMindshield + - id: ClothingOuterHardsuitWarden + - id: OxygenTankFilled - type: entity id: LockerWardenFilled @@ -34,22 +28,15 @@ contents: - id: FlashlightSeclite - id: WeaponDisabler - - id: ClothingHeadHatWarden - - id: ClothingHeadHatBeretWarden - id: ClothingBeltSecurityFilled - id: Flash - - id: ClothingEyesGlassesSecurity - - id: ClothingHeadsetAltSecurity - - id: ClothingHandsGlovesCombat - - id: ClothingShoesBootsJack - - id: ClothingOuterCoatWarden - - id: ClothingOuterWinterWarden - id: RubberStampWarden - id: DoorRemoteArmory - id: HoloprojectorSecurity - id: BoxBodyCamera - id: WeaponPistolMk58Nonlethal - id: MagazinePistol + - id: BoxMindshield - type: entity id: LockerSecurityFilled @@ -77,7 +64,7 @@ prob: 0.6 - id: WeaponTempGun - id: WeaponPistolMk58Nonlethal - - id: BoxBodyCamera + - id: SurveillanceBodyCamera - id: MagazinePistol - type: entity diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index 4e77d63987..192051c0c2 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -209,6 +209,21 @@ sprite: Clothing/Belt/belt_overlay.rsi - type: Appearance +- type: entity + parent: ClothingBeltAssault # WD edit + id: ClothingBeltAssaultFilled + suffix: Filled + name: assault belt + description: A tactical assault belt. + components: + - type: StorageFill + contents: + - id: GrenadeFlashBang + - id: TearGasGrenade + - id: Stunbaton + - id: Handcuffs + - id: Handcuffs + - type: entity parent: ClothingBeltStorageBase id: ClothingBeltJanitor diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 1bc4fb5e98..65f9fc4d16 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -250,10 +250,10 @@ - WhitelistChameleon - type: entity - parent: ClothingOuterBaseLarge + parent: ClothingOuterBaseMedium id: ClothingOuterArmorCaptainCarapace - name: "captain's carapace" - description: "An armored chestpiece that provides protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest." + name: captain's carapace + description: An armored chestpiece that provides protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest. components: - type: Sprite sprite: Clothing/OuterClothing/Armor/captain_carapace.rsi @@ -262,14 +262,11 @@ - type: Armor modifiers: coefficients: - Blunt: 0.5 - Slash: 0.5 + Blunt: 0.6 + Slash: 0.6 Piercing: 0.6 - Heat: 0.5 + Heat: 0.6 Caustic: 0.9 - - type: ClothingSpeedModifier - walkModifier: 1.0 - sprintModifier: 1.0 - type: HeldSpeedModifier - type: ExplosionResistance damageCoefficient: 0.65 diff --git a/Resources/Prototypes/Entities/Debugging/debug_sweps.yml b/Resources/Prototypes/Entities/Debugging/debug_sweps.yml index e3289569a2..b446b6a3d3 100644 --- a/Resources/Prototypes/Entities/Debugging/debug_sweps.yml +++ b/Resources/Prototypes/Entities/Debugging/debug_sweps.yml @@ -40,6 +40,7 @@ whitelist: tags: - CartridgePistol + - type: GiftIgnore - type: entity id: MagazinePistolDebug @@ -55,6 +56,7 @@ capacity: 1000 - type: Sprite sprite: Objects/Weapons/Guns/Ammunition/Magazine/Pistol/pistol_mag.rsi + - type: GiftIgnore - type: entity id: BulletDebug @@ -103,6 +105,7 @@ - type: Item size: Tiny sprite: Objects/Weapons/Melee/debug.rsi + - type: GiftIgnore - type: entity name: bang stick 100dmg @@ -116,6 +119,7 @@ damage: types: Blunt: 100 + - type: GiftIgnore - type: entity name: bang stick 200dmg @@ -129,3 +133,4 @@ damage: types: Blunt: 200 + - type: GiftIgnore diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 639a24a41f..4f45453c3c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -2188,6 +2188,21 @@ description: ghost-role-information-giant-spider-description - type: GhostTakeoverAvailable +- type: entity + name: angry monkey + parent: MobMonkey + id: MobMonkeyAngry + suffix: Angry + components: + - type: NpcFactionMember + factions: + - SimpleHostile + - type: InputMover + - type: MobMover + - type: HTN + rootTask: + task: SimpleHostileCompound + - type: entity name: clown spider parent: MobGiantSpiderAngry @@ -3205,4 +3220,4 @@ components: - type: ReplacementAccent accent: nymph - + diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index ae553682fc..af6ff0b10c 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -87,6 +87,7 @@ - type: IgnoreUIRange - type: ShowRevIcons - type: ShowZombieIcons + - type: ShowCultHud - type: Inventory templateId: aghost - type: InventorySlots diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index 34cba6da71..e1d7ae0b0e 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -217,6 +217,8 @@ type: SpellSelectorBUI - key: enum.CultEmpowerRemoveUiKey.Key type: SpellRemoverBUI + - key: enum.BloodRitesUi.Key + type: CultistFactoryBUI # WD-EDIT END - type: Puller - type: Butcherable diff --git a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml index 16b7538423..528ecdc903 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml @@ -40,6 +40,7 @@ map: [ "implantFull" ] visible: false - type: Item + storedRotation: -90 sprite: Objects/Specific/Medical/implanter.rsi heldPrefix: 0 size: Small diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml index 0b2aa254c6..006cd7366f 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/body-camera.yml @@ -5,7 +5,7 @@ description: MP3 player sized pocket camera for security officers. components: - type: SurveillanceBodyCamera - - type: Sprite # Sprites section + - type: Sprite sprite: Objects/Specific/Security/body-camera.rsi layers: - state: unpowered @@ -66,6 +66,7 @@ slots: cell_slot: name: power-cell-slot-component-slot-name-default + startingItem: PowerCellMedium - type: UserInterface interfaces: - key: enum.SurveillanceCameraSetupUiKey.Camera diff --git a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml index 4cab76a6cb..316080501b 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/syndicate.yml @@ -85,7 +85,6 @@ preset: StorePresetUplink balance: Telecrystal: 20 - - type: GiftIgnore - type: entity parent: BaseUplinkRadio @@ -96,7 +95,6 @@ preset: StorePresetUplink balance: Telecrystal: 25 - - type: GiftIgnore #this uplink MUST be used for nukeops, as it has the tag for filtering the listing. - type: entity @@ -111,7 +109,6 @@ - type: Tag tags: - NukeOpsUplink - - type: GiftIgnore - type: entity parent: BaseUplinkRadio diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml index 9970bec869..e6828f8c75 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Launchers/launchers.yml @@ -340,6 +340,7 @@ unshaded: True: { visible: true } False: { visible: false } + - type: GiftIgnore - type: entity name: force gun @@ -382,6 +383,7 @@ unshaded: True: { visible: true } False: { visible: false } + - type: GiftIgnore - type: entity name: meteor launcher @@ -395,6 +397,7 @@ tags: - CartridgeRocket proto: MeteorLarge + - type: GiftIgnore - type: entity name: immovable rod launcher @@ -408,3 +411,4 @@ tags: - CartridgeRocket proto: ImmovableRodSlow + - type: GiftIgnore diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml index 48568e0b00..87d8d2a3a5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml @@ -1379,3 +1379,19 @@ shader: unshaded - type: ChangeTemperatureOnCollide temperature: -20 + +- type: entity + name: blood bolt + id: BloodBolt + parent: BaseBullet + noSpawn: true + components: + - type: Sprite + sprite: White/Cult/Entities/arcane_barrage.rsi + state: bullet + - type: Ammo + muzzleFlash: null + - type: Projectile + damage: + types: + Piercing: 20 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml index 9a92b88590..0abfaae309 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/cult.yml @@ -20,8 +20,10 @@ size: Normal - type: Clothing sprite: Objects/Weapons/Melee/cult_dagger.rsi + quickEquip: false slots: - back + - suitStorage - type: DisarmMalus - type: RuneDrawerProvider runePrototypes: [ OfferingRune, @@ -33,6 +35,10 @@ SummoningRune, BloodBoilRune, ApocalypseRune ] + - type: ActivatableUI + key: enum.ListViewSelectorUiKey.Key + inHandsOnly: true + closeOnHandDeselect: true - type: UserInterface interfaces: - key: enum.ListViewSelectorUiKey.Key @@ -64,8 +70,10 @@ size: Huge - type: Clothing sprite: Objects/Weapons/Melee/cult_blade.rsi + quickEquip: false slots: - back + - suitStorage - type: DisarmMalus - type: CultItem diff --git a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml index 68b94ef03b..ca7f5309f1 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/dresser.yml @@ -15,7 +15,6 @@ - trigger: !type:DamageTrigger damage: 50 - behaviors: - !type:SpawnEntitiesBehavior spawn: @@ -26,8 +25,8 @@ acts: [ "Destruction" ] - type: Storage grid: - - 0,0,6,3 - maxItemSize: Normal + - 0,0,8,5 + maxItemSize: Huge - type: ContainerContainer containers: storagebase: !type:Container diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml index f760baae0d..2e1e610ba1 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml @@ -422,6 +422,47 @@ stateDoorOpen: clown_open stateDoorClosed: clown_door +- type: entity + id: LockerClownFilled + name: clown locker + parent: LockerClown + suffix: Filled + components: + - type: StorageFill + contents: + - id: ClothingUniformJumpsuitClown + - id: ClothingShoesClown + - id: ClothingMaskClown + - id: ClownRecorder + - id: RubberStampClown + - id: ClothingHeadsetService + - id: CrayonRainbow + - id: ClothingBackpackClown + prob: 0.33 + orGroup: clownbackpack + - id: ClothingBackpackSatchelClown + prob: 0.33 + orGroup: clownbackpack + - id: ClothingBackpackDuffelClown + prob: 0.33 + orGroup: clownbackpack + - id: ClothingShoesClownLarge + prob: 0.66 + - id: ClothingNeckClownmedal + prob: 0.33 + - id: ClothingOuterHardsuitClown + prob: 0.2 + - id: ClothingShoesClownBanana + prob: 0.05 + - id: ClothingUniformJumpsuitClownBanana + prob: 0.05 + - id: ClothingMaskClownBanana + prob: 0.05 + - id: BananiumHorn + prob: 0.1 + - id: GoldenBikeHorn + prob: 0.1 + # Mime - type: entity id: LockerMime @@ -436,6 +477,45 @@ stateDoorOpen: mime_open stateDoorClosed: mime_door +- type: entity + id: LockerMimeFilled + name: mime locker + parent: LockerMime + suffix: Filled + components: + - type: StorageFill + contents: + - id: ClothingUniformJumpsuitMime + - id: ClothingUniformJumpskirtMime + - id: ClothingMaskMime + prob: 0.25 + onGroup: mimemask + - id: ClothingMaskSadMime + prob: 0.25 + onGroup: mimemask + - id: ClothingMaskScaredMime + prob: 0.25 + onGroup: mimemask + - id: ClothingMaskSexyMime + prob: 0.25 + onGroup: mimemask + - id: ClothingShoesColorWhite + - id: ClothingHeadHatBeret + - id: ClothingHandsGlovesLatex + - id: ClothingHeadsetService + - id: RubberStampMime + - id: CrayonMime + - id: ClothingBackpackSatchelMime + prob: 0.5 + onGroup: mimebackpack + - id: ClothingBackpackMime + prob: 0.5 + onGroup: mimebackpack + - id: ClothingOuterWinterMime + prob: 0.5 + - id: ClothingOuterHardsuitMime + prob: 0.2 + # Representative - type: entity id: LockerRepresentative diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index ece31ec918..9aca56144b 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -197,13 +197,13 @@ thresholds: - trigger: !type:DamageTrigger - damage: 1200 + damage: 600 behaviors: - !type:DoActsBehavior acts: ["Destruction"] - trigger: !type:DamageTrigger - damage: 600 + damage: 300 behaviors: - !type:PlaySoundBehavior sound: @@ -220,6 +220,16 @@ - type: Construction graph: CultGirder node: wall + - type: Appearance + - type: Concealable + examinableWhileConcealed: true + concealedSprite: White/Cult/Structures/Concealed/cult.rsi + revealedSprite: Structures/Walls/cult.rsi + changeMeta: true + concealedName: обычная стена + concealedDesc: Удерживает воздух внутри, а ассистентов снаружи. + revealedName: стена культа + revealedDesc: Удерживает воздух внутри, а ассистентов снаружи. - type: entity parent: BaseWall diff --git a/Resources/Prototypes/Reagents/narcotics.yml b/Resources/Prototypes/Reagents/narcotics.yml index ba86e86406..24a072adf9 100644 --- a/Resources/Prototypes/Reagents/narcotics.yml +++ b/Resources/Prototypes/Reagents/narcotics.yml @@ -32,8 +32,8 @@ key: Stutter component: StutteringAccent - !type:GenericStatusEffect - key: BlurryVision - component: BlurryVision + key: NarcoticEffect + component: NarcoticEffect - !type:Jitter - !type:GenericStatusEffect key: Stun @@ -76,8 +76,8 @@ Asphyxiation: 2 - !type:Jitter - !type:GenericStatusEffect - key: BlurryVision - component: BlurryVision + key: NarcoticEffect + component: NarcoticEffect - !type:GenericStatusEffect key: Stun time: 1 diff --git a/Resources/Prototypes/White/Fluff/fluff.yml b/Resources/Prototypes/White/Fluff/fluff.yml index de65a83e43..04ba455468 100644 --- a/Resources/Prototypes/White/Fluff/fluff.yml +++ b/Resources/Prototypes/White/Fluff/fluff.yml @@ -1014,34 +1014,33 @@ # kreses - type: entity - parent: ClothingBackpack - id: KresesClothingBackpackDeath - name: рюкзак из исследователя пустоты - suffix: fluff - description: Кажется когда то это не было рюкзаком. Вы чувствуйте на себя взгляды из пустоты. + parent: ClothingBackpackSatchel + id: KresesClothingBackpackVoid + name: Сумка солдата сингулярности + description: В ней может храниться все, что угодно, даже сама сингулярность. components: - - type: Sprite - sprite: Clothing/Back/Backpacks/ertleader.rsi + - type: Sprite + sprite: White/Fluff/kreses/sachel.rsi - type: entity - parent: ClothingUniformJumpsuitDeathSquad - id: KresesClothingJumpsuitDeath - name: комбинезон исследователя из пустоты - suffix: fluff - description: Костюм тех, кто видел что внутри черной дыры. Если слишком долго смотреть в пустоту, то пустота начнёт смотреть в тебя. + parent: ClothingShoesBaseButcherable + id: KresesClothingShoesVoid + name: Ботинки солдата пустоты + description: Стандартная обувь исcледователей бездны, все еще покрыты бурлящей кровью. + components: + - type: Sprite + sprite: White/Fluff/kreses/boots.rsi - type: entity - parent: ClothingMaskGas - id: KresesClothingMaskGasDeath - name: противогаз исследователя пустоты - suffix: fluff - description: Стандартный противогаз для тех, кто любит полетать в космосе и понаблюдать вблизи за чёрной дырой. + parent: ClothingOuterBase + id: KresesClothingOuterVoid + name: Шинель солдата пустоты + description: Прямиком из сингулярности, как долго ты сможешь её носить? components: - - type: Sprite - sprite: Clothing/Mask/squadron.rsi - - type: Clothing - sprite: Clothing/Mask/squadron.rsi + - type: Sprite + sprite: White/Fluff/kreses/coat.rsi +#Reider207 - type: entity parent: ClothingOuterStorageBase id: ClothingOuterJacketReider207 diff --git a/Resources/Prototypes/White/Fluff/sponsor.yml b/Resources/Prototypes/White/Fluff/sponsor.yml index 98f46470da..9465c079cf 100644 --- a/Resources/Prototypes/White/Fluff/sponsor.yml +++ b/Resources/Prototypes/White/Fluff/sponsor.yml @@ -388,18 +388,18 @@ # kreses - type: loadout - id: KresesGasMaskDeath - entity: KresesClothingMaskGasDeath + id: KresesBackpackVoid + entity: KresesClothingBackpackVoid sponsorOnly: true - type: loadout - id: KresesJumpsuitDeath - entity: KresesClothingJumpsuitDeath + id: KresesShoesVoid + entity: KresesClothingShoesVoid sponsorOnly: true - type: loadout - id: KresesBackpackDeath - entity: KresesClothingBackpackDeath + id: KresesCoatVoid + entity: KresesClothingOuterVoid # Reider207 - type: loadout diff --git a/Resources/Prototypes/White/Ghosts/custom_ghosts.yml b/Resources/Prototypes/White/Ghosts/custom_ghosts.yml index 1fbc499236..444949561f 100644 --- a/Resources/Prototypes/White/Ghosts/custom_ghosts.yml +++ b/Resources/Prototypes/White/Ghosts/custom_ghosts.yml @@ -409,5 +409,5 @@ ckey: kreses sprite: White/Ghosts/kreses-ghost.rsi alpha: 0.9 - ghostName: Gawr - ghostDescription: Из океана... + ghostName: Дракон сингулярности + ghostDescription: Владыка сингулярности diff --git a/Resources/Prototypes/White/Mobs/Species/harpy.yml b/Resources/Prototypes/White/Mobs/Species/harpy.yml index 351a45d5ae..1f16f43833 100644 --- a/Resources/Prototypes/White/Mobs/Species/harpy.yml +++ b/Resources/Prototypes/White/Mobs/Species/harpy.yml @@ -45,6 +45,8 @@ type: SpellSelectorBUI - key: enum.CultEmpowerRemoveUiKey.Key type: SpellRemoverBUI + - key: enum.BloodRitesUi.Key + type: CultistFactoryBUI # WD-EDIT END - type: Sprite scale: 0.9, 0.9 diff --git a/Resources/Prototypes/White/Mood/generic_positveEffects.yml b/Resources/Prototypes/White/Mood/generic_positveEffects.yml index 71fd30dc0b..539b9a2a68 100644 --- a/Resources/Prototypes/White/Mood/generic_positveEffects.yml +++ b/Resources/Prototypes/White/Mood/generic_positveEffects.yml @@ -50,3 +50,10 @@ desc: "Знаю правду, славим великого!" moodChange: enum.MoodChangeLevel.Big positiveEffect: true + +- type: moodEffect + id: Stimulator + desc: "Я ЧУВСТВУЮ ЭТО, В МОЕЙ КРОВИ НАХОДИТСЯ ЧТО-ТО НЕОБЫЧНОЕ!!" + moodChange: enum.MoodChangeLevel.Medium + positiveEffect: true + timeout: 2 \ No newline at end of file diff --git a/Resources/Prototypes/_White/Actions/cult_actions.yml b/Resources/Prototypes/_White/Actions/cult_actions.yml index 099a61f336..fd5098ee21 100644 --- a/Resources/Prototypes/_White/Actions/cult_actions.yml +++ b/Resources/Prototypes/_White/Actions/cult_actions.yml @@ -27,8 +27,6 @@ - HumanoidAppearance - Cultist canTargetSelf: true - deselectOnMiss: true - repeat: false icon: sprite: /Textures/White/Cult/actions_cult.rsi state: teleport @@ -50,8 +48,6 @@ - HumanoidAppearance - Cultist canTargetSelf: true - deselectOnMiss: true - repeat: false icon: sprite: /Textures/White/Cult/actions_cult.rsi state: armor @@ -72,8 +68,6 @@ components: - HumanoidAppearance canTargetSelf: false - deselectOnMiss: true - repeat: false icon: sprite: /Textures/White/Cult/actions_cult.rsi state: stun @@ -94,8 +88,6 @@ components: - HumanoidAppearance canTargetSelf: false - deselectOnMiss: true - repeat: false icon: sprite: /Textures/White/Cult/actions_cult.rsi state: shackles @@ -131,7 +123,7 @@ sprite: /Textures/White/Cult/actions_cult.rsi state: blood_rites event: !type:CultBloodRitesInstantActionEvent - charges: 4 + charges: 5 temporary: true removeOnNoCharges: true @@ -149,3 +141,27 @@ charges: 1 temporary: true removeOnNoCharges: true + +- type: entity + id: InstantActionConcealPresence + name: Conceal Presence + description: A multi-function spell that alternates between hiding and revealing nearby runes and cult structures. + noSpawn: true + components: + - type: InstantAction + icon: + sprite: /Textures/White/Cult/actions_cult.rsi + state: gone + event: !type:CultConcealInstantActionEvent + charges: 10 + temporary: true + removeOnNoCharges: true + - type: ConcealPresenceSpell + concealEvent: !type:CultConcealInstantActionEvent + revealEvent: !type:CultRevealInstantActionEvent + concealIcon: + sprite: /Textures/White/Cult/actions_cult.rsi + state: gone + revealIcon: + sprite: /Textures/White/Cult/actions_cult.rsi + state: telerune diff --git a/Resources/Prototypes/_White/Construction/Cult/graphs.yml b/Resources/Prototypes/_White/Construction/Cult/graphs.yml index 73a6574d4e..fafb578917 100644 --- a/Resources/Prototypes/_White/Construction/Cult/graphs.yml +++ b/Resources/Prototypes/_White/Construction/Cult/graphs.yml @@ -64,6 +64,18 @@ doAfter: 1 - node: airlock entity: AirlockGlassCult + edges: + - to: start + completed: + - !type:SpawnPrototype + prototype: CultRunicMetal1 + amount: 1 + - !type:DeleteEntity { } + conditions: + - !type:EntityAnchored + steps: + - tool: Dagger + cultistOnly: true - type: constructionGraph id: CultPylon diff --git a/Resources/Prototypes/_White/Construction/Cult/structures.yml b/Resources/Prototypes/_White/Construction/Cult/structures.yml index 212fa632ee..96c575d359 100644 --- a/Resources/Prototypes/_White/Construction/Cult/structures.yml +++ b/Resources/Prototypes/_White/Construction/Cult/structures.yml @@ -1,4 +1,4 @@ -- type: construction +- type: construction id: CultGirder name: руническая балка description: Большой конструктивный элемент, изготовленный из металла. На этом есть руна. @@ -37,7 +37,7 @@ - type: construction id: CultPylon name: пилон - description: Мистический конструкция. + description: Мистическая конструкция. graph: CultPylon startNode: start targetNode: pylon diff --git a/Resources/Prototypes/_White/Entities/Boxes/mindshiled.yml b/Resources/Prototypes/_White/Entities/Boxes/mindshiled.yml new file mode 100644 index 0000000000..53089cc893 --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Boxes/mindshiled.yml @@ -0,0 +1,14 @@ +- type: entity + name: mindshield implanters box + parent: BoxCardboard + id: BoxMindshield + description: A box full of implants. + components: + - type: StorageFill + contents: + - id: MindShieldImplanter + amount: 4 + - type: Sprite + layers: + - state: box + - state: syringe diff --git a/Resources/Prototypes/_White/Entities/Cult/Altars/cult_altars.yml b/Resources/Prototypes/_White/Entities/Cult/Altars/cult_altars.yml index ff772fa561..7498ec6ef5 100644 --- a/Resources/Prototypes/_White/Entities/Cult/Altars/cult_altars.yml +++ b/Resources/Prototypes/_White/Entities/Cult/Altars/cult_altars.yml @@ -68,6 +68,7 @@ - type: Construction graph: CultPylon node: pylon + - type: Concealable - type: entity id: AltarTome @@ -127,6 +128,7 @@ - type: Construction graph: AltarTome node: tome + - type: Concealable - type: entity id: CultBloodAltar @@ -185,6 +187,7 @@ - type: Construction graph: CultBloodAltar node: altar + - type: Concealable - type: entity id: CultForge @@ -247,6 +250,7 @@ - type: Construction graph: CultForge node: forge + - type: Concealable - type: cultStructure id: CultStructureAltarTome diff --git a/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml b/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml new file mode 100644 index 0000000000..2e0c5d4452 --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Cult/Items/blood_barrage.yml @@ -0,0 +1,34 @@ +- type: entity + name: blood bolt barrage + parent: BaseItem + id: BloodBarrage + description: Blood for blood. + components: + - type: Sprite + sprite: White/Cult/Entities/arcane_barrage.rsi + state: icon + - type: Item + size: Ginormous + sprite: White/Cult/Entities/arcane_barrage.rsi + - type: AmmoCounter + - type: Gun + fireRate: 4 + selectedMode: SemiAuto + availableModes: + - SemiAuto + soundEmpty: null + soundGunshot: + path: /Audio/White/Cult/wand_teleport.ogg + - type: BasicEntityAmmoProvider + proto: BloodBolt + capacity: 25 + - type: BoltBarrage + - type: GiftIgnore + +- type: cultistFactoryProduction + id: FactoryCultBloodBarrage + name: Залп Кровавых Снарядов (300 крови) + icon: "/Textures/White/Cult/Entities/arcane_barrage.rsi/icon.png" + bloodCost: 300 + item: + - BloodBarrage diff --git a/Resources/Prototypes/_White/Entities/Cult/Items/soul_shard.yml b/Resources/Prototypes/_White/Entities/Cult/Items/soul_shard.yml index 58a4d115d7..1c95a849dd 100644 --- a/Resources/Prototypes/_White/Entities/Cult/Items/soul_shard.yml +++ b/Resources/Prototypes/_White/Entities/Cult/Items/soul_shard.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity name: soul shard description: Mysterious glowing shard. parent: BaseItem @@ -25,6 +25,7 @@ True: { state: "soulstone2" } False: { state: "soulstone" } - type: Speech + - type: IsDeadIC - type: entity parent: SoulShard diff --git a/Resources/Prototypes/_White/Entities/Cult/Items/tome_craft.yml b/Resources/Prototypes/_White/Entities/Cult/Items/tome_craft.yml index bd532120f0..3816ff0208 100644 --- a/Resources/Prototypes/_White/Entities/Cult/Items/tome_craft.yml +++ b/Resources/Prototypes/_White/Entities/Cult/Items/tome_craft.yml @@ -49,6 +49,7 @@ - type: ShowHealthIcons damageContainers: - Biological + - type: ShowSecurityIcons - type: entity name: veil shifter diff --git a/Resources/Prototypes/_White/Entities/Cult/Runes/cult_runes.yml b/Resources/Prototypes/_White/Entities/Cult/Runes/cult_runes.yml index 587fad5cab..0ab3d8e9ed 100644 --- a/Resources/Prototypes/_White/Entities/Cult/Runes/cult_runes.yml +++ b/Resources/Prototypes/_White/Entities/Cult/Runes/cult_runes.yml @@ -14,6 +14,7 @@ invokePhrase: "Mah'weyh pleggh at e'ntrath!" - type: CultRuneOffering - type: CultRune + - type: Concealable - type: entity parent: CollideRune @@ -31,6 +32,7 @@ invokePhrase: "Qu'laris ver'don, thal'sorin mik'thar!" - type: CultRuneBuff - type: CultRune + - type: Concealable - type: entity parent: CollideRune @@ -52,6 +54,8 @@ - key: enum.CultEmpowerUiKey.Key type: SpellSelectorBUI - type: CultRune + - type: Concealable + examinableWhileConcealed: true - type: entity parent: CollideRune @@ -71,6 +75,7 @@ - type: CultRuneTeleport label: "безымянная метка" - type: CultRune + - type: Concealable - type: entity parent: CollideRune @@ -89,6 +94,7 @@ gatherInvokers: true - type: CultRuneSummoning - type: CultRune + - type: Concealable - type: entity parent: CollideRune @@ -106,6 +112,7 @@ invokePhrase: "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" - type: CultRuneRevive - type: CultRune + - type: Concealable - type: entity parent: CollideRune @@ -123,6 +130,7 @@ invokePhrase: "Khari'd! Eske'te tannin!" - type: CultRuneBarrier - type: CultRune + - type: Concealable - type: entity parent: CollideRune @@ -141,6 +149,7 @@ - type: CultRuneBloodBoil projectilePrototype: ProjectileCult - type: CultRune + - type: Concealable - type: entity parent: BaseRune @@ -155,4 +164,5 @@ - type: Appearance - type: CultRuneBase invokePhrase: "TOK-LYR RQA-NAP G'OLT-ULOFT!" + cultistGatheringRange: 1.5 - type: CultRuneApocalypse diff --git a/Resources/Prototypes/_White/Entities/Cult/Weapons/blood_spear.yml b/Resources/Prototypes/_White/Entities/Cult/Weapons/blood_spear.yml new file mode 100644 index 0000000000..dfcdfc7c9b --- /dev/null +++ b/Resources/Prototypes/_White/Entities/Cult/Weapons/blood_spear.yml @@ -0,0 +1,82 @@ +- type: entity + name: blood spear + parent: BaseItem + id: BloodSpear + description: A sickening spear composed entirely of crystallized blood. + components: + - type: EmbeddableProjectile + offset: 0.15,0.15 + - type: ThrowingAngle + angle: 225 + - type: Fixtures + fixtures: + fix1: + shape: !type:PolygonShape + vertices: + - -0.20,-0.10 + - -0.10,-0.20 + - 0.40,0.30 + - 0.30,0.40 + density: 20 + mask: + - ItemMask + restitution: 0.3 + friction: 0.2 + - type: Sharp + - type: Sprite + sprite: White/Cult/Entities/blood_spear.rsi + state: icon + - type: MeleeWeapon + wideAnimationRotation: -135 + damage: + types: + Piercing: 36 + angle: 0 + animation: WeaponArcThrust + soundHit: + path: /Audio/Weapons/bladeslice.ogg + range: 2 + - type: DamageOtherOnHit + damage: + types: + Piercing: 40 + - type: Item + sprite: White/Cult/Entities/blood_spear.rsi + size: Ginormous + - type: Clothing + slots: + - back + - type: Wieldable + - type: IncreaseDamageOnWield + damage: + types: + Piercing: 8 + - type: UseDelay + - type: DisarmMalus + - type: CultItem + - type: BloodSpear + action: InstantActionRecallBloodSpear + - type: ChangeThrowForce + throwForce: 20 + +- type: cultistFactoryProduction + id: FactoryCultBloodSpear + name: Кровавое Копьё (150 крови) + icon: "/Textures/White/Cult/Entities/blood_spear.rsi/icon.png" + bloodCost: 150 + item: + - BloodSpear + +- type: entity + id: InstantActionRecallBloodSpear + name: Recall Blood Spear + description: Recalls blood spear to your hand. + noSpawn: true + components: + - type: InstantAction + icon: + sprite: /Textures/White/Cult/actions_cult.rsi + state: bloodspear + event: !type:CultBloodSpearRecallInstantActionEvent + useDelay: 1 + temporary: true diff --git a/Resources/Prototypes/_White/Entities/Cult/constructs.yml b/Resources/Prototypes/_White/Entities/Cult/constructs.yml index e3793c1cc4..25704d1d7a 100644 --- a/Resources/Prototypes/_White/Entities/Cult/constructs.yml +++ b/Resources/Prototypes/_White/Entities/Cult/constructs.yml @@ -60,6 +60,18 @@ - type: Pullable - type: ContentEye - type: Actions + - type: Hands + - type: ShowCultHud + - type: IsDeadIC + - type: NightVision + toggleSound: null + color: White + - type: ShowWhiteHealthBars + damageContainers: + - Biological + - type: ShowHealthIcons + damageContainers: + - Biological - type: Tag tags: - CannotSuicide @@ -77,17 +89,15 @@ thresholds: 0: Alive 150: Dead - - type: MovementSpeedModifier - baseWalkSpeed: 2 - baseSprintSpeed: 2 - type: Construct actions: - InstantActionJuggernautCreateWall - type: MeleeWeapon + canHeavyAttack: false hidden: true angle: 30 - animation: WeaponArcFist - attackRate: 0.25 + animation: WeaponArcSmash + attackRate: 1 damage: types: Structural: 90 @@ -114,13 +124,18 @@ InstantActionArtificerCreateCultistWall, InstantActionArtificerCreateCultistAirlock, ] + - type: MovementSpeedModifier + baseWalkSpeed: 3 + baseSprintSpeed: 3 + - type: MovementIgnoreGravity - type: Puller needsHands: false - type: MeleeWeapon + canHeavyAttack: false hidden: true angle: 30 - animation: WeaponArcFist - attackRate: 0.85 + animation: WeaponArcPunch + attackRate: 1 damage: types: Blunt: 5 @@ -133,8 +148,8 @@ description: run... components: - type: MovementSpeedModifier - baseWalkSpeed: 3.0 - baseSprintSpeed: 3.0 + baseWalkSpeed: 4.0 + baseSprintSpeed: 4.0 - type: MobThresholds thresholds: 0: Alive @@ -148,14 +163,16 @@ actions: [InstantActionWraithPhase] - type: MovementIgnoreGravity - type: MeleeWeapon + canHeavyAttack: false hidden: true angle: 30 - animation: WeaponArcFist - attackRate: 0.5 + animation: WeaponArcPunch + attackRate: 1 damage: types: Blunt: 10 Slash: 10 + Structural: 40 - type: entity id: ReaperConstruct @@ -165,8 +182,8 @@ components: - type: MovementIgnoreGravity - type: MovementSpeedModifier - baseWalkSpeed: 3.0 - baseSprintSpeed: 3.0 + baseWalkSpeed: 5.0 + baseSprintSpeed: 5.0 - type: MobThresholds thresholds: 0: Alive @@ -176,10 +193,11 @@ - type: Puller needsHands: false - type: MeleeWeapon + canHeavyAttack: false hidden: true angle: 30 - animation: WeaponArcFist - attackRate: 0.9 + animation: WeaponArcPunch + attackRate: 1 damage: types: Blunt: 20 diff --git a/Resources/Prototypes/_White/Entities/Cult/other_structures.yml b/Resources/Prototypes/_White/Entities/Cult/other_structures.yml index 85244ec319..78a1a35f5d 100644 --- a/Resources/Prototypes/_White/Entities/Cult/other_structures.yml +++ b/Resources/Prototypes/_White/Entities/Cult/other_structures.yml @@ -9,7 +9,7 @@ Brute: collection: GlassSmash - type: Sprite - sprite: /Textures/White/Cult/Structures/cult_airlock.rsi + sprite: White/Cult/Structures/cult_airlock.rsi layers: - state: closed map: ["enum.DoorVisualLayers.Base"] @@ -18,8 +18,8 @@ - type: Occluder enabled: false - type: Door - occludes: false bumpOpen: true + occludes: false crushDamage: types: Blunt: 15 @@ -27,8 +27,6 @@ path: /Audio/Effects/stonedoor_openclose.ogg closeSound: path: /Audio/Effects/stonedoor_openclose.ogg - denySound: - path: /Audio/Machines/airlock_deny.ogg - type: Airtight fixVacuum: true noAirWhenFullyAirBlocked: false @@ -38,7 +36,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 500 + damage: 200 behaviors: - !type:DoActsBehavior acts: ["Destruction"] @@ -48,6 +46,22 @@ node: airlock - type: PlacementReplacement key: walls + - type: Appearance + - type: Concealable + examinableWhileConcealed: true + iconSmooth: true + interactionOutline: true + concealedSprite: White/Cult/Structures/Concealed/cult_airlock.rsi + revealedSprite: White/Cult/Structures/cult_airlock.rsi + changeMeta: true + concealedName: обычная стена + concealedDesc: Удерживает воздух внутри, а ассистентов снаружи. + revealedName: рунический шлюз + revealedDesc: Странный стеклянный шлюз с руной. + - type: IconSmooth + enabled: false + key: walls + mode: NoSprite placement: mode: SnapgridCenter @@ -75,7 +89,7 @@ - GlassAirlockLayer - type: InteractionOutline - type: Sprite - sprite: /Textures/White/Cult/Structures/cult_girder.rsi + sprite: White/Cult/Structures/cult_girder.rsi state: cultgirder - type: Damageable damageContainer: StructuralInorganic @@ -104,3 +118,13 @@ - type: Construction graph: CultGirder node: girder + - type: Appearance + - type: Concealable + examinableWhileConcealed: true + concealedSprite: White/Cult/Structures/Concealed/cult_girder.rsi + revealedSprite: White/Cult/Structures/cult_girder.rsi + changeMeta: true + concealedName: каркас + concealedDesc: Большой металлический каркас; Необходимо покрыть листами металла, чтобы он считался стеной. + revealedName: руническая балка + revealedDesc: Большой конструктивный элемент, изготовленный из металла. На этом есть руна. diff --git a/Resources/Prototypes/_White/Tiles/cult.yml b/Resources/Prototypes/_White/Tiles/cult.yml index 8e735e076d..ae49e33345 100644 --- a/Resources/Prototypes/_White/Tiles/cult.yml +++ b/Resources/Prototypes/_White/Tiles/cult.yml @@ -1,4 +1,4 @@ -- type: tile +- type: tile id: CultFloor name: tiles-cult-floor sprite: /Textures/White/Cult/Tiles/cult_tile.rsi/cult.png @@ -10,3 +10,20 @@ collection: FootstepFloor itemDrop: FloorTileItemSteel heatCapacity: 10000 + +- type: tile + id: CultFloorConcealed + name: tiles-steel-floor + sprite: /Textures/White/Cult/Tiles/concealed.png + variants: 3 + placementVariants: + - 1.0 + - 1.0 + - 1.0 + baseTurf: Plating + isSubfloor: false + deconstructTools: [ Prying ] + footstepSounds: + collection: FootstepFloor + itemDrop: FloorTileItemSteel + heatCapacity: 10000 diff --git a/Resources/Prototypes/_White/narsie.yml b/Resources/Prototypes/_White/narsie.yml index f25956f309..221ed2fa13 100644 --- a/Resources/Prototypes/_White/narsie.yml +++ b/Resources/Prototypes/_White/narsie.yml @@ -1,7 +1,20 @@ -- type: entity +- type: entity id: Narsie + parent: BaseMob name: Nar'si components: + - type: AnnounceOnSpawn + message: narsie-has-risen + sender: narsie-has-risen-sender + sound: + path: /Audio/Misc/narsie_rises.ogg + color: darkred + - type: CargoSellBlacklist + - type: ContentEye + maxZoom: 2.0,2.0 + - type: WarpPoint + follow: true + location: Nar'Sie - type: Sprite layers: - map: [ "enum.NarsieLayer.Default" ] @@ -15,6 +28,8 @@ - type: Narsie - type: Physics bodyType: Dynamic + bodyStatus: InAir + - type: CanMoveInAir - type: Fixtures fixtures: Penis: diff --git a/Resources/Prototypes/status_effects.yml b/Resources/Prototypes/status_effects.yml index 1c2bd7fbf8..a9ea56db57 100644 --- a/Resources/Prototypes/status_effects.yml +++ b/Resources/Prototypes/status_effects.yml @@ -64,6 +64,10 @@ id: BlurryVision alwaysAllowed: true +- type: statusEffect + id: NarcoticEffect + alwaysAllowed: true + #WD EDIT - type: statusEffect id: Incorporeal diff --git a/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/bullet.png b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/bullet.png new file mode 100644 index 0000000000..98351139f2 Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/bullet.png differ diff --git a/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/icon.png b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/icon.png new file mode 100644 index 0000000000..678418769a Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/icon.png differ diff --git a/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/inhand-left.png b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/inhand-left.png new file mode 100644 index 0000000000..5aa69c6f0c Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/inhand-right.png b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/inhand-right.png new file mode 100644 index 0000000000..72d7a44ff7 Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/meta.json b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/meta.json new file mode 100644 index 0000000000..39fae95edd --- /dev/null +++ b/Resources/Textures/White/Cult/Entities/arcane_barrage.rsi/meta.json @@ -0,0 +1,77 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "inhand-right", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "bullet", + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/White/Cult/Entities/blood_spear.rsi/icon.png b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/icon.png new file mode 100644 index 0000000000..8a1814a9bb Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/icon.png differ diff --git a/Resources/Textures/White/Cult/Entities/blood_spear.rsi/inhand-left.png b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/inhand-left.png new file mode 100644 index 0000000000..6dbe881610 Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Cult/Entities/blood_spear.rsi/inhand-right.png b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/inhand-right.png new file mode 100644 index 0000000000..ff278aaf9b Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Cult/Entities/blood_spear.rsi/meta.json b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/meta.json new file mode 100644 index 0000000000..caacbe7781 --- /dev/null +++ b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/meta.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from yogstation", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "wielded-inhand-left", + "directions": 4 + }, + { + "name": "wielded-inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/White/Cult/Entities/blood_spear.rsi/wielded-inhand-left.png b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/wielded-inhand-left.png new file mode 100644 index 0000000000..def85c257f Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/wielded-inhand-left.png differ diff --git a/Resources/Textures/White/Cult/Entities/blood_spear.rsi/wielded-inhand-right.png b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/wielded-inhand-right.png new file mode 100644 index 0000000000..def85c257f Binary files /dev/null and b/Resources/Textures/White/Cult/Entities/blood_spear.rsi/wielded-inhand-right.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult0.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult0.png new file mode 100644 index 0000000000..404b6ac1c6 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult0.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult1.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult1.png new file mode 100644 index 0000000000..258b734263 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult1.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult2.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult2.png new file mode 100644 index 0000000000..404b6ac1c6 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult2.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult3.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult3.png new file mode 100644 index 0000000000..258b734263 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult3.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult4.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult4.png new file mode 100644 index 0000000000..5af1322d5e Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult4.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult5.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult5.png new file mode 100644 index 0000000000..773e85c48a Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult5.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult6.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult6.png new file mode 100644 index 0000000000..5af1322d5e Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult6.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult7.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult7.png new file mode 100644 index 0000000000..47900fe305 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/cult7.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/full.png b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/full.png new file mode 100644 index 0000000000..c3f6fbc79f Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/full.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/meta.json b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/meta.json new file mode 100644 index 0000000000..c289aa5878 --- /dev/null +++ b/Resources/Textures/White/Cult/Structures/Concealed/cult.rsi/meta.json @@ -0,0 +1 @@ +{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "https://github.com/vgstation-coders/vgstation13/raw/99cc2ab62d65a3a7b554dc7b21ff5f57c835f973/icons/turf/walls.dmi", "states": [{"name": "cult0", "directions": 4}, {"name": "cult1", "directions": 4}, {"name": "cult2", "directions": 4}, {"name": "cult3", "directions": 4}, {"name": "cult4", "directions": 4}, {"name": "cult5", "directions": 4}, {"name": "cult6", "directions": 4}, {"name": "cult7", "directions": 4}, {"name": "full"}]} \ No newline at end of file diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/assembly.png b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/assembly.png new file mode 100644 index 0000000000..e872d82c5d Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/assembly.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/closed.png b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/closed.png new file mode 100644 index 0000000000..198151d903 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/closed.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/closing.png b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/closing.png new file mode 100644 index 0000000000..96bba25801 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/closing.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/meta.json b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/meta.json new file mode 100644 index 0000000000..7e8135f216 --- /dev/null +++ b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/meta.json @@ -0,0 +1,60 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by Nimfar11 (GitHub) for Space Station 14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "assembly" + }, + { + "name": "closed", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "closing", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "open", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "opening", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + } + ] +} diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/open.png b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/open.png new file mode 100644 index 0000000000..7ca06de1ed Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/open.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/opening.png b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/opening.png new file mode 100644 index 0000000000..861f6fbbc3 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult_airlock.rsi/opening.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_girder.rsi/cultgirder.png b/Resources/Textures/White/Cult/Structures/Concealed/cult_girder.rsi/cultgirder.png new file mode 100644 index 0000000000..2453b42338 Binary files /dev/null and b/Resources/Textures/White/Cult/Structures/Concealed/cult_girder.rsi/cultgirder.png differ diff --git a/Resources/Textures/White/Cult/Structures/Concealed/cult_girder.rsi/meta.json b/Resources/Textures/White/Cult/Structures/Concealed/cult_girder.rsi/meta.json new file mode 100644 index 0000000000..7ea2c16749 --- /dev/null +++ b/Resources/Textures/White/Cult/Structures/Concealed/cult_girder.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/frosty-dev/white", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "cultgirder" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/White/Cult/Tiles/concealed.png b/Resources/Textures/White/Cult/Tiles/concealed.png new file mode 100644 index 0000000000..1c9c4588d1 Binary files /dev/null and b/Resources/Textures/White/Cult/Tiles/concealed.png differ diff --git a/Resources/Textures/White/Fluff/kreses/boots.rsi/equipped-FEET-reptilian.png b/Resources/Textures/White/Fluff/kreses/boots.rsi/equipped-FEET-reptilian.png new file mode 100644 index 0000000000..b494ac03d2 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/boots.rsi/equipped-FEET-reptilian.png differ diff --git a/Resources/Textures/White/Fluff/kreses/boots.rsi/equipped-FEET.png b/Resources/Textures/White/Fluff/kreses/boots.rsi/equipped-FEET.png new file mode 100644 index 0000000000..72dabdd965 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/boots.rsi/equipped-FEET.png differ diff --git a/Resources/Textures/White/Fluff/kreses/boots.rsi/icon.png b/Resources/Textures/White/Fluff/kreses/boots.rsi/icon.png new file mode 100644 index 0000000000..60196610b2 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/boots.rsi/icon.png differ diff --git a/Resources/Textures/White/Fluff/kreses/boots.rsi/inhand-left.png b/Resources/Textures/White/Fluff/kreses/boots.rsi/inhand-left.png new file mode 100644 index 0000000000..511b29debd Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/boots.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Fluff/kreses/boots.rsi/inhand-right.png b/Resources/Textures/White/Fluff/kreses/boots.rsi/inhand-right.png new file mode 100644 index 0000000000..93a97fbc64 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/boots.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Fluff/kreses/boots.rsi/meta.json b/Resources/Textures/White/Fluff/kreses/boots.rsi/meta.json new file mode 100644 index 0000000000..76b2013cf1 --- /dev/null +++ b/Resources/Textures/White/Fluff/kreses/boots.rsi/meta.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by @ninruB#7795, based off tgstation's jackboots at commit https://github.com/tgstation/tgstation/commit/7e4e9d432d88981fb9bb463970c5b98ce85c0abe, reptilian made by kuro(388673708753027083)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-FEET", + "directions": 4 + }, + { + "name": "equipped-FEET-reptilian", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/White/Fluff/kreses/coat.rsi/equipped-OUTERCLOTHING.png b/Resources/Textures/White/Fluff/kreses/coat.rsi/equipped-OUTERCLOTHING.png new file mode 100644 index 0000000000..3b632e3d71 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/coat.rsi/equipped-OUTERCLOTHING.png differ diff --git a/Resources/Textures/White/Fluff/kreses/coat.rsi/icon.png b/Resources/Textures/White/Fluff/kreses/coat.rsi/icon.png new file mode 100644 index 0000000000..bedf81bc05 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/coat.rsi/icon.png differ diff --git a/Resources/Textures/White/Fluff/kreses/coat.rsi/inhand-left.png b/Resources/Textures/White/Fluff/kreses/coat.rsi/inhand-left.png new file mode 100644 index 0000000000..19094f2f37 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/coat.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Fluff/kreses/coat.rsi/inhand-right.png b/Resources/Textures/White/Fluff/kreses/coat.rsi/inhand-right.png new file mode 100644 index 0000000000..de439abc1e Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/coat.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Fluff/kreses/coat.rsi/meta.json b/Resources/Textures/White/Fluff/kreses/coat.rsi/meta.json new file mode 100644 index 0000000000..e482264df5 --- /dev/null +++ b/Resources/Textures/White/Fluff/kreses/coat.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-OUTERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/White/Fluff/kreses/sachel.rsi/equipped-BACKPACK.png b/Resources/Textures/White/Fluff/kreses/sachel.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..fa0cdabd18 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/sachel.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/White/Fluff/kreses/sachel.rsi/icon.png b/Resources/Textures/White/Fluff/kreses/sachel.rsi/icon.png new file mode 100644 index 0000000000..e50fe18a61 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/sachel.rsi/icon.png differ diff --git a/Resources/Textures/White/Fluff/kreses/sachel.rsi/inhand-left.png b/Resources/Textures/White/Fluff/kreses/sachel.rsi/inhand-left.png new file mode 100644 index 0000000000..8929e28860 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/sachel.rsi/inhand-left.png differ diff --git a/Resources/Textures/White/Fluff/kreses/sachel.rsi/inhand-right.png b/Resources/Textures/White/Fluff/kreses/sachel.rsi/inhand-right.png new file mode 100644 index 0000000000..ef10784276 Binary files /dev/null and b/Resources/Textures/White/Fluff/kreses/sachel.rsi/inhand-right.png differ diff --git a/Resources/Textures/White/Fluff/kreses/sachel.rsi/meta.json b/Resources/Textures/White/Fluff/kreses/sachel.rsi/meta.json new file mode 100644 index 0000000000..819e5c0d2b --- /dev/null +++ b/Resources/Textures/White/Fluff/kreses/sachel.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/2e24b7af2221928e4b844a29408e821b60a5fe29, modified by linkblyat (Discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +}