Merge branch 'something-something' into great-merge

This commit is contained in:
Remuchi
2024-01-26 17:52:56 +07:00
82 changed files with 2958 additions and 191 deletions

View File

@@ -1,16 +1,22 @@
using Content.Shared.White.Animations;
using System.Numerics;
using Content.Shared.Animations;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Animations;
using Robust.Shared.GameStates;
using Robust.Client.GameObjects;
using static Content.Shared.Animations.EmoteAnimationComponent;
namespace Content.Client.Animations;
using static Content.Shared.White.Animations.EmoteAnimationComponent;
public class EmoteAnimationSystem : EntitySystem
namespace Content.Client.White.Animations;
public sealed class EmoteAnimationSystem : EntitySystem
{
[Dependency] private readonly AnimationPlayerSystem _animationSystem = default!;
private readonly Dictionary<string, Action<EntityUid>> _emoteList = new();
private const string AnimationKey = "emoteAnimationKeyId";
private const string AnimationKeyTurn = "emoteAnimationKeyId_rotate";
//OnVerbsResponse?.Invoke(msg);
public override void Initialize()
{
@@ -19,16 +25,13 @@ public class EmoteAnimationSystem : EntitySystem
// EmoteFlip animation
_emoteList.Add("EmoteFlip", uid =>
{
var animationKey = "emoteAnimationKeyId";
if (_animationSystem.HasRunningAnimation(uid, animationKey))
if (_animationSystem.HasRunningAnimation(uid, AnimationKey))
return;
var baseAngle = Angle.Zero;
if (EntityManager.TryGetComponent(uid, out SpriteComponent? sprite))
{
if (sprite != null)
baseAngle = sprite.Rotation;
baseAngle = sprite.Rotation;
}
var animation = new Animation
@@ -43,7 +46,7 @@ public class EmoteAnimationSystem : EntitySystem
InterpolationMode = AnimationInterpolationMode.Linear,
KeyFrames =
{
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(baseAngle.Degrees), 0f),
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(baseAngle.Degrees - 10), 0f),
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(baseAngle.Degrees + 180), 0.25f),
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(baseAngle.Degrees + 360), 0.25f),
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(baseAngle.Degrees), 0f),
@@ -52,14 +55,13 @@ public class EmoteAnimationSystem : EntitySystem
}
};
_animationSystem.Play(uid, animation, animationKey);
_animationSystem.Play(uid, animation, AnimationKey);
});
// EmoteJump animation
_emoteList.Add("EmoteJump", (EntityUid uid) =>
{
var animationKey = "emoteAnimationKeyId";
if (_animationSystem.HasRunningAnimation(uid, animationKey))
// EmoteJump animation
_emoteList.Add("EmoteJump", uid =>
{
if (_animationSystem.HasRunningAnimation(uid, AnimationKey))
return;
var animation = new Animation
@@ -82,19 +84,18 @@ public class EmoteAnimationSystem : EntitySystem
}
};
_animationSystem.Play(uid, animation, animationKey);
_animationSystem.Play(uid, animation, AnimationKey);
});
// EmoteTurn animation
_emoteList.Add("EmoteTurn", (EntityUid uid) =>
{
var animationKey = "emoteAnimationKeyId_rotate"; // it needs for only rotate anim
if (_animationSystem.HasRunningAnimation(uid, animationKey))
// EmoteTurn animation
_emoteList.Add("EmoteTurn", uid =>
{
if (_animationSystem.HasRunningAnimation(uid, AnimationKeyTurn))
return;
var animation = new Animation
{
Length = TimeSpan.FromMilliseconds(600), // Пока пусть на 0.6 секунд. В идеале бы до 0.9 на 3 поворота
Length = TimeSpan.FromMilliseconds(900),
AnimationTracks =
{
new AnimationTrackComponentProperty
@@ -118,7 +119,7 @@ public class EmoteAnimationSystem : EntitySystem
}
};
_animationSystem.Play(uid, animation, animationKey);
_animationSystem.Play(uid, animation, AnimationKeyTurn);
});
}
@@ -128,9 +129,9 @@ public class EmoteAnimationSystem : EntitySystem
return;
component.AnimationId = state.AnimationId;
if (_emoteList.ContainsKey(component.AnimationId))
if (_emoteList.TryGetValue(component.AnimationId, out var value))
{
_emoteList[component.AnimationId].Invoke(uid);
value.Invoke(uid);
}
}
}

View File

@@ -0,0 +1,49 @@
using Content.Client.White.UserInterface.Controls;
using Content.Shared.White.CheapSurgery;
using Robust.Client.GameObjects;
namespace Content.Client.White.CheapSurgery;
public sealed class CheapSurgerySystem : SharedCheapSurgerySystem
{
[Dependency] private readonly SpriteSystem _sprite = default!;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent<OnSurgeryStarted>(OnStarted);
}
private void OnStarted(OnSurgeryStarted ev)
{
OpenRadialMenu(ev.OrganItems);
}
public void OpenRadialMenu(List<OrganItem> items)
{
if (items.Count == 0)
return;
var radialContainer = new RadialContainer();
foreach (var organ in items)
{
var radialButton = radialContainer.AddButton(organ.Name, _sprite.Frame0(organ.Icon));
radialButton.Controller.OnPressed += _ =>
{
radialContainer.Close();
if (organ.Children.Count > 0)
OpenRadialMenu(organ.Children);
else
SelectOrgan(GetEntity(organ.Uid));
};
}
radialContainer.OpenCentered();
}
public void SelectOrgan(EntityUid uid)
{
var ev = new OnOrganSelected(GetNetEntity(uid));
RaiseNetworkEvent(ev);
}
}

View File

@@ -0,0 +1,73 @@
using Content.Client.Items;
using Content.Client.Message;
using Content.Client.Stylesheets;
using Content.Shared.White.Item.Tricorder;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameStates;
using Robust.Shared.Timing;
namespace Content.Client.White.Items.Tricorder;
/// <inheritdoc/>
public sealed class TricorderSystem : SharedTricorderSystem
{
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TricorderComponent, ItemStatusCollectMessage>(OnCollectItemStatus);
SubscribeLocalEvent<TricorderComponent, ComponentHandleState>(HandleTricorderState);
}
private static void OnCollectItemStatus(EntityUid uid, TricorderComponent component, ItemStatusCollectMessage args)
{
if (component.CurrentMode != TricorderMode.Multitool)
{
args.Controls.Clear();
}
args.Controls.Add(new StatusControl(component));
}
private static void HandleTricorderState(EntityUid uid, TricorderComponent component, ref ComponentHandleState args)
{
if (args.Current is not TricorderComponentState state)
{
return;
}
component.CurrentMode = state.CurrentMode;
}
private sealed class StatusControl : Control
{
private readonly RichTextLabel _label;
private readonly TricorderComponent _tricorder;
private TricorderMode? _linkModeActive;
public StatusControl(TricorderComponent tricorder)
{
_tricorder = tricorder;
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
AddChild(_label);
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
if (_linkModeActive != null && _linkModeActive == _tricorder.CurrentMode)
return;
_linkModeActive = _tricorder.CurrentMode;
var modeLocString = GetNameByMode(_tricorder.CurrentMode);
_label.SetMarkup(Robust.Shared.Localization.Loc.GetString("tricorder-item-status-label",
("mode", Robust.Shared.Localization.Loc.GetString(modeLocString))));
}
}
}

View File

@@ -0,0 +1,50 @@
using Content.Shared.White.Overlays;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
namespace Content.Client.White.Overlays
{
public sealed class NightVisionOverlay : Overlay
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
public override bool RequestScreenTexture => true;
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private readonly ShaderInstance _shader;
public NightVisionOverlay()
{
IoCManager.InjectDependencies(this);
_shader = _prototypeManager.Index<ShaderPrototype>("NightVision").InstanceUnique();
}
protected override void Draw(in OverlayDrawArgs args)
{
if (ScreenTexture == null)
return;
var handle = args.WorldHandle;
if (!_entityManager.TryGetComponent<NightVisionComponent>(_playerManager.LocalSession?.AttachedEntity,
out var component))
{
return;
}
_shader.SetParameter("SCREEN_TEXTURE", ScreenTexture);
_shader.SetParameter("tint", component.Tint);
_shader.SetParameter("luminance_threshold", component.Strength);
_shader.SetParameter("noise_amount", component.Noise);
handle.UseShader(_shader);
handle.DrawRect(args.WorldBounds, component.Color);
handle.UseShader(null);
}
}
}

View File

@@ -0,0 +1,66 @@
using Content.Shared.GameTicking;
using Content.Shared.White.Overlays;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;
namespace Content.Client.White.Overlays;
public sealed class NightVisionSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlayMan = default!;
[Dependency] private readonly ILightManager _lightManager = default!;
private NightVisionOverlay _overlay = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<NightVisionComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<NightVisionComponent, ComponentRemove>(OnRemove);
SubscribeLocalEvent<NightVisionComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<NightVisionComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRestart);
_overlay = new NightVisionOverlay();
}
private void OnPlayerAttached(EntityUid uid, NightVisionComponent component, PlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
_lightManager.DrawLighting = false;
}
private void OnPlayerDetached(EntityUid uid, NightVisionComponent component, PlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
_lightManager.DrawLighting = true;
}
private void OnInit(EntityUid uid, NightVisionComponent component, ComponentInit args)
{
if (_player.LocalSession?.AttachedEntity != uid)
return;
_overlayMan.AddOverlay(_overlay);
_lightManager.DrawLighting = false;
}
private void OnRemove(EntityUid uid, NightVisionComponent component, ComponentRemove args)
{
if (_player.LocalSession?.AttachedEntity != uid)
return;
_overlayMan.RemoveOverlay(_overlay);
_lightManager.DrawLighting = true;
}
private void OnRestart(RoundRestartCleanupEvent ev)
{
_overlayMan.RemoveOverlay(_overlay);
_lightManager.DrawLighting = true;
}
}

View File

