Merge branch 'DeltaV-Station:master' into Fixhouse

This commit is contained in:
turtlemutt 2026-07-07 09:41:00 -07:00 committed by GitHub
commit 2264450764
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
118 changed files with 1301 additions and 269 deletions

View File

@ -86,7 +86,7 @@ Any individual requiring any above item in the course of their job, or for regul
Should the holder commit crimes through the use of such authorized items, the authorizing party may be found guilty of Accessory to said crimes, in addition to Endangerment and Abuse of Power where applicable. The Commanding Officer is also authorized to supervise the approval and revocation of documentation as they see fit.
== Controlled Substances ==
Any individual requiring a Controlled Substance in the course of their job, or for regular function, must request access to a prescription or special dispensation from the Chief Medical Officer. Medical personnel are also permitted to [[Standard Operating Procedure#Prescribing Medicine|prescribe medication]] for chronic illnesses or mental health. Any such document must state the substance(s) being prescribed, the amount(s) where applicable, and the stamp and signature of the authorizing party.
Any individual requiring a Controlled Substance in the course of their job, or for regular function, must request access to a prescription or special dispensation from the Chief Medical Officer. Medical personnel are also permitted to [[Standard Operating Procedure#Prescribing Medication|prescribe medication]] for chronic illnesses or mental health. Any such document must state the substance(s) being prescribed, the amount(s) where applicable, and the stamp and signature of the authorizing party.
A list of such Substances follow:

View File

@ -1,8 +1,10 @@
using Content.Shared.MedicalScanner;
using Content.Shared._DV.MedicalRecords;
using JetBrains.Annotations; // DeltaV - Medical Records
using Content.Shared._DV.Medical; // DeltaV
using Content.Shared._DV.MedicalRecords; // DeltaV
using JetBrains.Annotations; // DeltaV
using Robust.Client.UserInterface;
namespace Content.Client.HealthAnalyzer.UI
{
[UsedImplicitly]
@ -22,6 +24,7 @@ namespace Content.Client.HealthAnalyzer.UI
_window = this.CreateWindow<HealthAnalyzerWindow>();
_window.HealthAnalyzer.OnTriageStatusChanged += SendTriageStatusMessage; // DeltaV - Medical Records
_window.HealthAnalyzer.OnClaimPatient += SendTriageClaimMessage; // DeltaV - Medical Records
_window.HealthAnalyzer.OnPrintMedTekRecord += () => SendMessage(new HealthAnalyzerPrintReportMessage()); // DeltaV - MedTekReports
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
}

View File

@ -1,7 +1,9 @@
<BoxContainer
xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client._DV.UserInterfaces"
xmlns:xe="clr-namespace:Content.Client.UserInterface.XamlExtensions"
VerticalExpand="True"
Orientation="Vertical">
Orientation="Vertical"> <!-- DeltaV - added ui and xe namespaces -->
<Label
Name="NoPatientDataText"
Text="{Loc health-analyzer-window-no-patient-data-text}" />
@ -11,7 +13,8 @@
Margin="0 0 0 5"
Orientation="Vertical">
<BoxContainer Orientation="Horizontal" Margin="0 0 0 5">
<TextureRect Name="NoDataTex" Access="Public" SetSize="96 96" Visible="false" Stretch="KeepAspectCentered" TexturePath="/Textures/Interface/Misc/health_analyzer_out_of_range.png"/> <!-- DeltaV - Size changed to 96-->
<SpriteView OverrideDirection="South" Scale="2 2" Name="SpriteView" Access="Public" SetSize="64 64" />
<TextureRect Name="NoDataTex" Access="Public" SetSize="64 64" Visible="false" Stretch="KeepAspectCentered" TexturePath="/Textures/Interface/Misc/health_analyzer_out_of_range.png"/>
<BoxContainer Margin="5 0 0 0" Orientation="Vertical" VerticalAlignment="Top">
<RichTextLabel Name="NameLabel" SetWidth="150" />
<Label Name="SpeciesLabel" VerticalAlignment="Top" StyleClasses="LabelSubText" />
@ -22,6 +25,14 @@
<Label Margin="0 0 5 0" HorizontalExpand="True" HorizontalAlignment="Right" VerticalExpand="True"
VerticalAlignment="Top" Name="ScanModeLabel"
Text="{Loc 'health-analyzer-window-entity-unknown-text'}" />
<!-- BEGIN DeltaV - MedTek Reports -->
<BoxContainer HorizontalExpand="False"
Orientation="Vertical"
Name="PrintButtonsContainer"
Margin="0 0 5 0">
<ui:IconButton Name="PrintReportButton" Icon="{xe:Tex '/Textures/_DV/Interface/VerbIcons/print.png'}" />
</BoxContainer>
<!-- END DeltaV -->
</BoxContainer>
<PanelContainer StyleClasses="LowDivider" />

View File

@ -49,6 +49,8 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
public event Action<TriageStatus>? OnTriageStatusChanged;
public event Action? OnClaimPatient;
// End DeltaV - Medical Records
public Action? OnPrintMedTekRecord; // DeltaV - MedTek Reports
public HealthAnalyzerControl()
{
@ -84,6 +86,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
StatusBox.Children.Last().RemoveStyleClass("ButtonSquare");
ClaimButton.OnPressed += _ => OnClaimPatient?.Invoke();
// End DeltaV - Medical Records
PrintReportButton.OnPressed += (_) => OnPrintMedTekRecord?.Invoke(); // DeltaV - MedTek Reports
}
public void Populate(HealthAnalyzerUiState state)
@ -109,7 +112,12 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
ScanModeLabel.FontColorOverride = state.ScanMode.HasValue && state.ScanMode.Value ? Color.Green : Color.Red;
PrintReportButton.Disabled = state is { ScanMode: false }; // DeltaV
// Patient Information
SpriteView.SetEntity(target.Value);
SpriteView.Visible = state.ScanMode.HasValue && state.ScanMode.Value;
NoDataTex.Visible = !SpriteView.Visible;
var name = new FormattedMessage();
name.PushColor(Color.White);
@ -255,7 +263,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
var groupTitleText = $"{Loc.GetString(
"health-analyzer-window-damage-group-text",
("damageGroup", _prototypes.Index<DamageGroupPrototype>(damageGroupId).LocalizedName),
("damageGroup", _prototypes.Index(damageGroupId).LocalizedName),
("amount", damageAmount)
)}";
@ -270,7 +278,7 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
GroupsContainer.AddChild(groupContainer);
// Show the damage for each type in that group.
var group = _prototypes.Index<DamageGroupPrototype>(damageGroupId);
var group = _prototypes.Index(damageGroupId);
foreach (var type in group.DamageTypes)
{

View File

@ -29,11 +29,22 @@ public sealed class WelderStatusControl : PollingItemStatusControl<WelderStatusC
protected override Data PollData()
{
var (fuel, capacity) = _toolSystem.GetWelderFuelAndCapacity(_parent, _parent.Comp);
return new Data(fuel, capacity, _parent.Comp.Enabled);
return new Data(fuel, capacity, _parent.Comp.Enabled, _parent.Comp.OnlyDisplayFuel); // Monolith - Nanite Applicators
}
protected override void Update(in Data data)
{
// BEGIN Monolith - Nanite applicator
if (data.OnlyDisplayFuel)
{
_label.SetMarkup(Loc.GetString("welder-component-on-examine-less-detailed-message",
("colorName", data.Fuel < data.FuelCapacity / 4f ? "darkorange" : "orange"),
("fuelLeft", data.Fuel),
("fuelCapacity", data.FuelCapacity)));
return;
}
// END Monolith
_label.SetMarkup(Loc.GetString("welder-component-on-examine-detailed-message",
("colorName", data.Fuel < data.FuelCapacity / 4f ? "darkorange" : "orange"),
("fuelLeft", data.Fuel),
@ -41,5 +52,5 @@ public sealed class WelderStatusControl : PollingItemStatusControl<WelderStatusC
("status", Loc.GetString(data.Lit ? "welder-component-on-examine-welder-lit-message" : "welder-component-on-examine-welder-not-lit-message"))));
}
public record struct Data(FixedPoint2 Fuel, FixedPoint2 FuelCapacity, bool Lit);
public record struct Data(FixedPoint2 Fuel, FixedPoint2 FuelCapacity, bool Lit, bool OnlyDisplayFuel = false); // Monolith - Nanite Applicators
}

View File

@ -0,0 +1,53 @@
using Content.Client.UserInterface.Controls;
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Prototypes;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Client._DV.CosmicCult.UI;
[UsedImplicitly]
public sealed class CosmicGlyphDrawBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
{
[Dependency] private readonly IPrototypeManager _prototype = default!;
private SimpleRadialMenu? _menu;
protected override void Open()
{
base.Open();
IoCManager.InjectDependencies(this);
_menu = this.CreateWindow<SimpleRadialMenu>();
_menu.OpenOverMouseScreenPosition();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not CosmicGlyphDrawBuiState glyphState || _menu == null)
return;
var options = new List<RadialMenuOptionBase>();
foreach (var glyphId in glyphState.Glyphs)
{
var glyph = _prototype.Index(glyphId);
options.Add(new RadialMenuActionOption<ProtoId<GlyphPrototype>>(SelectGlyph, glyph.ID)
{
IconSpecifier = RadialMenuIconSpecifier.With(glyph.Entity),
ToolTip = $"{Loc.GetString(glyph.Name)}\n{Loc.GetString(glyph.Tooltip)}",
});
}
_menu.SetButtons(options);
}
private void SelectGlyph(ProtoId<GlyphPrototype> glyphId)
{
SendMessage(new CosmicGlyphDrawSelectedMessage(glyphId));
}
}

View File

@ -19,9 +19,6 @@ public sealed class MonumentBoundUserInterface(EntityUid owner, Enum uiKey) : Bo
_menu = this.CreateWindow<MonumentMenu>();
_menu.OnSelectGlyphButtonPressed += protoId => SendMessage(new GlyphSelectedMessage(protoId));
_menu.OnRemoveGlyphButtonPressed += () => SendMessage(new GlyphRemovedMessage());
_menu.OnGainButtonPressed += OnInfluenceSelected;
}

