Add wagon chest options to multistation

This commit is contained in:
hal8174 2025-04-25 21:31:48 +02:00
parent 7ef42e5202
commit 0ced2c3c44
7 changed files with 110 additions and 71 deletions

View file

@ -1,8 +1,9 @@
use clap::Parser; use clap::Parser;
use factorio_blueprint::abstraction::serde::AbstractBlueprintString; use factorio_blueprint::abstraction::serde::AbstractBlueprintString;
use factorio_blueprint::abstraction::{InserterType, Quality}; use factorio_blueprint::abstraction::{ChestType, InserterType, Quality};
use factorio_blueprint::encode; use factorio_blueprint::encode;
use factorio_blueprint_generator::multistation::{StationSpec, multistation}; use factorio_blueprint_generator::multistation::{StationSpec, multistation};
use factorio_blueprint_generator::station::StationBasicSpec;
use factorio_core::beltoptions::{Beltspeed, Belttype}; use factorio_core::beltoptions::{Beltspeed, Belttype};
use factorio_core::visualize::Visualize; use factorio_core::visualize::Visualize;
@ -17,6 +18,12 @@ struct Args {
#[arg(short, long, default_value = "normal")] #[arg(short, long, default_value = "normal")]
wagon_inserter_quality: Quality, wagon_inserter_quality: Quality,
#[arg(short, long, default_value = "steel")]
chest_type: ChestType,
#[arg(short, long, default_value = "normal")]
chest_quality: Quality,
stacker_size: usize, stacker_size: usize,
/// format: <locomotives>-<wagons>[lu][nfet]<lanes>[lr]? /// format: <locomotives>-<wagons>[lu][nfet]<lanes>[lr]?
stations: Vec<String>, stations: Vec<String>,
@ -72,8 +79,12 @@ fn main() {
let mut b = multistation( let mut b = multistation(
&stations, &stations,
args.stacker_size, args.stacker_size,
args.wagon_inserter_type, &StationBasicSpec {
args.wagon_inserter_quality, inserter_type: args.wagon_inserter_type,
inserter_quality: args.wagon_inserter_quality,
chest_type: args.chest_type,
chest_quality: args.chest_quality,
},
) )
.0; .0;

View file

@ -1,6 +1,6 @@
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use factorio_blueprint::{BlueprintBook, BlueprintBookEntry, BlueprintString, encode}; use factorio_blueprint::{BlueprintBook, BlueprintBookEntry, BlueprintString, encode};
use factorio_blueprint_generator::station::basic_station; use factorio_blueprint_generator::station::{StationBasicSpec, basic_station};
use factorio_core::beltoptions::{Beltspeed, Belttype}; use factorio_core::beltoptions::{Beltspeed, Belttype};
#[derive(Parser)] #[derive(Parser)]
@ -70,8 +70,7 @@ fn main() {
beltspeed, beltspeed,
Belttype::Full, Belttype::Full,
false, false,
factorio_blueprint::abstraction::InserterType::Bulk, &factorio_blueprint_generator::station::StationBasicSpec::default(),
factorio_blueprint::abstraction::Quality::Normal,
); );
inner_inner_b.push(BlueprintBookEntry::new( inner_inner_b.push(BlueprintBookEntry::new(
@ -140,8 +139,7 @@ fn main() {
beltspeed, beltspeed,
belttype, belttype,
false, false,
factorio_blueprint::abstraction::InserterType::Bulk, &StationBasicSpec::default(),
factorio_blueprint::abstraction::Quality::Normal,
) )
.to_blueprint(), .to_blueprint(),
); );

View file

@ -783,8 +783,7 @@ pub fn generate_factory<L: Layouter, P: Pathfinder + Sync, R: Rng + SeedableRng
let (multistation_blueprint, multistation_x_offset, mut multistation_y_offsets) = multistation( let (multistation_blueprint, multistation_x_offset, mut multistation_y_offsets) = multistation(
&station_spec, &station_spec,
8, 8,
factorio_blueprint::abstraction::InserterType::Bulk, &crate::station::StationBasicSpec::default(),
factorio_blueprint::abstraction::Quality::Normal,
); );
let multistation_y_offset = multistation_y_offsets[0]; let multistation_y_offset = multistation_y_offsets[0];

View file

@ -1,4 +1,7 @@
use crate::{balancer::binary_balancer, station::basic_station}; use crate::{
balancer::binary_balancer,
station::{StationBasicSpec, basic_station},
};
use factorio_blueprint::abstraction::{ use factorio_blueprint::abstraction::{
Blueprint, ElectricPoleType, Entity, Quality, RailType, UndergroundType, Blueprint, ElectricPoleType, Entity, Quality, RailType, UndergroundType,
}; };
@ -50,8 +53,7 @@ fn calculate_station_height(
pub fn multistation( pub fn multistation(
stations: &[StationSpec], stations: &[StationSpec],
stacker_size: usize, stacker_size: usize,
wagon_inserter_type: factorio_blueprint::abstraction::InserterType, basic_spec: &StationBasicSpec,
wagon_inserter_quality: Quality,
) -> (Blueprint, PositionType, Vec<PositionType>) { ) -> (Blueprint, PositionType, Vec<PositionType>) {
let longest_train = stations let longest_train = stations
.iter() .iter()
@ -272,8 +274,7 @@ pub fn multistation(
station.beltspeed, station.beltspeed,
station.belttype, station.belttype,
station.stacked, station.stacked,
wagon_inserter_type, basic_spec,
wagon_inserter_quality,
); );
let output_height = -b.bounding_box().min().y; let output_height = -b.bounding_box().min().y;

View file

@ -1,4 +1,6 @@
use factorio_blueprint::abstraction::{Blueprint, ElectricPoleType, Entity, InserterType, Quality}; use factorio_blueprint::abstraction::{
Blueprint, ChestType, ElectricPoleType, Entity, InserterType, Quality,
};
use factorio_core::{ use factorio_core::{
beltoptions::{Beltspeed, Belttype}, beltoptions::{Beltspeed, Belttype},
prelude::*, prelude::*,
@ -6,12 +8,29 @@ use factorio_core::{
use crate::binary_merger::merger; use crate::binary_merger::merger;
pub struct StationBasicSpec {
pub inserter_type: InserterType,
pub inserter_quality: Quality,
pub chest_type: ChestType,
pub chest_quality: Quality,
}
impl Default for StationBasicSpec {
fn default() -> Self {
Self {
inserter_type: InserterType::Bulk,
inserter_quality: Quality::Normal,
chest_type: ChestType::Steel,
chest_quality: Quality::Normal,
}
}
}
pub fn unloader( pub fn unloader(
beltspeed: Beltspeed, beltspeed: Beltspeed,
belttype: Belttype, belttype: Belttype,
stacked: bool, stacked: bool,
wagon_inserter_type: InserterType, basic_spec: &StationBasicSpec,
wagon_inserter_quality: Quality,
) -> (Blueprint, PositionType) { ) -> (Blueprint, PositionType) {
let mut b = Blueprint::new(); let mut b = Blueprint::new();
@ -33,20 +52,21 @@ pub fn unloader(
)); ));
if belttype.contains_left() { if belttype.contains_left() {
b.add_entity(Entity::new_unknown( b.add_entity(
"steel-chest", Entity::new_chest(
Position::new(1, 1) + 2 * Position::new(5, -2), basic_spec.chest_type,
Direction::Up, Position::new(1, 1) + 2 * Position::new(5, -2),
Position::new(2, 2), )
)); .quality(basic_spec.chest_quality),
);
b.add_entity( b.add_entity(
Entity::new_inserter( Entity::new_inserter(
wagon_inserter_type, basic_spec.inserter_type,
None, None,
Position::new(1, 1) + 2 * Position::new(5, -1), Position::new(1, 1) + 2 * Position::new(5, -1),
Direction::Down, Direction::Down,
) )
.quality(wagon_inserter_quality), .quality(basic_spec.inserter_quality),
); );
b.add_entity( b.add_entity(
@ -61,20 +81,21 @@ pub fn unloader(
} }
if belttype.contains_right() { if belttype.contains_right() {
b.add_entity(Entity::new_unknown( b.add_entity(
"steel-chest", Entity::new_chest(
Position::new(1, 1) + 2 * Position::new(1, -2), basic_spec.chest_type,
Direction::Up, Position::new(1, 1) + 2 * Position::new(1, -2),
Position::new(2, 2), )
)); .quality(basic_spec.chest_quality),
);
b.add_entity( b.add_entity(
Entity::new_inserter( Entity::new_inserter(
wagon_inserter_type, basic_spec.inserter_type,
None, None,
Position::new(1, 1) + 2 * Position::new(1, -1), Position::new(1, 1) + 2 * Position::new(1, -1),
Direction::Down, Direction::Down,
) )
.quality(wagon_inserter_quality), .quality(basic_spec.inserter_quality),
); );
b.add_entity( b.add_entity(
@ -111,20 +132,21 @@ pub fn unloader(
) )
.quality(quality), .quality(quality),
); );
b.add_entity(Entity::new_unknown( b.add_entity(
"steel-chest", Entity::new_chest(
Position::new(1, 1) + 2 * Position::new(x, -2), basic_spec.chest_type,
Direction::Up, Position::new(1, 1) + 2 * Position::new(x, -2),
Position::new(2, 2), )
)); .quality(basic_spec.chest_quality),
);
b.add_entity( b.add_entity(
Entity::new_inserter( Entity::new_inserter(
wagon_inserter_type, basic_spec.inserter_type,
None, None,
Position::new(1, 1) + 2 * Position::new(x, -1), Position::new(1, 1) + 2 * Position::new(x, -1),
Direction::Down, Direction::Down,
) )
.quality(wagon_inserter_quality), .quality(basic_spec.inserter_quality),
); );
}; };
@ -145,8 +167,7 @@ pub fn unloader(
pub fn one_loader( pub fn one_loader(
beltspeed: Beltspeed, beltspeed: Beltspeed,
stacked: bool, stacked: bool,
wagon_inserter_type: InserterType, basic_spec: &StationBasicSpec,
wagon_inserter_quality: Quality,
) -> (Blueprint, PositionType) { ) -> (Blueprint, PositionType) {
let (belt_inserter, quality) = match (beltspeed, stacked) { let (belt_inserter, quality) = match (beltspeed, stacked) {
(Beltspeed::Normal, false) => (InserterType::Fast, Quality::Normal), (Beltspeed::Normal, false) => (InserterType::Fast, Quality::Normal),
@ -184,20 +205,18 @@ pub fn one_loader(
Entity::new_inserter(belt_inserter, None, Position::new(x, -5), Direction::Up) Entity::new_inserter(belt_inserter, None, Position::new(x, -5), Direction::Up)
.quality(quality), .quality(quality),
); );
b.add_entity(Entity::new_unknown( b.add_entity(
"steel-chest", Entity::new_chest(basic_spec.chest_type, Position::new(x, -3))
Position::new(x, -3), .quality(basic_spec.chest_quality),
Direction::Up, );
Position::new(2, 2),
));
b.add_entity( b.add_entity(
Entity::new_inserter( Entity::new_inserter(
wagon_inserter_type, basic_spec.inserter_type,
None, None,
Position::new(x, -1), Position::new(x, -1),
Direction::Up, Direction::Up,
) )
.quality(wagon_inserter_quality), .quality(basic_spec.inserter_quality),
); );
} }
@ -212,8 +231,7 @@ pub fn basic_station(
beltspeed: Beltspeed, beltspeed: Beltspeed,
belttype: Belttype, belttype: Belttype,
stacked: bool, stacked: bool,
wagon_inserter_type: InserterType, basic_spec: &StationBasicSpec,
wagon_inserter_quality: Quality,
) -> Blueprint { ) -> Blueprint {
let section_size = length / outputs; let section_size = length / outputs;
assert!(length % outputs == 0); assert!(length % outputs == 0);
@ -244,14 +262,12 @@ pub fn basic_station(
beltspeed.halvings((length / outputs).ilog2() as usize), beltspeed.halvings((length / outputs).ilog2() as usize),
belttype, belttype,
stacked, stacked,
wagon_inserter_type, basic_spec,
wagon_inserter_quality,
), ),
true => one_loader( true => one_loader(
beltspeed.halvings((length / outputs).ilog2() as usize), beltspeed.halvings((length / outputs).ilog2() as usize),
stacked, stacked,
wagon_inserter_type, basic_spec,
wagon_inserter_quality,
), ),
}; };
for l in 0..length { for l in 0..length {
@ -260,14 +276,12 @@ pub fn basic_station(
beltspeed.halvings((length / outputs).ilog2() as usize), beltspeed.halvings((length / outputs).ilog2() as usize),
belttype, belttype,
stacked, stacked,
wagon_inserter_type, basic_spec,
wagon_inserter_quality,
), ),
true => one_loader( true => one_loader(
beltspeed.halvings((length / outputs).ilog2() as usize), beltspeed.halvings((length / outputs).ilog2() as usize),
stacked, stacked,
wagon_inserter_type, basic_spec,
wagon_inserter_quality,
), ),
}; };

View file

@ -49,6 +49,24 @@ impl InserterType {
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, ValueEnum)]
pub enum ChestType {
Wood,
Iron,
Steel,
}
impl ChestType {
fn string(&self) -> String {
match self {
ChestType::Wood => "wooden-chest",
ChestType::Iron => "iron-chest",
ChestType::Steel => "steel-chest",
}
.to_owned()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ElectricPoleType { pub enum ElectricPoleType {
Small, Small,
@ -172,6 +190,7 @@ pub enum EntityType {
rail_type: RailType, rail_type: RailType,
}, },
Roboport, Roboport,
Chest(ChestType),
Unknown { Unknown {
name: String, name: String,
size: Position, size: Position,
@ -219,6 +238,10 @@ impl Entity {
) )
} }
pub fn new_chest(chest_type: ChestType, position: Position) -> Self {
Self::new(EntityType::Chest(chest_type), position, Direction::Up)
}
pub fn new_splitter(beltspeed: Beltspeed, position: Position, direction: Direction) -> Self { pub fn new_splitter(beltspeed: Beltspeed, position: Position, direction: Direction) -> Self {
Self::new( Self::new(
EntityType::Splitter { EntityType::Splitter {
@ -356,6 +379,7 @@ impl Entity {
} => name.clone(), } => name.clone(),
EntityType::Rail { rail_type } => rail_type.string(), EntityType::Rail { rail_type } => rail_type.string(),
EntityType::Roboport => "roboport".to_string(), EntityType::Roboport => "roboport".to_string(),
EntityType::Chest(chest_type) => chest_type.string(),
} }
} }

View file

@ -99,7 +99,6 @@ impl Serialize for SerializeEntityWrapper<'_> {
} }
match &self.1.entity { match &self.1.entity {
super::EntityType::Belt(_beltspeed) => (),
super::EntityType::UndergroundBelt(_beltspeed, underground_type) => { super::EntityType::UndergroundBelt(_beltspeed, underground_type) => {
entity_map.serialize_entry( entity_map.serialize_entry(
"type", "type",
@ -134,7 +133,6 @@ impl Serialize for SerializeEntityWrapper<'_> {
)?; )?;
} }
} }
super::EntityType::ElectricPole(_electric_pole_type) => (),
super::EntityType::Inserter { super::EntityType::Inserter {
inserter_type: _, inserter_type: _,
override_stack_size, override_stack_size,
@ -150,13 +148,7 @@ impl Serialize for SerializeEntityWrapper<'_> {
} => { } => {
entity_map.serialize_entry("recipe", recipe)?; entity_map.serialize_entry("recipe", recipe)?;
} }
super::EntityType::Rail { rail_type: _ } => (), _ => (),
super::EntityType::Roboport => (),
super::EntityType::Unknown {
name: _,
size: _,
misc: _,
} => (),
} }
entity_map.end() entity_map.end()