1039 lines
38 KiB
Rust
1039 lines
38 KiB
Rust
#![allow(clippy::module_name_repetitions, clippy::enum_glob_use)]
|
|
|
|
use std::{
|
|
collections::BTreeMap,
|
|
io::{BufWriter, Write},
|
|
path::PathBuf,
|
|
};
|
|
|
|
use quote::quote;
|
|
use serde_derive::{Deserialize, Serialize};
|
|
|
|
use crate::{
|
|
enums,
|
|
stationpedia::{self, Memory, Page, Stationpedia},
|
|
};
|
|
|
|
use stationeers_data::{
|
|
enums::MemoryAccess,
|
|
templates::{
|
|
ConnectionInfo, ConsumerInfo, DeviceInfo, Instruction, InternalAtmoInfo,
|
|
ItemCircuitHolderTemplate, ItemConsumerTemplate, ItemInfo, ItemLogicMemoryTemplate,
|
|
ItemLogicTemplate, ItemSlotsTemplate, ItemSuitCircuitHolderTemplate, ItemSuitLogicTemplate,
|
|
ItemSuitTemplate, ItemTemplate, LogicInfo, MemoryInfo, ObjectTemplate, PrefabInfo,
|
|
SlotInfo, StructureCircuitHolderTemplate, StructureInfo,
|
|
StructureLogicDeviceConsumerMemoryTemplate, StructureLogicDeviceConsumerTemplate,
|
|
StructureLogicDeviceMemoryTemplate, StructureLogicDeviceTemplate, StructureLogicTemplate,
|
|
StructureSlotsTemplate, StructureTemplate, SuitInfo, ThermalInfo,
|
|
},
|
|
};
|
|
|
|
#[allow(clippy::too_many_lines)]
|
|
pub fn generate_database(
|
|
stationpedia: &stationpedia::Stationpedia,
|
|
enums: &enums::Enums,
|
|
workspace: &std::path::Path,
|
|
) -> color_eyre::Result<Vec<PathBuf>> {
|
|
let templates = generate_templates(stationpedia);
|
|
|
|
eprintln!("Writing prefab database ...");
|
|
|
|
let prefabs: BTreeMap<String, ObjectTemplate> = templates
|
|
.into_iter()
|
|
.map(|obj| (obj.prefab().prefab_name.clone(), obj))
|
|
.collect();
|
|
let prefabs_by_hash: BTreeMap<i32, String> = prefabs
|
|
.iter()
|
|
.map(|(key, val)| (val.prefab().prefab_hash, key.clone()))
|
|
.collect();
|
|
|
|
let structures = prefabs
|
|
.iter()
|
|
.filter_map(|(_, val)| {
|
|
use ObjectTemplate::*;
|
|
match val {
|
|
Structure(_)
|
|
| StructureSlots(_)
|
|
| StructureLogic(_)
|
|
| StructureLogicDevice(_)
|
|
| StructureCircuitHolder(_)
|
|
| StructureLogicDeviceConsumer(_)
|
|
| StructureLogicDeviceMemory(_)
|
|
| StructureLogicDeviceConsumerMemory(_) => Some(val.prefab().prefab_name.clone()),
|
|
Item(_)
|
|
| ItemSlots(_)
|
|
| ItemConsumer(_)
|
|
| ItemLogic(_)
|
|
| ItemCircuitHolder(_)
|
|
| ItemLogicMemory(_)
|
|
| ItemSuit(_)
|
|
| ItemSuitLogic(_)
|
|
| ItemSuitCircuitHolder(_) => None,
|
|
}
|
|
})
|
|
.collect();
|
|
let items = prefabs
|
|
.iter()
|
|
.filter_map(|(_, val)| {
|
|
use ObjectTemplate::*;
|
|
match val {
|
|
Structure(_)
|
|
| StructureSlots(_)
|
|
| StructureLogic(_)
|
|
| StructureLogicDevice(_)
|
|
| StructureCircuitHolder(_)
|
|
| StructureLogicDeviceConsumer(_)
|
|
| StructureLogicDeviceMemory(_)
|
|
| StructureLogicDeviceConsumerMemory(_) => None,
|
|
Item(_)
|
|
| ItemSlots(_)
|
|
| ItemConsumer(_)
|
|
| ItemLogic(_)
|
|
| ItemCircuitHolder(_)
|
|
| ItemLogicMemory(_)
|
|
| ItemSuit(_)
|
|
| ItemSuitLogic(_)
|
|
| ItemSuitCircuitHolder(_) => Some(val.prefab().prefab_name.clone()),
|
|
}
|
|
})
|
|
.collect();
|
|
let logicable_items = prefabs
|
|
.iter()
|
|
.filter_map(|(_, val)| {
|
|
use ObjectTemplate::*;
|
|
match val {
|
|
Structure(_)
|
|
| StructureSlots(_)
|
|
| StructureLogic(_)
|
|
| StructureLogicDevice(_)
|
|
| StructureCircuitHolder(_)
|
|
| StructureLogicDeviceConsumer(_)
|
|
| StructureLogicDeviceMemory(_)
|
|
| StructureLogicDeviceConsumerMemory(_)
|
|
| Item(_)
|
|
| ItemSlots(_)
|
|
| ItemSuit(_)
|
|
| ItemConsumer(_) => None,
|
|
ItemLogic(_)
|
|
| ItemCircuitHolder(_)
|
|
| ItemLogicMemory(_)
|
|
| ItemSuitLogic(_)
|
|
| ItemSuitCircuitHolder(_) => Some(val.prefab().prefab_name.clone()),
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
let devices = prefabs
|
|
.iter()
|
|
.filter_map(|(_, val)| {
|
|
use ObjectTemplate::*;
|
|
match val {
|
|
Structure(_)
|
|
| StructureSlots(_)
|
|
| StructureLogic(_)
|
|
| Item(_)
|
|
| ItemSlots(_)
|
|
| ItemConsumer(_)
|
|
| ItemLogic(_)
|
|
| ItemCircuitHolder(_)
|
|
| ItemLogicMemory(_)
|
|
| ItemSuit(_)
|
|
| ItemSuitLogic(_)
|
|
| ItemSuitCircuitHolder(_) => None,
|
|
StructureLogicDevice(_)
|
|
| StructureCircuitHolder(_)
|
|
| StructureLogicDeviceMemory(_)
|
|
| StructureLogicDeviceConsumer(_)
|
|
| StructureLogicDeviceConsumerMemory(_) => Some(val.prefab().prefab_name.clone()),
|
|
}
|
|
})
|
|
.collect();
|
|
let suits = prefabs
|
|
.iter()
|
|
.filter_map(|(_, val)| {
|
|
use ObjectTemplate::*;
|
|
match val {
|
|
ItemSuitCircuitHolder(_) | ItemSuitLogic(_) | ItemSuit(_) => {
|
|
Some(val.prefab().prefab_name.clone())
|
|
}
|
|
_ => None,
|
|
}
|
|
})
|
|
.collect();
|
|
let circuit_holders = prefabs
|
|
.iter()
|
|
.filter_map(|(_, val)| {
|
|
use ObjectTemplate::*;
|
|
match val {
|
|
ItemSuitCircuitHolder(_) | ItemCircuitHolder(_) | StructureCircuitHolder(_) => {
|
|
Some(val.prefab().prefab_name.clone())
|
|
}
|
|
_ => None,
|
|
}
|
|
})
|
|
.collect();
|
|
let db: ObjectDatabase = ObjectDatabase {
|
|
prefabs,
|
|
reagents: stationpedia.reagents.clone(),
|
|
enums: enums.clone(),
|
|
prefabs_by_hash,
|
|
structures,
|
|
devices,
|
|
items,
|
|
logicable_items,
|
|
suits,
|
|
circuit_holders,
|
|
};
|
|
|
|
let data_path = workspace.join("data");
|
|
if !data_path.exists() {
|
|
std::fs::create_dir(&data_path)?;
|
|
}
|
|
let database_path = data_path.join("database.json");
|
|
let mut database_file = std::io::BufWriter::new(std::fs::File::create(database_path)?);
|
|
serde_json::to_writer_pretty(&mut database_file, &db)?;
|
|
database_file.flush()?;
|
|
|
|
let prefab_map_path = workspace
|
|
.join("stationeers_data")
|
|
.join("src")
|
|
.join("database")
|
|
.join("prefab_map.rs");
|
|
let mut prefab_map_file = std::io::BufWriter::new(std::fs::File::create(&prefab_map_path)?);
|
|
write_prefab_map(&mut prefab_map_file, &db.prefabs)?;
|
|
|
|
Ok(vec![prefab_map_path])
|
|
}
|
|
|
|
fn write_prefab_map<T: std::io::Write>(
|
|
writer: &mut BufWriter<T>,
|
|
prefabs: &BTreeMap<String, ObjectTemplate>,
|
|
) -> color_eyre::Result<()> {
|
|
write!(
|
|
writer,
|
|
"{}",
|
|
quote! {
|
|
use crate::enums::script_enums::*;
|
|
use crate::enums::basic_enums::*;
|
|
use crate::enums::{MemoryAccess, ConnectionType, ConnectionRole};
|
|
use crate::templates::*;
|
|
}
|
|
)?;
|
|
let entries = prefabs
|
|
.values()
|
|
.map(|prefab| {
|
|
let hash = prefab.prefab().prefab_hash;
|
|
let obj = syn::parse_str::<syn::Expr>(&uneval::to_string(prefab)?)?;
|
|
let entry = quote! {
|
|
(
|
|
#hash,
|
|
#obj.into(),
|
|
)
|
|
};
|
|
Ok(entry)
|
|
})
|
|
.collect::<Result<Vec<_>, color_eyre::Report>>()?;
|
|
write!(
|
|
writer,
|
|
"{}",
|
|
quote! {
|
|
pub fn build_prefab_database() -> std::collections::BTreeMap<i32, crate::templates::ObjectTemplate> {
|
|
#[allow(clippy::unreadable_literal)]
|
|
std::collections::BTreeMap::from([
|
|
#(#entries),*
|
|
])
|
|
}
|
|
},
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
#[allow(clippy::too_many_lines)]
|
|
fn generate_templates(pedia: &Stationpedia) -> Vec<ObjectTemplate> {
|
|
println!("Generating templates ...");
|
|
let mut templates: Vec<ObjectTemplate> = Vec::new();
|
|
for page in &pedia.pages {
|
|
let prefab = PrefabInfo {
|
|
prefab_name: page.prefab_name.clone(),
|
|
prefab_hash: page.prefab_hash,
|
|
desc: page.description.clone(),
|
|
name: page.title.clone(),
|
|
};
|
|
// every page should either by a item or a structure
|
|
// in theory every device is logicable
|
|
// in theory everything with memory is logicable
|
|
match page {
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: None,
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if slot_inserts.is_empty() && item.suit.is_none() => {
|
|
templates.push(ObjectTemplate::Item(ItemTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
}));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: None,
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_none() => {
|
|
templates.push(ObjectTemplate::ItemSlots(ItemSlotsTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
}));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: None,
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
resource_consumer: Some(consumer),
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_none() => {
|
|
templates.push(ObjectTemplate::ItemConsumer(ItemConsumerTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
consumer_info: consumer.into(),
|
|
}));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: None,
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_some() => {
|
|
templates.push(ObjectTemplate::ItemSuit(ItemSuitTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
suit_info: item.suit.as_ref().unwrap().into(),
|
|
}));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_some() => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
|
|
templates.push(ObjectTemplate::ItemSuitLogic(ItemSuitLogicTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
suit_info: item.suit.as_ref().unwrap().into(),
|
|
}));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_none() => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
|
|
templates.push(ObjectTemplate::ItemLogic(ItemLogicTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
}));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: true,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_none() => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = true;
|
|
|
|
templates.push(ObjectTemplate::ItemCircuitHolder(
|
|
ItemCircuitHolderTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
},
|
|
));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: Some(memory),
|
|
device: None,
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: true,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_some() => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = true;
|
|
|
|
templates.push(ObjectTemplate::ItemSuitCircuitHolder(
|
|
ItemSuitCircuitHolderTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
suit_info: item.suit.as_ref().unwrap().into(),
|
|
memory: memory.into(),
|
|
},
|
|
));
|
|
}
|
|
Page {
|
|
item: Some(item),
|
|
structure: None,
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: Some(memory),
|
|
device: None,
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if item.suit.is_none() => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
|
|
templates.push(ObjectTemplate::ItemLogicMemory(ItemLogicMemoryTemplate {
|
|
prefab,
|
|
item: item.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
memory: memory.into(),
|
|
}));
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
slot_inserts,
|
|
logic_info: None,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} if slot_inserts.is_empty() => {
|
|
templates.push(ObjectTemplate::Structure(StructureTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
}));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
slot_inserts,
|
|
logic_info: None,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
templates.push(ObjectTemplate::StructureSlots(StructureSlotsTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
}));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: None,
|
|
device: None,
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
|
|
templates.push(ObjectTemplate::StructureLogic(StructureLogicTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
}));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: None,
|
|
device: Some(device),
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
|
|
templates.push(ObjectTemplate::StructureLogicDevice(
|
|
StructureLogicDeviceTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
device: device.into(),
|
|
},
|
|
));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
// NOTE: at the time of writing StructureCircuitHolder structure has a read write 0b memory, useless
|
|
// other holders have no memory
|
|
memory:
|
|
Some(Memory {
|
|
instructions: None,
|
|
memory_size: 0,
|
|
..
|
|
})
|
|
| None,
|
|
device: Some(device),
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: true,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = true;
|
|
|
|
templates.push(ObjectTemplate::StructureCircuitHolder(
|
|
StructureCircuitHolderTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
device: device.into(),
|
|
},
|
|
));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: None,
|
|
device: Some(device),
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: Some(consumer),
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
|
|
templates.push(ObjectTemplate::StructureLogicDeviceConsumer(
|
|
StructureLogicDeviceConsumerTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
device: device.into(),
|
|
consumer_info: consumer.into(),
|
|
},
|
|
));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: Some(memory),
|
|
device: Some(device),
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: None,
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
templates.push(ObjectTemplate::StructureLogicDeviceMemory(
|
|
StructureLogicDeviceMemoryTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
device: device.into(),
|
|
memory: memory.into(),
|
|
},
|
|
));
|
|
// println!("Structure")
|
|
}
|
|
Page {
|
|
item: None,
|
|
structure: Some(structure),
|
|
logic_info: Some(logic),
|
|
slot_inserts,
|
|
memory: Some(memory),
|
|
device: Some(device),
|
|
transmission_receiver,
|
|
wireless_logic,
|
|
circuit_holder: false,
|
|
resource_consumer: Some(consumer),
|
|
internal_atmosphere,
|
|
thermal,
|
|
..
|
|
} => {
|
|
let mut logic: LogicInfo = logic.into();
|
|
if !page.mode_insert.is_empty() {
|
|
logic.modes = Some(mode_inserts_to_info(&page.mode_insert));
|
|
}
|
|
logic.transmission_receiver = *transmission_receiver;
|
|
logic.wireless_logic = *wireless_logic;
|
|
logic.circuit_holder = false;
|
|
templates.push(ObjectTemplate::StructureLogicDeviceConsumerMemory(
|
|
StructureLogicDeviceConsumerMemoryTemplate {
|
|
prefab,
|
|
structure: structure.into(),
|
|
thermal_info: thermal.as_ref().map(Into::into),
|
|
internal_atmo_info: internal_atmosphere.as_ref().map(Into::into),
|
|
logic,
|
|
slots: slot_inserts_to_info(slot_inserts),
|
|
device: device.into(),
|
|
consumer_info: consumer.into(),
|
|
memory: memory.into(),
|
|
},
|
|
));
|
|
// println!("Structure")
|
|
}
|
|
_ => panic!(
|
|
"\
|
|
Non conforming: {:?} \n\t\
|
|
item: {:?}\n\t\
|
|
structure: {:?}\n\t\
|
|
logic_info: {:?}\n\t\
|
|
slot_inserts: {:?}\n\t\
|
|
slot_logic: {:?}\n\t\
|
|
memory: {:?}\n\t\
|
|
circuit_holder: {:?}\n\t\
|
|
device: {:?}\n\t\
|
|
resource_consumer: {:?}\n\t\
|
|
internal_atmosphere: {:?}\n\t\
|
|
thermal: {:?}\n\t\
|
|
",
|
|
page.key,
|
|
page.item,
|
|
page.structure,
|
|
page.logic_info,
|
|
page.slot_inserts,
|
|
page.logic_slot_insert,
|
|
page.memory,
|
|
page.circuit_holder,
|
|
page.device,
|
|
page.resource_consumer,
|
|
page.internal_atmosphere,
|
|
page.thermal,
|
|
),
|
|
}
|
|
}
|
|
templates
|
|
}
|
|
|
|
fn slot_inserts_to_info(slots: &[stationpedia::SlotInsert]) -> Vec<SlotInfo> {
|
|
let mut tmp: Vec<_> = slots.into();
|
|
tmp.sort_by(|a, b| a.slot_index.cmp(&b.slot_index));
|
|
tmp.iter()
|
|
.map(|slot| SlotInfo {
|
|
name: slot.slot_name.clone(),
|
|
typ: slot
|
|
.slot_type
|
|
.parse()
|
|
.unwrap_or_else(|err| panic!("faild to parse slot class: {err}")),
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn mode_inserts_to_info(modes: &[stationpedia::ModeInsert]) -> BTreeMap<u32, String> {
|
|
modes
|
|
.iter()
|
|
.map(|mode| (mode.logic_access_types, mode.logic_name.clone()))
|
|
.collect()
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ObjectDatabase {
|
|
pub prefabs: BTreeMap<String, ObjectTemplate>,
|
|
pub reagents: BTreeMap<String, stationpedia::Reagent>,
|
|
pub enums: enums::Enums,
|
|
pub prefabs_by_hash: BTreeMap<i32, String>,
|
|
pub structures: Vec<String>,
|
|
pub devices: Vec<String>,
|
|
pub items: Vec<String>,
|
|
pub logicable_items: Vec<String>,
|
|
pub suits: Vec<String>,
|
|
pub circuit_holders: Vec<String>,
|
|
}
|
|
|
|
impl From<&stationpedia::SuitInfo> for SuitInfo {
|
|
fn from(value: &stationpedia::SuitInfo) -> Self {
|
|
SuitInfo {
|
|
hygine_reduction_multiplier: value.hygine_reduction_multiplier,
|
|
waste_max_pressure: value.waste_max_pressure,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::ThermalInfo> for ThermalInfo {
|
|
fn from(value: &stationpedia::ThermalInfo) -> Self {
|
|
ThermalInfo {
|
|
convection_factor: value.convection,
|
|
radiation_factor: value.radiation,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::InternalAtmosphereInfo> for InternalAtmoInfo {
|
|
fn from(value: &stationpedia::InternalAtmosphereInfo) -> Self {
|
|
InternalAtmoInfo {
|
|
volume: value.volume,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::LogicInfo> for LogicInfo {
|
|
fn from(value: &stationpedia::LogicInfo) -> Self {
|
|
LogicInfo {
|
|
logic_slot_types: value
|
|
.logic_slot_types
|
|
.iter()
|
|
.map(|(index, slt_map)| {
|
|
(
|
|
*index,
|
|
slt_map
|
|
.slot_types
|
|
.iter()
|
|
.map(|(key, val)| {
|
|
(
|
|
key.parse().unwrap_or_else(|err| {
|
|
panic!("failed to parse logic slot type: {err}")
|
|
}),
|
|
val.parse().unwrap_or_else(|err| {
|
|
panic!("failed to parse memory access: {err}")
|
|
}),
|
|
)
|
|
})
|
|
.collect(),
|
|
)
|
|
})
|
|
.collect(),
|
|
logic_types: value
|
|
.logic_types
|
|
.types
|
|
.iter()
|
|
.map(|(key, val)| {
|
|
(
|
|
key.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse logic type: {err}")),
|
|
val.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse memory access: {err}")),
|
|
)
|
|
})
|
|
.collect(),
|
|
modes: None,
|
|
transmission_receiver: false,
|
|
wireless_logic: false,
|
|
circuit_holder: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::Item> for ItemInfo {
|
|
fn from(item: &stationpedia::Item) -> Self {
|
|
ItemInfo {
|
|
consumable: item.consumable,
|
|
filter_type: item.filter_type.as_ref().map(|typ| {
|
|
typ.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse filter type: {err}"))
|
|
}),
|
|
ingredient: item.ingredient,
|
|
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
|
max_quantity: item.max_quantity.unwrap_or(1.0) as u32,
|
|
reagents: item
|
|
.reagents
|
|
.as_ref()
|
|
.map(|map| map.iter().map(|(key, val)| (key.clone(), *val)).collect()),
|
|
slot_class: item
|
|
.slot_class
|
|
.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse slot class: {err}")),
|
|
sorting_class: item
|
|
.sorting_class
|
|
.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse sorting class: {err}")),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::Device> for DeviceInfo {
|
|
fn from(value: &stationpedia::Device) -> Self {
|
|
DeviceInfo {
|
|
connection_list: value
|
|
.connection_list
|
|
.iter()
|
|
.map(|(typ, role)| ConnectionInfo {
|
|
typ: typ
|
|
.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse connection type: {err}")),
|
|
role: role
|
|
.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse connection role: {err}")),
|
|
})
|
|
.collect(),
|
|
device_pins_length: value.devices_length,
|
|
has_activate_state: value.has_activate_state,
|
|
has_atmosphere: value.has_atmosphere,
|
|
has_color_state: value.has_color_state,
|
|
has_lock_state: value.has_lock_state,
|
|
has_mode_state: value.has_mode_state,
|
|
has_on_off_state: value.has_on_off_state,
|
|
has_open_state: value.has_open_state,
|
|
has_reagents: value.has_reagents,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::Structure> for StructureInfo {
|
|
fn from(value: &stationpedia::Structure) -> Self {
|
|
StructureInfo {
|
|
small_grid: value.small_grid,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::Instruction> for Instruction {
|
|
fn from(value: &stationpedia::Instruction) -> Self {
|
|
Instruction {
|
|
description: value.description.clone(),
|
|
typ: value.type_.clone(),
|
|
value: value.value,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::Memory> for MemoryInfo {
|
|
fn from(value: &stationpedia::Memory) -> Self {
|
|
MemoryInfo {
|
|
instructions: value.instructions.as_ref().map(|insts| {
|
|
insts
|
|
.iter()
|
|
.map(|(key, value)| (key.clone(), value.into()))
|
|
.collect()
|
|
}),
|
|
memory_access: value
|
|
.memory_access
|
|
.parse()
|
|
.unwrap_or_else(|err| panic!("failed to parse memory access: {err}")),
|
|
memory_size: value.memory_size,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<&stationpedia::ResourceConsumer> for ConsumerInfo {
|
|
fn from(value: &stationpedia::ResourceConsumer) -> Self {
|
|
ConsumerInfo {
|
|
consumed_resouces: value.consumed_resources.clone(),
|
|
processed_reagents: value.processed_reagents.clone(),
|
|
}
|
|
}
|
|
}
|