Merge pull request #101 from frosty-dev/ups

Ups
This commit is contained in:
Jabak
2024-07-29 13:01:26 +03:00
committed by GitHub
167 changed files with 2923 additions and 468 deletions

View File

@@ -1,5 +1,6 @@
using Content.Client.Administration.Managers;
using Content.Client.Ghost;
using Content.Shared._White.Cult.Components;
using Content.Shared.Administration;
using Content.Shared.Changeling;
using Content.Shared.Chat;
@@ -54,7 +55,8 @@ namespace Content.Client.Chat.Managers
case ChatSelectChannel.Cult:
var localEnt = _player.LocalPlayer != null ? _player.LocalPlayer.ControlledEntity : null;
if (_entityManager.TryGetComponent(localEnt, out CultistComponent? comp))
if (_entityManager.HasComponent<CultistComponent>(localEnt) ||
_entityManager.HasComponent<ConstructComponent>(localEnt))
_consoleHost.ExecuteCommand($"csay \"{CommandParsing.Escape(text)}\"");
break;

View File

@@ -56,7 +56,7 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
}
// If the placer has not changed, exit
_rcdSystem.UpdateCachedPrototype(heldEntity.Value, rcd);
_rcdSystem.UpdateCachedPrototype(rcd);
if (heldEntity == placerEntity && rcd.CachedPrototype.Prototype == placerProto)
return;

View File

@@ -1,47 +1,19 @@
<ui:RadialMenu xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:rcd="clr-namespace:Content.Client.RCD"
BackButtonStyleClass="RadialMenuBackButton"
CloseButtonStyleClass="RadialMenuCloseButton"
VerticalExpand="True"
HorizontalExpand="True"
MinSize="450 450">
<!-- Note: The min size of the window just determine how close to the edge of the screen the center of the radial menu can be placed -->
<!-- The radial menu will try to open so that its center is located where the player's cursor is currently -->
<!-- Entry layer (shows main categories) -->
<ui:RadialContainer Name="Main" VerticalExpand="True" HorizontalExpand="True" Radius="64" ReserveSpaceForHiddenChildren="False">
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rcd-component-walls-and-flooring'}" TargetLayer="WallsAndFlooring" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Interface/Radial/RCD/walls_and_flooring.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rcd-component-windows-and-grilles'}" TargetLayer="WindowsAndGrilles" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Interface/Radial/RCD/windows_and_grilles.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rcd-component-airlocks'}" TargetLayer="Airlocks" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Interface/Radial/RCD/airlocks.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rcd-component-electrical'}" TargetLayer="Electrical" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Interface/Radial/RCD/multicoil.png"/>
</ui:RadialMenuTextureButton>
<ui:RadialMenuTextureButton StyleClasses="RadialMenuButton" SetSize="64 64" ToolTip="{Loc 'rcd-component-lighting'}" TargetLayer="Lighting" Visible="False">
<TextureRect VerticalAlignment="Center" HorizontalAlignment="Center" TextureScale="2 2" TexturePath="/Textures/Interface/Radial/RCD/lighting.png"/>
</ui:RadialMenuTextureButton>
<!-- Categories -->
</ui:RadialContainer>
<!-- Walls and flooring -->
<ui:RadialContainer Name="WallsAndFlooring" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Windows and grilles -->
<ui:RadialContainer Name="WindowsAndGrilles" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Airlocks -->
<ui:RadialContainer Name="Airlocks" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Computer and machine frames -->
<ui:RadialContainer Name="Electrical" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Lighting -->
<ui:RadialContainer Name="Lighting" VerticalExpand="True" HorizontalExpand="True" Radius="64"/>
<!-- Another categories -->
</ui:RadialMenu>

View File

@@ -1,3 +1,4 @@
using System.Linq;
using Content.Client.UserInterface.Controls;
using Content.Shared.Popups;
using Content.Shared.RCD;
@@ -10,6 +11,10 @@ using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Shared.Graphics.RSI;
using Robust.Shared.Serialization.Manager.Exceptions;
using Robust.Shared.Utility;
namespace Content.Client.RCD;
@@ -40,13 +45,12 @@ public sealed partial class RCDMenu : RadialMenu
// Find the main radial container
var main = FindControl<RadialContainer>("Main");
if (main == null)
return;
// Populate secondary radial containers
if (!_entManager.TryGetComponent<RCDComponent>(owner, out var rcd))
return;
SetupCategories(main, rcd); // WD
foreach (var protoId in rcd.AvailablePrototypes)
{
if (!_protoManager.TryIndex(protoId, out var proto))
@@ -55,12 +59,9 @@ public sealed partial class RCDMenu : RadialMenu
if (proto.Mode == RcdMode.Invalid)
continue;
var parent = FindControl<RadialContainer>(proto.Category);
var parent = Children.First(c => c.Name == proto.Category.Id);
if (parent == null)
continue;
var tooltip = Loc.GetString(proto.SetName);
var tooltip = Loc.GetString(proto.Name);
if ((proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject) &&
proto.Prototype != null && _protoManager.TryIndex(proto.Prototype, out var entProto))
@@ -80,17 +81,16 @@ public sealed partial class RCDMenu : RadialMenu
if (proto.Sprite != null)
{
var tex = new TextureRect()
var tex = new TextureRect
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Texture = _spriteSystem.Frame0(proto.Sprite),
Texture = GetSprite(proto.Sprite),
TextureScale = new Vector2(2f, 2f),
};
button.AddChild(tex);
}
parent.AddChild(button);
// Ensure that the button that transitions the menu to the associated category layer
@@ -119,6 +119,50 @@ public sealed partial class RCDMenu : RadialMenu
SendRCDSystemMessageAction += bui.SendRCDSystemMessage;
}
private void SetupCategories(RadialContainer main, RCDComponent rcd)
{
foreach (var categoryId in rcd.CategoryPrototypes)
{
if (!_protoManager.TryIndex(categoryId, out var category))
continue;
var button = new RadialMenuTextureButton
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
ToolTip = Loc.GetString(category.TooltipBase + categoryId), // rcd-component- + WindowsAndGrilles = rcd-component-WindowsAndGrilles
TargetLayer = categoryId,
Visible = false,
};
var texture = new TextureRect
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
TextureScale = new Vector2(2, 2),
Texture = GetSprite(category.SpritePath)
};
button.AddChild(texture);
main.AddChild(button);
var container = new RadialContainer
{
Name = categoryId,
VerticalExpand = true,
HorizontalExpand = true,
Radius = 64
};
AddChild(container);
}
}
private Texture GetSprite(SpriteSpecifier specifier)
{
return _spriteSystem.Frame0(specifier);
}
private void AddRCDMenuButtonOnClickActions(Control control)
{
var radialContainer = control as RadialContainer;
@@ -140,11 +184,11 @@ public sealed partial class RCDMenu : RadialMenu
if (_playerManager.LocalSession?.AttachedEntity != null &&
_protoManager.TryIndex(castChild.ProtoId, out var proto))
{
var msg = Loc.GetString("rcd-component-change-mode", ("mode", Loc.GetString(proto.SetName)));
var msg = Loc.GetString("rcd-component-change-mode", ("mode", Loc.GetString(proto.Name)));
if (proto.Mode == RcdMode.ConstructTile || proto.Mode == RcdMode.ConstructObject)
{
var name = Loc.GetString(proto.SetName);
var name = Loc.GetString(proto.Name);
if (proto.Prototype != null &&
_protoManager.TryIndex(proto.Prototype, out var entProto))

View File

@@ -70,9 +70,15 @@ public class RadialContainer : LayoutContainer
protected override void Draw(DrawingHandleScreen handle)
{
const float baseRadius = 15f; // WD
const float radiusIncrement = 12f; // WD
var children = ReserveSpaceForHiddenChildren ? Children : Children.Where(x => x.Visible);
var childCount = children.Count();
// Add padding from the center at higher child counts so they don't overlap.
Radius = baseRadius + (childCount * radiusIncrement);
// Determine the size of the arc, accounting for clockwise and anti-clockwise arrangements
var arc = AngularRange.Y - AngularRange.X;
arc = (arc < 0) ? MathF.Tau + arc : arc;

View File

@@ -20,6 +20,7 @@ using Content.Shared.Damage.ForceSay;
using Content.Shared.Input;
using Content.Shared.Radio;
using Content.Shared._White;
using Content.Shared._White.Cult.Components;
using Content.Shared._White.Utils;
using Content.Shared._White.Cult.Systems;
using Robust.Client.Graphics;
@@ -235,8 +236,8 @@ public sealed class ChatUIController : UIController
_input.SetInputCommand(ContentKeyFunctions.CycleChatChannelBackward,
InputCmdHandler.FromDelegate(_ => CycleChatChannel(false)));
SubscribeLocalEvent<ChangelingUserStart>(OnUpdateChangelingChat);
// WD EDIT
SubscribeLocalEvent<ChangelingUserStart>(OnUpdateChangelingChat);
SubscribeLocalEvent<EventCultistComponentState>(OnUpdateCultState);
// WD EDIT END
@@ -563,7 +564,7 @@ public sealed class ChatUIController : UIController
// WD EDIT
var localEnt = _player.LocalEntity;
if (_entities.HasComponent<CultistComponent>(localEnt))
if (_entities.HasComponent<CultistComponent>(localEnt) || _entities.HasComponent<ConstructComponent>(localEnt))
{
FilterableChannels |= ChatChannel.Cult;
CanSendChannels |= ChatSelectChannel.Cult;

View File

@@ -1,5 +1,4 @@
using Content.Shared._White.Cult;
using Content.Shared._White.Cult.Components;
using Content.Shared._White.Cult.Components;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;
@@ -29,7 +28,7 @@ public sealed class ShowCultHudSystem : EntitySystem
_overlay = new CultHudOverlay(EntityManager);
}
private void OnComponentInit(EntityUid uid, ShowCultHudComponent component, ComponentInit args)
private void OnComponentInit<T>(EntityUid uid, T component, ComponentInit args)
{
if (_player.LocalSession?.AttachedEntity != uid)
return;
@@ -38,7 +37,7 @@ public sealed class ShowCultHudSystem : EntitySystem
}
private void OnComponentRemoved(EntityUid uid, ShowCultHudComponent component, ComponentRemove args)
private void OnComponentRemoved<T>(EntityUid uid, T component, ComponentRemove args)
{
if (_player.LocalSession?.AttachedEntity != uid)
return;
@@ -47,7 +46,7 @@ public sealed class ShowCultHudSystem : EntitySystem
}
private void OnPlayerAttached(EntityUid uid, ShowCultHudComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached<T>(EntityUid uid, T component, PlayerAttachedEvent args)
{
if (_player.LocalSession != args.Player)
return;
@@ -55,7 +54,7 @@ public sealed class ShowCultHudSystem : EntitySystem
_overlayManager.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, ShowCultHudComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached<T>(EntityUid uid, T component, PlayerDetachedEvent args)
{
if (_player.LocalSession != args.Player)
return;

View File

@@ -1,5 +1,6 @@
using System.Linq;
using Content.Client.Construction;
using Content.Shared._White.Cult.Pylon;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Popups;
using Robust.Client.Placement;
@@ -8,60 +9,33 @@ using Robust.Shared.Map;
namespace Content.Client._White.Cult.UI.StructureRadial;
public sealed class CultPylonPlacementHijack : PlacementHijack
public sealed class CultPylonPlacementHijack(ConstructionPrototype? prototype, IEntityManager entMan, EntityUid player)
: PlacementHijack
{
private readonly ConstructionSystem _constructionSystem;
private readonly IEntityManager _entMan;
private readonly ConstructionPrototype? _prototype;
private readonly EntityUid _player;
private readonly ConstructionSystem _constructionSystem = entMan.System<ConstructionSystem>();
public override bool CanRotate { get; }
public CultPylonPlacementHijack(ConstructionPrototype? prototype, IEntityManager entMan, EntityUid player)
{
_prototype = prototype;
_entMan = entMan;
_player = player;
_constructionSystem = entMan.System<ConstructionSystem>();
CanRotate = prototype?.CanRotate ?? true;
}
public override bool CanRotate { get; } = prototype?.CanRotate ?? true;
/// <inheritdoc />
public override bool HijackPlacementRequest(EntityCoordinates coordinates)
{
if (_prototype == null)
if (prototype == null)
return true;
if (CheckForStructure(coordinates))
if (SharedPylonComponent.CheckForStructure(coordinates, entMan, 10f))
{
var popup = _entMan.System<SharedPopupSystem>();
popup.PopupClient(Loc.GetString("cult-structure-craft-another-structure-nearby"), _player, _player);
var popup = entMan.System<SharedPopupSystem>();
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);
_constructionSystem.SpawnGhost(prototype, coordinates, dir);
return true;
}
private bool CheckForStructure(EntityCoordinates coordinates)
{
var lookupSystem = _entMan.System<EntityLookupSystem>();
var entities = lookupSystem.GetEntitiesInRange(coordinates, 10f);
foreach (var ent in entities)
{
if (!_entMan.TryGetComponent<MetaDataComponent>(ent, out var metadata))
continue;
if (metadata.EntityPrototype?.ID is "CultPylon")
return true;
}
return false;
}
/// <inheritdoc />
public override bool HijackDeletion(EntityUid entity)
{
@@ -77,6 +51,6 @@ public sealed class CultPylonPlacementHijack : PlacementHijack
public override void StartHijack(PlacementManager manager)
{
base.StartHijack(manager);
manager.CurrentTextures = _prototype?.Layers.Select(sprite => sprite.DirFrame0()).ToList();
manager.CurrentTextures = prototype?.Layers.Select(sprite => sprite.DirFrame0()).ToList();
}
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Chat.Systems;
using Content.Shared.Administration;
using Content.Shared._White.Cult;
using Content.Shared._White.Cult.Components;
using Robust.Shared.Console;
using Robust.Shared.Enums;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
@@ -35,7 +36,8 @@ namespace Content.Server.Chat.Commands
var entityManager = IoCManager.Resolve<EntityManager>();
if (!entityManager.HasComponent<CultistComponent>(entity))
if (!entityManager.HasComponent<CultistComponent>(entity) &&
!entityManager.HasComponent<ConstructComponent>(entity))
{
return;
}

View File

@@ -3,6 +3,7 @@ using Content.Server.Damage.Components;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Camera;
using Content.Server._White.Crossbow;
using Content.Shared._White.Cult.Systems;
using Content.Shared.Damage;
using Content.Shared.Damage.Events;
using Content.Shared.Damage.Systems;
@@ -30,7 +31,8 @@ namespace Content.Server.Damage.Systems
public override void Initialize()
{
SubscribeLocalEvent<DamageOtherOnHitComponent, ThrowDoHitEvent>(OnDoHit,
before: new[] {typeof(MeleeThrowOnHitSystem)}); // WD EDIT
before: new[] {typeof(MeleeThrowOnHitSystem)},
after: new[] {typeof(BloodSpearSystem)}); // WD EDIT
SubscribeLocalEvent<DamageOtherOnHitComponent, DamageExamineEvent>(OnDamageExamine);
}

View File

@@ -217,7 +217,6 @@ namespace Content.Server.GameTicking
var readyPlayers = new List<ICommonSession>();
var readyPlayerProfiles = new Dictionary<NetUserId, HumanoidCharacterProfile>();
var autoDeAdmin = _cfg.GetCVar(CCVars.AdminDeadminOnJoin);
var stalinBunkerEnabled = _configurationManager.GetCVar(WhiteCVars.StalinEnabled);
foreach (var (userId, status) in _playerGameStatuses)
@@ -225,11 +224,17 @@ namespace Content.Server.GameTicking
if (LobbyEnabled && status != PlayerGameStatus.ReadyToPlay) continue;
if (!_playerManager.TryGetSessionById(userId, out var session)) continue;
#if FULL_RELEASE // dont deadmin me in debug
var autoDeAdmin = _cfg.GetCVar(CCVars.AdminDeadminOnJoin);
if (autoDeAdmin && _adminManager.IsAdmin(session))
{
_adminManager.DeAdmin(session);
}
#endif
if (stalinBunkerEnabled)
{
await _stalinManager.RefreshUsersData();

View File

@@ -50,6 +50,8 @@ public sealed partial class CultRuleComponent : Component
public List<ConstructComponent> Constructs = new();
public CultWinCondition WinCondition = CultWinCondition.Draw;
public CultStage Stage = CultStage.Normal;
}
public enum CultWinCondition : byte
@@ -59,4 +61,11 @@ public enum CultWinCondition : byte
Failure,
}
public enum CultStage : byte
{
Normal,
RedEyes,
Pentagram,
}
public sealed class CultNarsieSummoned : EntityEventArgs;

View File

@@ -6,6 +6,7 @@ using Content.Server.Bible.Components;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Hands.Systems;
using Content.Server.Objectives.Components;
using Content.Server.Roles;
using Content.Server.RoundEnd;
@@ -53,6 +54,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
[Dependency] private readonly GulagSystem _gulag = default!;
[Dependency] private readonly BloodSpearSystem _bloodSpear = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly HandsSystem _hands = default!;
private const int PlayerPerCultist = 10;
private int _minStartingCultists;
@@ -175,6 +177,8 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
if (TryComp<ActorComponent>(uid, out var actor))
{
cult.CultistsCache.TryAdd(name, actor.PlayerSession.Name);
_mindSystem.TryGetMind(actor.PlayerSession.UserId, out var mind);
component.OriginalMind = mind;
}
UpdateCultistsAppearance(cult);
@@ -339,7 +343,12 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
var cultistsCount = cultRuleComponent.CurrentCultists.Count;
var constructsCount = cultRuleComponent.Constructs.Count;
var totalCultMembers = cultistsCount + constructsCount;
if (totalCultMembers < cultRuleComponent.ReadEyeThreshold)
if (totalCultMembers >= cultRuleComponent.PentagramThreshold)
cultRuleComponent.Stage = CultStage.Pentagram;
else if (totalCultMembers >= cultRuleComponent.ReadEyeThreshold && cultRuleComponent.Stage == CultStage.Normal)
cultRuleComponent.Stage = CultStage.RedEyes;
if (cultRuleComponent.Stage == CultStage.Normal)
return;
foreach (var cultistComponent in cultRuleComponent.CurrentCultists)
@@ -350,7 +359,7 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
Dirty(cultistComponent.Owner, appearanceComponent);
}
if (totalCultMembers < cultRuleComponent.PentagramThreshold)
if (cultRuleComponent.Stage != CultStage.Pentagram)
return;
EnsureComp<PentagramComponent>(cultistComponent.Owner);
@@ -458,6 +467,13 @@ public sealed class CultRuleSystem : GameRuleSystem<CultRuleComponent>
_container.Remove(container.ContainedEntity.Value, container, true, true);
}
}
foreach (var item in _hands.EnumerateHeld(uid))
{
if (TryComp(item, out CultItemComponent? cultItem) && !cultItem.CanPickUp &&
!_hands.TryDrop(uid, item, null, false, false))
QueueDel(item);
}
}
public void TransferRole(EntityUid transferFrom, EntityUid transferTo)

View File

@@ -0,0 +1,20 @@
namespace Content.Server._White.Cult.Items.Components;
[RegisterComponent]
public sealed partial class CultStunHandComponent : Component
{
[DataField]
public TimeSpan Duration = TimeSpan.FromSeconds(16);
[DataField]
public TimeSpan HaloDuration = TimeSpan.FromSeconds(1.5);
[DataField]
public TimeSpan MuteDuration = TimeSpan.FromSeconds(12);
[DataField]
public TimeSpan HaloMuteDuration = TimeSpan.FromSeconds(1);
[DataField]
public string Speech = "Fuu ma'jin!";
}

View File

@@ -0,0 +1,56 @@
using Content.Server._White.Cult.Items.Components;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Chat.Systems;
using Content.Server.Popups;
using Content.Server.Stunnable;
using Content.Shared._White.Chaplain;
using Content.Shared.Popups;
using Content.Shared.StatusEffect;
using Content.Shared.Weapons.Melee.Events;
namespace Content.Server._White.Cult.Items.Systems;
public sealed class CultStunHandSystem : EntitySystem
{
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly HolyWeaponSystem _holyWeapon = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly BloodstreamSystem _bloodstream = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<CultStunHandComponent, MeleeHitEvent>(OnHit);
}
private void OnHit(Entity<CultStunHandComponent> ent, ref MeleeHitEvent args)
{
if (args.HitEntities.Count == 0)
return;
var target = args.HitEntities[0];
var (uid, comp) = ent;
QueueDel(uid);
Spawn("CultStunFlashEffect", Transform(target).Coordinates);
_chat.TrySendInGameICMessage(args.User, comp.Speech, InGameICChatType.Whisper, false);
if (TryComp(args.User, out BloodstreamComponent? bloodstream))
_bloodstream.TryModifyBloodLevel(args.User, -10, bloodstream, createPuddle: false);
if (_holyWeapon.IsHoldingHolyWeapon(target))
{
_popupSystem.PopupEntity(Loc.GetString("cult-magic-holy"), args.User, args.User, PopupType.MediumCaution);
return;
}
var halo = HasComp<PentagramComponent>(args.User);
_statusEffects.TryAddStatusEffect(target, "Muted", halo ? comp.HaloMuteDuration : comp.MuteDuration, true,
"Muted");
_stun.TryParalyze(target, halo ? comp.HaloDuration : comp.Duration, true);
}
}

View File

@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System.Numerics;
using Content.Server.Atmos.Piping.Other.Components;
using Content.Server.Body.Components;
@@ -61,6 +61,15 @@ public sealed class PylonSystem : EntitySystem
private void OnInit(EntityUid uid, SharedPylonComponent component, ComponentInit args)
{
var coords = Transform(uid).Coordinates;
if (SharedPylonComponent.CheckForStructure(coords, EntityManager, 9f, uid))
{
QueueDel(uid);
_popupSystem.PopupCoordinates(Loc.GetString("cult-structure-craft-another-structure-nearby"),
coords, PopupType.MediumCaution);
Spawn("CultRunicMetal4", coords);
return;
}
UpdateAppearance(uid, component);
}

View File

@@ -1,3 +1,5 @@
using Content.Server.Chat.Systems;
namespace Content.Server._White.Cult.Runes.Comps;
[RegisterComponent]
@@ -14,4 +16,7 @@ public sealed partial class CultRuneBaseComponent : Component
[ViewVariables(VVAccess.ReadWrite), DataField("invokePhrase")]
public string InvokePhrase = "";
[DataField]
public InGameICChatType InvokeChatType = InGameICChatType.Whisper;
}

View File

@@ -5,6 +5,8 @@ using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Emp;
using Content.Server.EUI;
using Content.Server._White.Cult.UI;
using Content.Server._White.Wizard.Magic;
using Content.Server.Chat.Systems;
using Content.Shared._White.Chaplain;
using Content.Shared.Chemistry.Components;
using Content.Shared.Damage;
@@ -50,6 +52,7 @@ public partial class CultSystem
[Dependency] private readonly PhysicsSystem _physics = default!;
[Dependency] private readonly HolyWeaponSystem _holyWeapon = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
[Dependency] private readonly WizardSpellsSystem _spells = default!;
private const string TileId = "CultFloor";
private const string ConcealedTileId = "CultFloorConcealed";
@@ -66,7 +69,7 @@ public partial class CultSystem
SubscribeLocalEvent<CultistComponent, CultBloodRitesInstantActionEvent>(OnBloodRites);
SubscribeLocalEvent<CultistComponent, CultBloodSpearRecallInstantActionEvent>(OnBloodSpearRecall);
SubscribeLocalEvent<CultistComponent, CultTeleportTargetActionEvent>(OnTeleport);
SubscribeLocalEvent<CultistComponent, CultStunTargetActionEvent>(OnStunTarget);
SubscribeLocalEvent<CultistComponent, CultStunActionEvent>(OnStun);
SubscribeLocalEvent<CultistComponent, ActionGettingRemovedEvent>(OnActionRemoved);
SubscribeLocalEvent<CultistComponent, ShacklesEvent>(OnShackles);
}
@@ -84,6 +87,11 @@ public partial class CultSystem
if (_cuffable.TryAddNewCuffs(args.Target.Value, args.User, cuffs, cuffable, handcuffComponent))
{
SharedCuffableSystem.SetUsed(handcuffComponent, true);
if (_statusEffectsSystem.TryAddStatusEffect(args.Target.Value, "Muted", TimeSpan.FromSeconds(10),
true, "Muted"))
{
_popupSystem.PopupEntity("Цель обезмолвлена.", args.User, args.User);
}
return;
}
@@ -96,32 +104,16 @@ public partial class CultSystem
Dirty(ent);
}
private void OnStunTarget(EntityUid uid, CultistComponent component, CultStunTargetActionEvent args)
private void OnStun(EntityUid uid, CultistComponent component, CultStunActionEvent args)
{
if (args.Target == uid || !TryComp<BloodstreamComponent>(args.Performer, out var bloodstream) ||
!TryComp<StatusEffectsComponent>(args.Target, out var status))
return;
if (_holyWeapon.IsHoldingHolyWeapon(args.Target))
var entity = Spawn("StunHand", Transform(uid).Coordinates);
if (!_handsSystem.TryPickupAnyHand(uid, entity))
{
_popupSystem.PopupEntity("Сила священного оружия препятствует магии.", args.Performer, args.Performer,
PopupType.MediumCaution);
_popupSystem.PopupEntity(Loc.GetString("cult-magic-no-empty-hand"), uid, uid);
QueueDel(entity);
_actionsSystem.SetCooldown(args.Action, TimeSpan.FromSeconds(1));
return;
}
if (HasComp<MindShieldComponent>(args.Target))
{
_popupSystem.PopupEntity("Он имплантирован чипом защиты разума.", args.Performer, args.Performer,
PopupType.MediumCaution);
return;
}
if (!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(6), true, status) &
!_statusEffectsSystem.TryAddStatusEffect(args.Target, "Muted", TimeSpan.FromSeconds(12), true, "Muted",
status))
return;
_bloodstreamSystem.TryModifyBloodLevel(uid, -10, bloodstream, createPuddle: false);
args.Handled = true;
}
@@ -133,7 +125,7 @@ public partial class CultSystem
if (_holyWeapon.IsHoldingHolyWeapon(args.Target))
{
_popupSystem.PopupEntity("Сила священного оружия препятствует магии.", args.Performer, args.Performer,
_popupSystem.PopupEntity(Loc.GetString("cult-magic-holy"), args.Performer, args.Performer,
PopupType.MediumCaution);
return;
}
@@ -152,6 +144,7 @@ public partial class CultSystem
_euiManager.OpenEui(eui, actor.PlayerSession);
eui.StateDirty();
Speak(args);
args.Handled = true;
}
@@ -210,6 +203,7 @@ public partial class CultSystem
_popupSystem.PopupEntity(Loc.GetString("verb-blood-rites-message", ("blood", component.RitesBloodAmount)), uid,
uid);
Speak(args);
args.Handled = true;
}
@@ -342,6 +336,7 @@ public partial class CultSystem
_audio.PlayPvs(conceal ? "/Audio/White/Cult/smoke.ogg" : "/Audio/White/Cult/enter_blood.ogg", uid,
AudioParams.Default.WithMaxDistance(5f));
_bloodstreamSystem.TryModifyBloodLevel(uid, -2, bloodstream, createPuddle: false);
Speak(args);
args.Handled = true;
}
@@ -420,6 +415,7 @@ public partial class CultSystem
_empSystem.EmpPulse(_transform.GetMapCoordinates(uid), 5, 100000, 10f);
Speak(args);
args.Handled = true;
}
@@ -430,13 +426,6 @@ public partial class CultSystem
_bloodstreamSystem.TryModifyBloodLevel(uid, -5, bloodstream, createPuddle: false);
if (!_holyWeapon.IsHoldingHolyWeapon(args.Target) &&
_statusEffectsSystem.TryAddStatusEffect(args.Target, "Muted", TimeSpan.FromSeconds(10), true, "Muted"))
{
_popupSystem.PopupEntity("Цель обезмолвлена.", args.Performer, args.Performer);
args.Handled = true;
}
if (!TryComp(args.Target, out CuffableComponent? cuffs) || cuffs.Container.ContainedEntities.Count > 0)
return;
@@ -447,6 +436,7 @@ public partial class CultSystem
BreakOnDamage = true
});
Speak(args);
args.Handled = true;
}
@@ -482,6 +472,7 @@ public partial class CultSystem
stackNew.Count = count;
_popupSystem.PopupEntity("Конвертируем сталь в руинический металл!", args.Performer, args.Performer);
Speak(args);
args.Handled = true;
}
@@ -498,6 +489,12 @@ public partial class CultSystem
_bloodstreamSystem.TryModifyBloodLevel(args.Performer, -10, bloodstreamComponent, false);
_handsSystem.TryPickupAnyHand(args.Performer, dagger);
Speak(args);
args.Handled = true;
}
private void Speak(BaseActionEvent args)
{
_spells.Speak(args, InGameICChatType.Whisper);
}
}

