diff --git a/patches/ips/remove_bluesuits.ips b/patches/ips/remove_bluesuits.ips new file mode 100644 index 0000000000..60b8415103 Binary files /dev/null and b/patches/ips/remove_bluesuits.ips differ diff --git a/patches/ips/remove_spikesuits.ips b/patches/ips/remove_spikesuits.ips new file mode 100644 index 0000000000..a11f38facd Binary files /dev/null and b/patches/ips/remove_spikesuits.ips differ diff --git a/patches/ips/vanilla_bugfixes.ips b/patches/ips/vanilla_bugfixes.ips index 21a421e9c2..50bfbfd8c7 100644 Binary files a/patches/ips/vanilla_bugfixes.ips and b/patches/ips/vanilla_bugfixes.ips differ diff --git a/patches/rom_map/Bank 80.txt b/patches/rom_map/Bank 80.txt index 830a074d72..bdc76daf49 100644 --- a/patches/rom_map/Bank 80.txt +++ b/patches/rom_map/Bank 80.txt @@ -12,7 +12,7 @@ DA00 - DD00: msu1.asm DD00 - E100: Palette pointer table for Mosaic E100 - E180: area_palette.asm E180 - E1B0: fix_horiz_doors.asm -E1B0 - E2A0: [FREE] +E1B0 - E2A0: remove_spikesuits.asm E2A0 - E3C0: decompression.asm E3C0 - E440: disable_etanks.asm E440 - E540: load_plms_early.asm diff --git a/patches/rom_map/Bank 85.txt b/patches/rom_map/Bank 85.txt index 62deded811..da43322e7a 100644 --- a/patches/rom_map/Bank 85.txt +++ b/patches/rom_map/Bank 85.txt @@ -18,4 +18,4 @@ $AB00 - $ACA0: map_area.asm $ACA0 - $AD00: load_flash_suit $AD00 - $AFD0: map_area.asm $AFD0 - $B000: [FREE] -$B000 - $B4B0: vanilla_bugfixes.asm +$B000 - $D4B0: vanilla_bugfixes.asm diff --git a/patches/src/remove_bluesuits.asm b/patches/src/remove_bluesuits.asm new file mode 100644 index 0000000000..b10864e38a --- /dev/null +++ b/patches/src/remove_bluesuits.asm @@ -0,0 +1,9 @@ +; Removes a spikesuit state from samus + +arch snes.cpu +lorom + + +org $91DE5C ; replace the instruction that allows Samus to gain a bluesuit (speedbooster is only cancelled if running flag is 0) + nop + nop \ No newline at end of file diff --git a/patches/src/remove_spikesuits.asm b/patches/src/remove_spikesuits.asm new file mode 100644 index 0000000000..e00c0eb793 --- /dev/null +++ b/patches/src/remove_spikesuits.asm @@ -0,0 +1,30 @@ +; Removes a spikesuit state from samus + +arch snes.cpu +lorom + +!any_bank_free_space_start = $80E1B0 +!any_bank_free_space_end = $80E2A0 + +org $90D4BC ; hook end of shinespark crash + jsl check_ss + nop + nop + +org !any_bank_free_space_start +check_ss: + LDA $0ACC ; Samus palette type normal? [regular shinecharge] + BNE .skip + LDA $0A68 ; special timer non zero? [can spark] + BEQ .skip + LDA #$0000 + STA $0A68 ; goodbye spikesuit + LDA #$0045 ; msg ID + JSL $85B000 + .skip: + LDA #$0002 + STA $0A32 + STZ $0DEC + RTL + +assert pc() <= !any_bank_free_space_end diff --git a/patches/src/tables/remove_bluesuits.asm b/patches/src/tables/remove_bluesuits.asm new file mode 100644 index 0000000000..f5426b13bd --- /dev/null +++ b/patches/src/tables/remove_bluesuits.asm @@ -0,0 +1,12 @@ +; Removes a spikesuit state from samus + +arch snes.cpu +lorom + + +org $91DE59 ; replace the instruction that allows Samus to gain a bluesuit (speedbooster is only cancelled if running flag is 0) + STZ $0B3E + LDA $0B3C + BEQ $2F + STZ $0B3C + \ No newline at end of file diff --git a/patches/src/vanilla_bugfixes.asm b/patches/src/vanilla_bugfixes.asm index 530f2e25df..0a940d6bba 100644 --- a/patches/src/vanilla_bugfixes.asm +++ b/patches/src/vanilla_bugfixes.asm @@ -79,7 +79,7 @@ check_empty: .end: rts -warnpc $a0f830 +assert pc() <= $a0f830 ;;; Fixes for the extra save stations in area rando/random start : @@ -123,7 +123,7 @@ save_station_check: jmp search_loop_found ;;; end of unused space -warnpc $8485b2 +assert pc() <= $8485b2 ; Use door direction ($0791) to check in Big Boy room if we are coming in from the left vs. right. @@ -181,7 +181,7 @@ fix_camera_alignment: LDA $B1 : SEC RTS -warnpc !bank_80_free_space_end +assert pc() <= !bank_80_free_space_end ; skip loading special x-ray blocks (only used in BT room during escape, and we repurpose the space for other things) @@ -209,7 +209,7 @@ check_item_plm: clc rts -warnpc $848398 +assert pc() <= $848398 org $848398 special_xray_end: @@ -239,7 +239,7 @@ pause_func: stz $9d6 ; clear reserve health rts -warnpc !bank_82_free_space_end +assert pc() <= !bank_82_free_space_end ; Fix for powamp projectile bug ; @@ -268,7 +268,7 @@ powamp_fix: sta $1a4b,y ; replaced code rts -warnpc !bank_86_free_space_end +assert pc() <= !bank_86_free_space_end ; Fix improper clearing of BG2 ; Noted by PJBoy: https://patrickjohnston.org/bank/80#fA23F @@ -299,7 +299,7 @@ yapping_maw_crash: .skip jmp ($d37d,x) ; valid entry -warnPC !bank_90_free_space_end +assert pc() <= !bank_90_free_space_end ;;; Spring ball menu crash fix by strotlog. ;;; Fix obscure vanilla bug where: turning off spring ball while bouncing, can crash in $91:EA07, @@ -314,7 +314,7 @@ org $91f1fc jsl spring_ball_crash !bank_85_free_space_start = $85b000 ; do not change, first jmp used externally -!bank_85_free_space_end = $85b4b0 +!bank_85_free_space_end = $85d4b0 org !bank_85_free_space_start jmp bug_dialog ; for external calls, do not move @@ -352,7 +352,8 @@ bug_dialog: ; A = msg ID pla ; dlg box parameter jsl $858080 ; dlg box - + cmp #$0045 ; spikesuit disabled msg + beq .nokillmsg ; we don't want to kill samus for spikesuiting so skip the death sequence lda #$8000 ; init death sequence (copied from $82db80) sta $a78 lda #$0011 @@ -360,6 +361,7 @@ bug_dialog: ; A = msg ID lda #$0013 ; set gamestate sta $998 + .nokillmsg rtl hook_message_box: @@ -416,6 +418,7 @@ new_message_boxes: dw $83c5, $825a, springball_msg ; 0x42 dw $83c5, $825a, yapping_maw_msg ; 0x43 dw $83c5, $825a, oob_msg ; 0x44 + dw $83c5, $825a, ss_msg ; 0x45 dw $0000, $0000, msg_end table "tables/dialog_chars.tbl",RTL @@ -443,10 +446,16 @@ oob_msg: dw $000e,$000e,$000e, " SAMUS OUT-OF-BOUNDS! ", $000e,$000e,$000e dw $000e,$000e,$000e, " ", $000e,$000e,$000e dw $000e,$000e,$000e, " ", $000e,$000e,$000e + +ss_msg: + dw $000e,$000e,$000e, " ", $000e,$000e,$000e + dw $000e,$000e,$000e, " SPIKE SUIT DISABLED! ", $000e,$000e,$000e + dw $000e,$000e,$000e, " ", $000e,$000e,$000e + dw $000e,$000e,$000e, " ", $000e,$000e,$000e msg_end: -warnPC !bank_85_free_space_end +assert pc() <= !bank_85_free_space_end org $858093 jsr hook_message_box @@ -483,7 +492,7 @@ check_unpause: lda #$0008 ; replaced code jmp $93be -warnPC !bank_82_free_space2_end +assert pc() <= !bank_82_free_space2_end ; Map scrolling bug ; Leftmost edge function @ $829f4a has an off-by-one bug when scanning 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 a1189bb38b..f66e02133b 100644 --- a/rust/data/presets/full-settings/Community Race Season 4.json +++ b/rust/data/presets/full-settings/Community Race Season 4.json @@ -4513,6 +4513,8 @@ "door_locks_size": "Large", "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/data/presets/full-settings/Default.json b/rust/data/presets/full-settings/Default.json index 5498ce53ab..49dbdbfac6 100644 --- a/rust/data/presets/full-settings/Default.json +++ b/rust/data/presets/full-settings/Default.json @@ -4514,6 +4514,8 @@ "door_locks_size": "Large", "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": false, "random_seed": null diff --git a/rust/data/presets/full-settings/Winter Tournament - 4 Random Objectives.json b/rust/data/presets/full-settings/Winter Tournament - 4 Random Objectives.json index 8e49963c2b..7e53837673 100644 --- a/rust/data/presets/full-settings/Winter Tournament - 4 Random Objectives.json +++ b/rust/data/presets/full-settings/Winter Tournament - 4 Random Objectives.json @@ -4586,6 +4586,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/data/presets/full-settings/Winter Tournament - Double Suit.json b/rust/data/presets/full-settings/Winter Tournament - Double Suit.json index 4e2fb929db..e6953b3076 100644 --- a/rust/data/presets/full-settings/Winter Tournament - Double Suit.json +++ b/rust/data/presets/full-settings/Winter Tournament - Double Suit.json @@ -4586,6 +4586,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/data/presets/full-settings/Winter Tournament - Gravity 9 + 1.json b/rust/data/presets/full-settings/Winter Tournament - Gravity 9 + 1.json index 7605ec9abc..5436762a0a 100644 --- a/rust/data/presets/full-settings/Winter Tournament - Gravity 9 + 1.json +++ b/rust/data/presets/full-settings/Winter Tournament - Gravity 9 + 1.json @@ -4586,6 +4586,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/data/presets/full-settings/Winter Tournament - Metroid Objectives.json b/rust/data/presets/full-settings/Winter Tournament - Metroid Objectives.json index 8d4b60c9ea..6650d8a64e 100644 --- a/rust/data/presets/full-settings/Winter Tournament - Metroid Objectives.json +++ b/rust/data/presets/full-settings/Winter Tournament - Metroid Objectives.json @@ -4586,6 +4586,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/data/presets/full-settings/Winter Tournament - No Objectives.json b/rust/data/presets/full-settings/Winter Tournament - No Objectives.json index 928ce79f4e..2c460c2e65 100644 --- a/rust/data/presets/full-settings/Winter Tournament - No Objectives.json +++ b/rust/data/presets/full-settings/Winter Tournament - No Objectives.json @@ -4586,6 +4586,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/data/presets/full-settings/Winter Tournament - Varia + Movement.json b/rust/data/presets/full-settings/Winter Tournament - Varia + Movement.json index f121d8bd81..d015ddcb32 100644 --- a/rust/data/presets/full-settings/Winter Tournament - Varia + Movement.json +++ b/rust/data/presets/full-settings/Winter Tournament - Varia + Movement.json @@ -4586,6 +4586,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": true, "random_seed": null diff --git a/rust/maprando-game/src/lib.rs b/rust/maprando-game/src/lib.rs index 4223bbf42f..8fc3d0b5d5 100644 --- a/rust/maprando-game/src/lib.rs +++ b/rust/maprando-game/src/lib.rs @@ -70,6 +70,14 @@ pub const TECH_ID_CAN_ELEVATOR_CRYSTAL_FLASH: TechId = 178; pub const TECH_ID_CAN_CARRY_FLASH_SUIT: TechId = 207; pub const TECH_ID_CAN_TRICKY_CARRY_FLASH_SUIT: TechId = 142; pub const TECH_ID_CAN_HYPER_GATE_SHOT: TechId = 10001; +pub const TECH_ID_CAN_SLOPE_SPARK: TechId = 210; +pub const TECH_ID_CAN_RMODE_KNOCKBACK_SPARK: TechId = 213; +pub const TECH_ID_CAN_CRYSTAL_SPARK: TechId = 217; +pub const TECH_ID_CAN_RMODE_SPARK_INTERRUPT: TechId = 216; +pub const TECH_ID_CAN_RMODE_PAUSE_SPARK_INTERRUPT: TechId = 222; +pub const TECH_ID_CAN_XMODE_BLUE_SUIT: TechId = 223; +pub const TECH_ID_CAN_SLOPE_XMODE: TechId = 225; + #[allow(clippy::type_complexity)] #[derive(Deserialize, Serialize, Clone, Debug)] diff --git a/rust/maprando-web/templates/generate/game_variations.html b/rust/maprando-web/templates/generate/game_variations.html index 800b5d26d4..7b243507c7 100644 --- a/rust/maprando-web/templates/generate/game_variations.html +++ b/rust/maprando-web/templates/generate/game_variations.html @@ -63,6 +63,32 @@ +
+
+ {% include "help/variations/remove_spikesuits.html" %} + +
+
+ + + + +
+
+
+
+ {% include "help/variations/remove_bluesuits.html" %} + +
+
+ + + + +
+
{% include "help/variations/ultra_low_qol.html" %} diff --git a/rust/maprando-web/templates/generate/help/variations/remove_bluesuits.html b/rust/maprando-web/templates/generate/help/variations/remove_bluesuits.html new file mode 100644 index 0000000000..e9e6c6974d --- /dev/null +++ b/rust/maprando-web/templates/generate/help/variations/remove_bluesuits.html @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/rust/maprando-web/templates/generate/help/variations/remove_spikesuits.html b/rust/maprando-web/templates/generate/help/variations/remove_spikesuits.html new file mode 100644 index 0000000000..cd0a7d0538 --- /dev/null +++ b/rust/maprando-web/templates/generate/help/variations/remove_spikesuits.html @@ -0,0 +1,23 @@ + + + + \ 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 f87f73e2e6..39541d2a4f 100644 --- a/rust/maprando-web/templates/generate/scripts.html +++ b/rust/maprando-web/templates/generate/scripts.html @@ -291,6 +291,8 @@ "maps_revealed": formData.get("maps_revealed"), "map_station_reveal": formData.get("map_station_reveal"), "energy_free_shinesparks": formData.get("energy_free_shinesparks") == "true", + "remove_spikesuits": formData.get("remove_spikesuits"), + "remove_bluesuits": formData.get("remove_bluesuits"), "ultra_low_qol": formData.get("ultra_low_qol") == "true", "race_mode": formData.get("race_mode") == "true", "random_seed": tryParseInt(formData.get("random_seed")), diff --git a/rust/maprando/src/patch.rs b/rust/maprando/src/patch.rs index 69f414e280..417d0866dd 100644 --- a/rust/maprando/src/patch.rs +++ b/rust/maprando/src/patch.rs @@ -19,7 +19,7 @@ use crate::{ randomize::{LockedDoor, Randomization}, settings::{ AreaAssignment, ETankRefill, Fanfares, ItemCount, MotherBrainFight, Objective, - ObjectiveScreen, RandomizerSettings, SaveAnimals, StartLocationMode, WallJump, + ObjectiveScreen, RandomizerSettings, SaveAnimals, StartLocationMode, WallJump, SpikeSuits, BlueSuits, }, }; use anyhow::{Context, Result, bail, ensure}; @@ -555,6 +555,20 @@ impl Patcher<'_> { } } + match self.settings.other_settings.remove_spikesuits{ + SpikeSuits::Disabled => {} + SpikeSuits::Enabled => { + patches.push("remove_spikesuits"); + } + } + + match self.settings.other_settings.remove_bluesuits{ + BlueSuits::Disabled => {} + BlueSuits::Enabled => { + patches.push("remove_bluesuits"); + } + } + if self .settings .quality_of_life_settings diff --git a/rust/maprando/src/randomize.rs b/rust/maprando/src/randomize.rs index ec9ff29b2b..cee48a53d2 100644 --- a/rust/maprando/src/randomize.rs +++ b/rust/maprando/src/randomize.rs @@ -36,8 +36,9 @@ use maprando_game::{ TECH_ID_CAN_SIDE_PLATFORM_CROSS_ROOM_JUMP, TECH_ID_CAN_SPEEDBALL, TECH_ID_CAN_SPRING_BALL_BOUNCE, TECH_ID_CAN_STATIONARY_SPIN_JUMP, TECH_ID_CAN_STUTTER_WATER_SHINECHARGE, TECH_ID_CAN_SUPER_SINK, TECH_ID_CAN_TEMPORARY_BLUE, - TECH_ID_CAN_TRICKY_CARRY_FLASH_SUIT, TechId, TemporaryBlueDirection, TraversalId, VertexId, - VertexKey, + TECH_ID_CAN_TRICKY_CARRY_FLASH_SUIT, TECH_ID_CAN_SPIKE_SUIT, TECH_ID_CAN_SLOPE_SPARK, + TECH_ID_CAN_RMODE_KNOCKBACK_SPARK, TECH_ID_CAN_CRYSTAL_SPARK, TECH_ID_CAN_RMODE_SPARK_INTERRUPT, TECH_ID_CAN_RMODE_PAUSE_SPARK_INTERRUPT, + TECH_ID_CAN_XMODE_BLUE_SUIT, TECH_ID_CAN_SLOPE_XMODE, TechId, TemporaryBlueDirection, TraversalId, VertexId, VertexKey, }; use maprando_logic::{GlobalState, Inventory, LocalState}; use rand::SeedableRng; @@ -98,6 +99,15 @@ impl DifficultyConfig { let mut tech: Vec = vec![false; game_data.tech_isv.keys.len()]; let mut notables: Vec = vec![false; game_data.notable_isv.keys.len()]; + // todo alter function to exclude bluesuit / spikesuit tech if disable in game + + let spikesuit_tech_list=[TECH_ID_CAN_SPIKE_SUIT, TECH_ID_CAN_SLOPE_SPARK, + TECH_ID_CAN_RMODE_KNOCKBACK_SPARK]; + + let bluesuit_tech_list=[TECH_ID_CAN_CRYSTAL_SPARK, TECH_ID_CAN_RMODE_SPARK_INTERRUPT,TECH_ID_CAN_RMODE_PAUSE_SPARK_INTERRUPT, + TECH_ID_CAN_XMODE_BLUE_SUIT, TECH_ID_CAN_SLOPE_XMODE]; + + // for &tech_id in implicit_tech { let tech_idx = game_data.tech_isv.index_by_key[&tech_id]; tech[tech_idx] = true; diff --git a/rust/maprando/src/settings.rs b/rust/maprando/src/settings.rs index f422215284..8c39dbb5e0 100644 --- a/rust/maprando/src/settings.rs +++ b/rust/maprando/src/settings.rs @@ -347,6 +347,8 @@ pub struct OtherSettings { pub door_locks_size: DoorLocksSize, pub map_station_reveal: MapStationReveal, pub energy_free_shinesparks: bool, + pub remove_spikesuits: SpikeSuits, + pub remove_bluesuits: BlueSuits, pub ultra_low_qol: bool, pub race_mode: bool, pub random_seed: Option, @@ -451,6 +453,17 @@ pub enum WallJump { Collectible, } +#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq)] +pub enum SpikeSuits { + Disabled, + Enabled, +} + +#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq)] +pub enum BlueSuits { + Disabled, + Enabled, +} #[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq)] pub enum ETankRefill { Disabled, diff --git a/rust/maprando/tests/logic_scenarios.rs b/rust/maprando/tests/logic_scenarios.rs index 9be955cc2b..31a4be143c 100644 --- a/rust/maprando/tests/logic_scenarios.rs +++ b/rust/maprando/tests/logic_scenarios.rs @@ -250,6 +250,8 @@ fn get_settings(scenario: &Scenario) -> Result { door_locks_size: maprando::settings::DoorLocksSize::Large, map_station_reveal: maprando::settings::MapStationReveal::Full, energy_free_shinesparks: false, + remove_spikesuits: maprando::settings::SpikeSuits::Disabled, + remove_bluesuits: maprando::settings::BlueSuits::Disabled, ultra_low_qol: false, race_mode: false, random_seed: None, diff --git a/rust/maprando/tests/presets/v119-Default.json b/rust/maprando/tests/presets/v119-Default.json index 2854762dfd..2b35acb654 100644 --- a/rust/maprando/tests/presets/v119-Default.json +++ b/rust/maprando/tests/presets/v119-Default.json @@ -4346,6 +4346,8 @@ "maps_revealed": null, "map_station_reveal": "Full", "energy_free_shinesparks": false, + "remove_spikesuits": "Disabled", + "remove_bluesuits": "Disabled", "ultra_low_qol": false, "race_mode": false, "random_seed": null diff --git a/scripts/download_data.sh b/scripts/download_data.sh index 28b12c5a30..9636b16278 100644 --- a/scripts/download_data.sh +++ b/scripts/download_data.sh @@ -3,7 +3,6 @@ set -e mkdir -p tmp cd tmp - # Download the map pools mkdir -p ../maps for pool in "v119-small-avro" "v119-standard-avro" "v119-wild-avro"