mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-06-09 13:26:34 +02:00
merge remote wizden/master
This commit is contained in:
@@ -14,7 +14,6 @@ namespace Content.Client.Humanoid;
|
||||
public sealed partial class OrganMarkingPicker : Control
|
||||
{
|
||||
[Dependency] private readonly MarkingManager _marking = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IEntityManager _entity = default!;
|
||||
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.ComponentModel.Design;
|
||||
using System.Linq;
|
||||
using Content.Client.Light.Components;
|
||||
using Content.Shared.Trigger.Components.Effects;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Shared.Random;
|
||||
@@ -36,6 +38,10 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
container.LightBehaviour.UpdatePlaybackValues(container.Animation);
|
||||
_player.Play(uid, container.Animation, container.FullKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopLightBehaviour((uid, component), container.LightBehaviour.ID, resetToOriginalSettings: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLightStartup(Entity<LightBehaviourComponent> entity, ref ComponentStartup args)
|
||||
@@ -53,7 +59,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
{
|
||||
if (container.LightBehaviour.Enabled)
|
||||
{
|
||||
StartLightBehaviour(entity, container.LightBehaviour.ID);
|
||||
StartLightBehaviour((entity, entity), container.LightBehaviour.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,12 +88,13 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
/// If specified light behaviours are already animating, calling this does nothing.
|
||||
/// Multiple light behaviours can have the same ID.
|
||||
/// </summary>
|
||||
public void StartLightBehaviour(Entity<LightBehaviourComponent> entity, string id = "")
|
||||
public void StartLightBehaviour(Entity<LightBehaviourComponent?> entity, string id = "")
|
||||
{
|
||||
if (!TryComp(entity, out AnimationPlayerComponent? animation))
|
||||
{
|
||||
if (!Resolve(entity, ref entity.Comp))
|
||||
return;
|
||||
|
||||
if (!TryComp(entity, out AnimationPlayerComponent? animation))
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var container in entity.Comp.Animations)
|
||||
{
|
||||
@@ -95,7 +102,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
{
|
||||
if (!_player.HasRunningAnimation(entity, animation, LightBehaviourComponent.KeyPrefix + container.Key))
|
||||
{
|
||||
CopyLightSettings(entity, container.LightBehaviour.Property);
|
||||
CopyLightSettings((entity, entity.Comp), container.LightBehaviour.Property);
|
||||
container.LightBehaviour.UpdatePlaybackValues(container.Animation);
|
||||
_player.Play(entity, container.Animation, LightBehaviourComponent.KeyPrefix + container.Key);
|
||||
}
|
||||
@@ -118,11 +125,9 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
var comp = entity.Comp;
|
||||
|
||||
var toRemove = new List<LightBehaviourComponent.AnimationContainer>();
|
||||
|
||||
foreach (var container in comp.Animations)
|
||||
foreach (var container in entity.Comp.Animations)
|
||||
{
|
||||
if (container.LightBehaviour.ID == id || id == string.Empty)
|
||||
{
|
||||
@@ -140,18 +145,24 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
|
||||
foreach (var container in toRemove)
|
||||
{
|
||||
comp.Animations.Remove(container);
|
||||
entity.Comp.Animations.Remove(container);
|
||||
}
|
||||
|
||||
if (resetToOriginalSettings && TryComp(entity, out PointLightComponent? light))
|
||||
if (resetToOriginalSettings)
|
||||
ResetToOriginalSettings(entity);
|
||||
|
||||
entity.Comp.OriginalPropertyValues.Clear();
|
||||
}
|
||||
|
||||
private void ResetToOriginalSettings(Entity<LightBehaviourComponent, PointLightComponent?> entity)
|
||||
{
|
||||
if (!Resolve(entity, ref entity.Comp2))
|
||||
return;
|
||||
|
||||
foreach (var (property, value) in entity.Comp1.OriginalPropertyValues)
|
||||
{
|
||||
foreach (var (property, value) in comp.OriginalPropertyValues)
|
||||
{
|
||||
AnimationHelper.SetAnimatableProperty(light, property, value);
|
||||
}
|
||||
AnimationHelper.SetAnimatableProperty(entity.Comp2, property, value);
|
||||
}
|
||||
|
||||
comp.OriginalPropertyValues.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -194,7 +205,7 @@ public sealed class LightBehaviorSystem : EntitySystem
|
||||
|
||||
if (playImmediately)
|
||||
{
|
||||
StartLightBehaviour(entity, behaviour.ID);
|
||||
StartLightBehaviour((entity, entity), behaviour.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ public sealed partial class LobbyUIController : UIController, IOnStateEntered<Lo
|
||||
[Dependency] private readonly IStateManager _stateManager = default!;
|
||||
[Dependency] private readonly JobRequirementsManager _requirements = default!;
|
||||
[Dependency] private readonly MarkingManager _markings = default!;
|
||||
[UISystemDependency] private readonly VisualBodySystem _visualBody = default!;
|
||||
[UISystemDependency] private readonly ClientInventorySystem _inventory = default!;
|
||||
[UISystemDependency] private readonly StationSpawningSystem _spawn = default!;
|
||||
[UISystemDependency] private readonly GuidebookSystem _guide = default!;
|
||||
@@ -183,13 +182,12 @@ public sealed partial class LobbyUIController : UIController, IOnStateEntered<Lo
|
||||
|
||||
if (character is not HumanoidCharacterProfile humanoid)
|
||||
{
|
||||
PreviewPanel.SetSprite(EntityUid.Invalid);
|
||||
PreviewPanel.ProfilePreviewSpriteView.ClearPreview();
|
||||
PreviewPanel.SetSummaryText(string.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
var dummy = LoadProfileEntity(humanoid, null, true);
|
||||
PreviewPanel.SetSprite(dummy);
|
||||
PreviewPanel.ProfilePreviewSpriteView.LoadPreview(humanoid);
|
||||
PreviewPanel.SetSummaryText(humanoid.Summary);
|
||||
}
|
||||
|
||||
@@ -326,175 +324,4 @@ public sealed partial class LobbyUIController : UIController, IOnStateEntered<Lo
|
||||
|
||||
return (_characterSetup, _profileEditor);
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Applies the highest priority job's clothes to the dummy.
|
||||
/// </summary>
|
||||
public void GiveDummyJobClothesLoadout(EntityUid dummy, JobPrototype? jobProto, HumanoidCharacterProfile profile)
|
||||
{
|
||||
var job = jobProto ?? GetPreferredJob(profile);
|
||||
GiveDummyJobClothes(dummy, profile, job);
|
||||
|
||||
if (_prototypeManager.HasIndex<RoleLoadoutPrototype>(LoadoutSystem.GetJobPrototype(job.ID)))
|
||||
{
|
||||
var loadout = profile.GetLoadoutOrDefault(LoadoutSystem.GetJobPrototype(job.ID), _playerManager.LocalSession, profile.Species, EntityManager, _prototypeManager);
|
||||
GiveDummyLoadout(dummy, loadout);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the highest priority job for the profile.
|
||||
/// </summary>
|
||||
public JobPrototype GetPreferredJob(HumanoidCharacterProfile profile)
|
||||
{
|
||||
var highPriorityJob = profile.JobPriorities.FirstOrDefault(p => p.Value == JobPriority.High).Key;
|
||||
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract (what is resharper smoking?)
|
||||
return _prototypeManager.Index<JobPrototype>(highPriorityJob.Id ?? SharedGameTicker.FallbackOverflowJob);
|
||||
}
|
||||
|
||||
public void GiveDummyLoadout(EntityUid uid, RoleLoadout? roleLoadout)
|
||||
{
|
||||
if (roleLoadout == null)
|
||||
return;
|
||||
|
||||
foreach (var group in roleLoadout.SelectedLoadouts.Values)
|
||||
{
|
||||
foreach (var loadout in group)
|
||||
{
|
||||
if (!_prototypeManager.Resolve(loadout.Prototype, out var loadoutProto))
|
||||
continue;
|
||||
|
||||
_spawn.EquipStartingGear(uid, loadoutProto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the specified job's clothes to the dummy.
|
||||
/// </summary>
|
||||
public void GiveDummyJobClothes(EntityUid dummy, HumanoidCharacterProfile profile, JobPrototype job)
|
||||
{
|
||||
if (!_inventory.TryGetSlots(dummy, out var slots))
|
||||
return;
|
||||
|
||||
// Apply loadout
|
||||
if (profile.Loadouts.TryGetValue(job.ID, out var jobLoadout))
|
||||
{
|
||||
foreach (var loadouts in jobLoadout.SelectedLoadouts.Values)
|
||||
{
|
||||
foreach (var loadout in loadouts)
|
||||
{
|
||||
if (!_prototypeManager.Resolve(loadout.Prototype, out var loadoutProto))
|
||||
continue;
|
||||
|
||||
// TODO: Need some way to apply starting gear to an entity and replace existing stuff coz holy fucking shit dude.
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
// Try startinggear first
|
||||
if (_prototypeManager.Resolve(loadoutProto.StartingGear, out var loadoutGear))
|
||||
{
|
||||
var itemType = ((IEquipmentLoadout) loadoutGear).GetGear(slot.Name);
|
||||
|
||||
if (_inventory.TryUnequip(dummy, slot.Name, out var unequippedItem, silent: true, force: true, reparent: false))
|
||||
{
|
||||
EntityManager.DeleteEntity(unequippedItem.Value);
|
||||
}
|
||||
|
||||
if (itemType != string.Empty)
|
||||
{
|
||||
var item = EntityManager.SpawnEntity(itemType, MapCoordinates.Nullspace);
|
||||
_inventory.TryEquip(dummy, item, slot.Name, true, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemType = ((IEquipmentLoadout) loadoutProto).GetGear(slot.Name);
|
||||
|
||||
if (_inventory.TryUnequip(dummy, slot.Name, out var unequippedItem, silent: true, force: true, reparent: false))
|
||||
{
|
||||
EntityManager.DeleteEntity(unequippedItem.Value);
|
||||
}
|
||||
|
||||
if (itemType != string.Empty)
|
||||
{
|
||||
var item = EntityManager.SpawnEntity(itemType, MapCoordinates.Nullspace);
|
||||
_inventory.TryEquip(dummy, item, slot.Name, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_prototypeManager.Resolve(job.StartingGear, out var gear))
|
||||
return;
|
||||
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
var itemType = ((IEquipmentLoadout) gear).GetGear(slot.Name);
|
||||
|
||||
if (_inventory.TryUnequip(dummy, slot.Name, out var unequippedItem, silent: true, force: true, reparent: false))
|
||||
{
|
||||
EntityManager.DeleteEntity(unequippedItem.Value);
|
||||
}
|
||||
|
||||
if (itemType != string.Empty)
|
||||
{
|
||||
var item = EntityManager.SpawnEntity(itemType, MapCoordinates.Nullspace);
|
||||
_inventory.TryEquip(dummy, item, slot.Name, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the profile onto a dummy entity.
|
||||
/// </summary>
|
||||
public EntityUid LoadProfileEntity(HumanoidCharacterProfile? humanoid, JobPrototype? job, bool jobClothes)
|
||||
{
|
||||
EntityUid dummyEnt;
|
||||
|
||||
EntProtoId? previewEntity = null;
|
||||
if (humanoid != null && jobClothes)
|
||||
{
|
||||
job ??= GetPreferredJob(humanoid);
|
||||
|
||||
previewEntity = job.JobPreviewEntity ?? (EntProtoId?)job?.JobEntity;
|
||||
}
|
||||
|
||||
if (previewEntity != null)
|
||||
{
|
||||
// Special type like borg or AI, do not spawn a human just spawn the entity.
|
||||
dummyEnt = EntityManager.SpawnEntity(previewEntity, MapCoordinates.Nullspace);
|
||||
return dummyEnt;
|
||||
}
|
||||
else if (humanoid is not null)
|
||||
{
|
||||
var dummy = _prototypeManager.Index(humanoid.Species).DollPrototype;
|
||||
dummyEnt = EntityManager.SpawnEntity(dummy, MapCoordinates.Nullspace);
|
||||
_visualBody.ApplyProfileTo(dummyEnt, humanoid);
|
||||
}
|
||||
else
|
||||
{
|
||||
dummyEnt = EntityManager.SpawnEntity(_prototypeManager.Index(HumanoidCharacterProfile.DefaultSpecies).DollPrototype, MapCoordinates.Nullspace);
|
||||
}
|
||||
|
||||
if (humanoid != null && jobClothes)
|
||||
{
|
||||
DebugTools.Assert(job != null);
|
||||
|
||||
GiveDummyJobClothes(dummyEnt, humanoid, job);
|
||||
|
||||
if (_prototypeManager.HasIndex<RoleLoadoutPrototype>(LoadoutSystem.GetJobPrototype(job.ID)))
|
||||
{
|
||||
var loadout = humanoid.GetLoadoutOrDefault(LoadoutSystem.GetJobPrototype(job.ID), _playerManager.LocalSession, humanoid.Species, EntityManager, _prototypeManager);
|
||||
GiveDummyLoadout(dummyEnt, loadout);
|
||||
}
|
||||
}
|
||||
|
||||
return dummyEnt;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<ContainerButton xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:profile="clr-namespace:Content.Client.Lobby.UI.ProfileEditorControls"
|
||||
xmlns:style="clr-namespace:Content.Client.Stylesheets">
|
||||
<BoxContainer Orientation="Horizontal"
|
||||
HorizontalExpand="True"
|
||||
SeparationOverride="0"
|
||||
Name="InternalHBox">
|
||||
<SpriteView Scale="2 2"
|
||||
Margin="0 4 4 4"
|
||||
OverrideDirection="South"
|
||||
Name="View"
|
||||
SetSize="64 64"/>
|
||||
<profile:ProfilePreviewSpriteView Scale="2 2"
|
||||
Margin="0 4 4 4"
|
||||
OverrideDirection="South"
|
||||
Name="View"
|
||||
SetSize="64 64"/>
|
||||
<Label Name="DescriptionLabel"
|
||||
ClipText="True"
|
||||
HorizontalExpand="True"/>
|
||||
|
||||
@@ -10,6 +10,7 @@ using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Lobby.UI;
|
||||
@@ -20,37 +21,28 @@ namespace Content.Client.Lobby.UI;
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CharacterPickerButton : ContainerButton
|
||||
{
|
||||
private IEntityManager _entManager;
|
||||
|
||||
private EntityUid _previewDummy;
|
||||
|
||||
/// <summary>
|
||||
/// Invoked if we should delete the attached character
|
||||
/// </summary>
|
||||
public event Action? OnDeletePressed;
|
||||
|
||||
public CharacterPickerButton(
|
||||
IEntityManager entityManager,
|
||||
IPrototypeManager prototypeManager,
|
||||
ISharedPlayerManager playerMan,
|
||||
ButtonGroup group,
|
||||
ICharacterProfile profile,
|
||||
bool isSelected)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_entManager = entityManager;
|
||||
AddStyleClass(StyleClassButton);
|
||||
ToggleMode = true;
|
||||
Group = group;
|
||||
var description = profile.Name;
|
||||
|
||||
if (profile is not HumanoidCharacterProfile humanoid)
|
||||
View.LoadPreview(profile);
|
||||
|
||||
if (profile is HumanoidCharacterProfile humanoid)
|
||||
{
|
||||
_previewDummy = entityManager.SpawnEntity(prototypeManager.Index<SpeciesPrototype>(HumanoidCharacterProfile.DefaultSpecies).DollPrototype, MapCoordinates.Nullspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
_previewDummy = UserInterfaceManager.GetUIController<LobbyUIController>()
|
||||
.LoadProfileEntity(humanoid, null, true);
|
||||
|
||||
var highPriorityJob = humanoid.JobPriorities.SingleOrDefault(p => p.Value == JobPriority.High).Key;
|
||||
if (highPriorityJob != default)
|
||||
@@ -63,7 +55,6 @@ public sealed partial class CharacterPickerButton : ContainerButton
|
||||
Pressed = isSelected;
|
||||
DeleteButton.Visible = !isSelected;
|
||||
|
||||
View.SetEntity(_previewDummy);
|
||||
DescriptionLabel.Text = description;
|
||||
|
||||
ConfirmDeleteButton.OnPressed += _ =>
|
||||
@@ -79,14 +70,4 @@ public sealed partial class CharacterPickerButton : ContainerButton
|
||||
ConfirmDeleteButton.Visible = true;
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
_entManager.DeleteEntity(_previewDummy);
|
||||
_previewDummy = default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Lobby.UI
|
||||
@@ -22,10 +23,10 @@ namespace Content.Client.Lobby.UI
|
||||
public sealed partial class CharacterSetupGui : Control
|
||||
{
|
||||
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protomanager = default!;
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;
|
||||
|
||||
private readonly Button _createNewCharacterButton;
|
||||
|
||||
@@ -99,8 +100,8 @@ namespace Content.Client.Lobby.UI
|
||||
foreach (var (slot, character) in _preferencesManager.Preferences!.Characters)
|
||||
{
|
||||
numberOfFullSlots++;
|
||||
var characterPickerButton = new CharacterPickerButton(_entManager,
|
||||
_protomanager,
|
||||
var characterPickerButton = new CharacterPickerButton(_protomanager,
|
||||
_playerManager,
|
||||
characterButtonsGroup,
|
||||
character,
|
||||
slot == selectedSlot);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
xmlns:humanoid="clr-namespace:Content.Client.Humanoid"
|
||||
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:ui="clr-namespace:Content.Client.Lobby.UI"
|
||||
xmlns:profile="clr-namespace:Content.Client.Lobby.UI.ProfileEditorControls"
|
||||
HorizontalExpand="True">
|
||||
<!-- Left side -->
|
||||
<BoxContainer Orientation="Vertical" Margin="10 10 10 10" HorizontalExpand="True">
|
||||
@@ -133,7 +134,7 @@
|
||||
</BoxContainer>
|
||||
<!-- Right side -->
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True" VerticalAlignment="Center">
|
||||
<SpriteView Name="SpriteView" Scale="8 8" Margin="4" SizeFlagsStretchRatio="1" />
|
||||
<profile:ProfilePreviewSpriteView Name="SpriteView" Scale="8 8" Margin="4" SizeFlagsStretchRatio="1" />
|
||||
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Center" Margin="0 5">
|
||||
<Button Name="SpriteRotateLeft" Text="◀" StyleClasses="OpenRight" />
|
||||
<cc:VSeparator Margin="2 0 3 0" />
|
||||
|
||||
@@ -77,11 +77,6 @@ namespace Content.Client.Lobby.UI
|
||||
/// </summary>
|
||||
public event Action? Save;
|
||||
|
||||
/// <summary>
|
||||
/// Entity used for the profile editor preview
|
||||
/// </summary>
|
||||
public EntityUid PreviewDummy;
|
||||
|
||||
/// <summary>
|
||||
/// Temporary override of their selected job, used to preview roles.
|
||||
/// </summary>
|
||||
@@ -683,15 +678,10 @@ namespace Content.Client.Lobby.UI
|
||||
/// </remarks>
|
||||
private void ReloadPreview()
|
||||
{
|
||||
_entManager.DeleteEntity(PreviewDummy);
|
||||
PreviewDummy = EntityUid.Invalid;
|
||||
|
||||
if (Profile == null || !_prototypeManager.HasIndex(Profile.Species))
|
||||
if (Profile == null)
|
||||
return;
|
||||
|
||||
PreviewDummy = _controller.LoadProfileEntity(Profile, JobOverride, ShowClothes.Pressed);
|
||||
SpriteView.SetEntity(PreviewDummy);
|
||||
_entManager.System<MetaDataSystem>().SetEntityName(PreviewDummy, Profile.Name);
|
||||
SpriteView.LoadPreview(Profile, JobOverride, ShowClothes.Pressed);
|
||||
|
||||
// Check and set the dirty flag to enable the save/reset buttons as appropriate.
|
||||
SetDirty();
|
||||
@@ -743,16 +733,15 @@ namespace Content.Client.Lobby.UI
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A slim reload that only updates the entity itself and not any of the job entities, etc.
|
||||
/// </summary>
|
||||
private void ReloadProfilePreview()
|
||||
{
|
||||
if (Profile == null || !_entManager.EntityExists(PreviewDummy))
|
||||
if (Profile == null)
|
||||
return;
|
||||
|
||||
_entManager.System<SharedVisualBodySystem>().ApplyProfileTo(PreviewDummy, Profile);
|
||||
SpriteView.ReloadProfilePreview(Profile);
|
||||
|
||||
// Check and set the dirty flag to enable the save/reset buttons as appropriate.
|
||||
SetDirty();
|
||||
@@ -1104,13 +1093,6 @@ namespace Content.Client.Lobby.UI
|
||||
ReloadPreview();
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
base.ExitedTree();
|
||||
_entManager.DeleteEntity(PreviewDummy);
|
||||
PreviewDummy = EntityUid.Invalid;
|
||||
}
|
||||
|
||||
private void SetAge(int newAge)
|
||||
{
|
||||
Profile = Profile?.WithAge(newAge);
|
||||
@@ -1177,7 +1159,7 @@ namespace Content.Client.Lobby.UI
|
||||
if (!IsDirty)
|
||||
return;
|
||||
|
||||
_entManager.System<MetaDataSystem>().SetEntityName(PreviewDummy, newName);
|
||||
SpriteView.SetName(newName);
|
||||
}
|
||||
|
||||
private void SetSpawnPriority(SpawnPriorityPreference newSpawnPriority)
|
||||
@@ -1397,7 +1379,7 @@ namespace Content.Client.Lobby.UI
|
||||
|
||||
// I tried disabling the button but it looks sorta goofy as it only takes a frame or two to save
|
||||
_imaging = true;
|
||||
await _entManager.System<ContentSpriteSystem>().Export(PreviewDummy, dir, includeId: false);
|
||||
await _entManager.System<ContentSpriteSystem>().Export(SpriteView.PreviewDummy, dir, includeId: false);
|
||||
_imaging = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<Control
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:profile="clr-namespace:Content.Client.Lobby.UI.ProfileEditorControls">
|
||||
<BoxContainer Name="VBox" Orientation="Vertical">
|
||||
<controls:NanoHeading Name="Header" Text="{Loc 'lobby-character-preview-panel-header'}">
|
||||
|
||||
@@ -10,7 +11,12 @@
|
||||
Visible="False">
|
||||
<Label Name="Summary" HorizontalAlignment="Center" Margin="3 3"/>
|
||||
<BoxContainer Name="ViewBox" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
|
||||
<profile:ProfilePreviewSpriteView Name="ProfilePreviewSpriteView"
|
||||
OverrideDirection="South"
|
||||
Scale="4 4"
|
||||
MaxSize="112 112"
|
||||
Stretch="Fill"
|
||||
Access="Public" />
|
||||
</BoxContainer>
|
||||
<controls:VSpacer/>
|
||||
<Button Name="CharacterSetup" Text="{Loc 'lobby-character-preview-panel-character-setup-button'}"
|
||||
|
||||
@@ -4,18 +4,16 @@ using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Lobby.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class LobbyCharacterPreviewPanel : Control
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
|
||||
public Button CharacterSetupButton => CharacterSetup;
|
||||
|
||||
private EntityUid? _previewDummy;
|
||||
|
||||
public LobbyCharacterPreviewPanel()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
@@ -32,32 +30,4 @@ public sealed partial class LobbyCharacterPreviewPanel : Control
|
||||
{
|
||||
Summary.Text = value;
|
||||
}
|
||||
|
||||
public void SetSprite(EntityUid uid)
|
||||
{
|
||||
if (_previewDummy != null)
|
||||
{
|
||||
_entManager.DeleteEntity(_previewDummy);
|
||||
}
|
||||
|
||||
_previewDummy = uid;
|
||||
|
||||
ViewBox.RemoveAllChildren();
|
||||
var spriteView = new SpriteView
|
||||
{
|
||||
OverrideDirection = Direction.South,
|
||||
Scale = new Vector2(4f, 4f),
|
||||
MaxSize = new Vector2(112, 112),
|
||||
Stretch = SpriteView.StretchMode.Fill,
|
||||
};
|
||||
spriteView.SetEntity(uid);
|
||||
ViewBox.AddChild(spriteView);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
_entManager.DeleteEntity(_previewDummy);
|
||||
_previewDummy = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Humanoid;
|
||||
using Content.Client.Station;
|
||||
using Content.Shared.Body;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Preferences.Loadouts;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client.Lobby.UI.ProfileEditorControls;
|
||||
|
||||
public sealed partial class ProfilePreviewSpriteView
|
||||
{
|
||||
/// <summary>
|
||||
/// A slim reload that only updates the entity itself and not any of the job entities, etc.
|
||||
/// </summary>
|
||||
private void ReloadHumanoidEntity(HumanoidCharacterProfile humanoid)
|
||||
{
|
||||
if (!EntMan.EntityExists(PreviewDummy) ||
|
||||
!EntMan.HasComponent<VisualBodyComponent>(PreviewDummy))
|
||||
return;
|
||||
|
||||
EntMan.System<SharedVisualBodySystem>().ApplyProfileTo(PreviewDummy, humanoid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the profile onto a dummy entity.
|
||||
/// </summary>
|
||||
private void LoadHumanoidEntity(HumanoidCharacterProfile? humanoid, JobPrototype? job, bool jobClothes)
|
||||
{
|
||||
EntProtoId? previewEntity = null;
|
||||
if (humanoid != null && jobClothes)
|
||||
{
|
||||
job ??= GetPreferredJob(humanoid);
|
||||
|
||||
previewEntity = job.JobPreviewEntity ?? (EntProtoId?)job?.JobEntity;
|
||||
}
|
||||
|
||||
if (previewEntity != null)
|
||||
{
|
||||
// Special type like borg or AI, do not spawn a human just spawn the entity.
|
||||
PreviewDummy = EntMan.SpawnEntity(previewEntity, MapCoordinates.Nullspace);
|
||||
}
|
||||
else if (humanoid is not null)
|
||||
{
|
||||
var dummy = _prototypeManager.Index(humanoid.Species).DollPrototype;
|
||||
PreviewDummy = EntMan.SpawnEntity(dummy, MapCoordinates.Nullspace);
|
||||
EntMan.System<SharedVisualBodySystem>().ApplyProfileTo(PreviewDummy, humanoid);
|
||||
}
|
||||
else
|
||||
{
|
||||
PreviewDummy = EntMan.SpawnEntity(_prototypeManager.Index(HumanoidCharacterProfile.DefaultSpecies).DollPrototype, MapCoordinates.Nullspace);
|
||||
}
|
||||
|
||||
if (humanoid != null && jobClothes)
|
||||
{
|
||||
DebugTools.Assert(job != null);
|
||||
|
||||
GiveDummyJobClothes(humanoid, job);
|
||||
|
||||
if (_prototypeManager.HasIndex<RoleLoadoutPrototype>(LoadoutSystem.GetJobPrototype(job.ID)))
|
||||
{
|
||||
var loadout = humanoid.GetLoadoutOrDefault(LoadoutSystem.GetJobPrototype(job.ID), _playerManager.LocalSession, humanoid.Species, EntMan, _prototypeManager);
|
||||
GiveDummyLoadout(loadout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the highest priority job for the profile.
|
||||
/// </summary>
|
||||
private JobPrototype GetPreferredJob(HumanoidCharacterProfile profile)
|
||||
{
|
||||
var highPriorityJob = profile.JobPriorities.FirstOrDefault(p => p.Value == JobPriority.High).Key;
|
||||
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract (what is resharper smoking?)
|
||||
return _prototypeManager.Index<JobPrototype>(highPriorityJob.Id ?? SharedGameTicker.FallbackOverflowJob);
|
||||
}
|
||||
|
||||
private void GiveDummyLoadout(RoleLoadout? roleLoadout)
|
||||
{
|
||||
if (roleLoadout == null)
|
||||
return;
|
||||
|
||||
var spawnSys = EntMan.System<StationSpawningSystem>();
|
||||
|
||||
foreach (var group in roleLoadout.SelectedLoadouts.Values)
|
||||
{
|
||||
foreach (var loadout in group)
|
||||
{
|
||||
if (!_prototypeManager.Resolve(loadout.Prototype, out var loadoutProto))
|
||||
continue;
|
||||
|
||||
spawnSys.EquipStartingGear(PreviewDummy, loadoutProto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the specified job's clothes to the dummy.
|
||||
/// </summary>
|
||||
private void GiveDummyJobClothes(HumanoidCharacterProfile profile, JobPrototype job)
|
||||
{
|
||||
var inventorySys = EntMan.System<InventorySystem>();
|
||||
if (!inventorySys.TryGetSlots(PreviewDummy, out var slots))
|
||||
return;
|
||||
|
||||
// Apply loadout
|
||||
if (profile.Loadouts.TryGetValue(job.ID, out var jobLoadout))
|
||||
{
|
||||
foreach (var loadouts in jobLoadout.SelectedLoadouts.Values)
|
||||
{
|
||||
foreach (var loadout in loadouts)
|
||||
{
|
||||
if (!_prototypeManager.Resolve(loadout.Prototype, out var loadoutProto))
|
||||
continue;
|
||||
|
||||
// TODO: Need some way to apply starting gear to an entity and replace existing stuff coz holy fucking shit dude.
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
// Try startinggear first
|
||||
if (_prototypeManager.Resolve(loadoutProto.StartingGear, out var loadoutGear))
|
||||
{
|
||||
var itemType = ((IEquipmentLoadout) loadoutGear).GetGear(slot.Name);
|
||||
|
||||
if (inventorySys.TryUnequip(PreviewDummy, slot.Name, out var unequippedItem, silent: true, force: true, reparent: false))
|
||||
{
|
||||
EntMan.DeleteEntity(unequippedItem.Value);
|
||||
}
|
||||
|
||||
if (itemType != string.Empty)
|
||||
{
|
||||
var item = EntMan.SpawnEntity(itemType, MapCoordinates.Nullspace);
|
||||
inventorySys.TryEquip(PreviewDummy, item, slot.Name, true, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemType = ((IEquipmentLoadout) loadoutProto).GetGear(slot.Name);
|
||||
|
||||
if (inventorySys.TryUnequip(PreviewDummy, slot.Name, out var unequippedItem, silent: true, force: true, reparent: false))
|
||||
{
|
||||
EntMan.DeleteEntity(unequippedItem.Value);
|
||||
}
|
||||
|
||||
if (itemType != string.Empty)
|
||||
{
|
||||
var item = EntMan.SpawnEntity(itemType, MapCoordinates.Nullspace);
|
||||
inventorySys.TryEquip(PreviewDummy, item, slot.Name, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_prototypeManager.Resolve(job.StartingGear, out var gear))
|
||||
return;
|
||||
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
var itemType = ((IEquipmentLoadout) gear).GetGear(slot.Name);
|
||||
|
||||
if (inventorySys.TryUnequip(PreviewDummy, slot.Name, out var unequippedItem, silent: true, force: true, reparent: false))
|
||||
{
|
||||
EntMan.DeleteEntity(unequippedItem.Value);
|
||||
}
|
||||
|
||||
if (itemType != string.Empty)
|
||||
{
|
||||
var item = EntMan.SpawnEntity(itemType, MapCoordinates.Nullspace);
|
||||
inventorySys.TryEquip(PreviewDummy, item, slot.Name, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Content.Shared.Preferences;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.Lobby.UI.ProfileEditorControls;
|
||||
|
||||
public sealed partial class ProfilePreviewSpriteView : SpriteView
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Entity used for the profile editor preview
|
||||
/// </summary>
|
||||
public EntityUid PreviewDummy;
|
||||
|
||||
public ProfilePreviewSpriteView()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reloads the entire dummy entity for preview.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is expensive so not recommended to run if you have a slider.
|
||||
/// </remarks>
|
||||
public void LoadPreview(ICharacterProfile profile, JobPrototype? jobOverride = null, bool showClothes = true)
|
||||
{
|
||||
EntMan.DeleteEntity(PreviewDummy);
|
||||
PreviewDummy = EntityUid.Invalid;
|
||||
|
||||
switch (profile)
|
||||
{
|
||||
case HumanoidCharacterProfile humanoid:
|
||||
LoadHumanoidEntity(humanoid, jobOverride, showClothes);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Only humanoid profiles are implemented in ProfilePreviewSpriteView");
|
||||
}
|
||||
|
||||
SetEntity(PreviewDummy);
|
||||
SetName(profile.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the preview entity's name without reloading anything else.
|
||||
/// </summary>
|
||||
public void SetName(string newName)
|
||||
{
|
||||
EntMan.System<MetaDataSystem>().SetEntityName(PreviewDummy, newName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A slim reload that only updates the entity itself and not any of the job entities, etc.
|
||||
/// </summary>
|
||||
public void ReloadProfilePreview(ICharacterProfile profile)
|
||||
{
|
||||
switch (profile)
|
||||
{
|
||||
case HumanoidCharacterProfile humanoid:
|
||||
ReloadHumanoidEntity(humanoid);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Only humanoid profiles are implemented in ProfilePreviewSpriteView");
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearPreview()
|
||||
{
|
||||
EntMan.DeleteEntity(PreviewDummy);
|
||||
PreviewDummy = EntityUid.Invalid;
|
||||
}
|
||||
|
||||
protected override void ExitedTree()
|
||||
{
|
||||
base.ExitedTree();
|
||||
ClearPreview();
|
||||
}
|
||||
}
|
||||
@@ -15,8 +15,8 @@
|
||||
<ui:OptionSlider Name="SpeechBubbleSpeakerOpacitySlider" Title="{Loc 'ui-options-speech-bubble-speaker-opacity'}" />
|
||||
<ui:OptionSlider Name="SpeechBubbleBackgroundOpacitySlider" Title="{Loc 'ui-options-speech-bubble-background-opacity'}" />
|
||||
<CheckBox Name="AutoFillHighlightsCheckBox" Text="{Loc 'ui-options-auto-fill-highlights'}" />
|
||||
<ui:OptionColorSlider Name="HighlightsColorSlider"
|
||||
Title="{Loc 'ui-options-highlights-color'}"
|
||||
<ui:OptionColorSlider Name="HighlightsColorSlider"
|
||||
Title="{Loc 'ui-options-highlights-color'}"
|
||||
Example="{Loc 'ui-options-highlights-color-example'}"/>
|
||||
<Label Text="{Loc 'ui-options-accessability-header-content'}"
|
||||
StyleClasses="LabelKeyText"/>
|
||||
|
||||
@@ -36,12 +36,6 @@ namespace Content.Client.Options.UI.Tabs
|
||||
|
||||
private readonly List<Action> _deferCommands = new();
|
||||
|
||||
private void HandleToggleUSQWERTYCheckbox(BaseButton.ButtonToggledEventArgs args)
|
||||
{
|
||||
_cfg.SetCVar(CVars.DisplayUSQWERTYHotkeys, args.Pressed);
|
||||
_cfg.SaveToFile();
|
||||
}
|
||||
|
||||
private void InitToggleWalk()
|
||||
{
|
||||
if (_cfg.GetCVar(CCVars.ToggleWalk))
|
||||
@@ -150,8 +144,23 @@ namespace Content.Client.Options.UI.Tabs
|
||||
KeybindsContainer.AddChild(newCheckBox);
|
||||
}
|
||||
|
||||
void AddToggleCvarCheckBox(string checkBoxName, CVarDef<bool> cvar)
|
||||
{
|
||||
CheckBox newCheckBox = new CheckBox() { Text = Loc.GetString(checkBoxName) };
|
||||
newCheckBox.Pressed = _cfg.GetCVar(cvar);
|
||||
newCheckBox.OnToggled += (e) =>
|
||||
{
|
||||
_cfg.SetCVar(cvar, e.Pressed);
|
||||
_cfg.SaveToFile();
|
||||
};
|
||||
|
||||
KeybindsContainer.AddChild(newCheckBox);
|
||||
}
|
||||
|
||||
AddHeader("ui-options-header-general");
|
||||
AddCheckBox("ui-options-hotkey-keymap", _cfg.GetCVar(CVars.DisplayUSQWERTYHotkeys), HandleToggleUSQWERTYCheckbox);
|
||||
AddToggleCvarCheckBox("ui-options-hotkey-keymap", CVars.DisplayUSQWERTYHotkeys);
|
||||
AddToggleCvarCheckBox("ui-options-hold-to-attack-melee", CCVars.ControlHoldToAttackMelee);
|
||||
AddToggleCvarCheckBox("ui-options-hold-to-attack-ranged", CCVars.ControlHoldToAttackRanged);
|
||||
|
||||
AddHeader("ui-options-header-movement");
|
||||
AddButton(EngineKeyFunctions.MoveUp);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using Content.Client.Light.EntitySystems;
|
||||
using Content.Shared.Trigger;
|
||||
using Content.Shared.Trigger.Components.Effects;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Trigger.Systems;
|
||||
|
||||
/// <summary>
|
||||
/// This handles...
|
||||
/// </summary>
|
||||
public sealed class LightBehaviorOnTriggerSystem : XOnTriggerSystem<LightBehaviorOnTriggerComponent>
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly LightBehaviorSystem _light = default!;
|
||||
|
||||
protected override void OnTrigger(Entity<LightBehaviorOnTriggerComponent> ent, EntityUid target, ref TriggerEvent args)
|
||||
{
|
||||
if (_timing.IsFirstTimePredicted)
|
||||
_light.StartLightBehaviour(target, ent.Comp.Behavior);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,12 @@
|
||||
using System.Numerics;
|
||||
using Content.Client.Administration.Managers;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Markers;
|
||||
using Content.Client.Sandbox;
|
||||
using Content.Client.SubFloor;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Client.UserInterface.Systems.DecalPlacer;
|
||||
using Content.Client.UserInterface.Systems.Sandbox.Windows;
|
||||
using Content.Shared.Input;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Debugging;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
@@ -30,14 +26,10 @@ namespace Content.Client.UserInterface.Systems.Sandbox;
|
||||
public sealed class SandboxUIController : UIController, IOnStateChanged<GameplayState>, IOnSystemChanged<SandboxSystem>
|
||||
{
|
||||
[Dependency] private readonly IConsoleHost _console = default!;
|
||||
[Dependency] private readonly IEyeManager _eye = default!;
|
||||
[Dependency] private readonly IInputManager _input = default!;
|
||||
[Dependency] private readonly ILightManager _light = default!;
|
||||
[Dependency] private readonly IClientAdminManager _admin = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
[UISystemDependency] private readonly DebugPhysicsSystem _debugPhysics = default!;
|
||||
[UISystemDependency] private readonly MarkerSystem _marker = default!;
|
||||
[UISystemDependency] private readonly SandboxSystem _sandbox = default!;
|
||||
|
||||
private SandboxWindow? _window;
|
||||
@@ -117,13 +109,6 @@ public sealed class SandboxUIController : UIController, IOnStateChanged<Gameplay
|
||||
_window.OnOpen += () => { SandboxButton!.Pressed = true; };
|
||||
_window.OnClose += () => { SandboxButton!.Pressed = false; };
|
||||
|
||||
// TODO: These need moving to opened so at least if they're not synced properly on open they work.
|
||||
_window.ToggleLightButton.Pressed = !_light.Enabled;
|
||||
_window.ToggleFovButton.Pressed = !_eye.CurrentEye.DrawFov;
|
||||
_window.ToggleShadowsButton.Pressed = !_light.DrawShadows;
|
||||
_window.ShowMarkersButton.Pressed = _marker.MarkersVisible;
|
||||
_window.ShowBbButton.Pressed = (_debugPhysics.Flags & PhysicsDebugFlags.Shapes) != 0x0;
|
||||
|
||||
_window.AiOverlayButton.OnPressed += args =>
|
||||
{
|
||||
var player = _player.LocalEntity;
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
using Content.Client.SubFloor;
|
||||
using Content.Client.Markers;
|
||||
using Content.Client.SubFloor;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Silicons.StationAi;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Debugging;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
@@ -10,17 +15,33 @@ namespace Content.Client.UserInterface.Systems.Sandbox.Windows;
|
||||
public sealed partial class SandboxWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = null!;
|
||||
[Dependency] private readonly IEyeManager _eyeManager = null!;
|
||||
[Dependency] private readonly ILightManager _lightManager = null!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = null!;
|
||||
private readonly DebugPhysicsSystem _debugPhysicsSystem;
|
||||
private readonly MarkerSystem _markerSystem;
|
||||
private readonly SubFloorHideSystem _subFloorSystem;
|
||||
|
||||
public SandboxWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_debugPhysicsSystem = _entManager.System<DebugPhysicsSystem>();
|
||||
_markerSystem = _entManager.System<MarkerSystem>();
|
||||
_subFloorSystem = _entManager.System<SubFloorHideSystem>();
|
||||
}
|
||||
|
||||
protected override void Opened()
|
||||
{
|
||||
base.Opened();
|
||||
// Make sure state is up to date.
|
||||
ToggleSubfloorButton.Pressed = _entManager.System<SubFloorHideSystem>().ShowAll;
|
||||
|
||||
ToggleSubfloorButton.Pressed = _subFloorSystem.ShowAll;
|
||||
ToggleLightButton.Pressed = !_lightManager.Enabled;
|
||||
ToggleFovButton.Pressed = !_eyeManager.CurrentEye.DrawFov;
|
||||
ToggleShadowsButton.Pressed = !_lightManager.DrawShadows;
|
||||
ShowMarkersButton.Pressed = _markerSystem.MarkersVisible;
|
||||
ShowBbButton.Pressed = (_debugPhysicsSystem.Flags & PhysicsDebugFlags.Shapes) != 0x0;
|
||||
AiOverlayButton.Pressed = _playerManager.LocalEntity is { } player && _entManager.HasComponent<StationAiOverlayComponent>(player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,18 +12,28 @@ namespace Content.Client.Voting.UI
|
||||
{
|
||||
[Dependency] private readonly IVoteManager _voteManager = default!;
|
||||
|
||||
private VoteCallMenu? _voteCallMenu;
|
||||
|
||||
public VoteCallMenuButton()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Text = Loc.GetString("ui-vote-menu-button");
|
||||
ToggleMode = true;
|
||||
OnPressed += OnOnPressed;
|
||||
}
|
||||
|
||||
private void OnOnPressed(ButtonEventArgs obj)
|
||||
{
|
||||
var menu = new VoteCallMenu();
|
||||
menu.OpenCentered();
|
||||
if (_voteCallMenu is { IsOpen: true })
|
||||
{
|
||||
_voteCallMenu.Close();
|
||||
return;
|
||||
}
|
||||
|
||||
_voteCallMenu = new VoteCallMenu();
|
||||
_voteCallMenu.OnClose += () => Pressed = false;
|
||||
_voteCallMenu.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void EnteredTree()
|
||||
@@ -38,6 +48,9 @@ namespace Content.Client.Voting.UI
|
||||
{
|
||||
base.ExitedTree();
|
||||
|
||||
if (_voteCallMenu is { IsOpen: true })
|
||||
_voteCallMenu.Close();
|
||||
|
||||
_voteManager.CanCallVoteChanged += UpdateCanCall;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.CombatMode;
|
||||
using Content.Shared.Effects;
|
||||
using Content.Shared.Hands.Components;
|
||||
@@ -14,6 +15,7 @@ using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.State;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
@@ -31,6 +33,7 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
||||
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
|
||||
[Dependency] private readonly MapSystem _map = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
|
||||
private EntityQuery<TransformComponent> _xformQuery;
|
||||
|
||||
@@ -76,7 +79,7 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
||||
var useDown = _inputSystem.CmdStates.GetState(EngineKeyFunctions.Use);
|
||||
var altDown = _inputSystem.CmdStates.GetState(EngineKeyFunctions.UseSecondary);
|
||||
|
||||
if (weapon.AutoAttack || useDown != BoundKeyState.Down && altDown != BoundKeyState.Down)
|
||||
if (weapon.AutoAttack || useDown != BoundKeyState.Down && altDown != BoundKeyState.Down || _cfg.GetCVar(CCVars.ControlHoldToAttackMelee))
|
||||
{
|
||||
if (weapon.Attacking)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Client.Gameplay;
|
||||
using Content.Client.Items;
|
||||
using Content.Client.Weapons.Ranged.Components;
|
||||
using Content.Shared.Camera;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.CombatMode;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Weapons.Hitscan.Components;
|
||||
@@ -19,6 +20,7 @@ using Robust.Client.Player;
|
||||
using Robust.Client.State;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
@@ -38,6 +40,7 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
[Dependency] private readonly IOverlayManager _overlayManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly IStateManager _state = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly SharedCameraRecoilSystem _recoil = default!;
|
||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xform = default!;
|
||||
@@ -203,11 +206,13 @@ public sealed partial class GunSystem : SharedGunSystem
|
||||
|
||||
Log.Debug($"Sending shoot request tick {Timing.CurTick} / {Timing.CurTime}");
|
||||
|
||||
|
||||
RaisePredictiveEvent(new RequestShootEvent
|
||||
{
|
||||
Target = target,
|
||||
Coordinates = GetNetCoordinates(coordinates),
|
||||
Gun = GetNetEntity(gun),
|
||||
Continuous = _cfg.GetCVar(CCVars.ControlHoldToAttackRanged),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -240,14 +240,6 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
column: "ban_id",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_server_ban_hit_ban_ban_id",
|
||||
table: "server_ban_hit",
|
||||
column: "ban_id",
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.Sql("""
|
||||
CREATE INDEX "IX_ban_address_address"
|
||||
ON ban_address
|
||||
@@ -490,6 +482,14 @@ namespace Content.Server.Database.Migrations.Postgres
|
||||
AND round_id IS NOT NULL;
|
||||
""");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_server_ban_hit_ban_ban_id",
|
||||
table: "server_ban_hit",
|
||||
column: "ban_id",
|
||||
principalTable: "ban",
|
||||
principalColumn: "ban_id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_server_ban_hit_server_ban_ban_id",
|
||||
table: "server_ban_hit");
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed class AddActionCommand : LocalizedEntityCommands
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
shell.WriteError(Loc.GetString(Loc.GetString("cmd-addaction-invalid-args")));
|
||||
shell.WriteError(Loc.GetString("cmd-addaction-invalid-args"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public sealed class RemoveActionCommand : LocalizedEntityCommands
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
shell.WriteError(Loc.GetString(Loc.GetString("cmd-rmaction-invalid-args")));
|
||||
shell.WriteError(Loc.GetString("cmd-rmaction-invalid-args"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ namespace Content.Server.Administration.Commands
|
||||
{
|
||||
// ReSharper disable once ConvertIfStatementToSwitchStatement
|
||||
if (args.Length == 1 && TimeSpan.TryParseExact(args[0], ContentLocalizationManager.TimeSpanMinutesFormats, LocalizationManager.DefaultCulture, out var timeSpan))
|
||||
_roundEndSystem.RequestRoundEnd(timeSpan, shell.Player?.AttachedEntity, false);
|
||||
_roundEndSystem.RequestRoundEnd(timeSpan, shell.Player?.AttachedEntity, checkCooldown: false);
|
||||
|
||||
else if (args.Length == 1)
|
||||
shell.WriteLine(Loc.GetString("shell-timespan-minutes-must-be-correct"));
|
||||
|
||||
else
|
||||
_roundEndSystem.RequestRoundEnd(shell.Player?.AttachedEntity, false);
|
||||
_roundEndSystem.RequestRoundEnd(shell.Player?.AttachedEntity, checkCooldown: false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ public sealed partial class BanManager : IBanManager, IPostInjectInit
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IChatManager _chat = default!;
|
||||
[Dependency] private readonly IServerDbManager _db = default!;
|
||||
[Dependency] private readonly ServerDbEntryManager _entryManager = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
|
||||
@@ -48,7 +48,7 @@ public sealed class GasCanisterSystem : SharedGasCanisterSystem
|
||||
|
||||
protected override void DirtyUI(EntityUid uid, GasCanisterComponent? canister = null, NodeContainerComponent? nodeContainer = null)
|
||||
{
|
||||
if (!Resolve(uid, ref canister, ref nodeContainer))
|
||||
if (!Resolve(uid, ref canister, ref nodeContainer, logMissing: false))
|
||||
return;
|
||||
|
||||
var portStatus = false;
|
||||
|
||||
@@ -3,7 +3,6 @@ using Content.Server.Hands.Systems;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Body.Commands
|
||||
{
|
||||
@@ -11,7 +10,6 @@ namespace Content.Server.Body.Commands
|
||||
sealed class AddHandCommand : IConsoleCommand
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||
|
||||
private static int _handIdAccumulator;
|
||||
|
||||
|
||||
@@ -312,7 +312,7 @@ namespace Content.Server.Communications
|
||||
return;
|
||||
}
|
||||
|
||||
_roundEndSystem.RequestRoundEnd(uid);
|
||||
_roundEndSystem.RequestRoundEnd(mob, uid);
|
||||
_adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(mob):player} has called the shuttle.");
|
||||
}
|
||||
|
||||
@@ -321,13 +321,15 @@ namespace Content.Server.Communications
|
||||
if (!CanCallOrRecall(comp))
|
||||
return;
|
||||
|
||||
if (!CanUse(message.Actor, uid))
|
||||
var mob = message.Actor;
|
||||
|
||||
if (!CanUse(mob, uid))
|
||||
{
|
||||
_popupSystem.PopupEntity(Loc.GetString("comms-console-permission-denied"), uid, message.Actor);
|
||||
return;
|
||||
}
|
||||
|
||||
_roundEndSystem.CancelRoundEndCountdown(uid);
|
||||
_roundEndSystem.CancelRoundEndCountdown(mob, uid);
|
||||
_adminLogger.Add(LogType.Action, LogImpact.High, $"{ToPrettyString(message.Actor):player} has recalled the shuttle.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ namespace Content.Server.Construction
|
||||
if ((!temperatureChangeStep.MinTemperature.HasValue || temp >= temperatureChangeStep.MinTemperature.Value) &&
|
||||
(!temperatureChangeStep.MaxTemperature.HasValue || temp <= temperatureChangeStep.MaxTemperature.Value))
|
||||
{
|
||||
return HandleResult.True;
|
||||
return validation ? HandleResult.Validated : HandleResult.True;
|
||||
}
|
||||
|
||||
return HandleResult.False;
|
||||
@@ -422,7 +422,7 @@ namespace Content.Server.Construction
|
||||
break;
|
||||
|
||||
if (partAssemblyStep.Condition(uid, EntityManager))
|
||||
return HandleResult.True;
|
||||
return validation ? HandleResult.Validated : HandleResult.True;
|
||||
return HandleResult.False;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace Content.Server.Database
|
||||
{
|
||||
return document.Deserialize<TValue>();
|
||||
}
|
||||
catch (JsonException exception)
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ using Robust.Server.ServerStatus;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared.Emp;
|
||||
@@ -91,6 +92,8 @@ namespace Content.Server.Entry
|
||||
var cast = (ServerModuleTestingCallbacks)callback;
|
||||
cast.ServerBeforeIoC?.Invoke();
|
||||
}
|
||||
|
||||
Dependencies.Resolve<IRobustSerializer>().FloatFlags = SerializerFloatFlags.RemoveReadNan;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -197,8 +197,8 @@ namespace Content.Server.Forensics
|
||||
{
|
||||
Act = () => TryStartCleaning(entity, user, target),
|
||||
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/bubbles.svg.192dpi.png")),
|
||||
Text = Loc.GetString(Loc.GetString("forensics-verb-text")),
|
||||
Message = Loc.GetString(Loc.GetString("forensics-verb-message")),
|
||||
Text = Loc.GetString("forensics-verb-text"),
|
||||
Message = Loc.GetString("forensics-verb-message"),
|
||||
// This is important because if its true using the cleaning device will count as touching the object.
|
||||
DoContactInteraction = false
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Content.Server.GameTicking.Commands
|
||||
{
|
||||
if (args.Length != 1)
|
||||
{
|
||||
shell.WriteLine(Loc.GetString(Loc.GetString($"shell-need-exactly-one-argument")));
|
||||
shell.WriteLine(Loc.GetString("shell-need-exactly-one-argument"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed class XenoborgsRuleSystem : GameRuleSystem<XenoborgsRuleComponent>
|
||||
{
|
||||
_chatSystem.DispatchStationAnnouncement(station, Loc.GetString("xenoborg-shuttle-call"), colorOverride: Color.BlueViolet);
|
||||
}
|
||||
_roundEnd.RequestRoundEnd(null, false, cantRecall: true);
|
||||
_roundEnd.RequestRoundEnd(null, null, false, cantRecall: true);
|
||||
xenoborgsRuleComponent.XenoborgShuttleCalled = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
|
||||
{
|
||||
_chat.DispatchStationAnnouncement(station, Loc.GetString("zombie-shuttle-call"), colorOverride: Color.Crimson);
|
||||
}
|
||||
_roundEnd.RequestRoundEnd(null, false);
|
||||
_roundEnd.RequestRoundEnd(checkCooldown: false);
|
||||
}
|
||||
|
||||
// we include dead for this count because we don't want to end the round
|
||||
|
||||
@@ -438,20 +438,22 @@ public sealed partial class InstrumentSystem : SharedInstrumentSystem
|
||||
if (Deleted(master))
|
||||
{
|
||||
Clean(uid, instrument);
|
||||
continue;
|
||||
}
|
||||
|
||||
var masterActive = activeQuery.CompOrNull(master);
|
||||
if (masterActive == null)
|
||||
{
|
||||
Clean(uid, instrument);
|
||||
continue;
|
||||
}
|
||||
|
||||
var trans = transformQuery.GetComponent(uid);
|
||||
var masterTrans = transformQuery.GetComponent(master);
|
||||
if (!_transform.InRange(masterTrans.Coordinates, trans.Coordinates, 10f)
|
||||
)
|
||||
if (!_transform.InRange(masterTrans.Coordinates, trans.Coordinates, 10f))
|
||||
{
|
||||
Clean(uid, instrument);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public sealed class ToggleNukeCommand : LocalizedCommands
|
||||
{
|
||||
if (args.Length == 1)
|
||||
{
|
||||
return CompletionResult.FromHint(Loc.GetString(Loc.GetString("cmd-nukearm-1-help")));
|
||||
return CompletionResult.FromHint(Loc.GetString("cmd-nukearm-1-help"));
|
||||
}
|
||||
|
||||
if (args.Length == 2)
|
||||
|
||||
@@ -24,7 +24,7 @@ public sealed class AddObjectiveCommand : LocalizedEntityCommands
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
shell.WriteError(Loc.GetString(Loc.GetString("cmd-addobjective-invalid-args")));
|
||||
shell.WriteError(Loc.GetString("cmd-addobjective-invalid-args"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,6 @@ public sealed class AddObjectiveCommand : LocalizedEntityCommands
|
||||
|
||||
return CompletionResult.FromHintOptions(
|
||||
_objectives.Objectives(),
|
||||
Loc.GetString(Loc.GetString("cmd-add-objective-obj-completion")));
|
||||
Loc.GetString("cmd-add-objective-obj-completion"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Content.Server.Objectives.Commands
|
||||
{
|
||||
if (args.Length != 2)
|
||||
{
|
||||
shell.WriteError(Loc.GetString(Loc.GetString("cmd-rmobjective-invalid-args")));
|
||||
shell.WriteError(Loc.GetString("cmd-rmobjective-invalid-args"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,118 +1,33 @@
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
using Content.Shared.PowerCell;
|
||||
using Content.Shared.Radio.EntitySystems;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
|
||||
namespace Content.Server.Radio.EntitySystems;
|
||||
|
||||
public sealed class JammerSystem : SharedJammerSystem
|
||||
{
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly SharedBatterySystem _battery = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly SharedDeviceNetworkJammerSystem _jammer = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RadioJammerComponent, ActivateInWorldEvent>(OnActivate);
|
||||
SubscribeLocalEvent<ActiveRadioJammerComponent, PowerCellChangedEvent>(OnPowerCellChanged);
|
||||
SubscribeLocalEvent<RadioSendAttemptEvent>(OnRadioSendAttempt);
|
||||
}
|
||||
|
||||
// TODO: Very important: Make this charge rate based instead of updating every single tick
|
||||
// See BatteryComponent
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
var query = EntityQueryEnumerator<ActiveRadioJammerComponent, RadioJammerComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var _, out var jam))
|
||||
{
|
||||
|
||||
if (_powerCell.TryGetBatteryFromSlot(uid, out var battery))
|
||||
{
|
||||
if (!_battery.TryUseCharge(battery.Value.AsNullable(), GetCurrentWattage((uid, jam)) * frameTime))
|
||||
{
|
||||
ChangeLEDState(uid, false);
|
||||
RemComp<ActiveRadioJammerComponent>(uid);
|
||||
RemComp<DeviceNetworkJammerComponent>(uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
var chargeFraction = _battery.GetChargeLevel(battery.Value.AsNullable());
|
||||
var chargeLevel = chargeFraction switch
|
||||
{
|
||||
> 0.50f => RadioJammerChargeLevel.High,
|
||||
< 0.15f => RadioJammerChargeLevel.Low,
|
||||
_ => RadioJammerChargeLevel.Medium,
|
||||
};
|
||||
ChangeChargeLevel(uid, chargeLevel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void OnActivate(Entity<RadioJammerComponent> ent, ref ActivateInWorldEvent args)
|
||||
{
|
||||
if (args.Handled || !args.Complex)
|
||||
return;
|
||||
|
||||
var activated = !HasComp<ActiveRadioJammerComponent>(ent) &&
|
||||
_powerCell.TryGetBatteryFromSlot(ent.Owner, out var battery) &&
|
||||
_battery.GetCharge(battery.Value.AsNullable()) > GetCurrentWattage(ent);
|
||||
if (activated)
|
||||
{
|
||||
ChangeLEDState(ent.Owner, true);
|
||||
EnsureComp<ActiveRadioJammerComponent>(ent);
|
||||
EnsureComp<DeviceNetworkJammerComponent>(ent, out var jammingComp);
|
||||
_jammer.SetRange((ent, jammingComp), GetCurrentRange(ent));
|
||||
_jammer.AddJammableNetwork((ent, jammingComp), DeviceNetworkComponent.DeviceNetIdDefaults.Wireless.ToString());
|
||||
|
||||
// Add excluded frequencies using the system method
|
||||
if (ent.Comp.FrequenciesExcluded != null)
|
||||
{
|
||||
foreach (var freq in ent.Comp.FrequenciesExcluded)
|
||||
{
|
||||
_jammer.AddExcludedFrequency((ent, jammingComp), (uint)freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeLEDState(ent.Owner, false);
|
||||
RemCompDeferred<ActiveRadioJammerComponent>(ent);
|
||||
RemCompDeferred<DeviceNetworkJammerComponent>(ent);
|
||||
}
|
||||
var state = Loc.GetString(activated ? "radio-jammer-component-on-state" : "radio-jammer-component-off-state");
|
||||
var message = Loc.GetString("radio-jammer-component-on-use", ("state", state));
|
||||
Popup.PopupEntity(message, args.User, args.User);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnPowerCellChanged(Entity<ActiveRadioJammerComponent> ent, ref PowerCellChangedEvent args)
|
||||
{
|
||||
if (args.Ejected)
|
||||
{
|
||||
ChangeLEDState(ent.Owner, false);
|
||||
RemCompDeferred<ActiveRadioJammerComponent>(ent);
|
||||
}
|
||||
SubscribeLocalEvent<RadioReceiveAttemptEvent>(OnRadioReceiveAttempt);
|
||||
}
|
||||
|
||||
private void OnRadioSendAttempt(ref RadioSendAttemptEvent args)
|
||||
{
|
||||
if (ShouldCancelSend(args.RadioSource, args.Channel.Frequency))
|
||||
{
|
||||
if (ShouldCancel(args.RadioSource, args.Channel.Frequency))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ShouldCancelSend(EntityUid sourceUid, int frequency)
|
||||
private void OnRadioReceiveAttempt(ref RadioReceiveAttemptEvent args)
|
||||
{
|
||||
if (ShouldCancel(args.RadioReceiver, args.Channel.Frequency))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
|
||||
private bool ShouldCancel(EntityUid sourceUid, int frequency)
|
||||
{
|
||||
var source = Transform(sourceUid).Coordinates;
|
||||
var query = EntityQueryEnumerator<ActiveRadioJammerComponent, RadioJammerComponent, TransformComponent>();
|
||||
@@ -120,7 +35,7 @@ public sealed class JammerSystem : SharedJammerSystem
|
||||
while (query.MoveNext(out var uid, out _, out var jam, out var transform))
|
||||
{
|
||||
// Check if this jammer excludes the frequency
|
||||
if (jam.FrequenciesExcluded != null && jam.FrequenciesExcluded.Contains(frequency))
|
||||
if (jam.FrequenciesExcluded.Contains(frequency))
|
||||
continue;
|
||||
|
||||
if (_transform.InRange(source, transform.Coordinates, GetCurrentRange((uid, jam))))
|
||||
|
||||
@@ -135,12 +135,13 @@ namespace Content.Server.RoundEnd
|
||||
/// <summary>
|
||||
/// Starts the process of ending the round by calling evac
|
||||
/// </summary>
|
||||
/// <param name="requester"></param>
|
||||
/// <param name="requester">who called evac</param>
|
||||
/// <param name="machine">machine used to call evac</param>
|
||||
/// <param name="checkCooldown"></param>
|
||||
/// <param name="text">text in the announcement of shuttle calling</param>
|
||||
/// <param name="name">name in the announcement of shuttle calling</param>
|
||||
/// <param name="cantRecall">if the station shouldn't be able to recall the shuttle</param>
|
||||
public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement", bool cantRecall = false)
|
||||
public void RequestRoundEnd(EntityUid? requester = null, EntityUid? machine = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement", bool cantRecall = false)
|
||||
{
|
||||
var duration = DefaultCountdownDuration;
|
||||
|
||||
@@ -155,19 +156,20 @@ namespace Content.Server.RoundEnd
|
||||
}
|
||||
}
|
||||
|
||||
RequestRoundEnd(duration, requester, checkCooldown, text, name, cantRecall);
|
||||
RequestRoundEnd(duration, requester, machine, checkCooldown, text, name, cantRecall);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the process of ending the round by calling evac
|
||||
/// </summary>
|
||||
/// <param name="countdownTime">time for evac to arrive</param>
|
||||
/// <param name="requester"></param>
|
||||
/// <param name="requester">who called evac</param>
|
||||
/// <param name="machine">machine used to call evac</param>
|
||||
/// <param name="checkCooldown"></param>
|
||||
/// <param name="text">text in the announcement of shuttle calling</param>
|
||||
/// <param name="name">name in the announcement of shuttle calling</param>
|
||||
/// <param name="cantRecall">if the station shouldn't be able to recall the shuttle</param>
|
||||
public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement", bool cantRecall = false)
|
||||
public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, EntityUid? machine = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement", bool cantRecall = false)
|
||||
{
|
||||
if (_gameTicker.RunLevel != GameRunLevel.InRound)
|
||||
return;
|
||||
@@ -181,14 +183,11 @@ namespace Content.Server.RoundEnd
|
||||
_countdownTokenSource = new();
|
||||
CantRecall = cantRecall;
|
||||
|
||||
var what = machine != null ? $" with {ToPrettyString(machine.Value):entity} " : "";
|
||||
if (requester != null)
|
||||
{
|
||||
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called by {ToPrettyString(requester.Value):user}");
|
||||
}
|
||||
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called by {ToPrettyString(requester.Value):player}{what}");
|
||||
else
|
||||
{
|
||||
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called");
|
||||
}
|
||||
_adminLogger.Add(LogType.ShuttleCalled, LogImpact.High, $"Shuttle called{what}");
|
||||
|
||||
// I originally had these set up here but somehow time gets passed as 0 to Loc so IDEK.
|
||||
int time;
|
||||
@@ -241,7 +240,7 @@ namespace Content.Server.RoundEnd
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelRoundEndCountdown(EntityUid? requester = null, bool forceRecall = false)
|
||||
public void CancelRoundEndCountdown(EntityUid? requester = null, EntityUid? machine = null, bool forceRecall = false)
|
||||
{
|
||||
if (_gameTicker.RunLevel != GameRunLevel.InRound)
|
||||
return;
|
||||
@@ -255,14 +254,11 @@ namespace Content.Server.RoundEnd
|
||||
_countdownTokenSource.Cancel();
|
||||
_countdownTokenSource = null;
|
||||
|
||||
var what = machine != null ? $" with {ToPrettyString(machine.Value):entity} " : "";
|
||||
if (requester != null)
|
||||
{
|
||||
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled by {ToPrettyString(requester.Value):user}");
|
||||
}
|
||||
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled by {ToPrettyString(requester.Value):player}{what}");
|
||||
else
|
||||
{
|
||||
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled");
|
||||
}
|
||||
_adminLogger.Add(LogType.ShuttleRecalled, LogImpact.High, $"Shuttle recalled{what}");
|
||||
|
||||
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString("round-end-system-shuttle-recalled-announcement"),
|
||||
Loc.GetString("round-end-system-shuttle-sender-announcement"), false, colorOverride: Color.Gold);
|
||||
@@ -352,8 +348,8 @@ namespace Content.Server.RoundEnd
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestRoundEnd(time, null, false, textCall,
|
||||
Loc.GetString(sender));
|
||||
RequestRoundEnd(time, checkCooldown: false, text: textCall,
|
||||
name: Loc.GetString(sender));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -390,7 +386,7 @@ namespace Content.Server.RoundEnd
|
||||
if (!_shuttle.EmergencyShuttleArrived && ExpectedCountdownEnd is null)
|
||||
{
|
||||
_autoCalledBefore = true; // Corvax-Announcements: Move before call RequestRoundEnd to play correct announcement sound type
|
||||
RequestRoundEnd(null, false, "round-end-system-shuttle-auto-called-announcement");
|
||||
RequestRoundEnd(checkCooldown: false, text: "round-end-system-shuttle-auto-called-announcement");
|
||||
}
|
||||
|
||||
// Always reset auto-call in case of a recall.
|
||||
|
||||
@@ -270,8 +270,7 @@ public sealed partial class EmergencyShuttleSystem
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: This is fucking bad
|
||||
if (!component.AuthorizedEntities.Remove(MetaData(idCard).EntityName))
|
||||
if (!component.AuthorizedEntities.Remove(idCard.Owner))
|
||||
return;
|
||||
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle early launch REPEAL by {args.Actor:user}");
|
||||
@@ -291,10 +290,13 @@ public sealed partial class EmergencyShuttleSystem
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: This is fucking bad
|
||||
if (!component.AuthorizedEntities.Add(MetaData(idCard).EntityName))
|
||||
var idCardUid = idCard.Owner;
|
||||
|
||||
if (component.AuthorizedEntities.ContainsKey(idCardUid))
|
||||
return;
|
||||
|
||||
component.AuthorizedEntities[idCardUid] = MetaData(idCard).EntityName;
|
||||
|
||||
_logger.Add(LogType.EmergencyShuttle, LogImpact.High, $"Emergency shuttle early launch AUTH by {args.Actor:user}");
|
||||
var remaining = component.AuthorizationsRequired - component.AuthorizedEntities.Count;
|
||||
|
||||
@@ -337,7 +339,7 @@ public sealed partial class EmergencyShuttleSystem
|
||||
{
|
||||
var auths = new List<string>();
|
||||
|
||||
foreach (var auth in component.AuthorizedEntities)
|
||||
foreach (var auth in component.AuthorizedEntities.Values)
|
||||
{
|
||||
auths.Add(auth);
|
||||
}
|
||||
|
||||
@@ -7,41 +7,100 @@ namespace Content.Server.StationEvents.Components;
|
||||
[RegisterComponent, Access(typeof(GasLeakRule))]
|
||||
public sealed partial class GasLeakRuleComponent : Component
|
||||
{
|
||||
public readonly Gas[] LeakableGases =
|
||||
/// <summary>
|
||||
/// Gas types that can be selected for the leak event.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Gas[] LeakableGases =
|
||||
{
|
||||
Gas.Ammonia,
|
||||
Gas.Plasma,
|
||||
Gas.Tritium,
|
||||
Gas.Frezon,
|
||||
Gas.WaterVapor, // the fog
|
||||
Gas.WaterVapor,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Running cooldown of how much time until another leak.
|
||||
/// Time remaining until the next gas addition to the leak tile.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float TimeUntilLeak;
|
||||
|
||||
/// <summary>
|
||||
/// How long between more gas being added to the tile.
|
||||
/// Fixed interval in seconds between gas additions to the leak tile.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float LeakCooldown = 1.0f;
|
||||
|
||||
// Event variables
|
||||
/// <summary>
|
||||
/// The station where the leak is located.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid TargetStation;
|
||||
public EntityUid TargetGrid;
|
||||
public Vector2i TargetTile;
|
||||
public EntityCoordinates TargetCoords;
|
||||
public bool FoundTile;
|
||||
public Gas LeakGas;
|
||||
public float MolesPerSecond;
|
||||
public readonly int MinimumMolesPerSecond = 80;
|
||||
|
||||
/// <summary>
|
||||
/// Don't want to make it too fast to give people time to flee.
|
||||
/// The specific grid where the leak is located.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid TargetGrid;
|
||||
|
||||
/// <summary>
|
||||
/// The tile coordinates where the leak is located.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Vector2i TargetTile;
|
||||
|
||||
/// <summary>
|
||||
/// The world coordinates of the leak location.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityCoordinates TargetCoords;
|
||||
|
||||
/// <summary>
|
||||
/// Whether a suitable tile for leaking has been found.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool FoundTile;
|
||||
|
||||
/// <summary>
|
||||
/// The specific gas type currently leaking.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Gas LeakGas;
|
||||
|
||||
/// <summary>
|
||||
/// Current leak rate in moles per second.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float MolesPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum leak rate in moles per second.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MinimumMolesPerSecond = 80;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum leak rate in moles per second. Limited to give people time to flee.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MaximumMolesPerSecond = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum total amount of gas to leak over the entire event duration.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MinimumGas = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum total amount of gas to leak over the entire event duration.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MaximumGas = 4000;
|
||||
|
||||
/// <summary>
|
||||
/// Chance to create an ignition spark when the event ends.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SparkChance = 0.05f;
|
||||
}
|
||||
|
||||
@@ -9,25 +9,59 @@ namespace Content.Server.StationEvents.Components;
|
||||
public sealed partial class PowerGridCheckRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Default sound of the announcement when power is back on.
|
||||
/// Default sound for power restoration announcement.
|
||||
/// </summary>
|
||||
private static readonly ProtoId<SoundCollectionPrototype> DefaultPowerOn = new("PowerOn");
|
||||
|
||||
/// <summary>
|
||||
/// Sound of the announcement to play when power is back on.
|
||||
/// Sound to play when power is restored.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier PowerOnSound = new SoundCollectionSpecifier(DefaultPowerOn, AudioParams.Default.WithVolume(-4f));
|
||||
|
||||
/// <summary>
|
||||
/// Token source for cancelling the power restoration announcement.
|
||||
/// </summary>
|
||||
public CancellationTokenSource? AnnounceCancelToken;
|
||||
|
||||
/// <summary>
|
||||
/// Station affected by the power grid event.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityUid AffectedStation;
|
||||
public readonly List<EntityUid> Powered = new();
|
||||
public readonly List<EntityUid> Unpowered = new();
|
||||
|
||||
/// <summary>
|
||||
/// List of APC entities that will be sequentially turned off during the event.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntityUid> Powered = new();
|
||||
|
||||
/// <summary>
|
||||
/// List of APC entities that have been turned off.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntityUid> Unpowered = new();
|
||||
|
||||
/// <summary>
|
||||
/// Time delay in seconds before starting to turn off APCs.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SecondsUntilOff = 30.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Number of APC toggles to process per second during the shutdown phase.
|
||||
/// Dynamically calculated based on total APC count and <see cref="SecondsUntilOff"/>.
|
||||
/// </summary>
|
||||
public int NumberPerSecond = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Computed time interval between APC toggles.
|
||||
/// </summary>
|
||||
public float UpdateRate => 1.0f / NumberPerSecond;
|
||||
|
||||
/// <summary>
|
||||
/// Accumulated frame time to track when to process the next APC toggle.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float FrameTimeAccumulator = 0.0f;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public sealed class BreakerFlipRule : StationEventSystem<BreakerFlipRuleComponen
|
||||
if (!TryComp<StationEventComponent>(uid, out var stationEvent))
|
||||
return;
|
||||
|
||||
var str = Loc.GetString("station-event-breaker-flip-announcement", ("data", Loc.GetString(Loc.GetString($"random-sentience-event-data-{RobustRandom.Next(1, 6)}"))));
|
||||
var str = Loc.GetString("station-event-breaker-flip-announcement", ("data", Loc.GetString($"random-sentience-event-data-{RobustRandom.Next(1, 6)}")));
|
||||
stationEvent.StartAnnouncement = str;
|
||||
|
||||
base.Added(uid, component, gameRule, args);
|
||||
|
||||
@@ -306,10 +306,15 @@ namespace Content.Server.Voting.Managers
|
||||
var ticker = _entityManager.EntitySysManager.GetEntitySystem<GameTicker>();
|
||||
if (ticker.CanUpdateMap())
|
||||
{
|
||||
if (_gameMapManager.TrySelectMapIfEligible(picked.ID))
|
||||
if (_gameMapManager.CheckMapExists(picked.ID))
|
||||
{
|
||||
_gameMapManager.SelectMap(picked.ID);
|
||||
ticker.UpdateInfoText();
|
||||
}
|
||||
else
|
||||
{
|
||||
_chatManager.DispatchServerAnnouncement(Loc.GetString("ui-vote-map-invalid", ("winner", maps[picked])));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -217,7 +217,7 @@ namespace Content.Shared.Atmos
|
||||
/// <summary>
|
||||
/// Amount of heat released per mole of burnt hydrogen or tritium (hydrogen isotope)
|
||||
/// </summary>
|
||||
public const float FireHydrogenEnergyReleased = 284e3f; // hydrogen is 284 kJ/mol
|
||||
public const float FireHydrogenEnergyReleased = 284e4f;
|
||||
public const float FireMinimumTemperatureToExist = T0C + 100f;
|
||||
public const float FireMinimumTemperatureToSpread = T0C + 150f;
|
||||
public const float FireSpreadRadiosityScale = 0.85f;
|
||||
|
||||
@@ -23,6 +23,8 @@ public abstract class SharedGasCanisterSystem : EntitySystem
|
||||
SubscribeLocalEvent<GasCanisterComponent, EntRemovedFromContainerMessage>(OnCanisterContainerModified);
|
||||
SubscribeLocalEvent<GasCanisterComponent, ItemSlotInsertAttemptEvent>(OnCanisterInsertAttempt);
|
||||
SubscribeLocalEvent<GasCanisterComponent, ComponentStartup>(OnCanisterStartup);
|
||||
SubscribeLocalEvent<GasCanisterComponent, MapInitEvent>(OnCanisterMapInit);
|
||||
SubscribeLocalEvent<GasCanisterComponent, BoundUIOpenedEvent>(OnCanisterUIOpened);
|
||||
|
||||
// Bound UI subscriptions
|
||||
SubscribeLocalEvent<GasCanisterComponent, GasCanisterHoldingTankEjectMessage>(OnHoldingTankEjectMessage);
|
||||
@@ -30,6 +32,19 @@ public abstract class SharedGasCanisterSystem : EntitySystem
|
||||
SubscribeLocalEvent<GasCanisterComponent, GasCanisterChangeReleaseValveMessage>(OnCanisterChangeReleaseValve);
|
||||
}
|
||||
|
||||
private void OnCanisterUIOpened(Entity<GasCanisterComponent> ent, ref BoundUIOpenedEvent args)
|
||||
{
|
||||
// Fixes all canisters not populating UI elements before MapInit. Mappers rejoice
|
||||
// We still need to DirtyUI after MapInit because this has latency, bad UX for players.
|
||||
DirtyUI(ent.Owner, ent);
|
||||
}
|
||||
|
||||
private void OnCanisterMapInit(Entity<GasCanisterComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
// Fixes empty canisters not populating UI elements
|
||||
DirtyUI(ent.Owner, ent);
|
||||
}
|
||||
|
||||
private void OnCanisterStartup(Entity<GasCanisterComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
// Ensure container
|
||||
|
||||
@@ -25,7 +25,6 @@ public abstract class SharedRottingSystem : EntitySystem
|
||||
SubscribeLocalEvent<PerishableComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||
SubscribeLocalEvent<PerishableComponent, ExaminedEvent>(OnPerishableExamined);
|
||||
|
||||
SubscribeLocalEvent<RottingComponent, ComponentShutdown>(OnShutdown);
|
||||
SubscribeLocalEvent<RottingComponent, MobStateChangedEvent>(OnRottingMobStateChanged);
|
||||
SubscribeLocalEvent<RottingComponent, RejuvenateEvent>(OnRejuvenate);
|
||||
SubscribeLocalEvent<RottingComponent, ExaminedEvent>(OnExamined);
|
||||
@@ -63,14 +62,6 @@ public abstract class SharedRottingSystem : EntitySystem
|
||||
args.PushMarkup(Loc.GetString(description, ("target", Identity.Entity(perishable, EntityManager))));
|
||||
}
|
||||
|
||||
private void OnShutdown(Entity<RottingComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (TryComp<PerishableComponent>(ent, out var perishable))
|
||||
{
|
||||
perishable.RotNextUpdate = TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRottingMobStateChanged(EntityUid uid, RottingComponent component, MobStateChangedEvent args)
|
||||
{
|
||||
if (args.NewMobState == MobState.Dead)
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Content.Shared.Body;
|
||||
public sealed class InitialBodySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -70,4 +70,17 @@ public sealed partial class CCVars
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> NestedStorage =
|
||||
CVarDef.Create("control.nested_storage", true, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, melee weapons that have click-to-attack patterns (unarmed, slow weapons) will continue attacking if the button is held.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ControlHoldToAttackMelee =
|
||||
CVarDef.Create("control.hold_to_attack_melee", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, ranged weapons that have click-to-attack patterns (burst and semi-auto guns) will continue attacking if the button is held.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> ControlHoldToAttackRanged =
|
||||
CVarDef.Create("control.hold_to_attack_ranged", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reaction;
|
||||
|
||||
@@ -17,7 +16,6 @@ public sealed partial class ReactionMixerSystem : EntitySystem
|
||||
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@ public sealed class InsulatedSystem : EntitySystem
|
||||
|
||||
_examine.AddHoverExamineVerb(args,
|
||||
component,
|
||||
Loc.GetString("identity-block-examinable-verb-text"),
|
||||
Loc.GetString("identity-block-examinable-verb-text-message"),
|
||||
Loc.GetString("insulated-examinable-verb-text"),
|
||||
Loc.GetString("insulated-examinable-verb-text-message"),
|
||||
iconTexture
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,11 +104,6 @@ public sealed partial class HumanoidCharacterAppearance : ICharacterAppearance,
|
||||
};
|
||||
|
||||
return new HumanoidCharacterAppearance(newEyeColor, newSkinColor, new());
|
||||
|
||||
float RandomizeColor(float channel)
|
||||
{
|
||||
return MathHelper.Clamp01(channel + random.Next(-25, 25) / 100f);
|
||||
}
|
||||
}
|
||||
|
||||
public static Color ClampColor(Color color)
|
||||
|
||||
@@ -9,7 +9,6 @@ using Content.Shared.Popups;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Kitchen.EntitySystems;
|
||||
@@ -22,7 +21,6 @@ internal sealed class HandheldGrinderSystem : EntitySystem
|
||||
[Dependency] private readonly SharedDestructibleSystem _destructibleSystem = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
[Dependency] private readonly SharedPuddleSystem _puddle = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
|
||||
@@ -129,6 +129,11 @@ namespace Content.Shared.Maps
|
||||
/// </summary>
|
||||
[DataField("indestructible")] public bool Indestructible = false;
|
||||
|
||||
/// <summary>
|
||||
/// Hide this tile in the tile placement editor.
|
||||
/// </summary>
|
||||
[DataField] public bool EditorHidden { get; private set; } = false;
|
||||
|
||||
public void AssignTileId(ushort id)
|
||||
{
|
||||
TileId = id;
|
||||
|
||||
@@ -46,6 +46,7 @@ public abstract class SharedChameleonProjectorSystem : EntitySystem
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, DamageChangedEvent>(OnDisguiseDamaged);
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, InsertIntoEntityStorageAttemptEvent>(OnDisguiseInsertAttempt);
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, ComponentShutdown>(OnDisguiseShutdown);
|
||||
SubscribeLocalEvent<ChameleonDisguiseComponent, BeforeGettingEquippedHandEvent>(OnDisguiseBeforeEquippedHand);
|
||||
|
||||
SubscribeLocalEvent<ChameleonDisguisedComponent, EntGotInsertedIntoContainerMessage>(OnDisguisedInserted);
|
||||
|
||||
@@ -86,6 +87,12 @@ public abstract class SharedChameleonProjectorSystem : EntitySystem
|
||||
_actions.RemoveProvidedActions(ent.Comp.User, ent.Comp.Projector);
|
||||
}
|
||||
|
||||
private void OnDisguiseBeforeEquippedHand(Entity<ChameleonDisguiseComponent> ent, ref BeforeGettingEquippedHandEvent args)
|
||||
{
|
||||
args.Cancelled = true;
|
||||
TryReveal(ent.Comp.User);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Disguised player
|
||||
|
||||
@@ -11,11 +11,11 @@ public sealed partial class PowerCellSystem
|
||||
[PublicAPI]
|
||||
public void SetDrawEnabled(Entity<PowerCellDrawComponent?> ent, bool enabled)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false) || ent.Comp.Enabled == enabled)
|
||||
return;
|
||||
|
||||
ent.Comp.Enabled = enabled;
|
||||
Dirty(ent, ent.Comp);
|
||||
if (Resolve(ent, ref ent.Comp, false) && ent.Comp.Enabled != enabled)
|
||||
{
|
||||
ent.Comp.Enabled = enabled;
|
||||
Dirty(ent, ent.Comp);
|
||||
}
|
||||
|
||||
if (TryGetBatteryFromSlot(ent.Owner, out var battery))
|
||||
_battery.RefreshChargeRate(battery.Value.AsNullable());
|
||||
|
||||
@@ -36,9 +36,7 @@ public sealed class ToggleCellDrawSystem : EntitySystem
|
||||
|
||||
private void OnToggled(Entity<ToggleCellDrawComponent> ent, ref ItemToggledEvent args)
|
||||
{
|
||||
var uid = ent.Owner;
|
||||
var draw = Comp<PowerCellDrawComponent>(uid);
|
||||
_cell.SetDrawEnabled((uid, draw), args.Activated);
|
||||
_cell.SetDrawEnabled(ent.Owner, args.Activated);
|
||||
}
|
||||
|
||||
private void OnEmpty(Entity<ToggleCellDrawComponent> ent, ref PowerCellSlotEmptyEvent args)
|
||||
|
||||
@@ -1,25 +1,66 @@
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Content.Shared.DeviceNetwork.Systems;
|
||||
using Content.Shared.Item.ItemToggle;
|
||||
using Content.Shared.Item.ItemToggle.Components;
|
||||
using Content.Shared.Power;
|
||||
|
||||
namespace Content.Shared.Radio.EntitySystems;
|
||||
|
||||
public abstract class SharedJammerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly ItemToggleSystem _itemToggle = default!;
|
||||
[Dependency] private readonly SharedDeviceNetworkJammerSystem _jammer = default!;
|
||||
[Dependency] protected readonly SharedPopupSystem Popup = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RadioJammerComponent, ItemToggledEvent>(OnItemToggle);
|
||||
SubscribeLocalEvent<RadioJammerComponent, RefreshChargeRateEvent>(OnRefreshChargeRate);
|
||||
SubscribeLocalEvent<RadioJammerComponent, GetVerbsEvent<Verb>>(OnGetVerb);
|
||||
SubscribeLocalEvent<RadioJammerComponent, ExaminedEvent>(OnExamine);
|
||||
}
|
||||
|
||||
private void OnItemToggle(Entity<RadioJammerComponent> entity, ref ItemToggledEvent args)
|
||||
{
|
||||
if (args.Activated)
|
||||
{
|
||||
EnsureComp<ActiveRadioJammerComponent>(entity);
|
||||
EnsureComp<DeviceNetworkJammerComponent>(entity, out var jammingComp);
|
||||
_jammer.SetRange((entity, jammingComp), GetCurrentRange(entity));
|
||||
_jammer.AddJammableNetwork((entity, jammingComp), DeviceNetworkComponent.DeviceNetIdDefaults.Wireless.ToString());
|
||||
|
||||
// Add excluded frequencies using the system method
|
||||
foreach (var freq in entity.Comp.FrequenciesExcluded)
|
||||
{
|
||||
_jammer.AddExcludedFrequency((entity, jammingComp), (uint)freq);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RemCompDeferred<ActiveRadioJammerComponent>(entity);
|
||||
RemCompDeferred<DeviceNetworkJammerComponent>(entity);
|
||||
}
|
||||
|
||||
if (args.User == null)
|
||||
return;
|
||||
|
||||
var state = Loc.GetString(args.Activated ? "radio-jammer-component-on-state" : "radio-jammer-component-off-state");
|
||||
var message = Loc.GetString("radio-jammer-component-on-use", ("state", state));
|
||||
_popup.PopupPredicted(message, args.User.Value, args.User.Value);
|
||||
}
|
||||
|
||||
private void OnRefreshChargeRate(Entity<RadioJammerComponent> entity, ref RefreshChargeRateEvent args)
|
||||
{
|
||||
if (_itemToggle.IsActivated(entity.Owner))
|
||||
args.NewChargeRate -= GetCurrentWattage(entity);
|
||||
}
|
||||
|
||||
private void OnGetVerb(Entity<RadioJammerComponent> entity, ref GetVerbsEvent<Verb> args)
|
||||
{
|
||||
if (!args.CanAccess || !args.CanInteract)
|
||||
@@ -47,7 +88,7 @@ public abstract class SharedJammerSystem : EntitySystem
|
||||
// The range should be updated when it turns on again!
|
||||
_jammer.TrySetRange(entity.Owner, GetCurrentRange(entity));
|
||||
|
||||
Popup.PopupClient(Loc.GetString(setting.Message), user, user);
|
||||
_popup.PopupClient(Loc.GetString(setting.Message), user, user);
|
||||
},
|
||||
Text = Loc.GetString(setting.Name),
|
||||
};
|
||||
@@ -58,37 +99,26 @@ public abstract class SharedJammerSystem : EntitySystem
|
||||
|
||||
private void OnExamine(Entity<RadioJammerComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
if (args.IsInDetailsRange)
|
||||
{
|
||||
var powerIndicator = HasComp<ActiveRadioJammerComponent>(ent)
|
||||
? Loc.GetString("radio-jammer-component-examine-on-state")
|
||||
: Loc.GetString("radio-jammer-component-examine-off-state");
|
||||
args.PushMarkup(powerIndicator);
|
||||
if (!args.IsInDetailsRange)
|
||||
return;
|
||||
|
||||
var powerLevel = Loc.GetString(ent.Comp.Settings[ent.Comp.SelectedPowerLevel].Name);
|
||||
var switchIndicator = Loc.GetString("radio-jammer-component-switch-setting", ("powerLevel", powerLevel));
|
||||
args.PushMarkup(switchIndicator);
|
||||
}
|
||||
var powerIndicator = _itemToggle.IsActivated(ent.Owner)
|
||||
? Loc.GetString("radio-jammer-component-examine-on-state")
|
||||
: Loc.GetString("radio-jammer-component-examine-off-state");
|
||||
args.PushMarkup(powerIndicator);
|
||||
|
||||
var powerLevel = Loc.GetString(ent.Comp.Settings[ent.Comp.SelectedPowerLevel].Name);
|
||||
var switchIndicator = Loc.GetString("radio-jammer-component-switch-setting", ("powerLevel", powerLevel));
|
||||
args.PushMarkup(switchIndicator);
|
||||
}
|
||||
|
||||
public float GetCurrentWattage(Entity<RadioJammerComponent> jammer)
|
||||
private float GetCurrentWattage(Entity<RadioJammerComponent> jammer)
|
||||
{
|
||||
return jammer.Comp.Settings[jammer.Comp.SelectedPowerLevel].Wattage;
|
||||
}
|
||||
|
||||
public float GetCurrentRange(Entity<RadioJammerComponent> jammer)
|
||||
protected float GetCurrentRange(Entity<RadioJammerComponent> jammer)
|
||||
{
|
||||
return jammer.Comp.Settings[jammer.Comp.SelectedPowerLevel].Range;
|
||||
}
|
||||
|
||||
protected void ChangeLEDState(Entity<AppearanceComponent?> ent, bool isLEDOn)
|
||||
{
|
||||
_appearance.SetData(ent, RadioJammerVisuals.LEDOn, isLEDOn, ent.Comp);
|
||||
}
|
||||
|
||||
protected void ChangeChargeLevel(Entity<AppearanceComponent?> ent, RadioJammerChargeLevel chargeLevel)
|
||||
{
|
||||
_appearance.SetData(ent, RadioJammerVisuals.ChargeLevel, chargeLevel, ent.Comp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@ namespace Content.Shared.Shuttles.Components;
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public sealed partial class EmergencyShuttleConsoleComponent : Component
|
||||
{
|
||||
// TODO: Okay doing it by string is kinda suss but also ID card tracking doesn't seem to be robust enough
|
||||
|
||||
/// <summary>
|
||||
/// ID cards that have been used to authorize an early launch.
|
||||
/// Key is the UID of the ID card,
|
||||
/// value is the card's name at the time of authorization.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("authorized")]
|
||||
public HashSet<string> AuthorizedEntities = new();
|
||||
public Dictionary<EntityUid, string> AuthorizedEntities = new();
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("authorizationsRequired")]
|
||||
public int AuthorizationsRequired = 3;
|
||||
|
||||
@@ -33,7 +33,6 @@ public abstract class SharedPortalSystem : EntitySystem
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly PullingSystem _pulling = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedGrapplingGunSystem _grappling = default!;
|
||||
[Dependency] private readonly SharedJointSystem _joints = default!;
|
||||
|
||||
private const string PortalFixture = "portalFixture";
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Trigger.Components.Effects;
|
||||
|
||||
/// <summary>
|
||||
/// Plays a light behavior on the target when this trigger is activated, of note is that the entity needs a PointLightComponent
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class LightBehaviorOnTriggerComponent : BaseXOnTriggerComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The light behavior we're triggering.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Behavior = string.Empty;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Numerics;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
@@ -12,10 +13,10 @@ namespace Content.Shared.Trigger.Components.Effects;
|
||||
public sealed partial class ScramOnTriggerComponent : BaseXOnTriggerComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Up to how far to teleport the entity.
|
||||
/// Up to how far to teleport the entity. Represented with X as Min Radius, and Y as Max Radius
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float TeleportRadius = 100f;
|
||||
public Vector2 TeleportRadius = new (10f, 15f);
|
||||
|
||||
/// <summary>
|
||||
/// the sound to play when teleporting.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Movement.Pulling.Components;
|
||||
using Content.Shared.Movement.Pulling.Systems;
|
||||
@@ -50,7 +51,7 @@ public sealed class ScramOnTriggerSystem : XOnTriggerSystem<ScramOnTriggerCompon
|
||||
/// null if no tile is found within a certain number of tries.
|
||||
/// </summary>
|
||||
/// <remarks> Trends towards the outer radius. Compensates for small grids. </remarks>
|
||||
private EntityCoordinates? SelectRandomTileInRange(EntityUid uid, float radius, int tries = 40, PhysicsComponent? physicsComponent = null)
|
||||
private EntityCoordinates? SelectRandomTileInRange(EntityUid uid, Vector2 radius, int tries = 40, PhysicsComponent? physicsComponent = null)
|
||||
{
|
||||
var userCoords = Transform(uid).Coordinates;
|
||||
EntityCoordinates? targetCoords = null;
|
||||
@@ -68,7 +69,7 @@ public sealed class ScramOnTriggerSystem : XOnTriggerSystem<ScramOnTriggerCompon
|
||||
// i = A percentage based on the current try count, which results in each
|
||||
// subsequent try landing closer and closer towards the entity.
|
||||
// Beneficial for smaller maps, especially when the radius is large.
|
||||
var distance = radius * MathF.Sqrt(_random.NextFloat()) * (1 - (float)i / tries);
|
||||
var distance = (radius.Y - radius.X) * MathF.Sqrt(_random.NextFloat()) * (1 - (float)i / tries) + radius.X;
|
||||
|
||||
// We then offset the user coords from a random angle * distance
|
||||
var tempTargetCoords = userCoords.Offset(_random.NextAngle().ToVec() * distance);
|
||||
|
||||
@@ -9,7 +9,24 @@ namespace Content.Shared.Weapons.Ranged.Events;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestShootEvent : EntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The gun shooting.
|
||||
/// </summary>
|
||||
public NetEntity Gun;
|
||||
|
||||
/// <summary>
|
||||
/// The location the player is shooting at.
|
||||
/// </summary>
|
||||
public NetCoordinates Coordinates;
|
||||
|
||||
/// <summary>
|
||||
/// The target the player is shooting at, if any.
|
||||
/// </summary>
|
||||
public NetEntity? Target;
|
||||
|
||||
/// <summary>
|
||||
/// If the client wants to continuously shoot.
|
||||
/// If true, the gun will continue firing until a stop event is sent from the client.
|
||||
/// </summary>
|
||||
public bool Continuous;
|
||||
}
|
||||
|
||||
@@ -158,6 +158,8 @@ public abstract partial class SharedGunSystem : EntitySystem
|
||||
gun.Comp.ShootCoordinates = GetCoordinates(msg.Coordinates);
|
||||
gun.Comp.Target = GetEntity(msg.Target);
|
||||
AttemptShoot(user.Value, gun);
|
||||
if (msg.Continuous)
|
||||
gun.Comp.ShotCounter = 0;
|
||||
}
|
||||
|
||||
private void OnStopShootRequest(RequestStopShootEvent ev, EntitySessionEventArgs args)
|
||||
|
||||
@@ -121,7 +121,7 @@ public abstract class SharedArtifactCrusherSystem : EntitySystem
|
||||
crusher.Crushing = true;
|
||||
crusher.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1);
|
||||
crusher.CrushEndTime = _timing.CurTime + crusher.CrushDuration;
|
||||
crusher.CrushingSoundEntity = AudioSystem.PlayPvs(crusher.CrushingSound, ent)?.Entity;
|
||||
crusher.CrushingSoundEntity = AudioSystem.PlayPredicted(crusher.CrushingSound, ent, user)?.Entity ?? crusher.CrushingSoundEntity;
|
||||
_appearance.SetData(ent, ArtifactCrusherVisuals.Crushing, true);
|
||||
Dirty(ent, ent.Comp1);
|
||||
}
|
||||
@@ -135,10 +135,7 @@ public abstract class SharedArtifactCrusherSystem : EntitySystem
|
||||
_appearance.SetData(ent, ArtifactCrusherVisuals.Crushing, false);
|
||||
|
||||
if (early)
|
||||
{
|
||||
AudioSystem.Stop(ent.Comp.CrushingSoundEntity);
|
||||
ent.Comp.CrushingSoundEntity = null;
|
||||
}
|
||||
ent.Comp.CrushingSoundEntity = AudioSystem.Stop(ent.Comp.CrushingSoundEntity);
|
||||
|
||||
Dirty(ent, ent.Comp);
|
||||
}
|
||||
|
||||
@@ -1605,5 +1605,13 @@ Entries:
|
||||
id: 195
|
||||
time: '2026-01-16T22:24:15.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42443
|
||||
- author: Samuka
|
||||
changes:
|
||||
- message: shuttle called and recalled logs now show who recalled or called the
|
||||
shuttle
|
||||
type: Fix
|
||||
id: 196
|
||||
time: '2026-01-24T19:15:40.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/41557
|
||||
Name: Admin
|
||||
Order: 3
|
||||
|
||||
@@ -1,103 +1,4 @@
|
||||
Entries:
|
||||
- author: imatsoup
|
||||
changes:
|
||||
- message: Butterflies can no longer be infected by Romerol or become Romerol zombies.
|
||||
type: Tweak
|
||||
id: 8948
|
||||
time: '2025-09-10T21:48:53.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40265
|
||||
- author: Princess-Cheeseballs
|
||||
changes:
|
||||
- message: Cardboard boxes can no longer freely move in space.
|
||||
type: Fix
|
||||
id: 8949
|
||||
time: '2025-09-10T22:13:59.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40260
|
||||
- author: TsjipTsjip LuckyShotPictures IProduceWidgets
|
||||
changes:
|
||||
- message: Admin shuttles have been added to the repo, and can be found in /Maps/Shuttles/AdminSpawn/..
|
||||
type: Add
|
||||
id: 8950
|
||||
time: '2025-09-11T01:01:28.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32139
|
||||
- author: ToastEnjoyer
|
||||
changes:
|
||||
- message: Fixed the laser carbine not being labeled as contraband
|
||||
type: Fix
|
||||
id: 8951
|
||||
time: '2025-09-11T02:37:10.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40253
|
||||
- author: IProduceWidgets
|
||||
changes:
|
||||
- message: Tennis balls! Found in arcade machines, maintenance and the cargo toy
|
||||
crate!
|
||||
type: Add
|
||||
id: 8952
|
||||
time: '2025-09-11T10:57:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40143
|
||||
- author: 5tickman
|
||||
changes:
|
||||
- message: Food and ingredient item sizes have been adjusted.
|
||||
type: Tweak
|
||||
- message: Mimes now start with a Nutribrick instead of a Baguette.
|
||||
type: Tweak
|
||||
- message: The combat bakery kit is now a 4x4 sized box.
|
||||
type: Tweak
|
||||
id: 8953
|
||||
time: '2025-09-11T11:37:25.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/39203
|
||||
- author: aada
|
||||
changes:
|
||||
- message: Cups, bottles, mugs, and other drinks have had minor changes. Most are
|
||||
now destructible.
|
||||
type: Tweak
|
||||
id: 8954
|
||||
time: '2025-09-11T15:59:11.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/39221
|
||||
- author: luegamer
|
||||
changes:
|
||||
- message: SmartFridge Circuitboards are now printable, SmartFridge destruction
|
||||
no longer deletes all contents
|
||||
type: Add
|
||||
id: 8955
|
||||
time: '2025-09-11T19:59:21.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/39879
|
||||
- author: SurrealShibe
|
||||
changes:
|
||||
- message: Toilet seats are now displayed on the correct layer.
|
||||
type: Fix
|
||||
id: 8956
|
||||
time: '2025-09-12T22:47:21.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40313
|
||||
- author: Princess-Cheeseballs
|
||||
changes:
|
||||
- message: Chameleon Projector will no longer cause you to be permanently slowed
|
||||
down
|
||||
type: Fix
|
||||
id: 8957
|
||||
time: '2025-09-12T23:23:58.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/37960
|
||||
- author: FungiFellow
|
||||
changes:
|
||||
- message: Cockroaches can Gib when Stepped on
|
||||
type: Add
|
||||
id: 8958
|
||||
time: '2025-09-13T07:01:14.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40103
|
||||
- author: Huaqas
|
||||
changes:
|
||||
- message: Vulpkanin now have Undergarments.
|
||||
type: Add
|
||||
id: 8959
|
||||
time: '2025-09-13T17:36:28.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40321
|
||||
- author: MissKay1994
|
||||
changes:
|
||||
- message: Greatly reduced lethality of Man-O-War shuttle
|
||||
type: Tweak
|
||||
id: 8960
|
||||
time: '2025-09-14T05:44:32.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/40339
|
||||
- author: ScarKy0
|
||||
changes:
|
||||
- message: Vulpkanin now use the corrent undergarments when "Censor character nudity"
|
||||
@@ -3977,3 +3878,132 @@ Entries:
|
||||
id: 9454
|
||||
time: '2026-01-23T02:05:59.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42172
|
||||
- author: Princess-Cheeseballs
|
||||
changes:
|
||||
- message: Added the Syndimov Lawboard to the Traitor Uplink.
|
||||
type: Add
|
||||
- message: You can now get Pythons and Cat Ears in the Syndicate Snack box.
|
||||
type: Add
|
||||
- message: Removed Whitehole Grenade, Necronomicon, Explosive Banana Peel and Super
|
||||
Surplus crates from the uplink.
|
||||
type: Remove
|
||||
- message: Removed Singularity Beacon and Antimov Lawboard from the Traitor Uplink.
|
||||
type: Remove
|
||||
- message: Several less used uplink items have had their costs reduced.
|
||||
type: Tweak
|
||||
- message: Clustersoap and Cluster Bananas now explodes into soaplets when thrown
|
||||
and no longer needs to be primed. The Clustersoap has been reduced to 1 TC as
|
||||
well.
|
||||
type: Tweak
|
||||
- message: Martyr Cyborgs now start glowing red before exploding.
|
||||
type: Tweak
|
||||
- message: Scram Implanter's range has been crunched down to 10-15 tiles from 0-100.
|
||||
type: Tweak
|
||||
- message: Rigged Boxing Gloves have had their overall time to stun increased but
|
||||
are also now available for all Traitors to purchase.
|
||||
type: Tweak
|
||||
- message: Combat bakery kit now comes with a flatpack microwave instead of a machine
|
||||
board. The throwing croissants and baguette have been made equivalent in damage
|
||||
to other Traitor uplink items as well.
|
||||
type: Tweak
|
||||
- message: Holoclowns no longer try to attack their host.
|
||||
type: Fix
|
||||
- message: Singularity grenade shouldn't throw you inside walls anymore
|
||||
type: Fix
|
||||
id: 9455
|
||||
time: '2026-01-24T00:26:43.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42582
|
||||
- author: alexalexmax
|
||||
changes:
|
||||
- message: Tasers no longer slow holoparasites down.
|
||||
type: Fix
|
||||
id: 9456
|
||||
time: '2026-01-24T04:18:37.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42315
|
||||
- author: Hitlinemoss
|
||||
changes:
|
||||
- message: The "Auto-fill the highlights with the character's information" accessibility
|
||||
option has been renamed to "Automatically set the highlights list based on your
|
||||
character's name and job".
|
||||
type: Tweak
|
||||
- message: More automatic job-text highlights have been added.
|
||||
type: Tweak
|
||||
id: 9457
|
||||
time: '2026-01-24T21:06:28.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42630
|
||||
- author: SlamBamActionman
|
||||
changes:
|
||||
- message: Added an toggle for "hold-to-attack" under the accessibility tab.
|
||||
type: Add
|
||||
id: 9458
|
||||
time: '2026-01-25T22:30:52.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42596
|
||||
- author: roryflowers
|
||||
changes:
|
||||
- message: Tritium's thermal output is increased to its previous value, to reenable
|
||||
maxcap explosives and make the TEG easier to run.
|
||||
type: Fix
|
||||
id: 9459
|
||||
time: '2026-01-26T00:39:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42641
|
||||
- author: SlamBamActionman
|
||||
changes:
|
||||
- message: Crowbars are now consistent with other 1x2 items in terms of storage,
|
||||
e.g. in pockets.
|
||||
type: Tweak
|
||||
id: 9460
|
||||
time: '2026-01-26T01:35:49.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42585
|
||||
- author: ScholarNZL
|
||||
changes:
|
||||
- message: Fixed a dev environment crash related to construction event validation.
|
||||
type: Fix
|
||||
id: 9461
|
||||
time: '2026-01-26T06:12:02.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/41396
|
||||
- author: B_Kirill
|
||||
changes:
|
||||
- message: Fixed being able to pick up chameleon projector disguises via context
|
||||
menu.
|
||||
type: Fix
|
||||
id: 9462
|
||||
time: '2026-01-26T14:03:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42656
|
||||
- author: Ohelig
|
||||
changes:
|
||||
- message: Empty gas canisters now have a populated UI.
|
||||
type: Fix
|
||||
id: 9463
|
||||
time: '2026-01-26T15:02:20.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42616
|
||||
- author: notquitehadouken
|
||||
changes:
|
||||
- message: Doors close on clown spider webs now
|
||||
type: Fix
|
||||
id: 9464
|
||||
time: '2026-01-26T15:19:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42589
|
||||
- author: Marlyn
|
||||
changes:
|
||||
- message: Opporozidone no longer has instarot issues that get worse the longer
|
||||
the server has been running
|
||||
type: Fix
|
||||
id: 9465
|
||||
time: '2026-01-26T15:45:24.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42472
|
||||
- author: PJB3005
|
||||
changes:
|
||||
- message: Job lizard plushies can be found in various lockers around the station
|
||||
instead of being loadout items.
|
||||
type: Tweak
|
||||
id: 9466
|
||||
time: '2026-01-26T16:15:54.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42545
|
||||
- author: Princess-Cheeseballs
|
||||
changes:
|
||||
- message: Boxing gloves in the uplink are now the rigged variants instead of the
|
||||
normal variants.
|
||||
type: Fix
|
||||
id: 9467
|
||||
time: '2026-01-26T20:25:53.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/42662
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
[game]
|
||||
hostname = "[EN][Testing] Wizard's Den Vulture [US East 2]"
|
||||
desc = "Official English testing server for Space Station 14.\nVanilla, roleplay ruleset.\n\nYou can play with the newest changes to the game here, but these changes may not be final or stable, and may be reverted before the next stable release.\nPlease report bugs on our GitHub, forum, or community Discord."
|
||||
panic_bunker.enabled = false
|
||||
panic_bunker.disable_with_admins = false
|
||||
panic_bunker.enable_without_admins = false
|
||||
panic_bunker.custom_reason = ""
|
||||
|
||||
[hub]
|
||||
tags = "lang:en,region:am_n_e,rp:low"
|
||||
@@ -14,3 +18,6 @@ force_client_hud_version_watermark = true
|
||||
|
||||
[chat]
|
||||
motd = "\n########################################################\n\n[font size=17]This is a test server. You can play with the newest changes to the game, but these [color=red]changes may not be final or stable[/color], and may be reverted. Please report bugs via our GitHub, forum, or community Discord.[/font]\n\n########################################################\n"
|
||||
|
||||
[feedback]
|
||||
valid_origins = "wizden wizden_master"
|
||||
|
||||
@@ -58,3 +58,6 @@ max_explosion_range = 10
|
||||
privacy_policy_link = "https://spacestation14.com/about/privacy/#game-server-privacy-policy"
|
||||
privacy_policy_identifier = "wizden"
|
||||
privacy_policy_version = "2025-01-19"
|
||||
|
||||
[feedback]
|
||||
valid_origins = "wizden"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,54 +2,55 @@
|
||||
highlights-captain = Captain, "Cap", Bridge, Command
|
||||
highlights-head-of-personnel = Head Of Personnel, "HoP", Service, Bridge, Command
|
||||
highlights-chief-engineer = Chief Engineer, "CE", Engineering, Engineer, "Engi", Bridge, Command
|
||||
highlights-chief-medical-officer = Chief Medical Officer, "CMO", MedBay, "Med", Bridge, Command
|
||||
highlights-head-of-security = Head of Security, "HoS", Security, "Sec", Bridge, Command
|
||||
highlights-quartermaster = Quartermaster, "QM", Cargo, Bridge, Command
|
||||
highlights-research-director = Research Director, "RD", Science, "Sci", Bridge, Command
|
||||
highlights-chief-medical-officer = Chief Medical Officer, "CMO", Medbay, Medical, "Med", Bridge, Command
|
||||
highlights-head-of-security = Head of Security, "HoS", Armory, Security, "Sec", Bridge, Command
|
||||
highlights-quartermaster = Quartermaster, "QM", Cargo, Supply, Bridge, Command
|
||||
highlights-research-director = Research Director, "RD", Science, "Sci", "RND", "R&D", Bridge, Command
|
||||
|
||||
# Security
|
||||
highlights-detective = Detective, "Det", Security, "Sec"
|
||||
highlights-security-cadet = Security Cadet, Secoff, Cadet, Security, "Sec"
|
||||
highlights-security-officer = Security Officer, Secoff, Officer, Security, "Sec"
|
||||
highlights-warden = Warden, "Ward", Security, "Sec"
|
||||
highlights-detective = Detective, "Det", Armory, Security, "Sec"
|
||||
highlights-security-cadet = Security Cadet, Secoff, Cadet, Armory, Security, "Sec"
|
||||
highlights-security-officer = Security Officer, Secoff, Officer, Armory, Security, "Sec"
|
||||
highlights-warden = Warden, "Ward", Brig, Genpop, Jail, "Prison", Armory, Security, "Sec"
|
||||
|
||||
# Cargo
|
||||
highlights-cargo-technician = Cargo Technician, Cargo Tech, "Cargo"
|
||||
highlights-salvage-specialist = Salvage Specialist, Salvager, Salvage, "Salv", "Cargo", Miner
|
||||
highlights-cargo-technician = Cargo Technician, Cargo Tech, "Cargo", Supply
|
||||
highlights-salvage-specialist = Salvage Specialist, Salvager, Salvage, "Salv", Miner, "Cargo", Supply
|
||||
|
||||
# Engineering
|
||||
highlights-atmospheric-technician = Atmospheric Technician, Atmos tech, Atmospheric, Engineering, "Atmos", "Engi"
|
||||
highlights-atmospheric-technician = Atmospheric Technician, Atmos Tech, Atmospheric, Engineering, "Atmos", "Engi"
|
||||
highlights-station-engineer = Station Engineer, Engineering, Engineer, "Engi"
|
||||
highlights-technical-assistant = Technical Assistant, Tech Assistant, Engineering, Engineer, "Engi"
|
||||
|
||||
# Medical
|
||||
highlights-chemist = Chemist, Chemistry, "Chem", MedBay, "Med"
|
||||
highlights-medical-doctor = Medical Doctor, Doctor, "Doc", MedBay, "Med"
|
||||
highlights-medical-intern = Medical Intern, "Doc", Intern, MedBay, "Med"
|
||||
highlights-paramedic = Paramedic, "Para", MedBay, "Med"
|
||||
highlights-chemist = Chemist, Chemistry, "Chem", Medbay, Medical, "Med"
|
||||
highlights-medical-doctor = Medical Doctor, Doctor, "Doc", Medbay, Medical, "Med"
|
||||
highlights-medical-intern = Medical Intern, Intern, Medbay, Medical, "Med"
|
||||
highlights-paramedic = Paramedic, "Para", "Medic", Medbay, Medical, "Med"
|
||||
|
||||
# Science
|
||||
highlights-scientist = Scientist, Science, "Sci"
|
||||
highlights-research-assistant = Research Assistant, Science, "Sci"
|
||||
highlights-scientist = Scientist, Science, "Sci", "RND", "R&D"
|
||||
highlights-research-assistant = Research Assistant, Science, "Sci", "RND", "R&D"
|
||||
|
||||
# Civilian
|
||||
highlights-bartender = Bartender, Barkeeper, Barkeep, "Bar"
|
||||
highlights-botanist = Botanist, Botany, Hydroponics
|
||||
highlights-chaplain = Chaplain, "Chap", Chapel
|
||||
highlights-chef = Chef, "Cook", Kitchen
|
||||
highlights-clown = Clown, Jester
|
||||
highlights-janitor = Janitor, "Jani"
|
||||
highlights-lawyer = Lawyer, Attorney
|
||||
highlights-librarian = Librarian, Library
|
||||
highlights-mime = Mime
|
||||
highlights-passenger = Passenger, Greytider, "Tider"
|
||||
highlights-service-worker = Service Worker
|
||||
highlights-bartender = Bartender, Barkeeper, Barkeep, "Bar", Service, "Serv"
|
||||
highlights-botanist = Botanist, Botany, Hydroponics, Service, "Serv"
|
||||
highlights-chaplain = Chaplain, "Chap", Chapel, Service, "Serv"
|
||||
highlights-chef = Chef, "Cook", Kitchen, Service, "Serv"
|
||||
highlights-clown = Clown, Theatre, Theater, Service, "Serv"
|
||||
highlights-janitor = Janitor, "Jani", Service, "Serv"
|
||||
highlights-lawyer = Lawyer, Attorney, "Law", Service, "Serv"
|
||||
highlights-librarian = Librarian, Library, Service, "Serv"
|
||||
highlights-mime = Mime, Theatre, Theater, Service, "Serv"
|
||||
highlights-musician = Musician, "Music", Theatre, Theater, Service, "Serv"
|
||||
highlights-passenger = Passenger, Greytider, Graytider, "Tider", "Tide"
|
||||
highlights-service-worker = Service Worker, Service, "Serv"
|
||||
|
||||
# Station-specific
|
||||
highlights-reporter = Reporter, Journalist
|
||||
highlights-psychologist = Psychologist, Psychology
|
||||
highlights-reporter = Reporter, Journalist, Newsroom, News
|
||||
highlights-psychologist = Psychologist, Psychology, "Psych", Medbay, Medical, "Med"
|
||||
|
||||
# Silicon
|
||||
highlights-personal-ai = Personal AI, "pAI"
|
||||
highlights-cyborg = Cyborg, Silicon, Borg
|
||||
highlights-cyborg = Cyborg, Silicon, Borg, Robotics, "Robot"
|
||||
highlights-station-ai = Station AI, Silicon, "AI", "sAI"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
identity-block-examinable-verb-text = Insulatated
|
||||
identity-block-examinable-verb-text-message = This item appears to be electrically insulated. It should protect the wearer from shocks.
|
||||
insulated-examinable-verb-text = Insulated
|
||||
insulated-examinable-verb-text-message = This item appears to be electrically insulated. It should protect the wearer from shocks.
|
||||
|
||||
@@ -49,7 +49,7 @@ ui-options-misc-label = Misc
|
||||
ui-options-interface-label = Interface
|
||||
|
||||
|
||||
ui-options-auto-fill-highlights = Auto-fill the highlights with the character's information
|
||||
ui-options-auto-fill-highlights = Automatically set the highlights list based on your character's name and job
|
||||
ui-options-highlights-color = Highlights color:
|
||||
ui-options-highlights-color-example = This is highlighted text.
|
||||
ui-options-show-held-item = Show held item next to cursor
|
||||
@@ -108,6 +108,9 @@ ui-options-hud-layout = HUD layout:
|
||||
|
||||
## Controls menu
|
||||
|
||||
ui-options-hold-to-attack-melee = Hold to attack (melee)
|
||||
ui-options-hold-to-attack-ranged = Hold to attack (ranged)
|
||||
|
||||
ui-options-binds-reset-all = Reset ALL keybinds
|
||||
ui-options-binds-explanation = Click to change binding, right-click to clear
|
||||
ui-options-unbound = Unbound
|
||||
|
||||
@@ -202,6 +202,9 @@ uplink-singularity-beacon-desc = A device that attracts singularities. Has to be
|
||||
uplink-antimov-law-name = Antimov Law Circuit
|
||||
uplink-antimov-law-desc = A very dangerous Lawset to use when you want to cause the A.I. to go haywire, use with caution.
|
||||
|
||||
uplink-syndimov-law-name = Syndi Law Circuit
|
||||
uplink-syndimov-law-desc = A subversive Lawset to use when you want to turn the A.I. to your side, use as much as possible.
|
||||
|
||||
# Implants
|
||||
uplink-storage-implanter-name = Storage Implanter
|
||||
uplink-storage-implanter-desc = Hide goodies inside of yourself with new bluespace technology!
|
||||
@@ -236,8 +239,8 @@ uplink-micro-bomb-implanter-desc = Explode on death or manual activation with th
|
||||
uplink-radio-implanter-name = Radio Implanter
|
||||
uplink-radio-implanter-desc = Implants a Syndicate radio, allowing covert communication without a headset.
|
||||
|
||||
uplink-voice-mask-implanter-name = Voice Mask Implanter
|
||||
uplink-voice-mask-implanter-desc = Modifies your vocal cords to be able to sound like anyone you could imagine.
|
||||
uplink-voice-mask-implanter-name = Identity Mask Implanter
|
||||
uplink-voice-mask-implanter-desc = Modifies your vocal cords and facial structure to be able to mimic anyone you could imagine.
|
||||
|
||||
# Bundles
|
||||
uplink-observation-kit-name = Observation Kit
|
||||
@@ -295,7 +298,7 @@ uplink-starter-kit-desc = Contains 40 telecrystals of basic operative gear. For
|
||||
uplink-toolbox-name = Toolbox
|
||||
uplink-toolbox-desc = A full compliment of tools for the mechanically inclined traitor. Includes a pair of insulated combat gloves and a syndicate gas mask as well.
|
||||
|
||||
uplink-syndicate-jaws-of-life-name = Jaws Of Life
|
||||
uplink-syndicate-jaws-of-life-name = Jaws Of Death
|
||||
uplink-syndicate-jaws-of-life-desc = A combined prying and cutting tool. Useful for entering the station or its departments. Can even open bolted doors!
|
||||
|
||||
uplink-duffel-surgery-name = Surgical Duffel Bag
|
||||
@@ -333,7 +336,7 @@ uplink-chimp-upgrade-kit-name = C.H.I.M.P. Handcannon Upgrade Chip
|
||||
uplink-chimp-upgrade-kit-desc = Insert this chip into a standard C.H.I.M.P. handcannon to allow it to fire omega particles. Omega particles inflict severe burns and cause anomalies to go supercritical.
|
||||
|
||||
uplink-proximity-mine-name = Proximity Mine
|
||||
uplink-proximity-mine-desc = A mine disguised as a wet floor sign.
|
||||
uplink-proximity-mine-desc = A throwable mine disguised as a wet floor sign. Detonates on contact with almost anything, safety always off.
|
||||
|
||||
uplink-disposable-turret-name = Disposable Ballistic Turret
|
||||
uplink-disposable-turret-desc = Looks and functions like a normal electrical toolbox. Upon hitting the toolbox it will transform into a ballistic turret, theoretically shooting at anyone except members of the syndicate. Can be turned back into a toolbox using a screwdriver and repaired using a wrench.
|
||||
|
||||
@@ -20,7 +20,7 @@ ui-vote-map-tie = Tie for map vote! Picking... { $picked }
|
||||
ui-vote-map-win = { $winner } won the map vote!
|
||||
ui-vote-map-notlobby = Voting for maps is only valid in the pre-round lobby!
|
||||
ui-vote-map-notlobby-time = Voting for maps is only valid in the pre-round lobby with { $time } remaining!
|
||||
|
||||
ui-vote-map-invalid = { $winner } became invalid after the map vote! It will not be selected!
|
||||
|
||||
# Votekick votes
|
||||
ui-vote-votekick-unknown-initiator = A player
|
||||
|
||||
+66
-185
@@ -1,11 +1,11 @@
|
||||
meta:
|
||||
format: 7
|
||||
category: Map
|
||||
engineVersion: 266.0.0
|
||||
engineVersion: 270.0.0
|
||||
forkId: ""
|
||||
forkVersion: ""
|
||||
time: 08/31/2025 05:06:28
|
||||
entityCount: 3156
|
||||
time: 12/29/2025 08:52:17
|
||||
entityCount: 3158
|
||||
maps:
|
||||
- 23
|
||||
grids:
|
||||
@@ -1580,143 +1580,47 @@ entities:
|
||||
uniqueMixes:
|
||||
- volume: 2500
|
||||
immutable: True
|
||||
moles:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
moles: {}
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 21.824879
|
||||
- 82.10312
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 21.824879
|
||||
Nitrogen: 82.10312
|
||||
- volume: 2500
|
||||
temperature: 235
|
||||
moles:
|
||||
- 21.824879
|
||||
- 82.10312
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 21.824879
|
||||
Nitrogen: 82.10312
|
||||
- volume: 2500
|
||||
temperature: 293.14975
|
||||
moles:
|
||||
- 20.078888
|
||||
- 75.53487
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 20.078888
|
||||
Nitrogen: 75.53487
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles: {}
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Nitrogen: 6666.982
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 0
|
||||
- 6666.982
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 6666.982
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 6666.982
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 6666.982
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Plasma: 6666.982
|
||||
- volume: 2500
|
||||
temperature: 5000
|
||||
moles:
|
||||
- 6666.982
|
||||
- 0
|
||||
- 0
|
||||
- 6666.982
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 6666.982
|
||||
Plasma: 6666.982
|
||||
chunkSize: 4
|
||||
- type: BecomesStation
|
||||
id: Dev
|
||||
- type: ImplicitRoof
|
||||
- type: ExplosionAirtightGrid
|
||||
- uid: 23
|
||||
components:
|
||||
- type: MetaData
|
||||
@@ -1809,37 +1713,16 @@ entities:
|
||||
- volume: 2500
|
||||
temperature: 293.15
|
||||
moles:
|
||||
- 21.824879
|
||||
- 82.10312
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 21.824879
|
||||
Nitrogen: 82.10312
|
||||
- volume: 2500
|
||||
immutable: True
|
||||
moles:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
moles: {}
|
||||
chunkSize: 4
|
||||
- type: GasTileOverlay
|
||||
- type: RadiationGridResistance
|
||||
- type: ImplicitRoof
|
||||
- type: ExplosionAirtightGrid
|
||||
- uid: 2869
|
||||
components:
|
||||
- type: MetaData
|
||||
@@ -2106,14 +1989,6 @@ entities:
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 1220
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 51.5,37.5
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 1394
|
||||
components:
|
||||
- type: Transform
|
||||
@@ -3064,6 +2939,15 @@ entities:
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- proto: BaseAPC
|
||||
entities:
|
||||
- uid: 2753
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -0.5,1.5
|
||||
parent: 2709
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- proto: BaseBallBat
|
||||
entities:
|
||||
- uid: 2686
|
||||
@@ -6404,6 +6288,11 @@ entities:
|
||||
- type: Transform
|
||||
pos: 77.5,11.5
|
||||
parent: 1
|
||||
- uid: 3158
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 52.5,37.5
|
||||
parent: 1
|
||||
- proto: CableApcStack
|
||||
entities:
|
||||
- uid: 3139
|
||||
@@ -9831,18 +9720,8 @@ entities:
|
||||
immutable: False
|
||||
temperature: 293.14673
|
||||
moles:
|
||||
- 1.7459903
|
||||
- 6.568249
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 1.7459903
|
||||
Nitrogen: 6.568249
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
entity_storage: !type:Container
|
||||
@@ -9923,13 +9802,25 @@ entities:
|
||||
- type: Transform
|
||||
pos: 70.5,15.5
|
||||
parent: 1
|
||||
- proto: DebugAPC
|
||||
- proto: DebugAPCRecharging
|
||||
entities:
|
||||
- uid: 2753
|
||||
- uid: 1220
|
||||
components:
|
||||
- type: Transform
|
||||
pos: -0.5,1.5
|
||||
parent: 2709
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 51.5,37.5
|
||||
parent: 1
|
||||
- type: AccessReader
|
||||
accessListsOriginal:
|
||||
- - Engineering
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- uid: 2115
|
||||
components:
|
||||
- type: Transform
|
||||
rot: 3.141592653589793 rad
|
||||
pos: 52.5,37.5
|
||||
parent: 1
|
||||
- type: Fixtures
|
||||
fixtures: {}
|
||||
- proto: DebugGenerator
|
||||
@@ -9943,15 +9834,6 @@ entities:
|
||||
supplyRampRate: 500000
|
||||
supplyRampTolerance: 5000
|
||||
supplyRate: 3000000
|
||||
- proto: DebugSubstation
|
||||
entities:
|
||||
- uid: 2296
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 43.5,32.5
|
||||
parent: 1
|
||||
- type: Battery
|
||||
maxCharge: 25000000
|
||||
- proto: DefaultStationBeaconMedical
|
||||
entities:
|
||||
- uid: 2882
|
||||
@@ -11884,18 +11766,8 @@ entities:
|
||||
immutable: False
|
||||
temperature: 293.14673
|
||||
moles:
|
||||
- 1.7459903
|
||||
- 6.568249
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
Oxygen: 1.7459903
|
||||
Nitrogen: 6.568249
|
||||
- proto: LockerChiefEngineerFilledHardsuit
|
||||
entities:
|
||||
- uid: 1332
|
||||
@@ -15902,6 +15774,15 @@ entities:
|
||||
- type: Transform
|
||||
pos: 77.5,6.5
|
||||
parent: 1
|
||||
- proto: SubstationBasicEmpty
|
||||
entities:
|
||||
- uid: 2296
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 43.5,32.5
|
||||
parent: 1
|
||||
- type: Battery
|
||||
maxCharge: 25000000
|
||||
- proto: SubstationWallBasic
|
||||
entities:
|
||||
- uid: 2800
|
||||
|
||||
@@ -95,8 +95,8 @@
|
||||
containers:
|
||||
storagebase: !type:AllSelector
|
||||
children:
|
||||
- id: SyndicateMicrowaveFlatpack
|
||||
- id: WeaponCroissant
|
||||
amount: 2
|
||||
- id: WeaponBaguette
|
||||
- id: SyndicateMicrowaveMachineCircuitboard
|
||||
- id: PaperWrittenCombatBakeryKit
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
prob: 0.3
|
||||
rolls: !type:ConstantNumberSelector
|
||||
value: 3
|
||||
- id: PlushieLizardJobSalvagespecialist
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: LockerSalvageSpecialistFilledHardsuit
|
||||
|
||||
@@ -159,6 +159,8 @@
|
||||
- id: RCD
|
||||
- id: RCDAmmo
|
||||
- id: AirGrenade
|
||||
- id: PlushieLizardJobAtmospherictechnician
|
||||
prob: 0.02
|
||||
|
||||
- type: entityTable
|
||||
id: FillAtmosphericsHardsuit
|
||||
@@ -202,6 +204,10 @@
|
||||
- id: RCD
|
||||
- id: RCDAmmo
|
||||
- id: MetalFoamGrenade
|
||||
- id: PlushieLizardJobTechnicalassistant
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobStationengineer
|
||||
prob: 0.02
|
||||
|
||||
- type: entityTable
|
||||
id: FillEngineerHardsuit
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
- id: DoorRemoteCargo
|
||||
- id: AstroNavCartridge
|
||||
- id: ClothingHandsKnuckleDustersQM
|
||||
- id: PlushieLizardJobQuartermaster
|
||||
prob: 0.02
|
||||
- id: PrinterDocFlatpack # Corvax-Printer
|
||||
|
||||
- type: entity
|
||||
@@ -50,6 +52,8 @@
|
||||
conditions:
|
||||
- !type:PlayerCountCondition
|
||||
max: 15
|
||||
- id: PlushieLizardJobCaptain
|
||||
prob: 0.02
|
||||
# Corvax-Resprite-Start
|
||||
- id: ClothingHeadCaptainHat
|
||||
- id: ClothingOuterCoatCaptain
|
||||
@@ -135,6 +139,8 @@
|
||||
- id: HoPIDCard
|
||||
- id: WeaponDisabler
|
||||
- id: ClothingEyesHudCommand
|
||||
- id: PlushieLizardJobHeadofpersonnel
|
||||
prob: 0.02
|
||||
- id: ClothingOuterCoatHOP # Corvax-Resprite
|
||||
- id: PrinterDocFlatpack # Corvax-Printer
|
||||
|
||||
@@ -167,6 +173,8 @@
|
||||
- id: RCDAmmo
|
||||
- id: RubberStampCE
|
||||
- id: MetalFoamGrenade
|
||||
- id: PlushieLizardJobChiefengineer
|
||||
prob: 0.02
|
||||
|
||||
# Hardsuit table, used for suit storage as well
|
||||
- type: entityTable
|
||||
@@ -221,6 +229,8 @@
|
||||
- id: DoorRemoteMedical
|
||||
- id: BoxEncryptionKeyMedical
|
||||
- id: BoxCMOCircuitboards
|
||||
- id: PlushieLizardJobChiefmedicalofficer
|
||||
prob: 0.02
|
||||
|
||||
# Hardsuit table, used for suit storage as well
|
||||
- type: entityTable
|
||||
@@ -270,6 +280,8 @@
|
||||
- id: DoorRemoteResearch
|
||||
- id: HandTeleporter
|
||||
- id: RubberStampRd
|
||||
- id: PlushieLizardJobResearchdirector
|
||||
prob: 0.02
|
||||
|
||||
# Hardsuit table, used for suit storage as well
|
||||
- type: entityTable
|
||||
@@ -330,6 +342,8 @@
|
||||
- id: WeaponTaser
|
||||
- id: WantedListCartridge
|
||||
- id: DrinkHosFlask
|
||||
- id: PlushieLizardJobHeadofsecurity
|
||||
prob: 0.02
|
||||
# Corvax-Start
|
||||
- id: ClothingHeadHatCapHoS
|
||||
prob: 0.5
|
||||
|
||||
@@ -49,6 +49,12 @@
|
||||
- id: HandheldHealthAnalyzer
|
||||
- id: ChemistryBottleLaughter # Widely recognized as the best medicine :o)
|
||||
prob: 0.01
|
||||
- id: PlushieLizardJobMedicaldoctor
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobMedicalintern
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobPsychologist
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
parent: LockerMedical
|
||||
@@ -94,6 +100,8 @@
|
||||
- id: SprayBottle
|
||||
- id: Bucket
|
||||
- id: DrinkCartonMilk
|
||||
- id: PlushieLizardJobChemist
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
parent: LockerChemistry
|
||||
@@ -120,6 +128,8 @@
|
||||
- id: RollerBedSpawnFolded
|
||||
- id: CheapRollerBedSpawnFolded
|
||||
- id: EmergencyRollerBedSpawnFolded
|
||||
- id: PlushieLizardJobParamedic
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
parent: LockerParamedic
|
||||
|
||||
@@ -206,6 +206,10 @@
|
||||
prob: 0.10
|
||||
rolls: !type:RangeNumberSelector
|
||||
range: 1, 2
|
||||
- !type:NestedSelector
|
||||
tableId: MaintenancePlushies
|
||||
prob: 0.02
|
||||
|
||||
# Weapons
|
||||
- !type:NestedSelector
|
||||
tableId: MaintWeaponTable
|
||||
@@ -218,6 +222,19 @@
|
||||
- id: ClosetMaintenanceFilledRandom
|
||||
prob: 0.01
|
||||
|
||||
- type: entityTable
|
||||
id: MaintenancePlushies
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- id: PlushieLizardJobBoxer
|
||||
- id: PlushieLizardJobClown
|
||||
- id: PlushieLizardJobLibrarian
|
||||
- id: PlushieLizardJobMime
|
||||
- id: PlushieLizardJobMusician
|
||||
- id: PlushieLizardJobPassenger
|
||||
- id: PlushieLizardJobReporter
|
||||
- id: PlushieLizardJobZookeeper
|
||||
|
||||
- type: entity
|
||||
id: ClosetMaintenanceFilledRandom
|
||||
suffix: Filled, Random
|
||||
|
||||
@@ -20,3 +20,7 @@
|
||||
- id: NodeScanner
|
||||
- id: NetworkConfigurator
|
||||
prob: 0.5
|
||||
- id: PlushieLizardJobResearchassistant
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobScientist
|
||||
prob: 0.02
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
amount: 2
|
||||
- id: NetworkConfigurator
|
||||
- id: Binoculars
|
||||
- id: PlushieLizardJobWarden
|
||||
prob: 0.02
|
||||
|
||||
- type: entityTable
|
||||
id: FillLockerWardenHarduit
|
||||
@@ -93,6 +95,10 @@
|
||||
prob: 0.6
|
||||
- id: BookSpaceLaw
|
||||
prob: 0.5
|
||||
- id: PlushieLizardJobSecuritycadet
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobSecurityofficer
|
||||
prob: 0.02
|
||||
- id: ClothingOuterCoatSecurityOvercoat # Corvax-SecFashion
|
||||
prob: 0.2
|
||||
|
||||
@@ -185,6 +191,8 @@
|
||||
- id: HoloprojectorSecurity
|
||||
- id: BoxEvidenceMarkers
|
||||
- id: HandLabeler
|
||||
- id: PlushieLizardJobDetective
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: ClosetBombFilled
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
children:
|
||||
- id: BoxBeanbag
|
||||
- id: RagItem
|
||||
- id: PlushieLizardJobBartender
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobServiceworker
|
||||
prob: 0.02
|
||||
|
||||
#- type: entity
|
||||
# id: LockerFormalFilled
|
||||
@@ -64,6 +68,10 @@
|
||||
children:
|
||||
- id: FoodCondimentPacketSalt
|
||||
- id: FoodCondimentPacketPepper
|
||||
- id: PlushieLizardJobChef
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobServiceworker
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: ClosetJanitorFilled
|
||||
@@ -94,6 +102,8 @@
|
||||
- id: FlashlightLantern
|
||||
- id: Plunger
|
||||
- id: WireBrush
|
||||
- id: PlushieLizardJobJanitor
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: ClosetLegalFilled
|
||||
@@ -112,6 +122,8 @@
|
||||
- id: BriefcaseBrownFilled
|
||||
prob: 0.80
|
||||
- id: ClothingOuterRobesJudge
|
||||
- id: PlushieLizardJobLawyer
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: LockerBotanistFilled
|
||||
@@ -140,6 +152,10 @@
|
||||
- id: ClothingUniformOveralls
|
||||
- id: ClothingHeadHatTrucker
|
||||
prob: 0.1
|
||||
- id: PlushieLizardJobBotanist
|
||||
prob: 0.02
|
||||
- id: PlushieLizardJobServiceworker
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: LockerBotanistLoot
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
prob: 0.5
|
||||
- id: ClothingOuterCoatBomber
|
||||
prob: 0.3
|
||||
- id: PlushieLizardJobPassenger
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: WardrobeMixedFilled
|
||||
|
||||
@@ -267,6 +267,8 @@
|
||||
- id: ClothingUniformJumpsuitChaplain
|
||||
- id: ClothingShoesColorBlack
|
||||
- id: ClothingUniformJumpskirtChaplain
|
||||
- id: PlushieLizardJobChaplain
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: WardrobeSecurityFilled
|
||||
@@ -313,6 +315,8 @@
|
||||
- id: ClothingUniformJumpskirtCargo
|
||||
- id: ClothingHandsGlovesFingerless
|
||||
- id: AppraisalTool
|
||||
- id: PlushieLizardJobCargotechnician
|
||||
prob: 0.02
|
||||
|
||||
- type: entity
|
||||
id: WardrobeSalvageFilled
|
||||
|
||||
@@ -124,24 +124,6 @@
|
||||
categories:
|
||||
- UplinkWeaponry
|
||||
|
||||
- type: listing
|
||||
id: UplinkDisposableTurret
|
||||
name: uplink-disposable-turret-name
|
||||
description: uplink-disposable-turret-desc
|
||||
productEntity: ToolboxElectricalTurretFilled
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 3
|
||||
cost:
|
||||
Telecrystal: 6
|
||||
categories:
|
||||
- UplinkWeaponry
|
||||
conditions:
|
||||
- !type:StoreWhitelistCondition
|
||||
blacklist:
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: UplinkEshield
|
||||
name: uplink-eshield-name
|
||||
@@ -161,6 +143,20 @@
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: uplinkRiggedBoxingGloves
|
||||
name: uplink-rigged-boxing-gloves-name
|
||||
description: uplink-rigged-boxing-gloves-desc
|
||||
icon: { sprite: Clothing/Hands/Gloves/Boxing/boxingblue.rsi, state: icon }
|
||||
productEntity: ClothingHandsGlovesBoxingRiggedBlue # TODO Replace this with the random spawner when it's not bugged
|
||||
discountCategory: veryRareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 8
|
||||
cost:
|
||||
Telecrystal: 10
|
||||
categories:
|
||||
- UplinkWeaponry
|
||||
|
||||
- type: listing
|
||||
id: UplinkSniperBundle
|
||||
name: uplink-sniper-bundle-name
|
||||
@@ -408,19 +404,6 @@
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
|
||||
- type: listing
|
||||
id: UplinkWhiteholeGrenade
|
||||
name: uplink-whitehole-grenade-name
|
||||
description: uplink-whitehole-grenade-desc
|
||||
productEntity: WhiteholeGrenade
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
|
||||
- type: listing
|
||||
id: UplinkGrenadePenguin
|
||||
name: uplink-penguin-grenade-name
|
||||
@@ -1049,6 +1032,24 @@
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
|
||||
- type: listing
|
||||
id: UplinkDisposableTurret
|
||||
name: uplink-disposable-turret-name
|
||||
description: uplink-disposable-turret-desc
|
||||
productEntity: ToolboxElectricalTurretFilled
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 2
|
||||
cost:
|
||||
Telecrystal: 4
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
conditions:
|
||||
- !type:StoreWhitelistCondition
|
||||
blacklist:
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: UplinkSyndicateMartyrModule
|
||||
name: uplink-syndicate-martyr-module-name
|
||||
@@ -1079,10 +1080,8 @@
|
||||
description: uplink-slipocalypse-clustersoap-desc
|
||||
productEntity: SlipocalypseClusterSoap
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
|
||||
@@ -1137,23 +1136,18 @@
|
||||
cost:
|
||||
Telecrystal: 8
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
conditions:
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
- UplinkExplosives
|
||||
|
||||
- type: listing
|
||||
id: UplinkAntimovCircuitBoard
|
||||
name: uplink-antimov-law-name
|
||||
description: uplink-antimov-law-desc
|
||||
productEntity: AntimovCircuitBoard
|
||||
id: UplinkSyndimovCircuitBoard
|
||||
name: uplink-syndimov-law-name
|
||||
description: uplink-syndimov-law-desc
|
||||
productEntity: SyndimovCircuitBoard
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 10
|
||||
Telecrystal: 6
|
||||
cost:
|
||||
Telecrystal: 14
|
||||
Telecrystal: 8
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
conditions:
|
||||
@@ -1163,7 +1157,7 @@
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: UplinkNukieAntimovCircuitBoard
|
||||
id: UplinkAntimovCircuitBoard
|
||||
name: uplink-antimov-law-name
|
||||
description: uplink-antimov-law-desc
|
||||
productEntity: AntimovCircuitBoard
|
||||
@@ -1199,25 +1193,6 @@
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: UplinkSuperSurplusBundle
|
||||
name: uplink-super-surplus-bundle-name
|
||||
description: uplink-super-surplus-bundle-desc
|
||||
productEntity: CrateSyndicateSuperSurplusBundle
|
||||
cost:
|
||||
Telecrystal: 40
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
conditions:
|
||||
- !type:StoreWhitelistCondition
|
||||
blacklist:
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: UplinkStarterKit
|
||||
name: uplink-starter-kit-name
|
||||
@@ -1249,14 +1224,26 @@
|
||||
Telecrystal: 12
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
conditions:
|
||||
- !type:StoreWhitelistCondition
|
||||
whitelist:
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: UplinkCameraBug
|
||||
name: uplink-cameraBug-name
|
||||
description: uplink-cameraBug-desc
|
||||
productEntity: CameraBug
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 4
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkDisruption
|
||||
|
||||
@@ -1272,7 +1259,7 @@
|
||||
discountDownTo:
|
||||
Telecrystal: 8
|
||||
cost:
|
||||
Telecrystal: 14
|
||||
Telecrystal: 12
|
||||
categories:
|
||||
- UplinkAllies
|
||||
conditions:
|
||||
@@ -1291,7 +1278,7 @@
|
||||
discountDownTo:
|
||||
Telecrystal: 7
|
||||
cost:
|
||||
Telecrystal: 14
|
||||
Telecrystal: 11
|
||||
categories:
|
||||
- UplinkAllies
|
||||
conditions:
|
||||
@@ -1375,11 +1362,8 @@
|
||||
name: uplink-carp-dehydrated-name
|
||||
description: uplink-carp-dehydrated-desc
|
||||
productEntity: DehydratedSpaceCarp
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkAllies
|
||||
conditions:
|
||||
@@ -1445,9 +1429,9 @@
|
||||
productEntity: FreedomImplanter
|
||||
discountCategory: veryRareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 3
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 5
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkImplants
|
||||
|
||||
@@ -1459,9 +1443,9 @@
|
||||
productEntity: ScramImplanter
|
||||
discountCategory: veryRareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 4
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 6 # it's a gamble that may kill you easily so 6 TC per 2 uses, second one more of a backup
|
||||
Telecrystal: 2 # it's a gamble that may kill you easily so 1 TC per use.
|
||||
categories:
|
||||
- UplinkImplants
|
||||
|
||||
@@ -1475,7 +1459,7 @@
|
||||
discountDownTo:
|
||||
Telecrystal: 2
|
||||
cost:
|
||||
Telecrystal: 5
|
||||
Telecrystal: 3
|
||||
categories:
|
||||
- UplinkImplants
|
||||
|
||||
@@ -1569,11 +1553,8 @@
|
||||
description: uplink-uplink-implanter-desc
|
||||
icon: { sprite: /Textures/Objects/Devices/communication.rsi, state: old-radio }
|
||||
productEntity: UplinkImplanter
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkImplants
|
||||
conditions:
|
||||
@@ -1818,16 +1799,6 @@
|
||||
tags:
|
||||
- NukeOpsUplink
|
||||
|
||||
- type: listing
|
||||
id: UplinkClothingConductingGloves
|
||||
name: uplink-clothing-conducting-gloves-name
|
||||
description: uplink-clothing-conducting-gloves-desc
|
||||
productEntity: ClothingHandsGlovesConducting
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
|
||||
- type: listing
|
||||
id: UplinkBackpackSyndicate
|
||||
name: uplink-backpack-syndicate-name
|
||||
@@ -1860,16 +1831,23 @@
|
||||
categories:
|
||||
- UplinkPointless
|
||||
|
||||
- type: listing
|
||||
id: UplinkClothingConductingGloves
|
||||
name: uplink-clothing-conducting-gloves-name
|
||||
description: uplink-clothing-conducting-gloves-desc
|
||||
productEntity: ClothingHandsGlovesConducting
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
|
||||
- type: listing
|
||||
id: UplinkRevolverCapGun
|
||||
name: uplink-revolver-cap-gun-name
|
||||
description: uplink-revolver-cap-gun-desc
|
||||
productEntity: RevolverCapGun
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 2
|
||||
cost:
|
||||
Telecrystal: 4
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
|
||||
@@ -1878,13 +1856,11 @@
|
||||
name: uplink-syndicate-stamp-name
|
||||
description: uplink-syndicate-stamp-desc
|
||||
productEntity: RubberStampSyndicate
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: UplinkCatEars
|
||||
@@ -1895,16 +1871,22 @@
|
||||
Telecrystal: 26
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: UplinkOutlawHat
|
||||
name: uplink-outlaw-hat-name
|
||||
description: uplink-outlaw-hat-desc
|
||||
productEntity: ClothingHeadHatOutlawHat
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: UplinkOutlawGlasses
|
||||
@@ -1922,7 +1904,7 @@
|
||||
description: uplink-costume-pyjama-desc
|
||||
productEntity: ClothingBackpackDuffelSyndicatePyjamaBundle
|
||||
cost:
|
||||
Telecrystal: 4
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkPointless
|
||||
|
||||
@@ -1942,7 +1924,7 @@
|
||||
description: uplink-carp-suit-bundle-desc
|
||||
productEntity: ClothingBackpackDuffelSyndicateCarpSuit
|
||||
cost:
|
||||
Telecrystal: 4
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkPointless
|
||||
|
||||
@@ -1951,20 +1933,22 @@
|
||||
name: uplink-operative-suit-name
|
||||
description: uplink-operative-suit-desc
|
||||
productEntity: ClothingUniformJumpsuitOperative
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: UplinkOperativeSkirt
|
||||
name: uplink-operative-skirt-name
|
||||
description: uplink-operative-skirt-desc
|
||||
productEntity: ClothingUniformJumpskirtOperative
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: UplinkBalloon
|
||||
@@ -1975,26 +1959,33 @@
|
||||
Telecrystal: 20
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: UplinkScarfSyndieRed
|
||||
name: uplink-scarf-syndie-red-name
|
||||
description: uplink-scarf-syndie-red-desc
|
||||
productEntity: ClothingNeckScarfStripedSyndieRed
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: UplinkScarfSyndieGreen
|
||||
name: uplink-scarf-syndie-green-name
|
||||
description: uplink-scarf-syndie-green-desc
|
||||
productEntity: ClothingNeckScarfStripedSyndieGreen
|
||||
cost:
|
||||
Telecrystal: 1
|
||||
categories:
|
||||
- UplinkPointless
|
||||
conditions:
|
||||
- !type:ListingLimitedStockCondition
|
||||
stock: 1
|
||||
|
||||
- type: listing
|
||||
id: UplinkSyndicateBusinessCard
|
||||
@@ -2037,44 +2028,6 @@
|
||||
whitelist:
|
||||
- Botanist
|
||||
|
||||
- type: listing
|
||||
id: uplinkRiggedBoxingGlovesPassenger
|
||||
name: uplink-rigged-boxing-gloves-name
|
||||
description: uplink-rigged-boxing-gloves-desc
|
||||
productEntity: ClothingHandsGlovesBoxingRigged
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 3
|
||||
cost:
|
||||
Telecrystal: 6
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
- !type:BuyerJobCondition
|
||||
whitelist:
|
||||
- Passenger
|
||||
|
||||
- type: listing
|
||||
id: uplinkNecronomicon
|
||||
name: uplink-necronomicon-name
|
||||
description: uplink-necronomicon-desc
|
||||
productEntity: BibleNecronomicon
|
||||
discountCategory: usualDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 2
|
||||
cost:
|
||||
Telecrystal: 4
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
- !type:BuyerJobCondition
|
||||
whitelist:
|
||||
- Chaplain
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: uplinkHolyHandGrenade
|
||||
name: uplink-holy-hand-grenade-name
|
||||
@@ -2099,9 +2052,9 @@
|
||||
productEntity: RevolverCapGunFake
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 3
|
||||
Telecrystal: 2
|
||||
cost:
|
||||
Telecrystal: 5
|
||||
Telecrystal: 3
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
@@ -2110,24 +2063,6 @@
|
||||
- Mime
|
||||
- Clown
|
||||
|
||||
- type: listing
|
||||
id: uplinkBananaPeelExplosive
|
||||
name: uplink-banana-peel-explosive-name
|
||||
description: uplink-banana-peel-explosive-desc
|
||||
icon: { sprite: Objects/Specific/Hydroponics/banana.rsi, state: peel }
|
||||
productEntity: TrashBananaPeelExplosiveUnarmed
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 1
|
||||
cost:
|
||||
Telecrystal: 2
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
- !type:BuyerJobCondition
|
||||
whitelist:
|
||||
- Clown
|
||||
|
||||
- type: listing
|
||||
id: UplinkClusterBananaPeel
|
||||
name: uplink-cluster-banana-peel-name
|
||||
@@ -2137,7 +2072,7 @@
|
||||
discountDownTo:
|
||||
Telecrystal: 3
|
||||
cost:
|
||||
Telecrystal: 6
|
||||
Telecrystal: 5
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
@@ -2228,10 +2163,10 @@
|
||||
icon: { sprite: Objects/Misc/monkeycube.rsi, state: box}
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 4
|
||||
Telecrystal: 2
|
||||
productEntity: SyndicateSpongeBox
|
||||
cost:
|
||||
Telecrystal: 7
|
||||
Telecrystal: 4
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
@@ -2259,10 +2194,6 @@
|
||||
- !type:BuyerJobCondition
|
||||
whitelist:
|
||||
- Librarian
|
||||
- !type:BuyerWhitelistCondition
|
||||
blacklist:
|
||||
components:
|
||||
- SurplusBundle
|
||||
|
||||
- type: listing
|
||||
id: UplinkCombatBakery
|
||||
@@ -2349,7 +2280,7 @@
|
||||
discountDownTo:
|
||||
Telecrystal: 10
|
||||
cost:
|
||||
Telecrystal: 15
|
||||
Telecrystal: 14
|
||||
categories:
|
||||
- UplinkJob
|
||||
conditions:
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
- type: entity
|
||||
abstract: true
|
||||
parent: ClothingHandsBase
|
||||
id: ClothingHandsGlovesBoxingRed
|
||||
name: red boxing gloves
|
||||
description: Red gloves for competitive boxing.
|
||||
id: ClothingHandsGlovesBoxingBase
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/Hands/Gloves/Boxing/boxingred.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Hands/Gloves/Boxing/boxingred.rsi
|
||||
- type: StaminaDamageOnHit
|
||||
damage: 8 #Stam damage values seem a bit higher than regular damage because of the decay, etc
|
||||
# This needs to be moved to boxinggloves
|
||||
@@ -21,17 +16,28 @@
|
||||
collection: BoxingHit
|
||||
animation: WeaponArcFist
|
||||
mustBeEquippedToUse: true
|
||||
- type: Fiber
|
||||
fiberMaterial: fibers-leather
|
||||
fiberColor: fibers-red
|
||||
- type: FingerprintMask
|
||||
- type: Tag
|
||||
tags:
|
||||
- Kangaroo
|
||||
- WhitelistChameleon
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesBoxingRed
|
||||
parent: ClothingHandsGlovesBoxingBase
|
||||
id: ClothingHandsGlovesBoxingRed
|
||||
name: red boxing gloves
|
||||
description: Red gloves for competitive boxing.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Clothing/Hands/Gloves/Boxing/boxingred.rsi
|
||||
- type: Clothing
|
||||
sprite: Clothing/Hands/Gloves/Boxing/boxingred.rsi
|
||||
- type: Fiber
|
||||
fiberMaterial: fibers-leather
|
||||
fiberColor: fibers-red
|
||||
- type: FingerprintMask
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesBoxingBase
|
||||
id: ClothingHandsGlovesBoxingBlue
|
||||
name: blue boxing gloves
|
||||
description: Blue gloves for competitive boxing.
|
||||
@@ -47,7 +53,7 @@
|
||||
- type: FingerprintMask
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesBoxingRed
|
||||
parent: ClothingHandsGlovesBoxingBase
|
||||
id: ClothingHandsGlovesBoxingGreen
|
||||
name: green boxing gloves
|
||||
description: Green gloves for competitive boxing.
|
||||
@@ -63,7 +69,7 @@
|
||||
- type: FingerprintMask
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesBoxingRed
|
||||
parent: ClothingHandsGlovesBoxingBase
|
||||
id: ClothingHandsGlovesBoxingYellow
|
||||
name: yellow boxing gloves
|
||||
description: Yellow gloves for competitive boxing.
|
||||
@@ -79,19 +85,53 @@
|
||||
- type: FingerprintMask
|
||||
|
||||
- type: entity
|
||||
parent: ClothingHandsGlovesBoxingBlue
|
||||
id: ClothingHandsGlovesBoxingRigged
|
||||
abstract: true
|
||||
parent: ClothingHandsGlovesBoxingBase
|
||||
id: ClothingHandsGlovesBoxingRiggedBase
|
||||
suffix: Rigged
|
||||
components:
|
||||
- type: StaminaDamageOnHit
|
||||
damage: 25
|
||||
- type: MeleeWeapon
|
||||
attackRate: 1.4
|
||||
damage:
|
||||
types:
|
||||
Blunt: 8
|
||||
bluntStaminaDamageFactor: 0.0 # so blunt doesn't deal stamina damage at all
|
||||
mustBeEquippedToUse: true
|
||||
bluntStaminaDamageFactor: 2
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingHandsGlovesBoxingRiggedBase, ClothingHandsGlovesBoxingRed ]
|
||||
id: ClothingHandsGlovesBoxingRiggedRed
|
||||
name: red boxing gloves
|
||||
description: Red gloves for competitive boxing.
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingHandsGlovesBoxingRiggedBase, ClothingHandsGlovesBoxingBlue ]
|
||||
id: ClothingHandsGlovesBoxingRiggedBlue
|
||||
name: blue boxing gloves
|
||||
description: Blue gloves for competitive boxing.
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingHandsGlovesBoxingRiggedBase, ClothingHandsGlovesBoxingGreen ]
|
||||
id: ClothingHandsGlovesBoxingRiggedGreen
|
||||
name: green boxing gloves
|
||||
description: Green gloves for competitive boxing.
|
||||
|
||||
- type: entity
|
||||
parent: [ ClothingHandsGlovesBoxingRiggedBase, ClothingHandsGlovesBoxingYellow ]
|
||||
id: ClothingHandsGlovesBoxingRiggedYellow
|
||||
name: yellow boxing gloves
|
||||
description: Yellow gloves for competitive boxing.
|
||||
|
||||
- type: entity
|
||||
id: GlovesBoxingRiggedRandomSpawner
|
||||
categories: [ HideSpawnMenu ]
|
||||
name: random rigged boxing glove spawner
|
||||
components:
|
||||
- type: EntityTableSpawner
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
- id: ClothingHandsGlovesBoxingRiggedRed
|
||||
- id: ClothingHandsGlovesBoxingRiggedBlue
|
||||
- id: ClothingHandsGlovesBoxingRiggedGreen
|
||||
- id: ClothingHandsGlovesBoxingRiggedYellow
|
||||
|
||||
- type: entity
|
||||
parent: [ClothingHandsBase, BaseCommandContraband]
|
||||
|
||||
@@ -111,6 +111,8 @@
|
||||
- type: Tag
|
||||
tags:
|
||||
- CannotSuicide
|
||||
- StunImmune
|
||||
- SlowImmune
|
||||
|
||||
# From the uplink injector
|
||||
- type: entity
|
||||
@@ -234,15 +236,6 @@
|
||||
Hand:
|
||||
location: Left
|
||||
- type: ComplexInteraction
|
||||
- type: Clumsy
|
||||
gunShootFailDamage:
|
||||
types:
|
||||
Blunt: 5
|
||||
Piercing: 4
|
||||
Heat: 3
|
||||
catchingFailDamage:
|
||||
types:
|
||||
Blunt: 1
|
||||
- type: MeleeWeapon
|
||||
angle: 30
|
||||
animation: WeaponArcFist
|
||||
@@ -257,9 +250,6 @@
|
||||
- type: RandomMetadata
|
||||
nameSegments:
|
||||
- NamesClown
|
||||
- type: NpcFactionMember
|
||||
factions:
|
||||
- Syndicate
|
||||
- type: HTN
|
||||
rootTask:
|
||||
task: SimpleHumanoidHostileCompound
|
||||
|
||||
@@ -811,10 +811,6 @@
|
||||
Quantity: 2
|
||||
- ReagentId: Vitamin
|
||||
Quantity: 1
|
||||
- type: DamageOtherOnHit
|
||||
damage:
|
||||
types:
|
||||
Blunt: 0 # so the damage stats icon doesn't immediately give away the syndie ones
|
||||
|
||||
- type: entity
|
||||
parent: FoodBakedCroissant
|
||||
|
||||
@@ -583,7 +583,7 @@
|
||||
children:
|
||||
- id: FoodSaladValid
|
||||
weight: 0.05
|
||||
amount: 4
|
||||
amount: 2
|
||||
- id: FoodSnackSyndi
|
||||
amount: 4
|
||||
|
||||
@@ -699,13 +699,17 @@
|
||||
- type: entityTable # size: 1x2
|
||||
id: HappyHonkToyUnsafeEntityTable
|
||||
table: !type:GroupSelector
|
||||
children:
|
||||
children: # Total Weight 6
|
||||
- id: ClothingHeadHatCatEars
|
||||
weight: 0.25
|
||||
- id: C4
|
||||
weight: 0.02
|
||||
weight: 0.05
|
||||
- id: ToyMarauder
|
||||
- id: ToyMauler
|
||||
- id: ToyNuke
|
||||
- id: ToySword
|
||||
- id: WeaponRevolverPythonAP
|
||||
weight: 0.4
|
||||
- id: BalloonSyn
|
||||
weight: 0.6
|
||||
weight: 0.3
|
||||
- id: PlushieNuke
|
||||
|
||||
@@ -124,6 +124,18 @@
|
||||
- type: StaticPrice
|
||||
price: 10000
|
||||
|
||||
- type: entity
|
||||
id: SyndimovCircuitBoard
|
||||
parent: [BaseSiliconLawboard, BaseSyndicateContraband]
|
||||
name: law board (Syndimov)
|
||||
description: An electronics board containing the Syndimov lawset.
|
||||
components:
|
||||
- type: SiliconLawProvider
|
||||
laws: SyndicateStatic
|
||||
lawUploadSound: /Audio/Ambience/Antag/emagged_borg.ogg # This should probably have its own sound but it's fine for now.
|
||||
- type: StaticPrice
|
||||
price: 5000
|
||||
|
||||
- type: entity
|
||||
id: NutimovCircuitBoard
|
||||
parent: BaseSiliconLawboard
|
||||
|
||||
@@ -266,3 +266,17 @@
|
||||
guides:
|
||||
- Botany
|
||||
- Chemicals
|
||||
|
||||
- type: entity
|
||||
parent: [ BaseFlatpack, BaseSyndicateContraband ]
|
||||
id: SyndicateMicrowaveFlatpack
|
||||
name: donk co. microwave flatpack
|
||||
description: A flatpack used for constructing a microwave too hot for Nanotrasen to handle.
|
||||
components:
|
||||
- type: Item
|
||||
size: Normal
|
||||
- type: Flatpack
|
||||
entity: SyndicateMicrowave
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- FoodRecipes
|
||||
|
||||
@@ -259,7 +259,7 @@
|
||||
|
||||
- type: entity
|
||||
id: VoiceMaskImplanter
|
||||
name: voice mask implanter
|
||||
name: identity mask implanter
|
||||
parent: BaseImplantOnlyImplanterSyndi
|
||||
components:
|
||||
- type: Implanter
|
||||
|
||||
@@ -242,8 +242,8 @@
|
||||
- type: entity
|
||||
parent: BaseSubdermalImplant
|
||||
id: VoiceMaskImplant
|
||||
name: voice mask implant
|
||||
description: This implant allows you to change your voice at will.
|
||||
name: identity mask implant
|
||||
description: This implant allows you to change your identity at will.
|
||||
categories: [ HideSpawnMenu ]
|
||||
components:
|
||||
- type: SubdermalImplant
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
- type: ExaminableBattery
|
||||
- type: PowerConsumer
|
||||
voltage: High
|
||||
drawRate: 1000000
|
||||
drawRate: 10000000
|
||||
- type: Sprite
|
||||
sprite: Objects/Power/powersink.rsi
|
||||
state: powersink
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user