use factorio_blueprint::abstraction::{Blueprint, Entity}; use factorio_core::{beltoptions::Beltspeed, prelude::*}; pub fn merger( reverse: bool, beltspeed: Beltspeed, intervall: usize, outputs: usize, inputs: usize, ) -> Blueprint { let section_size = inputs / outputs; assert!(inputs % outputs == 0); assert!(section_size.is_power_of_two()); assert!(outputs <= inputs); let mut b = Blueprint::new(); // output and merging for o in 0..outputs { // stubs let stubspeed = beltspeed.halvings(section_size.ilog2() as usize); for i in 0..section_size { let depth = o + i.count_ones() as usize; for j in 0..depth { b.add_entity(Entity::new_belt( stubspeed, Position::new(1, 1) + 2 * Position::new( (intervall * (i + o * section_size)) as PositionType, -(j as PositionType), ), match reverse { true => Direction::Down, false => Direction::Up, }, )); } b.add_entity(Entity::new_belt( stubspeed, Position::new(1, 1) + 2 * Position::new( (intervall * (i + o * section_size)) as PositionType, -(depth as PositionType), ), match reverse { true => Direction::Down, false => Direction::Left, }, )); } // merger for i in 1..(section_size.ilog2() as usize + 1) { let p = 1 << i; let mergespeed = beltspeed.halvings((section_size.ilog2() as usize) - i); for j in 0..(section_size / p) { let depth = o + j.count_ones() as usize; b.add_entity(Entity::new_splitter( mergespeed, Position::new( 2 * ((intervall * (j * p + o * section_size)) as PositionType - i as PositionType) + 1, 2 * (1 - i as PositionType - depth as PositionType), ), match reverse { true => Direction::Right, false => Direction::Left, }, )); for l in 0..(7 * p / 2) { b.add_entity(Entity::new_belt( mergespeed.halve(), Position::new(1, 1) + 2 * Position::new( (intervall * (j * p + o * section_size) + l + 1) as PositionType - i as PositionType, 0 - i as PositionType - depth as PositionType, ), match reverse { true => Direction::Right, false => Direction::Left, }, )); } } } // connect let step = o + section_size.ilog2() as usize; for l in 0..(7 * o * section_size) { b.add_entity(Entity::new_belt( beltspeed, Position::new(1, 1) + 2 * Position::new( l as PositionType - section_size.ilog2() as PositionType, -(step as PositionType), ), match reverse { true => Direction::Right, false => Direction::Left, }, )); } } b }