diff --git a/src/gui/maps.rs b/src/gui/maps.rs index eaf154f..ddb15a2 100644 --- a/src/gui/maps.rs +++ b/src/gui/maps.rs @@ -1,7 +1,7 @@ use dioxus::prelude::*; use crate::gui::checkbox; -use crate::json::{Preset, ShopItems}; +use crate::json::{GroupStrategy, Preset, ShopItems}; #[component] pub fn maps() -> Element { @@ -14,6 +14,9 @@ pub fn maps() -> Element { let backgrounds = read_state.randomizer.maps.backgrounds; let fight_backgrounds = read_state.randomizer.maps.fight_backgrounds; let item_boxes = read_state.randomizer.maps.item_boxes; + + let selected_group_strategy = read_state.randomizer.maps.group_strategy; + let selected = read_state.randomizer.maps.item_boxes_items_only.clone(); rsx! { @@ -61,8 +64,8 @@ pub fn maps() -> Element { } }, div { + class: "left", div { - class: "left", checkbox::checkbox { label: "Fight Backgrounds", id: "maps.fight_backgrounds", @@ -73,6 +76,44 @@ pub fn maps() -> Element { state.write().randomizer.maps.fight_backgrounds = x; } }, + }, + div { + class: "tooltip", + span { + class: "tooltiptext", + style: "width: 200px", + "None => fully random", + br {}, + "Map => group based on overworld map", + br {}, + "Party => group based on party id" + }, + label { + r#for: "maps.group_strategy", + "Group Strategy" + }, + select { + id: "maps.group_strategy", + disabled: !enabled || !fight_backgrounds, + onchange: move |x: Event| { + state.write().randomizer.maps.group_strategy = GroupStrategy::from(x.data.value().parse::().unwrap_or(0)); + }, + option { + value: "0", + selected: selected_group_strategy == GroupStrategy::None, + "None" + }, + option { + value: "1", + selected: selected_group_strategy == GroupStrategy::Map, + "Map" + }, + option { + value: "2", + selected: selected_group_strategy == GroupStrategy::Party, + "Party" + }, + } } }, div { diff --git a/src/json.rs b/src/json.rs index 86cc26f..bdd8c73 100644 --- a/src/json.rs +++ b/src/json.rs @@ -73,6 +73,8 @@ pub struct Maps { pub item_boxes_items_only: ShopItems, #[serde(default = "default_bool_true")] pub fight_backgrounds: bool, + #[serde(default = "GroupStrategy::default")] + pub group_strategy: GroupStrategy, } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -339,6 +341,26 @@ impl From for TNTStrategy { } } +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Copy)] +#[serde(rename_all = "lowercase")] +#[derive(Default)] +pub enum GroupStrategy { + None, + Map, + #[default] + Party, +} + +impl From for GroupStrategy { + fn from(value: u8) -> Self { + match value { + 0 => GroupStrategy::None, + 1 => GroupStrategy::Map, + _ => GroupStrategy::Party, + } + } +} + #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] #[serde(rename_all = "lowercase")] #[derive(Default)] diff --git a/src/rand/maps.rs b/src/rand/maps.rs index 6383354..9ba49df 100644 --- a/src/rand/maps.rs +++ b/src/rand/maps.rs @@ -1,6 +1,6 @@ -use std::collections::{BTreeSet, HashSet}; +use std::collections::{BTreeSet, HashMap}; -use crate::{rand::Objects, util}; +use crate::{json::GroupStrategy, rand::Objects, util}; use anyhow::Context; use rand_xoshiro::rand_core::RngCore; use rand_xoshiro::Xoshiro256StarStar; @@ -58,13 +58,13 @@ pub fn patch( } if maps.fight_backgrounds { - random_fight_backgrounds(objects, rng); + random_fight_backgrounds(preset, objects, rng); } Ok(()) } -fn random_fight_backgrounds(objects: &mut Objects, rng: &mut Xoshiro256StarStar) { +fn random_fight_backgrounds_ungrouped(objects: &mut Objects, rng: &mut Xoshiro256StarStar) { for map in &mut objects.map_objects { if let Some(se_obj) = &mut map.stage_encounters { for opt in &mut se_obj.stage_encounters { @@ -78,6 +78,51 @@ fn random_fight_backgrounds(objects: &mut Objects, rng: &mut Xoshiro256StarStar) } } +fn random_fight_backgrounds_grouped( + preset: &Randomizer, + objects: &mut Objects, + rng: &mut Xoshiro256StarStar, +) { + let mut generated = HashMap::new(); + + for map in &mut objects.map_objects { + if let Some(se_obj) = &mut map.stage_encounters { + for opt in &mut se_obj.stage_encounters { + if let Some(encounters_obj) = opt { + for encounter in &mut encounters_obj.modified { + encounter.stage = match generated.get(&encounter.team_id) { + Some(x) => *x, + None => { + let nv = rng.next_u32() % 0x39; + + generated.insert(encounter.team_id, rng.next_u32() % 0x39); + + nv + } + }; + } + } + } + } + + if preset.maps.group_strategy == GroupStrategy::Map { + generated.clear(); + } + } +} + +fn random_fight_backgrounds( + preset: &Randomizer, + objects: &mut Objects, + rng: &mut Xoshiro256StarStar, +) { + if preset.maps.group_strategy == GroupStrategy::None { + random_fight_backgrounds_ungrouped(objects, rng); + } else { + random_fight_backgrounds_grouped(preset, objects, rng); + } +} + fn color(objects: &mut Objects, rng: &mut Xoshiro256StarStar) { for map in &mut objects.map_objects { if let Some(color_object) = &mut map.map_color {