Add train generation and builder for blueprints
This commit is contained in:
parent
3ec2d34f65
commit
6ac0cab8d5
7 changed files with 338 additions and 18 deletions
95
Cargo.lock
generated
95
Cargo.lock
generated
|
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
|
|
@ -225,6 +225,31 @@ version = "2.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b81e1519b0d82120d2fd469d5bfb2919a9361c48b02d82d04befc1cdd2002452"
|
checksum = "b81e1519b0d82120d2fd469d5bfb2919a9361c48b02d82d04befc1cdd2002452"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bon"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a636f83af97c6946f3f5cf5c268ec02375bf5efd371110292dfd57961f57a509"
|
||||||
|
dependencies = [
|
||||||
|
"bon-macros",
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bon-macros"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7eaf1bfaa5b8d512abfd36d0c432591fef139d3de9ee54f1f839ea109d70d33"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"ident_case",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "built"
|
name = "built"
|
||||||
version = "0.7.4"
|
version = "0.7.4"
|
||||||
|
|
@ -448,6 +473,41 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
|
@ -491,6 +551,7 @@ name = "factorio_blueprint"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
|
"bon",
|
||||||
"clap 4.5.17",
|
"clap 4.5.17",
|
||||||
"criterion",
|
"criterion",
|
||||||
"flate2",
|
"flate2",
|
||||||
|
|
@ -609,6 +670,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.25.2"
|
version = "0.25.2"
|
||||||
|
|
@ -1029,10 +1096,20 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "prettyplease"
|
||||||
version = "1.0.86"
|
version = "0.2.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
@ -1282,6 +1359,12 @@ dependencies = [
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusty-fork"
|
name = "rusty-fork"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -1450,9 +1533,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.77"
|
version = "2.0.89"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64 = "0.21.5"
|
base64 = "0.21.5"
|
||||||
|
bon = "3.0.2"
|
||||||
clap = { version = "4.4.8", features = ["derive"] }
|
clap = { version = "4.4.8", features = ["derive"] }
|
||||||
flate2 = "1.0.28"
|
flate2 = "1.0.28"
|
||||||
image = "0.25.2"
|
image = "0.25.2"
|
||||||
|
|
|
||||||
14
examples/train_blueprint.rs
Normal file
14
examples/train_blueprint.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
use factorio_blueprint::blueprint::{train::generate_train, BlueprintString};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let b = generate_train(2, 4, true, true);
|
||||||
|
|
||||||
|
let b = BlueprintString::Blueprint(b);
|
||||||
|
|
||||||
|
println!("{}", serde_json::to_string_pretty(&b).unwrap());
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
factorio_blueprint::blueprint::encode(&serde_json::to_string(&b).unwrap())
|
||||||
|
);
|
||||||
|
}
|
||||||
29
src/bin/decode_blueprint.rs
Normal file
29
src/bin/decode_blueprint.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use base64::prelude::*;
|
||||||
|
use clap::Parser;
|
||||||
|
use factorio_blueprint::blueprint::{decode, encode};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
struct Args {
|
||||||
|
filename: PathBuf,
|
||||||
|
#[arg(short, long)]
|
||||||
|
encode: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let s = std::fs::read_to_string(args.filename).unwrap();
|
||||||
|
|
||||||
|
if args.encode {
|
||||||
|
let j: serde_json::Value = serde_json::from_str(&s).unwrap();
|
||||||
|
let d = encode(&serde_json::to_string(&j).unwrap());
|
||||||
|
println!("{}", d);
|
||||||
|
} else {
|
||||||
|
let d = decode(&s);
|
||||||
|
|
||||||
|
let j: serde_json::Value = serde_json::from_str(&d).unwrap();
|
||||||
|
|
||||||
|
println!("{}", serde_json::to_string_pretty(&j).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use base64::engine::general_purpose::STANDARD;
|
use base64::engine::general_purpose::STANDARD;
|
||||||
|
use base64::prelude::BASE64_STANDARD;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
@ -7,11 +8,13 @@ pub mod structs;
|
||||||
|
|
||||||
pub use structs::*;
|
pub use structs::*;
|
||||||
|
|
||||||
|
pub mod train;
|
||||||
|
|
||||||
pub fn decode(s: &str) -> String {
|
pub fn decode(s: &str) -> String {
|
||||||
let raw = s.as_bytes();
|
let raw = s.trim().as_bytes();
|
||||||
assert!(raw[0] == b'0');
|
assert!(raw[0] == b'0');
|
||||||
|
|
||||||
let u = STANDARD.decode(&raw[1..]).unwrap();
|
let u = BASE64_STANDARD.decode(&raw[1..]).unwrap();
|
||||||
|
|
||||||
let mut o = String::new();
|
let mut o = String::new();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use bon::Builder;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
|
@ -28,63 +29,164 @@ pub struct BlueprintBookEntry {
|
||||||
index: u32,
|
index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Builder)]
|
||||||
pub struct Blueprint {
|
pub struct Blueprint {
|
||||||
|
#[builder(skip = "blueprint".to_owned())]
|
||||||
item: String,
|
item: String,
|
||||||
label: Option<String>,
|
label: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
label_color: Option<BlueprintColor>,
|
label_color: Option<BlueprintColor>,
|
||||||
#[serde(default)]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
#[builder(default)]
|
||||||
entities: Vec<BlueprintEntity>,
|
entities: Vec<BlueprintEntity>,
|
||||||
#[serde(default)]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
#[builder(default)]
|
||||||
tiles: Vec<BlueprintTile>,
|
tiles: Vec<BlueprintTile>,
|
||||||
#[serde(default)]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
#[builder(default)]
|
||||||
icons: Vec<BlueprintIcon>,
|
icons: Vec<BlueprintIcon>,
|
||||||
#[serde(default)]
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
#[builder(default)]
|
||||||
schedules: Vec<BlueprintSchedule>,
|
schedules: Vec<BlueprintSchedule>,
|
||||||
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||||
|
#[builder(default)]
|
||||||
|
stock_connections: Vec<BlueprintStockConnection>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
snap_to_grid: Option<BlueprintPosition>,
|
snap_to_grid: Option<BlueprintPosition>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
absolute_snapping: Option<bool>,
|
absolute_snapping: Option<bool>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
position_relative_to_grid: Option<BlueprintPosition>,
|
position_relative_to_grid: Option<BlueprintPosition>,
|
||||||
version: u64,
|
version: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug, Builder)]
|
||||||
|
pub struct BlueprintStockConnection {
|
||||||
|
#[builder(start_fn)]
|
||||||
|
stock: u32,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
front: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
back: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Builder)]
|
||||||
pub struct BlueprintEntity {
|
pub struct BlueprintEntity {
|
||||||
entity_number: u64,
|
#[builder(start_fn)]
|
||||||
name: String,
|
name: String,
|
||||||
|
#[builder(start_fn)]
|
||||||
|
entity_number: u32,
|
||||||
|
#[builder(start_fn)]
|
||||||
position: BlueprintPosition,
|
position: BlueprintPosition,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
direciton: Option<u8>,
|
direciton: Option<u8>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
orientation: Option<f32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
connections: Option<BlueprintConnection>,
|
connections: Option<BlueprintConnection>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
neighbours: Option<Vec<u64>>,
|
neighbours: Option<Vec<u64>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
control_behaviour: Option<()>,
|
control_behaviour: Option<()>,
|
||||||
items: Option<HashMap<String, u32>>,
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
items: Option<Vec<BlueprintItemRequest>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
recipe: Option<String>,
|
recipe: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
bar: Option<u64>,
|
bar: Option<u64>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
inventory: Option<BlueprintInventory>,
|
inventory: Option<BlueprintInventory>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
infinity_settings: Option<()>,
|
infinity_settings: Option<()>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
|
||||||
underground_type: Option<String>,
|
underground_type: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
input_priority: Option<String>,
|
input_priority: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
output_priority: Option<String>,
|
output_priority: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
filter: Option<String>,
|
filter: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
filters: Option<Vec<BlueprintItemFilter>>,
|
filters: Option<Vec<BlueprintItemFilter>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
filter_mode: Option<String>,
|
filter_mode: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
override_stack_size: Option<u8>,
|
override_stack_size: Option<u8>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
drop_position: Option<BlueprintPosition>,
|
drop_position: Option<BlueprintPosition>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pickup_position: Option<BlueprintPosition>,
|
pickup_position: Option<BlueprintPosition>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
request_filters: Option<Vec<BlueprintLogisticFilter>>,
|
request_filters: Option<Vec<BlueprintLogisticFilter>>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
request_from_buffers: Option<bool>,
|
request_from_buffers: Option<bool>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
parameters: Option<BlueprintSpeakerParameter>,
|
parameters: Option<BlueprintSpeakerParameter>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
alert_parameters: Option<BlueprintSpeakerAlertParameter>,
|
alert_parameters: Option<BlueprintSpeakerAlertParameter>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
auto_launch: Option<bool>,
|
auto_launch: Option<bool>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
variation: Option<u8>,
|
variation: Option<u8>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
color: Option<BlueprintColor>,
|
color: Option<BlueprintColor>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
station: Option<String>,
|
station: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
manuel_trains_limit: Option<u32>,
|
manuel_trains_limit: Option<u32>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
switch_state: Option<bool>,
|
switch_state: Option<bool>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
tags: Option<serde_json::Value>,
|
tags: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct BlueprintItemRequest {
|
||||||
|
id: BlueprintItemID,
|
||||||
|
items: BlueprintItem,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlueprintItemRequest {
|
||||||
|
pub fn new(id: BlueprintItemID, items: Vec<BlueprintInventoryLocation>) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
items: BlueprintItem {
|
||||||
|
in_inventory: items,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Builder)]
|
||||||
|
pub struct BlueprintItemID {
|
||||||
|
#[builder(start_fn)]
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct BlueprintItem {
|
||||||
|
in_inventory: Vec<BlueprintInventoryLocation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct BlueprintInventoryLocation {
|
||||||
|
count: u32,
|
||||||
|
inventory: u32,
|
||||||
|
stack: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlueprintInventoryLocation {
|
||||||
|
pub fn new(count: u32, inventory: u32, stack: u32) -> Self {
|
||||||
|
Self {
|
||||||
|
count,
|
||||||
|
inventory,
|
||||||
|
stack,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct BlueprintInventory {
|
pub struct BlueprintInventory {
|
||||||
filters: Vec<BlueprintItemFilter>,
|
filters: Vec<BlueprintItemFilter>,
|
||||||
|
|
@ -154,6 +256,12 @@ pub struct BlueprintPosition {
|
||||||
y: f64,
|
y: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BlueprintPosition {
|
||||||
|
pub fn new(x: f64, y: f64) -> Self {
|
||||||
|
BlueprintPosition { x, y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct BlueprintIcon {
|
pub struct BlueprintIcon {
|
||||||
index: u32,
|
index: u32,
|
||||||
|
|
|
||||||
82
src/blueprint/train.rs
Normal file
82
src/blueprint/train.rs
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
use super::{
|
||||||
|
Blueprint, BlueprintEntity, BlueprintInventoryLocation, BlueprintItemID, BlueprintItemRequest,
|
||||||
|
BlueprintPosition, BlueprintStockConnection,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn generate_train(locomotives: u32, wagons: u32, rails: bool, fluid: bool) -> Blueprint {
|
||||||
|
let mut e = Vec::new();
|
||||||
|
|
||||||
|
for i in 0..locomotives {
|
||||||
|
e.push(
|
||||||
|
BlueprintEntity::builder(
|
||||||
|
"locomotive".to_owned(),
|
||||||
|
i + 1,
|
||||||
|
BlueprintPosition::new(1.0, 3.5 + 7.0 * i as f64),
|
||||||
|
)
|
||||||
|
.items(vec![BlueprintItemRequest::new(
|
||||||
|
BlueprintItemID::builder("rocket-fuel".to_owned()).build(),
|
||||||
|
vec![BlueprintInventoryLocation::new(5, 1, 0)],
|
||||||
|
)])
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..wagons {
|
||||||
|
e.push(
|
||||||
|
BlueprintEntity::builder(
|
||||||
|
if fluid {
|
||||||
|
"fluid-wagon".to_owned()
|
||||||
|
} else {
|
||||||
|
"cargo-wagon".to_owned()
|
||||||
|
},
|
||||||
|
locomotives + i + 1,
|
||||||
|
BlueprintPosition::new(1.0, 3.5 + 7.0 * (locomotives + i) as f64),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if rails {
|
||||||
|
for i in 0..((locomotives + wagons) * 7).div_ceil(2) {
|
||||||
|
e.push(
|
||||||
|
BlueprintEntity::builder(
|
||||||
|
"straight-rail".to_owned(),
|
||||||
|
locomotives + wagons + i + 1,
|
||||||
|
BlueprintPosition::new(1.0, 1.0 + 2.0 * i as f64),
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut stock_connections = Vec::new();
|
||||||
|
|
||||||
|
if locomotives + wagons > 1 {
|
||||||
|
stock_connections.push(BlueprintStockConnection::builder(1).back(2).build());
|
||||||
|
for i in 2..=(locomotives + wagons - 1) {
|
||||||
|
stock_connections.push(
|
||||||
|
BlueprintStockConnection::builder(i)
|
||||||
|
.front(i - 1)
|
||||||
|
.back(i + 1)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
stock_connections.push(
|
||||||
|
BlueprintStockConnection::builder(locomotives + wagons)
|
||||||
|
.front(locomotives + wagons - 1)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Blueprint::builder()
|
||||||
|
.label("train".to_string())
|
||||||
|
.entities(e)
|
||||||
|
.stock_connections(stock_connections)
|
||||||
|
.version(562949954797573)
|
||||||
|
.snap_to_grid(BlueprintPosition::new(
|
||||||
|
4.0,
|
||||||
|
2.0 * ((locomotives + wagons) * 7).div_ceil(2) as f64,
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue