use factorio_blueprint::abstraction::{Blueprint, ElectricPoleType, Entity, InserterType, Quality}; use factorio_core::{ beltoptions::{Beltspeed, Belttype}, prelude::*, }; use crate::binary_merger::merger; pub fn unloader( beltspeed: Beltspeed, belttype: Belttype, stacked: bool, ) -> (Blueprint, PositionType) { let mut b = Blueprint::new(); let (belt_inserter, stack_size, quality) = match (beltspeed, stacked) { (Beltspeed::Normal, false) => (InserterType::Fast, None, Quality::Normal), (Beltspeed::Fast, false) => (InserterType::Fast, None, Quality::Normal), (Beltspeed::Express, false) => (InserterType::Bulk, Some(7), Quality::Normal), (Beltspeed::Turbo, false) => (InserterType::Bulk, Some(10), Quality::Normal), (Beltspeed::Normal, true) => (InserterType::Stack, None, Quality::Normal), (Beltspeed::Fast, true) => (InserterType::Stack, None, Quality::Normal), (Beltspeed::Express, true) => (InserterType::Stack, None, Quality::Rare), (Beltspeed::Turbo, true) => (InserterType::Stack, None, Quality::Epic), }; if beltspeed == Beltspeed::Normal { b.add_entity(Entity::new_belt( Beltspeed::Fast, Position::new(1, 1) + 2 * Position::new(3, -2), Direction::Up, )); if belttype.contains_left() { b.add_entity(Entity::new_unknown( "steel-chest", Position::new(1, 1) + 2 * Position::new(5, -2), Direction::Up, Position::new(2, 2), )); b.add_entity(Entity::new_inserter( InserterType::Bulk, None, Position::new(1, 1) + 2 * Position::new(5, -1), Direction::Down, )); b.add_entity( Entity::new_inserter( belt_inserter, stack_size, Position::new(1, 1) + 2 * Position::new(4, -2), Direction::Right, ) .quality(quality), ); } if belttype.contains_right() { b.add_entity(Entity::new_unknown( "steel-chest", Position::new(1, 1) + 2 * Position::new(1, -2), Direction::Up, Position::new(2, 2), )); b.add_entity(Entity::new_inserter( InserterType::Bulk, None, Position::new(1, 1) + 2 * Position::new(1, -1), Direction::Down, )); b.add_entity( Entity::new_inserter( belt_inserter, stack_size, Position::new(1, 1) + 2 * Position::new(2, -2), Direction::Left, ) .quality(quality), ); } (b, -3) } else { b.add_entity(Entity::new_belt( beltspeed, Position::new(1, 1) + 2 * Position::new(3, -4), Direction::Up, )); let mut s = |x, beltdir| { b.add_entity(Entity::new_belt( beltspeed, Position::new(1, 1) + 2 * Position::new(x, -4), beltdir, )); b.add_entity( Entity::new_inserter( belt_inserter, stack_size, Position::new(1, 1) + 2 * Position::new(x, -3), Direction::Down, ) .quality(quality), ); b.add_entity(Entity::new_unknown( "steel-chest", Position::new(1, 1) + 2 * Position::new(x, -2), Direction::Up, Position::new(2, 2), )); b.add_entity(Entity::new_inserter( InserterType::Bulk, None, Position::new(1, 1) + 2 * Position::new(x, -1), Direction::Down, )); }; if belttype.contains_left() { s(1, Direction::Right); s(2, Direction::Right); } if belttype.contains_right() { s(4, Direction::Left); s(5, Direction::Left); } (b, -5) } } pub fn one_loader(beltspeed: Beltspeed, stacked: bool) -> (Blueprint, PositionType) { let (belt_inserter, quality) = match (beltspeed, stacked) { (Beltspeed::Normal, false) => (InserterType::Fast, Quality::Normal), (Beltspeed::Fast, false) => (InserterType::Bulk, Quality::Uncommon), (Beltspeed::Express, false) => (InserterType::Bulk, Quality::Rare), (Beltspeed::Turbo, false) => (InserterType::Bulk, Quality::Legendary), (Beltspeed::Normal, true) => todo!(), (Beltspeed::Fast, true) => todo!(), (Beltspeed::Express, true) => todo!(), (Beltspeed::Turbo, true) => todo!(), }; let mut b = Blueprint::new(); b.add_entity(Entity::new_splitter( beltspeed, Position::new(8, -9), Direction::Down, )); b.add_entity(Entity::new_belt( beltspeed, Position::new(1, 1) + 2 * Position::new(3, -4), Direction::Left, )); b.add_entity(Entity::new_belt( beltspeed, Position::new(1, 1) + 2 * Position::new(4, -4), Direction::Right, )); let mut s = |x, beltdir| { b.add_entity(Entity::new_belt( beltspeed, Position::new(1, 1) + 2 * Position::new(x, -4), beltdir, )); b.add_entity( Entity::new_inserter( belt_inserter, None, Position::new(1, 1) + 2 * Position::new(x, -3), Direction::Up, ) .quality(quality), ); b.add_entity(Entity::new_unknown( "steel-chest", Position::new(1, 1) + 2 * Position::new(x, -2), Direction::Up, Position::new(2, 2), )); b.add_entity(Entity::new_inserter( InserterType::Bulk, None, Position::new(1, 1) + 2 * Position::new(x, -1), Direction::Up, )); }; s(2, Direction::Left); s(5, Direction::Right); (b, -6) } pub fn basic_station( load: bool, locomotives: usize, length: usize, outputs: usize, beltspeed: Beltspeed, belttype: Belttype, stacked: bool, ) -> Blueprint { let section_size = length / outputs; assert!(length % outputs == 0); assert!(section_size.is_power_of_two()); assert!(outputs <= length); let mut blueprint = Blueprint::new(); let global_x_offset = locomotives * 7; // electric poles let mut poles = Vec::new(); for l in 1..=(length + locomotives) { poles.push(blueprint.add_entity(Entity::new_electric_pole( ElectricPoleType::Medium, Position::new(1, 1) + 2 * Position::new(7 * l as PositionType, -2), ))); } for (&a, &b) in poles.iter().zip(poles[1..].iter()) { blueprint.add_wire(a, 5, b, 5); } // unloader let (_, output_y) = match load { false => unloader( beltspeed.halvings((length / outputs).ilog2() as usize), belttype, stacked, ), true => one_loader( beltspeed.halvings((length / outputs).ilog2() as usize), stacked, ), }; for l in 0..length { let (mut unloader, _) = match load { false => unloader( beltspeed.halvings((length / outputs).ilog2() as usize), belttype, stacked, ), true => one_loader( beltspeed.halvings((length / outputs).ilog2() as usize), stacked, ), }; unloader.transform(Transformation::new( Direction::Up, 2 * Position::new((7 * l + global_x_offset) as PositionType, 0), )); blueprint.add_blueprint(unloader); } // train stop blueprint.add_entity(Entity::new_unknown( "train-stop", Position::new(2, -2), Direction::Left, Position::new(4, 4), )); // rails for l in 0..(length * 7 + global_x_offset).div_ceil(2) { blueprint.add_entity(Entity::new_unknown( "straight-rail", Position::new(2 + 4 * l as PositionType, 2), Direction::Left, Position::new(4, 4), )); } // output and merging let mut m = merger(load, beltspeed, 7, outputs, length); m.transform(Transformation::new( Direction::Up, 2 * Position::new(global_x_offset as PositionType + 3, output_y), )); blueprint.add_blueprint(m); blueprint }