View File

@@ -16,6 +16,7 @@ using Content.Server.Chemistry.Components;
using Content.Server.Chemistry.Containers.EntitySystems;
using Content.Server.Fluids.Components;
using Content.Server.Ghost;
using Content.Server.Pinpointer;
using Content.Server.Revenant.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Cuffs.Components;
@@ -51,6 +52,7 @@ using Robust.Shared.Map;
using Robust.Shared.Physics.Events;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Utility;
using CultistComponent = Content.Shared._White.Cult.Components.CultistComponent;
namespace Content.Server._White.Cult.Runes.Systems;
@@ -77,6 +79,7 @@ public sealed partial class CultSystem : EntitySystem
[Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly MobThresholdSystem _thresholdSystem = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
public override void Initialize()
{
@@ -404,7 +407,7 @@ public sealed partial class CultSystem : EntitySystem
foreach (var cultist in cultists)
{
_chat.TrySendInGameICMessage(cultist, component.InvokePhrase, InGameICChatType.Speak, false, false, null,
_chat.TrySendInGameICMessage(cultist, component.InvokePhrase, component.InvokeChatType, false, false, null,
null, null, false);
}
}
@@ -1347,11 +1350,8 @@ public sealed partial class CultSystem : EntitySystem
}
damage = 40;
var pos = _transform.GetMapCoordinates(uid, transComp);
var x = (int) pos.X;
var y = (int) pos.Y;
var posText = $"(x = {x}, y = {y})";
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-narsie-summon-drawn-position", ("posText", posText)),
_chat.DispatchGlobalAnnouncement(Loc.GetString("cult-narsie-summon-drawn-position",
("location", FormattedMessage.RemoveMarkup(_navMap.GetNearestBeaconString((uid, transComp))))),
"CULT", true, _apocRuneEndDrawing, colorOverride: Color.DarkRed);
}

View File

