use std::sync::Arc; use super::{ belt::{Beltspeed, Belttype}, Blueprint, BlueprintEntity, BlueprintPosition, }; pub fn station_unload( length: usize, locomotives: usize, unloader: &Vec, beltspeed: Beltspeed, outputs: usize, output_x: f64, output_y: f64, ) -> Blueprint { let section_size = length / outputs; assert!(length % outputs == 0); assert!(section_size.is_power_of_two()); assert!(outputs <= length); let mut e = Vec::new(); let global_x_offset = locomotives * 7; // electric poles for l in 1..=(length + locomotives) { e.push( BlueprintEntity::builder( "medium-electric-pole".to_owned(), l as u32 - 1, BlueprintPosition::new((7 * l) as f64 + 0.5, -1.5), ) .build(), ); } // unloader let offset = e.len(); for l in 0..length { e.extend(unloader.iter().cloned().map(|mut e| { e.position.x += (7 * l + global_x_offset) as f64; e.entity_number += (offset + unloader.len() * l) as u32; e })); } // train stop let offset = e.len(); e.push( BlueprintEntity::builder( "train-stop".to_owned(), offset as u32, BlueprintPosition::new(1.0, -1.0), ) .direction(12) .build(), ); // rails for l in 0..((length * 7 + global_x_offset + 1) / 2) { let offset = e.len() as u32; e.push( BlueprintEntity::builder( "straight-rail".to_owned(), offset, BlueprintPosition::new(2.0 * l as f64 + 1.0, 1.0), ) .direction(4) .build(), ); } // 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 { let offset = e.len() as u32; e.push( BlueprintEntity::builder( stubspeed.string(), offset, BlueprintPosition::new( (7 * (i + o * section_size) + global_x_offset) as f64 + output_x, output_y - j as f64, ), ) .build(), ); } let offset = e.len() as u32; e.push( BlueprintEntity::builder( stubspeed.string(), offset, BlueprintPosition::new( (7 * (i + o * section_size) + global_x_offset) as f64 + output_x, output_y - depth as f64, ), ) .direction(12) .build(), ); } // 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; let offset = e.len() as u32; e.push( BlueprintEntity::builder( mergespeed.string_splitter(), offset, BlueprintPosition::new( (7 * (j * p + o * section_size) + global_x_offset) as f64 - i as f64 + output_x, output_y - i as f64 + 0.5 - depth as f64, ), ) .direction(12) .build(), ); e.extend((0..(7 * p / 2)).map(|l| { BlueprintEntity::builder( mergespeed.halve().string(), offset + 1 + l as u32, BlueprintPosition::new( (7 * (j * p + o * section_size) + global_x_offset) as f64 - i as f64 + output_x + l as f64 + 1.0, output_y - i as f64 - depth as f64, ), ) .direction(12) .build() })); } } // connect let offset = e.len() as u32; let step = o + section_size.ilog2() as usize; e.extend((0..(7 * o * section_size)).map(|l| { BlueprintEntity::builder( beltspeed.string(), offset + l as u32, BlueprintPosition::new( (l + global_x_offset) as f64 + output_x - section_size.ilog2() as f64, output_y - step as f64, ), ) .direction(12) .build() })); } Blueprint::builder() .label("station".to_owned()) .entities(e) .wires( (0..((length + locomotives - 1) as u32)) .map(|i| [i, 5, i + 1, 5]) .collect(), ) .build() } pub fn unloader(beltspeed: Beltspeed, belttype: Belttype) -> (Vec, f64) { match beltspeed { Beltspeed::Normal => { let mut e = vec![BlueprintEntity::builder( "fast-transport-belt".to_owned(), 0, BlueprintPosition::new(3.5, -1.5), ) .build()]; if belttype.contains_left() { let offset = e.len() as u32; e.extend_from_slice(&[ BlueprintEntity::builder( "steel-chest".to_owned(), offset, BlueprintPosition::new(5.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 1, BlueprintPosition::new(5.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-inserter".to_owned(), offset + 2, BlueprintPosition::new(4.5, -1.5), ) .direction(4) .build(), ]); } if belttype.contains_right() { let offset = e.len() as u32; e.extend_from_slice(&[ BlueprintEntity::builder( "steel-chest".to_owned(), offset, BlueprintPosition::new(1.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 1, BlueprintPosition::new(1.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-inserter".to_owned(), offset + 2, BlueprintPosition::new(2.5, -1.5), ) .direction(12) .build(), ]); } (e, -2.5) } Beltspeed::Fast => { let mut e = vec![BlueprintEntity::builder( "fast-transport-belt".to_owned(), 0, BlueprintPosition::new(3.5, -3.5), ) .build()]; if belttype.contains_left() { let offset = e.len() as u32; e.extend_from_slice(&[ BlueprintEntity::builder( "steel-chest".to_owned(), offset, BlueprintPosition::new(1.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 1, BlueprintPosition::new(1.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-inserter".to_owned(), offset + 2, BlueprintPosition::new(1.5, -2.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-transport-belt".to_owned(), offset + 3, BlueprintPosition::new(1.5, -3.5), ) .direction(4) .build(), BlueprintEntity::builder( "steel-chest".to_owned(), offset + 4, BlueprintPosition::new(2.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 5, BlueprintPosition::new(2.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-inserter".to_owned(), offset + 6, BlueprintPosition::new(2.5, -2.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-transport-belt".to_owned(), offset + 7, BlueprintPosition::new(2.5, -3.5), ) .direction(4) .build(), ]); } if belttype.contains_right() { let offset = e.len() as u32; e.extend_from_slice(&[ BlueprintEntity::builder( "steel-chest".to_owned(), offset, BlueprintPosition::new(4.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 1, BlueprintPosition::new(4.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-inserter".to_owned(), offset + 2, BlueprintPosition::new(4.5, -2.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-transport-belt".to_owned(), offset + 3, BlueprintPosition::new(4.5, -3.5), ) .direction(12) .build(), BlueprintEntity::builder( "steel-chest".to_owned(), offset + 4, BlueprintPosition::new(5.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 5, BlueprintPosition::new(5.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-inserter".to_owned(), offset + 6, BlueprintPosition::new(5.5, -2.5), ) .direction(8) .build(), BlueprintEntity::builder( "fast-transport-belt".to_owned(), offset + 7, BlueprintPosition::new(5.5, -3.5), ) .direction(12) .build(), ]); } (e, -4.5) } Beltspeed::Express => { let mut e = vec![BlueprintEntity::builder( "express-transport-belt".to_owned(), 0, BlueprintPosition::new(3.5, -3.5), ) .build()]; if belttype.contains_left() { let offset = e.len() as u32; e.extend_from_slice(&[ BlueprintEntity::builder( "steel-chest".to_owned(), offset, BlueprintPosition::new(1.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 1, BlueprintPosition::new(1.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 2, BlueprintPosition::new(1.5, -2.5), ) .direction(8) .override_stack_size(8) .build(), BlueprintEntity::builder( "express-transport-belt".to_owned(), offset + 3, BlueprintPosition::new(1.5, -3.5), ) .direction(4) .build(), BlueprintEntity::builder( "steel-chest".to_owned(), offset + 4, BlueprintPosition::new(2.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 5, BlueprintPosition::new(2.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 6, BlueprintPosition::new(2.5, -2.5), ) .direction(8) .override_stack_size(8) .build(), BlueprintEntity::builder( "express-transport-belt".to_owned(), offset + 7, BlueprintPosition::new(2.5, -3.5), ) .direction(4) .build(), ]); } if belttype.contains_right() { let offset = e.len() as u32; e.extend_from_slice(&[ BlueprintEntity::builder( "steel-chest".to_owned(), offset, BlueprintPosition::new(4.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 1, BlueprintPosition::new(4.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 2, BlueprintPosition::new(4.5, -2.5), ) .direction(8) .override_stack_size(8) .build(), BlueprintEntity::builder( "express-transport-belt".to_owned(), offset + 3, BlueprintPosition::new(4.5, -3.5), ) .direction(12) .build(), BlueprintEntity::builder( "steel-chest".to_owned(), offset + 4, BlueprintPosition::new(5.5, -1.5), ) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 5, BlueprintPosition::new(5.5, -0.5), ) .direction(8) .build(), BlueprintEntity::builder( "bulk-inserter".to_owned(), offset + 6, BlueprintPosition::new(5.5, -2.5), ) .direction(8) .override_stack_size(8) .build(), BlueprintEntity::builder( "express-transport-belt".to_owned(), offset + 7, BlueprintPosition::new(5.5, -3.5), ) .direction(12) .build(), ]); } (e, -4.5) } Beltspeed::Turbo => (Vec::new(), -4.5), } } pub fn basic_unload_station( locomotives: usize, length: usize, outputs: usize, beltspeed: Beltspeed, belttype: Belttype, ) -> Blueprint { let (unloader, output_y) = unloader( beltspeed.halvings((length / outputs).ilog2() as usize), belttype, ); station_unload( length, locomotives, &unloader, beltspeed, outputs, 3.5, output_y, ) }