mindustry logic execution, map- and schematic- parsing and rendering
Implement build cost for BlockLogic
| -rw-r--r-- | src/block/base.rs | 50 | ||||
| -rw-r--r-- | src/block/defense.rs | 60 | ||||
| -rw-r--r-- | src/block/extraction.rs | 16 | ||||
| -rw-r--r-- | src/block/factory.rs | 40 | ||||
| -rw-r--r-- | src/block/fluid.rs | 50 | ||||
| -rw-r--r-- | src/block/logic.rs | 116 | ||||
| -rw-r--r-- | src/block/mod.rs | 3 | ||||
| -rw-r--r-- | src/block/payload.rs | 69 | ||||
| -rw-r--r-- | src/block/power.rs | 61 | ||||
| -rw-r--r-- | src/block/simple.rs | 32 | ||||
| -rw-r--r-- | src/block/transport.rs | 73 | ||||
| -rw-r--r-- | src/block/turret.rs | 38 |
12 files changed, 426 insertions, 182 deletions
diff --git a/src/block/base.rs b/src/block/base.rs index 4c849cf..33b4ae8 100644 --- a/src/block/base.rs +++ b/src/block/base.rs @@ -1,27 +1,28 @@ use std::any::Any; use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::block::transport::ItemBlock; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; +use crate::item::storage::Storage; make_register! ( - MENDER: "mender" => SimpleBlock::new(1, true); - MEND_PROJECTOR: "mend-projector" => SimpleBlock::new(2, true); - OVERDRIVE_PROJECTOR: "overdrive-projector" => SimpleBlock::new(2, true); - OVERDRIVE_DOME: "overdrive-dome" => SimpleBlock::new(3, true); - FORCE_PROJECTOR: "force-projector" => SimpleBlock::new(3, true); - SHOCK_MINE: "shock-mine" => SimpleBlock::new(1, true); - CORE_SHARD: "core-shard" => SimpleBlock::new(3, true); - CORE_FOUNDATION: "core-foundation" => SimpleBlock::new(4, true); - CORE_NUCLEUS: "core-nucleus" => SimpleBlock::new(5, true); - CONTAINER: "container" => SimpleBlock::new(2, true); - VAULT: "vault" => SimpleBlock::new(3, true); - UNLOADER: "unloader" => ItemBlock::new(1, true); - ILLUMINATOR: "illuminator" => LampBlock::new(1, true); - LAUNCH_PAD: "launch-pad" => SimpleBlock::new(3, true); + MENDER: "mender" => SimpleBlock::new(1, true, cost!(Copper: 25, Lead: 30)); + MEND_PROJECTOR: "mend-projector" => SimpleBlock::new(2, true, cost!(Copper: 50, Lead: 100, Titanium: 25, Silicon: 40)); + OVERDRIVE_PROJECTOR: "overdrive-projector" => SimpleBlock::new(2, true, cost!(Lead: 100, Titanium: 75, Silicon: 75, Plastanium: 30)); + OVERDRIVE_DOME: "overdrive-dome" => SimpleBlock::new(3, true, cost!(Lead: 200, Titanium: 130, Silicon: 130, Plastanium: 80, SurgeAlloy: 120)); + FORCE_PROJECTOR: "force-projector" => SimpleBlock::new(3, true, cost!(Lead: 100, Titanium: 75, Silicon: 125)); + SHOCK_MINE: "shock-mine" => SimpleBlock::new(1, true, cost!(Lead: 25, Silicon: 12)); + CORE_SHARD: "core-shard" => SimpleBlock::new(3, true, cost!(Copper: 1000, Lead: 800)); + CORE_FOUNDATION: "core-foundation" => SimpleBlock::new(4, true, cost!(Copper: 3000, Lead: 3000, Silicon: 2000)); + CORE_NUCLEUS: "core-nucleus" => SimpleBlock::new(5, true, cost!(Copper: 8000, Lead: 8000, Thorium: 4000, Silicon: 5000)); + CONTAINER: "container" => SimpleBlock::new(2, true, cost!(Titanium: 100)); + VAULT: "vault" => SimpleBlock::new(3, true, cost!(Titanium: 250, Thorium: 125)); + UNLOADER: "unloader" => ItemBlock::new(1, true, cost!(Titanium: 25, Silicon: 30)); + ILLUMINATOR: "illuminator" => LampBlock::new(1, true, cost!(Lead: 8, Graphite: 12, Silicon: 8)); + LAUNCH_PAD: "launch-pad" => SimpleBlock::new(3, true, cost!(Copper: 350, Lead: 200, Titanium: 150, Silicon: 140)); ); #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -47,17 +48,18 @@ pub struct LampBlock { size: u8, symmetric: bool, + build_cost: BuildCost, } impl LampBlock { - pub const fn new(size: u8, symmetric: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self { if size == 0 { panic!("invalid size"); } - Self{size, symmetric} + Self{size, symmetric, build_cost} } state_impl!(pub RGBA); @@ -75,6 +77,20 @@ impl BlockLogic for LampBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, config: i32, _: GridPos) -> Result<DynData, DataConvertError> { Ok(DynData::Int(config)) diff --git a/src/block/defense.rs b/src/block/defense.rs index c31ba46..dd1f926 100644 --- a/src/block/defense.rs +++ b/src/block/defense.rs @@ -1,49 +1,51 @@ use std::any::Any; use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; +use crate::item::storage::Storage; make_register! ( - COPPER_WALL: "copper-wall" => SimpleBlock::new(1, true); - COPPER_WALL_LARGE: "copper-wall-large" => SimpleBlock::new(2, true); - TITANIUM_WALL: "titanium-wall" => SimpleBlock::new(1, true); - TITANIUM_WALL_LARGE: "titanium-wall-large" => SimpleBlock::new(2, true); - PLASTANIUM_WALL: "plastanium-wall" => SimpleBlock::new(1, true); - PLASTANIUM_WALL_LARGE: "plastanium-wall-large" => SimpleBlock::new(2, true); - THORIUM_WALL: "thorium-wall" => SimpleBlock::new(1, true); - THORIUM_WALL_LARGE: "thorium-wall-large" => SimpleBlock::new(2, true); - PHASE_WALL: "phase-wall" => SimpleBlock::new(1, true); - PHASE_WALL_LARGE: "phase-wall-large" => SimpleBlock::new(2, true); - SURGE_WALL: "surge-wall" => SimpleBlock::new(1, true); - SURGE_WALL_LARGE: "surge-wall-large" => SimpleBlock::new(2, true); - DOOR: "door" => DoorBlock::new(1, true); - DOOR_LARGE: "door-large" => DoorBlock::new(2, true); + COPPER_WALL: "copper-wall" => SimpleBlock::new(1, true, cost!(Copper: 6)); + COPPER_WALL_LARGE: "copper-wall-large" => SimpleBlock::new(2, true, cost!(Copper: 24)); + TITANIUM_WALL: "titanium-wall" => SimpleBlock::new(1, true, cost!(Titanium: 6)); + TITANIUM_WALL_LARGE: "titanium-wall-large" => SimpleBlock::new(2, true, cost!(Titanium: 24)); + PLASTANIUM_WALL: "plastanium-wall" => SimpleBlock::new(1, true, cost!(Metaglass: 2, Plastanium: 5)); + PLASTANIUM_WALL_LARGE: "plastanium-wall-large" => SimpleBlock::new(2, true, cost!(Metaglass: 8, Plastanium: 20)); + THORIUM_WALL: "thorium-wall" => SimpleBlock::new(1, true, cost!(Thorium: 6)); + THORIUM_WALL_LARGE: "thorium-wall-large" => SimpleBlock::new(2, true, cost!(Thorium: 24)); + PHASE_WALL: "phase-wall" => SimpleBlock::new(1, true, cost!(PhaseFabric: 6)); + PHASE_WALL_LARGE: "phase-wall-large" => SimpleBlock::new(2, true, cost!(PhaseFabric: 24)); + SURGE_WALL: "surge-wall" => SimpleBlock::new(1, true, cost!(SurgeAlloy: 6)); + SURGE_WALL_LARGE: "surge-wall-large" => SimpleBlock::new(2, true, cost!(SurgeAlloy: 24)); + DOOR: "door" => DoorBlock::new(1, true, cost!(Titanium: 6, Silicon: 4)); + DOOR_LARGE: "door-large" => DoorBlock::new(2, true, cost!(Titanium: 24, Silicon: 16)); // sandbox only - SCRAP_WALL: "scrap-wall" => SimpleBlock::new(1, true); - SCRAP_WALL_LARGE: "scrap-wall-large" => SimpleBlock::new(2, true); - SCRAP_WALL_HUGE: "scrap-wall-huge" => SimpleBlock::new(3, true); - SCRAP_WALL_GIGANTIC: "scrap-wall-gigantic" => SimpleBlock::new(4, true); - THRUSTER: "thruster" => SimpleBlock::new(4, false); + SCRAP_WALL: "scrap-wall" => SimpleBlock::new(1, true, cost!(Scrap: 6)); + SCRAP_WALL_LARGE: "scrap-wall-large" => SimpleBlock::new(2, true, cost!(Scrap: 24)); + SCRAP_WALL_HUGE: "scrap-wall-huge" => SimpleBlock::new(3, true, cost!(Scrap: 54)); + SCRAP_WALL_GIGANTIC: "scrap-wall-gigantic" => SimpleBlock::new(4, true, cost!(Scrap: 96)); + THRUSTER: "thruster" => SimpleBlock::new(4, false, cost!(Scrap: 96)); ); pub struct DoorBlock { size: u8, symmetric: bool, + build_cost: BuildCost, } impl DoorBlock { - pub const fn new(size: u8, symmetric: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self { if size == 0 { panic!("invalid size"); } - Self{size, symmetric} + Self{size, symmetric, build_cost} } state_impl!(pub bool); @@ -61,6 +63,20 @@ impl BlockLogic for DoorBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> { Ok(DynData::Boolean(false)) diff --git a/src/block/extraction.rs b/src/block/extraction.rs index 3e50701..b036081 100644 --- a/src/block/extraction.rs +++ b/src/block/extraction.rs @@ -1,13 +1,13 @@ use crate::block::make_register; -use crate::block::simple::SimpleBlock; +use crate::block::simple::{cost, SimpleBlock}; make_register! ( - MECHANICAL_DRILL: "mechanical-drill" => SimpleBlock::new(2, true); - PNEUMATIC_DRILL: "pneumatic-drill" => SimpleBlock::new(2, true); - LASER_DRILL: "laser-drill" => SimpleBlock::new(3, true); - BLAST_DRILL: "blast-drill" => SimpleBlock::new(4, true); - WATER_EXTRACTOR: "water-extractor" => SimpleBlock::new(2, true); - CULTIVATOR: "cultivator" => SimpleBlock::new(2, true); - OIL_EXTRACTOR: "oil-extractor" => SimpleBlock::new(3, true); + MECHANICAL_DRILL: "mechanical-drill" => SimpleBlock::new(2, true, cost!(Copper: 12)); + PNEUMATIC_DRILL: "pneumatic-drill" => SimpleBlock::new(2, true, cost!(Copper: 18, Graphite: 10)); + LASER_DRILL: "laser-drill" => SimpleBlock::new(3, true, cost!(Copper: 35, Graphite: 30, Titanium: 20, Silicon: 30)); + BLAST_DRILL: "blast-drill" => SimpleBlock::new(4, true, cost!(Copper: 65, Titanium: 50, Thorium: 75, Silicon: 60)); + WATER_EXTRACTOR: "water-extractor" => SimpleBlock::new(2, true, cost!(Copper: 30, Lead: 30, Metaglass: 30, Graphite: 30)); + CULTIVATOR: "cultivator" => SimpleBlock::new(2, true, cost!(Copper: 25, Lead: 25, Silicon: 10)); + OIL_EXTRACTOR: "oil-extractor" => SimpleBlock::new(3, true, cost!(Copper: 150, Lead: 115, Graphite: 175, Thorium: 115, Silicon: 75)); ); diff --git a/src/block/factory.rs b/src/block/factory.rs index 790d52f..9374140 100644 --- a/src/block/factory.rs +++ b/src/block/factory.rs @@ -1,26 +1,26 @@ use crate::block::make_register; -use crate::block::simple::SimpleBlock; +use crate::block::simple::{cost, SimpleBlock}; make_register! ( - GRAPHITE_PRESS: "graphite-press" => SimpleBlock::new(2, true); - MULTI_PRESS: "multi-press" => SimpleBlock::new(3, true); - SILICON_SMELTER: "silicon-smelter" => SimpleBlock::new(2, true); - SILICON_CRUCIBLE: "silicon-crucible" => SimpleBlock::new(3, true); - KILN: "kiln" => SimpleBlock::new(2, true); - PLASTANIUM_COMPRESSOR: "plastanium-compressor" => SimpleBlock::new(2, true); - PHASE_WEAVER: "phase-weaver" => SimpleBlock::new(2, true); - SURGE_SMELTER: "surge-smelter" => SimpleBlock::new(3, true); - CRYOFLUID_MIXER: "cryofluid-mixer" => SimpleBlock::new(2, true); - PYRATITE_MIXER: "pyratite-mixer" => SimpleBlock::new(2, true); - BLAST_MIXER: "blast-mixer" => SimpleBlock::new(2, true); - MELTER: "melter" => SimpleBlock::new(1, true); - SEPARATOR: "separator" => SimpleBlock::new(2, true); - DISASSEMBLER: "disassembler" => SimpleBlock::new(3, true); - SPORE_PRESS: "spore-press" => SimpleBlock::new(2, true); - PULVERIZER: "pulverizer" => SimpleBlock::new(1, true); - COAL_CENTRIFUGE: "coal-centrifuge" => SimpleBlock::new(2, true); - INCINERATOR: "incinerator" => SimpleBlock::new(1, true); + GRAPHITE_PRESS: "graphite-press" => SimpleBlock::new(2, true, cost!(Copper: 75, Lead: 30)); + MULTI_PRESS: "multi-press" => SimpleBlock::new(3, true, cost!(Lead: 100, Graphite: 50, Titanium: 100, Silicon: 25)); + SILICON_SMELTER: "silicon-smelter" => SimpleBlock::new(2, true, cost!(Copper: 30, Lead: 25)); + SILICON_CRUCIBLE: "silicon-crucible" => SimpleBlock::new(3, true, cost!(Metaglass: 80, Titanium: 120, Silicon: 60, Plastanium: 35)); + KILN: "kiln" => SimpleBlock::new(2, true, cost!(Copper: 60, Lead: 30, Graphite: 30)); + PLASTANIUM_COMPRESSOR: "plastanium-compressor" => SimpleBlock::new(2, true, cost!(Lead: 115, Graphite: 60, Titanium: 80, Silicon: 80)); + PHASE_WEAVER: "phase-weaver" => SimpleBlock::new(2, true, cost!(Lead: 120, Thorium: 75, Silicon: 130)); + SURGE_SMELTER: "surge-smelter" => SimpleBlock::new(3, true, cost!(Lead: 80, Thorium: 70, Silicon: 80)); + CRYOFLUID_MIXER: "cryofluid-mixer" => SimpleBlock::new(2, true, cost!(Lead: 65, Thorium: 60, Silicon: 40)); + PYRATITE_MIXER: "pyratite-mixer" => SimpleBlock::new(2, true, cost!(Copper: 50, Lead: 25)); + BLAST_MIXER: "blast-mixer" => SimpleBlock::new(2, true, cost!(Lead: 30, Thorium: 20)); + MELTER: "melter" => SimpleBlock::new(1, true, cost!(Copper: 30, Lead: 35, Graphite: 45)); + SEPARATOR: "separator" => SimpleBlock::new(2, true, cost!(Copper: 30, Titanium: 25)); + DISASSEMBLER: "disassembler" => SimpleBlock::new(3, true, cost!(Titanium: 100, Thorium: 80, Silicon: 150, Plastanium: 40)); + SPORE_PRESS: "spore-press" => SimpleBlock::new(2, true, cost!(Lead: 35, Silicon: 30)); + PULVERIZER: "pulverizer" => SimpleBlock::new(1, true, cost!(Copper: 30, Lead: 25)); + COAL_CENTRIFUGE: "coal-centrifuge" => SimpleBlock::new(2, true, cost!(Lead: 30, Graphite: 40, Titanium: 20)); + INCINERATOR: "incinerator" => SimpleBlock::new(1, true, cost!(Lead: 15, Graphite: 5)); // sandbox only - HEAT_SOURCE: "heat-source" => SimpleBlock::new(1, false); + HEAT_SOURCE: "heat-source" => SimpleBlock::new(1, false, &[]); ); diff --git a/src/block/fluid.rs b/src/block/fluid.rs index 6174eee..a9f1349 100644 --- a/src/block/fluid.rs +++ b/src/block/fluid.rs @@ -3,47 +3,49 @@ use std::error::Error; use std::fmt; use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::block::transport::BridgeBlock; use crate::content; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; use crate::fluid; +use crate::item::storage::Storage; make_register! ( - MECHANICAL_PUMP: "mechanical-pump" => SimpleBlock::new(1, true); - ROTARY_PUMP: "rotary-pump" => SimpleBlock::new(2, true); - IMPULSE_PUMP: "impulse-pump" => SimpleBlock::new(3, true); - CONDUIT: "conduit" => SimpleBlock::new(1, false); - PULSE_CONDUIT: "pulse-conduit" => SimpleBlock::new(1, false); - PLATED_CONDUIT: "plated-conduit" => SimpleBlock::new(1, false); - LIQUID_ROUTER: "liquid-router" => SimpleBlock::new(1, true); - LIQUID_CONTAINER: "liquid-container" => SimpleBlock::new(2, true); - LIQUID_TANK: "liquid-tank" => SimpleBlock::new(3, true); - LIQUID_JUNCTION: "liquid-junction" => SimpleBlock::new(1, true); - BRIDGE_CONDUIT: "bridge-conduit" => BridgeBlock::new(1, true, 4, true); - PHASE_CONDUIT: "phase-conduit" => BridgeBlock::new(1, true, 12, true); + MECHANICAL_PUMP: "mechanical-pump" => SimpleBlock::new(1, true, cost!(Copper: 15, Metaglass: 10)); + ROTARY_PUMP: "rotary-pump" => SimpleBlock::new(2, true, cost!(Copper: 70, Metaglass: 50, Titanium: 35, Silicon: 20)); + IMPULSE_PUMP: "impulse-pump" => SimpleBlock::new(3, true, cost!(Copper: 80, Metaglass: 90, Titanium: 40, Thorium: 35, Silicon: 30)); + CONDUIT: "conduit" => SimpleBlock::new(1, false, cost!(Metaglass: 1)); + PULSE_CONDUIT: "pulse-conduit" => SimpleBlock::new(1, false, cost!(Metaglass: 1, Titanium: 2)); + PLATED_CONDUIT: "plated-conduit" => SimpleBlock::new(1, false, cost!(Metaglass: 1, Thorium: 2, Plastanium: 1)); + LIQUID_ROUTER: "liquid-router" => SimpleBlock::new(1, true, cost!(Metaglass: 2, Graphite: 4)); + LIQUID_CONTAINER: "liquid-container" => SimpleBlock::new(2, true, cost!(Metaglass: 15, Titanium: 10)); + LIQUID_TANK: "liquid-tank" => SimpleBlock::new(3, true, cost!(Metaglass: 40, Titanium: 30)); + LIQUID_JUNCTION: "liquid-junction" => SimpleBlock::new(1, true, cost!(Metaglass: 8, Graphite: 4)); + BRIDGE_CONDUIT: "bridge-conduit" => BridgeBlock::new(1, true, cost!(Metaglass: 8, Graphite: 4), 4, true); + PHASE_CONDUIT: "phase-conduit" => BridgeBlock::new(1, true, cost!(Metaglass: 20, Titanium: 10, Silicon: 7, PhaseFabric: 5), 12, true); // sandbox only - LIQUID_SOURCE: "liquid-source" => FluidBlock::new(1, true); - LIQUID_VOID: "liquid-void" => SimpleBlock::new(1, true); + LIQUID_SOURCE: "liquid-source" => FluidBlock::new(1, true, &[]); + LIQUID_VOID: "liquid-void" => SimpleBlock::new(1, true, &[]); ); pub struct FluidBlock { size: u8, symmetric: bool, + build_cost: BuildCost, } impl FluidBlock { - pub const fn new(size: u8, symmetric: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self { if size == 0 { panic!("invalid size"); } - Self{size, symmetric} + Self{size, symmetric, build_cost} } state_impl!(pub Option<fluid::Type>); @@ -61,6 +63,20 @@ impl BlockLogic for FluidBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, config: i32, _: GridPos) -> Result<DynData, DataConvertError> { if config < 0 || config > u16::MAX as i32 diff --git a/src/block/logic.rs b/src/block/logic.rs index fa77f7d..9e13e5c 100644 --- a/src/block/logic.rs +++ b/src/block/logic.rs @@ -7,27 +7,42 @@ use std::string::FromUtf8Error; use flate2::{Compress, CompressError, Compression, Decompress, DecompressError, FlushCompress, FlushDecompress, Status}; use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::data::{self, DataRead, DataWrite, GridPos}; use crate::data::dynamic::{DynData, DynType}; +use crate::item::storage::Storage; make_register! ( - MESSAGE: "message" => MessageLogic; - SWITCH: "switch" => SwitchLogic; - MICRO_PROCESSOR: "micro-processor" => ProcessorLogic{size: 1}; - LOGIC_PROCESSOR: "logic-processor" => ProcessorLogic{size: 2}; - HYPER_PROCESSOR: "hyper-processor" => ProcessorLogic{size: 3}; - MEMORY_CELL: "memory-cell" => SimpleBlock::new(1, true); - MEMORY_BANK: "memory-bank" => SimpleBlock::new(2, true); - LOGIC_DISPLAY: "logic-display" => SimpleBlock::new(3, true); - LARGE_LOGIC_DISPLAY: "large-logic-display" => SimpleBlock::new(6, true); + MESSAGE: "message" => MessageLogic::new(1, true, cost!(Copper: 5, Graphite: 5)); + SWITCH: "switch" => SwitchLogic::new(1, true, cost!(Copper: 5, Graphite: 5)); + MICRO_PROCESSOR: "micro-processor" => ProcessorLogic::new(1, true, cost!(Copper: 90, Lead: 50, Silicon: 50)); + LOGIC_PROCESSOR: "logic-processor" => ProcessorLogic::new(2, true, cost!(Lead: 320, Graphite: 60, Thorium: 50, Silicon: 80)); + HYPER_PROCESSOR: "hyper-processor" => ProcessorLogic::new(3, true, cost!(Lead: 450, Thorium: 75, Silicon: 150, SurgeAlloy: 50)); + MEMORY_CELL: "memory-cell" => SimpleBlock::new(1, true, cost!(Copper: 30, Graphite: 30, Silicon: 30)); + MEMORY_BANK: "memory-bank" => SimpleBlock::new(2, true, cost!(Copper: 30, Graphite: 80, Silicon: 80, PhaseFabric: 30)); + LOGIC_DISPLAY: "logic-display" => SimpleBlock::new(3, true, cost!(Lead: 100, Metaglass: 50, Silicon: 50)); + LARGE_LOGIC_DISPLAY: "large-logic-display" => SimpleBlock::new(6, true, cost!(Lead: 200, Metaglass: 100, Silicon: 150, PhaseFabric: 75)); ); -pub struct MessageLogic; +pub struct MessageLogic +{ + size: u8, + symmetric: bool, + build_cost: BuildCost, +} impl MessageLogic { + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self + { + if size == 0 + { + panic!("invalid size"); + } + Self{size, symmetric, build_cost} + } + state_impl!(pub String); } @@ -35,12 +50,26 @@ impl BlockLogic for MessageLogic { fn get_size(&self) -> u8 { - 1 + self.size } fn is_symmetric(&self) -> bool { - true + self.symmetric + } + + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} } fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> @@ -69,10 +98,24 @@ impl BlockLogic for MessageLogic } } -pub struct SwitchLogic; +pub struct SwitchLogic +{ + size: u8, + symmetric: bool, + build_cost: BuildCost, +} impl SwitchLogic { + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self + { + if size == 0 + { + panic!("invalid size"); + } + Self{size, symmetric, build_cost} + } + state_impl!(pub bool); } @@ -80,12 +123,26 @@ impl BlockLogic for SwitchLogic { fn get_size(&self) -> u8 { - 1 + self.size } fn is_symmetric(&self) -> bool { - true + self.symmetric + } + + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} } fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> @@ -117,10 +174,21 @@ impl BlockLogic for SwitchLogic pub struct ProcessorLogic { size: u8, + symmetric: bool, + build_cost: BuildCost, } impl ProcessorLogic { + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self + { + if size == 0 + { + panic!("invalid size"); + } + Self{size, symmetric, build_cost} + } + state_impl!(pub ProcessorState); } @@ -133,7 +201,21 @@ impl BlockLogic for ProcessorLogic fn is_symmetric(&self) -> bool { - true + self.symmetric + } + + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} } fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> diff --git a/src/block/mod.rs b/src/block/mod.rs index 9e81442..69ff37c 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -6,6 +6,7 @@ use std::fmt; use crate::access::BoxAccess; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; +use crate::item::storage::Storage as ItemStorage; use crate::registry::RegistryEntry; pub mod base; @@ -27,6 +28,8 @@ pub trait BlockLogic fn is_symmetric(&self) -> bool; + fn create_build_cost(&self) -> Option<ItemStorage>; + fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError>; fn deserialize_state(&self, data: DynData) -> Result<Option<Box<dyn Any>>, DeserializeError>; diff --git a/src/block/payload.rs b/src/block/payload.rs index f543ca6..e302770 100644 --- a/src/block/payload.rs +++ b/src/block/payload.rs @@ -3,10 +3,11 @@ use std::error::Error; use std::fmt; use crate::block::{self, BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::content; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; +use crate::item::storage::Storage; use crate::unit; const GROUND_UNITS: &[unit::Type] = &[unit::Type::Dagger, unit::Type::Crawler, unit::Type::Nova]; @@ -15,32 +16,35 @@ const NAVAL_UNITS: &[unit::Type] = &[unit::Type::Risso, unit::Type::Retusa]; make_register! ( - GROUND_FACTORY: "ground-factory" => AssemblerBlock::new(3, false, GROUND_UNITS); - AIR_FACTORY: "air-factory" => AssemblerBlock::new(3, false, AIR_UNITS); - NAVAL_FACTORY: "naval-factory" => AssemblerBlock::new(3, false, NAVAL_UNITS); - ADDITIVE_RECONSTRUCTOR: "additive-reconstructor" => SimpleBlock::new(3, false); - MULTIPLICATIVE_RECONSTRUCTOR: "multiplicative-reconstructor" => SimpleBlock::new(5, false); - EXPONENTIAL_RECONSTRUCTOR: "exponential-reconstructor" => SimpleBlock::new(7, false); - TETRATIVE_RECONSTRUCTOR: "tetrative-reconstructor" => SimpleBlock::new(9, false); - REPAIR_POINT: "repair-point" => SimpleBlock::new(1, true); - REPAIR_TURRET: "repair-turret" => SimpleBlock::new(2, true); - PAYLOAD_CONVEYOR: "payload-conveyor" => SimpleBlock::new(3, false); - PAYLOAD_ROUTER: "payload-router" => SimpleBlock::new(3, false); + GROUND_FACTORY: "ground-factory" => AssemblerBlock::new(3, false, cost!(Copper: 50, Lead: 120, Silicon: 80), GROUND_UNITS); + AIR_FACTORY: "air-factory" => AssemblerBlock::new(3, false, cost!(Copper: 60, Lead: 70), AIR_UNITS); + NAVAL_FACTORY: "naval-factory" => AssemblerBlock::new(3, false, cost!(Copper: 150, Lead: 130, Metaglass: 120), NAVAL_UNITS); + ADDITIVE_RECONSTRUCTOR: "additive-reconstructor" => SimpleBlock::new(3, false, cost!(Copper: 200, Lead: 120, Silicon: 90)); + MULTIPLICATIVE_RECONSTRUCTOR: "multiplicative-reconstructor" => SimpleBlock::new(5, false, cost!(Lead: 650, Titanium: 350, Thorium: 650, Silicon: 450)); + EXPONENTIAL_RECONSTRUCTOR: "exponential-reconstructor" => SimpleBlock::new(7, false, + cost!(Lead: 2000, Titanium: 2000, Thorium: 750, Silicon: 1000, Plastanium: 450, PhaseFabric: 600)); + TETRATIVE_RECONSTRUCTOR: "tetrative-reconstructor" => SimpleBlock::new(9, false, + cost!(Lead: 4000, Thorium: 1000, Silicon: 3000, Plastanium: 600, PhaseFabric: 600, SurgeAlloy: 800)); + REPAIR_POINT: "repair-point" => SimpleBlock::new(1, true, cost!(Copper: 30, Lead: 30, Silicon: 20)); + REPAIR_TURRET: "repair-turret" => SimpleBlock::new(2, true, cost!(Thorium: 80, Silicon: 90, Plastanium: 60)); + PAYLOAD_CONVEYOR: "payload-conveyor" => SimpleBlock::new(3, false, cost!(Copper: 10, Graphite: 10)); + PAYLOAD_ROUTER: "payload-router" => SimpleBlock::new(3, false, cost!(Copper: 10, Graphite: 15)); // sandbox only - PAYLOAD_SOURCE: "payload-source" => PayloadBlock::new(5, false); - PAYLOAD_VOID: "payload-void" => SimpleBlock::new(5, true); + PAYLOAD_SOURCE: "payload-source" => PayloadBlock::new(5, false, &[]); + PAYLOAD_VOID: "payload-void" => SimpleBlock::new(5, true, &[]); ); pub struct AssemblerBlock { size: u8, symmetric: bool, + build_cost: BuildCost, valid: &'static [unit::Type], } impl AssemblerBlock { - pub const fn new(size: u8, symmetric: bool, valid: &'static [unit::Type]) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost, valid: &'static [unit::Type]) -> Self { if size == 0 { @@ -54,7 +58,7 @@ impl AssemblerBlock { panic!("too many valid units"); } - Self{size, symmetric, valid} + Self{size, symmetric, build_cost, valid} } state_impl!(pub Option<unit::Type>); @@ -72,6 +76,20 @@ impl BlockLogic for AssemblerBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> { Ok(DynData::Int(-1)) @@ -169,17 +187,18 @@ pub struct PayloadBlock { size: u8, symmetric: bool, + build_cost: BuildCost, } impl PayloadBlock { - pub const fn new(size: u8, symmetric: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self { if size == 0 { panic!("invalid size"); } - Self{size, symmetric} + Self{size, symmetric, build_cost} } state_impl!(pub Payload); @@ -197,6 +216,20 @@ impl BlockLogic for PayloadBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> { Ok(DynData::Empty) diff --git a/src/block/power.rs b/src/block/power.rs index 5996d87..55a51da 100644 --- a/src/block/power.rs +++ b/src/block/power.rs @@ -3,40 +3,45 @@ use std::error::Error; use std::fmt; use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; +use crate::item::storage::Storage; make_register! ( - POWER_NODE: "power-node" => ConnectorBlock::new(1, 10); - POWER_NODE_LARGE: "power-node-large" => ConnectorBlock::new(2, 15); - SURGE_TOWER: "surge-tower" => ConnectorBlock::new(2, 2); - DIODE: "diode" => SimpleBlock::new(1, false); - BATTERY: "battery" => SimpleBlock::new(1, true); - BATTERY_LARGE: "battery-large" => SimpleBlock::new(3, true); - COMBUSTION_GENERATOR: "combustion-generator" => SimpleBlock::new(1, true); - THERMAL_GENERATOR: "thermal-generator" => SimpleBlock::new(2, true); - STEAM_GENERATOR: "steam-generator" => SimpleBlock::new(2, true); - DIFFERENTIAL_GENERATOR: "differential-generator" => SimpleBlock::new(3, true); - RTG_GENERATOR: "rtg-generator" => SimpleBlock::new(2, true); - SOLAR_PANEL: "solar-panel" => SimpleBlock::new(1, true); - SOLAR_PANEL_LARGE: "solar-panel-large" => SimpleBlock::new(3, true); - THORIUM_REACTOR: "thorium-reactor" => SimpleBlock::new(3, true); - IMPACT_REACTOR: "impact-reactor" => SimpleBlock::new(4, true); - POWER_SOURCE: "power-source" => ConnectorBlock::new(1, 100); - POWER_VOID: "power-void" => SimpleBlock::new(1, true); + POWER_NODE: "power-node" => ConnectorBlock::new(1, true, cost!(Copper: 1, Lead: 3), 10); + POWER_NODE_LARGE: "power-node-large" => ConnectorBlock::new(2, true, cost!(Lead: 10, Titanium: 5, Silicon: 3), 15); + SURGE_TOWER: "surge-tower" => ConnectorBlock::new(2, true, cost!(Lead: 10, Titanium: 7, Silicon: 15, SurgeAlloy: 15), 2); + DIODE: "diode" => SimpleBlock::new(1, false, cost!(Metaglass: 10, Silicon: 10, Plastanium: 5)); + BATTERY: "battery" => SimpleBlock::new(1, true, cost!(Copper: 5, Lead: 20)); + BATTERY_LARGE: "battery-large" => SimpleBlock::new(3, true, cost!(Lead: 50, Titanium: 20, Silicon: 30)); + COMBUSTION_GENERATOR: "combustion-generator" => SimpleBlock::new(1, true, cost!(Copper: 25, Lead: 15)); + THERMAL_GENERATOR: "thermal-generator" => SimpleBlock::new(2, true, cost!(Copper: 40, Lead: 50, Metaglass: 40, Graphite: 35, Silicon: 35)); + STEAM_GENERATOR: "steam-generator" => SimpleBlock::new(2, true, cost!(Copper: 35, Lead: 40, Graphite: 25, Silicon: 30)); + DIFFERENTIAL_GENERATOR: "differential-generator" => SimpleBlock::new(3, true, cost!(Copper: 70, Lead: 100, Metaglass: 50, Titanium: 50, Silicon: 65)); + RTG_GENERATOR: "rtg-generator" => SimpleBlock::new(2, true, cost!(Lead: 100, Thorium: 50, Silicon: 75, Plastanium: 75, PhaseFabric: 25)); + SOLAR_PANEL: "solar-panel" => SimpleBlock::new(1, true, cost!(Lead: 10, Silicon: 15)); + SOLAR_PANEL_LARGE: "solar-panel-large" => SimpleBlock::new(3, true, cost!(Lead: 80, Silicon: 110, PhaseFabric: 15)); + THORIUM_REACTOR: "thorium-reactor" => SimpleBlock::new(3, true, cost!(Lead: 300, Metaglass: 50, Graphite: 150, Thorium: 150, Silicon: 200)); + IMPACT_REACTOR: "impact-reactor" => SimpleBlock::new(4, true, + cost!(Lead: 500, Metaglass: 250, Graphite: 400, Thorium: 100, Silicon: 300, SurgeAlloy: 250)); + // sandbox only + POWER_SOURCE: "power-source" => ConnectorBlock::new(1, true, &[], 100); + POWER_VOID: "power-void" => SimpleBlock::new(1, true, &[]); ); pub struct ConnectorBlock { size: u8, + symmetric: bool, + build_cost: BuildCost, max: u8, } impl ConnectorBlock { - pub const fn new(size: u8, max: u8) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost, max: u8) -> Self { if size == 0 { @@ -46,7 +51,7 @@ impl ConnectorBlock { panic!("invalid maximum link count"); } - Self{size, max} + Self{size, symmetric, build_cost, max} } pub fn get_max_links(&self) -> u8 @@ -66,7 +71,21 @@ impl BlockLogic for ConnectorBlock fn is_symmetric(&self) -> bool { - true + self.symmetric + } + + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} } fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> diff --git a/src/block/simple.rs b/src/block/simple.rs index 49f7151..dcbe0dc 100644 --- a/src/block/simple.rs +++ b/src/block/simple.rs @@ -3,6 +3,8 @@ use std::any::{Any, type_name}; use crate::block::{BlockLogic, DataConvertError, DeserializeError, SerializeError}; use crate::data::GridPos; use crate::data::dynamic::DynData; +use crate::item; +use crate::item::storage::Storage; macro_rules!state_impl { @@ -29,21 +31,24 @@ macro_rules!state_impl } pub(crate) use state_impl; +pub type BuildCost = &'static [(item::Type, u32)]; + pub struct SimpleBlock { size: u8, symmetric: bool, + build_cost: BuildCost, } impl SimpleBlock { - pub const fn new(size: u8, symmetric: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self { if size == 0 { panic!("invalid size"); } - Self{size, symmetric} + Self{size, symmetric, build_cost} } } @@ -59,6 +64,20 @@ impl BlockLogic for SimpleBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> { Ok(DynData::Empty) @@ -79,3 +98,12 @@ impl BlockLogic for SimpleBlock Ok(DynData::Empty) } } + +macro_rules!cost +{ + ($($item:ident: $cnt:literal),+) => + { + &[$((crate::item::Type::$item, $cnt)),*] + }; +} +pub(crate) use cost; diff --git a/src/block/transport.rs b/src/block/transport.rs index 8491721..e2b4384 100644 --- a/src/block/transport.rs +++ b/src/block/transport.rs @@ -3,48 +3,50 @@ use std::error::Error; use std::fmt; use crate::block::{BlockLogic, DataConvertError, DeserializeError, make_register, SerializeError}; -use crate::block::simple::{SimpleBlock, state_impl}; +use crate::block::simple::{BuildCost, cost, SimpleBlock, state_impl}; use crate::content; use crate::data::GridPos; use crate::data::dynamic::{DynData, DynType}; use crate::item; +use crate::item::storage::Storage; make_register! ( - CONVEYOR: "conveyor" => SimpleBlock::new(1, false); - TITANIUM_CONVEYOR: "titanium-conveyor" => SimpleBlock::new(1, false); - PLASTANIUM_CONVEYOR: "plastanium-conveyor" => SimpleBlock::new(1, false); - ARMORED_CONVEYOR: "armored-conveyor" => SimpleBlock::new(1, false); - JUNCTION: "junction" => SimpleBlock::new(1, true); - BRIDGE_CONVEYOR: "bridge-conveyor" => BridgeBlock::new(1, false, 4, true); - PHASE_CONVEYOR: "phase-conveyor" => BridgeBlock::new(1, false, 12, true); - SORTER: "sorter" => ItemBlock::new(1, true); - INVERTED_SORTER: "inverted-sorter" => ItemBlock::new(1, true); - ROUTER: "router" => SimpleBlock::new(1, true); - DISTRIBUTOR: "distributor" => SimpleBlock::new(2, true); - OVERFLOW_GATE: "overflow-gate" => SimpleBlock::new(1, true); - UNDERFLOW_GATE: "underflow-gate" => SimpleBlock::new(1, true); - MASS_DRIVER: "mass-driver" => BridgeBlock::new(3, true, 55, false); + CONVEYOR: "conveyor" => SimpleBlock::new(1, false, cost!(Copper: 1)); + TITANIUM_CONVEYOR: "titanium-conveyor" => SimpleBlock::new(1, false, cost!(Copper: 1, Lead: 1, Titanium: 1)); + PLASTANIUM_CONVEYOR: "plastanium-conveyor" => SimpleBlock::new(1, false, cost!(Graphite: 1, Silicon: 1, Plastanium: 1)); + ARMORED_CONVEYOR: "armored-conveyor" => SimpleBlock::new(1, false, cost!(Metaglass: 1, Thorium: 1, Plastanium: 1)); + JUNCTION: "junction" => SimpleBlock::new(1, true, cost!(Copper: 2)); + BRIDGE_CONVEYOR: "bridge-conveyor" => BridgeBlock::new(1, false, cost!(Copper: 6, Lead: 6), 4, true); + PHASE_CONVEYOR: "phase-conveyor" => BridgeBlock::new(1, false, cost!(Lead: 10, Graphite: 10, Silicon: 7, PhaseFabric: 5), 12, true); + SORTER: "sorter" => ItemBlock::new(1, true, cost!(Copper: 2, Lead: 2)); + INVERTED_SORTER: "inverted-sorter" => ItemBlock::new(1, true, cost!(Copper: 2, Lead: 2)); + ROUTER: "router" => SimpleBlock::new(1, true, cost!(Copper: 3)); + DISTRIBUTOR: "distributor" => SimpleBlock::new(2, true, cost!(Copper: 4, Lead: 4)); + OVERFLOW_GATE: "overflow-gate" => SimpleBlock::new(1, true, cost!(Copper: 4, Lead: 2)); + UNDERFLOW_GATE: "underflow-gate" => SimpleBlock::new(1, true, cost!(Copper: 4, Lead: 2)); + MASS_DRIVER: "mass-driver" => BridgeBlock::new(3, true, cost!(Lead: 125, Titanium: 125, Thorium: 50, Silicon: 75), 55, false); // sandbox only - ITEM_SOURCE: "item-source" => ItemBlock::new(1, true); - ITEM_VOID: "item-void" => SimpleBlock::new(1, true); + ITEM_SOURCE: "item-source" => ItemBlock::new(1, true, &[]); + ITEM_VOID: "item-void" => SimpleBlock::new(1, true, &[]); ); pub struct ItemBlock { size: u8, symmetric: bool, + build_cost: BuildCost, } impl ItemBlock { - pub const fn new(size: u8, symmetric: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost) -> Self { if size == 0 { panic!("invalid size"); } - Self{size, symmetric} + Self{size, symmetric, build_cost} } state_impl!(pub Option<item::Type>); @@ -62,6 +64,20 @@ impl BlockLogic for ItemBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, config: i32, _: GridPos) -> Result<DynData, DataConvertError> { if config < 0 || config > u16::MAX as i32 @@ -166,6 +182,7 @@ pub struct BridgeBlock { size: u8, symmetric: bool, + build_cost: BuildCost, range: u16, ortho: bool, } @@ -174,7 +191,7 @@ type Point2 = (i32, i32); impl BridgeBlock { - pub const fn new(size: u8, symmetric: bool, range: u16, ortho: bool) -> Self + pub const fn new(size: u8, symmetric: bool, build_cost: BuildCost, range: u16, ortho: bool) -> Self { if size == 0 { @@ -184,7 +201,7 @@ impl BridgeBlock { panic!("invalid range"); } - Self{size, symmetric, range, ortho} + Self{size, symmetric, build_cost, range, ortho} } state_impl!(pub Option<Point2>); @@ -202,6 +219,20 @@ impl BlockLogic for BridgeBlock self.symmetric } + fn create_build_cost(&self) -> Option<Storage> + { + if !self.build_cost.is_empty() + { + let mut storage = Storage::new(); + for (ty, cnt) in self.build_cost + { + storage.add(*ty, *cnt, u32::MAX); + } + Some(storage) + } + else {None} + } + fn data_from_i32(&self, config: i32, pos: GridPos) -> Result<DynData, DataConvertError> { let (x, y) = ((config >> 16) as i16, config as i16); diff --git a/src/block/turret.rs b/src/block/turret.rs index 97f9a7a..61fd07d 100644 --- a/src/block/turret.rs +++ b/src/block/turret.rs @@ -1,24 +1,24 @@ use crate::block::make_register; -use crate::block::simple::SimpleBlock; +use crate::block::simple::{cost, SimpleBlock}; make_register! ( - DUO: "duo" => SimpleBlock::new(1, true); - SCATTER: "scatter" => SimpleBlock::new(2, true); - SCORCH: "scorch" => SimpleBlock::new(1, true); - HAIL: "hail" => SimpleBlock::new(1, true); - WAVE: "wave" => SimpleBlock::new(2, true); - LANCER: "lancer" => SimpleBlock::new(2, true); - ARC: "arc" => SimpleBlock::new(1, true); - PARALLAX: "parallax" => SimpleBlock::new(2, true); - SWARMER: "swarmer" => SimpleBlock::new(2, true); - SALVO: "salvo" => SimpleBlock::new(2, true); - SEGMENT: "segment" => SimpleBlock::new(2, true); - TSUNAMI: "tsunami" => SimpleBlock::new(3, true); - FUSE: "fuse" => SimpleBlock::new(3, true); - RIPPLE: "ripple" => SimpleBlock::new(3, true); - CYCLONE: "cyclone" => SimpleBlock::new(3, true); - FORESHADOW: "foreshadow" => SimpleBlock::new(4, true); - SPECTRE: "spectre" => SimpleBlock::new(4, true); - MELTDOWN: "meltdown" => SimpleBlock::new(4, true); + DUO: "duo" => SimpleBlock::new(1, true, cost!(Copper: 35)); + SCATTER: "scatter" => SimpleBlock::new(2, true, cost!(Copper: 85, Lead: 45)); + SCORCH: "scorch" => SimpleBlock::new(1, true, cost!(Copper: 25, Graphite: 22)); + HAIL: "hail" => SimpleBlock::new(1, true, cost!(Copper: 40, Graphite: 17)); + WAVE: "wave" => SimpleBlock::new(2, true, cost!(Copper: 25, Lead: 75, Metaglass: 45)); + LANCER: "lancer" => SimpleBlock::new(2, true, cost!(Copper: 60, Lead: 70, Titanium: 30, Silicon: 60)); + ARC: "arc" => SimpleBlock::new(1, true, cost!(Copper: 50, Lead: 50)); + PARALLAX: "parallax" => SimpleBlock::new(2, true, cost!(Graphite: 30, Titanium: 90, Silicon: 120)); + SWARMER: "swarmer" => SimpleBlock::new(2, true, cost!(Graphite: 35, Titanium: 35, Silicon: 30, Plastanium: 45)); + SALVO: "salvo" => SimpleBlock::new(2, true, cost!(Copper: 100, Graphite: 80, Titanium: 50)); + SEGMENT: "segment" => SimpleBlock::new(2, true, cost!(Titanium: 40, Thorium: 80, Silicon: 130, PhaseFabric: 40)); + TSUNAMI: "tsunami" => SimpleBlock::new(3, true, cost!(Lead: 400, Metaglass: 100, Titanium: 250, Thorium: 100)); + FUSE: "fuse" => SimpleBlock::new(3, true, cost!(Copper: 225, Graphite: 225, Thorium: 100)); + RIPPLE: "ripple" => SimpleBlock::new(3, true, cost!(Copper: 150, Graphite: 135, Titanium: 60)); + CYCLONE: "cyclone" => SimpleBlock::new(3, true, cost!(Copper: 200, Titanium: 125, Plastanium: 80)); + FORESHADOW: "foreshadow" => SimpleBlock::new(4, true, cost!(Copper: 1000, Metaglass: 600, Silicon: 600, Plastanium: 200, SurgeAlloy: 300)); + SPECTRE: "spectre" => SimpleBlock::new(4, true, cost!(Copper: 900, Graphite: 300, Thorium: 250, Plastanium: 175, SurgeAlloy: 250)); + MELTDOWN: "meltdown" => SimpleBlock::new(4, true, cost!(Copper: 1200, Lead: 350, Graphite: 300, Silicon: 325, SurgeAlloy: 325)); ); |