Merge remote-tracking branch 'refs/remotes/wizards/master'

# Conflicts:
#	Content.Client/Lobby/LobbyUIController.cs
#	Content.Client/Lobby/UI/CharacterSetupGui.xaml
#	Content.Client/Lobby/UI/CharacterSetupGui.xaml.cs
#	Content.Server/Antag/AntagSelectionSystem.cs
#	Content.Server/GameTicking/GameTicker.Lobby.cs
#	Content.Server/Objectives/Systems/KillPersonConditionSystem.cs
#	Content.Server/Store/Systems/StoreSystem.Ui.cs
#	Content.Shared/Inventory/InventorySystem.Relay.cs
#	Resources/Maps/_Sunrise/Shuttles/abandoned_outpost.yml
#	Resources/Prototypes/Entities/Stations/base.yml
#	Resources/Textures/Interface/Misc/job_icons.rsi/meta.json
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarm0.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarm1.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarm2.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarm_b1.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarm_b2.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarm_bitem.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarmp.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/alarmx.png
#	Resources/Textures/Structures/Wallmounts/air_monitors.rsi/meta.json
This commit is contained in:
Vigers Ray 2024-11-19 18:34:32 +03:00
commit d853b875eb
103 changed files with 8381 additions and 2257 deletions

View file

@ -31,7 +31,7 @@ namespace Content.Client.Crayon.UI
private void PopulateCrayons()
{
var crayonDecals = _protoManager.EnumeratePrototypes<DecalPrototype>().Where(x => x.Tags.Contains("crayon"));
_menu?.Populate(crayonDecals);
_menu?.Populate(crayonDecals.ToList());
}
public override void OnProtoReload(PrototypesReloadedEventArgs args)
@ -44,6 +44,16 @@ namespace Content.Client.Crayon.UI
PopulateCrayons();
}
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
{
base.ReceiveMessage(message);
if (_menu is null || message is not CrayonUsedMessage crayonMessage)
return;
_menu.AdvanceState(crayonMessage.DrawnDecal);
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);

View file

@ -1,14 +1,13 @@
<DefaultWindow xmlns="https://spacestation14.io"
Title="{Loc 'crayon-window-title'}"
MinSize="250 300"
SetSize="250 300">
MinSize="450 500"
SetSize="450 500">
<BoxContainer Orientation="Vertical">
<ColorSelectorSliders Name="ColorSelector" Visible="False" />
<LineEdit Name="Search" />
<LineEdit Name="Search" Margin="0 0 0 8" PlaceHolder="{Loc 'crayon-window-placeholder'}" />
<ScrollContainer VerticalExpand="True">
<GridContainer Name="Grid" Columns="6">
<!-- Crayon decals get added here by code -->
</GridContainer>
<BoxContainer Name="Grids" Orientation="Vertical">
</BoxContainer>
</ScrollContainer>
</BoxContainer>
</DefaultWindow>

View file

@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using Content.Client.Stylesheets;
using Content.Shared.Crayon;
using Content.Shared.Decals;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
@ -18,7 +20,12 @@ namespace Content.Client.Crayon.UI
[GenerateTypedNameReferences]
public sealed partial class CrayonWindow : DefaultWindow
{
private Dictionary<string, Texture>? _decals;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
private readonly SpriteSystem _spriteSystem = default!;
private Dictionary<string, List<(string Name, Texture Texture)>>? _decals;
private List<string>? _allDecals;
private string? _autoSelected;
private string? _selected;
private Color _color;
@ -28,8 +35,10 @@ namespace Content.Client.Crayon.UI
public CrayonWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
Search.OnTextChanged += _ => RefreshList();
Search.OnTextChanged += SearchChanged;
ColorSelector.OnColorChanged += SelectColor;
}
@ -44,51 +53,94 @@ namespace Content.Client.Crayon.UI
private void RefreshList()
{
// Clear
Grid.DisposeAllChildren();
if (_decals == null)
Grids.DisposeAllChildren();
if (_decals == null || _allDecals == null)
return;
var filter = Search.Text;
foreach (var (decal, tex) in _decals)
var comma = filter.IndexOf(',');
var first = (comma == -1 ? filter : filter[..comma]).Trim();
var names = _decals.Keys.ToList();
names.Sort((a, b) => a == "random" ? 1 : b == "random" ? -1 : a.CompareTo(b));
if (_autoSelected != null && first != _autoSelected && _allDecals.Contains(first))
{
if (!decal.Contains(filter))
_selected = first;
_autoSelected = _selected;
OnSelected?.Invoke(_selected);
}
foreach (var categoryName in names)
{
var locName = Loc.GetString("crayon-category-" + categoryName);
var category = _decals[categoryName].Where(d => locName.Contains(first) || d.Name.Contains(first)).ToList();
if (category.Count == 0)
continue;
var button = new TextureButton()
var label = new Label
{
TextureNormal = tex,
Name = decal,
ToolTip = decal,
Modulate = _color,
Text = locName
};
button.OnPressed += ButtonOnPressed;
if (_selected == decal)
var grid = new GridContainer
{
var panelContainer = new PanelContainer()
Columns = 6,
Margin = new Thickness(0, 0, 0, 16)
};
Grids.AddChild(label);
Grids.AddChild(grid);
foreach (var (name, texture) in category)
{
var button = new TextureButton()
{
PanelOverride = new StyleBoxFlat()
{
BackgroundColor = StyleNano.ButtonColorDefault,
},
Children =
{
button,
},
TextureNormal = texture,
Name = name,
ToolTip = name,
Modulate = _color,
Scale = new System.Numerics.Vector2(2, 2)
};
Grid.AddChild(panelContainer);
}
else
{
Grid.AddChild(button);
button.OnPressed += ButtonOnPressed;
if (_selected == name)
{
var panelContainer = new PanelContainer()
{
PanelOverride = new StyleBoxFlat()
{
BackgroundColor = StyleNano.ButtonColorDefault,
},
Children =
{
button,
},
};
grid.AddChild(panelContainer);
}
else
{
grid.AddChild(button);
}
}
}
}
private void SearchChanged(LineEdit.LineEditEventArgs obj)
{
_autoSelected = ""; // Placeholder to kick off the auto-select in refreshlist()
RefreshList();
}
private void ButtonOnPressed(ButtonEventArgs obj)
{
if (obj.Button.Name == null) return;
_selected = obj.Button.Name;
_autoSelected = null;
OnSelected?.Invoke(_selected);
RefreshList();
}
@ -107,12 +159,38 @@ namespace Content.Client.Crayon.UI
RefreshList();
}
public void Populate(IEnumerable<DecalPrototype> prototypes)
public void AdvanceState(string drawnDecal)
{
_decals = new Dictionary<string, Texture>();
var filter = Search.Text;
if (!filter.Contains(',') || !filter.Contains(drawnDecal))
return;
var first = filter[..filter.IndexOf(',')].Trim();
if (first.Equals(drawnDecal, StringComparison.InvariantCultureIgnoreCase))
{
Search.Text = filter[(filter.IndexOf(',') + 1)..].Trim();
_autoSelected = first;
}
RefreshList();
}
public void Populate(List<DecalPrototype> prototypes)
{
_decals = [];
_allDecals = [];
prototypes.Sort((a, b) => a.ID.CompareTo(b.ID));
foreach (var decalPrototype in prototypes)
{
_decals.Add(decalPrototype.ID, decalPrototype.Sprite.Frame0());
var category = "random";
if (decalPrototype.Tags.Count > 1 && decalPrototype.Tags[1].StartsWith("crayon-"))
category = decalPrototype.Tags[1].Replace("crayon-", "");
var list = _decals.GetOrNew(category);
list.Add((decalPrototype.ID, _spriteSystem.Frame0(decalPrototype.Sprite)));
_allDecals.Add(decalPrototype.ID);
}
RefreshList();

View file

@ -282,7 +282,7 @@ public sealed partial class LobbyUIController : UIController, IOnStateEntered<Lo
_profileEditor.OnOpenGuidebook += _guide.OpenHelp;
_characterSetup = new CharacterSetupGui(EntityManager, _prototypeManager, _resourceCache, _preferencesManager, _profileEditor, _configurationManager);
_characterSetup = new CharacterSetupGui(_profileEditor);
_characterSetup.CloseButton.OnPressed += _ =>
{

View file

@ -2,6 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:style="clr-namespace:Content.Client.Stylesheets"
xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"
VerticalExpand="True">
<Control>
<PanelContainer Name="BackgroundPanel" StyleClasses="AngleRect"/>
@ -10,16 +11,15 @@
<Label Text="{Loc 'character-setup-gui-character-setup-label'}"
Margin="8 0 0 0" VAlign="Center"
StyleClasses="LabelHeadingBigger" />
<Button Name="StatsButton" HorizontalExpand="True"
Text="{Loc 'character-setup-gui-character-setup-stats-button'}"
StyleClasses="ButtonBig"
HorizontalAlignment="Right" />
<!-- Sunrise-Sponsor-Start -->
<Button Name="SponsorButton"
Text="{Loc 'character-setup-gui-character-setup-sponsor-button'}"
Visible="False"
StyleClasses="ButtonBig" />
<!-- Sunrise-Sponsor-End -->
<cc:CommandButton Name="AdminRemarksButton"
Command="adminremarks"
Text="{Loc 'character-setup-gui-character-setup-adminremarks-button'}"
StyleClasses="ButtonBig" />
<Button Name="RulesButton"
Text="{Loc 'character-setup-gui-character-setup-rules-button'}"
StyleClasses="ButtonBig"/>

View file

@ -1,6 +1,7 @@
using Content.Client.Info;
using Content.Client.Info.PlaytimeStats;
using Content.Client.Resources;
using Content.Shared.CCVar;
using Content.Shared._Sunrise.SunriseCCVars;
using Content.Shared.Preferences;
using Robust.Client.AutoGenerated;
@ -20,9 +21,11 @@ namespace Content.Client.Lobby.UI
[GenerateTypedNameReferences]
public sealed partial class CharacterSetupGui : Control
{
private readonly IClientPreferencesManager _preferencesManager;
private readonly IEntityManager _entManager;
private readonly IPrototypeManager _protomanager;
[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!;
private readonly Button _createNewCharacterButton;
@ -31,21 +34,12 @@ namespace Content.Client.Lobby.UI
private readonly StyleBoxTexture _back;
public CharacterSetupGui(
IEntityManager entManager,
IPrototypeManager protoManager,
IResourceCache resourceCache,
IClientPreferencesManager preferencesManager,
HumanoidProfileEditor profileEditor,
IConfigurationManager configurationManager)
public CharacterSetupGui(HumanoidProfileEditor profileEditor)
{
RobustXamlLoader.Load(this);
_preferencesManager = preferencesManager;
_entManager = entManager;
_protomanager = protoManager;
var configurationManager1 = configurationManager;
IoCManager.InjectDependencies(this);
var panelTex = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
var panelTex = _resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
_back = new StyleBoxTexture
{
Texture = panelTex,
@ -64,7 +58,7 @@ namespace Content.Client.Lobby.UI
_createNewCharacterButton.OnPressed += args =>
{
preferencesManager.CreateCharacter(HumanoidCharacterProfile.Random());
_preferencesManager.CreateCharacter(HumanoidCharacterProfile.Random());
ReloadCharacterPickers();
args.Event.Handle();
};
@ -74,7 +68,9 @@ namespace Content.Client.Lobby.UI
StatsButton.OnPressed += _ => new PlaytimeStatsWindow().OpenCentered();
configurationManager1.OnValueChanged(SunriseCCVars.LobbyOpacity, OnLobbyOpacityChanged);
_cfg.OnValueChanged(CCVars.SeeOwnNotes, p => AdminRemarksButton.Visible = p, true);
_cfg.OnValueChanged(SunriseCCVars.LobbyOpacity, OnLobbyOpacityChanged);
}
private void OnLobbyOpacityChanged(float opacity)

View file

@ -23,6 +23,7 @@ using Content.Shared.Administration;
using Content.Shared.Administration.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.Clumsy;
using Content.Shared.Clothing.Components;
using Content.Shared.Cluwne;
using Content.Shared.Damage;

View file

@ -1,27 +1,27 @@
using Content.Server.Administration.Components;
using Content.Shared.Climbing.Components;
using Content.Shared.Climbing.Events;
using Content.Shared.Climbing.Systems;
using Content.Shared.Interaction.Components;
using Content.Shared.Clumsy;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Robust.Shared.Audio.Systems;
namespace Content.Server.Administration.Systems;
public sealed class SuperBonkSystem: EntitySystem
public sealed class SuperBonkSystem : EntitySystem
{
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
[Dependency] private readonly BonkSystem _bonkSystem = default!;
[Dependency] private readonly ClumsySystem _clumsySystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SuperBonkComponent, ComponentShutdown>(OnBonkShutdown);
SubscribeLocalEvent<SuperBonkComponent, MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<SuperBonkComponent, ComponentShutdown>(OnBonkShutdown);
}
public void StartSuperBonk(EntityUid target, float delay = 0.1f, bool stopWhenDead = false )
public void StartSuperBonk(EntityUid target, float delay = 0.1f, bool stopWhenDead = false)
{
//The other check in the code to stop when the target dies does not work if the target is already dead.
@ -31,7 +31,6 @@ public sealed class SuperBonkSystem: EntitySystem
return;
}
var hadClumsy = EnsureComp<ClumsyComponent>(target, out _);
var tables = EntityQueryEnumerator<BonkableComponent>();
@ -79,16 +78,17 @@ public sealed class SuperBonkSystem: EntitySystem
private void Bonk(SuperBonkComponent comp)
{
var uid = comp.Tables.Current.Key;
var bonkComp = comp.Tables.Current.Value;
// It would be very weird for something without a transform component to have a bonk component
// but just in case because I don't want to crash the server.
if (!HasComp<TransformComponent>(uid))
if (!HasComp<TransformComponent>(uid) || !TryComp<ClumsyComponent>(comp.Target, out var clumsyComp))
return;
_transformSystem.SetCoordinates(comp.Target, Transform(uid).Coordinates);
_bonkSystem.TryBonk(comp.Target, uid, bonkComp);
_clumsySystem.HitHeadClumsy((comp.Target, clumsyComp), uid);
_audioSystem.PlayPvs(clumsyComp.TableBonkSound, comp.Target);
}
private void OnMobStateChanged(EntityUid uid, SuperBonkComponent comp, MobStateChangedEvent args)

View file

@ -196,19 +196,9 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
if (component.SelectionsComplete)
return;
// Sunrise-Start
var players = _playerManager.Sessions
.Where(x =>
{
// Try to get the PlayerGameStatus for the current player's UserId
if (GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status))
{
return status == PlayerGameStatus.JoinedGame;
}
return false;
})
.Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame)
.ToList();
// Sunrise-End
ChooseAntags((uid, component), players, midround: true);
}

View file

@ -38,6 +38,7 @@ public sealed class SeedExtractorSystem : EntitySystem
args.User, PopupType.Medium);
QueueDel(args.Used);
args.Handled = true;
var amount = _random.Next(seedExtractor.BaseMinSeeds, seedExtractor.BaseMaxSeeds + 1);
var coords = Transform(uid).Coordinates;

View file

@ -1,6 +1,7 @@
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Chemistry.Hypospray.Events;
using Content.Shared.Chemistry;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
@ -108,14 +109,44 @@ public sealed class HypospraySystem : SharedHypospraySystem
return false;
}
if (target == user)
msgFormat = "hypospray-component-inject-self-message";
else if (EligibleEntity(user, EntityManager, component) && _interaction.TryRollClumsy(user, component.ClumsyFailChance))
// Self event
var selfEvent = new SelfBeforeHyposprayInjectsEvent(user, entity.Owner, target);
RaiseLocalEvent(user, selfEvent);
if (selfEvent.Cancelled)
{
msgFormat = "hypospray-component-inject-self-clumsy-message";
target = user;
_popup.PopupEntity(Loc.GetString(selfEvent.InjectMessageOverride ?? "hypospray-cant-inject", ("owner", Identity.Entity(target, EntityManager))), target, user);
return false;
}
target = selfEvent.TargetGettingInjected;
if (!EligibleEntity(target, EntityManager, component))
return false;
// Target event
var targetEvent = new TargetBeforeHyposprayInjectsEvent(user, entity.Owner, target);
RaiseLocalEvent(target, targetEvent);
if (targetEvent.Cancelled)
{
_popup.PopupEntity(Loc.GetString(targetEvent.InjectMessageOverride ?? "hypospray-cant-inject", ("owner", Identity.Entity(target, EntityManager))), target, user);
return false;
}
target = targetEvent.TargetGettingInjected;
if (!EligibleEntity(target, EntityManager, component))
return false;
// The target event gets priority for the overriden message.
if (targetEvent.InjectMessageOverride != null)
msgFormat = targetEvent.InjectMessageOverride;
else if (selfEvent.InjectMessageOverride != null)
msgFormat = selfEvent.InjectMessageOverride;
else if (target == user)
msgFormat = "hypospray-component-inject-self-message";
if (!_solutionContainers.TryGetSolution(uid, component.SolutionName, out var hypoSpraySoln, out var hypoSpraySolution) || hypoSpraySolution.Volume == 0)
{
_popup.PopupEntity(Loc.GetString("hypospray-component-empty-message"), target, user);

View file

@ -16,6 +16,7 @@ using Content.Shared.Cluwne;
using Content.Shared.Interaction.Components;
using Robust.Shared.Audio.Systems;
using Content.Shared.NameModifier.EntitySystems;
using Content.Shared.Clumsy;
namespace Content.Server.Cluwne;

View file

@ -82,6 +82,8 @@ public sealed class CrayonSystem : SharedCrayonSystem
if (component.DeleteEmpty && component.Charges <= 0)
UseUpCrayon(uid, args.User);
else
_uiSystem.ServerSendUiMessage(uid, SharedCrayonComponent.CrayonUiKey.Key, new CrayonUsedMessage(component.SelectedState));
}
private void OnCrayonUse(EntityUid uid, CrayonComponent component, UseInHandEvent args)

