diff --git a/Content.Server/Stories/ThermalVision/ThermalVisionSystem.cs b/Content.Server/Stories/ThermalVision/ThermalVisionSystem.cs new file mode 100644 index 0000000000..3c1227828a --- /dev/null +++ b/Content.Server/Stories/ThermalVision/ThermalVisionSystem.cs @@ -0,0 +1,44 @@ +using Content.Shared.Actions; +using Content.Shared.GameTicking; +using Content.Shared.Inventory.Events; +using Content.Shared.Stories.ThermalVision; +using Robust.Shared.Player; +using Robust.Shared.Timing; + +namespace Content.Server.Stories.ThermalVision; + +public sealed class ThermalVisionSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnEquipped); + SubscribeLocalEvent(OnUnequipped); + SubscribeLocalEvent(OnStartUp); + SubscribeLocalEvent(OnShutdown); + } + private void OnUnequipped(EntityUid uid, ThermalVisionClothingComponent component, GotUnequippedEvent args) + { + if (args.Slot == "eyes" && !(TryComp(args.Equipee, out var comp) && comp.Innate)) + RemCompDeferred(args.Equipee); + } + private void OnEquipped(EntityUid uid, ThermalVisionClothingComponent component, GotEquippedEvent args) + { + if (_gameTiming.ApplyingState) + return; + + if (args.Slot == "eyes" && component.Enabled && !HasComp(args.Equipee)) + AddComp(args.Equipee); + } + private void OnStartUp(EntityUid uid, ThermalVisionComponent component, ComponentStartup args) + { + _actions.AddAction(uid, ref component.ToggleActionEntity, component.ToggleAction); + } + private void OnShutdown(EntityUid uid, ThermalVisionComponent component, ComponentShutdown args) + { + Del(component.ToggleActionEntity); + } +} diff --git a/Content.Shared/Stories/ThermalVision/SharedThermalVisionSystem.cs b/Content.Shared/Stories/ThermalVision/SharedThermalVisionSystem.cs index dd3620af6d..dc6de72ebd 100644 --- a/Content.Shared/Stories/ThermalVision/SharedThermalVisionSystem.cs +++ b/Content.Shared/Stories/ThermalVision/SharedThermalVisionSystem.cs @@ -1,13 +1,20 @@ -namespace Content.Shared.Stories.ThermalVision; +using Robust.Shared.Timing; + +namespace Content.Shared.Stories.ThermalVision; public abstract class SharedThermalVisionSystem : EntitySystem { + [Dependency] private readonly IGameTiming _timing = default!; public override void Initialize() { + base.Initialize(); + SubscribeLocalEvent(OnThermalVisionMapInit); SubscribeLocalEvent(OnThermalVisionRemove); SubscribeLocalEvent(OnThermalVisionAfterHandle); + + SubscribeLocalEvent(OnToggle); } private void OnThermalVisionAfterHandle(Entity ent, ref AfterAutoHandleStateEvent args) @@ -32,4 +39,12 @@ protected virtual void ThermalVisionChanged(Entity ent) protected virtual void ThermalVisionRemoved(Entity ent) { } + private void OnToggle(EntityUid uid, ThermalVisionComponent component, ToggleThermalVisionEvent args) + { + if (!_timing.IsFirstTimePredicted) + return; + component.Enabled = !component.Enabled; + var ent = new Entity(uid, component); + ThermalVisionChanged(ent); + } } diff --git a/Content.Shared/Stories/ThermalVision/ThermalVisionClothingComponent.cs b/Content.Shared/Stories/ThermalVision/ThermalVisionClothingComponent.cs new file mode 100644 index 0000000000..b60e5cbcdf --- /dev/null +++ b/Content.Shared/Stories/ThermalVision/ThermalVisionClothingComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Stories.ThermalVision; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] +public sealed partial class ThermalVisionClothingComponent : Component +{ + [DataField, AutoNetworkedField] + public bool Enabled = true; +} diff --git a/Content.Shared/Stories/ThermalVision/ThermalVisionComponent.cs b/Content.Shared/Stories/ThermalVision/ThermalVisionComponent.cs index c3c3972944..a9baf5800b 100644 --- a/Content.Shared/Stories/ThermalVision/ThermalVisionComponent.cs +++ b/Content.Shared/Stories/ThermalVision/ThermalVisionComponent.cs @@ -1,10 +1,18 @@ -using Robust.Shared.GameStates; +using Content.Shared.Actions; +using Robust.Shared.GameStates; namespace Content.Shared.Stories.ThermalVision; [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class ThermalVisionComponent : Component { + [ViewVariables(VVAccess.ReadWrite), DataField("enabled"), AutoNetworkedField] + public bool Enabled { get; set; } = false; + [ViewVariables(VVAccess.ReadWrite), DataField("innate"), AutoNetworkedField] + public bool Innate { get; set; } = false; + [DataField] + public string ToggleAction = "ToggleThermalVisionAction"; [DataField, AutoNetworkedField] - public bool Enabled = true; + public EntityUid? ToggleActionEntity; } +public sealed partial class ToggleThermalVisionEvent : InstantActionEvent { } diff --git a/Resources/Prototypes/Stories/Actions/thermalvision.yml b/Resources/Prototypes/Stories/Actions/thermalvision.yml new file mode 100644 index 0000000000..53ef3cbc8d --- /dev/null +++ b/Resources/Prototypes/Stories/Actions/thermalvision.yml @@ -0,0 +1,9 @@ +- type: entity + id: ToggleThermalVisionAction + name: Термальное зрение + description: Переключить своё термальное зрение. + components: + - type: InstantAction + useDelay: 5 + icon: { sprite: Stories/Actions/thermalVision.rsi, state: toggle } + event: !type:ToggleThermalVisionEvent diff --git a/Resources/Prototypes/Stories/Catalog/uplink_catalog.yml b/Resources/Prototypes/Stories/Catalog/uplink_catalog.yml index f93fc6e4c5..8b447f10a4 100644 --- a/Resources/Prototypes/Stories/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Stories/Catalog/uplink_catalog.yml @@ -30,3 +30,39 @@ Telecrystal: 8 categories: - UplinkWeaponry + +- type: listing + id: UplinkClothingEyesThermalVisionMonocular + name: Монокль термального зрения + description: Новейшая разведочная технология, которую поместили внутрь монокля. Позволяет видеть органические цели в полной темноте и даже через стены. + productEntity: ClothingEyesThermalVisionMonocular + discountCategory: rareDiscounts + discountDownTo: + Telecrystal: 4 + cost: + Telecrystal: 6 + categories: + - UplinkWearables + conditions: + - !type:StoreWhitelistCondition + blacklist: + tags: + - NukeOpsUplink + +- type: listing + id: UplinkClothingEyesThermalVisionHud + name: Термальный визор оперативника + description: Новейшая разведочная технология, которую поместили внутрь визора. Позволяет видеть органические цели в полной темноте и даже через стены. Этот вариант специально для Ядерных Оперативников имеет встроенный визор Синдиката. + productEntity: ClothingEyesThermalVisionHud + discountCategory: rareDiscounts + discountDownTo: + Telecrystal: 6 + cost: + Telecrystal: 9 + categories: + - UplinkWearables + conditions: + - !type:StoreWhitelistCondition + whitelist: + tags: + - NukeOpsUplink diff --git a/Resources/Prototypes/Stories/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/Stories/Entities/Clothing/Eyes/glasses.yml index 06e5538b0e..3e84439290 100644 --- a/Resources/Prototypes/Stories/Entities/Clothing/Eyes/glasses.yml +++ b/Resources/Prototypes/Stories/Entities/Clothing/Eyes/glasses.yml @@ -1,3 +1,32 @@ +- type: entity + parent: ClothingEyesBase + id: ClothingEyesThermalVisionBase + abstract: true + components: + - type: ThermalVisionClothing + +- type: entity + parent: ClothingEyesThermalVisionBase + id: ClothingEyesThermalVisionMonocular + name: монокль термального зрения + description: Новейшая разведочная технология, которую поместили внутрь монокля. Позволяет видеть органические цели в полной темноте и даже через стены. + components: + - type: Sprite + sprite: Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi + - type: Clothing + sprite: Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi + +- type: entity + parent: [ ClothingEyesThermalVisionBase, ClothingEyesHudSyndicate ] + id: ClothingEyesThermalVisionHud + name: термальный визор оперативника + description: Новейшая разведочная технология, которую поместили внутрь визора. Позволяет видеть органические цели в полной темноте и даже через стены. Этот вариант специально для Ядерных Оперативников имеет встроенный визор Синдиката. + components: + - type: Sprite + sprite: Stories/Clothing/Eyes/Glasses/termalhud.rsi + - type: Clothing + sprite: Stories/Clothing/Eyes/Glasses/termalhud.rsi + - type: entity parent: ClothingEyesBase id: ClothingEyesNightvision diff --git a/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/ascendance.yml b/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/ascendance.yml index 79ac9977eb..27b8fe98a3 100644 --- a/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/ascendance.yml +++ b/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/ascendance.yml @@ -8,6 +8,7 @@ components: - type: ZombieImmune - type: ThermalVision + innate: true - type: MobState allowedStates: - Alive diff --git a/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/shadowling.yml b/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/shadowling.yml index 0a3f45e168..d952b9c7f0 100644 --- a/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/shadowling.yml +++ b/Resources/Prototypes/Stories/Entities/Mobs/Ghosts/shadowling.yml @@ -8,6 +8,7 @@ components: - type: ZombieImmune - type: ThermalVision + innate: true - type: MobState allowedStates: - Alive diff --git a/Resources/Prototypes/Stories/Entities/Mobs/Species/shadowling.yml b/Resources/Prototypes/Stories/Entities/Mobs/Species/shadowling.yml index d1ba65428c..beec58ac78 100644 --- a/Resources/Prototypes/Stories/Entities/Mobs/Species/shadowling.yml +++ b/Resources/Prototypes/Stories/Entities/Mobs/Species/shadowling.yml @@ -11,6 +11,7 @@ components: - type: ZombieImmune - type: ThermalVision + innate: true - type: ComplexInteraction - type: Destructible thresholds: diff --git a/Resources/Prototypes/Stories/conversions.yml b/Resources/Prototypes/Stories/conversions.yml index 6df5c04773..df382a8d8f 100644 --- a/Resources/Prototypes/Stories/conversions.yml +++ b/Resources/Prototypes/Stories/conversions.yml @@ -12,6 +12,7 @@ color: Red components: - type: ThermalVision + innate: true - type: ShadowlingThrall mindRoles: - MindRoleShadowlingThrall diff --git a/Resources/Textures/Stories/Actions/thermalVision.rsi/meta.json b/Resources/Textures/Stories/Actions/thermalVision.rsi/meta.json new file mode 100644 index 0000000000..bfdc4d157d --- /dev/null +++ b/Resources/Textures/Stories/Actions/thermalVision.rsi/meta.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Created By RustedTim(discord:helloo4771) for SpaceStories(Server SS14).", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "toggle" + } + ] +} diff --git a/Resources/Textures/Stories/Actions/thermalVision.rsi/toggle.png b/Resources/Textures/Stories/Actions/thermalVision.rsi/toggle.png new file mode 100644 index 0000000000..f99b71a868 Binary files /dev/null and b/Resources/Textures/Stories/Actions/thermalVision.rsi/toggle.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/equipped-EYES.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/equipped-EYES.png new file mode 100644 index 0000000000..48c8c9d292 Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/equipped-EYES.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/icon.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/icon.png new file mode 100644 index 0000000000..0c5902490b Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/icon.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/inhand-left.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/inhand-left.png new file mode 100644 index 0000000000..62836e8410 Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/inhand-left.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/inhand-right.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/inhand-right.png new file mode 100644 index 0000000000..1884514a5b Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/inhand-right.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/meta.json b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/meta.json new file mode 100644 index 0000000000..6d79471170 --- /dev/null +++ b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Created By RustedTim(discord:helloo4771) for SpaceStories(Server SS14).", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "equipped-EYES", + "directions": 4 + }, + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/equipped-EYES.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/equipped-EYES.png new file mode 100644 index 0000000000..0390a64c0e Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/equipped-EYES.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/icon.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/icon.png new file mode 100644 index 0000000000..235e9f09e2 Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/icon.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/inhand-left.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/inhand-left.png new file mode 100644 index 0000000000..023e4bbc17 Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/inhand-left.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/inhand-right.png b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/inhand-right.png new file mode 100644 index 0000000000..53a9729dad Binary files /dev/null and b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/inhand-right.png differ diff --git a/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/meta.json b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/meta.json new file mode 100644 index 0000000000..6d79471170 --- /dev/null +++ b/Resources/Textures/Stories/Clothing/Eyes/Glasses/termalhud_oneglass.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-NC-SA-3.0", + "copyright": "Created By RustedTim(discord:helloo4771) for SpaceStories(Server SS14).", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "equipped-EYES", + "directions": 4 + }, + { + "name": "icon" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +}