From 953210c5bfd436628a1136b420bd915ee211b7ae Mon Sep 17 00:00:00 2001 From: Alex Knauth Date: Wed, 20 Dec 2023 02:20:18 -0500 Subject: [PATCH] Colo splits (#11) * Start on Colo splits * Colo pointers and accessors * Colo split conditions --- src/hollow_knight_memory.rs | 48 +++++++++++++++++++++++++++ src/splits.rs | 65 +++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/src/hollow_knight_memory.rs b/src/hollow_knight_memory.rs index 21bc62c3..86f3b14e 100644 --- a/src/hollow_knight_memory.rs +++ b/src/hollow_knight_memory.rs @@ -364,9 +364,15 @@ struct PlayerDataPointers { hornet_outskirts_defeated: UnityPointer<3>, killed_ghost_markoth: UnityPointer<3>, markoth_defeated: UnityPointer<3>, + colosseum_bronze_opened: UnityPointer<3>, killed_zote: UnityPointer<3>, + colosseum_bronze_completed: UnityPointer<3>, + colosseum_silver_opened: UnityPointer<3>, + colosseum_silver_completed: UnityPointer<3>, + colosseum_gold_opened: UnityPointer<3>, // God Tamer killed_lobster_lancer: UnityPointer<3>, + colosseum_gold_completed: UnityPointer<3>, // Uumuu encountered_mega_jelly: UnityPointer<3>, killed_mega_jellyfish: UnityPointer<3>, @@ -577,8 +583,14 @@ impl PlayerDataPointers { hornet_outskirts_defeated: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "hornetOutskirtsDefeated"]), killed_ghost_markoth: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "killedGhostMarkoth"]), markoth_defeated: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "markothDefeated"]), + colosseum_bronze_opened: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "colosseumBronzeOpened"]), killed_zote: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "killedZote"]), + colosseum_bronze_completed: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "colosseumBronzeCompleted"]), + colosseum_silver_opened: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "colosseumSilverOpened"]), + colosseum_silver_completed: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "colosseumSilverCompleted"]), + colosseum_gold_opened: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "colosseumGoldOpened"]), killed_lobster_lancer: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "killedLobsterLancer"]), + colosseum_gold_completed: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "colosseumGoldCompleted"]), encountered_mega_jelly: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "encounteredMegaJelly"]), killed_mega_jellyfish: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "killedMegaJellyfish"]), killed_ghost_marmu: UnityPointer::new("GameManager", 0, &["_instance", "playerData", "killedGhostMarmu"]), @@ -1437,14 +1449,38 @@ impl GameManagerFinder { self.player_data_pointers.markoth_defeated.deref(process, &self.module, &self.image).ok() } + pub fn colosseum_bronze_opened(&self, process: &Process) -> Option { + self.player_data_pointers.colosseum_bronze_opened.deref(process, &self.module, &self.image).ok() + } + pub fn killed_zote(&self, process: &Process) -> Option { self.player_data_pointers.killed_zote.deref(process, &self.module, &self.image).ok() } + pub fn colosseum_bronze_completed(&self, process: &Process) -> Option { + self.player_data_pointers.colosseum_bronze_completed.deref(process, &self.module, &self.image).ok() + } + + pub fn colosseum_silver_opened(&self, process: &Process) -> Option { + self.player_data_pointers.colosseum_silver_opened.deref(process, &self.module, &self.image).ok() + } + + pub fn colosseum_silver_completed(&self, process: &Process) -> Option { + self.player_data_pointers.colosseum_silver_completed.deref(process, &self.module, &self.image).ok() + } + + pub fn colosseum_gold_opened(&self, process: &Process) -> Option { + self.player_data_pointers.colosseum_gold_opened.deref(process, &self.module, &self.image).ok() + } + pub fn killed_lobster_lancer(&self, process: &Process) -> Option { self.player_data_pointers.killed_lobster_lancer.deref(process, &self.module, &self.image).ok() } + pub fn colosseum_gold_completed(&self, process: &Process) -> Option { + self.player_data_pointers.colosseum_gold_completed.deref(process, &self.module, &self.image).ok() + } + // Uumuu pub fn encountered_mega_jelly(&self, process: &Process) -> Option { self.player_data_pointers.encountered_mega_jelly.deref(process, &self.module, &self.image).ok() @@ -1825,6 +1861,18 @@ impl PlayerDataStore { self.decremented_i32(process, game_manager_finder, "kills_zombie_miner", &game_manager_finder.player_data_pointers.kills_zombie_miner) } + pub fn colosseum_bronze_completed(&mut self, p: &Process, g: &GameManagerFinder) -> bool { + self.get_bool(p, g, "colosseum_bronze_completed", &g.player_data_pointers.colosseum_bronze_completed).unwrap_or(false) + } + + pub fn colosseum_silver_completed(&mut self, p: &Process, g: &GameManagerFinder) -> bool { + self.get_bool(p, g, "colosseum_silver_completed", &g.player_data_pointers.colosseum_silver_completed).unwrap_or(false) + } + + pub fn colosseum_gold_completed(&mut self, p: &Process, g: &GameManagerFinder) -> bool { + self.get_bool(p, g, "colosseum_gold_completed", &g.player_data_pointers.colosseum_gold_completed).unwrap_or(false) + } + pub fn increased_royal_charm_state(&mut self, process: &Process, game_manager_finder: &GameManagerFinder) -> bool { self.increased_i32(process, game_manager_finder, "royal_charm_state", &game_manager_finder.player_data_pointers.royal_charm_state) } diff --git a/src/splits.rs b/src/splits.rs index 955481a7..42c32bb7 100644 --- a/src/splits.rs +++ b/src/splits.rs @@ -1206,14 +1206,62 @@ pub enum Split { MarkothEssence, // endregion: Kingdom's Edge // region: Colosseum + /// Colosseum Unlocked 1 (Trial) + /// + /// Splits when the knight unlocks the Trial of the Warrior at Little Fool + ColosseumBronzeUnlocked, + /// Colosseum Entrance 1 (Transition) + /// + /// Splits on the transition into the Trial of the Warrior + ColosseumBronzeEntry, /// Zote Defeated - Colosseum (Mini Boss) /// /// Splits when defeating Zote in the Colosseum ZoteKilled, + /// Colosseum Fight 1 (Trial) + /// + /// Splits when beating the Trial of the Warrior + ColosseumBronze, + /// Colosseum Exit 1 (Transition) + /// + /// Splits on the transition out of the trial, or in the load-in after quitout + ColosseumBronzeExit, + /// Colosseum Unlocked 2 (Trial) + /// + /// Splits when the knight unlocks the Trial of the Conqueror at Little Fool + ColosseumSilverUnlocked, + /// Colosseum Entrance 2 (Transition) + /// + /// Splits on the transition into the Trial of the Conqueror + ColosseumSilverEntry, + /// Colosseum Fight 2 (Trial) + /// + /// Splits when beating the Trial of the Conqueror + ColosseumSilver, + /// Colosseum Exit 2 (Transition) + /// + /// Splits on the transition out of the trial, or in the load-in after quitout + ColosseumSilverExit, + /// Colosseum Unlocked 3 (Trial) + /// + /// Splits when the knight unlocks the Trial of the Fool at Little Fool + ColosseumGoldUnlocked, + /// Colosseum Entrance 3 (Transition) + /// + /// Splits on the transition into the Trial of the Warrior + ColosseumGoldEntry, /// God Tamer (Boss) /// /// Splits when killing the God Tamer GodTamer, + /// Colosseum Fight 3 (Trial) + /// + /// Splits when beating the Trial of the Warrior + ColosseumGold, + /// Colosseum Exit 3 (Transition) + /// + /// Splits on the transition out of the trial, or in the load-in after quitout + ColosseumGoldExit, // endregion: Colosseum // region: Fog Canyon /// Teachers Archive (Area) @@ -1436,6 +1484,14 @@ pub fn transition_splits(s: &Split, p: &Pair<&str>, prc: &Process, g: &GameManag Split::EnterHiveKnight => p.current.starts_with("Hive_05") && p.current != p.old, Split::EnterHornet2 => p.current.starts_with("Deepnest_East_Hornet") && p.current != p.old, // endregion: Kingdom's Edge + // region: Colosseum + Split::ColosseumBronzeEntry => p.old == "Room_Colosseum_01" && p.current == "Room_Colosseum_Bronze", + Split::ColosseumBronzeExit => pds.colosseum_bronze_completed(prc, g) && !p.current.starts_with("Room_Colosseum_Bronze"), + Split::ColosseumSilverEntry => p.old == "Room_Colosseum_01" && p.current == "Room_Colosseum_Silver", + Split::ColosseumSilverExit => pds.colosseum_bronze_completed(prc, g) && !p.current.starts_with("Room_Colosseum_Silver"), + Split::ColosseumGoldEntry => p.old == "Room_Colosseum_01" && p.current == "Room_Colosseum_Gold", + Split::ColosseumGoldExit => pds.colosseum_bronze_completed(prc, g) && !p.current.starts_with("Room_Colosseum_Gold"), + // endregion: Colosseum // region: Fog Canyon Split::TeachersArchive => p.current.starts_with("Fungus3_archive") && !p.old.starts_with("Fungus3_archive"), // endregion: Fog Canyon @@ -1774,8 +1830,17 @@ pub fn continuous_splits(s: &Split, p: &Process, g: &GameManagerFinder, pds: &mu Split::MarkothEssence => g.markoth_defeated(p).is_some_and(|d| d == 2), // endregion: Kingdom's Edge // region: Colosseum + Split::ColosseumBronzeUnlocked => g.colosseum_bronze_opened(p).is_some_and(|o| o), Split::ZoteKilled => g.killed_zote(p).is_some_and(|k| k), + Split::ColosseumBronze => g.colosseum_bronze_completed(p).is_some_and(|c| c), + Split::ColosseumBronzeExit => { pds.colosseum_bronze_completed(p, g); false }, + Split::ColosseumSilverUnlocked => g.colosseum_silver_opened(p).is_some_and(|o| o), + Split::ColosseumSilver => g.colosseum_silver_completed(p).is_some_and(|c| c), + Split::ColosseumSilverExit => { pds.colosseum_silver_completed(p, g); false }, + Split::ColosseumGoldUnlocked => g.colosseum_gold_opened(p).is_some_and(|o| o), Split::GodTamer => g.killed_lobster_lancer(p).is_some_and(|k| k), + Split::ColosseumGold => g.colosseum_gold_completed(p).is_some_and(|c| c), + Split::ColosseumGoldExit => { pds.colosseum_gold_completed(p, g); false }, // endregion: Colosseum // region: Fog Canyon Split::UumuuEncountered => g.encountered_mega_jelly(p).is_some_and(|b| b),