mindustry logic execution, map- and schematic- parsing and rendering
Implement build cost for BlockLogic
KosmosPrime 2023-01-24
parent 7b0e105 · commit f4d106a
-rw-r--r--src/block/base.rs50
-rw-r--r--src/block/defense.rs60
-rw-r--r--src/block/extraction.rs16
-rw-r--r--src/block/factory.rs40
-rw-r--r--src/block/fluid.rs50
-rw-r--r--src/block/logic.rs116
-rw-r--r--src/block/mod.rs3
-rw-r--r--src/block/payload.rs69
-rw-r--r--src/block/power.rs61
-rw-r--r--src/block/simple.rs32
-rw-r--r--src/block/transport.rs73
-rw-r--r--src/block/turret.rs38
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));
);