From 05f4edf83abc24d97f951b9ee0c5a04ba4153dd9 Mon Sep 17 00:00:00 2001 From: hal8174 Date: Thu, 23 Jan 2025 21:01:25 +0100 Subject: [PATCH] Add assembly generation --- factorio-blueprint-generator/src/assembly.rs | 217 ++++++++++++++++++ .../src/bin/assembly.rs | 21 ++ factorio-blueprint-generator/src/lib.rs | 1 + factorio-blueprint/src/abstraction.rs | 47 ++++ 4 files changed, 286 insertions(+) create mode 100644 factorio-blueprint-generator/src/assembly.rs create mode 100644 factorio-blueprint-generator/src/bin/assembly.rs diff --git a/factorio-blueprint-generator/src/assembly.rs b/factorio-blueprint-generator/src/assembly.rs new file mode 100644 index 0000000..2847080 --- /dev/null +++ b/factorio-blueprint-generator/src/assembly.rs @@ -0,0 +1,217 @@ +use factorio_blueprint::abstraction::{Blueprint, ElectricPoleType, Entity, InserterType}; +use factorio_core::{beltoptions::Beltspeed, prelude::*}; + +pub fn assembly_line(assembly_machines: usize) -> Blueprint { + let mut blueprint = Blueprint::new(); + + let mut last = None; + for i in 0..assembly_machines.div_ceil(3) { + let top = blueprint.add_entity(Entity::new_electric_pole( + ElectricPoleType::Medium, + Position::new(9 + 18 * i as PositionType, 5), + )); + + let bottom = blueprint.add_entity(Entity::new_electric_pole( + ElectricPoleType::Medium, + Position::new(9 + 18 * i as PositionType, 13), + )); + + blueprint.add_wire(top, 5, bottom, 5); + if let Some((last_top, last_bottom)) = last { + blueprint.add_wire(top, 5, last_top, 5); + blueprint.add_wire(bottom, 5, last_bottom, 5); + } + + last = Some((top, bottom)); + } + + for i in 0..assembly_machines { + blueprint.add_entity(Entity::new_production( + "assembling-machine-3", + "iron-gears", + Position::new(3 + 6 * i as PositionType, 9), + Direction::Up, + Position::new(6, 6), + )); + + match i % 3 { + 0 => { + blueprint.add_entity(Entity::new_inserter( + InserterType::Long, + None, + Position::new(3 + 6 * i as PositionType, 5), + Direction::Down, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Fast, + None, + Position::new(5 + 6 * i as PositionType, 5), + Direction::Up, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Long, + None, + Position::new(3 + 6 * i as PositionType, 13), + Direction::Down, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Fast, + None, + Position::new(5 + 6 * i as PositionType, 13), + Direction::Down, + )); + } + 1 => { + blueprint.add_entity(Entity::new_inserter( + InserterType::Long, + None, + Position::new(1 + 6 * i as PositionType, 5), + Direction::Down, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Fast, + None, + Position::new(5 + 6 * i as PositionType, 5), + Direction::Up, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Long, + None, + Position::new(1 + 6 * i as PositionType, 13), + Direction::Down, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Fast, + None, + Position::new(5 + 6 * i as PositionType, 13), + Direction::Down, + )); + } + 2 => { + blueprint.add_entity(Entity::new_inserter( + InserterType::Long, + None, + Position::new(1 + 6 * i as PositionType, 5), + Direction::Down, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Fast, + None, + Position::new(3 + 6 * i as PositionType, 5), + Direction::Up, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Long, + None, + Position::new(1 + 6 * i as PositionType, 13), + Direction::Down, + )); + blueprint.add_entity(Entity::new_inserter( + InserterType::Fast, + None, + Position::new(3 + 6 * i as PositionType, 13), + Direction::Down, + )); + } + _ => unreachable!(), + } + } + + for i in 0..(3 * (assembly_machines - 1) + 1) { + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(1 + 2 * i as PositionType, 1), + Direction::Left, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(1 + 2 * i as PositionType, 3), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(1 + 2 * i as PositionType, 15), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(1 + 2 * i as PositionType, 17), + Direction::Right, + )); + } + + match assembly_machines % 3 { + 0 => { + let i = 3 * (assembly_machines - 1); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 3), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 15), + Direction::Right, + )); + } + 1 => { + let i = 3 * (assembly_machines - 1); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 1), + Direction::Left, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 3), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 15), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 17), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(5 + 2 * i as PositionType, 3), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(5 + 2 * i as PositionType, 15), + Direction::Right, + )); + } + 2 => { + let i = 3 * (assembly_machines - 1); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 3), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(3 + 2 * i as PositionType, 15), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(5 + 2 * i as PositionType, 3), + Direction::Right, + )); + blueprint.add_entity(Entity::new_belt( + Beltspeed::Normal, + Position::new(5 + 2 * i as PositionType, 15), + Direction::Right, + )); + } + _ => unreachable!(), + } + + blueprint +} diff --git a/factorio-blueprint-generator/src/bin/assembly.rs b/factorio-blueprint-generator/src/bin/assembly.rs new file mode 100644 index 0000000..357acf5 --- /dev/null +++ b/factorio-blueprint-generator/src/bin/assembly.rs @@ -0,0 +1,21 @@ +use clap::Parser; +use factorio_blueprint::{BlueprintString, encode}; +use factorio_blueprint_generator::assembly::assembly_line; + +#[derive(Parser)] +struct Args { + #[arg(short, long)] + json: bool, + assembly_machines: usize, +} + +fn main() { + let args = Args::parse(); + let b = BlueprintString::Blueprint(assembly_line(args.assembly_machines).to_blueprint()); + + if args.json { + println!("{}", serde_json::to_string_pretty(&b).unwrap()); + } + + println!("{}", encode(&serde_json::to_string(&b).unwrap())); +} diff --git a/factorio-blueprint-generator/src/lib.rs b/factorio-blueprint-generator/src/lib.rs index c3b8fbb..d024449 100644 --- a/factorio-blueprint-generator/src/lib.rs +++ b/factorio-blueprint-generator/src/lib.rs @@ -1,3 +1,4 @@ +pub mod assembly; pub mod balancer; pub mod binary_merger; pub mod station; diff --git a/factorio-blueprint/src/abstraction.rs b/factorio-blueprint/src/abstraction.rs index a790965..44e90bb 100644 --- a/factorio-blueprint/src/abstraction.rs +++ b/factorio-blueprint/src/abstraction.rs @@ -17,6 +17,7 @@ pub enum UndergroundType { pub enum InserterType { Burner, Normal, + Long, Fast, Bulk, Stack, @@ -27,6 +28,7 @@ impl InserterType { match self { InserterType::Burner => "burner-inserter", InserterType::Normal => "inserter", + InserterType::Long => "long-handed-inserter", InserterType::Fast => "fast-inserter", InserterType::Bulk => "bulk-inserter", InserterType::Stack => "stack-inserter", @@ -87,6 +89,11 @@ pub enum EntityType { inserter_type: InserterType, override_stack_size: Option, }, + Production { + name: String, + recipe: String, + size: Position, + }, Unknown { name: String, size: Position, @@ -149,6 +156,24 @@ impl Entity { ) } + pub fn new_production( + name: impl AsRef, + recipe: impl AsRef, + position: Position, + direction: Direction, + size: Position, + ) -> Self { + Self::new( + EntityType::Production { + name: name.as_ref().to_owned(), + recipe: recipe.as_ref().to_owned(), + size, + }, + position, + direction, + ) + } + pub fn new_unknown( name: impl AsRef, position: Position, @@ -188,6 +213,11 @@ impl Entity { inserter_type, override_stack_size: _, } => inserter_type.string(), + EntityType::Production { + name, + recipe: _, + size: _, + } => name.clone(), } } @@ -211,6 +241,17 @@ impl Entity { } } + pub fn get_maybe_recipe(&self) -> Option { + match &self.entity { + EntityType::Production { + name: _, + recipe, + size: _, + } => Some(recipe.clone()), + _ => None, + } + } + pub fn size(&self) -> Position { match &self.entity { EntityType::Splitter(_) => Position::new(4, 2), @@ -219,6 +260,11 @@ impl Entity { size, misc: _, } => *size, + EntityType::Production { + name: _, + recipe: _, + size, + } => *size, EntityType::ElectricPole(electric_pole_type) => electric_pole_type.size(), _ => Position::new(2, 2), } @@ -321,6 +367,7 @@ impl Blueprint { }) .maybe_underground_type(e.get_maybe_underground_type_string()) .maybe_override_stack_size(e.get_maybe_override_stack_size()) + .maybe_recipe(e.get_maybe_recipe()) .build() }) .collect();