@@ -8,13 +8,13 @@ namespace Content.Server._White.Mood;
[RegisterComponent]
public sealed partial class MoodComponent : Component
{
[DataField("currentMoodLevel"), ViewVariables(VVAccess.ReadOnly)]
[DataField, ViewVariables(VVAccess.ReadOnly)]
public float CurrentMoodLevel;
[DataField("currentMoodThreshold"), ViewVariables(VVAccess.ReadOnly)]
[DataField, ViewVariables(VVAccess.ReadOnly)]
public MoodThreshold CurrentMoodThreshold;
[DataField("lastThreshold"), ViewVariables(VVAccess.ReadOnly)]
[DataField, ViewVariables(VVAccess.ReadOnly)]
public MoodThreshold LastThreshold;
[ViewVariables(VVAccess.ReadOnly)]
@@ -23,22 +23,22 @@ public sealed partial class MoodComponent : Component
[ViewVariables(VVAccess.ReadOnly)]
public readonly Dictionary<string, float> UncategorisedEffects = new();
[DataField("slowdownSpeedModifier"), ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float SlowdownSpeedModifier = 0.75f;
[DataField("increaseSpeedModifier"), ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float IncreaseSpeedModifier = 1.15f;
[DataField("increaseCritThreshold"), ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float IncreaseCritThreshold = 1.2f;
[DataField("decreaseCritThreshold"), ViewVariables(VVAccess.ReadWrite)]
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float DecreaseCritThreshold = 0.9f;
[ViewVariables(VVAccess.ReadOnly)]
public FixedPoint2 CritThresholdBeforeModify;
[DataField("moodThresholds", customTypeSerializer: typeof(DictionarySerializer<MoodThreshold, float>))]
[DataField(customTypeSerializer: typeof(DictionarySerializer<MoodThreshold, float>))]
public Dictionary<MoodThreshold, float> MoodThresholds = new()
{
{ MoodThreshold.VeryVeryGood, 10.0f },
@@ -53,7 +53,7 @@ public sealed partial class MoodComponent : Component
{ MoodThreshold.Dead, 0.0f }
};
[DataField("moodThresholdsAlerts", customTypeSerializer: typeof(DictionarySerializer<MoodThreshold, AlertType>))]
[DataField(customTypeSerializer: typeof(DictionarySerializer<MoodThreshold, AlertType>))]
public Dictionary<MoodThreshold, AlertType> MoodThresholdsAlerts = new()
{
{ MoodThreshold.Dead, AlertType.MoodDead },
@@ -69,7 +69,7 @@ public sealed partial class MoodComponent : Component
{ MoodThreshold.Insane, AlertType.Insane }
};
[DataField("moodChangeValues", customTypeSerializer: typeof(DictionarySerializer<Enum, float>))]
[DataField(customTypeSerializer: typeof(DictionarySerializer<Enum, float>))]
public Dictionary<Enum, float> MoodChangeValues = new()
{
{ MoodChangeLevel.None , 0.0f },
@@ -80,7 +80,7 @@ public sealed partial class MoodComponent : Component
{ MoodChangeLevel.Large , 2f }
};
[DataField("healthMoodEffectsThresholds", customTypeSerializer: typeof(DictionarySerializer<string, float>))]
[DataField(customTypeSerializer: typeof(DictionarySerializer<string, float>))]
public Dictionary<string, float> HealthMoodEffectsThresholds = new()
{
{ "HealthHeavyDamage", 80f },

View File

@@ -108,8 +108,8 @@ public sealed class MoodSystem : EntitySystem
if (!component.MoodChangeValues.TryGetValue(oldPrototype.MoodChange, out var oldValue))
return;
amount += (oldPrototype.PositiveEffect ? -oldValue : oldValue) +
(prototype.PositiveEffect ? value : -value);
amount += (oldPrototype.Positive ? -oldValue : oldValue) +
(prototype.Positive ? value : -value);
component.CategorisedEffects[prototype.Category] = prototype.ID;
}
@@ -117,7 +117,7 @@ public sealed class MoodSystem : EntitySystem
else
{
component.CategorisedEffects.Add(prototype.Category, prototype.ID);
amount += prototype.PositiveEffect ? value : -value;
amount += prototype.Positive ? value : -value;
}
if (prototype.Timeout != 0)
@@ -132,7 +132,7 @@ public sealed class MoodSystem : EntitySystem
if (component.UncategorisedEffects.TryGetValue(prototype.ID, out _))
return;
var effectValue = prototype.PositiveEffect ? value : -value;
var effectValue = prototype.Positive ? value : -value;
component.UncategorisedEffects.Add(prototype.ID, effectValue);
amount += effectValue;
@@ -173,7 +173,7 @@ public sealed class MoodSystem : EntitySystem
if (!comp.MoodChangeValues.TryGetValue(currentProto.MoodChange, out var value))
return;
amount += currentProto.PositiveEffect ? -value : value;
amount += currentProto.Positive ? -value : value;
comp.CategorisedEffects.Remove(category);
}
@@ -205,7 +205,7 @@ public sealed class MoodSystem : EntitySystem
if (!component.MoodChangeValues.TryGetValue(prototype.MoodChange, out var value))
return;
amount += prototype.PositiveEffect ? value : -value;
amount += prototype.Positive ? value : -value;
}
foreach (var (_, value) in component.UncategorisedEffects)
@@ -438,7 +438,7 @@ public sealed partial class ShowMoodEffects : IAlertClick
{
var chatManager = IoCManager.Resolve<IChatManager>();
var color = proto.PositiveEffect ? "#008000" : "#BA0000";
var color = proto.Positive ? "#008000" : "#BA0000";
var msg = $"[font size=10][color={color}]{proto.Description}[/color][/font]";
chatManager.ChatMessageToOne(ChatChannel.Emotes, msg, msg, EntityUid.Invalid, false,

View File

@@ -174,6 +174,12 @@ public sealed class WizardSpellsSystem : EntitySystem
return;
}
if (HasComp<CultistComponent>(target))
{
_popupSystem.PopupEntity(Loc.GetString("mindswap-cultist-failed"), uid, uid, PopupType.MediumCaution);
return;
}
var userHasMind = _mindSystem.TryGetMind(uid, out var mindId, out var mind);
var targetHasMind = _mindSystem.TryGetMind(target, out var targetMindId, out var targetMind);
@@ -183,8 +189,6 @@ public sealed class WizardSpellsSystem : EntitySystem
SwapComponent<WizardComponent>(uid, target);
SwapComponent<RevolutionaryComponent>(uid, target);
SwapComponent<HeadRevolutionaryComponent>(uid, target);
SwapComponent<PentagramComponent>(uid, target);
SwapComponent<CultistComponent>(uid, target);
SwapComponent<GlobalAntagonistComponent>(uid, target);
_mindSystem.TransferTo(mindId, target, mind: mind);
@@ -854,13 +858,12 @@ public sealed class WizardSpellsSystem : EntitySystem
!_statusEffectsSystem.HasStatusEffect(msg.Performer, "Incorporeal");
}
private void Speak(BaseActionEvent args)
public void Speak(BaseActionEvent args, InGameICChatType type = InGameICChatType.Speak)
{
if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
return;
_chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech),
InGameICChatType.Speak, false);
_chat.TrySendInGameICMessage(args.Performer, Loc.GetString(speak.Speech), type, false);
}
private void SetCooldown(EntityUid action, ActionUseType useType)

View File

@@ -212,6 +212,7 @@ public sealed partial class BlockingSystem : EntitySystem
hard: true,
collisionLayer: (int) CollisionGroup.WallLayer,
body: physicsComponent);
_physics.SetBodyType(user, BodyType.Static, body: physicsComponent);
}
component.IsBlocking = true;

View File

@@ -838,7 +838,7 @@ namespace Content.Shared.CCVar
/// de-admin them.
/// </summary>
public static readonly CVarDef<bool> AdminDeadminOnJoin =
CVarDef.Create("admin.deadmin_on_join", false, CVar.SERVERONLY);
CVarDef.Create("admin.deadmin_on_join", true, CVar.SERVERONLY);
/// <summary>
/// Overrides the name the client sees in ahelps. Set empty to disable.
@@ -851,7 +851,7 @@ namespace Content.Shared.CCVar
/// If 0, appearing as a new player is disabled.
/// </summary>
public static readonly CVarDef<int> NewPlayerThreshold =
CVarDef.Create("admin.new_player_threshold", 0, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
CVarDef.Create("admin.new_player_threshold", 4320, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
/// <summary>
/// How long an admin client can go without any input before being considered AFK.
@@ -1346,7 +1346,7 @@ namespace Content.Shared.CCVar
/// <summary>
/// Config for when the restart vote should be allowed to be called based on percentage of ghosts.
///
/// </summary>
public static readonly CVarDef<int> VoteRestartGhostPercentage =
CVarDef.Create("vote.restart_ghost_percentage", 75, CVar.SERVERONLY);
@@ -1441,7 +1441,7 @@ namespace Content.Shared.CCVar
/// Whether the arrivals terminal should be on a planet map.
/// </summary>
public static readonly CVarDef<bool> ArrivalsPlanet =
CVarDef.Create("shuttle.arrivals_planet", true, CVar.SERVERONLY);
CVarDef.Create("shuttle.arrivals_planet", false, CVar.SERVERONLY);
/// <summary>
/// Whether the arrivals shuttle is enabled.
@@ -1459,7 +1459,7 @@ namespace Content.Shared.CCVar
/// Cooldown between arrivals departures. This should be longer than the FTL time or it will double cycle.
/// </summary>
public static readonly CVarDef<float> ArrivalsCooldown =
CVarDef.Create("shuttle.arrivals_cooldown", 50f, CVar.SERVERONLY);
CVarDef.Create("shuttle.arrivals_cooldown", 10f, CVar.SERVERONLY);
/// <summary>
/// Are players allowed to return on the arrivals shuttle.

View File

@@ -38,7 +38,6 @@ public sealed partial class StaminaSystem : EntitySystem
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!; // WD EDIT
/// <summary>
/// How much of a buffer is there between the stun duration and when stuns can be re-applied.
@@ -365,7 +364,7 @@ public sealed partial class StaminaSystem : EntitySystem
continue;
// We were in crit so come out of it and continue.
if (!_statusEffectsSystem.HasStatusEffect(uid, "Stun") && comp.Critical) // WD EIT
if (comp.Critical)
{
ExitStamCrit(uid, comp);
continue;

View File

@@ -101,7 +101,7 @@ public abstract partial class SharedHandsSystem : EntitySystem
if (TryComp(session?.AttachedEntity, out HandsComponent? hands) && hands.ActiveHand != null)
// WD EDIT START
{
if (HasComp<BoltBarrageComponent>(hands.ActiveHandEntity))
if (HasComp<DeleteOnDropAttemptComponent>(hands.ActiveHandEntity))
{
if (_net.IsServer)
QueueDel(hands.ActiveHandEntity.Value);

View File

@@ -114,7 +114,7 @@ public sealed class HungerSystem : EntitySystem
return;
//WD start
if (_net.IsServer)
if (_net.IsServer && component.CurrentThreshold != HungerThreshold.Overfed)
{
var ev = new MoodEffectEvent("Hunger" + component.CurrentThreshold);
RaiseLocalEvent(uid, ev);

View File

@@ -112,10 +112,13 @@ public sealed class ThirstSystem : EntitySystem
_alerts.ClearAlertCategory(uid, AlertCategory.Thirst);
}
//WD start
var ev = new MoodEffectEvent("Thirst" + component.CurrentThirstThreshold);
RaiseLocalEvent(uid, ev);
//WD end
// WD start
if (component.CurrentThirstThreshold != ThirstThreshold.OverHydrated)
{
var ev = new MoodEffectEvent("Thirst" + component.CurrentThirstThreshold);
RaiseLocalEvent(uid, ev);
}
// WD end
switch (component.CurrentThirstThreshold)
{

View File

@@ -116,6 +116,9 @@ public abstract partial class SharedProjectileSystem : EntitySystem
return;
// WD START
if (args.Handled)
return;
if (component is {Penetrate: true, PenetratedUid: null} &&
TryComp(args.Target, out PenetratedComponent? penetrated) &&
penetrated is {ProjectileUid: null, IsPinned: false} &&

View File

@@ -13,4 +13,8 @@ public sealed partial class RCDAmmoComponent : Component
/// </summary>
[DataField("charges"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public int Charges = 30;
[DataField] public bool CanBeExamined = true; // WD
[DataField] public float ChargeCountModifier = 1; // WD
}

View File

@@ -1,3 +1,4 @@
using Content.Shared._White.RCD;
using Content.Shared.RCD.Systems;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
@@ -33,6 +34,12 @@ public sealed partial class RCDComponent : Component
[DataField, AutoNetworkedField]
public ProtoId<RCDPrototype> ProtoId { get; set; } = "Invalid";
/// <summary>
/// The ProtoId of the currently selected RCD prototype
/// </summary>
[DataField(required: true), AutoNetworkedField]
public HashSet<ProtoId<RCDCategoryPrototype>> CategoryPrototypes = default!;
/// <summary>
/// A cached copy of currently selected RCD prototype
/// </summary>

View File

@@ -1,3 +1,4 @@
using Content.Shared._White.RCD;
using Content.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Prototypes;
@@ -23,14 +24,14 @@ public sealed class RCDPrototype : IPrototype
/// <summary>
/// The name associated with the prototype
/// </summary>
[DataField("name"), ViewVariables(VVAccess.ReadOnly)]
public string SetName { get; private set; } = "Unknown";
[DataField, ViewVariables(VVAccess.ReadOnly)]
public string Name { get; private set; } = "Unknown";
/// <summary>
/// The name of the radial container that this prototype will be listed under on the RCD menu
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public string Category { get; private set; } = "Undefined";
public ProtoId<RCDCategoryPrototype> Category { get; private set; } = "WallsAndFlooring"; // WD
/// <summary>
/// Texture path for this prototypes menu icon
@@ -42,7 +43,7 @@ public sealed class RCDPrototype : IPrototype
/// The entity prototype that will be constructed (mode dependent)
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public string? Prototype { get; private set; } = string.Empty;
public ProtoId<EntityPrototype>? Prototype { get; private set; } = null;
/// <summary>
/// Number of charges consumed when the operation is completed
@@ -51,7 +52,7 @@ public sealed class RCDPrototype : IPrototype
public int Cost { get; private set; } = 1;
/// <summary>
/// The length of the operation
/// The length of the operation
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public float Delay { get; private set; } = 1f;
@@ -75,7 +76,7 @@ public sealed class RCDPrototype : IPrototype
public CollisionGroup CollisionMask { get; private set; } = CollisionGroup.None;
/// <summary>
/// Specifies a set of custom collision bounds for determining whether the entity prototype will fit into a target tile
/// Specifies a set of custom collision bounds for determining whether the entity prototype will fit into a target tile
/// </summary>
/// <remarks>
/// Should be set assuming that the entity faces south.
@@ -106,7 +107,7 @@ public sealed class RCDPrototype : IPrototype
private Box2? _collisionBounds = null;
/// <summary>
/// The polygon shape associated with the prototype CollisionBounds (if set)
/// The polygon shape associated with the prototype CollisionBounds (if set)
/// </summary>
[ViewVariables(VVAccess.ReadOnly)]
public PolygonShape? CollisionPolygon { get; private set; } = null;

View File

@@ -4,6 +4,7 @@ using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.RCD.Components;
using Content.Shared.Stacks;
using Robust.Shared.Timing;
namespace Content.Shared.RCD.Systems;
@@ -13,20 +14,37 @@ public sealed class RCDAmmoSystem : EntitySystem
[Dependency] private readonly SharedChargesSystem _charges = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedStackSystem _stack = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RCDAmmoComponent, ComponentInit>(OnInit); // WD edit
SubscribeLocalEvent<RCDAmmoComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<RCDAmmoComponent, AfterInteractEvent>(OnAfterInteract);
}
// WD edit start
private void OnInit(EntityUid uid, RCDAmmoComponent rcdAmmoComponent, ComponentInit _)
{
if (TryComp<StackComponent>(uid, out var stackComponent))
rcdAmmoComponent.Charges = (int) (stackComponent.Count * rcdAmmoComponent.ChargeCountModifier);
else
rcdAmmoComponent.Charges = (int) (rcdAmmoComponent.Charges * rcdAmmoComponent.ChargeCountModifier);
}
// WD edit end
private void OnExamine(EntityUid uid, RCDAmmoComponent comp, ExaminedEvent args)
{
if (!args.IsInDetailsRange)
return;
if (!comp.CanBeExamined) // WD edit
return;
var examineMessage = Loc.GetString("rcd-ammo-component-on-examine", ("charges", comp.Charges));
args.PushText(examineMessage);
}
@@ -51,6 +69,15 @@ public sealed class RCDAmmoSystem : EntitySystem
}
_popup.PopupClient(Loc.GetString("rcd-ammo-component-after-interact-refilled"), target, user);
// WD edit start
if (TryComp<StackComponent>(uid, out var stackComponent))
{
var spent = (int) (count / comp.ChargeCountModifier) == 0 ? 1 : (int) (count / comp.ChargeCountModifier);
_stack.SetCount(uid, stackComponent.Count - spent);
}
// WD edit end
_charges.AddCharges(target, count, charges);
comp.Charges -= count;
Dirty(uid, comp);

View File

@@ -25,6 +25,7 @@ using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared._White.ClothingGrant.Systems;
namespace Content.Shared.RCD.Systems;
@@ -75,7 +76,7 @@ public class RCDSystem : EntitySystem
if (component.AvailablePrototypes.Any())
{
component.ProtoId = component.AvailablePrototypes.First();
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
Dirty(uid, component);
return;
@@ -96,7 +97,7 @@ public class RCDSystem : EntitySystem
// Set the current RCD prototype to the one supplied
component.ProtoId = args.ProtoId;
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
Dirty(uid, component);
}
@@ -106,13 +107,14 @@ public class RCDSystem : EntitySystem
return;
// Update cached prototype if required
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
var msg = Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(component.CachedPrototype.SetName)));
var msg = Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(component.CachedPrototype.Name)));
if (component.CachedPrototype.Mode == RcdMode.ConstructTile || component.CachedPrototype.Mode == RcdMode.ConstructObject)
var mode = component.CachedPrototype.Mode;
if (mode == RcdMode.ConstructTile || mode == RcdMode.ConstructObject)
{
var name = Loc.GetString(component.CachedPrototype.SetName);
var name = Loc.GetString(component.CachedPrototype.Name);
if (component.CachedPrototype.Prototype != null &&
_protoManager.TryIndex(component.CachedPrototype.Prototype, out var proto))
@@ -225,7 +227,7 @@ public class RCDSystem : EntitySystem
private void OnDoAfterAttempt(EntityUid uid, RCDComponent component, DoAfterAttemptEvent<RCDDoAfterEvent> args)
{
if (args.Event?.DoAfter?.Args == null)
if (args.Event?.DoAfter?.Args == null) // wtf if this
return;
// Exit if the RCD prototype has changed
@@ -302,7 +304,7 @@ public class RCDSystem : EntitySystem
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user, bool popMsgs = true)
{
// Update cached prototype if required
UpdateCachedPrototype(uid, component);
UpdateCachedPrototype(component);
// Check that the RCD has enough ammo to get the job done
TryComp<LimitedChargesComponent>(uid, out var charges);
@@ -589,7 +591,7 @@ public class RCDSystem : EntitySystem
return boundingPolygon.ComputeAABB(boundingTransform, 0).Intersects(fixture.Shape.ComputeAABB(entXform, 0));
}
public void UpdateCachedPrototype(EntityUid uid, RCDComponent component)
public void UpdateCachedPrototype(RCDComponent component)
{
if (component.ProtoId.Id != component.CachedPrototype?.Prototype)
component.CachedPrototype = _protoManager.Index(component.ProtoId);

View File

@@ -1,5 +1,6 @@
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
@@ -62,19 +63,31 @@ public sealed partial class MeleeWeaponComponent : Component
public bool Attacking = false;
// WD START
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool CanHeavyAttack = true;
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool CanAttackSelf = true;
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool CanMiss = true;
[DataField]
public EntityWhitelist? AttackWhitelist;
[DataField]
public EntityWhitelist? AttackBlacklist;
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public bool IgnoreResistances;
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public float HeavyAttackStaminaCost = 8;
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public EntProtoId MissAnimation = "WeaponArcPunch";
[ViewVariables(VVAccess.ReadWrite), DataField]
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
public EntProtoId DisarmAnimation = "WeaponArcDisarm";
// WD END

View File

@@ -365,6 +365,30 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
if (weaponUid == lightTarget)
return false;
// WD START
if (user == lightTarget && !weapon.CanAttackSelf)
return false;
if (lightTarget == null)
{
if (weapon.CanMiss)
break;
return false;
}
if (weapon.AttackWhitelist != null)
{
if (!weapon.AttackWhitelist.IsValid(lightTarget.Value, EntityManager))
return false;
}
if (weapon.AttackBlacklist != null)
{
if (weapon.AttackBlacklist.IsValid(lightTarget.Value, EntityManager))
return false;
}
// WD END
break;
case DisarmAttackEvent disarm:
var disarmTarget = GetEntity(disarm.Target);

View File

@@ -3,6 +3,7 @@ using Content.Shared.Inventory.Events;
using Robust.Shared.Serialization.Manager;
using Content.Shared.Tag;
using Content.Shared._White.ClothingGrant.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Shared._White.ClothingGrant.Systems;
@@ -40,24 +41,29 @@ public sealed class ClothingGrantingSystem : EntitySystem
return;
}
foreach (var (name, data) in component.Components)
{
var newComp = (Component) _componentFactory.GetComponent(name);
if (HasComp(args.Equipee, newComp.GetType()))
continue;
newComp.Owner = args.Equipee;
var temp = (object) newComp;
_serializationManager.CopyTo(data.Component, ref temp);
EntityManager.AddComponent(args.Equipee, (Component)temp!);
}
AddComponents(args.Equipee, component.Components);
component.IsActive = true;
Dirty(uid, component);
}
public void AddComponents(EntityUid uid, ComponentRegistry components)
{
foreach (var (name, data) in components)
{
var newComp = (Component) _componentFactory.GetComponent(name);
if (HasComp(uid, newComp.GetType()))
continue;
newComp.Owner = uid;
var temp = (object) newComp;
_serializationManager.CopyTo(data.Component, ref temp);
EntityManager.AddComponent(uid, (Component)temp!);
}
}
private void OnCompUnequip(EntityUid uid, ClothingGrantComponentComponent component, GotUnequippedEvent args)
{
if (!component.IsActive) return;

View File

@@ -1,29 +1,40 @@
using Content.Shared.Actions;
using Content.Shared.Magic;
namespace Content.Shared._White.Cult.Actions;
public sealed partial class CultTwistedConstructionActionEvent : EntityTargetActionEvent
public sealed partial class CultTwistedConstructionActionEvent : EntityTargetActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultStunActionEvent : InstantActionEvent
{
}
public sealed partial class CultSummonDaggerActionEvent : InstantActionEvent
public sealed partial class CultTeleportTargetActionEvent : EntityTargetActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultStunTargetActionEvent : EntityTargetActionEvent
public sealed partial class CultElectromagneticPulseInstantActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultTeleportTargetActionEvent : EntityTargetActionEvent
{
}
public sealed partial class CultElectromagneticPulseInstantActionEvent : InstantActionEvent
{
}
public sealed partial class CultShadowShacklesTargetActionEvent : EntityTargetActionEvent
public sealed partial class CultShadowShacklesTargetActionEvent : EntityTargetActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityTargetActionEvent
@@ -31,8 +42,10 @@ public sealed partial class CultSummonCombatEquipmentTargetActionEvent : EntityT
}
[Virtual]
public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent
public partial class CultConcealPresenceInstantActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultConcealInstantActionEvent : CultConcealPresenceInstantActionEvent
@@ -43,8 +56,10 @@ public sealed partial class CultRevealInstantActionEvent : CultConcealPresenceIn
{
}
public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent
public sealed partial class CultBloodRitesInstantActionEvent : InstantActionEvent, ISpeakSpell
{
[DataField("speech")]
public string? Speech { get; private set; }
}
public sealed partial class CultBloodSpearRecallInstantActionEvent : InstantActionEvent

View File

@@ -11,7 +11,7 @@ namespace Content.Shared._White.Cult.Components;
/// This is used for tagging a mob as a cultist.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class CultistComponent : ShowCultHudComponent
public sealed partial class CultistComponent : Component
{
[DataField("greetSound", customTypeSerializer: typeof(SoundSpecifierTypeSerializer))]
public SoundSpecifier? CultistGreetSound = new SoundPathSpecifier("/Audio/CultSounds/fart.ogg");
@@ -41,7 +41,7 @@ public sealed partial class CultistComponent : ShowCultHudComponent
public static string CultSummonCombatEquipmentAction = "ActionCultSummonCombatEquipment";
public static string CultStunAction = "ActionCultStun";
public static string CultStunAction = "InstantActionCultStun";
public static string CultShadowShacklesAction = "ActionCultShadowShackles";

View File

@@ -0,0 +1,8 @@
namespace Content.Shared._White.Cult.Components;
[RegisterComponent]
public sealed partial class DeleteOnDropAttemptComponent : Component
{
[DataField]
public string Message = string.Empty;
}

View File

@@ -1,5 +1,6 @@
using Content.Shared.Damage;
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
namespace Content.Shared._White.Cult.Pylon;
@@ -64,6 +65,25 @@ public sealed partial class SharedPylonComponent : Component
[DataField("wallConvertEffect")]
public string WallConvertEffect = "CultWallGlow";
public static bool CheckForStructure(EntityCoordinates coordinates, IEntityManager entMan, float range, EntityUid? pylon = null)
{
var lookupSystem = entMan.System<EntityLookupSystem>();
var entities = lookupSystem.GetEntitiesInRange(coordinates, range);
foreach (var ent in entities)
{
if (ent == pylon)
continue;
if (!entMan.TryGetComponent<MetaDataComponent>(ent, out var metadata))
continue;
if (metadata.EntityPrototype?.ID is "CultPylon")
return true;
}
return false;
}
}
[Serializable, NetSerializable]

View File

@@ -1,7 +1,9 @@
using Content.Shared._White.Chaplain;
using Content.Shared._White.Cult.Components;
using Content.Shared.Actions;
using Content.Shared.Examine;
using Content.Shared.Hands;
using Content.Shared.Projectiles;
using Content.Shared.StatusEffect;
using Content.Shared.Stunnable;
using Content.Shared.Throwing;
@@ -15,6 +17,7 @@ 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 HolyWeaponSystem _holy = default!;
[Dependency] private readonly INetManager _net = default!;
public override void Initialize()
@@ -23,7 +26,8 @@ public sealed class BloodSpearSystem : EntitySystem
SubscribeLocalEvent<BloodSpearComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<BloodSpearComponent, GotEquippedHandEvent>(OnEquip);
SubscribeLocalEvent<BloodSpearComponent, ThrowDoHitEvent>(OnThrowDoHit);
SubscribeLocalEvent<BloodSpearComponent, ThrowDoHitEvent>(OnThrowDoHit,
before: new[] {typeof(SharedProjectileSystem)});
SubscribeLocalEvent<BloodSpearComponent, ExaminedEvent>(OnExamine);
}
@@ -34,11 +38,20 @@ public sealed class BloodSpearSystem : EntitySystem
private void OnThrowDoHit(Entity<BloodSpearComponent> ent, ref ThrowDoHitEvent args)
{
if (HasComp<CultistComponent>(args.Target) || HasComp<ConstructComponent>(args.Target))
{
args.Handled = true;
return;
}
if (!TryComp(args.Target, out StatusEffectsComponent? status))
return;
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(6), true, status))
return;
if (!_holy.IsHoldingHolyWeapon(args.Target))
{
if(!_stunSystem.TryParalyze(args.Target, TimeSpan.FromSeconds(4), true, status))
return;
}
if (_net.IsClient)
return;

