diff --git a/code/game/objects/effects/map_effects/mapmanip.dm b/code/game/objects/effects/map_effects/mapmanip.dm index 7abb97fc2a2..ddd4cc3734c 100644 --- a/code/game/objects/effects/map_effects/mapmanip.dm +++ b/code/game/objects/effects/map_effects/mapmanip.dm @@ -13,6 +13,8 @@ pixel_x = -32 pixel_y = -32 + var/singleton_id + /obj/effect/map_effect/marker/mapmanip/submap/insert name = "mapmanip marker, insert submap" icon = 'icons/effects/map_effects_96x96.dmi' diff --git a/rust/Cargo.lock b/rust/Cargo.lock index e3df62388fa..6e80f6d3d7d 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -947,6 +947,7 @@ dependencies = [ "chrono", "diff", "dmm-tools", + "dreammaker", "eyre", "fxhash", "itertools", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5ab9f163e6a..78a807d5d59 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -19,6 +19,7 @@ thread-priority = "1.1.0" # spacemandmm, also used by strongmandmm dmmtools = { git = "https://github.com/SpaceManiac/SpacemanDMM", rev = "6c5a751516ae0e8add4b2aa4388a1e84e96e7082", package = "dmm-tools" } +dreammaker = { git = "https://github.com/SpaceManiac/SpacemanDMM", rev = "6c5a751516ae0e8add4b2aa4388a1e84e96e7082", package = "dreammaker" } # diffs between two strings/texts/files, used in tests diff = "0.1" # general utility lib for iterator operations diff --git a/rust/src/mapmanip/core/mod.rs b/rust/src/mapmanip/core/mod.rs index 7aa0dd994c7..da84cac2c48 100644 --- a/rust/src/mapmanip/core/mod.rs +++ b/rust/src/mapmanip/core/mod.rs @@ -6,6 +6,8 @@ pub use to_grid_map::to_grid_map; pub mod map_to_string; pub use map_to_string::map_to_string; +use eyre::Context; + use dmmtools::dmm; use dmmtools::dmm::Coord3; @@ -141,7 +143,7 @@ pub struct GridMap { } impl GridMap { - pub fn from_file(path: &std::path::Path) -> Option { - Some(to_grid_map(&dmm::Map::from_file(&path).ok()?)) + pub fn from_file(path: &std::path::Path) -> eyre::Result { + Ok(to_grid_map(&dmm::Map::from_file(&path).wrap_err(format!("failure to read from dmm parser"))?)) } } diff --git a/rust/src/mapmanip/mod.rs b/rust/src/mapmanip/mod.rs index f9c7f25b0df..de65b85ddc1 100644 --- a/rust/src/mapmanip/mod.rs +++ b/rust/src/mapmanip/mod.rs @@ -1,9 +1,15 @@ use core::map_to_string; use core::to_grid_map; use core::GridMap; +use std::collections::HashMap; use byondapi::byond_string; use byondapi::value::ByondValue; +use dmmtools::dmm::Coord3; +use dmmtools::dmm::Prefab; + +use dreammaker::constants::Constant; +use eyre::eyre; use eyre::Context; use eyre::ContextCompat; use itertools::Itertools; @@ -61,6 +67,7 @@ pub fn mapmanip( ) -> eyre::Result { // convert to gridmap let mut map = to_grid_map(&map); + let mut singleton_tags: Vec = vec![]; // go through all the manipulations in `.jsonc` config for this `.dmm` for (n, manipulation) in config.iter().enumerate() { @@ -87,6 +94,7 @@ pub fn mapmanip( marker_extract, marker_insert, *submaps_can_repeat, + &mut singleton_tags, ) .wrap_err(format!( "submap extract insert fail; @@ -110,6 +118,7 @@ fn mapmanip_submap_extract_insert( marker_extract: &String, marker_insert: &String, submaps_can_repeat: bool, + singleton_tags: &mut Vec, ) -> eyre::Result<()> { let submap_size = dmmtools::dmm::Coord3::new( submap_size_x.try_into().wrap_err("invalid submap_size_x")?, @@ -123,12 +132,17 @@ fn mapmanip_submap_extract_insert( let submaps_map = GridMap::from_file(&submaps_dmm) .wrap_err(format!("can't read and parse submap dmm: {submaps_dmm:?}"))?; + let mut marker_lookup: HashMap = Default::default(); // find all the submap extract markers - let mut marker_extract_coords = vec![]; for (coord, tile) in submaps_map.grid.iter() { - if tile.prefabs.iter().any(|p| p.path == *marker_extract) { - marker_extract_coords.push(coord); - } + tile.prefabs.iter().for_each(|p| { + if p.path == *marker_extract { + marker_lookup.insert(coord, p); + } + }); + } + if marker_lookup.is_empty() { + return Err(eyre!("marker lookup empty for submap {submaps_dmm:?}")); } // find all the insert markers @@ -142,18 +156,24 @@ fn mapmanip_submap_extract_insert( // do all the extracts-inserts for insert_coord in marker_insert_coords { // pick a submap - let (extract_coord_index, extract_coord) = marker_extract_coords + let (&extract_coord, &extract_prefab) = marker_lookup .iter() - .cloned() - .enumerate() + .filter(|(_, &prefab)| { + !singleton_tags.contains( + prefab + .vars + .get("singleton_id") + .unwrap_or(Constant::null()) + ) + }) .choose(&mut rand::thread_rng()) .wrap_err(format!( - "can't pick a submap to extract; no more extract markers in the submaps dmm; marker type: {marker_extract}" + "no extractions found for marker {marker_extract}, singletons={singleton_tags:?}" ))?; - // if submaps should not be repeating, remove this one from the list + // if submaps should not be repeating, remove this one if !submaps_can_repeat { - marker_extract_coords.remove(extract_coord_index); + marker_lookup.remove(&extract_coord); } // extract that submap from the submap dmm @@ -163,6 +183,14 @@ fn mapmanip_submap_extract_insert( // and insert the submap into the manipulated map insert_submap(&extracted, insert_coord, map) .wrap_err(format!("submap insertion failed; at {insert_coord}"))?; + + let singleton_id = extract_prefab + .vars + .get("singleton_id") + .unwrap_or(Constant::null()); + if !singleton_id.is_null() { + singleton_tags.push(singleton_id.clone()); + } } Ok(()) diff --git a/rustlibs_515.dll b/rustlibs_515.dll index 2c65bedafeb..2c0c5fab214 100644 Binary files a/rustlibs_515.dll and b/rustlibs_515.dll differ diff --git a/rustlibs_515_prod.dll b/rustlibs_515_prod.dll index 3b855a32789..09b29907c8d 100644 Binary files a/rustlibs_515_prod.dll and b/rustlibs_515_prod.dll differ diff --git a/rustlibs_516.dll b/rustlibs_516.dll index aa2deb2a58d..b3856eeac36 100644 Binary files a/rustlibs_516.dll and b/rustlibs_516.dll differ diff --git a/rustlibs_516_prod.dll b/rustlibs_516_prod.dll index c04c533f9e9..9086fe5f4d3 100644 Binary files a/rustlibs_516_prod.dll and b/rustlibs_516_prod.dll differ diff --git a/tools/ci/librustlibs_ci_515.so b/tools/ci/librustlibs_ci_515.so index b7b4069ac33..24bad0ca6d7 100644 Binary files a/tools/ci/librustlibs_ci_515.so and b/tools/ci/librustlibs_ci_515.so differ diff --git a/tools/ci/librustlibs_ci_516.so b/tools/ci/librustlibs_ci_516.so index ccab9f88c27..149d655666a 100644 Binary files a/tools/ci/librustlibs_ci_516.so and b/tools/ci/librustlibs_ci_516.so differ