@@ -6,6 +6,7 @@ using Content.Client.Viewport;
using JetBrains.Annotations;
using Robust.Client.Animations;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.ResourceManagement;
@@ -31,10 +32,10 @@ public sealed class RadialContainerCommandTest : LocalizedCommands
for (int i = 0; i < 24; i++)
{
var testButton = radial.AddButton("Action " + i, "/Textures/Interface/emotions.svg.192dpi.png");
testButton.Controller.OnPressed += (_) => { Logger.Debug("Press gay"); };
testButton.Controller.OnPressed += _ => { Logger.Debug("Press gay"); };
}
radial.CloseButton.Controller.OnPressed += (_) =>
radial.CloseButton.Controller.OnPressed += _ =>
{
Logger.Debug("Close event for your own logic");
};
@@ -46,17 +47,16 @@ public sealed class RadialContainerCommandTest : LocalizedCommands
[GenerateTypedNameReferences, Virtual]
public partial class RadialContainer : Control
{
private bool _isOpened = false;
private bool _isOpened;
private Vector2 _focusSize = new Vector2(64, 64);
private Vector2 _normalSize = new Vector2(50, 50);
private Vector2 _focusSize = new(64, 64);
private Vector2 _normalSize = new(50, 50);
private float _moveAniTime = 0.3f;
private float _focusAniTime = 0.25f;
private IResourceCache _resourceCache;
private int _maxButtons = 8;
private const int MaxButtons = 8;
private string _backgroundTexture = "/Textures/Interface/Default/SlotBackground.png";
private const string BackgroundTexture = "/Textures/Interface/Default/SlotBackground.png";
public const string MoveAnimationKey = "move";
public const string InSizeAnimationKey = "insize";
@@ -67,29 +67,24 @@ public partial class RadialContainer : Control
get => _focusSize.Y;
set => _focusSize = new Vector2(value, value);
}
public float NormalSize
{
get => _normalSize.Y;
set => _normalSize = new Vector2(value, value);
}
public float MoveAnimationTime
{
get => _moveAniTime;
set => _moveAniTime = value;
}
public float FocusAnimationTime
{
get => _focusAniTime;
set => _focusAniTime = value;
}
public float MoveAnimationTime { get; set; } = 0.3f;
public float FocusAnimationTime { get; set; } = 0.25f;
public bool IsAction = true;
public RadialContainer() : base()
public RadialContainer()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_resourceCache = IoCManager.Resolve<IResourceCache>();
}
public void Open(Vector2 position)
@@ -103,9 +98,10 @@ public partial class RadialContainer : Control
{
AddToRoot();
if (Parent != null)
LayoutContainer.SetPosition(this, (Parent.Size/2) - (this.Size/2));
LayoutContainer.SetPosition(this, Parent.Size / 2 - Size / 2);
else
LayoutContainer.SetPosition(this, (UserInterfaceManager.MainViewport.Size/2) - (this.Size/2));
LayoutContainer.SetPosition(this, UserInterfaceManager.MainViewport.Size / 2 - Size / 2);
UpdateButtons();
}
@@ -114,7 +110,7 @@ public partial class RadialContainer : Control
if (UserInterfaceManager.ActiveScreen == null)
return;
var ent = IoCManager.Resolve<IPlayerManager>().LocalPlayer?.ControlledEntity;
var ent = IoCManager.Resolve<IPlayerManager>().LocalSession?.AttachedEntity;
if (ent == null)
return;
@@ -122,7 +118,11 @@ public partial class RadialContainer : Control
return;
AddToRoot();
LayoutContainer.SetPosition(this, (IoCManager.Resolve<IEyeManager>().MapToScreen(xform.MapPosition).Position * 1.5f));
var position = IoCManager.Resolve<TransformSystem>().GetMapCoordinates(xform);
LayoutContainer.SetPosition(this,
IoCManager.Resolve<IEyeManager>().MapToScreen(position).Position * 1.5f);
UpdateButtons();
}
@@ -139,9 +139,21 @@ public partial class RadialContainer : Control
{
var button = new RadialButton();
button.Content = action;
button.Controller.TextureNormal = IoCManager.Resolve<IResourceCache>().GetTexture(_backgroundTexture);
button.Controller.TextureNormal = _resourceCache.GetTexture(BackgroundTexture);
if (texture != null)
button.BackgroundTexture.Texture = IoCManager.Resolve<IResourceCache>().GetTexture(texture);
button.BackgroundTexture.Texture = _resourceCache.GetTexture(texture);
Layout.AddChild(button);
return button;
}
public RadialButton AddButton(string action, Texture texture)
{
var button = new RadialButton();
button.Content = action;
button.Controller.TextureNormal = _resourceCache.GetTexture(BackgroundTexture);
button.BackgroundTexture.Texture = texture;
Layout.AddChild(button);
return button;
@@ -151,6 +163,7 @@ public partial class RadialContainer : Control
{
if (_isOpened)
return;
UserInterfaceManager.WindowRoot.AddChild(this);
_isOpened = !_isOpened;
}
@@ -159,31 +172,33 @@ public partial class RadialContainer : Control
{
Visible = true;
var angleDegrees = 360/Layout.ChildCount;
var angleDegrees = 360 / Layout.ChildCount;
var stepAngle = -angleDegrees + -90;
var distance = FocusSize * 1.2;
if (Layout.Children.Count() > _maxButtons)
if (Layout.Children.Count() > MaxButtons)
{
for (int i = 0; i < (Layout.Children.Count() - _maxButtons); i++)
for (int i = 0; i < (Layout.Children.Count() - MaxButtons); i++)
{
distance += (NormalSize/3);
distance += (NormalSize / 3);
}
}
foreach (var child in Layout.Children)
{
var button = (RadialButton)child;
var button = (RadialButton) child;
button.ButtonSize = _normalSize;
stepAngle += angleDegrees;
var pos = GetPointFromPolar(stepAngle, distance);
PlayRadialAnimation(button, pos, MoveAnimationKey);
button.Controller.OnMouseEntered += (_) =>
button.Controller.OnMouseEntered += _ =>
{
PlaySizeAnimation(button, _focusSize, OutSizeAnimationKey, InSizeAnimationKey);
ActionLabel.Text = button.Content ?? string.Empty;
ActionLabel.Visible = IsAction;
};
button.Controller.OnMouseExited += (_) =>
button.Controller.OnMouseExited += _ =>
{
PlaySizeAnimation(button, _normalSize, InSizeAnimationKey, OutSizeAnimationKey);
ActionLabel.Visible = false;
@@ -191,18 +206,20 @@ public partial class RadialContainer : Control
}
CloseButton.ButtonSize = _normalSize;
CloseButton.Controller.OnMouseEntered += (_) =>
CloseButton.Controller.OnMouseEntered += _ =>
{
PlaySizeAnimation(CloseButton, _focusSize, OutSizeAnimationKey, InSizeAnimationKey);
ActionLabel.Text = CloseButton.Content ?? string.Empty;
ActionLabel.Visible = true;
};
CloseButton.Controller.OnMouseExited += (_) =>
CloseButton.Controller.OnMouseExited += _ =>
{
PlaySizeAnimation(CloseButton, _normalSize, InSizeAnimationKey, OutSizeAnimationKey);
ActionLabel.Visible = false;
};
CloseButton.Controller.OnPressed += (_) =>
CloseButton.Controller.OnPressed += _ =>
{
Close();
};
@@ -212,7 +229,7 @@ public partial class RadialContainer : Control
{
var anim = new Animation
{
Length = TimeSpan.FromMilliseconds(_moveAniTime * 1000),
Length = TimeSpan.FromMilliseconds(MoveAnimationTime * 1000),
AnimationTracks =
{
new AnimationTrackControlProperty
@@ -221,12 +238,13 @@ public partial class RadialContainer : Control
InterpolationMode = AnimationInterpolationMode.Linear,
KeyFrames =
{
new AnimationTrackProperty.KeyFrame(new Vector2(0,0), 0f),
new AnimationTrackProperty.KeyFrame(pos, _moveAniTime)
new AnimationTrackProperty.KeyFrame(new Vector2(0, 0), 0f),
new AnimationTrackProperty.KeyFrame(pos, MoveAnimationTime)
}
}
}
};
if (!button.HasRunningAnimation(playKey))
button.PlayAnimation(anim, playKey);
}
@@ -235,7 +253,7 @@ public partial class RadialContainer : Control
{
var anim = new Animation
{
Length = TimeSpan.FromMilliseconds(_focusAniTime * 1000),
Length = TimeSpan.FromMilliseconds(FocusAnimationTime * 1000),
AnimationTracks =
{
new AnimationTrackControlProperty
@@ -245,7 +263,7 @@ public partial class RadialContainer : Control
KeyFrames =
{
new AnimationTrackProperty.KeyFrame(button.Size, 0f),
new AnimationTrackProperty.KeyFrame(size, _focusAniTime)
new AnimationTrackProperty.KeyFrame(size, FocusAnimationTime)
}
}
}
@@ -253,6 +271,7 @@ public partial class RadialContainer : Control
if (stopKey != null && button.HasRunningAnimation(stopKey))
button.StopAnimation(stopKey);
if (!button.HasRunningAnimation(playKey))
button.PlayAnimation(anim, playKey);
}
@@ -263,11 +282,12 @@ public partial class RadialContainer : Control
foreach (var child in Layout.Children)
{
var button = (RadialButton)child;
LayoutContainer.SetPosition(child, button.Offset - (button.Size/2));
var button = (RadialButton) child;
LayoutContainer.SetPosition(child, button.Offset - (button.Size / 2));
}
LayoutContainer.SetPosition(CloseButton, CloseButton.Offset - (CloseButton.Size/2));
LayoutContainer.SetPosition(ActionBox, new Vector2(0 - (ActionLabel.Size.X), FocusSize*1.5f));
LayoutContainer.SetPosition(CloseButton, CloseButton.Offset - (CloseButton.Size / 2));
LayoutContainer.SetPosition(ActionBox, new Vector2(0 - (ActionLabel.Size.X), FocusSize * 1.5f));
}
private static Vector2 GetPointFromPolar(double angleDegrees, double distance)
@@ -277,6 +297,6 @@ public partial class RadialContainer : Control
var x = distance * Math.Cos(angleRadians);
var y = distance * Math.Sin(angleRadians);
return new Vector2((int)Math.Round(x), (int)Math.Round(y));
return new Vector2((int) Math.Round(x), (int) Math.Round(y));
}
}

View File

@@ -1,4 +1,5 @@
using Content.Server.Speech.EntitySystems;
using Content.Server.White.AspectsSystem.Aspects;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Humanoid;
using Robust.Shared.Audio;
@@ -12,7 +13,7 @@ namespace Content.Server.Speech.Components;
/// Component required for entities to be able to do vocal emotions.
/// </summary>
[RegisterComponent]
[Access(typeof(VocalSystem))]
[Access(typeof(VocalSystem), typeof(CatEarsAspect))]
public sealed partial class VocalComponent : Component
{
/// <summary>
@@ -41,6 +42,6 @@ public sealed partial class VocalComponent : Component
/// Currently loaded emote sounds prototype, based on entity sex.
/// Null if no valid prototype for entity sex was found.
/// </summary>
[ViewVariables]
[ViewVariables(VVAccess.ReadWrite)]
public EmoteSoundsPrototype? EmoteSounds = null;
}

View File

@@ -1,4 +1,4 @@
namespace Content.Server.Animations;
namespace Content.Server.White.Animations;
[RegisterComponent]
public sealed partial class DancingComponent : Component

View File

@@ -1,11 +1,10 @@
using Content.Server.White.Animations;
using Content.Shared.Animations;
using Content.Shared.Bed.Sleep;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.White.Animations;
using Robust.Shared.Random;
namespace Content.Server.Animations;
namespace Content.Server.White.Animations;
public sealed class DancingSystem : EntitySystem
{
@@ -13,7 +12,7 @@ public sealed class DancingSystem : EntitySystem
[Dependency] private readonly EmoteAnimationSystem _emoteAnimation = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
private readonly string[] _emoteList = {"EmoteFlip", "EmoteTurn"};
private readonly string[] _emoteList = { "EmoteFlip", "EmoteTurn" };
public override void Initialize()
{

View File

@@ -1,31 +1,17 @@
using Content.Server.Actions;
using Content.Server.Chat.Systems;
using Content.Shared.Animations;
using Content.Shared.Chat.Prototypes;
using Content.Shared.White.Animations;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using static Content.Shared.Animations.EmoteAnimationComponent;
using static Content.Shared.White.Animations.EmoteAnimationComponent;
namespace Content.Server.White.Animations;
public sealed class EmoteAnimationSystem : EntitySystem
{
[Dependency] private readonly ActionsSystem _action = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
/// <summary>
/// We write 'EmoteAction' word before id name for instant action.
/// Example: EmoteActionJump, EmoteActionFlip and etc.
/// </summary>
private const string InstantIdentifier = "EmoteAction";
public override void Initialize()
{
SubscribeLocalEvent<EmoteAnimationComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<EmoteAnimationComponent, MapInitEvent>(OnMapInint);
SubscribeLocalEvent<EmoteAnimationComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<EmoteAnimationComponent, EmoteEvent>(OnEmote);
SubscribeLocalEvent<EmoteAnimationComponent, EmoteActionEvent>(OnEmoteAction);
}
private void OnGetState(EntityUid uid, EmoteAnimationComponent component, ref ComponentGetState args)
@@ -33,28 +19,6 @@ public sealed class EmoteAnimationSystem : EntitySystem
args.State = new EmoteAnimationComponentState(component.AnimationId);
}
private void OnMapInint(EntityUid uid, EmoteAnimationComponent component, MapInitEvent args)
{
foreach (var item in _proto.EnumeratePrototypes<EntityPrototype>())
{
if (item.ID.Length <= InstantIdentifier.Length ||
item.ID[..InstantIdentifier.Length] != InstantIdentifier)
continue;
EntityUid? action = null;
component.Actions.Add(action);
_action.AddAction(uid, ref action, item.ID);
}
}
private void OnShutdown(EntityUid uid, EmoteAnimationComponent component, ComponentShutdown args)
{
foreach (var item in component.Actions)
{
_action.RemoveAction(uid, item);
}
}
private void OnEmote(EntityUid uid, EmoteAnimationComponent component, ref EmoteEvent args)
{
if (args.Handled || !args.Emote.Category.HasFlag(EmoteCategory.Gesture))
@@ -63,12 +27,6 @@ public sealed class EmoteAnimationSystem : EntitySystem
PlayEmoteAnimation(uid, component, args.Emote.ID);
}
private void OnEmoteAction(EntityUid uid, EmoteAnimationComponent component, EmoteActionEvent args)
{
PlayEmoteAnimation(uid, component, args.Emote);
args.Handled = true;
}
public void PlayEmoteAnimation(EntityUid uid, EmoteAnimationComponent component, string emoteId)
{
component.AnimationId = emoteId;

View File

@@ -1,12 +1,14 @@
using Content.Server.Chat.Systems;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Speech.Components;
using Content.Server.White.AspectsSystem.Aspects.Components;
using Content.Server.White.AspectsSystem.Base;
using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Content.Shared.Speech;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
@@ -21,6 +23,9 @@ public sealed class CatEarsAspect : AspectSystem<CatEarsAspectComponent>
private MarkingPrototype _ears = default!;
private MarkingPrototype _tail = default!;
private const string FemaleFelinidVoices = "FemaleFelinid";
private const string MaleFelinidVoices = "MaleFelinid";
public override void Initialize()
{
base.Initialize();
@@ -42,13 +47,16 @@ public sealed class CatEarsAspect : AspectSystem<CatEarsAspectComponent>
var entQuery = EntityQueryEnumerator<SpeechComponent, HumanoidAppearanceComponent>();
while (entQuery.MoveNext(out var ent, out _, out _))
{
_chat.TrySendInGameICMessage(ent, _random.Pick(new[] {"Мяу", "Мур", "Ня"}), InGameICChatType.Speak,
_chat.TrySendInGameICMessage(ent, _random.Pick(new[] { "Мяу", "Мур", "Ня" }), InGameICChatType.Speak,
ChatTransmitRange.Normal);
}
}
}
protected override void Started(EntityUid uid, CatEarsAspectComponent component, GameRuleComponent gameRule,
protected override void Started(
EntityUid uid,
CatEarsAspectComponent component,
GameRuleComponent gameRule,
GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);
@@ -93,12 +101,14 @@ public sealed class CatEarsAspect : AspectSystem<CatEarsAspectComponent>
AddTail(appearance);
Dirty(uid, appearance);
ChangeEmotesVoice(uid, appearance);
return;
}
default:
AddEars(appearance);
AddTail(appearance);
Dirty(uid, appearance);
ChangeEmotesVoice(uid, appearance);
break;
}
}
@@ -114,7 +124,7 @@ public sealed class CatEarsAspect : AspectSystem<CatEarsAspectComponent>
if (!appearance.MarkingSet.TryGetMarking(MarkingCategories.Tail, _tail.ID, out _))
{
appearance.MarkingSet.AddFront(MarkingCategories.Tail,
new Marking(_tail.ID, GetColors(appearance, _tail)) {Forced = true});
new Marking(_tail.ID, GetColors(appearance, _tail)) { Forced = true });
}
}
@@ -123,7 +133,25 @@ public sealed class CatEarsAspect : AspectSystem<CatEarsAspectComponent>
if (!appearance.MarkingSet.TryGetMarking(MarkingCategories.HeadTop, _tail.ID, out _))
{
appearance.MarkingSet.AddFront(MarkingCategories.HeadTop,
new Marking(_ears.ID, GetColors(appearance, _ears)) {Forced = true});
new Marking(_ears.ID, GetColors(appearance, _ears)) { Forced = true });
}
}
}
private void ChangeEmotesVoice(EntityUid user, HumanoidAppearanceComponent appearanceComponent)
{
if (!TryComp(user, out VocalComponent? vocals))
{
return;
}
switch (appearanceComponent.Gender)
{
case Gender.Female:
_protoMan.TryIndex(FemaleFelinidVoices, out vocals.EmoteSounds);
break;
case Gender.Male:
_protoMan.TryIndex(MaleFelinidVoices, out vocals.EmoteSounds);
break;
}
}
}

View File

@@ -1,10 +1,10 @@
using Content.Server.Animations;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.White.Animations;
using Content.Server.White.AspectsSystem.Aspects.Components;
using Content.Server.White.AspectsSystem.Base;
using Content.Shared.Animations;
using Content.Shared.Mobs.Components;
using Content.Shared.White.Animations;
namespace Content.Server.White.AspectsSystem.Aspects;
@@ -16,7 +16,11 @@ public sealed class DancingAspect : AspectSystem<DancingAspectComponent>
SubscribeLocalEvent<PlayerSpawnCompleteEvent>(HandleLateJoin);
}
protected override void Started(EntityUid uid, DancingAspectComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
protected override void Started(
EntityUid uid,
DancingAspectComponent component,
GameRuleComponent gameRule,
GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);
var query = EntityQueryEnumerator<EmoteAnimationComponent, MobStateComponent>();

View File

@@ -0,0 +1,122 @@
using Content.Server.Body.Systems;
using Content.Server.Construction;
using Content.Server.Construction.Components;
using Content.Server.Kitchen.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Organ;
using Content.Shared.Body.Part;
using Content.Shared.Humanoid;
using Content.Shared.Interaction;
using Content.Shared.Mobs.Systems;
using Content.Shared.White.CheapSurgery;
using Robust.Shared.Utility;
namespace Content.Server.White.CheapSurgery;
public sealed class CheapSurgerySystem : SharedCheapSurgerySystem
{
[Dependency] private readonly BodySystem _body = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly ConstructionSystem _construction = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BodyComponent, InteractUsingEvent>(OnUsing);
SubscribeNetworkEvent<OnOrganSelected>(OnSelected);
}
private void OnSelected(OnOrganSelected ev)
{
var entity = GetEntity(ev.Uid);
if (TryComp<BodyPartComponent>(entity, out var partComponent) && partComponent.Body != null)
{
StartDrop(partComponent.Body.Value, entity);
}
else if (TryComp<OrganComponent>(entity, out var organComponent) && organComponent.Body != null)
{
StartDrop(organComponent.Body.Value, entity);
}
}
private void OnUsing(EntityUid uid, BodyComponent component, InteractUsingEvent args)
{
if (args.Handled || !TryComp<SharpComponent>(args.Used, out _) || _mobState.IsAlive(uid)
|| TryComp<ActiveSurgeryComponent>(uid, out _))
return;
if (!TryComp<HumanoidAppearanceComponent>(uid, out _))
return;
var organs = GenList(uid);
var ev = new OnSurgeryStarted(GetNetEntity(uid), organs);
RaiseNetworkEvent(ev, args.User);
}
private OrganItem GetOrganItem(EntityUid part, List<OrganItem>? child = null)
{
var metadata = MetaData(part);
var organ = new OrganItem(metadata.EntityName, GetNetEntity(part),
new SpriteSpecifier.EntityPrototype(metadata.EntityPrototype!.ID));
if (child != null)
organ.Children = child;
return organ;
}
public List<OrganItem> GenList(EntityUid uid)
{
var organs = new List<OrganItem>();
if (TryComp<BodyComponent>(uid, out var bodyComponent))
{
foreach (var (part, _) in _body.GetBodyChildren(uid, bodyComponent))
{
if (part == uid)
{
continue;
}
var child = GenList(part);
if (child.Count > 0)
organs.Add(GetOrganItem(part, child));
}
}
else if (TryComp<BodyPartComponent>(uid, out var partComponent))
{
foreach (var (part, _) in _body.GetBodyPartChildren(uid, partComponent))
{
if (part == uid)
{
continue;
}
var child = GenList(part);
if (child.Count > 0)
organs.Add(GetOrganItem(part, child));
}
foreach (var (part, _) in _body.GetPartOrgans(uid, partComponent))
{
organs.Add(GetOrganItem(part, GenList(part)));
}
}
return organs;
}
public bool StartDrop(EntityUid uid, EntityUid organUid, EntityUid? user = null, BodyComponent? component = null)
{
if (!Resolve(uid, ref component))
return false;
EnsureComp<ActiveSurgeryComponent>(uid).OrganUid = organUid;
var construct = EnsureComp<ConstructionComponent>(uid);
return _construction.ChangeGraph(uid, user, "BodySurgery", "head", true, construct);
}
}

View File

@@ -0,0 +1,28 @@
using Content.Server.Body.Systems;
using Content.Shared.Body.Organ;
using Content.Shared.Construction;
using Content.Shared.White.CheapSurgery;
namespace Content.Server.White.Construction.Completions;
public sealed partial class Surgery : IGraphAction
{
private ISawmill _sawmill = default!;
public void PerformAction(EntityUid uid, EntityUid? userUid, IEntityManager entityManager)
{
_sawmill = Logger.GetSawmill("Surgery");
var bodySystem = entityManager.EntitySysManager.GetEntitySystem<BodySystem>();
if (!entityManager.TryGetComponent<ActiveSurgeryComponent>(uid, out var surgeryComponent))
{
_sawmill.Warning($"Entity {uid} does not have a ActiveSurgery Component");
return;
}
if (entityManager.TryGetComponent<OrganComponent>(surgeryComponent.OrganUid, out var organComponent))
bodySystem.RemoveOrgan(surgeryComponent.OrganUid, organComponent);
entityManager.RemoveComponent<ActiveSurgeryComponent>(uid);
}
}

View File

