Merge branch 'master' into tailstuff
This commit is contained in:
commit
da8804dd9d
|
|
@ -0,0 +1,90 @@
|
|||
using System.Numerics;
|
||||
using Content.Shared.Alert.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
namespace Content.Client.Alerts;
|
||||
|
||||
/// <summary>
|
||||
/// This handles <see cref="GenericCounterAlertComponent"/>
|
||||
/// </summary>
|
||||
public sealed class GenericCounterAlertSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<GenericCounterAlertComponent, UpdateAlertSpriteEvent>(OnUpdateAlertSprite);
|
||||
}
|
||||
|
||||
private void OnUpdateAlertSprite(Entity<GenericCounterAlertComponent> ent, ref UpdateAlertSpriteEvent args)
|
||||
{
|
||||
var sprite = args.SpriteViewEnt.Comp;
|
||||
|
||||
var ev = new GetGenericAlertCounterAmountEvent(args.Alert);
|
||||
RaiseLocalEvent(args.ViewerEnt, ref ev);
|
||||
|
||||
if (!ev.Handled)
|
||||
return;
|
||||
|
||||
// It cannot be null if its handled, but good to check to avoid ugly null ignores.
|
||||
if (ev.Amount == null)
|
||||
return;
|
||||
|
||||
// How many digits can we display
|
||||
var maxDigitCount = GetMaxDigitCount((ent, ent, sprite));
|
||||
|
||||
// Clamp it to a positive number that we can actually display in full (no rollover to 0)
|
||||
var amount = (int) Math.Clamp(ev.Amount.Value, 0, Math.Pow(10, maxDigitCount) - 1);
|
||||
|
||||
// This is super wack but ig it works?
|
||||
var digitCount = ent.Comp.HideLeadingZeroes
|
||||
? amount.ToString().Length
|
||||
: maxDigitCount;
|
||||
|
||||
if (ent.Comp.HideLeadingZeroes)
|
||||
{
|
||||
for (var i = 0; i < ent.Comp.DigitKeys.Count; i++)
|
||||
{
|
||||
if (!_sprite.LayerMapTryGet(ent.Owner, ent.Comp.DigitKeys[i], out var layer, false))
|
||||
continue;
|
||||
|
||||
_sprite.LayerSetVisible(ent.Owner, layer, i <= digitCount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once PossibleLossOfFraction
|
||||
var baseOffset = (ent.Comp.AlertSize.X - digitCount * ent.Comp.GlyphWidth) / 2 * (1f / EyeManager.PixelsPerMeter);
|
||||
|
||||
for (var i = 0; i < ent.Comp.DigitKeys.Count; i++)
|
||||
{
|
||||
if (!_sprite.LayerMapTryGet(ent.Owner, ent.Comp.DigitKeys[i], out var layer, false))
|
||||
continue;
|
||||
|
||||
var result = amount / (int) Math.Pow(10, i) % 10;
|
||||
_sprite.LayerSetRsiState(ent.Owner, layer, result.ToString());
|
||||
|
||||
if (ent.Comp.CenterGlyph)
|
||||
{
|
||||
var offset = baseOffset + (digitCount - 1 - i) * ent.Comp.GlyphWidth * (1f / EyeManager.PixelsPerMeter);
|
||||
_sprite.LayerSetOffset(ent.Owner, layer, new Vector2(offset, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of digits that we can display.
|
||||
/// </summary>
|
||||
/// <returns>The number of digits.</returns>
|
||||
private int GetMaxDigitCount(Entity<GenericCounterAlertComponent, SpriteComponent> ent)
|
||||
{
|
||||
for (var i = ent.Comp1.DigitKeys.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (_sprite.LayerExists((ent.Owner, ent.Comp2), ent.Comp1.DigitKeys[i]))
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,11 +11,14 @@ public record struct UpdateAlertSpriteEvent
|
|||
{
|
||||
public Entity<SpriteComponent> SpriteViewEnt;
|
||||
|
||||
public EntityUid ViewerEnt;
|
||||
|
||||
public AlertPrototype Alert;
|
||||
|
||||
public UpdateAlertSpriteEvent(Entity<SpriteComponent> spriteViewEnt, AlertPrototype alert)
|
||||
public UpdateAlertSpriteEvent(Entity<SpriteComponent> spriteViewEnt, EntityUid viewerEnt, AlertPrototype alert)
|
||||
{
|
||||
SpriteViewEnt = spriteViewEnt;
|
||||
ViewerEnt = viewerEnt;
|
||||
Alert = alert;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using Content.Client.Alerts;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Alert.Components;
|
||||
using Content.Shared.Revenant;
|
||||
using Content.Shared.Revenant.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
|
@ -15,7 +17,7 @@ public sealed class RevenantSystem : EntitySystem
|
|||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RevenantComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
SubscribeLocalEvent<RevenantComponent, UpdateAlertSpriteEvent>(OnUpdateAlert);
|
||||
SubscribeLocalEvent<RevenantComponent, GetGenericAlertCounterAmountEvent>(OnGetCounterAmount);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(EntityUid uid, RevenantComponent component, ref AppearanceChangeEvent args)
|
||||
|
|
@ -40,14 +42,14 @@ public sealed class RevenantSystem : EntitySystem
|
|||
}
|
||||
}
|
||||
|
||||
private void OnUpdateAlert(Entity<RevenantComponent> ent, ref UpdateAlertSpriteEvent args)
|
||||
private void OnGetCounterAmount(Entity<RevenantComponent> ent, ref GetGenericAlertCounterAmountEvent args)
|
||||
{
|
||||
if (args.Alert.ID != ent.Comp.EssenceAlert)
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
var essence = Math.Clamp(ent.Comp.Essence.Int(), 0, 999);
|
||||
_sprite.LayerSetRsiState(args.SpriteViewEnt.AsNullable(), RevenantVisualLayers.Digit1, $"{(essence / 100) % 10}");
|
||||
_sprite.LayerSetRsiState(args.SpriteViewEnt.AsNullable(), RevenantVisualLayers.Digit2, $"{(essence / 10) % 10}");
|
||||
_sprite.LayerSetRsiState(args.SpriteViewEnt.AsNullable(), RevenantVisualLayers.Digit3, $"{essence % 10}");
|
||||
if (ent.Comp.EssenceAlert != args.Alert)
|
||||
return;
|
||||
|
||||
args.Amount = ent.Comp.Essence.Int();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Content.Shared.CCVar;
|
||||
using Content.Shared._DV.Mind; // DeltaV
|
||||
using Content.Shared.CCVar; // DeltaV
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.NPC;
|
||||
|
|
@ -35,6 +36,12 @@ public sealed class SSDIndicatorSystem : EntitySystem
|
|||
TryComp<MindContainerComponent>(uid, out var mindContainer) &&
|
||||
mindContainer.ShowExamineInfo)
|
||||
{
|
||||
// Begin DeltaV Addition
|
||||
var ev = new ShowSSDIndicatorEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
if (ev.Hidden)
|
||||
return;
|
||||
// End DeltaV Addition
|
||||
args.StatusIcons.Add(_prototype.Index(component.Icon));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ public sealed class AlertsUIController : UIController, IOnStateEntered<GameplayS
|
|||
if (!EntityManager.TryGetComponent<SpriteComponent>(spriteViewEnt, out var sprite))
|
||||
return;
|
||||
|
||||
var ev = new UpdateAlertSpriteEvent((spriteViewEnt, sprite), alert);
|
||||
var ev = new UpdateAlertSpriteEvent((spriteViewEnt, sprite), player, alert);
|
||||
EntityManager.EventBus.RaiseLocalEvent(player, ref ev);
|
||||
EntityManager.EventBus.RaiseLocalEvent(spriteViewEnt, ref ev);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,10 +57,15 @@ namespace Content.Client.UserInterface.Systems.Alerts.Controls
|
|||
_sprite = _entityManager.System<SpriteSystem>();
|
||||
TooltipSupplier = SupplyTooltip;
|
||||
Alert = alert;
|
||||
|
||||
HorizontalAlignment = HAlignment.Left;
|
||||
_severity = severity;
|
||||
_icon = new SpriteView
|
||||
{
|
||||
Scale = new Vector2(2, 2)
|
||||
Scale = new Vector2(2, 2),
|
||||
MaxSize = new Vector2(64, 64),
|
||||
Stretch = SpriteView.StretchMode.None,
|
||||
HorizontalAlignment = HAlignment.Left
|
||||
};
|
||||
|
||||
SetupIcon();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
using Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
namespace Content.Client._DV.Abilities.Psionics;
|
||||
|
||||
public sealed class FracturedFormPowerSystem : SharedFracturedFormPowerSystem;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using Content.Shared._DV.Grappling.EntitySystems;
|
||||
|
||||
namespace Content.Client._DV.Grappling.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Client side handling for grapplers.
|
||||
/// </summary>
|
||||
public sealed class GrapplingSystem : SharedGrapplingSystem;
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._Mono.CorticalBorer
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public sealed class CorticalBorerDispenserBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private CorticalBorerDispenserWindow? _window;
|
||||
|
||||
public CorticalBorerDispenserBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CorticalBorerDispenserWindow>();
|
||||
_window.SetInfoFromEntity(EntMan, Owner);
|
||||
|
||||
// Setup static button actions.
|
||||
_window.AmountGrid.OnButtonPressed += s => SendMessage(new CorticalBorerDispenserSetInjectAmountMessage(s));
|
||||
|
||||
_window.OnDispenseReagentButtonPressed += id => SendMessage(new CorticalBorerDispenserInjectMessage(id));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the UI each time new state data is sent from the server.
|
||||
/// </summary>
|
||||
/// <param name="state">
|
||||
/// Data of the <see cref="ReagentDispenserComponent"/> that this UI represents.
|
||||
/// Sent from the server.
|
||||
/// </param>
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
var castState = (CorticalBorerDispenserBoundUserInterfaceState) state;
|
||||
_window?.UpdateState(castState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:ui="clr-namespace:Content.Client.Chemistry.UI"
|
||||
Title="{Loc 'reagent-dispenser-bound-user-interface-title'}"
|
||||
MinSize="400 175"
|
||||
SetSize="600 300">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer Orientation="Vertical" MinWidth="170">
|
||||
<Label Text="{Loc 'reagent-dispenser-window-amount-to-dispense-label'}" HorizontalAlignment="Center" />
|
||||
<ui:ButtonGrid
|
||||
Name="AmountGrid"
|
||||
Access="Public"
|
||||
Columns="3"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="5"
|
||||
ButtonList="1,5,10,15,20,25,30,50,100"
|
||||
RadioGroup="True">
|
||||
</ui:ButtonGrid>
|
||||
</BoxContainer>
|
||||
<SplitContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<ScrollContainer HScrollEnabled="False"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
MinHeight="50"
|
||||
SizeFlagsStretchRatio="2.5">
|
||||
<GridContainer Name="ReagentList"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
Access="Public"
|
||||
Columns="3" />
|
||||
</ScrollContainer>
|
||||
<ScrollContainer HScrollEnabled="False"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
MinHeight="50">
|
||||
</ScrollContainer>
|
||||
</SplitContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Mono.CorticalBorer;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CorticalBorerDispenserWindow : FancyWindow
|
||||
{
|
||||
|
||||
public event Action<string>? OnDispenseReagentButtonPressed;
|
||||
|
||||
public CorticalBorerDispenserWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
var castState = (CorticalBorerDispenserBoundUserInterfaceState)state;
|
||||
|
||||
UpdateReagentsList(castState.DisList);
|
||||
|
||||
AmountGrid.Selected = castState.SelectedDispenseAmount.ToString();
|
||||
}
|
||||
|
||||
public void UpdateReagentsList(List<CorticalBorerDispenserItem> chemicals)
|
||||
{
|
||||
if (ReagentList == null)
|
||||
return;
|
||||
|
||||
ReagentList.Children.Clear();
|
||||
|
||||
chemicals.Sort((x, y) => x.ReagentName.CompareTo(y.ReagentName));
|
||||
|
||||
foreach (var chem in chemicals)
|
||||
{
|
||||
var card = new CorticalBorerReagentCardControl(chem);
|
||||
card.OnPressed += OnDispenseReagentButtonPressed;
|
||||
ReagentList.Children.Add(card);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using Content.Shared.Chemistry;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Mono.CorticalBorer;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CorticalBorerReagentCardControl : Control
|
||||
{
|
||||
public Action<string>? OnPressed;
|
||||
|
||||
public CorticalBorerReagentCardControl(CorticalBorerDispenserItem set)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
ColorPanel.PanelOverride = new StyleBoxFlat{ BackgroundColor = set.ReagentColor};
|
||||
ReagentNameLabel.Text = set.ReagentName;
|
||||
FillLabel.Text = Loc.GetString("cortical-borer-dispenser-window-cost", ("cost", set.Cost * set.Amount));
|
||||
|
||||
// disable the button if you can't afford it, makes it easier
|
||||
MainButton.Disabled = set.Chems < set.Cost * set.Amount;
|
||||
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke(set.ReagentId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<Control xmlns="https://spacestation14.io" HorizontalExpand="True">
|
||||
<BoxContainer Name="MainContainer"
|
||||
Orientation="Horizontal"
|
||||
HorizontalExpand="True">
|
||||
<PanelContainer Name="ColorPanel"
|
||||
VerticalExpand="True"
|
||||
SetWidth="7"
|
||||
Margin="0 1 0 0" />
|
||||
<Button Name="MainButton"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
StyleClasses="ButtonSquare"
|
||||
Margin="-1 0 0 0">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True"
|
||||
Margin="-5 0 0 0">
|
||||
<Label Name="ReagentNameLabel" />
|
||||
<Label Name="FillLabel"
|
||||
StyleClasses="LabelSubText"
|
||||
Margin="0 -5 0 0" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</Button>
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using Content.Shared.Alert.Components;
|
||||
|
||||
namespace Content.Client._Mono.CorticalBorer;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public sealed class CorticalBorerSystem : SharedCorticalBorerSystem
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerComponent, GetGenericAlertCounterAmountEvent>(OnGetCounterAmount);
|
||||
}
|
||||
|
||||
private void OnGetCounterAmount(Entity<CorticalBorerComponent> ent, ref GetGenericAlertCounterAmountEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.ChemicalAlert != args.Alert)
|
||||
return;
|
||||
|
||||
args.Amount = ent.Comp.ChemicalPoints;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,8 @@ namespace Content.IntegrationTests.Tests
|
|||
"Chibi", // DeltaV
|
||||
"Elegance", // DeltaV
|
||||
"Division", // DeltaV
|
||||
"ArenaMedieval" //DeltaV
|
||||
"ArenaMedieval", //DeltaV
|
||||
"Submarine" //DeltaV
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -251,6 +251,17 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
if (string.IsNullOrEmpty(message))
|
||||
return;
|
||||
|
||||
// Begin Mono Changes - Is this being sent direct
|
||||
var targetEv = new CheckTargetedSpeechEvent();
|
||||
RaiseLocalEvent(source, targetEv);
|
||||
|
||||
if (targetEv.Targets.Count > 0)
|
||||
{
|
||||
SendEntityDirect(source, message, range, nameOverride, targetEv.Targets);
|
||||
return;
|
||||
}
|
||||
// End Mono Changes - Is this being sent direct
|
||||
|
||||
// This message may have a radio prefix, and should then be whispered to the resolved radio channel
|
||||
if (checkRadioPrefix)
|
||||
{
|
||||
|
|
@ -591,6 +602,72 @@ public sealed partial class ChatSystem : SharedChatSystem
|
|||
}
|
||||
}
|
||||
|
||||
// Begin Mono Changes
|
||||
private void SendEntityDirect(
|
||||
EntityUid source,
|
||||
string originalMessage,
|
||||
ChatTransmitRange range,
|
||||
string? nameOverride,
|
||||
List<EntityUid> recipients,
|
||||
bool hideLog = false,
|
||||
bool ignoreActionBlocker = false)
|
||||
{
|
||||
var message = TransformSpeech(source, FormattedMessage.RemoveMarkupOrThrow(originalMessage));
|
||||
if (message.Length == 0)
|
||||
return;
|
||||
|
||||
string name;
|
||||
if (nameOverride != null)
|
||||
{
|
||||
name = nameOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
var nameEv = new TransformSpeakerNameEvent(source, Name(source));
|
||||
RaiseLocalEvent(source, nameEv);
|
||||
name = nameEv.VoiceName;
|
||||
}
|
||||
name = FormattedMessage.EscapeText(name);
|
||||
|
||||
var wrappedMessage = Loc.GetString("chat-manager-entity-whisper-wrap-message",
|
||||
("entityName", name), ("message", FormattedMessage.EscapeText(message)));
|
||||
|
||||
foreach (var (session, data) in GetRecipients(source, WhisperMuffledRange))
|
||||
{
|
||||
EntityUid listener;
|
||||
|
||||
if (session.AttachedEntity is not { Valid: true } playerEntity)
|
||||
continue;
|
||||
listener = session.AttachedEntity.Value;
|
||||
|
||||
if (MessageRangeCheck(session, data, range) != MessageRangeCheckResult.Full ||
|
||||
!recipients.Contains(listener) &&
|
||||
!HasComp<GhostComponent>(listener))
|
||||
continue;
|
||||
|
||||
_chatManager.ChatMessageToOne(ChatChannel.Local, message, wrappedMessage, source, false, session.Channel); // DeltaV - no collective mind chat channel, use local..?
|
||||
}
|
||||
|
||||
if (!hideLog)
|
||||
if (originalMessage == message)
|
||||
{
|
||||
if (name != Name(source))
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Direct messaged from {ToPrettyString(source):user} as {name}: {originalMessage}.");
|
||||
else
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Direct messaged from {ToPrettyString(source):user}: {originalMessage}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (name != Name(source))
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low,
|
||||
$"Direct messaged from {ToPrettyString(source):user} as {name}, original: {originalMessage}, transformed: {message}.");
|
||||
else
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low,
|
||||
$"Direct messaged from {ToPrettyString(source):user}, original: {originalMessage}, transformed: {message}.");
|
||||
}
|
||||
}
|
||||
// End Mono Changes
|
||||
|
||||
private void SendEntityEmote(
|
||||
EntityUid source,
|
||||
string action,
|
||||
|
|
@ -959,6 +1036,13 @@ public sealed class CheckIgnoreSpeechBlockerEvent : EntityEventArgs
|
|||
}
|
||||
}
|
||||
|
||||
// Begin Mono Changes
|
||||
public sealed class CheckTargetedSpeechEvent : EntityEventArgs
|
||||
{
|
||||
public List<EntityUid> Targets = new List<EntityUid>();
|
||||
}
|
||||
// End Mono Changes
|
||||
|
||||
/// <summary>
|
||||
/// Raised on an entity when it speaks, either through 'say' or 'whisper'.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ public sealed class HealthAnalyzerSystem : EntitySystem
|
|||
/// <param name="healthAnalyzer">The health analyzer that should receive the updates</param>
|
||||
/// <param name="target">The entity to start analyzing</param>
|
||||
/// <param name="part">Shitmed Change: The body part to analyze, if any</param>
|
||||
private void BeginAnalyzingEntity(Entity<HealthAnalyzerComponent> healthAnalyzer, EntityUid target, EntityUid? part = null)
|
||||
public void BeginAnalyzingEntity(Entity<HealthAnalyzerComponent> healthAnalyzer, EntityUid target, EntityUid? part = null) // Mono - make public
|
||||
{
|
||||
//Link the health analyzer to the scanned entity
|
||||
healthAnalyzer.Comp.ScannedEntity = target;
|
||||
|
|
@ -202,7 +202,7 @@ public sealed class HealthAnalyzerSystem : EntitySystem
|
|||
/// </summary>
|
||||
/// <param name="healthAnalyzer">The health analyzer that's receiving the updates</param>
|
||||
/// <param name="target">The entity to analyze</param>
|
||||
private void StopAnalyzingEntity(Entity<HealthAnalyzerComponent> healthAnalyzer, EntityUid target)
|
||||
public void StopAnalyzingEntity(Entity<HealthAnalyzerComponent> healthAnalyzer, EntityUid target) // Mono - make public
|
||||
{
|
||||
//Unlink the analyzer
|
||||
healthAnalyzer.Comp.ScannedEntity = null;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ using Content.Shared.Damage;
|
|||
using Content.Shared.Mobs.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
namespace Content.Server.Abilities.Psionics
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Server.Abilities.Psionics
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class MindSwappedComponent : Component
|
||||
{
|
||||
[ViewVariables]
|
||||
public EntityUid OriginalEntity = default!;
|
||||
[DataField("mindSwapReturnActionId",
|
||||
customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string? MindSwapReturnActionId = "ActionMindSwapReturn";
|
||||
|
||||
[DataField("mindSwapReturnActionEntity")]
|
||||
public EntityUid? MindSwapReturnActionEntity;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Disposal.Unit;
|
||||
using Content.Shared._DV.Abilities.Psionics;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Events;
|
||||
|
|
@ -24,7 +25,6 @@ namespace Content.Server.Abilities.Psionics
|
|||
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
|
||||
[Dependency] private readonly AtmosphereSystem _atmos = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -66,8 +66,6 @@ namespace Content.Server.Abilities.Psionics
|
|||
{
|
||||
var projection = Spawn(component.Prototype, Transform(uid).Coordinates);
|
||||
|
||||
_mind.ShowExamineInfo(uid, false); // Hide SSD indicator
|
||||
|
||||
_transform.AttachToGridOrMap(projection);
|
||||
_mindSwap.Swap(uid, projection);
|
||||
|
||||
|
|
@ -76,11 +74,6 @@ namespace Content.Server.Abilities.Psionics
|
|||
}
|
||||
private void OnMindRemoved(EntityUid uid, TelegnosticProjectionComponent component, MindRemovedMessage args)
|
||||
{
|
||||
// This is called during transfer to, so the MindSwappedComponent is still present.
|
||||
if (TryComp<MindSwappedComponent>(uid, out var mindSwapped))
|
||||
{
|
||||
_mind.ShowExamineInfo(mindSwapped.OriginalEntity, true);
|
||||
}
|
||||
QueueDel(uid);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ using Robust.Shared.Audio.Systems;
|
|||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Random;
|
||||
using Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
namespace Content.Server.Psionics
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
using Content.Server.Abilities.Psionics;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Nyanotrasen.StationEvents.Events;
|
||||
using Content.Server.Radio.Components;
|
||||
using Content.Server.Radio.EntitySystems;
|
||||
using Content.Server.StationEvents.Events;
|
||||
using Content.Shared._DV.Abilities.Psionics;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Psionics.Glimmer;
|
||||
using Content.Shared.Radio;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,11 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
|||
EntityUid? station,
|
||||
EntityUid? entity = null)
|
||||
{
|
||||
_prototypeManager.TryIndex(job ?? string.Empty, out var prototype);
|
||||
// Delta-V, prevent errors if this is an empty job.
|
||||
JobPrototype? prototype = null;
|
||||
if (!string.IsNullOrWhiteSpace(job))
|
||||
_prototypeManager.TryIndex(job ?? string.Empty, out prototype);
|
||||
// Delta-V end
|
||||
RoleLoadout? loadout = null;
|
||||
|
||||
// Need to get the loadout up-front to handle names if we use an entity spawn override.
|
||||
|
|
@ -163,7 +167,8 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
|||
SetPdaAndIdCardData(entity.Value, metaData.EntityName, prototype, station);
|
||||
}
|
||||
|
||||
DoJobSpecials(job, entity.Value);
|
||||
if (!string.IsNullOrWhiteSpace(job)) // Delta-V, empty job is okay, actually
|
||||
DoJobSpecials(job, entity.Value);
|
||||
_identity.QueueIdentityUpdate(entity.Value);
|
||||
return entity.Value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,283 @@
|
|||
using Content.Server.Abilities.Psionics;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.Cloning;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared._DV.Abilities.Psionics;
|
||||
using Content.Shared.Abilities.Psionics;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.Bed.Sleep;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Psionics.Events;
|
||||
using Content.Shared.SSDIndicator;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._DV.Abilities.Psionics;
|
||||
|
||||
public sealed class FracturedFormPowerSystem : SharedFracturedFormPowerSystem
|
||||
{
|
||||
[Dependency] private readonly ChatSystem _chat = default!;
|
||||
[Dependency] private readonly CloningSystem _cloning = default!;
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly MindSystem _mind = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popups = default!;
|
||||
[Dependency] private readonly SharedPsionicAbilitiesSystem _psionics = default!;
|
||||
[Dependency] private readonly SleepingSystem _sleeping = default!;
|
||||
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
|
||||
[Dependency] private readonly StationSystem _station = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<FracturedFormPowerComponent, ComponentInit>(OnInit);
|
||||
SubscribeLocalEvent<FracturedFormPowerComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<FracturedFormPowerComponent, FracturedFormPowerActionEvent>(OnPowerUsed);
|
||||
SubscribeLocalEvent<FracturedFormPowerComponent, DispelledEvent>(OnDispelled);
|
||||
SubscribeLocalEvent<FracturedFormPowerComponent, FracturedFormDoAfterEvent>(OnDoAfter);
|
||||
SubscribeLocalEvent<FracturedFormBodyComponent, ExaminedEvent>(OnExamine);
|
||||
}
|
||||
|
||||
private void OnInit(Entity<FracturedFormPowerComponent> entity, ref ComponentInit args)
|
||||
{
|
||||
var component = entity.Comp;
|
||||
_actions.AddAction(entity, ref component.FracturedFormActionEntity, component.FracturedFormActionId);
|
||||
_actions.StartUseDelay(component.FracturedFormActionEntity);
|
||||
if (TryComp<PsionicComponent>(entity, out var psionic) && psionic.PsionicAbility == null)
|
||||
{
|
||||
psionic.PsionicAbility = component.FracturedFormActionEntity;
|
||||
psionic.ActivePowers.Add(component);
|
||||
}
|
||||
|
||||
// Next random swap is between 5 to 20 minutes.
|
||||
component.NextSwap = _timing.CurTime + TimeSpan.FromSeconds(_random.Next(300, 1200));
|
||||
|
||||
if (HasComp<FracturedFormBodyComponent>(entity)) return; // Don't generate a new body if we're already part of a network.
|
||||
AddComp<FracturedFormBodyComponent>(entity);
|
||||
component.Bodies.Add(entity);
|
||||
GenerateForm(entity);
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<FracturedFormPowerComponent> entity, ref ComponentShutdown args)
|
||||
{
|
||||
_actions.RemoveAction(entity.Owner, entity.Comp.FracturedFormActionEntity);
|
||||
|
||||
if (TryComp<PsionicComponent>(entity, out var psionic))
|
||||
{
|
||||
psionic.ActivePowers.Remove(entity.Comp);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
// Loop through fracturedForm havers, if they pass the NextSwap threshold, or they're asleep, force swap them.
|
||||
var ents = EntityQueryEnumerator<FracturedFormPowerComponent>();
|
||||
var t = _timing.CurTime;
|
||||
List<Entity<FracturedFormPowerComponent>> toSwap = new();
|
||||
while (ents.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
if (!comp.SleepWarned && t > comp.NextSwap - TimeSpan.FromSeconds(5))
|
||||
{
|
||||
comp.SleepWarned = true;
|
||||
_popups.PopupEntity(Loc.GetString("fractured-form-sleepy"), uid, uid, PopupType.LargeCaution);
|
||||
_chat.TryEmoteWithChat(uid, "Yawn", ChatTransmitRange.Normal);
|
||||
}
|
||||
if (HasComp<SleepingComponent>(uid) || _mobState.IsIncapacitated(uid) || t > comp.NextSwap)
|
||||
{
|
||||
toSwap.Add(new(uid, comp));
|
||||
}
|
||||
}
|
||||
foreach (var ent in toSwap)
|
||||
{
|
||||
TrySwap(ent);
|
||||
}
|
||||
|
||||
var bodies = EntityQueryEnumerator<FracturedFormBodyComponent>();
|
||||
while (bodies.MoveNext(out var uid, out var _))
|
||||
{
|
||||
if (!HasComp<SleepingComponent>(uid) && !HasComp<FracturedFormPowerComponent>(uid))
|
||||
{
|
||||
_sleeping.TrySleeping(uid);
|
||||
}
|
||||
|
||||
if (TryComp<SSDIndicatorComponent>(uid, out var ssd) && ssd.IsSSD)
|
||||
{
|
||||
// Ensure the body isn't forcesleep'd by the SSD system.
|
||||
ssd.IsSSD = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EntityUid GenerateForm(Entity<FracturedFormPowerComponent> original)
|
||||
{
|
||||
// Form:
|
||||
// - Same appearance as original
|
||||
// - Different apperance, still humanoid
|
||||
// Equipment:
|
||||
// - Same as original body
|
||||
// - Nude and helpless
|
||||
|
||||
var xform = Transform(original);
|
||||
|
||||
bool hasClothes = _random.Prob(0.4f);
|
||||
|
||||
EntityUid? newBody;
|
||||
if (_random.Prob(0.6f) || !_cloning.TryCloning(original, _transform.GetMapCoordinates(original), hasClothes ? original.Comp.CopyClothed : original.Comp.CopyNaked, out newBody)) // Slightly lower chance to copy the original body
|
||||
{
|
||||
// Either the dice rolled poorly, or the cloning failed. Either way, make a new body instead. (Or try to)
|
||||
var validSpecies = new List<ProtoId<SpeciesPrototype>>();
|
||||
var speciesPrototypes = _prototype.EnumeratePrototypes<SpeciesPrototype>();
|
||||
foreach (var proto in speciesPrototypes)
|
||||
{
|
||||
if (proto.RoundStart)
|
||||
validSpecies.Add(proto.ID);
|
||||
}
|
||||
var species = _random.Pick(validSpecies);
|
||||
var character = HumanoidCharacterProfile.RandomWithSpecies(species);
|
||||
newBody = _stationSpawning.SpawnPlayerMob(xform.Coordinates, hasClothes ? original.Comp.VisitorJob : original.Comp.NakedJob, character, _station.GetCurrentStation(original.Owner));
|
||||
if (newBody is not { } bodyV || Deleted(bodyV))
|
||||
{
|
||||
Log.Error($"Failed to create a new body for {ToPrettyString(original)}. This is a bug.");
|
||||
return EntityUid.Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
if (newBody is { } body && !Deleted(body))
|
||||
{
|
||||
AddComp<FracturedFormBodyComponent>(body);
|
||||
original.Comp.Bodies.Add(body);
|
||||
return body;
|
||||
}
|
||||
|
||||
return default!;
|
||||
}
|
||||
|
||||
private bool IsValidBody(Entity<FracturedFormPowerComponent> entity, EntityUid body)
|
||||
{
|
||||
if (body == entity.Owner)
|
||||
return false;
|
||||
if (!entity.Comp.Bodies.Contains(body))
|
||||
return false;
|
||||
if (!TryComp<MindContainerComponent>(body, out var cmind))
|
||||
return false;
|
||||
if (cmind.HasMind)
|
||||
return false;
|
||||
if (HasComp<ForcedSleepingComponent>(body))
|
||||
return false;
|
||||
if (_mobState.IsIncapacitated(body))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<EntityUid> ValidBodies(Entity<FracturedFormPowerComponent> entity)
|
||||
{
|
||||
var bodies = new List<EntityUid>();
|
||||
foreach (var body in entity.Comp.Bodies)
|
||||
{
|
||||
if (IsValidBody(entity, body))
|
||||
bodies.Add(body);
|
||||
}
|
||||
return bodies;
|
||||
}
|
||||
|
||||
public bool CanSwap(Entity<FracturedFormPowerComponent> entity)
|
||||
{
|
||||
foreach (var body in entity.Comp.Bodies)
|
||||
{
|
||||
if (IsValidBody(entity, body))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool TrySwap(Entity<FracturedFormPowerComponent> entity)
|
||||
{
|
||||
// Pick a random body, or the other one, if we have more than one.
|
||||
// Only picks bodies which don't have actives minds (In case of mindswap or something stupid)
|
||||
if (!CanSwap(entity))
|
||||
return false;
|
||||
var targetBody = _random.Pick(ValidBodies(entity));
|
||||
_audio.PlayPredicted(entity.Comp.SwapSound, entity, entity);
|
||||
if (TryComp<MindContainerComponent>(entity, out var mindContainer))
|
||||
_mind.TransferTo(mindContainer.Mind!.Value, targetBody);
|
||||
|
||||
// If the body is sleeping, try to wake up.
|
||||
_sleeping.TryWaking(targetBody, false, entity);
|
||||
|
||||
var duplicate = AddComp<FracturedFormPowerComponent>(targetBody);
|
||||
duplicate.Bodies = entity.Comp.Bodies;
|
||||
RemCompDeferred(entity, entity.Comp);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnPowerUsed(Entity<FracturedFormPowerComponent> entity, ref FracturedFormPowerActionEvent args)
|
||||
{
|
||||
if (!CanSwap(entity))
|
||||
{
|
||||
_popups.PopupEntity(Loc.GetString("fractured-form-nobodies"), entity, entity, PopupType.Large);
|
||||
return;
|
||||
}
|
||||
|
||||
entity.Comp.SleepWarned = true;
|
||||
_chat.TryEmoteWithChat(entity.Owner, "Yawn", ChatTransmitRange.Normal);
|
||||
_popups.PopupEntity(Loc.GetString("fractured-form-sleepy"), entity, entity, PopupType.LargeCaution);
|
||||
var ev = new FracturedFormDoAfterEvent();
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, entity, entity.Comp.ManualSwapTime, ev, entity);
|
||||
_doAfter.TryStartDoAfter(doAfterArgs, out var doAfterId);
|
||||
entity.Comp.DoAfter = doAfterId;
|
||||
_psionics.LogPowerUsed(entity, "fractured form swap", 1, 3);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDispelled(Entity<FracturedFormPowerComponent> entity, ref DispelledEvent args)
|
||||
{
|
||||
if (entity.Comp.DoAfter == null)
|
||||
return;
|
||||
|
||||
_doAfter.Cancel(entity.Comp.DoAfter);
|
||||
entity.Comp.DoAfter = null;
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDoAfter(Entity<FracturedFormPowerComponent> entity, ref FracturedFormDoAfterEvent args)
|
||||
{
|
||||
entity.Comp.DoAfter = null;
|
||||
|
||||
if (args.Cancelled || args.Handled)
|
||||
return;
|
||||
|
||||
_sleeping.TrySleeping(entity.Owner);
|
||||
}
|
||||
|
||||
private void OnExamine(Entity<FracturedFormBodyComponent> entity, ref ExaminedEvent args)
|
||||
{
|
||||
if (HasComp<FracturedFormPowerComponent>(entity))
|
||||
return;
|
||||
if (TryComp<FracturedFormPowerComponent>(args.Examiner, out var fracturedHost) && fracturedHost.Bodies.Contains(entity.Owner))
|
||||
args.PushMarkup($"[color=yellow]{Loc.GetString("fractured-form-examine-self", ("ent", entity))}[/color]");
|
||||
else
|
||||
args.PushMarkup($"[color=yellow]{Loc.GetString("fractured-form-ssd", ("ent", entity))}[/color]");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,499 @@
|
|||
using Content.Server.DoAfter;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Server.Interaction;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared._DV.Grappling.Components;
|
||||
using Content.Shared._DV.Grappling.EntitySystems;
|
||||
using Content.Shared._DV.Grappling.Events;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.CombatMode;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Inventory.VirtualItem;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Pulling.Events;
|
||||
using Content.Shared.Standing;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Server.Physics;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._DV.Grappling.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Server side handling of grappling
|
||||
/// </summary>
|
||||
public sealed partial class GrapplingSystem : SharedGrapplingSystem
|
||||
{
|
||||
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly InteractionSystem _interaction = default!;
|
||||
[Dependency] private readonly JointSystem _joint = default!;
|
||||
[Dependency] private readonly HandsSystem _hands = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly StandingStateSystem _standingState = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly SharedVirtualItemSystem _virtual = default!;
|
||||
|
||||
private ProtoId<TagPrototype> _grappleTargetId = "GrappleTarget";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GrapplerComponent, StartPullAttemptEvent>(OnPullAttempt);
|
||||
SubscribeLocalEvent<GrapplerComponent, EscapeGrappleAlertEvent>(OnEscapeGrapplerAlert);
|
||||
SubscribeLocalEvent<GrapplerComponent, MobStateChangedEvent>(OnGrapplerStateChanged);
|
||||
|
||||
SubscribeLocalEvent<GrappledComponent, MoveInputEvent>(OnGrappledMove);
|
||||
SubscribeLocalEvent<GrappledComponent, GrappledEscapeDoAfter>(OnEscapeDoAfter);
|
||||
SubscribeLocalEvent<GrappledComponent, EscapeGrappleAlertEvent>(OnEscapeGrappledAlert);
|
||||
SubscribeLocalEvent<GrappledComponent, EntInsertedIntoContainerMessage>(OnCuffsInsertedIntoContainer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates whether a grappler can actually grapple the victim.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity performing the grapple.</param>
|
||||
/// <param name="victim">Intended victim of the grapple.</param>
|
||||
/// <returns>True if the grapple could start, false otherwise.</returns>
|
||||
public bool CanGrapple(Entity<GrapplerComponent?> grappler, EntityUid victim)
|
||||
{
|
||||
if (!Resolve(grappler, ref grappler.Comp))
|
||||
return false;
|
||||
|
||||
if (grappler.Comp.ActiveVictim.HasValue)
|
||||
return false; // Can't grapple more than one target
|
||||
|
||||
if (_gameTiming.CurTime < grappler.Comp.CooldownEnd)
|
||||
return false; // Cooldown on the grapple is not over yet
|
||||
|
||||
if (!HasComp<GrappleTargetComponent>(victim))
|
||||
return false; // Not a valid target
|
||||
|
||||
return _actionBlocker.CanInteract(grappler, victim);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a grapple is currently active on a victim.
|
||||
/// </summary>
|
||||
/// <param name="grappler">The grappler to check.</param>
|
||||
/// <returns>True if there is an ongoing grapple, false otherwise.</returns>
|
||||
public bool IsGrappling(Entity<GrapplerComponent?> grappler)
|
||||
{
|
||||
if (!Resolve(grappler, ref grappler.Comp))
|
||||
return false; // Isn't a grappler, so nothing to do.
|
||||
|
||||
return grappler.Comp.ActiveVictim.HasValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to start grappling a victim, rendering them unable to move and possibly
|
||||
/// removing their ability to use their hands.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity attempting to begin a grapple</param>
|
||||
/// <param name="victim">Entity to be grappled.</param>
|
||||
/// <returns>True if the grapple started, false otherwise.</returns>
|
||||
public bool TryStartGrapple(Entity<GrapplerComponent?> grappler, EntityUid victim)
|
||||
{
|
||||
if (!Resolve(grappler, ref grappler.Comp))
|
||||
return false;
|
||||
|
||||
if (!CanGrapple(grappler, victim))
|
||||
return false;
|
||||
|
||||
if (!_interaction.InRangeUnobstructed(grappler.Owner, victim))
|
||||
return false;
|
||||
|
||||
StartGrapple((grappler, grappler.Comp), victim);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases a victim from a grapple allowing them to move again and returning any
|
||||
/// hands that were disabled.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity, which was performing the grapple.</param>
|
||||
/// <param name="manualRelease">Whether this release is performed by the grappler, or by the grappled.</param>
|
||||
/// <returns>True if the grapple was released, false otherwise.</returns>
|
||||
public bool ReleaseGrapple(Entity<GrapplerComponent?> grappler, bool manualRelease = false)
|
||||
{
|
||||
if (!Resolve(grappler, ref grappler.Comp))
|
||||
return false;
|
||||
|
||||
if (grappler.Comp.ActiveVictim is not { } victim)
|
||||
return false; // Not grappling anything
|
||||
|
||||
if (!TryComp<GrappledComponent>(victim, out var victimComp))
|
||||
return false; // Somehow not a grappled target
|
||||
|
||||
ReleaseGrapple((grappler, grappler.Comp),
|
||||
(victim, victimComp),
|
||||
manualRelease: manualRelease);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles applying the effects of grappling.
|
||||
/// Optionally starts a pulling action.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity starting the grapple.</param>
|
||||
/// <param name="victim">Entity to be grappled.</param>
|
||||
private void StartGrapple(Entity<GrapplerComponent> grappler, EntityUid victim)
|
||||
{
|
||||
// Throw the victim and grappler (if requested) prone
|
||||
_standingState.Down(victim);
|
||||
|
||||
if (grappler.Comp.ProneOnGrapple)
|
||||
_standingState.Down(grappler);
|
||||
|
||||
// Ensure they have the grappled component for handling escapes and blocking movement.
|
||||
EnsureComp<GrappledComponent>(victim, out var grappled);
|
||||
grappled.Grappler = grappler;
|
||||
grappled.EscapeTime = grappler.Comp.EscapeTime;
|
||||
|
||||
// Disable hands if requested
|
||||
DisableHands(grappler!, (victim, grappled));
|
||||
|
||||
// Update the grappler's victim
|
||||
grappler.Comp.ActiveVictim = victim;
|
||||
grappler.Comp.PullJointId = $"grapple-joint-{GetNetEntity(victim)}";
|
||||
Dirty(grappler);
|
||||
|
||||
// Update any movement blocks that the grappler/grappled now have
|
||||
_actionBlocker.UpdateCanMove(grappler);
|
||||
_actionBlocker.UpdateCanMove(victim);
|
||||
|
||||
// Joint the two together so both the grappler and the victim can't be tugged away from one another.
|
||||
_joint.CreateDistanceJoint(grappler, victim, id: grappler.Comp.PullJointId);
|
||||
|
||||
_popup.PopupEntity(
|
||||
Loc.GetString("grapple-start", ("part", grappler.Comp.GrapplingPart), ("victim", victim)),
|
||||
victim,
|
||||
grappler,
|
||||
PopupType.MediumCaution);
|
||||
_popup.PopupEntity(
|
||||
Loc.GetString("grapple-start-victim", ("part", grappler.Comp.GrapplingPart), ("grappler", grappler)),
|
||||
victim,
|
||||
victim,
|
||||
PopupType.MediumCaution);
|
||||
|
||||
_audio.PlayPvs(grappler.Comp.GrappleSound, victim);
|
||||
|
||||
_alerts.ShowAlert(grappler, grappler.Comp.GrappledAlert);
|
||||
_alerts.ShowAlert(victim, grappler.Comp.GrappledAlert);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappler attempts to start pulling an entity.
|
||||
/// If they have an existing target, they will drop them.
|
||||
/// If they do NOT have a target then they will attempt to grapple them if they are in combat mode.
|
||||
/// Will stop the pull attempt if this system handles it via a grapple.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity attempting to start pulling.</param>
|
||||
/// <param name="args">Args for the event, notably the entity being pulled.</param>
|
||||
private void OnPullAttempt(Entity<GrapplerComponent> grappler, ref StartPullAttemptEvent args)
|
||||
{
|
||||
if (grappler.Comp.ActiveVictim.HasValue)
|
||||
{
|
||||
if (ReleaseGrapple(grappler.AsNullable(), manualRelease: true))
|
||||
args.Cancel();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!TryComp<CombatModeComponent>(grappler, out var combatMode) ||
|
||||
!combatMode.IsInCombatMode)
|
||||
return; // Not in harm mode, this is just a regular pull
|
||||
|
||||
if (TryStartGrapple(grappler.AsNullable(), args.Pulled))
|
||||
args.Cancel(); // We've handled it.
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to disable hands as requested by the Grappler's component.
|
||||
/// Disabled hands are stored on the GrappledComponent and will be re-enabled.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity performing the grapple.</param>
|
||||
/// <param name="victim">Victim which has become grappled.</param>
|
||||
private void DisableHands(Entity<GrapplerComponent> grappler, Entity<GrappledComponent> victim)
|
||||
{
|
||||
if (!TryComp<HandsComponent>(victim, out var hands))
|
||||
return; // This victim has no hands
|
||||
|
||||
if (grappler.Comp.HandDisabling == HandDisabling.None)
|
||||
return; // Nothing left to do
|
||||
|
||||
var toBlock = new List<Hand>(2); // Most entities have a maximum of two hands, so default to a list of two hands
|
||||
switch (grappler.Comp.HandDisabling)
|
||||
{
|
||||
case HandDisabling.None:
|
||||
return;
|
||||
case HandDisabling.SingleRandom:
|
||||
var randomHand = _random.Next(0, hands.Count);
|
||||
var handName = hands.SortedHands[randomHand];
|
||||
var handComp = hands.Hands[handName];
|
||||
toBlock.Add(handComp);
|
||||
break;
|
||||
case HandDisabling.SingleActive:
|
||||
var activeHand = _hands.GetActiveHand((victim, hands));
|
||||
if (activeHand != null)
|
||||
toBlock.Add(activeHand!);
|
||||
break;
|
||||
case HandDisabling.All:
|
||||
foreach (var hand in _hands.EnumerateHands(victim, hands))
|
||||
{
|
||||
toBlock.Add(hand);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var hand in toBlock)
|
||||
{
|
||||
if (_virtual.TrySpawnVirtualItemInHand(grappler, victim, out var virtItem, dropOthers: true, hand))
|
||||
{
|
||||
EnsureComp<UnremoveableComponent>(virtItem.Value);
|
||||
victim.Comp.DisabledHands.Add(hand.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to enable hands that were previously disabled,
|
||||
/// as requested by the Grappler's component.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity which was performing grapple.</param>
|
||||
/// <param name="victim">Victim which had become grappled.</param>
|
||||
private void EnableHands(Entity<GrapplerComponent> grappler, Entity<GrappledComponent> victim)
|
||||
{
|
||||
if (!TryComp<HandsComponent>(victim, out var hands))
|
||||
return; // This victim has no hands
|
||||
|
||||
if (grappler.Comp.HandDisabling == HandDisabling.None)
|
||||
return; // Nothing left to do
|
||||
|
||||
_virtual.DeleteInHandsMatching(victim, grappler);
|
||||
|
||||
// Because the virtual items are queued for deletion, but not actually removed from hands yet,
|
||||
// we remove the component that makes them "unremovable", so that other systems like cuffs
|
||||
// can add virtual items immediately.
|
||||
foreach (var handName in victim.Comp.DisabledHands)
|
||||
{
|
||||
if (!_hands.TryGetHand(victim, handName, out var hand, hands))
|
||||
continue;
|
||||
|
||||
if (!hand.HeldEntity.HasValue)
|
||||
continue;
|
||||
|
||||
RemComp<UnremoveableComponent>(hand.HeldEntity.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappled entity attempts to move, and allows them to start
|
||||
/// to wriggling free of the grapple.
|
||||
/// Raises a DoAfter for the user to complete their escape.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Entity attempting to move.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnGrappledMove(Entity<GrappledComponent> grappled, ref MoveInputEvent args)
|
||||
{
|
||||
if (!args.HasDirectionalMovement)
|
||||
return;
|
||||
|
||||
BeginEscapeAttempt(grappled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles starting an escape attempt.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Entity beginning the escape.</param>
|
||||
private void BeginEscapeAttempt(Entity<GrappledComponent> grappled)
|
||||
{
|
||||
if (!TryComp<GrapplerComponent>(grappled.Comp.Grappler, out var grappler))
|
||||
return; // Somehow grappled by a non-grappler?
|
||||
|
||||
var escapeDoAfter = new DoAfterArgs(
|
||||
EntityManager,
|
||||
grappled,
|
||||
grappled.Comp.EscapeTime,
|
||||
new GrappledEscapeDoAfter(),
|
||||
grappled)
|
||||
{
|
||||
BreakOnMove = false,
|
||||
BreakOnDamage = false,
|
||||
NeedHand = true
|
||||
};
|
||||
|
||||
if (!_doAfter.TryStartDoAfter(escapeDoAfter, out var doAfterId))
|
||||
return;
|
||||
|
||||
grappled.Comp.DoAfterId = doAfterId;
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("grapple-start-escaping", ("victim", grappled)),
|
||||
grappled,
|
||||
grappled.Comp.Grappler,
|
||||
PopupType.MediumCaution);
|
||||
_popup.PopupEntity(Loc.GetString("grapple-start-escaping-victim", ("part", grappler.GrapplingPart)),
|
||||
grappled,
|
||||
grappled,
|
||||
PopupType.MediumCaution);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when the escape doafter is successful, which removes the grappling from the entity.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Entity which has finished escaping from the grapple.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnEscapeDoAfter(Entity<GrappledComponent> grappled, ref GrappledEscapeDoAfter args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return; // Was manually cancelled in some way
|
||||
|
||||
if (!TryComp<GrapplerComponent>(grappled.Comp.Grappler, out var grappler))
|
||||
return; // Somehow not a grappler for this entity?
|
||||
|
||||
ReleaseGrapple((grappled.Comp.Grappler, grappler), grappled, manualRelease: false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappled player clicks the grappled alert, beginning an escape attempt.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Grappled player entity which triggered the escape attempt.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnEscapeGrappledAlert(Entity<GrappledComponent> grappled, ref EscapeGrappleAlertEvent args)
|
||||
{
|
||||
BeginEscapeAttempt(grappled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when an entity is inserted into a container on the grappled entity.
|
||||
/// Specifically checks for cuffs being added, which will cause a release of the grapple.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Entity which has had an item inserted into a container.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnCuffsInsertedIntoContainer(Entity<GrappledComponent> grappled, ref EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
if (!TryComp<CuffableComponent>(grappled, out var cuffable))
|
||||
return; // Isn't cuffable so don't need to worry
|
||||
|
||||
if (args.Container.ID != cuffable.Container?.ID)
|
||||
return; // Wasn't inserted into the cuff container
|
||||
|
||||
// This entity is being cuffed, release the grapple and let hands be cuffed properly.
|
||||
ReleaseGrapple(grappled.Comp.Grappler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappler player clicks the grappled alert, beginning an escape attempt.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Grappler player entity which has stopped grappling.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnEscapeGrapplerAlert(Entity<GrapplerComponent> grappler, ref EscapeGrappleAlertEvent args)
|
||||
{
|
||||
ReleaseGrapple(grappler.AsNullable(), manualRelease: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappler enters crit or dies while holding a grappler, which will then release it.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Grappler player entity which has entered crit or death.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnGrapplerStateChanged(Entity<GrapplerComponent> grappler, ref MobStateChangedEvent args)
|
||||
{
|
||||
if (!grappler.Comp.ActiveVictim.HasValue)
|
||||
return; // Not actively grappling anything
|
||||
|
||||
if (args.NewMobState == MobState.Critical ||
|
||||
args.NewMobState == MobState.Dead)
|
||||
{
|
||||
ReleaseGrapple(grappler.AsNullable(), manualRelease: true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles releasing the effects of a grapple from both entities.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Entity performing the grapple.</param>
|
||||
/// <param name="victim">Victim who has escaped or been released from the grapple</param>
|
||||
private void ReleaseGrapple(Entity<GrapplerComponent> grappler,
|
||||
Entity<GrappledComponent> victim,
|
||||
bool manualRelease = false)
|
||||
{
|
||||
// Ensure any jointing is cleaned up
|
||||
if (grappler.Comp.PullJointId != null)
|
||||
{
|
||||
_joint.RemoveJoint(grappler, grappler.Comp.PullJointId);
|
||||
grappler.Comp.PullJointId = null;
|
||||
}
|
||||
|
||||
// Inform the grappler that their victim is now free and they can move, updating the cooldown as well.
|
||||
grappler.Comp.ActiveVictim = null;
|
||||
grappler.Comp.CooldownEnd = _gameTiming.CurTime + grappler.Comp.Cooldown;
|
||||
Dirty(grappler);
|
||||
_actionBlocker.UpdateCanMove(grappler);
|
||||
|
||||
// Clean up the hold on their hands we have
|
||||
EnableHands(grappler, victim);
|
||||
|
||||
// If this was a manul release by the grappler, we should cancel the doafter they have in progress, if any.
|
||||
if (manualRelease)
|
||||
{
|
||||
if (victim.Comp.DoAfterId.HasValue)
|
||||
{
|
||||
_doAfter.Cancel(victim.Comp.DoAfterId.Value);
|
||||
}
|
||||
|
||||
_popup.PopupEntity(
|
||||
Loc.GetString("grapple-manual-release", ("victim", victim), ("part", grappler.Comp.GrapplingPart)),
|
||||
victim,
|
||||
grappler,
|
||||
PopupType.Medium);
|
||||
_popup.PopupEntity(Loc.GetString("grapple-manual-release-victim",
|
||||
("grappler", grappler),
|
||||
("part", grappler.Comp.GrapplingPart)),
|
||||
victim,
|
||||
victim,
|
||||
PopupType.Medium);
|
||||
}
|
||||
else
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("grapple-finished-escaping",
|
||||
("victim", victim),
|
||||
("part", grappler.Comp.GrapplingPart)),
|
||||
victim,
|
||||
grappler,
|
||||
PopupType.MediumCaution);
|
||||
_popup.PopupEntity(
|
||||
Loc.GetString("grapple-finished-escaping-victim", ("part", grappler.Comp.GrapplingPart)),
|
||||
victim,
|
||||
victim,
|
||||
PopupType.MediumCaution);
|
||||
}
|
||||
|
||||
// Cleanup the grappling on the victim
|
||||
RemComp<GrappledComponent>(victim);
|
||||
_actionBlocker.UpdateCanMove(victim); // Must be done AFTER the component is removed.
|
||||
|
||||
// Automatically get the grappler back up
|
||||
if (grappler.Comp.ProneOnGrapple && _standingState.IsDown(grappler))
|
||||
_standingState.Stand(grappler);
|
||||
|
||||
_alerts.ClearAlert(grappler, grappler.Comp.GrappledAlert);
|
||||
_alerts.ClearAlert(victim, grappler.Comp.GrappledAlert);
|
||||
}
|
||||
}
|
||||
|
|
@ -6,21 +6,34 @@ namespace Content.Server._DV.Light;
|
|||
public sealed partial class LightReactiveSystem : SharedLightReactiveSystem
|
||||
{
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
private EntityQuery<PointLightComponent> _lightQuery = default!;
|
||||
|
||||
private readonly HashSet<Entity<PointLightComponent>> _lightsInRange = new();
|
||||
private readonly HashSet<Entity<SharedPointLightComponent>> _validLightsInRange = new();
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_lightQuery = EntityManager.GetEntityQuery<PointLightComponent>();
|
||||
}
|
||||
|
||||
private readonly HashSet<Entity<SharedPointLightComponent>> _validLightsInRange = [];
|
||||
public override HashSet<Entity<SharedPointLightComponent>> GetLights(EntityUid targetEntity)
|
||||
{
|
||||
_lightsInRange.Clear();
|
||||
_lookup.GetEntitiesInRange(Transform(targetEntity).Coordinates, 10f, _lightsInRange);
|
||||
|
||||
var entitiesInRange = _lookup.GetEntitiesInRange(targetEntity, 10f);
|
||||
|
||||
_validLightsInRange.Clear();
|
||||
foreach (var light in _lightsInRange)
|
||||
foreach (var ent in entitiesInRange)
|
||||
{
|
||||
// On the server, we check if it's Enabled OR if netSyncEnabled is false
|
||||
if (!_lightQuery.TryComp(ent, out var comp))
|
||||
continue;
|
||||
// On the server, we check if it's Enabled OR if netSyncEnabled i s false
|
||||
// Because sometimes the server doesn't actually know if it should be enabled or not.
|
||||
// The Client however, can be assumed to always be right.
|
||||
if ((light.Comp.Enabled || !light.Comp.NetSyncEnabled) && !light.Comp.Deleted)
|
||||
_validLightsInRange.Add(new(light.Owner, light.Comp));
|
||||
if (!comp.Enabled && comp.NetSyncEnabled)
|
||||
continue;
|
||||
if (comp.Deleted)
|
||||
continue;
|
||||
|
||||
_validLightsInRange.Add((ent, comp));
|
||||
}
|
||||
return _validLightsInRange;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
// SPDX-FileCopyrightText: 2025 Cojoke
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using Content.Shared._Shitmed.Body.Events;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._Mono.CorticalBorer;
|
||||
|
||||
public sealed class CorticalBorerInfestedSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly CorticalBorerSystem _borer = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, MapInitEvent>(OnInit);
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, ExaminedEvent>(OnExaminedInfested);
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, BodyPartRemovedEvent>(OnBodyPartRemoved);
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, MobStateChangedEvent>(OnStateChange);
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, MindRemovedMessage>(OnMindRemoved);
|
||||
}
|
||||
|
||||
private void OnInit(Entity<CorticalBorerInfestedComponent> infested, ref MapInitEvent args)
|
||||
{
|
||||
infested.Comp.ControlContainer = _container.EnsureContainer<Container>(infested, "ControlContainer");
|
||||
infested.Comp.InfestationContainer = _container.EnsureContainer<Container>(infested, "InfestationContainer");
|
||||
}
|
||||
|
||||
private void OnExaminedInfested(Entity<CorticalBorerInfestedComponent> infected, ref ExaminedEvent args)
|
||||
{
|
||||
if (!args.IsInDetailsRange
|
||||
|| args.Examined != args.Examiner)
|
||||
return;
|
||||
|
||||
if (!infected.Comp.Borer.Comp.ControlingHost)
|
||||
return;
|
||||
|
||||
if (infected.Comp.ControlTimeEnd is { } cte)
|
||||
{
|
||||
var timeRemaining = Math.Floor((cte - _timing.CurTime).TotalSeconds);
|
||||
args.PushMarkup(Loc.GetString("infested-control-examined", ("timeremaining", timeRemaining)));
|
||||
}
|
||||
|
||||
args.PushMarkup(Loc.GetString("cortical-borer-self-examine", ("chempoints", infected.Comp.Borer.Comp.ChemicalPoints)));
|
||||
}
|
||||
|
||||
private void OnStateChange(Entity<CorticalBorerInfestedComponent> infected, ref MobStateChangedEvent args)
|
||||
{
|
||||
if (args.NewMobState != MobState.Dead)
|
||||
return;
|
||||
|
||||
if(infected.Comp.Borer.Comp.ControlingHost)
|
||||
_borer.EndControl(infected.Comp.Borer);
|
||||
}
|
||||
|
||||
private void OnBodyPartRemoved(Entity<CorticalBorerInfestedComponent> infected, ref BodyPartRemovedEvent args)
|
||||
{
|
||||
if (TryComp<BodyPartComponent>(args.Part, out var part) &&
|
||||
part.PartType == BodyPartType.Head)
|
||||
{
|
||||
_borer.EndControl(infected.Comp.Borer);
|
||||
_borer.TryEjectBorer(infected.Comp.Borer);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMindRemoved(Entity<CorticalBorerInfestedComponent> infected, ref MindRemovedMessage args)
|
||||
{
|
||||
if (infected.Comp.Borer.Comp.ControlingHost)
|
||||
{
|
||||
_borer.EndControl(infected.Comp.Borer);
|
||||
_borer.TryEjectBorer(infected.Comp.Borer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
// SPDX-FileCopyrightText: 2025 Cojoke
|
||||
// SPDX-FileCopyrightText: 2025 ark1368
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Medical;
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using Content.Shared._Shitmed.Medical.Surgery;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Popups;
|
||||
|
||||
namespace Content.Server._Mono.CorticalBorer;
|
||||
|
||||
public sealed partial class CorticalBorerSystem
|
||||
{
|
||||
[Dependency] private readonly VomitSystem _vomit = default!;
|
||||
|
||||
private void SubscribeAbilities()
|
||||
{
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalInfestEvent>(OnInfest);
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalInfestDoAfterEvent>(OnInfestDoAfter);
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalEjectEvent>(OnEjectHost);
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalTakeControlEvent>(OnTakeControl);
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalChemMenuActionEvent>(OnChemcialMenu);
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalCheckBloodEvent>(OnCheckBlood);
|
||||
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, CorticalEndControlEvent>(OnEndControl);
|
||||
SubscribeLocalEvent<CorticalBorerInfestedComponent, CorticalLayEggEvent>(OnLayEgg);
|
||||
}
|
||||
|
||||
private void OnChemcialMenu(Entity<CorticalBorerComponent> ent, ref CorticalChemMenuActionEvent args)
|
||||
{
|
||||
if(!TryComp<UserInterfaceComponent>(ent, out var uic))
|
||||
return;
|
||||
|
||||
if (ent.Comp.Host is null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-no-host"), ent, ent, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
_ui.TryToggleUi((ent, uic), CorticalBorerDispenserUiKey.Key, ent);
|
||||
}
|
||||
|
||||
private void OnInfest(Entity<CorticalBorerComponent> ent, ref CorticalInfestEvent args)
|
||||
{
|
||||
var (uid, comp) = ent;
|
||||
var target = args.Target;
|
||||
var targetIdentity = Identity.Entity(target, EntityManager);
|
||||
|
||||
if (comp.Host is not null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-has-host"), uid, uid, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasComp<CorticalBorerInfestedComponent>(target))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-host-already-infested", ("target", targetIdentity)), uid, uid, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
// anything with bloodstream
|
||||
if (!HasComp<BloodstreamComponent>(target))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-invalid-host", ("target", targetIdentity)), uid, uid, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
// target is on sugar for some reason, can't go in there
|
||||
if (!CanUseAbility(ent, target))
|
||||
return;
|
||||
|
||||
var infestAttempt = new InfestHostAttempt();
|
||||
RaiseLocalEvent(target, infestAttempt);
|
||||
|
||||
if (infestAttempt.Cancelled)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-face-covered", ("target", targetIdentity)), uid, uid, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-start-infest", ("target", targetIdentity)), uid, uid, PopupType.Medium);
|
||||
|
||||
var infestArgs = new DoAfterArgs(EntityManager, uid, TimeSpan.FromSeconds(3), new CorticalInfestDoAfterEvent(), uid, target)
|
||||
{
|
||||
DistanceThreshold = 1.5f,
|
||||
BreakOnDamage = true,
|
||||
BreakOnMove = true,
|
||||
BreakOnWeightlessMove = true,
|
||||
AttemptFrequency = AttemptFrequency.StartAndEnd,
|
||||
Hidden = true,
|
||||
};
|
||||
_doAfter.TryStartDoAfter(infestArgs);
|
||||
}
|
||||
|
||||
private void OnInfestDoAfter(Entity<CorticalBorerComponent> ent, ref CorticalInfestDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (args.Args.Target is not { } target)
|
||||
return;
|
||||
|
||||
if (args.Cancelled || HasComp<CorticalBorerInfestedComponent>(target))
|
||||
return;
|
||||
|
||||
InfestTarget(ent, target);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnEjectHost(Entity<CorticalBorerComponent> ent, ref CorticalEjectEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
var (uid, comp) = ent;
|
||||
|
||||
if (comp.Host is null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-no-host"), uid, uid, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanUseAbility(ent, comp.Host.Value))
|
||||
return;
|
||||
|
||||
TryEjectBorer(ent);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnCheckBlood(Entity<CorticalBorerComponent> ent, ref CorticalCheckBloodEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.Host is null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-no-host"), ent, ent, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
TryToggleCheckBlood(ent);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnTakeControl(Entity<CorticalBorerComponent> ent, ref CorticalTakeControlEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (ent.Comp.Host is null)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-no-host"), ent, ent, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
// Host is dead, you can't take control
|
||||
if (TryComp<MobStateComponent>(ent.Comp.Host, out var mobState) &&
|
||||
mobState.CurrentState == MobState.Dead)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-dead-host"), ent, ent, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TryComp<CorticalBorerInfestedComponent>(ent.Comp.Host, out var infestedComp))
|
||||
return;
|
||||
|
||||
if (!CanUseAbility(ent, ent.Comp.Host.Value))
|
||||
return;
|
||||
|
||||
// idk how you would cause this...
|
||||
if (ent.Comp.ControlingHost)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-already-control"), ent, ent, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
TakeControlHost(ent, infestedComp);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnEndControl(Entity<CorticalBorerInfestedComponent> host, ref CorticalEndControlEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
EndControl(host.Comp.Borer);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnLayEgg(Entity<CorticalBorerInfestedComponent> host, ref CorticalLayEggEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
var borer = host.Comp.Borer;
|
||||
|
||||
if (borer.Comp.EggCost > borer.Comp.ChemicalPoints)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-not-enough-chem"), host, host, PopupType.Medium);
|
||||
return;
|
||||
}
|
||||
|
||||
_vomit.Vomit(host, -20, -20); // half as much chem vomit, a lot that is coming up is the egg
|
||||
LayEgg(borer);
|
||||
UpdateChems(borer, -borer.Comp.EggCost);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,390 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
// SPDX-FileCopyrightText: 2025 Cojoke
|
||||
// SPDX-FileCopyrightText: 2025 ScyronX
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Ghost.Roles;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.Medical;
|
||||
using Content.Server.Medical.Components;
|
||||
using Content.Server.Nutrition.Components;
|
||||
using Content.Shared._Mono.CorticalBorer;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Chat; // Einstein Engines - Languages
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.MedicalScanner;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Nutrition.Components; // DeltaV - IngestionBlocker in shared
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.SSDIndicator;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._Mono.CorticalBorer;
|
||||
|
||||
public sealed partial class CorticalBorerSystem : SharedCorticalBorerSystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly BloodstreamSystem _blood = default!;
|
||||
[Dependency] private readonly HealthAnalyzerSystem _analyzer = default!;
|
||||
[Dependency] private readonly DoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
|
||||
[Dependency] private readonly ISharedAdminLogManager _admin = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mind = default!;
|
||||
[Dependency] private readonly IChatManager _chat = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly GhostRoleSystem _ghost = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeAbilities();
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerComponent, ComponentStartup>(OnStartup);
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalBorerDispenserInjectMessage>(OnInjectReagentMessage);
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CorticalBorerDispenserSetInjectAmountMessage>(OnSetInjectAmountMessage);
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, InfestHostAttempt>(OnInfestHostAttempt);
|
||||
SubscribeLocalEvent<CorticalBorerComponent, CheckTargetedSpeechEvent>(OnSpeakEvent);
|
||||
|
||||
SubscribeLocalEvent<CorticalBorerComponent, MindRemovedMessage>(OnMindRemoved);
|
||||
}
|
||||
|
||||
private void OnStartup(Entity<CorticalBorerComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
//add actions
|
||||
foreach (var actionId in ent.Comp.InitialCorticalBorerActions)
|
||||
_actions.AddAction(ent, actionId);
|
||||
|
||||
_alerts.ShowAlert(ent, ent.Comp.ChemicalAlert);
|
||||
UpdateUiState(ent);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var comp in EntityManager.EntityQuery<CorticalBorerComponent>())
|
||||
{
|
||||
if (_timing.CurTime < comp.UpdateTimer)
|
||||
continue;
|
||||
|
||||
comp.UpdateTimer = _timing.CurTime + TimeSpan.FromSeconds(comp.UpdateCooldown);
|
||||
|
||||
if (comp.Host != null)
|
||||
UpdateChems((comp.Owner, comp), comp.ChemicalGenerationRate);
|
||||
}
|
||||
|
||||
foreach (var comp in EntityManager.EntityQuery<CorticalBorerInfestedComponent>())
|
||||
{
|
||||
if (_timing.CurTime >= comp.ControlTimeEnd)
|
||||
EndControl(comp.Borer);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSpeakEvent(Entity<CorticalBorerComponent> ent, ref CheckTargetedSpeechEvent args)
|
||||
{
|
||||
//args.ChatTypeIgnore.Add(InGameICChatType.CollectiveMind); // DeltaV - eradicate language code
|
||||
|
||||
if (ent.Comp.Host.HasValue)
|
||||
{
|
||||
args.Targets.Add(ent);
|
||||
args.Targets.Add(ent.Comp.Host.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateChems(Entity<CorticalBorerComponent> ent, int change)
|
||||
{
|
||||
var (_, comp) = ent;
|
||||
|
||||
if (comp.ChemicalPoints + change >= comp.ChemicalPointCap)
|
||||
comp.ChemicalPoints = comp.ChemicalPointCap;
|
||||
else if (comp.ChemicalPoints + change <= 0)
|
||||
comp.ChemicalPoints = 0;
|
||||
else
|
||||
comp.ChemicalPoints += change;
|
||||
|
||||
if (comp.ChemicalPoints % comp.UiUpdateInterval == 0)
|
||||
UpdateUiState(ent);
|
||||
|
||||
_alerts.ShowAlert(ent, ent.Comp.ChemicalAlert);
|
||||
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
public void OnInfestHostAttempt(Entity<InventoryComponent> entity, ref InfestHostAttempt args)
|
||||
{
|
||||
IngestionBlockerComponent? blocker;
|
||||
|
||||
if (_inventory.TryGetSlotEntity(entity.Owner, "head", out var headUid) &&
|
||||
TryComp(headUid, out blocker) &&
|
||||
blocker.Enabled)
|
||||
{
|
||||
args.Blocker = headUid;
|
||||
args.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to inject the Borer's host with chems
|
||||
/// </summary>
|
||||
public bool TryInjectHost(Entity<CorticalBorerComponent> ent,
|
||||
CorticalBorerChemicalPrototype chemicalPrototype,
|
||||
float chemAmount)
|
||||
{
|
||||
var (uid, comp) = ent;
|
||||
|
||||
// Need a host to inject something
|
||||
if (!comp.Host.HasValue)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-no-host"), uid, uid, PopupType.Medium);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sugar block from injecting stuff
|
||||
if (!CanUseAbility(ent, comp.Host.Value))
|
||||
return false;
|
||||
|
||||
// Make sure you can even hold the amount of chems you need
|
||||
if (chemicalPrototype.Cost > comp.ChemicalPointCap)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-not-enough-chem-storage"), uid, uid, PopupType.Medium);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure you have enough chems
|
||||
if (chemicalPrototype.Cost > comp.ChemicalPoints)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-not-enough-chem"), uid, uid, PopupType.Medium);
|
||||
return false;
|
||||
}
|
||||
|
||||
// no injecting things that don't have blood silly
|
||||
if (!TryComp<BloodstreamComponent>(comp.Host, out var bloodstream))
|
||||
return false;
|
||||
|
||||
var solution = new Solution();
|
||||
solution.AddReagent(chemicalPrototype.Reagent, chemAmount);
|
||||
|
||||
// add the chemicals to the bloodstream of the host
|
||||
if (!_blood.TryAddToChemicals(comp.Host.Value, solution, bloodstream))
|
||||
return false;
|
||||
|
||||
UpdateChems(ent, -((int)chemAmount * chemicalPrototype.Cost));
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnInjectReagentMessage(Entity<CorticalBorerComponent> ent, ref CorticalBorerDispenserInjectMessage message)
|
||||
{
|
||||
CorticalBorerChemicalPrototype? chemProto = null;
|
||||
foreach (var chem in _proto.EnumeratePrototypes<CorticalBorerChemicalPrototype>())
|
||||
{
|
||||
if (chem.Reagent.Equals(message.ChemProtoId))
|
||||
{
|
||||
chemProto = chem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chemProto != null)
|
||||
TryInjectHost(ent, chemProto, ent.Comp.InjectAmount);
|
||||
|
||||
UpdateUiState(ent);
|
||||
}
|
||||
|
||||
private void OnSetInjectAmountMessage(Entity<CorticalBorerComponent> ent, ref CorticalBorerDispenserSetInjectAmountMessage message)
|
||||
{
|
||||
ent.Comp.InjectAmount = message.CorticalBorerDispenserDispenseAmount;
|
||||
UpdateUiState(ent);
|
||||
}
|
||||
|
||||
private List<CorticalBorerDispenserItem> GetAllBorerChemicals(Entity<CorticalBorerComponent> ent)
|
||||
{
|
||||
var clones = new List<CorticalBorerDispenserItem>();
|
||||
foreach (var prototype in _proto.EnumeratePrototypes<CorticalBorerChemicalPrototype>())
|
||||
{
|
||||
if (!_proto.TryIndex(prototype.Reagent, out ReagentPrototype? proto))
|
||||
continue;
|
||||
|
||||
var reagentName = proto.LocalizedName;
|
||||
var reagentId = proto.ID;
|
||||
var cost = prototype.Cost;
|
||||
var amount = ent.Comp.InjectAmount;
|
||||
var chems = ent.Comp.ChemicalPoints;
|
||||
var color = proto.SubstanceColor;
|
||||
|
||||
clones.Add(new CorticalBorerDispenserItem(reagentName,reagentId, cost, amount, chems, color)); // need color and name
|
||||
}
|
||||
|
||||
return clones;
|
||||
}
|
||||
|
||||
private void UpdateUiState(Entity<CorticalBorerComponent> ent)
|
||||
{
|
||||
var chems = GetAllBorerChemicals(ent);
|
||||
|
||||
var state = new CorticalBorerDispenserBoundUserInterfaceState(chems, (int)ent.Comp.InjectAmount);
|
||||
_userInterfaceSystem.SetUiState(ent.Owner, CorticalBorerDispenserUiKey.Key, state);
|
||||
}
|
||||
|
||||
public bool TryToggleCheckBlood(Entity<CorticalBorerComponent> ent)
|
||||
{
|
||||
if(!TryComp<UserInterfaceComponent>(ent, out var uic))
|
||||
return false;
|
||||
|
||||
if (!TryComp<HealthAnalyzerComponent>(ent, out var health))
|
||||
return false;
|
||||
|
||||
_ui.TryToggleUi((ent, uic), HealthAnalyzerUiKey.Key, ent);
|
||||
|
||||
if (health.ScannedEntity is null && ent.Comp.Host.HasValue)
|
||||
OpenCheckBlood(ent, uic);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OpenCheckBlood(Entity<CorticalBorerComponent> ent, UserInterfaceComponent uic)
|
||||
{
|
||||
if (!ent.Comp.Host.HasValue)
|
||||
return;
|
||||
|
||||
if (!TryComp<HealthAnalyzerComponent>(ent, out var health))
|
||||
return;
|
||||
|
||||
if (!_ui.IsUiOpen((ent,uic), HealthAnalyzerUiKey.Key))
|
||||
_ui.OpenUi((ent, uic), HealthAnalyzerUiKey.Key, ent);
|
||||
_analyzer.BeginAnalyzingEntity((ent, health), ent.Comp.Host.Value);
|
||||
}
|
||||
|
||||
public void CloseCheckBlood(Entity<CorticalBorerComponent> ent, UserInterfaceComponent uic)
|
||||
{
|
||||
if (!ent.Comp.Host.HasValue)
|
||||
return;
|
||||
|
||||
if (!TryComp<HealthAnalyzerComponent>(ent, out var health))
|
||||
return;
|
||||
|
||||
if(!health.ScannedEntity.HasValue)
|
||||
return;
|
||||
|
||||
_ui.CloseUi((ent, uic), HealthAnalyzerUiKey.Key, ent);
|
||||
_analyzer.StopAnalyzingEntity((ent, health), health.ScannedEntity.Value);
|
||||
}
|
||||
|
||||
public void TakeControlHost(Entity<CorticalBorerComponent> ent, CorticalBorerInfestedComponent infestedComp)
|
||||
{
|
||||
var (worm, comp) = ent;
|
||||
|
||||
if (comp.Host is not { } host)
|
||||
return;
|
||||
|
||||
// make sure they aren't dead, would throw the worm into a ghost mode and just kill em
|
||||
if (TryComp<MobStateComponent>(ent.Comp.Host, out var mobState) &&
|
||||
mobState.CurrentState == MobState.Dead)
|
||||
return;
|
||||
|
||||
if (TryComp<MindContainerComponent>(host, out var mindContainer) &&
|
||||
mindContainer.HasMind ||
|
||||
HasComp<GhostRoleComponent>(host))
|
||||
infestedComp.ControlTimeEnd = _timing.CurTime + comp.ControlDuration;
|
||||
|
||||
if (_mind.TryGetMind(worm, out var wormMind, out _))
|
||||
infestedComp.BorerMindId = wormMind;
|
||||
|
||||
if (_mind.TryGetMind(host, out var controledMind, out _))
|
||||
{
|
||||
infestedComp.OrigininalMindId = controledMind; // set this var here just in case somehow the mind changes from when the infestation started
|
||||
|
||||
// fish head...
|
||||
var dummy = Spawn("FoodMeatFish", MapCoordinates.Nullspace);
|
||||
_container.Insert(dummy, infestedComp.ControlContainer);
|
||||
|
||||
_mind.TransferTo(controledMind, dummy);
|
||||
}
|
||||
else
|
||||
{
|
||||
infestedComp.OrigininalMindId = null;
|
||||
}
|
||||
|
||||
comp.ControlingHost = true;
|
||||
_mind.TransferTo(wormMind, host);
|
||||
|
||||
if (TryComp<GhostRoleComponent>(worm, out var ghostRole))
|
||||
_ghost.UnregisterGhostRole((worm, ghostRole)); // prevent players from taking the worm role once mind isn't in the worm
|
||||
|
||||
// add the end control and vomit egg action
|
||||
if (_actions.AddAction(host, "ActionEndControlHost") is {} actionEnd)
|
||||
infestedComp.RemoveAbilities.Add(actionEnd);
|
||||
if (comp.CanReproduce &&
|
||||
infestedComp.ControlTimeEnd != null) // you can't lay eggs with something you can control forever
|
||||
{
|
||||
if (_actions.AddAction(host, "ActionLayEggHost") is {} actionLay)
|
||||
infestedComp.RemoveAbilities.Add(actionLay);
|
||||
}
|
||||
|
||||
var str = $"{ToPrettyString(worm)} has taken control over {ToPrettyString(host)}";
|
||||
|
||||
Log.Info(str);
|
||||
_admin.Add(LogType.Mind, LogImpact.High, $"{ToPrettyString(worm)} has taken control over {ToPrettyString(host)}");
|
||||
_chat.SendAdminAlert(str);
|
||||
}
|
||||
|
||||
public void EndControl(Entity<CorticalBorerComponent> worm)
|
||||
{
|
||||
var (uid, comp) = worm;
|
||||
|
||||
if (comp.Host is not { } host)
|
||||
return;
|
||||
|
||||
if (!TryComp<CorticalBorerInfestedComponent>(host, out var infestedComp))
|
||||
return;
|
||||
|
||||
// not controlling anyone
|
||||
if (!comp.ControlingHost)
|
||||
return;
|
||||
|
||||
comp.ControlingHost = false;
|
||||
|
||||
// remove all the actions set to remove
|
||||
foreach (var ability in infestedComp.RemoveAbilities)
|
||||
{
|
||||
_actions.RemoveAction(host, ability);
|
||||
}
|
||||
infestedComp.RemoveAbilities = new(); // clear out the list
|
||||
|
||||
if (TryComp<GhostRoleComponent>(worm, out var ghostRole))
|
||||
_ghost.RegisterGhostRole((worm, ghostRole)); // re-enable the ghost role after you return to the body
|
||||
|
||||
// Return everyone to their own bodies
|
||||
if (!TerminatingOrDeleted(infestedComp.BorerMindId))
|
||||
_mind.TransferTo(infestedComp.BorerMindId, infestedComp.Borer);
|
||||
if (!TerminatingOrDeleted(infestedComp.OrigininalMindId) && infestedComp.OrigininalMindId.HasValue)
|
||||
_mind.TransferTo(infestedComp.OrigininalMindId.Value, host);
|
||||
|
||||
infestedComp.ControlTimeEnd = null;
|
||||
_container.CleanContainer(infestedComp.ControlContainer);
|
||||
}
|
||||
|
||||
private void OnMindRemoved(Entity<CorticalBorerComponent> ent, ref MindRemovedMessage args)
|
||||
{
|
||||
if (!ent.Comp.ControlingHost)
|
||||
TryEjectBorer(ent); // No storing them in hosts if you don't have a soul
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Alert.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for an alert which simply displays a generic number over a texture.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class GenericCounterAlertComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The width, in pixels, of an individual glyph, accounting for the space between glyphs.
|
||||
/// A 3 pixel wide glyph with one pixel of space between it and the next would be a width of 4.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int GlyphWidth = 6;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the numbers should be centered on the glyph or just follow a static position.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool CenterGlyph = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether leading zeros should be hidden.
|
||||
/// If true, "005" would display as "5".
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool HideLeadingZeroes = true;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the alert sprite.
|
||||
/// Used to calculate offsets.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Vector2i AlertSize = new(32, 32);
|
||||
|
||||
/// <summary>
|
||||
/// Digits that can be displayed by the alert, represented by their sprite layer.
|
||||
/// Order defined corresponds to the digit it affects. 1st defined will affect 1st digit, 2nd affect 2nd digit and so on.
|
||||
/// In this case ones would be on layer "1", tens on layer "10" etc.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<string> DigitKeys = new()
|
||||
{
|
||||
"1",
|
||||
"10",
|
||||
"100",
|
||||
"1000",
|
||||
"10000"
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event raised to gather the amount the alert will display.
|
||||
/// </summary>
|
||||
/// <param name="Alert">The alert which is currently requesting an update.</param>
|
||||
/// <param name="Amount">The number to display on the alert.</param>
|
||||
[ByRefEvent]
|
||||
public record struct GetGenericAlertCounterAmountEvent(AlertPrototype Alert, int? Amount = null)
|
||||
{
|
||||
public bool Handled => Amount.HasValue;
|
||||
}
|
||||
|
|
@ -48,6 +48,12 @@ public sealed partial class GenericStatusEffect : EntityEffect
|
|||
{
|
||||
statusSys.TryAddStatusEffect(args.TargetEntity, Key, TimeSpan.FromSeconds(time), Refresh, Component);
|
||||
}
|
||||
// Begin Mono Changes - just add status without component
|
||||
else if (Type == StatusEffectMetabolismType.Add)
|
||||
{
|
||||
statusSys.TryAddStatusEffect(args.TargetEntity, Key, TimeSpan.FromSeconds(time), Refresh);
|
||||
}
|
||||
// End Mono Changes - just add status without component
|
||||
else if (Type == StatusEffectMetabolismType.Remove)
|
||||
{
|
||||
statusSys.TryRemoveTime(args.TargetEntity, Key, TimeSpan.FromSeconds(time));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared._DV.Mind; // DeltaV
|
||||
using Content.Shared._EE.Silicon.Components; // Goobstation
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
|
|
@ -159,6 +160,13 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||
if (_net.IsClient)
|
||||
return;
|
||||
|
||||
// Begin DeltaV Addition
|
||||
var ev = new ShowSSDIndicatorEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
if (ev.Hidden)
|
||||
return;
|
||||
// End DeltaV Addition
|
||||
|
||||
var dead = _mobState.IsDead(uid);
|
||||
var mind = CompOrNull<MindComponent>(mindContainer.Mind);
|
||||
var hasUserId = mind?.UserId;
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ public partial class MobStateSystem
|
|||
//unused
|
||||
break;
|
||||
case MobState.Critical:
|
||||
_standing.Stand(target);
|
||||
//_standing.Stand(target); // DeltaV - Remove Redundancy
|
||||
break;
|
||||
case MobState.Dead:
|
||||
RemComp<CollisionWakeComponent>(target);
|
||||
_standing.Stand(target);
|
||||
//_standing.Stand(target); // DeltaV - Remove Redundancy
|
||||
break;
|
||||
case MobState.Invalid:
|
||||
//unused
|
||||
|
|
@ -102,7 +102,9 @@ public partial class MobStateSystem
|
|||
switch (state)
|
||||
{
|
||||
case MobState.Alive:
|
||||
_standing.Stand(target);
|
||||
if (!TryComp(target, out BuckleComponent? buckle)
|
||||
|| !buckle.Buckled) // DeltaV - Stop buckled mobs from standing up.
|
||||
_standing.Stand(target);
|
||||
_appearance.SetData(target, MobStateVisuals.State, MobState.Alive);
|
||||
break;
|
||||
case MobState.Critical:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using Content.Shared._DV.Abilities.Psionics;
|
||||
using Content.Shared._DV.Mind;
|
||||
using Content.Shared.Interaction.Events;
|
||||
|
||||
namespace Content.Shared.Abilities.Psionics;
|
||||
|
|
@ -9,6 +11,7 @@ public abstract class SharedTelegnosisPowerSystem : EntitySystem
|
|||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<TelegnosticProjectionComponent, InteractionAttemptEvent>(OnInteractionAttempt);
|
||||
SubscribeLocalEvent<TelegnosisPowerComponent, ShowSSDIndicatorEvent>(OnShowSSDIndicator);
|
||||
}
|
||||
|
||||
private void OnInteractionAttempt(Entity<TelegnosticProjectionComponent> ent, ref InteractionAttemptEvent args)
|
||||
|
|
@ -16,4 +19,11 @@ public abstract class SharedTelegnosisPowerSystem : EntitySystem
|
|||
// no astrally stealing someones shoes
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private void OnShowSSDIndicator(Entity<TelegnosisPowerComponent> entity, ref ShowSSDIndicatorEvent args)
|
||||
{
|
||||
if (!TryComp<MindSwappedComponent>(entity, out var mindSwapped) || !HasComp<TelegnosticProjectionComponent>(mindSwapped.OriginalEntity))
|
||||
return; // Only hide if currently projecting
|
||||
args.Hidden = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
|
||||
namespace Content.Shared.Abilities.Psionics
|
||||
{
|
||||
[RegisterComponent, Access(typeof(SharedTelegnosisPowerSystem))]
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedTelegnosisPowerSystem))]
|
||||
public sealed partial class TelegnosisPowerComponent : Component
|
||||
{
|
||||
[DataField("prototype")]
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public enum RevenantVisuals : byte
|
|||
}
|
||||
|
||||
[NetSerializable, Serializable]
|
||||
public enum RevenantVisualLayers : byte
|
||||
public enum RevenantVisualLayers : byte // DeltaV - kept for impstation rev compatibility
|
||||
{
|
||||
Digit1,
|
||||
Digit2,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class FracturedFormBodyComponent : Component;
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Content.Shared.Cloning;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Content.Shared.DoAfter;
|
||||
|
||||
namespace Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class FracturedFormPowerComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntProtoId FracturedFormActionId = "ActionFracturedForm";
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? FracturedFormActionEntity;
|
||||
[DataField]
|
||||
public DoAfterId? DoAfter;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CloningSettingsPrototype> CopyNaked = "CloningPod";
|
||||
[DataField]
|
||||
public ProtoId<CloningSettingsPrototype> CopyClothed = "Antag";
|
||||
[DataField]
|
||||
public ProtoId<JobPrototype> VisitorJob = "Passenger";
|
||||
[DataField]
|
||||
public ProtoId<JobPrototype>? NakedJob = null; // Scary null, but we explicitely want no job for naked spawns.
|
||||
[DataField]
|
||||
public TimeSpan NextSwap = TimeSpan.MaxValue;
|
||||
[DataField]
|
||||
public float ManualSwapTime = 5f;
|
||||
[DataField]
|
||||
public bool SleepWarned = false;
|
||||
[DataField]
|
||||
public List<EntityUid> Bodies { get; set; } = new();
|
||||
[DataField]
|
||||
public SoundSpecifier SwapSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg")
|
||||
{
|
||||
Params = AudioParams.Default.WithVariation(0.05f)
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class MindSwappedComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid OriginalEntity = default!;
|
||||
[DataField]
|
||||
public EntProtoId? MindSwapReturnActionId = "ActionMindSwapReturn";
|
||||
|
||||
[DataField]
|
||||
public EntityUid? MindSwapReturnActionEntity;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using Content.Shared._DV.Mind;
|
||||
|
||||
namespace Content.Shared._DV.Abilities.Psionics;
|
||||
|
||||
public abstract class SharedFracturedFormPowerSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<FracturedFormBodyComponent, ShowSSDIndicatorEvent>(OnShowSSDIndicator);
|
||||
}
|
||||
|
||||
private void OnShowSSDIndicator(Entity<FracturedFormBodyComponent> entity, ref ShowSSDIndicatorEvent args)
|
||||
{
|
||||
if (HasComp<FracturedFormPowerComponent>(entity))
|
||||
return;
|
||||
args.Hidden = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
namespace Content.Shared.Actions.Events;
|
||||
|
||||
public sealed partial class FracturedFormPowerActionEvent : InstantActionEvent;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using Content.Shared._DV.Grappling.EntitySystems;
|
||||
|
||||
namespace Content.Shared._DV.Grappling.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Marks this entity as a valid target for grapples.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[Access(typeof(SharedGrapplingSystem))]
|
||||
public sealed partial class GrappleTargetComponent : Component;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using Content.Shared._DV.Grappling.EntitySystems;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._DV.Grappling.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Marks this entity as having been grappled.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(SharedGrapplingSystem))]
|
||||
public sealed partial class GrappledComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The entity which is performing the grapple.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid Grappler = EntityUid.Invalid;
|
||||
|
||||
/// <summary>
|
||||
/// How much time is required to escape.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan EscapeTime = TimeSpan.FromSeconds(15);
|
||||
|
||||
/// <summary>
|
||||
/// The in-progress DoAfter, if any.
|
||||
/// Used to cancel the doAfter if the grappler manually releases their victim.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public DoAfterId? DoAfterId = null;
|
||||
|
||||
/// <summary>
|
||||
/// A list of all hands, if any, that have been disabled as part of the grapple
|
||||
/// via a virtual item.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<string> DisabledHands = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a player manually clicks the grappled icon to begin attempting to escape.
|
||||
/// </summary>
|
||||
public sealed partial class EscapeGrappleAlertEvent : BaseAlertEvent;
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
using Content.Shared._DV.Grappling.EntitySystems;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared._DV.Grappling.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Marks this entity as a grappler.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
[Access(typeof(SharedGrapplingSystem))]
|
||||
public sealed partial class GrapplerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// How much time is required to escape a grapple from this entity.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan EscapeTime = TimeSpan.FromSeconds(15);
|
||||
|
||||
/// <summary>
|
||||
/// The sound to play when the grapple action is successful on a target.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier GrappleSound = new SoundPathSpecifier("/Audio/_DV/Grappling/grapple_action.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// Whether this entity can move by itself while grappling.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool CanMoveWhileGrappling = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this entity should also lay prone when grappling.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool ProneOnGrapple = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether grapples from this entity should disable no, a random, or all hands of the victim.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HandDisabling HandDisabling = HandDisabling.None;
|
||||
|
||||
/// <summary>
|
||||
/// What localized string is to be used for the body part in the grapple.
|
||||
/// I.e. Jaws, Hands, Claws, etc.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public LocId GrapplingPart;
|
||||
|
||||
/// <summary>
|
||||
/// The entity, if any, which this unit is grappling.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public EntityUid? ActiveVictim = null;
|
||||
|
||||
/// <summary>
|
||||
/// Cooldown for grappling to apply at the moment the grapple is broken.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan Cooldown = TimeSpan.FromSeconds(5);
|
||||
|
||||
/// <summary>
|
||||
/// Time when the cooldown for the grapple will be over.
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
|
||||
public TimeSpan CooldownEnd;
|
||||
|
||||
/// <summary>
|
||||
/// Which alert to show when a victim is grappled.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> GrappledAlert = "Grappled";
|
||||
|
||||
/// <summary>
|
||||
/// The joint ID used between the grappler and victim.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public string? PullJointId = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether hands should be disabled by the grappling.
|
||||
/// </summary>
|
||||
public enum HandDisabling
|
||||
{
|
||||
None, // No hands to be disabled.
|
||||
SingleRandom, // A single hand is disabled at random from available hands.
|
||||
SingleActive, // The active hand is disabled.
|
||||
All, // All hands are disabled.
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
using Content.Shared._DV.Grappling.Components;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Standing;
|
||||
|
||||
namespace Content.Shared._DV.Grappling.EntitySystems;
|
||||
|
||||
/// <summary>
|
||||
/// Shared logic for grapplers.
|
||||
/// Enables some prediction of events and updates.
|
||||
/// </summary>
|
||||
public abstract partial class SharedGrapplingSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GrapplerComponent, UpdateCanMoveEvent>(OnCanMoveQuery);
|
||||
SubscribeLocalEvent<GrapplerComponent, AttackAttemptEvent>(OnAttemptAttack);
|
||||
|
||||
SubscribeLocalEvent<GrappledComponent, StandAttemptEvent>(OnGrappledStand);
|
||||
SubscribeLocalEvent<GrappledComponent, UpdateCanMoveEvent>(OnGrappleCanMoveQuery);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappler attempts to move.
|
||||
/// Potentially disallows movement of the grappler when they are grappling a target.
|
||||
/// </summary>
|
||||
/// <param name="grappler">The grappling entity.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnCanMoveQuery(Entity<GrapplerComponent> grappler, ref UpdateCanMoveEvent args)
|
||||
{
|
||||
if (grappler.Comp.CanMoveWhileGrappling)
|
||||
return; // This entity can always move.
|
||||
|
||||
if (grappler.Comp.ActiveVictim.HasValue)
|
||||
args.Cancel(); // Can't move while grappling
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappled target attempts to stand and blocks it.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Grappled entity attempting to stand.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnGrappledStand(Entity<GrappledComponent> grappled, ref StandAttemptEvent args)
|
||||
{
|
||||
args.Cancel(); // Can't stand while being grappled
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappled target attempts to move and blocks it.
|
||||
/// </summary>
|
||||
/// <param name="grappled">Grappled entity attempting to move.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnGrappleCanMoveQuery(Entity<GrappledComponent> grappled, ref UpdateCanMoveEvent args)
|
||||
{
|
||||
args.Cancel(); // Can't move while grappled
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles when a grappler attempts to attack an entity.
|
||||
/// If they have an active victim, they will not be able to attack because their body
|
||||
/// is currently being used in the grapple.
|
||||
/// </summary>
|
||||
/// <param name="grappler">Grappler attempting to attack an entity.</param>
|
||||
/// <param name="args">Args for the event.</param>
|
||||
private void OnAttemptAttack(Entity<GrapplerComponent> grappler, ref AttackAttemptEvent args)
|
||||
{
|
||||
if (grappler.Comp.ActiveVictim.HasValue)
|
||||
args.Cancel(); // You cannot attack while grappling
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._DV.Grappling.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a player attempts to wriggle from a grapple.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class GrappledEscapeDoAfter : SimpleDoAfterEvent;
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
using Content.Shared.Mind.Components;
|
||||
|
||||
namespace Content.Shared.Mind;
|
||||
|
||||
public partial class SharedMindSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Set whether or not to show examine information about the mind. Used to obscure if a mind is SSD or not.
|
||||
/// </summary>
|
||||
/// <param name="uid">Entity to set the mind examine info for.</param>
|
||||
/// <param name="showExamineInfo">True to show examine information, false to hide it.</param>
|
||||
public void ShowExamineInfo(EntityUid uid, bool showExamineInfo)
|
||||
{
|
||||
if (!TryComp<MindContainerComponent>(uid, out var mindContainer))
|
||||
return;
|
||||
|
||||
mindContainer.ShowExamineInfo = showExamineInfo;
|
||||
Dirty(uid, mindContainer);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
namespace Content.Shared._DV.Mind;
|
||||
|
||||
[ByRefEvent]
|
||||
public record struct ShowSSDIndicatorEvent(bool Hidden = false);
|
||||
|
|
@ -14,3 +14,6 @@ public sealed partial class MassSleepDoAfterEvent : SimpleDoAfterEvent;
|
|||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class PsionicEruptionDoAfterEvent : SimpleDoAfterEvent;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class FracturedFormDoAfterEvent : SimpleDoAfterEvent;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,109 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
// SPDX-FileCopyrightText: 2025 Cojoke
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class CorticalBorerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Host of this Borer
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public EntityUid? Host = null;
|
||||
|
||||
/// <summary>
|
||||
/// Current number of chemical points this Borer has, used to level up and buy chems
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[AutoNetworkedField]
|
||||
[DataField]
|
||||
public int ChemicalPoints = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Chemicals added every second WHILE IN A HOST
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public int ChemicalGenerationRate = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Max Chemicals that can be held
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public int ChemicalPointCap = 250;
|
||||
|
||||
/// <summary>
|
||||
/// Reagent injection amount
|
||||
/// </summary>
|
||||
public int InjectAmount = 10;
|
||||
|
||||
/// <summary>
|
||||
/// At what interval does the chem ui update
|
||||
/// </summary>
|
||||
public int UiUpdateInterval = 5; // every 6 to prevent constant update on cap
|
||||
|
||||
/// <summary>
|
||||
/// The max duration you can take control of your host
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public TimeSpan ControlDuration = TimeSpan.FromSeconds(40);
|
||||
|
||||
/// <summary>
|
||||
/// Cooldown between chem regen events.
|
||||
/// </summary>
|
||||
public TimeSpan UpdateTimer = TimeSpan.Zero;
|
||||
public float UpdateCooldown = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// Can this borer make more
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public bool CanReproduce = true;
|
||||
|
||||
/// <summary>
|
||||
/// What does it vomit out of its mouth when it lays an egg
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public string EggProto = "CorticalBorerEgg";
|
||||
|
||||
/// <summary>
|
||||
/// cost to lay an egg... will not update ability desc if changed
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public int EggCost = 200;
|
||||
|
||||
[DataField]
|
||||
public bool ControlingHost;
|
||||
|
||||
[DataField]
|
||||
public ComponentRegistry? AddOnInfest;
|
||||
|
||||
[DataField]
|
||||
public ComponentRegistry? RemoveOnInfest;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> ChemicalAlert = "Chemicals";
|
||||
|
||||
public readonly List<EntProtoId> InitialCorticalBorerActions = new()
|
||||
{
|
||||
"ActionCorticalBorerInfest",
|
||||
"ActionCorticalBorerEject",
|
||||
"ActionCorticalBorerChemMenu",
|
||||
"ActionCheckBlood",
|
||||
"ActionControlHost",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
// SPDX-FileCopyrightText: 2025 Cojoke
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class CorticalBorerInfestedComponent : Robust.Shared.GameObjects.Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Borer in the person
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public Entity<CorticalBorerComponent> Borer = new();
|
||||
|
||||
/// <summary>
|
||||
/// Container for borer
|
||||
/// </summary>
|
||||
public Container InfestationContainer = new();
|
||||
|
||||
/// <summary>
|
||||
/// is the person under the borer's control
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan? ControlTimeEnd;
|
||||
|
||||
[ViewVariables]
|
||||
public EntityUid? OrigininalMindId;
|
||||
|
||||
[ViewVariables]
|
||||
public EntityUid BorerMindId;
|
||||
|
||||
/// <summary>
|
||||
/// Where the mind gets hidden when the worm takes control
|
||||
/// </summary>
|
||||
public Container ControlContainer;
|
||||
|
||||
/// <summary>
|
||||
/// Abilities to be removed once host gets control back
|
||||
/// </summary>
|
||||
public List<EntityUid> RemoveAbilities = new();
|
||||
}
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class SurgeryCorticalBorerConditionComponent : Robust.Shared.GameObjects.Component;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class SurgeryStepRemoveCorticalBorerComponent : Component { }
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared.Actions;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
public sealed partial class CorticalInfestEvent : EntityTargetActionEvent { }
|
||||
public sealed partial class CorticalEjectEvent : InstantActionEvent { }
|
||||
public sealed partial class CorticalChemMenuActionEvent : InstantActionEvent {}
|
||||
public sealed partial class CorticalCheckBloodEvent : InstantActionEvent {}
|
||||
public sealed partial class CorticalTakeControlEvent : InstantActionEvent {}
|
||||
public sealed partial class CorticalEndControlEvent : InstantActionEvent {}
|
||||
public sealed partial class CorticalLayEggEvent : InstantActionEvent {}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared.DoAfter;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed partial class CorticalInfestDoAfterEvent : SimpleDoAfterEvent { }
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
[Prototype("borerChemical")]
|
||||
public sealed partial class CorticalBorerChemicalPrototype : IPrototype
|
||||
{
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Chemical cost per u of reagent
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int Cost { get; set; } = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Reagent to inject into host
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string Reagent { get; set; } = "";
|
||||
}
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
// SPDX-FileCopyrightText: 2025 Coenx-flex
|
||||
// SPDX-FileCopyrightText: 2025 Cojoke
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
using System.Linq;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Body.Systems;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.MedicalScanner;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Coordinates;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
|
||||
namespace Content.Shared._Mono.CorticalBorer;
|
||||
|
||||
public partial class SharedCorticalBorerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedBodySystem _bodySystem = default!;
|
||||
[Dependency] private readonly StatusEffectsSystem _statusEffects = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly ISerializationManager _serManager = default!;
|
||||
[Dependency] private readonly DamageableSystem _damage = default!;
|
||||
[Dependency] protected readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] protected readonly SharedUserInterfaceSystem _ui = default!;
|
||||
[Dependency] protected readonly SharedActionsSystem _actions = default!;
|
||||
[Dependency] protected readonly SharedContainerSystem _container = default!;
|
||||
|
||||
public bool CanUseAbility(Entity<CorticalBorerComponent> ent, EntityUid target)
|
||||
{
|
||||
if (_statusEffects.HasStatusEffect(target,
|
||||
"CorticalBorerProtection")) // hardcoded the status effect because...
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("cortical-borer-sugar-block"), ent.Owner, ent.Owner, PopupType.Medium);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void InfestTarget(Entity<CorticalBorerComponent> ent, EntityUid target)
|
||||
{
|
||||
var (uid, comp) = ent;
|
||||
|
||||
// Make sure the infected person is infected right
|
||||
var infestedComp = EnsureComp<CorticalBorerInfestedComponent>(target);
|
||||
|
||||
// Make sure they get into the target
|
||||
if (!_container.Insert(uid, infestedComp.InfestationContainer))
|
||||
{
|
||||
RemCompDeferred<CorticalBorerInfestedComponent>(target); // oh no it didn't work somehow so remove the comp you just added...
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the Borer
|
||||
infestedComp.Borer = ent;
|
||||
comp.Host = target;
|
||||
|
||||
if (comp.AddOnInfest is not null)
|
||||
{
|
||||
foreach (var (key, compReg) in comp.AddOnInfest)
|
||||
{
|
||||
var compType = compReg.Component.GetType();
|
||||
if (HasComp(ent, compType))
|
||||
continue;
|
||||
|
||||
var newComp = (Component) _serManager.CreateCopy(compReg.Component, notNullableOverride: true);
|
||||
EntityManager.AddComponent(ent, newComp, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.RemoveOnInfest is not null)
|
||||
{
|
||||
foreach (var (key, compReg) in comp.RemoveOnInfest)
|
||||
RemCompDeferred(ent, compReg.Component.GetType());
|
||||
}
|
||||
|
||||
if (TryComp<DamageableComponent>(ent, out var damComp))
|
||||
_damage.SetAllDamage(ent, damComp, 0);
|
||||
}
|
||||
|
||||
public bool TryEjectBorer(Entity<CorticalBorerComponent> ent)
|
||||
{
|
||||
var (uid, comp) = ent;
|
||||
|
||||
if (ent.Comp.Host is not { } host)
|
||||
return false;
|
||||
|
||||
// Make sure they get out of the host
|
||||
if (!_container.TryRemoveFromContainer(uid))
|
||||
return false;
|
||||
|
||||
// close all the UIs that relate to host
|
||||
if (TryComp<UserInterfaceComponent>(ent, out var uic))
|
||||
{
|
||||
_ui.CloseUi((ent.Owner,uic), HealthAnalyzerUiKey.Key);
|
||||
_ui.CloseUi((ent.Owner,uic), CorticalBorerDispenserUiKey.Key);
|
||||
}
|
||||
|
||||
RemCompDeferred<CorticalBorerInfestedComponent>(ent.Comp.Host.Value);
|
||||
ent.Comp.Host = null;
|
||||
|
||||
if (comp.RemoveOnInfest is not null)
|
||||
{
|
||||
foreach (var (key, compReg) in comp.RemoveOnInfest)
|
||||
{
|
||||
var compType = compReg.Component.GetType();
|
||||
if (HasComp(ent, compType))
|
||||
continue;
|
||||
|
||||
var newComp = (Component) _serManager.CreateCopy(compReg.Component, notNullableOverride: true);
|
||||
EntityManager.AddComponent(ent, newComp, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.AddOnInfest is not null)
|
||||
{
|
||||
foreach (var (key, compReg) in comp.AddOnInfest)
|
||||
RemCompDeferred(ent, compReg.Component.GetType());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void LayEgg(Entity<CorticalBorerComponent> ent)
|
||||
{
|
||||
if (ent.Comp.Host is not { } host)
|
||||
return;
|
||||
|
||||
if (ent.Comp.EggProto is not {} egg)
|
||||
return;
|
||||
|
||||
var coordinates = _transform.ToMapCoordinates(host.ToCoordinates());
|
||||
var spawnedEgg = Spawn(egg, coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class InfestHostAttempt : CancellableEntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The equipment that is blocking the entrance
|
||||
/// </summary>
|
||||
public EntityUid? Blocker = null;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CorticalBorerDispenserUiKey
|
||||
{
|
||||
Key
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CorticalBorerDispenserSetInjectAmountMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly int CorticalBorerDispenserDispenseAmount;
|
||||
|
||||
public CorticalBorerDispenserSetInjectAmountMessage(int amount)
|
||||
{
|
||||
CorticalBorerDispenserDispenseAmount = amount;
|
||||
}
|
||||
|
||||
public CorticalBorerDispenserSetInjectAmountMessage(String s)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case "1":
|
||||
CorticalBorerDispenserDispenseAmount = 1;
|
||||
break;
|
||||
case "5":
|
||||
CorticalBorerDispenserDispenseAmount = 5;
|
||||
break;
|
||||
case "10":
|
||||
CorticalBorerDispenserDispenseAmount = 10;
|
||||
break;
|
||||
case "15":
|
||||
CorticalBorerDispenserDispenseAmount = 15;
|
||||
break;
|
||||
case "20":
|
||||
CorticalBorerDispenserDispenseAmount = 20;
|
||||
break;
|
||||
case "25":
|
||||
CorticalBorerDispenserDispenseAmount = 25;
|
||||
break;
|
||||
case "30":
|
||||
CorticalBorerDispenserDispenseAmount = 30;
|
||||
break;
|
||||
case "50":
|
||||
CorticalBorerDispenserDispenseAmount = 50;
|
||||
break;
|
||||
case "100":
|
||||
CorticalBorerDispenserDispenseAmount = 100;
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Cannot convert the string `{s}` into a valid DispenseAmount");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CorticalBorerDispenserInjectMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly string ChemProtoId;
|
||||
|
||||
public CorticalBorerDispenserInjectMessage(string proto)
|
||||
{
|
||||
ChemProtoId = proto;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CorticalBorerDispenserBoundUserInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public readonly List<CorticalBorerDispenserItem> DisList;
|
||||
|
||||
public readonly int SelectedDispenseAmount;
|
||||
public CorticalBorerDispenserBoundUserInterfaceState(List<CorticalBorerDispenserItem> disList, int dispenseAmount)
|
||||
{
|
||||
DisList = disList;
|
||||
SelectedDispenseAmount = dispenseAmount;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CorticalBorerDispenserItem(string reagentName, string reagentId, int cost, int amount, int chems, Color reagentColor)
|
||||
{
|
||||
public string ReagentName = reagentName;
|
||||
public string ReagentId = reagentId;
|
||||
public int Cost = cost;
|
||||
public int Amount = amount;
|
||||
public int Chems = chems;
|
||||
public Color ReagentColor = reagentColor;
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ using Content.Shared.Popups;
|
|||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
using System.Linq;
|
||||
using Content.Shared._Mono.CorticalBorer; // Mono
|
||||
|
||||
namespace Content.Shared._Shitmed.Medical.Surgery;
|
||||
|
||||
|
|
@ -47,6 +48,7 @@ public abstract partial class SharedSurgerySystem
|
|||
|
||||
SubSurgery<SurgeryTendWoundsEffectComponent>(OnTendWoundsStep, OnTendWoundsCheck);
|
||||
SubSurgery<SurgeryStepCavityEffectComponent>(OnCavityStep, OnCavityCheck);
|
||||
SubSurgery<SurgeryStepRemoveCorticalBorerComponent>(OnCorticalBorerRemovalStep, OnCorticalBorerRemovalCheck); // Mono
|
||||
SubSurgery<SurgeryAddPartStepComponent>(OnAddPartStep, OnAddPartCheck);
|
||||
SubSurgery<SurgeryAffixPartStepComponent>(OnAffixPartStep, OnAffixPartCheck);
|
||||
SubSurgery<SurgeryRemovePartStepComponent>(OnRemovePartStep, OnRemovePartCheck);
|
||||
|
|
@ -427,6 +429,21 @@ public abstract partial class SharedSurgerySystem
|
|||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
// Begin Mono Changes - borer
|
||||
private void OnCorticalBorerRemovalStep(Entity<SurgeryStepRemoveCorticalBorerComponent> ent, ref SurgeryStepEvent args)
|
||||
{
|
||||
if (TryComp<CorticalBorerInfestedComponent>(args.Body, out var infested) &&
|
||||
infested.InfestationContainer.ContainedEntities.Count != 0)
|
||||
_corticalBorer.TryEjectBorer(infested.Borer);
|
||||
}
|
||||
|
||||
private void OnCorticalBorerRemovalCheck(Entity<SurgeryStepRemoveCorticalBorerComponent> ent, ref SurgeryStepCompleteCheckEvent args)
|
||||
{
|
||||
if (HasComp<CorticalBorerInfestedComponent>(args.Body))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
// End Mono Changes - borer
|
||||
|
||||
private void OnAddPartStep(Entity<SurgeryAddPartStepComponent> ent, ref SurgeryStepEvent args)
|
||||
{
|
||||
if (!TryComp(args.Surgery, out SurgeryPartRemovedConditionComponent? removedComp))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Linq;
|
||||
using Content.Shared._Mono.CorticalBorer; // Mono
|
||||
using Content.Shared._Shitmed.Medical.Surgery.Conditions;
|
||||
using Content.Shared._Shitmed.Medical.Surgery.Effects.Complete;
|
||||
using Content.Shared.Body.Systems;
|
||||
|
|
@ -50,6 +51,7 @@ public abstract partial class SharedSurgerySystem : EntitySystem
|
|||
[Dependency] private readonly StandingStateSystem _standing = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!; // DeltaV: surgery can operate through some clothing
|
||||
[Dependency] private readonly SharedCorticalBorerSystem _corticalBorer = default!; // Mono
|
||||
|
||||
/// <summary>
|
||||
/// Cache of all surgery prototypes' singleton entities.
|
||||
|
|
@ -87,6 +89,7 @@ public abstract partial class SharedSurgerySystem : EntitySystem
|
|||
SubscribeLocalEvent<SurgeryPartComponentConditionComponent, SurgeryValidEvent>(OnPartComponentConditionValid);
|
||||
SubscribeLocalEvent<SurgeryOrganOnAddConditionComponent, SurgeryValidEvent>(OnOrganOnAddConditionValid);
|
||||
//SubscribeLocalEvent<SurgeryRemoveLarvaComponent, SurgeryCompletedEvent>(OnRemoveLarva);
|
||||
SubscribeLocalEvent<SurgeryCorticalBorerConditionComponent, SurgeryValidEvent>(OnCorticalBorerValid); // Mono
|
||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypesReloaded);
|
||||
|
||||
InitializeSteps();
|
||||
|
|
@ -161,6 +164,15 @@ public abstract partial class SharedSurgerySystem : EntitySystem
|
|||
args.Cancelled = true;
|
||||
}*/
|
||||
|
||||
// Begin Mono Changes - borer
|
||||
private void OnCorticalBorerValid(Entity<SurgeryCorticalBorerConditionComponent> ent, ref SurgeryValidEvent args)
|
||||
{
|
||||
if (!HasComp<CorticalBorerInfestedComponent>(args.Body) ||
|
||||
!HasComp<IncisionOpenComponent>(args.Part))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
// End Mono Changes - borer
|
||||
|
||||
private void OnBodyComponentConditionValid(Entity<SurgeryBodyComponentConditionComponent> ent, ref SurgeryValidEvent args)
|
||||
{
|
||||
var present = true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
- files: ["grapple_action.ogg"]
|
||||
license: "CC-BY-SA-3.0"
|
||||
copyright: "Made for DeltaV by BarryNorfolk"
|
||||
source: "https://github.com/BarryNorfolk"
|
||||
Binary file not shown.
|
|
@ -1,102 +1,4 @@
|
|||
Entries:
|
||||
- author: ewokswagger
|
||||
changes:
|
||||
- message: Paramedics will now start with 15tc (down from 16)
|
||||
type: Tweak
|
||||
id: 1246
|
||||
time: '2025-04-12T02:24:53.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3416
|
||||
- author: boogiebogus
|
||||
changes:
|
||||
- message: Revised juggernaut suit sprites, as well as its reverse engineered counterpart.
|
||||
type: Tweak
|
||||
id: 1247
|
||||
time: '2025-04-12T02:42:26.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3364
|
||||
- author: erhardsteinhauer
|
||||
changes:
|
||||
- message: The Vulcan, Energy Gun, Ceremonial rifle and the Jackdaw now have proper
|
||||
sprites when in the back.
|
||||
type: Fix
|
||||
- message: The Vulcan and Jackdaw now have wielded sprites.
|
||||
type: Fix
|
||||
id: 1248
|
||||
time: '2025-04-12T02:45:31.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3405
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: Merged last 2 weeks changes from upstream.
|
||||
type: Add
|
||||
id: 1249
|
||||
time: '2025-04-12T14:46:26.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3394
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: Fixed operating on animals not making surgical tools dirty.
|
||||
type: Fix
|
||||
- message: Fixed held non-surgical items becoming dirty during surgery.
|
||||
type: Fix
|
||||
id: 1250
|
||||
time: '2025-04-12T14:52:21.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3424
|
||||
- author: HTMLSystem
|
||||
changes:
|
||||
- message: Added jumpskirt versions of the casual atmos jumpsuit and botanist overalls.
|
||||
Find them in the uniform printer and loadouts!
|
||||
type: Add
|
||||
- message: Added recipes for the senior bartender outfits in the uniform printer!
|
||||
type: Add
|
||||
id: 1251
|
||||
time: '2025-04-13T02:09:18.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3399
|
||||
- author: sowelipililimute
|
||||
changes:
|
||||
- message: Robotics can now print IPC chasses that can receive a brain and limbs
|
||||
type: Add
|
||||
- message: IPCs do not feel pain in surgery anymore
|
||||
type: Add
|
||||
- message: MMIs can now be inserted into IPC chasses
|
||||
type: Add
|
||||
id: 1252
|
||||
time: '2025-04-13T10:27:42.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3418
|
||||
- author: Toby222
|
||||
changes:
|
||||
- message: Disabled mob pushing for the time being
|
||||
type: Remove
|
||||
id: 1253
|
||||
time: '2025-04-13T15:00:57.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3443
|
||||
- author: Quanteey
|
||||
changes:
|
||||
- message: Medical masks can now be found in surgeon lockers and made in the medical
|
||||
techfab!
|
||||
type: Tweak
|
||||
id: 1254
|
||||
time: '2025-04-13T22:47:05.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3391
|
||||
- author: Solaris7518
|
||||
changes:
|
||||
- message: Resprited a variety of objects that are commonly used by medical! Medical
|
||||
mains rejoice!
|
||||
type: Add
|
||||
id: 1255
|
||||
time: '2025-04-13T22:55:53.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3420
|
||||
- author: Field Command
|
||||
changes:
|
||||
- message: Reworked security on Pebble, alongside some other changes.
|
||||
type: Tweak
|
||||
id: 1256
|
||||
time: '2025-04-13T23:51:41.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3440
|
||||
- author: Radezolid
|
||||
changes:
|
||||
- message: Now the tape recorder is able to be printed at every departamental TechFab.
|
||||
type: Tweak
|
||||
id: 1257
|
||||
time: '2025-04-14T12:08:32.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3454
|
||||
- author: Blackdutchie
|
||||
changes:
|
||||
- message: Slimes can now digest and metabolize food, drinks, medicine, and other
|
||||
|
|
@ -4183,3 +4085,107 @@
|
|||
id: 1745
|
||||
time: '2025-10-13T18:57:32.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4509
|
||||
- author: EmberAstra
|
||||
changes:
|
||||
- message: Fixed the criminal records computer board being called "security records"
|
||||
type: Fix
|
||||
- message: Fixed robotic arms (and other automation machines) icons in the circuit
|
||||
lathe.
|
||||
type: Fix
|
||||
- message: Fixed unholy water's guidebook description.
|
||||
type: Fix
|
||||
id: 1746
|
||||
time: '2025-10-14T13:39:59.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4511
|
||||
- author: TehFlaminTaco
|
||||
changes:
|
||||
- message: Added a new psionic ability, "Fractured Form"
|
||||
type: Add
|
||||
id: 1747
|
||||
time: '2025-10-14T19:42:43.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4506
|
||||
- author: TehFlaminTaco
|
||||
changes:
|
||||
- message: Held items such as PDAs and Flashlights now count as light sources as
|
||||
they were supposed to.
|
||||
type: Fix
|
||||
- message: Diona no-longer take 4 times the intended damage in darkness
|
||||
type: Fix
|
||||
id: 1748
|
||||
time: '2025-10-15T09:37:17.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4525
|
||||
- author: kotobdev
|
||||
changes:
|
||||
- message: Reworded the asakim >CONFISCATE objective for clarity.
|
||||
type: Tweak
|
||||
id: 1749
|
||||
time: '2025-10-15T15:58:02.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4528
|
||||
- author: leonardo-dabepis
|
||||
changes:
|
||||
- message: "Added four paintings by Belgian surrealist painter Ren\xE9 Magritte"
|
||||
type: Add
|
||||
id: 1750
|
||||
time: '2025-10-16T04:02:06.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3732
|
||||
- author: BarryNorfolk
|
||||
changes:
|
||||
- message: Added ability for Laika to grapple ne'er-do-wells with her jaws, grabbing
|
||||
in combat mode will throw them to the floor!
|
||||
type: Add
|
||||
id: 1751
|
||||
time: '2025-10-16T04:52:35.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4157
|
||||
- author: kotobdev
|
||||
changes:
|
||||
- message: Cortical Borers have been ported from Monolith, check Minor Antagonists
|
||||
in the guidebook for more information. Remember to not listen to the voices
|
||||
in your head.
|
||||
type: Add
|
||||
id: 1752
|
||||
time: '2025-10-16T05:11:24.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4466
|
||||
- author: SirWarock
|
||||
changes:
|
||||
- message: Most Cryochemicals now evenly heal 7 damage of their respective type!
|
||||
type: Tweak
|
||||
- message: Necrosol has been buffed to even heal your emotional damage, as well
|
||||
as every other damage type!
|
||||
type: Tweak
|
||||
- message: Prometheum and Ichor now evenly heal!
|
||||
type: Tweak
|
||||
- message: The infamous Pyrogenics also warmed up to evenly heal!
|
||||
type: Tweak
|
||||
- message: The Cryogenics guidebookpage has been updated!
|
||||
type: Tweak
|
||||
id: 1753
|
||||
time: '2025-10-16T05:21:56.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4455
|
||||
- author: TehFlaminTaco
|
||||
changes:
|
||||
- message: Fractured Form bodies no-longer get stuck when left too long
|
||||
type: Fix
|
||||
id: 1754
|
||||
time: '2025-10-16T05:54:33.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4530
|
||||
- author: SirWarock
|
||||
changes:
|
||||
- message: Buckled Patients do not stand up after recovering from critical state!
|
||||
type: Tweak
|
||||
id: 1755
|
||||
time: '2025-10-16T09:04:22.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4316
|
||||
- author: Stop-Signs
|
||||
changes:
|
||||
- message: Added the Rhino Industrial hardsuit, a unique suit for logistics officers.
|
||||
type: Add
|
||||
id: 1756
|
||||
time: '2025-10-16T13:47:45.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/3911
|
||||
- author: Vapetastic-Gaming
|
||||
changes:
|
||||
- message: SUBMARINE RETURNS TO DELTA-V
|
||||
type: Add
|
||||
id: 1757
|
||||
time: '2025-10-18T16:26:03.0000000+00:00'
|
||||
url: https://github.com/DeltaV-Station/Delta-v/pull/4497
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
ent-CriminalRecordsComputerCircuitboard = security records computer board
|
||||
.desc = A computer printed circuit board for a security records computer.
|
||||
# DeltaV - Was security records computer board
|
||||
ent-CriminalRecordsComputerCircuitboard = criminal records computer board
|
||||
.desc = A computer printed circuit board for a criminal records computer.
|
||||
|
||||
ent-StationRecordsComputerCircuitboard = employment records computer board
|
||||
.desc = A computer printed circuit board for a employment records computer.
|
||||
|
|
|
|||
|
|
@ -83,3 +83,8 @@ eruption-warning-window-prompt-text-part = You feel a strong pressure building u
|
|||
eruption-warning-window-acknowledge-button = I Understand
|
||||
|
||||
telegnosis-power-ssd = { CAPITALIZE(POSS-ADJ($ent)) } eyes are unfocused and darting around, as if trying to see something that isn't there.
|
||||
|
||||
fractured-form-nobodies = You have no alternate forms to switch to!
|
||||
fractured-form-sleepy = You feel very sleepy... You should find somewhere to rest.
|
||||
fractured-form-ssd = { CAPITALIZE(SUBJECT($ent)) } { CONJUGATE-BE($ent) } in a deep sleep. { CAPITALIZE(POSS-ADJ($ent)) } eyes seem to be darting around as if dreaming.
|
||||
fractured-form-examine-self = You feel a strange connection to { OBJECT($ent) }.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ alerts-vow-silence-desc-delta = You have taken a vow forbidding verbal communica
|
|||
|
||||
alerts-vow-broken-desc-delta = You've broken your vows to Mimes everywhere. You can speak, but you've lost your powers for at least 5 entire minutes!!! Click to try and retake your vow.
|
||||
|
||||
alerts-grappled-name = [color=yellow]Grappled[/color]
|
||||
alerts-grappled-desc = You're [color=yellow]grappled[/color] and cannot move, your hands may be bound.
|
||||
|
||||
alerts-light-level-dark-name = Darkness
|
||||
alerts-light-level-dark-desc = You are in an area with very low light.
|
||||
alerts-light-level-neutral-name = Dim Light
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
grapple-start = Your {LOC($part)} clamp down on {$victim}!
|
||||
grapple-start-victim = The {$grappler}'s {LOC($part)} clamps down on you, throwing you to the floor!
|
||||
|
||||
grapple-start-escaping = {THE($victim)} is attempting to get free!
|
||||
grapple-start-escaping-victim = You start trying to escape from their {LOC($part)}!
|
||||
|
||||
grapple-manual-release = You gently release {$victim} from your {LOC($part)}.
|
||||
grapple-manual-release-victim = {THE($grappler)} releases you from their {LOC($part)}.
|
||||
|
||||
grapple-finished-escaping = {$victim} has escaped from your {LOC($part)}!
|
||||
grapple-finished-escaping-victim = You escape from their {LOC($part)}!
|
||||
|
||||
grapple-part-hands = hands
|
||||
grapple-part-jaws = jaws
|
||||
grapple-part-claws = claws
|
||||
|
|
@ -13,3 +13,4 @@ steal-target-groups-engineering-techfab-circuitboard = engineering techfab's cir
|
|||
steal-target-groups-logistics-techfab-circuitboard = logistics techfab's circuitboard
|
||||
steal-target-groups-service-techfab-circuitboard = service techfab's circuitboard
|
||||
steal-target-groups-epistemics-techfab-circuitboard = epistemics techfab's circuitboard
|
||||
steal-target-groups-hardsuit-rhino = logistics officer's rhino hardsuit
|
||||
|
|
|
|||
|
|
@ -40,3 +40,6 @@ construction-graph-tag-hoodie = hoodie
|
|||
|
||||
# Ancient books
|
||||
construction-graph-tag-ancientbook = Damaged Ancient Book
|
||||
|
||||
# Weapons
|
||||
construction-graph-tag-silversword = silver sword
|
||||
|
|
|
|||
|
|
@ -9,3 +9,6 @@ tool-quality-censer-tool-name = Censer
|
|||
|
||||
tool-quality-restoration-name = Restoring
|
||||
tool-quality-restoration-tool-name = Restoration Kit
|
||||
|
||||
tool-quality-bible-name = Blessing
|
||||
tool-quality-bible-tool-name = Bible
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
alerts-borer-chemical-name = Chemicals
|
||||
alerts-borer-chemical-desc = Chemicals made in your body, used for your abilities.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
## Infest Messages
|
||||
cortical-borer-has-host = You already have a host.
|
||||
cortical-borer-host-already-infested = {THE($target)} is already infested.
|
||||
cortical-borer-invalid-host = {THE($target)} is not a valid host.
|
||||
cortical-borer-face-covered = {THE($target)}'s face is covered.
|
||||
cortical-borer-headless = {THE($target)} does not have a head!
|
||||
cortical-borer-start-infest = You begin to crawl into {THE($target)}.
|
||||
|
||||
## Generic messages
|
||||
cortical-borer-no-host = You do not have a host.
|
||||
cortical-borer-dead-host = Your host is dead.
|
||||
cortical-borer-not-enough-chem = You do not have enough chemicals.
|
||||
cortical-borer-not-enough-chem-storage = You cannot hold enough chemicals.
|
||||
cortical-borer-sugar-block = You taste something sweet.
|
||||
|
||||
## Control messages
|
||||
cortical-borer-already-control = You are already controlling your host.
|
||||
cortical-borer-vomit = {$name} vomits out a {$egg}!
|
||||
|
||||
## UI
|
||||
cortical-borer-dispenser-window-cost = {$cost} chemicals
|
||||
cortical-borer-ghostrole-name = Cortical Borer
|
||||
cortical-borer-ghostrole-desc = A space worm with the sole purpose in life to enter peoples heads and lay its eggs.
|
||||
|
||||
## Examine Text
|
||||
infested-control-examined = You have [color=#d842fc]{$timeremaining}[/color] seconds left controlling this body.
|
||||
cortical-borer-self-examine = You have [color=#d842fc]{$chempoints}[/color] chemicals.
|
||||
|
|
@ -0,0 +1 @@
|
|||
surgery-popup-step-SurgeryStepRemoveCorticalBorer = {$user} is removing the Cortical Borer from {$target}'s {$part}!
|
||||
|
|
@ -1,6 +1,17 @@
|
|||
meta:
|
||||
format: 6
|
||||
postmapinit: false
|
||||
format: 7
|
||||
category: Grid
|
||||
engineVersion: 262.0.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 10/05/2025 22:51:52
|
||||
entityCount: 2351
|
||||
maps: []
|
||||
grids:
|
||||
- 1
|
||||
orphans:
|
||||
- 1
|
||||
nullspace: []
|
||||
tilemap:
|
||||
0: Space
|
||||
14: FloorBar
|
||||
|
|
@ -31,52 +42,52 @@ entities:
|
|||
chunks:
|
||||
-1,0:
|
||||
ind: -1,0
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAABNQAAAAADNQAAAAABTwAAAAADTwAAAAAATwAAAAADTwAAAAABXgAAAAACPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAAANQAAAAAANQAAAAABTwAAAAAATwAAAAACXgAAAAADTwAAAAAAXgAAAAADPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACTwAAAAABTwAAAAABTwAAAAABTwAAAAACTwAAAAABXgAAAAACTwAAAAADXgAAAAABTwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACTwAAAAACTwAAAAABTwAAAAAATwAAAAAATwAAAAADXgAAAAACTwAAAAABTwAAAAACTwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACXgAAAAAAXgAAAAADXgAAAAADTwAAAAAAXgAAAAACXgAAAAAAXgAAAAAAXgAAAAADXgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACTwAAAAAATwAAAAACTwAAAAACTwAAAAADTwAAAAAAXgAAAAABTwAAAAACTwAAAAADTwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABTwAAAAADTwAAAAAATwAAAAABTwAAAAAATwAAAAABXgAAAAAATwAAAAACXgAAAAACXgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAACNQAAAAACNQAAAAAATwAAAAACTwAAAAAAXgAAAAADTwAAAAACXgAAAAAAIAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAfgAAAAAANQAAAAACTwAAAAACTwAAAAADTwAAAAAATwAAAAADXgAAAAADIAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAADTwAAAAACIAAAAAACIAAAAAADIAAAAAAAXgAAAAACIAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAATwAAAAABIAAAAAADIAAAAAABIAAAAAABTwAAAAACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAABTwAAAAAAIAAAAAACIAAAAAADIAAAAAADXgAAAAAAIAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAATwAAAAADIAAAAAADIAAAAAABIAAAAAAAXgAAAAACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAATwAAAAABIAAAAAAAIAAAAAACIAAAAAABTwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAIAAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAA
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUAAAAAAQA1AAAAAAMANQAAAAABAE8AAAAAAwBPAAAAAAAATwAAAAADAE8AAAAAAQBeAAAAAAIAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAA1AAAAAAAANQAAAAAAADUAAAAAAQBPAAAAAAAATwAAAAACAF4AAAAAAwBPAAAAAAAAXgAAAAADAD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAIATwAAAAABAE8AAAAAAQBPAAAAAAEATwAAAAACAE8AAAAAAQBeAAAAAAIATwAAAAADAF4AAAAAAQBPAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAE8AAAAAAgBPAAAAAAEATwAAAAAAAE8AAAAAAABPAAAAAAMAXgAAAAACAE8AAAAAAQBPAAAAAAIATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAgBeAAAAAAAAXgAAAAADAF4AAAAAAwBPAAAAAAAAXgAAAAACAF4AAAAAAABeAAAAAAAAXgAAAAADAF4AAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAIATwAAAAAAAE8AAAAAAgBPAAAAAAIATwAAAAADAE8AAAAAAABeAAAAAAEATwAAAAACAE8AAAAAAwBPAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAE8AAAAAAwBPAAAAAAAATwAAAAABAE8AAAAAAABPAAAAAAEAXgAAAAAAAE8AAAAAAgBeAAAAAAIAXgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAA1AAAAAAIANQAAAAACADUAAAAAAABPAAAAAAIATwAAAAAAAF4AAAAAAwBPAAAAAAIAXgAAAAAAACAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAH4AAAAAAAA1AAAAAAIATwAAAAACAE8AAAAAAwBPAAAAAAAATwAAAAADAF4AAAAAAwAgAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAANQAAAAADAE8AAAAAAgAgAAAAAAIAIAAAAAADACAAAAAAAABeAAAAAAIAIAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUAAAAAAABPAAAAAAEAIAAAAAADACAAAAAAAQAgAAAAAAEATwAAAAACACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1AAAAAAEATwAAAAAAACAAAAAAAgAgAAAAAAMAIAAAAAADAF4AAAAAAAAgAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAAAE8AAAAAAwAgAAAAAAMAIAAAAAABACAAAAAAAABeAAAAAAIAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUAAAAAAABPAAAAAAEAIAAAAAAAACAAAAAAAgAgAAAAAAEATwAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAACAAAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAA==
|
||||
version: 7
|
||||
0,-1:
|
||||
ind: 0,-1
|
||||
tiles: TwAAAAAATwAAAAAATwAAAAADTwAAAAABTwAAAAADTwAAAAAATwAAAAADTwAAAAABXgAAAAADTwAAAAABXgAAAAADTwAAAAACTwAAAAADNQAAAAABfgAAAAAAfgAAAAAAXgAAAAADXgAAAAAAXgAAAAAAXgAAAAABXgAAAAABXgAAAAADXgAAAAACXgAAAAACXgAAAAADXgAAAAABXgAAAAABTwAAAAACTwAAAAACNQAAAAAANQAAAAADNQAAAAABTwAAAAACTwAAAAADTwAAAAAATwAAAAACTwAAAAAATwAAAAABTwAAAAACTwAAAAABTwAAAAADTwAAAAADXgAAAAABTwAAAAACTwAAAAABTwAAAAAATwAAAAABTwAAAAAATwAAAAABTwAAAAABTwAAAAABTwAAAAADTwAAAAAATwAAAAACTwAAAAAATwAAAAABTwAAAAADTwAAAAABXgAAAAADTwAAAAABTwAAAAAATwAAAAABTwAAAAACTwAAAAABXgAAAAADXgAAAAABXgAAAAADXgAAAAAAXgAAAAACXgAAAAABXgAAAAABXgAAAAADXgAAAAABXgAAAAABXgAAAAABXgAAAAAATwAAAAAAXgAAAAAAXgAAAAAAXgAAAAADTwAAAAACTwAAAAABTwAAAAACTwAAAAABTwAAAAACTwAAAAACTwAAAAAATwAAAAAATwAAAAABTwAAAAABXgAAAAACTwAAAAABTwAAAAACTwAAAAACTwAAAAACTwAAAAAATwAAAAACXgAAAAABXgAAAAABXgAAAAADXgAAAAAAXgAAAAAATwAAAAACTwAAAAABXgAAAAACTwAAAAAAXgAAAAADTwAAAAADTwAAAAACTwAAAAAATwAAAAADTwAAAAADcQAAAAACcQAAAAAAcQAAAAAAcQAAAAABcQAAAAADcQAAAAAAcQAAAAACcQAAAAABXgAAAAACTwAAAAABXgAAAAACTwAAAAABTwAAAAACNQAAAAAANQAAAAACNQAAAAABcQAAAAABcQAAAAADcQAAAAABcQAAAAAAcQAAAAABcQAAAAADcQAAAAADcQAAAAAAXgAAAAACTwAAAAAATwAAAAABTwAAAAADTwAAAAABNQAAAAAANQAAAAABNQAAAAABcQAAAAACcQAAAAAAUAAAAAAAUAAAAAAAUAAAAAAAcQAAAAADcQAAAAAAcQAAAAADTwAAAAAATwAAAAACXgAAAAADTwAAAAABTwAAAAACNQAAAAAANQAAAAABNQAAAAADcQAAAAADcQAAAAABTwAAAAAATwAAAAAATwAAAAADcQAAAAADcQAAAAABcQAAAAACTwAAAAAATwAAAAADXgAAAAABTwAAAAADTwAAAAACTwAAAAADTwAAAAADTwAAAAADcQAAAAAAcQAAAAADTwAAAAAATwAAAAAATwAAAAABcQAAAAADcQAAAAADcQAAAAABTwAAAAACTwAAAAADXgAAAAADTwAAAAADTwAAAAAATwAAAAADTwAAAAAATwAAAAACXgAAAAACXgAAAAACXgAAAAACXgAAAAACXgAAAAADXgAAAAAAXgAAAAABTwAAAAADXgAAAAABTwAAAAABXgAAAAACXgAAAAABTwAAAAAAXgAAAAADXgAAAAADXgAAAAACDgAAAAACDgAAAAACDgAAAAADDgAAAAADDgAAAAABDgAAAAAADgAAAAADDgAAAAADTwAAAAACTwAAAAACXgAAAAADTwAAAAACTwAAAAACTwAAAAABTwAAAAABTwAAAAABDgAAAAADDgAAAAADDgAAAAAADgAAAAADDgAAAAACDgAAAAACDgAAAAADDgAAAAABTwAAAAAATwAAAAADXgAAAAACTwAAAAACTwAAAAACTwAAAAADTwAAAAACTwAAAAADPwAAAAAAPwAAAAAADgAAAAABDgAAAAABDgAAAAACDgAAAAAADgAAAAACTwAAAAABTwAAAAADTwAAAAACXgAAAAAATwAAAAAATwAAAAADNQAAAAABNQAAAAACNQAAAAAA
|
||||
version: 6
|
||||
tiles: TwAAAAAAAE8AAAAAAABPAAAAAAMATwAAAAABAE8AAAAAAwBPAAAAAAAATwAAAAADAE8AAAAAAQBeAAAAAAMATwAAAAABAF4AAAAAAwBPAAAAAAIATwAAAAADADUAAAAAAQB+AAAAAAAAfgAAAAAAAF4AAAAAAwBeAAAAAAAAXgAAAAAAAF4AAAAAAQBeAAAAAAEAXgAAAAADAF4AAAAAAgBeAAAAAAIAXgAAAAADAF4AAAAAAQBeAAAAAAEATwAAAAACAE8AAAAAAgA1AAAAAAAANQAAAAADADUAAAAAAQBPAAAAAAIATwAAAAADAE8AAAAAAABPAAAAAAIATwAAAAAAAE8AAAAAAQBPAAAAAAIATwAAAAABAE8AAAAAAwBPAAAAAAMAXgAAAAABAE8AAAAAAgBPAAAAAAEATwAAAAAAAE8AAAAAAQBPAAAAAAAATwAAAAABAE8AAAAAAQBPAAAAAAEATwAAAAADAE8AAAAAAABPAAAAAAIATwAAAAAAAE8AAAAAAQBPAAAAAAMATwAAAAABAF4AAAAAAwBPAAAAAAEATwAAAAAAAE8AAAAAAQBPAAAAAAIATwAAAAABAF4AAAAAAwBeAAAAAAEAXgAAAAADAF4AAAAAAABeAAAAAAIAXgAAAAABAF4AAAAAAQBeAAAAAAMAXgAAAAABAF4AAAAAAQBeAAAAAAEAXgAAAAAAAE8AAAAAAABeAAAAAAAAXgAAAAAAAF4AAAAAAwBPAAAAAAIATwAAAAABAE8AAAAAAgBPAAAAAAEATwAAAAACAE8AAAAAAgBPAAAAAAAATwAAAAAAAE8AAAAAAQBPAAAAAAEAXgAAAAACAE8AAAAAAQBPAAAAAAIATwAAAAACAE8AAAAAAgBPAAAAAAAATwAAAAACAF4AAAAAAQBeAAAAAAEAXgAAAAADAF4AAAAAAABeAAAAAAAATwAAAAACAE8AAAAAAQBeAAAAAAIATwAAAAAAAF4AAAAAAwBPAAAAAAMATwAAAAACAE8AAAAAAABPAAAAAAMATwAAAAADAHEAAAAAAgBxAAAAAAAAcQAAAAAAAHEAAAAAAQBxAAAAAAMAcQAAAAAAAHEAAAAAAgBxAAAAAAEAXgAAAAACAE8AAAAAAQBeAAAAAAIATwAAAAABAE8AAAAAAgA1AAAAAAAANQAAAAACADUAAAAAAQBxAAAAAAEAcQAAAAADAHEAAAAAAQBxAAAAAAAAcQAAAAABAHEAAAAAAwBxAAAAAAMAcQAAAAAAAF4AAAAAAgBPAAAAAAAATwAAAAABAE8AAAAAAwBPAAAAAAEANQAAAAAAADUAAAAAAQA1AAAAAAEAcQAAAAACAHEAAAAAAABQAAAAAAAAUAAAAAAAAFAAAAAAAABxAAAAAAMAcQAAAAAAAHEAAAAAAwBPAAAAAAAATwAAAAACAF4AAAAAAwBPAAAAAAEATwAAAAACADUAAAAAAAA1AAAAAAEANQAAAAADAHEAAAAAAwBxAAAAAAEATwAAAAAAAE8AAAAAAABPAAAAAAMAcQAAAAADAHEAAAAAAQBxAAAAAAIATwAAAAAAAE8AAAAAAwBeAAAAAAEATwAAAAADAE8AAAAAAgBPAAAAAAMATwAAAAADAE8AAAAAAwBxAAAAAAAAcQAAAAADAE8AAAAAAABPAAAAAAAATwAAAAABAHEAAAAAAwBxAAAAAAMAcQAAAAABAE8AAAAAAgBPAAAAAAMAXgAAAAADAE8AAAAAAwBPAAAAAAAATwAAAAADAE8AAAAAAABPAAAAAAIAXgAAAAACAF4AAAAAAgBeAAAAAAIAXgAAAAACAF4AAAAAAwBeAAAAAAAAXgAAAAABAE8AAAAAAwBeAAAAAAEATwAAAAABAF4AAAAAAgBeAAAAAAEATwAAAAAAAF4AAAAAAwBeAAAAAAMAXgAAAAACAA4AAAAAAgAOAAAAAAIADgAAAAADAA4AAAAAAwAOAAAAAAEADgAAAAAAAA4AAAAAAwAOAAAAAAMATwAAAAACAE8AAAAAAgBeAAAAAAMATwAAAAACAE8AAAAAAgBPAAAAAAEATwAAAAABAE8AAAAAAQAOAAAAAAMADgAAAAADAA4AAAAAAAAOAAAAAAMADgAAAAACAA4AAAAAAgAOAAAAAAMADgAAAAABAE8AAAAAAABPAAAAAAMAXgAAAAACAE8AAAAAAgBPAAAAAAIATwAAAAADAE8AAAAAAgBPAAAAAAMAPwAAAAAAAD8AAAAAAAAOAAAAAAEADgAAAAABAA4AAAAAAgAOAAAAAAAADgAAAAACAE8AAAAAAQBPAAAAAAMATwAAAAACAF4AAAAAAABPAAAAAAAATwAAAAADADUAAAAAAQA1AAAAAAIANQAAAAAAAA==
|
||||
version: 7
|
||||
-1,-1:
|
||||
ind: -1,-1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAATwAAAAAATwAAAAABXgAAAAACTwAAAAAAXgAAAAABTwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAACNQAAAAAANQAAAAACTwAAAAAATwAAAAACXgAAAAACXgAAAAAAXgAAAAAAXgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABTwAAAAADTwAAAAAATwAAAAACTwAAAAACTwAAAAAAXgAAAAADTwAAAAADTwAAAAADTwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACTwAAAAABTwAAAAABTwAAAAACTwAAAAACTwAAAAABXgAAAAADTwAAAAAATwAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABXgAAAAAAXgAAAAAAXgAAAAABTwAAAAADXgAAAAACXgAAAAADXgAAAAACXgAAAAACXgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADTwAAAAAATwAAAAABTwAAAAACTwAAAAADTwAAAAACXgAAAAADTwAAAAADTwAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAATwAAAAACTwAAAAACTwAAAAAATwAAAAADTwAAAAAAXgAAAAADTwAAAAACXgAAAAADTwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAAANQAAAAAANQAAAAADTwAAAAACTwAAAAADXgAAAAADTwAAAAAAXgAAAAABcQAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAACNQAAAAADNQAAAAADTwAAAAACTwAAAAACTwAAAAABTwAAAAABXgAAAAACcQAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAADNQAAAAADNQAAAAABTwAAAAAATwAAAAACXgAAAAABTwAAAAABTwAAAAAAcQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAXgAAAAABXgAAAAABXgAAAAADTwAAAAADTwAAAAAAXgAAAAADTwAAAAABTwAAAAADcQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABTwAAAAABTwAAAAAATwAAAAADTwAAAAACTwAAAAACXgAAAAABTwAAAAACTwAAAAABcQAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACXgAAAAABXgAAAAAAXgAAAAAATwAAAAACXgAAAAABXgAAAAADTwAAAAACTwAAAAABTwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADTwAAAAACTwAAAAABTwAAAAADTwAAAAACTwAAAAAAXgAAAAABTwAAAAAATwAAAAADDgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACTwAAAAACTwAAAAACTwAAAAADTwAAAAADTwAAAAACXgAAAAAATwAAAAADTwAAAAABDgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAACNQAAAAABNQAAAAAATwAAAAAATwAAAAAAXgAAAAADTwAAAAAATwAAAAABTwAAAAAD
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAAAE8AAAAAAABPAAAAAAEAXgAAAAACAE8AAAAAAABeAAAAAAEATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAA1AAAAAAIANQAAAAAAADUAAAAAAgBPAAAAAAAATwAAAAACAF4AAAAAAgBeAAAAAAAAXgAAAAAAAF4AAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAEATwAAAAADAE8AAAAAAABPAAAAAAIATwAAAAACAE8AAAAAAABeAAAAAAMATwAAAAADAE8AAAAAAwBPAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAE8AAAAAAQBPAAAAAAEATwAAAAACAE8AAAAAAgBPAAAAAAEAXgAAAAADAE8AAAAAAABPAAAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAQBeAAAAAAAAXgAAAAAAAF4AAAAAAQBPAAAAAAMAXgAAAAACAF4AAAAAAwBeAAAAAAIAXgAAAAACAF4AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAMATwAAAAAAAE8AAAAAAQBPAAAAAAIATwAAAAADAE8AAAAAAgBeAAAAAAMATwAAAAADAE8AAAAAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAE8AAAAAAgBPAAAAAAIATwAAAAAAAE8AAAAAAwBPAAAAAAAAXgAAAAADAE8AAAAAAgBeAAAAAAMATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAA1AAAAAAAANQAAAAAAADUAAAAAAwBPAAAAAAIATwAAAAADAF4AAAAAAwBPAAAAAAAAXgAAAAABAHEAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAACADUAAAAAAwA1AAAAAAMATwAAAAACAE8AAAAAAgBPAAAAAAEATwAAAAABAF4AAAAAAgBxAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAADUAAAAAAwA1AAAAAAMANQAAAAABAE8AAAAAAABPAAAAAAIAXgAAAAABAE8AAAAAAQBPAAAAAAAAcQAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAABeAAAAAAEAXgAAAAABAF4AAAAAAwBPAAAAAAMATwAAAAAAAF4AAAAAAwBPAAAAAAEATwAAAAADAHEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAEATwAAAAABAE8AAAAAAABPAAAAAAMATwAAAAACAE8AAAAAAgBeAAAAAAEATwAAAAACAE8AAAAAAQBxAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAF4AAAAAAQBeAAAAAAAAXgAAAAAAAE8AAAAAAgBeAAAAAAEAXgAAAAADAE8AAAAAAgBPAAAAAAEATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAwBPAAAAAAIATwAAAAABAE8AAAAAAwBPAAAAAAIATwAAAAAAAF4AAAAAAQBPAAAAAAAATwAAAAADAA4AAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAIATwAAAAACAE8AAAAAAgBPAAAAAAMATwAAAAADAE8AAAAAAgBeAAAAAAAATwAAAAADAE8AAAAAAQAOAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAADUAAAAAAgA1AAAAAAEANQAAAAAAAE8AAAAAAABPAAAAAAAAXgAAAAADAE8AAAAAAABPAAAAAAEATwAAAAADAA==
|
||||
version: 7
|
||||
0,0:
|
||||
ind: 0,0
|
||||
tiles: PwAAAAAAPwAAAAAADgAAAAACDgAAAAAADgAAAAADDgAAAAABDgAAAAABDgAAAAADXgAAAAABTwAAAAADTwAAAAADTwAAAAABTwAAAAADNQAAAAACNQAAAAACNQAAAAAAPwAAAAAAPwAAAAAADgAAAAADDgAAAAAADgAAAAACDgAAAAABDgAAAAAADgAAAAADXgAAAAACTwAAAAADXgAAAAABTwAAAAABTwAAAAAANQAAAAAANQAAAAACNQAAAAABTwAAAAAATwAAAAACTwAAAAAAXgAAAAABTwAAAAAATwAAAAABTwAAAAACTwAAAAABXgAAAAAATwAAAAABXgAAAAACTwAAAAACTwAAAAAATwAAAAABTwAAAAADTwAAAAAATwAAAAADTwAAAAAATwAAAAABTwAAAAADTwAAAAACTwAAAAACTwAAAAAATwAAAAADTwAAAAADTwAAAAADXgAAAAAATwAAAAACTwAAAAACTwAAAAACTwAAAAABTwAAAAADXgAAAAAAXgAAAAACXgAAAAAAXgAAAAABXgAAAAAAXgAAAAAAXgAAAAABXgAAAAABXgAAAAACXgAAAAADXgAAAAABXgAAAAADTwAAAAABXgAAAAADXgAAAAAAXgAAAAACTwAAAAAATwAAAAAATwAAAAABTwAAAAABTwAAAAAATwAAAAACTwAAAAAATwAAAAABTwAAAAACTwAAAAAAXgAAAAAATwAAAAACTwAAAAACTwAAAAADTwAAAAACTwAAAAACTwAAAAACXgAAAAAATwAAAAAATwAAAAAATwAAAAAAXgAAAAABTwAAAAADXgAAAAACXgAAAAABTwAAAAACXgAAAAAATwAAAAABTwAAAAABTwAAAAADTwAAAAABTwAAAAABIAAAAAACAgAAAAAAAgAAAAAATwAAAAAAAgAAAAAAAgAAAAAAIAAAAAABIAAAAAAAXgAAAAADTwAAAAADXgAAAAAATwAAAAABTwAAAAADNQAAAAADNQAAAAACNQAAAAACIAAAAAACAgAAAAAAAgAAAAAATwAAAAAAAgAAAAAAAgAAAAAAIAAAAAACIAAAAAAAXgAAAAAATwAAAAABTwAAAAACTwAAAAACTwAAAAACNQAAAAAAAAAAAAAAAAAAAAAAIAAAAAABAgAAAAAAAgAAAAAATwAAAAAAAgAAAAAAAgAAAAAAIAAAAAABIAAAAAADTwAAAAABIAAAAAACIAAAAAABIAAAAAADTwAAAAAANQAAAAABfgAAAAAAAAAAAAAAIAAAAAAAIAAAAAAAAgAAAAAAIAAAAAADAgAAAAAAIAAAAAAAIAAAAAADIAAAAAADTwAAAAADIAAAAAAAIAAAAAAAIAAAAAACTwAAAAAANQAAAAABfgAAAAAAAAAAAAAAIAAAAAADIAAAAAAAIAAAAAAAIAAAAAACIAAAAAAAIAAAAAAAIAAAAAACIAAAAAAATwAAAAABIAAAAAADIAAAAAABIAAAAAAAXgAAAAADNQAAAAACAAAAAAAAAAAAAAAAIAAAAAAAIAAAAAAAIAAAAAAAIAAAAAAAIAAAAAAAIAAAAAAAIAAAAAAAIAAAAAAAXgAAAAAAIAAAAAABIAAAAAAAIAAAAAAATwAAAAAANQAAAAABfgAAAAAAAAAAAAAAAgAAAAAAIAAAAAACAgAAAAAAAgAAAAAAAgAAAAAAIAAAAAACAgAAAAAAAgAAAAAATwAAAAADIAAAAAACIAAAAAABIAAAAAAATwAAAAADNQAAAAABAAAAAAAAAAAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAAIAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: PwAAAAAAAD8AAAAAAAAOAAAAAAIADgAAAAAAAA4AAAAAAwAOAAAAAAEADgAAAAABAA4AAAAAAwBeAAAAAAEATwAAAAADAE8AAAAAAwBPAAAAAAEATwAAAAADADUAAAAAAgA1AAAAAAIANQAAAAAAAD8AAAAAAAA/AAAAAAAADgAAAAADAA4AAAAAAAAOAAAAAAIADgAAAAABAA4AAAAAAAAOAAAAAAMAXgAAAAACAE8AAAAAAwBeAAAAAAEATwAAAAABAE8AAAAAAAA1AAAAAAAANQAAAAACADUAAAAAAQBPAAAAAAAATwAAAAACAE8AAAAAAABeAAAAAAEATwAAAAAAAE8AAAAAAQBPAAAAAAIATwAAAAABAF4AAAAAAABPAAAAAAEAXgAAAAACAE8AAAAAAgBPAAAAAAAATwAAAAABAE8AAAAAAwBPAAAAAAAATwAAAAADAE8AAAAAAABPAAAAAAEATwAAAAADAE8AAAAAAgBPAAAAAAIATwAAAAAAAE8AAAAAAwBPAAAAAAMATwAAAAADAF4AAAAAAABPAAAAAAIATwAAAAACAE8AAAAAAgBPAAAAAAEATwAAAAADAF4AAAAAAABeAAAAAAIAXgAAAAAAAF4AAAAAAQBeAAAAAAAAXgAAAAAAAF4AAAAAAQBeAAAAAAEAXgAAAAACAF4AAAAAAwBeAAAAAAEAXgAAAAADAE8AAAAAAQBeAAAAAAMAXgAAAAAAAF4AAAAAAgBPAAAAAAAATwAAAAAAAE8AAAAAAQBPAAAAAAEATwAAAAAAAE8AAAAAAgBPAAAAAAAATwAAAAABAE8AAAAAAgBPAAAAAAAAXgAAAAAAAE8AAAAAAgBPAAAAAAIATwAAAAADAE8AAAAAAgBPAAAAAAIATwAAAAACAF4AAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAABeAAAAAAEATwAAAAADAF4AAAAAAgBeAAAAAAEATwAAAAACAF4AAAAAAABPAAAAAAEATwAAAAABAE8AAAAAAwBPAAAAAAEATwAAAAABACAAAAAAAgACAAAAAAAAAgAAAAAAAE8AAAAAAAACAAAAAAAAAgAAAAAAACAAAAAAAQAgAAAAAAAAXgAAAAADAE8AAAAAAwBeAAAAAAAATwAAAAABAE8AAAAAAwA1AAAAAAMANQAAAAACADUAAAAAAgAgAAAAAAIAAgAAAAAAAAIAAAAAAABPAAAAAAAAAgAAAAAAAAIAAAAAAAAgAAAAAAIAIAAAAAAAAF4AAAAAAABPAAAAAAEATwAAAAACAE8AAAAAAgBPAAAAAAIANQAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAABAAIAAAAAAAACAAAAAAAATwAAAAAAAAIAAAAAAAACAAAAAAAAIAAAAAABACAAAAAAAwBPAAAAAAEAIAAAAAACACAAAAAAAQAgAAAAAAMATwAAAAAAADUAAAAAAQB+AAAAAAAAAAAAAAAAACAAAAAAAAAgAAAAAAAAAgAAAAAAACAAAAAAAwACAAAAAAAAIAAAAAAAACAAAAAAAwAgAAAAAAMATwAAAAADACAAAAAAAAAgAAAAAAAAIAAAAAACAE8AAAAAAAA1AAAAAAEAfgAAAAAAAAAAAAAAAAAgAAAAAAMAIAAAAAAAACAAAAAAAAAgAAAAAAIAIAAAAAAAACAAAAAAAAAgAAAAAAIAIAAAAAAAAE8AAAAAAQAgAAAAAAMAIAAAAAABACAAAAAAAABeAAAAAAMANQAAAAACAAAAAAAAAAAAAAAAAAAAIAAAAAAAACAAAAAAAAAgAAAAAAAAIAAAAAAAACAAAAAAAAAgAAAAAAAAIAAAAAAAACAAAAAAAABeAAAAAAAAIAAAAAABACAAAAAAAAAgAAAAAAAATwAAAAAAADUAAAAAAQB+AAAAAAAAAAAAAAAAAAIAAAAAAAAgAAAAAAIAAgAAAAAAAAIAAAAAAAACAAAAAAAAIAAAAAACAAIAAAAAAAACAAAAAAAATwAAAAADACAAAAAAAgAgAAAAAAEAIAAAAAAAAE8AAAAAAwA1AAAAAAEAAAAAAAAAAAAAAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAAATwAAAAAAACAAAAAAAAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
1,-1:
|
||||
ind: 1,-1
|
||||
tiles: fgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: fgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
1,0:
|
||||
ind: 1,0
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
-1,-2:
|
||||
ind: -1,-2
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAIAAAAAAAIAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAIAAAAAACIAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAIAAAAAADIAAAAAADIAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAIAAAAAABIAAAAAADIAAAAAAAXgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAIAAAAAACIAAAAAADTwAAAAABXgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAAATwAAAAABTwAAAAADIAAAAAAAIAAAAAABTwAAAAAAXgAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAADfwAAAAAATwAAAAABIAAAAAAAIAAAAAAATwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANQAAAAADfwAAAAAATwAAAAABIAAAAAACIAAAAAADTwAAAAABfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAABfwAAAAAATwAAAAABTwAAAAADTwAAAAAAIAAAAAACfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAANQAAAAACXgAAAAAATwAAAAACXgAAAAABTwAAAAAAXgAAAAABTwAAAAAC
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAACAAAAAAAAAgAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAAgAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAAgAAAAAAIAIAAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAIAAAAAADACAAAAAAAwAgAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAIAAAAAABACAAAAAAAwAgAAAAAAAAXgAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAACAAAAAAAgAgAAAAAAMATwAAAAABAF4AAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1AAAAAAAATwAAAAABAE8AAAAAAwAgAAAAAAAAIAAAAAABAE8AAAAAAABeAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAANQAAAAADAH8AAAAAAABPAAAAAAEAIAAAAAAAACAAAAAAAABPAAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADUAAAAAAwB/AAAAAAAATwAAAAABACAAAAAAAgAgAAAAAAMATwAAAAABAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAAA1AAAAAAEAfwAAAAAAAH8AAAAAAABPAAAAAAMATwAAAAAAACAAAAAAAgB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAANQAAAAACAF4AAAAAAABPAAAAAAIAXgAAAAABAE8AAAAAAABeAAAAAAEATwAAAAACAA==
|
||||
version: 7
|
||||
0,-2:
|
||||
ind: 0,-2
|
||||
tiles: fwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAACIAAAAAABIAAAAAACIAAAAAADIAAAAAADIAAAAAADIAAAAAABIAAAAAAAIAAAAAABfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAADIAAAAAACfwAAAAAAfwAAAAAAfwAAAAAAIAAAAAAAIAAAAAADIAAAAAADIAAAAAABfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAABIAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAIAAAAAADIAAAAAABIAAAAAACIAAAAAACIAAAAAACfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAIAAAAAACIAAAAAACIAAAAAAAIAAAAAADfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAXgAAAAABfwAAAAAAfwAAAAAAfwAAAAAAXgAAAAABIAAAAAACIAAAAAACIAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAXgAAAAACfwAAAAAAfwAAAAAAfwAAAAAAXgAAAAADTwAAAAADIAAAAAAAIAAAAAADfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAXgAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAXgAAAAAATwAAAAACIAAAAAABIAAAAAAATwAAAAAAfwAAAAAANQAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAATwAAAAADTwAAAAABIAAAAAADIAAAAAADTwAAAAACfwAAAAAANQAAAAABfgAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAATwAAAAADTwAAAAACIAAAAAACIAAAAAAATwAAAAAAfwAAAAAANQAAAAABAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAIAAAAAADTwAAAAABIAAAAAADTwAAAAACfwAAAAAANQAAAAADAAAAAAAAAAAAAAAATwAAAAAATwAAAAAATwAAAAACTwAAAAADTwAAAAABTwAAAAABTwAAAAACTwAAAAABXgAAAAADTwAAAAACXgAAAAABTwAAAAADXgAAAAACNQAAAAAAfgAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: fwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAIAIAAAAAABACAAAAAAAgAgAAAAAAMAIAAAAAADACAAAAAAAwAgAAAAAAEAIAAAAAAAACAAAAAAAQB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAADACAAAAAAAgB/AAAAAAAAfwAAAAAAAH8AAAAAAAAgAAAAAAAAIAAAAAADACAAAAAAAwAgAAAAAAEAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAQAgAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAIAAAAAADACAAAAAAAQAgAAAAAAIAIAAAAAACACAAAAAAAgB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAgAAAAAAIAIAAAAAACACAAAAAAAAAgAAAAAAMAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAXgAAAAABAH8AAAAAAAB/AAAAAAAAfwAAAAAAAF4AAAAAAQAgAAAAAAIAIAAAAAACACAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAF4AAAAAAgB/AAAAAAAAfwAAAAAAAH8AAAAAAABeAAAAAAMATwAAAAADACAAAAAAAAAgAAAAAAMAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAABeAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAXgAAAAAAAE8AAAAAAgAgAAAAAAEAIAAAAAAAAE8AAAAAAAB/AAAAAAAANQAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAE8AAAAAAwBPAAAAAAEAIAAAAAADACAAAAAAAwBPAAAAAAIAfwAAAAAAADUAAAAAAQB+AAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAABPAAAAAAMATwAAAAACACAAAAAAAgAgAAAAAAAATwAAAAAAAH8AAAAAAAA1AAAAAAEAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAACAAAAAAAwBPAAAAAAEAIAAAAAADAH8AAAAAAAB/AAAAAAAANQAAAAADAAAAAAAAAAAAAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAIATwAAAAADAE8AAAAAAQBPAAAAAAEATwAAAAACAE8AAAAAAQBeAAAAAAMATwAAAAACAF4AAAAAAQBPAAAAAAMAXgAAAAACADUAAAAAAAB+AAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
0,1:
|
||||
ind: 0,1
|
||||
tiles: AwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAIAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAIAAAAAAAIAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAAQAAAAAAAQAAAAAATwAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAAQAAAAAATwAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAwAAAAAAAQAAAAAAAQAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAATwAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: AwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAABPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAMAAAAAAAADAAAAAAAAAwAAAAAAAAMAAAAAAAAgAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAEAAAAAAAADAAAAAAAAAQAAAAAAACAAAAAAAAAgAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAMAAAAAAAADAAAAAAAAAwAAAAAAAAMAAAAAAAADAAAAAAAAAQAAAAAAAAEAAAAAAABPAAAAAAAAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAADAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAATwAAAAAAAH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAwAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAMAAAAAAAABAAAAAAAAAQAAAAAAAE8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAABPAAAAAAAATwAAAAAAAE8AAAAAAAB+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
-1,1:
|
||||
ind: -1,1
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAIAAAAAAAAwAAAAAAAwAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAIAAAAAAAIAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAATwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAATwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATwAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPAAAAAAAAAQAAAAAAAAEAAAAAAAABAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfgAAAAAAACAAAAAAAAADAAAAAAAAAwAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAAIAAAAAAAACAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAAAAABPAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAATwAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE8AAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+AAAAAAAATwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
0,-3:
|
||||
ind: 0,-3
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
-1,-3:
|
||||
ind: -1,-3
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
version: 6
|
||||
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAAAAAAfwAAAAAAAH8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAAAAAAB/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
|
||||
version: 7
|
||||
- type: Broadphase
|
||||
- type: Physics
|
||||
bodyStatus: InAir
|
||||
|
|
@ -89,15 +100,16 @@ entities:
|
|||
- type: OccluderTree
|
||||
- type: SpreaderGrid
|
||||
- type: Shuttle
|
||||
dampingModifier: 0.25
|
||||
- type: GridPathfinding
|
||||
- type: Gravity
|
||||
gravityShakeSound: !type:SoundPathSpecifier
|
||||
path: /Audio/Effects/alert.ogg
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
configurators: []
|
||||
deviceLists: []
|
||||
transmitFrequencyId: ShuttleTimer
|
||||
deviceNetId: Wireless
|
||||
- type: DecalGrid
|
||||
chunkCollection:
|
||||
version: 2
|
||||
|
|
@ -1251,6 +1263,7 @@ entities:
|
|||
chunkSize: 4
|
||||
- type: GasTileOverlay
|
||||
- type: RadiationGridResistance
|
||||
- type: ImplicitRoof
|
||||
- proto: AirAlarm
|
||||
entities:
|
||||
- uid: 1885
|
||||
|
|
@ -1379,7 +1392,6 @@ entities:
|
|||
- 1562
|
||||
- 85
|
||||
- 1737
|
||||
- 21
|
||||
- 722
|
||||
- 762
|
||||
- 1589
|
||||
|
|
@ -1398,10 +1410,8 @@ entities:
|
|||
- 1342
|
||||
- 1340
|
||||
- 1738
|
||||
- 1739
|
||||
- 971
|
||||
- 1737
|
||||
- 21
|
||||
- 973
|
||||
- 1592
|
||||
- 1591
|
||||
|
|
@ -1422,7 +1432,6 @@ entities:
|
|||
- 681
|
||||
- 689
|
||||
- 1738
|
||||
- 1739
|
||||
- 971
|
||||
- 1601
|
||||
- 762
|
||||
|
|
@ -1523,11 +1532,6 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: 9.5,-17.5
|
||||
parent: 1
|
||||
- uid: 1748
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,-17.5
|
||||
parent: 1
|
||||
- proto: AirlockCommandGlassLocked
|
||||
entities:
|
||||
- uid: 47
|
||||
|
|
@ -1560,12 +1564,6 @@ entities:
|
|||
- type: Transform
|
||||
pos: -2.5,-22.5
|
||||
parent: 1
|
||||
- uid: 1747
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -4.5,-17.5
|
||||
parent: 1
|
||||
- proto: AirlockExternalEngineeringLocked
|
||||
entities:
|
||||
- uid: 1636
|
||||
|
|
@ -1577,9 +1575,11 @@ entities:
|
|||
- type: DeviceLinkSource
|
||||
linkedPorts:
|
||||
1637:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
1635:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
- uid: 1640
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -1589,9 +1589,11 @@ entities:
|
|||
- type: DeviceLinkSource
|
||||
linkedPorts:
|
||||
1635:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
1637:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
- proto: AirlockExternalGlass
|
||||
entities:
|
||||
- uid: 25
|
||||
|
|
@ -1671,9 +1673,11 @@ entities:
|
|||
- type: DeviceLinkSource
|
||||
linkedPorts:
|
||||
1636:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
1640:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
- uid: 1637
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -1683,9 +1687,11 @@ entities:
|
|||
- type: DeviceLinkSource
|
||||
linkedPorts:
|
||||
1636:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
1640:
|
||||
- DoorStatus: DoorBolt
|
||||
- - DoorStatus
|
||||
- DoorBolt
|
||||
- proto: AirlockGlass
|
||||
entities:
|
||||
- uid: 26
|
||||
|
|
@ -2260,12 +2266,6 @@ entities:
|
|||
parent: 1
|
||||
- proto: BenchSofaCorpLeft
|
||||
entities:
|
||||
- uid: 45
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -4.5,-19.5
|
||||
parent: 1
|
||||
- uid: 268
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -2446,12 +2446,6 @@ entities:
|
|||
- type: Transform
|
||||
pos: 6.5,-13.5
|
||||
parent: 1
|
||||
- uid: 690
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -4.5,-20.5
|
||||
parent: 1
|
||||
- uid: 733
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -5247,21 +5241,28 @@ entities:
|
|||
- type: Transform
|
||||
pos: 7.5,-4.5
|
||||
parent: 1
|
||||
- uid: 215
|
||||
- uid: 45
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -0.5,-4.5
|
||||
parent: 1
|
||||
- uid: 216
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-4.5
|
||||
parent: 1
|
||||
- uid: 326
|
||||
- uid: 214
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 0.5,-4.5
|
||||
parent: 1
|
||||
- uid: 215
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -0.5,-6.5
|
||||
parent: 1
|
||||
- uid: 330
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 0.5,-6.5
|
||||
parent: 1
|
||||
- uid: 378
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -5284,18 +5285,6 @@ entities:
|
|||
rot: 3.141592653589793 rad
|
||||
pos: 7.5,-6.5
|
||||
parent: 1
|
||||
- uid: 426
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -0.5,-6.5
|
||||
parent: 1
|
||||
- uid: 427
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 0.5,-6.5
|
||||
parent: 1
|
||||
- uid: 485
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -5338,6 +5327,11 @@ entities:
|
|||
rot: -1.5707963267948966 rad
|
||||
pos: 7.5,8.5
|
||||
parent: 1
|
||||
- uid: 690
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5,-4.5
|
||||
parent: 1
|
||||
- uid: 1584
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -5441,6 +5435,14 @@ entities:
|
|||
- type: Transform
|
||||
pos: 4.5,18.5
|
||||
parent: 1
|
||||
- proto: ChemistryBottleEpinephrine
|
||||
entities:
|
||||
- uid: 352
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 2.3577118,-8.211421
|
||||
parent: 1
|
||||
- proto: ClosetWallEmergencyFilledRandom
|
||||
entities:
|
||||
- uid: 175
|
||||
|
|
@ -5517,21 +5519,6 @@ entities:
|
|||
rot: -1.5707963267948966 rad
|
||||
pos: 12.5,-9.5
|
||||
parent: 1
|
||||
- proto: ComputerCloningConsole
|
||||
entities:
|
||||
- uid: 214
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,-6.5
|
||||
parent: 1
|
||||
- type: DeviceLinkSource
|
||||
linkedPorts:
|
||||
330:
|
||||
- MedicalScannerSender: MedicalScannerReceiver
|
||||
- CloningPodSender: MedicalScannerReceiver
|
||||
370:
|
||||
- MedicalScannerSender: CloningPodReceiver
|
||||
- CloningPodSender: CloningPodReceiver
|
||||
- proto: ComputerComms
|
||||
entities:
|
||||
- uid: 2238
|
||||
|
|
@ -6291,26 +6278,8 @@ entities:
|
|||
- type: Transform
|
||||
pos: 3.136067,-5.337432
|
||||
parent: 1
|
||||
- proto: EpinephrineChemistryBottle
|
||||
entities:
|
||||
- uid: 352
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 2.3577118,-8.211421
|
||||
parent: 1
|
||||
- proto: FirelockGlass
|
||||
entities:
|
||||
- uid: 21
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -4.5,-17.5
|
||||
parent: 1
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 1893
|
||||
- 1894
|
||||
- uid: 23
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -6550,16 +6519,6 @@ entities:
|
|||
deviceLists:
|
||||
- 1895
|
||||
- 1894
|
||||
- uid: 1739
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 11.5,-17.5
|
||||
parent: 1
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 1895
|
||||
- 1894
|
||||
- proto: FloorDrain
|
||||
entities:
|
||||
- uid: 2085
|
||||
|
|
@ -6593,7 +6552,7 @@ entities:
|
|||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- proto: FloraTree02
|
||||
- proto: FloraTree
|
||||
entities:
|
||||
- uid: 1923
|
||||
components:
|
||||
|
|
@ -6607,15 +6566,13 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: -7.6932545,7.499033
|
||||
parent: 1
|
||||
- proto: FloraTree04
|
||||
entities:
|
||||
- uid: 1926
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 14.759519,-6.5801034
|
||||
parent: 1
|
||||
- proto: FloraTreeLarge04
|
||||
- proto: FloraTreeLarge
|
||||
entities:
|
||||
- uid: 1927
|
||||
components:
|
||||
|
|
@ -11424,6 +11381,13 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: -0.70859075,18.949242
|
||||
parent: 1
|
||||
- proto: HolopadCentCommEvacShuttle
|
||||
entities:
|
||||
- uid: 1748
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.5,19.5
|
||||
parent: 1
|
||||
- proto: HospitalCurtainsOpen
|
||||
entities:
|
||||
- uid: 382
|
||||
|
|
@ -11527,6 +11491,23 @@ entities:
|
|||
- type: Transform
|
||||
pos: -1.5,-25.5
|
||||
parent: 1
|
||||
- proto: LockerEvacRepairFilled
|
||||
entities:
|
||||
- uid: 21
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -4.5,-18.5
|
||||
parent: 1
|
||||
- uid: 1739
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -4.5,-20.5
|
||||
parent: 1
|
||||
- uid: 1747
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -4.5,-19.5
|
||||
parent: 1
|
||||
- proto: LockerEvidence
|
||||
entities:
|
||||
- uid: 685
|
||||
|
|
@ -11637,13 +11618,6 @@ entities:
|
|||
- type: Transform
|
||||
pos: 7.5,-8.5
|
||||
parent: 1
|
||||
- proto: MedicalScanner
|
||||
entities:
|
||||
- uid: 330
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,-6.5
|
||||
parent: 1
|
||||
- proto: MedkitAdvancedFilled
|
||||
entities:
|
||||
- uid: 2064
|
||||
|
|
@ -11660,13 +11634,6 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: 2.1233368,-8.3442335
|
||||
parent: 1
|
||||
- proto: MetempsychoticMachine
|
||||
entities:
|
||||
- uid: 370
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-6.5
|
||||
parent: 1
|
||||
- proto: MopBucketFull
|
||||
entities:
|
||||
- uid: 2083
|
||||
|
|
@ -11770,13 +11737,6 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: -0.21379477,-16.4499
|
||||
parent: 1
|
||||
- proto: PlushieLizard
|
||||
entities:
|
||||
- uid: 2044
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 1.5054002,-4.5560694
|
||||
parent: 1
|
||||
- proto: PlushieMoth
|
||||
entities:
|
||||
- uid: 2039
|
||||
|
|
@ -11799,14 +11759,6 @@ entities:
|
|||
- type: Transform
|
||||
pos: 6.8242917,-37.207977
|
||||
parent: 1
|
||||
- proto: PlushiePenguin
|
||||
entities:
|
||||
- uid: 2034
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -4.4982705,-20.393938
|
||||
parent: 1
|
||||
- proto: PlushieRGBee
|
||||
entities:
|
||||
- uid: 2028
|
||||
|
|
@ -11867,14 +11819,6 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: 9.399769,-3.016137
|
||||
parent: 1
|
||||
- proto: PlushieSpaceLizard
|
||||
entities:
|
||||
- uid: 2037
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -4.529521,-19.893938
|
||||
parent: 1
|
||||
- proto: PlushieXeno
|
||||
entities:
|
||||
- uid: 2038
|
||||
|
|
@ -13242,42 +13186,7 @@ entities:
|
|||
- type: Transform
|
||||
pos: 5.5,14.5
|
||||
parent: 1
|
||||
- proto: ShadowTree01
|
||||
entities:
|
||||
- uid: 1918
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 13.273117,-15.984801
|
||||
parent: 1
|
||||
- uid: 1929
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -6.6538024,7.966305
|
||||
parent: 1
|
||||
- proto: ShadowTree03
|
||||
entities:
|
||||
- uid: 1914
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -6.367117,13.323404
|
||||
parent: 1
|
||||
- uid: 1920
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -8.080735,-6.4842486
|
||||
parent: 1
|
||||
- proto: ShadowTree04
|
||||
entities:
|
||||
- uid: 1915
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 14.303209,7.7148037
|
||||
parent: 1
|
||||
- proto: ShadowTree05
|
||||
- proto: ShadowTree
|
||||
entities:
|
||||
- uid: 422
|
||||
components:
|
||||
|
|
@ -13290,26 +13199,53 @@ entities:
|
|||
rot: 1.5707963267948966 rad
|
||||
pos: 13.382492,13.271562
|
||||
parent: 1
|
||||
- uid: 1914
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -6.367117,13.323404
|
||||
parent: 1
|
||||
- uid: 1915
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 14.303209,7.7148037
|
||||
parent: 1
|
||||
- uid: 1916
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 13.640305,-19.63101
|
||||
parent: 1
|
||||
- uid: 1918
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 13.273117,-15.984801
|
||||
parent: 1
|
||||
- uid: 1919
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -7.7875977,-14.561567
|
||||
parent: 1
|
||||
- proto: ShadowTree06
|
||||
entities:
|
||||
- uid: 1920
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -8.080735,-6.4842486
|
||||
parent: 1
|
||||
- uid: 1922
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 13.233812,1.3556528
|
||||
parent: 1
|
||||
- uid: 1929
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -6.6538024,7.966305
|
||||
parent: 1
|
||||
- proto: SheetSteel
|
||||
entities:
|
||||
- uid: 556
|
||||
|
|
@ -14239,6 +14175,18 @@ entities:
|
|||
- type: Transform
|
||||
pos: 3.5,-7.5
|
||||
parent: 1
|
||||
- proto: StasisBed
|
||||
entities:
|
||||
- uid: 216
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 2.5,-6.5
|
||||
parent: 1
|
||||
- uid: 326
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 4.5,-6.5
|
||||
parent: 1
|
||||
- proto: StoolBar
|
||||
entities:
|
||||
- uid: 399
|
||||
|
|
@ -14346,7 +14294,7 @@ entities:
|
|||
- type: Transform
|
||||
pos: 9.5,12.5
|
||||
parent: 1
|
||||
- proto: SuitStorageSec
|
||||
- proto: SuitStorageSecDeltaV
|
||||
entities:
|
||||
- uid: 1373
|
||||
components:
|
||||
|
|
@ -15338,6 +15286,11 @@ entities:
|
|||
rot: -1.5707963267948966 rad
|
||||
pos: -5.5,-5.5
|
||||
parent: 1
|
||||
- uid: 370
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -4.5,-17.5
|
||||
parent: 1
|
||||
- uid: 373
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -15349,6 +15302,11 @@ entities:
|
|||
rot: -1.5707963267948966 rad
|
||||
pos: -5.5,4.5
|
||||
parent: 1
|
||||
- uid: 426
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 11.5,-17.5
|
||||
parent: 1
|
||||
- uid: 442
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -15874,6 +15832,14 @@ entities:
|
|||
rot: -1.5707963267948966 rad
|
||||
pos: -0.5,19.5
|
||||
parent: 1
|
||||
- proto: WehMedipen
|
||||
entities:
|
||||
- uid: 427
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: 2.6532867,-4.4037185
|
||||
parent: 1
|
||||
- proto: WindoorBarKitchenLocked
|
||||
entities:
|
||||
- uid: 392
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ meta:
|
|||
engineVersion: 262.0.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 10/09/2025 12:04:17
|
||||
time: 10/13/2025 17:47:39
|
||||
entityCount: 10383
|
||||
maps: []
|
||||
grids:
|
||||
|
|
@ -52930,7 +52930,7 @@ entities:
|
|||
- uid: 5608
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -19.5,17.5
|
||||
pos: -20.5,17.5
|
||||
parent: 1
|
||||
- uid: 5609
|
||||
components:
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ meta:
|
|||
engineVersion: 262.0.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 10/13/2025 02:04:30
|
||||
entityCount: 46427
|
||||
time: 10/15/2025 20:26:10
|
||||
entityCount: 46437
|
||||
maps:
|
||||
- 1
|
||||
grids:
|
||||
|
|
@ -75107,11 +75107,6 @@ entities:
|
|||
- type: Transform
|
||||
pos: -2.5,40.5
|
||||
parent: 2
|
||||
- uid: 46228
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.5,39.5
|
||||
parent: 2
|
||||
- uid: 46396
|
||||
components:
|
||||
- type: Transform
|
||||
|
|
@ -75122,6 +75117,16 @@ entities:
|
|||
- type: Transform
|
||||
pos: -48.5,-16.5
|
||||
parent: 2
|
||||
- uid: 46435
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -3.5,41.5
|
||||
parent: 2
|
||||
- uid: 46436
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -2.5,35.5
|
||||
parent: 2
|
||||
- proto: CableApcStack
|
||||
entities:
|
||||
- uid: 5935
|
||||
|
|
@ -98775,6 +98780,11 @@ entities:
|
|||
- type: Transform
|
||||
pos: -70.5,-9.5
|
||||
parent: 2
|
||||
- uid: 46437
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -67.5,-8.5
|
||||
parent: 2
|
||||
- proto: CableMVStack
|
||||
entities:
|
||||
- uid: 5937
|
||||
|
|
@ -263305,6 +263315,48 @@ entities:
|
|||
- type: Transform
|
||||
pos: 10.5,47.5
|
||||
parent: 2
|
||||
- proto: SpawnPointLatejoin
|
||||
entities:
|
||||
- uid: 46228
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 33.5,22.5
|
||||
parent: 2
|
||||
- uid: 46428
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 33.5,21.5
|
||||
parent: 2
|
||||
- uid: 46429
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 33.5,17.5
|
||||
parent: 2
|
||||
- uid: 46430
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 33.5,16.5
|
||||
parent: 2
|
||||
- uid: 46431
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 35.5,22.5
|
||||
parent: 2
|
||||
- uid: 46432
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 35.5,21.5
|
||||
parent: 2
|
||||
- uid: 46433
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 35.5,17.5
|
||||
parent: 2
|
||||
- uid: 46434
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 35.5,16.5
|
||||
parent: 2
|
||||
- proto: SpawnPointLawyer
|
||||
entities:
|
||||
- uid: 46047
|
||||
|
|
|
|||
160855
Resources/Maps/submarine.yml
160855
Resources/Maps/submarine.yml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,4 @@
|
|||
- type: alert
|
||||
- type: alert
|
||||
id: Essence
|
||||
category: Health #it's like ghostie health
|
||||
icons:
|
||||
|
|
@ -18,12 +18,15 @@
|
|||
id: AlertEssenceSpriteView
|
||||
categories: [ HideSpawnMenu ]
|
||||
components:
|
||||
- type: GenericCounterAlert
|
||||
centerGlyph: false
|
||||
hideLeadingZeroes: false
|
||||
- type: Sprite
|
||||
sprite: /Textures/Interface/Alerts/essence_counter.rsi
|
||||
layers:
|
||||
- map: [ "enum.AlertVisualLayers.Base" ]
|
||||
- map: [ "enum.RevenantVisualLayers.Digit1" ]
|
||||
- map: [ "enum.RevenantVisualLayers.Digit2" ]
|
||||
offset: 0.125, 0
|
||||
- map: [ "enum.RevenantVisualLayers.Digit3" ]
|
||||
- map: [ "1" ]
|
||||
offset: 0.25, 0
|
||||
- map: [ "10" ]
|
||||
offset: 0.125, 0
|
||||
- map: [ "100" ]
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
SilverRing: 2 # DeltaV
|
||||
RingBox: 2 # DeltaV
|
||||
CosmicCenser: 1 # DeltaV - Cosmic Cult
|
||||
SilverSword: 1 # DeltaV - Most stations start them with a kitchen knife. They can have this.
|
||||
contrabandInventory:
|
||||
FoodBakedBunHotX: 2
|
||||
DrinkWineBottleFull: 1
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
- PaintingRedBlueYellow
|
||||
- PaintingHelloWorld
|
||||
- PaintingSpoon # DeltaV Painting, see Resources/Prototypes/_DV/Entities/Structures/Wallmount/painting.yml
|
||||
- PaintingUnePipe # _DEN edit
|
||||
- PaintingTheWrathOfGods # _DEN edit
|
||||
- PaintingHumanCondition # _DEN edit
|
||||
- PaintingKnowledge # _DEN edit
|
||||
chance: 1
|
||||
rarePrototypes:
|
||||
- PaintingSkeletonBoof
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
id: SpawnPointGhostRatKing
|
||||
name: ghost role spawn point
|
||||
suffix: rat king
|
||||
parent: MarkerBase
|
||||
parent: BaseAntagSpawner
|
||||
components:
|
||||
- type: GhostRole
|
||||
name: ghost-role-information-rat-king-name
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@
|
|||
- type: CosmicCenserTarget # DeltaV - Cosmic Cult
|
||||
- type: Carriable # DeltaV
|
||||
- type: EmoteCooldown # DeltaV - implement RMC emote cooldown
|
||||
- type: GrappleTarget # DeltaV - Allow targets to be grappled
|
||||
|
||||
- type: entity
|
||||
save: false
|
||||
|
|
|
|||
|
|
@ -126,8 +126,8 @@
|
|||
darkThreshold: 0.4
|
||||
lightThreshold: 1.2
|
||||
darkDamage:
|
||||
groups:
|
||||
Burn: 1.0
|
||||
types:
|
||||
Heat: 1.0
|
||||
lightDamage:
|
||||
groups:
|
||||
Brute: -0.1
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@
|
|||
- type: Sprite
|
||||
sprite: Objects/Specific/Chapel/bible.rsi
|
||||
state: icon
|
||||
- type: Tool # DeltaV - Lets it be used to bless things.
|
||||
qualities:
|
||||
- Blessing
|
||||
- type: Item
|
||||
size: Small
|
||||
sprite: Objects/Specific/Chapel/bible.rsi
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@
|
|||
- id: MobWhimperlet # DeltaV - added Whimperlet
|
||||
weight: 0.03
|
||||
#- id: MobMouseCancer # DeltaV - no
|
||||
- id: MobCorticalBorer # DeltaV - ported Borer
|
||||
weight: 0.015 # DeltaV - original probability was 0.001 but that seems WAY too low
|
||||
# Events always spawn a critter regardless of Probability https://github.com/space-wizards/space-station-14/issues/28480 I added the Rat King to their own event with a player cap.
|
||||
|
||||
- type: entity
|
||||
|
|
@ -96,6 +98,8 @@
|
|||
weight: 0.21
|
||||
- id: MobWhimperlet # DeltaV - Added Whimperlet and its weight
|
||||
weight: 0.02
|
||||
- id: MobCorticalBorer # DeltaV - ported Borer
|
||||
weight: 0.015 # DeltaV - original probability was 0.001 but that seems WAY too low
|
||||
|
||||
- type: entity
|
||||
id: SnailMigrationLowPop
|
||||
|
|
@ -140,7 +144,9 @@
|
|||
- id: MobSnail
|
||||
weight: 0.84
|
||||
- id: MobSnailSpeed
|
||||
weight: 0.08
|
||||
weight: 0.07 # DeltaV - was 0.08
|
||||
- id: MobSnailMoth
|
||||
weight: 0.08
|
||||
weight: 0.07 # DeltaV - was 0.08
|
||||
#- id: MobSnailInstantDeath # DeltaV - no
|
||||
- id: MobCorticalBorer # DeltaV - ported Borer
|
||||
weight: 0.02 # DeltaV - 2% chance on snails
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
# - Micro - to be revisited later ~Colin
|
||||
- Pebble
|
||||
- Shoukou
|
||||
- Submarine
|
||||
- Terra
|
||||
- Tortuga
|
||||
- TheHive
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
- type: gameMap
|
||||
id: Submarine
|
||||
mapName: 'Submarine'
|
||||
mapPath: /Maps/submarine.yml
|
||||
minPlayers: 90
|
||||
stations:
|
||||
Submarine:
|
||||
stationProto: StandardNanotrasenStation
|
||||
components:
|
||||
- type: StationNameSetup
|
||||
mapNameTemplate: '{0} Submarine {1}'
|
||||
nameGenerator:
|
||||
!type:NanotrasenNameGenerator
|
||||
prefixCreator: 'DV'
|
||||
- type: StationEmergencyShuttle
|
||||
emergencyShuttlePath: /Maps/_DV/Shuttles/NTES_Propeller.yml
|
||||
- type: StationCargoShuttle
|
||||
path: /Maps/_DV/Shuttles/cargo_model_B.yml
|
||||
- type: StationJobs
|
||||
availableJobs:
|
||||
#civilian
|
||||
Passenger: [ -1, -1 ]
|
||||
Librarian: [ 1, 1 ]
|
||||
#command
|
||||
Captain: [ 1, 1 ]
|
||||
#engineering
|
||||
AtmosphericTechnician: [ 3, 4 ]
|
||||
ChiefEngineer: [ 1, 1 ]
|
||||
StationEngineer: [ 4, 6 ]
|
||||
TechnicalAssistant: [ 1, 2 ]
|
||||
#medical
|
||||
Chemist: [ 2, 2 ]
|
||||
ChiefMedicalOfficer: [ 1, 1 ]
|
||||
MedicalDoctor: [ 4, 5 ]
|
||||
MedicalIntern: [ 2, 3 ]
|
||||
Paramedic: [ 2, 3 ]
|
||||
Psychologist: [ 1, 2 ]
|
||||
Surgeon: [ 1, 2 ]
|
||||
#security
|
||||
Brigmedic: [ 2, 2 ]
|
||||
Detective: [ 2, 2 ]
|
||||
HeadOfSecurity: [ 1, 1 ]
|
||||
Prisoner: [ 2, 4 ]
|
||||
PrisonGuard: [ 1, 2 ]
|
||||
SecurityOfficer: [ 8, 10 ]
|
||||
SecurityCadet: [ 2, 4 ]
|
||||
Warden: [ 1, 1 ]
|
||||
#service
|
||||
Bartender: [ 2, 3 ]
|
||||
Botanist: [ 2, 4 ]
|
||||
Boxer: [ 2, 2 ]
|
||||
Chef: [ 4, 5 ]
|
||||
Clown: [ 1, 2 ]
|
||||
HeadOfPersonnel: [ 1, 1 ]
|
||||
Janitor: [ 2, 3 ]
|
||||
MartialArtist: [ 1, 2 ]
|
||||
Mime: [ 1, 1 ]
|
||||
Musician: [ 2, 2 ]
|
||||
Reporter: [ 1, 2 ]
|
||||
ServiceWorker: [ 1, 2 ]
|
||||
Zookeeper: [ 2, 2 ]
|
||||
#science
|
||||
Roboticist: [ 1, 1 ]
|
||||
Chaplain: [ 1, 1 ]
|
||||
ForensicMantis: [ 1, 1 ]
|
||||
ResearchAssistant: [ 1, 2 ]
|
||||
ResearchDirector: [ 2, 2 ]
|
||||
Scientist: [ 4, 5 ]
|
||||
#supply
|
||||
CargoTechnician: [ 2, 4 ]
|
||||
CargoAssistant: [ 1, 2 ]
|
||||
Courier: [ 3, 3 ]
|
||||
SalvageSpecialist: [ 3, 5 ]
|
||||
Quartermaster: [ 1, 1 ]
|
||||
#Justice
|
||||
ChiefJustice: [ 1, 1 ]
|
||||
Prosecutor: [ 2, 2 ]
|
||||
Clerk: [ 1, 1 ]
|
||||
Lawyer: [ 2, 2 ]
|
||||
#Synthetics
|
||||
StationAi: [ 1, 1]
|
||||
Borg: [ 2, 4 ]
|
||||
MedicalBorg: [ 2, 2 ]
|
||||
|
|
@ -27,13 +27,13 @@
|
|||
amount: -1
|
||||
- !type:ModifyBloodLevel
|
||||
amount: 2
|
||||
- !type:EvenHealthChange
|
||||
damage:
|
||||
Burn: -4
|
||||
Brute: -4
|
||||
- !type:HealthChange
|
||||
damage:
|
||||
groups:
|
||||
Burn: -5
|
||||
Brute: -4
|
||||
types:
|
||||
Caustic: -3
|
||||
Poison: -3
|
||||
Bloodloss: -3
|
||||
|
||||
|
|
@ -108,4 +108,4 @@
|
|||
probability: 0.4
|
||||
damage:
|
||||
groups:
|
||||
Toxin: 2
|
||||
Toxin: 2
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
PsychokineticScreamPower: 1
|
||||
MassSleepPower: 0.3
|
||||
NoosphericZapPower: 0.3
|
||||
FracturedFormPower: 0.3
|
||||
# PsionicInvisibilityPower: 0.15
|
||||
MindSwapPower: 0.15
|
||||
PsionicEruptionPower: 0.1
|
||||
|
|
|
|||
|
|
@ -16,21 +16,23 @@
|
|||
#CMOCrewMonitorStealObjective: 1 # DeltaV - You can buy this + paramedics all have them
|
||||
RDHardsuitStealObjective: 1
|
||||
NukeDiskStealObjective: 0.25 # DeltaV - was 1
|
||||
PlutoniumCoreStealObjective: 0.5 # DeltaV
|
||||
MagbootsStealObjective: 1
|
||||
# CorgiMeatStealObjective: 1 # DeltaV - Disable the horrible murder of Ian as an objective
|
||||
MantisKnifeStealObjective: 1 # Nyanotrasen - ForensicMantis steal objective, see Resources/Prototypes/Nyanotrasen/Objectives/traitor.yml
|
||||
ClipboardStealObjective: 1
|
||||
RdClipboardStealObjective: 1 # DeltaV - Mysta steal Objective see Resources/Prototypes/_DV/Objectives/traitor.yml
|
||||
CaptainGunStealObjective: 0.5
|
||||
CaptainJetpackStealObjective: 0.5
|
||||
HandTeleporterStealObjective: 0.5
|
||||
#EnergyShotgunStealObjective: 0.5 # DeltaV - replaced by X-01 objective
|
||||
ClerkNotaryStealObjective: 0.5 # DeltaV
|
||||
LOLuckyBillStealObjective: 0.5 # DeltaV - LO steal objective, see Resources/Prototypes/_DV/Objectives/traitor.yml
|
||||
HoPBookIanDossierStealObjective: 1 # DeltaV - HoP steal objective, see Resources/Prototypes/_DV/Objectives/traitor.yml
|
||||
HoSGunStealObjective: 0.5 # DeltaV
|
||||
BibleMystagogueStealObjective: 0.5 # DeltaV - Mysta steal objective see Resources/Prototypes/_DV/Objectives/traitor.yml
|
||||
# Begin DeltaV Additions
|
||||
ClerkNotaryStealObjective: 0.5
|
||||
HoPBookIanDossierStealObjective: 1
|
||||
HoSGunStealObjective: 0.5
|
||||
BibleMystagogueStealObjective: 0.5
|
||||
HardsuitRhinoStealObjective: 0.5
|
||||
PlutoniumCoreStealObjective: 0.5
|
||||
MantisKnifeStealObjective: 1
|
||||
RdClipboardStealObjective: 1
|
||||
# End DeltaV Additions
|
||||
|
||||
- type: weightedRandom
|
||||
id: TraitorObjectiveGroupKill
|
||||
|
|
|
|||
|
|
@ -90,6 +90,11 @@
|
|||
reagent: Nutriment
|
||||
min: 0.1
|
||||
factor: 1
|
||||
- !type:GenericStatusEffect # Mono change
|
||||
key: CorticalBorerProtection
|
||||
type: Add
|
||||
time: 3 # May be too much, needs testing
|
||||
refresh: false
|
||||
plantMetabolism:
|
||||
- !type:PlantAdjustNutrition
|
||||
amount: 0.1
|
||||
|
|
|
|||
|
|
@ -166,15 +166,15 @@
|
|||
# Dragon doesn't require airloss healing, so omnizine is still best for humans.
|
||||
- !type:ModifyBloodLevel
|
||||
amount: 3
|
||||
- !type:HealthChange
|
||||
# Begin DeltaV additions
|
||||
- !type:EvenHealthChange # Changed from HealthChange to EvenHealthChange
|
||||
damage:
|
||||
groups:
|
||||
Burn: -5
|
||||
Brute: -5
|
||||
Toxin: -4 # Funkychem - was -2
|
||||
Airloss: -6 # Funkychem - ichor does airloss now too
|
||||
types:
|
||||
Bloodloss: -5
|
||||
Brute: -2 # Was -5 with HealthChange
|
||||
Burn: -2 # Was -5 with HealthChange
|
||||
Toxin: -2 # Funkychem - Was -2 with HealthChange
|
||||
Airloss: -3 # Funkychem - Ichor heals Airloss now.
|
||||
# -6 Bloodloss with HealthChange has been removed due to -3 Airloss with EvenHealthChange above.
|
||||
# End DeltaV additions
|
||||
- !type:ModifyBleedAmount
|
||||
amount: -1.5
|
||||
# Just in case you REALLY want to water your plants
|
||||
|
|
|
|||
|
|
@ -194,16 +194,15 @@
|
|||
Medicine:
|
||||
effects:
|
||||
- !type:ModifyBloodLevel
|
||||
amount: 4
|
||||
- !type:HealthChange
|
||||
amount: 6 # DeltaV - Same as Saline, was 4.
|
||||
- !type:EvenHealthChange # DeltaV - Cryochems heal evenly.
|
||||
conditions:
|
||||
- !type:Temperature
|
||||
# this is a little arbitrary but they gotta be pretty cold
|
||||
max: 213.0
|
||||
damage:
|
||||
# todo scale with temp like SS13
|
||||
groups:
|
||||
Airloss: -10
|
||||
Airloss: -7 # DeltaV - Was -10 with HealthChange.
|
||||
|
||||
- type: reagent
|
||||
id: Doxarubixadone
|
||||
|
|
@ -1278,16 +1277,20 @@
|
|||
metabolisms:
|
||||
Medicine:
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
# Begin DeltaV additions
|
||||
- !type:EvenHealthChange # DeltaV - Cryochems heal evenly.
|
||||
conditions:
|
||||
- !type:MobStateCondition
|
||||
mobstate: Dead # It's called NECROsol, not ALIVEsol
|
||||
- !type:Temperature
|
||||
max: 213.0
|
||||
max: 150.0 # Same as Opporozidone for flavor with chemicals for dead bodies.
|
||||
damage:
|
||||
groups:
|
||||
Brute: -4
|
||||
Burn: -5
|
||||
types:
|
||||
Poison: -2
|
||||
Brute: -5 # Was -4 with HealthChange.
|
||||
Burn: -5
|
||||
Airloss: -5 # Added as a buff.
|
||||
Toxin: -5 # Was -2 Poison with HealthChange.
|
||||
Genetic: -5 # Added as a buff.
|
||||
# End DeltaV additions
|
||||
|
||||
- type: reagent
|
||||
id: Aloxadone
|
||||
|
|
@ -1301,16 +1304,13 @@
|
|||
metabolisms:
|
||||
Medicine:
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
- !type:EvenHealthChange # DeltaV - Cryochems heal evenly.
|
||||
conditions:
|
||||
- !type:Temperature
|
||||
max: 213.0
|
||||
damage:
|
||||
types:
|
||||
Cold: -5 # DeltaV - was -4
|
||||
Heat: -5 # DeltaV - was -4
|
||||
Shock: -5 # DeltaV - was -4
|
||||
Caustic: -2 # DeltaV - was -1.5
|
||||
Burn: -7 # DeltaV - Cryochems heal evenly.
|
||||
# Previous values with HealthChange were: -4 Heat/Cold/Shock, -1.5 Caustic
|
||||
|
||||
- type: reagent
|
||||
id: Traumoxadone
|
||||
|
|
@ -1329,7 +1329,7 @@
|
|||
- !type:Temperature
|
||||
max: 213.0
|
||||
damage:
|
||||
Brute: -4
|
||||
Brute: -7 # DeltaV - Was -4
|
||||
|
||||
- type: reagent
|
||||
id : Mannitol # currently this is just a way to create psicodine
|
||||
|
|
@ -1486,14 +1486,14 @@
|
|||
metabolisms:
|
||||
Medicine:
|
||||
effects:
|
||||
- !type:HealthChange
|
||||
- !type:EvenHealthChange # DeltaV - Cryochems heal evenly.
|
||||
conditions:
|
||||
- !type:Temperature
|
||||
max: 213.0
|
||||
damage:
|
||||
groups:
|
||||
Brute: 3
|
||||
Genetic: 1
|
||||
types:
|
||||
Poison: -6
|
||||
Radiation: -3
|
||||
# Begin DeltaV additions
|
||||
Brute: 3
|
||||
Genetic: 1
|
||||
Toxin: -7 # Was -6 Poison and -3 Radiation.
|
||||
# Previous values with HealthChange were: +3 Brute, +1 Genetic, -6 Poison, -3 Radiation
|
||||
# End DeltaV additions
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
- type: entity #den port
|
||||
parent: PaintingBase
|
||||
id: PaintingUnePipe
|
||||
name: The Treachery of Images
|
||||
description: Ceci n'est pas une pipe...
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DEN/Structures/Wallmounts/paintings.rsi
|
||||
state: painting0
|
||||
|
||||
- type: entity #den port
|
||||
parent: PaintingBase
|
||||
id: PaintingTheWrathOfGods
|
||||
name: The Wrath of Gods
|
||||
description: A symbolic painting of a racing horse juxtaposed above a car.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DEN/Structures/Wallmounts/paintings.rsi
|
||||
state: painting1
|
||||
|
||||
- type: entity #den port
|
||||
parent: PaintingBase
|
||||
id: PaintingHumanCondition
|
||||
name: The Human Condition
|
||||
description: A painting of a painting of a beach in front of a door in front of a beach... Really makes you think.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DEN/Structures/Wallmounts/paintings.rsi
|
||||
state: painting2
|
||||
|
||||
- type: entity #den port
|
||||
parent: PaintingBase
|
||||
id: PaintingKnowledge
|
||||
name: Knowledge
|
||||
description: A painting of a daytime landscape with a door. Inside the door is a nighttime landscape.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DEN/Structures/Wallmounts/paintings.rsi
|
||||
state: painting3
|
||||
|
|
@ -222,3 +222,17 @@
|
|||
useDelay: 60
|
||||
- type: InstantAction
|
||||
event: !type:ShatterLightsActionEvent
|
||||
|
||||
- type: entity
|
||||
id: ActionFracturedForm
|
||||
name: Swap Form
|
||||
description: Switch to one of your alternate forms, if you have one. This can also be done by sleeping.
|
||||
components:
|
||||
- type: Action
|
||||
icon:
|
||||
sprite: _DV/Interface/Actions/actions_psionics_small.rsi
|
||||
state: fractured_form
|
||||
useDelay: 60
|
||||
checkCanInteract: false
|
||||
- type: InstantAction
|
||||
event: !type:FracturedFormPowerActionEvent
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
- type: alert
|
||||
id: Grappled
|
||||
clickEvent: !type:EscapeGrappleAlertEvent
|
||||
icons: [ /Textures/_DV/Interface/Alerts/Grappled/grappled.png ]
|
||||
name: alerts-grappled-name
|
||||
description: alerts-grappled-desc
|
||||
|
|
@ -5,13 +5,13 @@
|
|||
id: LockerFillQuarterMasterDeltaV
|
||||
table: !type:AllSelector
|
||||
children:
|
||||
- id: SpaceCashLuckyBill # LO steal objective, see Resources/Prototypes/_DV/Entities/Objects/Misc/first_bill.yml
|
||||
- id: BoxPDACargo
|
||||
- id: QuartermasterIDCard
|
||||
- id: ClothingShoesBootsWinterLogisticsOfficer
|
||||
- id: MiningShuttleConsoleCircuitboard
|
||||
- id: StockTradingCartridge
|
||||
- id: LogisticsTechFabCircuitboard
|
||||
- id: ClothingOuterHardsuitRhino # LO suit and steal objective
|
||||
- id: SalvageExpeditionsComputerCircuitboard
|
||||
- id: FundingAllocationComputerCircuitboard # To be removed when it's in techvault on all maps
|
||||
- id: LunchboxCommandFilledRandom
|
||||
|
|
|
|||
|
|
@ -414,3 +414,39 @@
|
|||
sprite: _DV/Clothing/OuterClothing/Hardsuits/ERTSuits/eliteertjanitor.rsi
|
||||
- type: ToggleableClothing
|
||||
clothingPrototype: ClothingHeadHelmetHardsuitERTJanitorElite
|
||||
|
||||
#LO Hardsuit
|
||||
- type: entity
|
||||
parent: [ClothingOuterHardsuitSalvage, BaseJetpack, BaseCargoContraband]
|
||||
id: ClothingOuterHardsuitRhino
|
||||
name: rhino industrial hardsuit
|
||||
description: A hardsuit adorned with purple fabric and gold metal. Made specifically by Nanotrasen for their Logistics Officers, this hardsuit boasts better protection than most salvage suits and has an internal jetpack.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DV/Clothing/OuterClothing/Hardsuits/rhinosuit.rsi
|
||||
- type: Clothing
|
||||
sprite: _DV/Clothing/OuterClothing/Hardsuits/rhinosuit.rsi
|
||||
- type: Item
|
||||
sprite: _DV/Clothing/OuterClothing/Hardsuits/rhinosuit.rsi
|
||||
- type: Armor
|
||||
modifiers:
|
||||
coefficients:
|
||||
Blunt: 0.7
|
||||
Slash: 0.5
|
||||
Piercing: 0.7
|
||||
Heat: 0.6
|
||||
Radiation: 0.3
|
||||
Caustic: 0.7
|
||||
- type: ClothingSpeedModifier
|
||||
walkModifier: 0.7
|
||||
sprintModifier: 0.7
|
||||
- type: GasTank
|
||||
outputPressure: 21.3
|
||||
air:
|
||||
volume: 5
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 1.025689525 # oxygen
|
||||
- 1.025689525 # nitrogen
|
||||
- type: StealTarget
|
||||
stealGroup: HardsuitRhino
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@
|
|||
- type: Temperature
|
||||
heatDamageThreshold: 315 # 10 lower than base
|
||||
coldDamageThreshold: 240 # 20 lower than base
|
||||
- type: LayingDown
|
||||
- type: Grappler
|
||||
handDisabling: SingleActive
|
||||
grapplingPart: grapple-part-jaws
|
||||
proneOnGrapple: true # Make sure Laika isn't shot by sprays
|
||||
grappleSound:
|
||||
collection: VulpkaninGrowls
|
||||
|
||||
- type: entity
|
||||
parent: MobCarp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
- type: entity
|
||||
parent: BaseSword
|
||||
id: SilverSword
|
||||
name: silver sword
|
||||
description: A beautiful sword made almost entirely of silver. It's blade is dull and can't hold an edge, but perhaps it could be something more...
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DV/Objects/Weapons/Melee/silversword.rsi
|
||||
- type: MeleeWeapon
|
||||
damage:
|
||||
types:
|
||||
Slash: 15
|
||||
- type: Item
|
||||
sprite: _DV/Objects/Weapons/Melee/silversword.rsi
|
||||
- type: Construction
|
||||
graph: RadiantSword
|
||||
node: start
|
||||
- type: Clothing
|
||||
quickEquip: false
|
||||
slots:
|
||||
- back
|
||||
- suitStorage
|
||||
- belt
|
||||
- type: Tag
|
||||
tags:
|
||||
- SilverSword
|
||||
|
||||
- type: entity
|
||||
parent: SilverSword
|
||||
id: EmbeddedSword
|
||||
name: bluespace embedded sword
|
||||
description: you didn't think just adding bluespace would make this a workable weapon, did you?
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DV/Objects/Weapons/Melee/silversword.rsi
|
||||
state: bluespace_embedded
|
||||
- type: Construction
|
||||
graph: RadiantSword
|
||||
node: embeddedsword
|
||||
|
||||
|
||||
- type: entity
|
||||
parent: SilverSword
|
||||
id: RadiantSword
|
||||
name: radiant sword
|
||||
description: A silver sword infused with the light of a Chaplain's faith. While it remains ineffective against the physical, it is a powerful tool against those from beyond the veil.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DV/Objects/Weapons/Melee/radiantsword.rsi
|
||||
- type: MeleeWeapon
|
||||
damage:
|
||||
types:
|
||||
Slash: 15
|
||||
Holy: 15
|
||||
soundHit:
|
||||
path: /Audio/Weapons/bladeslice.ogg
|
||||
- type: Item
|
||||
sprite: _DV/Objects/Weapons/Melee/radiantsword.rsi
|
||||
- type: Construction
|
||||
graph: RadiantSword
|
||||
node: radiantsword
|
||||
- type: RevealRevenantOnCollide
|
||||
- type: CollisionWake
|
||||
enabled: false
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
- id: RoboNeuroticist
|
||||
- id: MenaceSkeleton
|
||||
- id: SkiaSpawn
|
||||
- id: RatKingSpawn
|
||||
|
||||
# Replaces upstream meteor events until they're good
|
||||
- type: entity
|
||||
|
|
@ -159,15 +160,23 @@
|
|||
minimumPlayers: 15
|
||||
earliestStart: 25
|
||||
- type: MidRoundAntagRule
|
||||
# Rat king
|
||||
#- type: entity
|
||||
# parent: BaseMidRoundAntag
|
||||
# id: RatKingSpawn
|
||||
# components:
|
||||
# if you uncomment this update this for antag refactor, below wont work
|
||||
# - type: MidRoundAntagRule
|
||||
# spawner: SpawnPointGhostRatKing
|
||||
# Fugitive
|
||||
|
||||
- type: entity
|
||||
parent: BaseMidRoundAntag
|
||||
id: RatKingSpawn
|
||||
components:
|
||||
- type: StationEvent
|
||||
weight: 7
|
||||
minimumPlayers: 20
|
||||
- type: AntagSpawner
|
||||
prototype: MobRatKing
|
||||
- type: AntagSelection
|
||||
definitions:
|
||||
- spawnerPrototype: SpawnPointGhostRatKing
|
||||
min: 1
|
||||
max: 1
|
||||
pickPlayer: false
|
||||
|
||||
- type: entity
|
||||
parent: BaseMidRoundAntag
|
||||
id: Fugitive
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
parent: [BaseAsakimObjective, BaseSurviveObjective]
|
||||
id: AsakimTheftObjective
|
||||
name: ">CONFISCATE"
|
||||
description: Records indicate that this sector may have valuable artifacts. Confiscate such items for further study.
|
||||
description: Records indicate that this sector may have valuable items. Confiscate such items for further study.
|
||||
components:
|
||||
- type: Objective
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue