294 lines
8.7 KiB
Rust
294 lines
8.7 KiB
Rust
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
|
|
}
|