View File

@@ -1,3 +1,5 @@
using Content.Shared._White.Cult.Components;
namespace Content.Shared._White.Cult.Systems;
/// <summary>
@@ -9,16 +11,18 @@ public sealed class CultistSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<Components.CultistComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<Components.CultistComponent, ComponentShutdown>(OnRemove);
SubscribeLocalEvent<ConstructComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<ConstructComponent, ComponentShutdown>(OnRemove);
SubscribeLocalEvent<CultistComponent, ComponentStartup>(OnInit);
SubscribeLocalEvent<CultistComponent, ComponentShutdown>(OnRemove);
}
private void OnInit(EntityUid uid, Components.CultistComponent component, ComponentStartup args)
private void OnInit<T>(EntityUid uid, T component, ComponentStartup args)
{
RaiseLocalEvent(new EventCultistComponentState(true));
}
private void OnRemove(EntityUid uid, Components.CultistComponent component, ComponentShutdown args)
private void OnRemove<T>(EntityUid uid, T component, ComponentShutdown args)
{
RaiseLocalEvent(new EventCultistComponentState(false));
}

View File

@@ -0,0 +1,19 @@
using Content.Shared._White.Cult.Components;
using Content.Shared.Examine;
namespace Content.Shared._White.Cult.Systems;
public sealed class DeleteOnDropAttemptSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DeleteOnDropAttemptComponent, ExaminedEvent>(OnExamine);
}
private void OnExamine(Entity<DeleteOnDropAttemptComponent> ent, ref ExaminedEvent args)
{
args.PushMarkup(Loc.GetString(ent.Comp.Message));
}
}

View File

@@ -3,29 +3,25 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations;
namespace Content.Shared._White.Mood;
[Prototype("moodEffect")]
[Prototype]
public sealed class MoodEffectPrototype : IPrototype
{
[ViewVariables]
[IdDataField]
public string ID { get; } = default!;
[DataField("desc", required: true)]
[DataField(required: true)]
public string Description = string.Empty;
[DataField("moodChange", customTypeSerializer: typeof(EnumSerializer), required: true)]
[DataField(customTypeSerializer: typeof(EnumSerializer), required: true)]
public Enum MoodChange = default!;
[DataField("positiveEffect", required: true)]
public bool PositiveEffect;
[DataField] public bool Positive;
[DataField("timeout")]
public int Timeout;
[DataField] public int Timeout;
[DataField("hidden")]
public bool Hidden;
[DataField] public bool Hidden;
//If mob already has effect of the same category, the new one will replace the old one.
[DataField("category")]
public string? Category;
// If mob already has effect of the same category, the new one will replace the old one.
[DataField] public string? Category;
}

View File

@@ -0,0 +1,17 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared._White.RCD;
[Prototype("rcdCategory")]
public sealed class RCDCategoryPrototype : IPrototype
{
[IdDataField]
public string ID { get; private set; } = default!;
[DataField]
public string TooltipBase = "rcd-category-";
[DataField(required: true)]
public SpriteSpecifier SpritePath = default!;
}

View File