View File

@ -5,13 +5,6 @@
MinSize="650 600"
SetSize="750 620">
<BoxContainer Orientation="Vertical" Margin="5 5 5 0">
<!-- Header -->
<BoxContainer Margin="7 10 7 0">
<!-- Progress bar -->
<ProgressBar Name="CultProgressBar" SetHeight="30" MaxValue="100" HorizontalExpand="True">
<Label Name="ProgressBarPercentage" HorizontalAlignment="Center"/>
</ProgressBar>
</BoxContainer>
<!-- Main body -->
<BoxContainer Orientation="Horizontal" VerticalExpand="True" Margin="10 20 10 10">
<!-- Left section -->
@ -31,27 +24,6 @@
<Label HorizontalAlignment="Center" Text="{Loc 'monument-interface-entropy-available-label'}" Margin="0 0 5 0" StyleClasses="LabelSmall" />
<Label HorizontalAlignment="Center" Name="AvailableEntropy" FontColorOverride="#4CA7AD" StyleClasses="LabelSmall" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="0 5 0 0" HorizontalAlignment="Center">
<Label HorizontalAlignment="Center" Text="{Loc 'monument-interface-entropy-next-stage-title'}" Margin="0 0 5 0" StyleClasses="LabelSmall" />
<Label HorizontalAlignment="Center" Name="EntropyUntilNextStage" FontColorOverride="#4CA7AD" StyleClasses="LabelSmall" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" Margin="0 5 0 0" HorizontalAlignment="Center">
<Label HorizontalAlignment="Center" Text="{Loc 'monument-interface-entropy-seperator'}" Margin="0 0 5 0" StyleClasses="LabelSmall" />
<Label HorizontalAlignment="Center" Name="OrSeperator" FontColorOverride="#4CA7AD" StyleClasses="LabelSmall" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Center">
<Label HorizontalAlignment="Center" Text="{Loc 'monument-interface-entropy-crew-convert-title'}" Margin="0 0 5 0" StyleClasses="LabelSmall" />
<Label HorizontalAlignment="Center" Name="CrewToConvertUntilNextStage" FontColorOverride="#4CA7AD" StyleClasses="LabelSmall" />
</BoxContainer>
</BoxContainer>
<!-- Second section (Glyphs) -->
<BoxContainer Name="GlyphArea" HorizontalExpand="True" MinHeight="75" Orientation="Vertical" Margin="0 20 0 0">
<Label HorizontalAlignment="Center" Text="{Loc 'monument-interface-glyphs-title'}" />
<PanelContainer StyleClasses="LowDivider" />
<!-- Filled out programatically -->
<GridContainer HorizontalAlignment="Center" Name="GlyphContainer" Columns="3" Margin="0 5" />
<Button Name="SelectGlyphButton" Text="{Loc 'monument-interface-glyphs-button-scribe'}" SetHeight="50" Margin="0 10 0 0" StyleClasses="ButtonColorPurpleAndCool" />
<Button Name="RemoveGlyphButton" Text="{Loc 'monument-interface-glyphs-button-unscribe'}" SetHeight="50" Margin="0 10 0 0" StyleClasses="ButtonColorPurpleAndCool" />
</BoxContainer>
</BoxContainer>
<!-- Right section -->

View File

@ -8,7 +8,6 @@ using Content.Shared._DV.CosmicCult.Prototypes;
using Content.Shared._DV.CosmicCult;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
@ -32,10 +31,6 @@ public sealed partial class MonumentMenu : FancyWindow
// All influence prototypes
private readonly IEnumerable<InfluencePrototype> _influencePrototypes;
private readonly ButtonGroup _glyphButtonGroup;
private ProtoId<GlyphPrototype> _selectedGlyphProtoId = string.Empty;
private HashSet<ProtoId<GlyphPrototype>> _unlockedGlyphProtoIds = [];
public Action<ProtoId<GlyphPrototype>>? OnSelectGlyphButtonPressed;
public Action? OnRemoveGlyphButtonPressed;
public Action<ProtoId<InfluencePrototype>>? OnGainButtonPressed;
private int _entropyPerCultist = 0;
@ -52,9 +47,6 @@ public sealed partial class MonumentMenu : FancyWindow
_glyphButtonGroup = new ButtonGroup();
RemoveGlyphButton.OnPressed += _ => OnRemoveGlyphButtonPressed?.Invoke();
SelectGlyphButton.OnPressed += _ => OnSelectGlyphButtonPressed?.Invoke(_selectedGlyphProtoId);
_cfg.OnValueChanged(DCCVars.CosmicCultistEntropyValue, entropy =>
{
_entropyPerCultist = entropy;
@ -64,32 +56,10 @@ public sealed partial class MonumentMenu : FancyWindow
public void UpdateState(MonumentBuiState state)
{
_selectedGlyphProtoId = state.SelectedGlyph;
_unlockedGlyphProtoIds = state.UnlockedGlyphs;
CultProgressBar.BackgroundStyleBoxOverride = new StyleBoxFlat { BackgroundColor = new Color(15, 17, 30) };
CultProgressBar.ForegroundStyleBoxOverride = new StyleBoxFlat { BackgroundColor = new Color(91, 62, 124) };
UpdateBar(state);
UpdateEntropy(state);
UpdateGlyphs();
UpdateInfluences(state);
}
/// <summary>
/// Updates the progress bar
/// </summary>
private void UpdateBar(MonumentBuiState state)
{
var percentComplete = 100f * ((float)state.CurrentProgress / state.TargetProgress);
percentComplete = Math.Min(percentComplete, 100f);
CultProgressBar.Value = percentComplete;
ProgressBarPercentage.Text = Loc.GetString("monument-interface-progress-bar", ("percentage", percentComplete.ToString("0")));
}
/// <summary>
/// Updates the entropy fields
/// </summary>
@ -106,39 +76,6 @@ public sealed partial class MonumentMenu : FancyWindow
var crewToNextStage = (int)Math.Max(Math.Round((double)entropyToNextStage / _entropyPerCultist, MidpointRounding.ToPositiveInfinity), min); //force it to be at least one
AvailableEntropy.Text = Loc.GetString("monument-interface-entropy-value", ("infused", availableEntropy));
EntropyUntilNextStage.Text = Loc.GetString("monument-interface-entropy-value", ("infused", entropyToNextStage.ToString()));
CrewToConvertUntilNextStage.Text = crewToNextStage.ToString();
}
// Update all the glyph buttons
private void UpdateGlyphs()
{
GlyphContainer.RemoveAllChildren();
foreach (var glyph in _glyphPrototypes)
{
var boxContainer = new BoxContainer();
var unlocked = _unlockedGlyphProtoIds.Contains(glyph.ID);
var button = new Button
{
HorizontalExpand = true,
StyleClasses = { StyleClass.ButtonSquare },
ToolTip = Loc.GetString(glyph.Tooltip),
Group = _glyphButtonGroup,
Pressed = glyph.ID == _selectedGlyphProtoId,
Disabled = !unlocked,
Modulate = !unlocked ? Color.Gray : Color.White,
};
button.OnPressed += _ => _selectedGlyphProtoId = glyph.ID;
var glyphIcon = new TextureRect
{
Texture = _sprite.Frame0(glyph.Icon),
TextureScale = new Vector2(2f, 2f),
Stretch = TextureRect.StretchMode.KeepCentered,
};
button.AddChild(glyphIcon);
boxContainer.AddChild(button);
GlyphContainer.AddChild(boxContainer);
}
}
// Update all the influence thingies

View File

@ -22,6 +22,7 @@ public abstract partial class InteractionTest
protected const string Wrench = "Wrench";
protected const string Screw = "Screwdriver";
protected const string Weld = "WelderExperimental";
protected const string Applicator = "NaniteApplicatorSyndicate"; // DeltaV
protected const string Pry = "Crowbar";
protected const string Cut = "Wirecutter";

View File

@ -186,7 +186,7 @@ public sealed class VendingInteractionTest : InteractionTest
Assert.That(IsUiOpen(VendingMachineUiKey.Key), Is.False, "Opened BUI of broken vending machine.");
// Repair the vending machine
await InteractUsing(Weld);
await InteractUsing(Applicator); // DeltaV
// Make sure the BUI can open now that the machine has been repaired
await Activate();

View File

@ -27,7 +27,7 @@ using Content.Shared._DV.MedicalRecords;
namespace Content.Server.Medical;
public sealed class HealthAnalyzerSystem : EntitySystem
public sealed partial class HealthAnalyzerSystem : EntitySystem // DeltaV - Made Partial
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly PowerCellSystem _cell = default!;
@ -55,6 +55,7 @@ public sealed class HealthAnalyzerSystem : EntitySystem
subs.Event<HealthAnalyzerTriageClaimMessage>(OnHealthAnalyzerTriageClaimSelected);
});
// End DeltaV - Medical Records
InitializeReportPrinting(); // DeltaV - MedTek Reports
}
public override void Update(float frameTime)

View File

