From 85992518256e85c7980b784b6462727f9158a413 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Fri, 6 Sep 2024 10:05:53 -0400 Subject: [PATCH] Mineral Scanner (#31390) * Mineral Scanner * doink * review * sunday funday * review and fix bugs i think? * Update MiningOverlay.cs --- Content.Client/Mining/MiningOverlay.cs | 96 +++++++++++++++++ Content.Client/Mining/MiningOverlaySystem.cs | 54 ++++++++++ .../Mining/OreVeinVisualsComponent.cs | 6 -- Content.Server/Mining/MiningSystem.cs | 2 +- .../Item/ItemToggle/ItemToggleSystem.cs | 2 +- .../Components/MiningScannerComponent.cs | 13 +++ .../MiningScannerViewableComponent.cs | 13 +++ .../MiningScannerViewerComponent.cs | 36 +++++++ .../Mining/Components/OreVeinComponent.cs | 15 ++- Content.Shared/Mining/MiningScannerSystem.cs | 101 ++++++++++++++++++ Content.Shared/Mining/OrePrototype.cs | 15 +-- Resources/Audio/Machines/attributions.yml | 5 + Resources/Audio/Machines/sonar-ping.ogg | Bin 0 -> 32532 bytes .../Spawners/Random/Salvage/tables_loot.yml | 3 + .../Specific/Robotics/borg_modules.yml | 1 + .../Objects/Specific/Salvage/scanner.yml | 91 ++++++++++++++++ .../Entities/Structures/Machines/lathe.yml | 2 + .../Entities/Structures/Walls/asteroid.yml | 91 ++++++++++++++++ .../Prototypes/Recipes/Lathes/salvage.yml | 20 ++++ Resources/Prototypes/Research/industrial.yml | 2 + .../Mining/mineral_scanner.rsi/adv-o.png | Bin 0 -> 595 bytes .../Mining/mineral_scanner.rsi/adv.png | Bin 0 -> 937 bytes .../Mining/mineral_scanner.rsi/icon-o.png | Bin 0 -> 572 bytes .../Mining/mineral_scanner.rsi/icon.png | Bin 0 -> 875 bytes .../Mining/mineral_scanner.rsi/meta.json | 23 ++++ 25 files changed, 568 insertions(+), 23 deletions(-) create mode 100644 Content.Client/Mining/MiningOverlay.cs create mode 100644 Content.Client/Mining/MiningOverlaySystem.cs delete mode 100644 Content.Client/Mining/OreVeinVisualsComponent.cs create mode 100644 Content.Shared/Mining/Components/MiningScannerComponent.cs create mode 100644 Content.Shared/Mining/Components/MiningScannerViewableComponent.cs create mode 100644 Content.Shared/Mining/Components/MiningScannerViewerComponent.cs create mode 100644 Content.Shared/Mining/MiningScannerSystem.cs create mode 100644 Resources/Audio/Machines/sonar-ping.ogg create mode 100644 Resources/Prototypes/Entities/Objects/Specific/Salvage/scanner.yml create mode 100644 Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/adv-o.png create mode 100644 Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/adv.png create mode 100644 Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/icon-o.png create mode 100644 Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/icon.png create mode 100644 Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/meta.json diff --git a/Content.Client/Mining/MiningOverlay.cs b/Content.Client/Mining/MiningOverlay.cs new file mode 100644 index 0000000000..b23835b36e --- /dev/null +++ b/Content.Client/Mining/MiningOverlay.cs @@ -0,0 +1,96 @@ +using System.Numerics; +using Content.Shared.Mining.Components; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Player; +using Robust.Shared.Enums; +using Robust.Shared.Timing; +using Robust.Shared.Utility; + +namespace Content.Client.Mining; + +public sealed class MiningOverlay : Overlay +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IPlayerManager _player = default!; + private readonly EntityLookupSystem _lookup; + private readonly SpriteSystem _sprite; + private readonly TransformSystem _xform; + + private readonly EntityQuery _spriteQuery; + private readonly EntityQuery _xformQuery; + + public override OverlaySpace Space => OverlaySpace.WorldSpace; + public override bool RequestScreenTexture => false; + + private readonly HashSet> _viewableEnts = new(); + + public MiningOverlay() + { + IoCManager.InjectDependencies(this); + + _lookup = _entityManager.System(); + _sprite = _entityManager.System(); + _xform = _entityManager.System(); + + _spriteQuery = _entityManager.GetEntityQuery(); + _xformQuery = _entityManager.GetEntityQuery(); + } + + protected override void Draw(in OverlayDrawArgs args) + { + var handle = args.WorldHandle; + + if (_player.LocalEntity is not { } localEntity || + !_entityManager.TryGetComponent(localEntity, out var viewerComp)) + return; + + if (viewerComp.LastPingLocation == null) + return; + + var scaleMatrix = Matrix3Helpers.CreateScale(Vector2.One); + + _viewableEnts.Clear(); + _lookup.GetEntitiesInRange(viewerComp.LastPingLocation.Value, viewerComp.ViewRange, _viewableEnts); + foreach (var ore in _viewableEnts) + { + if (!_xformQuery.TryComp(ore, out var xform) || + !_spriteQuery.TryComp(ore, out var sprite)) + continue; + + if (xform.MapID != args.MapId || !sprite.Visible) + continue; + + if (!sprite.LayerMapTryGet(MiningScannerVisualLayers.Overlay, out var idx)) + continue; + var layer = sprite[idx]; + + if (layer.ActualRsi?.Path == null || layer.RsiState.Name == null) + continue; + + var gridRot = xform.GridUid == null ? 0 : _xformQuery.CompOrNull(xform.GridUid.Value)?.LocalRotation ?? 0; + var rotationMatrix = Matrix3Helpers.CreateRotation(gridRot); + + var worldMatrix = Matrix3Helpers.CreateTranslation(_xform.GetWorldPosition(xform)); + var scaledWorld = Matrix3x2.Multiply(scaleMatrix, worldMatrix); + var matty = Matrix3x2.Multiply(rotationMatrix, scaledWorld); + handle.SetTransform(matty); + + var spriteSpec = new SpriteSpecifier.Rsi(layer.ActualRsi.Path, layer.RsiState.Name); + var texture = _sprite.GetFrame(spriteSpec, TimeSpan.FromSeconds(layer.AnimationTime)); + + var animTime = (viewerComp.NextPingTime - _timing.CurTime).TotalSeconds; + + + var alpha = animTime < viewerComp.AnimationDuration + ? 0 + : (float) Math.Clamp((animTime - viewerComp.AnimationDuration) / viewerComp.AnimationDuration, 0f, 1f); + var color = Color.White.WithAlpha(alpha); + + handle.DrawTexture(texture, -(Vector2) texture.Size / 2f / EyeManager.PixelsPerMeter, layer.Rotation, modulate: color); + + } + handle.SetTransform(Matrix3x2.Identity); + } +} diff --git a/Content.Client/Mining/MiningOverlaySystem.cs b/Content.Client/Mining/MiningOverlaySystem.cs new file mode 100644 index 0000000000..294cab30ca --- /dev/null +++ b/Content.Client/Mining/MiningOverlaySystem.cs @@ -0,0 +1,54 @@ +using Content.Shared.Mining.Components; +using Robust.Client.Graphics; +using Robust.Client.Player; +using Robust.Shared.Player; + +namespace Content.Client.Mining; + +/// +/// This handles the lifetime of the for a given entity. +/// +public sealed class MiningOverlaySystem : EntitySystem +{ + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IOverlayManager _overlayMan = default!; + + private MiningOverlay _overlay = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnPlayerAttached); + SubscribeLocalEvent(OnPlayerDetached); + + _overlay = new(); + } + + private void OnPlayerAttached(Entity ent, ref LocalPlayerAttachedEvent args) + { + _overlayMan.AddOverlay(_overlay); + } + + private void OnPlayerDetached(Entity ent, ref LocalPlayerDetachedEvent args) + { + _overlayMan.RemoveOverlay(_overlay); + } + + private void OnInit(Entity ent, ref ComponentInit args) + { + if (_player.LocalEntity == ent) + { + _overlayMan.AddOverlay(_overlay); + } + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + if (_player.LocalEntity == ent) + { + _overlayMan.RemoveOverlay(_overlay); + } + } +} diff --git a/Content.Client/Mining/OreVeinVisualsComponent.cs b/Content.Client/Mining/OreVeinVisualsComponent.cs deleted file mode 100644 index c662111c3e..0000000000 --- a/Content.Client/Mining/OreVeinVisualsComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Content.Client.Mining; - -public sealed class OreVeinVisualsComponent -{ - -} diff --git a/Content.Server/Mining/MiningSystem.cs b/Content.Server/Mining/MiningSystem.cs index a673cda946..18e96e5769 100644 --- a/Content.Server/Mining/MiningSystem.cs +++ b/Content.Server/Mining/MiningSystem.cs @@ -1,6 +1,6 @@ -using Content.Server.Mining.Components; using Content.Shared.Destructible; using Content.Shared.Mining; +using Content.Shared.Mining.Components; using Content.Shared.Random; using Content.Shared.Random.Helpers; using Robust.Shared.Prototypes; diff --git a/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs b/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs index 33b88dbaf8..98029f97d5 100644 --- a/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs +++ b/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs @@ -282,7 +282,7 @@ public sealed class ItemToggleSystem : EntitySystem if (comp.ActiveSound != null && comp.PlayingStream == null) { - var loop = AudioParams.Default.WithLoop(true); + var loop = comp.ActiveSound.Params.WithLoop(true); var stream = args.Predicted ? _audio.PlayPredicted(comp.ActiveSound, uid, args.User, loop) : _audio.PlayPvs(comp.ActiveSound, uid, loop); diff --git a/Content.Shared/Mining/Components/MiningScannerComponent.cs b/Content.Shared/Mining/Components/MiningScannerComponent.cs new file mode 100644 index 0000000000..3cf65e810d --- /dev/null +++ b/Content.Shared/Mining/Components/MiningScannerComponent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Mining.Components; + +/// +/// This is a component that, when held in the inventory or pocket of a player, gives the the MiningOverlay. +/// +[RegisterComponent, NetworkedComponent, Access(typeof(MiningScannerSystem))] +public sealed partial class MiningScannerComponent : Component +{ + [DataField] + public float Range = 5; +} diff --git a/Content.Shared/Mining/Components/MiningScannerViewableComponent.cs b/Content.Shared/Mining/Components/MiningScannerViewableComponent.cs new file mode 100644 index 0000000000..9ab1207025 --- /dev/null +++ b/Content.Shared/Mining/Components/MiningScannerViewableComponent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Mining.Components; + +[RegisterComponent, NetworkedComponent, Access(typeof(MiningScannerSystem))] +public sealed partial class MiningScannerViewableComponent : Component; + +[Serializable, NetSerializable] +public enum MiningScannerVisualLayers : byte +{ + Overlay +} diff --git a/Content.Shared/Mining/Components/MiningScannerViewerComponent.cs b/Content.Shared/Mining/Components/MiningScannerViewerComponent.cs new file mode 100644 index 0000000000..65fe1f23c4 --- /dev/null +++ b/Content.Shared/Mining/Components/MiningScannerViewerComponent.cs @@ -0,0 +1,36 @@ +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Map; + +namespace Content.Shared.Mining.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause, Access(typeof(MiningScannerSystem))] +public sealed partial class MiningScannerViewerComponent : Component +{ + [DataField, ViewVariables(VVAccess.ReadOnly), AutoNetworkedField] + public float ViewRange; + + [DataField, AutoNetworkedField] + public float AnimationDuration = 1.5f; + + [DataField, AutoNetworkedField] + public TimeSpan PingDelay = TimeSpan.FromSeconds(5); + + [DataField, AutoNetworkedField, AutoPausedField] + public TimeSpan NextPingTime = TimeSpan.MaxValue; + + [DataField] + public EntityCoordinates? LastPingLocation; + + [DataField, AutoNetworkedField] + public SoundSpecifier? PingSound = new SoundPathSpecifier("/Audio/Machines/sonar-ping.ogg") + { + Params = new AudioParams + { + Volume = -3, + } + }; + + [DataField] + public bool QueueRemoval; +} diff --git a/Content.Shared/Mining/Components/OreVeinComponent.cs b/Content.Shared/Mining/Components/OreVeinComponent.cs index 03e6a976cb..6ee40a624e 100644 --- a/Content.Shared/Mining/Components/OreVeinComponent.cs +++ b/Content.Shared/Mining/Components/OreVeinComponent.cs @@ -1,8 +1,7 @@ -using Content.Shared.Mining; using Content.Shared.Random; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Prototypes; -namespace Content.Server.Mining.Components; +namespace Content.Shared.Mining.Components; /// /// Defines an entity that will drop a random ore after being destroyed. @@ -14,19 +13,19 @@ public sealed partial class OreVeinComponent : Component /// How often an entity will be seeded with ore. Note: the amount of ore /// that is dropped is dependent on the ore prototype. /// - [DataField("oreChance")] + [DataField] public float OreChance = 0.1f; /// /// The weighted random prototype used for determining what ore will be dropped. /// - [DataField("oreRarityPrototypeId", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? OreRarityPrototypeId; + [DataField] + public ProtoId? OreRarityPrototypeId; /// /// The ore that this entity holds. /// If set in the prototype, it will not be overriden. /// - [DataField("currentOre", customTypeSerializer: typeof(PrototypeIdSerializer)), ViewVariables(VVAccess.ReadWrite)] - public string? CurrentOre; + [DataField] + public ProtoId? CurrentOre; } diff --git a/Content.Shared/Mining/MiningScannerSystem.cs b/Content.Shared/Mining/MiningScannerSystem.cs new file mode 100644 index 0000000000..22e9061b09 --- /dev/null +++ b/Content.Shared/Mining/MiningScannerSystem.cs @@ -0,0 +1,101 @@ +using Content.Shared.Inventory; +using Content.Shared.Item.ItemToggle.Components; +using Content.Shared.Mining.Components; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Network; +using Robust.Shared.Timing; + +namespace Content.Shared.Mining; + +public sealed class MiningScannerSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly InventorySystem _inventory = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnInserted); + SubscribeLocalEvent(OnRemoved); + SubscribeLocalEvent(OnToggled); + } + + private void OnInserted(Entity ent, ref EntGotInsertedIntoContainerMessage args) + { + UpdateViewerComponent(args.Container.Owner); + } + + private void OnRemoved(Entity ent, ref EntGotRemovedFromContainerMessage args) + { + UpdateViewerComponent(args.Container.Owner); + } + + private void OnToggled(Entity ent, ref ItemToggledEvent args) + { + if (_container.TryGetContainingContainer((ent.Owner, null, null), out var container)) + UpdateViewerComponent(container.Owner); + } + + public void UpdateViewerComponent(EntityUid uid) + { + Entity? scannerEnt = null; + + var ents = _inventory.GetHandOrInventoryEntities(uid); + foreach (var ent in ents) + { + if (!TryComp(ent, out var scannerComponent) || + !TryComp(ent, out var toggle)) + continue; + + if (!toggle.Activated) + continue; + + if (scannerEnt == null || scannerComponent.Range > scannerEnt.Value.Comp.Range) + scannerEnt = (ent, scannerComponent); + } + + if (_net.IsServer) + { + if (scannerEnt == null) + { + if (TryComp(uid, out var viewer)) + viewer.QueueRemoval = true; + } + else + { + var viewer = EnsureComp(uid); + viewer.ViewRange = scannerEnt.Value.Comp.Range; + viewer.QueueRemoval = false; + viewer.NextPingTime = _timing.CurTime + viewer.PingDelay; + Dirty(uid, viewer); + } + } + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var viewer, out var xform)) + { + if (viewer.QueueRemoval) + { + RemCompDeferred(uid, viewer); + continue; + } + + if (_timing.CurTime < viewer.NextPingTime) + continue; + + viewer.NextPingTime = _timing.CurTime + viewer.PingDelay; + viewer.LastPingLocation = xform.Coordinates; + if (_net.IsClient && _timing.IsFirstTimePredicted) + _audio.PlayEntity(viewer.PingSound, uid, uid); + } + } +} diff --git a/Content.Shared/Mining/OrePrototype.cs b/Content.Shared/Mining/OrePrototype.cs index a4f8a40a6f..d75ab19c49 100644 --- a/Content.Shared/Mining/OrePrototype.cs +++ b/Content.Shared/Mining/OrePrototype.cs @@ -1,26 +1,27 @@ using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.Utility; namespace Content.Shared.Mining; /// /// This is a prototype for defining ores that generate in rock /// -[Prototype("ore")] +[Prototype] public sealed partial class OrePrototype : IPrototype { /// [IdDataField] public string ID { get; private set; } = default!; - [DataField("oreEntity", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string? OreEntity; + [DataField] + public EntProtoId? OreEntity; - [DataField("minOreYield")] + [DataField] public int MinOreYield = 1; - [DataField("maxOreYield")] + [DataField] public int MaxOreYield = 1; - //TODO: add sprites for ores for things like mining analyzer + [DataField] + public SpriteSpecifier? OreSprite; } diff --git a/Resources/Audio/Machines/attributions.yml b/Resources/Audio/Machines/attributions.yml index 83725f2b80..b1f9924546 100644 --- a/Resources/Audio/Machines/attributions.yml +++ b/Resources/Audio/Machines/attributions.yml @@ -143,6 +143,11 @@ copyright: "/tg/station" source: "https://github.com/tgstation/tgstation/blob/3eeba3899f22638595333c63b7b7433001f91bb2/sound/machines/eject.ogg" +- files: ["sonar-ping.ogg"] + license: "CC-BY-SA-3.0" + copyright: "/tg/station" + source: "https://github.com/tgstation/tgstation/blob/002051a3d5e4a35af504e52c0990bf4e22a908dc/sound/machines/sonar-ping.ogg" + - files: ["scanning.ogg"] license: "CC0-1.0" copyright: "Samuel Gremaud on freesound.org" diff --git a/Resources/Audio/Machines/sonar-ping.ogg b/Resources/Audio/Machines/sonar-ping.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c69d43520958dba612a28ae4452227c7eab070bb GIT binary patch literal 32532 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 G(EkUC3UGY@ literal 0 HcmV?d00001 diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml index 78c338fcb5..552b8aae0d 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/Salvage/tables_loot.yml @@ -228,6 +228,8 @@ - id: ClothingEyesGlassesMeson - id: ClothingBeltSalvageWebbing - id: SeismicCharge + - id: MineralScanner + weight: 0.5 - id: WeaponCrusher weight: 0.5 - !type:GroupSelector @@ -239,6 +241,7 @@ id: SalvageEquipmentLegendary table: !type:GroupSelector children: + - id: AdvancedMineralScanner - id: BlueprintFulton - id: BlueprintSeismicCharge - id: WeaponCrusherGlaive diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 062e261dc5..3b3a539664 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -206,6 +206,7 @@ items: - MiningDrill - Shovel + - MineralScannerUnpowered - OreBag - Crowbar - RadioHandheld diff --git a/Resources/Prototypes/Entities/Objects/Specific/Salvage/scanner.yml b/Resources/Prototypes/Entities/Objects/Specific/Salvage/scanner.yml new file mode 100644 index 0000000000..9c3e783c51 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/Salvage/scanner.yml @@ -0,0 +1,91 @@ +- type: entity + id: MineralScannerUnpowered + parent: BaseItem + name: mineral scanner + description: A scanner that checks surrounding rock for useful minerals. It must be in your hand or pocket to work. + suffix: Unpowered + components: + - type: Sprite + sprite: Objects/Specific/Mining/mineral_scanner.rsi + layers: + - state: icon + - state: icon-o + shader: unshaded + visible: false + map: ["enum.ToggleVisuals.Layer"] + - type: ItemToggleActiveSound + activeSound: + path: /Audio/Ambience/Objects/light_hum.ogg + params: + volume: -10 + maxDistance: 1 + - type: Appearance + - type: GenericVisualizer + visuals: + enum.ToggleVisuals.Toggled: + enum.ToggleVisuals.Layer: + True: { visible: true } + False: { visible: false } + - type: ItemToggle + soundActivate: + path: /Audio/Weapons/click.ogg + params: + maxDistance: 1 + - type: MiningScanner + +- type: entity + id: MineralScanner + parent: [ MineralScannerUnpowered, PowerCellSlotMediumItem ] + suffix: Powered + components: + - type: ToggleCellDraw + - type: PowerCellDraw + drawRate: 2.4 # ~5 minutes on a medium power cell. + useRate: 0 + +- type: entity + id: MineralScannerEmpty + parent: MineralScanner + suffix: Empty + components: + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default + +- type: entity + id: AdvancedMineralScannerUnpowered + parent: MineralScannerUnpowered + name: advanced mineral scanner + description: A scanner that checks surrounding rock for useful minerals. It must be in your hand or pocket to work. This one has an extended range. + suffix: Unpowered + components: + - type: Sprite + layers: + - state: adv + - state: adv-o + shader: unshaded + visible: false + map: ["enum.ToggleVisuals.Layer"] + - type: MiningScanner + range: 10 + +- type: entity + id: AdvancedMineralScanner + parent: [ AdvancedMineralScannerUnpowered, PowerCellSlotMediumItem ] + suffix: Powered + components: + - type: ToggleCellDraw + - type: PowerCellDraw + drawRate: 1.2 # ~10 minutes on a medium power cell. + useRate: 0 + +- type: entity + id: AdvancedMineralScannerEmpty + parent: AdvancedMineralScanner + suffix: Empty + components: + - type: ItemSlots + slots: + cell_slot: + name: power-cell-slot-component-slot-name-default diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index d1d3088113..1bd5bc74a9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -323,6 +323,8 @@ - PowerCellHigh - WeaponPistolCHIMP - ClothingMaskWeldingGas + - MineralScannerEmpty + - AdvancedMineralScannerEmpty - WeaponGauntletGorilla - SynthesizerInstrument - ClothingShoesBootsMagSci diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index 755a1ee8b4..54f553ab9c 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -31,6 +31,7 @@ state: rock_asteroid_north - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west + - type: MiningScannerViewable - type: Damageable damageContainer: StructuralInorganic damageModifierSet: Rock @@ -70,6 +71,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockGold @@ -92,6 +94,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockDiamond @@ -114,6 +117,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockPlasma @@ -136,6 +140,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockQuartz @@ -158,6 +163,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockQuartzCrab @@ -180,6 +186,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockSilver @@ -202,6 +209,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockSilverCrab @@ -234,6 +242,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockTinCrab @@ -265,6 +274,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockUraniumCrab @@ -296,6 +306,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockSalt @@ -318,6 +329,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockArtifactFragment @@ -340,6 +352,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: AsteroidRockMining @@ -412,6 +425,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockGold @@ -434,6 +448,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockPlasma @@ -456,6 +471,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockQuartz @@ -478,6 +494,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockSilver @@ -500,6 +517,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockIron @@ -522,6 +540,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockUranium @@ -544,6 +563,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockBananium @@ -566,6 +586,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockSalt @@ -588,6 +609,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockArtifactFragment @@ -610,6 +632,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: IronRockDiamond @@ -632,6 +655,7 @@ - map: [ "enum.EdgeLayer.West" ] state: ironrock_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Rocks and ore veins - type: entity @@ -664,6 +688,7 @@ - type: Icon sprite: Structures/Walls/rock.rsi state: rock + - type: MiningScannerViewable - type: SmoothEdge - type: Sprite sprite: Structures/Walls/rock.rsi @@ -707,6 +732,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockGold @@ -736,6 +762,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockDiamond @@ -758,6 +785,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockPlasma @@ -787,6 +815,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockQuartz @@ -816,6 +845,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSilver @@ -845,6 +875,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Yes I know it drops steel but we may get smelting at some point - type: entity @@ -875,6 +906,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockUranium @@ -904,6 +936,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity @@ -934,6 +967,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockArtifactFragment @@ -963,6 +997,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSalt @@ -992,6 +1027,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Basalt variants - type: entity @@ -1036,6 +1072,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltGold @@ -1058,6 +1095,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltDiamond @@ -1080,6 +1118,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltPlasma @@ -1102,6 +1141,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltQuartz @@ -1124,6 +1164,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltSilver @@ -1146,6 +1187,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltTin @@ -1168,6 +1210,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltUranium @@ -1190,6 +1233,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity @@ -1213,6 +1257,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltArtifactFragment @@ -1235,6 +1280,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockBasaltSalt @@ -1257,6 +1303,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_wall_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Snow variants - type: entity @@ -1301,6 +1348,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowGold @@ -1323,6 +1371,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowDiamond @@ -1345,6 +1394,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowPlasma @@ -1367,6 +1417,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowQuartz @@ -1389,6 +1440,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowSilver @@ -1411,6 +1463,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowTin @@ -1433,6 +1486,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowUranium @@ -1455,6 +1509,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity @@ -1478,6 +1533,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowArtifactFragment @@ -1500,6 +1556,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSnowSalt @@ -1522,6 +1579,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_snow_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Sand variants - type: entity @@ -1566,6 +1624,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandGold @@ -1588,6 +1647,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandDiamond @@ -1610,6 +1670,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandPlasma @@ -1632,6 +1693,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandQuartz @@ -1654,6 +1716,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandSilver @@ -1676,6 +1739,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandTin @@ -1698,6 +1762,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandUranium @@ -1720,6 +1785,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandBananium @@ -1742,6 +1808,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandArtifactFragment @@ -1764,6 +1831,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockSandSalt @@ -1786,6 +1854,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_sand_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Chromite variants - type: entity @@ -1830,6 +1899,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteGold @@ -1852,6 +1922,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteDiamond @@ -1874,6 +1945,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromitePlasma @@ -1896,6 +1968,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteQuartz @@ -1918,6 +1991,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteSilver @@ -1940,6 +2014,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteTin @@ -1962,6 +2037,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteUranium @@ -1984,6 +2060,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity @@ -2007,6 +2084,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteArtifactFragment @@ -2029,6 +2107,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockChromiteSalt @@ -2051,6 +2130,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_chromite_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] # Andesite variants - type: entity @@ -2095,6 +2175,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_coal + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteGold @@ -2117,6 +2198,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_gold + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteDiamond @@ -2139,6 +2221,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_diamond + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesitePlasma @@ -2161,6 +2244,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_phoron + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteQuartz @@ -2183,6 +2267,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_quartz + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteSilver @@ -2205,6 +2290,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_silver + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteTin @@ -2227,6 +2313,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_tin + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteUranium @@ -2249,6 +2336,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_uranium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity @@ -2272,6 +2360,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_bananium + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteArtifactFragment @@ -2294,6 +2383,7 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_artifact_fragment + map: [ "enum.MiningScannerVisualLayers.Overlay" ] - type: entity id: WallRockAndesiteSalt @@ -2316,3 +2406,4 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_andesite_west - state: rock_salt + map: [ "enum.MiningScannerVisualLayers.Overlay" ] diff --git a/Resources/Prototypes/Recipes/Lathes/salvage.yml b/Resources/Prototypes/Recipes/Lathes/salvage.yml index 2def767e91..4600669cc5 100644 --- a/Resources/Prototypes/Recipes/Lathes/salvage.yml +++ b/Resources/Prototypes/Recipes/Lathes/salvage.yml @@ -1,3 +1,23 @@ +- type: latheRecipe + id: MineralScannerEmpty + result: MineralScannerEmpty + completetime: 3 + materials: + Steel: 1000 + Glass: 300 + Plastic: 300 + Gold: 500 + +- type: latheRecipe + id: AdvancedMineralScannerEmpty + result: AdvancedMineralScannerEmpty + completetime: 1 + materials: + Steel: 1000 + Glass: 300 + Plastic: 300 + Uranium: 500 + - type: latheRecipe id: Fulton result: Fulton1 diff --git a/Resources/Prototypes/Research/industrial.yml b/Resources/Prototypes/Research/industrial.yml index 8e11f661a8..1ee724ecdf 100644 --- a/Resources/Prototypes/Research/industrial.yml +++ b/Resources/Prototypes/Research/industrial.yml @@ -11,6 +11,7 @@ cost: 7500 recipeUnlocks: - MiningDrill + - MineralScannerEmpty - BorgModuleMining - BorgModuleGrapplingGun - OreProcessorIndustrialMachineCircuitboard @@ -179,6 +180,7 @@ recipeUnlocks: - OreBagOfHolding - MiningDrillDiamond + - AdvancedMineralScannerEmpty # Tier 3 diff --git a/Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/adv-o.png b/Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/adv-o.png new file mode 100644 index 0000000000000000000000000000000000000000..f33c745e6e007e7899bb40fa4307495259c30b6f GIT binary patch literal 595 zcmV-Z0<8UsP)EX>4Tx04R}tkv&MmKpe$i(@I5J94u7CAwzYtAS&XhRVYG*P%E_RU~=gfG-*gu zTpR`0f`cE6RRKlt6PRhXP;C4~||&x_-Hi~zx1pjmgE?_?Mp`AgZg2q3ksq@wtFB2VetO9K~R)N4dG9 hU=)mkQ7{VV1pue_9cu{``(pqA002ovPDHLkV1mL61qlEE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/adv.png b/Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/adv.png new file mode 100644 index 0000000000000000000000000000000000000000..85ff9509f0d7c02274f88a24ded00c3547d039a3 GIT binary patch literal 937 zcmV;a16KTrP)EX>4Tx04R}tkv&MmKpe$i(@I5J94u7CAwzYtAS&XhRVYG*P%E_RU~=gfG-*gu zTpR`0f`cE6RRKlt6PRhXP;C4~||&x_-Hi~zx1pjmgE?_1wIG}&f@Y#B~dnBtXi- z(uvgz&hiQH+;3nQroRHHZ2`b+He1VpiK%mzPZ)+Nr$2tbw@!f$SjA{G`r~*RW`SM< zz5pLeDJ!uaufkX0jXK~~>Ly;*iGS{ZQi^`R4^aE`8FKLz*zyIKUlNn!qodl~?%rO_ zkb3W5?<>$UFu!v^tJ{Witn;gRdvd~lDtPrqvj0F3eUKdAuP2I(XHzHZJz;*k1f#%~ zvzBzwVLbU}C600000 LNkvXXu0mjfyQsM} literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/icon-o.png b/Resources/Textures/Objects/Specific/Mining/mineral_scanner.rsi/icon-o.png new file mode 100644 index 0000000000000000000000000000000000000000..c1313c5140610641634ac816b76342a7030d245f GIT binary patch literal 572 zcmV-C0>k}@P)EX>4Tx04R}tkv&MmKpe$i(@I5J94u7CAwzYtAS&XhRVYG*P%E_RU~=gfG-*gu zTpR`0f`cE6RRKlt6PRhXP;C4~||&x_-Hi~zx1pjmgE?_EX>4Tx04R}tkv&MmKpe$i(@I5J94u7CAwzYtAS&XhRVYG*P%E_RU~=gfG-*gu zTpR`0f`cE6RRKlt6PRhXP;C4~||&x_-Hi~zx1pjmgE?_@-VLxuy_Vu~anfmSd=(!oL<%7vtfhC6iCvs`X)OuAZY(0jtIhR;-G82R1 z8}_S80RUjn7Qvit`^+MkNa5nNU=r-v0zcm?2<9VbX$O(<)bwMVdP4@3qioA?wkq{<^UD3Sr7nfwOa5j>>Z#8Cl416$J02F>NW({ zJG4AtI2goY6$tzfP)rYds6z(K_gJjnkTFFMmM7pYps;5Ps7hgd@gxZ}edJ3L;EEDp z`{