upstream merge 2/11 (#2090)
* Fix multiplying colors of differing nullabilities (#32991) * revert the temporary hack * Make atmos alert computer colors private variables (#32992) * Add flash reaction effect (#32377) add flash reaction effect * Automatic changelog update * Fix loneop spawnrate by reverting it to not use the shuttle event system. (#32942) Fix loneop spawnrate by reverting it to not use the custom shuttle event system. * Automatic changelog update * add atmosia to devmap (#32460) change * bowls now make drinking sounds (#32819) * Automatic changelog update * Add health analyzer unrevivability warning (#32636) * Add health analyzer unrevivability warning * Remove errornous comment * Automatic changelog update * Removed the name "Hujsak" (#32998) removed hujsak * fix pie throwing sound not playing (#33017) * Automatic changelog update * Fix TestSuicideByHeldItem and TestSuicideByHeldItemSpreadDamage (#33030) * make ai speak robotically (#33025) * Automatic changelog update * Extends the minimum round time for meteor swarm events (#32876) * adjusted minimum timers in meteorswarms.yml * Updated timer minimum from 20 to 15 minutes * Reduced minimum timer to 10 minutes as a result of other meteor changes --------- Co-authored-by: august-sun <45527070+august.sun@users.noreply.github.com> * Automatic changelog update * add StartDelay bool to actions (#33026) * add StartDelay bool to actions * forgot summary * Updated an incorrect sprite in the smite menu (#33043) changed the synth sprite used in the icon for the instrumentify smite out for the more accurate supersynth sprite * fix lava expeds (#33042) Co-authored-by: deltanedas <@deltanedas:kde.org> * Automatic changelog update * Fix separated game screen bumping (#33046) I don't really understand why RecordedSplitContainer exists but removing it looks identical and fixes the panel bumping occasionally. * Automatic changelog update * Fix: Make Plushie Damage Unexaminable (#33061) Set hidden to true * fix chameleon projector bot whitelist (#33055) fix * Various Vaugely Connected Sprite Updates™: Encryption Keys, Station Map, Brig Timer (#32786) * various resprites (encryption keys + signal screens + station map) * brig timer update * fixes n shit * Give proto-kinetic crushers, glaives, and daggers better inhands. Update the crusher and glaive icons. (#32212) * inhands * better inhands * indent * Automatic changelog update * Make the security belt contain more useful items by default (#32291) * replace tear gas and flashbang with holobarrier and sec radio * holobarrier-belt-fix * revert changes of 32291 * Automatic changelog update * Add 3 bottle boxes to nanomed plus (#33018) three bottle boxes in nanomed plus * Automatic changelog update * Nukie med bundle now costs 24 tc and contains a unique defibrillator (#32720) * a-few-injectors * comment * defib-ops-when * Automatic changelog update * Pill Bottles can only store pills now (#33074) * no longer absurd * Update Resources/Prototypes/Entities/Objects/Specific/chemistry.yml --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Automatic changelog update * Add a spare bible to PietyVend (#32363) Update chapel.yml * Automatic changelog update * [#28722 fix] Add notification for dependent wearables being dropped (#33078) * add notification for dependent wearables being dropped * fix dropped item popup redundancy - did a check to see if any item was dropped, instead of making a notification for each item being dropped. * change popup to client-only variant * fix redundant messages, add plural locale string * fix conventions, fix locale input to be more intuitive --------- Co-authored-by: Justin <justinbrick1@gmail.com> * Automatic changelog update * More pda space (#32601) * Rebalance the max programs that a PDA can hold * Give Caps PDA more programs too. * Make the max programs a static 8 * I forgor sec and med * CaseCase * Empty commit to re-run checks * The final change, I hope. * Automatic changelog update * Fixed spelling mistake in water blaster description. (#33087) Fixed minor spelling mistake * [#20285 fix] Carp Plush and Rehydratables can now be put into mop bucket (#33079) * Make shark plush janitor-bucketable * fix bucketed grey shark texture * Make sprites less shiny and adapt copyright notice * Made shark way way less shiny * Allow carp plush and rehydratables in mop bucket. * Remove old mop bucket shark sprites * Fix post-merge bugs * Fix errors * Move ReactiveContainer stuff to shared That should mean it is now predicted. * Custom eject verb for the mop bucket * Fixes OnSolutionChange, removes pop-up as there already is one. * .ftl is not necessary as the custom pop-up was removed * Review fixes * Update Content.Shared/Chemistry/Components/ReactiveContainerComponent.cs * Update Content.Shared/Chemistry/EntitySystems/ReactiveContainerSystem.cs --------- Co-authored-by: Psychpsyo <psychpsyo@gmail.com> Co-authored-by: Psychpsyo <60073468+Psychpsyo@users.noreply.github.com> Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Automatic changelog update * remove now duplicated nyano PlushieCarp tag * Fixes tailthump breaking positional audio by making it mono (#33092) * Automatic changelog update * ExaminableDamage now puts its message at the bottom and in color (#32820) * the examineableDamage component now puts its messages at the bottom, and in color * god help us if something is priority -100 :godo: * Automatic changelog update * Lower in-round votekick requirements (#32953) Initial commit * Allow votekicks to be initiated in the lobby (#32528) Initial commit * Automatic changelog update * Fixes bolt lights of previously unpowered bolted doors (#33063) fix * Automatic changelog update * Muffins (#29318) * Update meta.json * Add files via upload * Update misc.yml * Update meal_recipes.yml * Update meta.json * Add files via upload * Update plate.yml * Update food_baked_single.yml * Update dinnerware.yml * Update cooking.yml * Update misc.yml * Add files via upload * Delete Resources/Textures/Objects/Consumable/Food/Baked/misc.rsi/muffin-cherry.png * Add files via upload * Update meta.json * Update misc.yml * Update meal_recipes.yml * Update meta.json * Fix meta.json * Fix meta.json again * Update misc.yml * Update misc.yml * Update misc.yml * Update misc.yml * Update meta.json * Update meta.json * Update misc.yml * Update meal_recipes.yml * Update Resources/Prototypes/Entities/Objects/Consumable/Food/Baked/misc.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update dinnerware.yml * Delete cherry * Add files via upload * Delete banana * Add banana * Delete chocolate * Add chocolate * lathe recipe fix --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Automatic changelog update * Borgs can no longer see mindshield + AI can no longer toggle off seeing job icons (#33069) * :( * Removed the sprite + updated RSI * Automatic changelog update * Add CanLoad for biomes (#33050) CPUJob to come later. * Remove CargoPallet component from the cargo pallet (#33022) * Change cargo shuttle pallets to catwalks. * Remove CargoPallet component from the cargo pallet. * Undo cargo shuttle changes. * Automatic changelog update * Minor antagonist guidebook changes (#32824) * took a two month nap. accidentally pushed too many buttons. let's try this again. added thieves to antagonists.xml * even after that nap, i don't feel well-rested at all. * please don't kill me for using webedit * capitalization, typo * Apply suggestions from code review (more period moving) Thanks Evan, very cool Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * guess you could say im not pro-proper noun * typo * Update Resources/ServerInfo/Guidebook/Antagonist/Nuclear Operatives.xml * ok Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> * Give Nukies a Hand Labeler (#33053) * Add hand-labeler to nukie planet * Rearrange nukie chem table * Fix `ItemSlotSystem` popup Logic (#28856) * move popup call out of `CanInsert` into `OnInteractUsing` * im stupid and `reason` is completely unnecessary Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com> * return early when `itemSlots.Slots.Count == 0` * tweak logic for triggering popups * change popup logic again * Consolidate whitelist check * Get any popup message not just last failed slot * Apply suggestions from code review Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * yoink Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> --------- Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com> Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> * Add cvars to votekick to customize requirements for the initiator. (#32490) * Automatic changelog update * Add on-call functionality for adminning (#30443) * Add on-call functionality for adminning The first time an ahelp gets SOS it gets relayed to the specified channel with the specified ping. Every time after that it doesn't until it gets a non-SOS response received. * Remove redundant name Pretty sure this already gets chucked on the name of the msg itself I think it just didn't show in screenshot because they were subsequent. * Update Content.Server/Administration/Systems/BwoinkSystem.cs Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> --------- Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> Co-authored-by: deathride58 <deathride58@users.noreply.github.com> * Automatic changelog update * Pills are explosion resistant (partially reverts #15851) (#32458) * idk how to revert a pr so I just deleted some lines * pill destructible with explosion resistance * comment for explosion resist * "and" to "but" --------- Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> * Automatic changelog update * Hasten handcraft gauze recipe & decrease techfab gauze cost (#32744) * med lathe gauze price reduction * gauze craft doafter time * 3 second doafter craft * Automatic changelog update * Service workers antagonist fix. (#31359) * add * Revert "add" This reverts commit 25da34b0fead5812fe5800c9bf5dd7b10ef48d7d. * antagonism allowed™️ * Automatic changelog update * Adds a new AME sound effect! (#33097) * Changes the AME sound effect to not be the default MetalThud. * Was told on discord to make a minor change to autorerun the tests due to the Build & Test Debug failing! * Attribution and licensing, as requsted by deathride58 * Fixes the high-pitched squeak audible to some people! * Audio file tweaked by SlamBamActionMan to eliminate a weird squeak they were still able to hear. Thanks! * Automatic changelog update * Allow for the ai's laws to be changed from its core and eye (#32461) * Allow for the ai's laws to be changed from its core and eye * Address reviews * Automatic changelog update * clean up tools lathe recipes (#31521) * clean up tools lathe recipes * add medical and cooking tools * add result * add result to others * review * engine --------- Co-authored-by: deltanedas <@deltanedas:kde.org> * Automatic changelog update * Intercoms and Radios both pick up proximate speech (#32737) * Deduping of recent messages should consider the channel it's being sent to * rerun actions * Automatic changelog update * Adds headphones to loadouts (#33067) added headphones to trinkets * Automatic changelog update * Cardboard Box Capacity 4 -> 5 (#32743) * capacity upgrade * comment update * remove our duplicate pill whitelist * fix * remove broken crew monitor from dev map, how did it even get there --------- Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com> Co-authored-by: chromiumboy <50505512+chromiumboy@users.noreply.github.com> Co-authored-by: deltanedas <@deltanedas:kde.org> Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Co-authored-by: PJBot <pieterjan.briers+bot@gmail.com> Co-authored-by: BramvanZijp <56019239+BramvanZijp@users.noreply.github.com> Co-authored-by: Ilya246 <57039557+Ilya246@users.noreply.github.com> Co-authored-by: Moomoobeef <62638182+Moomoobeef@users.noreply.github.com> Co-authored-by: Saphire Lattice <lattice@saphi.re> Co-authored-by: FluffMe <1780586+FluffMe@users.noreply.github.com> Co-authored-by: Theodore Lukin <66275205+pheenty@users.noreply.github.com> Co-authored-by: August Sun <45527070+august-sun@users.noreply.github.com> Co-authored-by: august-sun <45527070+august.sun@users.noreply.github.com> Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Preston Smith <92108534+thetolbean@users.noreply.github.com> Co-authored-by: Milon <plmilonpl@gmail.com> Co-authored-by: Flareguy <78941145+Flareguy@users.noreply.github.com> Co-authored-by: Alzore <140123969+Blackern5000@users.noreply.github.com> Co-authored-by: Boaz1111 <149967078+Boaz1111@users.noreply.github.com> Co-authored-by: Jarmer123 <148848017+Jarmer123@users.noreply.github.com> Co-authored-by: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Co-authored-by: Justin <justinbrick1@gmail.com> Co-authored-by: SpaceLizard <the.justice.league.of.canada@gmail.com> Co-authored-by: Psychpsyo <psychpsyo@gmail.com> Co-authored-by: Psychpsyo <60073468+Psychpsyo@users.noreply.github.com> Co-authored-by: deathride58 <deathride58@users.noreply.github.com> Co-authored-by: PopGamer46 <yt1popgamer@gmail.com> Co-authored-by: RumiTiger <154005209+RumiTiger@users.noreply.github.com> Co-authored-by: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Co-authored-by: Minemoder5000 <minemoder50000@gmail.com> Co-authored-by: UBlueberry <161545003+UBlueberry@users.noreply.github.com> Co-authored-by: Brandon Li <48413902+aspiringLich@users.noreply.github.com> Co-authored-by: ShadowCommander <10494922+ShadowCommander@users.noreply.github.com> Co-authored-by: Vasilis <vasilis@pikachu.systems> Co-authored-by: Chief-Engineer <119664036+Chief-Engineer@users.noreply.github.com> Co-authored-by: K-Dynamic <20566341+K-Dynamic@users.noreply.github.com> Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com> Co-authored-by: AftrLite <61218133+AftrLite@users.noreply.github.com> Co-authored-by: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Co-authored-by: Centronias <me@centronias.com> Co-authored-by: joshepvodka <86210200+joshepvodka@users.noreply.github.com> Co-authored-by: Scribbles0 <91828755+Scribbles0@users.noreply.github.com>
This commit is contained in:
parent
6508f8b6de
commit
2620eb48a8
|
|
@ -43,6 +43,18 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
|
||||
private const float SilencingDuration = 2.5f;
|
||||
|
||||
// Colors
|
||||
private Color _wallColor = new Color(64, 64, 64);
|
||||
private Color _tileColor = new Color(28, 28, 28);
|
||||
private Color _monitorBlipColor = Color.Cyan;
|
||||
private Color _untrackedEntColor = Color.DimGray;
|
||||
private Color _regionBaseColor = new Color(154, 154, 154);
|
||||
private Color _inactiveColor = StyleNano.DisabledFore;
|
||||
private Color _statusTextColor = StyleNano.GoodGreenFore;
|
||||
private Color _goodColor = Color.LimeGreen;
|
||||
private Color _warningColor = new Color(255, 182, 72);
|
||||
private Color _dangerColor = new Color(255, 67, 67);
|
||||
|
||||
public AtmosAlertsComputerWindow(AtmosAlertsComputerBoundUserInterface userInterface, EntityUid? owner)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
|
@ -55,8 +67,8 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
NavMap.Owner = _owner;
|
||||
|
||||
// Set nav map colors
|
||||
NavMap.WallColor = new Color(64, 64, 64);
|
||||
NavMap.TileColor = Color.DimGray * NavMap.WallColor;
|
||||
NavMap.WallColor = _wallColor;
|
||||
NavMap.TileColor = _tileColor;
|
||||
|
||||
// Set nav map grid uid
|
||||
var stationName = Loc.GetString("atmos-alerts-window-unknown-location");
|
||||
|
|
@ -214,7 +226,7 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
if (consoleCoords != null && consoleUid != null)
|
||||
{
|
||||
var texture = _spriteSystem.Frame0(new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")));
|
||||
var blip = new NavMapBlip(consoleCoords.Value, texture, Color.Cyan, true, false);
|
||||
var blip = new NavMapBlip(consoleCoords.Value, texture, _monitorBlipColor, true, false);
|
||||
NavMap.TrackedEntities[consoleUid.Value] = blip;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +275,7 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
VerticalAlignment = VAlignment.Center,
|
||||
};
|
||||
|
||||
label.SetMarkup(Loc.GetString("atmos-alerts-window-no-active-alerts", ("color", StyleNano.GoodGreenFore.ToHexNoAlpha())));
|
||||
label.SetMarkup(Loc.GetString("atmos-alerts-window-no-active-alerts", ("color", _statusTextColor.ToHexNoAlpha())));
|
||||
|
||||
AlertsTable.AddChild(label);
|
||||
}
|
||||
|
|
@ -292,7 +304,7 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
if (!TryGetSensorRegionColor(regionOwner, alarmState, out var regionColor))
|
||||
continue;
|
||||
|
||||
regionOverlay.Color = regionColor.Value;
|
||||
regionOverlay.Color = regionColor;
|
||||
|
||||
var priority = (_trackedEntity == regionOwner) ? 999 : (int)alarmState;
|
||||
prioritizedRegionOverlays.Add(regionOverlay, priority);
|
||||
|
|
@ -323,7 +335,7 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
var coords = _entManager.GetCoordinates(metaData.NetCoordinates);
|
||||
|
||||
if (_trackedEntity != null && _trackedEntity != metaData.NetEntity)
|
||||
color *= Color.DimGray;
|
||||
color *= _untrackedEntColor;
|
||||
|
||||
var selectable = true;
|
||||
var blip = new NavMapBlip(coords, _spriteSystem.Frame0(texture), color, _trackedEntity == metaData.NetEntity, selectable);
|
||||
|
|
@ -331,23 +343,20 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
NavMap.TrackedEntities[metaData.NetEntity] = blip;
|
||||
}
|
||||
|
||||
private bool TryGetSensorRegionColor(NetEntity regionOwner, AtmosAlarmType alarmState, [NotNullWhen(true)] out Color? color)
|
||||
private bool TryGetSensorRegionColor(NetEntity regionOwner, AtmosAlarmType alarmState, out Color color)
|
||||
{
|
||||
color = null;
|
||||
color = Color.White;
|
||||
|
||||
var blip = GetBlipTexture(alarmState);
|
||||
|
||||
if (blip == null)
|
||||
return false;
|
||||
|
||||
// DeltaV: fix client until upstream does
|
||||
// Color the region based on alarm state and entity tracking
|
||||
var output = blip.Value.Item2 * new Color(154, 154, 154);
|
||||
color = blip.Value.Item2 * _regionBaseColor;
|
||||
|
||||
if (_trackedEntity != null && _trackedEntity != regionOwner)
|
||||
output *= Color.DimGray;
|
||||
|
||||
color = output;
|
||||
color *= _untrackedEntColor;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -588,13 +597,13 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow
|
|||
switch (alarmState)
|
||||
{
|
||||
case AtmosAlarmType.Invalid:
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")), StyleNano.DisabledFore); break;
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")), _inactiveColor); break;
|
||||
case AtmosAlarmType.Normal:
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")), Color.LimeGreen); break;
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_circle.png")), _goodColor); break;
|
||||
case AtmosAlarmType.Warning:
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_triangle.png")), new Color(255, 182, 72)); break;
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_triangle.png")), _warningColor); break;
|
||||
case AtmosAlarmType.Danger:
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_square.png")), new Color(255, 67, 67)); break;
|
||||
output = (new SpriteSpecifier.Texture(new ResPath("/Textures/Interface/NavMap/beveled_square.png")), _dangerColor); break;
|
||||
}
|
||||
|
||||
return output;
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@
|
|||
|
||||
<PanelContainer Name="AlertsDivider" Visible="False" StyleClasses="LowDivider" />
|
||||
|
||||
<BoxContainer Name="AlertsContainer" Visible="False" Margin="0 5" Orientation="Horizontal"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center">
|
||||
<BoxContainer Name="AlertsContainer" Visible="False" Margin="0 5" Orientation="Vertical" HorizontalAlignment="Center">
|
||||
|
||||
</BoxContainer>
|
||||
|
||||
|
|
|
|||
|
|
@ -110,18 +110,29 @@ namespace Content.Client.HealthAnalyzer.UI
|
|||
|
||||
// Alerts
|
||||
|
||||
AlertsDivider.Visible = msg.Bleeding == true;
|
||||
AlertsContainer.Visible = msg.Bleeding == true;
|
||||
var showAlerts = msg.Unrevivable == true || msg.Bleeding == true;
|
||||
|
||||
AlertsDivider.Visible = showAlerts;
|
||||
AlertsContainer.Visible = showAlerts;
|
||||
|
||||
if (showAlerts)
|
||||
AlertsContainer.DisposeAllChildren();
|
||||
|
||||
if (msg.Unrevivable == true)
|
||||
AlertsContainer.AddChild(new RichTextLabel
|
||||
{
|
||||
Text = Loc.GetString("health-analyzer-window-entity-unrevivable-text"),
|
||||
Margin = new Thickness(0, 4),
|
||||
MaxWidth = 300
|
||||
});
|
||||
|
||||
if (msg.Bleeding == true)
|
||||
{
|
||||
AlertsContainer.DisposeAllChildren();
|
||||
AlertsContainer.AddChild(new Label
|
||||
AlertsContainer.AddChild(new RichTextLabel
|
||||
{
|
||||
Text = Loc.GetString("health-analyzer-window-entity-bleeding-text"),
|
||||
FontColorOverride = Color.Red,
|
||||
Margin = new Thickness(0, 4),
|
||||
MaxWidth = 300
|
||||
});
|
||||
}
|
||||
|
||||
// Damage Groups
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
VerticalExpand="False"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center">
|
||||
<controls:RecordedSplitContainer Name="ScreenContainer" HorizontalExpand="True"
|
||||
<SplitContainer Name="ScreenContainer" HorizontalExpand="True"
|
||||
VerticalExpand="True" SplitWidth="0"
|
||||
StretchDirection="TopLeft">
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True" Name="SpawnContainer" MinWidth="200" SetWidth="600">
|
||||
|
|
@ -82,5 +82,5 @@
|
|||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</LayoutContainer>
|
||||
</controls:RecordedSplitContainer>
|
||||
</SplitContainer>
|
||||
</mapping:MappingScreen>
|
||||
|
|
|
|||
|
|
@ -197,7 +197,6 @@ public sealed partial class MappingScreen : InGameScreen
|
|||
|
||||
public override void SetChatSize(Vector2 size)
|
||||
{
|
||||
ScreenContainer.DesiredSplitCenter = size.X;
|
||||
ScreenContainer.ResizeMode = SplitContainer.SplitResizeMode.RespectChildrenMinSize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
using System.Numerics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
||||
namespace Content.Client.UserInterface.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// A split container that performs an action when the split resizing is finished.
|
||||
/// </summary>
|
||||
public sealed class RecordedSplitContainer : SplitContainer
|
||||
{
|
||||
public double? DesiredSplitCenter;
|
||||
|
||||
protected override Vector2 ArrangeOverride(Vector2 finalSize)
|
||||
{
|
||||
if (ResizeMode == SplitResizeMode.RespectChildrenMinSize
|
||||
&& DesiredSplitCenter != null
|
||||
&& !finalSize.Equals(Vector2.Zero))
|
||||
{
|
||||
SplitFraction = (float) DesiredSplitCenter.Value;
|
||||
|
||||
if (!Size.Equals(Vector2.Zero))
|
||||
{
|
||||
DesiredSplitCenter = null;
|
||||
}
|
||||
}
|
||||
|
||||
return base.ArrangeOverride(finalSize);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
VerticalExpand="False"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center">
|
||||
<controls:RecordedSplitContainer Name="ScreenContainer" HorizontalExpand="True" VerticalExpand="True" SplitWidth="0" StretchDirection="TopLeft">
|
||||
<SplitContainer Name="ScreenContainer" HorizontalExpand="True" VerticalExpand="True" SplitWidth="0" StretchDirection="TopLeft">
|
||||
<LayoutContainer Name="ViewportContainer" HorizontalExpand="True" VerticalExpand="True">
|
||||
<controls:MainViewport Name="MainViewport"/>
|
||||
<widgets:GhostGui Name="Ghost" Access="Protected" />
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
</BoxContainer>
|
||||
<alerts:AlertsUI Name="Alerts" Access="Protected" />
|
||||
</LayoutContainer>
|
||||
<PanelContainer HorizontalExpand="True" MinWidth="300">
|
||||
<PanelContainer Name="SeparatedChatPanel" MinWidth="300">
|
||||
<PanelContainer.PanelOverride>
|
||||
<graphics:StyleBoxFlat BackgroundColor="#2B2C3B" />
|
||||
</PanelContainer.PanelOverride>
|
||||
|
|
@ -36,5 +36,5 @@
|
|||
<chat:ChatBox VerticalExpand="True" HorizontalExpand="True" Name="Chat" Access="Protected" MinSize="0 0"/>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</controls:RecordedSplitContainer>
|
||||
</SplitContainer>
|
||||
</screens:SeparatedChatGameScreen>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ public sealed partial class SeparatedChatGameScreen : InGameScreen
|
|||
|
||||
public override void SetChatSize(Vector2 size)
|
||||
{
|
||||
ScreenContainer.DesiredSplitCenter = size.X;
|
||||
ScreenContainer.ResizeMode = SplitContainer.SplitResizeMode.RespectChildrenMinSize;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client.Gameplay;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.CCVar;
|
||||
|
|
@ -8,6 +9,7 @@ using Content.Shared.Voting;
|
|||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Console;
|
||||
using Robust.Client.State;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
|
@ -28,6 +30,7 @@ namespace Content.Client.Voting.UI
|
|||
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Dependency] private readonly IEntityNetworkManager _entNetManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IStateManager _state = default!;
|
||||
|
||||
private VotingSystem _votingSystem;
|
||||
|
||||
|
|
@ -62,7 +65,7 @@ namespace Content.Client.Voting.UI
|
|||
|
||||
Stylesheet = IoCManager.Resolve<IStylesheetManager>().SheetSpace;
|
||||
CloseButton.OnPressed += _ => Close();
|
||||
VoteNotTrustedLabel.Text = Loc.GetString("ui-vote-trusted-users-notice", ("timeReq", _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime) / 60));
|
||||
VoteNotTrustedLabel.Text = Loc.GetString("ui-vote-trusted-users-notice", ("timeReq", _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime)));
|
||||
|
||||
foreach (StandardVoteType voteType in Enum.GetValues<StandardVoteType>())
|
||||
{
|
||||
|
|
@ -70,6 +73,7 @@ namespace Content.Client.Voting.UI
|
|||
VoteTypeButton.AddItem(Loc.GetString(option.Name), (int)voteType);
|
||||
}
|
||||
|
||||
_state.OnStateChanged += OnStateChanged;
|
||||
VoteTypeButton.OnItemSelected += VoteTypeSelected;
|
||||
CreateButton.OnPressed += CreatePressed;
|
||||
FollowButton.OnPressed += FollowSelected;
|
||||
|
|
@ -101,6 +105,14 @@ namespace Content.Client.Voting.UI
|
|||
UpdateVoteTimeout();
|
||||
}
|
||||
|
||||
private void OnStateChanged(StateChangedEventArgs obj)
|
||||
{
|
||||
if (obj.NewState is not GameplayState)
|
||||
return;
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
private void CanCallVoteChanged(bool obj)
|
||||
{
|
||||
if (!obj)
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@ public sealed class VotingSystem : EntitySystem
|
|||
|
||||
private void OnVotePlayerListResponseEvent(VotePlayerListResponseEvent msg)
|
||||
{
|
||||
if (!_ghostSystem.IsGhost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VotePlayerListResponse?.Invoke(msg);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ public sealed class SuicideCommandTests
|
|||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Run the suicide command in the console
|
||||
/// Should only ghost the player but not kill them
|
||||
/// </summary>
|
||||
|
|
@ -241,6 +241,7 @@ public sealed class SuicideCommandTests
|
|||
var mindSystem = entManager.System<SharedMindSystem>();
|
||||
var mobStateSystem = entManager.System<MobStateSystem>();
|
||||
var transformSystem = entManager.System<TransformSystem>();
|
||||
var damageableSystem = entManager.System<DamageableSystem>();
|
||||
|
||||
// We need to know the player and whether they can be hurt, killed, and whether they have a mind
|
||||
var player = playerMan.Sessions.First().AttachedEntity!.Value;
|
||||
|
|
@ -276,6 +277,8 @@ public sealed class SuicideCommandTests
|
|||
// and that all the damage is concentrated in the Slash category
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
// Heal all damage first (possible low pressure damage taken)
|
||||
damageableSystem.SetAllDamage(player, damageableComp, 0);
|
||||
consoleHost.GetSessionShell(playerMan.Sessions.First()).ExecuteCommand("suicide");
|
||||
var lethalDamageThreshold = mobThresholdsComp.Thresholds.Keys.Last();
|
||||
|
||||
|
|
@ -313,6 +316,7 @@ public sealed class SuicideCommandTests
|
|||
var mindSystem = entManager.System<SharedMindSystem>();
|
||||
var mobStateSystem = entManager.System<MobStateSystem>();
|
||||
var transformSystem = entManager.System<TransformSystem>();
|
||||
var damageableSystem = entManager.System<DamageableSystem>();
|
||||
|
||||
// We need to know the player and whether they can be hurt, killed, and whether they have a mind
|
||||
var player = playerMan.Sessions.First().AttachedEntity!.Value;
|
||||
|
|
@ -348,6 +352,8 @@ public sealed class SuicideCommandTests
|
|||
// and that slash damage is split in half
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
// Heal all damage first (possible low pressure damage taken)
|
||||
damageableSystem.SetAllDamage(player, damageableComp, 0);
|
||||
consoleHost.GetSessionShell(playerMan.Sessions.First()).ExecuteCommand("suicide");
|
||||
var lethalDamageThreshold = mobThresholdsComp.Thresholds.Keys.Last();
|
||||
|
||||
|
|
|
|||
|
|
@ -654,7 +654,7 @@ public sealed partial class AdminVerbSystem
|
|||
{
|
||||
Text = "admin-smite-become-mouse-name",
|
||||
Category = VerbCategory.Smite,
|
||||
Icon = new SpriteSpecifier.Rsi(new ("/Textures/Objects/Fun/Instruments/h_synthesizer.rsi"), "icon"),
|
||||
Icon = new SpriteSpecifier.Rsi(new ("/Textures/Objects/Fun/Instruments/h_synthesizer.rsi"), "supersynth"),
|
||||
Act = () =>
|
||||
{
|
||||
_polymorphSystem.PolymorphEntity(args.Target, "AdminInstrumentSmite");
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ using Robust.Shared.Toolshed;
|
|||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Server.Silicons.Laws;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Laws.Components;
|
||||
using Robust.Server.Player;
|
||||
using Content.Shared.Silicons.StationAi;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using static Content.Shared.Configurable.ConfigurationComponent;
|
||||
|
||||
|
|
@ -345,7 +347,30 @@ namespace Content.Server.Administration.Systems
|
|||
Impact = LogImpact.Low
|
||||
});
|
||||
|
||||
if (TryComp<SiliconLawBoundComponent>(args.Target, out var lawBoundComponent))
|
||||
// This logic is needed to be able to modify the AI's laws through its core and eye.
|
||||
EntityUid? target = null;
|
||||
SiliconLawBoundComponent? lawBoundComponent = null;
|
||||
|
||||
if (TryComp(args.Target, out lawBoundComponent))
|
||||
{
|
||||
target = args.Target;
|
||||
}
|
||||
// When inspecting the core we can find the entity with its laws by looking at the AiHolderComponent.
|
||||
else if (TryComp<StationAiHolderComponent>(args.Target, out var holder) && holder.Slot.Item != null
|
||||
&& TryComp(holder.Slot.Item, out lawBoundComponent))
|
||||
{
|
||||
target = holder.Slot.Item.Value;
|
||||
// For the eye we can find the entity with its laws as the source of the movement relay since the eye
|
||||
// is just a proxy for it to move around and look around the station.
|
||||
}
|
||||
else if (TryComp<MovementRelayTargetComponent>(args.Target, out var relay)
|
||||
&& TryComp(relay.Source, out lawBoundComponent))
|
||||
{
|
||||
target = relay.Source;
|
||||
|
||||
}
|
||||
|
||||
if (lawBoundComponent != null && target != null)
|
||||
{
|
||||
args.Verbs.Add(new Verb()
|
||||
{
|
||||
|
|
@ -359,7 +384,7 @@ namespace Content.Server.Administration.Systems
|
|||
return;
|
||||
}
|
||||
_euiManager.OpenEui(ui, session);
|
||||
ui.UpdateLaws(lawBoundComponent, args.Target);
|
||||
ui.UpdateLaws(lawBoundComponent, target.Value);
|
||||
},
|
||||
Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/Interface/Actions/actions_borg.rsi"), "state-laws"),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -47,20 +47,23 @@ namespace Content.Server.Administration.Systems
|
|||
[GeneratedRegex(@"^https://discord\.com/api/webhooks/(\d+)/((?!.*/).*)$")]
|
||||
private static partial Regex DiscordRegex();
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
private readonly HttpClient _httpClient = new();
|
||||
private string _webhookUrl = string.Empty;
|
||||
private WebhookData? _webhookData;
|
||||
|
||||
private string _onCallUrl = string.Empty;
|
||||
private WebhookData? _onCallData;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
private readonly HttpClient _httpClient = new();
|
||||
|
||||
private string _footerIconUrl = string.Empty;
|
||||
private string _avatarUrl = string.Empty;
|
||||
private string _serverName = string.Empty;
|
||||
|
||||
private readonly
|
||||
Dictionary<NetUserId, (string? id, string username, string description, string? characterName, GameRunLevel
|
||||
lastRunLevel)> _relayMessages = new();
|
||||
private readonly Dictionary<NetUserId, DiscordRelayInteraction> _relayMessages = new();
|
||||
|
||||
private Dictionary<NetUserId, string> _oldMessageIds = new();
|
||||
private readonly Dictionary<NetUserId, Queue<string>> _messageQueues = new();
|
||||
private readonly Dictionary<NetUserId, Queue<DiscordRelayedData>> _messageQueues = new();
|
||||
private readonly HashSet<NetUserId> _processingChannels = new();
|
||||
private readonly Dictionary<NetUserId, (TimeSpan Timestamp, bool Typing)> _typingUpdateTimestamps = new();
|
||||
private string _overrideClientName = string.Empty;
|
||||
|
|
@ -82,12 +85,16 @@ namespace Content.Server.Administration.Systems
|
|||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
Subs.CVar(_config, CCVars.DiscordOnCallWebhook, OnCallChanged, true);
|
||||
|
||||
Subs.CVar(_config, CCVars.DiscordAHelpWebhook, OnWebhookChanged, true);
|
||||
Subs.CVar(_config, CCVars.DiscordAHelpFooterIcon, OnFooterIconChanged, true);
|
||||
Subs.CVar(_config, CCVars.DiscordAHelpAvatar, OnAvatarChanged, true);
|
||||
Subs.CVar(_config, CVars.GameHostName, OnServerNameChanged, true);
|
||||
Subs.CVar(_config, CCVars.AdminAhelpOverrideClientName, OnOverrideChanged, true);
|
||||
_sawmill = IoCManager.Resolve<ILogManager>().GetSawmill("AHELP");
|
||||
|
||||
var defaultParams = new AHelpMessageParams(
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
|
|
@ -96,7 +103,7 @@ namespace Content.Server.Administration.Systems
|
|||
_gameTicker.RunLevel,
|
||||
playedSound: false
|
||||
);
|
||||
_maxAdditionalChars = GenerateAHelpMessage(defaultParams).Length;
|
||||
_maxAdditionalChars = GenerateAHelpMessage(defaultParams).Message.Length;
|
||||
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;
|
||||
|
||||
SubscribeLocalEvent<GameRunLevelChangedEvent>(OnGameRunLevelChanged);
|
||||
|
|
@ -111,6 +118,33 @@ namespace Content.Server.Administration.Systems
|
|||
);
|
||||
}
|
||||
|
||||
private async void OnCallChanged(string url)
|
||||
{
|
||||
_onCallUrl = url;
|
||||
|
||||
if (url == string.Empty)
|
||||
return;
|
||||
|
||||
var match = DiscordRegex().Match(url);
|
||||
|
||||
if (!match.Success)
|
||||
{
|
||||
Log.Error("On call URL does not appear to be valid.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (match.Groups.Count <= 2)
|
||||
{
|
||||
Log.Error("Could not get webhook ID or token for on call URL.");
|
||||
return;
|
||||
}
|
||||
|
||||
var webhookId = match.Groups[1].Value;
|
||||
var webhookToken = match.Groups[2].Value;
|
||||
|
||||
_onCallData = await GetWebhookData(webhookId, webhookToken);
|
||||
}
|
||||
|
||||
private void PlayerRateLimitedAction(ICommonSession obj)
|
||||
{
|
||||
RaiseNetworkEvent(
|
||||
|
|
@ -259,13 +293,13 @@ namespace Content.Server.Administration.Systems
|
|||
|
||||
// Store the Discord message IDs of the previous round
|
||||
_oldMessageIds = new Dictionary<NetUserId, string>();
|
||||
foreach (var message in _relayMessages)
|
||||
foreach (var (user, interaction) in _relayMessages)
|
||||
{
|
||||
var id = message.Value.id;
|
||||
var id = interaction.Id;
|
||||
if (id == null)
|
||||
return;
|
||||
|
||||
_oldMessageIds[message.Key] = id;
|
||||
_oldMessageIds[user] = id;
|
||||
}
|
||||
|
||||
_relayMessages.Clear();
|
||||
|
|
@ -330,10 +364,10 @@ namespace Content.Server.Administration.Systems
|
|||
var webhookToken = match.Groups[2].Value;
|
||||
|
||||
// Fire and forget
|
||||
await SetWebhookData(webhookId, webhookToken);
|
||||
_webhookData = await GetWebhookData(webhookId, webhookToken);
|
||||
}
|
||||
|
||||
private async Task SetWebhookData(string id, string token)
|
||||
private async Task<WebhookData?> GetWebhookData(string id, string token)
|
||||
{
|
||||
var response = await _httpClient.GetAsync($"https://discord.com/api/v10/webhooks/{id}/{token}");
|
||||
|
||||
|
|
@ -342,10 +376,10 @@ namespace Content.Server.Administration.Systems
|
|||
{
|
||||
_sawmill.Log(LogLevel.Error,
|
||||
$"Discord returned bad status code when trying to get webhook data (perhaps the webhook URL is invalid?): {response.StatusCode}\nResponse: {content}");
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
_webhookData = JsonSerializer.Deserialize<WebhookData>(content);
|
||||
return JsonSerializer.Deserialize<WebhookData>(content);
|
||||
}
|
||||
|
||||
private void OnFooterIconChanged(string url)
|
||||
|
|
@ -358,14 +392,14 @@ namespace Content.Server.Administration.Systems
|
|||
_avatarUrl = url;
|
||||
}
|
||||
|
||||
private async void ProcessQueue(NetUserId userId, Queue<string> messages)
|
||||
private async void ProcessQueue(NetUserId userId, Queue<DiscordRelayedData> messages)
|
||||
{
|
||||
// Whether an embed already exists for this player
|
||||
var exists = _relayMessages.TryGetValue(userId, out var existingEmbed);
|
||||
|
||||
// Whether the message will become too long after adding these new messages
|
||||
var tooLong = exists && messages.Sum(msg => Math.Min(msg.Length, MessageLengthCap) + "\n".Length)
|
||||
+ existingEmbed.description.Length > DescriptionMax;
|
||||
var tooLong = exists && messages.Sum(msg => Math.Min(msg.Message.Length, MessageLengthCap) + "\n".Length)
|
||||
+ existingEmbed?.Description.Length > DescriptionMax;
|
||||
|
||||
// If there is no existing embed, or it is getting too long, we create a new embed
|
||||
if (!exists || tooLong)
|
||||
|
|
@ -385,10 +419,10 @@ namespace Content.Server.Administration.Systems
|
|||
// If we have all the data required, we can link to the embed of the previous round or embed that was too long
|
||||
if (_webhookData is { GuildId: { } guildId, ChannelId: { } channelId })
|
||||
{
|
||||
if (tooLong && existingEmbed.id != null)
|
||||
if (tooLong && existingEmbed?.Id != null)
|
||||
{
|
||||
linkToPrevious =
|
||||
$"**[Go to previous embed of this round](https://discord.com/channels/{guildId}/{channelId}/{existingEmbed.id})**\n";
|
||||
$"**[Go to previous embed of this round](https://discord.com/channels/{guildId}/{channelId}/{existingEmbed.Id})**\n";
|
||||
}
|
||||
else if (_oldMessageIds.TryGetValue(userId, out var id) && !string.IsNullOrEmpty(id))
|
||||
{
|
||||
|
|
@ -398,13 +432,22 @@ namespace Content.Server.Administration.Systems
|
|||
}
|
||||
|
||||
var characterName = _minds.GetCharacterName(userId);
|
||||
existingEmbed = (null, lookup.Username, linkToPrevious, characterName, _gameTicker.RunLevel);
|
||||
existingEmbed = new DiscordRelayInteraction()
|
||||
{
|
||||
Id = null,
|
||||
CharacterName = characterName,
|
||||
Description = linkToPrevious,
|
||||
Username = lookup.Username,
|
||||
LastRunLevel = _gameTicker.RunLevel,
|
||||
};
|
||||
|
||||
_relayMessages[userId] = existingEmbed;
|
||||
}
|
||||
|
||||
// Previous message was in another RunLevel, so show that in the embed
|
||||
if (existingEmbed.lastRunLevel != _gameTicker.RunLevel)
|
||||
if (existingEmbed!.LastRunLevel != _gameTicker.RunLevel)
|
||||
{
|
||||
existingEmbed.description += _gameTicker.RunLevel switch
|
||||
existingEmbed.Description += _gameTicker.RunLevel switch
|
||||
{
|
||||
GameRunLevel.PreRoundLobby => "\n\n:arrow_forward: _**Pre-round lobby started**_\n",
|
||||
GameRunLevel.InRound => "\n\n:arrow_forward: _**Round started**_\n",
|
||||
|
|
@ -413,26 +456,35 @@ namespace Content.Server.Administration.Systems
|
|||
$"{_gameTicker.RunLevel} was not matched."),
|
||||
};
|
||||
|
||||
existingEmbed.lastRunLevel = _gameTicker.RunLevel;
|
||||
existingEmbed.LastRunLevel = _gameTicker.RunLevel;
|
||||
}
|
||||
|
||||
// If last message of the new batch is SOS then relay it to on-call.
|
||||
// ... as long as it hasn't been relayed already.
|
||||
var discordMention = messages.Last();
|
||||
var onCallRelay = !discordMention.Receivers && !existingEmbed.OnCall;
|
||||
|
||||
// Add available messages to the embed description
|
||||
while (messages.TryDequeue(out var message))
|
||||
{
|
||||
// In case someone thinks they're funny
|
||||
if (message.Length > MessageLengthCap)
|
||||
message = message[..(MessageLengthCap - TooLongText.Length)] + TooLongText;
|
||||
string text;
|
||||
|
||||
existingEmbed.description += $"\n{message}";
|
||||
// In case someone thinks they're funny
|
||||
if (message.Message.Length > MessageLengthCap)
|
||||
text = message.Message[..(MessageLengthCap - TooLongText.Length)] + TooLongText;
|
||||
else
|
||||
text = message.Message;
|
||||
|
||||
existingEmbed.Description += $"\n{text}";
|
||||
}
|
||||
|
||||
var payload = GeneratePayload(existingEmbed.description,
|
||||
existingEmbed.username,
|
||||
existingEmbed.characterName);
|
||||
var payload = GeneratePayload(existingEmbed.Description,
|
||||
existingEmbed.Username,
|
||||
existingEmbed.CharacterName);
|
||||
|
||||
// If there is no existing embed, create a new one
|
||||
// Otherwise patch (edit) it
|
||||
if (existingEmbed.id == null)
|
||||
if (existingEmbed.Id == null)
|
||||
{
|
||||
var request = await _httpClient.PostAsync($"{_webhookUrl}?wait=true",
|
||||
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||
|
|
@ -455,11 +507,11 @@ namespace Content.Server.Administration.Systems
|
|||
return;
|
||||
}
|
||||
|
||||
existingEmbed.id = id.ToString();
|
||||
existingEmbed.Id = id.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
var request = await _httpClient.PatchAsync($"{_webhookUrl}/messages/{existingEmbed.id}",
|
||||
var request = await _httpClient.PatchAsync($"{_webhookUrl}/messages/{existingEmbed.Id}",
|
||||
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||
|
||||
if (!request.IsSuccessStatusCode)
|
||||
|
|
@ -474,6 +526,43 @@ namespace Content.Server.Administration.Systems
|
|||
|
||||
_relayMessages[userId] = existingEmbed;
|
||||
|
||||
// Actually do the on call relay last, we just need to grab it before we dequeue every message above.
|
||||
if (onCallRelay &&
|
||||
_onCallData != null)
|
||||
{
|
||||
existingEmbed.OnCall = true;
|
||||
var roleMention = _config.GetCVar(CCVars.DiscordAhelpMention);
|
||||
|
||||
if (!string.IsNullOrEmpty(roleMention))
|
||||
{
|
||||
var message = new StringBuilder();
|
||||
message.AppendLine($"<@&{roleMention}>");
|
||||
message.AppendLine("Unanswered SOS");
|
||||
|
||||
// Need webhook data to get the correct link for that channel rather than on-call data.
|
||||
if (_webhookData is { GuildId: { } guildId, ChannelId: { } channelId })
|
||||
{
|
||||
message.AppendLine(
|
||||
$"**[Go to ahelp](https://discord.com/channels/{guildId}/{channelId}/{existingEmbed.Id})**");
|
||||
}
|
||||
|
||||
payload = GeneratePayload(message.ToString(), existingEmbed.Username, existingEmbed.CharacterName);
|
||||
|
||||
var request = await _httpClient.PostAsync($"{_onCallUrl}?wait=true",
|
||||
new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json"));
|
||||
|
||||
var content = await request.Content.ReadAsStringAsync();
|
||||
if (!request.IsSuccessStatusCode)
|
||||
{
|
||||
_sawmill.Log(LogLevel.Error, $"Discord returned bad status code when posting relay message (perhaps the message is too long?): {request.StatusCode}\nResponse: {content}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
existingEmbed.OnCall = false;
|
||||
}
|
||||
|
||||
_processingChannels.Remove(userId);
|
||||
}
|
||||
|
||||
|
|
@ -652,7 +741,7 @@ namespace Content.Server.Administration.Systems
|
|||
if (sendsWebhook)
|
||||
{
|
||||
if (!_messageQueues.ContainsKey(msg.UserId))
|
||||
_messageQueues[msg.UserId] = new Queue<string>();
|
||||
_messageQueues[msg.UserId] = new Queue<DiscordRelayedData>();
|
||||
|
||||
var str = message.Text;
|
||||
var unameLength = senderSession.Name.Length;
|
||||
|
|
@ -701,7 +790,7 @@ namespace Content.Server.Administration.Systems
|
|||
.ToList();
|
||||
}
|
||||
|
||||
private static string GenerateAHelpMessage(AHelpMessageParams parameters)
|
||||
private static DiscordRelayedData GenerateAHelpMessage(AHelpMessageParams parameters)
|
||||
{
|
||||
var stringbuilder = new StringBuilder();
|
||||
|
||||
|
|
@ -718,13 +807,57 @@ namespace Content.Server.Administration.Systems
|
|||
stringbuilder.Append($" **{parameters.RoundTime}**");
|
||||
if (!parameters.PlayedSound)
|
||||
stringbuilder.Append(" **(S)**");
|
||||
|
||||
if (parameters.Icon == null)
|
||||
stringbuilder.Append($" **{parameters.Username}:** ");
|
||||
else
|
||||
stringbuilder.Append($" **{parameters.Username}** ");
|
||||
stringbuilder.Append(parameters.Message);
|
||||
return stringbuilder.ToString();
|
||||
|
||||
return new DiscordRelayedData()
|
||||
{
|
||||
Receivers = !parameters.NoReceivers,
|
||||
Message = stringbuilder.ToString(),
|
||||
};
|
||||
}
|
||||
|
||||
private record struct DiscordRelayedData
|
||||
{
|
||||
/// <summary>
|
||||
/// Was anyone online to receive it.
|
||||
/// </summary>
|
||||
public bool Receivers;
|
||||
|
||||
/// <summary>
|
||||
/// What's the payload to send to discord.
|
||||
/// </summary>
|
||||
public string Message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class specifically for holding information regarding existing Discord embeds
|
||||
/// </summary>
|
||||
private sealed class DiscordRelayInteraction
|
||||
{
|
||||
public string? Id;
|
||||
|
||||
public string Username = String.Empty;
|
||||
|
||||
public string? CharacterName;
|
||||
|
||||
/// <summary>
|
||||
/// Contents for the discord message.
|
||||
/// </summary>
|
||||
public string Description = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Run level of the last interaction. If different we'll link to the last Id.
|
||||
/// </summary>
|
||||
public GameRunLevel LastRunLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Did we relay this interaction to OnCall previously.
|
||||
/// </summary>
|
||||
public bool OnCall;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public sealed partial class AmeControllerComponent : SharedAmeControllerComponen
|
|||
/// </summary>
|
||||
[DataField("injectSound")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public SoundSpecifier InjectSound = new SoundCollectionSpecifier("MetalThud");
|
||||
public SoundSpecifier InjectSound = new SoundPathSpecifier("/Audio/Machines/ame_fuelinjection.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// The last time this could have injected fuel into the AME.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public sealed class ExaminableDamageSystem : EntitySystem
|
|||
|
||||
var level = GetDamageLevel(uid, component);
|
||||
var msg = Loc.GetString(messages[level]);
|
||||
args.PushMarkup(msg);
|
||||
args.PushMarkup(msg,-99);
|
||||
}
|
||||
|
||||
private int GetDamageLevel(EntityUid uid, ExaminableDamageComponent? component = null,
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
SetBoltsDown(ent, true);
|
||||
}
|
||||
|
||||
UpdateBoltLightStatus(ent);
|
||||
ent.Comp.Powered = args.Powered;
|
||||
Dirty(ent, ent.Comp);
|
||||
UpdateBoltLightStatus(ent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
using Content.Shared.EntityEffects;
|
||||
using Content.Server.Flash;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.EntityEffects.Effects;
|
||||
|
||||
[DataDefinition]
|
||||
public sealed partial class FlashReactionEffect : EntityEffect
|
||||
{
|
||||
/// <summary>
|
||||
/// Flash range per unit of reagent.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float RangePerUnit = 0.2f;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum flash range.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float MaxRange = 10f;
|
||||
|
||||
/// <summary>
|
||||
/// How much to entities are slowed down.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float SlowTo = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// The time entities will be flashed in seconds.
|
||||
/// The default is chosen to be better than the hand flash so it is worth using it for grenades etc.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float Duration = 4f;
|
||||
|
||||
/// <summary>
|
||||
/// The prototype ID used for the visual effect.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId? FlashEffectPrototype = "ReactionFlash";
|
||||
|
||||
/// <summary>
|
||||
/// The sound the flash creates.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? Sound = new SoundPathSpecifier("/Audio/Weapons/flash.ogg");
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
|
||||
=> Loc.GetString("reagent-effect-guidebook-flash-reaction-effect", ("chance", Probability));
|
||||
|
||||
public override void Effect(EntityEffectBaseArgs args)
|
||||
{
|
||||
var transform = args.EntityManager.GetComponent<TransformComponent>(args.TargetEntity);
|
||||
var transformSystem = args.EntityManager.System<SharedTransformSystem>();
|
||||
|
||||
var range = 1f;
|
||||
|
||||
if (args is EntityEffectReagentArgs reagentArgs)
|
||||
range = MathF.Min((float)(reagentArgs.Quantity * RangePerUnit), MaxRange);
|
||||
|
||||
args.EntityManager.System<FlashSystem>().FlashArea(
|
||||
args.TargetEntity,
|
||||
null,
|
||||
range,
|
||||
Duration * 1000,
|
||||
slowTo: SlowTo,
|
||||
sound: Sound);
|
||||
|
||||
if (FlashEffectPrototype == null)
|
||||
return;
|
||||
|
||||
var uid = args.EntityManager.SpawnEntity(FlashEffectPrototype, transformSystem.GetMapCoordinates(transform));
|
||||
transformSystem.AttachToGridOrMap(uid);
|
||||
|
||||
if (!args.EntityManager.TryGetComponent<PointLightComponent>(uid, out var pointLightComp))
|
||||
return;
|
||||
var pointLightSystem = args.EntityManager.System<SharedPointLightSystem>();
|
||||
// PointLights with a radius lower than 1.1 are too small to be visible, so this is hardcoded
|
||||
pointLightSystem.SetRadius(uid, MathF.Max(1.1f, range), pointLightComp);
|
||||
}
|
||||
}
|
||||
|
|
@ -213,14 +213,7 @@ namespace Content.Server.Ghost
|
|||
|
||||
private void OnMapInit(EntityUid uid, GhostComponent component, MapInitEvent args)
|
||||
{
|
||||
if (_actions.AddAction(uid, ref component.BooActionEntity, out var act, component.BooAction)
|
||||
&& act.UseDelay != null)
|
||||
{
|
||||
var start = _gameTiming.CurTime;
|
||||
var end = start + act.UseDelay.Value;
|
||||
_actions.SetCooldown(component.BooActionEntity.Value, start, end);
|
||||
}
|
||||
|
||||
_actions.AddAction(uid, ref component.BooActionEntity, component.BooAction);
|
||||
_actions.AddAction(uid, ref component.ToggleGhostHearingActionEntity, component.ToggleGhostHearingAction);
|
||||
_actions.AddAction(uid, ref component.ToggleLightingActionEntity, component.ToggleLightingAction);
|
||||
_actions.AddAction(uid, ref component.ToggleFoVActionEntity, component.ToggleFoVAction);
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ public sealed partial class CryoPodSystem : SharedCryoPodSystem
|
|||
? bloodSolution.FillFraction
|
||||
: 0,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using Content.Server.Body.Components;
|
|||
using Content.Server.Medical.Components;
|
||||
using Content.Server.PowerCell;
|
||||
using Content.Server.Temperature.Components;
|
||||
using Content.Server.Traits.Assorted;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.DoAfter;
|
||||
|
|
@ -196,6 +197,7 @@ public sealed class HealthAnalyzerSystem : EntitySystem
|
|||
|
||||
var bloodAmount = float.NaN;
|
||||
var bleeding = false;
|
||||
var unrevivable = false;
|
||||
|
||||
if (TryComp<BloodstreamComponent>(target, out var bloodstream) &&
|
||||
_solutionContainerSystem.ResolveSolution(target, bloodstream.BloodSolutionName,
|
||||
|
|
@ -205,12 +207,16 @@ public sealed class HealthAnalyzerSystem : EntitySystem
|
|||
bleeding = bloodstream.BleedAmount > 0;
|
||||
}
|
||||
|
||||
if (HasComp<UnrevivableComponent>(target))
|
||||
unrevivable = true;
|
||||
|
||||
_uiSystem.ServerSendUiMessage(healthAnalyzer, HealthAnalyzerUiKey.Key, new HealthAnalyzerScannedUserMessage(
|
||||
GetNetEntity(target),
|
||||
bodyTemperature,
|
||||
bloodAmount,
|
||||
scanMode,
|
||||
bleeding
|
||||
bleeding,
|
||||
unrevivable
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ namespace Content.Server.Nutrition.EntitySystems
|
|||
|
||||
protected override void SplattedCreamPie(EntityUid uid, CreamPieComponent creamPie)
|
||||
{
|
||||
_audio.PlayPvs(_audio.GetSound(creamPie.Sound), uid, AudioParams.Default.WithVariation(0.125f));
|
||||
// The entity is deleted, so play the sound at its position rather than parenting
|
||||
var coordinates = Transform(uid).Coordinates;
|
||||
_audio.PlayPvs(_audio.GetSound(creamPie.Sound), coordinates, AudioParams.Default.WithVariation(0.125f));
|
||||
|
||||
if (EntityManager.TryGetComponent(uid, out FoodComponent? foodComp))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Content.Server.Shuttles.Events;
|
|||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Decals;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Gravity;
|
||||
using Content.Shared.Parallax.Biomes;
|
||||
using Content.Shared.Parallax.Biomes.Layers;
|
||||
|
|
@ -51,6 +52,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||
|
||||
private EntityQuery<BiomeComponent> _biomeQuery;
|
||||
private EntityQuery<FixturesComponent> _fixturesQuery;
|
||||
private EntityQuery<GhostComponent> _ghostQuery;
|
||||
private EntityQuery<TransformComponent> _xformQuery;
|
||||
|
||||
private readonly HashSet<EntityUid> _handledEntities = new();
|
||||
|
|
@ -81,6 +83,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||
Log.Level = LogLevel.Debug;
|
||||
_biomeQuery = GetEntityQuery<BiomeComponent>();
|
||||
_fixturesQuery = GetEntityQuery<FixturesComponent>();
|
||||
_ghostQuery = GetEntityQuery<GhostComponent>();
|
||||
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||
SubscribeLocalEvent<BiomeComponent, MapInitEvent>(OnBiomeMapInit);
|
||||
SubscribeLocalEvent<FTLStartedEvent>(OnFTLStarted);
|
||||
|
|
@ -315,6 +318,11 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||
}
|
||||
}
|
||||
|
||||
private bool CanLoad(EntityUid uid)
|
||||
{
|
||||
return !_ghostQuery.HasComp(uid);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
|
@ -332,7 +340,8 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||
if (_xformQuery.TryGetComponent(pSession.AttachedEntity, out var xform) &&
|
||||
_handledEntities.Add(pSession.AttachedEntity.Value) &&
|
||||
_biomeQuery.TryGetComponent(xform.MapUid, out var biome) &&
|
||||
biome.Enabled)
|
||||
biome.Enabled &&
|
||||
CanLoad(pSession.AttachedEntity.Value))
|
||||
{
|
||||
var worldPos = _transform.GetWorldPosition(xform);
|
||||
AddChunksInRange(biome, worldPos);
|
||||
|
|
@ -349,7 +358,8 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
|
|||
if (!_handledEntities.Add(viewer) ||
|
||||
!_xformQuery.TryGetComponent(viewer, out xform) ||
|
||||
!_biomeQuery.TryGetComponent(xform.MapUid, out biome) ||
|
||||
!biome.Enabled)
|
||||
!biome.Enabled ||
|
||||
!CanLoad(viewer))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public sealed class RadioDeviceSystem : EntitySystem
|
|||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
|
||||
// Used to prevent a shitter from using a bunch of radios to spam chat.
|
||||
private HashSet<(string, EntityUid)> _recentlySent = new();
|
||||
private HashSet<(string, EntityUid, RadioChannelPrototype)> _recentlySent = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -114,7 +114,7 @@ public sealed class RadioDeviceSystem : EntitySystem
|
|||
{
|
||||
if (args.Powered)
|
||||
return;
|
||||
SetMicrophoneEnabled(uid, null, false, true, component);
|
||||
SetMicrophoneEnabled(uid, null, false, true, component);
|
||||
}
|
||||
|
||||
public void SetMicrophoneEnabled(EntityUid uid, EntityUid? user, bool enabled, bool quiet = false, RadioMicrophoneComponent? component = null)
|
||||
|
|
@ -191,8 +191,9 @@ public sealed class RadioDeviceSystem : EntitySystem
|
|||
if (HasComp<RadioSpeakerComponent>(args.Source))
|
||||
return; // no feedback loops please.
|
||||
|
||||
if (_recentlySent.Add((args.Message, args.Source)))
|
||||
_radio.SendRadioMessage(args.Source, args.Message, _protoMan.Index<RadioChannelPrototype>(component.BroadcastChannel), uid);
|
||||
var channel = _protoMan.Index<RadioChannelPrototype>(component.BroadcastChannel)!;
|
||||
if (_recentlySent.Add((args.Message, args.Source, channel)))
|
||||
_radio.SendRadioMessage(args.Source, args.Message, channel, uid);
|
||||
}
|
||||
|
||||
private void OnAttemptListen(EntityUid uid, RadioMicrophoneComponent component, ListenAttemptEvent args)
|
||||
|
|
@ -279,7 +280,7 @@ public sealed class RadioDeviceSystem : EntitySystem
|
|||
if (TryComp<RadioMicrophoneComponent>(ent, out var mic))
|
||||
mic.BroadcastChannel = channel;
|
||||
if (TryComp<RadioSpeakerComponent>(ent, out var speaker))
|
||||
speaker.Channels = new(){ channel };
|
||||
speaker.Channels = new() { channel };
|
||||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace Content.Server.Voting.Managers
|
|||
|
||||
private VotingSystem? _votingSystem;
|
||||
private RoleSystem? _roleSystem;
|
||||
private GameTicker? _gameTicker;
|
||||
|
||||
private static readonly Dictionary<StandardVoteType, CVarDef<bool>> _voteTypesToEnableCVars = new()
|
||||
{
|
||||
|
|
@ -70,8 +71,8 @@ namespace Content.Server.Voting.Managers
|
|||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(voteType), voteType, null);
|
||||
}
|
||||
var ticker = _entityManager.EntitySysManager.GetEntitySystem<GameTicker>();
|
||||
ticker.UpdateInfoText();
|
||||
_gameTicker = _entityManager.EntitySysManager.GetEntitySystem<GameTicker>();
|
||||
_gameTicker.UpdateInfoText();
|
||||
if (timeoutVote)
|
||||
TimeoutStandardVote(voteType);
|
||||
}
|
||||
|
|
@ -346,8 +347,14 @@ namespace Content.Server.Voting.Managers
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var voterEligibility = _cfg.GetCVar(CCVars.VotekickVoterGhostRequirement) ? VoterEligibility.GhostMinimumPlaytime : VoterEligibility.MinimumPlaytime;
|
||||
if (_cfg.GetCVar(CCVars.VotekickIgnoreGhostReqInLobby) && _gameTicker!.RunLevel == GameRunLevel.PreRoundLobby)
|
||||
voterEligibility = VoterEligibility.MinimumPlaytime;
|
||||
|
||||
var eligibleVoterNumberRequirement = _cfg.GetCVar(CCVars.VotekickEligibleNumberRequirement);
|
||||
var eligibleVoterNumber = _cfg.GetCVar(CCVars.VotekickVoterGhostRequirement) ? CalculateEligibleVoterNumber(VoterEligibility.GhostMinimumPlaytime) : CalculateEligibleVoterNumber(VoterEligibility.MinimumPlaytime);
|
||||
var eligibleVoterNumber = CalculateEligibleVoterNumber(voterEligibility);
|
||||
|
||||
string target = args[0];
|
||||
string reason = args[1];
|
||||
|
|
@ -441,7 +448,7 @@ namespace Content.Server.Voting.Managers
|
|||
},
|
||||
Duration = TimeSpan.FromSeconds(_cfg.GetCVar(CCVars.VotekickTimer)),
|
||||
InitiatorTimeout = TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.VotekickTimeout)),
|
||||
VoterEligibility = _cfg.GetCVar(CCVars.VotekickVoterGhostRequirement) ? VoterEligibility.GhostMinimumPlaytime : VoterEligibility.MinimumPlaytime,
|
||||
VoterEligibility = voterEligibility,
|
||||
DisplayVotes = false,
|
||||
TargetEntity = targetNetEntity
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Content.Server.Administration.Managers;
|
||||
using Content.Server.Database;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Ghost;
|
||||
using Content.Server.Roles.Jobs;
|
||||
using Content.Shared.CCVar;
|
||||
|
|
@ -12,6 +13,7 @@ using Robust.Shared.Network;
|
|||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Players.PlayTimeTracking;
|
||||
|
||||
namespace Content.Server.Voting;
|
||||
|
||||
|
|
@ -24,6 +26,8 @@ public sealed class VotingSystem : EntitySystem
|
|||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly JobSystem _jobs = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly ISharedPlaytimeManager _playtimeManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -34,8 +38,7 @@ public sealed class VotingSystem : EntitySystem
|
|||
|
||||
private async void OnVotePlayerListRequestEvent(VotePlayerListRequestEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession.AttachedEntity is not { Valid: true } entity
|
||||
|| !await CheckVotekickInitEligibility(args.SenderSession))
|
||||
if (!await CheckVotekickInitEligibility(args.SenderSession))
|
||||
{
|
||||
var deniedResponse = new VotePlayerListResponseEvent(new (NetUserId, NetEntity, string)[0], true);
|
||||
RaiseNetworkEvent(deniedResponse, args.SenderSession.Channel);
|
||||
|
|
@ -46,17 +49,23 @@ public sealed class VotingSystem : EntitySystem
|
|||
|
||||
foreach (var player in _playerManager.Sessions)
|
||||
{
|
||||
if (player.AttachedEntity is not { Valid: true } attached)
|
||||
continue;
|
||||
|
||||
if (attached == entity) continue;
|
||||
if (args.SenderSession == player) continue;
|
||||
|
||||
if (_adminManager.IsAdmin(player, false)) continue;
|
||||
|
||||
var playerName = GetPlayerVoteListName(attached);
|
||||
var netEntity = GetNetEntity(attached);
|
||||
if (player.AttachedEntity is not { Valid: true } attached)
|
||||
{
|
||||
var playerName = player.Name;
|
||||
var netEntity = NetEntity.Invalid;
|
||||
players.Add((player.UserId, netEntity, playerName));
|
||||
}
|
||||
else
|
||||
{
|
||||
var playerName = GetPlayerVoteListName(attached);
|
||||
var netEntity = GetNetEntity(attached);
|
||||
|
||||
players.Add((player.UserId, netEntity, playerName));
|
||||
players.Add((player.UserId, netEntity, playerName));
|
||||
}
|
||||
}
|
||||
|
||||
var response = new VotePlayerListResponseEvent(players.ToArray(), false);
|
||||
|
|
@ -86,22 +95,29 @@ public sealed class VotingSystem : EntitySystem
|
|||
if (initiator.AttachedEntity != null && _adminManager.IsAdmin(initiator.AttachedEntity.Value, false))
|
||||
return true;
|
||||
|
||||
if (_cfg.GetCVar(CCVars.VotekickInitiatorGhostRequirement))
|
||||
// If cvar enabled, skip the ghost requirement in the preround lobby
|
||||
if (!_cfg.GetCVar(CCVars.VotekickIgnoreGhostReqInLobby) || (_cfg.GetCVar(CCVars.VotekickIgnoreGhostReqInLobby) && _gameTicker.RunLevel != GameRunLevel.PreRoundLobby))
|
||||
{
|
||||
// Must be ghost
|
||||
if (!TryComp(initiator.AttachedEntity, out GhostComponent? ghostComp))
|
||||
return false;
|
||||
if (_cfg.GetCVar(CCVars.VotekickInitiatorGhostRequirement))
|
||||
{
|
||||
// Must be ghost
|
||||
if (!TryComp(initiator.AttachedEntity, out GhostComponent? ghostComp))
|
||||
return false;
|
||||
|
||||
// Must have been dead for x seconds
|
||||
if ((int)_gameTiming.RealTime.Subtract(ghostComp.TimeOfDeath).TotalSeconds < _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime))
|
||||
return false;
|
||||
// Must have been dead for x seconds
|
||||
if ((int)_gameTiming.RealTime.Subtract(ghostComp.TimeOfDeath).TotalSeconds < _cfg.GetCVar(CCVars.VotekickEligibleVoterDeathtime))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Must be whitelisted
|
||||
if (!await _dbManager.GetWhitelistStatusAsync(initiator.UserId))
|
||||
if (!await _dbManager.GetWhitelistStatusAsync(initiator.UserId) && _cfg.GetCVar(CCVars.VotekickInitiatorWhitelistedRequirement))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
// Must be eligible to vote
|
||||
var playtime = _playtimeManager.GetPlayTimes(initiator);
|
||||
return playtime.TryGetValue(PlayTimeTrackingShared.TrackerOverall, out TimeSpan overallTime) && (overallTime >= TimeSpan.FromHours(_cfg.GetCVar(CCVars.VotekickEligibleVoterPlaytime))
|
||||
|| !_cfg.GetCVar(CCVars.VotekickInitiatorTimeRequirement));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -76,6 +76,11 @@ public abstract partial class BaseActionComponent : Component
|
|||
// TODO serialization
|
||||
public (TimeSpan Start, TimeSpan End)? Cooldown;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the action will have an initial cooldown applied upon addition.
|
||||
/// </summary>
|
||||
[DataField] public bool StartDelay = false;
|
||||
|
||||
/// <summary>
|
||||
/// Time interval between action uses.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -813,6 +813,9 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||
if (action.AttachedEntity != null)
|
||||
RemoveAction(action.AttachedEntity.Value, actionId, action: action);
|
||||
|
||||
if (action.StartDelay && action.UseDelay != null)
|
||||
SetCooldown(actionId, action.UseDelay.Value);
|
||||
|
||||
DebugTools.AssertOwner(performer, comp);
|
||||
comp ??= EnsureComp<ActionsComponent>(performer);
|
||||
action.AttachedEntity = performer;
|
||||
|
|
|
|||
|
|
@ -130,9 +130,6 @@ public sealed partial class SleepingSystem : EntitySystem
|
|||
RaiseLocalEvent(ent, ref ev);
|
||||
_blindableSystem.UpdateIsBlind(ent.Owner);
|
||||
_actionsSystem.AddAction(ent, ref ent.Comp.WakeAction, WakeActionId, ent);
|
||||
|
||||
// TODO remove hardcoded time.
|
||||
_actionsSystem.SetCooldown(ent.Comp.WakeAction, _gameTiming.CurTime, _gameTiming.CurTime + TimeSpan.FromSeconds(2f));
|
||||
}
|
||||
|
||||
private void OnSpeakAttempt(Entity<SleepingComponent> ent, ref SpeakAttemptEvent args)
|
||||
|
|
|
|||
|
|
@ -461,6 +461,18 @@ namespace Content.Shared.CCVar
|
|||
* Discord
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// The role that will get mentioned if a new SOS ahelp comes in.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordAhelpMention =
|
||||
CVarDef.Create("discord.on_call_ping", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the discord webhook to relay unanswered ahelp messages.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<string> DiscordOnCallWebhook =
|
||||
CVarDef.Create("discord.on_call_webhook", string.Empty, CVar.SERVERONLY | CVar.CONFIDENTIAL);
|
||||
|
||||
/// <summary>
|
||||
/// URL of the Discord webhook which will relay all ahelp messages.
|
||||
/// </summary>
|
||||
|
|
@ -1469,7 +1481,7 @@ namespace Content.Shared.CCVar
|
|||
/// Config for when the votekick should be allowed to be called based on number of eligible voters.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickEligibleNumberRequirement =
|
||||
CVarDef.Create("votekick.eligible_number", 10, CVar.SERVERONLY);
|
||||
CVarDef.Create("votekick.eligible_number", 5, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether a votekick initiator must be a ghost or not.
|
||||
|
|
@ -1477,6 +1489,18 @@ namespace Content.Shared.CCVar
|
|||
public static readonly CVarDef<bool> VotekickInitiatorGhostRequirement =
|
||||
CVarDef.Create("votekick.initiator_ghost_requirement", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the initiator be whitelisted to initiate a votekick?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickInitiatorWhitelistedRequirement =
|
||||
CVarDef.Create("votekick.initiator_whitelist_requirement", true, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Should the initiator be able to start a votekick if they are bellow the votekick.voter_playtime requirement?
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickInitiatorTimeRequirement =
|
||||
CVarDef.Create("votekick.initiator_time_requirement", false, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether a votekick voter must be a ghost or not.
|
||||
/// </summary>
|
||||
|
|
@ -1493,7 +1517,7 @@ namespace Content.Shared.CCVar
|
|||
/// Config for how many seconds a player must have been dead to initiate a votekick / be able to vote on a votekick.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<int> VotekickEligibleVoterDeathtime =
|
||||
CVarDef.Create("votekick.voter_deathtime", 180, CVar.REPLICATED | CVar.SERVER);
|
||||
CVarDef.Create("votekick.voter_deathtime", 30, CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// The required ratio of eligible voters that must agree for a votekick to go through.
|
||||
|
|
@ -1537,6 +1561,12 @@ namespace Content.Shared.CCVar
|
|||
public static readonly CVarDef<int> VotekickBanDuration =
|
||||
CVarDef.Create("votekick.ban_duration", 180, CVar.SERVERONLY);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the ghost requirement settings for votekicks should be ignored for the lobby.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<bool> VotekickIgnoreGhostReqInLobby =
|
||||
CVarDef.Create("votekick.ignore_ghost_req_in_lobby", true, CVar.SERVERONLY);
|
||||
|
||||
/*
|
||||
* BAN
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public sealed partial class CartridgeLoaderComponent : Component
|
|||
/// The maximum amount of programs that can be installed on the cartridge loader entity
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int DiskSpace = 5;
|
||||
public int DiskSpace = 8;
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether the cartridge loader will play notifications if it supports it at all
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
namespace Content.Shared.Chemistry.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a container that also contains a solution.
|
||||
/// This means that reactive entities react when inserted into the container.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class ReactiveContainerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The container that holds the solution.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Container = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The solution in the container.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Solution = default!;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Shared.Chemistry.EntitySystems;
|
||||
|
||||
public sealed class ReactiveContainerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly ReactiveSystem _reactiveSystem = default!;
|
||||
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ReactiveContainerComponent, EntInsertedIntoContainerMessage>(OnInserted);
|
||||
SubscribeLocalEvent<ReactiveContainerComponent, SolutionContainerChangedEvent>(OnSolutionChange);
|
||||
}
|
||||
|
||||
private void OnInserted(EntityUid uid, ReactiveContainerComponent comp, EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
// Only reactive entities can react with the solution
|
||||
if (!HasComp<ReactiveComponent>(args.Entity))
|
||||
return;
|
||||
|
||||
if (!_solutionContainerSystem.TryGetSolution(uid, comp.Solution, out _, out var solution))
|
||||
return;
|
||||
if (solution.Volume == 0)
|
||||
return;
|
||||
|
||||
_reactiveSystem.DoEntityReaction(args.Entity, solution, ReactionMethod.Touch);
|
||||
}
|
||||
|
||||
private void OnSolutionChange(EntityUid uid, ReactiveContainerComponent comp, SolutionContainerChangedEvent args)
|
||||
{
|
||||
if (!_solutionContainerSystem.TryGetSolution(uid, comp.Solution, out _, out var solution))
|
||||
return;
|
||||
if (solution.Volume == 0)
|
||||
return;
|
||||
if (!TryComp<ContainerManagerComponent>(uid, out var manager))
|
||||
return;
|
||||
if (!_containerSystem.TryGetContainer(uid, comp.Container, out var container))
|
||||
return;
|
||||
|
||||
foreach (var entity in container.ContainedEntities)
|
||||
{
|
||||
if (!HasComp<ReactiveComponent>(entity))
|
||||
continue;
|
||||
_reactiveSystem.DoEntityReaction(entity, solution, ReactionMethod.Touch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,7 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
}
|
||||
|
||||
#region ComponentManagement
|
||||
|
||||
/// <summary>
|
||||
/// Spawn in starting items for any item slots that should have one.
|
||||
/// </summary>
|
||||
|
|
@ -70,7 +71,8 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
if (slot.HasItem || string.IsNullOrEmpty(slot.StartingItem))
|
||||
continue;
|
||||
|
||||
var item = EntityManager.SpawnEntity(slot.StartingItem, EntityManager.GetComponent<TransformComponent>(uid).Coordinates);
|
||||
var item = Spawn(slot.StartingItem, Transform(uid).Coordinates);
|
||||
|
||||
if (slot.ContainerSlot != null)
|
||||
_containers.Insert(item, slot.ContainerSlot);
|
||||
}
|
||||
|
|
@ -99,7 +101,8 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
if (itemSlots.Slots.TryGetValue(id, out var existing))
|
||||
{
|
||||
if (existing.Local)
|
||||
Log.Error($"Duplicate item slot key. Entity: {EntityManager.GetComponent<MetaDataComponent>(uid).EntityName} ({uid}), key: {id}");
|
||||
Log.Error(
|
||||
$"Duplicate item slot key. Entity: {EntityManager.GetComponent<MetaDataComponent>(uid).EntityName} ({uid}), key: {id}");
|
||||
else
|
||||
// server state takes priority
|
||||
slot.CopyFrom(existing);
|
||||
|
|
@ -134,7 +137,10 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
Dirty(uid, itemSlots);
|
||||
}
|
||||
|
||||
public bool TryGetSlot(EntityUid uid, string slotId, [NotNullWhen(true)] out ItemSlot? itemSlot, ItemSlotsComponent? component = null)
|
||||
public bool TryGetSlot(EntityUid uid,
|
||||
string slotId,
|
||||
[NotNullWhen(true)] out ItemSlot? itemSlot,
|
||||
ItemSlotsComponent? component = null)
|
||||
{
|
||||
itemSlot = null;
|
||||
|
||||
|
|
@ -143,9 +149,11 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
|
||||
return component.Slots.TryGetValue(slotId, out itemSlot);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Interactions
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to take an item from a slot, if any are set to EjectOnInteract.
|
||||
/// </summary>
|
||||
|
|
@ -201,20 +209,50 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
if (!EntityManager.TryGetComponent(args.User, out HandsComponent? hands))
|
||||
return;
|
||||
|
||||
if (itemSlots.Slots.Count == 0)
|
||||
return;
|
||||
|
||||
// If any slot can be inserted into don't show popup.
|
||||
// If any whitelist passes, but slot is locked, then show locked.
|
||||
// If whitelist fails all, show whitelist fail.
|
||||
|
||||
// valid, insertable slots (if any)
|
||||
var slots = new List<ItemSlot>();
|
||||
|
||||
string? whitelistFailPopup = null;
|
||||
string? lockedFailPopup = null;
|
||||
foreach (var slot in itemSlots.Slots.Values)
|
||||
{
|
||||
if (!slot.InsertOnInteract)
|
||||
continue;
|
||||
|
||||
if (!CanInsert(uid, args.Used, args.User, slot, swap: slot.Swap, popup: args.User))
|
||||
continue;
|
||||
if (CanInsert(uid, args.Used, args.User, slot, slot.Swap))
|
||||
{
|
||||
slots.Add(slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
var allowed = CanInsertWhitelist(args.Used, slot);
|
||||
if (lockedFailPopup == null && slot.LockedFailPopup != null && allowed && slot.Locked)
|
||||
lockedFailPopup = slot.LockedFailPopup;
|
||||
|
||||
slots.Add(slot);
|
||||
if (whitelistFailPopup == null && slot.WhitelistFailPopup != null)
|
||||
whitelistFailPopup = slot.WhitelistFailPopup;
|
||||
}
|
||||
}
|
||||
|
||||
if (slots.Count == 0)
|
||||
{
|
||||
// it's a bit weird that the popupMessage is stored with the item slots themselves, but in practice
|
||||
// the popup messages will just all be the same, so it's probably fine.
|
||||
//
|
||||
// doing a check to make sure that they're all the same or something is probably frivolous
|
||||
if (lockedFailPopup != null)
|
||||
_popupSystem.PopupClient(Loc.GetString(lockedFailPopup), uid, args.User);
|
||||
else if (whitelistFailPopup != null)
|
||||
_popupSystem.PopupClient(Loc.GetString(whitelistFailPopup), uid, args.User);
|
||||
return;
|
||||
}
|
||||
|
||||
// Drop the held item onto the floor. Return if the user cannot drop.
|
||||
if (!_handsSystem.TryDrop(args.User, args.Used, handsComp: hands))
|
||||
|
|
@ -236,23 +274,31 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Insert
|
||||
|
||||
/// <summary>
|
||||
/// Insert an item into a slot. This does not perform checks, so make sure to also use <see
|
||||
/// cref="CanInsert"/> or just use <see cref="TryInsert"/> instead.
|
||||
/// </summary>
|
||||
/// <param name="excludeUserAudio">If true, will exclude the user when playing sound. Does nothing client-side.
|
||||
/// Useful for predicted interactions</param>
|
||||
private void Insert(EntityUid uid, ItemSlot slot, EntityUid item, EntityUid? user, bool excludeUserAudio = false)
|
||||
private void Insert(EntityUid uid,
|
||||
ItemSlot slot,
|
||||
EntityUid item,
|
||||
EntityUid? user,
|
||||
bool excludeUserAudio = false)
|
||||
{
|
||||
bool? inserted = slot.ContainerSlot != null ? _containers.Insert(item, slot.ContainerSlot) : null;
|
||||
// ContainerSlot automatically raises a directed EntInsertedIntoContainerMessage
|
||||
|
||||
// Logging
|
||||
if (inserted != null && inserted.Value && user != null)
|
||||
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user.Value)} inserted {ToPrettyString(item)} into {slot.ContainerSlot?.ID + " slot of "}{ToPrettyString(uid)}");
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Low,
|
||||
$"{ToPrettyString(user.Value)} inserted {ToPrettyString(item)} into {slot.ContainerSlot?.ID + " slot of "}{ToPrettyString(uid)}");
|
||||
|
||||
_audioSystem.PlayPredicted(slot.InsertSound, uid, excludeUserAudio ? user : null);
|
||||
}
|
||||
|
|
@ -261,46 +307,53 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
/// Check whether a given item can be inserted into a slot. Unless otherwise specified, this will return
|
||||
/// false if the slot is already filled.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If a popup entity is given, and if the item slot is set to generate a popup message when it fails to
|
||||
/// pass the whitelist or due to slot being locked, then this will generate an appropriate popup.
|
||||
/// </remarks>
|
||||
public bool CanInsert(EntityUid uid, EntityUid usedUid, EntityUid? user, ItemSlot slot, bool swap = false, EntityUid? popup = null)
|
||||
public bool CanInsert(EntityUid uid,
|
||||
EntityUid usedUid,
|
||||
EntityUid? user,
|
||||
ItemSlot slot,
|
||||
bool swap = false)
|
||||
{
|
||||
if (slot.ContainerSlot == null)
|
||||
return false;
|
||||
|
||||
if (_whitelistSystem.IsWhitelistFail(slot.Whitelist, usedUid) || _whitelistSystem.IsBlacklistPass(slot.Blacklist, usedUid))
|
||||
{
|
||||
if (popup.HasValue && slot.WhitelistFailPopup.HasValue)
|
||||
_popupSystem.PopupClient(Loc.GetString(slot.WhitelistFailPopup), uid, popup.Value);
|
||||
if (slot.HasItem && (!swap || swap && !CanEject(uid, user, slot)))
|
||||
return false;
|
||||
|
||||
if (!CanInsertWhitelist(usedUid, slot))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slot.Locked)
|
||||
{
|
||||
if (popup.HasValue && slot.LockedFailPopup.HasValue)
|
||||
_popupSystem.PopupClient(Loc.GetString(slot.LockedFailPopup), uid, popup.Value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slot.HasItem && (!swap || (swap && !CanEject(uid, user, slot))))
|
||||
return false;
|
||||
|
||||
var ev = new ItemSlotInsertAttemptEvent(uid, usedUid, user, slot);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
RaiseLocalEvent(usedUid, ref ev);
|
||||
if (ev.Cancelled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _containers.CanInsert(usedUid, slot.ContainerSlot, assumeEmpty: swap);
|
||||
}
|
||||
|
||||
private bool CanInsertWhitelist(EntityUid usedUid, ItemSlot slot)
|
||||
{
|
||||
if (_whitelistSystem.IsWhitelistFail(slot.Whitelist, usedUid)
|
||||
|| _whitelistSystem.IsBlacklistPass(slot.Blacklist, usedUid))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to insert item into a specific slot.
|
||||
/// </summary>
|
||||
/// <returns>False if failed to insert item</returns>
|
||||
public bool TryInsert(EntityUid uid, string id, EntityUid item, EntityUid? user, ItemSlotsComponent? itemSlots = null, bool excludeUserAudio = false)
|
||||
public bool TryInsert(EntityUid uid,
|
||||
string id,
|
||||
EntityUid item,
|
||||
EntityUid? user,
|
||||
ItemSlotsComponent? itemSlots = null,
|
||||
bool excludeUserAudio = false)
|
||||
{
|
||||
if (!Resolve(uid, ref itemSlots))
|
||||
return false;
|
||||
|
|
@ -315,7 +368,11 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
/// Tries to insert item into a specific slot.
|
||||
/// </summary>
|
||||
/// <returns>False if failed to insert item</returns>
|
||||
public bool TryInsert(EntityUid uid, ItemSlot slot, EntityUid item, EntityUid? user, bool excludeUserAudio = false)
|
||||
public bool TryInsert(EntityUid uid,
|
||||
ItemSlot slot,
|
||||
EntityUid item,
|
||||
EntityUid? user,
|
||||
bool excludeUserAudio = false)
|
||||
{
|
||||
if (!CanInsert(uid, item, user, slot))
|
||||
return false;
|
||||
|
|
@ -329,7 +386,11 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
/// Does not check action blockers.
|
||||
/// </summary>
|
||||
/// <returns>False if failed to insert item</returns>
|
||||
public bool TryInsertFromHand(EntityUid uid, ItemSlot slot, EntityUid user, HandsComponent? hands = null, bool excludeUserAudio = false)
|
||||
public bool TryInsertFromHand(EntityUid uid,
|
||||
ItemSlot slot,
|
||||
EntityUid user,
|
||||
HandsComponent? hands = null,
|
||||
bool excludeUserAudio = false)
|
||||
{
|
||||
if (!Resolve(user, ref hands, false))
|
||||
return false;
|
||||
|
|
@ -406,6 +467,7 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Eject
|
||||
|
|
@ -425,7 +487,7 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
return false;
|
||||
}
|
||||
|
||||
if (slot.ContainerSlot?.ContainedEntity is not {} item)
|
||||
if (slot.ContainerSlot?.ContainedEntity is not { } item)
|
||||
return false;
|
||||
|
||||
var ev = new ItemSlotEjectAttemptEvent(uid, item, user, slot);
|
||||
|
|
@ -450,7 +512,9 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
|
||||
// Logging
|
||||
if (ejected != null && ejected.Value && user != null)
|
||||
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user.Value)} ejected {ToPrettyString(item)} from {slot.ContainerSlot?.ID + " slot of "}{ToPrettyString(uid)}");
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Low,
|
||||
$"{ToPrettyString(user.Value)} ejected {ToPrettyString(item)} from {slot.ContainerSlot?.ID + " slot of "}{ToPrettyString(uid)}");
|
||||
|
||||
_audioSystem.PlayPredicted(slot.EjectSound, uid, excludeUserAudio ? user : null);
|
||||
}
|
||||
|
|
@ -459,7 +523,11 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
/// Try to eject an item from a slot.
|
||||
/// </summary>
|
||||
/// <returns>False if item slot is locked or has no item inserted</returns>
|
||||
public bool TryEject(EntityUid uid, ItemSlot slot, EntityUid? user, [NotNullWhen(true)] out EntityUid? item, bool excludeUserAudio = false)
|
||||
public bool TryEject(EntityUid uid,
|
||||
ItemSlot slot,
|
||||
EntityUid? user,
|
||||
[NotNullWhen(true)] out EntityUid? item,
|
||||
bool excludeUserAudio = false)
|
||||
{
|
||||
item = null;
|
||||
|
||||
|
|
@ -481,8 +549,12 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
/// Try to eject item from a slot.
|
||||
/// </summary>
|
||||
/// <returns>False if the id is not valid, the item slot is locked, or it has no item inserted</returns>
|
||||
public bool TryEject(EntityUid uid, string id, EntityUid? user,
|
||||
[NotNullWhen(true)] out EntityUid? item, ItemSlotsComponent? itemSlots = null, bool excludeUserAudio = false)
|
||||
public bool TryEject(EntityUid uid,
|
||||
string id,
|
||||
EntityUid? user,
|
||||
[NotNullWhen(true)] out EntityUid? item,
|
||||
ItemSlotsComponent? itemSlots = null,
|
||||
bool excludeUserAudio = false)
|
||||
{
|
||||
item = null;
|
||||
|
||||
|
|
@ -513,12 +585,16 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Verbs
|
||||
private void AddAlternativeVerbs(EntityUid uid, ItemSlotsComponent itemSlots, GetVerbsEvent<AlternativeVerb> args)
|
||||
|
||||
private void AddAlternativeVerbs(EntityUid uid,
|
||||
ItemSlotsComponent itemSlots,
|
||||
GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (args.Hands == null || !args.CanAccess ||!args.CanInteract)
|
||||
if (args.Hands == null || !args.CanAccess || !args.CanInteract)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -612,7 +688,9 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
}
|
||||
}
|
||||
|
||||
private void AddInteractionVerbsVerbs(EntityUid uid, ItemSlotsComponent itemSlots, GetVerbsEvent<InteractionVerb> args)
|
||||
private void AddInteractionVerbsVerbs(EntityUid uid,
|
||||
ItemSlotsComponent itemSlots,
|
||||
GetVerbsEvent<InteractionVerb> args)
|
||||
{
|
||||
if (args.Hands == null || !args.CanAccess || !args.CanInteract)
|
||||
return;
|
||||
|
|
@ -671,7 +749,7 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
new SpriteSpecifier.Texture(
|
||||
new ResPath("/Textures/Interface/VerbIcons/insert.svg.192dpi.png"));
|
||||
}
|
||||
else if(slot.EjectOnInteract)
|
||||
else if (slot.EjectOnInteract)
|
||||
{
|
||||
// Inserting/ejecting is a primary interaction for this entity. Instead of using the insert
|
||||
// category, we will use a single "Place <item>" verb.
|
||||
|
|
@ -690,9 +768,11 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
args.Verbs.Add(insertVerb);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BUIs
|
||||
|
||||
private void HandleButtonPressed(EntityUid uid, ItemSlotsComponent component, ItemSlotButtonPressedEvent args)
|
||||
{
|
||||
if (!component.Slots.TryGetValue(args.SlotId, out var slot))
|
||||
|
|
@ -703,6 +783,7 @@ namespace Content.Shared.Containers.ItemSlots
|
|||
else if (args.TryInsert && !slot.HasItem)
|
||||
TryInsertFromHand(uid, slot, args.Actor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public abstract partial class InventorySystem
|
|||
|
||||
private void OnEntRemoved(EntityUid uid, InventoryComponent component, EntRemovedFromContainerMessage args)
|
||||
{
|
||||
if(!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component))
|
||||
if (!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component))
|
||||
return;
|
||||
|
||||
var unequippedEvent = new DidUnequipEvent(uid, args.Entity, slotDef);
|
||||
|
|
@ -59,8 +59,8 @@ public abstract partial class InventorySystem
|
|||
|
||||
private void OnEntInserted(EntityUid uid, InventoryComponent component, EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
if(!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component))
|
||||
return;
|
||||
if (!TryGetSlot(uid, args.Container.ID, out var slotDef, inventory: component))
|
||||
return;
|
||||
|
||||
var equippedEvent = new DidEquipEvent(uid, args.Entity, slotDef);
|
||||
RaiseLocalEvent(uid, equippedEvent, true);
|
||||
|
|
@ -118,7 +118,7 @@ public abstract partial class InventorySystem
|
|||
|
||||
RaiseLocalEvent(held.Value, new HandDeselectedEvent(actor));
|
||||
|
||||
TryEquip(actor, actor, held.Value, ev.Slot, predicted: true, inventory: inventory, force: true, checkDoafter:true);
|
||||
TryEquip(actor, actor, held.Value, ev.Slot, predicted: true, inventory: inventory, force: true, checkDoafter: true);
|
||||
}
|
||||
|
||||
public bool TryEquip(EntityUid uid, EntityUid itemUid, string slot, bool silent = false, bool force = false, bool predicted = false,
|
||||
|
|
@ -365,6 +365,25 @@ public abstract partial class InventorySystem
|
|||
ClothingComponent? clothing = null,
|
||||
bool reparent = true,
|
||||
bool checkDoafter = false)
|
||||
{
|
||||
var itemsDropped = 0;
|
||||
return TryUnequip(actor, target, slot, out removedItem, ref itemsDropped,
|
||||
silent, force, predicted, inventory, clothing, reparent, checkDoafter);
|
||||
}
|
||||
|
||||
private bool TryUnequip(
|
||||
EntityUid actor,
|
||||
EntityUid target,
|
||||
string slot,
|
||||
[NotNullWhen(true)] out EntityUid? removedItem,
|
||||
ref int itemsDropped,
|
||||
bool silent = false,
|
||||
bool force = false,
|
||||
bool predicted = false,
|
||||
InventoryComponent? inventory = null,
|
||||
ClothingComponent? clothing = null,
|
||||
bool reparent = true,
|
||||
bool checkDoafter = false)
|
||||
{
|
||||
removedItem = null;
|
||||
|
||||
|
|
@ -423,17 +442,27 @@ public abstract partial class InventorySystem
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!_containerSystem.Remove(removedItem.Value, slotContainer, force: force, reparent: reparent))
|
||||
return false;
|
||||
|
||||
// this is in order to keep track of whether this is the first instance of a recursion call
|
||||
var firstRun = itemsDropped == 0;
|
||||
++itemsDropped;
|
||||
|
||||
foreach (var slotDef in inventory.Slots)
|
||||
{
|
||||
if (slotDef != slotDefinition && slotDef.DependsOn == slotDefinition.Name)
|
||||
{
|
||||
//this recursive call might be risky
|
||||
TryUnequip(actor, target, slotDef.Name, true, true, predicted, inventory, reparent: reparent);
|
||||
TryUnequip(actor, target, slotDef.Name, out _, ref itemsDropped, true, true, predicted, inventory, reparent: reparent);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_containerSystem.Remove(removedItem.Value, slotContainer, force: force, reparent: reparent))
|
||||
return false;
|
||||
// we check if any items were dropped, and make a popup if they were.
|
||||
// the reason we check for > 1 is because the first item is always the one we are trying to unequip,
|
||||
// whereas we only want to notify for extra dropped items.
|
||||
if (!silent && _gameTiming.IsFirstTimePredicted && firstRun && itemsDropped > 1)
|
||||
_popup.PopupClient(Loc.GetString("inventory-component-dropped-from-unequip", ("items", itemsDropped - 1)), target, target);
|
||||
|
||||
// TODO: Inventory needs a hot cleanup hoo boy
|
||||
// Check if something else (AKA toggleable) dumped it into a container.
|
||||
|
|
@ -466,7 +495,7 @@ public abstract partial class InventorySystem
|
|||
if ((containerSlot == null || slotDefinition == null) && !TryGetSlotContainer(target, slot, out containerSlot, out slotDefinition, inventory))
|
||||
return false;
|
||||
|
||||
if (containerSlot.ContainedEntity is not {} itemUid)
|
||||
if (containerSlot.ContainedEntity is not { } itemUid)
|
||||
return false;
|
||||
|
||||
if (!_containerSystem.CanRemove(itemUid, containerSlot))
|
||||
|
|
|
|||
|
|
@ -13,14 +13,16 @@ public sealed class HealthAnalyzerScannedUserMessage : BoundUserInterfaceMessage
|
|||
public float BloodLevel;
|
||||
public bool? ScanMode;
|
||||
public bool? Bleeding;
|
||||
public bool? Unrevivable;
|
||||
|
||||
public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding)
|
||||
public HealthAnalyzerScannedUserMessage(NetEntity? targetEntity, float temperature, float bloodLevel, bool? scanMode, bool? bleeding, bool? unrevivable)
|
||||
{
|
||||
TargetEntity = targetEntity;
|
||||
Temperature = temperature;
|
||||
BloodLevel = bloodLevel;
|
||||
ScanMode = scanMode;
|
||||
Bleeding = bleeding;
|
||||
Unrevivable = unrevivable;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -181,3 +181,8 @@
|
|||
license: "CC0-1.0"
|
||||
copyright: "by ScarKy0"
|
||||
source: "https://github.com/space-wizards/space-station-14/pull/32012"
|
||||
|
||||
- files: ["ame_fuelinjection.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "by AftrLite (Github). Uses audio from hypospray.ogg and hiss.ogg (Found in Resources/Audio/Items)"
|
||||
source: "https://github.com/space-wizards/space-station-14/pull/33097"
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -567,5 +567,28 @@ Entries:
|
|||
id: 70
|
||||
time: '2024-10-16T22:24:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32844
|
||||
- author: BramvanZijp
|
||||
changes:
|
||||
- message: CC, ERT, Admin, and Deathsquad PDA's now have all departmental programs
|
||||
pre-installed.
|
||||
type: Tweak
|
||||
id: 71
|
||||
time: '2024-10-31T14:53:38.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32601
|
||||
- author: metalgearsloth
|
||||
changes:
|
||||
- message: Added on-call functionality for discord relay to get notified on unanswered
|
||||
ahelps.
|
||||
type: Add
|
||||
id: 72
|
||||
time: '2024-11-02T09:29:16.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30443
|
||||
- author: nikthechampiongr
|
||||
changes:
|
||||
- message: It is now possible to edit the AI's laws through its core and eye.
|
||||
type: Fix
|
||||
id: 73
|
||||
time: '2024-11-02T13:21:10.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32461
|
||||
Name: Admin
|
||||
Order: 3
|
||||
|
|
|
|||
|
|
@ -1,271 +1,4 @@
|
|||
Entries:
|
||||
- author: Errant
|
||||
changes:
|
||||
- message: Medical Mask sprite now works on vox.
|
||||
type: Fix
|
||||
id: 7052
|
||||
time: '2024-08-07T03:41:40.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30702
|
||||
- author: Lyroth001
|
||||
changes:
|
||||
- message: Dragons are immune to flashes
|
||||
type: Tweak
|
||||
id: 7053
|
||||
time: '2024-08-07T07:42:00.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30658
|
||||
- author: ShadowCommander
|
||||
changes:
|
||||
- message: Rollerbeds can now be dragged to the player to fold and pick them up.
|
||||
type: Add
|
||||
id: 7054
|
||||
time: '2024-08-07T09:19:10.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30002
|
||||
- author: Errant
|
||||
changes:
|
||||
- message: Survivors arriving via the Unknown Shuttle event, ERT and CBURN agents,
|
||||
and Death Squad members are now equipped with the appropriate species-specific
|
||||
survival gear.
|
||||
type: Fix
|
||||
- message: Unknown Shuttle event can once again spawn vox characters.
|
||||
type: Tweak
|
||||
id: 7055
|
||||
time: '2024-08-07T09:26:40.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29746
|
||||
- author: IProduceWidgets
|
||||
changes:
|
||||
- message: butter is slippery
|
||||
type: Tweak
|
||||
id: 7056
|
||||
time: '2024-08-07T21:47:03.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29772
|
||||
- author: Mervill
|
||||
changes:
|
||||
- message: Gas Miners now have detailed examine text
|
||||
type: Tweak
|
||||
id: 7057
|
||||
time: '2024-08-08T02:14:31.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30480
|
||||
- author: BackeTako
|
||||
changes:
|
||||
- message: "!, \u203D and multiple punctuations now work for Spanish."
|
||||
type: Tweak
|
||||
id: 7058
|
||||
time: '2024-08-08T03:08:28.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30551
|
||||
- author: strO0pwafel
|
||||
changes:
|
||||
- message: Fixed inconsistent naming of CentComm.
|
||||
type: Fix
|
||||
id: 7059
|
||||
time: '2024-08-08T10:04:20.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29217
|
||||
- author: Plykiya
|
||||
changes:
|
||||
- message: Buffed the range of EMP implants from a radius of 1.75 tiles to 2.75
|
||||
tiles.
|
||||
type: Tweak
|
||||
- message: Buffed the range of EMP grenades from a radius of 4 tiles to 5.5 tiles.
|
||||
type: Tweak
|
||||
id: 7060
|
||||
time: '2024-08-08T10:04:50.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30660
|
||||
- author: Plykiya
|
||||
changes:
|
||||
- message: You can drop food or drinks from your hands to interrupt eating it, again.
|
||||
type: Fix
|
||||
- message: Barber scissors are now interrupted if the item is dropped or if the
|
||||
user changes hands.
|
||||
type: Tweak
|
||||
id: 7061
|
||||
time: '2024-08-08T11:39:47.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30361
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Add "thieving beacon" to Thief antag - a device that counts objects within
|
||||
a radius of itself as stolen.
|
||||
type: Add
|
||||
- message: Return thief structures stealing objectives.
|
||||
type: Add
|
||||
- message: Animal theft objectives can no longer appear if the animals are not on
|
||||
the station.
|
||||
type: Fix
|
||||
id: 7062
|
||||
time: '2024-08-08T13:17:50.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29997
|
||||
- author: lzk228
|
||||
changes:
|
||||
- message: RD labcoat added in RD's dresser.
|
||||
type: Add
|
||||
id: 7063
|
||||
time: '2024-08-08T22:50:57.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30671
|
||||
- author: SlamBamActionman
|
||||
changes:
|
||||
- message: Animal DNA now shows up as "unknown DNA" in the Forensic Scanner.
|
||||
type: Tweak
|
||||
- message: Forensic Scanner can now scan fluid containers for DNA in reagents.
|
||||
type: Tweak
|
||||
- message: Fluids keep their DNA data when moved.
|
||||
type: Fix
|
||||
- message: Fluids now stain containers they're in with DNA. Make sure to scrub your
|
||||
blood bucket after use!
|
||||
type: Add
|
||||
- message: Vomit now includes DNA!
|
||||
type: Add
|
||||
id: 7064
|
||||
time: '2024-08-08T23:27:28.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/26699
|
||||
- author: themias
|
||||
changes:
|
||||
- message: Butter can be sliced, cookie and toast recipes now use butter slices.
|
||||
type: Tweak
|
||||
- message: Chefvend butter reduced from 4 to 3.
|
||||
type: Tweak
|
||||
id: 7065
|
||||
time: '2024-08-08T23:32:42.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30789
|
||||
- author: EmoGarbage404
|
||||
changes:
|
||||
- message: You should have significantly less friction when moving in space.
|
||||
type: Tweak
|
||||
id: 7066
|
||||
time: '2024-08-09T04:52:25.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29383
|
||||
- author: Plykiya
|
||||
changes:
|
||||
- message: Hardsuits and EVA suits now count as protection for unscrewing lightbulbs.
|
||||
type: Add
|
||||
- message: More gloves were given the ability to unscrew light bulbs.
|
||||
type: Add
|
||||
- message: Behonkers no longer hurt you when melee attacking them or interacting
|
||||
with them.
|
||||
type: Remove
|
||||
id: 7067
|
||||
time: '2024-08-09T05:32:41.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30244
|
||||
- author: Ian321
|
||||
changes:
|
||||
- message: The warden is now an important job.
|
||||
type: Tweak
|
||||
id: 7068
|
||||
time: '2024-08-09T05:45:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30745
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Added tooltips to the agent ID job icons
|
||||
type: Add
|
||||
id: 7069
|
||||
time: '2024-08-09T06:14:07.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28575
|
||||
- author: stalengd
|
||||
changes:
|
||||
- message: Head bandana no longer blocks food eating.
|
||||
type: Fix
|
||||
id: 7070
|
||||
time: '2024-08-09T06:17:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28910
|
||||
- author: Ubaser
|
||||
changes:
|
||||
- message: Oxygen and nitrogen canisters now have new sprites when worn.
|
||||
type: Add
|
||||
id: 7071
|
||||
time: '2024-08-09T10:32:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30809
|
||||
- author: Plykiya
|
||||
changes:
|
||||
- message: Buckling someone now triggers a short do-after.
|
||||
type: Tweak
|
||||
id: 7072
|
||||
time: '2024-08-09T15:43:02.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29621
|
||||
- author: Ubaser
|
||||
changes:
|
||||
- message: Normal crowbars cannot be placed in pockets, but can now fit in belts.
|
||||
type: Tweak
|
||||
- message: Depending on where you obtained the crowbars, they will now have different
|
||||
colours.
|
||||
type: Tweak
|
||||
id: 7073
|
||||
time: '2024-08-09T19:29:00.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28988
|
||||
- author: lzk228
|
||||
changes:
|
||||
- message: Hotplate works again.
|
||||
type: Fix
|
||||
id: 7074
|
||||
time: '2024-08-10T01:10:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30830
|
||||
- author: EmoGarbage404
|
||||
changes:
|
||||
- message: Maintenance closets have more variety in what they can contain.
|
||||
type: Tweak
|
||||
id: 7075
|
||||
time: '2024-08-10T02:12:40.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30579
|
||||
- author: Ko4erga
|
||||
changes:
|
||||
- message: Changed chemistry airlock color.
|
||||
type: Tweak
|
||||
id: 7076
|
||||
time: '2024-08-10T03:23:47.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30666
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Bent pipes now deal 8 thrown damage instead of 3.
|
||||
type: Tweak
|
||||
id: 7077
|
||||
time: '2024-08-10T03:30:43.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30634
|
||||
- author: shampunj
|
||||
changes:
|
||||
- message: Rat king can now wideswing
|
||||
type: Tweak
|
||||
id: 7078
|
||||
time: '2024-08-10T12:47:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30808
|
||||
- author: BackeTako
|
||||
changes:
|
||||
- message: Added a suitskirt for the psychologist
|
||||
type: Add
|
||||
id: 7079
|
||||
time: '2024-08-10T12:51:54.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30709
|
||||
- author: Unkn0wnGh0st333
|
||||
changes:
|
||||
- message: ERT Chaplain starting gear was fixed and will no longer give the ERT
|
||||
Engineer gear
|
||||
type: Fix
|
||||
id: 7080
|
||||
time: '2024-08-10T12:55:20.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30855
|
||||
- author: Ubaser
|
||||
changes:
|
||||
- message: Light tube structures now have new sprites.
|
||||
type: Tweak
|
||||
id: 7081
|
||||
time: '2024-08-10T15:00:22.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29091
|
||||
- author: lzk228
|
||||
changes:
|
||||
- message: Standartized some clothing recipes.
|
||||
type: Tweak
|
||||
id: 7082
|
||||
time: '2024-08-10T18:16:56.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29315
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: You cat cut burger bun into two halfs, and make custom burgers now!
|
||||
type: Add
|
||||
id: 7083
|
||||
time: '2024-08-10T19:31:32.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30755
|
||||
- author: thetolbean
|
||||
changes:
|
||||
- message: Updated Core's boxing ring beacon label to be correct
|
||||
type: Tweak
|
||||
id: 7084
|
||||
time: '2024-08-10T19:50:08.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/30800
|
||||
- author: Flareguy
|
||||
changes:
|
||||
- message: Added vox sprites for most of the remaining common mask items.
|
||||
|
|
@ -3927,3 +3660,264 @@
|
|||
id: 7551
|
||||
time: '2024-10-24T03:41:03.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32965
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Mix 1u aluminium, 1u potassium and 1u sulfur for a flash reaction effect.
|
||||
The radius scales with the reagent amount.
|
||||
type: Add
|
||||
id: 7552
|
||||
time: '2024-10-25T22:47:12.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32377
|
||||
- author: BramvanZijp
|
||||
changes:
|
||||
- message: Fixed the Lone Nuclear Operative mid-round antagonist being extremely
|
||||
rare.
|
||||
type: Fix
|
||||
id: 7553
|
||||
time: '2024-10-26T02:16:45.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32942
|
||||
- author: Moomoobeef
|
||||
changes:
|
||||
- message: Bowls no longer make an eating sound when drinking from them.
|
||||
type: Fix
|
||||
id: 7554
|
||||
time: '2024-10-26T04:00:49.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32819
|
||||
- author: SaphireLattice
|
||||
changes:
|
||||
- message: Added a warning about unrevivability in the health analyzer UI.
|
||||
type: Add
|
||||
id: 7555
|
||||
time: '2024-10-26T17:22:09.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32636
|
||||
- author: slarticodefast
|
||||
changes:
|
||||
- message: Fixed pie throwing sound not playing.
|
||||
type: Fix
|
||||
id: 7556
|
||||
time: '2024-10-27T04:25:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33017
|
||||
- author: stalengd
|
||||
changes:
|
||||
- message: Fixed playtime labels not being able to correctly display time greater
|
||||
than 24 hours
|
||||
type: Fix
|
||||
id: 7557
|
||||
time: '2024-10-28T18:00:00.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32974
|
||||
- author: august-sun
|
||||
changes:
|
||||
- message: Extended the minimum round time for meteor swarm events.
|
||||
type: Tweak
|
||||
id: 7558
|
||||
time: '2024-10-28T21:25:34.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32876
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: Fixed lava planet expeditions not working.
|
||||
type: Fix
|
||||
id: 7559
|
||||
time: '2024-10-29T05:00:29.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33042
|
||||
- author: metalgearsloth
|
||||
changes:
|
||||
- message: Fix separated game screen bumping slightly.
|
||||
type: Fix
|
||||
id: 7560
|
||||
time: '2024-10-29T05:07:57.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33046
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Proto-kitentic crushers, glaives, and daggers now have more accurate
|
||||
inhand sprites.
|
||||
type: Tweak
|
||||
id: 7561
|
||||
time: '2024-10-30T07:38:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32212
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Security belts now contain a holobarrier projector and a handheld security
|
||||
radio by default rather than tear gas and a flashbang.
|
||||
type: Tweak
|
||||
id: 7562
|
||||
time: '2024-10-30T07:40:33.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32291
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Added three bottle boxes to the nanomed plus inventory for doctors to
|
||||
carry small amounts of chemicals on their person
|
||||
type: Add
|
||||
id: 7563
|
||||
time: '2024-10-30T07:41:51.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33018
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Added the interdyne defibrillator, a black-and-red defibrillator that
|
||||
can be used as a melee weapon.
|
||||
type: Add
|
||||
- message: The syndicate medical bundle now contains an interdyne defibrillator,
|
||||
a collection of various instant injectors, tourniquets, and several combat kits.
|
||||
The price has been raised to 24 tc.
|
||||
type: Tweak
|
||||
id: 7564
|
||||
time: '2024-10-30T09:15:30.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32720
|
||||
- author: Boaz1111
|
||||
changes:
|
||||
- message: Pill bottles can now only store pills.
|
||||
type: Tweak
|
||||
id: 7565
|
||||
time: '2024-10-31T10:56:07.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33074
|
||||
- author: Jarmer123
|
||||
changes:
|
||||
- message: You can now find a spare bible in the PietyVend
|
||||
type: Add
|
||||
id: 7566
|
||||
time: '2024-10-31T13:26:46.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32363
|
||||
- author: justinbrick
|
||||
changes:
|
||||
- message: Added a pop-up notification when extra items are dropped while unequipping
|
||||
something.
|
||||
type: Tweak
|
||||
id: 7567
|
||||
time: '2024-10-31T14:12:26.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33078
|
||||
- author: BramvanZijp
|
||||
changes:
|
||||
- message: The maximum amount of programs that can be installed on a PDA has been
|
||||
increased from 5 to 8
|
||||
type: Tweak
|
||||
- message: The Detective and Head of Security now get the logprobe program pre-installed
|
||||
on their PDA.
|
||||
type: Tweak
|
||||
id: 7568
|
||||
time: '2024-10-31T14:53:38.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32601
|
||||
- author: Psychpsyo
|
||||
changes:
|
||||
- message: Carp plushies can now be placed in mop buckets, along with other rehydratable
|
||||
things like monkey cubes.
|
||||
type: Add
|
||||
id: 7569
|
||||
time: '2024-10-31T18:46:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33079
|
||||
- author: Bhijn and Myr
|
||||
changes:
|
||||
- message: Tail thumping has been downmixed to mono to fix the sound lacking any
|
||||
sort of positioning. They're now capable of having a presence in the actual
|
||||
soundspace, in turn meaning lizards are no longer occupying your headset at
|
||||
all times of day.
|
||||
type: Fix
|
||||
id: 7570
|
||||
time: '2024-10-31T21:30:58.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33092
|
||||
- author: reesque
|
||||
changes:
|
||||
- message: pie not dropping tin on thrown
|
||||
type: Fix
|
||||
id: 7571
|
||||
time: '2024-11-01T01:43:11.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33013
|
||||
- author: SlamBamActionman
|
||||
changes:
|
||||
- message: Votekicks can now be initiated during the pregame lobby.
|
||||
type: Fix
|
||||
id: 7572
|
||||
time: '2024-11-01T01:52:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32528
|
||||
- author: PopGamer46
|
||||
changes:
|
||||
- message: Fixed bolt lights of recently unpowered bolted doors
|
||||
type: Fix
|
||||
id: 7573
|
||||
time: '2024-11-01T02:04:09.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33063
|
||||
- author: RumiTiger
|
||||
changes:
|
||||
- message: A chocolate and banana muffin has been added to the game. The berry and
|
||||
cherry muffins have also been resprited!
|
||||
type: Add
|
||||
- message: Now you can make a regular, chocolate, banana, and berry muffin!
|
||||
type: Tweak
|
||||
- message: Muffin tins have been added to the game. They are needed for making muffins!
|
||||
type: Add
|
||||
id: 7574
|
||||
time: '2024-11-01T02:06:46.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/29318
|
||||
- author: ScarKy0
|
||||
changes:
|
||||
- message: AI can no longer toggle seeing jobs off.
|
||||
type: Tweak
|
||||
- message: Borgs can no longer see mindshield status.
|
||||
type: Fix
|
||||
id: 7575
|
||||
time: '2024-11-01T02:32:28.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33069
|
||||
- author: Minemoder5000
|
||||
changes:
|
||||
- message: The cargo shuttle's cargo pallets can no longer sell or buy.
|
||||
type: Fix
|
||||
id: 7576
|
||||
time: '2024-11-01T06:22:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33022
|
||||
- author: aspiringLich
|
||||
changes:
|
||||
- message: Fixed the logic triggering popups when inserting items into machines.
|
||||
type: Fix
|
||||
id: 7577
|
||||
time: '2024-11-02T01:33:26.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28856
|
||||
- author: K-Dynamic
|
||||
changes:
|
||||
- message: Pills are explosion resistant.
|
||||
type: Tweak
|
||||
id: 7578
|
||||
time: '2024-11-02T09:51:45.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32458
|
||||
- author: K-Dynamic
|
||||
changes:
|
||||
- message: Handcrafted gauze now takes 3 seconds instead of 10 seconds of crafting
|
||||
type: Tweak
|
||||
- message: Medical techfab gauze recipe now takes 1 cloth instead of 2
|
||||
type: Tweak
|
||||
id: 7579
|
||||
time: '2024-11-02T09:53:19.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32744
|
||||
- author: Ubaser
|
||||
changes:
|
||||
- message: Service workers can now be antagonists.
|
||||
type: Fix
|
||||
id: 7580
|
||||
time: '2024-11-02T10:07:52.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31359
|
||||
- author: AftrLite
|
||||
changes:
|
||||
- message: The AME now has a new sound effect for fuel injection!
|
||||
type: Add
|
||||
id: 7581
|
||||
time: '2024-11-02T13:19:33.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33097
|
||||
- author: deltanedas
|
||||
changes:
|
||||
- message: Printing cables in an autolathe is now 20 times faster.
|
||||
type: Tweak
|
||||
id: 7582
|
||||
time: '2024-11-02T13:24:08.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/31521
|
||||
- author: Centronias
|
||||
changes:
|
||||
- message: Fixed a bug where attempting to speak into a handheld radio and an intercom
|
||||
simultaneously would lead to only one device transmitting the message.
|
||||
type: Fix
|
||||
id: 7583
|
||||
time: '2024-11-02T15:04:22.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/32737
|
||||
- author: joshepvodka
|
||||
changes:
|
||||
- message: Headphones are now selectable in loadouts.
|
||||
type: Add
|
||||
id: 7584
|
||||
time: '2024-11-02T15:12:26.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/33067
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@ reagent-effect-guidebook-emp-reaction-effect =
|
|||
*[other] cause
|
||||
} an electromagnetic pulse
|
||||
|
||||
reagent-effect-guidebook-flash-reaction-effect =
|
||||
{ $chance ->
|
||||
[1] Causes
|
||||
*[other] cause
|
||||
} a blinding flash
|
||||
|
||||
reagent-effect-guidebook-foam-area-reaction-effect =
|
||||
{ $chance ->
|
||||
[1] Creates
|
||||
|
|
|
|||
|
|
@ -2,3 +2,9 @@ inventory-component-can-equip-cannot = You can't equip this!
|
|||
inventory-component-can-equip-does-not-fit = This doesn't fit!
|
||||
|
||||
inventory-component-can-unequip-cannot = You can't unequip this!
|
||||
|
||||
inventory-component-dropped-from-unequip =
|
||||
You dropped {$items ->
|
||||
[1] an item!
|
||||
*[other] some items!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# mop bucket
|
||||
mop-bucket-slot-component-slot-name-shark = Shark
|
||||
mop-bucket-slot-component-slot-name-item = Item
|
||||
mop-bucket-slot-component-eject-verb = Take out
|
||||
# janitorial trolley
|
||||
janitorial-trolley-slot-component-slot-name-plunger = Plunger
|
||||
janitorial-trolley-slot-component-slot-name-sign = Sign
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ health-analyzer-window-entity-damage-total-text = Total Damage:
|
|||
health-analyzer-window-damage-group-text = {$damageGroup}: {$amount}
|
||||
health-analyzer-window-damage-type-text = {$damageType}: {$amount}
|
||||
|
||||
health-analyzer-window-entity-bleeding-text = Patient is bleeding!
|
||||
health-analyzer-window-entity-unrevivable-text = [color=red]Unique body composition detected! Patient can not be resuscitated by normal means![/color]
|
||||
health-analyzer-window-entity-bleeding-text = [color=red]Patient is bleeding![/color]
|
||||
|
||||
health-analyzer-window-scan-mode-text = Scan Mode:
|
||||
health-analyzer-window-scan-mode-active = Active
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ uplink-chemistry-kit-desc = A starter kit for the aspiring chemist, includes tox
|
|||
uplink-knives-kit-name = Throwing Knives Kit
|
||||
uplink-knives-kit-desc = A set of 4 syndicate branded throwing knives, perfect for embedding into the body of your victims.
|
||||
|
||||
uplink-meds-bundle-name = Medical Bundle
|
||||
uplink-meds-bundle-desc = All you need to get your comrades back in the fight: mainly a combat medkit, a defibrillator and three combat medipens.
|
||||
uplink-meds-bundle-name = Interdyne Medical Bundle
|
||||
uplink-meds-bundle-desc = An assortment of autoinjectors and premium medical equipment to cover for every possible situation. Contains an elite compact defibrillator that can be used as a weapon.
|
||||
|
||||
uplink-ammo-bundle-name = Ammo Bundle
|
||||
uplink-ammo-bundle-desc = Reloading! Contains 4 magazines for the C-20r, 4 drums for the Bulldog, and 2 ammo boxes for the L6 SAW.
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ ui-vote-type-not-available = This vote type has been disabled
|
|||
|
||||
# Vote option only available for specific users.
|
||||
ui-vote-trusted-users-notice =
|
||||
This vote option is only available to whitelisted players.
|
||||
In addition, you must have been a ghost for { $timeReq } minutes.
|
||||
This vote option is only available to players who have enough playtime or are whitelisted.
|
||||
In addition, you must have been a ghost for { $timeReq } seconds.
|
||||
|
||||
# Warning to not abuse a specific vote option.
|
||||
ui-vote-abuse-warning =
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
# Shown when examining the window. Each entry represents the window's health condition
|
||||
comp-window-damaged-1 = It looks fully intact.
|
||||
comp-window-damaged-2 = It has a few scratches
|
||||
comp-window-damaged-2 = It has a few scratches.
|
||||
comp-window-damaged-3 = It has a few small cracks.
|
||||
comp-window-damaged-4 = It has several big cracks running along its surface.
|
||||
comp-window-damaged-5 = It has deep cracks across multiple layers.
|
||||
comp-window-damaged-6 = It's extremely cracked and on the verge of shattering.
|
||||
comp-window-damaged-4 = [color=yellow]It has several big cracks running along its surface.[/color]
|
||||
comp-window-damaged-5 = [color=orange]It has deep cracks across multiple layers.[/color]
|
||||
comp-window-damaged-6 = [color=red]It's extremely cracked and on the verge of shattering.[/color]
|
||||
|
||||
### Interaction Messages
|
||||
|
||||
# Shown when knocking on a window
|
||||
comp-window-knock = *knock knock*
|
||||
|
||||
|
|
|
|||
|
|
@ -6576,7 +6576,7 @@ entities:
|
|||
- uid: 2031
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.6114278,-10.732791
|
||||
pos: 4.0109396,-12.223828
|
||||
parent: 104
|
||||
- uid: 2095
|
||||
components:
|
||||
|
|
@ -10993,6 +10993,13 @@ entities:
|
|||
- type: Transform
|
||||
pos: 11.5,-6.5
|
||||
parent: 104
|
||||
- proto: HandLabeler
|
||||
entities:
|
||||
- uid: 1826
|
||||
components:
|
||||
- type: Transform
|
||||
pos: 3.4542694,-10.616036
|
||||
parent: 104
|
||||
- proto: KitchenKnife
|
||||
entities:
|
||||
- uid: 1061
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -5,35 +5,20 @@
|
|||
description: Sends your eye back to the core.
|
||||
components:
|
||||
- type: InstantAction
|
||||
priority: -10
|
||||
priority: -9
|
||||
itemIconStyle: BigAction
|
||||
icon:
|
||||
sprite: Interface/Actions/actions_ai.rsi
|
||||
state: ai_core
|
||||
event: !type:JumpToCoreEvent
|
||||
|
||||
- type: entity
|
||||
id: ActionShowJobIcons
|
||||
name: Show job icons
|
||||
description: Shows job icons for crew members.
|
||||
components:
|
||||
- type: InstantAction
|
||||
priority: -5
|
||||
itemIconStyle: BigAction
|
||||
icon:
|
||||
sprite: Interface/Actions/actions_ai.rsi
|
||||
state: job_view
|
||||
event: !type:ActionComponentChangeEvent
|
||||
components:
|
||||
- type: ShowJobIcons
|
||||
|
||||
- type: entity
|
||||
id: ActionSurvCameraLights
|
||||
name: Toggle camera lights
|
||||
description: Enable surveillance camera lights near wherever you're viewing.
|
||||
components:
|
||||
- type: InstantAction
|
||||
priority: -6
|
||||
priority: -5
|
||||
itemIconStyle: BigAction
|
||||
icon:
|
||||
sprite: Interface/Actions/actions_ai.rsi
|
||||
|
|
|
|||
|
|
@ -280,6 +280,8 @@
|
|||
checkCanInteract: false
|
||||
checkConsciousness: false
|
||||
event: !type:WakeActionEvent
|
||||
startDelay: true
|
||||
useDelay: 2
|
||||
|
||||
- type: entity
|
||||
id: ActionActivateHonkImplant
|
||||
|
|
|
|||
|
|
@ -302,13 +302,19 @@
|
|||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: DefibrillatorSyndicate
|
||||
- id: MedkitCombatFilled
|
||||
- id: Defibrillator
|
||||
amount: 4
|
||||
- id: Tourniquet
|
||||
amount: 4
|
||||
- id: CombatMedipen
|
||||
amount: 3
|
||||
- id: ClothingHandsGlovesNitrile
|
||||
- id: SyringeTranexamicAcid
|
||||
- id: SyringeHyronalin
|
||||
amount: 4
|
||||
- id: PunctAutoInjector
|
||||
amount: 4
|
||||
- id: PyraAutoInjector
|
||||
amount: 4
|
||||
- id: AirlossAutoInjector
|
||||
amount: 4
|
||||
|
||||
- type: entity
|
||||
parent: ClothingBackpackDuffelSyndicateBundle
|
||||
|
|
|
|||
|
|
@ -46,10 +46,12 @@
|
|||
table: !type:AllSelector
|
||||
children:
|
||||
- id: Stunbaton
|
||||
- id: GrenadeFlashBang
|
||||
- id: TearGasGrenade
|
||||
- id: GrenadeFlashBang # DeltaV: revert upstream #32291
|
||||
- id: TearGasGrenade # DeltaV
|
||||
- id: Handcuffs
|
||||
- id: Handcuffs
|
||||
#- id: HoloprojectorSecurity # DeltaV
|
||||
#- id: RadioHandheldSecurity # DeltaV
|
||||
|
||||
- type: entity
|
||||
id: ClothingBeltSecurityFilled
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@
|
|||
BoxCandle: 2
|
||||
BoxCandleSmall: 2
|
||||
Urn: 5
|
||||
SilverRing: 2 # Delta-V (Isn't the stuff above also deltav??)
|
||||
Bible: 1
|
||||
SilverRing: 2 # Delta-V
|
||||
RingBox: 2 # Delta-V
|
||||
emaggedInventory:
|
||||
ClothingOuterArmorCult: 1
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
FoodPlate: 10
|
||||
FoodPlateSmall: 10
|
||||
FoodPlateTin: 5
|
||||
FoodPlateMuffinTin: 5
|
||||
FoodKebabSkewer: 5
|
||||
DrinkGlass: 5
|
||||
Beaker: 5
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
Bloodpack: 5
|
||||
EpinephrineChemistryBottle: 3
|
||||
Syringe: 5
|
||||
BoxBottle: 3
|
||||
Portafib: 1 # DeltaV - Add Portafibs, see Prototypes/DeltaV/Entities/Objects/Devices/Medical/portafib.yml
|
||||
ClothingEyesHudMedical: 2
|
||||
ClothingEyesEyepatchHudMedical: 2
|
||||
|
|
|
|||
|
|
@ -699,9 +699,9 @@
|
|||
productEntity: ClothingBackpackDuffelSyndicateMedicalBundleFilled
|
||||
discountCategory: rareDiscounts
|
||||
discountDownTo:
|
||||
Telecrystal: 12
|
||||
Telecrystal: 16
|
||||
cost:
|
||||
Telecrystal: 20
|
||||
Telecrystal: 24
|
||||
categories:
|
||||
- UplinkChemicals
|
||||
conditions:
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@
|
|||
- Howe
|
||||
- Huey
|
||||
- Hughes
|
||||
- Hujsak
|
||||
- Hunt
|
||||
- Hunter
|
||||
- Hussain
|
||||
|
|
|
|||
|
|
@ -495,7 +495,6 @@
|
|||
- CartridgeAmmo
|
||||
- DoorRemote
|
||||
- Whistle
|
||||
- HolosignProjector
|
||||
- BalloonPopper
|
||||
- type: ItemMapper # DeltaV - adjust for DeltaV sprites.
|
||||
mapLayers:
|
||||
|
|
|
|||
|
|
@ -222,3 +222,16 @@
|
|||
state: metal_foam-north
|
||||
- map: [ "enum.EdgeLayer.West" ]
|
||||
state: metal_foam-west
|
||||
|
||||
- type: entity
|
||||
id: ReactionFlash
|
||||
categories: [ HideSpawnMenu ]
|
||||
components:
|
||||
- type: PointLight
|
||||
enabled: true
|
||||
radius: 2
|
||||
energy: 8
|
||||
- type: LightFade
|
||||
duration: 0.5
|
||||
- type: TimedDespawn
|
||||
lifetime: 0.5
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@
|
|||
- FoodBakedMuffinBerry
|
||||
- FoodBakedMuffinCherry
|
||||
- FoodBakedMuffinBluecherry
|
||||
- FoodBakedMuffinChocolate
|
||||
- FoodBakedMuffinBanana
|
||||
- FoodBakedBunHoney
|
||||
- FoodBakedBunHotX
|
||||
- FoodBakedBunMeat
|
||||
|
|
|
|||
|
|
@ -289,7 +289,6 @@
|
|||
- type: AccessReader
|
||||
access: [["Command"], ["Research"]]
|
||||
- type: ShowJobIcons
|
||||
- type: ShowMindShieldIcons
|
||||
|
||||
- type: entity
|
||||
id: BaseBorgChassisSyndicate
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@
|
|||
icon: { sprite: Interface/Actions/actions_ai.rsi, state: mass_scanner }
|
||||
iconOn: Interface/Actions/actions_ai.rsi/mass_scanner.png
|
||||
keywords: [ "AI", "console", "interface" ]
|
||||
priority: -7
|
||||
priority: -6
|
||||
event: !type:ToggleIntrinsicUIEvent { key: enum.RadarConsoleUiKey.Key }
|
||||
|
||||
- type: entity
|
||||
|
|
@ -157,7 +157,7 @@
|
|||
icon: { sprite: Interface/Actions/actions_ai.rsi, state: crew_monitor }
|
||||
iconOn: Interface/Actions/actions_ai.rsi/crew_monitor.png
|
||||
keywords: [ "AI", "console", "interface" ]
|
||||
priority: -9
|
||||
priority: -8
|
||||
event: !type:ToggleIntrinsicUIEvent { key: enum.CrewMonitoringUIKey.Key }
|
||||
|
||||
- type: entity
|
||||
|
|
@ -169,5 +169,5 @@
|
|||
icon: { sprite: Interface/Actions/actions_ai.rsi, state: station_records }
|
||||
iconOn: Interface/Actions/actions_ai.rsi/station_records.png
|
||||
keywords: [ "AI", "console", "interface" ]
|
||||
priority: -8
|
||||
priority: -7
|
||||
event: !type:ToggleIntrinsicUIEvent { key: enum.GeneralStationRecordConsoleKey.Key }
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@
|
|||
icon: Interface/Actions/scream.png
|
||||
checkCanInteract: false
|
||||
event: !type:BooActionEvent
|
||||
startDelay: true
|
||||
useDelay: 120
|
||||
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@
|
|||
- type: ActionGrant
|
||||
actions:
|
||||
- ActionJumpToCore
|
||||
- ActionShowJobIcons
|
||||
- ActionSurvCameraLights
|
||||
- ActionAIViewLaws
|
||||
- type: UserInterface
|
||||
|
|
@ -70,6 +69,9 @@
|
|||
canShuttle: false
|
||||
title: comms-console-announcement-title-station-ai
|
||||
color: "#2ed2fd"
|
||||
- type: Speech
|
||||
speechVerb: Robotic
|
||||
- type: ShowJobIcons
|
||||
|
||||
- type: entity
|
||||
id: AiHeldIntellicard
|
||||
|
|
|
|||
|
|
@ -19,44 +19,84 @@
|
|||
- type: Item
|
||||
size: Tiny
|
||||
|
||||
# Muffins/Buns
|
||||
# Muffins
|
||||
|
||||
- type: entity
|
||||
name: muffin
|
||||
parent: FoodBakedBase
|
||||
parent: FoodInjectableBase
|
||||
id: FoodBakedMuffin
|
||||
description: A delicious and spongy little cake.
|
||||
components:
|
||||
- type: Food
|
||||
trash:
|
||||
- FoodPlateMuffinTin
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Food/Baked/misc.rsi
|
||||
state: muffin
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
maxVol: 10
|
||||
reagents:
|
||||
- ReagentId: Nutriment
|
||||
Quantity: 6
|
||||
- ReagentId: Vitamin
|
||||
Quantity: 2
|
||||
- type: FlavorProfile
|
||||
flavors:
|
||||
- sweet
|
||||
- type: Item
|
||||
size: Tiny
|
||||
|
||||
- type: entity
|
||||
name: berry muffin
|
||||
parent: FoodBakedBase
|
||||
parent: FoodBakedMuffin
|
||||
id: FoodBakedMuffinBerry
|
||||
description: A delicious and spongy little cake, with berries.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: muffin-berry
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
maxVol: 12
|
||||
reagents:
|
||||
- ReagentId: Nutriment
|
||||
Quantity: 6
|
||||
- ReagentId: Vitamin
|
||||
Quantity: 2
|
||||
- ReagentId: JuiceBerry
|
||||
Quantity: 2
|
||||
- type: Tag
|
||||
tags:
|
||||
- Fruit
|
||||
|
||||
- type: entity
|
||||
name: cherry muffin
|
||||
parent: FoodBakedBase
|
||||
parent: FoodBakedMuffin
|
||||
id: FoodBakedMuffinCherry
|
||||
description: A sweet muffin with cherry bits.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: muffin-cherry
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
maxVol: 12
|
||||
reagents:
|
||||
- ReagentId: Nutriment
|
||||
Quantity: 6
|
||||
- ReagentId: Vitamin
|
||||
Quantity: 2
|
||||
- ReagentId: JuiceCherry
|
||||
Quantity: 2
|
||||
- type: Tag
|
||||
tags:
|
||||
- Fruit
|
||||
|
||||
- type: entity
|
||||
name: bluecherry muffin
|
||||
parent: FoodBakedBase
|
||||
parent: FoodBakedMuffin
|
||||
id: FoodBakedMuffinBluecherry
|
||||
description: Blue cherries inside a delicious muffin.
|
||||
components:
|
||||
|
|
@ -66,6 +106,51 @@
|
|||
tags:
|
||||
- Fruit
|
||||
|
||||
- type: entity
|
||||
name: chocolate muffin
|
||||
parent: FoodBakedMuffin
|
||||
id: FoodBakedMuffinChocolate
|
||||
description: A delicious and spongy chocolate muffin.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: muffin-chocolate
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
maxVol: 12
|
||||
reagents:
|
||||
- ReagentId: Nutriment
|
||||
Quantity: 6
|
||||
- ReagentId: Vitamin
|
||||
Quantity: 2
|
||||
- ReagentId: CocoaPowder
|
||||
Quantity: 2
|
||||
|
||||
- type: entity
|
||||
name: banana muffin
|
||||
parent: FoodBakedMuffin
|
||||
id: FoodBakedMuffinBanana
|
||||
description: A delicious and spongy banana muffin.
|
||||
components:
|
||||
- type: Sprite
|
||||
state: muffin-banana
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
food:
|
||||
maxVol: 12
|
||||
reagents:
|
||||
- ReagentId: Nutriment
|
||||
Quantity: 6
|
||||
- ReagentId: Vitamin
|
||||
Quantity: 2
|
||||
- ReagentId: JuiceBanana
|
||||
Quantity: 2
|
||||
- type: Tag
|
||||
tags:
|
||||
- Fruit
|
||||
|
||||
# Buns
|
||||
|
||||
- type: entity
|
||||
name: honey bun #TODO honey
|
||||
parent: FoodBakedBase
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@
|
|||
visible: false
|
||||
- type: MixableSolution
|
||||
solution: food
|
||||
- type: Drink
|
||||
solution: food
|
||||
useSound:
|
||||
path: /Audio/Items/drink.ogg
|
||||
- type: DamageOnLand
|
||||
damage:
|
||||
types:
|
||||
|
|
|
|||
|
|
@ -178,3 +178,27 @@
|
|||
materialComposition:
|
||||
Steel: 60
|
||||
- type: SpaceGarbage
|
||||
|
||||
# Muffin Tin
|
||||
|
||||
- type: entity
|
||||
name: muffin tin
|
||||
parent: BaseItem
|
||||
id: FoodPlateMuffinTin
|
||||
description: A cheap foil tin for muffins.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Food/plates.rsi
|
||||
state: muffin-tin
|
||||
- type: Item
|
||||
size: Small
|
||||
shape:
|
||||
- 0,0,1,0
|
||||
storedOffset: 0,-3
|
||||
- type: Tag
|
||||
tags:
|
||||
- Trash
|
||||
- type: PhysicalComposition
|
||||
materialComposition:
|
||||
Steel: 30
|
||||
- type: SpaceGarbage
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- HolofanProjector
|
||||
- SecBeltEquip
|
||||
- type: StaticPrice
|
||||
price: 50
|
||||
|
||||
|
|
|
|||
|
|
@ -730,6 +730,14 @@
|
|||
accentHColor: "#447987"
|
||||
- type: Icon
|
||||
state: pda-hos
|
||||
- type: CartridgeLoader
|
||||
preinstalled:
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- CrimeAssistCartridge # DeltaV
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces WantedList
|
||||
- LogProbeCartridge
|
||||
|
||||
- type: entity
|
||||
parent: BaseSecurityPDA
|
||||
|
|
@ -778,6 +786,16 @@
|
|||
borderColor: "#00842e"
|
||||
- type: Icon
|
||||
state: pda-centcom
|
||||
- type: CartridgeLoader
|
||||
uiKey: enum.PdaUiKey.Key
|
||||
preinstalled:
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- MedTekCartridge
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces WantedList
|
||||
- LogProbeCartridge
|
||||
- AstroNavCartridge
|
||||
|
||||
- type: entity
|
||||
parent: CentcomPDA
|
||||
|
|
@ -799,6 +817,9 @@
|
|||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- LogProbeCartridge
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces WantedList
|
||||
- MedTekCartridge
|
||||
- AstroNavCartridge
|
||||
- StockTradingCartridge # Delta-V
|
||||
|
||||
- type: entity
|
||||
|
|
@ -893,14 +914,6 @@
|
|||
uiKey: enum.PdaUiKey.Key
|
||||
preinstalled:
|
||||
- NotekeeperCartridge
|
||||
cartridgeSlot:
|
||||
priority: -1
|
||||
name: Cartridge
|
||||
ejectSound: /Audio/Machines/id_swipe.ogg
|
||||
insertSound: /Audio/Machines/id_insert.ogg
|
||||
whitelist:
|
||||
components:
|
||||
- Cartridge
|
||||
|
||||
- type: entity
|
||||
parent: BaseSecurityPDA
|
||||
|
|
@ -918,6 +931,16 @@
|
|||
accentVColor: "#447987"
|
||||
- type: Icon
|
||||
state: pda-ert
|
||||
- type: CartridgeLoader
|
||||
uiKey: enum.PdaUiKey.Key
|
||||
preinstalled:
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- MedTekCartridge
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces WantedList
|
||||
- LogProbeCartridge
|
||||
- AstroNavCartridge
|
||||
|
||||
- type: entity
|
||||
parent: ERTLeaderPDA
|
||||
|
|
@ -958,14 +981,6 @@
|
|||
components:
|
||||
- type: Pda
|
||||
id: ERTMedicIDCard
|
||||
- type: CartridgeLoader
|
||||
uiKey: enum.PdaUiKey.Key
|
||||
preinstalled:
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- MedTekCartridge
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces wantedList
|
||||
|
||||
- type: entity
|
||||
parent: ERTLeaderPDA
|
||||
|
|
@ -1073,6 +1088,14 @@
|
|||
borderColor: "#774705"
|
||||
- type: Icon
|
||||
state: pda-detective
|
||||
- type: CartridgeLoader
|
||||
preinstalled:
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- CrimeAssistCartridge # DeltaV
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces WantedList
|
||||
- LogProbeCartridge
|
||||
|
||||
- type: entity
|
||||
parent: BaseMedicalPDA
|
||||
|
|
@ -1089,14 +1112,14 @@
|
|||
accentVColor: "#d7d7d0"
|
||||
- type: Icon
|
||||
state: pda-brigmedic
|
||||
- type: CartridgeLoader # DeltaV - Crime Assist + SecWatch, increased diskSpace by 2 to fit them
|
||||
diskSpace: 7
|
||||
- type: CartridgeLoader
|
||||
preinstalled:
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- CrimeAssistCartridge
|
||||
- SecWatchCartridge
|
||||
- CrewManifestCartridge
|
||||
- NotekeeperCartridge
|
||||
- NewsReaderCartridge
|
||||
- CrimeAssistCartridge # DeltaV
|
||||
- SecWatchCartridge # DeltaV: SecWatch replaces WantedList
|
||||
- MedTekCartridge
|
||||
|
||||
- type: entity
|
||||
parent: ClownPDA
|
||||
|
|
@ -1213,11 +1236,3 @@
|
|||
preinstalled:
|
||||
- NotekeeperCartridge
|
||||
- MedTekCartridge
|
||||
cartridgeSlot:
|
||||
priority: -1
|
||||
name: Cartridge
|
||||
ejectSound: /Audio/Machines/id_swipe.ogg
|
||||
insertSound: /Audio/Machines/id_insert.ogg
|
||||
whitelist:
|
||||
components:
|
||||
- Cartridge
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
damage:
|
||||
types:
|
||||
Blunt: 0
|
||||
hidden: true
|
||||
- type: PhysicalComposition
|
||||
materialComposition:
|
||||
Cloth: 100
|
||||
|
|
@ -600,7 +601,9 @@
|
|||
animation: WeaponArcBite # Rrrr!
|
||||
- type: Tag
|
||||
tags:
|
||||
- PlushieCarp # DeltaV - fish labeler craft
|
||||
- Payload
|
||||
- ClothMade
|
||||
- PlushieCarp
|
||||
|
||||
- type: entity
|
||||
parent: PlushieCarp
|
||||
|
|
|
|||
|
|
@ -20,8 +20,6 @@
|
|||
density: 15
|
||||
mask:
|
||||
- MachineMask
|
||||
- type: CargoPallet
|
||||
palletType: All
|
||||
- type: StaticPrice
|
||||
price: 100
|
||||
- type: Sprite
|
||||
|
|
|
|||
|
|
@ -71,3 +71,69 @@
|
|||
id: DefibrillatorOneHandedUnpowered
|
||||
parent: BaseDefibrillator
|
||||
suffix: One-Handed, Unpowered
|
||||
|
||||
- type: entity
|
||||
id: DefibrillatorCompact # This should be a research item at some point
|
||||
parent: [ BaseDefibrillator, PowerCellSlotMediumItem ]
|
||||
name: compact defibrillator
|
||||
description: Now in fun size!
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Medical/defibsmall.rsi
|
||||
layers:
|
||||
- state: icon
|
||||
- state: screen
|
||||
map: [ "enum.ToggleVisuals.Layer" ]
|
||||
visible: false
|
||||
shader: unshaded
|
||||
- state: ready
|
||||
map: ["enum.PowerDeviceVisualLayers.Powered"]
|
||||
shader: unshaded
|
||||
- type: Item
|
||||
size: Normal
|
||||
- type: ToggleCellDraw
|
||||
- type: PowerCellDraw
|
||||
useRate: 100
|
||||
- type: Defibrillator
|
||||
zapHeal:
|
||||
types:
|
||||
Asphyxiation: -40
|
||||
doAfterDuration: 6
|
||||
- type: DoAfter
|
||||
- type: UseDelay
|
||||
|
||||
- type: entity
|
||||
id: DefibrillatorSyndicate
|
||||
parent: DefibrillatorCompact
|
||||
name: interdyne defibrillator
|
||||
description: Doubles as a self-defense weapon against war-crime inclined tiders.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Medical/defibsyndi.rsi
|
||||
layers:
|
||||
- state: icon
|
||||
- state: screen
|
||||
map: [ "enum.ToggleVisuals.Layer" ]
|
||||
visible: false
|
||||
shader: unshaded
|
||||
- state: ready
|
||||
map: ["enum.PowerDeviceVisualLayers.Powered"]
|
||||
shader: unshaded
|
||||
- type: MeleeWeapon
|
||||
damage:
|
||||
types:
|
||||
Blunt: 8
|
||||
- type: ItemToggleMeleeWeapon
|
||||
activatedSoundOnHit:
|
||||
path: /Audio/Items/Defib/defib_zap.ogg
|
||||
params:
|
||||
variation: 0.250
|
||||
activatedSoundOnHitNoDamage:
|
||||
path: /Audio/Items/Defib/defib_zap.ogg
|
||||
params:
|
||||
variation: 0.250
|
||||
volume: -10
|
||||
activatedDamage:
|
||||
types:
|
||||
Blunt: 8
|
||||
Shock: 16
|
||||
|
|
|
|||
|
|
@ -271,7 +271,6 @@
|
|||
transferAmount: 20
|
||||
onlyAffectsMobs: false
|
||||
injectOnly: true
|
||||
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
pen:
|
||||
|
|
@ -284,6 +283,102 @@
|
|||
- type: Tag
|
||||
tags: []
|
||||
|
||||
- type: entity
|
||||
name: puncturase auto-injector
|
||||
parent: ChemicalMedipen
|
||||
id: PunctAutoInjector
|
||||
description: A rapid dose of puncturase and tranexamic acid, intended for combat applications.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Medical/medipen.rsi
|
||||
layers:
|
||||
- state: punctpen
|
||||
map: ["enum.SolutionContainerLayers.Fill"]
|
||||
- type: SolutionContainerVisuals
|
||||
maxFillLevels: 1
|
||||
changeColor: false
|
||||
emptySpriteName: punctpen_empty
|
||||
- type: Hypospray
|
||||
solutionName: pen
|
||||
transferAmount: 15
|
||||
onlyAffectsMobs: false
|
||||
injectOnly: true
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
pen:
|
||||
maxVol: 15
|
||||
reagents:
|
||||
- ReagentId: Puncturase
|
||||
Quantity: 10
|
||||
- ReagentId: TranexamicAcid
|
||||
Quantity: 5
|
||||
- type: Tag
|
||||
tags: []
|
||||
|
||||
- type: entity
|
||||
name: pyrazine auto-injector
|
||||
parent: ChemicalMedipen
|
||||
id: PyraAutoInjector
|
||||
description: A rapid dose of pyrazine and dermaline, intended for combat applications.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Medical/medipen.rsi
|
||||
layers:
|
||||
- state: pyrapen
|
||||
map: ["enum.SolutionContainerLayers.Fill"]
|
||||
- type: SolutionContainerVisuals
|
||||
maxFillLevels: 1
|
||||
changeColor: false
|
||||
emptySpriteName: pyrapen_empty
|
||||
- type: Hypospray
|
||||
solutionName: pen
|
||||
transferAmount: 20
|
||||
onlyAffectsMobs: false
|
||||
injectOnly: true
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
pen:
|
||||
maxVol: 20
|
||||
reagents:
|
||||
- ReagentId: Pyrazine
|
||||
Quantity: 10
|
||||
- ReagentId: Dermaline
|
||||
Quantity: 10
|
||||
- type: Tag
|
||||
tags: []
|
||||
|
||||
- type: entity
|
||||
name: airloss auto-injector
|
||||
parent: ChemicalMedipen
|
||||
id: AirlossAutoInjector
|
||||
description: A rapid dose of saline and dexalin plus, intended to get someone up quickly.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Specific/Medical/medipen.rsi
|
||||
layers:
|
||||
- state: dexpen
|
||||
map: ["enum.SolutionContainerLayers.Fill"]
|
||||
- type: SolutionContainerVisuals
|
||||
maxFillLevels: 1
|
||||
changeColor: false
|
||||
emptySpriteName: dexpen_empty
|
||||
- type: Hypospray
|
||||
solutionName: pen
|
||||
transferAmount: 40
|
||||
onlyAffectsMobs: false
|
||||
injectOnly: true
|
||||
- type: SolutionContainerManager
|
||||
solutions:
|
||||
pen:
|
||||
maxVol: 40
|
||||
reagents:
|
||||
- ReagentId: Saline
|
||||
Quantity: 20
|
||||
- ReagentId: DexalinPlus
|
||||
Quantity: 20
|
||||
- type: Tag
|
||||
tags: []
|
||||
|
||||
- type: entity
|
||||
name: space medipen
|
||||
parent: ChemicalMedipen
|
||||
|
|
|
|||
|
|
@ -550,12 +550,8 @@
|
|||
solutions:
|
||||
food:
|
||||
maxVol: 20
|
||||
- type: SolutionSpiker
|
||||
sourceSolution: food
|
||||
- type: Extractable
|
||||
grindableSolutionName: food
|
||||
- type: StaticPrice
|
||||
price: 0
|
||||
- type: ExplosionResistance
|
||||
damageCoefficient: 0.025 # survives conventional explosives but not minibombs and nukes
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
- type: Destructible
|
||||
|
|
@ -568,6 +564,12 @@
|
|||
solution: food
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- type: SolutionSpiker
|
||||
sourceSolution: food
|
||||
- type: Extractable
|
||||
grindableSolutionName: food
|
||||
- type: StaticPrice
|
||||
price: 0
|
||||
- type: Tag
|
||||
tags:
|
||||
- Pill
|
||||
|
|
@ -588,9 +590,6 @@
|
|||
tags:
|
||||
- PillCanister
|
||||
- type: Storage
|
||||
whitelist: # DeltaV - Remove the ability to store anything other than pills in pill canisters
|
||||
tags:
|
||||
- Pill
|
||||
grid:
|
||||
- 0,0,4,1
|
||||
quickInsert: true
|
||||
|
|
@ -598,4 +597,7 @@
|
|||
areaInsertRadius: 1
|
||||
storageInsertSound: /Audio/Effects/pill_insert.ogg
|
||||
storageRemoveSound: /Audio/Effects/pill_remove.ogg
|
||||
whitelist:
|
||||
tags:
|
||||
- Pill
|
||||
- type: Dumpable
|
||||
|
|
|
|||
|
|
@ -209,8 +209,9 @@
|
|||
handle: false
|
||||
sound:
|
||||
path: /Audio/Effects/bite.ogg
|
||||
- type: Tag
|
||||
tags: [] # DeltaV - remove PlushieCarp tag to prevent wasting
|
||||
- type: Tag # DeltaV - remove PlushieCarp and ClothMade tag to prevent wasting/eating
|
||||
tags:
|
||||
- Payload
|
||||
|
||||
- type: entity #why is this all redefined down here as a parent of base object instead of just being parented to monkeycube?? TODO: Fix this shit
|
||||
parent: BaseItem
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- type: entity
|
||||
- type: entity
|
||||
id: WeaponWaterGunBase
|
||||
abstract: true
|
||||
parent: BaseItem
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
id: WeaponWaterBlaster
|
||||
parent: WeaponWaterGunBase
|
||||
name: water blaster
|
||||
description: With this bad boy, you'll be the cooleste kid at the summer barbecue.
|
||||
description: With this bad boy, you'll be the coolest kid at the summer barbecue.
|
||||
components:
|
||||
- type: Gun
|
||||
cameraRecoilScalar: 0 #no recoil
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@
|
|||
- type: GunRequiresWield
|
||||
- type: Item
|
||||
size: Ginormous
|
||||
sprite: Objects/Weapons/Melee/crusher-inhands.rsi
|
||||
- type: DisarmMalus
|
||||
- type: Prying
|
||||
|
||||
|
|
@ -195,3 +196,6 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- Pickaxe
|
||||
- type: Item
|
||||
size: Ginormous
|
||||
sprite: Objects/Weapons/Melee/crusher_glaive-inhands.rsi
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@
|
|||
- FoodPlateSmallPlastic
|
||||
- FoodBowlBig
|
||||
- FoodPlateTin
|
||||
- FoodPlateMuffinTin
|
||||
- FoodKebabSkewer
|
||||
- SprayBottle
|
||||
- MopItem
|
||||
|
|
|
|||
|
|
@ -113,6 +113,14 @@
|
|||
- type: GasMiner
|
||||
spawnGas: Tritium
|
||||
|
||||
- type: entity
|
||||
name: frezon gas miner
|
||||
parent: GasMinerBase
|
||||
id: GasMinerFrezon
|
||||
components:
|
||||
- type: GasMiner
|
||||
spawnGas: Frezon
|
||||
|
||||
- type: entity
|
||||
name: water vapor gas miner
|
||||
parent: GasMinerBase
|
||||
|
|
|
|||
|
|
@ -47,19 +47,30 @@
|
|||
whitelist:
|
||||
tags:
|
||||
- PlushieSharkGrey
|
||||
sprite: Objects/Fun/sharkplush.rsi
|
||||
mopbucket_carpplush:
|
||||
whitelist:
|
||||
tags:
|
||||
- PlushieCarp
|
||||
sprite: Objects/Specific/Janitorial/janitorial.rsi
|
||||
- type: Transform
|
||||
noRot: true
|
||||
- type: ItemSlots
|
||||
slots:
|
||||
shark_slot:
|
||||
name: mop-bucket-slot-component-slot-name-shark
|
||||
item_slot:
|
||||
name: mop-bucket-slot-component-slot-name-item
|
||||
ejectVerbText: mop-bucket-slot-component-eject-verb
|
||||
whitelist:
|
||||
tags:
|
||||
- PlushieSharkBlue
|
||||
- PlushieSharkPink
|
||||
- PlushieSharkGrey
|
||||
- PlushieCarp
|
||||
components:
|
||||
- Rehydratable
|
||||
priority: 3 # Higher than drinking priority
|
||||
- type: ReactiveContainer
|
||||
solution: bucket
|
||||
container: item_slot
|
||||
- type: Drink
|
||||
solution: bucket
|
||||
- type: Appearance
|
||||
|
|
@ -70,7 +81,7 @@
|
|||
containers:
|
||||
storagebase: !type:Container
|
||||
ents: []
|
||||
shark_slot: !type:ContainerSlot {}
|
||||
item_slot: !type:ContainerSlot {}
|
||||
- type: GuideHelp
|
||||
guides:
|
||||
- Janitorial
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
isCollidableWhenOpen: false
|
||||
openOnMove: false
|
||||
airtight: false
|
||||
capacity: 4 #4 Entities seems like a nice comfy fit for a cardboard box.
|
||||
capacity: 5 #5 entity capacity to fit all of your friends (or teammates on your nuclear operation without reinforcements).
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
entity_storage: !type:Container
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@
|
|||
canEditLabel: true
|
||||
- type: TextScreenVisuals
|
||||
color: FloralWhite
|
||||
textOffset: 0,8
|
||||
timerOffset: 0,8
|
||||
textOffset: 0,6
|
||||
timerOffset: 0,6
|
||||
textLength: 5
|
||||
rows: 1
|
||||
- type: Sprite
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
- id: RevenantSpawn
|
||||
- id: SleeperAgents
|
||||
- id: ZombieOutbreak
|
||||
- id: LoneOpsSpawn
|
||||
|
||||
- type: entity
|
||||
id: BaseStationEvent
|
||||
|
|
@ -457,7 +458,7 @@
|
|||
duration: 1
|
||||
- type: RuleGrids
|
||||
- type: LoadMapRule
|
||||
preloadedGrid: ShuttleStriker
|
||||
mapPath: /Maps/Shuttles/ShuttleEvent/striker.yml
|
||||
- type: NukeopsRule
|
||||
roundEndBehavior: Nothing
|
||||
- type: AntagSelection
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
components:
|
||||
- type: GameRule
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 300 # 5 min
|
||||
minimumTimeUntilFirstEvent: 600 # 10 min
|
||||
minMaxEventTiming:
|
||||
min: 750 # 12.5 min
|
||||
max: 930 # 17.5 min
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
components:
|
||||
- type: GameRule
|
||||
- type: BasicStationEventScheduler
|
||||
minimumTimeUntilFirstEvent: 300 # 5 min
|
||||
minimumTimeUntilFirstEvent: 600 # 10 min
|
||||
minMaxEventTiming:
|
||||
min: 750 # 12.5 min
|
||||
max: 930 # 17.5 min
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#- id: UnknownShuttleMeatZone
|
||||
#- id: UnknownShuttleMicroshuttle
|
||||
#- id: UnknownShuttleSpacebus
|
||||
#- id: UnknownShuttleInstigator # DeltaV - remove random ops
|
||||
|
||||
- type: entityTable
|
||||
id: UnknownShuttlesFreelanceTable
|
||||
|
|
@ -33,10 +32,10 @@
|
|||
- type: entityTable
|
||||
id: UnknownShuttlesHostileTable
|
||||
table: !type:AllSelector # we need to pass a list of rules, since rules have further restrictions to consider via StationEventComp
|
||||
children:
|
||||
- id: LoneOpsSpawn
|
||||
children: [] # DeltaV: empty list to remove instigator
|
||||
#- id: UnknownShuttleInstigator # DeltaV: remove random ops
|
||||
|
||||
# Shuttle Game Rules
|
||||
# Shuttle Game Rules
|
||||
|
||||
- type: entity
|
||||
abstract: true
|
||||
|
|
|
|||
|
|
@ -21,6 +21,13 @@
|
|||
back:
|
||||
- ClothingHeadHatHairflower
|
||||
|
||||
# Headphones
|
||||
- type: loadout
|
||||
id: Headphones
|
||||
storage:
|
||||
back:
|
||||
- ClothingNeckHeadphones
|
||||
|
||||
# Plushies
|
||||
- type: loadout
|
||||
id: PlushieLizard
|
||||
|
|
@ -165,7 +172,7 @@
|
|||
!type:OverallPlaytimeRequirement
|
||||
time: 36000 # 10hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorWhite
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -176,9 +183,9 @@
|
|||
!type:OverallPlaytimeRequirement
|
||||
time: 1800000 # 500hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorSilver
|
||||
|
||||
|
||||
- type: loadout
|
||||
id: TowelColorGold
|
||||
effects:
|
||||
|
|
@ -187,7 +194,7 @@
|
|||
!type:OverallPlaytimeRequirement
|
||||
time: 3600000 # 1000hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorGold
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -199,7 +206,7 @@
|
|||
department: Logistics # DeltaV: Logistics replaces Cargo
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorLightBrown
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -211,7 +218,7 @@
|
|||
department: Civilian
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorGreen
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -223,7 +230,7 @@
|
|||
department: Command
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorDarkBlue
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -235,9 +242,9 @@
|
|||
department: Engineering
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorOrange
|
||||
|
||||
|
||||
- type: loadout
|
||||
id: TowelColorLightBlue
|
||||
effects:
|
||||
|
|
@ -247,7 +254,7 @@
|
|||
department: Medical
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorLightBlue
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -259,7 +266,7 @@
|
|||
department: Epistemics # DeltaV: Epistemics replaces Science
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorPurple
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -271,7 +278,7 @@
|
|||
department: Security
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorRed
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -283,7 +290,7 @@
|
|||
role: JobPassenger
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorGray
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -295,7 +302,7 @@
|
|||
role: JobChaplain
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorBlack
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -307,7 +314,7 @@
|
|||
role: JobLibrarian
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorDarkGreen
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -319,7 +326,7 @@
|
|||
role: JobLawyer
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorMaroon
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -331,7 +338,7 @@
|
|||
role: JobClown
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorYellow
|
||||
|
||||
- type: loadout
|
||||
|
|
@ -343,5 +350,5 @@
|
|||
role: JobMime
|
||||
time: 360000 # 100hr
|
||||
storage:
|
||||
back:
|
||||
back:
|
||||
- TowelColorMime
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
loadouts:
|
||||
- FlowerWreath
|
||||
- Hairflower
|
||||
- Headphones
|
||||
- PlushieLizard
|
||||
- PlushieSpaceLizard
|
||||
- Lighter
|
||||
|
|
|
|||
|
|
@ -12,6 +12,3 @@
|
|||
|
||||
- type: Tag
|
||||
id: NormalityCrystal
|
||||
|
||||
- type: Tag
|
||||
id: PlushieCarp
|
||||
|
|
|
|||
|
|
@ -127,6 +127,8 @@
|
|||
Junction: BaseAirlock
|
||||
WallMounts: ScienceLabsWalls
|
||||
Window: BaseWindow
|
||||
tiles:
|
||||
FallbackTile: FloorDark
|
||||
whitelists:
|
||||
Rooms:
|
||||
tags:
|
||||
|
|
|
|||
|
|
@ -1779,6 +1779,67 @@
|
|||
FoodOrange: 1
|
||||
FoodAmbrosiaVulgaris: 1
|
||||
|
||||
# Muffins
|
||||
|
||||
- type: microwaveMealRecipe
|
||||
id: RecipeMuffin
|
||||
name: muffin recipe
|
||||
result: FoodBakedMuffin
|
||||
time: 15
|
||||
solids:
|
||||
FoodPlateMuffinTin: 1
|
||||
FoodDoughSlice: 1
|
||||
reagents:
|
||||
Sugar: 10
|
||||
|
||||
- type: microwaveMealRecipe
|
||||
id: RecipeMuffinChocolate
|
||||
name: chocolate muffin recipe
|
||||
result: FoodBakedMuffinChocolate
|
||||
time: 15
|
||||
solids:
|
||||
FoodPlateMuffinTin: 1
|
||||
FoodDoughSlice: 1
|
||||
FoodSnackChocolateBar: 1
|
||||
reagents:
|
||||
Sugar: 10
|
||||
|
||||
- type: microwaveMealRecipe
|
||||
id: RecipeMuffinBerry
|
||||
name: berry muffin recipe
|
||||
result: FoodBakedMuffinBerry
|
||||
time: 15
|
||||
solids:
|
||||
FoodPlateMuffinTin: 1
|
||||
FoodDoughSlice: 1
|
||||
FoodBerries: 1
|
||||
reagents:
|
||||
Sugar: 10
|
||||
|
||||
- type: microwaveMealRecipe
|
||||
id: RecipeMuffinBanana
|
||||
name: banana muffin recipe
|
||||
result: FoodBakedMuffinBanana
|
||||
time: 15
|
||||
solids:
|
||||
FoodPlateMuffinTin: 1
|
||||
FoodDoughSlice: 1
|
||||
FoodBanana: 1
|
||||
reagents:
|
||||
Sugar: 10
|
||||
|
||||
- type: microwaveMealRecipe
|
||||
id: RecipeMuffinCherry
|
||||
name: cherry muffin recipe
|
||||
result: FoodBakedMuffinCherry
|
||||
time: 15
|
||||
solids:
|
||||
FoodPlateMuffinTin: 1
|
||||
FoodDoughSlice: 1
|
||||
FoodCherry: 3
|
||||
reagents:
|
||||
Sugar: 10
|
||||
|
||||
# NOT ACTUAL FOOD
|
||||
|
||||
- type: microwaveMealRecipe
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
steps:
|
||||
- material: Cloth
|
||||
amount: 2
|
||||
doAfter: 10
|
||||
doAfter: 3
|
||||
- node: gauze
|
||||
entity: Gauze1
|
||||
|
|
|
|||
|
|
@ -1,39 +1,39 @@
|
|||
# Base prototypes
|
||||
|
||||
- type: latheRecipe
|
||||
id: MiniHoe
|
||||
result: HydroponicsToolMiniHoe
|
||||
completetime: 2
|
||||
abstract: true
|
||||
parent: BaseToolRecipe
|
||||
id: BaseHydroToolRecipe
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 100
|
||||
|
||||
# Recipes
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseHydroToolRecipe
|
||||
id: HydroponicsToolMiniHoe
|
||||
result: HydroponicsToolMiniHoe
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseHydroToolRecipe
|
||||
id: HydroponicsToolScythe
|
||||
result: HydroponicsToolScythe
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 300
|
||||
Plastic: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseHydroToolRecipe
|
||||
id: HydroponicsToolHatchet
|
||||
result: HydroponicsToolHatchet
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 100
|
||||
|
||||
- type: latheRecipe
|
||||
id: Spade
|
||||
parent: BaseHydroToolRecipe
|
||||
id: HydroponicsToolSpade
|
||||
result: HydroponicsToolSpade
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 100
|
||||
|
||||
|
||||
- type: latheRecipe
|
||||
id: Clippers
|
||||
parent: BaseHydroToolRecipe
|
||||
id: HydroponicsToolClippers
|
||||
result: HydroponicsToolClippers
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 100
|
||||
|
|
|
|||
|
|
@ -1,67 +1,65 @@
|
|||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: ButchCleaver
|
||||
result: ButchCleaver
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 300
|
||||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: KitchenKnife
|
||||
result: KitchenKnife
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
id: DrinkMug
|
||||
result: DrinkMug
|
||||
abstract: true
|
||||
id: BaseGlasswareRecipe
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGlasswareRecipe
|
||||
id: DrinkMug
|
||||
result: DrinkMug
|
||||
|
||||
- type: latheRecipe
|
||||
parent: DrinkMug
|
||||
id: DrinkMugMetal
|
||||
result: DrinkMugMetal
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Steel: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: DrinkMug
|
||||
id: DrinkGlass
|
||||
result: DrinkGlass
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: DrinkMug
|
||||
id: DrinkShotGlass
|
||||
result: DrinkShotGlass
|
||||
completetime: 0.4
|
||||
materials:
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: DrinkMug
|
||||
id: DrinkGlassCoupeShaped
|
||||
result: DrinkGlassCoupeShaped
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
id: CustomDrinkJug
|
||||
result: CustomDrinkJug
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 200
|
||||
|
||||
- type: latheRecipe
|
||||
id: CustomDrinkJug
|
||||
result: CustomDrinkJug
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseGlasswareRecipe
|
||||
id: FoodPlate
|
||||
result: FoodPlate
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
id: FoodPlateSmall
|
||||
|
|
@ -71,25 +69,23 @@
|
|||
Glass: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: FoodPlate
|
||||
id: FoodPlatePlastic
|
||||
result: FoodPlatePlastic
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Plastic: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: FoodPlateSmall
|
||||
id: FoodPlateSmallPlastic
|
||||
result: FoodPlateSmallPlastic
|
||||
completetime: 0.4
|
||||
materials:
|
||||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: FoodPlate
|
||||
id: FoodBowlBig
|
||||
result: FoodBowlBig
|
||||
completetime: 0.8
|
||||
materials:
|
||||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
id: FoodPlateTin
|
||||
|
|
@ -98,6 +94,13 @@
|
|||
materials:
|
||||
Steel: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: FoodPlateTin
|
||||
id: FoodPlateMuffinTin
|
||||
result: FoodPlateMuffinTin
|
||||
materials:
|
||||
Steel: 50
|
||||
|
||||
- type: latheRecipe
|
||||
id: FoodKebabSkewer
|
||||
result: FoodKebabSkewer
|
||||
|
|
|
|||
|
|
@ -1,51 +1,46 @@
|
|||
# Base prototypes
|
||||
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
parent: BaseToolRecipe
|
||||
id: BaseSurgicalRecipe
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
# Recipes
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSurgicalRecipe
|
||||
id: Scalpel
|
||||
result: Scalpel
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSurgicalRecipe
|
||||
id: Retractor
|
||||
result: Retractor
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSurgicalRecipe
|
||||
id: Cautery
|
||||
result: Cautery
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Drill
|
||||
result: Drill
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSurgicalRecipe
|
||||
id: Saw
|
||||
result: Saw
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseSurgicalRecipe
|
||||
id: Hemostat
|
||||
result: Hemostat
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
- type: latheRecipe
|
||||
id: BodyBag
|
||||
|
|
@ -75,7 +70,7 @@
|
|||
result: Gauze1
|
||||
completetime: 1
|
||||
materials:
|
||||
Cloth: 200
|
||||
Cloth: 100 # lathe more efficient than handcrafting
|
||||
|
||||
- type: latheRecipe
|
||||
id: HandheldCrewMonitor
|
||||
|
|
@ -150,66 +145,51 @@
|
|||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitBurn
|
||||
result: MedkitBurn
|
||||
name: lathe-recipe-MedkitBurn-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitToxin
|
||||
result: MedkitToxin
|
||||
name: lathe-recipe-MedkitToxin-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitO2
|
||||
result: MedkitO2
|
||||
name: lathe-recipe-MedkitO2-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitBrute
|
||||
result: MedkitBrute
|
||||
name: lathe-recipe-MedkitBrute-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitAdvanced
|
||||
result: MedkitAdvanced
|
||||
name: lathe-recipe-MedkitAdvanced-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitRadiation
|
||||
result: MedkitRadiation
|
||||
name: lathe-recipe-MedkitRadiation-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Medkit
|
||||
id: MedkitCombat
|
||||
result: MedkitCombat
|
||||
name: lathe-recipe-MedkitCombat-name
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: HandLabeler
|
||||
result: HandLabeler
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Plastic: 100
|
||||
|
||||
|
|
@ -229,20 +209,14 @@
|
|||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: RollerBedSpawnFolded
|
||||
id: CheapRollerBedSpawnFolded
|
||||
result: CheapRollerBedSpawnFolded
|
||||
completetime: 1
|
||||
materials:
|
||||
Steel: 600
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: RollerBedSpawnFolded
|
||||
id: EmergencyRollerBedSpawnFolded
|
||||
result: EmergencyRollerBedSpawnFolded
|
||||
completetime: 1
|
||||
materials:
|
||||
Steel: 600
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
id: WhiteCane
|
||||
|
|
|
|||
|
|
@ -1,40 +1,51 @@
|
|||
# Base prototypes
|
||||
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
id: BaseToolRecipe
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
abstract: true
|
||||
parent: BaseToolRecipe
|
||||
id: BaseBigToolRecipe
|
||||
materials:
|
||||
Steel: 800
|
||||
Glass: 300
|
||||
|
||||
# Recipes
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Wirecutter
|
||||
result: Wirecutter
|
||||
icon:
|
||||
sprite: Objects/Tools/wirecutters.rsi
|
||||
state: cutters-map
|
||||
result: Wirecutter
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Screwdriver
|
||||
result: Screwdriver
|
||||
icon:
|
||||
sprite: Objects/Tools/screwdriver.rsi
|
||||
state: screwdriver-map
|
||||
result: Screwdriver
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Welder
|
||||
result: Welder
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 400
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Wrench
|
||||
result: Wrench
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
|
|
@ -42,155 +53,122 @@
|
|||
id: CableStack
|
||||
result: CableApcStack1
|
||||
category: Parts
|
||||
completetime: 2
|
||||
completetime: 0.1
|
||||
materials:
|
||||
Steel: 30
|
||||
|
||||
- type: latheRecipe
|
||||
parent: CableStack
|
||||
id: CableMVStack
|
||||
result: CableMVStack1
|
||||
category: Parts
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 30
|
||||
|
||||
- type: latheRecipe
|
||||
parent: CableStack
|
||||
id: CableHVStack
|
||||
result: CableHVStack1
|
||||
category: Parts
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 30
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: CrowbarGreen
|
||||
result: CrowbarGreen
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Pickaxe
|
||||
result: Pickaxe
|
||||
category: Tools
|
||||
completetime: 4
|
||||
materials:
|
||||
Steel: 1000
|
||||
Wood: 500
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Shovel
|
||||
result: Shovel
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Wood: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: Multitool
|
||||
result: Multitool
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: Multitool
|
||||
id: NetworkConfigurator
|
||||
result: NetworkConfigurator
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 200
|
||||
Plastic: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: PowerDrill
|
||||
result: PowerDrill
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 600
|
||||
Plastic: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: RCD
|
||||
result: RCDEmpty
|
||||
category: Tools
|
||||
completetime: 4
|
||||
materials:
|
||||
Steel: 1000
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: RCDAmmo
|
||||
result: RCDAmmo
|
||||
category: Tools
|
||||
completetime: 2.4
|
||||
materials:
|
||||
Steel: 500
|
||||
Plastic: 250
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBigToolRecipe
|
||||
id: HandHeldMassScanner
|
||||
result: HandHeldMassScannerEmpty
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 800
|
||||
Glass: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBigToolRecipe
|
||||
id: HandheldGPSBasic
|
||||
result: HandheldGPSBasic
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 800
|
||||
Glass: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBigToolRecipe
|
||||
id: TRayScanner
|
||||
result: trayScanner
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 800
|
||||
Glass: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseBigToolRecipe
|
||||
id: GasAnalyzer
|
||||
result: GasAnalyzer
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 800
|
||||
Glass: 300
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: SprayPainter
|
||||
result: SprayPainter
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 300
|
||||
Plastic: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: UtilityBelt
|
||||
result: ClothingBeltUtility
|
||||
category: Tools
|
||||
completetime: 2
|
||||
materials:
|
||||
Cloth: 100
|
||||
Steel: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: HolofanProjector
|
||||
result: HolofanProjectorEmpty
|
||||
category: Tools
|
||||
completetime: 8
|
||||
materials:
|
||||
Steel: 300
|
||||
|
|
@ -198,18 +176,18 @@
|
|||
Plastic: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: WelderExperimental
|
||||
result: WelderExperimental
|
||||
category: Tools
|
||||
completetime: 6
|
||||
materials:
|
||||
Steel: 800
|
||||
Plasma: 200
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: JawsOfLife
|
||||
result: JawsOfLife
|
||||
category: Tools
|
||||
completetime: 6
|
||||
materials:
|
||||
Steel: 1000
|
||||
|
|
@ -218,9 +196,9 @@
|
|||
Gold: 50
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: HoloprojectorField
|
||||
result: HoloprojectorFieldEmpty
|
||||
category: Tools
|
||||
completetime: 3
|
||||
materials:
|
||||
Steel: 500
|
||||
|
|
@ -228,9 +206,9 @@
|
|||
Glass: 100
|
||||
|
||||
- type: latheRecipe
|
||||
parent: BaseToolRecipe
|
||||
id: WeaponParticleDecelerator
|
||||
result: WeaponParticleDecelerator
|
||||
category: Tools
|
||||
completetime: 6
|
||||
materials:
|
||||
Steel: 750
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
amount: 1
|
||||
Sulfur:
|
||||
amount: 1
|
||||
Oxygen:
|
||||
Oxygen:
|
||||
amount: 2
|
||||
products:
|
||||
SulfuricAcid: 3
|
||||
|
|
@ -205,6 +205,20 @@
|
|||
energyConsumption: 12500
|
||||
duration: 15
|
||||
|
||||
- type: reaction
|
||||
id: Flash
|
||||
impact: High
|
||||
priority: 20
|
||||
reactants:
|
||||
Aluminium:
|
||||
amount: 1
|
||||
Potassium:
|
||||
amount: 1
|
||||
Sulfur:
|
||||
amount: 1
|
||||
effects:
|
||||
- !type:FlashReactionEffect
|
||||
|
||||
- type: reaction
|
||||
id: TableSalt
|
||||
minTemp: 370
|
||||
|
|
@ -501,3 +515,4 @@
|
|||
amount: 1
|
||||
products:
|
||||
Tazinide: 1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- type: job
|
||||
- type: job
|
||||
id: ServiceWorker
|
||||
name: job-name-serviceworker
|
||||
description: job-description-serviceworker
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
startingGear: ServiceWorkerGear
|
||||
icon: "JobIconServiceWorker"
|
||||
supervisors: job-supervisors-service
|
||||
canBeAntag: true # DeltaV - Can be antagonist
|
||||
access:
|
||||
- Service
|
||||
- Maintenance
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
- type: preloadedGrid
|
||||
id: ShuttleStriker
|
||||
path: /Maps/Shuttles/ShuttleEvent/striker.yml
|
||||
copies: 2
|
||||
|
||||
- type: preloadedGrid
|
||||
id: ShuttleCargoLost
|
||||
path: /Maps/Shuttles/ShuttleEvent/lost_cargo.yml
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue