Refactor StationSpec

This commit is contained in:
hal8174 2025-05-10 22:22:35 +02:00
parent a98e2cfb2b
commit d26449195b
5 changed files with 570 additions and 410 deletions

View file

@ -1,25 +1,11 @@
use crate::{
balancer::binary_balancer,
station::{StationBasicSpec, basic_station},
station::{StationSpec, station},
};
use factorio_blueprint::abstraction::{
Blueprint, ElectricPoleType, Entity, RailType, UndergroundType,
};
use factorio_core::{
beltoptions::{Beltspeed, Belttype},
prelude::*,
};
#[derive(Debug, Clone)]
pub struct StationSpec {
pub locomotives: usize,
pub wagons: usize,
pub load: bool,
pub beltspeed: Beltspeed,
pub lanes: usize,
pub belttype: Belttype,
pub stacked: bool,
}
use factorio_core::{beltoptions::Beltspeed, prelude::*};
fn calculate_station_height(
output_height: PositionType,
@ -53,11 +39,10 @@ fn calculate_station_height(
pub fn multistation(
stations: &[StationSpec],
stacker_size: usize,
basic_spec: &StationBasicSpec,
) -> (Blueprint, PositionType, Vec<PositionType>) {
let longest_train = stations
.iter()
.map(|s| s.locomotives + s.wagons)
.map(|s| s.train_information.locomotives + s.train_information.wagons)
.max()
.unwrap();
@ -167,7 +152,7 @@ pub fn multistation(
let mut output_heights = Vec::new();
let mut previous_station_heights = 0;
// station
for (i, station) in stations.iter().enumerate() {
for (i, station_spec) in stations.iter().enumerate() {
// in turn
blueprint.add_entity(Entity::new_rail(
RailType::CurvedA,
@ -253,7 +238,9 @@ pub fn multistation(
));
for j in 0..((7 * longest_train).div_ceil(2)
- (7 * (station.locomotives + station.wagons)).div_ceil(2))
- (7 * (station_spec.train_information.locomotives
+ station_spec.train_information.wagons))
.div_ceil(2))
{
blueprint.add_entity(Entity::new_rail(
RailType::Straight,
@ -266,7 +253,7 @@ pub fn multistation(
}
// station
let mut b = basic_station(station, basic_spec);
let mut b = station(station_spec);
let output_height = -b.bounding_box().min().y;
b.transform(Transformation::new(
@ -279,104 +266,259 @@ pub fn multistation(
blueprint.add_blueprint(b);
// belt output
let station_height =
calculate_station_height(output_height, station.lanes, station.beltspeed);
let station_height = match &station_spec.station_type {
crate::station::StationType::Empty(station_type_empty) => 4 + station_type_empty.space,
crate::station::StationType::Belt(station_type_belt) => {
// belt output
let station_height = calculate_station_height(
output_height,
station_type_belt.lanes,
station_type_belt.beltspeed,
);
output_heights.push(30 + total_stacker_height + previous_station_heights + output_height);
output_heights
.push(30 + total_stacker_height + previous_station_heights + output_height);
// rail crossing
let (beltdirection, underground_left, underground_right) = match station.load {
true => (
Direction::Left,
UndergroundType::Output,
UndergroundType::Input,
),
false => (
Direction::Right,
UndergroundType::Input,
UndergroundType::Output,
),
};
let mut belt_x = outrail_x - 28 - 14 * station.locomotives as PositionType - 3
+ 2 * (station.wagons / station.lanes).ilog2() as PositionType;
let (balancer_length, mut b) = binary_balancer(station.lanes, station.beltspeed);
if station.load {
b.transform(Transformation::new(
Direction::Down,
Position::new(balancer_length, 2 * station.lanes as PositionType),
));
}
b.transform(Transformation::new(
Direction::Up,
Position::new(
belt_x - 1,
31 + total_stacker_height + previous_station_heights + output_height
- 2 * station.lanes as PositionType,
),
));
blueprint.add_blueprint(b);
belt_x += balancer_length;
for j in 0..station.lanes {
let (underground_x, signal) = match station_height
- (output_height - 2 * j as PositionType)
{
5 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 23,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
// rail crossing
let (beltdirection, underground_left, underground_right) =
match station_type_belt.load {
true => (
Direction::Left,
UndergroundType::Output,
UndergroundType::Input,
),
beltdirection,
));
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_right,
Position::new(
outrail_x - 9,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
false => (
Direction::Right,
UndergroundType::Input,
UndergroundType::Output,
),
beltdirection,
};
let mut belt_x = outrail_x
- 28
- 14 * station_spec.train_information.locomotives as PositionType
- 3
+ 2 * (station_spec.train_information.wagons / station_type_belt.lanes).ilog2()
as PositionType;
let (balancer_length, mut b) =
binary_balancer(station_type_belt.lanes, station_type_belt.beltspeed);
if station_type_belt.load {
b.transform(Transformation::new(
Direction::Down,
Position::new(balancer_length, 2 * station_type_belt.lanes as PositionType),
));
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 7,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 23, false)
}
7 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 17,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
if station.beltspeed != Beltspeed::Turbo {
b.transform(Transformation::new(
Direction::Up,
Position::new(
belt_x - 1,
31 + total_stacker_height + previous_station_heights + output_height
- 2 * station_type_belt.lanes as PositionType,
),
));
blueprint.add_blueprint(b);
belt_x += balancer_length;
for j in 0..station_type_belt.lanes {
let (underground_x, signal) =
match station_height - (output_height - 2 * j as PositionType) {
5 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 23,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_right,
Position::new(
outrail_x - 9,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 7,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 23, false)
}
7 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 17,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
if station_type_belt.beltspeed != Beltspeed::Turbo {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_right,
Position::new(
outrail_x - 7,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 5,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
}
(outrail_x - 17, false)
}
9 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 15,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 15, false)
}
11 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 11,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 11, false)
}
13 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 9,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 9, false)
}
15 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 9,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 9, true)
}
17 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 7,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 7, false)
}
19 | 21 | 23 => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 5,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 5, false)
}
_ => {
blueprint.add_entity(Entity::new_underground_belt(
station_type_belt.beltspeed,
underground_left,
Position::new(
outrail_x - 3,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 3, false)
}
};
if signal {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
station_type_belt.beltspeed,
underground_right,
Position::new(
outrail_x - 7,
outrail_x + 5,
30 + total_stacker_height
+ previous_station_heights
+ output_height
@ -384,11 +526,23 @@ pub fn multistation(
),
beltdirection,
));
} else {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
station_type_belt.beltspeed,
underground_right,
Position::new(
outrail_x - 5,
outrail_x + 3,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
blueprint.add_entity(Entity::new_belt(
station_type_belt.beltspeed,
Position::new(
outrail_x + 5,
30 + total_stacker_height
+ previous_station_heights
+ output_height
@ -397,146 +551,24 @@ pub fn multistation(
beltdirection,
));
}
(outrail_x - 17, false)
}
9 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 15,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 15, false)
}
11 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 11,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 11, false)
}
13 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 9,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 9, false)
}
15 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 9,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 9, true)
}
17 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 7,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 7, false)
}
19 | 21 | 23 => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 5,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 5, false)
}
_ => {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_left,
Position::new(
outrail_x - 3,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
(outrail_x - 3, false)
}
};
if signal {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_right,
Position::new(
outrail_x + 5,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
} else {
blueprint.add_entity(Entity::new_underground_belt(
station.beltspeed,
underground_right,
Position::new(
outrail_x + 3,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
blueprint.add_entity(Entity::new_belt(
station.beltspeed,
Position::new(
outrail_x + 5,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
for l in 0..((underground_x - belt_x) / 2) {
blueprint.add_entity(Entity::new_belt(
station_type_belt.beltspeed,
Position::new(
belt_x + 2 * l,
30 + total_stacker_height
+ previous_station_heights
+ output_height
- 2 * j as PositionType,
),
beltdirection,
));
}
}
station_height
}
for l in 0..((underground_x - belt_x) / 2) {
blueprint.add_entity(Entity::new_belt(
station.beltspeed,
Position::new(
belt_x + 2 * l,
30 + total_stacker_height + previous_station_heights + output_height
- 2 * j as PositionType,
),
beltdirection,
));
}
}
};
// rail connection
if i != stations.len() - 1 {