@@ -6814,3 +6814,159 @@
id: 422
time: '2024-07-27T15:48:25.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/492
- author: Aviu
changes:
- message: "\u041F\u0435\u0440\u0435\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E\
\ \u0437\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u0435 \u043E\u0433\u043B\
\u0443\u0448\u0435\u043D\u0438\u044F \u0443 \u043A\u0443\u043B\u044C\u0442\u0430\
. \u0422\u0435\u043F\u0435\u0440\u044C \u043E\u043D\u043E \u0434\u0430\u0451\
\u0442 \u0432 \u0440\u0443\u043A\u0443 \u0430\u0443\u0440\u0443, \u043A\u043E\
\u0442\u043E\u0440\u043E\u0439 \u043D\u0430\u0434\u043E \u0443\u0434\u0430\u0440\
\u0438\u0442\u044C \u043A\u043E\u0441\u043C\u043E\u043D\u0430\u0432\u0442\u0438\
\u043A\u0430, \u0447\u0442\u043E\u0431\u044B \u043E\u0433\u043B\u0443\u0448\u0438\
\u0442\u044C. \u0412\u0440\u0435\u043C\u044F \u0441\u0442\u0430\u043D\u0430\
: 16 \u0441\u0435\u043A\u0443\u043D\u0434, 1.5 \u0441\u0435\u043A\u0443\u043D\
\u0434\u044B \u0441 \u043F\u0435\u043D\u0442\u0430\u0433\u0440\u0430\u043C\u043C\
\u043E\u0439 \u043D\u0430\u0434 \u0433\u043E\u043B\u043E\u0432\u043E\u0439.\
\ \u0422\u0435\u043F\u0435\u0440\u044C \u0440\u0430\u0431\u043E\u0442\u0430\u0435\
\u0442 \u043D\u0430 \u0447\u0438\u043F\u0438\u0440\u043E\u0432\u0430\u043D\u043D\
\u044B\u0445."
type: Add
- message: "\u041A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u044B \u0442\u0435\
\u043F\u0435\u0440\u044C \u043C\u043E\u0433\u0443\u0442 \u043E\u0431\u0449\u0430\
\u0442\u044C\u0441\u044F \u0432 \u0447\u0430\u0442\u0435 \u043A\u0443\u043B\u044C\
\u0442\u0430."
type: Add
- message: "\u041A\u0443\u043B\u044C\u0442\u0438\u0441\u0442\u044B \u0442\u0435\u043F\
\u0435\u0440\u044C \u0448\u0435\u043F\u0447\u0443\u0442 \u0441\u043C\u0435\u0448\
\u043D\u044B\u0435 \u0444\u0440\u0430\u0437\u044B \u043F\u0440\u0438 \u043A\u0430\
\u0441\u0442\u0435 \u0437\u0430\u043A\u043B\u0438\u043D\u0430\u043D\u0438\u0439\
."
type: Add
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u043F\u0440\u0438 \u0430\u043A\
\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0431\u043E\u043B\u044C\u0448\u0438\
\u043D\u0441\u0442\u0432\u0430 \u0440\u0443\u043D \u043A\u0443\u043B\u044C\u0442\
\u0438\u0441\u0442\u044B \u0448\u0435\u043F\u0447\u0443\u0442, \u0430 \u043D\
\u0435 \u0433\u043E\u0432\u043E\u0440\u044F\u0442."
type: Tweak
- message: "\u0423\u043C\u0435\u043D\u044C\u0448\u0435\u043D\u043E \u0432\u0440\u0435\
\u043C\u044F \u0441\u0442\u0430\u043D\u0430 \u043A\u0440\u043E\u0432\u0430\u0432\
\u043E\u0433\u043E \u043A\u043E\u043F\u044C\u044F \u0434\u043E 4 \u0441\u0435\
\u043A\u0443\u043D\u0434, \u0442\u0435\u043F\u0435\u0440\u044C \u043E\u043D\u043E\
\ \u043E\u0442\u0441\u043A\u0430\u043A\u0438\u0432\u0430\u0435\u0442 \u043E\u0442\
\ \u043A\u0443\u043B\u044C\u0442\u0438\u0441\u0442\u043E\u0432 \u0438 \u043A\
\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0432 \u0438 \u043D\u0435\
\ \u0441\u0442\u0430\u043D\u0438\u0442 \u043A\u043E\u0441\u043C\u043E\u043D\u0430\
\u0432\u0442\u0438\u043A\u043E\u0432 \u0441\u043E \u0441\u0432\u044F\u0449\u0435\
\u043D\u043D\u044B\u043C \u043E\u0440\u0443\u0436\u0438\u0435\u043C \u0432 \u0440\
\u0443\u043A\u0430\u0445."
type: Tweak
- message: "\u041E\u0442\u043A\u0430\u0442 \u0431\u0430\u0444\u0444\u0430 \u043A\
\u0440\u043E\u0432\u0430\u0432\u043E\u0433\u043E \u0437\u0430\u043B\u043F\u0430\
."
type: Tweak
- message: "\u0411\u0430\u0433\u0444\u0438\u043A\u0441\u044B \u043A\u0443\u043B\u044C\
\u0442\u0430."
type: Fix
id: 423
time: '2024-07-28T16:54:32.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/507
- author: Spatison
changes:
- message: "\u041F\u043E\u0434\u043D\u044F\u0442\u044B\u0439 \u0449\u0438\u0442\
\ \u0441\u043D\u043E\u0432\u0430 \u043D\u0435 \u0434\u0430\u0435\u0442 \u043F\
\u0440\u043E\u0439\u0442\u0438"
type: Fix
- message: "\u0411\u043E\u0434\u0438\u043A\u0430\u043C\u0435\u0440\u044B \u0442\u0435\
\u043F\u0435\u0440\u044C \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0435\
\u0442\u0441\u044F \u043D\u0430 \u043C\u043E\u043D\u0438\u0442\u043E\u0440\u0438\
\u043D\u0433\u0435 \u0431\u0435\u0441\u043F\u0440\u043E\u0432\u043E\u0434\u043D\
\u044B\u0445 \u043A\u0430\u043C\u0435\u0440 \u043F\u0440\u0438 \u043D\u0430\u043B\
\u0438\u0447\u0438\u0438 \u043D\u0430 \u0441\u0442\u0430\u043D\u0446\u0438\u0438\
\ \u0431\u0435\u0441\u043F\u0440\u043E\u0432\u043E\u0434\u043D\u043E\u0433\u043E\
\ \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043E\u0440\
\u0430 \u0421\u0411"
type: Fix
id: 424
time: '2024-07-28T18:02:55.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/508
- author: ThereDrD
changes:
- message: "\u0414\u043E\u0431\u0430\u0432\u043B\u0435\u043D \u0420\u041F\u0414\
, \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u043E, \u043F\u043E\
\u0437\u0432\u043E\u043B\u044F\u044E\u0449\u0435\u0435 \u0431\u044B\u0441\u0442\
\u0440\u043E \u0441\u0442\u0440\u043E\u0438\u0442\u044C \u0430\u0442\u043C\u043E\
\u0441\u0444\u0435\u0440\u043D\u044B\u0435 \u0438 \u043C\u0443\u0441\u043E\u0440\
\u043D\u044B\u0435 \u0442\u0440\u0443\u0431\u044B. \u0410 \u0442\u0430\u043A\
\ \u0436\u0435 \u0441\u043E\u043F\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\
\u0438\u0435 \u044D\u0442\u043E\u043C\u0443 \u0443\u0441\u0442\u0440\u043E\u0439\
\u0441\u0442\u0432\u0430"
type: Add
- message: "\u0422\u0435\u043F\u0435\u0440\u044C \u0432\u0441\u0435 \u0420\u0426\
\u0414 \u0438 \u0420\u041F\u0414 \u043C\u043E\u0436\u043D\u043E \u0437\u0430\
\u0440\u044F\u0436\u0430\u0442\u044C \u0440\u0435\u0441\u0443\u0440\u0441\u0430\
\u043C\u0438, \u0432\u0440\u043E\u0434\u0435 \u043C\u0435\u0442\u0430\u043B\u043B\
\u0430, \u0441\u0442\u0430\u043B\u0438, \u0441\u0442\u0435\u043A\u043B\u0430\
\ \u0438 \u0442.\u043F. \u0414\u0430\u0436\u0435 \u043F\u0440\u043E\u0432\u043E\
\u0434\u0430\u043C\u0438. \u0420\u0430\u0437\u043D\u044B\u0435 \u0440\u0435\u0441\
\u0443\u0440\u0441\u044B \u0434\u0430\u044E\u0442 \u0440\u0430\u0437\u043D\u044B\
\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044B \u0434\u0430\u044E\u0442 \u0440\
\u0430\u0437\u043D\u043E\u0435 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\
\u0432\u043E \u0437\u0430\u0440\u044F\u0434\u043E\u0432"
type: Add
- message: "\u0420\u0426\u0414 \u043D\u0430\u0443\u0447\u0438\u043B\u0441\u044F\
\ \u0441\u0442\u0440\u043E\u0438\u0442\u044C \u043A\u0430\u043C\u0435\u0440\u044B\
\ \u0438 \u0410\u041F\u0426"
type: Add
- message: "\u0420\u041F\u0414 \u0438 \u0420\u0426\u0414 \u0434\u043E\u0431\u0430\
\u0432\u043B\u0435\u043D\u044B \u0432 \u0438\u0441\u0441\u043B\u0435\u0434\u043E\
\u0432\u0430\u043D\u0438\u044F \u0420\u043D\u0414 1\u0433\u043E \u0443\u0440\
\u043E\u0432\u043D\u044F."
type: Add
- message: "\u0418\u0433\u0440\u043E\u043A\u0438, \u0438\u0433\u0440\u0430\u0432\
\u0448\u0438\u0435 \u043C\u0435\u043D\u044C\u0448\u0435 3 \u0434\u043D\u0435\
\u0439 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043F\u043E\u043C\
\u0435\u0447\u0430\u044E\u0442\u0441\u044F \u0447\u0430\u0441\u0430\u043C\u0438\
\ \u0432 \u0430\u0434\u043C\u0438\u043D-\u043C\u0435\u043D\u044E, \u0447\u0442\
\u043E\u0431\u044B \u043F\u0435\u0434\u0430\u043B\u0438 \u043C\u043E\u0433\u043B\
\u0438 \u043B\u0435\u0433\u0447\u0435 \u043E\u0442\u043B\u0438\u0447\u0430\u0442\
\u044C \u043D\u043E\u0432\u044B\u0445 \u0438\u0433\u0440\u043E\u043A\u043E\u0432\
."
type: Add
- message: "\u0428\u0430\u0442\u0442\u043B \u043F\u0440\u0438\u0431\u044B\u0442\u0438\
\u044F \u043F\u0440\u0438\u0431\u044B\u0432\u0430\u044E\u0442 \u043D\u0430 \u0432\
\u043E\u043A\u0437\u0430\u043B \u043F\u0440\u0438\u0431\u044B\u0442\u0438\u044F\
\ \u0431\u044B\u0441\u0442\u0440\u0435\u0435"
type: Tweak
- message: "\u041F\u0435\u0434\u0430\u043B\u0438 \u0442\u0435\u043F\u0435\u0440\u044C\
\ \u0441\u043F\u0430\u0432\u043D\u044F\u0442\u0441\u044F \u0432 \u0434\u0435\
\u0430\u0434\u043C\u0438\u043D\u0435, \u043A\u043E\u0433\u0434\u0430 \u0437\u0430\
\u0445\u043E\u0434\u044F\u0442 \u0437\u0430 \u0440\u043E\u043B\u044C \u0432\
\ \u0440\u0430\u0443\u043D\u0434\u0435"
type: Tweak
- message: "\u0426\u0435\u043D\u044B \u0438 \u0432\u0440\u0435\u043C\u044F \u043F\
\u043E\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0432 \u0420\u0426\u0414 \u0441\
\u0442\u0430\u043B\u0438 \u043C\u0435\u043D\u044C\u0448\u0435."
type: Tweak
- message: "\u0420\u0430\u0434\u0438\u0430\u043B\u044C\u043D\u043E\u0435 \u043C\u0435\
\u043D\u044E \u0420\u0426\u0414 \u0438 \u0420\u041F\u0414 \u0442\u0435\u043F\
\u0435\u0440\u044C \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\
\u0441\u043A\u0438 \u0438\u0437\u043C\u0435\u043D\u044F\u0435\u0442 \u0441\u0432\
\u043E\u0439 \u0440\u0430\u0437\u043C\u0435\u0440 \u043E\u0442 \u043A\u043E\u043B\
\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0438\u043A\u043E\u043D\u043E\u043A"
type: Tweak
- message: "\u0423\u0431\u0440\u0430\u043D \u0434\u0435\u0431\u0430\u0444\u0444\
\ \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043D\u0438\u044F \u043E\u0442\
\ \u043F\u0435\u0440\u0435\u0435\u0434\u0430\u043D\u0438\u044F \u0438 \u043F\
\u0435\u0440\u0435\u043F\u0438\u0442\u0438\u044F \u0432 \u0432\u0438\u0434\u0443\
\ \u0435\u0433\u043E \u043D\u0435\u043E\u0447\u0435\u0432\u0438\u0434\u043D\u043E\
\u0439 \u043C\u0435\u0445\u0430\u043D\u0438\u043A\u0438 \u043F\u043E\u044F\u0432\
\u043B\u0435\u043D\u0438\u044F. \u041F\u0440\u0435\u0434\u0443\u0433\u0430\u0434\
\u0430\u0442\u044C, \u043A\u043E\u0433\u0434\u0430 \u043F\u0435\u0440\u0441\u043E\
\u043D\u0430\u0436 \u043F\u0435\u0440\u0435\u0435\u0441\u0442 \u0438\u043B\u0438\
\ \u043F\u0435\u0440\u0435\u043F\u044C\u0435\u0442 \u043D\u0435\u0432\u043E\u0437\
\u043C\u043E\u0436\u043D\u043E."
type: Remove
id: 425
time: '2024-07-29T03:04:21.0000000+00:00'
url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/510

View File

@@ -34,8 +34,8 @@ ent-InstantActionSummonCultDagger = Призыв Ритуального Кинж
ent-InstantActionBloodRites = Кровавые Обряды
.desc = Высасывает кровь и исцеляет вас.
ent-ActionCultStun = Оглушение
.desc = Сильное заклинание, которое оглушает и обезмолвливает жертв. Не работает на цели со священным оружием в руках или с чипом защиты разума.
ent-InstantActionCultStun = Оглушение
.desc = Сильное заклинание, которое оглушает и обезмолвливает жертв. Не работает на цели со священным оружием в руках. При наличии пентаграммы над головой эффект сильно ослабевает.
ent-ActionCultShadowShackles = Теневые Узы
.desc = Бесшумное заклинание, которое наложит на человека теневые наручники и заставит вашу жертву замолчать на 10 секунд.

View File

@@ -1,3 +1,4 @@
bolt-barrage-component-no-empty-hand = Вам нужно иметь свободную руку, чтобы стрелять.
bolt-barrage-component-not-cultist = Вы не умеете пользоваться магией.
bolt-barrage-component-extra-desc = [color=darkgray]Для стрельбы залпом необходимо иметь свободную руку. Вобросите залп, чтобы навсегда избавиться от него.[/color]
bolt-barrage-component-extra-desc = [color=darkgray]Для стрельбы залпом необходимо иметь свободную руку.[/color]
bolt-barrage-component-extra-message = [color=darkgray]Выбросите залп, чтобы навсегда избавиться от него.[/color]

View File

@@ -32,7 +32,7 @@ cult-blood-boil-rune-need-minimum = Необходимо минимум 3 кул
cult-blood-boil-rune-no-blood = Кому-то из культистов не хватает крови.
cult-blood-boil-rune-no-targets = Нет целей.
cult-teleport-rune-default-label = безымянная метка
cult-narsie-summon-drawn-position = Культ закончил рисовать руну ритуала разрыва измерений! Координаты: { $posText }
cult-narsie-summon-drawn-position = Культ закончил рисовать руну ритуала разрыва измерений! Локация: { $location }
cult-cant-draw-rune = Нельзя рисовать руну в космосе.
runes-window-title = Руны

View File

@@ -5,11 +5,11 @@ ent-SoulShardGhost = камень душ
.desc = Мистический светящийся осколок.
.suffix = Роль призраков
ent-WetStone = точильный камень
.desc = Используется для заточки кромок стальных инструментов.
ent-StunHand = оглушающая аура
.desc = Оглушит и обезмолвит жертву при ударе.
ent-CultSharpener = древний точильный камень
.desc = Используется для заточки кромок стальных инструментов.
ent-ShadowShackles = теневые оковы
.desc = Оковы, сковывающие запястья с помощью зловещей магии.
ent-CultRunicMetal = рунический металл
.desc = Необычный лист металла с пульсирующей руной.
@@ -19,10 +19,17 @@ ent-CultRunicMetal1 = рунический металл
.desc = Необычный лист металла с пульсирующей руной.
.suffix = Один
ent-CultRunicMetal4 = рунический металл
.desc = Необычный лист металла с пульсирующей руной.
.suffix = 4
ent-CultRunicMetal20 = рунический металл
.desc = Необычный лист металла с пульсирующей руной.
.suffix = 20
ent-AltarTome = архивы
.desc = Стол, заваленный тайными рукописями и книгами на неизвестных языках.
ent-CultBloodAltar = алтарь
.desc = Кровавый алтарь, посвященный какому-то существу.
@@ -38,9 +45,6 @@ ent-AirlockGlassCult = рунический шлюз
ent-WallForceCult = светящаяся стена
.desc = Нечестивый щит, блокирующий все атаки.
ent-CultClothingBlindfold = повязка Зилота
.desc = Повязка, наделенная странной силой.
ent-OfferingRune = руна предпонесения
.desc = Мгновенно превращает обычного члена экипажа в культиста, для чего требуется 2 культиста вокруг руны. Члена экипажа с имплантом защиты разума нельзя перевоплотить, можно только принести в жертву, для чего нужно 3 культиста, которые встанут вокруг руны. Если цель мертва, то она будет принесена в жертву, для чего требуется 1 культист.

View File

@@ -2,9 +2,6 @@ cultist-factory-charging = { $name } будут заряжаться ещё { $s
cultist-factory-create = Создать { $itemName }
cultist-factory-too-far = Слишком далеко
ent-AltarTome = архивы
.desc = Стол, заваленный тайными рукописями и книгами на неизвестных языках.
ent-CultRobeModify = одеяние флагелланта
.desc = Какая-то религиозная роба.
@@ -13,9 +10,18 @@ ent-CultMirrorShield = зеркальный щит
ent-CultOuterArmor = бронированная мантия
.desc = С первого взгляда кажется, что это простая мантия, но на ней имеется элементы брони.
ent-ShadowShackles = теневые оковы
.desc = Оковы, сковывающие запястья с помощью зловещей магии.
ent-WetStone = точильный камень
.desc = Используется для заточки кромок стальных инструментов.
ent-CultSharpener = древний точильный камень
.desc = Используется для заточки кромок стальных инструментов.
ent-CultClothingBlindfold = повязка Зилота
.desc = Повязка, наделенная странной силой.
ent-BloodSpear = кровавое копьё
.desc = Ужасающее копьё, полностью состоящее из кристаллизованной крови.
ent-BloodBarrage = залп кровавых снарядов
.desc = Кровь за кровь.

View File

@@ -0,0 +1,3 @@
cult-stun-component-extra-message = [color=darkgray]Выбросите ауру, чтобы навсегда избавиться от неё.[/color]
cult-magic-holy = Сила священного предмета в руках цели препятствует магии!
cult-magic-no-empty-hand = Вам нужна свободная рука для использования заклинания!

View File

@@ -43,6 +43,7 @@ arcane-barrage-no-empty-hand = Вам нужна свободная рука д
mindswap-success = Ваш разум подменили!
mindswap-borer-failed = Его разумом кто-то управляет.
mindswap-cultist-failed = Нечестивая сила препятствует подмене сознания.
store-currency-display-spell-point = Очки заклинаний

View File

@@ -1,30 +1,59 @@
### UI
# WD EDIT ALL
# Shown when an RCD is examined in details range
rcd-component-examine-detail = В данный момент выбран режим { $mode }.
# Shown when an RCD is examined in details range
rcd-component-examine-detail-count =
Находится в режиме { $mode ->
*[other] _
[floors] полы
[walls] стены
[airlock] шлюзы
[deconstruct] разбор
}, и { $ammoCount ->
*[zero] не содержит зарядов.
[one] содержит 1 заряд.
[few] содержит { $ammoCount } заряда.
[other] содержит { $ammoCount } зарядов.
}
# UI
### Interaction Messages
rcd-component-examine-mode-details = Текущий режим: '{$mode}'.
rcd-component-examine-build-details = Текущий режим строительства: {$name}.
# Shown when changing RCD Mode
rcd-component-change-mode = РЦД переключён в режим { $mode }.
## Interaction Messages
# Mode change
rcd-component-change-mode = РЦД переключён в режим '{$mode}'.
rcd-component-change-build-mode = РЦД переключён в режим строительства {$name}.
# Ammo count
rcd-component-no-ammo-message = В РЦД закончились заряды!
rcd-component-tile-indestructible-message = Эта плитка не может быть уничтожена!
rcd-component-tile-obstructed-message = Этот тайл заблокирован!
rcd-component-deconstruct-target-not-on-whitelist-message = Вы не можете это деконструировать!
rcd-component-cannot-build-floor-tile-not-empty-message = Пол можно построить только в космосе или на покрытии!
rcd-component-cannot-build-wall-tile-not-empty-message = Вы не можете построить стену в космосе!
rcd-component-cannot-build-airlock-tile-not-empty-message = Вы не можете построить шлюз в космосе!
rcd-component-insufficient-ammo-message = В РЦД недостаточно зарядов!
# Deconstruction
rcd-component-tile-indestructible-message = Эта плитка неразрушима!
rcd-component-deconstruct-target-not-on-whitelist-message = Вы не можете это демонтировать!
rcd-component-nothing-to-deconstruct-message = Здесь нечего демонтировать!
rcd-component-tile-obstructed-message = Вы не можете демонтировать плитку, если на ней что-то есть!
# Construction
rcd-component-no-valid-grid = Вы слишком далеко в открытом космосе, чтобы строить здесь!
rcd-component-must-build-on-empty-tile-message = Здесь уже есть фундамент!
rcd-component-cannot-build-on-empty-tile-message = Вы не можете строить это без фундамента!
rcd-component-must-build-on-subfloor-message = Вы можете строить это только на открытом полу!
rcd-component-cannot-build-on-subfloor-message = Вы не можете строить это на открытом полу!
rcd-component-cannot-build-on-occupied-tile-message = Вы не можете строить здесь, это место уже занято!
rcd-component-cannot-build-identical-tile = Эта плитка уже существует!
### Category names
# RCD
rcd-category-WallsAndFlooring = Стены и пол
rcd-category-WindowsAndGrilles = Окна и решётки
rcd-category-Airlocks = Шлюзы
rcd-category-Electrical = Электрика
rcd-category-Lighting = Освещение
# RPD
rcd-category-Pipes = Трубы
rcd-category-GasDevices = Атмосферные приборы
rcd-category-DisposalPipes = Мусорные трубы
rcd-category-DisposalUnits = Мусорные приборы
### Prototype names (note: constructable items will be puralized)
rcd-component-deconstruct = демонтаж
rcd-component-floor-steel = стальная плитка
rcd-component-plating = лист обшивки
# RPD naming
ent-RapidPipeDispenser = РПД
.desc = Новейшее ручное строительное устройство, которое может быстро размещать трубы и атмосферные приборы.

View File

@@ -92,6 +92,7 @@
- id: ClothingEyesGlassesMeson
- id: ClothingShoesBootsMag
- id: ClothingHandsGlovesColorYellow
- id: RapidPipeDispenser # WD
- type: entity
id: LockerAtmosphericsFilled
@@ -111,6 +112,7 @@
- id: ClothingEyesGlassesMeson
- id: ClothingShoesBootsMag
- id: ClothingHandsGlovesColorYellow
- id: RapidPipeDispenser # WD
- type: entity
id: LockerEngineerFilledHardsuit

View File

@@ -152,6 +152,7 @@
- id: ClothingOuterHardsuitEngineeringWhite
- id: ClothingMaskBreath
- id: OxygenTankFilled
- id: RapidPipeDispenser # WD
- type: entity
id: LockerChiefEngineerFilled
@@ -169,6 +170,7 @@
- id: RCDAmmo
amount: 2
- id: HolofanProjector
- id: RapidPipeDispenser # WD
- type: entity
id: LockerChiefMedicalOfficerFilledHardsuit

View File

@@ -12,6 +12,5 @@
GeigerCounter: 3
InflatableWallStack1: 24
InflatableDoorStack1: 8
emaggedInventory:
RCD: 1
RCDAmmo: 3
RCD: 3 # WD
RCDAmmo: 3 # WD

View File

@@ -82,7 +82,9 @@
- type: EmitSoundOnDrop
sound:
path: /Audio/White/Items/handling/drinkglass_drop.ogg
- type: Tag
tags:
- DrinkGlass
# Transformable container - normal glass
- type: entity
name: metamorphic glass

View File

@@ -34,6 +34,9 @@
solution: food
- type: TrashOnSolutionEmpty
solution: food
- type: Tag
tags:
- Ingredient
- type: entity
abstract: true
@@ -272,6 +275,9 @@
reagents:
- ReagentId: Nutriment
Quantity: 15
- type: Tag
tags:
- Ingredient
- type: entity
name: dough
@@ -648,3 +654,6 @@
reagents:
- ReagentId: CocoaPowder
Quantity: 2
- type: Tag
tags:
- Ingredient

View File

@@ -86,6 +86,8 @@
reagents:
- ReagentId: Silicon
Quantity: 10
- type: RCDAmmo # WD
canBeExamined: false
- type: entity
parent: SheetGlass
@@ -172,6 +174,9 @@
max: 1
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 2
- type: entity
parent: SheetRGlass
@@ -249,6 +254,9 @@
max: 1
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 2
- type: entity
parent: SheetPGlass
@@ -315,6 +323,9 @@
- ReagentId: Carbon
Quantity: 0.5
canReact: false
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 3
- type: entity
parent: SheetRPGlass

View File

@@ -70,6 +70,8 @@
Quantity: 9
- ReagentId: Carbon
Quantity: 1
- type: RCDAmmo # WD
canBeExamined: false
- type: entity
parent: SheetSteel
@@ -206,6 +208,9 @@
- ReagentId: Carbon
Quantity: 1
canReact: false
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 2
- type: entity
parent: SheetPlasteel

View File

@@ -164,6 +164,9 @@
- ReagentId: Phosphorus
Quantity: 5
canReact: false
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 0.5
- type: entity
parent: SheetPlastic

View File

@@ -74,6 +74,9 @@
Quantity: 4.5
- ReagentId: Carbon
Quantity: 0.5
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 0.5
- type: entity
parent: PartRodMetal

View File

@@ -27,6 +27,9 @@
price: 0
- type: StackPrice
price: 1
- type: RCDAmmo # WD
canBeExamined: false
chargeCountModifier: 0.2
- type: entity
id: CableHVStack

View File

@@ -395,32 +395,11 @@
path: "/Audio/Items/drill_hit.ogg"
- type: entity
id: RCD
id: BaseRCD
parent: BaseItem
name: RCD
description: The rapid construction device can be used to quickly place and remove various station structures and fixtures. Requires compressed matter to function.
components:
- type: RCD
availablePrototypes:
- WallSolid
- FloorSteel
- Plating
- Catwalk
- Grille
- Window
- WindowDirectional
- WindowReinforcedDirectional
- ReinforcedWindow
- Airlock
- AirlockGlass
- Firelock
- TubeLight
- BulbLight
- LVCable
- MVCable
- HVCable
- CableTerminal
- Deconstruct
- type: LimitedCharges
maxCharges: 30
charges: 30
@@ -449,13 +428,18 @@
key: enum.RcdUiKey.Key
- type: entity
id: RCDEmpty
parent: RCD
suffix: Empty
id: RCD
parent: BaseRCD
name: RCD
description: The rapid construction device can be used to quickly place and remove various station structures and fixtures. Requires compressed matter to function.
components:
- type: LimitedCharges
charges: 0
- type: RCD
categoryPrototypes: # WD
- WallsAndFlooring # WD
- WindowsAndGrilles # WD
- Airlocks # WD
- Electrical # WD
- Lighting # WD
availablePrototypes:
- WallSolid
- FloorSteel
@@ -469,6 +453,76 @@
- Airlock
- AirlockGlass
- Firelock
- TubeLight
- BulbLight
- LVCable
- MVCable
- HVCable
- CableTerminal
- APC # WD
- Camera # WD
- Deconstruct
- type: entity
id: RCDEmpty
parent: RCD
suffix: Empty
components:
- type: LimitedCharges
charges: 0
- type: entity # WD
id: RapidPipeDispenser
parent: BaseRCD
components:
- type: Sprite
sprite: White/Items/Tools/rpd.rsi
- type: Item
size: Normal
shape:
- 0, 0, 1, 0
- type: Clothing
sprite: White/Items/Tools/rpd.rsi
quickEquip: false
slots:
- Belt
- type: RCD
categoryPrototypes:
- Pipes
- GasDevices
- DisposalPipes
- DisposalUnits
availablePrototypes:
- PipeStraight # pipes
- PipeBend
- PipeTJunction
- PipeFourway
- GasCanisterPort # gas devices
- GasFilter
- GasMixer
- GasOutletInjector
- GasPressurePump
- GasVolumePump
- GasValve
- SignalControlledValve
- PressureControlledValve
- GasVentScrubber
- GasVentPump
- GasPassiveVent
- DisposalPipe # disposal pipes
- DisposalBend
- DisposalJunction
- DisposalJunctionFlipped
- DisposalYJunction
- DisposalRouter
- DisposalRouterFlipped
- DisposalTagger
- DisposalSignalRouter
- DisposalSignalRouterFlipped
- DisposalTrunk
- DisposalUnit # disposal units
- MailingUnit
- ToiletEmpty
- type: entity
id: RCDRecharging
@@ -500,6 +554,7 @@
description: A cartridge of raw matter compacted by bluespace technology. Used in rapid construction devices.
components:
- type: RCDAmmo
chargeCountModifier: 1.5
- type: Sprite
sprite: Objects/Tools/rcd.rsi
state: ammo

View File

@@ -1442,7 +1442,7 @@
- type: Projectile
damage:
types:
Piercing: 25
Piercing: 20
- type: entity
name: arcane bolt

View File

@@ -349,6 +349,8 @@
- KitchenKnife # WD EDIT
- ButchCleaver # WD EDIT
- WeaponTempGun # WD EDIT
- RapidPipeDispenserRecipe # WD edit
- RCDRecipe # WD edit
- DeviceQuantumSpinInverter
- type: EmagLatheRecipes
emagDynamicRecipes:

View File

@@ -164,3 +164,4 @@
components:
- type: SurveillanceCameraRouter
subnetFrequency: SurveillanceCameraSecurity
subnetColor: "#DE3A3AFF"

View File

@@ -0,0 +1,475 @@
# Parents
- type: entity
abstract: true
id: ShelfBase
parent: BaseStructure
name: shelf
description: a strange place to place, well, anything really. You feel like you shouldn't be seeing this.'
components:
- type: Sprite
drawdepth: WallMountedItems
sprite: Structures/Storage/Shelfs/wood.rsi
state: base
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb
bounds: "-0.35,-0.35,0.35,0.35"
density: 35
layer:
- BulletImpassable
- type: Transform
- type: Damageable
damageModifierSet: Wood
damageContainer: Inorganic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 60
behaviors:
- !type:PlaySoundBehavior
sound:
collection: WoodDestroyHeavy
- !type:DoActsBehavior
acts: ["Destruction"]
- type: WallMount
arc: 175
- type: Storage
grid:
- 0,0,3,1
- 0,3,3,4
maxItemSize: Normal
- type: UserInterface
interfaces:
- key: enum.StorageUiKey.Key
type: StorageBoundUserInterface
- type: InteractionOutline
- type: ContainerContainer
containers:
storagebase: !type:Container
- type: Tag
tags:
- Structure
- type: entity
abstract: true
id: ShelfBaseReinforced
parent: ShelfBase
name: reinforced shelf
description: It looks as strong as reality itself.
components:
- type: Lock
- type: LockVisuals
- type: Sprite
sprite: Structures/Storage/Shelfs/wood.rsi
state: base
layers:
- state: rbase
map: ["enum.StorageVisualLayers.Base"]
- state: unlocked
shader: unshaded
# used to keep the unlocked light visible while open.
- state: closed
map: ["enum.StorageVisualLayers.Door"]
- state: locked
map: ["enum.LockVisualLayers.Lock"]
shader: unshaded
- type: Appearance
- type: EntityStorageVisuals
stateDoorOpen: open
stateDoorClosed: closed
- type: AccessReader
# Normal
- type: entity
id: ShelfWood
parent: ShelfBase
name: wooden shelf
description: A convenient place to place, well, anything really.
components:
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 60
behaviors:
- !type:PlaySoundBehavior
sound:
collection: WoodDestroyHeavy
- !type:SpawnEntitiesBehavior
spawn:
MaterialWoodPlank1:
min: 1
max: 3
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Tag
tags:
- Structure
- Wooden
- type: Construction
graph: Shelf
node: ShelfWood
- type: entity
id: ShelfMetal
parent: ShelfBase
name: metal shelf
description: A sturdy place to place, well, anything really.
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/metal.rsi
state: base
- type: Damageable
damageModifierSet: Metallic
damageContainer: Inorganic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 120
behaviors:
- !type:PlaySoundBehavior
sound:
collection: MetalBreak
- !type:SpawnEntitiesBehavior
spawn:
SheetSteel1:
min: 2
max: 4
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Tag
tags:
- Structure
- type: Construction
graph: Shelf
node: ShelfMetal
- type: entity
id: ShelfGlass
parent: ShelfBase
name: glass shelf
description: A fragile place to place, well, anything really.
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/glass.rsi
state: base
- type: Damageable
damageModifierSet: Glass
damageContainer: Inorganic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 50
behaviors:
- !type:PlaySoundBehavior
sound:
collection: WindowShatter
- !type:SpawnEntitiesBehavior
spawn:
ShardGlass:
min: 0
max: 2
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Tag
tags:
- Structure
- type: Construction
graph: Shelf
node: ShelfGlass
# Reinforced
- type: entity
id: ShelfRWood
parent: ShelfBaseReinforced
name: sturdy wood shelf
description: A safe place to put your favorite bottle of whiskey
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/wood.rsi
state: base
layers:
- state: rbase
map: ["enum.StorageVisualLayers.Base"]
- state: closed
map: ["enum.StorageVisualLayers.Door"]
- state: locked
map: ["enum.LockVisualLayers.Lock"]
shader: unshaded
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 215
behaviors:
- !type:PlaySoundBehavior
sound:
collection: WoodDestroyHeavy
- !type:SpawnEntitiesBehavior
spawn:
MaterialWoodPlank:
min: 2
max: 5
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Construction
graph: Shelf
node: ShelfRWood
- type: entity
id: ShelfRMetal
parent: ShelfBaseReinforced
name: sturdy metal shelf
description: A strong & shiny place to keep all your vials safe
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/metal.rsi
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 450
behaviors:
- !type:PlaySoundBehavior
sound:
collection: MetalBreak
- !type:SpawnEntitiesBehavior
spawn:
SheetPlasteel1:
min: 2
max: 3
ShardGlass:
min: 1
max: 2
PartRodMetal1:
min: 1
max: 2
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Construction
graph: Shelf
node: ShelfRMetal
- type: entity
id: ShelfRGlass
parent: ShelfBaseReinforced
name: sturdy glass shelf
description: Crystal clear reinforced glass doors to show off all your fancy bottles you definitely didn't sell a co-worker's favorite mothroach for.
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/glass.rsi
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 250
behaviors:
- !type:PlaySoundBehavior
sound:
collection: WindowShatter
- !type:SpawnEntitiesBehavior
spawn:
SheetPlastic1:
min: 1
max: 3
ShardGlass:
min: 1
max: 2
PartRodMetal1:
min: 0
max: 1
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Construction
graph: Shelf
node: ShelfRGlass
# Departmental
- type: entity
id: ShelfBar
parent: ShelfBase
name: bar shelf
description: Made out of the finest synthetic wood for all alcohol holding needs.
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/Departments/Service/bar.rsi
state: base
layers:
- state: base
- state: bar-0
- map: ["enum.StorageFillLayers.Fill"]
- type: Appearance
- type: StorageFillVisualizer
maxFillLevels: 13
fillBaseName: bar
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 100
behaviors:
- !type:PlaySoundBehavior
sound:
collection: WoodDestroyHeavy
- !type:SpawnEntitiesBehavior
spawn:
MaterialWoodPlank1:
min: 1
max: 4
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Storage
grid:
- 0,0,5,1
- 0,3,5,4
maxItemSize: Normal
whitelist:
tags:
- DrinkGlass
- DrinkBottle
- DrinkCan
- Beer
- type: Construction
graph: Shelf
node: ShelfBar
- type: entity
id: ShelfKitchen
parent: ShelfBase
name: cooking shelf
description: Holds knifes, spice, and everything nice!
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/Departments/Service/kitchen.rsi
state: base
layers:
- state: base
- state: kitchen-0
- map: ["enum.StorageFillLayers.Fill"]
- type: Appearance
- type: StorageFillVisualizer
maxFillLevels: 13
fillBaseName: kitchen
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 150
behaviors:
- !type:PlaySoundBehavior
sound:
collection: MetalBreak
- !type:SpawnEntitiesBehavior
spawn:
SheetSteel1:
min: 1
max: 4
MaterialWoodPlank1:
min: 0
max: 1
PartRodMetal1:
min: 0
max: 2
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Storage
grid:
- 0,0,5,1
- 0,3,5,4
maxItemSize: Normal
whitelist:
tags:
- DrinkGlass
- BoxCardboard
- MonkeyCube
- Enzyme
- Mayo
- Packet
- Cleaver
- Knife
- KitchenKnife
- RollingPin
- Ingredient
- Trash
- type: Construction
graph: Shelf
node: ShelfKitchen
- type: entity
id: ShelfChemistry
parent: ShelfBaseReinforced
name: chemical shelf
description: Keeps all your chemicals safe and out of the clow- er, public hands!
components:
- type: Sprite
sprite: Structures/Storage/Shelfs/Departments/Medical/chemistry.rsi
layers:
- state: base
map: ["enum.StorageVisualLayers.Base"]
- state: unlocked
shader: unshaded
- state: chem-0
- map: ["enum.StorageFillLayers.Fill"]
- state: closed
map: ["enum.StorageVisualLayers.Door"]
- state: locked
map: ["enum.LockVisualLayers.Lock"]
shader: unshaded
- type: StorageFillVisualizer
maxFillLevels: 7
fillBaseName: chem
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 330
behaviors:
- !type:PlaySoundBehavior
sound:
collection: MetalBreak
- !type:SpawnEntitiesBehavior
spawn:
SheetPlasteel1:
min: 1
max: 2
SheetPlastic1:
min: 1
max: 2
ShardGlass:
min: 1
max: 1
- !type:DoActsBehavior
acts: ["Destruction"]
- type: Storage
grid:
- 0,0,5,1
- 0,3,5,4
maxItemSize: Normal
whitelist:
tags:
- ChemDispensable
- GlassBeaker
- Bottle
- type: Construction
graph: Shelf
node: ShelfChemistry
# Access presets
# Try to keep alphabetical sorting if adding more
- type: entity
parent: ShelfChemistry
id: ShelfChemistryChemistrySecure
suffix: Chemistry, Secure
components:
- type: AccessReader
access: [["Chemistry"]]

View File

@@ -62,3 +62,23 @@
uiWindowPos: 3,0
strippingWindowPos: 0,2
displayName: Back
- name: underwearb #WD slot
slotTexture: underwearb
slotFlags: UNDERWEARB
stripTime: 6
uiWindowPos: 3,0
strippingWindowPos: 2,1
displayName: Panties
whitelist:
tags:
- underwearb
- name: underweart #WD slot
slotTexture: underweart
slotFlags: UNDERWEART
stripTime: 6
uiWindowPos: 3,1
strippingWindowPos: 2,0
displayName: Bra
whitelist:
tags:
- underweart

View File

@@ -2,7 +2,7 @@
- type: rcd
id: Invalid # Hidden prototype - do not add to RCDs
mode: Invalid
- type: rcd
id: Deconstruct
name: rcd-component-deconstruct
@@ -13,14 +13,14 @@
rotation: Camera
- type: rcd
id: DeconstructLattice # Hidden prototype - do not add to RCDs
id: DeconstructLattice # Hidden prototype - do not add to RCDs
name: rcd-component-deconstruct
mode: Deconstruct
cost: 2
delay: 0
rotation: Camera
fx: EffectRCDConstruct0
- type: rcd
id: DeconstructTile # Hidden prototype - do not add to RCDs
name: rcd-component-deconstruct
@@ -30,7 +30,7 @@
rotation: Camera
fx: EffectRCDDeconstruct4
# Flooring
# Flooring
- type: rcd
id: Plating
name: rcd-component-plating
@@ -39,12 +39,12 @@
mode: ConstructTile
prototype: Plating
cost: 1
delay: 1
delay: 0
collisionMask: InteractImpassable
rules:
- CanBuildOnEmptyTile
fx: EffectRCDConstruct1
fx: EffectRCDConstruct0
- type: rcd
id: FloorSteel
name: rcd-component-floor-steel
@@ -53,11 +53,11 @@
mode: ConstructTile
prototype: FloorSteel
cost: 1
delay: 1
delay: 0
collisionMask: InteractImpassable
rules:
- CanBuildOnEmptyTile
fx: EffectRCDConstruct1
fx: EffectRCDConstruct0
- type: rcd
id: Catwalk
@@ -66,13 +66,13 @@
mode: ConstructObject
prototype: Catwalk
cost: 1
delay: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
- IsCatwalk
rotation: Fixed
fx: EffectRCDConstruct1
fx: EffectRCDConstruct0
# Walls
- type: rcd
@@ -80,7 +80,7 @@
category: WallsAndFlooring
sprite: /Textures/Interface/Radial/RCD/solid_wall.png
mode: ConstructObject
prototype: WallSolid
prototype: WallSolid
cost: 4
delay: 2
collisionMask: FullTileMask
@@ -93,11 +93,11 @@
sprite: /Textures/Interface/Radial/RCD/grille.png
mode: ConstructObject
prototype: Grille
cost: 4
delay: 2
cost: 1
delay: 1
collisionMask: FullTileMask
rotation: Fixed
fx: EffectRCDConstruct2
fx: EffectRCDConstruct1
# Windows
- type: rcd
@@ -106,20 +106,49 @@
sprite: /Textures/Interface/Radial/RCD/window.png
mode: ConstructObject
prototype: Window
cost: 3
delay: 2
cost: 2
delay: 1
collisionMask: FullTileMask
rules:
- IsWindow
rotation: Fixed
fx: EffectRCDConstruct2
fx: EffectRCDConstruct1
- type: rcd
id: WindowDirectional
category: WindowsAndGrilles
sprite: /Textures/Interface/Radial/RCD/directional.png
mode: ConstructObject
prototype: WindowDirectional
cost: 1
delay: 1
collisionMask: FullTileMask
collisionBounds: "-0.23,-0.49,0.23,-0.36"
rules:
- IsWindow
rotation: User
fx: EffectRCDConstruct1
- type: rcd
id: ReinforcedWindow
category: WindowsAndGrilles
sprite: /Textures/Interface/Radial/RCD/window_reinforced.png
mode: ConstructObject
prototype: ReinforcedWindow
cost: 4
delay: 2
collisionMask: FullTileMask
rules:
- IsWindow
rotation: User
fx: EffectRCDConstruct2
- type: rcd
id: WindowReinforcedDirectional
category: WindowsAndGrilles
sprite: /Textures/Interface/Radial/RCD/directional_reinforced.png
mode: ConstructObject
prototype: WindowReinforcedDirectional
cost: 2
delay: 1
collisionMask: FullTileMask
@@ -128,35 +157,6 @@
- IsWindow
rotation: User
fx: EffectRCDConstruct1
- type: rcd
id: ReinforcedWindow
category: WindowsAndGrilles
sprite: /Textures/Interface/Radial/RCD/window_reinforced.png
mode: ConstructObject
prototype: ReinforcedWindow
cost: 4
delay: 3
collisionMask: FullTileMask
rules:
- IsWindow
rotation: User
fx: EffectRCDConstruct3
- type: rcd
id: WindowReinforcedDirectional
category: WindowsAndGrilles
sprite: /Textures/Interface/Radial/RCD/directional_reinforced.png
mode: ConstructObject
prototype: WindowReinforcedDirectional
cost: 3
delay: 2
collisionMask: FullTileMask
collisionBounds: "-0.23,-0.49,0.23,-0.36"
rules:
- IsWindow
rotation: User
fx: EffectRCDConstruct2
# Airlocks
- type: rcd
@@ -166,11 +166,11 @@
mode: ConstructObject
prototype: Airlock
cost: 4
delay: 4
delay: 3
collisionMask: FullTileMask
rotation: Camera
fx: EffectRCDConstruct4
fx: EffectRCDConstruct3
- type: rcd
id: AirlockGlass
category: Airlocks
@@ -178,22 +178,22 @@
mode: ConstructObject
prototype: AirlockGlass
cost: 4
delay: 4
delay: 3
collisionMask: FullTileMask
rotation: Camera
fx: EffectRCDConstruct4
fx: EffectRCDConstruct3
- type: rcd
id: Firelock
category: Airlocks
sprite: /Textures/Interface/Radial/RCD/firelock.png
mode: ConstructObject
prototype: Firelock
cost: 4
delay: 3
cost: 2
delay: 2
collisionMask: FullTileMask
rotation: Camera
fx: EffectRCDConstruct3
fx: EffectRCDConstruct2
# Lighting
- type: rcd
@@ -202,25 +202,25 @@
sprite: /Textures/Interface/Radial/RCD/tube_light.png
mode: ConstructObject
prototype: Poweredlight
cost: 2
delay: 1
cost: 1
delay: 0
collisionMask: TabletopMachineMask
collisionBounds: "-0.23,-0.49,0.23,-0.36"
rotation: User
fx: EffectRCDConstruct1
fx: EffectRCDConstruct0
- type: rcd
id: BulbLight
category: Lighting
sprite: /Textures/Interface/Radial/RCD/bulb_light.png
mode: ConstructObject
prototype: PoweredSmallLight
cost: 2
delay: 1
cost: 1
delay: 0
collisionMask: TabletopMachineMask
collisionBounds: "-0.23,-0.49,0.23,-0.36"
rotation: User
fx: EffectRCDConstruct1
fx: EffectRCDConstruct0
# Electrical
- type: rcd
@@ -236,7 +236,7 @@
- MustBuildOnSubfloor
rotation: Fixed
fx: EffectRCDConstruct0
- type: rcd
id: MVCable
category: Electrical
@@ -250,7 +250,7 @@
- MustBuildOnSubfloor
rotation: Fixed
fx: EffectRCDConstruct0
- type: rcd
id: HVCable
category: Electrical
@@ -264,7 +264,7 @@
- MustBuildOnSubfloor
rotation: Fixed
fx: EffectRCDConstruct0
- type: rcd
id: CableTerminal
category: Electrical
@@ -277,4 +277,29 @@
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
fx: EffectRCDConstruct0
- type: rcd # WD
id: APC
category: Electrical
sprite: /Textures/Structures/Power/apc.rsi/static.png
mode: ConstructObject
prototype: APCConstructed
cost: 4
delay: 1
collisionMask: None
rotation: User
fx: EffectRCDConstruct1
- type: rcd # WD
id: Camera
category: Electrical
sprite: /Textures/Structures/Wallmounts/camera.rsi/cameracase.png
mode: ConstructObject
prototype: SurveillanceCameraConstructed
cost: 1
delay: 1
collisionMask: TabletopMachineMask
collisionBounds: "-0.23,-0.49,0.23,-0.36"
rotation: User
fx: EffectRCDConstruct1

View File

@@ -0,0 +1,268 @@
- type: constructionGraph
id: Shelf
start: start
graph:
- node: start
actions:
- !type:DeleteEntity {}
edges:
# Normal
- to: ShelfWood
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: WoodPlank
amount: 4
doAfter: 2
- to: ShelfMetal
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: Steel
amount: 5
doAfter: 3
- to: ShelfGlass
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: Glass
amount: 4
doAfter: 2
# Reinforced
- to: ShelfRWood
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: WoodPlank
amount: 8
doAfter: 3
- material: Cable
amount: 2
doAfter: 1
- to: ShelfRMetal
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: Plasteel
amount: 5
doAfter: 3
- material: ReinforcedGlass
amount: 5
doAfter: 2
- material: Cable
amount: 3
doAfter: 1
- to: ShelfRGlass
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: Plastic
amount: 5
doAfter: 2
- material: ReinforcedGlass
amount: 5
doAfter: 3
- material: Cable
amount: 2
doAfter: 1
# Departmental
- to: ShelfBar
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: WoodPlank
amount: 6
doAfter: 2
- to: ShelfKitchen
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: MetalRod
amount: 2
doAfter: 1
- material: Steel
amount: 5
- material: WoodPlank
amount: 3
doAfter: 2
- to: ShelfChemistry
completed:
- !type:SnapToGrid
southRotation: true
steps:
- material: Plasteel
amount: 2
doAfter: 2
- material: ReinforcedGlass
amount: 5
doAfter: 2
- material: Plastic
amount: 5
doAfter: 2
- material: Cable
amount: 2
doAfter: 1
# Normal deconstructs
- node: ShelfWood
entity: ShelfWood
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: MaterialWoodPlank1
amount: 4
steps:
- tool: Prying
doAfter: 2
- node: ShelfMetal
entity: ShelfMetal
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: SheetSteel1
amount: 5
steps:
- tool: Screwing
doAfter: 5
- node: ShelfGlass
entity: ShelfGlass
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: SheetGlass1
amount: 4
steps:
- tool: Screwing
doAfter: 2
# Reinforced deconstructs
- node: ShelfRWood
entity: ShelfRWood
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: MaterialWoodPlank1
amount: 8
- !type:SpawnPrototype
prototype: CableApcStack1
amount: 2
steps:
- tool: Screwing
doAfter: 5
- tool: Prying
doAfter: 2
- node: ShelfRMetal
entity: ShelfRMetal
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: SheetPlasteel1
amount: 5
- !type:SpawnPrototype
prototype: SheetRGlass1
amount: 5
- !type:SpawnPrototype
prototype: CableApcStack1
amount: 3
steps:
- tool: Screwing
doAfter: 2
- tool: Welding
doAfter: 5
- node: ShelfRGlass
entity: ShelfRGlass
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: SheetPlastic1
amount: 5
- !type:SpawnPrototype
prototype: SheetRGlass1
amount: 5
- !type:SpawnPrototype
prototype: CableApcStack1
amount: 2
steps:
- tool: Welding
doAfter: 2
- tool: Screwing
doAfter: 4
# Departmental deconstructs
- node: ShelfBar
entity: ShelfBar
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: MaterialWoodPlank1
amount: 6
steps:
- tool: Prying
doAfter: 3
- node: ShelfKitchen
entity: ShelfKitchen
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: PartRodMetal
amount: 2
- !type:SpawnPrototype
prototype: SheetSteel1
amount: 5
- !type:SpawnPrototype
prototype: MaterialWoodPlank1
amount: 3
steps:
- tool: Screwing
doAfter: 2
- tool: Welding
doAfter: 2
- tool: Prying
doAfter: 1
- node: ShelfChemistry
entity: ShelfChemistry
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: SheetPlasteel1
amount: 2
- !type:SpawnPrototype
prototype: SheetPlastic1
amount: 5
- !type:SpawnPrototype
prototype: SheetRGlass1
amount: 5
- !type:SpawnPrototype
prototype: CableApcStack1
amount: 2
steps:
- tool: Welding
doAfter: 2
- tool: Screwing
doAfter: 1
- tool: Anchoring
doAfter: 2
- tool: Prying
doAfter: 4

View File

@@ -49,3 +49,150 @@
canBuildInImpassable: false
conditions:
- !type:TileNotBlocked
# Shelfs
# Normals
- type: construction
id: ShelfWood
name: wooden shelf
description: A convenient place to place, well, anything really.
graph: Shelf
startNode: start
targetNode: ShelfWood
icon:
sprite: Structures/Storage/Shelfs/wood.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
- type: construction
id: ShelfMetal
name: metal shelf
description: A sturdy place to place, well, anything really.
graph: Shelf
startNode: start
targetNode: ShelfMetal
icon:
sprite: Structures/Storage/Shelfs/metal.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
- type: construction
id: ShelfGlass
name: glass shelf
description: Just like a normal shelf! But fragile and without the walls!
graph: Shelf
startNode: start
targetNode: ShelfGlass
icon:
sprite: Structures/Storage/Shelfs/glass.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
# Reinforced
- type: construction
id: ShelfRWood
name: sturdy wooden shelf
description: The perfect place to store all your vintage records.
graph: Shelf
startNode: start
targetNode: ShelfRWood
icon:
sprite: Structures/Storage/Shelfs/wood.rsi
state: rbase
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
- type: construction
id: ShelfRMetal
name: sturdy metal shelf
description: Nice and strong, and keeps your maints loot secure.
graph: Shelf
startNode: start
targetNode: ShelfRMetal
icon:
sprite: Structures/Storage/Shelfs/metal.rsi
state: rbase
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
- type: construction
id: ShelfRGlass
name: sturdy glass shelf
description: See through, decent strength, shiny plastic case. Whats not to love?
graph: Shelf
startNode: start
targetNode: ShelfRGlass
icon:
sprite: Structures/Storage/Shelfs/glass.rsi
state: rbase
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
# Departmental
- type: construction
id: ShelfBar
name: bar shelf
description: A convenient place for all your extra booze, specifically designed to hold more bottles!
graph: Shelf
startNode: start
targetNode: ShelfBar
icon:
sprite: Structures/Storage/Shelfs/Departments/Service/bar.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
- type: construction
id: ShelfKitchen
name: cooking shelf
description: Holds your knifes, spice, and everything nice!
graph: Shelf
startNode: start
targetNode: ShelfKitchen
icon:
sprite: Structures/Storage/Shelfs/Departments/Service/kitchen.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition
- type: construction
id: ShelfChemistry
name: chemical shelf
description: Perfect for keeping the most important chemicals safe, and out of the clumsy clowns hands!
graph: Shelf
startNode: start
targetNode: ShelfChemistry
icon:
sprite: Structures/Storage/Shelfs/Departments/Medical/chemistry.rsi
state: base
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: true
conditions:
- !type:WallmountCondition

View File

@@ -54,6 +54,7 @@
- AutolatheHyperConvectionMachineCircuitboard
- ProtolatheHyperConvectionMachineCircuitboard
- SheetifierMachineCircuitboard
- RCDRecipe # WD
- type: technology
id: PowerGeneration
@@ -85,6 +86,7 @@
recipeUnlocks:
- ThermomachineFreezerMachineCircuitBoard
- GasRecyclerMachineCircuitboard
- RapidPipeDispenserRecipe # WD
- type: technology
id: RipleyAPLU

View File

@@ -10,6 +10,7 @@
sprite: /Textures/Objects/Materials/Sheets/metal.rsi
state: steel
event: !type:CultTwistedConstructionActionEvent
speech: "Ethra p'ni dedol!"
itemIconStyle: BigAction
charges: 1
temporary: true
@@ -31,6 +32,7 @@
sprite: /Textures/White/Cult/actions_cult.rsi
state: teleport
event: !type:CultTeleportTargetActionEvent
speech: "Sas'so c'arta forbici!"
itemIconStyle: BigAction
charges: 1
temporary: true
@@ -58,20 +60,16 @@
removeOnNoCharges: true
- type: entity
id: ActionCultStun
id: InstantActionCultStun
name: Stun
description: A potent spell that will stun and mute victims.
noSpawn: true
components:
- type: EntityTargetAction
whitelist:
components:
- HumanoidAppearance
canTargetSelf: false
- type: InstantAction
icon:
sprite: /Textures/White/Cult/actions_cult.rsi
state: stun
event: !type:CultStunTargetActionEvent
event: !type:CultStunActionEvent
itemIconStyle: BigAction
charges: 1
temporary: true
@@ -92,6 +90,7 @@
sprite: /Textures/White/Cult/actions_cult.rsi
state: shackles
event: !type:CultShadowShacklesTargetActionEvent
speech: "In'totum Lig'abis!"
itemIconStyle: BigAction
charges: 4
temporary: true
@@ -108,6 +107,7 @@
sprite: /Textures/White/Cult/interface.rsi
state: icon
event: !type:CultSummonDaggerActionEvent
speech: "Wur d'dai leev'mai k'sagan!"
charges: 1
temporary: true
removeOnNoCharges: true
@@ -123,6 +123,7 @@
sprite: /Textures/White/Cult/actions_cult.rsi
state: blood_rites
event: !type:CultBloodRitesInstantActionEvent
speech: "Fel'th Dol Ab'orod!"
charges: 5
temporary: true
removeOnNoCharges: true
@@ -138,6 +139,7 @@
sprite: /Textures/White/Cult/actions_cult.rsi
state: emp
event: !type:CultElectromagneticPulseInstantActionEvent
speech: "Ta'gh fara'qha fel d'amar det!"
charges: 1
temporary: true
removeOnNoCharges: true
@@ -153,12 +155,15 @@
sprite: /Textures/White/Cult/actions_cult.rsi
state: gone
event: !type:CultConcealInstantActionEvent
speech: "Kla'atu barada nikt'o!"
charges: 10
temporary: true
removeOnNoCharges: true
- type: ConcealPresenceSpell
concealEvent: !type:CultConcealInstantActionEvent
speech: "Kla'atu barada nikt'o!"
revealEvent: !type:CultRevealInstantActionEvent
speech: "Kla'atu barada nikt'o!"
concealIcon:
sprite: /Textures/White/Cult/actions_cult.rsi
state: gone

View File

@@ -1,4 +1,4 @@
- type: entity
- type: entity
id: CultTileSpawnEffect
name: Sparkle
placement:
@@ -103,3 +103,18 @@
drawdepth: Effects
- type: PointLight
color: "#FF0000"
- type: entity
id: CultStunFlashEffect
noSpawn: true
components:
- type: PointLight
enabled: true
radius: 5
energy: 8
netsync: false
color: Red
- type: LightFade
duration: 0.5
- type: TimedDespawn
lifetime: 0.5

View File

@@ -24,6 +24,8 @@
proto: BloodBolt
capacity: 25
- type: BoltBarrage
- type: DeleteOnDropAttempt
message: bolt-barrage-component-extra-message
- type: GiftIgnore
- type: CultItem
canPickUp: false

View File

@@ -0,0 +1,34 @@
- type: entity
parent: BaseItem
id: StunHand
name: stunning aura
description: Will stun and mute a weak-minded victim on hit.
components:
- type: Sprite
sprite: White/Cult/Entities/stun.rsi
state: icon
- type: Item
size: Ginormous
sprite: White/Cult/Entities/stun.rsi
- type: MeleeWeapon
canHeavyAttack: false
canAttackSelf: false
canMiss: false
attackWhitelist:
components:
- StatusEffects
attackBlacklist:
components:
- Cultist
- Construct
wideAnimationRotation: 180
damage:
types:
Heat: 0
- type: CultStunHand
- type: DeleteOnDropAttempt
message: cult-stun-component-extra-message
- type: Unremoveable
deleteOnDrop: true
- type: CultItem
canPickUp: false

View File

@@ -187,6 +187,16 @@
- type: Stack
count: 1
- type: entity
parent: CultRunicMetal
id: CultRunicMetal4
suffix: 4
components:
- type: Sprite
state: runic
- type: Stack
count: 4
- type: entity
parent: CultRunicMetal
id: CultRunicMetal20

View File

@@ -165,4 +165,5 @@
- type: CultRuneBase
invokePhrase: "TOK-LYR RQA-NAP G'OLT-ULOFT!"
cultistGatheringRange: 1.5
invokeChatType: Speak
- type: CultRuneApocalypse

View File

@@ -19,7 +19,7 @@
- 0.30,0.40
density: 20
mask:
- ItemMask
- BulletImpassable
restitution: 0.3
friction: 0.2
- type: Sharp

View File

@@ -65,7 +65,7 @@
types:
Heat: 18
- type: Item
size: Normal
size: Ginormous
sprite: White/Objects/Weapons/Chaplain/godhand.rsi
- type: Unremoveable
deleteOnDrop: true

View File

@@ -1,51 +1,43 @@
- type: moodEffect
id: Handcuffed
desc: "Кажется мои выходки кто-то заметил."
description: "Кажется мои выходки кто-то заметил."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
- type: moodEffect
id: Suffocating
desc: "НЕ.. МОГУ... ДЫШАТЬ..."
description: "НЕ.. МОГУ... ДЫШАТЬ..."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
timeout: 1
- type: moodEffect
id: OnFire
desc: "ГОРЮ!!!"
description: "ГОРЮ!!!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: false
- type: moodEffect
id: Creampied
desc: "Меня окремили. На вкус как пирог."
description: "Меня окремили. На вкус как пирог."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
timeout: 3
- type: moodEffect
id: MobSlipped
desc: "Опять поскальзываюсь. Надо быть аккуратней."
description: "Опять поскальзываюсь. Надо быть аккуратней."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
timeout: 3
- type: moodEffect
id: MobVomit
desc: "Меня только что вырвало. Мерзость."
description: "Меня только что вырвало. Мерзость."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
timeout: 8
- type: moodEffect
id: MobLowPressure
desc: "Меня сейчас разорвёт наружу!"
description: "Меня сейчас разорвёт наружу!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
- type: moodEffect
id: MobHighPressure
desc: "На меня оказывается огромное давление!"
description: "На меня оказывается огромное давление!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false

View File

@@ -1,66 +1,66 @@
- type: moodEffect
id: BeingHugged
desc: "Обнимашки - круто."
description: "Обнимашки - круто."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
positive: true
timeout: 2
- type: moodEffect
id: BeingPet
desc: "Меня погладили!"
description: "Меня погладили!"
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
positive: true
timeout: 2
- type: moodEffect
id: ArcadePlay
desc: "Я весело поиграл в интересную аркаду."
description: "Я весело поиграл в интересную аркаду."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
positive: true
timeout: 8
- type: moodEffect
id: GotBlessed
desc: "Меня благословили."
description: "Меня благословили."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
positive: true
timeout: 8
- type: moodEffect
id: PetAnimal
desc: "Животные такие милые! Не могу перестать их гладить!"
description: "Животные такие милые! Не могу перестать их гладить!"
moodChange: enum.MoodChangeLevel.Small
positiveEffect: true
positive: true
timeout: 5
- type: moodEffect
id: SavedLife
desc: "Так приятно спасать чью-то жизнь."
description: "Так приятно спасать чью-то жизнь."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
positive: true
timeout: 8
- type: moodEffect
id: TraitorFocused #Used for traitors to boost their goals completion.
desc: "У меня есть цель, и я добьюсь её, во что бы то ни стало!"
description: "У меня есть цель, и я добьюсь её, во что бы то ни стало!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
positive: true
- type: moodEffect
id: RevolutionFocused #Used for revolution
desc: "СЛАВА РЕВОЛЮЦИИ!!!"
description: "СЛАВА РЕВОЛЮЦИИ!!!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
positive: true
- type: moodEffect
id: CultFocused
desc: "Знаю правду, славим великого!"
description: "Знаю правду, славим великого!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: true
positive: true
- type: moodEffect
id: Stimulator
desc: "Я ЧУВСТВУЮ ЭТО, В МОЕЙ КРОВИ НАХОДИТСЯ ЧТО-ТО НЕОБЫЧНОЕ!!"
description: "Я ЧУВСТВУЮ ЭТО, В МОЕЙ КРОВИ НАХОДИТСЯ ЧТО-ТО НЕОБЫЧНОЕ!!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
timeout: 2
positive: true
timeout: 2

View File

@@ -1,87 +1,78 @@
#Hunger
- type: moodEffect
id: HungerOverfed
desc: "Во мне столько жира..."
description: "Во мне столько жира..."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
category: "Hunger"
- type: moodEffect
id: HungerOkay
desc: "Мой желудок полон!"
description: "Мой желудок полон!"
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
positive: true
category: "Hunger"
- type: moodEffect
id: HungerPeckish
desc: "Хочу есть."
description: "Хочу есть."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
category: "Hunger"
- type: moodEffect
id: HungerStarving
desc: "Голодаю!"
description: "Голодаю!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: false
category: "Hunger"
#Thirst
- type: moodEffect
id: ThirstOverHydrated
desc: "СЛИШКОМ МНОГО ВОДЫ..."
description: "СЛИШКОМ МНОГО ВОДЫ..."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
category: "Thirst"
- type: moodEffect
id: ThirstOkay
desc: "Не хочу пить."
description: "Не хочу пить."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: true
positive: true
category: "Thirst"
- type: moodEffect
id: ThirstThirsty
desc: "Хочу пить."
description: "Хочу пить."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
category: "Thirst"
- type: moodEffect
id: ThirstParched
desc: "ВОДЫ!"
description: "ВОДЫ!"
moodChange: enum.MoodChangeLevel.Big
positiveEffect: false
category: "Thirst"
#Health
- type: moodEffect
id: HealthNoDamage
desc: "Чувствую себя лишённым боли."
description: "Чувствую себя лишённым боли."
moodChange: enum.MoodChangeLevel.None
positiveEffect: true
positive: true
hidden: true
category: "Health"
- type: moodEffect
id: HealthLightDamage
desc: "Мои ссадины жгутся."
description: "Мои ссадины жгутся."
moodChange: enum.MoodChangeLevel.Small
positiveEffect: false
category: "Health"
- type: moodEffect
id: HealthSevereDamage
desc: "Сильная боль пронзает меня."
description: "Сильная боль пронзает меня."
moodChange: enum.MoodChangeLevel.Medium
positiveEffect: false
category: "Health"
- type: moodEffect
id: HealthHeavyDamage
desc: "Агония гложет мою душу!"
description: "Агония гложет мою душу!"
moodChange: enum.MoodChangeLevel.Large
positiveEffect: false
category: "Health"

View File

@@ -0,0 +1,43 @@
- type: rcdCategory
id: WallsAndFlooring
spritePath: /Textures/Interface/Radial/RCD/walls_and_flooring.png
- type: rcdCategory
id: WindowsAndGrilles
spritePath: /Textures/Interface/Radial/RCD/windows_and_grilles.png
- type: rcdCategory
id: Airlocks
spritePath: /Textures/Interface/Radial/RCD/airlocks.png
- type: rcdCategory
id: Electrical
spritePath: /Textures/Interface/Radial/RCD/multicoil.png
- type: rcdCategory
id: Lighting
spritePath: /Textures/Interface/Radial/RCD/lighting.png
- type: rcdCategory
id: Pipes
spritePath:
sprite: /Textures/Structures/Piping/Atmospherics/pipe.rsi
state: pipeFourway
- type: rcdCategory
id: GasDevices
spritePath:
sprite: /Textures/Structures/Piping/Atmospherics/vent.rsi
state: vent_off
- type: rcdCategory
id: DisposalPipes
spritePath:
sprite: /Textures/Structures/Piping/disposal.rsi
state: conpipe-t
- type: rcdCategory
id: DisposalUnits
spritePath:
sprite: /Textures/Structures/Piping/disposal.rsi
state: disposal

View File

@@ -0,0 +1,482 @@
# Pipes
- type: rcd
id: PipeStraight
category: Pipes
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pipe.rsi
state: pipeStraight
mode: ConstructObject
prototype: GasPipeStraight
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: PipeBend
category: Pipes
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pipe.rsi
state: pipeBend
mode: ConstructObject
prototype: GasPipeBend
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: PipeTJunction
category: Pipes
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pipe.rsi
state: pipeTJunction
mode: ConstructObject
prototype: GasPipeTJunction
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: PipeFourway
category: Pipes
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pipe.rsi
state: pipeFourway
mode: ConstructObject
prototype: GasPipeFourway
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
# Gas devices
- type: rcd
id: GasCanisterPort
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/gascanisterport.rsi
state: gasCanisterPort
mode: ConstructObject
prototype: GasPort
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasFilter
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/gasfilter.rsi
state: gasFilter
mode: ConstructObject
prototype: GasFilter
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasMixer
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/gasmixer.rsi
state: gasMixer
mode: ConstructObject
prototype: GasMixer
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasOutletInjector
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/outletinjector.rsi
state: injector
mode: ConstructObject
prototype: GasOutletInjector
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasPressurePump
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pump.rsi
state: pumpPressure
mode: ConstructObject
prototype: GasPressurePump
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasVolumePump
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pump.rsi
state: pumpVolume
mode: ConstructObject
prototype: GasVolumePump
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasValve
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pump.rsi
state: pumpManualValve
mode: ConstructObject
prototype: GasValve
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: SignalControlledValve
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pump.rsi
state: pumpDigitalValve
mode: ConstructObject
prototype: SignalControlledValve
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: PressureControlledValve
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/pneumaticvalve.rsi
state: off
mode: ConstructObject
prototype: PressureControlledValve
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasVentScrubber
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/scrubber.rsi
state: scrub_off
mode: ConstructObject
prototype: GasVentScrubber
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasVentPump
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/vent.rsi
state: vent_off
mode: ConstructObject
prototype: GasVentPump
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: GasPassiveVent
category: GasDevices
sprite:
sprite: /Textures/Structures/Piping/Atmospherics/vent.rsi
state: vent_off
mode: ConstructObject
prototype: GasPassiveVent
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
# Disposal pipes
- type: rcd
id: DisposalPipe
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-s
mode: ConstructObject
prototype: DisposalPipe
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalBend
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-c
mode: ConstructObject
prototype: DisposalBend
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalJunction
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-j1
mode: ConstructObject
prototype: DisposalJunction
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalJunctionFlipped
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-j1
mode: ConstructObject
prototype: DisposalJunctionFlipped
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalYJunction
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-y
mode: ConstructObject
prototype: DisposalYJunction
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalRouter
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-j1s
mode: ConstructObject
prototype: DisposalRouter
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalRouterFlipped
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-j2s
mode: ConstructObject
prototype: DisposalRouterFlipped
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalTagger
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: pipe-tagger
mode: ConstructObject
prototype: DisposalTagger
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalSignalRouter
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: signal-router
mode: ConstructObject
prototype: DisposalSignalRouter
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalSignalRouterFlipped
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: signal-router-flipped
mode: ConstructObject
prototype: DisposalSignalRouterFlipped
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
- type: rcd
id: DisposalTrunk
category: DisposalPipes
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: conpipe-t
mode: ConstructObject
prototype: DisposalTrunk
cost: 1
delay: 0
collisionMask: InteractImpassable
rules:
- MustBuildOnSubfloor
rotation: User
fx: EffectRCDConstruct0
# Disposal units
- type: rcd
id: DisposalUnit
category: DisposalUnits
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: disposal
mode: ConstructObject
prototype: DisposalUnit
cost: 2
delay: 1
collisionMask: InteractImpassable
rotation: User
fx: EffectRCDConstruct1
- type: rcd
id: MailingUnit
category: DisposalUnits
sprite:
sprite: /Textures/Structures/Piping/disposal.rsi
state: mailing
mode: ConstructObject
prototype: MailingUnit
cost: 2
delay: 1
collisionMask: InteractImpassable
rotation: User
fx: EffectRCDConstruct1
- type: rcd
id: ToiletEmpty
category: DisposalUnits
sprite:
sprite: /Textures/Structures/Furniture/toilet.rsi
state: condisposal
mode: ConstructObject
prototype: ToiletEmpty
cost: 2
delay: 1
collisionMask: InteractImpassable
rotation: User
fx: EffectRCDConstruct1

View File

@@ -166,4 +166,20 @@
result: ShinanoGrenadeBeanbag
completetime: 3
materials:
Steel: 800
Steel: 800
- type: latheRecipe
id: RapidPipeDispenserRecipe
result: RapidPipeDispenser
completetime: 1
materials:
Steel: 300
Glass: 300
- type: latheRecipe
id: RCDRecipe
result: RCD
completetime: 1
materials:
Steel: 300
Glass: 300

View File

@@ -133,5 +133,7 @@
- type: BasicEntityAmmoProvider
proto: ArcaneBolt
capacity: 30
- type: DeleteOnDropAttempt
message: bolt-barrage-component-extra-message
- type: BoltBarrage
- type: GiftIgnore

View File

@@ -1323,6 +1323,12 @@
- type: Tag
id: Wrench
- type: Tag
id: DrinkGlass
- type: Tag
id: Ingredient
- type: Tag
id: Wringer

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

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