--- /dev/null
+using Content.Shared.Lathe;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Server.Lathe.Components;
+
+/// <summary>
+/// This is used for a <see cref="LatheComponent"/> that releases heat into the surroundings while producing items.
+/// </summary>
+[RegisterComponent]
+[Access(typeof(LatheSystem))]
+public sealed partial class LatheHeatProducingComponent : Component
+{
+ /// <summary>
+ /// The amount of energy produced each second when producing an item.
+ /// </summary>
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float EnergyPerSecond = 40000;
+
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
+ public TimeSpan NextSecond;
+}
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Administration.Logs;
-using Content.Server.Construction;
+using Content.Server.Atmos;
+using Content.Server.Atmos.EntitySystems;
using Content.Server.Lathe.Components;
using Content.Server.Materials;
using Content.Server.Power.Components;
using Content.Shared.Research.Prototypes;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
-using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UserInterfaceSystem _uiSys = default!;
[Dependency] private readonly MaterialStorageSystem _materialStorage = default!;
[Dependency] private readonly StackSystem _stack = default!;
- [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly TransformSystem _transform = default!;
+
+ /// <summary>
+ /// Per-tick cache
+ /// </summary>
+ private readonly List<GasMixture> _environments = new();
public override void Initialize()
{
SubscribeLocalEvent<LatheComponent, GetMaterialWhitelistEvent>(OnGetWhitelist);
SubscribeLocalEvent<LatheComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<LatheComponent, PowerChangedEvent>(OnPowerChanged);
- SubscribeLocalEvent<LatheComponent, RefreshPartsEvent>(OnPartsRefresh);
- SubscribeLocalEvent<LatheComponent, UpgradeExamineEvent>(OnUpgradeExamine);
SubscribeLocalEvent<LatheComponent, TechnologyDatabaseModifiedEvent>(OnDatabaseModified);
SubscribeLocalEvent<LatheComponent, ResearchRegistrationChangedEvent>(OnResearchRegistrationChanged);
SubscribeLocalEvent<LatheComponent, MaterialAmountChangedEvent>(OnMaterialAmountChanged);
SubscribeLocalEvent<TechnologyDatabaseComponent, LatheGetRecipesEvent>(OnGetRecipes);
SubscribeLocalEvent<EmagLatheRecipesComponent, LatheGetRecipesEvent>(GetEmagLatheRecipes);
+ SubscribeLocalEvent<LatheHeatProducingComponent, LatheStartPrintingEvent>(OnHeatStartPrinting);
SubscribeLocalEvent<LatheComponent, LatheEjectMaterialMessage>(OnLatheEjectMessage);
}
if (!lathe.CanEjectStoredMaterials)
return;
- if (!_prototypeManager.TryIndex<MaterialPrototype>(message.Material, out var material))
+ if (!_proto.TryIndex<MaterialPrototype>(message.Material, out var material))
return;
var volume = 0;
if (material.StackEntity != null)
{
- var entProto = _prototypeManager.Index<EntityPrototype>(material.StackEntity);
+ var entProto = _proto.Index<EntityPrototype>(material.StackEntity);
if (!entProto.TryGetComponent<PhysicalCompositionComponent>(out var composition))
return;
if (_timing.CurTime - comp.StartTime >= comp.ProductionLength)
FinishProducing(uid, lathe);
}
+
+ var heatQuery = EntityQueryEnumerator<LatheHeatProducingComponent, LatheProducingComponent, TransformComponent>();
+ while (heatQuery.MoveNext(out var uid, out var heatComp, out _, out var xform))
+ {
+ if (_timing.CurTime < heatComp.NextSecond)
+ continue;
+ heatComp.NextSecond += TimeSpan.FromSeconds(1);
+
+ var position = _transform.GetGridTilePositionOrDefault((uid,xform));
+ _environments.Clear();
+
+ if (_atmosphere.GetTileMixture(xform.GridUid, xform.MapUid, position, true) is { } tileMix)
+ _environments.Add(tileMix);
+
+ if (xform.GridUid != null)
+ {
+ _environments.AddRange(_atmosphere.GetAdjacentTileMixtures(xform.GridUid.Value, position, false, true));
+ }
+
+ if (_environments.Count > 0)
+ {
+ var heatPerTile = heatComp.EnergyPerSecond / _environments.Count;
+ foreach (var env in _environments)
+ {
+ _atmosphere.AddHeat(env, heatPerTile);
+ }
+ }
+ }
}
private void OnGetWhitelist(EntityUid uid, LatheComponent component, ref GetMaterialWhitelistEvent args)
lathe.ProductionLength = recipe.CompleteTime * component.TimeMultiplier;
component.CurrentRecipe = recipe;
+ var ev = new LatheStartPrintingEvent(recipe);
+ RaiseLocalEvent(uid, ref ev);
+
_audio.PlayPvs(component.ProducingSound, uid);
UpdateRunningAppearance(uid, true);
UpdateUserInterfaceState(uid, component);
}
}
+ private void OnHeatStartPrinting(EntityUid uid, LatheHeatProducingComponent component, LatheStartPrintingEvent args)
+ {
+ component.NextSecond = _timing.CurTime;
+ }
+
private void OnMaterialAmountChanged(EntityUid uid, LatheComponent component, ref MaterialAmountChangedEvent args)
{
UpdateUserInterfaceState(uid, component);
}
}
- private void OnPartsRefresh(EntityUid uid, LatheComponent component, RefreshPartsEvent args)
- {
- var printTimeRating = args.PartRatings[component.MachinePartPrintSpeed];
- var materialUseRating = args.PartRatings[component.MachinePartMaterialUse];
-
- component.TimeMultiplier = MathF.Pow(component.PartRatingPrintTimeMultiplier, printTimeRating - 1);
- component.MaterialUseMultiplier = MathF.Pow(component.PartRatingMaterialUseMultiplier, materialUseRating - 1);
- Dirty(component);
- }
-
- private void OnUpgradeExamine(EntityUid uid, LatheComponent component, UpgradeExamineEvent args)
- {
- args.AddPercentageUpgrade("lathe-component-upgrade-speed", 1 / component.TimeMultiplier);
- args.AddPercentageUpgrade("lathe-component-upgrade-material-use", component.MaterialUseMultiplier);
- }
-
private void OnDatabaseModified(EntityUid uid, LatheComponent component, ref TechnologyDatabaseModifiedEvent args)
{
UpdateUserInterfaceState(uid, component);
/// <summary>
/// A modifier that changes how long it takes to print a recipe
/// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
public float TimeMultiplier = 1;
- /// <summary>
- /// The machine part that reduces how long it takes to print a recipe.
- /// </summary>
- [DataField]
- public ProtoId<MachinePartPrototype> MachinePartPrintSpeed = "Manipulator";
-
- /// <summary>
- /// The value that is used to calculate the modified <see cref="TimeMultiplier"/>
- /// </summary>
- [DataField]
- public float PartRatingPrintTimeMultiplier = 0.5f;
-
/// <summary>
/// A modifier that changes how much of a material is needed to print a recipe
/// </summary>
- [ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+ [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public float MaterialUseMultiplier = 1;
- /// <summary>
- /// The machine part that reduces how much material it takes to print a recipe.
- /// </summary>
- [DataField]
- public ProtoId<MachinePartPrototype> MachinePartMaterialUse = "MatterBin";
-
- /// <summary>
- /// The value that is used to calculate the modifier <see cref="MaterialUseMultiplier"/>
- /// </summary>
- [DataField]
- public float PartRatingMaterialUseMultiplier = DefaultPartRatingMaterialUseMultiplier;
-
public const float DefaultPartRatingMaterialUseMultiplier = 0.85f;
#endregion
}
Lathe = lathe;
}
}
+
+ /// <summary>
+ /// Event raised on a lathe when it starts producing a recipe.
+ /// </summary>
+ [ByRefEvent]
+ public readonly record struct LatheStartPrintingEvent(LatheRecipePrototype Recipe);
}
materialRequirements:
Glass: 1
+- type: entity
+ parent: BaseMachineCircuitboard
+ id: AutolatheHyperConvectionMachineCircuitboard
+ name: hyper convection autolathe machine board
+ description: A machine printed circuit board for a hyper convection autolathe
+ components:
+ - type: MachineBoard
+ prototype: AutolatheHyperConvection
+ requirements:
+ MatterBin: 3
+ materialRequirements:
+ Glass: 1
+ tagRequirements:
+ Igniter:
+ Amount: 1
+ DefaultPrototype: Igniter
+ ExamineName: Igniter
+
- type: entity
id: ProtolatheMachineCircuitboard
parent: BaseMachineCircuitboard
DefaultPrototype: Beaker
ExamineName: Glass Beaker
+- type: entity
+ parent: BaseMachineCircuitboard
+ id: ProtolatheHyperConvectionMachineCircuitboard
+ name: hyper convection protolathe machine board
+ description: A machine printed circuit board for a hyper convection protolathe.
+ components:
+ - type: MachineBoard
+ prototype: ProtolatheHyperConvection
+ requirements:
+ MatterBin: 2
+ tagRequirements:
+ GlassBeaker:
+ Amount: 2
+ DefaultPrototype: Beaker
+ ExamineName: Glass Beaker
+ Igniter:
+ Amount: 1
+ DefaultPrototype: Igniter
+ ExamineName: Igniter
+
- type: entity
id: SecurityTechFabCircuitboard
parent: BaseMachineCircuitboard
materialRequirements:
Glass: 1
+- type: entity
+ parent: BaseMachineCircuitboard
+ id: OreProcessorIndustrialMachineCircuitboard
+ name: industrial ore processor machine board
+ components:
+ - type: Sprite
+ state: supply
+ - type: MachineBoard
+ prototype: OreProcessorIndustrial
+ requirements:
+ MatterBin: 1
+ Manipulator: 3
+ materialRequirements:
+ Glass: 1
+
- type: entity
id: SheetifierMachineCircuitboard
parent: BaseMachineCircuitboard
- MagazineBoxLightRifleUranium
- MagazineBoxRifleUranium
+- type: entity
+ id: AutolatheHyperConvection
+ parent: Autolathe
+ name: hyper convection autolathe
+ description: A highly-experimental autolathe that harnesses the power of extreme heat to slowly create objects more cost-effectively.
+ components:
+ - type: Sprite
+ sprite: Structures/Machines/autolathe_hypercon.rsi
+ - type: Lathe
+ materialUseMultiplier: 0.70
+ timeMultiplier: 1.5
+ - type: LatheHeatProducing
+ - type: Machine
+ board: AutolatheHyperConvectionMachineCircuitboard
+
- type: entity
id: Protolathe
parent: BaseLathe
- WeaponLaserCannon
- WeaponXrayCannon
+- type: entity
+ id: ProtolatheHyperConvection
+ parent: Protolathe
+ name: hyper convection protolathe
+ description: A highly-experimental protolathe that harnesses the power of extreme heat to slowly create objects more cost-effectively.
+ components:
+ - type: Sprite
+ sprite: Structures/Machines/protolathe_hypercon.rsi
+ - type: Lathe
+ materialUseMultiplier: 0.70
+ timeMultiplier: 1.5
+ - type: LatheHeatProducing
+ - type: Machine
+ board: ProtolatheHyperConvectionMachineCircuitboard
+
- type: entity
id: CircuitImprinter
parent: BaseLathe
idleState: icon
runningState: building
staticRecipes:
+ - ProtolatheMachineCircuitboard
+ - AutolatheMachineCircuitboard
+ - CircuitImprinterMachineCircuitboard
+ - OreProcessorMachineCircuitboard
+ - MaterialReclaimerMachineCircuitboard
- ElectrolysisUnitMachineCircuitboard
- CentrifugeMachineCircuitboard
- CondenserMachineCircuitBoard
- SolarControlComputerCircuitboard
- SolarTrackerElectronics
- PowerComputerCircuitboard
- - AutolatheMachineCircuitboard
- - ProtolatheMachineCircuitboard
+ - AutolatheHyperConvectionMachineCircuitboard
+ - ProtolatheHyperConvectionMachineCircuitboard
- ReagentGrinderMachineCircuitboard
- HotplateMachineCircuitboard
- MicrowaveMachineCircuitboard
- UniformPrinterMachineCircuitboard
- ShuttleConsoleCircuitboard
- RadarConsoleCircuitboard
- - CircuitImprinterMachineCircuitboard
- TechDiskComputerCircuitboard
- DawInstrumentMachineCircuitboard
- CloningConsoleComputerCircuitboard
- StasisBedMachineCircuitboard
- - MaterialReclaimerMachineCircuitboard
- - OreProcessorMachineCircuitboard
+ - OreProcessorIndustrialMachineCircuitboard
- CargoTelepadMachineCircuitboard
- RipleyCentralElectronics
- RipleyPeripheralsElectronics
- IngotSilver30
- MaterialBananium10
+- type: entity
+ parent: OreProcessor
+ id: OreProcessorIndustrial
+ name: industrial ore processor
+ description: An ore processor specifically designed for mass-producing metals in industrial applications.
+ components:
+ - type: Sprite
+ sprite: Structures/Machines/ore_processor_industrial.rsi
+ - type: Machine
+ board: OreProcessorIndustrialMachineCircuitboard
+ - type: Lathe
+ materialUseMultiplier: 0.75
+ timeMultiplier: 0.5
+
- type: entity
parent: BaseLathe
id: Sheetifier
Steel: 100
Glass: 900
+- type: latheRecipe
+ id: AutolatheHyperConvectionMachineCircuitboard
+ result: AutolatheHyperConvectionMachineCircuitboard
+ completetime: 4
+ materials:
+ Steel: 100
+ Glass: 900
+ Gold: 100
+
+- type: latheRecipe
+ id: ProtolatheHyperConvectionMachineCircuitboard
+ result: ProtolatheHyperConvectionMachineCircuitboard
+ completetime: 4
+ materials:
+ Steel: 100
+ Glass: 900
+ Gold: 100
+
- type: latheRecipe
id: CircuitImprinterMachineCircuitboard
result: CircuitImprinterMachineCircuitboard
materials:
Steel: 100
Glass: 900
+
+- type: latheRecipe
+ id: OreProcessorIndustrialMachineCircuitboard
+ result: OreProcessorIndustrialMachineCircuitboard
+ completetime: 4
+ materials:
+ Steel: 100
+ Glass: 900
Gold: 100
- type: latheRecipe
recipeUnlocks:
- MiningDrill
- BorgModuleMining
- - OreProcessorMachineCircuitboard
+ - OreProcessorIndustrialMachineCircuitboard
- OreBagOfHolding
- type: technology
id: IndustrialEngineering
name: research-technology-industrial-engineering
icon:
- sprite: Structures/Machines/protolathe.rsi
- state: icon
+ sprite: Structures/Machines/protolathe_hypercon.rsi
+ state: building
discipline: Industrial
tier: 1
- cost: 7500
+ cost: 10000
recipeUnlocks:
- - ProtolatheMachineCircuitboard
- - AutolatheMachineCircuitboard
- - CircuitImprinterMachineCircuitboard
- - MaterialReclaimerMachineCircuitboard
+ - AutolatheHyperConvectionMachineCircuitboard
+ - ProtolatheHyperConvectionMachineCircuitboard
- SheetifierMachineCircuitboard
- type: technology
--- /dev/null
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Created by UbaserB (GitHub) for SS14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "panel"
+ },
+ {
+ "name": "unlit"
+ },
+ {
+ "name": "building",
+ "delays": [
+ [
+ 0.5,
+ 0.5,
+ 0.5,
+ 0.5,
+ 0.5,
+ 0.5,
+ 0.5,
+ 0.5,
+ 0.5
+ ]
+ ]
+ },
+ {
+ "name": "inserting",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ }
+ ]
+}
--- /dev/null
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Created by UbaserB (GitHub) for SS14, based on ore processor sprite from tgstation",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "inserting",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 5
+ ]
+ ]
+ },
+ {
+ "name": "building",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ },
+ {
+ "name": "icon"
+ },
+ {
+ "name": "panel"
+ },
+ {
+ "name": "unlit"
+ }
+ ]
+}
--- /dev/null
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Created by UbaserB (GitHub) for SS14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "panel"
+ },
+ {
+ "name": "unlit"
+ },
+ {
+ "name": "building",
+ "delays": [
+ [
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0
+ ]
+ ]
+ },
+ {
+ "name": "inserting",
+ "delays": [
+ [
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1,
+ 0.1
+ ]
+ ]
+ }
+ ]
+}