View file

@ -192,12 +192,6 @@ namespace Content.Server.GameTicking
=> UserHasJoinedGame(session.UserId);
public bool UserHasJoinedGame(NetUserId userId)
{
// Sunrise-Edit: Я не понимаю почему, но PlayerGameStatuses[userId] может вернуть ошибку.
if (!PlayerGameStatuses.TryGetValue(userId, out var status))
return false;
return status == PlayerGameStatus.JoinedGame;
}
=> PlayerGameStatuses.TryGetValue(userId, out var status) && status == PlayerGameStatus.JoinedGame;
}
}

View file

@ -77,7 +77,20 @@ public sealed class DefibrillatorSystem : EntitySystem
Zap(uid, target, args.User, component);
}
public bool CanZap(EntityUid uid, EntityUid target, EntityUid? user = null, DefibrillatorComponent? component = null)
/// <summary>
/// Checks if you can actually defib a target.
/// </summary>
/// <param name="uid">Uid of the defib</param>
/// <param name="target">Uid of the target getting defibbed</param>
/// <param name="user">Uid of the entity using the defibrillator</param>
/// <param name="component">Defib component</param>
/// <param name="targetCanBeAlive">
/// If true, the target can be alive. If false, the function will check if the target is alive and will return false if they are.
/// </param>
/// <returns>
/// Returns true if the target is valid to be defibed, false otherwise.
/// </returns>
public bool CanZap(EntityUid uid, EntityUid target, EntityUid? user = null, DefibrillatorComponent? component = null, bool targetCanBeAlive = false)
{
if (!Resolve(uid, ref component))
return false;
@ -98,15 +111,25 @@ public sealed class DefibrillatorSystem : EntitySystem
if (!_powerCell.HasActivatableCharge(uid, user: user))
return false;
if (_mobState.IsAlive(target, mobState))
if (!targetCanBeAlive && _mobState.IsAlive(target, mobState))
return false;
if (!component.CanDefibCrit && _mobState.IsCritical(target, mobState))
if (!targetCanBeAlive && !component.CanDefibCrit && _mobState.IsCritical(target, mobState))
return false;
return true;
}
/// <summary>
/// Tries to start defibrillating the target. If the target is valid, will start the defib do-after.
/// </summary>
/// <param name="uid">Uid of the defib</param>
/// <param name="target">Uid of the target getting defibbed</param>
/// <param name="user">Uid of the entity using the defibrillator</param>
/// <param name="component">Defib component</param>
/// <returns>
/// Returns true if the defibrillation do-after started, otherwise false.
/// </returns>
public bool TryStartZap(EntityUid uid, EntityUid target, EntityUid user, DefibrillatorComponent? component = null)
{
if (!Resolve(uid, ref component))
@ -118,27 +141,44 @@ public sealed class DefibrillatorSystem : EntitySystem
_audio.PlayPvs(component.ChargeSound, uid);
return _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, component.DoAfterDuration, new DefibrillatorZapDoAfterEvent(),
uid, target, uid)
{
NeedHand = true,
BreakOnMove = !component.AllowDoAfterMovement
});
{
NeedHand = true,
BreakOnMove = !component.AllowDoAfterMovement
});
}
public void Zap(EntityUid uid, EntityUid target, EntityUid user, DefibrillatorComponent? component = null, MobStateComponent? mob = null, MobThresholdsComponent? thresholds = null)
/// <summary>
/// Tries to defibrillate the target with the given defibrillator.
/// </summary>
public void Zap(EntityUid uid, EntityUid target, EntityUid user, DefibrillatorComponent? component = null)
{
if (!Resolve(uid, ref component) || !Resolve(target, ref mob, ref thresholds, false))
if (!Resolve(uid, ref component))
return;
// clowns zap themselves
if (HasComp<ClumsyComponent>(user) && user != target)
{
Zap(uid, user, user, component);
return;
}
if (!_powerCell.TryUseActivatableCharge(uid, user: user))
return;
var selfEvent = new SelfBeforeDefibrillatorZapsEvent(user, uid, target);
RaiseLocalEvent(user, selfEvent);
target = selfEvent.DefibTarget;
// Ensure thet new target is still valid.
if (selfEvent.Cancelled || !CanZap(uid, target, user, component, true))
return;
var targetEvent = new TargetBeforeDefibrillatorZapsEvent(user, uid, target);
RaiseLocalEvent(target, targetEvent);
target = targetEvent.DefibTarget;
if (targetEvent.Cancelled || !CanZap(uid, target, user, component, true))
return;
if (!TryComp<MobStateComponent>(target, out var mob) ||
!TryComp<MobThresholdsComponent>(target, out var thresholds))
return;
_audio.PlayPvs(component.ZapSound, uid);
_electrocution.TryDoElectrocution(target, null, component.ZapDamage, component.WritheDuration, true, ignoreInsulation: true);
component.NextZapTime = _timing.CurTime + component.ZapDelay;

View file

@ -44,7 +44,7 @@ namespace Content.Server.Nutrition.EntitySystems
public (bool Success, bool Handled) TryUseUtensil(EntityUid user, EntityUid target, Entity<UtensilComponent> utensil)
{
if (!EntityManager.TryGetComponent(target, out FoodComponent? food))
return (false, true);
return (false, false);
//Prevents food usage with a wrong utensil
if ((food.Utensil & utensil.Comp.Types) == 0)

View file

@ -61,7 +61,6 @@ public sealed class KillPersonConditionSystem : EntitySystem
// no other humans to kill
var allHumans = GetAliveTargetsExcept(args.MindId);
if (allHumans.Count == 0)
{
args.Cancelled = true;
@ -86,14 +85,13 @@ public sealed class KillPersonConditionSystem : EntitySystem
// no other humans to kill
var allHumans = GetAliveTargetsExcept(args.MindId);
if (allHumans.Count == 0)
{
args.Cancelled = true;
return;
}
var allHeads = new List<EntityUid>();
var allHeads = new HashSet<Entity<MindComponent>>();
foreach (var person in allHumans)
{
if (TryComp<MindComponent>(person, out var mind) && mind.OwnedEntity is { } ent && HasComp<CommandStaffComponent>(ent))

View file

@ -314,6 +314,9 @@ public sealed class MoverController : SharedMoverController
var linearInput = Vector2.Zero;
var brakeInput = 0f;
var angularInput = 0f;
var linearCount = 0;
var brakeCount = 0;
var angularCount = 0;
foreach (var (pilotUid, pilot, _, consoleXform) in pilots)
{
@ -322,24 +325,27 @@ public sealed class MoverController : SharedMoverController
if (brakes > 0f)
{
brakeInput += brakes;
brakeCount++;
}
if (strafe.Length() > 0f)
{
var offsetRotation = consoleXform.LocalRotation;
linearInput += offsetRotation.RotateVec(strafe);
linearCount++;
}
if (rotation != 0f)
{
angularInput += rotation;
angularCount++;
}
}
var count = pilots.Count;
linearInput /= count;
angularInput /= count;
brakeInput /= count;
// Don't slow down the shuttle if there's someone just looking at the console
linearInput /= Math.Max(1, linearCount);
angularInput /= Math.Max(1, angularCount);
brakeInput /= Math.Max(1, brakeCount);
// Handle shuttle movement
if (brakeInput > 0f)

View file

@ -179,14 +179,14 @@ public sealed partial class StoreSystem
var ev = new SubtractCashEvent(buyer, currency, amount);
RaiseLocalEvent(buyer, ref ev);
// Sunrise-End
}
//spawn entity
if (listing.ProductEntity != null)
{
var product = Spawn(listing.ProductEntity, Transform(buyer).Coordinates);
// Sunrise-Start
var ev = new ItemPurchasedEvent(buyer);
RaiseLocalEvent(product, ref ev);
@ -269,6 +269,10 @@ public sealed partial class StoreSystem
RaiseLocalEvent(buyer, listing.ProductEvent);
}
if (listing.DisableRefund)
{
component.RefundAllowed = false;
}
//log dat shit.
_admin.Add(LogType.StorePurchase,

View file

@ -1,15 +1,12 @@
using System.Linq;
using System.Numerics;
using Content.Server.Cargo.Systems;
using Content.Server.Interaction;
using Content.Server.Power.EntitySystems;
using Content.Server.Stunnable;
using Content.Server.Weapons.Ranged.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Effects;
using Content.Shared.Interaction.Components;
using Content.Shared.Projectiles;
using Content.Shared.Weapons.Melee;
using Content.Shared.Weapons.Ranged;
@ -33,16 +30,13 @@ public sealed partial class GunSystem : SharedGunSystem
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly BatterySystem _battery = default!;
[Dependency] private readonly DamageExamineSystem _damageExamine = default!;
[Dependency] private readonly InteractionSystem _interaction = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly StaminaSystem _stamina = default!;
[Dependency] private readonly StunSystem _stun = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
private const float DamagePitchVariation = 0.05f;
public const float GunClumsyChance = 0.5f;
public override void Initialize()
{
@ -71,26 +65,14 @@ public sealed partial class GunSystem : SharedGunSystem
{
userImpulse = true;
// Try a clumsy roll
// TODO: Who put this here
if (TryComp<ClumsyComponent>(user, out var clumsy) && gun.ClumsyProof == false)
if (user != null)
{
for (var i = 0; i < ammo.Count; i++)
var selfEvent = new SelfBeforeGunShotEvent(user.Value, (gunUid, gun), ammo);
RaiseLocalEvent(user.Value, selfEvent);
if (selfEvent.Cancelled)
{
if (_interaction.TryRollClumsy(user.Value, GunClumsyChance, clumsy))
{
// Wound them
Damageable.TryChangeDamage(user, clumsy.ClumsyDamage, origin: user);
_stun.TryParalyze(user.Value, TimeSpan.FromSeconds(3f), true);
// Apply salt to the wound ("Honk!")
Audio.PlayPvs(new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg"), gunUid);
Audio.PlayPvs(clumsy.ClumsySound, gunUid);
PopupSystem.PopupEntity(Loc.GetString("gun-clumsy"), user.Value);
userImpulse = false;
return;
}
userImpulse = false;
return;
}
}

View file

@ -11,11 +11,6 @@ public sealed partial class HyposprayComponent : Component
[DataField]
public string SolutionName = "hypospray";
// TODO: This should be on clumsycomponent.
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public float ClumsyFailChance = 0.5f;
[DataField]
[ViewVariables(VVAccess.ReadWrite)]
public FixedPoint2 TransferAmount = FixedPoint2.New(5);

View file

@ -0,0 +1,38 @@
using Content.Shared.Inventory;
namespace Content.Shared.Chemistry.Hypospray.Events;
public abstract partial class BeforeHyposprayInjectsTargetEvent : CancellableEntityEventArgs, IInventoryRelayEvent
{
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
public EntityUid EntityUsingHypospray;
public readonly EntityUid Hypospray;
public EntityUid TargetGettingInjected;
public string? InjectMessageOverride;
public BeforeHyposprayInjectsTargetEvent(EntityUid user, EntityUid hypospray, EntityUid target)
{
EntityUsingHypospray = user;
Hypospray = hypospray;
TargetGettingInjected = target;
InjectMessageOverride = null;
}
}
/// <summary>
/// This event is raised on the user using the hypospray before the hypospray is injected.
/// The event is triggered on the user and all their clothing.
/// </summary>
public sealed class SelfBeforeHyposprayInjectsEvent : BeforeHyposprayInjectsTargetEvent
{
public SelfBeforeHyposprayInjectsEvent(EntityUid user, EntityUid hypospray, EntityUid target) : base(user, hypospray, target) { }
}
/// <summary>
/// This event is raised on the target before the hypospray is injected.
/// The event is triggered on the target itself and all its clothing.
/// </summary>
public sealed class TargetBeforeHyposprayInjectsEvent : BeforeHyposprayInjectsTargetEvent
{
public TargetBeforeHyposprayInjectsEvent (EntityUid user, EntityUid hypospray, EntityUid target) : base(user, hypospray, target) { }
}

View file

@ -1,5 +1,4 @@
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
namespace Content.Shared.Climbing.Components;
@ -8,39 +7,18 @@ namespace Content.Shared.Climbing.Components;
/// Makes entity do damage and stun entities with ClumsyComponent
/// upon DragDrop or Climb interactions.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(Systems.BonkSystem))]
[RegisterComponent, NetworkedComponent]
public sealed partial class BonkableComponent : Component
{
/// <summary>
/// Chance of bonk triggering if the user is clumsy.
/// How long to stun players on bonk, in seconds.
/// </summary>
[DataField("bonkClumsyChance")]
public float BonkClumsyChance = 0.5f;
[DataField]
public TimeSpan BonkTime = TimeSpan.FromSeconds(2);
/// <summary>
/// Sound to play when bonking.
/// How much damage to apply on bonk.
/// </summary>
/// <seealso cref="Bonk"/>
[DataField("bonkSound")]
public SoundSpecifier? BonkSound;
/// <summary>
/// How long to stun players on bonk, in seconds.
/// </summary>
/// <seealso cref="Bonk"/>
[DataField("bonkTime")]
public float BonkTime = 2;
/// <summary>
/// How much damage to apply on bonk.
/// </summary>
/// <seealso cref="Bonk"/>
[DataField("bonkDamage")]
[DataField]
public DamageSpecifier? BonkDamage;
/// <summary>
/// How long it takes to bonk.
/// </summary>
[DataField("bonkDelay")]
public float BonkDelay = 1.5f;
}

View file

@ -0,0 +1,36 @@
using Content.Shared.Inventory;
using Content.Shared.Climbing.Components;
namespace Content.Shared.Climbing.Events;
public abstract partial class BeforeClimbEvent : CancellableEntityEventArgs
{
public readonly EntityUid GettingPutOnTable;
public readonly EntityUid PuttingOnTable;
public readonly Entity<ClimbableComponent> BeingClimbedOn;
public BeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn)
{
GettingPutOnTable = gettingPutOntable;
PuttingOnTable = puttingOnTable;
BeingClimbedOn = beingClimbedOn;
}
}
/// <summary>
/// This event is raised on the the person either getting put on or going on the table.
/// The event is also called on their clothing as well.
/// </summary>
public sealed class SelfBeforeClimbEvent : BeforeClimbEvent, IInventoryRelayEvent
{
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
public SelfBeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn) : base(gettingPutOntable, puttingOnTable, beingClimbedOn) { }
}
/// <summary>
/// This event is raised on the thing being climbed on.
/// </summary>
public sealed class TargetBeforeClimbEvent : BeforeClimbEvent
{
public TargetBeforeClimbEvent(EntityUid gettingPutOntable, EntityUid puttingOnTable, Entity<ClimbableComponent> beingClimbedOn) : base(gettingPutOntable, puttingOnTable, beingClimbedOn) { }
}

View file

@ -1,130 +0,0 @@
using Content.Shared.CCVar;
using Content.Shared.Climbing.Components;
using Content.Shared.Climbing.Events;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
using Content.Shared.DragDrop;
using Content.Shared.Hands.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Components;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Player;
using Robust.Shared.Serialization;
namespace Content.Shared.Climbing.Systems;
public sealed partial class BonkSystem : EntitySystem
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BonkableComponent, BonkDoAfterEvent>(OnBonkDoAfter);
SubscribeLocalEvent<BonkableComponent, AttemptClimbEvent>(OnAttemptClimb);
}
private void OnBonkDoAfter(EntityUid uid, BonkableComponent component, BonkDoAfterEvent args)
{
if (args.Handled || args.Cancelled || args.Args.Used == null)
return;
TryBonk(args.Args.Used.Value, uid, component, source: args.Args.User);
args.Handled = true;
}
public bool TryBonk(EntityUid user, EntityUid bonkableUid, BonkableComponent? bonkableComponent = null, EntityUid? source = null)
{
if (!Resolve(bonkableUid, ref bonkableComponent, false))
return false;
// BONK!
var userName = Identity.Entity(user, EntityManager);
var bonkableName = Identity.Entity(bonkableUid, EntityManager);
if (user == source)
{
// Non-local, non-bonking players
var othersMessage = Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName));
// Local, bonking player
var selfMessage = Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName));
_popupSystem.PopupPredicted(selfMessage, othersMessage, user, user);
}
else if (source != null)
{
// Local, non-bonking player (dragger)
_popupSystem.PopupClient(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, source.Value);
// Non-local, non-bonking players
_popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-others", ("user", userName), ("bonkable", bonkableName)), user, Filter.Pvs(user).RemoveWhereAttachedEntity(e => e == user || e == source.Value), true);
// Non-local, bonking player
_popupSystem.PopupEntity(Loc.GetString("bonkable-success-message-user", ("user", userName), ("bonkable", bonkableName)), user, user);
}
if (source != null)
_audioSystem.PlayPredicted(bonkableComponent.BonkSound, bonkableUid, source);
else
_audioSystem.PlayPvs(bonkableComponent.BonkSound, bonkableUid);
_stunSystem.TryParalyze(user, TimeSpan.FromSeconds(bonkableComponent.BonkTime), true);
if (bonkableComponent.BonkDamage is { } bonkDmg)
_damageableSystem.TryChangeDamage(user, bonkDmg, true, origin: user);
return true;
}
private bool TryStartBonk(EntityUid uid, EntityUid user, EntityUid climber, BonkableComponent? bonkableComponent = null)
{
if (!Resolve(uid, ref bonkableComponent, false))
return false;
if (!HasComp<ClumsyComponent>(climber) || !HasComp<HandsComponent>(user))
return false;
if (!_cfg.GetCVar(CCVars.GameTableBonk))
{
// Not set to always bonk, try clumsy roll.
if (!_interactionSystem.TryRollClumsy(climber, bonkableComponent.BonkClumsyChance))
return false;
}
var doAfterArgs = new DoAfterArgs(EntityManager, user, bonkableComponent.BonkDelay, new BonkDoAfterEvent(), uid, target: uid, used: climber)
{
BreakOnMove = true,
BreakOnDamage = true,
DuplicateCondition = DuplicateConditions.SameTool | DuplicateConditions.SameTarget
};
return _doAfter.TryStartDoAfter(doAfterArgs);
}
private void OnAttemptClimb(EntityUid uid, BonkableComponent component, ref AttemptClimbEvent args)
{
if (args.Cancelled)
return;
if (TryStartBonk(uid, args.User, args.Climber, component))
args.Cancelled = true;
}
[Serializable, NetSerializable]
private sealed partial class BonkDoAfterEvent : SimpleDoAfterEvent
{
}
}

View file

@ -251,6 +251,18 @@ public sealed partial class ClimbSystem : VirtualController
if (!Resolve(climbable, ref comp, false))
return;
var selfEvent = new SelfBeforeClimbEvent(uid, user, (climbable, comp));
RaiseLocalEvent(uid, selfEvent);
if (selfEvent.Cancelled)
return;
var targetEvent = new TargetBeforeClimbEvent(uid, user, (climbable, comp));
RaiseLocalEvent(climbable, targetEvent);
if (targetEvent.Cancelled)
return;
if (!ReplaceFixtures(uid, climbing, fixtures))
return;

View file

@ -0,0 +1,61 @@
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
namespace Content.Shared.Clumsy;
/// <summary>
/// A simple clumsy tag-component.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ClumsyComponent : Component
{
// Standard options. Try to fit these in if you can!
/// <summary>
/// Sound to play when clumsy interactions fail.
/// </summary>
[DataField]
public SoundSpecifier ClumsySound = new SoundPathSpecifier("/Audio/Items/bikehorn.ogg");
/// <summary>
/// Default chance to fail a clumsy interaction.
/// If a system needs to use something else, add a new variable in the component, do not modify this percentage.
/// </summary>
[DataField, AutoNetworkedField]
public float ClumsyDefaultCheck = 0.5f;
/// <summary>
/// Default stun time.
/// If a system needs to use something else, add a new variable in the component, do not modify this number.
/// </summary>
[DataField, AutoNetworkedField]
public TimeSpan ClumsyDefaultStunTime = TimeSpan.FromSeconds(2.5);
// Specific options
/// <summary>
/// Sound to play after hitting your head on a table. Ouch!
/// </summary>
[DataField]
public SoundCollectionSpecifier TableBonkSound = new SoundCollectionSpecifier("TrayHit");
/// <summary>
/// Stun time after failing to shoot a gun.
/// </summary>
[DataField, AutoNetworkedField]
public TimeSpan GunShootFailStunTime = TimeSpan.FromSeconds(3);
/// <summary>
/// Stun time after failing to shoot a gun.
/// </summary>
[DataField, AutoNetworkedField]
public DamageSpecifier? GunShootFailDamage;
/// <summary>
/// Noise to play after failing to shoot a gun. Boom!
/// </summary>
[DataField]
public SoundSpecifier GunShootFailSound = new SoundPathSpecifier("/Audio/Weapons/Guns/Gunshots/bang.ogg");
}

View file

@ -0,0 +1,146 @@
using Content.Shared.CCVar;
using Content.Shared.Chemistry.Hypospray.Events;
using Content.Shared.Climbing.Components;
using Content.Shared.Climbing.Events;
using Content.Shared.Damage;
using Content.Shared.IdentityManagement;
using Content.Shared.Medical;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Content.Shared.Weapons.Ranged.Events;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Random;
using Robust.Shared.Timing;
namespace Content.Shared.Clumsy;
public sealed class ClumsySystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
public override void Initialize()
{
SubscribeLocalEvent<ClumsyComponent, SelfBeforeHyposprayInjectsEvent>(BeforeHyposprayEvent);
SubscribeLocalEvent<ClumsyComponent, SelfBeforeDefibrillatorZapsEvent>(BeforeDefibrillatorZapsEvent);
SubscribeLocalEvent<ClumsyComponent, SelfBeforeGunShotEvent>(BeforeGunShotEvent);
SubscribeLocalEvent<ClumsyComponent, SelfBeforeClimbEvent>(OnBeforeClimbEvent);
}
// If you add more clumsy interactions add them in this section!
#region Clumsy interaction events
private void BeforeHyposprayEvent(Entity<ClumsyComponent> ent, ref SelfBeforeHyposprayInjectsEvent args)
{
// Clumsy people sometimes inject themselves! Apparently syringes are clumsy proof...
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
return;
args.TargetGettingInjected = args.EntityUsingHypospray;
args.InjectMessageOverride = "hypospray-component-inject-self-clumsy-message";
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
}
private void BeforeDefibrillatorZapsEvent(Entity<ClumsyComponent> ent, ref SelfBeforeDefibrillatorZapsEvent args)
{
// Clumsy people sometimes defib themselves!
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
return;
args.DefibTarget = args.EntityUsingDefib;
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
}
private void BeforeGunShotEvent(Entity<ClumsyComponent> ent, ref SelfBeforeGunShotEvent args)
{
// Clumsy people sometimes can't shoot :(
if (args.Gun.Comp.ClumsyProof)
return;
if (!_random.Prob(ent.Comp.ClumsyDefaultCheck))
return;
if (ent.Comp.GunShootFailDamage != null)
_damageable.TryChangeDamage(ent, ent.Comp.GunShootFailDamage, origin: ent);
_stun.TryParalyze(ent, ent.Comp.GunShootFailStunTime, true);
// Apply salt to the wound ("Honk!") (No idea what this comment means)
_audio.PlayPvs(ent.Comp.GunShootFailSound, ent);
_audio.PlayPvs(ent.Comp.ClumsySound, ent);
_popup.PopupEntity(Loc.GetString("gun-clumsy"), ent, ent);
args.Cancel();
}
private void OnBeforeClimbEvent(Entity<ClumsyComponent> ent, ref SelfBeforeClimbEvent args)
{
// This event is called in shared, thats why it has all the extra prediction stuff.
var rand = new System.Random((int)_timing.CurTick.Value);
// If someone is putting you on the table, always get past the guard.
if (!_cfg.GetCVar(CCVars.GameTableBonk) && args.PuttingOnTable == ent.Owner && !rand.Prob(ent.Comp.ClumsyDefaultCheck))
return;
HitHeadClumsy(ent, args.BeingClimbedOn);
_audio.PlayPredicted(ent.Comp.ClumsySound, ent, ent);
_audio.PlayPredicted(ent.Comp.TableBonkSound, ent, ent);
var gettingPutOnTableName = Identity.Entity(args.GettingPutOnTable, EntityManager);
var puttingOnTableName = Identity.Entity(args.PuttingOnTable, EntityManager);
if (args.PuttingOnTable == ent.Owner)
{
// You are slamming yourself onto the table.
_popup.PopupPredicted(
Loc.GetString("bonkable-success-message-user", ("bonkable", args.BeingClimbedOn)),
Loc.GetString("bonkable-success-message-others", ("victim", gettingPutOnTableName), ("bonkable", args.BeingClimbedOn)),
ent,
ent);
}
else
{
// Someone else slamed you onto the table.
// This is only run in server so you need to use popup entity.
_popup.PopupPredicted(
Loc.GetString("forced-bonkable-success-message",
("bonker", puttingOnTableName),
("victim", gettingPutOnTableName),
("bonkable", args.BeingClimbedOn)),
ent,
null);
}
args.Cancel();
}
#endregion
#region Helper functions
/// <summary>
/// "Hits" an entites head against the given table.
/// </summary>
// Oh this fucntion is public le- NO!! This is only public for the one admin command if you use this anywhere else I will cry.
public void HitHeadClumsy(Entity<ClumsyComponent> target, EntityUid table)
{
var stunTime = target.Comp.ClumsyDefaultStunTime;
if (TryComp<BonkableComponent>(table, out var bonkComp))
{
stunTime = bonkComp.BonkTime;
if (bonkComp.BonkDamage != null)
_damageable.TryChangeDamage(target, bonkComp.BonkDamage, true);
}
_stun.TryParalyze(target, stunTime, true);
}
#endregion
}

View file

@ -3,12 +3,23 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Crayon
{
/// <summary>
/// Component holding the state of a crayon-like component
/// </summary>
[NetworkedComponent, ComponentProtoName("Crayon"), Access(typeof(SharedCrayonSystem))]
public abstract partial class SharedCrayonComponent : Component
{
/// <summary>
/// The ID of currently selected decal prototype that will be placed when the crayon is used
/// </summary>
public string SelectedState { get; set; } = string.Empty;
[DataField("color")] public Color Color;
/// <summary>
/// Color with which the crayon will draw
/// </summary>
[DataField("color")]
public Color Color;
[Serializable, NetSerializable]
public enum CrayonUiKey : byte
@ -17,6 +28,9 @@ namespace Content.Shared.Crayon
}
}
/// <summary>
/// Used by the client to notify the server about the selected decal ID
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonSelectMessage : BoundUserInterfaceMessage
{
@ -27,6 +41,9 @@ namespace Content.Shared.Crayon
}
}
/// <summary>
/// Sets the color of the crayon, used by Rainbow Crayon
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonColorMessage : BoundUserInterfaceMessage
{
@ -37,13 +54,25 @@ namespace Content.Shared.Crayon
}
}
/// <summary>
/// Server to CLIENT. Notifies the BUI that a decal with given ID has been drawn.
/// Allows the client UI to advance forward in the client-only ephemeral queue,
/// preventing the crayon from becoming a magic text storage device.
/// </summary>
[Serializable, NetSerializable]
public enum CrayonVisuals
public sealed class CrayonUsedMessage : BoundUserInterfaceMessage
{
State,
Color
public readonly string DrawnDecal;
public CrayonUsedMessage(string drawn)
{
DrawnDecal = drawn;
}
}
/// <summary>
/// Component state, describes how many charges are left in the crayon in the near-hand UI
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonComponentState : ComponentState
{
@ -60,10 +89,17 @@ namespace Content.Shared.Crayon
Capacity = capacity;
}
}
/// <summary>
/// The state of the crayon UI as sent by the server
/// </summary>
[Serializable, NetSerializable]
public sealed class CrayonBoundUserInterfaceState : BoundUserInterfaceState
{
public string Selected;
/// <summary>
/// Whether or not the color can be selected
/// </summary>
public bool SelectableColor;
public Color Color;

View file

@ -1,24 +0,0 @@
using Content.Shared.Damage;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
namespace Content.Shared.Interaction.Components;
/// <summary>
/// A simple clumsy tag-component.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class ClumsyComponent : Component
{
/// <summary>
/// Damage dealt to a clumsy character when they try to fire a gun.
/// </summary>
[DataField(required: true), AutoNetworkedField]
public DamageSpecifier ClumsyDamage = default!;
/// <summary>
/// Sound to play when clumsy interactions fail.
/// </summary>
[DataField]
public SoundSpecifier ClumsySound = new SoundPathSpecifier("/Audio/Items/bikehorn.ogg");
}

View file

@ -1,26 +0,0 @@
using Content.Shared.Interaction.Components;
using Robust.Shared.Random;
namespace Content.Shared.Interaction
{
public partial class SharedInteractionSystem
{
public bool RollClumsy(ClumsyComponent component, float chance)
{
return component.Running && _random.Prob(chance);
}
/// <summary>
/// Rolls a probability chance for a "bad action" if the target entity is clumsy.
/// </summary>
/// <param name="entity">The entity that the clumsy check is happening for.</param>
/// <param name="chance">
/// The chance that a "bad action" happens if the user is clumsy, between 0 and 1 inclusive.
/// </param>
/// <returns>True if a "bad action" happened, false if the normal action should happen.</returns>
public bool TryRollClumsy(EntityUid entity, float chance, ClumsyComponent? component = null)
{
return Resolve(entity, ref component, false) && RollClumsy(component, chance);
}
}
}

View file

@ -1,5 +1,7 @@
using Content.Shared._Sunrise.Eye.NightVision.Components;
using Content.Shared.Chat;
using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Hypospray.Events;
using Content.Shared.Climbing.Events;
using Content.Shared.Damage;
using Content.Shared.Electrocution;
using Content.Shared.Explosion;
@ -16,7 +18,8 @@ using Content.Shared.Slippery;
using Content.Shared.Strip.Components;
using Content.Shared.Temperature;
using Content.Shared.Verbs;
using Content.Shared.Chat;
using Content.Shared.Weapons.Ranged.Events;
using Content.Shared._Sunrise.Eye.NightVision.Components;
namespace Content.Shared.Inventory;
@ -34,6 +37,10 @@ public partial class InventorySystem
SubscribeLocalEvent<InventoryComponent, GetDefaultRadioChannelEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, RefreshNameModifiersEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, TransformSpeakerNameEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SelfBeforeHyposprayInjectsEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, TargetBeforeHyposprayInjectsEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SelfBeforeGunShotEvent>(RelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, SelfBeforeClimbEvent>(RelayInventoryEvent);
// by-ref events
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);

View file

@ -0,0 +1,23 @@
using Content.Shared.Actions;
using Content.Shared.Storage;
using Robust.Shared.Audio;
namespace Content.Shared.Magic.Events;
public sealed partial class RandomGlobalSpawnSpellEvent : InstantActionEvent, ISpeakSpell
{
/// <summary>
/// The list of prototypes this spell can spawn, will select one randomly
/// </summary>
[DataField]
public List<EntitySpawnEntry> Spawns = new();
/// <summary>
/// Sound that will play globally when cast
/// </summary>
[DataField]
public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Magic/staff_animation.ogg");
[DataField]
public string? Speech { get; private set; }
}

View file

@ -1,4 +1,4 @@
using System.Numerics;
using System.Numerics;
using Content.Shared.Actions;
using Content.Shared.Body.Components;
using Content.Shared.Body.Systems;
@ -7,12 +7,17 @@ using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid;
using Content.Shared.Interaction;
using Content.Shared.Inventory;
using Content.Shared.Lock;
using Content.Shared.Magic.Components;
using Content.Shared.Magic.Events;
using Content.Shared.Maps;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Speech.Muting;
@ -20,6 +25,7 @@ using Content.Shared.Storage;
using Content.Shared.Tag;
using Content.Shared.Weapons.Ranged.Components;
using Content.Shared.Weapons.Ranged.Systems;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
@ -53,6 +59,9 @@ public abstract class SharedMagicSystem : EntitySystem
[Dependency] private readonly LockSystem _lock = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly TagSystem _tag = default!;
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
public override void Initialize()
{
@ -67,6 +76,7 @@ public abstract class SharedMagicSystem : EntitySystem
SubscribeLocalEvent<SmiteSpellEvent>(OnSmiteSpell);
SubscribeLocalEvent<KnockSpellEvent>(OnKnockSpell);
SubscribeLocalEvent<ChargeSpellEvent>(OnChargeSpell);
SubscribeLocalEvent<RandomGlobalSpawnSpellEvent>(OnRandomGlobalSpawnSpell);
// Spell wishlist
// A wishlish of spells that I'd like to implement or planning on implementing in a future PR
@ -501,6 +511,37 @@ public abstract class SharedMagicSystem : EntitySystem
_gunSystem.UpdateBasicEntityAmmoCount(wand.Value, basicAmmoComp.Count.Value + ev.Charge, basicAmmoComp);
}
// End Charge Spells
#endregion
#region Global Spells
private void OnRandomGlobalSpawnSpell(RandomGlobalSpawnSpellEvent ev)
{
if (!_net.IsServer || ev.Handled || !PassesSpellPrerequisites(ev.Action, ev.Performer) || ev.Spawns is not { } spawns)
return;
ev.Handled = true;
Speak(ev);
var allHumans = _mind.GetAliveHumans();
foreach (var human in allHumans)
{
if (!human.Comp.OwnedEntity.HasValue)
continue;
var ent = human.Comp.OwnedEntity.Value;
var mapCoords = _transform.GetMapCoordinates(ent);
foreach (var spawn in EntitySpawnCollection.GetSpawns(spawns, _random))
{
var spawned = Spawn(spawn, mapCoords);
_hands.PickupOrDrop(ent, spawned);
}
}
_audio.PlayGlobal(ev.Sound, ev.Performer);
}
#endregion
// End Spells
#endregion

View file

@ -0,0 +1,39 @@
using Content.Shared.Inventory;
namespace Content.Shared.Medical;
[ByRefEvent]
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);
public abstract class BeforeDefibrillatorZapsEvent : CancellableEntityEventArgs, IInventoryRelayEvent
{
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
public EntityUid EntityUsingDefib;
public readonly EntityUid Defib;
public EntityUid DefibTarget;
public BeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibTarget)
{
EntityUsingDefib = entityUsingDefib;
Defib = defib;
DefibTarget = defibTarget;
}
}
/// <summary>
/// This event is raised on the user using the defibrillator before is actually zaps someone.
/// The event is triggered on the user and all their clothing.
/// </summary>
public sealed class SelfBeforeDefibrillatorZapsEvent : BeforeDefibrillatorZapsEvent
{
public SelfBeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibtarget) : base(entityUsingDefib, defib, defibtarget) { }
}
/// <summary>
/// This event is raised on the target before it gets zapped with the defibrillator.
/// The event is triggered on the target itself and all its clothing.
/// </summary>
public sealed class TargetBeforeDefibrillatorZapsEvent : BeforeDefibrillatorZapsEvent
{
public TargetBeforeDefibrillatorZapsEvent(EntityUid entityUsingDefib, EntityUid defib, EntityUid defibtarget) : base(entityUsingDefib, defib, defibtarget) { }
}

View file

@ -1,4 +0,0 @@
namespace Content.Shared.Medical;
[ByRefEvent]
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);

View file

@ -532,22 +532,19 @@ public abstract class SharedMindSystem : EntitySystem
/// <summary>
/// Returns a list of every living humanoid player's minds, except for a single one which is exluded.
/// </summary>
public List<EntityUid> GetAliveHumansExcept(EntityUid exclude)
public HashSet<Entity<MindComponent>> GetAliveHumans(EntityUid? exclude = null)
{
var mindQuery = EntityQuery<MindComponent>();
var allHumans = new List<EntityUid>();
var allHumans = new HashSet<Entity<MindComponent>>();
// HumanoidAppearanceComponent is used to prevent mice, pAIs, etc from being chosen
var query = EntityQueryEnumerator<MindContainerComponent, MobStateComponent, HumanoidAppearanceComponent>();
while (query.MoveNext(out var uid, out var mc, out var mobState, out _))
var query = EntityQueryEnumerator<MobStateComponent, HumanoidAppearanceComponent>();
while (query.MoveNext(out var uid, out var mobState, out _))
{
// the player needs to have a mind and not be the excluded one
if (mc.Mind == null || mc.Mind == exclude)
// the player needs to have a mind and not be the excluded one +
// the player has to be alive
if (!TryGetMind(uid, out var mind, out var mindComp) || mind == exclude || !_mobState.IsAlive(uid, mobState))
continue;
// the player has to be alive
if (_mobState.IsAlive(uid, mobState))
allHumans.Add(mc.Mind.Value);
allHumans.Add(new Entity<MindComponent>(mind, mindComp));
}
return allHumans;

View file

@ -40,7 +40,8 @@ public partial class ListingData : IEquatable<ListingData>
other.Categories,
other.OriginalCost,
other.RestockTime,
other.DiscountDownTo
other.DiscountDownTo,
other.DisableRefund
)
{
@ -64,7 +65,8 @@ public partial class ListingData : IEquatable<ListingData>
HashSet<ProtoId<StoreCategoryPrototype>> categories,
IReadOnlyDictionary<ProtoId<CurrencyPrototype>, FixedPoint2> originalCost,
TimeSpan restockTime,
Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> dataDiscountDownTo
Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> dataDiscountDownTo,
bool disableRefund
)
{
Name = name;
@ -85,6 +87,7 @@ public partial class ListingData : IEquatable<ListingData>
OriginalCost = originalCost;
RestockTime = restockTime;
DiscountDownTo = new Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2>(dataDiscountDownTo);
DisableRefund = disableRefund;
}
[ViewVariables]
@ -195,6 +198,12 @@ public partial class ListingData : IEquatable<ListingData>
[DataField]
public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> DiscountDownTo = new();
/// <summary>
/// Whether or not to disable refunding for the store when the listing is purchased from it.
/// </summary>
[DataField]
public bool DisableRefund = false;
public bool Equals(ListingData? listing)
{
if (listing == null)
@ -288,7 +297,8 @@ public sealed partial class ListingDataWithCostModifiers : ListingData
listingData.Categories,
listingData.OriginalCost,
listingData.RestockTime,
listingData.DiscountDownTo
listingData.DiscountDownTo,
listingData.DisableRefund
)
{
}

View file

@ -0,0 +1,20 @@
using Content.Shared.Inventory;
using Content.Shared.Weapons.Ranged.Components;
namespace Content.Shared.Weapons.Ranged.Events;
/// <summary>
/// This event is triggered on an entity right before they shoot a gun.
/// </summary>
public sealed partial class SelfBeforeGunShotEvent : CancellableEntityEventArgs, IInventoryRelayEvent
{
public SlotFlags TargetSlots { get; } = SlotFlags.WITHOUT_POCKET;
public readonly EntityUid Shooter;
public readonly Entity<GunComponent> Gun;
public readonly List<(EntityUid? Entity, IShootable Shootable)> Ammo;
public SelfBeforeGunShotEvent(EntityUid shooter, Entity<GunComponent> gun, List<(EntityUid? Entity, IShootable Shootable)> ammo)
{
Shooter = shooter;
Gun = gun;
Ammo = ammo;
}
}

View file

@ -1,120 +1,4 @@
Entries:
- author: Erisfiregamer1
changes:
- message: New chemical, Sedin. It restores seeds on plants 20% of the time with
other adverse effects included.
type: Add
id: 7111
time: '2024-08-15T00:38:24.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/27110
- author: PoorMansDreams
changes:
- message: Added Star sticker in loadouts for Secoffs
type: Add
id: 7112
time: '2024-08-15T01:50:55.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/29767
- author: FATFSAAM2
changes:
- message: added 7 new figurine voice lines.
type: Add
- message: changed a hos figurine voice line to not include a typo.
type: Fix
id: 7113
time: '2024-08-15T12:34:41.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30865
- author: to4no_fix
changes:
- message: Added a new electropack that shocks when a trigger is triggered
type: Add
- message: Added a new shock collar that shocks when a trigger is triggered
type: Add
- message: Two shock collars and two remote signallers added to the warden's locker
type: Add
- message: Shock collar added as a new target for the thief
type: Add
- message: A new Special Means technology has been added to the Arsenal research
branch at the 1st research level. Its research opens up the possibility of producing
electropacks at security techfab. The cost of technology research is 5000
type: Add
id: 7114
time: '2024-08-15T14:30:39.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30529
- author: Mervill
changes:
- message: The Gas Analyzer won't spuriously shut down for seemly no reason.
type: Tweak
- message: The Gas Analyzer will always switch to the device tab when a new object
is scanned.
type: Tweak
- message: The Gas Analyzer's interaction range is now equal to the standard interaction
range
type: Fix
- message: Clicking the Gas Analyzer when it's in your hand has proper enable/disable
behavior.
type: Fix
id: 7115
time: '2024-08-15T14:45:13.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30763
- author: Nimfar11
changes:
- message: Adds a gold toilet
type: Add
- message: Adds a target for the Thief to steal the golden toilet
type: Add
- message: Corrected the sprite image for the normal toilet.
type: Fix
id: 7116
time: '2024-08-15T19:23:59.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31049
- author: themias
changes:
- message: Raw meat cutlets can be cooked on a grill
type: Tweak
id: 7117
time: '2024-08-15T19:30:09.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31048
- author: IProduceWidgets
changes:
- message: Meteor dust should more consistently happen instead of meteors.
type: Tweak
id: 7118
time: '2024-08-15T19:33:17.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31018
- author: Emisse
changes:
- message: Atlas, Cluster, Europa, & Saltern removed from the game.
type: Remove
id: 7119
time: '2024-08-15T21:10:07.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31058
- author: Emisse
changes:
- message: Origin removed from the game.
type: Remove
id: 7120
time: '2024-08-15T22:22:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31059
- author: Psychpsyo
changes:
- message: You can now be German on ze space station! (added German accent)
type: Add
id: 7121
time: '2024-08-15T23:30:21.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30541
- author: EmoGarbage404
changes:
- message: Reduced the amount of ore on the mining asteroid and expeditions.
type: Tweak
- message: Increased the amount of ore on magnet asteroids.
type: Tweak
- message: Each piece of ore now only has enough material to create 1 sheet.
type: Tweak
- message: The salvage magnet now accurately reports the contents of asteroids.
type: Fix
id: 7122
time: '2024-08-16T01:43:54.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/30920
- author: metalgearsloth
changes:
- message: Fix mains light on wires not being lit.
@ -3945,3 +3829,92 @@
id: 7610
time: '2024-11-15T06:54:53.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33315
- author: RedBookcase
changes:
- message: Mixing up a Snow White no longer creates extra liquid out of thin air.
type: Fix
id: 7611
time: '2024-11-15T20:52:19.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33331
- author: lzk228
changes:
- message: Added 10 seconds delay to Succumb action
type: Add
id: 7612
time: '2024-11-15T21:21:08.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32985
- author: Beck Thompson
changes:
- message: Minor tweaks to clumsiness. Some of the timings and or noises have been
changed slightly!
type: Tweak
id: 7613
time: '2024-11-15T23:46:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31147
- author: SaphireLattice
changes:
- message: Crayon UI now has categories and queue
type: Add
id: 7614
time: '2024-11-16T03:25:06.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33101
- author: Southbridge
changes:
- message: The BRB sign is now included in the Bureaucracy Crate
type: Add
id: 7615
time: '2024-11-16T03:26:48.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33341
- author: SaphireLattice
changes:
- message: Utensils can finally go into disposals
type: Fix
id: 7616
time: '2024-11-16T03:39:19.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33326
- author: K-Dynamic
changes:
- message: Solar assembly crate now comes with 10 flatpacks and 20 glass to make
expansion and repairs easier, as well as increasing in price from 525 to 1250
spesos.
type: Tweak
id: 7617
time: '2024-11-16T04:30:48.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33019
- author: Aquif
changes:
- message: There is now a button to view your admin remarks in the character editor,
right next to the stats button.
type: Tweak
id: 7618
time: '2024-11-16T05:09:29.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/31761
- author: SpaceRox1244
changes:
- message: Closets and lockers now have visuals for being labeled with papers.
type: Add
id: 7619
time: '2024-11-17T03:27:29.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33318
- author: Ubaser
changes:
- message: You can now craft dim light bulbs at an autolathe.
type: Add
id: 7620
time: '2024-11-18T06:32:08.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33383
- author: Ilya246
changes:
- message: Multiple people using one shuttle console will no longer cause the shuttle
to slow down.
type: Fix
id: 7621
time: '2024-11-19T02:59:42.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/32381
- author: ScarKy0
changes:
- message: Secret doors no longer tell you if they're welded shut on examine.
type: Tweak
id: 7622
time: '2024-11-19T05:07:02.0000000+00:00'
url: https://github.com/space-wizards/space-station-14/pull/33365

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,4 @@
bonkable-success-message-others = { CAPITALIZE(THE($user)) } bonks { POSS-ADJ($user) } head against { THE($bonkable) }
bonkable-success-message-user = You bonk your head against { THE($bonkable) }
forced-bonkable-success-message = { CAPITALIZE($bonker) } bonks {$victim}s head against { THE($bonkable) }!
bonkable-success-message-user = You bonk your head against { THE($bonkable) }!
bonkable-success-message-others = {$victim} bonks their head against { THE($bonkable) }!

View file

@ -8,3 +8,10 @@ crayon-interact-invalid-location = Can't reach there!
## UI
crayon-window-title = Crayon
crayon-window-placeholder = Search, or queue a comma-separated list of names
crayon-category-1-brushes = Brushes
crayon-category-2-alphanum = Numbers and letters
crayon-category-3-symbols = Symbols
crayon-category-4-info = Signs
crayon-category-5-graffiti = Graffiti
crayon-category-random = Random

View file

@ -1,4 +1,4 @@
ui-lobby-title = Lobby
ui-lobby-title = Lobby
ui-lobby-ahelp-button = AHelp
ui-lobby-options-button = Options
ui-lobby-leave-button = Leave

View file

@ -1,5 +1,7 @@
action-speech-spell-forcewall = TARCOL MINTI ZHERI
action-speech-spell-forcewall = TARCOL MINTI ZHERI
action-speech-spell-knock = AULIE OXIN FIERA
action-speech-spell-smite = EI NATH!
action-speech-spell-summon-magicarp = AIE KHUSE EU
action-speech-spell-fireball = ONI'SOMA!
action-speech-spell-summon-guns = YOR'NEE VES-KORFA
action-speech-spell-summon-magic = RYGOIN FEMA-VERECO

View file

@ -1,4 +1,5 @@
character-setup-gui-character-setup-label = Character setup
character-setup-gui-character-setup-adminremarks-button = Admin Remarks
character-setup-gui-character-setup-stats-button = Stats
character-setup-gui-character-setup-rules-button = Rules
character-setup-gui-character-setup-close-button = Close
@ -10,4 +11,4 @@ character-setup-gui-character-picker-button-confirm-delete-button = Confirm
character-setup-gui-save-panel-title = Unsaved character changes
character-setup-gui-save-panel-save = Save
character-setup-gui-save-panel-nosave = Don't save
character-setup-gui-save-panel-cancel = Cancel
character-setup-gui-save-panel-cancel = Cancel

View file

@ -1,4 +1,4 @@
# Spells
# Spells
spellbook-fireball-name = Fireball
spellbook-fireball-desc = Get most crew exploding with rage when they see this fireball heading toward them!
@ -33,6 +33,12 @@ spellbook-wand-polymorph-carp-description = For when you need a carp filet quick
spellbook-event-summon-ghosts-name = Summon Ghosts
spellbook-event-summon-ghosts-description = Who ya gonna call?
spellbook-event-summon-guns-name = Summon Guns
spellbook-event-summon-guns-description = AK47s for everyone! Places a random gun in front of everybody. Disables refunds when bought!
spellbook-event-summon-magic-name = Summon Magic
spellbook-event-summon-magic-description = Places a random magical item in front of everybody. Nothing could go wrong! Disables refunds when bought!
# Upgrades
spellbook-upgrade-fireball-name = Upgrade Fireball
spellbook-upgrade-fireball-description = Upgrades Fireball to a maximum of level 3!

File diff suppressed because it is too large Load diff

View file

@ -665,7 +665,6 @@ entities:
1325: 54,12
1326: 53,12
1327: 52,12
1374: 6,-20
1486: 30,-23
1516: -48,16
1517: -47,17
@ -733,6 +732,7 @@ entities:
3954: 13,-14
3979: -56,13
3980: -54,13
4774: 6,-20
- node:
cleanable: True
color: '#FFFFFFFF'
@ -2224,6 +2224,22 @@ entities:
3652: 23,-38
3653: 23,-37
3654: 23,-39
- node:
color: '#DE3A3A96'
id: CheckerNESW
decals:
4750: 6,-22
4751: 6,-21
4752: 6,-20
4753: 7,-20
4754: 8,-20
4755: 9,-20
4756: 9,-21
4757: 9,-22
4758: 8,-22
4759: 7,-22
4760: 7,-21
4761: 8,-21
- node:
color: '#334E6DC8'
id: CheckerNWSE
@ -2236,6 +2252,22 @@ entities:
620: -68,17
621: -69,17
622: -62,17
- node:
color: '#43990996'
id: CheckerNWSE
decals:
4762: 6,-22
4763: 6,-21
4764: 6,-20
4765: 7,-20
4766: 7,-21
4767: 7,-22
4768: 8,-22
4769: 8,-21
4770: 8,-20
4771: 9,-20
4772: 9,-21
4773: 9,-22
- node:
color: '#52B4E996'
id: CheckerNWSE
@ -2833,6 +2865,7 @@ entities:
3856: -11,-14
3947: 13,-14
3948: 12,-11
4778: 9,-22
- node:
color: '#FFFFFFFF'
id: DirtLight
@ -2955,11 +2988,6 @@ entities:
830: -8,-25
835: -4,-24
836: -1,-25
837: 7,-21
889: 7,-20
890: 8,-20
891: 9,-20
892: 9,-21
893: 10,-23
895: -6,-23
896: -25,-23
@ -2996,7 +3024,6 @@ entities:
1172: 5,8
1173: -7,9
1174: -8,8
1213: 7,-22
1214: 5,-23
1215: 4,-23
1216: 7,-24
@ -3190,6 +3217,9 @@ entities:
4668: 16,-25
4669: 13,-25
4670: 12,-23
4775: 6,-22
4776: 9,-21
4777: 9,-20
- node:
angle: 3.141592653589793 rad
color: '#FFFFFFFF'
@ -3243,7 +3273,6 @@ entities:
690: -16,6
833: -3,-25
834: -6,-25
1212: 6,-22
1985: -40,-8
2215: 0,13
2216: -1,14
@ -3278,6 +3307,7 @@ entities:
4630: -28,-19
4658: 17,-16
4659: 17,-15
4779: 6,-20
- node:
angle: 3.141592653589793 rad
color: '#FFFFFFFF'
@ -4057,6 +4087,23 @@ entities:
886: -1,-12
887: -1,-11
888: -1,-10
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale
decals:
4685: 6,-23
4686: 7,-23
4687: 8,-23
4688: 9,-23
4689: 5,-23
4690: 4,-23
4691: 3,-23
4692: 10,-23
4693: 11,-23
4694: 12,-23
4695: 13,-23
4696: 14,-23
4697: 15,-23
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale
@ -4173,12 +4220,6 @@ entities:
1183: -17,19
1184: -17,20
1185: -17,21
1364: 6,-22
1365: 6,-21
1366: 6,-20
1367: 7,-20
1368: 8,-20
1369: 9,-20
1370: 6,-23
1371: 5,-23
1372: 4,-23
@ -4352,6 +4393,18 @@ entities:
662: -17,-6
698: -18,1
699: -18,2
4813: 29,-23
4814: 28,-23
4815: 27,-23
4816: 26,-23
4817: 25,-23
4818: 24,-23
4819: 23,-23
4820: 22,-23
4821: 21,-23
4822: 20,-23
4823: 19,-23
4824: 18,-23
- node:
color: '#EFCC4196'
id: QuarterTileOverlayGreyscale
@ -4395,6 +4448,26 @@ entities:
3886: -29,30
3887: -30,30
3888: -31,30
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale180
decals:
4718: 17,-25
4720: 19,-25
4721: 20,-25
4723: 21,-25
4724: 22,-25
4725: 23,-25
4726: 24,-25
4727: 25,-25
4728: 26,-25
4729: 27,-25
4730: 28,-25
4731: 29,-25
4732: 30,-25
4733: 31,-25
4734: 32,-25
4826: 18,-25
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale180
@ -4482,9 +4555,6 @@ entities:
1448: -32,7
1449: -33,7
1450: -34,7
1465: 9,-20
1466: 9,-21
1467: 9,-22
1494: -14,-2
1495: -15,-2
1496: -15,-3
@ -4598,6 +4668,16 @@ entities:
4470: 36,50
4521: 44,20
4522: 45,20
- node:
color: '#DE3A3A96'
id: QuarterTileOverlayGreyscale180
decals:
4792: 14,-25
4793: 13,-25
4794: 12,-25
4795: 11,-25
4796: 10,-25
4797: 9,-25
- node:
color: '#EFB3414A'
id: QuarterTileOverlayGreyscale180
@ -4631,6 +4711,17 @@ entities:
610: -74,16
611: -73,16
612: -72,16
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale270
decals:
4711: 9,-25
4712: 10,-25
4713: 11,-25
4714: 12,-25
4715: 13,-25
4716: 14,-25
4717: 15,-25
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale270
@ -4855,6 +4946,21 @@ entities:
decals:
696: -18,-1
697: -18,0
4798: 18,-25
4799: 19,-25
4800: 20,-25
4801: 21,-25
4802: 22,-25
4803: 23,-25
4804: 24,-25
4805: 25,-25
4806: 26,-25
4807: 27,-25
4808: 28,-25
4809: 29,-25
4810: 30,-25
4811: 31,-25
4812: 32,-25
- node:
color: '#EFB3414A'
id: QuarterTileOverlayGreyscale270
@ -4899,6 +5005,23 @@ entities:
874: 1,-19
875: 1,-20
876: 1,-21
- node:
color: '#43990996'
id: QuarterTileOverlayGreyscale90
decals:
4698: 17,-23
4700: 19,-23
4701: 20,-23
4702: 21,-23
4703: 22,-23
4704: 23,-23
4705: 24,-23
4706: 25,-23
4707: 26,-23
4708: 27,-23
4709: 28,-23
4710: 29,-23
4825: 18,-23
- node:
color: '#52B4E92E'
id: QuarterTileOverlayGreyscale90
@ -5041,7 +5164,6 @@ entities:
1482: 21,-23
1483: 20,-23
1484: 19,-23
1485: 18,-23
1491: -15,1
1492: -15,0
1493: -14,0
@ -5187,6 +5309,18 @@ entities:
1635: -8,-15
1636: -8,-14
1637: -8,-13
4780: 3,-23
4781: 4,-23
4782: 5,-23
4783: 6,-23
4784: 7,-23
4785: 8,-23
4786: 9,-23
4787: 10,-23
4788: 11,-23
4789: 12,-23
4790: 13,-23
4791: 14,-23
- node:
color: '#EFB34160'
id: QuarterTileOverlayGreyscale90
@ -5920,7 +6054,6 @@ entities:
1768: 35,7
1779: 2,-25
1780: -2,-25
1781: 18,-25
2543: 39,-35
2994: -41,23
3306: -15,48
@ -5946,6 +6079,7 @@ entities:
4103: -18,7
4211: -17,32
4243: 38,23
4828: 18,-25
- node:
color: '#DE3A3A96'
id: WarnLineS
@ -6034,7 +6168,6 @@ entities:
1767: 35,9
1777: 2,-23
1778: -2,-23
1782: 18,-23
1890: -42,-2
2063: -27,-23
2110: 0,24
@ -6083,6 +6216,7 @@ entities:
4187: 57,3
4213: -17,34
4244: 38,25
4827: 18,-23
- node:
angle: -3.141592653589793 rad
color: '#FFFFFFFF'
@ -15564,6 +15698,13 @@ entities:
- type: Transform
pos: 12.5,-25.5
parent: 60
- proto: BarSpoon
entities:
- uid: 23918
components:
- type: Transform
pos: 9.20146,-36.4394
parent: 60
- proto: BaseGasCondenser
entities:
- uid: 400
@ -49095,6 +49236,26 @@ entities:
- type: Transform
pos: -23.5,16.5
parent: 60
- uid: 23652
components:
- type: Transform
pos: 8.5,-21.5
parent: 60
- uid: 23653
components:
- type: Transform
pos: 7.5,-20.5
parent: 60
- uid: 23914
components:
- type: Transform
pos: 7.5,-21.5
parent: 60
- uid: 23915
components:
- type: Transform
pos: 8.5,-20.5
parent: 60
- uid: 24171
components:
- type: Transform
@ -49274,6 +49435,31 @@ entities:
parent: 60
- proto: CarpetGreen
entities:
- uid: 666
components:
- type: Transform
pos: 20.5,-27.5
parent: 60
- uid: 2278
components:
- type: Transform
pos: 19.5,-26.5
parent: 60
- uid: 2569
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- uid: 2584
components:
- type: Transform
pos: 19.5,-27.5
parent: 60
- uid: 3156
components:
- type: Transform
pos: 21.5,-26.5
parent: 60
- uid: 4195
components:
- type: Transform
@ -49621,6 +49807,11 @@ entities:
- type: Transform
pos: 52.5,-44.5
parent: 60
- uid: 23892
components:
- type: Transform
pos: 21.5,-27.5
parent: 60
- proto: CarpetOrange
entities:
- uid: 1071
@ -49764,11 +49955,6 @@ entities:
- type: Transform
pos: -8.5,-12.5
parent: 60
- uid: 15672
components:
- type: Transform
pos: 20.5,-28.5
parent: 60
- uid: 16543
components:
- type: Transform
@ -49839,21 +50025,11 @@ entities:
- type: Transform
pos: 20.5,-30.5
parent: 60
- uid: 21598
components:
- type: Transform
pos: 18.5,-28.5
parent: 60
- uid: 24409
components:
- type: Transform
pos: 19.5,-31.5
parent: 60
- uid: 24410
components:
- type: Transform
pos: 19.5,-28.5
parent: 60
- uid: 24417
components:
- type: Transform
@ -57498,12 +57674,6 @@ entities:
rot: -1.5707963267948966 rad
pos: -7.5,25.5
parent: 60
- uid: 14388
components:
- type: Transform
rot: 1.5707963267948966 rad
pos: 18.5,-28.5
parent: 60
- uid: 14389
components:
- type: Transform
@ -57639,12 +57809,6 @@ entities:
rot: -1.5707963267948966 rad
pos: 20.5,-29.5
parent: 60
- uid: 24414
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 20.5,-28.5
parent: 60
- proto: CheapLighter
entities:
- uid: 24688
@ -59916,6 +60080,46 @@ entities:
- type: Transform
pos: -15.664602,-30.50866
parent: 60
- uid: 23905
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23906
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23907
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23908
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23909
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23910
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23911
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- uid: 23912
components:
- type: Transform
pos: -27.341524,-2.4224424
parent: 60
- proto: ClothingHeadHatSkub
entities:
- uid: 6791
@ -60609,6 +60813,48 @@ entities:
- type: Transform
pos: 22.509872,-51.419544
parent: 60
- proto: ClothingOuterSanta
entities:
- uid: 23897
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23898
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23899
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23900
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23901
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23902
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23903
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- uid: 23904
components:
- type: Transform
pos: -27.591524,-2.2661924
parent: 60
- proto: ClothingOuterSkub
entities:
- uid: 6793
@ -61165,12 +61411,6 @@ entities:
rot: -1.5707963267948966 rad
pos: 24.5,-5.5
parent: 60
- uid: 24349
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: 13.5,-26.5
parent: 60
- proto: CommandmentCircuitBoard
entities:
- uid: 24825
@ -62937,6 +63177,11 @@ entities:
- type: Transform
pos: -16.5,-29.5
parent: 60
- uid: 23919
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- proto: DefaultStationBeacon
entities:
- uid: 20983
@ -72222,6 +72467,11 @@ entities:
- type: Transform
pos: -7.5,-2.5
parent: 60
- uid: 23894
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- proto: Flare
entities:
- uid: 9525
@ -73130,6 +73380,13 @@ entities:
- type: Transform
pos: -65.522354,23.506481
parent: 60
- proto: FloraTreeChristmas02
entities:
- uid: 23913
components:
- type: Transform
pos: 7.9998736,-21.48742
parent: 60
- proto: FoodApple
entities:
- uid: 7496
@ -73262,10 +73519,10 @@ entities:
parent: 60
- proto: FoodCondimentBottleHotsauce
entities:
- uid: 23671
- uid: 15672
components:
- type: Transform
pos: 21.70029,-26.388956
pos: 11.203171,-26.288023
parent: 60
- proto: FoodFrozenSandwich
entities:
@ -73374,30 +73631,40 @@ entities:
parent: 60
- proto: FoodPlateSmall
entities:
- uid: 21775
- uid: 14388
components:
- type: Transform
pos: 20.513836,-26.289145
pos: 12.531296,-26.131773
parent: 60
- uid: 21789
- uid: 16144
components:
- type: Transform
pos: 20.513836,-26.195395
pos: 12.531296,-26.506773
parent: 60
- uid: 23621
- uid: 21774
components:
- type: Transform
pos: 20.513836,-26.382895
pos: 12.531296,-26.381773
parent: 60
- uid: 23629
components:
- type: Transform
pos: 20.513836,-26.507895
pos: 12.531296,-26.303648
parent: 60
- uid: 23630
- uid: 23667
components:
- type: Transform
pos: 20.513836,-26.445395
pos: 12.531296,-26.178648
parent: 60
- uid: 23671
components:
- type: Transform
pos: 12.531296,-26.428648
parent: 60
- uid: 23891
components:
- type: Transform
pos: 12.531296,-26.241148
parent: 60
- proto: FoodPoppy
entities:
@ -73512,20 +73779,20 @@ entities:
parent: 60
- proto: Fork
entities:
- uid: 2584
- uid: 21598
components:
- type: Transform
pos: 21.138836,-26.476645
pos: 11.828171,-26.428648
parent: 60
- uid: 23653
- uid: 21775
components:
- type: Transform
pos: 21.138836,-26.476645
pos: 11.828171,-26.428648
parent: 60
- uid: 23665
- uid: 23668
components:
- type: Transform
pos: 21.138836,-26.476645
pos: 11.828171,-26.428648
parent: 60
- proto: FuelDispenser
entities:
@ -114793,13 +115060,6 @@ entities:
rot: 1.5707963267948966 rad
pos: -12.5,19.5
parent: 60
- uid: 2278
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- type: ApcPowerReceiver
powerLoad: 0
- uid: 2279
components:
- type: Transform
@ -117916,6 +118176,23 @@ entities:
parent: 60
- type: ApcPowerReceiver
powerLoad: 0
- proto: PresentRandom
entities:
- uid: 23920
components:
- type: Transform
pos: 19.509592,-26.607985
parent: 60
- uid: 23921
components:
- type: Transform
pos: 19.650217,-27.232985
parent: 60
- uid: 23922
components:
- type: Transform
pos: 21.337717,-26.654861
parent: 60
- proto: Protolathe
entities:
- uid: 7081
@ -119477,11 +119754,6 @@ entities:
parent: 60
- proto: RandomVendingDrinks
entities:
- uid: 3156
components:
- type: Transform
pos: 8.5,-19.5
parent: 60
- uid: 6319
components:
- type: Transform
@ -119507,13 +119779,13 @@ entities:
- type: Transform
pos: -37.5,26.5
parent: 60
- proto: RandomVendingSnacks
entities:
- uid: 666
- uid: 23916
components:
- type: Transform
pos: 7.5,-19.5
parent: 60
- proto: RandomVendingSnacks
entities:
- uid: 6320
components:
- type: Transform
@ -119529,6 +119801,11 @@ entities:
- type: Transform
pos: -38.5,26.5
parent: 60
- uid: 23917
components:
- type: Transform
pos: 8.5,-19.5
parent: 60
- proto: RCD
entities:
- uid: 1912
@ -131513,20 +131790,20 @@ entities:
parent: 60
- proto: Spoon
entities:
- uid: 23666
- uid: 5786
components:
- type: Transform
pos: 21.43571,-26.476645
pos: 11.546921,-26.428648
parent: 60
- uid: 23667
- uid: 23893
components:
- type: Transform
pos: 21.43571,-26.476645
pos: 11.546921,-26.428648
parent: 60
- uid: 23668
- uid: 23895
components:
- type: Transform
pos: 21.43571,-26.476645
pos: 11.546921,-26.428648
parent: 60
- proto: SprayBottle
entities:
@ -134805,11 +135082,6 @@ entities:
rot: -1.5707963267948966 rad
pos: 27.5,-32.5
parent: 60
- uid: 2569
components:
- type: Transform
pos: 19.5,-26.5
parent: 60
- uid: 2681
components:
- type: Transform
@ -135421,11 +135693,6 @@ entities:
- type: Transform
pos: 42.5,-1.5
parent: 60
- uid: 16144
components:
- type: Transform
pos: 20.5,-26.5
parent: 60
- uid: 16410
components:
- type: Transform
@ -135699,15 +135966,25 @@ entities:
- type: Transform
pos: -10.5,-34.5
parent: 60
- uid: 21789
components:
- type: Transform
pos: 13.5,-26.5
parent: 60
- uid: 23424
components:
- type: Transform
pos: 47.5,12.5
parent: 60
- uid: 23652
- uid: 23665
components:
- type: Transform
pos: 21.5,-26.5
pos: 11.5,-26.5
parent: 60
- uid: 23666
components:
- type: Transform
pos: 12.5,-26.5
parent: 60
- uid: 23838
components:
@ -135841,10 +136118,12 @@ entities:
- type: Transform
pos: 19.5,-31.5
parent: 60
- uid: 24416
- proto: TableFancyGreen
entities:
- uid: 23896
components:
- type: Transform
pos: 19.5,-28.5
pos: -27.5,-2.5
parent: 60
- proto: TableGlass
entities:
@ -136982,12 +137261,6 @@ entities:
- type: Transform
pos: -24.5,19.5
parent: 60
- uid: 24348
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 12.5,-26.5
parent: 60
- proto: TargetSyndicate
entities:
- uid: 10824
@ -138090,11 +138363,6 @@ entities:
- type: Transform
pos: 29.5,-22.5
parent: 60
- uid: 5786
components:
- type: Transform
pos: 18.5,-26.5
parent: 60
- uid: 6039
components:
- type: Transform
@ -138125,6 +138393,11 @@ entities:
- type: Transform
pos: 26.5,-7.5
parent: 60
- uid: 23630
components:
- type: Transform
pos: 15.5,-26.5
parent: 60
- uid: 25214
components:
- type: Transform
@ -138181,10 +138454,10 @@ entities:
parent: 60
- proto: VendingMachineCondiments
entities:
- uid: 21774
- uid: 23621
components:
- type: Transform
pos: 19.5,-26.5
pos: 13.5,-26.5
parent: 60
- proto: VendingMachineCuraDrobe
entities:

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,8 @@
sprite: Mobs/Ghosts/ghost_human.rsi
state: icon
event: !type:CritSuccumbEvent
startDelay: true
useDelay: 10
- type: entity
id: ActionCritFakeDeath
@ -41,3 +43,5 @@
sprite: Interface/Actions/actions_crit.rsi
state: lastwords
event: !type:CritLastWordsEvent
startDelay: true
useDelay: 10

View file

@ -66,7 +66,7 @@
sprite: Objects/Devices/flatpack.rsi
state: solar-assembly-part
product: CrateEngineeringSolar
cost: 525
cost: 1250
category: cargoproduct-category-name-engineering
group: market

View file

@ -84,4 +84,4 @@
amount: 2
- id: WeaponBaguette
- id: SyndicateMicrowaveMachineCircuitboard
- id: PaperWrittenCombatBakeryKit
- id: PaperWrittenCombatBakeryKit

View file

@ -120,12 +120,14 @@
id: CrateEngineeringSolar
parent: CrateEngineering
name: solar assembly crate
description: Parts for constructing solar panels and trackers.
description: A kit with solar flatpacks and glass to construct ten solar panels.
components:
- type: StorageFill
contents:
- id: SolarAssemblyFlatpack
amount: 6
amount: 10
- id: SheetGlass10
amount: 2
- type: entity
id: CrateEngineeringShuttle

View file

@ -130,6 +130,7 @@
- id: BoxFolderYellow
- id: NewtonCradle
- id: BoxEnvelope
- id: BrbSign
- type: entity
id: CrateServiceFaxMachine

View file

@ -1,4 +1,4 @@
# Offensive
# Offensive
- type: listing
id: SpellbookFireball
name: spellbook-fireball-name
@ -132,6 +132,34 @@
- !type:ListingLimitedStockCondition
stock: 1
- type: listing
id: SpellbookEventSummonGuns
name: spellbook-event-summon-guns-name
description: spellbook-event-summon-guns-description
productAction: ActionSummonGuns
cost:
WizCoin: 2
categories:
- SpellbookEvents
conditions:
- !type:ListingLimitedStockCondition
stock: 1
disableRefund: true
- type: listing
id: SpellbookEventSummonMagic
name: spellbook-event-summon-magic-name
description: spellbook-event-summon-magic-description
productAction: ActionSummonMagic
cost:
WizCoin: 2
categories:
- SpellbookEvents
conditions:
- !type:ListingLimitedStockCondition
stock: 1
disableRefund: true
# Upgrades
- type: listing
id: SpellbookFireballUpgrade

File diff suppressed because it is too large Load diff

View file

@ -1363,7 +1363,7 @@
rules: ghost-role-information-nonantagonist-rules
- type: GhostTakeoverAvailable
- type: Clumsy
clumsyDamage:
gunShootFailDamage:
types:
Blunt: 5
Piercing: 4
@ -1539,7 +1539,7 @@
description: Cousins to the sentient race of lizard people, kobolds blend in with their natural habitat and are as nasty as monkeys; ready to pull out your hair and stab you to death.
components:
- type: Clumsy
clumsyDamage:
gunShootFailDamage:
types:
Blunt: 2
Piercing: 7

View file

@ -233,7 +233,7 @@
- type: Hands
- type: ComplexInteraction
- type: Clumsy
clumsyDamage:
gunShootFailDamage:
types:
Blunt: 5
Piercing: 4

View file

@ -150,6 +150,23 @@
- LightBulb
- Trash
- type: entity
parent: BaseLightbulb
name: dim light bulb
id: DimLightBulb
description: A dim light bulb for populating the darkness of maintenance.
components:
- type: LightBulb
bulb: Bulb
color: "#ba473f"
lightEnergy: 0.5
lightRadius: 5
lightSoftness: 3
- type: Tag
tags:
- LightBulb
- Trash
- type: entity
parent: LightBulb
name: old incandescent light bulb