@ -66,10 +66,7 @@ public sealed class EventManagerSystem : EntitySystem
/// </remarks>
public EntProtoId? TryGenerateRandomEvent(EntityTableSelector limitedEventsTable, TimeSpan? eventRunTime = null)
{
var availableEvents = AvailableEvents(eventRunTime: eventRunTime); // handles the player counts and individual event restrictions.
// Putting this here only makes any sense in the context of the toolshed commands in BasicStationEventScheduler. Kill me.
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents))
if (!TryBuildLimitedEvents(limitedEventsTable, out var limitedEvents, currentTime: eventRunTime))
{
Log.Warning("Provided event table could not build dict!");
return null;

View File

@ -1,14 +1,20 @@
using System.Linq;
using Content.Server.Popups;
using Content.Shared._DV.CosmicCult.Components.Examine;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared._DV.CosmicCult.Prototypes;
using Content.Shared._DV.CosmicCult;
using Content.Shared.Actions.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Humanoid;
using Content.Shared.Interaction;
using Content.Shared.UserInterface;
using Content.Shared.Mobs.Systems;
using Content.Shared.Verbs;
using Robust.Server.Audio;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Server._DV.CosmicCult;
@ -21,8 +27,11 @@ public sealed class CosmicGlyphSystem : SharedCosmicGlyphSystem
[Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly CosmicCultRuleSystem _cultRule = default!;
[Dependency] private readonly SharedCosmicCultSystem _cosmicCult = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
[Dependency] private readonly IGameTiming _timing = default!;
private readonly HashSet<Entity<CosmicCultComponent>> _cultists = [];
@ -32,9 +41,72 @@ public sealed class CosmicGlyphSystem : SharedCosmicGlyphSystem
{
SubscribeLocalEvent<CosmicGlyphComponent, ActivateInWorldEvent>(OnUseGlyph);
SubscribeLocalEvent<CosmicGlyphComponent, ComponentStartup>(OnGlyphCreated);
SubscribeLocalEvent<CosmicGlyphComponent, GetVerbsEvent<AlternativeVerb>>(OnGetAlternativeVerbs);
SubscribeLocalEvent<CosmicCultComponent, EventCosmicDrawGlyph>(OnDrawGlyph);
SubscribeLocalEvent<CosmicGlyphDrawComponent, CosmicGlyphDrawSelectedMessage>(OnGlyphSelected);
base.Initialize();
}
private void OnGetAlternativeVerbs(Entity<CosmicGlyphComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanInteract || !args.CanAccess || !_cosmicCult.EntityIsCultist(args.User) || ent.Comp.State == GlyphStatus.Despawning)
return;
args.Verbs.Add(new AlternativeVerb
{
Text = Loc.GetString("cult-glyph-verb-erase"),
Act = () => EraseGlyph(ent),
});
}
private void OnDrawGlyph(Entity<CosmicCultComponent> ent, ref EventCosmicDrawGlyph args)
{
if (_cultRule.AssociatedGamerule(ent) is not { } cult ||
!TryComp<CosmicGlyphDrawComponent>(args.Action, out var drawComp))
return;
args.Handled = true;
var glyphs = GetAvailableGlyphs(cult.Comp.CurrentTier);
if (glyphs.Count == 0)
{
drawComp.Target = null;
_ui.CloseUi(args.Action.Owner, CosmicGlyphDrawUiKey.Key, args.Performer);
return;
}
drawComp.Target = args.Target;
_ui.OpenUi(args.Action.Owner, CosmicGlyphDrawUiKey.Key, args.Performer);
_ui.SetUiState(args.Action.Owner, CosmicGlyphDrawUiKey.Key, new CosmicGlyphDrawBuiState(glyphs));
}
private void OnGlyphSelected(Entity<CosmicGlyphDrawComponent> ent, ref CosmicGlyphDrawSelectedMessage args)
{
if (ent.Comp.Target is not { } target || !TryComp<ActionComponent>(ent, out var action) || action.Container != args.Actor
|| !TryComp<CosmicCultComponent>(args.Actor, out _) || _cultRule.AssociatedGamerule(args.Actor) is not { } cult
|| !_prototype.TryIndex(args.GlyphProtoId, out var glyph) || glyph.Tier > cult.Comp.CurrentTier)
{
ent.Comp.Target = null;
_ui.CloseUi(ent.Owner, CosmicGlyphDrawUiKey.Key, args.Actor);
return;
}
var spawned = Spawn(glyph.Entity, target);
_cultRule.TransferCultAssociation(args.Actor, spawned);
ent.Comp.Target = null;
_ui.CloseUi(ent.Owner, CosmicGlyphDrawUiKey.Key, args.Actor);
}
private List<ProtoId<GlyphPrototype>> GetAvailableGlyphs(int currentTier)
{
return _prototype.EnumeratePrototypes<GlyphPrototype>()
.Where(glyph => glyph.Tier <= currentTier)
.OrderBy(glyph => Loc.GetString(glyph.Name))
.Select(glyph => new ProtoId<GlyphPrototype>(glyph.ID))
.ToList();
}
#region Base trigger
private void OnGlyphCreated(Entity<CosmicGlyphComponent> ent, ref ComponentStartup args)

View File

@ -324,12 +324,6 @@ public sealed class MonumentSystem : SharedMonumentSystem
UpdateMonumentAppearance(uid, false);
//this is probably unnecessary but I have no idea where they get added to the list atm - ruddygreat
foreach (var glyphProto in _protoMan.EnumeratePrototypes<GlyphPrototype>().Where(proto => proto.Tier == 1))
{
uid.Comp.UnlockedGlyphs.Add(glyphProto.ID);
}
//basically completely unnecessary, but putting this here for sanity & futureproofing - ruddygreat
var query = EntityQueryEnumerator<CosmicCultComponent>();
while (query.MoveNext(out var cultist, out var cultComp))
@ -356,11 +350,6 @@ public sealed class MonumentSystem : SharedMonumentSystem
UpdateMonumentAppearance(uid, true);
foreach (var glyphProto in _protoMan.EnumeratePrototypes<GlyphPrototype>().Where(proto => proto.Tier == 2))
{
uid.Comp.UnlockedGlyphs.Add(glyphProto.ID);
}
var objectiveQuery = EntityQueryEnumerator<CosmicTierConditionComponent>();
while (objectiveQuery.MoveNext(out _, out var objectiveComp))
{
@ -398,11 +387,6 @@ public sealed class MonumentSystem : SharedMonumentSystem
if (_cosmicRule.AssociatedGamerule(uid) is not { } cult)
return;
foreach (var glyphProto in _protoMan.EnumeratePrototypes<GlyphPrototype>().Where(proto => proto.Tier == 3))
{
uid.Comp.UnlockedGlyphs.Add(glyphProto.ID);
}
UpdateMonumentAppearance(uid, true);
var objectiveQuery = EntityQueryEnumerator<CosmicTierConditionComponent>();

View File

@ -0,0 +1,35 @@
using Content.Shared.Paper;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.Medical.Components;
/// <summary>
/// Extends upstream's HealthAnalyzerComponent.
/// </summary>
/// </remarks>
public sealed partial class HealthAnalyzerComponent : Component
{
/// <summary>
/// Time when the component can print again
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan PrintAllowedAfter = TimeSpan.Zero;
/// <summary>
/// Cooldown between individual prints to prevent entity and noise spam.
/// </summary>
[DataField]
public TimeSpan PrintCooldown = TimeSpan.FromSeconds(5);
/// <summary>
/// Prototype of an entity to use as a template for printing. The paper may contain placeholders (wrapped in braces)
/// which will be filled in during printing.
/// </summary>
[DataField]
public EntProtoId<PaperComponent> PrintTemplate = "PaperWrittenMedicalMedtekPatientRecord";
[DataField]
public SoundSpecifier PrintReportSound = new SoundPathSpecifier("/Audio/Machines/printer.ogg");
}

View File

@ -0,0 +1,181 @@
using System.Linq;
using System.Text.RegularExpressions;
using Content.Server.Hands.Systems;
using Content.Server.Medical.Components;
using Content.Shared._DV.Medical;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.GameTicking;
using Content.Shared.Humanoid;
using Content.Shared.IdentityManagement;
using Content.Shared.Labels.EntitySystems;
using Content.Shared.Paper;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Medical;
public sealed partial class HealthAnalyzerSystem : EntitySystem
{
private static readonly Regex TemplateInsert = new(@"\{([\w.]+)\}", RegexOptions.Compiled);
[Dependency] private readonly IPrototypeManager _prototypes = default!;
[Dependency] private readonly LabelSystem _label = default!;
[Dependency] private readonly HandsSystem _hands = default!;
[Dependency] private readonly PaperSystem _paper = default!;
[Dependency] private readonly SharedGameTicker _gameTicker = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
public void InitializeReportPrinting()
{
SubscribeLocalEvent<HealthAnalyzerComponent, HealthAnalyzerPrintReportMessage>(OnPrint);
}
private void OnPrint(Entity<HealthAnalyzerComponent> entity, ref HealthAnalyzerPrintReportMessage args)
{
var printer = entity.Comp;
// Prevent users from printing too quickly
if (printer.PrintAllowedAfter >= _timing.CurTime)
return;
HealthAnalyzerComponent? analyzer = null;
if (!Resolve(entity.Owner, ref analyzer))
return;
// The health analyzer UI disables the button when the patient is invalid or out of range
if (analyzer.ScannedEntity is not { Valid: true } patient)
return;
var user = args.Actor;
if (!IsInRange(patient, user, analyzer.MaxScanRange))
return;
// Create slip of paper according to template
var paper = Spawn(printer.PrintTemplate, Transform(user).Coordinates);
ComposePatientRecord(paper, user, patient);
_label.Label(paper, GetEntityName(patient));
_hands.PickupOrDrop(user, paper);
_audio.PlayPvs(entity.Comp.PrintReportSound, user);
// Start cooldown
printer.PrintAllowedAfter = _timing.CurTime + printer.PrintCooldown;
}
private bool IsInRange(EntityUid patient, EntityUid user, float? maxScanRange)
{
if (maxScanRange == null)
{
return true;
}
return _transformSystem.InRange(
(patient, Transform(patient)),
(user, Transform(user)),
maxScanRange.Value
);
}
private void ComposePatientRecord(EntityUid uid, EntityUid responder, EntityUid patient)
{
PaperComponent? paper = null;
DamageableComponent? damageable = null;
if (!Resolve(uid, ref paper) || !Resolve(patient, ref damageable))
{
return;
}
var template = paper.Content;
// Anything in this dictionary can be interpolated into the print template
Dictionary<string, Func<string>> inserts = new()
{
{ "patient.name", () => GetEntityName(patient) },
{ "patient.species", () => GetEntitySpecies(patient) },
{ "responder.name", () => GetEntityName(responder) },
{ "roundTime", () => (_timing.CurTime - _gameTicker.RoundStartTimeSpan).ToString(@"hh\:mm") },
{ "damageList", () => ComposeDamageList((patient, damageable)) },
};
var content = TemplateInsert.Replace(template,
match =>
{
var key = match.Groups[1].Value;
if (inserts.TryGetValue(key, out var value))
{
return value.Invoke();
}
return match.Value;
});
_paper.SetContent((uid, paper), content);
}
private string ComposeDamageList(Entity<DamageableComponent> ent)
{
var damages = _damageable.GetPositiveDamage(ent);
if (damages.GetTotal() <= 0)
{
return Loc.GetString("health-analyzer-printout-damage-none");
}
var report = new FormattedMessage();
var groupDamages = damages.GetDamagePerGroup(_prototypes);
var groups = groupDamages.OrderByDescending(entry => entry.Value);
var damage = damages.DamageDict;
foreach (var (groupId, groupDamage) in groups)
{
if (groupDamage <= 0)
{
continue;
}
var group = _prototypes.Index(groupId);
// Group header
var groupTitleText = Loc.GetString(
"health-analyzer-printout-damage-group-text",
("damageGroup", group.LocalizedName),
("amount", groupDamage)
);
report.AddMarkupPermissive(groupTitleText);
report.PushNewline();
// List individual damage types
foreach (var type in group.DamageTypes)
{
var amount = damage.GetValueOrDefault(type, 0);
if (amount <= 0)
{
continue;
}
report.AddMarkupPermissive(Loc.GetString(
"health-analyzer-printout-damage-type-text",
("damageType", _prototypes.Index(type).LocalizedName),
("amount", amount)
));
report.PushNewline();
}
}
return report.ToMarkup();
}
private string GetEntityName(EntityUid uid)
{
return HasComp<MetaDataComponent>(uid)
? Identity.Name(uid, EntityManager)
: Loc.GetString("health-analyzer-window-entity-unknown-text");
}
private string GetEntitySpecies(EntityUid uid)
{
return Loc.GetString(
TryComp<HumanoidProfileComponent>(uid, out var appearance)
? _prototypes.Index(appearance.Species).Name
: "health-analyzer-window-entity-unknown-species-text"
);
}
}

View File

@ -42,7 +42,7 @@ public sealed partial class RepairableComponent : Component
/// Tool quality necessary to repair this device.
/// </summary>
[DataField, AutoNetworkedField]
public ProtoId<ToolQualityPrototype> QualityNeeded = "Welding";
public ProtoId<ToolQualityPrototype> QualityNeeded = "Applicating"; // Monolith - Nanite Applicator
/// <summary>
/// The base tool use delay (seconds). This will be modified by the tool's quality

View File

@ -5,6 +5,7 @@ using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Tools.Components; // Monolith - Nanite Applicators
using Content.Shared.Tools.Systems;
using Robust.Shared.Serialization;
@ -115,8 +116,26 @@ public sealed partial class RepairableSystem : EntitySystem
delay *= ent.Comp.SelfRepairPenalty;
}
// BEGIN DeltaV - Scale Repair Time with Damage
// If its a self-repair, ignore it since they've already been penalized.
if (args.User != args.Target && TryComp<DamageableComponent>(args.Target, out var damageComp))
{
// TODO: Scale with the destructible threshold if DestructibleSystem ever gets more prediction added.
// For now, just scale up the delay per 100 damage, or reduce the delay if its less.
var totalDamage = _damageableSystem.GetPositiveDamage((args.Target, damageComp)).GetTotal();
delay *= Math.Clamp((float)totalDamage / 100.0f, 0.5f, 3.0f);
}
// END DeltaV
// BEGIN Monolith - Nanite Applicators
if (!TryComp<ToolComponent>(args.Used, out var tool))
return;
// END Monolith
// Run the repairing doafter
args.Handled = _toolSystem.UseTool(args.Used, args.User, ent.Owner, delay, ent.Comp.QualityNeeded, new RepairDoAfterEvent(), ent.Comp.FuelCost);
}
}

