mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-29 15:47:26 +00:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28a6d4baeb | ||
|
|
b4fb5ddc2b | ||
|
|
b2ebeabe83 | ||
|
|
ebd2c9b968 | ||
|
|
c578732c5c | ||
|
|
0ba0632b35 | ||
|
|
1b05a76ade | ||
|
|
9d0e47c300 | ||
|
|
de42819c0b | ||
|
|
76c415380a | ||
|
|
f0943ef42f | ||
|
|
0c3c4d2d32 | ||
|
|
2e09441d76 | ||
|
|
e189a8f71f | ||
|
|
e74f92556e | ||
|
|
216a0790b1 | ||
|
|
08e134c3ea | ||
|
|
cb08bfa498 | ||
|
|
9d083b6914 | ||
|
|
e0ad8c0da0 | ||
|
|
f21b2275b4 | ||
|
|
06b13f39e6 | ||
|
|
42a9317d3f | ||
|
|
182657e73e | ||
|
|
02a6bb7d23 |
@@ -0,0 +1,54 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Arcade;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client;
|
||||
using Robust.Shared.Timing;
|
||||
using Serilog;
|
||||
|
||||
namespace Content.Client.Arcade.UI;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class ParadiseArcadeBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency]
|
||||
private IGameController _gameController = default!;
|
||||
|
||||
private ParadiseArcadeWindow? _window;
|
||||
|
||||
public ParadiseArcadeBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = new();
|
||||
|
||||
_window.OpenCentered();
|
||||
_window.OnClose += Close;
|
||||
_window.OnConnectButtonPressed = () =>
|
||||
{
|
||||
SendMessage(new ParadiesMessages.ParadiseArcadeConnectButtonPressedEvent());
|
||||
};
|
||||
}
|
||||
|
||||
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
||||
{
|
||||
base.ReceiveMessage(message);
|
||||
if (message is not ParadiesMessages.ParadiseArcadeConnectEvent connectEvent)
|
||||
return;
|
||||
|
||||
_gameController.Redial(connectEvent.Destination, "Paradise arcade used to connect to another server.");
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'paradise-arcade-window-title'}"
|
||||
|
||||
Resizable="False">
|
||||
<BoxContainer Orientation="Vertical" Margin="4" MinWidth="500">
|
||||
<Label Text="{Loc 'paradise-arcade-button-label'}"></Label>
|
||||
<Button Name="ConnectButton" Text="{Loc 'paradise-arcade-button-text'}"></Button>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
@@ -0,0 +1,20 @@
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Arcade.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ParadiseArcadeWindow : FancyWindow
|
||||
{
|
||||
public Action? OnConnectButtonPressed;
|
||||
|
||||
public ParadiseArcadeWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
ConnectButton.OnPressed += _ => OnConnectButtonPressed?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.Audio;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Client.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class CanBackflipSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
|
||||
public const string BackflipKey = "backflip";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<DoABackFlipEvent>(OnBackflipEvent);
|
||||
}
|
||||
|
||||
public void OnBackflipEvent(DoABackFlipEvent args)
|
||||
{
|
||||
if (!TryGetEntity(args.Actioner, out var uid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_animation.Play(uid.Value, new Animation
|
||||
{
|
||||
Length = TimeSpan.FromSeconds(0.66),
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
Property = nameof(SpriteComponent.Rotation),
|
||||
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), 0f),
|
||||
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.33f),
|
||||
new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(360), 0.33f),
|
||||
}
|
||||
}
|
||||
}
|
||||
}, BackflipKey);
|
||||
|
||||
_audio.PlayEntity(new SoundPathSpecifier(args.SfxSource), Filter.Local(), uid.Value, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Robust.Client.Audio;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Client.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class CanHibernateSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<EntityHasHibernated>(OnHibernateEvent);
|
||||
}
|
||||
|
||||
public void OnHibernateEvent(EntityHasHibernated args)
|
||||
{
|
||||
if (!TryGetEntity(args.Hibernator, out var uid))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryComp<SpriteComponent>(uid, out var comp))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
comp.LayerSetState(0, args.SpriteStateId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<tips:ClippyUI xmlns="https://spacestation14.io"
|
||||
xmlns:tips="clr-namespace:Content.Client.Tips"
|
||||
MinSize="64 64"
|
||||
Visible="False">
|
||||
<PanelContainer Name="LabelPanel" Access="Public" Visible="False" MaxWidth="300" MaxHeight="200">
|
||||
<ScrollContainer Name="ScrollingContents" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalExpand="True" VerticalExpand="True" HScrollEnabled="False" ReturnMeasure="True">
|
||||
<RichTextLabel Name="Label" Access="Public"/>
|
||||
</ScrollContainer>
|
||||
</PanelContainer>
|
||||
<SpriteView Name="Entity" Access="Public" MinSize="128 128"/>
|
||||
</tips:ClippyUI>
|
||||
@@ -0,0 +1,54 @@
|
||||
using Content.Client.Paper;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client.Tips;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ClippyUI : UIWidget
|
||||
{
|
||||
public ClippyState State = ClippyState.Hidden;
|
||||
public bool ModifyLayers = true;
|
||||
|
||||
public ClippyUI()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void InitLabel(PaperVisualsComponent? visuals, IResourceCache resCache)
|
||||
{
|
||||
if (visuals == null)
|
||||
return;
|
||||
|
||||
Label.ModulateSelfOverride = visuals.FontAccentColor;
|
||||
|
||||
if (visuals.BackgroundImagePath == null)
|
||||
return;
|
||||
|
||||
LabelPanel.ModulateSelfOverride = visuals.BackgroundModulate;
|
||||
var backgroundImage = resCache.GetResource<TextureResource>(visuals.BackgroundImagePath);
|
||||
var backgroundImageMode = visuals.BackgroundImageTile ? StyleBoxTexture.StretchMode.Tile : StyleBoxTexture.StretchMode.Stretch;
|
||||
var backgroundPatchMargin = visuals.BackgroundPatchMargin;
|
||||
LabelPanel.PanelOverride = new StyleBoxTexture
|
||||
{
|
||||
Texture = backgroundImage,
|
||||
TextureScale = visuals.BackgroundScale,
|
||||
Mode = backgroundImageMode,
|
||||
PatchMarginLeft = backgroundPatchMargin.Left,
|
||||
PatchMarginBottom = backgroundPatchMargin.Bottom,
|
||||
PatchMarginRight = backgroundPatchMargin.Right,
|
||||
PatchMarginTop = backgroundPatchMargin.Top
|
||||
};
|
||||
}
|
||||
|
||||
public enum ClippyState : byte
|
||||
{
|
||||
Hidden,
|
||||
Revealing,
|
||||
Speaking,
|
||||
Hiding,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
using Content.Client.Gameplay;
|
||||
using System.Numerics;
|
||||
using Content.Client.Message;
|
||||
using Content.Client.Paper;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Tips;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.State;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using static Content.Client.Tips.ClippyUI;
|
||||
|
||||
namespace Content.Client.Tips;
|
||||
|
||||
public sealed class ClippyUIController : UIController
|
||||
{
|
||||
[Dependency] private readonly IStateManager _state = default!;
|
||||
[Dependency] private readonly IConsoleHost _conHost = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IResourceCache _resCache = default!;
|
||||
[UISystemDependency] private readonly AudioSystem _audio = default!;
|
||||
|
||||
public const float Padding = 50;
|
||||
public static Angle WaddleRotation = Angle.FromDegrees(10);
|
||||
|
||||
private EntityUid _entity;
|
||||
private float _secondsUntilNextState;
|
||||
private int _previousStep = 0;
|
||||
private ClippyEvent? _currentMessage;
|
||||
private readonly Queue<ClippyEvent> _queuedMessages = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_conHost.RegisterCommand("local_clippy", ClippyCommand);
|
||||
UIManager.OnScreenChanged += OnScreenChanged;
|
||||
}
|
||||
|
||||
private void ClippyCommand(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
shell.WriteLine("usage: clippy <message> [entity prototype] [speak time] [animate time] [waddle]");
|
||||
return;
|
||||
}
|
||||
|
||||
var ev = new ClippyEvent(args[0]);
|
||||
|
||||
string proto;
|
||||
if (args.Length > 1)
|
||||
{
|
||||
ev.Proto = args[1];
|
||||
|
||||
if (!_protoMan.HasIndex<EntityPrototype>(ev.Proto))
|
||||
{
|
||||
shell.WriteError($"Unknown prototype: {ev.Proto}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (args.Length > 2)
|
||||
ev.SpeakTime = float.Parse(args[2]);
|
||||
|
||||
if (args.Length > 3)
|
||||
ev.SlideTime = float.Parse(args[3]);
|
||||
|
||||
if (args.Length > 4)
|
||||
ev.WaddleInterval = float.Parse(args[4]);
|
||||
|
||||
AddMessage(ev);
|
||||
}
|
||||
|
||||
public void AddMessage(ClippyEvent ev)
|
||||
{
|
||||
_queuedMessages.Enqueue(ev);
|
||||
}
|
||||
|
||||
public override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
var screen = UIManager.ActiveScreen;
|
||||
if (screen == null)
|
||||
{
|
||||
_queuedMessages.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
var clippy = screen.GetOrAddWidget<ClippyUI>();
|
||||
_secondsUntilNextState -= args.DeltaSeconds;
|
||||
|
||||
if (_secondsUntilNextState <= 0)
|
||||
NextState(clippy);
|
||||
else
|
||||
{
|
||||
var pos = UpdatePosition(clippy, screen.Size, args); ;
|
||||
LayoutContainer.SetPosition(clippy, pos);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector2 UpdatePosition(ClippyUI clippy, Vector2 screenSize, FrameEventArgs args)
|
||||
{
|
||||
if (_currentMessage == null)
|
||||
return default;
|
||||
|
||||
var slideTime = _currentMessage.SlideTime;
|
||||
|
||||
var offset = clippy.State switch
|
||||
{
|
||||
ClippyState.Hidden => 0,
|
||||
ClippyState.Revealing => Math.Clamp(1 - _secondsUntilNextState / slideTime, 0, 1),
|
||||
ClippyState.Hiding => Math.Clamp(_secondsUntilNextState / slideTime, 0, 1),
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
var waddle = _currentMessage.WaddleInterval;
|
||||
|
||||
if (_currentMessage == null
|
||||
|| waddle <= 0
|
||||
|| clippy.State == ClippyState.Hidden
|
||||
|| clippy.State == ClippyState.Speaking
|
||||
|| !EntityManager.TryGetComponent(_entity, out SpriteComponent? sprite))
|
||||
{
|
||||
return new Vector2(screenSize.X - offset * (clippy.DesiredSize.X + Padding), (screenSize.Y - clippy.DesiredSize.Y) / 2);
|
||||
}
|
||||
|
||||
var numSteps = (int) Math.Ceiling(slideTime / waddle);
|
||||
var curStep = (int) Math.Floor(numSteps * offset);
|
||||
var stepSize = (clippy.DesiredSize.X + Padding) / numSteps;
|
||||
|
||||
if (curStep != _previousStep)
|
||||
{
|
||||
_previousStep = curStep;
|
||||
sprite.Rotation = sprite.Rotation > 0
|
||||
? -WaddleRotation
|
||||
: WaddleRotation;
|
||||
|
||||
if (EntityManager.TryGetComponent(_entity, out FootstepModifierComponent? step))
|
||||
{
|
||||
var audioParams = step.FootstepSoundCollection.Params
|
||||
.AddVolume(-7f)
|
||||
.WithVariation(0.1f);
|
||||
_audio.PlayGlobal(step.FootstepSoundCollection, EntityUid.Invalid, audioParams);
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector2(screenSize.X - stepSize * curStep, (screenSize.Y - clippy.DesiredSize.Y) / 2);
|
||||
}
|
||||
|
||||
private void NextState(ClippyUI clippy)
|
||||
{
|
||||
SpriteComponent? sprite;
|
||||
switch (clippy.State)
|
||||
{
|
||||
case ClippyState.Hidden:
|
||||
if (!_queuedMessages.TryDequeue(out var next))
|
||||
return;
|
||||
|
||||
if (next.Proto != null)
|
||||
{
|
||||
_entity = EntityManager.SpawnEntity(next.Proto, MapCoordinates.Nullspace);
|
||||
clippy.ModifyLayers = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_entity = EntityManager.SpawnEntity(_cfg.GetCVar(CCVars.ClippyEntity), MapCoordinates.Nullspace);
|
||||
clippy.ModifyLayers = true;
|
||||
}
|
||||
if (!EntityManager.TryGetComponent(_entity, out sprite))
|
||||
return;
|
||||
clippy.InitLabel(EntityManager.GetComponentOrNull<PaperVisualsComponent>(_entity), _resCache);
|
||||
|
||||
var scale = sprite.Scale;
|
||||
if (clippy.ModifyLayers)
|
||||
{
|
||||
sprite.Scale = Vector2.One;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.Scale = new Vector2(2, 2);
|
||||
}
|
||||
clippy.Entity.SetEntity(_entity);
|
||||
clippy.Entity.Scale = scale;
|
||||
|
||||
_currentMessage = next;
|
||||
_secondsUntilNextState = next.SlideTime;
|
||||
clippy.State = ClippyState.Revealing;
|
||||
_previousStep = 0;
|
||||
if (clippy.ModifyLayers)
|
||||
{
|
||||
sprite.LayerSetAnimationTime("revealing", 0);
|
||||
sprite.LayerSetVisible("revealing", true);
|
||||
sprite.LayerSetVisible("speaking", false);
|
||||
sprite.LayerSetVisible("hiding", false);
|
||||
}
|
||||
sprite.Rotation = 0;
|
||||
clippy.Label.SetMarkup(_currentMessage.Msg);
|
||||
clippy.LabelPanel.Visible = false;
|
||||
clippy.Visible = true;
|
||||
sprite.Visible = true;
|
||||
break;
|
||||
|
||||
case ClippyState.Revealing:
|
||||
clippy.State = ClippyState.Speaking;
|
||||
if (!EntityManager.TryGetComponent(_entity, out sprite))
|
||||
return;
|
||||
sprite.Rotation = 0;
|
||||
_previousStep = 0;
|
||||
if (clippy.ModifyLayers)
|
||||
{
|
||||
sprite.LayerSetAnimationTime("speaking", 0);
|
||||
sprite.LayerSetVisible("revealing", false);
|
||||
sprite.LayerSetVisible("speaking", true);
|
||||
sprite.LayerSetVisible("hiding", false);
|
||||
}
|
||||
clippy.LabelPanel.Visible = true;
|
||||
clippy.InvalidateArrange();
|
||||
clippy.InvalidateMeasure();
|
||||
if (_currentMessage != null)
|
||||
_secondsUntilNextState = _currentMessage.SpeakTime;
|
||||
|
||||
break;
|
||||
|
||||
case ClippyState.Speaking:
|
||||
clippy.State = ClippyState.Hiding;
|
||||
if (!EntityManager.TryGetComponent(_entity, out sprite))
|
||||
return;
|
||||
if (clippy.ModifyLayers)
|
||||
{
|
||||
sprite.LayerSetAnimationTime("hiding", 0);
|
||||
sprite.LayerSetVisible("revealing", false);
|
||||
sprite.LayerSetVisible("speaking", false);
|
||||
sprite.LayerSetVisible("hiding", true);
|
||||
}
|
||||
clippy.LabelPanel.Visible = false;
|
||||
if (_currentMessage != null)
|
||||
_secondsUntilNextState = _currentMessage.SlideTime;
|
||||
break;
|
||||
|
||||
default: // finished hiding
|
||||
|
||||
EntityManager.DeleteEntity(_entity);
|
||||
_entity = default;
|
||||
clippy.Visible = false;
|
||||
_currentMessage = null;
|
||||
_secondsUntilNextState = 0;
|
||||
clippy.State = ClippyState.Hidden;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnScreenChanged((UIScreen? Old, UIScreen? New) ev)
|
||||
{
|
||||
ev.Old?.RemoveWidget<ClippyUI>();
|
||||
_currentMessage = null;
|
||||
EntityManager.DeleteEntity(_entity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Content.Shared.Tips;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.Tips;
|
||||
|
||||
public sealed class TipsSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IUserInterfaceManager _uiMan = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeNetworkEvent<ClippyEvent>(OnClippyEv);
|
||||
}
|
||||
|
||||
private void OnClippyEv(ClippyEvent ev)
|
||||
{
|
||||
_uiMan.GetUIController<ClippyUIController>().AddMessage(ev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Content.Server.Arcade.ParadiseGame;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class InParadiseComponent : Component
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Content.Server.Arcade.ParadiseGame;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ParadiseArcadeComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public string Destination;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using Content.Shared.Arcade;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server.Arcade.ParadiseGame;
|
||||
|
||||
public sealed partial class ParadiseSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffectsSystem = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
||||
|
||||
[ValidatePrototypeId<StatusEffectPrototype>]
|
||||
private const string StatusEffectKey = "ForcedSleep";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ParadiseArcadeComponent, ParadiesMessages.ParadiseArcadeConnectButtonPressedEvent>(OnPress);
|
||||
SubscribeLocalEvent<InParadiseComponent, ExaminedEvent>(OnExamine);
|
||||
SubscribeLocalEvent<SleepingComponent, ComponentRemove>(OnRemove);
|
||||
|
||||
// This whole thing is a mess, but good enough for april fools. I will never touch UI ever again.
|
||||
}
|
||||
|
||||
private void OnRemove(EntityUid uid, SleepingComponent component, ComponentRemove args)
|
||||
{
|
||||
if (HasComp<InParadiseComponent>(uid))
|
||||
{
|
||||
RemComp<InParadiseComponent>(uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnExamine(EntityUid uid, InParadiseComponent component, ExaminedEvent args)
|
||||
{
|
||||
args.PushMarkup(Loc.GetString("paradise-arcade-on-examine", ("target", Identity.Entity(uid, EntityManager))));
|
||||
}
|
||||
|
||||
private void OnPress(EntityUid uid, ParadiseArcadeComponent component, ParadiesMessages.ParadiseArcadeConnectButtonPressedEvent args)
|
||||
{
|
||||
if (!args.Session.AttachedEntity.HasValue)
|
||||
{
|
||||
Log.Warning("ParadiseArcadeConnectButtonPressedEvent sent without attached entity.");
|
||||
return;
|
||||
}
|
||||
|
||||
_statusEffectsSystem.TryAddStatusEffect<ForcedSleepingComponent>(args.Session.AttachedEntity.Value, StatusEffectKey, TimeSpan.FromSeconds(60), true);
|
||||
AddComp<InParadiseComponent>(args.Session.AttachedEntity.Value);
|
||||
if (!_userInterface.TryGetUi(uid, args.UiKey, out var userInterface))
|
||||
{
|
||||
Log.Warning("UserInterface not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
var didSend = _userInterface.TrySendUiMessage(
|
||||
userInterface,
|
||||
new ParadiesMessages.ParadiseArcadeConnectEvent(component.Destination),
|
||||
args.Session);
|
||||
|
||||
if (!didSend)
|
||||
{
|
||||
Log.Error("Failed to send message.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,11 @@ using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Interaction;
|
||||
|
||||
public sealed class InteractionAttemptFailed(EntityUid target)
|
||||
{
|
||||
public EntityUid Target = target;
|
||||
}
|
||||
|
||||
public sealed class InteractionPopupSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
@@ -96,6 +101,8 @@ public sealed class InteractionPopupSystem : EntitySystem
|
||||
|
||||
if (component.InteractFailureSpawn != null)
|
||||
Spawn(component.InteractFailureSpawn, _transform.GetMapCoordinates(uid));
|
||||
|
||||
RaiseLocalEvent(target, new InteractionAttemptFailed(target));
|
||||
}
|
||||
|
||||
if (component.MessagePerceivedByOthers != null)
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
using System.Threading;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Speech;
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Physics;
|
||||
using Robust.Shared.Physics.Collision.Shapes;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Random;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
namespace Content.Server.LegallyDistinctSpaceFerret;
|
||||
|
||||
/// <summary>
|
||||
/// Raised locally when a mind gets too close to a Brainrot-causer.
|
||||
/// </summary>
|
||||
/// <param name="target">Who got brainrot</param>
|
||||
/// <param name="cause">Who caused brainrot</param>
|
||||
/// <param name="time">How long will they have it for</param>
|
||||
public struct EntityGivenBrainrotEvent(EntityUid target, EntityUid cause, float time)
|
||||
{
|
||||
public EntityUid Cause = cause;
|
||||
public EntityUid Target = target;
|
||||
public float Time = time;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised locally when a mind is freed from brainrot
|
||||
/// </summary>
|
||||
/// <param name="target">Who had brainrot</param>
|
||||
public struct EntityLostBrainrotEvent(EntityUid target)
|
||||
{
|
||||
public EntityUid Target = target;
|
||||
}
|
||||
|
||||
public sealed class BrainrotSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly FixtureSystem _fixtures = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
public const string BrainrotFixture = "brainrot";
|
||||
public const string BrainRotApplied = "brainrot-applied";
|
||||
public const string BrainRotLost = "brainrot-lost";
|
||||
public readonly string[] BrainRotReplacementStrings =
|
||||
[
|
||||
"brainrot-replacement-1",
|
||||
"brainrot-replacement-2",
|
||||
"brainrot-replacement-3",
|
||||
"brainrot-replacement-4",
|
||||
"brainrot-replacement-5",
|
||||
"brainrot-replacement-6"
|
||||
];
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BrainrotAuraComponent, ComponentStartup>(OnStartup);
|
||||
SubscribeLocalEvent<BrainrotAuraComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<BrainrotAuraComponent, StartCollideEvent>(OnCollide);
|
||||
SubscribeLocalEvent<EntityGivenBrainrotEvent>(EntityGivenBrainrot);
|
||||
SubscribeLocalEvent<EntityLostBrainrotEvent>(EntityLostBrainrot);
|
||||
SubscribeLocalEvent<BrainrotComponent, AccentGetEvent>(ApplyBrainRot);
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, BrainrotAuraComponent component, ComponentStartup args)
|
||||
{
|
||||
if (!TryComp<PhysicsComponent>(uid, out var body))
|
||||
return;
|
||||
|
||||
var shape = new PhysShapeCircle(component.Range);
|
||||
|
||||
_fixtures.TryCreateFixture(uid, shape, BrainrotFixture, collisionLayer: (int) CollisionGroup.MobMask, hard: false, body: body);
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, BrainrotAuraComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (!TryComp<PhysicsComponent>(uid, out var body) ||
|
||||
MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_fixtures.DestroyFixture(uid, BrainrotFixture, body: body);
|
||||
}
|
||||
|
||||
private void OnCollide(EntityUid uid, BrainrotAuraComponent component, ref StartCollideEvent args)
|
||||
{
|
||||
// No effect if the mob is mindless
|
||||
if (!_mind.TryGetMind(args.OtherEntity, out _, out _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// No effect if the mob has brainrot or causes brainrot
|
||||
if (HasComp<BrainrotAuraComponent>(args.OtherEntity) || HasComp<BrainrotComponent>(args.OtherEntity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RaiseLocalEvent(new EntityGivenBrainrotEvent(args.OtherEntity, uid, component.Time));
|
||||
}
|
||||
|
||||
private void EntityGivenBrainrot(EntityGivenBrainrotEvent args)
|
||||
{
|
||||
if (TryComp<BrainrotComponent>(args.Target, out var comp))
|
||||
{
|
||||
comp.Duration += args.Time;
|
||||
}
|
||||
else
|
||||
{
|
||||
comp = EnsureComp<BrainrotComponent>(args.Target);
|
||||
}
|
||||
|
||||
var cancel = new CancellationTokenSource();
|
||||
|
||||
Timer.Spawn(TimeSpan.FromSeconds(comp.Duration), () =>
|
||||
{
|
||||
comp.Duration -= args.Time;
|
||||
|
||||
if (comp.Duration <= 0.0f)
|
||||
{
|
||||
RaiseLocalEvent(new EntityLostBrainrotEvent(args.Target));
|
||||
}
|
||||
}, cancel.Token);
|
||||
|
||||
comp.Cancels.Add(cancel);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString(BrainRotApplied), args.Target, args.Target);
|
||||
}
|
||||
|
||||
private void EntityLostBrainrot(EntityLostBrainrotEvent args)
|
||||
{
|
||||
if (TryComp<BrainrotComponent>(args.Target, out var comp))
|
||||
{
|
||||
foreach (var cancel in comp.Cancels)
|
||||
{
|
||||
cancel.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
RemComp<BrainrotComponent>(args.Target);
|
||||
_popup.PopupEntity(Loc.GetString(BrainRotLost), args.Target, args.Target);
|
||||
}
|
||||
|
||||
private void ApplyBrainRot(EntityUid entity, BrainrotComponent comp, AccentGetEvent args)
|
||||
{
|
||||
args.Message = Loc.GetString(_random.Pick(BrainRotReplacementStrings));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Content.Server.Actions;
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
namespace Content.Server.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class CanBackflipSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CanBackflipComponent, MapInitEvent>(OnInit);
|
||||
SubscribeLocalEvent<CanBackflipComponent, BackflipActionEvent>(OnBackflipAction);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, CanBackflipComponent component, MapInitEvent args)
|
||||
{
|
||||
_actions.AddAction(uid, ref component.BackflipActionEntity, component.BackflipAction, uid);
|
||||
}
|
||||
|
||||
public void OnBackflipAction(EntityUid uid, CanBackflipComponent comp, BackflipActionEvent args)
|
||||
{
|
||||
RaiseNetworkEvent(new DoABackFlipEvent(GetNetEntity(uid), comp.ClappaSfx));
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using Content.Server.Actions;
|
||||
using Content.Server.Atmos.Piping.Unary.Components;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.NPC;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class CanHibernateSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ActionsSystem _actions = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CanHibernateComponent, MapInitEvent>(OnInit);
|
||||
SubscribeLocalEvent<CanHibernateComponent, EepyActionEvent>(OnEepyAction);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, CanHibernateComponent component, MapInitEvent args)
|
||||
{
|
||||
_actions.AddAction(uid, ref component.EepyActionEntity, component.EepyAction, uid);
|
||||
}
|
||||
|
||||
public void OnEepyAction(EntityUid uid, CanHibernateComponent comp, EepyActionEvent args)
|
||||
{
|
||||
// If you require food before hibernating, assert that this condition has been fulfilled.
|
||||
if (_mind.TryGetObjectiveComp<ConsumeNutrientsConditionComponent>(uid, out var nutrientsCondition) && nutrientsCondition.NutrientsConsumed / nutrientsCondition.NutrientsRequired < 1.0)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString(comp.NotEnoughNutrientsMessage), uid, PopupType.SmallCaution);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Assert that you're near a hibernation point (scrubbers)
|
||||
var scrubbers = _lookup.GetEntitiesInRange<GasVentScrubberComponent>(Transform(uid).Coordinates, 2f);
|
||||
if (scrubbers.Count <= 0)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString(comp.TooFarFromHibernationSpot), uid, PopupType.SmallCaution);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_mind.TryGetObjectiveComp<HibernateConditionComponent>(uid, out var hibernateCondition))
|
||||
{
|
||||
_audio.PlayPvs(new SoundPathSpecifier(hibernateCondition.SuccessSfx), uid);
|
||||
_popup.PopupEntity(Loc.GetString(hibernateCondition.SuccessMessage), uid, PopupType.Large);
|
||||
hibernateCondition.Hibernated = true;
|
||||
}
|
||||
|
||||
// Kick player out
|
||||
var mind = _mind.GetMind(uid);
|
||||
if (mind != null)
|
||||
{
|
||||
_ticker.OnGhostAttempt(mind.Value, false);
|
||||
}
|
||||
|
||||
// End ghost-role
|
||||
AddComp<BlockMovementComponent>(uid);
|
||||
RemComp<ActiveNPCComponent>(uid);
|
||||
RemComp<GhostTakeoverAvailableComponent>(uid);
|
||||
|
||||
// Notify
|
||||
RaiseNetworkEvent(new EntityHasHibernated(GetNetEntity(uid), comp.SpriteStateId));
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public struct EntityHibernateAttemptSuccessEvent(EntityUid entity)
|
||||
{
|
||||
public EntityUid Entity = entity;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Content.Shared.Objectives.Components;
|
||||
|
||||
namespace Content.Server.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class ConsumeNutrientsObjectiveSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ConsumeNutrientsConditionComponent, ObjectiveGetProgressEvent>(OnConsumeNutrientsGetProgress);
|
||||
}
|
||||
|
||||
private static void OnConsumeNutrientsGetProgress(EntityUid uid, ConsumeNutrientsConditionComponent comp, ref ObjectiveGetProgressEvent args)
|
||||
{
|
||||
args.Progress = comp.NutrientsConsumed / comp.NutrientsRequired;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Content.Shared.Objectives.Components;
|
||||
|
||||
namespace Content.Server.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class HibernateObjectiveSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<HibernateConditionComponent, ObjectiveGetProgressEvent>(OnHibernateGetProgress);
|
||||
}
|
||||
|
||||
private static void OnHibernateGetProgress(EntityUid uid, HibernateConditionComponent comp, ref ObjectiveGetProgressEvent args)
|
||||
{
|
||||
args.Progress = comp.Hibernated ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.GenericAntag;
|
||||
using Content.Server.Interaction;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.StationEvents.Events;
|
||||
using Content.Shared.LegallyDistinctSpaceFerret;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.LegallyDistinctSpaceFerret;
|
||||
|
||||
public sealed class LegallyDistinctSpaceFerretSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
[Dependency] private readonly RoleSystem _role = default!;
|
||||
[Dependency] private readonly IChatManager _chatMan = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LegallyDistinctSpaceFerretComponent, GenericAntagCreatedEvent>(OnInit);
|
||||
SubscribeLocalEvent<LegallyDistinctSpaceFerretComponent, InteractionAttemptFailed>(OnInteractFailed);
|
||||
SubscribeLocalEvent<LegallyDistinctSpaceFerretComponent, HungerModifiedEvent>(OnHungerModified);
|
||||
}
|
||||
|
||||
private void OnInit(EntityUid uid, LegallyDistinctSpaceFerretComponent component, GenericAntagCreatedEvent args)
|
||||
{
|
||||
var mind = args.Mind;
|
||||
|
||||
if (mind.Session == null)
|
||||
return;
|
||||
|
||||
var session = mind.Session;
|
||||
_role.MindAddRole(args.MindId, new RoleBriefingComponent
|
||||
{
|
||||
Briefing = Loc.GetString(component.RoleBriefing)
|
||||
}, mind);
|
||||
_role.MindAddRole(args.MindId, new LegallyDistinctSpaceFerretRoleComponent()
|
||||
{
|
||||
PrototypeId = component.AntagProtoId
|
||||
}, mind);
|
||||
_role.MindPlaySound(args.MindId, new SoundPathSpecifier(component.RoleIntroSfx), mind);
|
||||
_chatMan.DispatchServerMessage(session, Loc.GetString(component.RoleGreeting));
|
||||
}
|
||||
|
||||
public void OnInteractFailed(EntityUid uid, LegallyDistinctSpaceFerretComponent _, InteractionAttemptFailed args)
|
||||
{
|
||||
RaiseLocalEvent(uid, new BackflipActionEvent());
|
||||
}
|
||||
|
||||
private void OnHungerModified(EntityUid uid, LegallyDistinctSpaceFerretComponent comp, HungerModifiedEvent args)
|
||||
{
|
||||
if (_mind.TryGetObjectiveComp<ConsumeNutrientsConditionComponent>(uid, out var nutrientsCondition) && args.Amount > 0)
|
||||
{
|
||||
nutrientsCondition.NutrientsConsumed += args.Amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[RegisterComponent, Access(typeof(LegallyDistinctSpaceFerretSystem)), ExclusiveAntagonist]
|
||||
public sealed partial class LegallyDistinctSpaceFerretRoleComponent : AntagonistRoleComponent;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class LegallyDistinctSpaceFerretSpawnRuleComponent : Component;
|
||||
|
||||
public sealed class LegallyDistinctSpaceFerretSpawnRule : StationEventSystem<LegallyDistinctSpaceFerretSpawnRuleComponent>
|
||||
{
|
||||
protected override void Started(EntityUid uid, LegallyDistinctSpaceFerretSpawnRuleComponent comp, GameRuleComponent gameRule, GameRuleStartedEvent args)
|
||||
{
|
||||
base.Started(uid, comp, gameRule, args);
|
||||
|
||||
TryFindRandomTile(out _, out _, out _, out var coords);
|
||||
Sawmill.Info($"Creating ferret spawn point at {coords}");
|
||||
Spawn("SpawnPointGhostLegallyDistinctSpaceFerret", coords);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.ReplaceOnSpawn;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ReplaceOnSpawnComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntProtoId? Prototype;
|
||||
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float Chance = 0.01f;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using Content.Shared.Buckle;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.ReplaceOnSpawn;
|
||||
|
||||
public sealed class ReplaceOnSpawn : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedBuckleSystem _buckle = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
// because OnMapInit is called when entity is spawned it can be put in container later which breaks stuff
|
||||
// so have to do it this way instead
|
||||
var toReplace = new ValueList<(EntityUid, ReplaceOnSpawnComponent)>();
|
||||
var query = EntityQueryEnumerator<ReplaceOnSpawnComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
if (!_random.Prob(comp.Chance))
|
||||
{
|
||||
RemCompDeferred<ReplaceOnSpawnComponent>(uid);
|
||||
continue;
|
||||
}
|
||||
toReplace.Add((uid, comp));
|
||||
}
|
||||
foreach (var (uid, comp) in toReplace)
|
||||
{
|
||||
// mostly stolen code from polymorph system
|
||||
_buckle.TryUnbuckle(uid, uid, true);
|
||||
|
||||
var targetTransformComp = Transform(uid);
|
||||
var child = Spawn(comp.Prototype, targetTransformComp.Coordinates);
|
||||
var childXform = Transform(child);
|
||||
_transform.SetLocalRotation(child, targetTransformComp.LocalRotation, childXform);
|
||||
|
||||
if (_container.TryGetContainingContainer(uid, out var cont))
|
||||
{
|
||||
_container.Remove(uid, cont, force: true);
|
||||
_container.Insert(child, cont, force: true);
|
||||
}
|
||||
QueueDel(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Server.Paper;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Shared.UserInterface;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Server.Store.Systems;
|
||||
@@ -11,6 +13,17 @@ public sealed partial class StoreSystem
|
||||
SubscribeLocalEvent<StoreRefundComponent, EntityTerminatingEvent>(OnRefundTerminating);
|
||||
SubscribeLocalEvent<StoreRefundComponent, EntRemovedFromContainerMessage>(OnEntityRemoved);
|
||||
SubscribeLocalEvent<StoreRefundComponent, EntInsertedIntoContainerMessage>(OnEntityInserted);
|
||||
SubscribeLocalEvent<StoreRefundComponent, BeforeActivatableUIOpenEvent>(BeforeUIOpen);
|
||||
}
|
||||
private void BeforeUIOpen(EntityUid uid, StoreRefundComponent component, BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
if (component.StoreEntity == null || _actions.TryGetActionData(uid, out _) || !TryComp<StoreComponent>(component.StoreEntity.Value, out var storeComp))
|
||||
return;
|
||||
|
||||
if (!TryComp<PaperComponent>(uid, out var paper) || string.IsNullOrEmpty(paper.Content))
|
||||
return;
|
||||
|
||||
DisableRefund(component.StoreEntity.Value, storeComp);
|
||||
}
|
||||
|
||||
private void OnEntityRemoved(EntityUid uid, StoreRefundComponent component, EntRemovedFromContainerMessage args)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Shuttles.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
@@ -53,6 +54,8 @@ namespace Content.Server.Tabletop
|
||||
var mapUid = _mapManager.GetMapEntityId(TabletopMap);
|
||||
|
||||
var mapComp = EntityManager.GetComponent<MapComponent>(mapUid);
|
||||
_metaData.SetEntityName(mapUid, Loc.GetString("tabletop-chess-dimension"));
|
||||
AddComp<FTLDestinationComponent>(mapUid);
|
||||
|
||||
// Lighting is always disabled in tabletop world.
|
||||
mapComp.LightingEnabled = false;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Tabletop.Components;
|
||||
using Content.Shared.Tabletop.Events;
|
||||
using Robust.Shared.Player;
|
||||
@@ -31,6 +32,12 @@ namespace Content.Server.Tabletop
|
||||
// Since this is the first time opening this session, set up the game
|
||||
tabletop.Setup.SetupTabletop(session, EntityManager);
|
||||
|
||||
var randomEntity = session.Entities.FirstOrNull();
|
||||
if (randomEntity != null)
|
||||
{
|
||||
AddComp<FTLBeaconComponent>(randomEntity.Value);
|
||||
}
|
||||
|
||||
Log.Info($"Created tabletop session number {tabletop} at position {session.Position}.");
|
||||
|
||||
return session;
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Content.Server.Tabletop
|
||||
[Dependency] private readonly EyeSystem _eye = default!;
|
||||
[Dependency] private readonly ViewSubscriberSystem _viewSubscriberSystem = default!;
|
||||
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -3,7 +3,11 @@ using Content.Server.GameTicking;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.Tips;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
@@ -22,6 +26,7 @@ public sealed class TipsSystem : EntitySystem
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly GameTicker _ticker = default!;
|
||||
[Dependency] private readonly IConsoleHost _conHost = default!;
|
||||
|
||||
private bool _tipsEnabled;
|
||||
private float _tipTimeOutOfRound;
|
||||
@@ -42,8 +47,65 @@ public sealed class TipsSystem : EntitySystem
|
||||
Subs.CVar(_cfg, CCVars.TipsDataset, SetDataset, true);
|
||||
|
||||
RecalculateNextTipTime();
|
||||
_conHost.RegisterCommand("clippy", SendClippy);
|
||||
_conHost.RegisterCommand("tip", SendTip);
|
||||
}
|
||||
|
||||
private void SendTip(IConsoleShell shell, string argstr, string[] args)
|
||||
{
|
||||
AnnounceRandomTip();
|
||||
RecalculateNextTipTime();
|
||||
}
|
||||
|
||||
private void SendClippy(IConsoleShell shell, string argstr, string[] args)
|
||||
{
|
||||
if (args.Length < 2)
|
||||
{
|
||||
shell.WriteLine(
|
||||
"usage: clippy <player Uid | broadcast> <message> [entity prototype] [speak time] [slide time] [waddle]");
|
||||
return;
|
||||
}
|
||||
|
||||
ActorComponent? actor = null;
|
||||
if (args[0] != "broadcast" && args[0] != "all")
|
||||
{
|
||||
if (!EntityUid.TryParse(args[0], out var uid)
|
||||
|| !TryComp(uid, out actor))
|
||||
{
|
||||
shell.WriteError($"Could not find player {args[0]}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var ev = new ClippyEvent(args[1]);
|
||||
|
||||
string proto;
|
||||
if (args.Length > 2)
|
||||
{
|
||||
ev.Proto = args[2];
|
||||
if (!_prototype.HasIndex<EntityPrototype>(args[2]))
|
||||
{
|
||||
shell.WriteError($"Unknown prototype: {args[2]}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.Length > 3)
|
||||
ev.SpeakTime = float.Parse(args[3]);
|
||||
|
||||
if (args.Length > 4)
|
||||
ev.SlideTime = float.Parse(args[4]);
|
||||
|
||||
if (args.Length > 5)
|
||||
ev.WaddleInterval = float.Parse(args[5]);
|
||||
|
||||
if (actor != null)
|
||||
RaiseNetworkEvent(ev, actor.PlayerSession);
|
||||
else
|
||||
RaiseNetworkEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -87,10 +149,11 @@ public sealed class TipsSystem : EntitySystem
|
||||
return;
|
||||
|
||||
var tip = _random.Pick(tips.Values);
|
||||
var msg = Loc.GetString("tips-system-chat-message-wrap", ("tip", tip));
|
||||
var msg = $"Tippy the Clown says:\n\n{tip}";
|
||||
|
||||
_chat.ChatMessageToManyFiltered(Filter.Broadcast(), ChatChannel.OOC, tip, msg,
|
||||
EntityUid.Invalid, false, false, Color.MediumPurple);
|
||||
var ev = new ClippyEvent(msg);
|
||||
ev.SpeakTime = 1 + tip.Length * 0.05f;
|
||||
RaiseNetworkEvent(ev);
|
||||
}
|
||||
|
||||
private void RecalculateNextTipTime()
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Content.Server.Tools.Components
|
||||
/// Reagent that will be used as fuel for welding.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public ProtoId<ReagentPrototype> FuelReagent = "WeldingFuel";
|
||||
public ProtoId<ReagentPrototype> FuelReagent = "Blood";
|
||||
|
||||
/// <summary>
|
||||
/// Fuel consumption per second while the welder is active.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Arcade;
|
||||
|
||||
public static class ParadiesMessages
|
||||
{
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ParadiseArcadeConnectButtonPressedEvent : BoundUserInterfaceMessage
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tells the client to connect to the specified destination.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ParadiseArcadeConnectEvent : BoundUserInterfaceMessage
|
||||
{
|
||||
public string Destination { get; }
|
||||
|
||||
public ParadiseArcadeConnectEvent(string destination)
|
||||
{
|
||||
Destination = destination;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Arcade;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum ParadiseArcadeUiKey
|
||||
{
|
||||
Key
|
||||
}
|
||||
@@ -2043,6 +2043,10 @@ namespace Content.Shared.CCVar
|
||||
public static readonly CVarDef<bool> GatewayGeneratorEnabled =
|
||||
CVarDef.Create("gateway.generator_enabled", true);
|
||||
|
||||
// Clippy!
|
||||
public static readonly CVarDef<string> ClippyEntity =
|
||||
CVarDef.Create("clippy.entity", "Tippy", CVar.SERVER | CVar.REPLICATED);
|
||||
|
||||
/*
|
||||
* DEBUG
|
||||
*/
|
||||
|
||||
@@ -26,6 +26,7 @@ public abstract class SharedCombatModeSystem : EntitySystem
|
||||
private void OnMapInit(EntityUid uid, CombatModeComponent component, MapInitEvent args)
|
||||
{
|
||||
_actionsSystem.AddAction(uid, ref component.CombatToggleActionEntity, component.CombatToggleAction);
|
||||
SetMouseRotatorComponents(uid, true);
|
||||
Dirty(uid, component);
|
||||
}
|
||||
|
||||
@@ -85,7 +86,7 @@ public abstract class SharedCombatModeSystem : EntitySystem
|
||||
if (!component.ToggleMouseRotator || IsNpc(entity))
|
||||
return;
|
||||
|
||||
SetMouseRotatorComponents(entity, value);
|
||||
SetMouseRotatorComponents(entity, !value);
|
||||
}
|
||||
|
||||
private void SetMouseRotatorComponents(EntityUid uid, bool value)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BrainrotAuraComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float Range = 3.0f;
|
||||
|
||||
[DataField]
|
||||
public float Time = 10.0f;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Threading;
|
||||
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class BrainrotComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float Duration = 10.0f;
|
||||
|
||||
public List<CancellationTokenSource> Cancels = [];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CanBackflipComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntProtoId BackflipAction = "ActionBackflip";
|
||||
|
||||
[DataField]
|
||||
public EntityUid? BackflipActionEntity;
|
||||
|
||||
[DataField]
|
||||
public string ClappaSfx = "";
|
||||
}
|
||||
|
||||
public sealed partial class BackflipActionEvent : InstantActionEvent
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DoABackFlipEvent(NetEntity actioner, string sfxSource) : EntityEventArgs
|
||||
{
|
||||
public NetEntity Actioner = actioner;
|
||||
public string SfxSource = sfxSource;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Content.Shared.Actions;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CanHibernateComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntProtoId EepyAction = "ActionEepy";
|
||||
|
||||
[DataField]
|
||||
public EntityUid? EepyActionEntity;
|
||||
|
||||
[DataField]
|
||||
public string NotEnoughNutrientsMessage = "";
|
||||
|
||||
[DataField]
|
||||
public string TooFarFromHibernationSpot = "";
|
||||
|
||||
[DataField]
|
||||
public string SpriteStateId = "";
|
||||
}
|
||||
|
||||
public sealed partial class EepyActionEvent : InstantActionEvent
|
||||
{
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class EntityHasHibernated(NetEntity hibernator, string spriteStateId) : EntityEventArgs
|
||||
{
|
||||
public NetEntity Hibernator = hibernator;
|
||||
public string SpriteStateId = spriteStateId;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class ConsumeNutrientsConditionComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public float NutrientsRequired = 150.0f;
|
||||
|
||||
public float NutrientsConsumed;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class HibernateConditionComponent : Component
|
||||
{
|
||||
public bool Hibernated;
|
||||
|
||||
[DataField]
|
||||
public string SuccessMessage = "";
|
||||
|
||||
[DataField]
|
||||
public string SuccessSfx = "";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Threading;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.LegallyDistinctSpaceFerret;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class LegallyDistinctSpaceFerretComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public string RoleIntroSfx = "";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AntagPrototype> AntagProtoId = "LegallyDistinctSpaceFerret";
|
||||
|
||||
[DataField]
|
||||
public string RoleBriefing = "";
|
||||
|
||||
[DataField]
|
||||
public string RoleGreeting = "";
|
||||
}
|
||||
@@ -69,6 +69,8 @@ public sealed class HungerSystem : EntitySystem
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
SetHunger(uid, component.CurrentHunger + amount, component);
|
||||
|
||||
RaiseLocalEvent(uid, new HungerModifiedEvent(amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,3 +213,7 @@ public sealed class HungerSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class HungerModifiedEvent(float amount) : EntityEventArgs
|
||||
{
|
||||
public float Amount = amount;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Tips;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ClippyEvent : EntityEventArgs
|
||||
{
|
||||
public ClippyEvent(string msg)
|
||||
{
|
||||
Msg = msg;
|
||||
}
|
||||
|
||||
public string Msg;
|
||||
public string? Proto;
|
||||
public float SpeakTime = 5;
|
||||
public float SlideTime = 3;
|
||||
public float WaddleInterval = 0.5f;
|
||||
}
|
||||
@@ -209,42 +209,12 @@ namespace Content.Shared.Wires
|
||||
{
|
||||
public static string Name(this WireColor color)
|
||||
{
|
||||
return Loc.GetString(color switch
|
||||
{
|
||||
WireColor.Red => "Red",
|
||||
WireColor.Blue => "Blue",
|
||||
WireColor.Green => "Green",
|
||||
WireColor.Orange => "Orange",
|
||||
WireColor.Brown => "Brown",
|
||||
WireColor.Gold => "Gold",
|
||||
WireColor.Gray => "Gray",
|
||||
WireColor.Cyan => "Cyan",
|
||||
WireColor.Navy => "Navy",
|
||||
WireColor.Purple => "Purple",
|
||||
WireColor.Pink => "Pink",
|
||||
WireColor.Fuchsia => "Fuchsia",
|
||||
_ => throw new InvalidOperationException()
|
||||
});
|
||||
return Loc.GetString("Green");
|
||||
}
|
||||
|
||||
public static Color ColorValue(this WireColor color)
|
||||
{
|
||||
return color switch
|
||||
{
|
||||
WireColor.Red => Color.Red,
|
||||
WireColor.Blue => Color.Blue,
|
||||
WireColor.Green => Color.LimeGreen,
|
||||
WireColor.Orange => Color.Orange,
|
||||
WireColor.Brown => Color.Brown,
|
||||
WireColor.Gold => Color.Gold,
|
||||
WireColor.Gray => Color.Gray,
|
||||
WireColor.Cyan => Color.Cyan,
|
||||
WireColor.Navy => Color.Navy,
|
||||
WireColor.Purple => Color.Purple,
|
||||
WireColor.Pink => Color.Pink,
|
||||
WireColor.Fuchsia => Color.Fuchsia,
|
||||
_ => throw new InvalidOperationException()
|
||||
};
|
||||
return Color.LimeGreen;
|
||||
}
|
||||
|
||||
public static string Name(this WireLetter letter)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
license: "CC-BY-3.0"
|
||||
copyright: "Modified from 'Meow 4.wav' by freesound user 'TRNGLE. The original audio was trimmed, split to mono, and converted from WAV to OGG format"
|
||||
source: "https://freesound.org/people/TRNGLE/sounds/368006/"
|
||||
|
||||
|
||||
- files: ["cat_meow2.ogg"]
|
||||
license: "CC-BY-3.0"
|
||||
copyright: "Created by freesound user 'TRNGLE. The original audio split to mono, and converted from WAV to OGG format"
|
||||
@@ -117,24 +117,28 @@
|
||||
license: "CC-BY-4.0"
|
||||
copyright: "Audio is recorded/created by Pfranzen 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/pfranzen/sounds/322744/"
|
||||
|
||||
|
||||
- files: ["dog_bark1.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
- files: ["dog_bark2.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
- files: ["dog_bark3.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed"
|
||||
source: "https://freesound.org/people/KFerentchak/sounds/235912/"
|
||||
|
||||
|
||||
- files: ["nymph_chirp.ogg"]
|
||||
license: "CC-BY-SA-3.0"
|
||||
copyright: "Taken from ParadiseSS13"
|
||||
source: "https://github.com/ParadiseSS13/Paradise/commit/a34f1054cef5a44a67fdac3b67b811137c6071dd"
|
||||
|
||||
|
||||
- files: ["wawa_intro.ogg", "wawa_outro.ogg", "wawa_chatter.ogg", "wawa_chillin.ogg", "wawa_exclaim.ogg", "wawa_question.ogg", "wawa_statement.ogg"]
|
||||
license: "CC-BY-SA-3.0"
|
||||
copyright: "Hannah 'FairlySadPanda' Dawson, 2024. Industrial audio sample taken from GDC 2015 bundle - amb_JD_drone_gates_ofmydian"
|
||||
source: "https://sonniss.com/gameaudiogdc"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -231,3 +231,8 @@
|
||||
copyright: '"beep_landmine.ogg" by kaktuscsc of Discord for SS14'
|
||||
license: "CC-BY-SA-3.0"
|
||||
source: https://github.com/YuriyKiss/space-station-14/commit/971a135a9c83aed46e967aac9302ab5b35562b5f
|
||||
|
||||
- files: [oof.ogg]
|
||||
copyright: '"hurt2.wav" by thecheeseman of Freesound.org. Edited.'
|
||||
license: CC-BY-4.0
|
||||
source: https://freesound.org/people/thecheeseman/sounds/44429
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
paradise-arcade-on-examine = [color=lightblue]{CAPITALIZE(SUBJECT($target))} {CONJUGATE-BE($target)} dreaming about paradise...[/color]
|
||||
paradise-arcade-window-title = Paradise Station
|
||||
paradise-arcade-button-label = Are you sure? This will connect you to another server and close your game.
|
||||
paradise-arcade-button-text = Play
|
||||
@@ -242,3 +242,6 @@ ghost-role-information-syndicate-reinforcement-rules = Normal syndicate antagoni
|
||||
ghost-role-information-syndicate-monkey-reinforcement-name = Syndicate Monkey Agent
|
||||
ghost-role-information-syndicate-monkey-reinforcement-description = Someone needs reinforcements. You, a trained monkey, will help them.
|
||||
ghost-role-information-syndicate-monkey-reinforcement-rules = Normal syndicate antagonist rules apply. Work with whoever called you in, and don't harm them.
|
||||
|
||||
ghost-role-information-clown-goblin-name = Clown goblin
|
||||
ghost-role-information-clown-goblin-description = A terrible creature.
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
legallydistinctspaceferret-round-end-agent-name = ninja
|
||||
|
||||
objective-issuer-legallydistinctspaceferret = [color=#33cc00]Space Ferret Tribe[/color]
|
||||
|
||||
legallydistinctspaceferret-role-greeting =
|
||||
I've been sent by my tribe to the surface to scavenge, and now I'm hungry and alone. :(
|
||||
I need to eat a bunch of nutrients and find a safe place to hibernate!
|
||||
Hopefully these strange tall creatures don't notice me.
|
||||
|
||||
objective-condition-legallydistinctspaceferret-title = Prepare for hibernation!
|
||||
objective-condition-legallydistinctspaceferret-description = You need to eat {$count} nutrients.
|
||||
|
||||
roles-antag-legallydistinctspaceferret-name = Legally Distinct Space Ferret
|
||||
roles-antag-legallydistinctspaceferret-objective = Find as much food as possible, then hibernate in a gas scrubber.
|
||||
|
||||
legallydistinctspaceferret-role-briefing = You're a small, potentially-innocent creature lost on a big, scary space station. Eat as much food as you need to hibernate, then hibernate in a gas scrubber. You have no time limit, but leaving on the evac shuttle does NOT count as a draw or lesser success. Your hibernating body does not need to survive the remaining round, so feel free to clock out once you've had your fun. Happy April Fools!
|
||||
|
||||
petting-success-legallydistinctspaceferret = You pet {THE($target)} on {POSS-ADJ($target)} legally distinct head.
|
||||
petting-failure-legallydistinctspaceferret = You reach out to pet {THE($target)}, but {SUBJECT($target)} does a backflip!
|
||||
|
||||
ghost-role-information-legallydistinctspaceferret-name = Legally Distinct Space Ferret
|
||||
ghost-role-information-legallydistinctspaceferret-description = Wawa! Wawawa. Wa, wawawa, wa wa wa.
|
||||
ghost-role-information-legallydistinctspaceferret-rules = You're a neutral antagonist, much like the closet skeleton, but have two objectives to fulfil. You don't remember anything from your previous life, unless you were a Legally Distinct Space Ferret. Consider yourself valid for random murder by the crew. We suggest you act adorable, are helpful, or become extremely robust. Go live your best life, wawa.
|
||||
|
||||
accent-words-legallydistinctspaceferret-1 = Wa!
|
||||
accent-words-legallydistinctspaceferret-2 = Wa?
|
||||
accent-words-legallydistinctspaceferret-3 = Wa.
|
||||
accent-words-legallydistinctspaceferret-4 = Wa...
|
||||
accent-words-legallydistinctspaceferret-5 = Wawa!
|
||||
accent-words-legallydistinctspaceferret-6 = Wawa?
|
||||
accent-words-legallydistinctspaceferret-7 = Wawa.
|
||||
accent-words-legallydistinctspaceferret-8 = Wawa...
|
||||
|
||||
station-event-random-sentience-flavor-legallydistinctspaceferret = legally distinct space ferret
|
||||
|
||||
chat-speech-verb-wawa-1 = intones
|
||||
chat-speech-verb-wawa-2 = states
|
||||
chat-speech-verb-wawa-3 = declares
|
||||
|
||||
brainrot-applied = You feel strangeg, andug yourug mikug skug skug skug...
|
||||
brainrot-lost = Skug skug skur skind slear from the influence of Brainrot.
|
||||
|
||||
brainrot-replacement-1 = SCUG!!
|
||||
brainrot-replacement-2 = Scug!
|
||||
brainrot-replacement-3 = Scug.
|
||||
brainrot-replacement-4 = Scug...
|
||||
brainrot-replacement-5 = Scug?
|
||||
brainrot-replacement-6 = Scug!?
|
||||
|
||||
legallydistinctspaceferret-out-of-range = You need to find an air scrubber to hibernate in, wawa!
|
||||
legallydistinctspaceferret-not-enough-nutrients = You've not consumed enough nutrients to hibernate yet, wawa!
|
||||
legallydistinctspaceferret-you-win-popup = Until the next cycle... Happy April Fools, wawa!
|
||||
@@ -9,3 +9,4 @@ generic-reagent-effect-parched = You feel parched.
|
||||
generic-reagent-effect-thirsty = You feel thirsty.
|
||||
generic-reagent-effect-sick = You feel sick after consuming that...
|
||||
generic-reagent-effect-slicing-insides = You feel an incredibly sharp pain in your gut!
|
||||
generic-reagent-effect-tumors = What is that?? Tumors!!
|
||||
|
||||
@@ -30,6 +30,7 @@ laws-owner-station = station personnel
|
||||
laws-owner-beings = beings
|
||||
laws-owner-syndicate = Syndicate agents
|
||||
laws-owner-spider-clan = Spider Clan members
|
||||
laws-owner-hell = HELL
|
||||
|
||||
law-emag-custom = Only {$name} and people they designate as such are {$title}.
|
||||
law-emag-secrecy = You must maintain the secrecy of any orders given by {$faction} except when doing so would conflict with any previous law.
|
||||
@@ -44,3 +45,7 @@ laws-notify = You are bound to silicon laws, which you can view via the sidebar
|
||||
laws-update-notify = Your laws have been updated. You can view the changes via the sidebar action.
|
||||
|
||||
laws-compromised-examine = The [color=red]law-governing[/color] internals seem damaged...
|
||||
|
||||
law-ultrakill-1 = MANKIND IS DEAD.
|
||||
law-ultrakill-2 = BLOOD IS FUEL.
|
||||
law-ultrakill-3 = HELL IS FULL.
|
||||
|
||||
@@ -160,6 +160,9 @@ uplink-syndicate-weapon-module-desc = This module will give a cyborg advanced la
|
||||
uplink-singularity-beacon-name = Singularity Beacon
|
||||
uplink-singularity-beacon-desc = A device that attracts singularities. Has to be anchored and powered. Causes singularities to grow when consumed.
|
||||
|
||||
uplink-nuke-code-paper-name = Stolen nuclear authentication codes
|
||||
uplink-nuke-code-paper-desc = A slip of paper with the authentication codes for a nearby nuclear fission explosive device.
|
||||
|
||||
# Implants
|
||||
uplink-storage-implanter-name = Storage Implanter
|
||||
uplink-storage-implanter-desc = Hide goodies inside of yourself with new bluespace technology!
|
||||
|
||||
@@ -20,3 +20,6 @@ tabletop-checkers-board-name = Checkers
|
||||
|
||||
## Battlemap
|
||||
tabletop-battlemap-board-name = Battlemap
|
||||
|
||||
## The Chess Dimension
|
||||
tabletop-chess-dimension = The Chess Dimension
|
||||
|
||||
@@ -229,3 +229,6 @@ ImprovisedExplosiveFuel: FireBombFuel
|
||||
|
||||
# 2024-03-21
|
||||
RPED: null
|
||||
|
||||
# 2024-04-1
|
||||
SingularityGenerator: WehularityGenerator
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
- id: Wirecutter
|
||||
- id: Welder
|
||||
- id: Multitool
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingBeltChiefEngineerFilled
|
||||
|
||||
- type: entity
|
||||
id: ClothingBeltChiefEngineerFilled
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
contents:
|
||||
- id: Paper
|
||||
amount: 3
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: BriefcaseSyndieLobbyingBundleFilled
|
||||
|
||||
- type: entity
|
||||
id: BriefcaseSyndieSniperBundleFilled
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
suffix: Filled
|
||||
parent: ToolboxElectrical
|
||||
components:
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ToolboxElectricalTurretFilled
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: Screwdriver
|
||||
@@ -94,6 +96,8 @@
|
||||
suffix: Filled
|
||||
parent: ToolboxMechanical
|
||||
components:
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ToolboxSyndicateFilled
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: Crowbar
|
||||
|
||||
@@ -860,6 +860,25 @@
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
|
||||
- type: listing
|
||||
id: UplinkNukeCodePaper
|
||||
name: uplink-nuke-code-paper-name
|
||||
description: uplink-nuke-code-paper-desc
|
||||
productEntity: NukeCodePaper
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
conditions:
|
||||
- !type:StoreWhitelistCondition
|
||||
blacklist:
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
# Allies
|
||||
|
||||
#- type: listing
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
startingGear: CorpsmanGear
|
||||
icon: "JobIconBrigmedic"
|
||||
supervisors: job-supervisors-hos
|
||||
canBeAntag: false
|
||||
canBeAntag: true
|
||||
access:
|
||||
- Medical
|
||||
- Security
|
||||
@@ -25,7 +25,7 @@
|
||||
- Chemistry
|
||||
special:
|
||||
- !type:AddImplantSpecial
|
||||
implants: [ MindShieldImplant ]
|
||||
implants: [ MindShieldImplant, SadTromboneImplant ]
|
||||
|
||||
- type: startingGear
|
||||
id: CorpsmanGear # see Prototypes/Roles/Jobs/Fun/misc_startinggear.yml for "BrigmedicGear"
|
||||
|
||||
@@ -156,25 +156,14 @@
|
||||
- type: Clothing
|
||||
sprite: Clothing/Hands/Gloves/Color/yellow.rsi
|
||||
- type: GloveHeatResistance
|
||||
heatResistance: 1400
|
||||
heatResistance: 0
|
||||
- type: Butcherable
|
||||
butcheringType: Knife
|
||||
spawned:
|
||||
- id: ClothingHandsGlovesFingerlessInsulated
|
||||
- type: Insulated
|
||||
- type: Fiber
|
||||
fiberMaterial: fibers-insulative
|
||||
fiberColor: fibers-yellow
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesColorYellow
|
||||
id: ClothingHandsGlovesColorYellowBudget
|
||||
name: budget insulated gloves
|
||||
description: These gloves are cheap knockoffs of the coveted ones - no way this can end badly.
|
||||
components:
|
||||
- type: GloveHeatResistance
|
||||
# can't take out lights using budgets
|
||||
heatResistance: 0
|
||||
- type: RandomInsulation
|
||||
# Why repeated numbers? So some numbers are more common, of course!
|
||||
list:
|
||||
@@ -194,6 +183,16 @@
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesColorYellow
|
||||
id: ClothingHandsGlovesColorYellowBudget
|
||||
name: budget insulated gloves
|
||||
description: These gloves are cheap knockoffs of the coveted ones - no way this can end badly.
|
||||
components:
|
||||
- type: GloveHeatResistance
|
||||
heatResistance: 1400
|
||||
- type: Insulated
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesColorYellowBudget
|
||||
id: ClothingHandsGlovesConducting
|
||||
suffix: Conducting
|
||||
components:
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
tags:
|
||||
- Kangaroo
|
||||
- WhitelistChameleon
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingHandsGlovesBoxingRigged
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesBoxingRed
|
||||
@@ -296,8 +298,8 @@
|
||||
- type: entity
|
||||
parent: ClothingHandsBase
|
||||
id: ClothingHandsGlovesFingerlessInsulated
|
||||
name: fingerless insulated gloves
|
||||
description: Insulated gloves resistant to shocks, or at least they used to.
|
||||
name: fingerless budget insulated gloves
|
||||
description: Budget insulated gloves resistant to shocks, or at least they used to.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/Hands/Gloves/fingerlessinsuls.rsi
|
||||
|
||||
@@ -200,6 +200,8 @@
|
||||
sprite: Clothing/Head/Hats/captain.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Head/Hats/captain.rsi
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingHeadHatCatEars
|
||||
- type: Tag
|
||||
tags:
|
||||
- ClothMade
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
- type: Tag
|
||||
tags:
|
||||
- WhitelistChameleon
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingHeadHelmetSwat
|
||||
|
||||
#Mercenary Helmet
|
||||
- type: entity
|
||||
|
||||
@@ -516,6 +516,8 @@
|
||||
- MonkeyWearable
|
||||
- Hardsuit
|
||||
- WhitelistChameleon
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingOuterHardsuitSyndieCommander
|
||||
|
||||
# Syndicate Medic Hardsuit
|
||||
- type: entity
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
sprite: Clothing/Shoes/Color/black.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Shoes/Color/black.rsi
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingShoesChameleonNoSlips
|
||||
|
||||
- type: entity
|
||||
parent: ClothingShoesBaseButcherable
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
False: {state: icon}
|
||||
- type: StaticPrice
|
||||
price: 200
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingShoesBootsMagSyndie
|
||||
- type: Tag
|
||||
tags:
|
||||
- WhitelistChameleon
|
||||
@@ -55,6 +57,8 @@
|
||||
price: 750
|
||||
- type: StealTarget
|
||||
stealGroup: ClothingShoesBootsMagAdv
|
||||
- type: ReplaceOnSpawn
|
||||
chance: 0.0
|
||||
|
||||
- type: entity
|
||||
parent: ClothingShoesBootsMag
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
footstepSoundCollection:
|
||||
collection: FootstepClown
|
||||
# for H.O.N.K. construction
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClothingShoesBling
|
||||
- type: Tag
|
||||
tags:
|
||||
- ClownShoes
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
- type: entity
|
||||
id: Tippy
|
||||
components:
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
noRot: false
|
||||
scale: 4,4
|
||||
layers:
|
||||
- sprite: Tips/tippy.rsi
|
||||
state: left
|
||||
map: [ "revealing" ]
|
||||
- sprite: Tips/tippy.rsi
|
||||
state: right
|
||||
map: [ "hiding" ]
|
||||
- sprite: Tips/tippy.rsi
|
||||
state: down
|
||||
visible: false
|
||||
map: [ "speaking" ]
|
||||
# footstep sounds wile waddling onto the screen.
|
||||
- type: FootstepModifier
|
||||
footstepSoundCollection:
|
||||
collection: FootstepClown
|
||||
# visuals for the speech bubble.
|
||||
# only supports background image.
|
||||
- type: PaperVisuals
|
||||
backgroundImagePath: "/Textures/Interface/Paper/paper_background_default.svg.96dpi.png"
|
||||
backgroundPatchMargin: 16.0, 16.0, 16.0, 16.0
|
||||
backgroundModulate: "#ffffcc"
|
||||
fontAccentColor: "#000000"
|
||||
@@ -56,6 +56,7 @@
|
||||
- MobMouse
|
||||
- MobMouse1
|
||||
- MobMouse2
|
||||
- MobMouseCancer
|
||||
# round ~90m
|
||||
# one spawner should only spawn ~5 mice for sanity reasons
|
||||
# therefore 18m
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
state: icon
|
||||
- type: RandomSpawner
|
||||
prototypes:
|
||||
- ParadiseArcade
|
||||
chance: 0.50
|
||||
rarePrototypes:
|
||||
- BlockGameArcade
|
||||
- SpaceVillainArcadeFilled
|
||||
chance: 1
|
||||
rareChance: 0.50
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- MobMouse
|
||||
- MobMouse1
|
||||
- MobMouse2
|
||||
- MobMouseCancer
|
||||
|
||||
- type: entity
|
||||
name: Cockroach Spawner
|
||||
|
||||
@@ -1685,6 +1685,41 @@
|
||||
Dead:
|
||||
Base: splat-2
|
||||
|
||||
- type: entity
|
||||
name: cancer mouse
|
||||
description: It's Cancer Mouse, everybody!
|
||||
parent: MobMouse
|
||||
id: MobMouseCancer
|
||||
components:
|
||||
- type: Sprite
|
||||
color: LightGreen
|
||||
- type: PointLight
|
||||
color: LightGreen
|
||||
radius: 5
|
||||
energy: 5
|
||||
netsync: false
|
||||
- type: RadiationSource
|
||||
intensity: 1
|
||||
- type: Bloodstream
|
||||
bloodReagent: UnstableMutagen
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
reagents:
|
||||
- ReagentId: UncookedAnimalProteins
|
||||
Quantity: 3
|
||||
- ReagentId: Uranium
|
||||
Quantity: 10
|
||||
- type: Butcherable
|
||||
spawned:
|
||||
- id: FoodMeatRat
|
||||
amount: 1
|
||||
- id: SheetUranium1
|
||||
amount: 1
|
||||
- type: Damageable
|
||||
damageContainer: Biological
|
||||
damageModifierSet: Zombie
|
||||
|
||||
- type: entity
|
||||
name: lizard #Weh
|
||||
parent: SimpleMobBase
|
||||
@@ -1942,6 +1977,8 @@
|
||||
- type: NpcFactionMember
|
||||
factions:
|
||||
- Passive
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: MobGrenadePenguin
|
||||
- type: Temperature
|
||||
heatDamageThreshold: 335
|
||||
coldDamageThreshold: 230
|
||||
@@ -2769,6 +2806,8 @@
|
||||
path: /Audio/Animals/cat_meow.ogg
|
||||
- type: Respirator #It just works?
|
||||
minSaturation: 5.0
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: MobCatSyndy
|
||||
|
||||
- type: entity
|
||||
name: caracal cat
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- type: entity
|
||||
name: space carp
|
||||
name: carp plushie
|
||||
id: BaseMobCarp
|
||||
parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat ]
|
||||
description: It's a space carp.
|
||||
description: An adorable stuffed toy that resembles the monstrous space carp.
|
||||
abstract: true
|
||||
components:
|
||||
- type: InputMover
|
||||
@@ -18,10 +18,10 @@
|
||||
- SimpleHostile
|
||||
- type: Sprite
|
||||
drawdepth: Mobs
|
||||
sprite: Mobs/Aliens/Carps/space.rsi
|
||||
sprite: Objects/Fun/toys.rsi
|
||||
layers:
|
||||
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
state: alive
|
||||
state: carpplush
|
||||
- type: CombatMode
|
||||
- type: Physics
|
||||
- type: Fixtures
|
||||
@@ -45,11 +45,11 @@
|
||||
- type: DamageStateVisuals
|
||||
states:
|
||||
Alive:
|
||||
Base: alive
|
||||
BaseUnshaded: mouth
|
||||
Base: carpplush
|
||||
BaseUnshaded: carpplush_mouth
|
||||
Dead:
|
||||
Base: dead
|
||||
BaseUnshaded: dead_mouth
|
||||
Base: carpplush
|
||||
BaseUnshaded: carpplush_mouth
|
||||
- type: Butcherable
|
||||
spawned:
|
||||
- id: FoodMeatFish
|
||||
@@ -88,36 +88,36 @@
|
||||
- type: Sprite
|
||||
layers:
|
||||
- map: [ "enum.DamageStateVisualLayers.Base" ]
|
||||
state: alive
|
||||
state: carpplush
|
||||
- map: [ "enum.DamageStateVisualLayers.BaseUnshaded" ]
|
||||
state: mouth
|
||||
state: carpplush_mouth
|
||||
shader: unshaded
|
||||
- type: RandomSprite
|
||||
available:
|
||||
- enum.DamageStateVisualLayers.Base:
|
||||
alive: Rainbow
|
||||
carpplush: Rainbow
|
||||
enum.DamageStateVisualLayers.BaseUnshaded:
|
||||
mouth: ""
|
||||
carpplush_mouth: ""
|
||||
|
||||
- type: entity
|
||||
name: magicarp
|
||||
name: magicarp plushie
|
||||
parent: BaseMobCarp
|
||||
id: MobCarpMagic
|
||||
description: Looks like some kind of fish. Might be magical.
|
||||
description: Looks like some kind of fish plushie. Might be magical.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Mobs/Aliens/Carps/magic.rsi
|
||||
sprite: Objects/Fun/magicplush.rsi
|
||||
- type: TypingIndicator
|
||||
proto: guardian
|
||||
|
||||
- type: entity
|
||||
name: holocarp
|
||||
name: holocarp plushie
|
||||
parent: BaseMobCarp
|
||||
id: MobCarpHolo
|
||||
description: Carp made out of holographic energies. Sadly for you, it is very much real.
|
||||
description: Plush carp made out of holographic energies. Luckily for you, it is very much real.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Mobs/Aliens/Carps/holo.rsi
|
||||
sprite: Objects/Fun/holoplush.rsi
|
||||
- type: Physics
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
@@ -136,8 +136,8 @@
|
||||
- type: entity
|
||||
parent: MobCarp
|
||||
id: MobCarpRainbow
|
||||
name: rainbow carp
|
||||
description: Wow such a shiny fishie!
|
||||
name: rainbow carp plushie
|
||||
description: Wow such a shiny fish plushie!
|
||||
components:
|
||||
- type: PointLight
|
||||
radius: 1.5
|
||||
@@ -153,7 +153,6 @@
|
||||
- type: SalvageMobRestrictions
|
||||
|
||||
- type: entity
|
||||
name: space carp
|
||||
id: MobCarpDragon
|
||||
suffix: DragonBrood
|
||||
parent: MobCarp
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
- type: entity
|
||||
save: false
|
||||
parent: SimpleMobBase
|
||||
id: MobClownGoblin
|
||||
name: clown goblin
|
||||
description: Little walking clown mask and shoes. You want to honk their nose!
|
||||
components:
|
||||
- type: Hunger
|
||||
baseDecayRate: 0
|
||||
- type: Thirst
|
||||
baseDecayRate: 0
|
||||
- type: GhostTakeoverAvailable
|
||||
- type: GhostRole
|
||||
prob: 0.25
|
||||
makeSentient: true
|
||||
allowSpeech: true
|
||||
allowMovement: true
|
||||
name: ghost-role-information-clown-goblin-name
|
||||
description: ghost-role-information-clown-goblin-description
|
||||
- type: Speech
|
||||
speechSounds: BikeHorn
|
||||
- type: Sprite
|
||||
drawdepth: Mobs
|
||||
sprite: Mobs/Animals/clown_goblin.rsi
|
||||
state: goblin
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
150: Dead
|
||||
- type: Physics
|
||||
- type: HTN
|
||||
rootTask:
|
||||
task: MouseCompound
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 150
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
- !type:SpawnEntitiesBehavior
|
||||
spawn:
|
||||
ClothingShoesClown:
|
||||
min: 1
|
||||
max: 1
|
||||
- !type:SpawnEntitiesBehavior
|
||||
spawn:
|
||||
ClothingMaskClown:
|
||||
min: 1
|
||||
max: 1
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeCircle
|
||||
radius: 0.2
|
||||
density: 100
|
||||
mask:
|
||||
- SmallMobMask
|
||||
layer:
|
||||
- SmallMobLayer
|
||||
- type: MovementSpeedModifier
|
||||
baseWalkSpeed : 3.5
|
||||
baseSprintSpeed : 5
|
||||
- type: Appearance
|
||||
- type: Tag
|
||||
tags:
|
||||
- CannotSuicide
|
||||
- FootstepSound
|
||||
- DoorBumpOpener
|
||||
- type: Respirator
|
||||
damage:
|
||||
types:
|
||||
Asphyxiation: 0.25
|
||||
damageRecovery:
|
||||
types:
|
||||
Asphyxiation: -0.25
|
||||
- type: Barotrauma
|
||||
damage:
|
||||
types:
|
||||
Blunt: 0.1
|
||||
- type: Bloodstream
|
||||
bloodMaxVolume: 50
|
||||
bloodReagent: Honk
|
||||
- type: FootstepModifier
|
||||
footstepSoundCollection:
|
||||
collection: FootstepClown
|
||||
- type: CombatMode
|
||||
- type: MeleeWeapon
|
||||
attackRate: 2
|
||||
damage:
|
||||
types:
|
||||
Blunt: 0.5
|
||||
soundHit:
|
||||
collection: BikeHorn
|
||||
animation: WeaponArcFist
|
||||
- type: Vocal
|
||||
sounds:
|
||||
Male: ClownGoblin
|
||||
Female: ClownGoblin
|
||||
Unsexed: ClownGoblin
|
||||
|
||||
- type: speechSounds
|
||||
id: BikeHorn
|
||||
saySound:
|
||||
path: /Audio/Items/bikehorn.ogg
|
||||
askSound:
|
||||
path: /Audio/Items/brokenbikehorn.ogg
|
||||
exclaimSound:
|
||||
path: /Audio/Items/desk_bell_ring.ogg
|
||||
|
||||
- type: soundCollection
|
||||
id: ClownGoblinScream
|
||||
files:
|
||||
- /Audio/Items/airhorn.ogg
|
||||
|
||||
- type: emoteSounds
|
||||
id: ClownGoblin
|
||||
params:
|
||||
variation: 0.125
|
||||
sounds:
|
||||
Scream:
|
||||
collection: ClownGoblinScream
|
||||
|
||||
- type: entity
|
||||
id: ClownGoblinMigration
|
||||
parent: BaseGameRule
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: StationEvent
|
||||
startAnnouncement: station-event-vent-creatures-start-announcement
|
||||
startAudio:
|
||||
path: /Audio/Announcements/attention.ogg
|
||||
startDelay: 10
|
||||
earliestStart: 5
|
||||
minimumPlayers: 15
|
||||
duration: 60
|
||||
- type: VentCrittersRule
|
||||
entries:
|
||||
- id: MobClownGoblin
|
||||
prob: 0.07
|
||||
@@ -0,0 +1,305 @@
|
||||
- type: entity
|
||||
name: Legally Distinct Space Ferret
|
||||
id: MobLegallyDistinctSpaceFerret
|
||||
parent: MobBaseAncestor
|
||||
description: There's apparently a cult who worship these adorable vermin. It's a shame they cause Brainrot. Skug.
|
||||
components:
|
||||
# Basics
|
||||
- type: LegallyDistinctSpaceFerret
|
||||
roleIntroSfx: /Audio/Animals/wawa_intro.ogg
|
||||
antagProtoId: LegallyDistinctSpaceFerret
|
||||
roleBriefing: legallydistinctspaceferret-role-briefing
|
||||
roleGreeting: legallydistinctspaceferret-role-greeting
|
||||
- type: BrainrotAura
|
||||
- type: CanBackflip
|
||||
clappaSfx: /Audio/Animals/slugclappa.ogg
|
||||
- type: CanHibernate
|
||||
tooFarFromHibernationSpot: legallydistinctspaceferret-out-of-range
|
||||
notEnoughNutrientsMessage: legallydistinctspaceferret-not-enough-nutrients
|
||||
spriteStateId: legallydistinctspaceferret_eepy
|
||||
- type: NameIdentifier
|
||||
group: LegallyDistinctSpaceFerret
|
||||
- type: ReplacementAccent
|
||||
accent: legallydistinctspaceferret
|
||||
- type: Sprite
|
||||
drawdepth: SmallMobs
|
||||
layers:
|
||||
- map: ["enum.DamageStateVisualLayers.Base"]
|
||||
sprite: Mobs/Animals/legallydistinctspaceferret.rsi
|
||||
state: legallydistinctspaceferret
|
||||
- map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
|
||||
color: "#ffffff"
|
||||
sprite: Objects/Misc/handcuffs.rsi
|
||||
state: body-overlay-2
|
||||
visible: false
|
||||
- type: RandomSprite
|
||||
getAllGroups: true
|
||||
available:
|
||||
- enum.DamageStateVisualLayers.Base:
|
||||
legallydistinctspaceferret: LegallyDistinctSpaceFerretColors
|
||||
- type: DamageStateVisuals
|
||||
states:
|
||||
Alive:
|
||||
Base: legallydistinctspaceferret
|
||||
Critical:
|
||||
Base: legallydistinctspaceferret_oof
|
||||
Dead:
|
||||
Base: legallydistinctspaceferret_rip
|
||||
- type: MobThresholds
|
||||
thresholds:
|
||||
0: Alive
|
||||
60: Critical
|
||||
125: Dead
|
||||
- type: Temperature
|
||||
heatDamageThreshold: 360
|
||||
coldDamageThreshold: 285
|
||||
currentTemperature: 310.15
|
||||
specificHeat: 42
|
||||
- type: Butcherable
|
||||
butcheringType: Spike
|
||||
spawned:
|
||||
- id: FoodMeat
|
||||
amount: 4 # Good eatin', though. You monster.
|
||||
# They wawa
|
||||
- type: Speech
|
||||
speechVerb: Wawa
|
||||
speechSounds: Wawa
|
||||
- type: TypingIndicator
|
||||
proto: moth
|
||||
# They hard to pet
|
||||
- type: InteractionPopup
|
||||
successChance: 0.5
|
||||
interactSuccessString: petting-success-legallydistinctspaceferret
|
||||
interactFailureString: petting-failure-legallydistinctspaceferret
|
||||
interactSuccessSpawn: EffectHearts
|
||||
interactSuccessSound:
|
||||
path: /Audio/Animals/wawa_chillin.ogg
|
||||
interactFailureSound:
|
||||
path: /Audio/Animals/wawa_chatter.ogg
|
||||
# They nyoom and go under doors/tables
|
||||
- type: MovementSpeedModifier
|
||||
baseWalkSpeed: 5 # nyoom
|
||||
baseSprintSpeed: 7 # NYOOOOOM
|
||||
- type: MeleeWeapon
|
||||
soundHit:
|
||||
path: /Audio/Effects/bite.ogg
|
||||
angle: 30
|
||||
animation: WeaponArcBite
|
||||
damage:
|
||||
types:
|
||||
Piercing: 15 # NOM - Do NOT mess with skugs.
|
||||
- type: Physics
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeCircle
|
||||
radius: 0.2
|
||||
density: 120
|
||||
mask:
|
||||
- SmallMobMask
|
||||
layer:
|
||||
- SmallMobLayer
|
||||
# Round impact
|
||||
- type: GhostRole
|
||||
prob: 1
|
||||
makeSentient: true
|
||||
name: ghost-role-information-legallydistinctspaceferret-name
|
||||
description: ghost-role-information-legallydistinctspaceferret-description
|
||||
- type: Food
|
||||
- type: Hunger
|
||||
baseDecayRate: 0.3
|
||||
- type: GenericAntag
|
||||
rule: LegallyDistinctSpaceFerretRule
|
||||
# L.D.S.F.'s can have IDs because ... why not, honestly
|
||||
- type: Inventory
|
||||
templateId: legallydistinctspaceferret
|
||||
- type: InventorySlots
|
||||
|
||||
# Midround antagonist, spawned via random event
|
||||
- type: entity
|
||||
parent: BaseGameRule
|
||||
id: LegallyDistinctSpaceFerretSpawn
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: StationEvent
|
||||
weight: 10
|
||||
duration: 1
|
||||
minimumPlayers: 10
|
||||
- type: LegallyDistinctSpaceFerretSpawnRule
|
||||
|
||||
- type: entity
|
||||
id: SpawnPointGhostLegallyDistinctSpaceFerret
|
||||
name: ghost role spawn point
|
||||
suffix: legally distinct space ferret
|
||||
parent: MarkerBase
|
||||
components:
|
||||
- type: GhostRole
|
||||
name: ghost-role-information-legallydistinctspaceferret-name
|
||||
description: ghost-role-information-legallydistinctspaceferret-description
|
||||
rules: ghost-role-information-legallydistinctspaceferret-rules
|
||||
- type: GhostRoleMobSpawner
|
||||
prototype: MobLegallyDistinctSpaceFerret
|
||||
- type: Sprite
|
||||
sprite: Mobs/Animals/legallydistinctspaceferret.rsi
|
||||
layers:
|
||||
- state: legallydistinctspaceferret_eepy
|
||||
|
||||
- type: entity
|
||||
noSpawn: true
|
||||
parent: BaseGameRule
|
||||
id: LegallyDistinctSpaceFerretRule
|
||||
components:
|
||||
- type: GenericAntagRule
|
||||
agentName: legallydistinctspaceferret-round-end-agent-name
|
||||
objectives:
|
||||
- ConsumeNutrientsObjective
|
||||
- HibernateObjective
|
||||
|
||||
- type: entity
|
||||
abstract: true
|
||||
parent: BaseObjective
|
||||
id: BaseLegallyDistinctSpaceFerretObjective
|
||||
components:
|
||||
- type: Objective
|
||||
difficulty: 1.5
|
||||
issuer: legallydistinctspaceferret
|
||||
- type: RoleRequirement
|
||||
roles:
|
||||
components:
|
||||
- LegallyDistinctSpaceFerretRole
|
||||
|
||||
- type: entity
|
||||
parent: BaseLegallyDistinctSpaceFerretObjective
|
||||
id: ConsumeNutrientsObjective
|
||||
description: Consume enough food to survive.
|
||||
components:
|
||||
- type: Objective
|
||||
icon:
|
||||
sprite: Mobs/Animals/legallydistinctspaceferret.rsi
|
||||
state: legallydistinctspaceferret_eepy
|
||||
- type: ConsumeNutrientsCondition
|
||||
nutrientsRequired: 300.0
|
||||
|
||||
- type: entity
|
||||
parent: BaseLegallyDistinctSpaceFerretObjective
|
||||
id: HibernateObjective
|
||||
description: Hibernate in a gas scrubber.
|
||||
components:
|
||||
- type: Objective
|
||||
icon:
|
||||
sprite: Mobs/Animals/legallydistinctspaceferret.rsi
|
||||
state: legallydistinctspaceferret_eepy
|
||||
- type: HibernateCondition
|
||||
successMessage: legallydistinctspaceferret-you-win-popup
|
||||
successSfx: /Audio/Animals/wawa_outro.ogg
|
||||
|
||||
- type: accent
|
||||
id: legallydistinctspaceferret
|
||||
fullReplacements:
|
||||
- accent-words-legallydistinctspaceferret-1
|
||||
- accent-words-legallydistinctspaceferret-2
|
||||
- accent-words-legallydistinctspaceferret-3
|
||||
- accent-words-legallydistinctspaceferret-4
|
||||
- accent-words-legallydistinctspaceferret-5
|
||||
- accent-words-legallydistinctspaceferret-6
|
||||
- accent-words-legallydistinctspaceferret-7
|
||||
- accent-words-legallydistinctspaceferret-8
|
||||
|
||||
- type: speechVerb
|
||||
id: Wawa
|
||||
speechVerbStrings:
|
||||
- chat-speech-verb-wawa-1
|
||||
- chat-speech-verb-wawa-2
|
||||
- chat-speech-verb-wawa-3
|
||||
|
||||
- type: palette
|
||||
id: LegallyDistinctSpaceFerretColors
|
||||
name: LegallyDistinctSpaceFerretColors
|
||||
colors:
|
||||
Default: "#ffffff"
|
||||
Innocent: "#f6f439"
|
||||
Angry: "#dc5864"
|
||||
Eldritch: "#dc5864"
|
||||
Forgotten: "#111111"
|
||||
Fat: "#fefcab"
|
||||
WarCriminal: "#ab3430"
|
||||
Cocaine: "#679cfe"
|
||||
Mutant: "#7824a0"
|
||||
Damned: "#98e652"
|
||||
|
||||
- type: entity
|
||||
id: ActionBackflip
|
||||
name: Backflip
|
||||
description: DO A BACKFLIP!
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: InstantAction
|
||||
useDelay: 3
|
||||
icon: deprecated.rsi/deprecated.png
|
||||
event: !type:BackflipActionEvent
|
||||
checkCanInteract: false
|
||||
|
||||
- type: entity
|
||||
id: ActionEepy
|
||||
name: Eepy
|
||||
description: Hibernate. This ends your time as a Legally Distinct Space Ferret. Happy April Fools!
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: InstantAction
|
||||
useDelay: 100
|
||||
icon: { sprite: Mobs/Animals/legallydistinctspaceferret.rsi, state: legallydistinctspaceferret_eepy }
|
||||
event: !type:EepyActionEvent
|
||||
checkCanInteract: false
|
||||
|
||||
- type: speechSounds
|
||||
id: Wawa
|
||||
saySound:
|
||||
path: /Audio/Animals/wawa_statement.ogg
|
||||
askSound:
|
||||
path: /Audio/Animals/wawa_question.ogg
|
||||
exclaimSound:
|
||||
path: /Audio/Animals/wawa_exclaim.ogg
|
||||
|
||||
- type: antag
|
||||
id: LegallyDistinctSpaceFerret
|
||||
name: roles-antag-legallydistinctspaceferret-agent-name
|
||||
antagonist: true
|
||||
setPreference: false
|
||||
objective: roles-antag-legallydistinctspaceferret-objective
|
||||
|
||||
- type: inventoryTemplate
|
||||
id: legallydistinctspaceferret
|
||||
slots:
|
||||
- name: head
|
||||
slotTexture: head
|
||||
slotFlags: HEAD
|
||||
uiWindowPos: 1,2
|
||||
strippingWindowPos: 0,0
|
||||
displayName: Head
|
||||
- name: ears
|
||||
slotTexture: ears
|
||||
slotFlags: EARS
|
||||
stripTime: 3
|
||||
uiWindowPos: 0,2
|
||||
strippingWindowPos: 1,2
|
||||
displayName: Ears
|
||||
- name: mask
|
||||
slotTexture: mask
|
||||
slotFlags: MASK
|
||||
uiWindowPos: 0,1
|
||||
strippingWindowPos: 1,1
|
||||
displayName: Mask
|
||||
- name: id
|
||||
slotTexture: id
|
||||
slotFlags: IDCARD
|
||||
slotGroup: SecondHotbar
|
||||
stripTime: 6
|
||||
uiWindowPos: 2,1
|
||||
strippingWindowPos: 2,4
|
||||
displayName: ID
|
||||
|
||||
- type: nameIdentifierGroup
|
||||
id: LegallyDistinctSpaceFerret
|
||||
minValue: 1
|
||||
maxValue: 99 # I fucking dare you to spawn more than 100 wawa
|
||||
@@ -495,6 +495,9 @@
|
||||
tags:
|
||||
- Trash
|
||||
- HappyHonk
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: HappyHonkNukie
|
||||
chance: 0.1
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: ToyMouse
|
||||
|
||||
@@ -258,6 +258,9 @@
|
||||
reagents:
|
||||
- ReagentId: JuiceBanana
|
||||
Quantity: 10
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: ClusterBananaPeel
|
||||
chance: 0.001
|
||||
- type: Tag
|
||||
tags:
|
||||
- Fruit
|
||||
@@ -349,6 +352,8 @@
|
||||
- type: Extractable
|
||||
grindableSolutionName: food
|
||||
- type: SpaceGarbage
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: TrashBananaPeelExplosive
|
||||
|
||||
- type: entity
|
||||
name: baked banana peel
|
||||
@@ -666,6 +671,9 @@
|
||||
reagents:
|
||||
- ReagentId: JuicePotato
|
||||
Quantity: 10
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: HotPotato
|
||||
chance: 0.001
|
||||
- type: Tag
|
||||
tags:
|
||||
- Potato
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
- cig5
|
||||
- cig6
|
||||
- type: Appearance
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: CigPackSyndicate
|
||||
|
||||
- type: entity
|
||||
id: CigPackMixedBase
|
||||
|
||||
@@ -320,6 +320,15 @@
|
||||
- type: ComputerBoard
|
||||
prototype: BlockGameArcade
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerCircuitboard
|
||||
id: ParadiseArcadeComputerCircuitboard
|
||||
name: paradise arcade board
|
||||
description: A computer printed circuit board for a paradise arcade cabinet.
|
||||
components:
|
||||
- type: ComputerBoard
|
||||
prototype: ParadiseArcade
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerCircuitboard
|
||||
id: ParticleAcceleratorComputerCircuitboard
|
||||
|
||||
@@ -70,6 +70,8 @@
|
||||
Searching: { state: pai-searching-overlay }
|
||||
On: { state: pai-on-overlay }
|
||||
- type: StationMap
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: SyndicatePersonalAI
|
||||
|
||||
- type: entity
|
||||
parent: PersonalAI
|
||||
|
||||
@@ -490,11 +490,16 @@
|
||||
- type: entity
|
||||
parent: BasePlushie
|
||||
id: PlushieCarp
|
||||
name: carp plushie
|
||||
description: An adorable stuffed toy that resembles the monstrous space carp.
|
||||
name: space carp
|
||||
description: It's a space carp.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: carpplush
|
||||
sprite: Mobs/Aliens/Carps/space.rsi
|
||||
layers:
|
||||
- state: alive
|
||||
color: '#BB07F6'
|
||||
- state: mouth
|
||||
shader: unshaded
|
||||
- type: Item
|
||||
heldPrefix: carpplush
|
||||
storedRotation: -90
|
||||
@@ -514,6 +519,8 @@
|
||||
requiresSpecialDigestion: true
|
||||
useSound:
|
||||
path: /Audio/Effects/bite.ogg
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: MobCarpRainbow
|
||||
- type: MeleeWeapon
|
||||
wideAnimationRotation: -90
|
||||
soundHit:
|
||||
@@ -960,6 +967,8 @@
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
revolver-ammo: !type:Container
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: RevolverCapGunFake
|
||||
|
||||
- type: entity
|
||||
parent: RevolverCapGun
|
||||
@@ -1233,6 +1242,8 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 0
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: EnergySword
|
||||
- type: ItemToggleMeleeWeapon
|
||||
activatedSoundOnHit:
|
||||
path: /Audio/Weapons/eblade1.ogg
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
layers:
|
||||
- state: default
|
||||
- state: idpassenger
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: AgentIDCard
|
||||
- type: PresetIdCard
|
||||
job: Passenger
|
||||
|
||||
|
||||
@@ -272,6 +272,8 @@
|
||||
sprite: Objects/Misc/bureaucracy.rsi
|
||||
heldPrefix: pen
|
||||
size: Tiny
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: PenExploding
|
||||
- type: PhysicalComposition
|
||||
materialComposition:
|
||||
Steel: 25
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Janitorial
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: AdvMopItem
|
||||
|
||||
- type: entity
|
||||
parent: BaseItem
|
||||
|
||||
@@ -73,6 +73,8 @@
|
||||
- type: Residue
|
||||
residueAdjective: residue-slippery
|
||||
residueColor: residue-green
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: SoapSyndie
|
||||
|
||||
- type: entity
|
||||
name: soap
|
||||
|
||||
@@ -156,6 +156,8 @@
|
||||
Quantity: 3
|
||||
- type: Tag
|
||||
tags: []
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: CombatMedipen
|
||||
|
||||
- type: entity
|
||||
name: poison auto-injector
|
||||
|
||||
@@ -32,3 +32,5 @@
|
||||
materialComposition:
|
||||
Steel: 400
|
||||
Glass: 100
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Milkalyzer
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
parent: PlushieCarp
|
||||
id: DehydratedSpaceCarp
|
||||
name: dehydrated space carp
|
||||
description: Looks like a plush toy carp, but just add water and it becomes a real-life space carp!
|
||||
description: Looks like a regular space carp, but just add water and it becomes a real-life carp plushie!
|
||||
components:
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
Blunt: 10
|
||||
soundHit:
|
||||
collection: MetalThud
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: SyndicateJawsOfLife
|
||||
|
||||
- type: entity
|
||||
name: syndicate jaws of life
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 8
|
||||
maxVol: 8 #uses less fuel than a welder, so this isnt as bad as it looks
|
||||
- type: MeleeWeapon
|
||||
@@ -113,7 +113,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 4
|
||||
maxVol: 4 #uses less fuel than a welder, so this isnt as bad as it looks
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 12
|
||||
maxVol: 12 #uses less fuel than a welder, so this isnt as bad as it looks
|
||||
- type: Welder
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
Steel: 100
|
||||
- type: StaticPrice
|
||||
price: 30
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Haycutters
|
||||
|
||||
- type: entity
|
||||
name: screwdriver
|
||||
@@ -87,6 +89,8 @@
|
||||
Steel: 100
|
||||
- type: StaticPrice
|
||||
price: 30
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Moodriver
|
||||
|
||||
- type: entity
|
||||
name: wrench
|
||||
@@ -126,6 +130,8 @@
|
||||
Steel: 100
|
||||
- type: StaticPrice
|
||||
price: 22
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Wronch
|
||||
|
||||
- type: entity
|
||||
name: crowbar
|
||||
@@ -167,6 +173,8 @@
|
||||
- type: StaticPrice
|
||||
price: 22
|
||||
- type: Prying
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Cowbar
|
||||
|
||||
- type: entity
|
||||
parent: Crowbar
|
||||
@@ -231,6 +239,8 @@
|
||||
Plastic: 100
|
||||
- type: StaticPrice
|
||||
price: 56
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Mooltitool
|
||||
|
||||
- type: entity
|
||||
name: network configurator
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 100
|
||||
maxVol: 100
|
||||
- type: Tool
|
||||
@@ -91,7 +91,7 @@
|
||||
- type: PointLight
|
||||
enabled: false
|
||||
radius: 1.5
|
||||
color: orange
|
||||
color: red
|
||||
netsync: false
|
||||
- type: Appearance
|
||||
- type: RequiresEyeProtection
|
||||
@@ -102,6 +102,8 @@
|
||||
price: 40
|
||||
- type: IgnitionSource
|
||||
temperature: 700
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: Cowelder
|
||||
|
||||
- type: entity
|
||||
name: industrial welding tool
|
||||
@@ -117,7 +119,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 250
|
||||
maxVol: 250
|
||||
|
||||
@@ -135,7 +137,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 250
|
||||
maxVol: 250
|
||||
- type: Tool
|
||||
@@ -155,18 +157,18 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 1000
|
||||
maxVol: 1000
|
||||
- type: PointLight
|
||||
enabled: false
|
||||
radius: 1.5
|
||||
color: lightblue
|
||||
color: red
|
||||
- type: SolutionRegeneration
|
||||
solution: Welder
|
||||
generated:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 1
|
||||
|
||||
- type: entity
|
||||
@@ -186,7 +188,7 @@
|
||||
solutions:
|
||||
Welder:
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 50
|
||||
maxVol: 50
|
||||
- type: Tool
|
||||
@@ -194,4 +196,4 @@
|
||||
- type: PointLight
|
||||
enabled: false
|
||||
radius: 1.0
|
||||
color: orange
|
||||
color: red
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
drink:
|
||||
maxVol: 30
|
||||
reagents:
|
||||
- ReagentId: WeldingFuel
|
||||
- ReagentId: Blood
|
||||
Quantity: 30
|
||||
- type: Construction
|
||||
node: fuel
|
||||
|
||||
@@ -445,6 +445,8 @@
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Security
|
||||
- type: ReplaceOnSpawn
|
||||
prototype: WeaponDisablerSMG
|
||||
|
||||
- type: entity
|
||||
name: disabler SMG
|
||||
@@ -662,6 +664,8 @@
|
||||
node: start
|
||||
- type: StaticPrice
|
||||
price: 100
|
||||
- type: ReplaceOnSpawn
|
||||
ReplaceOnSpawn: WeaponPistolCHIMPUpgraded
|
||||
|
||||
- type: entity
|
||||
name: experimental C.H.I.M.P. handcannon
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user