diff --git a/Content.Server/DeltaV/Silicons/Borgs/BorgSwitchableTypeSystem.Lawset.cs b/Content.Server/DeltaV/Silicons/Borgs/BorgSwitchableTypeSystem.Lawset.cs
new file mode 100644
index 00000000000..03b7c54ad01
--- /dev/null
+++ b/Content.Server/DeltaV/Silicons/Borgs/BorgSwitchableTypeSystem.Lawset.cs
@@ -0,0 +1,33 @@
+using Content.Server.Silicons.Laws;
+using Content.Shared.Emag.Components;
+using Content.Shared.Emag.Systems;
+using Content.Shared.Silicons.Laws;
+using Content.Shared.Silicons.Laws.Components;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Silicons.Borgs;
+
+///
+/// Handles lawset patching when switching type.
+/// If a borg is made emagged it needs its emag laws carried over.
+///
+public sealed partial class BorgSwitchableTypeSystem
+{
+ [Dependency] private readonly SiliconLawSystem _law = default!;
+
+ private void ConfigureLawset(EntityUid uid, ProtoId id)
+ {
+ var laws = _law.GetLawset(id);
+ _law.SetLaws(laws.Laws, uid);
+
+ // re-add law 0 and final law based on new lawset
+ if (CompOrNull(uid)?.OwnerName != null)
+ {
+ // raising the event manually to bypass re-emagging checks
+ var ev = new GotEmaggedEvent(uid); // user wont be used since OwnerName isnt null, safe to pass itself
+ RaiseLocalEvent(uid, ref ev);
+ }
+
+ // ion storms don't get mirrored because thats basically impossible to track
+ }
+}
diff --git a/Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs b/Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
index d1a32a6a5ba..518652c2297 100644
--- a/Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
+++ b/Content.Server/Silicons/Borgs/BorgSwitchableTypeSystem.cs
@@ -11,7 +11,7 @@ namespace Content.Server.Silicons.Borgs;
///
/// Server-side logic for borg type switching. Handles more heavyweight and server-specific switching logic.
///
-public sealed class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeSystem
+public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeSystem // DeltaV: Made partial
{
[Dependency] private readonly BorgSystem _borgSystem = default!;
[Dependency] private readonly ServerInventorySystem _inventorySystem = default!;
@@ -59,6 +59,11 @@ protected override void SelectBorgModule(Entity ent
}
}
+ // Begin DeltaV Code: Custom lawset patching
+ if (prototype.Lawset is {} lawset)
+ ConfigureLawset(ent, lawset);
+ // End DeltaV Code
+
// Configure special components
if (Prototypes.TryIndex(ent.Comp.SelectedBorgType, out var previousPrototype))
{
diff --git a/Content.Server/Silicons/Laws/SiliconLawSystem.cs b/Content.Server/Silicons/Laws/SiliconLawSystem.cs
index 9a361132a5c..2cce871fb24 100644
--- a/Content.Server/Silicons/Laws/SiliconLawSystem.cs
+++ b/Content.Server/Silicons/Laws/SiliconLawSystem.cs
@@ -131,9 +131,10 @@ private void OnEmagLawsAdded(EntityUid uid, SiliconLawProviderComponent componen
component.Lawset = GetLawset(component.Laws);
// Add the first emag law before the others
+ var name = CompOrNull(uid)?.OwnerName ?? Name(args.UserUid); // DeltaV: Reuse emagger name if possible
component.Lawset?.Laws.Insert(0, new SiliconLaw
{
- LawString = Loc.GetString("law-emag-custom", ("name", Name(args.UserUid)), ("title", Loc.GetString(component.Lawset.ObeysTo))),
+ LawString = Loc.GetString("law-emag-custom", ("name", name), ("title", Loc.GetString(component.Lawset.ObeysTo))), // DeltaV: pass name from variable
Order = 0
});
diff --git a/Content.Server/_CD/Engraving/EngraveableComponent.cs b/Content.Server/_CD/Engraving/EngraveableComponent.cs
new file mode 100644
index 00000000000..f60ee3f584f
--- /dev/null
+++ b/Content.Server/_CD/Engraving/EngraveableComponent.cs
@@ -0,0 +1,32 @@
+namespace Content.Server._CD.Engraving;
+
+///
+/// Allows an items' description to be modified with an engraving
+///
+[RegisterComponent, Access(typeof(EngraveableSystem))]
+public sealed partial class EngraveableComponent : Component
+{
+ ///
+ /// Message given to user to notify them a message was sent
+ ///
+ [DataField]
+ public string EngravedMessage = string.Empty;
+
+ ///
+ /// The inspect text to use when there is no engraving
+ ///
+ [DataField]
+ public LocId NoEngravingText = "engraving-dogtags-no-message";
+
+ ///
+ /// The message to use when successfully engraving the item
+ ///
+ [DataField]
+ public LocId EngraveSuccessMessage = "engraving-dogtags-succeed";
+
+ ///
+ /// The inspect text to use when there is an engraving. The message will be shown seperately afterwards.
+ ///
+ [DataField]
+ public LocId HasEngravingText = "engraving-dogtags-has-message";
+}
diff --git a/Content.Server/_CD/Engraving/EngraveableSystem.cs b/Content.Server/_CD/Engraving/EngraveableSystem.cs
new file mode 100644
index 00000000000..370929511a5
--- /dev/null
+++ b/Content.Server/_CD/Engraving/EngraveableSystem.cs
@@ -0,0 +1,83 @@
+using Content.Server.Administration;
+using Content.Server.Administration.Logs;
+using Content.Server.Popups;
+using Content.Shared.Database;
+using Content.Shared.Popups;
+using Content.Shared.Examine;
+using Content.Shared.Verbs;
+using Robust.Shared.Player;
+using Robust.Shared.Utility;
+
+namespace Content.Server._CD.Engraving;
+
+public sealed class EngraveableSystem : EntitySystem
+{
+ [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly PopupSystem _popup = default!;
+ [Dependency] private readonly QuickDialogSystem _dialog = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnExamined);
+ SubscribeLocalEvent>(AddEngraveVerb);
+ }
+
+ private void OnExamined(Entity ent, ref ExaminedEvent args)
+ {
+ var msg = new FormattedMessage();
+ msg.AddMarkupOrThrow(Loc.GetString(ent.Comp.EngravedMessage == string.Empty
+ ? ent.Comp.NoEngravingText
+ : ent.Comp.HasEngravingText));
+
+ if (ent.Comp.EngravedMessage != string.Empty)
+ msg.AddMarkupPermissive(Loc.GetString(ent.Comp.EngravedMessage));
+
+ args.PushMessage(msg, 1);
+ }
+
+ private void AddEngraveVerb(Entity ent, ref GetVerbsEvent args)
+ {
+ // First check if it's already been engraved. If it has, don't let them do it again.
+ if (ent.Comp.EngravedMessage != string.Empty)
+ return;
+
+ // We need an actor to give the verb.
+ if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
+ return;
+
+ // Make sure ghosts can't engrave stuff.
+ if (!args.CanInteract)
+ return;
+
+ var engraveVerb = new ActivationVerb
+ {
+ Text = Loc.GetString("engraving-verb-engrave"),
+ Act = () =>
+ {
+ _dialog.OpenDialog(actor.PlayerSession,
+ Loc.GetString("engraving-verb-engrave"),
+ Loc.GetString("engraving-popup-ui-message"),
+ (string message) =>
+ {
+ // If either the actor or comp have magically vanished
+ if (actor.PlayerSession.AttachedEntity == null || !HasComp(ent))
+ return;
+
+ ent.Comp.EngravedMessage = message;
+ _popup.PopupEntity(Loc.GetString(ent.Comp.EngraveSuccessMessage),
+ actor.PlayerSession.AttachedEntity.Value,
+ actor.PlayerSession,
+ PopupType.Medium);
+ _adminLogger.Add(LogType.Action,
+ LogImpact.Low,
+ $"{ToPrettyString(actor.PlayerSession.AttachedEntity):player} engraved an item with message: {message}");
+ });
+ },
+ Impact = LogImpact.Low,
+ };
+ engraveVerb.Impact = LogImpact.Low;
+ args.Verbs.Add(engraveVerb);
+ }
+}
diff --git a/Content.Shared/Silicons/Borgs/BorgTypePrototype.cs b/Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
index 1518cfdfe50..5708b16cc11 100644
--- a/Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
+++ b/Content.Shared/Silicons/Borgs/BorgTypePrototype.cs
@@ -2,6 +2,7 @@
using Content.Shared.Inventory;
using Content.Shared.Radio;
using Content.Shared.Silicons.Borgs.Components;
+using Content.Shared.Silicons.Laws; // DeltaV
using Content.Shared.Whitelist;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
@@ -83,6 +84,13 @@ public sealed partial class BorgTypePrototype : IPrototype
[DataField]
public EntProtoId[] DefaultModules = [];
+ ///
+ /// DeltaV: Lawset to use instead of crewsimov.
+ /// If the chassis is emagged or ion stormed this is ignored.
+ ///
+ [DataField]
+ public ProtoId? Lawset;
+
///
/// Additional components to add to the borg entity when this type is selected.
///
diff --git a/Resources/Changelog/DeltaVChangelog.yml b/Resources/Changelog/DeltaVChangelog.yml
index 5091730c4bb..fef98ad16f3 100644
--- a/Resources/Changelog/DeltaVChangelog.yml
+++ b/Resources/Changelog/DeltaVChangelog.yml
@@ -1,17 +1,4 @@
Entries:
-- author: DebugOk
- changes:
- - message: Added gridinv, sorry.
- type: Add
- id: 212
- time: '2024-01-21T18:58:28.0000000+00:00'
-- author: TadJohnson00
- changes:
- - message: Pride vend has received an adjusted inventory. Make sure to check out
- the new cloaks available!
- type: Tweak
- id: 213
- time: '2024-01-30T14:22:13.0000000+00:00'
- author: Colin-Tel
changes:
- message: Updated Asterisk Station.
@@ -3775,3 +3762,18 @@
id: 711
time: '2024-11-27T20:22:30.0000000+00:00'
url: https://github.com/DeltaV-Station/Delta-v/pull/2302
+- author: deltanedas
+ changes:
+ - message: Fixed borgs with special lawsets fixing their emag laws when switched
+ to.
+ type: Fix
+ id: 712
+ time: '2024-11-28T07:22:06.0000000+00:00'
+ url: https://github.com/DeltaV-Station/Delta-v/pull/2299
+- author: Kr8art
+ changes:
+ - message: Added customizable dogtags from Cosmatic Drift to the trinket loadout!
+ type: Add
+ id: 713
+ time: '2024-11-28T12:04:17.0000000+00:00'
+ url: https://github.com/DeltaV-Station/Delta-v/pull/2301
diff --git a/Resources/Locale/en-US/_CD/engraving/engraving.ftl b/Resources/Locale/en-US/_CD/engraving/engraving.ftl
new file mode 100644
index 00000000000..fc6ca919ead
--- /dev/null
+++ b/Resources/Locale/en-US/_CD/engraving/engraving.ftl
@@ -0,0 +1,6 @@
+engraving-verb-engrave = Engrave
+engraving-popup-ui-message = Description
+
+engraving-dogtags-no-message = The dogtags don't seem to have any kind of engraving.
+engraving-dogtags-has-message = The dogtags are engraved with a message that reads:{" "}
+engraving-dogtags-succeed = You successfully engrave the dogtags with your message.
diff --git a/Resources/Prototypes/DeltaV/borg_types.yml b/Resources/Prototypes/DeltaV/borg_types.yml
index fd5be28db70..0fb7ab66153 100644
--- a/Resources/Prototypes/DeltaV/borg_types.yml
+++ b/Resources/Prototypes/DeltaV/borg_types.yml
@@ -18,9 +18,9 @@
- BorgModuleSecurityPatrol
- BorgModuleSecurityBastion
+ lawset: SiliconPolice
+
addComponents:
- - type: SiliconLawProvider
- laws: SiliconPolice
- type: FlashImmunity
- type: ShowMindShieldIcons
- type: ShowCriminalRecordIcons
diff --git a/Resources/Prototypes/Loadouts/loadout_groups.yml b/Resources/Prototypes/Loadouts/loadout_groups.yml
index ccf1bd50d39..d81dd6c6116 100644
--- a/Resources/Prototypes/Loadouts/loadout_groups.yml
+++ b/Resources/Prototypes/Loadouts/loadout_groups.yml
@@ -50,6 +50,7 @@
- SilverRing # DeltaV
- Cane # DeltaV
- WhiteCane #DeltaV
+ - CDDogtags # _CD
- type: loadoutGroup
id: Glasses
diff --git a/Resources/Prototypes/_CD/Entities/Objects/Misc/dogtags.yml b/Resources/Prototypes/_CD/Entities/Objects/Misc/dogtags.yml
new file mode 100644
index 00000000000..22a1b22a72f
--- /dev/null
+++ b/Resources/Prototypes/_CD/Entities/Objects/Misc/dogtags.yml
@@ -0,0 +1,14 @@
+- type: entity
+ id: CDDogtags
+ parent: ClothingNeckBase
+ name: dogtags
+ description: A set of dogtags, hanging from a small piece of cord for wearing and carrying.
+ components:
+ - type: Sprite
+ sprite: _CD/Objects/Misc/dogtags.rsi
+ layers:
+ - state: dogtag
+ - type: Clothing
+ sprite: _CD/Objects/Misc/dogtags.rsi
+ - type: Appearance
+ - type: Engraveable
diff --git a/Resources/Prototypes/_CD/Loadouts/Miscellaneous/trinkets.yml b/Resources/Prototypes/_CD/Loadouts/Miscellaneous/trinkets.yml
new file mode 100644
index 00000000000..5c04fc51dac
--- /dev/null
+++ b/Resources/Prototypes/_CD/Loadouts/Miscellaneous/trinkets.yml
@@ -0,0 +1,5 @@
+- type: loadout
+ id: CDDogtags
+ storage:
+ back:
+ - CDDogtags
diff --git a/Resources/Prototypes/borg_types.yml b/Resources/Prototypes/borg_types.yml
index 1ebeb9112d2..72b5c954eb8 100644
--- a/Resources/Prototypes/borg_types.yml
+++ b/Resources/Prototypes/borg_types.yml
@@ -49,9 +49,7 @@
- BorgModuleRCD
- BorgModuleCable
- addComponents: # DeltaV: Custom lawset
- - type: SiliconLawProvider
- laws: Engineer
+ lawset: Engineer # DeltaV: Custom lawset
radioChannels:
- Engineering
@@ -123,9 +121,7 @@
- BorgModuleLightReplacer
- BorgModuleCleaning
- addComponents: # DeltaV: Custom lawset
- - type: SiliconLawProvider
- laws: Janitor
+ lawset: Janitor # DeltaV: Custom lawset
radioChannels:
- Science
@@ -165,6 +161,8 @@
- Science
- Medical
+ lawset: Medical # DeltaV: Custom lawset
+
addComponents:
- type: SolutionScanner
- type: ShowHealthBars
@@ -174,8 +172,6 @@
damageContainers:
- Biological
- type: FabricateCandy # Nyanotrasen - The medical cyborg can generate candies filled with medicine.
- - type: SiliconLawProvider # DeltaV: Custom lawset
- laws: Medical
# Visual
inventoryTemplateId: borgDutch
diff --git a/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/dogtag.png b/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/dogtag.png
new file mode 100644
index 00000000000..05a5b71bc5e
Binary files /dev/null and b/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/dogtag.png differ
diff --git a/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/equipped-NECK.png b/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/equipped-NECK.png
new file mode 100644
index 00000000000..4d837168da6
Binary files /dev/null and b/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/equipped-NECK.png differ
diff --git a/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/meta.json b/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/meta.json
new file mode 100644
index 00000000000..da1b490e53b
--- /dev/null
+++ b/Resources/Textures/_CD/Objects/Misc/dogtags.rsi/meta.json
@@ -0,0 +1,18 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from cmss13 at https://github.com/cmss13-devs/cmss13/blob/a2d5ca6e69725341f0fa261a4a3f89c737e843b3/icons/obj/items/card.dmi",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "dogtag"
+ },
+ {
+ "name": "equipped-NECK",
+ "directions": 4
+ }
+ ]
+}