View File

@ -73,4 +73,10 @@ public sealed partial class WelderComponent : Component
/// </summary>
[DataField]
public bool TankSafe;
/// <summary>
/// Monolith - This variable gets rid of the status display.
/// </summary>
[DataField]
public bool OnlyDisplayFuel = false;
}

View File

@ -84,19 +84,33 @@ public abstract partial class SharedToolSystem
{
using (args.PushGroup(nameof(WelderComponent)))
{
if (ItemToggle.IsActivated(entity.Owner))
// BEGIN Monolith - Nanite Applicators
if (!entity.Comp.OnlyDisplayFuel)
{
args.PushMarkup(Loc.GetString("welder-component-on-examine-welder-lit-message"));
}
else
{
args.PushMarkup(Loc.GetString("welder-component-on-examine-welder-not-lit-message"));
var lit = Loc.GetString("welder-component-on-examine-welder-not-lit-message");
if (ItemToggle.IsActivated(entity.Owner))
lit = Loc.GetString("welder-component-on-examine-welder-lit-message");
args.PushMarkup(lit);
}
// END Monolith
if (args.IsInDetailsRange)
{
var (fuel, capacity) = GetWelderFuelAndCapacity(entity.Owner, entity.Comp);
// BEGIN Monolith - Nanite Applicator
if (entity.Comp.OnlyDisplayFuel)
{
args.PushMarkup(Loc.GetString("welder-component-on-examine-less-detailed-message",
("colorName", fuel < capacity / FixedPoint2.New(4f) ? "darkorange" : "orange"),
("fuelLeft", fuel),
("fuelCapacity", capacity)));
return;
}
// END Monolith
args.PushMarkup(Loc.GetString("welder-component-on-examine-detailed-message",
("colorName", fuel < capacity / FixedPoint2.New(4f) ? "darkorange" : "orange"),
("fuelLeft", fuel),
@ -120,6 +134,19 @@ public abstract partial class SharedToolSystem
&& _whitelist.IsWhitelistPass(tank.FuelWhitelist, entity.Owner) //imp
&& SolutionContainerSystem.TryGetSolution(entity.Owner, entity.Comp.FuelSolutionName, out var solutionComp, out var welderSolution))
{
// BEGIN Monolith - Nanite Applicators
foreach (var reagent in targetSolution.Contents)
{
if (reagent.Reagent.Prototype != entity.Comp.FuelReagent.Id)
{
_popup.PopupClient(
Loc.GetString("welder-component-incompatible-fuel", ("owner", args.Target)), entity, args.User);
return;
}
}
// END Monolith
var trans = FixedPoint2.Min(welderSolution.AvailableVolume, targetSolution.Volume);
if (trans > 0)
{

View File

@ -42,6 +42,7 @@ public sealed partial class CosmicCultComponent : Component
[
"ActionCosmicSiphon",
"ActionCosmicBlank",
"ActionCosmicDrawGlyph",
];
[DataField]

View File

@ -18,18 +18,6 @@ public sealed partial class MonumentComponent : Component
[DataField]
public SoundSpecifier InfusionSFX = new SoundPathSpecifier("/Audio/_DV/CosmicCult/insert_entropy.ogg");
/// <summary>
/// the list of glyphs that this monument is allowed to scribe
/// </summary>
[DataField, AutoNetworkedField]
public HashSet<ProtoId<GlyphPrototype>> UnlockedGlyphs = [];
/// <summary>
/// the glyph that will be scribed when the button is pressed
/// </summary>
[DataField, AutoNetworkedField]
public ProtoId<GlyphPrototype> SelectedGlyph;
/// <summary>
/// the total amount of entropy that has been inserted into the monument
/// </summary>
@ -120,15 +108,6 @@ public sealed class InfluenceSelectedMessage(ProtoId<InfluencePrototype> influen
public ProtoId<InfluencePrototype> InfluenceProtoId = influenceProtoId;
}
[Serializable, NetSerializable]
public sealed class GlyphSelectedMessage(ProtoId<GlyphPrototype> glyphProtoId) : BoundUserInterfaceMessage
{
public ProtoId<GlyphPrototype> GlyphProtoId = glyphProtoId;
}
[Serializable, NetSerializable]
public sealed class GlyphRemovedMessage : BoundUserInterfaceMessage;
[Serializable, NetSerializable]
public enum MonumentVisuals : byte
{

View File

@ -1,10 +1,18 @@
using Content.Shared.Actions;
using Robust.Shared.Map;
using Robust.Shared.GameStates;
namespace Content.Shared._DV.CosmicCult;
[RegisterComponent, NetworkedComponent]
public sealed partial class CosmicCultActionComponent : Component;
[RegisterComponent]
public sealed partial class CosmicGlyphDrawComponent : Component
{
public EntityCoordinates? Target;
}
public sealed partial class EventCosmicSiphon : EntityTargetActionEvent;
public sealed partial class EventCosmicBlank : EntityTargetActionEvent;
public sealed partial class EventCosmicPlaceMonument : InstantActionEvent; //given to the cult leader on roundstart
@ -16,6 +24,7 @@ public sealed partial class EventCosmicIngress : EntityTargetActionEvent;
public sealed partial class EventCosmicImposition : InstantActionEvent;
public sealed partial class EventCosmicNova : WorldTargetActionEvent;
public sealed partial class EventCosmicFragmentation : EntityTargetActionEvent;
public sealed partial class EventCosmicDrawGlyph : WorldTargetActionEvent;
// COLOSSUS ACTIONS
public sealed partial class EventCosmicColossusSunder : WorldTargetActionEvent;

View File

@ -0,0 +1,23 @@
using Content.Shared._DV.CosmicCult.Prototypes;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared._DV.CosmicCult;
[Serializable, NetSerializable]
public enum CosmicGlyphDrawUiKey : byte
{
Key,
}
[Serializable, NetSerializable]
public sealed class CosmicGlyphDrawBuiState(List<ProtoId<GlyphPrototype>> glyphs) : BoundUserInterfaceState
{
public List<ProtoId<GlyphPrototype>> Glyphs = glyphs;
}
[Serializable, NetSerializable]
public sealed class CosmicGlyphDrawSelectedMessage(ProtoId<GlyphPrototype> glyphProtoId) : BoundUserInterfaceMessage
{
public ProtoId<GlyphPrototype> GlyphProtoId = glyphProtoId;
}

View File

@ -16,22 +16,16 @@ public sealed class MonumentBuiState : BoundUserInterfaceState
{
public int CurrentProgress;
public int TargetProgress;
public ProtoId<GlyphPrototype> SelectedGlyph;
public HashSet<ProtoId<GlyphPrototype>> UnlockedGlyphs;
public MonumentBuiState(int currentProgress, int targetProgress, int progressOffset, ProtoId<GlyphPrototype> selectedGlyph, HashSet<ProtoId<GlyphPrototype>> unlockedGlyphs)
public MonumentBuiState(int currentProgress, int targetProgress, int progressOffset)
{
CurrentProgress = currentProgress - progressOffset;
TargetProgress = targetProgress - progressOffset;
SelectedGlyph = selectedGlyph;
UnlockedGlyphs = unlockedGlyphs;
}
public MonumentBuiState(MonumentComponent comp)
{
CurrentProgress = comp.CurrentProgress - comp.ProgressOffset;
TargetProgress = comp.TargetProgress - comp.ProgressOffset;
SelectedGlyph = comp.SelectedGlyph;
UnlockedGlyphs = comp.UnlockedGlyphs;
}
}

View File

@ -1,11 +1,7 @@
using Content.Shared._DV.CosmicCult;
using Content.Shared._DV.CosmicCult.Components;
using Content.Shared._DV.CosmicCult.Prototypes;
using Content.Shared.Actions;
using Content.Shared.Movement.Components;
using Content.Shared.Nutrition.Components;
using Content.Shared.UserInterface;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Prototypes;
using Robust.Shared.Spawners;
@ -21,16 +17,12 @@ public abstract class SharedMonumentSystem : EntitySystem
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedCosmicCultSystem _cosmicCult = default!;
[Dependency] private readonly SharedCosmicGlyphSystem _glyph = default!;
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MonumentComponent, BoundUIOpenedEvent>(OnUIOpened);
SubscribeLocalEvent<MonumentComponent, GlyphSelectedMessage>(OnGlyphSelected);
SubscribeLocalEvent<MonumentComponent, GlyphRemovedMessage>(OnGlyphRemove);
SubscribeLocalEvent<MonumentComponent, InfluenceSelectedMessage>(OnInfluenceSelected);
SubscribeLocalEvent<MonumentOnDespawnComponent, TimedDespawnEvent>(OnTimedDespawn);
SubscribeLocalEvent<MonumentCollisionComponent, PreventCollideEvent>(OnPreventCollide);
@ -80,38 +72,6 @@ public abstract class SharedMonumentSystem : EntitySystem
}
#region UI listeners
private void OnGlyphSelected(Entity<MonumentComponent> ent, ref GlyphSelectedMessage args)
{
ent.Comp.SelectedGlyph = args.GlyphProtoId;
if (!_prototype.TryIndex(args.GlyphProtoId, out var proto))
return;
var xform = Transform(ent);
if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
return;
var localTile = _map.GetTileRef(xform.GridUid.Value, grid, xform.Coordinates);
var targetIndices = localTile.GridIndices + new Vector2i(0, -1);
if (ent.Comp.CurrentGlyph is { } curGlyph) _glyph.EraseGlyph(curGlyph);
var glyphEnt = Spawn(proto.Entity, _map.ToCenterCoordinates(xform.GridUid.Value, targetIndices, grid));
ent.Comp.CurrentGlyph = glyphEnt;
var evt = new CosmicCultAssociateRuleEvent(ent, glyphEnt);
RaiseLocalEvent(ref evt);
_ui.SetUiState(ent.Owner, MonumentKey.Key, new MonumentBuiState(ent.Comp));
}
private void OnGlyphRemove(Entity<MonumentComponent> ent, ref GlyphRemovedMessage args)
{
if (ent.Comp.CurrentGlyph is { } curGlyph) _glyph.EraseGlyph(curGlyph);
_ui.SetUiState(ent.Owner, MonumentKey.Key, new MonumentBuiState(ent.Comp));
}
private void OnInfluenceSelected(Entity<MonumentComponent> ent, ref InfluenceSelectedMessage args)
{
if (!_prototype.TryIndex(args.InfluenceProtoId, out var proto) || !TryComp<ActivatableUIComponent>(ent, out var uiComp) || !TryComp<CosmicCultComponent>(args.Actor, out var cultComp))

View File

@ -68,6 +68,7 @@ public sealed class ChargeHolosignSystem : EntitySystem
var holoUid = PredictedSpawnAtPosition(ent.Comp1.SignProto, args.ClickLocation.SnapToGrid(EntityManager));
var xform = Transform(holoUid);
xform.LocalRotation = Angle.Zero;
if (!xform.Anchored)
_transform.AnchorEntity(holoUid, xform); // anchor to prevent any tempering with (don't know what could even interact with it)

View File

@ -0,0 +1,6 @@
using Robust.Shared.Serialization;
namespace Content.Shared._DV.Medical;
[Serializable, NetSerializable]
public sealed class HealthAnalyzerPrintReportMessage : BoundUserInterfaceMessage;

View File

@ -1,62 +1,4 @@
Entries:
- author: Stxcking
changes:
- message: Medical borgs now have access to a crew monitor as part of the rescue
cyborg module!
type: Add
id: 2024
time: '2026-01-06T01:31:14.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5117
- author: ShepardToTheStars
changes:
- message: The Santa anomalies have been removed from the anomaly pool (until next
December)!
type: Remove
id: 2025
time: '2026-01-06T05:27:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5145
- author: Stxcking
changes:
- message: Added some missing feroxi mask/helm sprites. In total, 10 bandanas, 2
hard suit helms (Goliath + Paramedic Void), 15 masks!
type: Add
id: 2026
time: '2026-01-06T15:59:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5149
- author: MilonPL
changes:
- message: Reworked the deep fryer! It can now be used to make new recipes, check
out the guidebook for more info!
type: Tweak
- message: Be careful about putting liquids that aren't cooking oils in the deep
fryer! It could start a grease fire!
type: Add
id: 2027
time: '2026-01-06T18:41:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5043
- author: ShepardToTheStars
changes:
- message: Secure crates from Logistics once again have a 75% chance of acidifying
the contents inside.
type: Tweak
id: 2028
time: '2026-01-06T21:57:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5152
- author: PureBreadBagel, ShepardToTheStars
changes:
- message: Added the medical Crashcart from funkystation! It holds life-saving equipment
and has a slot for a defibrillator and a gas tank!
type: Add
id: 2029
time: '2026-01-07T04:01:46.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5140
- author: MilonPL
changes:
- message: AAC tablet UI looks slightly better now.
type: Tweak
id: 2030
time: '2026-01-07T15:57:29.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/5153
- author: ShepardToTheStars
changes:
- message: The colossus should no longer get objectives to put the effigy on non-station
@ -4324,4 +4266,75 @@
id: 2524
time: '2026-07-06T01:55:41.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6177
- author: ShepardToTheStars, Bonfire Lit
changes:
- message: The health analyzer window can now print out the details of a medical
scan!
type: Add
id: 2525
time: '2026-07-06T17:43:22.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6194
- author: ShepardToTheStars, whatston3, ScyronX, tonotom1
changes:
- message: You can now examine the condition of most structures, walls, machines,
etc., similar to how you can check the condition of windows.
type: Add
- message: Nanite applicators have been added! They allow you to repair the damage
to most structures, walls, machines, and more! It comes in normal, experimental,
and syndicate versions. For now, borgs, windows, and tesla coils will still
be repaired with welders.
type: Add
- message: Welding fuel and nanite jerry cans have been added!
type: Add
- message: Time to repair something now scales with how much damage it has taken.
It can take less time if there's not much damage or it can take up to 3 times
as long if its very severely damaged.
type: Tweak
- message: The experimental welder has had its capacity reduced to 200.
type: Tweak
id: 2526
time: '2026-07-06T20:08:04.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6132
- author: sowelipililimute
changes:
- message: Cosmic Cultists can now draw glyphs wherever they damn please instead
of in front of the Monument
type: Tweak
id: 2527
time: '2026-07-06T20:13:02.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6197
- author: sowelipililimute
changes:
- message: Events are now properly gated by the round time once again. No more colossus
spawns at 10 minutes.
type: Fix
- message: Removed abductors.
type: Remove
id: 2528
time: '2026-07-07T14:23:28.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6236
- author: ShepardToTheStars
changes:
- message: Holosigns should now be the correct rotation.
type: Fix
id: 2529
time: '2026-07-07T14:24:33.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6232
- author: EmberAstra
changes:
- message: Allulalos can no longer reach APCs without something to stand on.
type: Tweak
- message: Allulalos can now check station maps without needing something to stand
on.
type: Tweak
id: 2530
time: '2026-07-07T14:56:40.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6237
- author: sowelipililimute
changes:
- message: The Monument's progress bar is now obscured.
type: Tweak
id: 2531
time: '2026-07-07T15:45:38.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/6202
Order: 1

View File

@ -5,6 +5,7 @@ cult-glyph-too-many-targets = Too many targets present on glyph!
cult-glyph-target-mindshield = Mental shielding prevents the glyph's influence from taking hold!
cult-glyph-target-chaplain = A spark of divine power prevents the glyph's influence from taking hold!
cult-glyph-target-mindless = The glyph fails to activate, as the target is currently mindless.
cult-glyph-verb-erase = Erase glyph
cult-glyph-name-knowledge = Pact of Knowledge
cult-glyph-description-knowledge = Knowledge. Instills the spark of indelible knowledge. Able to convert most to join our ranks.

View File

@ -0,0 +1,7 @@
# Base structure damage examine values
comp-structure-damaged-1 = It looks fully intact.
comp-structure-damaged-2 = It has a few scratches.
comp-structure-damaged-3 = It has a few large dents.
comp-structure-damaged-4 = [color=yellow]It has several big cracks running along its surface.[/color]
comp-structure-damaged-5 = [color=orange]It has deep cracks across multiple layers.[/color]
comp-structure-damaged-6 = [color=red]It's extremely damaged and on the verge of falling apart.[/color]

View File

@ -13,3 +13,8 @@ health-analyzer-window-triage-status-Immediate = Immediate
.ToolTip = Victim can be helped by immediate intervention and transport. Requires medical attention for survival.
health-analyzer-window-triage-status-Expectant = Expectant
.ToolTip = Victim unlikely to survive, or is already dead.
# MedTek Printouts
health-analyzer-printout-damage-none = [italic]None[/italic]
health-analyzer-printout-damage-group-text = [bold]{$damageGroup}: {$amount}[/bold]
health-analyzer-printout-damage-type-text = [bullet/]{$damageType}: {$amount}

View File

@ -0,0 +1,2 @@
reagent-name-nanite-fuel = Nanites
reagent-desc-nanite-fuel = Nanobots used for repairing.

View File

@ -0,0 +1,4 @@
# MARK: Utility
uplink-syndicate-applicator-name = Advanced Nanite Applicator
uplink-syndicate-applicator-desc = Advanced nanite applicator with a heavily upgraded nanite capacity capable of self-nanite generation.

View File

@ -0,0 +1,2 @@
welder-component-on-examine-less-detailed-message = Fuel: [color={$colorName}]{$fuelLeft}/{$fuelCapacity}[/color]
welder-component-incompatible-fuel = { $owner } contains incorrect or contaminated fuel!

View File

@ -0,0 +1,2 @@
tool-quality-nanite-applicator-name = Nanite Applicator
tool-quality-applicating-name = Nanite Applicating

View File

@ -46,6 +46,7 @@
- id: HolofanProjector
- id: GasAnalyzer
- id: trayScanner
- id: NaniteApplicatorExperimental # DeltaV - Nanite Applicators
- type: entityTable
id: BeltSecurityEntityTable

View File

@ -8,6 +8,9 @@
CrowbarYellow: 8
Multitool: 4
NetworkConfigurator: 5
NaniteApplicator: 4 # Monolith - Nanite Applicator
JerryCanWeldingFuel: 2 # New Frontier - Jerry Cans
JerryCanNaniteFuel: 2 # Monolith - Nanite Applicator
PowerCellMedium: 5
ClothingHandsGlovesColorYellow: 6
MetalFoamGrenade: 3 # DeltaV - added

View File

@ -118,6 +118,7 @@
damageValue: -10 # 10 seconds to repair from crit
doAfterDelay: 1
fuelCost: 0.5
qualityNeeded: Welding # DeltaV - for now
allowSelfRepair: true # DeltaV - was false
- type: BorgChassis
- type: LockingWhitelist

View File

@ -20,6 +20,7 @@
damageValue: -15 # 8 seconds to repair from dead
doAfterDelay: 1
fuelCost: 0.5
qualityNeeded: Welding # DeltaV - for now
- type: Pullable
- type: Tag
tags:

View File

@ -82,6 +82,7 @@
temperature: 373.15
- type: Repairable
doAfterDelay: 30 # you can heal the mothership core, but it takes a while
qualityNeeded: Welding # DeltaV
- type: DamagedSiliconAccent
enableChargeCorruption: false
# TODO: make it explosive again once until issue https://github.com/space-wizards/space-station-14/issues/40606 is fixed

View File

@ -89,7 +89,7 @@
fuelCost: 10 # 1/2 of a Welder for a full repair
doAfterDelay: 5
allowSelfRepair: false
qualityNeeded: Welding # DeltaV
#Security Shields
- type: entity

View File

@ -583,6 +583,7 @@
- item: Screwdriver
- item: Wirecutter
- item: WelderIndustrial
- item: NaniteApplicator # Monolith
- item: Multitool
- type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: tool-module }
@ -711,6 +712,7 @@
- item: PowerDrill
- item: WelderExperimental
- item: Multitool
- item: NaniteApplicatorExperimental # Monolith
- item: RemoteSignallerAdvanced
- item: NFWeaponHoloflareGun # DeltaV
- type: BorgModuleIcon

View File

@ -162,8 +162,8 @@
Welder:
reagents:
- ReagentId: WeldingFuel
Quantity: 1000
maxVol: 1000
Quantity: 200 # DeltaV - Experimental Welder Nerf
maxVol: 200 # DeltaV - Experimental Welder Nerf
- type: PointLight
enabled: false
radius: 1.5
@ -174,6 +174,7 @@
reagents:
- ReagentId: WeldingFuel
Quantity: 1
duration: 2 # DeltaV - Experimental Welder Nerf - Loses fuel while active
- type: RequiresEyeProtection
statusEffectTime: 5 # less harmful; sunglasses can block it

View File

@ -45,7 +45,7 @@
graph: WeaponTurretSyndicateDisposable
node: disposableTurret
- type: Repairable
qualityNeeded: "Anchoring"
qualityNeeded: Anchoring
doAfterDelay: 3
- type: TriggerOnEmptyGunshot
- type: ExplodeOnTrigger

View File

@ -84,6 +84,7 @@
- type: ExaminableDamage
messages: WindowMessages
- type: Repairable
qualityNeeded: Welding # DeltaV
- type: DamageVisuals
thresholds: [8, 16, 25]
damageDivisor: 3.333
@ -177,6 +178,7 @@
- type: ExaminableDamage
messages: WindowMessages
- type: Repairable
qualityNeeded: Welding # DeltaV
- type: Damageable
damageContainer: StructuralInorganic
- type: DamageVisuals

View File

@ -155,6 +155,7 @@
guides:
- VoltageNetworks
- Power
- type: TooShortForUIBlacklist # Delta V
# APC under construction
- type: entity

View File

@ -61,6 +61,7 @@
- type: Repairable
fuelCost: 15
doAfterDelay: 5
qualityNeeded: Welding # DeltaV
- type: Lock
- type: LockVisuals
- type: DamageVisuals

View File

@ -102,6 +102,7 @@
blacklist:
tags:
- NoConsoleSound
- type: TooShortForUIWhitelist # Delta V
- type: entity
parent: BaseWallmountMetallic

View File

@ -12,6 +12,7 @@
- type: Repairable
fuelCost: 10
doAfterDelay: 2
qualityNeeded: Welding # DeltaV
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass

View File

@ -11,6 +11,7 @@
- type: Repairable
fuelCost: 15
doAfterDelay: 3
qualityNeeded: Welding # DeltaV
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass

View File

@ -120,6 +120,7 @@
- type: Repairable
fuelCost: 15
doAfterDelay: 3
qualityNeeded: Welding
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass
@ -215,6 +216,7 @@
- type: Repairable
fuelCost: 15
doAfterDelay: 3
qualityNeeded: Welding
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass

View File

@ -11,6 +11,7 @@
- type: Repairable
fuelCost: 10
doAfterDelay: 2
qualityNeeded: Welding # DeltaV
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass

View File

@ -11,6 +11,7 @@
- type: Repairable
fuelCost: 15
doAfterDelay: 3
qualityNeeded: Welding # DeltaV
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: RGlass

View File

@ -45,6 +45,8 @@
- type: ExaminableDamage
messages: WindowMessages
- type: Repairable
doAfterDelay: 2 # DeltaV
qualityNeeded: Welding
- type: RCDDeconstructable
cost: 6
delay: 4
@ -171,6 +173,8 @@
layer:
- GlassLayer
- type: Repairable
doAfterDelay: 2 # DeltaV
qualityNeeded: Welding
- type: Damageable
damageContainer: StructuralInorganic
damageModifierSet: Glass

View File

@ -26,6 +26,11 @@
- type: Tag
tags:
- Structure
- type: ExaminableDamage # DeltaV
messages: BaseStructureMessages
- type: Repairable # Monolith - Nanite Applicator
doAfterDelay: 3
qualityNeeded: Applicating
- type: entity
# This means that it's not anchored on spawn.

View File

@ -63,6 +63,7 @@
- WelderExperimental
- JawsOfLife
- TrayGoggles # DeltaV
- ExperimentalNaniteApplicator # Monolith
#- Fulton # DeltaV - moved to MiningDeltaV
#- FultonBeacon # DeltaV - moved to MiningDeltaV

View File

@ -184,6 +184,7 @@
- JawsOfLife
- BorgModuleAdvancedTool
- TrayGoggles # DeltaV
- ExperimentalNaniteApplicator # Monolith
#- Fulton # DeltaV - seperate tech Aerial Extraction
#- FultonBeacon # DeltaV - seperate tech Aerial Extraction

View File

@ -0,0 +1,45 @@
- type: entity
id: PaperWrittenMedicalMedtekPatientRecord
parent: Paper
name: MedTek Patient Report
categories: [ HideSpawnMenu ]
description: A printeout of a recent medical scan.
components:
- type: Tag
tags:
- Document
- Trash
- Paper
- type: StaticPrice
price: 0
- type: Sprite
sprite: Objects/Misc/bureaucracy.rsi
layers:
- state: paper_receipt
- state: paper_receipt_words
map: ["enum.PaperVisualLayers.Writing"]
visible: false
- state: paper_stamp-generic
map: ["enum.PaperVisualLayers.Stamp"]
visible: false
- type: PaperVisuals
backgroundImagePath: "/Textures/Interface/Paper/paper_background_perforated.svg.96dpi.png"
headerImagePath: "/Textures/_DV/Interface/Paper/MedTekReports/paper_heading_medtek_report.svg.96dpi.png"
headerMargin: 0.0, 0.0, 0.0, 6.0
backgroundImageTile: true
backgroundPatchMargin: 0.0, 6.0, 0.0, 6.0
contentMargin: 12.0, 0.0, 12.0, 0.0
# This is a narrow piece of paper
maxWritableArea: 256.0, 0.0
- type: Paper
content: |
[head=3]Patient[/head]
[bold]Name:[/bold] {patient.name}
[bold]Species:[/bold] {patient.species}
[head=3]Attending Physician[/head]
[bold]Name:[/bold] {responder.name}
[bold]Shift Time:[/bold] {roundTime}
[head=3]Injuries[/head]
{damageList}

View File

@ -45,6 +45,28 @@
- BibleUser
event: !type:EventCosmicBlank {}
- type: entity
parent: BaseAction
id: ActionCosmicDrawGlyph
name: Draw Glyph
description: Scribe a glyph into realspace.
components:
- type: Action
useDelay: 60
itemIconStyle: NoItem
icon:
sprite: _DV/CosmicCult/Icons/cosmiccult_abilities.rsi
state: astral
- type: TargetAction
range: 4
- type: WorldTargetAction
event: !type:EventCosmicDrawGlyph {}
- type: CosmicGlyphDraw
- type: UserInterface
interfaces:
enum.CosmicGlyphDrawUiKey.Key:
type: CosmicGlyphDrawBoundUserInterface
- type: entity
parent: BaseAction
id: ActionCosmicPlaceMonument

View File

@ -0,0 +1,5 @@
- type: localizedDataset
id: BaseStructureMessages
values:
prefix: comp-structure-damaged-
count: 6

View File

@ -13,6 +13,7 @@
- BorgModulesStatic
- BorgLimbsStatic
- BorgModulesResearched
- RoboticsEmagStatic
- type: Machine
board: SyndieExosuitFabricatorMachineCircuitboard

View File

@ -5,6 +5,7 @@
recipes:
- HolotapeProjector
- SheetPlasteel1Engineering
- NaniteApplicator
## Dynamic

View File

@ -1,10 +1,5 @@
## Static
- type: latheRecipePack
id: RoboticsEmagStatic
recipes:
- IdChipSyndie
- type: latheRecipePack
id: BorgModulesSyndicateStatic
recipes:

View File

@ -0,0 +1,5 @@
- type: latheRecipePack
id: RoboticsEmagStatic
recipes:
- IdChipSyndie
- NaniteApplicatorSyndicate

View File

@ -130,7 +130,6 @@
- CableApcStack
- SheetPlasteel
- SheetSteel
belt:
- RCDRecharging
- type: startingGear
@ -164,7 +163,6 @@
- SheetPlasteel
- SheetSteel
- WeaponAdvancedLaser
belt:
- RCDCombat
# Security

View File

@ -0,0 +1,9 @@
- type: listing
id: UplinkSyndicateApplicator
name: uplink-syndicate-applicator-name
description: uplink-syndicate-applicator-desc
productEntity: NaniteApplicatorSyndicate
cost:
Telecrystal: 2
categories:
- UplinkDisruption

View File

@ -0,0 +1,13 @@
- type: entity
parent: JerryCan
suffix: nanite fuel
id: JerryCanNaniteFuel
components:
- type: Label
currentLabel: reagent-name-nanite-fuel
- type: SolutionContainerManager
solutions:
tank:
reagents:
- ReagentId: NaniteFuel
Quantity: 200

View File

@ -0,0 +1,91 @@
- type: entity
name: nanite applicator
parent: BaseItem
id: NaniteApplicator
description: "Advanced tool that uses nanotechnology to repair structures."
components:
- type: EmitSoundOnLand
sound:
path: /Audio/Items/welder_drop.ogg
- type: Sprite
sprite: _Mono/Objects/Tools/nanite_applicator.rsi
layers:
- state: icon
- type: MeleeWeapon
wideAnimationRotation: 135
attackRate: 1.5
damage:
types:
Blunt: 5
soundHit:
collection: MetalThud
- type: Tool
qualities:
- Applicating
useSound:
collection: Welder
- type: Welder
fuelReagent: NaniteFuel
onlyDisplayFuel: true
- type: RefillableSolution
solution: Welder
- type: SolutionContainerManager
solutions:
Welder:
reagents:
- ReagentId: NaniteFuel
Quantity: 50
maxVol: 50
- type: PhysicalComposition
materialComposition:
Steel: 100
- type: StaticPrice
price: 100
- type: GuideHelp
guides:
- Construction
- type: entity
name: experimental nanite applicator
parent: NaniteApplicator
id: NaniteApplicatorExperimental
description: "An experimental nanite applicator with a heavily upgraded nanite capacity capable of self-nanite generation."
components:
- type: Sprite
sprite: _Mono/Objects/Tools/nanite_applicator_experimental.rsi
layers:
- state: icon
- type: SolutionRegeneration
solution: Welder
generated:
reagents:
- ReagentId: NaniteFuel
Quantity: 1
- type: StaticPrice
price: 200
- type: entity
name: advanced nanite applicator
parent: NaniteApplicatorExperimental
id: NaniteApplicatorSyndicate
description: "Advanced nanite applicator with a heavily upgraded nanite capacity capable of self-nanite generation."
components:
- type: Sprite
sprite: _Mono/Objects/Tools/nanite_applicator_syndicate.rsi
layers:
- state: icon
- type: SolutionContainerManager
solutions:
Welder:
reagents:
- ReagentId: NaniteFuel
Quantity: 200
maxVol: 200
- type: SolutionRegeneration
solution: Welder
generated:
reagents:
- ReagentId: NaniteFuel
Quantity: 3
- type: StaticPrice
price: 400

View File

@ -0,0 +1,23 @@
- type: reagent
id: NaniteFuel
name: reagent-name-nanite-fuel
desc: reagent-desc-nanite-fuel
physicalDesc: reagent-physical-desc-oily
slipData:
requiredSlipSpeed: 3.5
flavor: bitter
flavorMinimum: 0.01
color: "#5775f4"
recognizable: true
boilingPoint: 8000.6
meltingPoint: 659.7
friction: 0.4
metabolisms:
Bloodstream:
effects:
- !type:HealthChange
damage:
types:
Poison: 0.4
Slash: 0.3
Piercing: 0.3

View File

@ -0,0 +1,22 @@
- type: latheRecipe
parent: BaseToolRecipe
id: NaniteApplicator
result: NaniteApplicator
materials:
Steel: 400
- type: latheRecipe
parent: BaseToolRecipe
id: ExperimentalNaniteApplicator
result: NaniteApplicatorExperimental
materials:
Steel: 800
Plasma: 200
- type: latheRecipe
parent: BaseToolRecipe
id: NaniteApplicatorSyndicate
result: NaniteApplicatorSyndicate
materials:
Steel: 800
Plasma: 200

View File

@ -0,0 +1,6 @@
- type: tool
id: Applicating
name: tool-quality-applicating-name
toolName: tool-quality-nanite-applicator-name
spawn: NaniteApplicator
icon: { sprite: _Mono/Objects/Tools/nanite_applicator.rsi, state: icon }

View File

@ -0,0 +1,103 @@
- type: entity
name: jerry can
parent: BaseItem
id: JerryCan
suffix: empty
description: A plastic jerry can with a spill-proof nozzle.
components:
- type: SolutionContainerManager
solutions:
tank:
maxVol: 200
- type: Sprite
sprite: _NF/Objects/Specific/Chemistry/jerrycan.rsi
layers:
- state: jerrycan
- state: jerrycan1
map: [ "enum.SolutionContainerLayers.Fill" ]
visible: false
- type: Item
size: Normal
sprite: _NF/Objects/Specific/Chemistry/jerrycan.rsi
- type: MixableSolution
solution: tank
- type: RefillableSolution
solution: tank
- type: DrainableSolution
solution: tank
- type: ExaminableSolution
solution: tank
- type: DrawableSolution
solution: tank
- type: InjectableSolution
solution: tank
- type: SolutionTransfer
canChangeTransferAmount: true
- type: SolutionItemStatus
solution: tank
- type: ReagentTank
tankType: Fuel
- type: UserInterface
interfaces:
enum.TransferAmountUiKey.Key:
type: TransferAmountBoundUserInterface
- type: Edible
solution: tank
delay: 1.5
destroyOnEmpty: false
forceFeedDelay: 5
- type: Appearance
- type: SolutionContainerVisuals
maxFillLevels: 5
fillBaseName: jerrycan
inHandsMaxFillLevels: 5
inHandsFillBaseName: -fill-
- type: StaticPrice
price: 10
- type: Damageable
damageContainer: Inorganic
- type: Destructible
thresholds:
- trigger:
!type:DamageTrigger
damage: 200
behaviors:
- !type:DoActsBehavior
acts: [ "Destruction" ]
- trigger:
!type:DamageTrigger
damage: 20
behaviors:
- !type:PlaySoundBehavior
sound:
collection: MetalBreak
params:
volume: -4
- !type:SpillBehavior
solution: tank
- !type:SpawnEntitiesBehavior
spawn:
SheetPlastic1:
min: 0
max: 1
transferForensics: true
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: Label
- type: TrashOnSolutionEmpty
solution: tank
- type: entity
parent: JerryCan
suffix: welding fuel
id: JerryCanWeldingFuel
# categories: [ HideSpawnMenu ] # Frontier
components:
- type: Label
currentLabel: reagent-name-welding-fuel
- type: SolutionContainerManager
solutions:
tank:
reagents:
- ReagentId: WeldingFuel
Quantity: 200

View File

@ -0,0 +1 @@
paper_heading_medtek_report by Bonfire Lit for Frontier Station, released under CC0 1.0.

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="230"
height="72"
viewBox="0 0 60.854165 19.05"
version="1.1"
id="svg1"
inkscape:version="1.4 (86a8ad7, 2024-10-11)"
sodipodi:docname="paper_heading_medtek_report.svg"
inkscape:export-filename="paper_heading_medtek_report.svg.96dpi.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="9.2070302"
inkscape:cx="95.796362"
inkscape:cy="79.55877"
inkscape:window-width="3840"
inkscape:window-height="2066"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="g7"
showgrid="false" />
<defs
id="defs1">
<rect
x="71.57574"
y="5.1047948"
width="107.39268"
height="80.978634"
id="rect10" />
<rect
x="66.68817"
y="9.449301"
width="39.643619"
height="32.366571"
id="rect9" />
<rect
x="93.624109"
y="4.5617315"
width="131.85576"
height="62.886727"
id="rect8" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g7"
transform="matrix(1.0754349,0,0,1.0754349,-23.847606,-1.4369447)">
<path
id="path2"
style="baseline-shift:baseline;display:inline;overflow:visible;vector-effect:none;fill:#000000;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
d="M 28.427331 3.5249053 L 28.427331 7.5247255 L 24.42703 7.5247255 L 24.42703 11.525026 L 28.427331 11.525026 L 28.427331 15.524846 L 32.427151 15.524846 L 32.427151 11.525026 L 36.427451 11.525026 L 36.427451 7.5247255 L 32.427151 7.5247255 L 32.427151 3.5249053 L 28.427331 3.5249053 z M 28.773783 3.9967726 L 29.364338 3.9967726 L 30.427241 5.424868 L 31.485819 3.9967726 L 32.080218 3.9967726 L 32.080218 7.3032073 L 31.538676 7.3032073 L 31.538676 4.8785206 L 30.427241 6.3710051 L 29.311481 4.8828452 L 29.311481 7.3032073 L 28.773783 7.3032073 L 28.773783 3.9967726 z M 24.830664 7.8716585 L 28.137579 7.8716585 L 28.137579 8.4823951 L 26.791652 8.4823951 L 26.791652 11.178093 L 26.180915 11.178093 L 26.180915 8.4823951 L 24.830664 8.4823951 L 24.830664 7.8716585 z M 28.773783 7.8716585 L 32.080218 7.8716585 L 32.080218 8.4823951 L 29.436896 8.4823951 L 29.436896 9.217105 L 31.56174 9.217105 L 31.56174 9.8326467 L 29.436896 9.8326467 L 29.436896 10.567357 L 32.080218 10.567357 L 32.080218 11.178093 L 28.773783 11.178093 L 28.773783 7.8716585 z M 32.775525 7.8716585 L 33.410288 7.8716585 L 33.410288 9.217105 L 34.216595 9.217105 L 35.390497 7.8716585 L 36.077155 7.8716585 L 36.077155 8.046086 L 34.78889 9.5251161 L 36.08196 11.003666 L 36.08196 11.178093 L 35.390497 11.178093 L 34.216595 9.8326467 L 33.410288 9.8326467 L 33.410288 11.178093 L 32.775525 11.178093 L 32.775525 7.8716585 z M 28.773783 11.746544 L 31.437287 11.746544 C 31.553629 11.746544 31.660779 11.775827 31.758752 11.833998 C 31.856725 11.89217 31.935073 11.970037 31.993244 12.06801 C 32.051416 12.162921 32.080218 12.268808 32.080218 12.385151 L 32.080218 14.414853 C 32.080218 14.531196 32.051416 14.638346 31.993244 14.736319 C 31.935073 14.83123 31.856725 14.907834 31.758752 14.966006 C 31.660779 15.024177 31.553629 15.05346 31.437287 15.05346 L 28.773783 15.05346 L 28.773783 11.746544 z M 29.430649 12.357761 C 29.415341 12.357761 29.401571 12.363775 29.389325 12.376021 C 29.38014 12.385206 29.37539 12.397232 29.37539 12.41254 L 29.37539 14.387464 C 29.37539 14.402772 29.38014 14.416541 29.389325 14.428788 C 29.401571 14.437973 29.415341 14.442723 29.430649 14.442723 L 31.409897 14.442723 C 31.425205 14.442723 31.438975 14.437973 31.451222 14.428788 C 31.463468 14.416541 31.469481 14.402772 31.469481 14.387464 L 31.469481 12.41254 C 31.469481 12.397232 31.463468 12.385206 31.451222 12.376021 C 31.438975 12.363775 31.425205 12.357761 31.409897 12.357761 L 29.430649 12.357761 z " />
<circle
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
id="path3"
cx="30.427084"
cy="9.5249996"
r="7.5" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.175px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:start;letter-spacing:0px;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:none;fill-opacity:1;stroke:#34c1e5;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
x="1.6092775"
y="11.437365"
id="text3"><tspan
sodipodi:role="line"
id="tspan3"
style="stroke-width:1"
x="1.6092775"
y="11.437365" /></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:1.41111px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';text-align:start;letter-spacing:0px;writing-mode:lr-tb;direction:ltr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
x="1.0219975"
y="18.663475"
id="text4"><tspan
sodipodi:role="line"
style="font-size:1.41111px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;-inkscape-font-specification:'Open Sans Bold';font-family:'Open Sans';font-weight:bold;font-style:normal;font-stretch:normal;font-variant:normal"
x="1.0219975"
y="18.663475"
id="tspan14">A NanoTrasen company</tspan></text>
<text
xml:space="preserve"
transform="scale(0.26458333)"
id="text8"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';text-align:end;letter-spacing:0px;writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect8);display:inline;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3.77953;stroke-dasharray:none;stroke-opacity:1"
x="55.063694"
y="0"><tspan
x="127.65058"
y="20.333534"
id="tspan9"><tspan
style="font-weight:bold;-inkscape-font-specification:'Open Sans Bold'"
id="tspan2">Automated
</tspan></tspan><tspan
x="99.475505"
y="42.000158"
id="tspan11"><tspan
style="font-weight:bold;-inkscape-font-specification:'Open Sans Bold'"
id="tspan10">Patient Health
</tspan></tspan><tspan
x="166.70129"
y="63.666782"
id="tspan13"><tspan
style="font-weight:bold;-inkscape-font-specification:'Open Sans Bold'"
id="tspan12">Report</tspan></tspan></text>
</g>
<metadata
id="metadata1">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:description>Letters in MedTek cross set in Orbitron from https://github.com/theleagueof/orbitron, available under the SIL Open Font License. Other letters set in OpenSans from https://github.com/googlefonts/opensans, available under the SIL Open Font License.</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -6,3 +6,10 @@ Released into the public domain
edit.svg.png by H2D2 Design under MIT License
https://www.svgrepo.com/svg/453928/edit
check and cross pulled from https://github.com/apancik/public-domain-icons, available in the public domain.
print.png and print.svg from https://lucide.dev/icons/printer under ISC License - Copyright (c) 2026 Lucide Icons and Contributors
ISC License - Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

View File

@ -0,0 +1,2 @@
sample:
filter: true

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-printer-icon lucide-printer"><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><path d="M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6"/><rect x="6" y="14" width="12" height="8" rx="1"/></svg>

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

View File

@ -0,0 +1,33 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "made by avalon2855 on discord. Slight color modification by javadocs(Discord) so it didn't look like the experimental one.",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "base"
},
{
"name": "icon",
"delays": [
[
0.1,
0.1,
0.1,
0.1
]
]
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

View File

@ -0,0 +1,33 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "made by avalon2855 on discord",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "base"
},
{
"name": "icon",
"delays": [
[
0.1,
0.1,
0.1,
0.1
]
]
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

View File

@ -0,0 +1,33 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "made by avalon2855 on discord",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "base"
},
{
"name": "icon",
"delays": [
[
0.1,
0.1,
0.1,
0.1
]
]
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

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