Merge branch 'space-wizards:master' into ion-storm-refactor
This commit is contained in:
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -16,7 +16,7 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: '**/*.swsl'
|
||||
|
||||
"No C#":
|
||||
"Changes: No C#":
|
||||
- changed-files:
|
||||
# Equiv to any-glob-to-all as long as this has one matcher. If ALL changed files are not C# files, then apply label.
|
||||
- all-globs-to-all-files: "!**/*.cs"
|
||||
|
||||
@@ -16,6 +16,6 @@ jobs:
|
||||
- name: Check for Merge Conflicts
|
||||
uses: eps1lon/actions-label-merge-conflict@v3.0.0
|
||||
with:
|
||||
dirtyLabel: "Merge Conflict"
|
||||
dirtyLabel: "S: Merge Conflict"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
commentOnDirty: "This pull request has conflicts, please resolve those before we can evaluate the pull request."
|
||||
4
.github/workflows/labeler-needsreview.yml
vendored
4
.github/workflows/labeler-needsreview.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
labels: "Status: Needs Review"
|
||||
labels: "S: Needs Review"
|
||||
- uses: actions-ecosystem/action-remove-labels@v1
|
||||
with:
|
||||
labels: "Status: Awaiting Changes"
|
||||
labels: "S: Awaiting Changes"
|
||||
|
||||
20
.github/workflows/labeler-size.yml
vendored
Normal file
20
.github/workflows/labeler-size.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: "Labels: Size"
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
size-label:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: size-label
|
||||
uses: "pascalgn/size-label-action@v0.5.5"
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
with:
|
||||
# Custom size configuration
|
||||
sizes: >
|
||||
{
|
||||
"0": "XS",
|
||||
"10": "S",
|
||||
"30": "M",
|
||||
"100": "L",
|
||||
"1000": "XL"
|
||||
}
|
||||
2
.github/workflows/labeler-stable.yml
vendored
2
.github/workflows/labeler-stable.yml
vendored
@@ -13,4 +13,4 @@ jobs:
|
||||
steps:
|
||||
- uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
labels: "Branch: stable"
|
||||
labels: "Branch: Stable"
|
||||
|
||||
2
.github/workflows/labeler-staging.yml
vendored
2
.github/workflows/labeler-staging.yml
vendored
@@ -13,4 +13,4 @@ jobs:
|
||||
steps:
|
||||
- uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
labels: "Branch: staging"
|
||||
labels: "Branch: Staging"
|
||||
|
||||
4
.github/workflows/labeler-untriaged.yml
vendored
4
.github/workflows/labeler-untriaged.yml
vendored
@@ -3,6 +3,8 @@
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
add_label:
|
||||
@@ -11,4 +13,4 @@ jobs:
|
||||
- uses: actions-ecosystem/action-add-labels@v1
|
||||
if: join(github.event.issue.labels) == ''
|
||||
with:
|
||||
labels: "Status: Untriaged"
|
||||
labels: "S: Untriaged"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<Label Name="ExpiryLabel" Text="{Loc admin-note-editor-expiry-label}" Visible="False" />
|
||||
<HistoryLineEdit Name="ExpiryLineEdit" PlaceHolder="{Loc admin-note-editor-expiry-placeholder}"
|
||||
Visible="False" HorizontalExpand="True" />
|
||||
<OptionButton Name="ExpiryLengthDropdown" Visible="False" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
|
||||
<OptionButton Name="TypeOption" HorizontalAlignment="Center" />
|
||||
|
||||
@@ -17,6 +17,17 @@ public sealed partial class NoteEdit : FancyWindow
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IClientConsoleHost _console = default!;
|
||||
|
||||
private enum Multipliers
|
||||
{
|
||||
Minutes,
|
||||
Hours,
|
||||
Days,
|
||||
Weeks,
|
||||
Months,
|
||||
Years,
|
||||
Centuries
|
||||
}
|
||||
|
||||
public event Action<int, NoteType, string, NoteSeverity?, bool, DateTime?>? SubmitPressed;
|
||||
|
||||
public NoteEdit(SharedAdminNote? note, string playerName, bool canCreate, bool canEdit)
|
||||
@@ -31,6 +42,20 @@ public sealed partial class NoteEdit : FancyWindow
|
||||
|
||||
ResetSubmitButton();
|
||||
|
||||
// It's weird to use minutes as the IDs, but it works and makes sense kind of :)
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-minutes"), (int) Multipliers.Minutes);
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-hours"), (int) Multipliers.Hours);
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-days"), (int) Multipliers.Days);
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-weeks"), (int) Multipliers.Weeks);
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-months"), (int) Multipliers.Months);
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-years"), (int) Multipliers.Years);
|
||||
ExpiryLengthDropdown.AddItem(Loc.GetString("admin-note-button-centuries"), (int) Multipliers.Centuries);
|
||||
ExpiryLengthDropdown.OnItemSelected += OnLengthChanged;
|
||||
|
||||
ExpiryLengthDropdown.SelectId((int) Multipliers.Weeks);
|
||||
|
||||
ExpiryLineEdit.OnTextChanged += OnTextChanged;
|
||||
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-note"), (int) NoteType.Note);
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-message"), (int) NoteType.Message);
|
||||
TypeOption.AddItem(Loc.GetString("admin-note-editor-type-watchlist"), (int) NoteType.Watchlist);
|
||||
@@ -172,8 +197,9 @@ public sealed partial class NoteEdit : FancyWindow
|
||||
{
|
||||
ExpiryLabel.Visible = !PermanentCheckBox.Pressed;
|
||||
ExpiryLineEdit.Visible = !PermanentCheckBox.Pressed;
|
||||
ExpiryLengthDropdown.Visible = !PermanentCheckBox.Pressed;
|
||||
|
||||
ExpiryLineEdit.Text = !PermanentCheckBox.Pressed ? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") : string.Empty;
|
||||
ExpiryLineEdit.Text = !PermanentCheckBox.Pressed ? 1.ToString() : string.Empty;
|
||||
}
|
||||
|
||||
private void OnSecretPressed(BaseButton.ButtonEventArgs _)
|
||||
@@ -187,6 +213,16 @@ public sealed partial class NoteEdit : FancyWindow
|
||||
SeverityOption.SelectId(args.Id);
|
||||
}
|
||||
|
||||
private void OnLengthChanged(OptionButton.ItemSelectedEventArgs args)
|
||||
{
|
||||
ExpiryLengthDropdown.SelectId(args.Id);
|
||||
}
|
||||
|
||||
private void OnTextChanged(HistoryLineEdit.LineEditEventArgs args)
|
||||
{
|
||||
ParseExpiryTime();
|
||||
}
|
||||
|
||||
private void OnSubmitButtonPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
if (!ParseExpiryTime())
|
||||
@@ -263,13 +299,24 @@ public sealed partial class NoteEdit : FancyWindow
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(ExpiryLineEdit.Text) || !DateTime.TryParse(ExpiryLineEdit.Text, out var result) || DateTime.UtcNow > result)
|
||||
if (string.IsNullOrWhiteSpace(ExpiryLineEdit.Text) || !uint.TryParse(ExpiryLineEdit.Text, out var inputInt))
|
||||
{
|
||||
ExpiryLineEdit.ModulateSelfOverride = Color.Red;
|
||||
return false;
|
||||
}
|
||||
|
||||
ExpiryTime = result.ToUniversalTime();
|
||||
var mult = ExpiryLengthDropdown.SelectedId switch
|
||||
{
|
||||
(int) Multipliers.Minutes => TimeSpan.FromMinutes(1).TotalMinutes,
|
||||
(int) Multipliers.Hours => TimeSpan.FromHours(1).TotalMinutes,
|
||||
(int) Multipliers.Days => TimeSpan.FromDays(1).TotalMinutes,
|
||||
(int) Multipliers.Weeks => TimeSpan.FromDays(7).TotalMinutes,
|
||||
(int) Multipliers.Months => TimeSpan.FromDays(30).TotalMinutes,
|
||||
(int) Multipliers.Years => TimeSpan.FromDays(365).TotalMinutes,
|
||||
(int) Multipliers.Centuries => TimeSpan.FromDays(36525).TotalMinutes,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(ExpiryLengthDropdown.SelectedId), "Multiplier out of range :(")
|
||||
};
|
||||
ExpiryTime = DateTime.UtcNow.AddMinutes(inputInt * mult);
|
||||
ExpiryLineEdit.ModulateSelfOverride = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ClothingComponent, GetEquipmentVisualsEvent>(OnGetVisuals);
|
||||
SubscribeLocalEvent<ClothingComponent, InventoryTemplateUpdated>(OnInventoryTemplateUpdated);
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, VisualsChangedEvent>(OnVisualsChanged);
|
||||
SubscribeLocalEvent<SpriteComponent, DidUnequipEvent>(OnDidUnequip);
|
||||
@@ -70,11 +71,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
if (args.Sprite == null)
|
||||
return;
|
||||
|
||||
var enumerator = _inventorySystem.GetSlotEnumerator((uid, component));
|
||||
while (enumerator.NextItem(out var item, out var slot))
|
||||
{
|
||||
RenderEquipment(uid, item, slot.Name, component);
|
||||
}
|
||||
UpdateAllSlots(uid, component);
|
||||
|
||||
// No clothing equipped -> make sure the layer is hidden, though this should already be handled by on-unequip.
|
||||
if (args.Sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
|
||||
@@ -84,6 +81,23 @@ public sealed class ClientClothingSystem : ClothingSystem
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInventoryTemplateUpdated(Entity<ClothingComponent> ent, ref InventoryTemplateUpdated args)
|
||||
{
|
||||
UpdateAllSlots(ent.Owner, clothing: ent.Comp);
|
||||
}
|
||||
|
||||
private void UpdateAllSlots(
|
||||
EntityUid uid,
|
||||
InventoryComponent? inventoryComponent = null,
|
||||
ClothingComponent? clothing = null)
|
||||
{
|
||||
var enumerator = _inventorySystem.GetSlotEnumerator((uid, inventoryComponent));
|
||||
while (enumerator.NextItem(out var item, out var slot))
|
||||
{
|
||||
RenderEquipment(uid, item, slot.Name, inventoryComponent, clothingComponent: clothing);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGetVisuals(EntityUid uid, ClothingComponent item, GetEquipmentVisualsEvent args)
|
||||
{
|
||||
if (!TryComp(args.Equipee, out InventoryComponent? inventory))
|
||||
|
||||
@@ -235,9 +235,23 @@ namespace Content.Client.Inventory
|
||||
EntityManager.RaisePredictiveEvent(new InteractInventorySlotEvent(GetNetEntity(item.Value), altInteract: true));
|
||||
}
|
||||
|
||||
protected override void UpdateInventoryTemplate(Entity<InventoryComponent> ent)
|
||||
{
|
||||
base.UpdateInventoryTemplate(ent);
|
||||
|
||||
if (TryComp(ent, out InventorySlotsComponent? inventorySlots))
|
||||
{
|
||||
foreach (var slot in ent.Comp.Slots)
|
||||
{
|
||||
if (inventorySlots.SlotData.TryGetValue(slot.Name, out var slotData))
|
||||
slotData.SlotDef = slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SlotData
|
||||
{
|
||||
public readonly SlotDefinition SlotDef;
|
||||
public SlotDefinition SlotDef;
|
||||
public EntityUid? HeldEntity => Container?.ContainedEntity;
|
||||
public bool Blocked;
|
||||
public bool Highlighted;
|
||||
|
||||
@@ -14,6 +14,7 @@ public abstract class EquipmentHudSystem<T> : EntitySystem where T : IComponent
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
[ViewVariables]
|
||||
protected bool IsActive;
|
||||
protected virtual SlotFlags TargetSlots => ~SlotFlags.POCKET;
|
||||
|
||||
@@ -102,7 +103,7 @@ public abstract class EquipmentHudSystem<T> : EntitySystem where T : IComponent
|
||||
args.Components.Add(component);
|
||||
}
|
||||
|
||||
private void RefreshOverlay(EntityUid uid)
|
||||
protected void RefreshOverlay(EntityUid uid)
|
||||
{
|
||||
if (uid != _player.LocalSession?.AttachedEntity)
|
||||
return;
|
||||
|
||||
@@ -21,9 +21,16 @@ public sealed class ShowHealthBarsSystem : EquipmentHudSystem<ShowHealthBarsComp
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ShowHealthBarsComponent, AfterAutoHandleStateEvent>(OnHandleState);
|
||||
|
||||
_overlay = new(EntityManager, _prototype);
|
||||
}
|
||||
|
||||
private void OnHandleState(Entity<ShowHealthBarsComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
RefreshOverlay(ent);
|
||||
}
|
||||
|
||||
protected override void UpdateInternal(RefreshEquipmentHudEvent<ShowHealthBarsComponent> component)
|
||||
{
|
||||
base.UpdateInternal(component);
|
||||
|
||||
@@ -17,6 +17,7 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem<ShowHealthIconsCo
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeMan = default!;
|
||||
|
||||
[ViewVariables]
|
||||
public HashSet<string> DamageContainers = new();
|
||||
|
||||
public override void Initialize()
|
||||
@@ -24,6 +25,7 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem<ShowHealthIconsCo
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DamageableComponent, GetStatusIconsEvent>(OnGetStatusIconsEvent);
|
||||
SubscribeLocalEvent<ShowHealthIconsComponent, AfterAutoHandleStateEvent>(OnHandleState);
|
||||
}
|
||||
|
||||
protected override void UpdateInternal(RefreshEquipmentHudEvent<ShowHealthIconsComponent> component)
|
||||
@@ -43,6 +45,11 @@ public sealed class ShowHealthIconsSystem : EquipmentHudSystem<ShowHealthIconsCo
|
||||
DamageContainers.Clear();
|
||||
}
|
||||
|
||||
private void OnHandleState(Entity<ShowHealthIconsComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
RefreshOverlay(ent);
|
||||
}
|
||||
|
||||
private void OnGetStatusIconsEvent(Entity<DamageableComponent> entity, ref GetStatusIconsEvent args)
|
||||
{
|
||||
if (!IsActive)
|
||||
|
||||
@@ -131,7 +131,8 @@ public sealed partial class BorgMenu : FancyWindow
|
||||
_modules.Clear();
|
||||
foreach (var module in chassis.ModuleContainer.ContainedEntities)
|
||||
{
|
||||
var control = new BorgModuleControl(module, _entity);
|
||||
var moduleComponent = _entity.GetComponent<BorgModuleComponent>(module);
|
||||
var control = new BorgModuleControl(module, _entity, !moduleComponent.DefaultModule);
|
||||
control.RemoveButtonPressed += () =>
|
||||
{
|
||||
RemoveModuleButtonPressed?.Invoke(module);
|
||||
|
||||
@@ -9,7 +9,7 @@ public sealed partial class BorgModuleControl : PanelContainer
|
||||
{
|
||||
public Action? RemoveButtonPressed;
|
||||
|
||||
public BorgModuleControl(EntityUid entity, IEntityManager entityManager)
|
||||
public BorgModuleControl(EntityUid entity, IEntityManager entityManager, bool canRemove)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
@@ -20,6 +20,7 @@ public sealed partial class BorgModuleControl : PanelContainer
|
||||
{
|
||||
RemoveButtonPressed?.Invoke();
|
||||
};
|
||||
RemoveButton.Visible = canRemove;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
43
Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml
Normal file
43
Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml
Normal file
@@ -0,0 +1,43 @@
|
||||
<controls:FancyWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
Title="{Loc 'borg-select-type-menu-title'}"
|
||||
SetSize="550 300">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal" VerticalExpand="True">
|
||||
<!-- Left pane: selection of borg type -->
|
||||
<BoxContainer Orientation="Vertical" MinWidth="200" Margin="2 0">
|
||||
<Label Text="{Loc 'borg-select-type-menu-available'}" StyleClasses="LabelHeading" />
|
||||
<ScrollContainer HScrollEnabled="False" VerticalExpand="True">
|
||||
<BoxContainer Name="SelectionsContainer" Orientation="Vertical" />
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<customControls:VSeparator />
|
||||
|
||||
<!-- Right pane: information about selected borg module, confirm button. -->
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="2 0">
|
||||
<Label Text="{Loc 'borg-select-type-menu-information'}" StyleClasses="LabelHeading" />
|
||||
<Control VerticalExpand="True">
|
||||
<controls:Placeholder Name="InfoPlaceholder" PlaceholderText="{Loc 'borg-select-type-menu-select-type'}" />
|
||||
<BoxContainer Name="InfoContents" Orientation="Vertical" Visible="False">
|
||||
<BoxContainer Orientation="Horizontal" Margin="0 0 0 4">
|
||||
<EntityPrototypeView Name="ChassisView" Scale="2,2" />
|
||||
<Label Name="NameLabel" HorizontalExpand="True" />
|
||||
</BoxContainer>
|
||||
|
||||
<RichTextLabel Name="DescriptionLabel" VerticalExpand="True" VerticalAlignment="Top" />
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
<controls:ConfirmButton Name="ConfirmTypeButton" Text="{Loc 'borg-select-type-menu-confirm'}"
|
||||
Disabled="True" HorizontalAlignment="Right"
|
||||
MinWidth="200" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<controls:StripeBack Margin="0 0 0 4">
|
||||
<Label Text="{Loc 'borg-select-type-menu-bottom-text'}" HorizontalAlignment="Center" StyleClasses="LabelSubText" Margin="4 4 0 4"/>
|
||||
</controls:StripeBack>
|
||||
</BoxContainer>
|
||||
|
||||
</controls:FancyWindow>
|
||||
81
Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs
Normal file
81
Content.Client/Silicons/Borgs/BorgSelectTypeMenu.xaml.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using System.Linq;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Systems.Guidebook;
|
||||
using Content.Shared.Guidebook;
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Menu used by borgs to select their type.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgSelectTypeUserInterface"/>
|
||||
/// <seealso cref="BorgSwitchableTypeComponent"/>
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class BorgSelectTypeMenu : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
private BorgTypePrototype? _selectedBorgType;
|
||||
|
||||
public event Action<ProtoId<BorgTypePrototype>>? ConfirmedBorgType;
|
||||
|
||||
[ValidatePrototypeId<GuideEntryPrototype>]
|
||||
private static readonly List<ProtoId<GuideEntryPrototype>> GuidebookEntries = new() { "Cyborgs", "Robotics" };
|
||||
|
||||
public BorgSelectTypeMenu()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
var group = new ButtonGroup();
|
||||
foreach (var borgType in _prototypeManager.EnumeratePrototypes<BorgTypePrototype>().OrderBy(PrototypeName))
|
||||
{
|
||||
var button = new Button
|
||||
{
|
||||
Text = PrototypeName(borgType),
|
||||
Group = group,
|
||||
};
|
||||
button.OnPressed += _ =>
|
||||
{
|
||||
_selectedBorgType = borgType;
|
||||
UpdateInformation(borgType);
|
||||
};
|
||||
SelectionsContainer.AddChild(button);
|
||||
}
|
||||
|
||||
ConfirmTypeButton.OnPressed += ConfirmButtonPressed;
|
||||
HelpGuidebookIds = GuidebookEntries;
|
||||
}
|
||||
|
||||
private void UpdateInformation(BorgTypePrototype prototype)
|
||||
{
|
||||
_selectedBorgType = prototype;
|
||||
|
||||
InfoContents.Visible = true;
|
||||
InfoPlaceholder.Visible = false;
|
||||
ConfirmTypeButton.Disabled = false;
|
||||
|
||||
NameLabel.Text = PrototypeName(prototype);
|
||||
DescriptionLabel.Text = Loc.GetString($"borg-type-{prototype.ID}-desc");
|
||||
ChassisView.SetPrototype(prototype.DummyPrototype);
|
||||
}
|
||||
|
||||
private void ConfirmButtonPressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_selectedBorgType == null)
|
||||
return;
|
||||
|
||||
ConfirmedBorgType?.Invoke(_selectedBorgType);
|
||||
}
|
||||
|
||||
private static string PrototypeName(BorgTypePrototype prototype)
|
||||
{
|
||||
return Loc.GetString($"borg-type-{prototype.ID}-name");
|
||||
}
|
||||
}
|
||||
30
Content.Client/Silicons/Borgs/BorgSelectTypeUserInterface.cs
Normal file
30
Content.Client/Silicons/Borgs/BorgSelectTypeUserInterface.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// User interface used by borgs to select their type.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgSelectTypeMenu"/>
|
||||
/// <seealso cref="BorgSwitchableTypeComponent"/>
|
||||
/// <seealso cref="BorgSwitchableTypeUiKey"/>
|
||||
[UsedImplicitly]
|
||||
public sealed class BorgSelectTypeUserInterface : BoundUserInterface
|
||||
{
|
||||
[ViewVariables]
|
||||
private BorgSelectTypeMenu? _menu;
|
||||
|
||||
public BorgSelectTypeUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_menu = this.CreateWindow<BorgSelectTypeMenu>();
|
||||
_menu.ConfirmedBorgType += prototype => SendMessage(new BorgSelectTypeMessage(prototype));
|
||||
}
|
||||
}
|
||||
81
Content.Client/Silicons/Borgs/BorgSwitchableTypeSystem.cs
Normal file
81
Content.Client/Silicons/Borgs/BorgSwitchableTypeSystem.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Client side logic for borg type switching. Sets up primarily client-side visual information.
|
||||
/// </summary>
|
||||
/// <seealso cref="SharedBorgSwitchableTypeSystem"/>
|
||||
/// <seealso cref="BorgSwitchableTypeComponent"/>
|
||||
public sealed class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeSystem
|
||||
{
|
||||
[Dependency] private readonly BorgSystem _borgSystem = default!;
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, AfterAutoHandleStateEvent>(AfterStateHandler);
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, ComponentStartup>(OnComponentStartup);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(Entity<BorgSwitchableTypeComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
UpdateEntityAppearance(ent);
|
||||
}
|
||||
|
||||
private void AfterStateHandler(Entity<BorgSwitchableTypeComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateEntityAppearance(ent);
|
||||
}
|
||||
|
||||
protected override void UpdateEntityAppearance(
|
||||
Entity<BorgSwitchableTypeComponent> entity,
|
||||
BorgTypePrototype prototype)
|
||||
{
|
||||
if (TryComp(entity, out SpriteComponent? sprite))
|
||||
{
|
||||
sprite.LayerSetState(BorgVisualLayers.Body, prototype.SpriteBodyState);
|
||||
sprite.LayerSetState(BorgVisualLayers.LightStatus, prototype.SpriteToggleLightState);
|
||||
}
|
||||
|
||||
if (TryComp(entity, out BorgChassisComponent? chassis))
|
||||
{
|
||||
_borgSystem.SetMindStates(
|
||||
(entity.Owner, chassis),
|
||||
prototype.SpriteHasMindState,
|
||||
prototype.SpriteNoMindState);
|
||||
|
||||
if (TryComp(entity, out AppearanceComponent? appearance))
|
||||
{
|
||||
// Queue update so state changes apply.
|
||||
_appearance.QueueUpdate(entity, appearance);
|
||||
}
|
||||
}
|
||||
|
||||
if (prototype.SpriteBodyMovementState is { } movementState)
|
||||
{
|
||||
var spriteMovement = EnsureComp<SpriteMovementComponent>(entity);
|
||||
spriteMovement.NoMovementLayers.Clear();
|
||||
spriteMovement.NoMovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = prototype.SpriteBodyState,
|
||||
};
|
||||
spriteMovement.MovementLayers.Clear();
|
||||
spriteMovement.MovementLayers["movement"] = new PrototypeLayerData
|
||||
{
|
||||
State = movementState,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
RemComp<SpriteMovementComponent>(entity);
|
||||
}
|
||||
|
||||
base.UpdateEntityAppearance(entity, prototype);
|
||||
}
|
||||
}
|
||||
@@ -92,4 +92,18 @@ public sealed class BorgSystem : SharedBorgSystem
|
||||
sprite.LayerSetState(MMIVisualLayers.Base, state);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the sprite states used for the borg "is there a mind or not" indication.
|
||||
/// </summary>
|
||||
/// <param name="borg">The entity and component to modify.</param>
|
||||
/// <param name="hasMindState">The state to use if the borg has a mind.</param>
|
||||
/// <param name="noMindState">The state to use if the borg has no mind.</param>
|
||||
/// <seealso cref="BorgChassisComponent.HasMindState"/>
|
||||
/// <seealso cref="BorgChassisComponent.NoMindState"/>
|
||||
public void SetMindStates(Entity<BorgChassisComponent> borg, string hasMindState, string noMindState)
|
||||
{
|
||||
borg.Comp.HasMindState = hasMindState;
|
||||
borg.Comp.NoMindState = noMindState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,8 +146,8 @@ namespace Content.Server.Abilities.Mime
|
||||
mimePowers.ReadyToRepent = false;
|
||||
mimePowers.VowBroken = false;
|
||||
AddComp<MutedComponent>(uid);
|
||||
_alertsSystem.ClearAlert(uid, mimePowers.VowAlert);
|
||||
_alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert);
|
||||
_alertsSystem.ClearAlert(uid, mimePowers.VowBrokenAlert);
|
||||
_alertsSystem.ShowAlert(uid, mimePowers.VowAlert);
|
||||
_actionsSystem.AddAction(uid, ref mimePowers.InvisibleWallActionEntity, mimePowers.InvisibleWallAction, uid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ using Content.Shared.Administration;
|
||||
using Content.Shared.Administration.Components;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Clumsy;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Cluwne;
|
||||
using Content.Shared.Damage;
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
using Content.Server.Administration.Components;
|
||||
using Content.Shared.Climbing.Components;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Climbing.Systems;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Clumsy;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
|
||||
namespace Content.Server.Administration.Systems;
|
||||
|
||||
public sealed class SuperBonkSystem: EntitySystem
|
||||
public sealed class SuperBonkSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly BonkSystem _bonkSystem = default!;
|
||||
[Dependency] private readonly ClumsySystem _clumsySystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SuperBonkComponent, ComponentShutdown>(OnBonkShutdown);
|
||||
SubscribeLocalEvent<SuperBonkComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||
SubscribeLocalEvent<SuperBonkComponent, ComponentShutdown>(OnBonkShutdown);
|
||||
}
|
||||
|
||||
public void StartSuperBonk(EntityUid target, float delay = 0.1f, bool stopWhenDead = false )
|
||||
public void StartSuperBonk(EntityUid target, float delay = 0.1f, bool stopWhenDead = false)
|
||||
{
|
||||
|
||||
//The other check in the code to stop when the target dies does not work if the target is already dead.
|
||||
@@ -31,7 +31,6 @@ public sealed class SuperBonkSystem: EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var hadClumsy = EnsureComp<ClumsyComponent>(target, out _);
|
||||
|
||||
var tables = EntityQueryEnumerator<BonkableComponent>();
|
||||
@@ -79,16 +78,17 @@ public sealed class SuperBonkSystem: EntitySystem
|
||||
private void Bonk(SuperBonkComponent comp)
|
||||
{
|
||||
var uid = comp.Tables.Current.Key;
|
||||
var bonkComp = comp.Tables.Current.Value;
|
||||
|
||||
// It would be very weird for something without a transform component to have a bonk component
|
||||
// but just in case because I don't want to crash the server.
|
||||
if (!HasComp<TransformComponent>(uid))
|
||||
if (!HasComp<TransformComponent>(uid) || !TryComp<ClumsyComponent>(comp.Target, out var clumsyComp))
|
||||
return;
|
||||
|
||||
_transformSystem.SetCoordinates(comp.Target, Transform(uid).Coordinates);
|
||||
|
||||
_bonkSystem.TryBonk(comp.Target, uid, bonkComp);
|
||||
_clumsySystem.HitHeadClumsy((comp.Target, clumsyComp), uid);
|
||||
|
||||
_audioSystem.PlayPvs(clumsyComp.TableBonkSound, comp.Target);
|
||||
}
|
||||
|
||||
private void OnMobStateChanged(EntityUid uid, SuperBonkComponent comp, MobStateChangedEvent args)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Chemistry.Hypospray.Events;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.FixedPoint;
|
||||
@@ -85,14 +86,44 @@ public sealed class HypospraySystem : SharedHypospraySystem
|
||||
|
||||
string? msgFormat = null;
|
||||
|
||||
if (target == user)
|
||||
msgFormat = "hypospray-component-inject-self-message";
|
||||
else if (EligibleEntity(user, EntityManager, component) && _interaction.TryRollClumsy(user, component.ClumsyFailChance))
|
||||
// Self event
|
||||
var selfEvent = new SelfBeforeHyposprayInjectsEvent(user, entity.Owner, target);
|
||||
RaiseLocalEvent(user, selfEvent);
|
||||
|
||||
if (selfEvent.Cancelled)
|
||||
{
|
||||
msgFormat = "hypospray-component-inject-self-clumsy-message";
|
||||
target = user;
|
||||
_popup.PopupEntity(Loc.GetString(selfEvent.InjectMessageOverride ?? "hypospray-cant-inject", ("owner", Identity.Entity(target, EntityManager))), target, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = selfEvent.TargetGettingInjected;
|
||||
|
||||
if (!EligibleEntity(target, EntityManager, component))
|
||||
return false;
|
||||
|
||||
// Target event
|
||||
var targetEvent = new TargetBeforeHyposprayInjectsEvent(user, entity.Owner, target);
|
||||
RaiseLocalEvent(target, targetEvent);
|
||||
|
||||
if (targetEvent.Cancelled)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString(targetEvent.InjectMessageOverride ?? "hypospray-cant-inject", ("owner", Identity.Entity(target, EntityManager))), target, user);
|
||||
return false;
|
||||
}
|
||||
|
||||
target = targetEvent.TargetGettingInjected;
|
||||
|
||||
if (!EligibleEntity(target, EntityManager, component))
|
||||
return false;
|
||||
|
||||
// The target event gets priority for the overriden message.
|
||||
if (targetEvent.InjectMessageOverride != null)
|
||||
msgFormat = targetEvent.InjectMessageOverride;
|
||||
else if (selfEvent.InjectMessageOverride != null)
|
||||
msgFormat = selfEvent.InjectMessageOverride;
|
||||
else if (target == user)
|
||||
msgFormat = "hypospray-component-inject-self-message";
|
||||
|
||||
if (!_solutionContainers.TryGetSolution(uid, component.SolutionName, out var hypoSpraySoln, out var hypoSpraySolution) || hypoSpraySolution.Volume == 0)
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("hypospray-component-empty-message"), target, user);
|
||||
|
||||
@@ -16,6 +16,7 @@ using Content.Shared.Cluwne;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Content.Shared.NameModifier.EntitySystems;
|
||||
using Content.Shared.Clumsy;
|
||||
|
||||
namespace Content.Server.Cluwne;
|
||||
|
||||
|
||||
@@ -77,7 +77,20 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
Zap(uid, target, args.User, component);
|
||||
}
|
||||
|
||||
public bool CanZap(EntityUid uid, EntityUid target, EntityUid? user = null, DefibrillatorComponent? component = null)
|
||||
/// <summary>
|
||||
/// Checks if you can actually defib a target.
|
||||
/// </summary>
|
||||
/// <param name="uid">Uid of the defib</param>
|
||||
/// <param name="target">Uid of the target getting defibbed</param>
|
||||
/// <param name="user">Uid of the entity using the defibrillator</param>
|
||||
/// <param name="component">Defib component</param>
|
||||
/// <param name="targetCanBeAlive">
|
||||
/// If true, the target can be alive. If false, the function will check if the target is alive and will return false if they are.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Returns true if the target is valid to be defibed, false otherwise.
|
||||
/// </returns>
|
||||
public bool CanZap(EntityUid uid, EntityUid target, EntityUid? user = null, DefibrillatorComponent? component = null, bool targetCanBeAlive = false)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return false;
|
||||
@@ -98,15 +111,25 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
if (!_powerCell.HasActivatableCharge(uid, user: user))
|
||||
return false;
|
||||
|
||||
if (_mobState.IsAlive(target, mobState))
|
||||
if (!targetCanBeAlive && _mobState.IsAlive(target, mobState))
|
||||
return false;
|
||||
|
||||
if (!component.CanDefibCrit && _mobState.IsCritical(target, mobState))
|
||||
if (!targetCanBeAlive && !component.CanDefibCrit && _mobState.IsCritical(target, mobState))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to start defibrillating the target. If the target is valid, will start the defib do-after.
|
||||
/// </summary>
|
||||
/// <param name="uid">Uid of the defib</param>
|
||||
/// <param name="target">Uid of the target getting defibbed</param>
|
||||
/// <param name="user">Uid of the entity using the defibrillator</param>
|
||||
/// <param name="component">Defib component</param>
|
||||
/// <returns>
|
||||
/// Returns true if the defibrillation do-after started, otherwise false.
|
||||
/// </returns>
|
||||
public bool TryStartZap(EntityUid uid, EntityUid target, EntityUid user, DefibrillatorComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
@@ -118,27 +141,44 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
_audio.PlayPvs(component.ChargeSound, uid);
|
||||
return _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, component.DoAfterDuration, new DefibrillatorZapDoAfterEvent(),
|
||||
uid, target, uid)
|
||||
{
|
||||
NeedHand = true,
|
||||
BreakOnMove = !component.AllowDoAfterMovement
|
||||
});
|
||||
{
|
||||
NeedHand = true,
|
||||
BreakOnMove = !component.AllowDoAfterMovement
|
||||
});
|
||||
}
|
||||
|
||||
public void Zap(EntityUid uid, EntityUid target, EntityUid user, DefibrillatorComponent? component = null, MobStateComponent? mob = null, MobThresholdsComponent? thresholds = null)
|
||||
/// <summary>
|
||||
/// Tries to defibrillate the target with the given defibrillator.
|
||||
/// </summary>
|
||||
public void Zap(EntityUid uid, EntityUid target, EntityUid user, DefibrillatorComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component) || !Resolve(target, ref mob, ref thresholds, false))
|
||||
if (!Resolve(uid, ref component))
|
||||
return;
|
||||
|
||||
// clowns zap themselves
|
||||
if (HasComp<ClumsyComponent>(user) && user != target)
|
||||
{
|
||||
Zap(uid, user, user, component);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_powerCell.TryUseActivatableCharge(uid, user: user))
|
||||
return;
|
||||
|
||||
var selfEvent = new SelfBeforeDefibrillatorZapsEvent(user, uid, target);
|
||||
RaiseLocalEvent(user, selfEvent);
|
||||
|
||||
target = selfEvent.DefibTarget;
|
||||
|
||||
// Ensure thet new target is still valid.
|
||||
if (selfEvent.Cancelled || !CanZap(uid, target, user, component, true))
|
||||
return;
|
||||
|
||||
var targetEvent = new TargetBeforeDefibrillatorZapsEvent(user, uid, target);
|
||||
RaiseLocalEvent(target, targetEvent);
|
||||
|
||||
target = targetEvent.DefibTarget;
|
||||
|
||||
if (targetEvent.Cancelled || !CanZap(uid, target, user, component, true))
|
||||
return;
|
||||
|
||||
if (!TryComp<MobStateComponent>(target, out var mob) ||
|
||||
!TryComp<MobThresholdsComponent>(target, out var thresholds))
|
||||
return;
|
||||
|
||||
_audio.PlayPvs(component.ZapSound, uid);
|
||||
_electrocution.TryDoElectrocution(target, null, component.ZapDamage, component.WritheDuration, true, ignoreInsulation: true);
|
||||
component.NextZapTime = _timing.CurTime + component.ZapDelay;
|
||||
|
||||
82
Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
Normal file
82
Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using Content.Server.Inventory;
|
||||
using Content.Server.Radio.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Server-side logic for borg type switching. Handles more heavyweight and server-specific switching logic.
|
||||
/// </summary>
|
||||
public sealed class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeSystem
|
||||
{
|
||||
[Dependency] private readonly BorgSystem _borgSystem = default!;
|
||||
[Dependency] private readonly ServerInventorySystem _inventorySystem = default!;
|
||||
|
||||
protected override void SelectBorgModule(Entity<BorgSwitchableTypeComponent> ent, ProtoId<BorgTypePrototype> borgType)
|
||||
{
|
||||
var prototype = Prototypes.Index(borgType);
|
||||
|
||||
// Assign radio channels
|
||||
string[] radioChannels = [.. ent.Comp.InherentRadioChannels, .. prototype.RadioChannels];
|
||||
if (TryComp(ent, out IntrinsicRadioTransmitterComponent? transmitter))
|
||||
transmitter.Channels = [.. radioChannels];
|
||||
|
||||
if (TryComp(ent, out ActiveRadioComponent? activeRadio))
|
||||
activeRadio.Channels = [.. radioChannels];
|
||||
|
||||
// Borg transponder for the robotics console
|
||||
if (TryComp(ent, out BorgTransponderComponent? transponder))
|
||||
{
|
||||
_borgSystem.SetTransponderSprite(
|
||||
(ent.Owner, transponder),
|
||||
new SpriteSpecifier.Rsi(new ResPath("Mobs/Silicon/chassis.rsi"), prototype.SpriteBodyState));
|
||||
|
||||
_borgSystem.SetTransponderName(
|
||||
(ent.Owner, transponder),
|
||||
Loc.GetString($"borg-type-{borgType}-transponder"));
|
||||
}
|
||||
|
||||
// Configure modules
|
||||
if (TryComp(ent, out BorgChassisComponent? chassis))
|
||||
{
|
||||
var chassisEnt = (ent.Owner, chassis);
|
||||
_borgSystem.SetMaxModules(
|
||||
chassisEnt,
|
||||
prototype.ExtraModuleCount + prototype.DefaultModules.Length);
|
||||
|
||||
_borgSystem.SetModuleWhitelist(chassisEnt, prototype.ModuleWhitelist);
|
||||
|
||||
foreach (var module in prototype.DefaultModules)
|
||||
{
|
||||
var moduleEntity = Spawn(module);
|
||||
var borgModule = Comp<BorgModuleComponent>(moduleEntity);
|
||||
_borgSystem.SetBorgModuleDefault((moduleEntity, borgModule), true);
|
||||
_borgSystem.InsertModule(chassisEnt, moduleEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure special components
|
||||
if (Prototypes.TryIndex(ent.Comp.SelectedBorgType, out var previousPrototype))
|
||||
{
|
||||
if (previousPrototype.AddComponents is { } removeComponents)
|
||||
EntityManager.RemoveComponents(ent, removeComponents);
|
||||
}
|
||||
|
||||
if (prototype.AddComponents is { } addComponents)
|
||||
{
|
||||
EntityManager.AddComponents(ent, addComponents);
|
||||
}
|
||||
|
||||
// Configure inventory template (used for hat spacing)
|
||||
if (TryComp(ent, out InventoryComponent? inventory))
|
||||
{
|
||||
_inventorySystem.SetTemplateId((ent.Owner, inventory), prototype.InventoryTemplateId);
|
||||
}
|
||||
|
||||
base.SelectBorgModule(ent, borgType);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System.Linq;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Server.Silicons.Borgs;
|
||||
@@ -300,6 +301,24 @@ public sealed partial class BorgSystem
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if a module can be removed from a borg.
|
||||
/// </summary>
|
||||
/// <param name="borg">The borg that the module is being removed from.</param>
|
||||
/// <param name="module">The module to remove from the borg.</param>
|
||||
/// <param name="user">The user attempting to remove the module.</param>
|
||||
/// <returns>True if the module can be removed.</returns>
|
||||
public bool CanRemoveModule(
|
||||
Entity<BorgChassisComponent> borg,
|
||||
Entity<BorgModuleComponent> module,
|
||||
EntityUid? user = null)
|
||||
{
|
||||
if (module.Comp.DefaultModule)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Installs and activates all modules currently inside the borg's module container
|
||||
/// </summary>
|
||||
@@ -369,4 +388,24 @@ public sealed partial class BorgSystem
|
||||
var ev = new BorgModuleUninstalledEvent(uid);
|
||||
RaiseLocalEvent(module, ref ev);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="BorgChassisComponent.MaxModules"/>.
|
||||
/// </summary>
|
||||
/// <param name="ent">The borg to modify.</param>
|
||||
/// <param name="maxModules">The new max module count.</param>
|
||||
public void SetMaxModules(Entity<BorgChassisComponent> ent, int maxModules)
|
||||
{
|
||||
ent.Comp.MaxModules = maxModules;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="BorgChassisComponent.ModuleWhitelist"/>.
|
||||
/// </summary>
|
||||
/// <param name="ent">The borg to modify.</param>
|
||||
/// <param name="whitelist">The new module whitelist.</param>
|
||||
public void SetModuleWhitelist(Entity<BorgChassisComponent> ent, EntityWhitelist? whitelist)
|
||||
{
|
||||
ent.Comp.ModuleWhitelist = whitelist;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Server.Explosion.Components;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.Silicons.Borgs;
|
||||
|
||||
@@ -134,4 +135,20 @@ public sealed partial class BorgSystem
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="BorgTransponderComponent.Sprite"/>.
|
||||
/// </summary>
|
||||
public void SetTransponderSprite(Entity<BorgTransponderComponent> ent, SpriteSpecifier sprite)
|
||||
{
|
||||
ent.Comp.Sprite = sprite;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="BorgTransponderComponent.Name"/>.
|
||||
/// </summary>
|
||||
public void SetTransponderName(Entity<BorgTransponderComponent> ent, string name)
|
||||
{
|
||||
ent.Comp.Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ public sealed partial class BorgSystem
|
||||
if (!component.ModuleContainer.Contains(module))
|
||||
return;
|
||||
|
||||
if (!CanRemoveModule((uid, component), (module, Comp<BorgModuleComponent>(module)), args.Actor))
|
||||
return;
|
||||
|
||||
_adminLog.Add(LogType.Action, LogImpact.Medium,
|
||||
$"{ToPrettyString(args.Actor):player} removed module {ToPrettyString(module)} from borg {ToPrettyString(uid)}");
|
||||
_container.Remove(module, component.ModuleContainer);
|
||||
|
||||
@@ -129,7 +129,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
|
||||
if (module != null && CanInsertModule(uid, used, component, module, args.User))
|
||||
{
|
||||
_container.Insert(used, component.ModuleContainer);
|
||||
InsertModule((uid, component), used);
|
||||
_adminLog.Add(LogType.Action, LogImpact.Low,
|
||||
$"{ToPrettyString(args.User):player} installed module {ToPrettyString(used)} into borg {ToPrettyString(uid)}");
|
||||
args.Handled = true;
|
||||
@@ -137,6 +137,19 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a new module into a borg, the same as if a player inserted it manually.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This does not run checks to see if the borg is actually allowed to be inserted, such as whitelists.
|
||||
/// </para>
|
||||
/// <param name="ent">The borg to insert into.</param>
|
||||
/// <param name="module">The module to insert.</param>
|
||||
public void InsertModule(Entity<BorgChassisComponent> ent, EntityUid module)
|
||||
{
|
||||
_container.Insert(module, ent.Comp.ModuleContainer);
|
||||
}
|
||||
|
||||
// todo: consider transferring over the ghost role? managing that might suck.
|
||||
protected override void OnInserted(EntityUid uid, BorgChassisComponent component, EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Server.Interaction;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Stunnable;
|
||||
using Content.Server.Weapons.Ranged.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Damage.Systems;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Effects;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using Content.Shared.Weapons.Ranged;
|
||||
@@ -33,16 +30,13 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||
[Dependency] private readonly BatterySystem _battery = default!;
|
||||
[Dependency] private readonly DamageExamineSystem _damageExamine = default!;
|
||||
[Dependency] private readonly InteractionSystem _interaction = default!;
|
||||
[Dependency] private readonly PricingSystem _pricing = default!;
|
||||
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly StaminaSystem _stamina = default!;
|
||||
[Dependency] private readonly StunSystem _stun = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
|
||||
private const float DamagePitchVariation = 0.05f;
|
||||
public const float GunClumsyChance = 0.5f;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -71,26 +65,14 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
{
|
||||
userImpulse = true;
|
||||
|
||||
// Try a clumsy roll
|
||||
// TODO: Who put this here
|
||||
if (TryComp<ClumsyComponent>(user, out var clumsy) && gun.ClumsyProof == false)
|
||||
if (user != null)
|
||||
{
|
||||
for (var i = 0; i < ammo.Count; i++)
|
||||
var selfEvent = new SelfBeforeGunShotEvent(user.Value, (gunUid, gun), ammo);
|
||||
RaiseLocalEvent(user.Value, selfEvent);
|
||||
if (selfEvent.Cancelled)
|
||||
{
|
||||
if (_interaction.TryRollClumsy(user.Value, GunClumsyChance, clumsy))
|
||||
{
|
||||
// Wound them
|
||||
Damageable.TryChangeDamage(user, clumsy.ClumsyDamage, origin: user);
|
||||
_stun.TryParalyze(user.Value, TimeSpan.FromSeconds(3f), true);
|
||||
|
||||
// Apply salt to the wound ("Honk!")
|
||||
Audio.PlayPvs(new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg"), gunUid);
|
||||
Audio.PlayPvs(clumsy.ClumsySound, gunUid);
|
||||
|
||||
PopupSystem.PopupEntity(Loc.GetString("gun-clumsy"), user.Value);
|
||||
userImpulse = false;
|
||||
return;
|
||||
}
|
||||
userImpulse = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,11 +11,6 @@ public sealed partial class HyposprayComponent : Component
|
||||
[DataField]
|
||||
public string SolutionName = "hypospray";
|
||||
|
||||
// TODO: This should be on clumsycomponent.
|
||||
[DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float ClumsyFailChance = 0.5f;
|
||||
|
||||
[DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public FixedPoint2 TransferAmount = FixedPoint2.New(5);
|
||||
|
||||
38
Content.Shared/Chemistry/Events/HyposprayEvents.cs
Normal file
38
Content.Shared/Chemistry/Events/HyposprayEvents.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
namespace Content.Shared.Chemistry.Hypospray.Events;
|
||||
|
||||
public abstract partial class BeforeHyposprayInjectsTargetEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public EntityUid EntityUsingHypospray;
|
||||
public readonly EntityUid Hypospray;
|
||||
public EntityUid TargetGettingInjected;
|
||||
public string? InjectMessageOverride;
|
||||
|
||||
public BeforeHyposprayInjectsTargetEvent(EntityUid user, EntityUid hypospray, EntityUid target)
|
||||
{
|
||||
EntityUsingHypospray = user;
|
||||
Hypospray = hypospray;
|
||||
TargetGettingInjected = target;
|
||||
InjectMessageOverride = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the user using the hypospray before the hypospray is injected.
|
||||
/// The event is triggered on the user and all their clothing.
|
||||
/// </summary>
|
||||
public sealed class SelfBeforeHyposprayInjectsEvent : BeforeHyposprayInjectsTargetEvent
|
||||
{
|
||||
public SelfBeforeHyposprayInjectsEvent(EntityUid user, EntityUid hypospray, EntityUid target) : base(user, hypospray, target) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the target before the hypospray is injected.
|
||||
/// The event is triggered on the target itself and all its clothing.
|
||||
/// </summary>
|
||||
public sealed class TargetBeforeHyposprayInjectsEvent : BeforeHyposprayInjectsTargetEvent
|
||||
{
|
||||
public TargetBeforeHyposprayInjectsEvent (EntityUid user, EntityUid hypospray, EntityUid target) : base(user, hypospray, target) { }
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Climbing.Components;
|
||||
@@ -8,39 +7,18 @@ namespace Content.Shared.Climbing.Components;
|
||||
/// Makes entity do damage and stun entities with ClumsyComponent
|
||||
/// upon DragDrop or Climb interactions.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(Systems.BonkSystem))]
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class BonkableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Chance of bonk triggering if the user is clumsy.
|
||||
/// How long to stun players on bonk, in seconds.
|
||||
/// </summary>
|
||||
[DataField("bonkClumsyChance")]
|
||||
public float BonkClumsyChance = 0.5f;
|
||||
[DataField]
|
||||
public TimeSpan BonkTime = TimeSpan.FromSeconds(2);
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when bonking.
|
||||
/// How much damage to apply on bonk.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkSound")]
|
||||
public SoundSpecifier? BonkSound;
|
||||
|
||||
/// <summary>
|
||||
/// How long to stun players on bonk, in seconds.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkTime")]
|
||||
public float BonkTime = 2;
|
||||
|
||||
/// <summary>
|
||||
/// How much damage to apply on bonk.
|
||||
/// </summary>
|
||||
/// <seealso cref="Bonk"/>
|
||||
[DataField("bonkDamage")]
|
||||
[DataField]
|
||||
public DamageSpecifier? BonkDamage;
|
||||
|
||||
/// <summary>
|
||||
/// How long it takes to bonk.
|
||||
/// </summary>
|
||||
[DataField("bonkDelay")]
|
||||
public float BonkDelay = 1.5f;
|
||||
}
|
||||
|
||||
36
Content.Shared/Climbing/Events/BeforeClimbEvents.cs
Normal file
36
Content.Shared/Climbing/Events/BeforeClimbEvents.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Climbing.Components;
|
||||
|
||||
namespace Content.Shared.Climbing.Events;
|
||||
|
||||
public abstract partial class BeforeClimbEvent : CancellableEntityEventArgs
|
||||
{
|
||||
public readonly EntityUid GettingPutOnTable;
|
||||
public readonly EntityUid PuttingOnTable;
|
||||
public readonly Entity<ClimbableComponent> BeingClimbedOn;
|
||||
|
||||
public BeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn)
|
||||
{
|
||||
GettingPutOnTable = gettingPutOntable;
|
||||
PuttingOnTable = puttingOnTable;
|
||||
BeingClimbedOn = beingClimbedOn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the the person either getting put on or going on the table.
|
||||
/// The event is also called on their clothing as well.
|
||||
/// </summary>
|
||||
public sealed class SelfBeforeClimbEvent : BeforeClimbEvent, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public SelfBeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn) : base(gettingPutOntable, puttingOnTable, beingClimbedOn) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the thing being climbed on.
|
||||
/// </summary>
|
||||
public sealed class TargetBeforeClimbEvent : BeforeClimbEvent
|
||||
{
|
||||
public TargetBeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn) : base(gettingPutOntable, puttingOnTable, beingClimbedOn) { }
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Climbing.Components;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.DragDrop;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stunnable;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Climbing.Systems;
|
||||
|
||||
public sealed partial class BonkSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<BonkableComponent, BonkDoAfterEvent>(OnBonkDoAfter);
|
||||
SubscribeLocalEvent<BonkableComponent, AttemptClimbEvent>(OnAttemptClimb);
|
||||
}
|
||||
|
||||
private void OnBonkDoAfter(EntityUid uid, BonkableComponent component, BonkDoAfterEvent args)
|
||||
{
|
||||
if (args.Handled || args.Cancelled || args.Args.Used == null)
|
||||
return;
|
||||
|
||||
TryBonk(args.Args.Used.Value, uid, component, source: args.Args.User);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
|
||||
public bool TryBonk(EntityUid user, EntityUid bonkableUid, BonkableComponent? bonkableComponent = null, EntityUid? source = null)
|
||||
{
|
||||
if (!Resolve(bonkableUid, ref bonkableComponent, false))
|
||||
return false;
|
||||
|
||||
// BONK!
|
||||
var userName = Identity.Entity(user, EntityManager);
|
||||
var bonkableName = Identity.Entity(bonkableUid, EntityManager);
|
||||
|
||||
if (user == source)
|
||||
{
|
||||
// Non-local, non-bonking players
|
||||
var othersMessage = Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName));
|
||||
// Local, bonking player
|
||||
var selfMessage = Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName));
|
||||
|
||||
_popupSystem.PopupPredicted(selfMessage, othersMessage, user, user);
|
||||
}
|
||||
else if (source != null)
|
||||
{
|
||||
// Local, non-bonking player (dragger)
|
||||
_popupSystem.PopupClient(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, source.Value);
|
||||
// Non-local, non-bonking players
|
||||
_popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, Filter.Pvs(user).RemoveWhereAttachedEntity(e => e == user || e == source.Value), true);
|
||||
// Non-local, bonking player
|
||||
_popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName)), user, user);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (source != null)
|
||||
_audioSystem.PlayPredicted(bonkableComponent.BonkSound, bonkableUid, source);
|
||||
else
|
||||
_audioSystem.PlayPvs(bonkableComponent.BonkSound, bonkableUid);
|
||||
|
||||
_stunSystem.TryParalyze(user, TimeSpan.FromSeconds(bonkableComponent.BonkTime), true);
|
||||
|
||||
if (bonkableComponent.BonkDamage is { } bonkDmg)
|
||||
_damageableSystem.TryChangeDamage(user, bonkDmg, true, origin: user);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private bool TryStartBonk(EntityUid uid, EntityUid user, EntityUid climber, BonkableComponent? bonkableComponent = null)
|
||||
{
|
||||
if (!Resolve(uid, ref bonkableComponent, false))
|
||||
return false;
|
||||
|
||||
if (!HasComp<ClumsyComponent>(climber) || !HasComp<HandsComponent>(user))
|
||||
return false;
|
||||
|
||||
if (!_cfg.GetCVar(CCVars.GameTableBonk))
|
||||
{
|
||||
// Not set to always bonk, try clumsy roll.
|
||||
if (!_interactionSystem.TryRollClumsy(climber, bonkableComponent.BonkClumsyChance))
|
||||
return false;
|
||||
}
|
||||
|
||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, bonkableComponent.BonkDelay, new BonkDoAfterEvent(), uid, target: uid, used: climber)
|
||||
{
|
||||
BreakOnMove = true,
|
||||
BreakOnDamage = true,
|
||||
DuplicateCondition = DuplicateConditions.SameTool | DuplicateConditions.SameTarget
|
||||
};
|
||||
|
||||
return _doAfter.TryStartDoAfter(doAfterArgs);
|
||||
}
|
||||
|
||||
private void OnAttemptClimb(EntityUid uid, BonkableComponent component, ref AttemptClimbEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
if (TryStartBonk(uid, args.User, args.Climber, component))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
private sealed partial class BonkDoAfterEvent : SimpleDoAfterEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -251,6 +251,18 @@ public sealed partial class ClimbSystem : VirtualController
|
||||
if (!Resolve(climbable, ref comp, false))
|
||||
return;
|
||||
|
||||
var selfEvent = new SelfBeforeClimbEvent(uid, user, (climbable, comp));
|
||||
RaiseLocalEvent(uid, selfEvent);
|
||||
|
||||
if (selfEvent.Cancelled)
|
||||
return;
|
||||
|
||||
var targetEvent = new TargetBeforeClimbEvent(uid, user, (climbable, comp));
|
||||
RaiseLocalEvent(climbable, targetEvent);
|
||||
|
||||
if (targetEvent.Cancelled)
|
||||
return;
|
||||
|
||||
if (!ReplaceFixtures(uid, climbing, fixtures))
|
||||
return;
|
||||
|
||||
|
||||
61
Content.Shared/Clumsy/ClumsyComponent.cs
Normal file
61
Content.Shared/Clumsy/ClumsyComponent.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Clumsy;
|
||||
|
||||
/// <summary>
|
||||
/// A simple clumsy tag-component.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ClumsyComponent : Component
|
||||
{
|
||||
|
||||
// Standard options. Try to fit these in if you can!
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when clumsy interactions fail.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier ClumsySound = new SoundPathSpecifier("/Audio/Items/bikehorn.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// Default chance to fail a clumsy interaction.
|
||||
/// If a system needs to use something else, add a new variable in the component, do not modify this percentage.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float ClumsyDefaultCheck = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Default stun time.
|
||||
/// If a system needs to use something else, add a new variable in the component, do not modify this number.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan ClumsyDefaultStunTime = TimeSpan.FromSeconds(2.5);
|
||||
|
||||
// Specific options
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play after hitting your head on a table. Ouch!
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundCollectionSpecifier TableBonkSound = new SoundCollectionSpecifier("TrayHit");
|
||||
|
||||
/// <summary>
|
||||
/// Stun time after failing to shoot a gun.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan GunShootFailStunTime = TimeSpan.FromSeconds(3);
|
||||
|
||||
/// <summary>
|
||||
/// Stun time after failing to shoot a gun.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public DamageSpecifier? GunShootFailDamage;
|
||||
|
||||
/// <summary>
|
||||
/// Noise to play after failing to shoot a gun. Boom!
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier GunShootFailSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg");
|
||||
}
|
||||
146
Content.Shared/Clumsy/ClumsySystem.cs
Normal file
146
Content.Shared/Clumsy/ClumsySystem.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Chemistry.Hypospray.Events;
|
||||
using Content.Shared.Climbing.Components;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Medical;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Stunnable;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared.Clumsy;
|
||||
|
||||
public sealed class ClumsySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stun = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeHyposprayInjectsEvent>(BeforeHyposprayEvent);
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeDefibrillatorZapsEvent>(BeforeDefibrillatorZapsEvent);
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeGunShotEvent>(BeforeGunShotEvent);
|
||||
SubscribeLocalEvent<ClumsyComponent, SelfBeforeClimbEvent>(OnBeforeClimbEvent);
|
||||
}
|
||||
|
||||
// If you add more clumsy interactions add them in this section!
|
||||
#region Clumsy interaction events
|
||||
private void BeforeHyposprayEvent(Entity<ClumsyComponent> ent, ref SelfBeforeHyposprayInjectsEvent args)
|
||||
{
|
||||
// Clumsy people sometimes inject themselves! Apparently syringes are clumsy proof...
|
||||
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
args.TargetGettingInjected = args.EntityUsingHypospray;
|
||||
args.InjectMessageOverride = "hypospray-component-inject-self-clumsy-message";
|
||||
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
|
||||
}
|
||||
|
||||
private void BeforeDefibrillatorZapsEvent(Entity<ClumsyComponent> ent, ref SelfBeforeDefibrillatorZapsEvent args)
|
||||
{
|
||||
// Clumsy people sometimes defib themselves!
|
||||
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
args.DefibTarget = args.EntityUsingDefib;
|
||||
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
|
||||
|
||||
}
|
||||
|
||||
private void BeforeGunShotEvent(Entity<ClumsyComponent> ent, ref SelfBeforeGunShotEvent args)
|
||||
{
|
||||
// Clumsy people sometimes can't shoot :(
|
||||
|
||||
if (args.Gun.Comp.ClumsyProof)
|
||||
return;
|
||||
|
||||
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
if (ent.Comp.GunShootFailDamage != null)
|
||||
_damageable.TryChangeDamage(ent, ent.Comp.GunShootFailDamage, origin: ent);
|
||||
|
||||
_stun.TryParalyze(ent, ent.Comp.GunShootFailStunTime, true);
|
||||
|
||||
// Apply salt to the wound ("Honk!") (No idea what this comment means)
|
||||
_audio.PlayPvs(ent.Comp.GunShootFailSound, ent);
|
||||
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("gun-clumsy"), ent, ent);
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void OnBeforeClimbEvent(Entity<ClumsyComponent> ent, ref SelfBeforeClimbEvent args)
|
||||
{
|
||||
// This event is called in shared, thats why it has all the extra prediction stuff.
|
||||
var rand = new System.Random((int)_timing.CurTick.Value);
|
||||
|
||||
// If someone is putting you on the table, always get past the guard.
|
||||
if (!_cfg.GetCVar(CCVars.GameTableBonk) && args.PuttingOnTable == ent.Owner && !rand.Prob(ent.Comp.ClumsyDefaultCheck))
|
||||
return;
|
||||
|
||||
HitHeadClumsy(ent, args.BeingClimbedOn);
|
||||
|
||||
_audio.PlayPredicted(ent.Comp.ClumsySound, ent, ent);
|
||||
|
||||
_audio.PlayPredicted(ent.Comp.TableBonkSound, ent, ent);
|
||||
|
||||
var gettingPutOnTableName = Identity.Entity(args.GettingPutOnTable, EntityManager);
|
||||
var puttingOnTableName = Identity.Entity(args.PuttingOnTable, EntityManager);
|
||||
|
||||
if (args.PuttingOnTable == ent.Owner)
|
||||
{
|
||||
// You are slamming yourself onto the table.
|
||||
_popup.PopupPredicted(
|
||||
Loc.GetString("bonkable-success-message-user", ("bonkable", args.BeingClimbedOn)),
|
||||
Loc.GetString("bonkable-success-message-others", ("victim", gettingPutOnTableName), ("bonkable", args.BeingClimbedOn)),
|
||||
ent,
|
||||
ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Someone else slamed you onto the table.
|
||||
// This is only run in server so you need to use popup entity.
|
||||
_popup.PopupPredicted(
|
||||
Loc.GetString("forced-bonkable-success-message",
|
||||
("bonker", puttingOnTableName),
|
||||
("victim", gettingPutOnTableName),
|
||||
("bonkable", args.BeingClimbedOn)),
|
||||
ent,
|
||||
null);
|
||||
}
|
||||
|
||||
args.Cancel();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Helper functions
|
||||
/// <summary>
|
||||
/// "Hits" an entites head against the given table.
|
||||
/// </summary>
|
||||
// Oh this fucntion is public le- NO!! This is only public for the one admin command if you use this anywhere else I will cry.
|
||||
public void HitHeadClumsy(Entity<ClumsyComponent> target, EntityUid table)
|
||||
{
|
||||
var stunTime = target.Comp.ClumsyDefaultStunTime;
|
||||
|
||||
if (TryComp<BonkableComponent>(table, out var bonkComp))
|
||||
{
|
||||
stunTime = bonkComp.BonkTime;
|
||||
if (bonkComp.BonkDamage != null)
|
||||
_damageable.TryChangeDamage(target, bonkComp.BonkDamage, true);
|
||||
}
|
||||
|
||||
_stun.TryParalyze(target, stunTime, true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Interaction.Components;
|
||||
|
||||
/// <summary>
|
||||
/// A simple clumsy tag-component.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ClumsyComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Damage dealt to a clumsy character when they try to fire a gun.
|
||||
/// </summary>
|
||||
[DataField(required: true), AutoNetworkedField]
|
||||
public DamageSpecifier ClumsyDamage = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Sound to play when clumsy interactions fail.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier ClumsySound = new SoundPathSpecifier("/Audio/Items/bikehorn.ogg");
|
||||
}
|
||||
@@ -159,4 +159,26 @@ public sealed class InteractionPopupSystem : EntitySystem
|
||||
_audio.PlayEntity(sfx, Filter.Empty().FromEntities(target), target, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="InteractionPopupComponent.InteractSuccessString"/>.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This field is not networked automatically, so this method must be called on both sides of the network.
|
||||
/// </para>
|
||||
public void SetInteractSuccessString(Entity<InteractionPopupComponent> ent, string str)
|
||||
{
|
||||
ent.Comp.InteractSuccessString = str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="InteractionPopupComponent.InteractFailureString"/>.
|
||||
/// </summary>
|
||||
/// <para>
|
||||
/// This field is not networked automatically, so this method must be called on both sides of the network.
|
||||
/// </para>
|
||||
public void SetInteractFailureString(Entity<InteractionPopupComponent> ent, string str)
|
||||
{
|
||||
ent.Comp.InteractFailureString = str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Shared.Interaction
|
||||
{
|
||||
public partial class SharedInteractionSystem
|
||||
{
|
||||
public bool RollClumsy(ClumsyComponent component, float chance)
|
||||
{
|
||||
return component.Running && _random.Prob(chance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rolls a probability chance for a "bad action" if the target entity is clumsy.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity that the clumsy check is happening for.</param>
|
||||
/// <param name="chance">
|
||||
/// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
|
||||
/// </param>
|
||||
/// <returns>True if a "bad action" happened, false if the normal action should happen.</returns>
|
||||
public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
|
||||
{
|
||||
return Resolve(entity, ref component, false) && RollClumsy(component, chance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,12 @@ namespace Content.Shared.Inventory;
|
||||
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[Access(typeof(InventorySystem))]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class InventoryComponent : Component
|
||||
{
|
||||
[DataField("templateId", customTypeSerializer: typeof(PrototypeIdSerializer<InventoryTemplatePrototype>))]
|
||||
public string TemplateId { get; private set; } = "human";
|
||||
[AutoNetworkedField]
|
||||
public string TemplateId { get; set; } = "human";
|
||||
|
||||
[DataField("speciesId")] public string? SpeciesId { get; set; }
|
||||
|
||||
@@ -32,3 +34,9 @@ public sealed partial class InventoryComponent : Component
|
||||
[DataField]
|
||||
public Dictionary<string, DisplacementData> MaleDisplacements = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised if the <see cref="InventoryComponent.TemplateId"/> of an inventory changed.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public struct InventoryTemplateUpdated;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Hypospray.Events;
|
||||
using Content.Shared.Climbing.Events;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Electrocution;
|
||||
using Content.Shared.Explosion;
|
||||
@@ -15,7 +18,7 @@ using Content.Shared.Slippery;
|
||||
using Content.Shared.Strip.Components;
|
||||
using Content.Shared.Temperature;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
|
||||
namespace Content.Shared.Inventory;
|
||||
|
||||
@@ -33,6 +36,10 @@ public partial class InventorySystem
|
||||
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, RefreshNameModifiersEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, TransformSpeakerNameEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeHyposprayInjectsEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, TargetBeforeHyposprayInjectsEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeGunShotEvent>(RelayInventoryEvent);
|
||||
SubscribeLocalEvent<InventoryComponent, SelfBeforeClimbEvent>(RelayInventoryEvent);
|
||||
|
||||
// by-ref events
|
||||
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Containers;
|
||||
@@ -19,6 +20,8 @@ public partial class InventorySystem : EntitySystem
|
||||
|
||||
_vvm.GetTypeHandler<InventoryComponent>()
|
||||
.AddHandler(HandleViewVariablesSlots, ListViewVariablesSlots);
|
||||
|
||||
SubscribeLocalEvent<InventoryComponent, AfterAutoHandleStateEvent>(AfterAutoState);
|
||||
}
|
||||
|
||||
private void ShutdownSlots()
|
||||
@@ -68,6 +71,27 @@ public partial class InventorySystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
private void AfterAutoState(Entity<InventoryComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
UpdateInventoryTemplate(ent);
|
||||
}
|
||||
|
||||
protected virtual void UpdateInventoryTemplate(Entity<InventoryComponent> ent)
|
||||
{
|
||||
if (ent.Comp.LifeStage < ComponentLifeStage.Initialized)
|
||||
return;
|
||||
|
||||
if (!_prototypeManager.TryIndex(ent.Comp.TemplateId, out InventoryTemplatePrototype? invTemplate))
|
||||
return;
|
||||
|
||||
DebugTools.Assert(ent.Comp.Slots.Length == invTemplate.Slots.Length);
|
||||
|
||||
ent.Comp.Slots = invTemplate.Slots;
|
||||
|
||||
var ev = new InventoryTemplateUpdated();
|
||||
RaiseLocalEvent(ent, ref ev);
|
||||
}
|
||||
|
||||
private void OnOpenSlotStorage(OpenSlotStorageNetworkMessage ev, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity is not { Valid: true } uid)
|
||||
@@ -170,6 +194,31 @@ public partial class InventorySystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Change the inventory template ID an entity is using. The new template must be compatible.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// For an inventory template to be compatible with another, it must have exactly the same slot names.
|
||||
/// All other changes are rejected.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="ent">The entity to update.</param>
|
||||
/// <param name="newTemplate">The ID of the new inventory template prototype.</param>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown if the new template is not compatible with the existing one.
|
||||
/// </exception>
|
||||
public void SetTemplateId(Entity<InventoryComponent> ent, ProtoId<InventoryTemplatePrototype> newTemplate)
|
||||
{
|
||||
var newPrototype = _prototypeManager.Index(newTemplate);
|
||||
|
||||
if (!newPrototype.Slots.Select(x => x.Name).SequenceEqual(ent.Comp.Slots.Select(x => x.Name)))
|
||||
throw new ArgumentException("Incompatible inventory template!");
|
||||
|
||||
ent.Comp.TemplateId = newTemplate;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerator for iterating over an inventory's slot containers. Also has methods that skip empty containers.
|
||||
/// It should be safe to add or remove items while enumerating.
|
||||
|
||||
39
Content.Shared/Medical/DefibrillatorEvents.cs
Normal file
39
Content.Shared/Medical/DefibrillatorEvents.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Content.Shared.Inventory;
|
||||
|
||||
namespace Content.Shared.Medical;
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);
|
||||
|
||||
public abstract class BeforeDefibrillatorZapsEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public EntityUid EntityUsingDefib;
|
||||
public readonly EntityUid Defib;
|
||||
public EntityUid DefibTarget;
|
||||
|
||||
public BeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibTarget)
|
||||
{
|
||||
EntityUsingDefib = entityUsingDefib;
|
||||
Defib = defib;
|
||||
DefibTarget = defibTarget;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the user using the defibrillator before is actually zaps someone.
|
||||
/// The event is triggered on the user and all their clothing.
|
||||
/// </summary>
|
||||
public sealed class SelfBeforeDefibrillatorZapsEvent : BeforeDefibrillatorZapsEvent
|
||||
{
|
||||
public SelfBeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibtarget) : base(entityUsingDefib, defib, defibtarget) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This event is raised on the target before it gets zapped with the defibrillator.
|
||||
/// The event is triggered on the target itself and all its clothing.
|
||||
/// </summary>
|
||||
public sealed class TargetBeforeDefibrillatorZapsEvent : BeforeDefibrillatorZapsEvent
|
||||
{
|
||||
public TargetBeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibtarget) : base(entityUsingDefib, defib, defibtarget) { }
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
namespace Content.Shared.Medical;
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);
|
||||
@@ -9,12 +9,14 @@ namespace Content.Shared.Overlays;
|
||||
/// This component allows you to see health bars above damageable mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class ShowHealthBarsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays health bars of the damage containers.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public List<ProtoId<DamageContainerPrototype>> DamageContainers = new()
|
||||
{
|
||||
"Biological"
|
||||
|
||||
@@ -8,12 +8,14 @@ namespace Content.Shared.Overlays;
|
||||
/// This component allows you to see health status icons above damageable mobs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState(true)]
|
||||
public sealed partial class ShowHealthIconsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Displays health status icons of the damage containers.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public List<ProtoId<DamageContainerPrototype>> DamageContainers = new()
|
||||
{
|
||||
"Biological"
|
||||
|
||||
155
Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
Normal file
155
Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Radio;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Information for a borg type that can be selected by <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
/// <seealso cref="SharedBorgSwitchableTypeSystem"/>
|
||||
[Prototype]
|
||||
public sealed partial class BorgTypePrototype : IPrototype
|
||||
{
|
||||
[ValidatePrototypeId<SoundCollectionPrototype>]
|
||||
private static readonly ProtoId<SoundCollectionPrototype> DefaultFootsteps = new("FootstepBorg");
|
||||
|
||||
[IdDataField]
|
||||
public required string ID { get; init; }
|
||||
|
||||
//
|
||||
// Description info (name/desc) is configured via localization strings directly.
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// The prototype displayed in the selection menu for this type.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public required EntProtoId DummyPrototype { get; init; }
|
||||
|
||||
//
|
||||
// Functional information
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// The amount of free module slots this borg type has.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This count is on top of the modules specified in <see cref="DefaultModules"/>.
|
||||
/// </remarks>
|
||||
/// <seealso cref="BorgChassisComponent.ModuleCount"/>
|
||||
[DataField]
|
||||
public int ExtraModuleCount { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The whitelist for borg modules that can be inserted into this borg type.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgChassisComponent.ModuleWhitelist"/>
|
||||
[DataField]
|
||||
public EntityWhitelist? ModuleWhitelist { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Inventory template used by this borg.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This template must be compatible with the normal borg templates,
|
||||
/// so in practice it can only be used to differentiate the visual position of the slots on the character sprites.
|
||||
/// </remarks>
|
||||
/// <seealso cref="InventorySystem.SetTemplateId"/>
|
||||
[DataField]
|
||||
public ProtoId<InventoryTemplatePrototype> InventoryTemplateId { get; set; } = "borgShort";
|
||||
|
||||
/// <summary>
|
||||
/// Radio channels that this borg will gain access to from this module.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These channels are provided on top of the ones specified in
|
||||
/// <see cref="BorgSwitchableTypeComponent.InherentRadioChannels"/>.
|
||||
/// </remarks>
|
||||
[DataField]
|
||||
public ProtoId<RadioChannelPrototype>[] RadioChannels = [];
|
||||
|
||||
/// <summary>
|
||||
/// Borg module types that are always available to borgs of this type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These modules still work like modules, although they cannot be removed from the borg.
|
||||
/// </remarks>
|
||||
/// <seealso cref="BorgModuleComponent.DefaultModule"/>
|
||||
[DataField]
|
||||
public EntProtoId[] DefaultModules = [];
|
||||
|
||||
/// <summary>
|
||||
/// Additional components to add to the borg entity when this type is selected.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ComponentRegistry? AddComponents { get; set; }
|
||||
|
||||
//
|
||||
// Visual information
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// The sprite state for the main borg body.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string SpriteBodyState { get; set; } = "robot";
|
||||
|
||||
/// <summary>
|
||||
/// An optional movement sprite state for the main borg body.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string? SpriteBodyMovementState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sprite state used to indicate that the borg has a mind in it.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgChassisComponent.HasMindState"/>
|
||||
[DataField]
|
||||
public string SpriteHasMindState { get; set; } = "robot_e";
|
||||
|
||||
/// <summary>
|
||||
/// Sprite state used to indicate that the borg has no mind in it.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgChassisComponent.NoMindState"/>
|
||||
[DataField]
|
||||
public string SpriteNoMindState { get; set; } = "robot_e_r";
|
||||
|
||||
/// <summary>
|
||||
/// Sprite state used when the borg's flashlight is on.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string SpriteToggleLightState { get; set; } = "robot_l";
|
||||
|
||||
//
|
||||
// Minor information
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// String to use on petting success.
|
||||
/// </summary>
|
||||
/// <seealso cref="InteractionPopupComponent"/>
|
||||
[DataField]
|
||||
public string PetSuccessString { get; set; } = "petting-success-generic-cyborg";
|
||||
|
||||
/// <summary>
|
||||
/// String to use on petting failure.
|
||||
/// </summary>
|
||||
/// <seealso cref="InteractionPopupComponent"/>
|
||||
[DataField]
|
||||
public string PetFailureString { get; set; } = "petting-failure-generic-cyborg";
|
||||
|
||||
//
|
||||
// Sounds
|
||||
//
|
||||
|
||||
/// <summary>
|
||||
/// Sound specifier for footstep sounds created by this borg.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier FootstepCollection { get; set; } = new SoundCollectionSpecifier(DefaultFootsteps);
|
||||
}
|
||||
@@ -89,5 +89,18 @@ public enum BorgVisuals : byte
|
||||
[Serializable, NetSerializable]
|
||||
public enum BorgVisualLayers : byte
|
||||
{
|
||||
Light
|
||||
/// <summary>
|
||||
/// Main borg body layer.
|
||||
/// </summary>
|
||||
Body,
|
||||
|
||||
/// <summary>
|
||||
/// Layer for the borg's mind state.
|
||||
/// </summary>
|
||||
Light,
|
||||
|
||||
/// <summary>
|
||||
/// Layer for the borg flashlight status.
|
||||
/// </summary>
|
||||
LightStatus,
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Content.Shared.Silicons.Borgs.Components;
|
||||
/// to give them unique abilities and attributes.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedBorgSystem))]
|
||||
[AutoGenerateComponentState]
|
||||
public sealed partial class BorgModuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
@@ -16,6 +17,13 @@ public sealed partial class BorgModuleComponent : Component
|
||||
public EntityUid? InstalledEntity;
|
||||
|
||||
public bool Installed => InstalledEntity != null;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this is a "default" module that cannot be removed from a borg.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[AutoNetworkedField]
|
||||
public bool DefaultModule;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Radio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Component for borgs that can switch their "type" after being created.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is used by all NT borgs, on construction and round-start spawn.
|
||||
/// Borgs are effectively useless until they have made their choice of type.
|
||||
/// Borg type selections are currently irreversible.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Available types are specified in <see cref="BorgTypePrototype"/>s.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <seealso cref="SharedBorgSwitchableTypeSystem"/>
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
[AutoGenerateComponentState(raiseAfterAutoHandleState: true)]
|
||||
[Access(typeof(SharedBorgSwitchableTypeSystem))]
|
||||
public sealed partial class BorgSwitchableTypeComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Action entity used by players to select their type.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityUid? SelectTypeAction;
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected borg type, if any.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be set in a prototype to immediately apply a borg type, and not have switching support.
|
||||
/// </remarks>
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<BorgTypePrototype>? SelectedBorgType;
|
||||
|
||||
/// <summary>
|
||||
/// Radio channels that the borg will always have. These are added on top of the selected type's radio channels.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<RadioChannelPrototype>[] InherentRadioChannels = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Action event used to open the selection menu of a <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
public sealed partial class BorgToggleSelectTypeEvent : InstantActionEvent;
|
||||
|
||||
/// <summary>
|
||||
/// UI message used by a borg to select their type with <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
/// <param name="prototype">The borg type prototype that the user selected.</param>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BorgSelectTypeMessage(ProtoId<BorgTypePrototype> prototype) : BoundUserInterfaceMessage
|
||||
{
|
||||
public ProtoId<BorgTypePrototype> Prototype = prototype;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UI key used by the selection menu for <see cref="BorgSwitchableTypeComponent"/>.
|
||||
/// </summary>
|
||||
[NetSerializable, Serializable]
|
||||
public enum BorgSwitchableTypeUiKey : byte
|
||||
{
|
||||
SelectBorgType,
|
||||
}
|
||||
125
Content.Shared/Silicons/Borgs/SharedBorgSwitchableTypeSystem.cs
Normal file
125
Content.Shared/Silicons/Borgs/SharedBorgSwitchableTypeSystem.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Components;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs;
|
||||
|
||||
/// <summary>
|
||||
/// Implements borg type switching.
|
||||
/// </summary>
|
||||
/// <seealso cref="BorgSwitchableTypeComponent"/>
|
||||
public abstract class SharedBorgSwitchableTypeSystem : EntitySystem
|
||||
{
|
||||
// TODO: Allow borgs to be reset to default configuration.
|
||||
|
||||
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
|
||||
[Dependency] protected readonly IPrototypeManager Prototypes = default!;
|
||||
[Dependency] private readonly InteractionPopupSystem _interactionPopup = default!;
|
||||
|
||||
[ValidatePrototypeId<EntityPrototype>]
|
||||
public const string ActionId = "ActionSelectBorgType";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, MapInitEvent>(OnMapInit);
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<BorgSwitchableTypeComponent, BorgToggleSelectTypeEvent>(OnSelectBorgTypeAction);
|
||||
|
||||
Subs.BuiEvents<BorgSwitchableTypeComponent>(BorgSwitchableTypeUiKey.SelectBorgType,
|
||||
sub =>
|
||||
{
|
||||
sub.Event<BorgSelectTypeMessage>(SelectTypeMessageHandler);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// UI-adjacent code
|
||||
//
|
||||
|
||||
private void OnMapInit(Entity<BorgSwitchableTypeComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
_actionsSystem.AddAction(ent, ref ent.Comp.SelectTypeAction, ActionId);
|
||||
Dirty(ent);
|
||||
|
||||
if (ent.Comp.SelectedBorgType != null)
|
||||
{
|
||||
SelectBorgModule(ent, ent.Comp.SelectedBorgType.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<BorgSwitchableTypeComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.SelectTypeAction);
|
||||
}
|
||||
|
||||
private void OnSelectBorgTypeAction(Entity<BorgSwitchableTypeComponent> ent, ref BorgToggleSelectTypeEvent args)
|
||||
{
|
||||
if (args.Handled || !TryComp<ActorComponent>(ent, out var actor))
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
|
||||
_userInterface.TryToggleUi((ent.Owner, null), BorgSwitchableTypeUiKey.SelectBorgType, actor.PlayerSession);
|
||||
}
|
||||
|
||||
private void SelectTypeMessageHandler(Entity<BorgSwitchableTypeComponent> ent, ref BorgSelectTypeMessage args)
|
||||
{
|
||||
if (ent.Comp.SelectedBorgType != null)
|
||||
return;
|
||||
|
||||
if (!Prototypes.HasIndex(args.Prototype))
|
||||
return;
|
||||
|
||||
SelectBorgModule(ent, args.Prototype);
|
||||
}
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
||||
protected virtual void SelectBorgModule(
|
||||
Entity<BorgSwitchableTypeComponent> ent,
|
||||
ProtoId<BorgTypePrototype> borgType)
|
||||
{
|
||||
ent.Comp.SelectedBorgType = borgType;
|
||||
|
||||
_actionsSystem.RemoveAction(ent, ent.Comp.SelectTypeAction);
|
||||
ent.Comp.SelectTypeAction = null;
|
||||
Dirty(ent);
|
||||
|
||||
_userInterface.CloseUi((ent.Owner, null), BorgSwitchableTypeUiKey.SelectBorgType);
|
||||
|
||||
UpdateEntityAppearance(ent);
|
||||
}
|
||||
|
||||
protected void UpdateEntityAppearance(Entity<BorgSwitchableTypeComponent> entity)
|
||||
{
|
||||
if (!Prototypes.TryIndex(entity.Comp.SelectedBorgType, out var proto))
|
||||
return;
|
||||
|
||||
UpdateEntityAppearance(entity, proto);
|
||||
}
|
||||
|
||||
protected virtual void UpdateEntityAppearance(
|
||||
Entity<BorgSwitchableTypeComponent> entity,
|
||||
BorgTypePrototype prototype)
|
||||
{
|
||||
if (TryComp(entity, out InteractionPopupComponent? popup))
|
||||
{
|
||||
_interactionPopup.SetInteractSuccessString((entity.Owner, popup), prototype.PetSuccessString);
|
||||
_interactionPopup.SetInteractFailureString((entity.Owner, popup), prototype.PetFailureString);
|
||||
}
|
||||
|
||||
if (TryComp(entity, out FootstepModifierComponent? footstepModifier))
|
||||
{
|
||||
footstepModifier.FootstepSoundCollection = prototype.FootstepCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,4 +124,13 @@ public abstract partial class SharedBorgSystem : EntitySystem
|
||||
var sprintDif = movement.BaseWalkSpeed / movement.BaseSprintSpeed;
|
||||
args.ModifySpeed(1f, sprintDif);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="BorgModuleComponent.DefaultModule"/>.
|
||||
/// </summary>
|
||||
public void SetBorgModuleDefault(Entity<BorgModuleComponent> ent, bool newDefault)
|
||||
{
|
||||
ent.Comp.DefaultModule = newDefault;
|
||||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
|
||||
20
Content.Shared/Weapons/Ranged/Events/BeforeGunShootEvent.cs
Normal file
20
Content.Shared/Weapons/Ranged/Events/BeforeGunShootEvent.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
|
||||
namespace Content.Shared.Weapons.Ranged.Events;
|
||||
/// <summary>
|
||||
/// This event is triggered on an entity right before they shoot a gun.
|
||||
/// </summary>
|
||||
public sealed partial class SelfBeforeGunShotEvent : CancellableEntityEventArgs, IInventoryRelayEvent
|
||||
{
|
||||
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
|
||||
public readonly EntityUid Shooter;
|
||||
public readonly Entity<GunComponent> Gun;
|
||||
public readonly List<(EntityUid? Entity, IShootable Shootable)> Ammo;
|
||||
public SelfBeforeGunShotEvent(EntityUid shooter, Entity<GunComponent> gun, List<(EntityUid? Entity, IShootable Shootable)> ammo)
|
||||
{
|
||||
Shooter = shooter;
|
||||
Gun = gun;
|
||||
Ammo = ammo;
|
||||
}
|
||||
}
|
||||
@@ -605,5 +605,12 @@ Entries:
|
||||
id: 75
|
||||
time: '2024-11-13T23:27:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31751
|
||||
- author: Beck Thompson
|
||||
changes:
|
||||
- message: Notes now use duration instead of timestamps for note expiry times.
|
||||
type: Tweak
|
||||
id: 76
|
||||
time: '2024-11-15T03:24:27.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33262
|
||||
Name: Admin
|
||||
Order: 1
|
||||
|
||||
@@ -1,56 +1,4 @@
|
||||
Entries:
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Combat medical kits now contain saline syringes.
|
||||
type: Add
|
||||
id: 7108
|
||||
time: '2024-08-14T06:25:54.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29954
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: added morbilliard variants of procedural tacos and kebabs
|
||||
type: Add
|
||||
- message: removed all microwave taco and kebabs recipes (except for the taco shell
|
||||
itself)
|
||||
type: Remove
|
||||
- message: you can fight with a skewer (even if it has food on it)
|
||||
type: Tweak
|
||||
- message: now you can't put more than 10 layers on a burger. (20 before)
|
||||
type: Tweak
|
||||
id: 7109
|
||||
time: '2024-08-14T13:04:00.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30905
|
||||
- author: themias
|
||||
changes:
|
||||
- message: Fixed lizards being unable to eat custom burgers
|
||||
type: Fix
|
||||
id: 7110
|
||||
time: '2024-08-14T19:47:04.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31005
|
||||
- author: Erisfiregamer1
|
||||
changes:
|
||||
- message: New chemical, Sedin. It restores seeds on plants 20% of the time with
|
||||
other adverse effects included.
|
||||
type: Add
|
||||
id: 7111
|
||||
time: '2024-08-15T00:38:24.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/27110
|
||||
- author: PoorMansDreams
|
||||
changes:
|
||||
- message: Added Star sticker in loadouts for Secoffs
|
||||
type: Add
|
||||
id: 7112
|
||||
time: '2024-08-15T01:50:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29767
|
||||
- author: FATFSAAM2
|
||||
changes:
|
||||
- message: added 7 new figurine voice lines.
|
||||
type: Add
|
||||
- message: changed a hos figurine voice line to not include a typo.
|
||||
type: Fix
|
||||
id: 7113
|
||||
time: '2024-08-15T12:34:41.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30865
|
||||
- author: to4no_fix
|
||||
changes:
|
||||
- message: Added a new electropack that shocks when a trigger is triggered
|
||||
@@ -3941,3 +3889,57 @@
|
||||
id: 7607
|
||||
time: '2024-11-13T23:36:37.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33201
|
||||
- author: CheddaCheez
|
||||
changes:
|
||||
- message: Fixed mimes being unable to break their vow more than once. Despicable!
|
||||
type: Fix
|
||||
id: 7608
|
||||
time: '2024-11-14T16:56:22.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33303
|
||||
- author: PJB3005
|
||||
changes:
|
||||
- message: Borgs can now select their chassis type upon creation (construction or
|
||||
job spawn), immediately giving borgs access to all chassis types.
|
||||
type: Add
|
||||
- message: Borg chassis types now come with built-in modules depending on the type,
|
||||
so you can immediately do your job without help from science. Some upgrade modules
|
||||
must still be installed later however.
|
||||
type: Add
|
||||
- message: Specialized chassis types have been removed from construction, as they
|
||||
are no longer necessary.
|
||||
type: Remove
|
||||
- message: Borg unlock access is no longer determined by their chassis, it's always
|
||||
science or command. This means the janitor can't unlock jani borgs anymore.
|
||||
type: Remove
|
||||
id: 7609
|
||||
time: '2024-11-14T17:08:35.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32586
|
||||
- author: thetolbean
|
||||
changes:
|
||||
- message: The Quartermaster's requisition digi-board can no longer be recycled.
|
||||
type: Fix
|
||||
id: 7610
|
||||
time: '2024-11-15T06:54:53.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33315
|
||||
- author: RedBookcase
|
||||
changes:
|
||||
- message: Mixing up a Snow White no longer creates extra liquid out of thin air.
|
||||
type: Fix
|
||||
id: 7611
|
||||
time: '2024-11-15T20:52:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33331
|
||||
- author: lzk228
|
||||
changes:
|
||||
- message: Added 10 seconds delay to Succumb action
|
||||
type: Add
|
||||
id: 7612
|
||||
time: '2024-11-15T21:21:08.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32985
|
||||
- author: Beck Thompson
|
||||
changes:
|
||||
- message: Minor tweaks to clumsiness. Some of the timings and or noises have been
|
||||
changed slightly!
|
||||
type: Tweak
|
||||
id: 7613
|
||||
time: '2024-11-15T23:46:02.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31147
|
||||
|
||||
@@ -57,13 +57,23 @@ admin-note-editor-severity-medium = Medium
|
||||
admin-note-editor-severity-high = High
|
||||
admin-note-editor-expiry-checkbox = Permanent?
|
||||
admin-note-editor-expiry-checkbox-tooltip = Check this to make it expire
|
||||
admin-note-editor-expiry-label = Expires on:
|
||||
admin-note-editor-expiry-label = Expires in:
|
||||
admin-note-editor-expiry-label-params = Expires on: {$date} (in {$expiresIn})
|
||||
admin-note-editor-expiry-label-expired = Expired
|
||||
admin-note-editor-expiry-placeholder = Enter expiration date (yyyy-MM-dd HH:mm:ss)
|
||||
admin-note-editor-expiry-placeholder = Enter expiration time (integer).
|
||||
admin-note-editor-submit = Submit
|
||||
admin-note-editor-submit-confirm = Are you sure?
|
||||
|
||||
# Time
|
||||
admin-note-button-minutes = Minutes
|
||||
admin-note-button-hours = Hours
|
||||
admin-note-button-days = Days
|
||||
admin-note-button-weeks = Weeks
|
||||
admin-note-button-months = Months
|
||||
admin-note-button-years = Years
|
||||
admin-note-button-centuries = Centuries
|
||||
|
||||
|
||||
# Verb
|
||||
admin-notes-verb-text = Open Admin Notes
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
bonkable-success-message-others = { CAPITALIZE(THE($user)) } bonks { POSS-ADJ($user) } head against { THE($bonkable) }
|
||||
bonkable-success-message-user = You bonk your head against { THE($bonkable) }
|
||||
forced-bonkable-success-message = { CAPITALIZE($bonker) } bonks {$victim}s head against { THE($bonkable) }!
|
||||
|
||||
bonkable-success-message-user = You bonk your head against { THE($bonkable) }!
|
||||
bonkable-success-message-others = {$victim} bonks their head against { THE($bonkable) }!
|
||||
|
||||
@@ -25,3 +25,40 @@ borg-transponder-disabling-popup = Your transponder begins to lock you out of th
|
||||
borg-transponder-destroying-popup = The self destruct of {$name} starts beeping!
|
||||
borg-transponder-emagged-disabled-popup = Your transponder's lights go out!
|
||||
borg-transponder-emagged-destroyed-popup = Your transponder's fuse blows!
|
||||
|
||||
## Borg type selection UI.
|
||||
borg-select-type-menu-title = Select Chassis Type
|
||||
borg-select-type-menu-bottom-text = Chassis selection is irreversible
|
||||
borg-select-type-menu-available = Available types
|
||||
borg-select-type-menu-information = Information
|
||||
borg-select-type-menu-select-type = Select type to view information
|
||||
borg-select-type-menu-confirm = Confirm selection
|
||||
borg-select-type-menu-guidebook = Guidebook
|
||||
|
||||
## Borg type information
|
||||
|
||||
borg-type-generic-name = Generic
|
||||
borg-type-generic-desc = Jack of all trades, master of none. Do various random station tasks, or maybe help out the science department that built you.
|
||||
borg-type-generic-transponder = generic cyborg
|
||||
|
||||
borg-type-engineering-name = Engineering
|
||||
borg-type-engineering-desc = Assist the engineering team in station construction, repairing damage, or fixing electrical and atmospheric issues.
|
||||
borg-type-engineering-transponder = engineering cyborg
|
||||
|
||||
borg-type-mining-name = Salvage
|
||||
borg-type-mining-desc = Join salvage and help them mine for materials, scavenge wrecks, and fight off hostile wildlife.
|
||||
borg-type-mining-transponder = salvage cyborg
|
||||
|
||||
borg-type-janitor-name = Janitor
|
||||
borg-type-janitor-desc = Keep the station nice and tidy, clean up spills, collect and properly dispose of trash left around by lazy crewmembers.
|
||||
borg-type-janitor-transponder = janitor cyborg
|
||||
|
||||
borg-type-medical-name = Medical
|
||||
borg-type-medical-desc = Provide medical attention to crew who need it, either in medbay or in hazardous areas conventional paramedics cannot reach.
|
||||
borg-type-medical-transponder = medical cyborg
|
||||
|
||||
borg-type-service-name = Service
|
||||
borg-type-service-desc = Help out with a wide range of crew services, ranging from serving snacks and drinks to botany to entertainment.
|
||||
borg-type-service-transponder = service cyborg
|
||||
|
||||
|
||||
|
||||
2786
Resources/Maps/Ruins/abandoned_outpost.yml
Normal file
2786
Resources/Maps/Ruins/abandoned_outpost.yml
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -586,7 +586,6 @@ entities:
|
||||
2445: -41,19
|
||||
2646: -33,-12
|
||||
2665: -28,-14
|
||||
2666: -23,-15
|
||||
2667: -19,-23
|
||||
2740: -20,-5
|
||||
2794: 18,16
|
||||
@@ -608,6 +607,7 @@ entities:
|
||||
2979: -3,-48
|
||||
3010: 12,14
|
||||
3015: 2,-51
|
||||
3114: -21,-15
|
||||
- node:
|
||||
angle: 1.5707963267948966 rad
|
||||
color: '#FFFFFFFF'
|
||||
@@ -1039,11 +1039,11 @@ entities:
|
||||
color: '#52B4E996'
|
||||
id: BrickTileWhiteCornerNw
|
||||
decals:
|
||||
2536: -23,-15
|
||||
2544: -15,-15
|
||||
2602: -19,-19
|
||||
2630: -31,-16
|
||||
2673: -16,-9
|
||||
3119: -23,-15
|
||||
- node:
|
||||
color: '#DE3A3A96'
|
||||
id: BrickTileWhiteCornerNw
|
||||
@@ -1068,8 +1068,8 @@ entities:
|
||||
color: '#FFFFFFFF'
|
||||
id: BrickTileWhiteCornerNw
|
||||
decals:
|
||||
2533: -23,-15
|
||||
2573: -19,-19
|
||||
3118: -23,-15
|
||||
- node:
|
||||
color: '#52B4E996'
|
||||
id: BrickTileWhiteCornerSe
|
||||
@@ -4510,9 +4510,9 @@ entities:
|
||||
color: '#52B4E996'
|
||||
id: WarnLineGreyscaleN
|
||||
decals:
|
||||
2537: -22,-15
|
||||
2605: -14,-19
|
||||
2608: -14,-15
|
||||
3115: -22,-15
|
||||
- node:
|
||||
color: '#D381C996'
|
||||
id: WarnLineGreyscaleN
|
||||
@@ -7544,6 +7544,16 @@ entities:
|
||||
parent: 30
|
||||
- proto: AirAlarm
|
||||
entities:
|
||||
- uid: 3167
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -23.5,-15.5
|
||||
parent: 30
|
||||
- type: DeviceList
|
||||
devices:
|
||||
- 9046
|
||||
- 9049
|
||||
- uid: 6224
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -7765,6 +7775,27 @@ entities:
|
||||
- 18435
|
||||
- 18436
|
||||
- 18437
|
||||
- uid: 18082
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -38.5,8.5
|
||||
parent: 30
|
||||
- type: DeviceList
|
||||
devices:
|
||||
- 3077
|
||||
- 3076
|
||||
- uid: 19145
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -35.5,-18.5
|
||||
parent: 30
|
||||
- type: DeviceList
|
||||
devices:
|
||||
- 6935
|
||||
- 6920
|
||||
- 22554
|
||||
- uid: 19570
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -8808,6 +8839,26 @@ entities:
|
||||
- 22084
|
||||
- 3484
|
||||
- 3481
|
||||
- uid: 22553
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -23.5,-23.5
|
||||
parent: 30
|
||||
- type: DeviceList
|
||||
devices:
|
||||
- 6834
|
||||
- 9713
|
||||
- uid: 22555
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -31.5,-22.5
|
||||
parent: 30
|
||||
- type: DeviceList
|
||||
devices:
|
||||
- 7115
|
||||
- 7119
|
||||
- proto: AirAlarmElectronics
|
||||
entities:
|
||||
- uid: 15214
|
||||
@@ -11906,6 +11957,14 @@ entities:
|
||||
- type: Transform
|
||||
pos: -2.5,8.5
|
||||
parent: 30
|
||||
- uid: 22554
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -34.5,-23.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 19145
|
||||
- proto: AltarConvertRed
|
||||
entities:
|
||||
- uid: 17468
|
||||
@@ -54920,11 +54979,11 @@ entities:
|
||||
parent: 30
|
||||
- proto: DefibrillatorCabinetFilled
|
||||
entities:
|
||||
- uid: 3167
|
||||
- uid: 6956
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -23.5,-15.5
|
||||
pos: -23.5,-14.5
|
||||
parent: 30
|
||||
- uid: 6970
|
||||
components:
|
||||
@@ -55583,6 +55642,12 @@ entities:
|
||||
- type: Transform
|
||||
pos: -19.5,-5.5
|
||||
parent: 30
|
||||
- uid: 6953
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -21.5,-14.5
|
||||
parent: 30
|
||||
- uid: 7412
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -55677,12 +55742,6 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -19.5,-9.5
|
||||
parent: 30
|
||||
- uid: 7354
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -21.5,-14.5
|
||||
parent: 30
|
||||
- uid: 12233
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -59804,12 +59863,6 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -18.5,-22.5
|
||||
parent: 30
|
||||
- uid: 6956
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -22.5,-14.5
|
||||
parent: 30
|
||||
- uid: 6962
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -59821,6 +59874,12 @@ entities:
|
||||
- type: Transform
|
||||
pos: -19.5,-4.5
|
||||
parent: 30
|
||||
- uid: 7354
|
||||
components:
|
||||
- type: Transform
|
||||
rot: -1.5707963267948966 rad
|
||||
pos: -20.5,-14.5
|
||||
parent: 30
|
||||
- uid: 9753
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -60216,11 +60275,6 @@ entities:
|
||||
- type: Transform
|
||||
pos: -19.5,-4.5
|
||||
parent: 30
|
||||
- uid: 6953
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -22.5,-14.5
|
||||
parent: 30
|
||||
- uid: 6954
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -60296,6 +60350,11 @@ entities:
|
||||
- type: Transform
|
||||
pos: 14.5,-17.5
|
||||
parent: 30
|
||||
- uid: 19150
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -20.5,-14.5
|
||||
parent: 30
|
||||
- uid: 19407
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -86755,6 +86814,9 @@ entities:
|
||||
- type: Transform
|
||||
pos: -40.5,10.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 18082
|
||||
- type: AtmosPipeColor
|
||||
color: '#0000FFFF'
|
||||
- uid: 3099
|
||||
@@ -87044,6 +87106,9 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -25.5,-22.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 22553
|
||||
- type: AtmosPipeColor
|
||||
color: '#0000FFFF'
|
||||
- uid: 6900
|
||||
@@ -87060,6 +87125,9 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -33.5,-16.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 19145
|
||||
- type: AtmosPipeColor
|
||||
color: '#0000FFFF'
|
||||
- uid: 6939
|
||||
@@ -87086,6 +87154,9 @@ entities:
|
||||
- type: Transform
|
||||
pos: -28.5,-20.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 22555
|
||||
- type: AtmosPipeColor
|
||||
color: '#0000FFFF'
|
||||
- uid: 7136
|
||||
@@ -87232,6 +87303,9 @@ entities:
|
||||
- type: Transform
|
||||
pos: -25.5,-15.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 3167
|
||||
- type: AtmosPipeColor
|
||||
color: '#0000FFFF'
|
||||
- uid: 9686
|
||||
@@ -88266,6 +88340,9 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -39.5,10.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 18082
|
||||
- type: AtmosPipeColor
|
||||
color: '#FF0000FF'
|
||||
- uid: 3100
|
||||
@@ -88548,6 +88625,9 @@ entities:
|
||||
rot: 1.5707963267948966 rad
|
||||
pos: -33.5,-18.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 19145
|
||||
- type: AtmosPipeColor
|
||||
color: '#FF0000FF'
|
||||
- uid: 7098
|
||||
@@ -88577,6 +88657,9 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -28.5,-18.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 22555
|
||||
- type: AtmosPipeColor
|
||||
color: '#FF0000FF'
|
||||
- uid: 7130
|
||||
@@ -88714,6 +88797,9 @@ entities:
|
||||
- type: Transform
|
||||
pos: -25.5,-16.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 3167
|
||||
- type: AtmosPipeColor
|
||||
color: '#FF0000FF'
|
||||
- uid: 9713
|
||||
@@ -88722,6 +88808,9 @@ entities:
|
||||
rot: 3.141592653589793 rad
|
||||
pos: -25.5,-23.5
|
||||
parent: 30
|
||||
- type: DeviceNetwork
|
||||
deviceLists:
|
||||
- 22553
|
||||
- type: AtmosPipeColor
|
||||
color: '#FF0000FF'
|
||||
- uid: 9793
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,3 +10,15 @@
|
||||
state: state-laws
|
||||
event: !type:ToggleLawsScreenEvent
|
||||
useDelay: 0.5
|
||||
|
||||
- type: entity
|
||||
id: ActionSelectBorgType
|
||||
name: Select Cyborg Type
|
||||
components:
|
||||
- type: InstantAction
|
||||
itemIconStyle: NoItem
|
||||
icon:
|
||||
sprite: Interface/Actions/actions_borg.rsi
|
||||
state: select-type
|
||||
event: !type:BorgToggleSelectTypeEvent
|
||||
useDelay: 0.5
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
sprite: Mobs/Ghosts/ghost_human.rsi
|
||||
state: icon
|
||||
event: !type:CritSuccumbEvent
|
||||
startDelay: true
|
||||
useDelay: 10
|
||||
|
||||
- type: entity
|
||||
id: ActionCritFakeDeath
|
||||
@@ -41,3 +43,5 @@
|
||||
sprite: Interface/Actions/actions_crit.rsi
|
||||
state: lastwords
|
||||
event: !type:CritLastWordsEvent
|
||||
startDelay: true
|
||||
useDelay: 10
|
||||
|
||||
@@ -28,82 +28,105 @@
|
||||
- Robotics
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgArmLeft
|
||||
id: LeftArmBorg
|
||||
parent: PartSilicon
|
||||
name: cyborg left arm
|
||||
abstract: true
|
||||
components:
|
||||
- type: BodyPart
|
||||
partType: Hand
|
||||
symmetry: Left
|
||||
- type: Sprite
|
||||
state: borg_l_arm
|
||||
- type: Icon
|
||||
state: borg_l_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgLArm
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgArmRight
|
||||
id: RightArmBorg
|
||||
parent: PartSilicon
|
||||
name: cyborg right arm
|
||||
abstract: true
|
||||
components:
|
||||
- type: BodyPart
|
||||
partType: Hand
|
||||
symmetry: Right
|
||||
- type: Sprite
|
||||
state: borg_r_arm
|
||||
- type: Icon
|
||||
state: borg_r_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgRArm
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgLegLeft
|
||||
id: LeftLegBorg
|
||||
parent: PartSilicon
|
||||
name: cyborg left leg
|
||||
abstract: true
|
||||
components:
|
||||
- type: BodyPart
|
||||
partType: Leg
|
||||
symmetry: Left
|
||||
- type: Sprite
|
||||
state: borg_l_leg
|
||||
- type: Icon
|
||||
state: borg_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgLLeg
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgLegRight
|
||||
id: RightLegBorg
|
||||
parent: PartSilicon
|
||||
name: cyborg right leg
|
||||
abstract: true
|
||||
components:
|
||||
- type: BodyPart
|
||||
partType: Leg
|
||||
symmetry: Right
|
||||
- type: Sprite
|
||||
state: borg_r_leg
|
||||
- type: Icon
|
||||
state: borg_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgRLeg
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgHead
|
||||
id: LightHeadBorg
|
||||
parent: PartSilicon
|
||||
name: cyborg head
|
||||
abstract: true
|
||||
components:
|
||||
- type: BodyPart
|
||||
partType: Head
|
||||
- type: Sprite
|
||||
state: borg_head
|
||||
- type: Icon
|
||||
state: borg_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgTorso
|
||||
id: TorsoBorg
|
||||
parent: PartSilicon
|
||||
name: cyborg torso
|
||||
abstract: true
|
||||
components:
|
||||
- type: BodyPart
|
||||
partType: Torso
|
||||
- type: Sprite
|
||||
state: borg_chest
|
||||
- type: Icon
|
||||
state: borg_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgTorso
|
||||
|
||||
@@ -69,6 +69,9 @@
|
||||
type: BorgBoundUserInterface
|
||||
enum.StrippingUiKey.Key:
|
||||
type: StrippableBoundUserInterface
|
||||
# Only used for NT borgs that can switch type, defined here to avoid copy-pasting the rest of this component.
|
||||
enum.BorgSwitchableTypeUiKey.SelectBorgType:
|
||||
type: BorgSelectTypeUserInterface
|
||||
- type: ActivatableUI
|
||||
key: enum.BorgUiKey.Key
|
||||
- type: SiliconLawBound
|
||||
@@ -157,6 +160,7 @@
|
||||
collection: FootstepBorg
|
||||
- type: Construction
|
||||
graph: Cyborg
|
||||
node: cyborg
|
||||
containers:
|
||||
- part-container
|
||||
- cell_slot
|
||||
@@ -285,6 +289,9 @@
|
||||
- type: AccessReader
|
||||
access: [["Command"], ["Research"]]
|
||||
- type: ShowJobIcons
|
||||
- type: InteractionPopup
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgChassisSyndicate
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
- type: entity
|
||||
id: BorgChassisGeneric
|
||||
id: BorgChassisSelectable
|
||||
parent: BaseBorgChassisNT
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: robot
|
||||
map: ["enum.BorgVisualLayers.Body", "movement"]
|
||||
- state: robot_e_r
|
||||
map: ["enum.BorgVisualLayers.Light"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: robot_l
|
||||
shader: unshaded
|
||||
map: ["light"]
|
||||
map: ["light","enum.BorgVisualLayers.LightStatus"]
|
||||
visible: false
|
||||
- type: BorgChassis
|
||||
maxModules: 6
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
# Default borg can take no modules until selected type.
|
||||
maxModules: 0
|
||||
hasMindState: robot_e
|
||||
noMindState: robot_e_r
|
||||
- type: BorgTransponder
|
||||
@@ -25,308 +24,62 @@
|
||||
sprite: Mobs/Silicon/chassis.rsi
|
||||
state: robot
|
||||
name: cyborg
|
||||
- type: Construction
|
||||
node: cyborg
|
||||
- type: Speech
|
||||
speechVerb: Robotic
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-generic-cyborg
|
||||
interactFailureString: petting-failure-generic-cyborg
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
- type: BorgSwitchableType
|
||||
inherentRadioChannels:
|
||||
- Common
|
||||
- Binary
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisGeneric
|
||||
parent: BorgChassisSelectable
|
||||
name: generic cyborg
|
||||
suffix: type picked
|
||||
components:
|
||||
- type: BorgSwitchableType
|
||||
selectedBorgType: generic
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisMining
|
||||
parent: BaseBorgChassisNT
|
||||
parent: BorgChassisSelectable
|
||||
name: salvage cyborg
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: miner
|
||||
map: ["movement"]
|
||||
- state: miner_e_r
|
||||
map: ["enum.BorgVisualLayers.Light"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: miner_l
|
||||
shader: unshaded
|
||||
map: ["light"]
|
||||
visible: false
|
||||
- type: SpriteMovement
|
||||
movementLayers:
|
||||
movement:
|
||||
state: miner_moving
|
||||
noMovementLayers:
|
||||
movement:
|
||||
state: miner
|
||||
- type: BorgChassis
|
||||
maxModules: 4
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleCargo
|
||||
hasMindState: miner_e
|
||||
noMindState: miner_e_r
|
||||
- type: BorgTransponder
|
||||
sprite:
|
||||
sprite: Mobs/Silicon/chassis.rsi
|
||||
state: miner
|
||||
name: salvage cyborg
|
||||
- type: Construction
|
||||
node: mining
|
||||
- type: IntrinsicRadioTransmitter
|
||||
channels:
|
||||
- Supply
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: ActiveRadio
|
||||
channels:
|
||||
- Supply
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: AccessReader
|
||||
access: [["Cargo"], ["Salvage"], ["Command"], ["Research"]]
|
||||
- type: Inventory
|
||||
templateId: borgTall
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-salvage-cyborg
|
||||
interactFailureString: petting-failure-salvage-cyborg
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
- type: BorgSwitchableType
|
||||
selectedBorgType: mining
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisEngineer
|
||||
parent: BaseBorgChassisNT
|
||||
parent: BorgChassisSelectable
|
||||
name: engineer cyborg
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: engineer
|
||||
- state: engineer_e_r
|
||||
map: ["enum.BorgVisualLayers.Light"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: engineer_l
|
||||
shader: unshaded
|
||||
map: ["light"]
|
||||
visible: false
|
||||
- type: BorgChassis
|
||||
maxModules: 4
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleEngineering
|
||||
hasMindState: engineer_e
|
||||
noMindState: engineer_e_r
|
||||
- type: BorgTransponder
|
||||
sprite:
|
||||
sprite: Mobs/Silicon/chassis.rsi
|
||||
state: engineer
|
||||
name: engineer cyborg
|
||||
- type: Construction
|
||||
node: engineer
|
||||
- type: IntrinsicRadioTransmitter
|
||||
channels:
|
||||
- Engineering
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: ActiveRadio
|
||||
channels:
|
||||
- Engineering
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: AccessReader
|
||||
access: [["Engineering"], ["Command"], ["Research"]]
|
||||
- type: Inventory
|
||||
templateId: borgShort
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-engineer-cyborg
|
||||
interactFailureString: petting-failure-engineer-cyborg
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
- type: BorgSwitchableType
|
||||
selectedBorgType: engineering
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisJanitor
|
||||
parent: BaseBorgChassisNT
|
||||
parent: BorgChassisSelectable
|
||||
name: janitor cyborg
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: janitor
|
||||
map: ["movement"]
|
||||
- state: janitor_e_r
|
||||
map: ["enum.BorgVisualLayers.Light"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: janitor_l
|
||||
shader: unshaded
|
||||
map: ["light"]
|
||||
visible: false
|
||||
- type: SpriteMovement
|
||||
movementLayers:
|
||||
movement:
|
||||
state: janitor_moving
|
||||
noMovementLayers:
|
||||
movement:
|
||||
state: janitor
|
||||
- type: BorgChassis
|
||||
maxModules: 4
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleJanitor
|
||||
hasMindState: janitor_e
|
||||
noMindState: janitor_e_r
|
||||
- type: BorgTransponder
|
||||
sprite:
|
||||
sprite: Mobs/Silicon/chassis.rsi
|
||||
state: janitor
|
||||
name: janitor cyborg
|
||||
- type: Construction
|
||||
node: janitor
|
||||
- type: IntrinsicRadioTransmitter
|
||||
channels:
|
||||
- Service
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: ActiveRadio
|
||||
channels:
|
||||
- Service
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: AccessReader
|
||||
access: [["Service"], ["Command"], ["Research"]]
|
||||
- type: Inventory
|
||||
templateId: borgShort
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-janitor-cyborg
|
||||
interactFailureString: petting-failure-janitor-cyborg
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
- type: BorgSwitchableType
|
||||
selectedBorgType: janitor
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisMedical
|
||||
parent: [BaseBorgChassisNT, ShowMedicalIcons]
|
||||
parent: BorgChassisSelectable
|
||||
name: medical cyborg
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: medical
|
||||
map: ["movement"]
|
||||
- state: medical_e_r
|
||||
map: ["enum.BorgVisualLayers.Light"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: medical_l
|
||||
shader: unshaded
|
||||
map: ["light"]
|
||||
visible: false
|
||||
- type: SpriteMovement
|
||||
movementLayers:
|
||||
movement:
|
||||
state: medical_moving
|
||||
noMovementLayers:
|
||||
movement:
|
||||
state: medical
|
||||
- type: BorgChassis
|
||||
maxModules: 4
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleMedical
|
||||
hasMindState: medical_e
|
||||
noMindState: medical_e_r
|
||||
- type: BorgTransponder
|
||||
sprite:
|
||||
sprite: Mobs/Silicon/chassis.rsi
|
||||
state: medical
|
||||
name: medical cyborg
|
||||
- type: Construction
|
||||
node: medical
|
||||
- type: IntrinsicRadioTransmitter
|
||||
channels:
|
||||
- Medical
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: ActiveRadio
|
||||
channels:
|
||||
- Medical
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: AccessReader
|
||||
access: [["Medical"], ["Command"], ["Research"]]
|
||||
- type: Inventory
|
||||
templateId: borgDutch
|
||||
- type: FootstepModifier
|
||||
footstepSoundCollection:
|
||||
collection: FootstepHoverBorg
|
||||
- type: SolutionScanner
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-medical-cyborg
|
||||
interactFailureString: petting-failure-medical-cyborg
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
- type: BorgSwitchableType
|
||||
selectedBorgType: medical
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisService
|
||||
parent: BaseBorgChassisNT
|
||||
parent: BorgChassisSelectable
|
||||
name: service cyborg
|
||||
components:
|
||||
- type: Sprite
|
||||
layers:
|
||||
- state: service
|
||||
- state: service_e_r
|
||||
map: ["enum.BorgVisualLayers.Light"]
|
||||
shader: unshaded
|
||||
visible: false
|
||||
- state: service_l
|
||||
shader: unshaded
|
||||
map: ["light"]
|
||||
visible: false
|
||||
- type: BorgChassis
|
||||
maxModules: 4
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleService
|
||||
hasMindState: service_e
|
||||
noMindState: service_e_r
|
||||
- type: BorgTransponder
|
||||
sprite:
|
||||
sprite: Mobs/Silicon/chassis.rsi
|
||||
state: service
|
||||
name: service cyborg
|
||||
- type: Construction
|
||||
node: service
|
||||
- type: IntrinsicRadioTransmitter
|
||||
channels:
|
||||
- Service
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: ActiveRadio
|
||||
channels:
|
||||
- Service
|
||||
- Binary
|
||||
- Common
|
||||
- Science
|
||||
- type: AccessReader
|
||||
access: [["Service"], ["Command"], ["Research"]]
|
||||
- type: Inventory
|
||||
templateId: borgTall
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-service-cyborg
|
||||
interactFailureString: petting-failure-service-cyborg
|
||||
interactSuccessSound:
|
||||
path: /Audio/Ambience/Objects/periodic_beep.ogg
|
||||
- type: BorgSwitchableType
|
||||
selectedBorgType: service
|
||||
|
||||
- type: entity
|
||||
id: BorgChassisSyndicateAssault
|
||||
@@ -354,8 +107,6 @@
|
||||
- BorgModuleSyndicateAssault
|
||||
hasMindState: synd_sec_e
|
||||
noMindState: synd_sec
|
||||
- type: Construction
|
||||
node: syndicateassault
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-syndicate-cyborg
|
||||
interactFailureString: petting-failure-syndicate-cyborg
|
||||
@@ -388,8 +139,6 @@
|
||||
- BorgModuleSyndicate
|
||||
hasMindState: synd_medical_e
|
||||
noMindState: synd_medical
|
||||
- type: Construction
|
||||
node: syndicatemedical
|
||||
- type: ShowHealthBars
|
||||
- type: InteractionPopup
|
||||
interactSuccessString: petting-success-syndicate-cyborg
|
||||
@@ -429,8 +178,6 @@
|
||||
- BorgModuleSyndicate
|
||||
hasMindState: synd_engi_e
|
||||
noMindState: synd_engi
|
||||
- type: Construction
|
||||
node: syndicatesaboteur
|
||||
- type: ShowHealthBars
|
||||
damageContainers:
|
||||
- Inorganic
|
||||
|
||||
@@ -1360,7 +1360,7 @@
|
||||
rules: ghost-role-information-nonantagonist-rules
|
||||
- type: GhostTakeoverAvailable
|
||||
- type: Clumsy
|
||||
clumsyDamage:
|
||||
gunShootFailDamage:
|
||||
types:
|
||||
Blunt: 5
|
||||
Piercing: 4
|
||||
@@ -1536,7 +1536,7 @@
|
||||
description: Cousins to the sentient race of lizard people, kobolds blend in with their natural habitat and are as nasty as monkeys; ready to pull out your hair and stab you to death.
|
||||
components:
|
||||
- type: Clumsy
|
||||
clumsyDamage:
|
||||
gunShootFailDamage:
|
||||
types:
|
||||
Blunt: 2
|
||||
Piercing: 7
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
- type: Hands
|
||||
- type: ComplexInteraction
|
||||
- type: Clumsy
|
||||
clumsyDamage:
|
||||
gunShootFailDamage:
|
||||
types:
|
||||
Blunt: 5
|
||||
Piercing: 4
|
||||
|
||||
@@ -429,28 +429,9 @@
|
||||
map: ["base"]
|
||||
|
||||
# Borgs
|
||||
- type: entity
|
||||
id: PlayerBorgGeneric
|
||||
parent: BorgChassisGeneric
|
||||
suffix: Battery, Tools
|
||||
components:
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
borg_brain:
|
||||
- PositronicBrain
|
||||
borg_module:
|
||||
- BorgModuleTool
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
cell_slot:
|
||||
name: power-cell-slot-component-slot-name-default
|
||||
startingItem: PowerCellMedium
|
||||
- type: RandomMetadata
|
||||
nameSegments: [names_borg]
|
||||
|
||||
- type: entity
|
||||
id: PlayerBorgBattery
|
||||
parent: BorgChassisGeneric
|
||||
parent: BorgChassisSelectable
|
||||
suffix: Battery
|
||||
components:
|
||||
- type: ContainerFill
|
||||
|
||||
@@ -597,6 +597,10 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 10
|
||||
- type: Tag
|
||||
tags:
|
||||
- Folder
|
||||
- HighRiskItem
|
||||
- type: StealTarget
|
||||
stealGroup: BoxFolderQmClipboard
|
||||
|
||||
|
||||
@@ -126,6 +126,9 @@
|
||||
state: icon
|
||||
- type: Item
|
||||
size: Large
|
||||
storedSprite:
|
||||
state: storage
|
||||
sprite: Objects/Weapons/Melee/gorilla.rsi
|
||||
- type: MeleeWeapon
|
||||
attackRate: 0.5
|
||||
angle: 0
|
||||
@@ -134,6 +137,8 @@
|
||||
damage:
|
||||
types:
|
||||
Blunt: 20
|
||||
soundHit:
|
||||
path: "/Audio/Weapons/Guns/Gunshots/kinetic_accel.ogg"
|
||||
- type: CorePoweredThrower
|
||||
- type: MeleeThrowOnHit
|
||||
unanchorOnHit: true
|
||||
|
||||
@@ -1,503 +0,0 @@
|
||||
# generic parts
|
||||
- type: entity
|
||||
id: LeftArmBorg
|
||||
parent: BaseBorgArmLeft
|
||||
components:
|
||||
- type: Sprite
|
||||
state: borg_l_arm
|
||||
- type: Icon
|
||||
state: borg_l_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgGenericLArm
|
||||
|
||||
- type: entity
|
||||
id: RightArmBorg
|
||||
parent: BaseBorgArmRight
|
||||
components:
|
||||
- type: Sprite
|
||||
state: borg_r_arm
|
||||
- type: Icon
|
||||
state: borg_r_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgGenericRArm
|
||||
|
||||
- type: entity
|
||||
id: LeftLegBorg
|
||||
parent: BaseBorgLegLeft
|
||||
components:
|
||||
- type: Sprite
|
||||
state: borg_l_leg
|
||||
- type: Icon
|
||||
state: borg_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgGenericLLeg
|
||||
|
||||
- type: entity
|
||||
id: RightLegBorg
|
||||
parent: BaseBorgLegRight
|
||||
components:
|
||||
- type: Sprite
|
||||
state: borg_r_leg
|
||||
- type: Icon
|
||||
state: borg_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgGenericRLeg
|
||||
|
||||
- type: entity
|
||||
id: LightHeadBorg
|
||||
parent: BaseBorgHead
|
||||
components:
|
||||
- type: Sprite
|
||||
state: borg_head
|
||||
- type: Icon
|
||||
state: borg_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
- BorgGenericHead
|
||||
|
||||
- type: entity
|
||||
id: TorsoBorg
|
||||
parent: BaseBorgTorso
|
||||
components:
|
||||
- type: Sprite
|
||||
state: borg_chest
|
||||
- type: Icon
|
||||
state: borg_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgGenericTorso
|
||||
|
||||
# engineer parts
|
||||
- type: entity
|
||||
id: LeftArmBorgEngineer
|
||||
parent: BaseBorgArmLeft
|
||||
name: engineer cyborg left arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: engineer_l_arm
|
||||
- type: Icon
|
||||
state: engineer_l_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgEngineerLArm
|
||||
|
||||
- type: entity
|
||||
id: RightArmBorgEngineer
|
||||
parent: BaseBorgArmRight
|
||||
name: engineer cyborg right arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: engineer_r_arm
|
||||
- type: Icon
|
||||
state: engineer_r_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgEngineerRArm
|
||||
|
||||
- type: entity
|
||||
id: LeftLegBorgEngineer
|
||||
parent: BaseBorgLegLeft
|
||||
name: engineer cyborg left leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: engineer_l_leg
|
||||
- type: Icon
|
||||
state: engineer_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgEngineerLLeg
|
||||
|
||||
- type: entity
|
||||
id: RightLegBorgEngineer
|
||||
parent: BaseBorgLegRight
|
||||
name: engineer cyborg right leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: engineer_r_leg
|
||||
- type: Icon
|
||||
state: engineer_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgEngineerRLeg
|
||||
|
||||
- type: entity
|
||||
id: HeadBorgEngineer
|
||||
parent: BaseBorgHead
|
||||
name: engineer cyborg head
|
||||
components:
|
||||
- type: Sprite
|
||||
state: engineer_head
|
||||
- type: Icon
|
||||
state: engineer_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
- BorgEngineerHead
|
||||
|
||||
- type: entity
|
||||
id: TorsoBorgEngineer
|
||||
parent: BaseBorgTorso
|
||||
name: engineer cyborg torso
|
||||
components:
|
||||
- type: Sprite
|
||||
state: engineer_chest
|
||||
- type: Icon
|
||||
state: engineer_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgEngineerTorso
|
||||
|
||||
# janitor parts
|
||||
- type: entity
|
||||
id: LeftLegBorgJanitor
|
||||
parent: BaseBorgLegLeft
|
||||
name: janitor cyborg left leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: janitor_l_leg
|
||||
- type: Icon
|
||||
state: janitor_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgJanitorLLeg
|
||||
|
||||
- type: entity
|
||||
id: RightLegBorgJanitor
|
||||
parent: BaseBorgLegRight
|
||||
name: janitor cyborg right leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: janitor_r_leg
|
||||
- type: Icon
|
||||
state: janitor_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgJanitorRLeg
|
||||
|
||||
- type: entity
|
||||
id: HeadBorgJanitor
|
||||
parent: BaseBorgHead
|
||||
name: janitor cyborg head
|
||||
components:
|
||||
- type: Sprite
|
||||
state: janitor_head
|
||||
- type: Icon
|
||||
state: janitor_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
- BorgJanitorHead
|
||||
|
||||
- type: entity
|
||||
id: TorsoBorgJanitor
|
||||
parent: BaseBorgTorso
|
||||
name: janitor cyborg torso
|
||||
components:
|
||||
- type: Sprite
|
||||
state: janitor_chest
|
||||
- type: Icon
|
||||
state: janitor_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgJanitorTorso
|
||||
|
||||
# medical parts
|
||||
- type: entity
|
||||
id: LeftArmBorgMedical
|
||||
parent: BaseBorgArmLeft
|
||||
name: medical cyborg left arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: medical_l_arm
|
||||
- type: Icon
|
||||
state: medical_l_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgMedicalLArm
|
||||
|
||||
- type: entity
|
||||
id: RightArmBorgMedical
|
||||
parent: BaseBorgArmRight
|
||||
name: medical cyborg right arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: medical_r_arm
|
||||
- type: Icon
|
||||
state: medical_r_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgMedicalRArm
|
||||
|
||||
- type: entity
|
||||
id: LeftLegBorgMedical
|
||||
parent: BaseBorgLegLeft
|
||||
name: medical cyborg left leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: medical_l_leg
|
||||
- type: Icon
|
||||
state: medical_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgMedicalLLeg
|
||||
|
||||
- type: entity
|
||||
id: RightLegBorgMedical
|
||||
parent: BaseBorgLegRight
|
||||
name: medical cyborg right leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: medical_r_leg
|
||||
- type: Icon
|
||||
state: medical_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgMedicalRLeg
|
||||
|
||||
- type: entity
|
||||
id: HeadBorgMedical
|
||||
parent: BaseBorgHead
|
||||
name: medical cyborg head
|
||||
components:
|
||||
- type: Sprite
|
||||
state: medical_head
|
||||
- type: Icon
|
||||
state: medical_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
- BorgMedicalHead
|
||||
|
||||
- type: entity
|
||||
id: TorsoBorgMedical
|
||||
parent: BaseBorgTorso
|
||||
name: medical cyborg torso
|
||||
components:
|
||||
- type: Sprite
|
||||
state: medical_chest
|
||||
- type: Icon
|
||||
state: medical_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgMedicalTorso
|
||||
|
||||
# mining parts
|
||||
- type: entity
|
||||
id: LeftArmBorgMining
|
||||
parent: BaseBorgArmLeft
|
||||
name: mining cyborg left arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: mining_l_arm
|
||||
- type: Icon
|
||||
state: mining_l_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgMiningLArm
|
||||
|
||||
- type: entity
|
||||
id: RightArmBorgMining
|
||||
parent: BaseBorgArmRight
|
||||
name: mining cyborg right arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: mining_r_arm
|
||||
- type: Icon
|
||||
state: mining_r_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgMiningRArm
|
||||
|
||||
- type: entity
|
||||
id: LeftLegBorgMining
|
||||
parent: BaseBorgLegLeft
|
||||
name: mining cyborg left leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: mining_l_leg
|
||||
- type: Icon
|
||||
state: mining_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgMiningLLeg
|
||||
|
||||
- type: entity
|
||||
id: RightLegBorgMining
|
||||
parent: BaseBorgLegRight
|
||||
name: mining cyborg right leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: mining_r_leg
|
||||
- type: Icon
|
||||
state: mining_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgMiningRLeg
|
||||
|
||||
- type: entity
|
||||
id: HeadBorgMining
|
||||
parent: BaseBorgHead
|
||||
name: mining cyborg head
|
||||
components:
|
||||
- type: Sprite
|
||||
state: mining_head
|
||||
- type: Icon
|
||||
state: mining_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
- BorgMiningHead
|
||||
|
||||
- type: entity
|
||||
id: TorsoBorgMining
|
||||
parent: BaseBorgTorso
|
||||
name: mining cyborg torso
|
||||
components:
|
||||
- type: Sprite
|
||||
state: mining_chest
|
||||
- type: Icon
|
||||
state: mining_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgMiningTorso
|
||||
|
||||
# service parts
|
||||
- type: entity
|
||||
id: LeftArmBorgService
|
||||
parent: BaseBorgArmLeft
|
||||
name: service cyborg left arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: service_l_arm
|
||||
- type: Icon
|
||||
state: service_l_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgServiceLArm
|
||||
|
||||
- type: entity
|
||||
id: RightArmBorgService
|
||||
parent: BaseBorgArmRight
|
||||
name: service cyborg right arm
|
||||
components:
|
||||
- type: Sprite
|
||||
state: service_r_arm
|
||||
- type: Icon
|
||||
state: service_r_arm
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgArm
|
||||
- BorgServiceRArm
|
||||
|
||||
- type: entity
|
||||
id: LeftLegBorgService
|
||||
parent: BaseBorgLegLeft
|
||||
name: service cyborg left leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: service_l_leg
|
||||
- type: Icon
|
||||
state: service_l_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgServiceLLeg
|
||||
|
||||
- type: entity
|
||||
id: RightLegBorgService
|
||||
parent: BaseBorgLegRight
|
||||
name: service cyborg right leg
|
||||
components:
|
||||
- type: Sprite
|
||||
state: service_r_leg
|
||||
- type: Icon
|
||||
state: service_r_leg
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgLeg
|
||||
- BorgServiceRLeg
|
||||
|
||||
- type: entity
|
||||
id: HeadBorgService
|
||||
parent: BaseBorgHead
|
||||
name: service cyborg head
|
||||
components:
|
||||
- type: Sprite
|
||||
state: service_head
|
||||
- type: Icon
|
||||
state: service_head
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgHead
|
||||
- BorgServiceHead
|
||||
|
||||
- type: entity
|
||||
id: TorsoBorgService
|
||||
parent: BaseBorgTorso
|
||||
name: service cyborg torso
|
||||
components:
|
||||
- type: Sprite
|
||||
state: service_chest
|
||||
- type: Icon
|
||||
state: service_chest
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- BorgServiceTorso
|
||||
@@ -33,139 +33,27 @@
|
||||
borg_l_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgGenericLArm
|
||||
- BorgLArm
|
||||
borg_r_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgGenericRArm
|
||||
- BorgRArm
|
||||
borg_l_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgGenericLLeg
|
||||
- BorgLLeg
|
||||
borg_r_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgGenericRLeg
|
||||
- BorgRLeg
|
||||
borg_head+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgGenericHead
|
||||
- BorgHead
|
||||
borg_chest+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgGenericTorso
|
||||
service_l_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgServiceLArm
|
||||
service_r_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgServiceRArm
|
||||
service_l_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgServiceLLeg
|
||||
service_r_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgServiceRLeg
|
||||
service_head+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgServiceHead
|
||||
service_chest+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgServiceTorso
|
||||
engineer_l_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgEngineerLArm
|
||||
engineer_r_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgEngineerRArm
|
||||
engineer_l_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgEngineerLLeg
|
||||
engineer_r_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgEngineerRLeg
|
||||
engineer_head+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgEngineerHead
|
||||
engineer_chest+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgEngineerTorso
|
||||
mining_l_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMiningLArm
|
||||
mining_r_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMiningRArm
|
||||
mining_l_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMiningLLeg
|
||||
mining_r_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMiningRLeg
|
||||
mining_head+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMiningHead
|
||||
mining_chest+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMiningTorso
|
||||
medical_l_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMedicalLArm
|
||||
medical_r_arm+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMedicalRArm
|
||||
medical_l_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMedicalLLeg
|
||||
medical_r_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMedicalRLeg
|
||||
medical_head+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMedicalHead
|
||||
medical_chest+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgMedicalTorso
|
||||
janitor_l_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgJanitorLLeg
|
||||
janitor_r_leg+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgJanitorRLeg
|
||||
janitor_head+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgJanitorHead
|
||||
janitor_chest+o:
|
||||
whitelist:
|
||||
tags:
|
||||
- BorgJanitorTorso
|
||||
- BorgTorso
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
part-container: !type:Container
|
||||
@@ -173,45 +61,12 @@
|
||||
- type: PartAssembly
|
||||
parts:
|
||||
generic:
|
||||
- BorgGenericLArm
|
||||
- BorgGenericRArm
|
||||
- BorgGenericLLeg
|
||||
- BorgGenericRLeg
|
||||
- BorgGenericHead
|
||||
- BorgGenericTorso
|
||||
service:
|
||||
- BorgServiceLArm
|
||||
- BorgServiceRArm
|
||||
- BorgServiceLLeg
|
||||
- BorgServiceRLeg
|
||||
- BorgServiceHead
|
||||
- BorgServiceTorso
|
||||
engineer:
|
||||
- BorgEngineerLArm
|
||||
- BorgEngineerRArm
|
||||
- BorgEngineerLLeg
|
||||
- BorgEngineerRLeg
|
||||
- BorgEngineerHead
|
||||
- BorgEngineerTorso
|
||||
medical:
|
||||
- BorgMedicalLArm
|
||||
- BorgMedicalRArm
|
||||
- BorgMedicalLLeg
|
||||
- BorgMedicalRLeg
|
||||
- BorgMedicalHead
|
||||
- BorgMedicalTorso
|
||||
janitor:
|
||||
- BorgJanitorLLeg
|
||||
- BorgJanitorRLeg
|
||||
- BorgJanitorHead
|
||||
- BorgJanitorTorso
|
||||
mining:
|
||||
- BorgMiningLArm
|
||||
- BorgMiningRArm
|
||||
- BorgMiningLLeg
|
||||
- BorgMiningRLeg
|
||||
- BorgMiningHead
|
||||
- BorgMiningTorso
|
||||
- BorgLArm
|
||||
- BorgRArm
|
||||
- BorgLLeg
|
||||
- BorgRLeg
|
||||
- BorgHead
|
||||
- BorgTorso
|
||||
- type: Construction
|
||||
graph: Cyborg
|
||||
node: start
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
maxCount: 2
|
||||
stationGrid: false
|
||||
paths:
|
||||
- /Maps/Ruins/abandoned_outpost.yml
|
||||
- /Maps/Ruins/chunked_tcomms.yml
|
||||
- /Maps/Ruins/biodome_satellite.yml
|
||||
- /Maps/Ruins/derelict.yml
|
||||
|
||||
@@ -104,6 +104,28 @@
|
||||
- type: Wires
|
||||
layoutId: AirlockEngineering
|
||||
|
||||
- type: entity
|
||||
parent: AirlockExternal
|
||||
id: AirlockExternalCommandLocked
|
||||
suffix: External, Command, Locked
|
||||
components:
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board: [ DoorElectronicsCommand ]
|
||||
- type: Wires
|
||||
layoutId: AirlockCommand
|
||||
|
||||
- type: entity
|
||||
parent: AirlockExternalGlass
|
||||
id: AirlockExternalGlassCommandLocked
|
||||
suffix: External, Glass, Command, Locked
|
||||
components:
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board: [ DoorElectronicsCommand ]
|
||||
- type: Wires
|
||||
layoutId: AirlockCommand
|
||||
|
||||
- type: entity
|
||||
parent: AirlockExternal
|
||||
id: AirlockExternalAtmosphericsLocked
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
bonkDamage:
|
||||
types:
|
||||
Blunt: 4
|
||||
bonkSound: !type:SoundCollectionSpecifier
|
||||
collection: TrayHit
|
||||
- type: Clickable
|
||||
- type: FootstepModifier
|
||||
footstepSoundCollection:
|
||||
|
||||
@@ -572,11 +572,6 @@
|
||||
- BorgModuleFireExtinguisher
|
||||
- BorgModuleRadiationDetection
|
||||
- BorgModuleTool
|
||||
- BorgModuleAppraisal
|
||||
- BorgModuleConstruction
|
||||
- BorgModuleService
|
||||
- BorgModuleTreatment
|
||||
- BorgModuleCleaning
|
||||
- CyborgEndoskeleton
|
||||
- LeftArmBorg
|
||||
- RightArmBorg
|
||||
@@ -584,50 +579,15 @@
|
||||
- RightLegBorg
|
||||
- LightHeadBorg
|
||||
- TorsoBorg
|
||||
- LeftArmBorgEngineer
|
||||
- RightArmBorgEngineer
|
||||
- LeftLegBorgEngineer
|
||||
- RightLegBorgEngineer
|
||||
- HeadBorgEngineer
|
||||
- TorsoBorgEngineer
|
||||
- LeftLegBorgJanitor
|
||||
- RightLegBorgJanitor
|
||||
- HeadBorgJanitor
|
||||
- TorsoBorgJanitor
|
||||
- LeftArmBorgMedical
|
||||
- RightArmBorgMedical
|
||||
- LeftLegBorgMedical
|
||||
- RightLegBorgMedical
|
||||
- HeadBorgMedical
|
||||
- TorsoBorgMedical
|
||||
- LeftArmBorgMining
|
||||
- RightArmBorgMining
|
||||
- LeftLegBorgMining
|
||||
- RightLegBorgMining
|
||||
- HeadBorgMining
|
||||
- TorsoBorgMining
|
||||
- LeftArmBorgService
|
||||
- RightArmBorgService
|
||||
- LeftLegBorgService
|
||||
- RightLegBorgService
|
||||
- HeadBorgService
|
||||
- TorsoBorgService
|
||||
dynamicRecipes:
|
||||
- ProximitySensor
|
||||
- BorgModuleLightReplacer
|
||||
- BorgModuleAdvancedCleaning
|
||||
- BorgModuleMining
|
||||
- BorgModuleGrapplingGun
|
||||
- BorgModuleAdvancedTool
|
||||
- BorgModuleGPS
|
||||
- BorgModuleRCD
|
||||
- BorgModuleArtifact
|
||||
- BorgModuleAnomaly
|
||||
- BorgModuleGardening
|
||||
- BorgModuleHarvesting
|
||||
- BorgModuleMusique
|
||||
- BorgModuleClowning
|
||||
- BorgModuleDiagnosis
|
||||
- BorgModuleDefibrillator
|
||||
- BorgModuleAdvancedTreatment
|
||||
- RipleyHarness
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
- name: head
|
||||
slotTexture: head
|
||||
slotFlags: HEAD
|
||||
slotGroup: MainHotbar
|
||||
uiWindowPos: 0,0
|
||||
uiWindowPos: 1,0
|
||||
strippingWindowPos: 0,0
|
||||
displayName: Head
|
||||
offset: 0.015625, 0
|
||||
|
||||
@@ -5,18 +5,6 @@
|
||||
- node: start
|
||||
entity: CyborgEndoskeleton
|
||||
edges:
|
||||
|
||||
# empty the parts via prying
|
||||
- to: start
|
||||
conditions:
|
||||
- !type:ContainerNotEmpty
|
||||
container: part-container
|
||||
steps:
|
||||
- tool: Prying
|
||||
doAfter: 0.5
|
||||
completed:
|
||||
- !type:EmptyAllContainers
|
||||
|
||||
- to: cyborg
|
||||
steps:
|
||||
- assemblyId: generic
|
||||
@@ -43,165 +31,6 @@
|
||||
|
||||
- tool: Screwing
|
||||
doAfter: 0.5
|
||||
|
||||
- to: engineer
|
||||
steps:
|
||||
- assemblyId: engineer
|
||||
guideString: borg-construction-guide-string
|
||||
|
||||
- material: Cable
|
||||
amount: 1
|
||||
doAfter: 1
|
||||
store: part-container
|
||||
|
||||
- component: Flash
|
||||
name: flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- component: Flash
|
||||
name: second flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- tool: Screwing
|
||||
doAfter: 0.5
|
||||
|
||||
- to: janitor
|
||||
steps:
|
||||
- assemblyId: janitor
|
||||
guideString: borg-construction-guide-string
|
||||
|
||||
- material: Cable
|
||||
amount: 1
|
||||
doAfter: 1
|
||||
store: part-container
|
||||
|
||||
- component: Flash
|
||||
name: flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- component: Flash
|
||||
name: second flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- tool: Screwing
|
||||
doAfter: 0.5
|
||||
|
||||
- to: medical
|
||||
steps:
|
||||
- assemblyId: medical
|
||||
guideString: borg-construction-guide-string
|
||||
|
||||
- material: Cable
|
||||
amount: 1
|
||||
doAfter: 1
|
||||
store: part-container
|
||||
|
||||
- component: Flash
|
||||
name: flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- component: Flash
|
||||
name: second flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- tool: Screwing
|
||||
doAfter: 0.5
|
||||
|
||||
- to: mining
|
||||
steps:
|
||||
- assemblyId: mining
|
||||
guideString: borg-construction-guide-string
|
||||
|
||||
- material: Cable
|
||||
amount: 1
|
||||
doAfter: 1
|
||||
store: part-container
|
||||
|
||||
- component: Flash
|
||||
name: flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- component: Flash
|
||||
name: second flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- tool: Screwing
|
||||
doAfter: 0.5
|
||||
|
||||
- to: service
|
||||
steps:
|
||||
- assemblyId: service
|
||||
guideString: borg-construction-guide-string
|
||||
|
||||
- material: Cable
|
||||
amount: 1
|
||||
doAfter: 1
|
||||
store: part-container
|
||||
|
||||
- component: Flash
|
||||
name: flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- component: Flash
|
||||
name: second flash
|
||||
store: part-container
|
||||
icon:
|
||||
sprite: Objects/Weapons/Melee/flash.rsi
|
||||
state: flash
|
||||
|
||||
- tool: Screwing
|
||||
doAfter: 0.5
|
||||
|
||||
- node: cyborg
|
||||
entity: BorgChassisGeneric
|
||||
|
||||
- node: engineer
|
||||
entity: BorgChassisEngineer
|
||||
|
||||
- node: janitor
|
||||
entity: BorgChassisJanitor
|
||||
|
||||
- node: mining
|
||||
entity: BorgChassisMining
|
||||
|
||||
- node: medical
|
||||
entity: BorgChassisMedical
|
||||
|
||||
- node: service
|
||||
entity: BorgChassisService
|
||||
|
||||
- node: syndicateassault
|
||||
entity: BorgChassisSyndicateAssault
|
||||
|
||||
- node: syndicatemedical
|
||||
entity: BorgChassisSyndicateMedical
|
||||
|
||||
- node: syndicatesaboteur
|
||||
entity: BorgChassisSyndicateSaboteur
|
||||
entity: BorgChassisSelectable
|
||||
|
||||
@@ -61,8 +61,6 @@
|
||||
materials:
|
||||
Steel: 1500
|
||||
|
||||
# Generic
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftArmBorg
|
||||
@@ -93,162 +91,6 @@
|
||||
id: TorsoBorg
|
||||
result: TorsoBorg
|
||||
|
||||
# Engineer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftArmBorgEngineer
|
||||
result: LeftArmBorgEngineer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightArmBorgEngineer
|
||||
result: RightArmBorgEngineer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftLegBorgEngineer
|
||||
result: LeftLegBorgEngineer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightLegBorgEngineer
|
||||
result: RightLegBorgEngineer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: HeadBorgEngineer
|
||||
result: HeadBorgEngineer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: TorsoBorgEngineer
|
||||
result: TorsoBorgEngineer
|
||||
|
||||
# Medical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftArmBorgMedical
|
||||
result: LeftArmBorgMedical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightArmBorgMedical
|
||||
result: RightArmBorgMedical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftLegBorgMedical
|
||||
result: LeftLegBorgMedical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightLegBorgMedical
|
||||
result: RightLegBorgMedical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: HeadBorgMedical
|
||||
result: HeadBorgMedical
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: TorsoBorgMedical
|
||||
result: TorsoBorgMedical
|
||||
|
||||
# Mining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftArmBorgMining
|
||||
result: LeftArmBorgMining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightArmBorgMining
|
||||
result: RightArmBorgMining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftLegBorgMining
|
||||
result: LeftLegBorgMining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightLegBorgMining
|
||||
result: RightLegBorgMining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: HeadBorgMining
|
||||
result: HeadBorgMining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: TorsoBorgMining
|
||||
result: TorsoBorgMining
|
||||
|
||||
# Service
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftArmBorgService
|
||||
result: LeftArmBorgService
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightArmBorgService
|
||||
result: RightArmBorgService
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftLegBorgService
|
||||
result: LeftLegBorgService
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightLegBorgService
|
||||
result: RightLegBorgService
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: HeadBorgService
|
||||
result: HeadBorgService
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: TorsoBorgService
|
||||
result: TorsoBorgService
|
||||
|
||||
# Janitor
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: LeftLegBorgJanitor
|
||||
result: LeftLegBorgJanitor
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: RightLegBorgJanitor
|
||||
result: RightLegBorgJanitor
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: HeadBorgJanitor
|
||||
result: HeadBorgJanitor
|
||||
materials:
|
||||
Steel: 500
|
||||
Glass: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgLimbRecipe
|
||||
id: TorsoBorgJanitor
|
||||
result: TorsoBorgJanitor
|
||||
materials:
|
||||
Steel: 500
|
||||
Glass: 200
|
||||
|
||||
# Parts
|
||||
|
||||
- type: latheRecipe
|
||||
@@ -304,23 +146,6 @@
|
||||
id: BorgModuleTool
|
||||
result: BorgModuleTool
|
||||
|
||||
# Mining Modules
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleAppraisal
|
||||
result: BorgModuleAppraisal
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleMining
|
||||
result: BorgModuleMining
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGoldBorgModuleRecipe
|
||||
id: BorgModuleGrapplingGun
|
||||
result: BorgModuleGrapplingGun
|
||||
|
||||
# Engineering Modules
|
||||
|
||||
- type: latheRecipe
|
||||
@@ -328,28 +153,8 @@
|
||||
id: BorgModuleAdvancedTool
|
||||
result: BorgModuleAdvancedTool
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleConstruction
|
||||
result: BorgModuleConstruction
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGoldBorgModuleRecipe
|
||||
id: BorgModuleRCD
|
||||
result: BorgModuleRCD
|
||||
|
||||
# Janitor Modules
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleLightReplacer
|
||||
result: BorgModuleLightReplacer
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleCleaning
|
||||
result: BorgModuleCleaning
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGoldBorgModuleRecipe
|
||||
id: BorgModuleAdvancedCleaning
|
||||
@@ -357,16 +162,6 @@
|
||||
|
||||
# Medical Modules
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleDiagnosis
|
||||
result: BorgModuleDiagnosis
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleTreatment
|
||||
result: BorgModuleTreatment
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGoldBorgModuleRecipe
|
||||
id: BorgModuleAdvancedTreatment
|
||||
@@ -391,16 +186,6 @@
|
||||
|
||||
# Service Modules
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleService
|
||||
result: BorgModuleService
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleMusique
|
||||
result: BorgModuleMusique
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleGardening
|
||||
@@ -410,8 +195,3 @@
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleHarvesting
|
||||
result: BorgModuleHarvesting
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBorgModuleRecipe
|
||||
id: BorgModuleClowning
|
||||
result: BorgModuleClowning
|
||||
|
||||
@@ -953,7 +953,7 @@
|
||||
LemonLime:
|
||||
amount: 1
|
||||
products:
|
||||
SnowWhite: 3
|
||||
SnowWhite: 2
|
||||
|
||||
- type: reaction
|
||||
id: SodaWater
|
||||
|
||||
@@ -66,8 +66,6 @@
|
||||
recipeUnlocks:
|
||||
- ComputerTelevisionCircuitboard
|
||||
- SynthesizerInstrument
|
||||
- BorgModuleMusique
|
||||
- BorgModuleClowning
|
||||
- DawInstrumentMachineCircuitboard
|
||||
- MassMediaCircuitboard
|
||||
- JukeboxCircuitBoard
|
||||
@@ -82,7 +80,6 @@
|
||||
tier: 1
|
||||
cost: 5000
|
||||
recipeUnlocks:
|
||||
- BorgModuleLightReplacer
|
||||
- BorgModuleAdvancedCleaning
|
||||
|
||||
- type: technology
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
recipeUnlocks:
|
||||
- MiningDrill
|
||||
- MineralScannerEmpty
|
||||
- BorgModuleMining
|
||||
- BorgModuleGrapplingGun
|
||||
- OreProcessorIndustrialMachineCircuitboard
|
||||
- ClothingMaskWeldingGas
|
||||
|
||||
@@ -168,7 +166,6 @@
|
||||
- PowerDrill
|
||||
- JawsOfLife
|
||||
- BorgModuleAdvancedTool
|
||||
- BorgModuleRCD
|
||||
|
||||
- type: technology
|
||||
id: MassExcavation
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
weight: 10
|
||||
startingGear: QuartermasterGear
|
||||
icon: "JobIconQuarterMaster"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-captain
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- !type:AddComponentSpecial
|
||||
components:
|
||||
- type: Clumsy
|
||||
clumsyDamage:
|
||||
gunShootFailDamage:
|
||||
types: #literally just picked semi random valus. i tested this once and tweaked it.
|
||||
Blunt: 5
|
||||
Piercing: 4
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
weight: 20
|
||||
startingGear: CaptainGear
|
||||
icon: "JobIconCaptain"
|
||||
requireAdminNotify: true
|
||||
joinNotifyCrew: true
|
||||
supervisors: job-supervisors-centcom
|
||||
canBeAntag: false
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
weight: 20
|
||||
startingGear: HoPGear
|
||||
icon: "JobIconHeadOfPersonnel"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-captain
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
weight: 10
|
||||
startingGear: ChiefEngineerGear
|
||||
icon: "JobIconChiefEngineer"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-captain
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
weight: 10
|
||||
startingGear: CMOGear
|
||||
icon: "JobIconChiefMedicalOfficer"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-captain
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
@@ -25,5 +25,5 @@
|
||||
canBeAntag: false
|
||||
icon: JobIconBorg
|
||||
supervisors: job-supervisors-rd
|
||||
jobEntity: PlayerBorgGeneric
|
||||
jobEntity: PlayerBorgBattery
|
||||
applyTraits: false
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
weight: 10
|
||||
startingGear: ResearchDirectorGear
|
||||
icon: "JobIconResearchDirector"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-captain
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
weight: 10
|
||||
startingGear: HoSGear
|
||||
icon: "JobIconHeadOfSecurity"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-captain
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
time: 36000 #10 hrs
|
||||
startingGear: WardenGear
|
||||
icon: "JobIconWarden"
|
||||
requireAdminNotify: true
|
||||
supervisors: job-supervisors-hos
|
||||
canBeAntag: false
|
||||
access:
|
||||
|
||||
218
Resources/Prototypes/borg_types.yml
Normal file
218
Resources/Prototypes/borg_types.yml
Normal file
@@ -0,0 +1,218 @@
|
||||
# Generic borg
|
||||
- type: borgType
|
||||
id: generic
|
||||
|
||||
# Description
|
||||
dummyPrototype: BorgChassisGeneric
|
||||
|
||||
# Functional
|
||||
extraModuleCount: 5
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
|
||||
defaultModules:
|
||||
- BorgModuleTool
|
||||
|
||||
radioChannels:
|
||||
- Science
|
||||
|
||||
# Visual
|
||||
inventoryTemplateId: borgShort
|
||||
spriteBodyState: robot
|
||||
spriteHasMindState: robot_e
|
||||
spriteNoMindState: robot_e_r
|
||||
spriteToggleLightState: robot_l
|
||||
|
||||
# Pet
|
||||
petSuccessString: petting-success-generic-cyborg
|
||||
petFailureString: petting-failure-generic-cyborg
|
||||
|
||||
|
||||
# Engineering borg
|
||||
- type: borgType
|
||||
id: engineering
|
||||
|
||||
# Description
|
||||
dummyPrototype: BorgChassisEngineer
|
||||
|
||||
# Functional
|
||||
extraModuleCount: 3
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleEngineering
|
||||
|
||||
defaultModules:
|
||||
- BorgModuleTool
|
||||
- BorgModuleConstruction
|
||||
- BorgModuleRCD
|
||||
- BorgModuleCable
|
||||
|
||||
radioChannels:
|
||||
- Engineering
|
||||
- Science
|
||||
|
||||
# Visual
|
||||
inventoryTemplateId: borgShort
|
||||
spriteBodyState: engineer
|
||||
spriteHasMindState: engineer_e
|
||||
spriteNoMindState: engineer_e_r
|
||||
spriteToggleLightState: engineer_l
|
||||
|
||||
# Pet
|
||||
petSuccessString: petting-success-engineer-cyborg
|
||||
petFailureString: petting-failure-engineer-cyborg
|
||||
|
||||
|
||||
# Salvage borg
|
||||
- type: borgType
|
||||
id: mining
|
||||
|
||||
# Description
|
||||
dummyPrototype: BorgChassisMining
|
||||
|
||||
# Functional
|
||||
extraModuleCount: 3
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleCargo
|
||||
|
||||
defaultModules:
|
||||
- BorgModuleGrapplingGun
|
||||
- BorgModuleMining
|
||||
- BorgModuleAppraisal
|
||||
|
||||
radioChannels:
|
||||
- Supply
|
||||
- Science
|
||||
|
||||
# Visual
|
||||
inventoryTemplateId: borgTall
|
||||
spriteBodyState: miner
|
||||
spriteBodyMovementState: miner_moving
|
||||
spriteHasMindState: miner_e
|
||||
spriteNoMindState: miner_e_r
|
||||
spriteToggleLightState: miner_l
|
||||
|
||||
# Pet
|
||||
petSuccessString: petting-success-salvage-cyborg
|
||||
petFailureString: petting-failure-salvage-cyborg
|
||||
|
||||
|
||||
# Janitor borg
|
||||
- type: borgType
|
||||
id: janitor
|
||||
|
||||
# Description
|
||||
dummyPrototype: BorgChassisJanitor
|
||||
|
||||
# Functional
|
||||
extraModuleCount: 3
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleJanitor
|
||||
|
||||
defaultModules:
|
||||
- BorgModuleLightReplacer
|
||||
- BorgModuleCleaning
|
||||
|
||||
radioChannels:
|
||||
- Science
|
||||
- Service
|
||||
|
||||
# Visual
|
||||
inventoryTemplateId: borgShort
|
||||
spriteBodyState: janitor
|
||||
spriteBodyMovementState: janitor_moving
|
||||
spriteHasMindState: janitor_e
|
||||
spriteNoMindState: janitor_e_r
|
||||
spriteToggleLightState: janitor_l
|
||||
|
||||
# Pet
|
||||
petSuccessString: petting-success-janitor-cyborg
|
||||
petFailureString: petting-failure-janitor-cyborg
|
||||
|
||||
|
||||
# Medical borg
|
||||
- type: borgType
|
||||
id: medical
|
||||
|
||||
# Description
|
||||
dummyPrototype: BorgChassisMedical
|
||||
|
||||
# Functional
|
||||
extraModuleCount: 3
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleMedical
|
||||
|
||||
defaultModules:
|
||||
- BorgModuleTreatment
|
||||
|
||||
radioChannels:
|
||||
- Science
|
||||
- Medical
|
||||
|
||||
addComponents:
|
||||
- type: SolutionScanner
|
||||
- type: ShowHealthBars
|
||||
damageContainers:
|
||||
- Biological
|
||||
- type: ShowHealthIcons
|
||||
damageContainers:
|
||||
- Biological
|
||||
|
||||
# Visual
|
||||
inventoryTemplateId: borgDutch
|
||||
spriteBodyState: medical
|
||||
spriteBodyMovementState: medical_moving
|
||||
spriteHasMindState: medical_e
|
||||
spriteNoMindState: medical_e_r
|
||||
spriteToggleLightState: medical_l
|
||||
|
||||
# Pet
|
||||
petSuccessString: petting-success-medical-cyborg
|
||||
petFailureString: petting-failure-medical-cyborg
|
||||
|
||||
# Sounds
|
||||
footstepCollection:
|
||||
collection: FootstepHoverBorg
|
||||
|
||||
|
||||
# Service borg
|
||||
- type: borgType
|
||||
id: service
|
||||
|
||||
# Description
|
||||
dummyPrototype: BorgChassisService
|
||||
|
||||
# Functional
|
||||
extraModuleCount: 3
|
||||
moduleWhitelist:
|
||||
tags:
|
||||
- BorgModuleGeneric
|
||||
- BorgModuleService
|
||||
|
||||
defaultModules:
|
||||
- BorgModuleMusique
|
||||
- BorgModuleService
|
||||
- BorgModuleClowning
|
||||
|
||||
radioChannels:
|
||||
- Science
|
||||
- Service
|
||||
|
||||
# Visual
|
||||
inventoryTemplateId: borgTall
|
||||
spriteBodyState: service
|
||||
spriteHasMindState: service_e
|
||||
spriteNoMindState: service_e_r
|
||||
spriteToggleLightState: service_l
|
||||
|
||||
# Pet
|
||||
petSuccessString: petting-success-service-cyborg
|
||||
petFailureString: petting-failure-service-cyborg
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user