@@ -0,0 +1,153 @@
using Content.Server.Medical.Components;
using Content.Server.UserInterface;
using Content.Shared.Atmos.Components;
using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Components;
using Content.Shared.Examine;
using Content.Shared.MedicalScanner;
using Content.Shared.Verbs;
using Content.Shared.White.Item.Tricorder;
using Robust.Server.Audio;
using Robust.Shared.Audio;
using Robust.Shared.Utility;
namespace Content.Server.White.Items.Tricorder;
public sealed class TricorderSystem : SharedTricorderSystem
{
[Dependency] private readonly IComponentFactory _componentFactory = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TricorderComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<TricorderComponent, GetVerbsEvent<AlternativeVerb>>(OnAddSwitchModeVerbs);
}
private void OnExamined(EntityUid uid, TricorderComponent component, ExaminedEvent args)
{
var mode = GetNameByMode(component.CurrentMode);
args.PushMarkup(Loc.GetString("network-configurator-examine-current-mode", ("mode", Loc.GetString(mode))));
}
private void OnAddSwitchModeVerbs(EntityUid uid, TricorderComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract || !args.Using.HasValue || !HasComp<TricorderComponent>(args.Target))
{
return;
}
var icon = new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/VerbIcons/settings.svg.192dpi.png"));
AlternativeVerb switchToMultitoolVerb = new()
{
Text = "Переключить на мультитул",
Icon = icon,
Act = () => SwitchToMode(args.User, uid, component, TricorderMode.Multitool),
Impact = LogImpact.Low
};
AlternativeVerb switchToGasAnalyzerlVerb = new()
{
Text = "Переключить на газоанализатор",
Icon = icon,
Act = () => SwitchToMode(args.User, uid, component, TricorderMode.GasAnalyzer),
Impact = LogImpact.Low
};
AlternativeVerb switchToHealthAnalyzerVerb = new()
{
Text = "Переключить на анализатор здоровья",
Icon = icon,
Act = () => SwitchToMode(args.User, uid, component, TricorderMode.HealthAnalyzer),
Impact = LogImpact.Low
};
args.Verbs.Add(switchToHealthAnalyzerVerb);
args.Verbs.Add(switchToGasAnalyzerlVerb);
args.Verbs.Add(switchToMultitoolVerb);
}
public void SwitchToMode(EntityUid? user, EntityUid tricoderUid, TricorderComponent tricorder, TricorderMode mode)
{
if (tricorder.CurrentMode == mode)
{
return;
}
tricorder.CurrentMode = mode;
switch (mode)
{
case TricorderMode.Multitool:
SetToMultitool(tricoderUid);
break;
case TricorderMode.GasAnalyzer:
SetToGasAnalyzer(tricoderUid);
break;
case TricorderMode.HealthAnalyzer:
SetToHealthAnalyzer(tricoderUid);
break;
}
if (!user.HasValue)
return;
UpdateModeAppearance(user.Value, tricoderUid, tricorder);
}
private void UpdateModeAppearance(EntityUid userUid, EntityUid tricoderUid, TricorderComponent tricorder)
{
_audioSystem.PlayPvs(tricorder.SoundSwitchMode, userUid, AudioParams.Default.WithVolume(1.5f));
Dirty(tricoderUid, tricorder);
}
private void SetToMultitool(EntityUid uid)
{
RemComp<GasAnalyzerComponent>(uid);
RemComp<HealthAnalyzerComponent>(uid);
var comp = AddComp<NetworkConfiguratorComponent>(uid);
if (TryComp(uid, out ActivatableUIComponent? ui))
{
ui.Key = NetworkConfiguratorUiKey.Configure;
}
Dirty(uid, comp);
}
private void SetToGasAnalyzer(EntityUid uid)
{
RemComp<NetworkConfiguratorComponent>(uid);
RemComp<HealthAnalyzerComponent>(uid);
var comp = AddComp<GasAnalyzerComponent>(uid);
if (TryComp(uid, out ActivatableUIComponent? ui))
{
ui.Key = GasAnalyzerComponent.GasAnalyzerUiKey.Key;
}
Dirty(uid, comp);
}
private void SetToHealthAnalyzer(EntityUid uid)
{
RemComp<NetworkConfiguratorComponent>(uid);
RemComp<GasAnalyzerComponent>(uid);
var healthAnalyzerComponent = _componentFactory.GetComponent<HealthAnalyzerComponent>();
healthAnalyzerComponent.ScanningEndSound = new SoundPathSpecifier("/Audio/Items/Medical/healthscanner.ogg");
healthAnalyzerComponent.Owner = uid;
_entityManager.AddComponent(uid, healthAnalyzerComponent);
if (TryComp(uid, out ActivatableUIComponent? ui))
{
ui.Key = HealthAnalyzerUiKey.Key;
}
}
}

View File

@@ -23,9 +23,6 @@
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="White\Other" />
</ItemGroup>
<Import Project="..\RobustToolbox\MSBuild\Robust.Properties.targets" />
<Import Project="..\RobustToolbox\MSBuild\Robust.CompNetworkGenerator.targets" />
</Project>

View File

