diff --git a/rust/data/presets/full-settings/Community Race Season 4.json b/rust/data/presets/full-settings/Community Race Season 4.json index ff143c5ac3..afda886e67 100644 --- a/rust/data/presets/full-settings/Community Race Season 4.json +++ b/rust/data/presets/full-settings/Community Race Season 4.json @@ -4532,6 +4532,21 @@ }, "quality_of_life_settings": { "preset": null, + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": null, "map_stations": "Full", @@ -4705,7 +4720,6 @@ "map_station_reveal": "Full", "energy_free_shinesparks": false, "all_enemies_respawn": false, - "ultra_low_qol": false, "disable_spikesuit": false, "disable_bluesuit": false, "enable_major_glitches": false, diff --git a/rust/data/presets/full-settings/Default.json b/rust/data/presets/full-settings/Default.json index d6a51ba379..eec9031595 100644 --- a/rust/data/presets/full-settings/Default.json +++ b/rust/data/presets/full-settings/Default.json @@ -4532,6 +4532,21 @@ }, "quality_of_life_settings": { "preset": "Default", + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": "Maps", "map_stations": "Full", @@ -4710,7 +4725,6 @@ "disable_bluesuit": false, "enable_major_glitches": false, "speed_booster": "Vanilla", - "ultra_low_qol": false, "race_mode": false, "random_seed": null } diff --git a/rust/data/presets/full-settings/Mentor Tournament.json b/rust/data/presets/full-settings/Mentor Tournament.json index e7ddc817f3..a63f6663d9 100644 --- a/rust/data/presets/full-settings/Mentor Tournament.json +++ b/rust/data/presets/full-settings/Mentor Tournament.json @@ -4588,6 +4588,21 @@ }, "quality_of_life_settings": { "preset": null, + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": null, "map_stations": "Full", @@ -4761,7 +4776,6 @@ "map_station_reveal": "Full", "energy_free_shinesparks": false, "all_enemies_respawn": false, - "ultra_low_qol": false, "disable_spikesuit": false, "disable_bluesuit": false, "enable_major_glitches": false, diff --git a/rust/data/presets/quality-of-life/Default.json b/rust/data/presets/quality-of-life/Default.json index fc8f167362..471b5f780e 100644 --- a/rust/data/presets/quality-of-life/Default.json +++ b/rust/data/presets/quality-of-life/Default.json @@ -1,5 +1,20 @@ { "preset": "Default", + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": "Maps", "map_stations": "Full", diff --git a/rust/data/presets/quality-of-life/High.json b/rust/data/presets/quality-of-life/High.json index ce19e4a407..b2630d813b 100644 --- a/rust/data/presets/quality-of-life/High.json +++ b/rust/data/presets/quality-of-life/High.json @@ -1,5 +1,20 @@ { "preset": "High", + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": "Maps", "map_stations": "Full", diff --git a/rust/data/presets/quality-of-life/Low.json b/rust/data/presets/quality-of-life/Low.json index 6844004473..29b6140ba9 100644 --- a/rust/data/presets/quality-of-life/Low.json +++ b/rust/data/presets/quality-of-life/Low.json @@ -1,5 +1,20 @@ { "preset": "Low", + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": "Maps", "map_stations": "Full", diff --git a/rust/data/presets/quality-of-life/Max.json b/rust/data/presets/quality-of-life/Max.json index 9aff7459c2..de80cb4613 100644 --- a/rust/data/presets/quality-of-life/Max.json +++ b/rust/data/presets/quality-of-life/Max.json @@ -1,5 +1,20 @@ { "preset": "Max", + "enhanced_map_settings": { + "preset": "Yes", + "blue_doors": "Visible", + "gray_doors": "Visible", + "ammo_doors": "Visible", + "beam_doors": "Visible", + "heat": "Visible", + "water": "Visible", + "lava": "Visible", + "acid": "Visible", + "walls": "White", + "objectives": "Icon", + "map_station": "Icon", + "refill_station": "Icon" + }, "initial_map_reveal_settings": { "preset": "Maps", "map_stations": "Full", diff --git a/rust/data/presets/quality-of-life/Off.json b/rust/data/presets/quality-of-life/Off.json index ddbfc506b9..3f17025817 100644 --- a/rust/data/presets/quality-of-life/Off.json +++ b/rust/data/presets/quality-of-life/Off.json @@ -1,5 +1,20 @@ { "preset": "Off", + "enhanced_map_settings": { + "preset": "No", + "blue_doors": "Hidden", + "gray_doors": "Hidden", + "ammo_doors": "Hidden", + "beam_doors": "Hidden", + "heat": "Hidden", + "water": "Hidden", + "lava": "Hidden", + "acid": "Hidden", + "walls": "Vanilla", + "objectives": "Vanilla", + "map_station": "Vanilla", + "refill_station": "Vanilla" + }, "initial_map_reveal_settings": { "preset": "No", "map_stations": "No", diff --git a/rust/maprando-web/src/main.rs b/rust/maprando-web/src/main.rs index 73f9f2327f..ceef3f89d9 100644 --- a/rust/maprando-web/src/main.rs +++ b/rust/maprando-web/src/main.rs @@ -478,7 +478,6 @@ struct SeedData { ammo_refill_all: bool, wall_jump: String, vanilla_map: bool, - ultra_low_qol: bool, } #[derive(MultipartForm)] @@ -781,7 +780,6 @@ async fn randomize( .unwrap() .to_string(), vanilla_map: settings.map_layout == "Vanilla", - ultra_low_qol: settings.other_settings.ultra_low_qol, }; let seed_name = &output.randomization.seed_name; diff --git a/rust/maprando-web/src/randomize_helpers.rs b/rust/maprando-web/src/randomize_helpers.rs index d0f79488e2..5bc199525a 100644 --- a/rust/maprando-web/src/randomize_helpers.rs +++ b/rust/maprando-web/src/randomize_helpers.rs @@ -192,9 +192,6 @@ impl SeedHeaderTemplate<'_> { if other_settings.energy_free_shinesparks { game_variations.push("Energy-free shinesparks"); } - if other_settings.ultra_low_qol { - game_variations.push("Ultra-low quality of life"); - } if other_settings.speed_booster == SpeedBooster::Split { game_variations.push("Split Speed Booster"); } @@ -219,8 +216,8 @@ impl SeedHeaderTemplate<'_> { pub struct SeedFooterTemplate { race_mode: bool, all_items_spawn: bool, + ammo_refill_all: bool, supers_double: bool, - ultra_low_qol: bool, settings: RandomizerSettings, } @@ -529,8 +526,8 @@ pub fn render_seed( let seed_footer_template = SeedFooterTemplate { race_mode: seed_data.race_mode, all_items_spawn: seed_data.all_items_spawn, + ammo_refill_all: seed_data.ammo_refill_all, supers_double: seed_data.supers_double, - ultra_low_qol: seed_data.ultra_low_qol, settings: seed_data.settings.clone(), }; let seed_footer_html = seed_footer_template.render()?; diff --git a/rust/maprando-web/src/seed.rs b/rust/maprando-web/src/seed.rs index f43dee866c..24dee3797b 100644 --- a/rust/maprando-web/src/seed.rs +++ b/rust/maprando-web/src/seed.rs @@ -236,16 +236,6 @@ async fn customize_seed( let orig_rom = Rom::new(req.rom.data.to_vec()); let mut rom = orig_rom.clone(); - let seed_data_str: String = String::from_utf8( - app_data - .seed_repository - .get_file(seed_name, "seed_data.json") - .await - .unwrap(), - ) - .unwrap(); - let seed_data = json::parse(&seed_data_str).unwrap(); - let settings_bytes = app_data .seed_repository .get_file(seed_name, "public/settings.json") @@ -277,8 +267,6 @@ async fn customize_seed( Some(serde_json::from_slice(&randomization_bytes).unwrap()) }; - let ultra_low_qol = seed_data["ultra_low_qol"].as_bool().unwrap_or(false); - let rom_digest = crypto_hash::hex_digest(crypto_hash::Algorithm::SHA256, &rom.data); info!("Rom digest: {rom_digest}"); if rom_digest != "12b77c4bc9c1832cee8881244659065ee1d84c70c3d29e6eaf92e6798cc2ca72" { @@ -286,14 +274,7 @@ async fn customize_seed( } let customize_settings = CustomizeSettings { - samus_sprite: if ultra_low_qol - && req.samus_sprite.0 == "samus_vanilla" - && req.vanilla_screw_attack_animation.0 - { - None - } else { - Some(req.samus_sprite.0.clone()) - }, + samus_sprite: Some(req.samus_sprite.0.clone()), etank_color: Some(( u8::from_str_radix(&req.etank_color.0[0..2], 16).unwrap() / 8, u8::from_str_radix(&req.etank_color.0[2..4], 16).unwrap() / 8, diff --git a/rust/maprando-web/templates/generate/enhanced_map.html b/rust/maprando-web/templates/generate/enhanced_map.html new file mode 100644 index 0000000000..93e4d6c61c --- /dev/null +++ b/rust/maprando-web/templates/generate/enhanced_map.html @@ -0,0 +1,218 @@ + \ No newline at end of file diff --git a/rust/maprando-web/templates/generate/game_variations.html b/rust/maprando-web/templates/generate/game_variations.html index 0cdccd8e60..0af75efea6 100644 --- a/rust/maprando-web/templates/generate/game_variations.html +++ b/rust/maprando-web/templates/generate/game_variations.html @@ -133,18 +133,6 @@ -
-
- {% include "help/variations/ultra_low_qol.html" %} - -
-
- - - - -
-
{% include "help/race.html" %} diff --git a/rust/maprando-web/templates/generate/help/quality/enhanced_map.html b/rust/maprando-web/templates/generate/help/quality/enhanced_map.html new file mode 100644 index 0000000000..588b19b36b --- /dev/null +++ b/rust/maprando-web/templates/generate/help/quality/enhanced_map.html @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/rust/maprando-web/templates/generate/help/variations/ultra_low_qol.html b/rust/maprando-web/templates/generate/help/variations/ultra_low_qol.html deleted file mode 100644 index e20b95a56b..0000000000 --- a/rust/maprando-web/templates/generate/help/variations/ultra_low_qol.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - \ No newline at end of file diff --git a/rust/maprando-web/templates/generate/quality_of_life.html b/rust/maprando-web/templates/generate/quality_of_life.html index 55ad03a9f2..1e7f2a8c14 100644 --- a/rust/maprando-web/templates/generate/quality_of_life.html +++ b/rust/maprando-web/templates/generate/quality_of_life.html @@ -13,6 +13,29 @@

Quality-of-life options

Map
+
+
+ + +
+
+ + + + + +
+
+ +
@@ -587,12 +608,12 @@

Quality-of-life options

- + - +
@@ -822,6 +843,7 @@

Quality-of-life options

+{% include "help/quality/enhanced_map.html" %} {% include "help/quality/initial_map_reveal.html" %} {% include "help/quality/item_markers.html" %} {% include "help/quality/room_outline.html" %} @@ -867,4 +889,5 @@

Quality-of-life options

{% include "help/quality/camera_fixes.html" %} {% include "initial_map_reveal.html" %} +{% include "enhanced_map.html" %} {% include "crash_fixes.html" %} \ No newline at end of file diff --git a/rust/maprando-web/templates/generate/scripts.html b/rust/maprando-web/templates/generate/scripts.html index 310e7de7f6..2ff6177092 100644 --- a/rust/maprando-web/templates/generate/scripts.html +++ b/rust/maprando-web/templates/generate/scripts.html @@ -194,6 +194,24 @@ } } +function buildEnhancedMapSettings(formData) { + return { + "preset": formData.get("enhanced_map"), + "blue_doors": formData.get("enhanced_map_blue_doors"), + "gray_doors": formData.get("enhanced_map_gray_doors"), + "ammo_doors": formData.get("enhanced_map_ammo_doors"), + "beam_doors": formData.get("enhanced_map_beam_doors"), + "heat": formData.get("enhanced_map_heat"), + "water": formData.get("enhanced_map_water"), + "lava": formData.get("enhanced_map_lava"), + "acid": formData.get("enhanced_map_acid"), + "walls": formData.get("enhanced_map_walls"), + "objectives": formData.get("enhanced_map_objectives"), + "map_station": formData.get("enhanced_map_station"), + "refill_station": formData.get("enhanced_map_refill"), + } +} + function emptyToNull(s) { if (s == "") { return null; @@ -257,6 +275,7 @@ }, "quality_of_life_settings": { "preset": formData.get("quality_of_life_preset"), + "enhanced_map_settings": buildEnhancedMapSettings(formData), "initial_map_reveal_settings": buildInitialMapRevealSettings(formData), "item_markers": formData.get("item_markers"), "room_outline_revealed": formData.get("room_outline_revealed") == "true", @@ -331,7 +350,6 @@ "map_station_reveal": formData.get("map_station_reveal"), "energy_free_shinesparks": formData.get("energy_free_shinesparks") == "true", "all_enemies_respawn": formData.get("all_enemies_respawn") == "true", - "ultra_low_qol": formData.get("ultra_low_qol") == "true", "race_mode": formData.get("race_mode") == "true", "random_seed": tryParseInt(formData.get("random_seed")), "disable_spikesuit": formData.get("disable_spike_suit") == "true", @@ -504,6 +522,22 @@ processInitialMapRevealPreset(); } +function applyEnhancedMapSettings(emSettings) { + applyRadioValue("enhancedMapBlueDoors", emSettings.blue_doors); + applyRadioValue("enhancedMapGrayDoors", emSettings.gray_doors); + applyRadioValue("enhancedMapAmmoDoors", emSettings.ammo_doors); + applyRadioValue("enhancedMapBeamDoors", emSettings.beam_doors); + applyRadioValue("enhancedMapHeat", emSettings.heat); + applyRadioValue("enhancedMapWater", emSettings.water); + applyRadioValue("enhancedMapLava", emSettings.lava); + applyRadioValue("enhancedMapAcid", emSettings.acid); + applyRadioValue("enhancedMapWalls", emSettings.walls); + applyRadioValue("enhancedMapObjectives", emSettings.objectives); + applyRadioValue("enhancedMapStation", emSettings.map_station); + applyRadioValue("enhancedMapRefill", emSettings.refill_station); + applyRadioValue("enhancedMapPreset", emSettings.preset); + processEnhancedMapPreset(); +} function applyQolPreset(preset) { for (var presetEl of document.getElementsByClassName("qol-preset-button")) { if (presetEl.value == preset.preset) { @@ -518,6 +552,7 @@ } applyInitialMapRevealSettings(preset.initial_map_reveal_settings); + applyEnhancedMapSettings(preset.enhanced_map_settings); applyRadioValue("itemMarkers", preset.item_markers); applyRadioValue("roomOutlineRevealed", preset.room_outline_revealed); applyRadioValue("oppositeAreaRevealed", preset.opposite_area_revealed); @@ -614,7 +649,6 @@ applyRadioValue("mapStationReveal", other.map_station_reveal); applyRadioValue("energyFreeShinesparks", other.energy_free_shinesparks); applyRadioValue("allEnemiesRespawn", other.all_enemies_respawn); - applyRadioValue("ultraLowQoL", other.ultra_low_qol); applyRadioValue("disableSpikesuit", other.disable_spikesuit); applyRadioValue("disableBluesuit", other.disable_bluesuit); applyRadioValue("enableMajorGlitches", other.enable_major_glitches); @@ -732,9 +766,6 @@ applyQolPreset(preset); } } - if (!isOff) { - document.getElementById("ultraLowQoLNo").checked = true; - } fullSettingsChanged(); } @@ -934,6 +965,47 @@ initialMapRevealPresetChanged(); } +function processEnhancedMapPreset() { + let mapTypes = [ + "BlueDoors", + "GrayDoors", + "AmmoDoors", + "BeamDoors", + "Heat", + "Water", + "Lava", + "Acid" + ] + if (document.getElementById("enhancedMapPresetNo").checked) { + for (t of mapTypes) { + document.getElementById(`enhancedMap${t}Hidden`).checked = true; + } + document.getElementById("enhancedMapWallsVanilla").checked = true; + document.getElementById("enhancedMapObjectivesVanilla").checked = true; + document.getElementById("enhancedMapStationVanilla").checked = true; + document.getElementById("enhancedMapRefillVanilla").checked = true; + } else if (document.getElementById("enhancedMapPresetYes").checked) { + for (t of mapTypes) { + document.getElementById(`enhancedMap${t}Visible`).checked = true; + } + document.getElementById("enhancedMapWallsWhite").checked = true; + document.getElementById("enhancedMapObjectivesIcon").checked = true; + document.getElementById("enhancedMapStationIcon").checked = true; + document.getElementById("enhancedMapRefillIcon").checked = true; +} +} + +function enhancedMapPresetChanged() { + processEnhancedMapPreset(); + qualityOfLifeSettingChanged(); +} + +function enhancedMapSettingChanged() { + document.getElementById("enhancedMapPresetNo").checked = false; + document.getElementById("enhancedMapPresetYes").checked = false; + enhancedMapPresetChanged(); +} + function objectivePresetChanged() { for (presetEl of document.getElementsByClassName("objective-preset-button")) { if (presetEl.checked) { @@ -1245,22 +1317,9 @@ } function gameVariationChanged() { - if (!document.getElementById("enableMajorGlitchesYes").checked) - { - document.getElementById("ultraLowQoLNo").checked = true; - } fullSettingsChanged(); } -function ultraLowQoLChanged() { - if (!document.getElementById("ultraLowQoLYes").checked) { - return; - } - document.getElementById("qualityOfLifeOff").checked = true; - document.getElementById("enableMajorGlitchesYes").checked = true; - qualityOfLifePresetChanged(); -} - function initializeSpoilerToken() { if (localStorage["spoilerToken"] === undefined) { let result = ''; @@ -1288,7 +1347,6 @@ !document.getElementById("areaAssignmentPresetStandard").checked || document.getElementById("doorLocksSizeSmall").checked || document.getElementById("mapStationRevealPartial").checked || - document.getElementById("ultraLowQoLYes").checked || document.getElementById("raceModeYes").checked) { document.getElementById("collapseGameVariations").classList.remove("collapse"); diff --git a/rust/maprando-web/templates/seed/enhanced_map_details.html b/rust/maprando-web/templates/seed/enhanced_map_details.html new file mode 100644 index 0000000000..319a547fae --- /dev/null +++ b/rust/maprando-web/templates/seed/enhanced_map_details.html @@ -0,0 +1,49 @@ +{% let em = settings.quality_of_life_settings.enhanced_map_settings %} +
+
Blue doors:
+
{{ em.blue_doors }}
+
+
+
Gray doors:
+
{{ em.gray_doors }}
+
+
+
Ammo doors:
+
{{ em.ammo_doors }}
+
+
+
Beam doors:
+
{{ em.beam_doors }}
+
+
+
Heat:
+
{{ em.heat }}
+
+
+
Water:
+
{{ em.water }}
+
+
+
Lava:
+
{{ em.lava }}
+
+
+
Acid:
+
{{ em.acid }}
+
+
+
Walls and passages:
+
{{ em.walls }}
+
+
+
Objectives:
+
{{ em.objectives}}
+
+
+
Map stations:
+
{{ em.map_station}}
+
+
+
Refill stations:
+
{{ em.refill_station }}
+
\ No newline at end of file diff --git a/rust/maprando-web/templates/seed/quality_of_life_details.html b/rust/maprando-web/templates/seed/quality_of_life_details.html index 25b74c0c05..b2ccc4f981 100644 --- a/rust/maprando-web/templates/seed/quality_of_life_details.html +++ b/rust/maprando-web/templates/seed/quality_of_life_details.html @@ -1,3 +1,9 @@ +
+
Enhanced map:
+
{{+ + settings.quality_of_life_settings.enhanced_map_settings.preset.as_ref().unwrap_or(&"Custom".to_string()) + }}
+
Initial map reveal:
{{+ diff --git a/rust/maprando-web/templates/seed/seed_footer.html b/rust/maprando-web/templates/seed/seed_footer.html index 55235bb1d4..9c98d0e06e 100644 --- a/rust/maprando-web/templates/seed/seed_footer.html +++ b/rust/maprando-web/templates/seed/seed_footer.html @@ -2,10 +2,8 @@
Important tips
    - {% if !ultra_low_qol %}
  • Save frequently! Saves are fast, and saving at a different station from the last save will move to the next slot before saving, so you can go back to an earlier save if you get stuck.
  • - {% endif %}
  • Be careful with one-ways: it's easy to get soft-locked. The logic usually doesn't require going down a one-way for an item, only if there is a way back to the Ship without using the new item. It's often best to avoid one-ways until you know there's a way back or have exhausted all other options.
  • @@ -51,7 +49,6 @@
    Things to know
    - {% if !ultra_low_qol %}
    Special inputs
    • Press Select or X/Y in the pause map to cycle through maps of explored areas. @@ -63,7 +60,6 @@
      Special inputs
    • Set reserves to Manual and hold B + Up in the pause equipment screen to transfer energy to reserve tanks. {% endif %}
    - {% endif %}
    Map info
      {% if settings.map_layout != "Small" %} @@ -90,7 +86,7 @@
      Item info
      Other info
        - {% if !ultra_low_qol %} + {% if !ammo_refill_all %}
      • Missile Refill stations refill all ammo types: Missiles, Supers, and Power Bombs.
      • {% endif %} {% if supers_double %} diff --git a/rust/maprando-web/templates/seed/seed_header.html b/rust/maprando-web/templates/seed/seed_header.html index b269d99de7..36cdbd3927 100644 --- a/rust/maprando-web/templates/seed/seed_header.html +++ b/rust/maprando-web/templates/seed/seed_header.html @@ -137,6 +137,15 @@

    +
    +
    + Enhanced map details +
    +
    + {% include "enhanced_map_details.html" %} +
    +
    +
    Initial map reveal details diff --git a/rust/maprando/src/patch.rs b/rust/maprando/src/patch.rs index ddbb01f47b..13c1f1d69a 100644 --- a/rust/maprando/src/patch.rs +++ b/rust/maprando/src/patch.rs @@ -471,28 +471,21 @@ impl Patcher<'_> { "wall_doors", "self_check", "door_irq_fix", + "extra_setup", + "vanilla_bugfixes", // from here to the end were moved from ultra_low_qol... these don't have a toggle but can be switched to one or moved into the other group toggles + "aim_anything", // i thought about having "ui fixes" toggle, group this with the menu fixes etc + "fix_kraid_vomit", + "fix_kraid_hud", // these 3 maybe camera fixes? or something else + "fix_kraid_door", + "boss_exit", + "load_plms_early", + "spin_lock", + "fix_transition_bad_tiles", // maybe this can be moved to be applied with camera fixes? + "fix_horiz_doors", // this too? + "fix_dust_torizo", + "fix_choot", ]; - if self.settings.other_settings.ultra_low_qol { - patches.extend(["ultra_low_qol_vanilla_bugfixes"]); - } else { - patches.extend([ - "vanilla_bugfixes", - "aim_anything", - "fix_kraid_vomit", - "fix_kraid_hud", - "fix_kraid_door", - "boss_exit", - "extra_setup", - "load_plms_early", - "spin_lock", - "fix_transition_bad_tiles", - "fix_horiz_doors", - "fix_dust_torizo", - "fix_choot", - ]); - } - patches.push("new_game"); if self.settings.quality_of_life_settings.all_items_spawn { @@ -671,9 +664,7 @@ impl Patcher<'_> { patches.push("remove_bluesuit"); } - if !self.settings.other_settings.enable_major_glitches - && !self.settings.other_settings.ultra_low_qol - { + if !self.settings.other_settings.enable_major_glitches { patches.push("disable_major_glitches"); patches.push("oob_death"); } @@ -693,7 +684,7 @@ impl Patcher<'_> { match self.settings.quality_of_life_settings.fanfares { Fanfares::Vanilla => { - if !self.settings.other_settings.ultra_low_qol { + if self.settings.quality_of_life_settings.fast_saves { // This is needed only if fast saves are enabled // (which is currently always except with ultra-low QoL) // It's important that it be applied after `fast_saves`` since it overrides the same hook point. @@ -1106,7 +1097,8 @@ impl Patcher<'_> { let mut extra_door_asm: HashMap> = HashMap::new(); extra_door_asm.insert(0x1A600, toilet_exit_asm.clone()); // Aqueduct toilet door down extra_door_asm.insert(0x1A60C, toilet_exit_asm.clone()); // Aqueduct toilet door up - if !self.settings.other_settings.ultra_low_qol { + if self.settings.quality_of_life_settings.camera_fixes { + // nn note - is this becuase of camera fixes (guess) or something else... check this. extra_door_asm.insert(0x191CE, boss_exit_asm.clone()); // Kraid left exit extra_door_asm.insert(0x191DA, boss_exit_asm.clone()); // Kraid right exit extra_door_asm.insert(0x1A96C, boss_exit_asm.clone()); // Draygon left exit @@ -3640,7 +3632,8 @@ pub fn make_rom( patcher.use_area_based_music()?; } patcher.setup_door_specific_fx()?; - if !randomizer_settings.other_settings.ultra_low_qol { + if randomizer_settings.quality_of_life_settings.camera_fixes { + //nn note - the cre wasn't applied in ultralow qol, is this also camera fixes or some other reason - check this too! patcher.setup_reload_cre()?; } patcher.apply_title_screen_patches()?; diff --git a/rust/maprando/src/patch/map_tiles.rs b/rust/maprando/src/patch/map_tiles.rs index 36bf119f07..612519ad00 100644 --- a/rust/maprando/src/patch/map_tiles.rs +++ b/rust/maprando/src/patch/map_tiles.rs @@ -4,8 +4,9 @@ use crate::{ customize::{CustomizeSettings, ItemDotChange}, randomize::{LockedDoor, Randomization}, settings::{ - DisableETankSetting, DoorLocksSize, InitialMapRevealSettings, ItemMarkers, MapRevealLevel, - MapStationReveal, Objective, RandomizerSettings, + DisableETankSetting, DoorLocksSize, EnhancedMapLevel, EnhancedMapOther, EnhancedMapWalls, + InitialMapRevealSettings, ItemMarkers, MapRevealLevel, MapStationReveal, Objective, + RandomizerSettings, }, }; use maprando_game::{ @@ -150,6 +151,12 @@ fn draw_edge( tile: &mut [[u8; 8]; 8], settings: &RandomizerSettings, ) { + let em = &settings.quality_of_life_settings.enhanced_map_settings; + let wall_color = if em.walls == EnhancedMapWalls::Black { + 4 + } else { + 3 + }; let wall_coords = match tile_side { TileSide::Top => [ (0, 0), @@ -290,90 +297,92 @@ fn draw_edge( match edge { MapTileEdge::Empty => {} MapTileEdge::QolEmpty => { - if settings.other_settings.ultra_low_qol { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); - set_wall_pixel(tile, 3, 3); - set_wall_pixel(tile, 4, 3); - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + if em.walls == EnhancedMapWalls::Vanilla { + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); + set_wall_pixel(tile, 3, wall_color); + set_wall_pixel(tile, 4, wall_color); + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } } MapTileEdge::Passage => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - if settings.other_settings.ultra_low_qol { - set_wall_pixel(tile, 2, 3); - set_wall_pixel(tile, 3, 3); - set_wall_pixel(tile, 4, 3); - set_wall_pixel(tile, 5, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + if em.walls == EnhancedMapWalls::Vanilla { + set_wall_pixel(tile, 2, wall_color); + set_wall_pixel(tile, 3, wall_color); + set_wall_pixel(tile, 4, wall_color); + set_wall_pixel(tile, 5, wall_color); } - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } MapTileEdge::QolPassage => { - if !settings.other_settings.ultra_low_qol { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + if em.walls == EnhancedMapWalls::White { + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } } MapTileEdge::Door | MapTileEdge::QolDoor => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); - if settings.other_settings.ultra_low_qol { - set_wall_pixel(tile, 3, 3); - set_wall_pixel(tile, 4, 3); - } - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + let hidden = matches!(em.blue_doors, EnhancedMapLevel::Hidden); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); + if hidden { + set_wall_pixel(tile, 3, wall_color); + set_wall_pixel(tile, 4, wall_color); + } + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } MapTileEdge::Wall | MapTileEdge::QolWall => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); - set_wall_pixel(tile, 3, 3); - set_wall_pixel(tile, 4, 3); - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); + set_wall_pixel(tile, 3, wall_color); + set_wall_pixel(tile, 4, wall_color); + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } MapTileEdge::Sand | MapTileEdge::QolSand => { - if settings.other_settings.ultra_low_qol { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); - set_wall_pixel(tile, 3, 3); - set_wall_pixel(tile, 4, 3); - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + if em.water == EnhancedMapLevel::Hidden { + //nn note - xxxwhat is this?xxx this is the sand pits right? maybe should be blue doors not water....? + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); + set_wall_pixel(tile, 3, wall_color); + set_wall_pixel(tile, 4, wall_color); + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } else if tile_side == TileSide::Bottom { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } else { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } } MapTileEdge::ElevatorEntrance => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); - set_air_pixel(tile, 0, 3); - set_air_pixel(tile, 7, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); + set_air_pixel(tile, 0, wall_color); + set_air_pixel(tile, 7, wall_color); } MapTileEdge::LockedDoor(lock_type) => match lock_type { Gray | Red | Green | Yellow => { @@ -386,26 +395,26 @@ fn draw_edge( }; match settings.other_settings.door_locks_size { DoorLocksSize::Small => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); set_wall_pixel(tile, 2, 12); set_wall_pixel(tile, 3, color); set_wall_pixel(tile, 4, color); set_wall_pixel(tile, 5, 12); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); set_air_pixel(tile, 3, 4); set_air_pixel(tile, 4, 4); } DoorLocksSize::Large => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); set_wall_pixel(tile, 2, 12); set_wall_pixel(tile, 3, color); set_wall_pixel(tile, 4, color); set_wall_pixel(tile, 5, 12); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); set_air_pixel(tile, 1, 4); set_air_pixel(tile, 2, color); set_air_pixel(tile, 3, color); @@ -430,28 +439,28 @@ fn draw_edge( }; match settings.other_settings.door_locks_size { DoorLocksSize::Small => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); set_wall_pixel(tile, 2, 12); set_wall_pixel(tile, 3, color); set_wall_pixel(tile, 4, color); set_wall_pixel(tile, 5, 12); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); set_air_pixel(tile, 2, 13); set_air_pixel(tile, 3, 4); set_air_pixel(tile, 4, 4); set_air_pixel(tile, 5, 13); } DoorLocksSize::Large => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); set_wall_pixel(tile, 3, color); set_wall_pixel(tile, 4, color); - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); set_air_pixel(tile, 2, 13); set_air_pixel(tile, 3, color); set_air_pixel(tile, 4, color); @@ -462,14 +471,14 @@ fn draw_edge( } } Wall => { - set_wall_pixel(tile, 0, 3); - set_wall_pixel(tile, 1, 3); - set_wall_pixel(tile, 2, 3); + set_wall_pixel(tile, 0, wall_color); + set_wall_pixel(tile, 1, wall_color); + set_wall_pixel(tile, 2, wall_color); set_wall_pixel(tile, 3, 13); set_wall_pixel(tile, 4, 13); - set_wall_pixel(tile, 5, 3); - set_wall_pixel(tile, 6, 3); - set_wall_pixel(tile, 7, 3); + set_wall_pixel(tile, 5, wall_color); + set_wall_pixel(tile, 6, wall_color); + set_wall_pixel(tile, 7, wall_color); } }, } @@ -480,7 +489,8 @@ pub fn render_tile( settings: &RandomizerSettings, customize_settings: &CustomizeSettings, ) -> Result<[[u8; 8]; 8]> { - let bg_color = if tile.heated && !settings.other_settings.ultra_low_qol { + let em = &settings.quality_of_life_settings.enhanced_map_settings; + let bg_color = if tile.heated && em.heat == EnhancedMapLevel::Visible { 2 } else { 1 @@ -495,33 +505,38 @@ pub fn render_tile( (MapLiquidType::Acid, true) => (2, 1), _ => panic!("unexpected liquid type"), }; - if let Some(liquid_level) = tile.liquid_level - && !settings.other_settings.ultra_low_qol - { - let level = (liquid_level * 8.0).floor() as isize; - for y in level..8 { - for x in 0..8 { - match tile.liquid_type { - MapLiquidType::Water => { - if (x + y) % 2 == 0 { - data[y as usize][x as usize] = liquid_colors.0; - } else { - data[y as usize][x as usize] = liquid_colors.1; + if let Some(liquid_level) = tile.liquid_level { + let visible = match tile.liquid_type { + MapLiquidType::Water => em.water, + MapLiquidType::Lava => em.lava, + MapLiquidType::Acid => em.acid, + MapLiquidType::None => EnhancedMapLevel::Hidden, + }; + if matches!(visible, EnhancedMapLevel::Visible) { + let level = (liquid_level * 8.0).floor() as isize; + for y in level..8 { + for x in 0..8 { + match tile.liquid_type { + MapLiquidType::Water => { + if (x + y) % 2 == 0 { + data[y as usize][x as usize] = liquid_colors.0; + } else { + data[y as usize][x as usize] = liquid_colors.1; + } } - } - MapLiquidType::Lava => { - data[y as usize][x as usize] = liquid_colors.1; - } - MapLiquidType::Acid => { - if (x + y) % 2 == 0 { + MapLiquidType::Lava => { data[y as usize][x as usize] = liquid_colors.1; } + MapLiquidType::Acid => { + if (x + y) % 2 == 0 { + data[y as usize][x as usize] = liquid_colors.1; + } + } + MapLiquidType::None => bail!("unexpected liquid type None"), } - MapLiquidType::None => bail!("unexpected liquid type None"), } } } - if tile.faded && tile.interior.is_item() && (tile.liquid_type == MapLiquidType::Lava @@ -625,57 +640,126 @@ pub fn render_tile( data[2][4] = 3; } MapTileInterior::SaveStation => { - update_tile( - &mut data, - 3, - &vec![ - (0, 0), - (1, 0), - (2, 0), - (3, 0), - (4, 0), - (5, 0), - (6, 0), - (7, 0), - (0, 1), - (1, 1), - (7, 1), - (0, 2), - (4, 2), - (5, 2), - (6, 2), - (7, 2), - (0, 3), - (6, 3), - (7, 3), - (0, 4), - (1, 4), - (7, 4), - (0, 5), - (1, 5), - (2, 5), - (3, 5), - (7, 5), - (0, 6), - (6, 6), - (7, 6), - (0, 7), - (1, 7), - (2, 7), - (3, 7), - (4, 7), - (5, 7), - (6, 7), - (7, 7), - ], - ); + if settings + .quality_of_life_settings + .enhanced_map_settings + .walls + == EnhancedMapWalls::Black + { + update_tile( + &mut data, + 0, + &vec![ + (2, 1), + (3, 1), + (4, 1), + (5, 1), + (6, 1), + (1, 2), + (2, 2), + (3, 2), + (1, 3), + (2, 3), + (3, 3), + (4, 3), + (5, 3), + (2, 4), + (3, 4), + (4, 4), + (5, 4), + (6, 4), + (4, 5), + (5, 5), + (6, 5), + (1, 6), + (2, 6), + (3, 6), + (4, 6), + (5, 6), + ], + ); + } else { + update_tile( + &mut data, + 3, + &vec![ + (0, 0), + (1, 0), + (2, 0), + (3, 0), + (4, 0), + (5, 0), + (6, 0), + (7, 0), + (0, 1), + (1, 1), + (7, 1), + (0, 2), + (4, 2), + (5, 2), + (6, 2), + (7, 2), + (0, 3), + (6, 3), + (7, 3), + (0, 4), + (1, 4), + (7, 4), + (0, 5), + (1, 5), + (2, 5), + (3, 5), + (7, 5), + (0, 6), + (6, 6), + (7, 6), + (0, 7), + (1, 7), + (2, 7), + (3, 7), + (4, 7), + (5, 7), + (6, 7), + (7, 7), + ], + ); + } } MapTileInterior::EnergyRefill => { - if settings.other_settings.ultra_low_qol { + if em.refill_station == EnhancedMapOther::Vanilla { data[3][3] = item_color; data[3][4] = item_color; data[4][3] = item_color; data[4][4] = item_color; + } else if em.refill_station == EnhancedMapOther::Icon + && em.walls == EnhancedMapWalls::Black + { + update_tile( + &mut data, + 0, + &vec![ + (3, 1), + (4, 1), + (3, 2), + (4, 2), + (1, 3), + (2, 3), + (3, 3), + (4, 3), + (5, 3), + (6, 3), + (1, 4), + (2, 4), + (3, 4), + (4, 4), + (5, 4), + (6, 4), + (3, 5), + (4, 5), + (3, 6), + (4, 6), + ], + ); } else { update_tile( &mut data, @@ -730,11 +814,40 @@ pub fn render_tile( } } MapTileInterior::AmmoRefill => { - if settings.other_settings.ultra_low_qol { + if em.refill_station == EnhancedMapOther::Vanilla { data[3][3] = item_color; data[3][4] = item_color; data[4][3] = item_color; data[4][4] = item_color; + } else if em.refill_station == EnhancedMapOther::Icon + && em.walls == EnhancedMapWalls::Black + { + update_tile( + &mut data, + 0, + &vec![ + (2, 2), + (3, 2), + (4, 2), + (5, 2), + (2, 3), + (5, 3), + (2, 4), + (3, 4), + (4, 4), + (5, 4), + (1, 5), + (2, 5), + (3, 5), + (4, 5), + (5, 5), + (6, 5), + (1, 6), + (3, 6), + (4, 6), + (6, 6), + ], + ); } else { update_tile( &mut data, @@ -787,11 +900,44 @@ pub fn render_tile( } } MapTileInterior::DoubleRefill | MapTileInterior::Ship => { - if settings.other_settings.ultra_low_qol { + if em.refill_station == EnhancedMapOther::Vanilla { data[3][3] = item_color; data[3][4] = item_color; data[4][3] = item_color; data[4][4] = item_color; + } else if em.refill_station == EnhancedMapOther::Icon + && em.walls == EnhancedMapWalls::Black + { + update_tile( + &mut data, + 0, + &vec![ + (1, 1), + (3, 1), + (4, 1), + (6, 1), + (3, 2), + (4, 2), + (1, 3), + (2, 3), + (3, 3), + (4, 3), + (5, 3), + (6, 3), + (1, 4), + (2, 4), + (3, 4), + (4, 4), + (5, 4), + (6, 4), + (3, 5), + (4, 5), + (1, 6), + (3, 6), + (4, 6), + (6, 6), + ], + ); } else { update_tile( &mut data, @@ -842,55 +988,125 @@ pub fn render_tile( } } MapTileInterior::Objective => { - update_tile( - &mut data, - 3, - &vec![ - (0, 0), - (1, 0), - (2, 0), - (3, 0), - (4, 0), - (5, 0), - (6, 0), - (7, 0), - (0, 1), - (3, 1), - (4, 1), - (7, 1), - (0, 2), - (7, 2), - (0, 3), - (1, 3), - (6, 3), - (7, 3), - (0, 4), - (1, 4), - (6, 4), - (7, 4), - (0, 5), - (7, 5), - (0, 6), - (3, 6), - (4, 6), - (7, 6), - (0, 7), - (1, 7), - (2, 7), - (3, 7), - (4, 7), - (5, 7), - (6, 7), - (7, 7), - ], - ); + if em.objectives == EnhancedMapOther::Icon && em.walls == EnhancedMapWalls::Black { + update_tile( + &mut data, + 0, + &vec![ + (1, 1), + (2, 1), + (5, 1), + (6, 1), + (1, 2), + (2, 2), + (3, 2), + (4, 2), + (5, 2), + (6, 2), + (2, 3), + (3, 3), + (4, 3), + (5, 3), + (2, 4), + (3, 4), + (4, 4), + (5, 4), + (1, 5), + (2, 5), + (3, 5), + (4, 5), + (5, 5), + (6, 5), + (1, 6), + (2, 6), + (5, 6), + (6, 6), + ], + ); + } else if em.objectives == EnhancedMapOther::Icon && em.walls == EnhancedMapWalls::White + { + update_tile( + &mut data, + 3, + &vec![ + (0, 0), + (1, 0), + (2, 0), + (3, 0), + (4, 0), + (5, 0), + (6, 0), + (7, 0), + (0, 1), + (3, 1), + (4, 1), + (7, 1), + (0, 2), + (7, 2), + (0, 3), + (1, 3), + (6, 3), + (7, 3), + (0, 4), + (1, 4), + (6, 4), + (7, 4), + (0, 5), + (7, 5), + (0, 6), + (3, 6), + (4, 6), + (7, 6), + (0, 7), + (1, 7), + (2, 7), + (3, 7), + (4, 7), + (5, 7), + (6, 7), + (7, 7), + ], + ); + } } MapTileInterior::MapStation => { - if settings.other_settings.ultra_low_qol { + if em.map_station == EnhancedMapOther::Vanilla { data[3][3] = item_color; data[3][4] = item_color; data[4][3] = item_color; data[4][4] = item_color; + } else if em.map_station == EnhancedMapOther::Icon + && em.walls == EnhancedMapWalls::Black + { + update_tile( + &mut data, + 0, + &vec![ + (1, 1), + (2, 1), + (3, 1), + (4, 1), + (5, 1), + (6, 1), + (1, 2), + (6, 2), + (1, 3), + (3, 3), + (4, 3), + (6, 3), + (1, 4), + (3, 4), + (4, 4), + (6, 4), + (1, 5), + (6, 5), + (1, 6), + (2, 6), + (3, 6), + (4, 6), + (5, 6), + ], + ); } else { update_tile( &mut data, @@ -942,12 +1158,16 @@ pub fn render_tile( } } - let apply_heat = |d: [[u8; 8]; 8]| { - if tile.heated && !settings.other_settings.ultra_low_qol { - d.map(|row| row.map(|c| if c == 1 { 2 } else { c })) - } else { - d + let apply_heat = |mut d: [[u8; 8]; 8]| { + if tile.heated && em.heat == EnhancedMapLevel::Visible { + d = d.map(|row| row.map(|c| if c == 1 { 2 } else { c })); + } + + if em.walls == EnhancedMapWalls::Black { + d = d.map(|row| row.map(|c| if c == 3 { 4 } else { c })); } + + d }; match tile.special_type { Some(MapTileSpecialType::AreaTransition(area_idx, dir)) => { @@ -1215,25 +1435,20 @@ pub fn render_tile( None => {} } - if tile.special_type.is_some() - || (!settings.other_settings.ultra_low_qol - && [ - MapTileInterior::AmmoRefill, - MapTileInterior::EnergyRefill, - MapTileInterior::DoubleRefill, - MapTileInterior::Ship, - MapTileInterior::SaveStation, - MapTileInterior::MapStation, - MapTileInterior::Objective, - ] - .contains(&tile.interior)) - { - // Skip drawing door & wall edges in special tiles - } else { - draw_edge(TileSide::Top, tile.top, &mut data, settings); - draw_edge(TileSide::Bottom, tile.bottom, &mut data, settings); - draw_edge(TileSide::Left, tile.left, &mut data, settings); - draw_edge(TileSide::Right, tile.right, &mut data, settings); + match tile.interior { + MapTileInterior::AmmoRefill if em.refill_station == EnhancedMapOther::Icon => {} + MapTileInterior::EnergyRefill if em.refill_station == EnhancedMapOther::Icon => {} + MapTileInterior::DoubleRefill if em.refill_station == EnhancedMapOther::Icon => {} + MapTileInterior::Ship if em.refill_station == EnhancedMapOther::Icon => {} + MapTileInterior::SaveStation => {} + MapTileInterior::MapStation if em.map_station == EnhancedMapOther::Icon => {} + MapTileInterior::Objective if em.objectives == EnhancedMapOther::Icon => {} + _ => { + draw_edge(TileSide::Top, tile.top, &mut data, settings); + draw_edge(TileSide::Bottom, tile.bottom, &mut data, settings); + draw_edge(TileSide::Left, tile.left, &mut data, settings); + draw_edge(TileSide::Right, tile.right, &mut data, settings); + } } Ok(data) } @@ -1964,11 +2179,15 @@ impl<'a> MapPatcher<'a> { for pass in [0, 1] { for (i, locked_door) in self.randomization.locked_doors.iter().enumerate() { // Process wall doors on a first pass, all other door types on second pass. + let locksettings = &self.settings.quality_of_life_settings.enhanced_map_settings; let valid = match (pass, locked_door.door_type) { (0, DoorType::Wall) => true, (0, _) => false, (1, DoorType::Wall) => false, - (1, _) => true, + (1, DoorType::Beam(_)) => locksettings.beam_doors == EnhancedMapLevel::Visible, + (1, DoorType::Red | DoorType::Green | DoorType::Yellow) => { + locksettings.ammo_doors == EnhancedMapLevel::Visible + } _ => panic!("internal error"), }; if !valid { @@ -2434,34 +2653,27 @@ impl<'a> MapPatcher<'a> { if [MapTileInterior::HiddenItem, MapTileInterior::DoubleItem].contains(&tile.interior) { tile.interior = MapTileInterior::Item; } - // the ultralow qol setting can be removed when its finally removed from the frontend. - // there is also the potential to have "non disappearing dots option" by using the ultralow QOL - // setting when using 2/3/4 tier items if its desired. This would replace a Major / Hollow / X with - // a non faded dot. - if self.settings.other_settings.ultra_low_qol { - tile.interior = MapTileInterior::Item; - self.set_room_tile(room_id, x, y, tile.clone()); - } else { - tile.interior = get_item_interior(item, self.settings); - self.dynamic_tile_data[area].push((item_idx, room_id, tile.clone())); - match self.customize_settings.item_dot_change { - ItemDotChange::Fade => { - tile.interior = apply_item_interior(orig_tile.clone(), item, self.settings); - tile.faded = true; - self.set_room_tile(room_id, x, y, tile.clone()); - } - ItemDotChange::Disappear => { - tile.interior = MapTileInterior::Empty; - self.set_room_tile(room_id, x, y, tile.clone()); - } - ItemDotChange::Stay => { - tile.interior = apply_item_interior(orig_tile.clone(), item, self.settings); - tile.faded = false; - self.set_room_tile(room_id, x, y, tile.clone()); - } + + tile.interior = get_item_interior(item, self.settings); + self.dynamic_tile_data[area].push((item_idx, room_id, tile.clone())); + match self.customize_settings.item_dot_change { + ItemDotChange::Fade => { + tile.interior = apply_item_interior(orig_tile.clone(), item, self.settings); + tile.faded = true; + self.set_room_tile(room_id, x, y, tile.clone()); + } + ItemDotChange::Disappear => { + tile.interior = MapTileInterior::Empty; + self.set_room_tile(room_id, x, y, tile.clone()); + } + ItemDotChange::Stay => { + tile.interior = apply_item_interior(orig_tile.clone(), item, self.settings); + tile.faded = false; + self.set_room_tile(room_id, x, y, tile.clone()); } } } + Ok(()) } @@ -2957,10 +3169,16 @@ impl<'a> MapPatcher<'a> { } self.apply_room_tiles()?; self.indicate_objective_tiles()?; - if !self.settings.other_settings.ultra_low_qol { + if self + .settings + .quality_of_life_settings + .enhanced_map_settings + .gray_doors + == EnhancedMapLevel::Visible + { self.indicate_gray_doors()?; - self.indicate_locked_doors()?; } + self.indicate_locked_doors()?; self.add_cross_area_arrows()?; self.set_map_activation_behavior()?; self.indicate_items()?; diff --git a/rust/maprando/src/settings.rs b/rust/maprando/src/settings.rs index 1c3ef38c7a..3da867dc84 100644 --- a/rust/maprando/src/settings.rs +++ b/rust/maprando/src/settings.rs @@ -157,6 +157,7 @@ impl Display for EnemyDrops { pub struct QualityOfLifeSettings { pub preset: Option, // Map: + pub enhanced_map_settings: EnhancedMapSettings, pub initial_map_reveal_settings: InitialMapRevealSettings, pub item_markers: ItemMarkers, pub room_outline_revealed: bool, @@ -215,6 +216,43 @@ impl Display for MapRevealLevel { } } +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] +pub enum EnhancedMapLevel { + Hidden, + Visible, +} + +impl Display for EnhancedMapLevel { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{self:?}") + } +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] +pub enum EnhancedMapOther { + Vanilla, + Icon, +} + +impl Display for EnhancedMapOther { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{self:?}") + } +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] +pub enum EnhancedMapWalls { + Vanilla, + White, + Black, +} + +impl Display for EnhancedMapWalls { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{self:?}") + } +} + #[derive(Serialize, Deserialize, Clone, PartialEq)] pub struct InitialMapRevealSettings { pub preset: Option, @@ -232,6 +270,23 @@ pub struct InitialMapRevealSettings { pub all_areas: bool, } +#[derive(Serialize, Deserialize, Clone, PartialEq)] +pub struct EnhancedMapSettings { + pub preset: Option, + pub blue_doors: EnhancedMapLevel, + pub gray_doors: EnhancedMapLevel, + pub ammo_doors: EnhancedMapLevel, + pub beam_doors: EnhancedMapLevel, + pub heat: EnhancedMapLevel, + pub water: EnhancedMapLevel, + pub lava: EnhancedMapLevel, + pub acid: EnhancedMapLevel, + pub walls: EnhancedMapWalls, + pub objectives: EnhancedMapOther, + pub map_station: EnhancedMapOther, + pub refill_station: EnhancedMapOther, +} + #[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] pub enum Objective { Kraid, @@ -394,7 +449,6 @@ pub struct OtherSettings { pub map_station_reveal: MapStationReveal, pub energy_free_shinesparks: bool, pub all_enemies_respawn: bool, - pub ultra_low_qol: bool, pub disable_spikesuit: bool, pub disable_bluesuit: bool, pub enable_major_glitches: bool, @@ -923,6 +977,52 @@ fn upgrade_initial_map_reveal_settings(settings: &mut serde_json::Value) -> Resu Ok(()) } +fn upgrade_enhanced_map_settings(settings: &mut serde_json::Value) -> Result<()> { + // Skip if already present + if settings["quality_of_life_settings"] + .as_object() + .unwrap() + .contains_key("enhanced_map_settings") + { + return Ok(()); + } + + let qol_settings = settings["quality_of_life_settings"] + .as_object_mut() + .context("missing 'quality_of_life_settings'")?; + + let enhanced = EnhancedMapSettings { + preset: Some("Yes".to_string()), + + // Doors + blue_doors: EnhancedMapLevel::Visible, + gray_doors: EnhancedMapLevel::Visible, + ammo_doors: EnhancedMapLevel::Visible, + beam_doors: EnhancedMapLevel::Visible, + + // Environment hazards + heat: EnhancedMapLevel::Visible, + water: EnhancedMapLevel::Visible, + lava: EnhancedMapLevel::Visible, + acid: EnhancedMapLevel::Visible, + + // Map structure + walls: EnhancedMapWalls::White, + + // Special tiles + objectives: EnhancedMapOther::Icon, + map_station: EnhancedMapOther::Icon, + refill_station: EnhancedMapOther::Icon, + }; + + qol_settings.insert( + "enhanced_map_settings".to_string(), + serde_json::to_value(enhanced)?, + ); + + Ok(()) +} + fn upgrade_qol_settings(settings: &mut serde_json::Value) -> Result<()> { let etank_refill = settings["other_settings"]["etank_refill"] .as_str() @@ -1021,6 +1121,7 @@ fn upgrade_qol_settings(settings: &mut serde_json::Value) -> Result<()> { } upgrade_initial_map_reveal_settings(settings)?; + upgrade_enhanced_map_settings(settings)?; Ok(()) } diff --git a/rust/maprando/src/traverse.rs b/rust/maprando/src/traverse.rs index ff9794099e..50ed11516d 100644 --- a/rust/maprando/src/traverse.rs +++ b/rust/maprando/src/traverse.rs @@ -1821,8 +1821,10 @@ fn apply_requirement_simple( Requirement::AcidChozoWithoutSpaceJump => { cx.settings.quality_of_life_settings.acid_chozo.into() } - Requirement::KraidCameraFix => (!cx.settings.other_settings.ultra_low_qol).into(), - Requirement::CrocomireCameraFix => (!cx.settings.other_settings.ultra_low_qol).into(), + Requirement::KraidCameraFix => (cx.settings.quality_of_life_settings.camera_fixes).into(), + Requirement::CrocomireCameraFix => { + (cx.settings.quality_of_life_settings.camera_fixes).into() + } Requirement::RegularEnergyDrain(count) => { let count = count.resolve(&cx.difficulty.numerics); let energy_remaining = local.energy_remaining(&cx.global.inventory, false); diff --git a/rust/maprando/tests/logic_scenarios.rs b/rust/maprando/tests/logic_scenarios.rs index ad0302303f..9a5d5c9d9e 100644 --- a/rust/maprando/tests/logic_scenarios.rs +++ b/rust/maprando/tests/logic_scenarios.rs @@ -5,9 +5,10 @@ use hashbrown::HashMap; use maprando::{ randomize::{DifficultyConfig, LockedDoor, Preprocessor, make_locked_door_data}, settings::{ - DisableETankSetting, DoorsSettings, EnemyDrops, InitialMapRevealSettings, - ItemProgressionSettings, Objective, ObjectiveSettings, OtherSettings, - QualityOfLifeSettings, RandomizerSettings, SkillAssumptionSettings, StartLocationSettings, + DisableETankSetting, DoorsSettings, EnemyDrops, EnhancedMapSettings, + InitialMapRevealSettings, ItemProgressionSettings, Objective, ObjectiveSettings, + OtherSettings, QualityOfLifeSettings, RandomizerSettings, SkillAssumptionSettings, + StartLocationSettings, }, traverse::{LockedDoorData, Traverser}, }; @@ -212,6 +213,21 @@ fn get_settings(scenario: &Scenario) -> Result { }, quality_of_life_settings: QualityOfLifeSettings { preset: None, + enhanced_map_settings: EnhancedMapSettings { + preset: None, + blue_doors: maprando::settings::EnhancedMapLevel::Hidden, + gray_doors: maprando::settings::EnhancedMapLevel::Hidden, + ammo_doors: maprando::settings::EnhancedMapLevel::Hidden, + beam_doors: maprando::settings::EnhancedMapLevel::Hidden, + heat: maprando::settings::EnhancedMapLevel::Hidden, + water: maprando::settings::EnhancedMapLevel::Hidden, + lava: maprando::settings::EnhancedMapLevel::Hidden, + acid: maprando::settings::EnhancedMapLevel::Hidden, + walls: maprando::settings::EnhancedMapWalls::Vanilla, + objectives: maprando::settings::EnhancedMapOther::Vanilla, + map_station: maprando::settings::EnhancedMapOther::Vanilla, + refill_station: maprando::settings::EnhancedMapOther::Vanilla, + }, initial_map_reveal_settings: InitialMapRevealSettings { preset: None, map_stations: maprando::settings::MapRevealLevel::No, @@ -319,7 +335,6 @@ fn get_settings(scenario: &Scenario) -> Result { disable_bluesuit: false, disable_spikesuit: false, enable_major_glitches: false, - ultra_low_qol: false, race_mode: false, random_seed: None, },