View file

@ -1036,7 +1036,7 @@
id: SyringeStimulants
components:
- type: Label
currentLabel: reagent-name-hyperzine
currentLabel: reagent-name-stimulants
- type: SolutionContainerManager
solutions:
injector:

View file

@ -126,6 +126,9 @@
state: icon
- type: Item
size: Large
storedSprite:
state: storage
sprite: Objects/Weapons/Melee/gorilla.rsi
- type: MeleeWeapon
attackRate: 0.5
angle: 0
@ -134,6 +137,8 @@
damage:
types:
Blunt: 20
soundHit:
path: "/Audio/Weapons/Guns/Gunshots/kinetic_accel.ogg"
- type: CorePoweredThrower
- type: MeleeThrowOnHit
unanchorOnHit: true

View file

@ -269,7 +269,7 @@
name: throwing knife
parent: [BaseKnife, BaseSyndicateContraband]
id: ThrowingKnife
description: This bloodred knife is very aerodynamic and easy to throw, but good luck trying to fight someone hand-to-hand.
description: This blood-red knife is very aerodynamic and easy to throw, but good luck trying to fight someone hand-to-hand.
components:
- type: Tag
tags:

View file

@ -61,6 +61,7 @@
# maxCount: 2
# stationGrid: false
# paths:
# - /Maps/Ruins/abandoned_outpost.yml
# - /Maps/Ruins/chunked_tcomms.yml
# - /Maps/Ruins/biodome_satellite.yml
# - /Maps/Ruins/derelict.yml

View file

@ -37,6 +37,7 @@
- type: Appearance
- type: Weldable
time: 2
weldedExamineMessage: null
- type: Airtight
- type: Damageable
damageContainer: StructuralInorganic

View file

@ -32,8 +32,6 @@
bonkDamage:
types:
Blunt: 4
bonkSound: !type:SoundCollectionSpecifier
collection: TrayHit
- type: Clickable
- type: FootstepModifier
footstepSoundCollection:

View file

@ -346,6 +346,27 @@
Heat: 1
popupText: powered-light-component-burn-hand
- type: entity
id: PoweredDimSmallLight
suffix: Dim
parent: PoweredSmallLightEmpty
components:
- type: Sprite
state: base
- type: PointLight
enabled: true
radius: 5
energy: 0.5
softness: 3
color: "#ba473f"
- type: PoweredLight
hasLampOnSpawn: DimLightBulb
- type: DamageOnInteract
damage:
types:
Heat: 1
popupText: powered-light-component-burn-hand
- type: entity
id: PoweredSmallLight
suffix: ""

View file

@ -150,6 +150,7 @@
- ExteriorLightTube
- LightBulb
- LedLightBulb
- DimLightBulb
- Bucket
- DrinkMug
- DrinkMugMetal

View file

@ -20,6 +20,11 @@
- state: welded
visible: false
map: ["enum.WeldableLayers.BaseWelded"]
- state: paper
visible: false
sprite: Structures/Storage/closet_labels.rsi
offset: "-0.065,0"
map: ["enum.PaperLabelVisuals.Layer"]
- type: Destructible
thresholds:
- trigger:

View file

@ -19,6 +19,10 @@
- state: welded
visible: false
map: ["enum.WeldableLayers.BaseWelded"]
- state: paper
visible: false
sprite: Structures/Storage/closet_labels.rsi
map: ["enum.PaperLabelVisuals.Layer"]
- type: MovedByPressure
- type: PaperLabel
labelSlot:
@ -86,6 +90,21 @@
SheetSteel1:
min: 1
max: 1
- type: GenericVisualizer
visuals:
enum.PaperLabelVisuals.HasLabel:
enum.PaperLabelVisuals.Layer:
True: { visible: true }
False: { visible: false }
enum.StorageVisuals.Open:
enum.PaperLabelVisuals.Layer:
True: { visible: false }
enum.PaperLabelVisuals.LabelType:
enum.PaperLabelVisuals.Layer:
Paper: { state: paper }
Bounty: { state: bounty }
CaptainsPaper: { state: captains_paper }
Invoice: { state: invoice }
- type: Appearance
- type: EntityStorageVisuals
stateBaseClosed: generic

View file

@ -1,4 +1,4 @@
- type: entity
- type: entity
id: ActionSummonGhosts
name: Summon Ghosts
description: Makes all current ghosts permanently invisible
@ -10,3 +10,195 @@
sprite: Mobs/Ghosts/ghost_human.rsi
state: icon
event: !type:ToggleGhostVisibilityToAllEvent
# TODO: Add Whitelist/Blacklist and Component support to EntitySpawnLists (to avoid making huge hardcoded lists like below).
- type: entity
id: ActionSummonGuns
name: Summon Guns
description: AK47s for everyone! Places a random gun in front of everybody.
components:
- type: Magic
- type: InstantAction
useDelay: 300
itemIconStyle: BigAction
icon:
sprite: Objects/Weapons/Guns/Rifles/ak.rsi
state: base
event: !type:RandomGlobalSpawnSpellEvent
spawns:
- id: WeaponPistolViper
orGroup: Guns
- id: WeaponPistolCobra
orGroup: Guns
- id: WeaponPistolMk58
orGroup: Guns
- id: WeaponPistolN1984
orGroup: Guns
- id: WeaponRevolverDeckard
orGroup: Guns
- id: WeaponRevolverInspector
orGroup: Guns
- id: WeaponRevolverMateba
orGroup: Guns
- id: WeaponRevolverPython
orGroup: Guns
- id: WeaponRevolverPirate
orGroup: Guns
- id: WeaponRifleAk
orGroup: Guns
- id: WeaponRifleM90GrenadeLauncher
orGroup: Guns
- id: WeaponRifleLecter
orGroup: Guns
- id: WeaponShotgunBulldog
orGroup: Guns
- id: WeaponShotgunDoubleBarreled
orGroup: Guns
- id: WeaponShotgunEnforcer
orGroup: Guns
- id: WeaponShotgunKammerer
orGroup: Guns
- id: WeaponShotgunSawn
orGroup: Guns
- id: WeaponShotgunHandmade
orGroup: Guns
- id: WeaponShotgunBlunderbuss
orGroup: Guns
- id: WeaponShotgunImprovised
orGroup: Guns
- id: WeaponSubMachineGunAtreides
orGroup: Guns
- id: WeaponSubMachineGunC20r
orGroup: Guns
- id: WeaponSubMachineGunDrozd
orGroup: Guns
- id: WeaponSubMachineGunWt550
orGroup: Guns
- id: WeaponSniperMosin
orGroup: Guns
- id: WeaponSniperHristov
orGroup: Guns
- id: Musket
orGroup: Guns
- id: WeaponPistolFlintlock
orGroup: Guns
- id: WeaponLauncherChinaLake
orGroup: Guns
- id: WeaponLauncherRocket
orGroup: Guns
- id: WeaponLauncherPirateCannon
orGroup: Guns
- id: WeaponTetherGun
orGroup: Guns
- id: WeaponForceGun
orGroup: Guns
- id: WeaponGrapplingGun
orGroup: Guns
- id: WeaponLightMachineGunL6
orGroup: Guns
- id: WeaponLaserSvalinn
orGroup: Guns
- id: WeaponLaserGun
orGroup: Guns
- id: WeaponMakeshiftLaser
orGroup: Guns
- id: WeaponTeslaGun
orGroup: Guns
- id: WeaponLaserCarbinePractice
orGroup: Guns
- id: WeaponLaserCarbine
orGroup: Guns
- id: WeaponPulsePistol
orGroup: Guns
- id: WeaponPulseCarbine
orGroup: Guns
- id: WeaponPulseRifle
orGroup: Guns
- id: WeaponLaserCannon
orGroup: Guns
- id: WeaponParticleDecelerator
orGroup: Guns
- id: WeaponXrayCannon
orGroup: Guns
- id: WeaponDisablerPractice
orGroup: Guns
- id: WeaponDisabler
orGroup: Guns
- id: WeaponDisablerSMG
orGroup: Guns
- id: WeaponTaser
orGroup: Guns
- id: WeaponAntiqueLaser
orGroup: Guns
- id: WeaponAdvancedLaser
orGroup: Guns
- id: WeaponPistolCHIMP
orGroup: Guns
- id: WeaponBehonkerLaser
orGroup: Guns
- id: WeaponEnergyShotgun
orGroup: Guns
- id: WeaponMinigun
orGroup: Guns
- id: BowImprovised
orGroup: Guns
- id: WeaponFlareGun
orGroup: Guns
- id: WeaponImprovisedPneumaticCannon
orGroup: Guns
- id: WeaponWaterPistol
orGroup: Guns
- id: WeaponWaterBlaster
orGroup: Guns
- id: WeaponWaterBlasterSuper
orGroup: Guns
- id: RevolverCapGun
orGroup: Guns
- id: RevolverCapGunFake
orGroup: Guns
speech: action-speech-spell-summon-guns
- type: entity
id: ActionSummonMagic
name: Summon Magic
description: Places a random magical item in front of everybody. Nothing could go wrong!
components:
- type: Magic
- type: InstantAction
useDelay: 300
itemIconStyle: BigAction
icon:
sprite: Objects/Magic/magicactions.rsi
state: magicmissile
event: !type:RandomGlobalSpawnSpellEvent
spawns:
- id: SpawnSpellbook
orGroup: Magics
- id: ForceWallSpellbook
orGroup: Magics
- id: BlinkBook
orGroup: Magics
- id: SmiteBook
orGroup: Magics
- id: KnockSpellbook
orGroup: Magics
- id: FireballSpellbook
orGroup: Magics
- id: WeaponWandPolymorphCarp
orGroup: Magics
- id: WeaponWandPolymorphMonkey
orGroup: Magics
- id: WeaponWandFireball
orGroup: Magics
- id: WeaponWandPolymorphDoor
orGroup: Magics
- id: WeaponWandCluwne
orGroup: Magics
- id: WeaponWandPolymorphBread
orGroup: Magics
- id: WeaponStaffHealing
orGroup: Magics
- id: WeaponStaffPolymorphDoor
orGroup: Magics
speech: action-speech-spell-summon-magic

View file

@ -52,6 +52,15 @@
Steel: 50
Glass: 50
- type: latheRecipe
id: DimLightBulb
result: DimLightBulb
category: Lights
completetime: 2
materials:
Steel: 50
Glass: 50
- type: latheRecipe
id: GlowstickRed
result: GlowstickRed

View file

@ -953,7 +953,7 @@
LemonLime:
amount: 1
products:
SnowWhite: 3
SnowWhite: 2
- type: reaction
id: SodaWater

View file

@ -16,7 +16,7 @@
- !type:AddComponentSpecial
components:
- type: Clumsy
clumsyDamage:
gunShootFailDamage:
types: #literally just picked semi random valus. i tested this once and tweaked it.
Blunt: 5
Piercing: 4

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 200 B

View file

@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/d917f4c2a088419d5c3aec7656b7ff8cebd1822e idcluwne made by brainfood1183 (github) for ss14, idbrigmedic made by PuroSlavKing (Github), pirate made by brainfood1183 (github), idadmin made by Arimah (github), idvisitor by IProduceWidgets (Github)",
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/d917f4c2a088419d5c3aec7656b7ff8cebd1822e idcluwne made by brainfood1183 (github) for ss14, idbrigmedic made by PuroSlavKing (Github), pirate made by brainfood1183 (github), idadmin made by Arimah (github), idvisitor by IProduceWidgets (Github), idintern-service by spanky-spanky (Github)",
"size": {
"x": 32,
"y": 32

Binary file not shown.

Before

Width:  |  Height:  |  Size: 753 B

After

Width:  |  Height:  |  Size: 775 B

View file

@ -1,14 +1,17 @@
{
"version": 1,
"license": "CC0-1.0",
"copyright": "Design and inhands by ricemar (discord) and icon by EmoGarbage404 (github)",
"copyright": "Design, inhands, and storage sprite by SpaceRox1244 (github) and icon by EmoGarbage404 (github)",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
"name": "icon"
},
{
"name": "storage"
},
{
"name": "inhand-left",

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 B

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 594 B

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 192 B

View file

@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Sprites by Vermidia.",
"copyright": "Sprites by Vermidia and modified by SpaceRox1244.",
"size": {
"x": 32,
"y": 32
@ -20,4 +20,4 @@
"name": "invoice"
}
]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

View file

@ -0,0 +1,23 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Sprites by Vermidia and modified by SpaceRox1244.",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "paper"
},
{
"name": "bounty"
},
{
"name": "captains_paper"
},
{
"name": "invoice"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

After

Width:  |  Height:  |  Size: 4.4 KiB

Some files were not shown because too many files have changed in this diff Show more