@@ -2,29 +2,25 @@ using Content.Shared.Actions;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Animations;
namespace Content.Shared.White.Animations;
/// <summary>
/// Event for playing animations
/// </summary>
public sealed partial class EmoteActionEvent : InstantActionEvent
{
[ViewVariables]
[DataField("emote", readOnly: true, required: true)]
[ViewVariables, DataField("emote", readOnly: true, required: true)]
public string Emote = default!;
};
[RegisterComponent]
[NetworkedComponent]
[RegisterComponent, NetworkedComponent]
public sealed partial class EmoteAnimationComponent : Component
{
[ViewVariables(VVAccess.ReadWrite)]
public string AnimationId = "none";
public readonly List<EntityUid?> Actions = new();
[Serializable, NetSerializable]
public class EmoteAnimationComponentState : ComponentState
public partial class EmoteAnimationComponentState : ComponentState
{
public string AnimationId { get; init; }

View File

@@ -0,0 +1,7 @@
namespace Content.Shared.White.CheapSurgery;
[RegisterComponent]
public sealed partial class ActiveSurgeryComponent : Component
{
[ViewVariables] public EntityUid OrganUid = EntityUid.Invalid;
}

View File

@@ -0,0 +1,44 @@
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared.White.CheapSurgery;
[Serializable, NetSerializable]
public sealed class OnSurgeryStarted : EntityEventArgs
{
public NetEntity Target;
public List<OrganItem> OrganItems;
public OnSurgeryStarted(NetEntity target, List<OrganItem> organItems)
{
Target = target;
OrganItems = organItems;
}
}
[Serializable, NetSerializable]
public sealed class OrganItem
{
public string Name;
public NetEntity Uid;
public SpriteSpecifier Icon;
public List<OrganItem> Children = new();
public OrganItem(string name, NetEntity uid, SpriteSpecifier icon)
{
Name = name;
Uid = uid;
Icon = icon;
}
}
[Serializable, NetSerializable]
public sealed class OnOrganSelected : EntityEventArgs
{
public NetEntity Uid;
public OnOrganSelected(NetEntity uid)
{
Uid = uid;
}
}

View File

@@ -0,0 +1,9 @@
namespace Content.Shared.White.CheapSurgery;
public abstract class SharedCheapSurgerySystem : EntitySystem
{
public override void Initialize()
{
}
}

View File

@@ -0,0 +1,30 @@
using Robust.Shared.GameStates;
namespace Content.Shared.White.Item.Tricorder;
public abstract class SharedTricorderSystem : EntitySystem
{
/// <inheritdoc/>
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<TricorderComponent, ComponentGetState>(GetTricorderState);
}
private static void GetTricorderState(EntityUid uid, TricorderComponent component, ref ComponentGetState args)
{
args.State = new TricorderComponentState(component.CurrentMode);
}
public static string GetNameByMode(TricorderMode mode)
{
return mode switch
{
TricorderMode.Multitool => "[color=yellow]мультитул[/color]",
TricorderMode.GasAnalyzer => "[color=cyan]газоанализатор[/color]",
TricorderMode.HealthAnalyzer => "[color=green]анализатор здоровья[/color]",
_ => "[color=yellow]мультитул[/color]"
};
}
}

View File

@@ -0,0 +1,36 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.White.Item.Tricorder;
[RegisterComponent, NetworkedComponent, Access(typeof(SharedTricorderSystem))]
public sealed partial class TricorderComponent : Component
{
[DataField("currentState"), ViewVariables(VVAccess.ReadWrite)]
public TricorderMode CurrentMode = TricorderMode.Multitool;
[DataField("soundSwitchMode")]
public SoundSpecifier SoundSwitchMode = new SoundPathSpecifier("/Audio/Machines/quickbeep.ogg");
}
/// <summary>
/// Contains network state for TricorderComponent.
/// </summary>
[Serializable, NetSerializable]
public sealed class TricorderComponentState : ComponentState
{
public TricorderMode CurrentMode;
public TricorderComponentState(TricorderMode currentMode)
{
CurrentMode = currentMode;
}
}
public enum TricorderMode
{
Multitool,
GasAnalyzer,
HealthAnalyzer
}

View File

@@ -0,0 +1,19 @@
using Robust.Shared.GameStates;
namespace Content.Shared.White.Overlays;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class NightVisionComponent : Component
{
[DataField("tint"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public Vector3 Tint = new(0.3f, 0.3f, 0.3f);
[DataField("strength"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Strength = 2f;
[DataField("noise"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float Noise = 0.5f;
[DataField("color"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public Color Color = Color.FromHex("#98FB98");
}

View File

@@ -8,6 +8,7 @@ materials-steel = сталь
materials-gold = золото
materials-silver = серебро
materials-plasteel = пласталь
materials-paper = бумага
# Other
materials-biomass = биомасса
materials-cloth = ткань

View File

@@ -1,6 +0,0 @@
emote-flip-action-name = Сальто
emote-flip-action-description = Сделать крутой акработический трюк!
emote-jump-action-name = Подпрыгнуть
emote-jump-action-description = Подпрыгни из-за радости или испуга от мыши.
emote-turn-action-name = Танцевать
emote-turn-action-description = You spin me right round baby...

View File

@@ -0,0 +1 @@
tricorder-item-status-label = Текущий режим: { $mode }

View File

@@ -1,7 +1,7 @@
hairball-action = Откашлять комок шерсти.
hairball-action-desc = Люди это не любят.
hairball-mask = Сначала сними { $mask }.
hairball-cough = { CAPITALIZE(THE($name)) } пытается выкашлять комок шесрти!
hairball-cough = { CAPITALIZE(THE($name)) } пытается выкашлять комок шерсти!
action-name-eat-mouse = Съесть мышь.
action-description-eat-mouse = Съешьте мышь в своей руке, получая питательные вещества и заряд комка шерсти.

View File

@@ -0,0 +1,610 @@
paper-text-request = Запрос Центральному Командованию
---------------------------------------------------------------------
Я, "имя капитана", в должности Капитана, запрашиваю цель для станции "номер станции"
---------------------------------------------------------------------
Для выполнения задачи Центрального Командования будут задействованы все доступные ресурсы станции с минимальным ущербом самой станции, если не было приказано иначе.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-report = Заявление в штаб Центрального Командования
---------------------------------------------------------------------
Я, "имя заявителя" "должность" станции "номер станции", отправляю рапорт о ходе выполнения цели станции и ее продвижении.
Цель: "цель смены".
Ситуация: "как проходит цель".
---------------------------------------------------------------------
Рапорт был составлен мною в пребывании адекватного состояния. Все расписанное, готов подтвердить повторно, при необходимости.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-completed = Заявление в штаб Центрального Командования
---------------------------------------------------------------------
Я, Капитан "имя заявителя" станции "номер станции", с гордостью сообщаю об успешном выполнении экипажем назначенной цели текущей смены.
Цель: "цель смены".
Оценка личного состава и состояния станции: "кратко опишите ситуацию на станции".
---------------------------------------------------------------------
Запрашиваю начало процедуры смены экипажа и ожидаю дальнейших указаний.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-failed = Заявление в штаб Центрального Командования
---------------------------------------------------------------------
Я, Капитан "имя заявителя" станции "номер станции", с прискорбием сообщаю о невозможности выполнения экипажем назначенной цели текущей смены.
Цель: "цель смены".
Причина: "почему ее нельзя выполнить".
---------------------------------------------------------------------
Вследствие провала задания, запрашиваю начало "процедуры смены экипажа / эвакуации" и ожидаю дальнейших указаний.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-request-CentComm = Рапорт Офицерскому составу Центрального Командования
---------------------------------------------------------------------
Номер станции: "укажите номер станции из ПДА"
Я, "имя заявителя", в должности "должность заявителя", представляю доклад о "происшествии/несоответствии" Офицерскому составу Центрального Командования.
Причина:"описание происшествия/несоответствия".
Данная ситуация требует вмешательства "сотрудника ЦК", так как не может быть решена силами экипажа и командования станции.
---------------------------------------------------------------------
Рапорт был составлен мною в пребывании адекватного состояния. Все расписанное, готов подтвердить повторно, при необходимости.
Отправляя этот запрос, возлагаю на себя полную ответственность и, в случае сокрытия информации для собственной выгоды, готов понести высшую меру наказания.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-request-ERT = Запрос в отдел Аварийно-Восстановительных Формирований NanoTrasen
---------------------------------------------------------------------
Я, "имя заявителя", в должности "должность заявителя", отправляю запрос в отдел Аварийно-Восстановительного Формирования для вызова на станцию "номер станции из ПДА" Отряда Быстрого Реагирования.
Причина: "описание происшествия".
Данная ситуация требует вмешательства "название типа ОБР" ОБР, так как не может быть решена силами экипажа и командования станции и ставит под угрозу существование самой станции.
---------------------------------------------------------------------
Запрос был составлен мною в пребывании адекватного состояния. Все расписанное, готов подтвердить повторно, при необходимости.
Отправляя этот запрос, возлагаю на себя полную ответственность и, в случае сокрытия информации для собственной выгоды, готов понести высшую меру наказания.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-request-RXBZZ = Запрос в отдел Аварийно-Восстановительных Формирований NanoTrasen
---------------------------------------------------------------------
Я, "имя заявителя", в должности "должность заявителя", отправляю запрос в отдел Аварийно-Восстановительного Формирования для вызова на станцию "номер станции из ПДА" Отряда Быстрого Реагирования.
Причина: "описание происшествия".
Данная ситуация требует вмешательства "название типа ОБР" ОБР, так как не может быть решена силами экипажа и командования станции и ставит под угрозу существование самой станции.
---------------------------------------------------------------------
Запрос был составлен мною в пребывании адекватного состояния. Все расписанное, готов подтвердить повторно, при необходимости.
Отправляя этот запрос, возлагаю на себя полную ответственность и, в случае сокрытия информации для собственной выгоды, готов понести высшую меру наказания.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-request-high-order-compaint = Заявление в бюро доносов NanoTrasen
---------------------------------------------------------------------
Номер станции: "укажите номер станции из ПДА"
Заявитель: "имя заявителя"
Должность: "должность заявителя"
Субъект правонарушения: "имя нарушителя"
Должность: "должность нарушителя"
Нарушенные пункты КЗ: "нарушенные статьи/отсутствует"
Нарушенные пункты СОП: "нарушенные пункты/отсутствует"
Нарушенные пункты ОПЧК: "нарушенные пункты/отсутствует"
Свидетели нарушений: "имена свидетелей/отсутствуют"
---------------------------------------------------------------------
Описание: "подробное, но лаконичное описание правонарушения".
Жалоба была составлена мною в пребывании адекватного состояния. Все, расписанное в данной жалобе, готов подтвердить повторно, при необходимости.
Запрос: "ожидаемый заявителем исход/принять соответствующие меры по пресечению будущих нарушений".
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-text-request-magistrat = Запрос в Верховный суд Nanotrasen
---------------------------------------------------------------------
Я, "имя заявителя", в должности "должность заявителя", отправляю запрос в Верховный суд для вызова на станцию "номер станции из ПДА" Магистрата.
Заявление об инициации судебного процесса: прилагается.
Данная ситуация требует вмешательства сотрудника Верховного суда, так как не может быть решена компетенцией экипажа и командования станции и ставит под угрозу справедливость вынесенного приговора.
---------------------------------------------------------------------
Запрос был составлен мною в пребывании адекватного состояния. Все расписанное, готов подтвердить повторно, при необходимости.
Отправляя этот запрос, возлагаю на себя полную ответственность и, в случае сокрытия информации для собственной выгоды, готов понести высшую меру наказания.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-comm-text-crew-mem-domotion = Постановление в архив командования станции
---------------------------------------------------------------------
Главе персонала станции "номер станции из ПДА".
Я, "имя заявителя", в должности главы отдела "ваш отдел" приказываю понизить сотрудника "должность сотрудника" "имя сотрудника" до должности "должность после понижения".
Причина: "кратко опишите причину понижения".
---------------------------------------------------------------------
Обязуюсь восполнить отсутствие персонала и поддерживать эффективность отдела на высшем уровне.
Приказ ввести в исполнение немедленно во избежание необратимого ущерба.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-comm-text-crew-mem-dismissal = Постановление в архив командования станции
---------------------------------------------------------------------
Главе персонала станции "номер станции из ПДА".
Я, "имя заявителя", в должности главы отдела "ваш отдел" приказываю немедленно уволить сотрудника "имя сотрудника" с должности "должность сотрудника".
Причина: "кратко опишите причину увольнения".
Сотрудник обязан(-а) немедленно покинуть рабочее место и сдать все выданное снаряжение и имущество отдела. В случае нарушения данного приказа, будут приняты дополнительные меры в соответствии с настоящим законодательством.
---------------------------------------------------------------------
Обязуюсь восполнить отсутствие персонала и поддерживать эффективность отдела на высшем уровне.
Приказ ввести в исполнение немедленно во избежание необратимого ущерба.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-comm-text-request-council = Запрос командному составу станции
---------------------------------------------------------------------
Я, "имя заявителя", в должности "ваша должность" запрашиваю провести голосование среди командного состава станции "номер станции".
Причина: "причина голосования".
Цель: "ожидаемый итог голосования".
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-comm-text-council-end = Отчет по голосованию
---------------------------------------------------------------------
Голосованием глав станции "номер станции", по вопросу "причина голосования", было принято решение "Поддержать / Отклонить" инициативу.
Количество голосов "За": "кол-во"
Количество голосов "Против": "кол-во"
---------------------------------------------------------------------
Подпись: "подпись"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-order = Ордер на обыск
---------------------------------------------------------------------
Выдан: "имя заявителя" "Юрист/Капитан".
Подозреваемый: "имя подозреваемого" "должность".
Характер обыска: "обыск отдела/обыск сотрудника".
Причина обыска: "причина подозрения"
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-complaint = Жалоба
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
Субъект правонарушения: "имя нарушителя"
Должность: "должность нарушителя"
Свидетели нарушений: "имена свидетелей/отсутствуют"
---------------------------------------------------------------------
Описание: "нарушение".
---------------------------------------------------------------------
Жалоба была составлена мною в пребывании адекватного состояния. Все, расписанное в данной жалобе, готов подтвердить повторно, при необходимости.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-lic = Разрешение на ношение оружия
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
Разрешение на ношение: "название оружия"
---------------------------------------------------------------------
Причина: "причина на запрос оружия".
---------------------------------------------------------------------
Обязуюсь, что орудоваемое мною оружие будет использовано в целях описаных выше или в целях вынужденной самообороны.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-request-weapon = Временный запрос оружия
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
Запрос оружия: "название оружия"
---------------------------------------------------------------------
Причина: "причина на запрос оружия".
На период: "через сколько обязан вернуть оружие"
---------------------------------------------------------------------
Обязуюсь использовать исключительно в целях указанных выше или при вынужденной самообороне и сдать оружие в арсенал в указанное время или по первому требованию службы безопасности.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-request-execution = Запрос на казнь сотрудника
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
Нарушитель: "имя и фамилия"
---------------------------------------------------------------------
Причина: "что нарушил".
---------------------------------------------------------------------
Отправляя этот запрос, возлагаю на себя полную ответственность и, в случае сокрытия информации для собственной выгоды, готов понести высшую меру наказания.
Данный документ приобретает юридическую силу, если имеет печать Капитана или Центрального Командования.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-request-cargo-weapon = Разрешение на заказ оружие отделом Снабжения
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
Причина: "по какой причине нужно оружие".
---------------------------------------------------------------------
Отправляя этот запрос, возлагаю на себя полную ответственность за заказанное оружие.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sec-text-request-guard = Заявление под программу защиты свидетелей
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
---------------------------------------------------------------------
Причина: "что угрожает вашей жизни".
Запрос: "убежища в бриге / предоставить вам защиту"
---------------------------------------------------------------------
Служба безопасности берет ответственность за жизнь данного сотрудника и обязана предоставить ему защиту.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-eng-text-request-build = Заявление о проведении строительных работ
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
---------------------------------------------------------------------
Строительные работы будут проведены в отделе "название отдела".
Объект: "что будет сделано".
---------------------------------------------------------------------
Исполнитель несёт полную ответственность за качество выполненных работ.
Во время строительства обязаны быть соблюдены все нормы безопасности.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-eng-text-request-material = Запрос материалов
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
---------------------------------------------------------------------
Список: "что вам нужно".
Причина: "зачем вам материалы".
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-eng-text-report-elect = Отчет об электроснабжении
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
---------------------------------------------------------------------
Производитель электроэнергии: "ДАМ / Сингулярность / альтернативный источник"
Коэффициент потраченной / производимой электроэнергии: "указать коэффициент, к примеру: 2/9"
Стабильность электропитания: "указать уровень стабильности"
---------------------------------------------------------------------
Я - подотчетное лицо, несу полную ответственность своих действий и не пытаюсь скрыть какую-либо информацию.
В случае сокрытия информации подотчетное лицо будет подвержено наказанию высшей степени.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-eng-text-report-atmos = Отчет об атмосфере
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
---------------------------------------------------------------------
Производимые газы:"указать производимые газы"
Коэффициент газов в атмосфере станции:"указать коэффициент газов, к примеру кислород - 22%, азот - 77%, углерод - 1%"
Дополнительно производимые газы:"указать дополнительно производимые газы, к примеру - тритий, фрезон и т.п."
---------------------------------------------------------------------
Я - подотчетное лицо, несу полную ответственность своих действий и не пытаюсь скрыть какую-либо информацию.
В случае сокрытия информации подотчетное лицо будет подвержено наказанию высшей степени.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-med-text-request-perm-narc = Лекарственный рецепт
---------------------------------------------------------------------
Я, "имя и фамилия", в должности "психолога/СМО", выписываю для лечения пациента "имя пациента" следующие препараты: "названия препаратов".
Причина: "заболевание".
---------------------------------------------------------------------
Этот документ подтверждает право пациента на хранение и употребление вышеперечисленных препаратов.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-med-text-request-execution = Запрос на проведение эвтаназии
---------------------------------------------------------------------
Я, "имя и фамилия", в должности "должность" в связи "указать причину", прошу провести для себя процедуру эвтаназии.
---------------------------------------------------------------------
Претензий к медицинскому отделу, при соблюдении ими протоколов, не имею.
Данный документ приобретает юридическую силу, если имеет печать Юриста.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-med-text-waiver-claims = Отказ от претензий
---------------------------------------------------------------------
Я, "имя и фамилия", в должности "должность" даю разрешение провести на мне ряд научных исследований во благо науки.
Эксперимент: "что на вас будут проверять".
---------------------------------------------------------------------
Претензий к "медицинскому/научному" отделу, при соблюдении ими протоколов, не имею.
Я полностью осведомлен(а) и информирован(а) об эксперименте и возможных угрозах.
Настоящая расписка составлена и подписана добровольно, без какого-либо давления, обещаний или угроз.
Данный документ приобретает юридическую силу, если имеет печать Юриста.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-med-text-durka = Заключение о невменяемости
---------------------------------------------------------------------
Я, "имя и фамилия", в должности "СМО/Психолога" признаю сотрудника "имя пациента" невменяемым. В связи с тем, что психические расстройства несут опасность как для самого пациента, так и для остального экипажа, пациент должен быть помещен в перманентную тюрьму.
---------------------------------------------------------------------
Служба безопасности обязана соблюдать все права в отношении пациента, защищать и проводить его для эвакуации до Центрального Командования.
Подписывая данный документ, возлагаю на себя полную ответственность и, в случае неправильного диагноза, понесу высшую меру наказания.
Данный документ приобретает юридическую силу, если имеет печать ГСБ или Капитана.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sci-text-reasonable = Признание разумности существа
---------------------------------------------------------------------
Я, "имя и фамилия", в должности "Ученого/Научного руководителя", подтверждаю разумность существа.
Существо: "название"
---------------------------------------------------------------------
В процессе проведения экспериментов было подтверждено, что данное существо обладает характеристиками, необходимыми для признания его разумным, такими как: способность к мышлению, обучаемость, понимание моральных норм и способность осознавать последствия своих действий.
Существо имеет потенциал для работы на корпорацию NanoTrasen, в связи с чем должно пройти процедуру найма.
---------------------------------------------------------------------
После того, как глава персонала сделает ПДА данному существу, оно официально войдёт под юрисдикцию ОПЧК на равных основах с остальными членами корпорации.
Заявитель несет ответственность за правильное признание существа разумным.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sci-text-request-law = Постановление о изменении законов боргов
---------------------------------------------------------------------
Данный документ информирует о изменении законов "всех/название борга" борга/ов.
Вносимые изменения: "перечень внесённых изменений".
---------------------------------------------------------------------
Данный документ приобретает юридическую силу, если имеет печати и подписи двух или более глав.
Подписи глав: "подписи через запятую"
Новые законы не нарушают ОПЧК и Космический Закон, направлены на принесение пользы корпорации NanoTrasen.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-sci-text-brain = Постановление о пересадке мозга
---------------------------------------------------------------------
Данный документ информирует о пересадке мозга человека в борга по причине невозможности реанимировать прошлого владельца.
Я, "имя и фамилия", в должности "должность" проведу операцию по пересадки мозга "должность" "имя и фамилия пациента" в тело борга.
---------------------------------------------------------------------
Данный документ приобретает юридическую силу, если имеет печать СМО.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-car-text-order = Заказ товара
---------------------------------------------------------------------
Заявитель: "имя заявителя"
Должность: "должность заявителя"
---------------------------------------------------------------------
Товар: "кол-во - название товара"
Причина: "зачем вам это".
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-up-IDcard = Повышение доступа
---------------------------------------------------------------------
Я, "имя заявителя" "должность", прошу предоставить мне дополнительно следующие доступы: "название мест".
Причина: "причина повышения доступов"
---------------------------------------------------------------------
Доступ будет использован исключительно в интересах станции и экипажа. Я обязуюсь не заимствовать вещи из других отделов без разрешения главы отдела, а также покину отдел в случае приказа главы.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-work = Ускоренный найм
---------------------------------------------------------------------
Главе персонала станции "номер станции из ПДА".
Я, "имя заявителя", желаю пройти процедуру ускоренного найма на космической станции NanoTrasen. Ознакомившись с условиями и положениями ускоренного трудоустройства.
Желаемая должность: "название должности"
Отдел: "название отдела"
"По желанию - опыт в профессии, причина трудоустройства"
---------------------------------------------------------------------
Со стандартными рабочими процедурами, правилами и политикой NanoTrasen ознакомлен. Ответственность, возлагаемую на себя, осознаю.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-trash = Свидетельство о заключении брака
---------------------------------------------------------------------
Я, "имя и фамилия", в должности священника, заключаю брак между "имя и фамилия" и "имя и фамилия" с согласия обоих сторон.
---------------------------------------------------------------------
После заключения брака присвоены фамилии: Мужу "фамилия" Жене "фамилия"
Подпись жениха: "имя и фамилия"
Подпись невесты: "имя и фамилия"
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-trash-end = Свидетельство о расторжении брака
---------------------------------------------------------------------
Я, "имя и фамилия", в должности священника, расторгаю брак между "имя и фамилия" и "имя и фамилия" с согласия обоих сторон.
---------------------------------------------------------------------
После расторжения брака присвоены фамилии: Мужу "фамилия" Жене "фамилия"
Подпись мужа: "имя и фамилия"
Подпись жены: "имя и фамилия"
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-court = Инициация судебного процесса
---------------------------------------------------------------------
Я, "имя и фамилия", в должности "должность", настаиваю на немедленной инициации судебного процесса в отношении "имя обвиняемого" в должности "должность обвиняемого".
Безотлагательный судебный процесс необходим, поскольку: "почему приговор несправедливый со стороны охранной службы".
Дополнительная документация: "прилагается / отсутствует".
Свидетели: "список свидетелей / отсутствуют".
Исходя из данных, представленных выше, должен пройти публичный судейский процесс, подающий пример остальным сотрудникам станции.
---------------------------------------------------------------------
Запрос был составлен мною в пребывании адекватного состояния. Все расписанное, готов подтвердить повторно, при необходимости.
Данный документ приобретает юридическую силу, если имеет печать Юриста.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-dismissal = Увольнение
---------------------------------------------------------------------
Я, "имя заявителя", прошу уволить меня с должности "ваша должность" по собственному желанию.
Причина: "кратко опишите причину увольнения".
---------------------------------------------------------------------
Документ составлен в адекватном состоянии, со всеми последствиями ознакомлен.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-promotion = Повышение
---------------------------------------------------------------------
Я, "имя заявителя", в должности "ваша должность" прошу повысить меня до "желаемая должность" в отделе "название отдела".
Причина: "кратко опишите свои заслуги".
---------------------------------------------------------------------
Я убежден, что повышение позволит мне сделать значительный вклад в работу отдела и обязуюсь с особой старательностью выполнять свои обязанности. Со стандартными рабочими процедурами, правилами и политикой NanoTrasen ознакомлен. Ответственность, возлагаемую на себя, осознаю.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-ser-text-request-botan = Запрос растений
---------------------------------------------------------------------
Я, "имя заявителя", в должности "должность" запрашиваю растения в ботанике.
Растения: "название растения"
Причина: "причина".
---------------------------------------------------------------------
Данное растения будет использовано исключительно в выше описанных целях.
---------------------------------------------------------------------
Подпись: "подпись заявителя"
Дата: "день"."месяц".2562
Печать:
paper-syn-text-ha-ha = .
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣾⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣷⣦⣀⡄⠀⠀⣠⣤⣾⡿⢿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣷⣜⣋⣸⣿⣿⣷⣤⣾⣿⣷⣤⣴⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⠏⠉⠻⣿⣿⣿⣿⣿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⡿⠟⠉⠀⠀⠀⠨⠛⠿⠿⠿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢰⣦⡀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡆⠀⠀⠀⠀⠀⠀
⠀⠀⠀⢰⣶⣤⠀⠙⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⣠⡄⠀⣄⡀⠀⠀⠀⠀⠀⠀⠀⣠⣼⡟⠁⠀⢠⠄⠀⠀⠀
⠀⠀⠀⠈⢿⣯⡀⠀⠈⠛⢿⣷⣦⣤⣤⣤⣶⣿⣿⠃⠀⢻⣿⣶⣤⣤⣤⣤⣴⣿⠟⠉⠀⠀⢰⠃⠀⠀⠀⠀
⠀⠀⠀⠀⠘⠿⡀⠀⢀⠀⠀⠈⠙⠛⠛⠛⠋⠉⠀⠀⠀⠀⠈⠛⠛⠛⠛⠋⠁⠀⢀⣤⣴⣶⠃⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠳⢶⣏⡀⣠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣠⣴⣾⡿⠿⠛⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠈⠻⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⣷⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠙⠛⠛⠿⠿⠿⠿⠿⠿⠿⠟⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴
⣿⣿⣿⣿⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣶⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣀⠀⠀⢠⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⡄⠀⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡘⢿⡿⣿⠛⠉⠉⠉⠉⠙⠻⡿⢿⡿⢁⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣴⣿⣦⠀⠀⠀⠀⢀⣼⣿⣦⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣟⠓⠀⠀⠀⠛⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿

View File

@@ -26,6 +26,7 @@
- id: Welder
- id: Multitool
# WD EDIT START
- type: entity
id: ClothingBeltChiefEngineerFilled
parent: ClothingBeltChiefEngineer
@@ -36,10 +37,11 @@
- id: PowerDrill
- id: JawsOfLife
- id: WelderExperimental
- id: Multitool
- id: Tricorder
- id: HolofanProjector
- id: GasAnalyzer
- id: trayScanner
amount: 2
- id: CableApcStack
# WD EDIT END
- type: entity
id: ClothingBeltSecurityFilled

View File

@@ -54,7 +54,7 @@
- type: entity
name: scalpel
id: Scalpel
parent: BaseToolSurgery
parent: [BaseToolSurgery, BaseKnife]
description: A surgical tool used to make incisions into flesh.
components:
- type: Sharp

View File

@@ -308,6 +308,7 @@
- FauxTileAstroGrass
- FauxTileAstroIce
- OreBagOfHolding
- ClothingEyesNightVisionGoggles # WD EDIT
- type: EmagLatheRecipes
emagDynamicRecipes:
- ExplosivePayload

View File

@@ -100,6 +100,11 @@
kind: source
path: "/Textures/Shaders/cataracts.swsl"
- type: shader
id: NightVision
kind: source
path: "/Textures/Shaders/White/nightvision.swsl"
- type: shader
id: SaturationScale
kind: source

View File

@@ -1,40 +1,3 @@
# flip animation
- type: entity
id: EmoteActionFlip
name: emote-flip-action-name
description: emote-flip-action-description
noSpawn: true
components:
- type: InstantAction
icon: White/Actions/EmoteFlip.png
event: !type:EmoteActionEvent
emote: EmoteFlip
# jump animation
- type: entity
id: EmoteActionJump
name: emote-jump-action-name
description: emote-jump-action-description
noSpawn: true
components:
- type: InstantAction
icon: White/Actions/EmoteJump.png
event: !type:EmoteActionEvent
emote: EmoteJump
# turn around in 4 directions animation
- type: entity
id: EmoteActionTurn
name: emote-turn-action-name
description: emote-turn-action-description
noSpawn: true
components:
- type: InstantAction
icon: White/Actions/EmoteTurn.png
event: !type:EmoteActionEvent
emote: EmoteTurn
# Using EmoteAnimation from IC action chat
- type: emote
id: EmoteFlip

View File

@@ -0,0 +1,9 @@
- type: entity
id: CratePaper
name: ящик бумаги
parent: CrateGenericSteel
components:
- type: StorageFill
contents:
- id: SheetPaper
amount: 3

View File

@@ -0,0 +1,9 @@
- type: cargoProduct
id: CratePaper
icon:
sprite: Objects/Materials/Sheets/other.rsi
state: paper
product: CratePaper
cost: 1000
category: Materials
group: market

View File

@@ -84,3 +84,15 @@
Telecrystal: 15
categories:
- UplinkImplants
# Night Vision
- type: listing
id: UplinkNightGoggles
name: ПНВ [Хамелеон]
description: Теперь ты видишь во тьме!
productEntity: ClothingEyesNightVisionGogglesSyndie
icon: { sprite: White/Clothing/Head/nightvision.rsi, state: icon }
cost:
Telecrystal: 3
categories:
- UplinkArmor

View File

@@ -0,0 +1,27 @@
# Paper window constructiom
- type: constructionGraph
id: WindowPaperGraph
start: start
graph:
- node: start
actions:
- !type:DestroyEntity { }
edges:
- to: paperDoor
completed:
- !type:SnapToGrid { }
steps:
- material: Paper
amount: 10
doAfter: 10
- node: paperDoor
entity: WindowPaper
edges:
- to: start
completed:
- !type:SpawnPrototype
prototype: SheetPaper1
amount: 10
steps:
- tool: Anchoring
doAfter: 15

View File

@@ -0,0 +1,15 @@
# Paper window construction
- type: construction
name: сёдзи
id: WindowPaper
graph: WindowPaperGraph
startNode: start
targetNode: paperDoor
category: construction-category-structures
description: Окно, но только из бумаги
objectType: Structure
placementMode: SnapgridCenter
canBuildInImpassable: false
icon:
sprite: White/Structures/Windows/paperwindow.rsi
state: full

View File

@@ -0,0 +1,21 @@
- type: constructionGraph
id: BodySurgery
start: head
graph:
- node: head
edges:
- to: drop
steps:
- tool: Sawing
doAfter: 1
- tool: Slicing
doAfter: 1
- tool: Sawing
doAfter: 1
- node: drop
actions:
- !type:Surgery

View File

@@ -0,0 +1,28 @@
# Night Vision Goggles
- type: entity
parent: ClothingEyesBase
id: ClothingEyesNightVisionGoggles
name: ПНВ
description: Теперь ты видишь во тьме!
components:
- type: Sprite
sprite: White/Clothing/Head/nightvision.rsi
- type: Clothing
sprite: White/Clothing/Head/nightvision.rsi
- type: ClothingGrantComponent
component:
- type: NightVision
# Night Vision Goggles (Chameleon)
- type: entity
parent: ClothingEyesNightVisionGoggles
id: ClothingEyesNightVisionGogglesSyndie
suffix: "Хамелеон"
components:
- type: ChameleonClothing
slot: [ eyes ]
default: ClothingEyesGlassesSunglasses
- type: UserInterface
interfaces:
- key: enum.ChameleonUiKey.Key
type: ChameleonBoundUserInterface

View File

@@ -0,0 +1,53 @@
- type: entity
parent: BaseItem
id: Tricorder
name: трикодер
description: Многофункциональное устройство, которое может выполнять огромный спектр задач.
components:
- type: Sprite
sprite: White/Items/Tools/tricorder.rsi
layers:
- state: icon
- state: on
map: [ "tricorder_power" ]
- type: Tricorder
- type: StaticPrice
price: 300
- type: Tool
qualities:
- Pulsing
- type: ActivatableUI
key: enum.NetworkConfiguratorUiKey.List
inHandsOnly: true
- type: UserInterface
interfaces:
- key: enum.NetworkConfiguratorUiKey.List
type: NetworkConfiguratorBoundUserInterface
- key: enum.NetworkConfiguratorUiKey.Configure
type: NetworkConfiguratorBoundUserInterface
- key: enum.NetworkConfiguratorUiKey.Link
type: NetworkConfiguratorBoundUserInterface
- key: enum.GasAnalyzerUiKey.Key
type: GasAnalyzerBoundUserInterface
- key: enum.HealthAnalyzerUiKey.Key
type: HealthAnalyzerBoundUserInterface
- type: NetworkConfigurator
- type: Tag
tags:
- DroneUsable
- Multitool
- DiscreteHealthAnalyzer
- type: Clothing
sprite: Objects/Tools/multitool.rsi
quickEquip: false
slots:
- Belt
- type: EmitSoundOnPickup
sound:
path: /Audio/White/Items/handling/multitool_pickup.ogg
- type: EmitSoundOnDrop
sound:
path: /Audio/Items/multitool_drop.ogg
- type: EmitSoundOnLand
sound:
path: /Audio/Items/multitool_drop.ogg

View File

@@ -0,0 +1,985 @@
# Base Document Printer
- type: entity
id: BaseDocPrinter
parent: BaseMachinePowered
abstract: true
name: принтер
components:
- type: Appearance
- type: Physics
bodyType: Static
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb
bounds: "-0.25,-0.25,0.25,0.25"
density: 25
mask:
- TabletopMachineMask
layer:
- TabletopMachineLayer
- type: Lathe
- type: MaterialStorage
- type: ActivatableUI
key: enum.LatheUiKey.Key
- type: ActivatableUIRequiresPower
- type: UserInterface
interfaces:
- key: enum.LatheUiKey.Key
type: LatheBoundUserInterface
- key: enum.ResearchClientUiKey.Key
type: ResearchClientBoundUserInterface
- type: Transform
anchored: true
- type: Pullable
- type: StaticPrice
price: 800
- type: ResearchClient
- type: TechnologyDatabase
# Document Printer
- type: entity
parent: BaseDocPrinter
id: DocPrinter
name: принтер форм документов
description: Принтер для распечатки разных форм документов. Блюспейс-технологии на службе бюрократии!
components:
- type: Physics
bodyType: Static
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
drawdepth: SmallObjects
layers:
- state: icon
map: [ "enum.LatheVisualLayers.IsRunning" ]
- state: unlit
shader: unshaded
map: [ "enum.PowerDeviceVisualLayers.Powered" ]
- state: inserting
map: [ "enum.MaterialStorageVisualLayers.Inserting" ]
- type: Lathe
producingSound: /Audio/Machines/scanning.ogg
idleState: icon
runningState: printing
staticRecipes:
- BoxFolderGreenBAN
- PaperRequestTargetStation
- PaperReportCC
- PaperCompletedStation
- PaperFailedStation
- PaperRequestCentComm
- PaperRequestERT
- PaperRequestRXBZZ
- PaperRequestExecution
- PaperRequestMagistrat
- BoxFolderBlueBAN
- PaperDomotionComm
- PaperDismissalReq
- PaperRequestHeadCouncil
- PaperHeadCouncilEnd
- BoxFolderRedBAN
- PaperOrderSec
- PaperDonos
- PaperLic
- PaperTimeRequestWeapon
- PaperRequestExecutionSec
- PaperOrderWeapon
- PaperRequestGuard
- BoxFolderRYellowBAN
- PaperRequestBuild
- PaperRequestMaterial
- PaperReportElect
- PaperReportAtmos
- BoxFolderWhiteBAN
- PaperRequestNarco
- PaperRequestExecutionMed
- PaperWaiverOfClaims
- PaperDurka
- BoxFolderPurpleBAN
- PaperRequestReasonable
- PaperRequestLaw
- PaperBrain
- BoxFolderYellowBAN
- PaperCargoOrder
- BoxFolderGreyBAN
- PaperRequestUpID
- PaperRequestWork
- PaperRequestTrash
- PaperEndTrash
- PaperRequestCourt
- PaperDismissalSer
- PaperPromotion
- PaperRequestBotan
- type: EmagLatheRecipes
emagStaticRecipes:
- BoxFolderBlackBAN
- PaperSyndicat
- type: MaterialStorage
# Recipe Paper
# Station->CentComm
- type: latheRecipe
id: PaperRequestTargetStation # Tide
result: PaperRequestTargetStation
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperReportCC # Tide
result: PaperReportCC
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperCompletedStation # Tide
result: PaperCompletedStation
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperFailedStation # Tide
result: PaperFailedStation
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestCentComm # Tide
result: PaperRequestCentComm
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestERT # Tide
result: PaperRequestERT
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestRXBZZ # Tide
result: PaperRequestRXBZZ
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestExecution # Tide
result: PaperRequestExecution
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestMagistrat # Tide
result: PaperRequestMagistrat
completetime: 5
materials:
Paper: 0
# PaperCommand
- type: latheRecipe
id: PaperDomotionComm # Tide
result: PaperDomotionComm
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperDismissalReq # Tide
result: PaperDismissalReq
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestHeadCouncil # Tide
result: PaperRequestHeadCouncil
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperHeadCouncilEnd # Tide
result: PaperHeadCouncilEnd
completetime: 5
materials:
Paper: 0
# PaperSecurity
- type: latheRecipe
id: PaperOrderSec # Tide
result: PaperOrderSec
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestExecutionSec # Tide
result: PaperRequestExecutionSec
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperDonos # Tide
result: PaperDonos
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperLic # Tide
result: PaperLic
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperTimeRequestWeapon # Tide
result: PaperTimeRequestWeapon
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperOrderWeapon # Tide
result: PaperOrderWeapon
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestGuard # Tide
result: PaperRequestGuard
completetime: 5
materials:
Paper: 0
# PaperEng
- type: latheRecipe
id: PaperRequestBuild # Tide
result: PaperRequestBuild
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestMaterial # Tide
result: PaperRequestMaterial
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperReportElect # Tide
result: PaperReportElect
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperReportAtmos # Tide
result: PaperReportAtmos
completetime: 5
materials:
Paper: 0
# PaperMed
- type: latheRecipe
id: PaperRequestNarco # Tide
result: PaperRequestNarco
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestExecutionMed # Tide
result: PaperRequestExecutionMed
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperWaiverOfClaims # Tide
result: PaperWaiverOfClaims
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperDurka # Tide
result: PaperDurka
completetime: 5
materials:
Paper: 0
# PaperSci
- type: latheRecipe
id: PaperRequestReasonable # Tide
result: PaperRequestReasonable
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestLaw # Tide
result: PaperRequestLaw
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperBrain # Tide
result: PaperBrain
completetime: 5
materials:
Paper: 0
# PaperCargo
- type: latheRecipe
id: PaperCargoOrder # Tide
result: PaperCargoOrder
completetime: 5
materials:
Paper: 0
# PaperService
- type: latheRecipe
id: PaperRequestUpID # Tide
result: PaperRequestUpID
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestWork # Tide
result: PaperRequestWork
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestTrash # Tide
result: PaperRequestTrash
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperEndTrash # Tide
result: PaperEndTrash
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestCourt # Tide
result: PaperRequestCourt
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperDismissalSer # Tide
result: PaperDismissalSer
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperPromotion # Tide
result: PaperPromotion
completetime: 5
materials:
Paper: 0
- type: latheRecipe
id: PaperRequestBotan # Tide
result: PaperRequestBotan
completetime: 5
materials:
Paper: 0
# PaperSyndicat
- type: latheRecipe
id: PaperSyndicat # Tide
result: PaperSyndicat
completetime: 5
materials:
Paper: 0
# PapersAll
# Station->CentComm
- type: entity
parent: Paper
id: PaperRequestTargetStation
noSpawn: true
name: запрос цели
components:
- type: Paper
content: paper-text-request
- type: entity
parent: Paper
id: PaperReportCC
noSpawn: true
name: отчет о цели
components:
- type: Paper
content: paper-text-report
- type: entity
parent: Paper
id: PaperCompletedStation
noSpawn: true
name: цель выполнена
components:
- type: Paper
content: paper-text-completed
- type: entity
parent: Paper
id: PaperFailedStation
noSpawn: true
name: цель провалена
components:
- type: Paper
content: paper-text-failed
- type: entity
parent: Paper
id: PaperRequestCentComm
noSpawn: true
name: запрос ПЦК
components:
- type: Paper
content: paper-text-request-CentComm
- type: entity
parent: Paper
id: PaperRequestERT
noSpawn: true
name: запрос ОБР
components:
- type: Paper
content: paper-text-request-ERT
- type: entity
parent: Paper
id: PaperRequestRXBZZ
noSpawn: true
name: запрос РХБЗЗ
components:
- type: Paper
content: paper-text-request-RXBZZ
- type: entity
parent: Paper
id: PaperRequestExecution
noSpawn: true
name: жалоба высшей степени
components:
- type: Paper
content: paper-text-request-high-order-compaint
- type: entity
parent: Paper
id: PaperRequestMagistrat
noSpawn: true
name: запрос в магистрат
components:
- type: Paper
content: paper-text-request-magistrat
# PaperCommand
- type: entity
parent: Paper
id: PaperDomotionComm
noSpawn: true
name: запрос на понижение
components:
- type: Paper
content: paper-comm-text-crew-mem-domotion
- type: entity
parent: Paper
id: PaperDismissalReq
noSpawn: true
name: запрос на увольнение
components:
- type: Paper
content: paper-comm-text-crew-mem-dismissal
- type: entity
parent: Paper
id: PaperRequestHeadCouncil
noSpawn: true
name: запрос на голосование глав
components:
- type: Paper
content: paper-comm-text-request-council
- type: entity
parent: Paper
id: PaperHeadCouncilEnd
noSpawn: true
name: отчет по голосованию глав
components:
- type: Paper
content: paper-comm-text-council-end
# PaperSecurity
- type: entity
parent: Paper
id: PaperOrderSec
noSpawn: true
name: ордер на арест
components:
- type: Paper
content: paper-sec-text-order
- type: entity
parent: Paper
id: PaperDonos
noSpawn: true
name: жалоба
components:
- type: Paper
content: paper-sec-text-complaint
- type: entity
parent: Paper
id: PaperLic
noSpawn: true
name: разрешение на ношение оружия
components:
- type: Paper
content: paper-sec-text-lic
- type: entity
parent: Paper
id: PaperTimeRequestWeapon
noSpawn: true
name: временный запрос на оружие
components:
- type: Paper
content: paper-sec-text-request-weapon
- type: entity
parent: Paper
id: PaperRequestExecutionSec
noSpawn: true
name: запрос на казнь
components:
- type: Paper
content: paper-sec-text-request-execution
- type: entity
parent: Paper
id: PaperOrderWeapon
noSpawn: true
name: разрешение на заказ оружия
components:
- type: Paper
content: paper-sec-text-request-cargo-weapon
- type: entity
parent: Paper
id: PaperRequestGuard
noSpawn: true
name: программа защиты свидетелей
components:
- type: Paper
content: paper-sec-text-request-guard
# PaperEng
- type: entity
parent: Paper
id: PaperRequestBuild
noSpawn: true
name: разрешение о проведении строительных работ
components:
- type: Paper
content: paper-eng-text-request-build
- type: entity
parent: Paper
id: PaperRequestMaterial
noSpawn: true
name: запрос материалов
components:
- type: Paper
content: paper-eng-text-request-material
- type: entity
parent: Paper
id: PaperReportElect
noSpawn: true
name: отчет об электроснабжении
components:
- type: Paper
content: paper-eng-text-report-elect
- type: entity
parent: Paper
id: PaperReportAtmos
noSpawn: true
name: отчет об атмосфере
components:
- type: Paper
content: paper-eng-text-report-atmos
# PaperMed
- type: entity
parent: Paper
id: PaperRequestNarco
noSpawn: true
name: лекарственный рецепт
components:
- type: Paper
content: paper-med-text-request-perm-narc
- type: entity
parent: Paper
id: PaperRequestExecutionMed
noSpawn: true
name: запрос на проведение эвтаназии
components:
- type: Paper
content: paper-med-text-request-execution
- type: entity
parent: Paper
id: PaperWaiverOfClaims
noSpawn: true
name: отказ от претензий
components:
- type: Paper
content: paper-med-text-waiver-claims
- type: entity
parent: Paper
id: PaperDurka
noSpawn: true
name: заключение о невменяемости
components:
- type: Paper
content: paper-med-text-durka
# PaperSci
- type: entity
parent: Paper
id: PaperRequestReasonable
noSpawn: true
name: признание разумности существа
components:
- type: Paper
content: paper-sci-text-reasonable
- type: entity
parent: Paper
id: PaperRequestLaw
noSpawn: true
name: постановление о изменении законов боргов
components:
- type: Paper
content: paper-sci-text-request-law
- type: entity
parent: Paper
id: PaperBrain
noSpawn: true
name: постановление о пересадке мозга
components:
- type: Paper
content: paper-sci-text-brain
# PaperCargo
- type: entity
parent: Paper
id: PaperCargoOrder
noSpawn: true
name: заказ товара
components:
- type: Paper
content: paper-car-text-order
# PaperService
- type: entity
parent: Paper
id: PaperRequestUpID
noSpawn: true
name: повышение доступа
components:
- type: Paper
content: paper-ser-text-up-IDcard
- type: entity
parent: Paper
id: PaperRequestWork
noSpawn: true
name: ускоренный найм
components:
- type: Paper
content: paper-ser-text-work
- type: entity
parent: Paper
id: PaperRequestTrash
noSpawn: true
name: свидетельство о заключении брака
components:
- type: Paper
content: paper-ser-text-trash
- type: entity
parent: Paper
id: PaperEndTrash
noSpawn: true
name: свидетельство о расторжении брака
components:
- type: Paper
content: paper-ser-text-trash-end
- type: entity
parent: Paper
id: PaperRequestCourt
noSpawn: true
name: инициация судебного процесса
components:
- type: Paper
content: paper-ser-text-court
- type: entity
parent: Paper
id: PaperDismissalSer
noSpawn: true
name: увольнение
components:
- type: Paper
content: paper-ser-text-dismissal
- type: entity
parent: Paper
id: PaperPromotion
noSpawn: true
name: повышение
components:
- type: Paper
content: paper-ser-text-promotion
- type: entity
parent: Paper
id: PaperRequestBotan
noSpawn: true
name: запрос растений
components:
- type: Paper
content: paper-ser-text-request-botan
# PaperSyndicat
- type: entity
parent: Paper
id: PaperSyndicat
noSpawn: true
name: секретные документы
components:
- type: Paper
content: paper-syn-text-ha-ha
# BoxFolder
- type: entity
id: BoxFolderRedBAN
parent: BoxFolderBase
noSpawn: true
name: формы службы безопасноти
suffix: Red
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-sec
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderBlueBAN
parent: BoxFolderBase
noSpawn: true
name: формы командования
suffix: Blue
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-com
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderYellowBAN
parent: BoxFolderBase
noSpawn: true
name: формы карго
suffix: Yellow
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-car
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderWhiteBAN
parent: BoxFolderBase
noSpawn: true
name: формы медиков
suffix: White
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-med
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderGreyBAN
parent: BoxFolderBase
noSpawn: true
name: формы сервиса
suffix: Grey
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-ser
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderGreenBAN
parent: BoxFolderBase
noSpawn: true
name: формы для ЦентКома
suffix: Green
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-CC
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderRYellowBAN
parent: BoxFolderBase
noSpawn: true
name: формы инженеров
suffix: RYellow
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-eng
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderPurpleBAN
parent: BoxFolderBase
noSpawn: true
name: формы учёных
suffix: Purple
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-sci
- type: TimedDespawn
lifetime: 0,1
- type: entity
id: BoxFolderBlackBAN
parent: BoxFolderBase
noSpawn: true
name: формы J@4D*S
suffix: Black
components:
- type: Sprite
sprite: White/Structures/Machines/doc_printer.rsi
layers:
- state: folder-syn
- type: TimedDespawn
lifetime: 0,1
# RecipeBoxFolder
- type: latheRecipe
id: BoxFolderGreenBAN # Tide
result: BoxFolderGreenBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderGreyBAN # Tide
result: BoxFolderGreyBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderWhiteBAN # Tide
result: BoxFolderWhiteBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderYellowBAN # Tide
result: BoxFolderYellowBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderBlueBAN # Tide
result: BoxFolderBlueBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderRedBAN # Tide
result: BoxFolderRedBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderRYellowBAN # Tide
result: BoxFolderRYellowBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderPurpleBAN # Tide
result: BoxFolderPurpleBAN
completetime: 5
materials:
Paper: 999
- type: latheRecipe
id: BoxFolderBlackBAN # Tide
result: BoxFolderBlackBAN
completetime: 5
materials:
Paper: 999

View File

@@ -11,3 +11,13 @@
completetime: 5
materials:
Steel: 1500
- type: latheRecipe
id: ClothingEyesNightVisionGoggles
result: ClothingEyesNightVisionGoggles
completetime: 2
materials:
Steel: 200
Glass: 100
Silver: 100
Gold: 100

View File

@@ -0,0 +1,43 @@
- type: technology
id: AdvancedRobotics
name: research-technology-advanced-robotics
icon:
sprite: White/Mobs/Player/Borgs/cyborg.rsi
state: icon
discipline: Experimental
tier: 1
cost: 5000
recipeUnlocks:
- CyborgMonitoringComputerCircuitboard
- BorgChargerMachineCircuitboard
- CyborgMonitoringServerMachineCircuitboard
- PositronicBrain
- type: technology
id: UpgradeBorgModule
name: research-technology-upgrade-borg
icon:
sprite: White/Objects/Devices/cyborgradiomodule.rsi
state: icon
discipline: Experimental
tier: 2
cost: 15000
recipeUnlocks:
- CyborgHUDModuleSec
- CyborgHUDModuleMed
- CyborgSpeedModule
- CyborgInstrumentModuleFilled
- CyborgJetpackModule
# Night Vision Tech
- type: technology
id: NightVisionTech
name: Технологии ночного видиния
icon:
sprite: White/Clothing/Head/nightvision.rsi
state: icon
discipline: Experimental
tier: 2
cost: 10000
recipeUnlocks:
- ClothingEyesNightVisionGoggles

View File

@@ -0,0 +1,62 @@
# Window Paper
- type: entity
id: WindowPaper
parent: BaseStructure
name: сёдзи
description: Окно, но только из бумаги
placement:
mode: SnapgridCenter
snap:
- Window
components:
- type: WallMount
arc: 360 # interact despite grilles
- type: Tag
tags:
- RCDDeconstructWhitelist
- ForceFixRotations
- Window
- type: Sprite
drawdepth: WallTops
sprite: White/Structures/Windows/paperwindow.rsi
- type: Icon
sprite: White/Structures/Windows/paperwindow.rsi
state: full
- type: Physics
bodyType: Static
- type: Fixtures
fixtures:
fix1:
shape:
!type:PhysShapeAabb { }
mask:
- FullTileMask
layer:
- GlassLayer
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Glass
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 50 #excess damage (nuke?). avoid computational cost of spawning entities.
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- trigger:
!type:DamageTrigger
damage: 25
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Airtight
- type: IconSmooth
key: windows
base: window
- type: Construction
graph: WindowPaperGraph
node: paperDoor
- type: Appearance
- type: StaticPrice
price: 100

View File

@@ -0,0 +1,38 @@
light_mode unshaded;
uniform sampler2D SCREEN_TEXTURE;
uniform highp vec3 tint; // Colour of the tint
uniform highp float luminance_threshold; // number between 0 and 1
uniform highp float noise_amount; // number between 0 and 1
lowp float rand (lowp vec2 n) {
return 0.5 + 0.5 * fract (sin (dot (n.xy, vec2 (12.9898, 78.233)))* 43758.5453);
}
void fragment() {
highp vec4 color = zTextureSpec(SCREEN_TEXTURE, FRAGCOORD.xy * SCREEN_PIXEL_SIZE);
// convert color to grayscale using luminance
highp float grey = dot(color.rgb, vec3(0.298, 0.5882, 0.1137));
// calculate local threshold
highp float threshold = grey * luminance_threshold;
// amplify low luminance parts
if (grey < threshold) {
grey += (threshold - grey) * 0.5;
if (grey > 1.0) {
grey = 1.0;
}
}
// apply night vision color tint
color.rgb = mix(color.rgb, tint, grey);
// add some noise for realism
lowp float noise = rand(FRAGCOORD.xy + TIME) * noise_amount / 10.0;
color.rgb += noise;
COLOR = color;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

View File

@@ -0,0 +1,26 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/5a73e8f825ff279e82949b9329783a9e3070e2da",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-EYES",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -0,0 +1,20 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "on"
},
{
"name": "off"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,96 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Made by Valentyi",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "unlit",
"delays": [
[
0.6,
0.7,
0.6,
0.7
]
]
},
{
"name": "folder-base"
},
{
"name": "idle"
},
{
"name": "folder-CC"
},
{
"name": "folder-overlay-paper"
},
{
"name": "folder-med"
},
{
"name": "folder-sec"
},
{
"name": "folder-eng"
},
{
"name": "folder-sci"
},
{
"name": "folder-car"
},
{
"name": "folder-syn"
},
{
"name": "folder-com"
},
{
"name": "folder-ser"
},
{
"name": "inserting",
"delays": [
[
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2,
0.2
]
]
},
{
"name": "printing",
"delays": [
[
0.4,
0.4,
0.4,
0.4,
0.4,
0.4,
0.4,
0.4,
0.4
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

View File

@@ -0,0 +1,46 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "full"
},
{
"name": "window0",
"directions": 4
},
{
"name": "window1",
"directions": 4
},
{
"name": "window2",
"directions": 4
},
{
"name": "window3",
"directions": 4
},
{
"name": "window4",
"directions": 4
},
{
"name": "window5",
"directions": 4
},
{
"name": "window6",
"directions": 4
},
{
"name": "window7",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B