1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2025-11-29 07:47:40 +00:00

Challenge fixes: saves, nikumaru timer, menu

This commit is contained in:
dawnDus 2022-02-25 17:00:14 -05:00
parent 49d14b58a3
commit befac5db85
No known key found for this signature in database
GPG key ID: 972AABDE81848F21
5 changed files with 105 additions and 64 deletions

View file

@ -1,7 +1,7 @@
use byteorder::{LE, ReadBytesExt, WriteBytesExt}; use byteorder::{ReadBytesExt, WriteBytesExt, LE};
use crate::common::Rect; use crate::common::Rect;
use crate::components::draw_common::{Alignment, draw_number, draw_number_zeros}; use crate::components::draw_common::{draw_number, draw_number_zeros, Alignment};
use crate::entity::GameEntity; use crate::entity::GameEntity;
use crate::frame::Frame; use crate::frame::Frame;
use crate::framework::context::Context; use crate::framework::context::Context;
@ -24,8 +24,8 @@ impl NikumaruCounter {
NikumaruCounter { tick: 0, shown: false } NikumaruCounter { tick: 0, shown: false }
} }
fn load_time(&mut self, ctx: &mut Context) -> GameResult<u32> { fn load_time(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult<u32> {
if let Ok(mut data) = filesystem::user_open(ctx, "/290.rec") { if let Ok(mut data) = filesystem::user_open(ctx, state.get_290_filename()) {
let mut ticks: [u32; 4] = [0; 4]; let mut ticks: [u32; 4] = [0; 4];
for iter in 0..=3 { for iter in 0..=3 {
@ -54,7 +54,9 @@ impl NikumaruCounter {
} }
fn save_time(&mut self, new_time: u32, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { fn save_time(&mut self, new_time: u32, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
if let Ok(mut data) = filesystem::open_options(ctx, "/290.rec", OpenOptions::new().write(true).create(true)) { if let Ok(mut data) =
filesystem::open_options(ctx, state.get_290_filename(), OpenOptions::new().write(true).create(true))
{
let mut ticks: [u32; 4] = [new_time; 4]; let mut ticks: [u32; 4] = [new_time; 4];
let mut random_list: [u8; 4] = [0; 4]; let mut random_list: [u8; 4] = [0; 4];
@ -78,16 +80,18 @@ impl NikumaruCounter {
Ok(()) Ok(())
} }
pub fn load_counter(&mut self, ctx: &mut Context) -> GameResult { pub fn load_counter(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
self.tick = self.load_time(ctx)? as usize; self.tick = self.load_time(state, ctx)? as usize;
if self.tick > 0 { if self.tick > 0 {
self.shown = true; self.shown = true;
} else {
self.shown = false;
} }
Ok(()) Ok(())
} }
pub fn save_counter(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { pub fn save_counter(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
let old_record = self.load_time(ctx)? as usize; let old_record = self.load_time(state, ctx)? as usize;
if self.tick < old_record || old_record == 0 { if self.tick < old_record || old_record == 0 {
self.save_time(self.tick as u32, state, ctx)?; self.save_time(self.tick as u32, state, ctx)?;
} }

View file

@ -47,7 +47,7 @@ impl SaveSelectMenu {
self.delete_confirm = Menu::new(0, 0, 75, 0); self.delete_confirm = Menu::new(0, 0, 75, 0);
for (iter, save) in self.saves.iter_mut().enumerate() { for (iter, save) in self.saves.iter_mut().enumerate() {
if let Ok(data) = filesystem::user_open(ctx, state.get_save_filename(iter + 1)) { if let Ok(data) = filesystem::user_open(ctx, state.get_save_filename(iter + 1).unwrap_or("".to_string())) {
let loaded_save = GameProfile::load_from_save(data)?; let loaded_save = GameProfile::load_from_save(data)?;
save.current_map = loaded_save.current_map; save.current_map = loaded_save.current_map;
@ -122,7 +122,10 @@ impl SaveSelectMenu {
CurrentMenu::DeleteConfirm => match self.delete_confirm.tick(controller, state) { CurrentMenu::DeleteConfirm => match self.delete_confirm.tick(controller, state) {
MenuSelectionResult::Selected(1, _) => { MenuSelectionResult::Selected(1, _) => {
state.sound_manager.play_sfx(17); // Player Death sfx state.sound_manager.play_sfx(17); // Player Death sfx
filesystem::user_delete(ctx, state.get_save_filename(self.save_menu.selected + 1))?; filesystem::user_delete(
ctx,
state.get_save_filename(self.save_menu.selected + 1).unwrap_or("".to_string()),
)?;
self.save_menu.entries[self.save_menu.selected] = MenuEntry::NewSave; self.save_menu.entries[self.save_menu.selected] = MenuEntry::NewSave;
self.current_menu = CurrentMenu::SaveMenu; self.current_menu = CurrentMenu::SaveMenu;
} }

View file

@ -171,4 +171,12 @@ impl ModList {
-1 -1
} }
} }
pub fn get_name_from_path(&self, mod_path: String) -> &str {
if let Some(mod_sel) = self.mods.iter().find(|x| x.path == mod_path) {
&mod_sel.name
} else {
"NoName"
}
}
} }

View file

@ -5,7 +5,6 @@ use crate::entity::GameEntity;
use crate::frame::Frame; use crate::frame::Frame;
use crate::framework::context::Context; use crate::framework::context::Context;
use crate::framework::error::GameResult; use crate::framework::error::GameResult;
use crate::framework::graphics;
use crate::input::combined_menu_controller::CombinedMenuController; use crate::input::combined_menu_controller::CombinedMenuController;
use crate::input::touch_controls::TouchControlType; use crate::input::touch_controls::TouchControlType;
use crate::map::Map; use crate::map::Map;
@ -25,8 +24,7 @@ enum CurrentMenu {
OptionMenu, OptionMenu,
SaveSelectMenu, SaveSelectMenu,
ChallengesMenu, ChallengesMenu,
StartGame, ChallengeConfirmMenu,
LoadGame,
} }
pub struct TitleScene { pub struct TitleScene {
@ -36,6 +34,7 @@ pub struct TitleScene {
main_menu: Menu, main_menu: Menu,
save_select_menu: SaveSelectMenu, save_select_menu: SaveSelectMenu,
challenges_menu: Menu, challenges_menu: Menu,
confirm_menu: Menu,
settings_menu: SettingsMenu, settings_menu: SettingsMenu,
background: Background, background: Background,
frame: Frame, frame: Frame,
@ -74,6 +73,7 @@ impl TitleScene {
main_menu: Menu::new(0, 0, 100, 0), main_menu: Menu::new(0, 0, 100, 0),
save_select_menu: SaveSelectMenu::new(), save_select_menu: SaveSelectMenu::new(),
challenges_menu: Menu::new(0, 0, 150, 0), challenges_menu: Menu::new(0, 0, 150, 0),
confirm_menu: Menu::new(0, 0, 150, 0),
settings_menu, settings_menu,
background: Background::new(), background: Background::new(),
frame: Frame::new(), frame: Frame::new(),
@ -166,10 +166,15 @@ impl Scene for TitleScene {
} }
self.challenges_menu.push_entry(MenuEntry::Active("< Back".to_string())); self.challenges_menu.push_entry(MenuEntry::Active("< Back".to_string()));
self.confirm_menu.push_entry(MenuEntry::Disabled("".to_owned()));
self.confirm_menu.push_entry(MenuEntry::Active("Start".to_owned()));
self.confirm_menu.push_entry(MenuEntry::Active("< Back".to_owned()));
self.confirm_menu.selected = 1;
self.controller.update(state, ctx)?; self.controller.update(state, ctx)?;
self.controller.update_trigger(); self.controller.update_trigger();
self.nikumaru_rec.load_counter(ctx)?; self.nikumaru_rec.load_counter(state, ctx)?;
self.update_menu_cursor(state, ctx)?; self.update_menu_cursor(state, ctx)?;
Ok(()) Ok(())
@ -236,50 +241,63 @@ impl Scene for TitleScene {
} }
CurrentMenu::SaveSelectMenu => { CurrentMenu::SaveSelectMenu => {
let cm = &mut self.current_menu; let cm = &mut self.current_menu;
let rm = if state.mod_path.is_none() { CurrentMenu::MainMenu } else { CurrentMenu::ChallengesMenu };
self.save_select_menu.tick( self.save_select_menu.tick(
&mut || { &mut || {
*cm = CurrentMenu::MainMenu; *cm = rm;
}, },
&mut self.controller, &mut self.controller,
state, state,
ctx, ctx,
)?; )?;
} }
CurrentMenu::StartGame => {
if self.tick == 10 {
state.reset_skip_flags();
state.start_new_game(ctx)?;
}
}
CurrentMenu::LoadGame => {
if self.tick == 10 {
state.load_or_start_game(ctx)?;
}
}
CurrentMenu::ChallengesMenu => { CurrentMenu::ChallengesMenu => {
let last_idx = self.challenges_menu.entries.len() - 1; let last_idx = self.challenges_menu.entries.len() - 1;
match self.challenges_menu.tick(&mut self.controller, state) { match self.challenges_menu.tick(&mut self.controller, state) {
MenuSelectionResult::Selected(idx, _) => { MenuSelectionResult::Selected(idx, _) => {
if last_idx == idx { if last_idx == idx {
state.mod_path = None;
self.nikumaru_rec.load_counter(state, ctx)?;
self.current_menu = CurrentMenu::MainMenu; self.current_menu = CurrentMenu::MainMenu;
} else if let Some(mod_info) = state.mod_list.mods.get(idx) { } else if let Some(mod_info) = state.mod_list.mods.get(idx) {
state.mod_path = Some(mod_info.path.clone()); state.mod_path = Some(mod_info.path.clone());
if mod_info.save_slot >= 0 { if mod_info.save_slot >= 0 {
self.save_select_menu.init(state, ctx)?; self.save_select_menu.init(state, ctx)?;
self.nikumaru_rec.load_counter(state, ctx)?;
self.current_menu = CurrentMenu::SaveSelectMenu; self.current_menu = CurrentMenu::SaveSelectMenu;
} else { } else {
state.reload_resources(ctx)?; let mod_name = mod_info.name.clone();
state.start_new_game(ctx)?; self.confirm_menu.width =
(state.font.text_width(mod_name.chars(), &state.constants).max(50.0) + 32.0) as u16;
self.confirm_menu.entries[0] = MenuEntry::Disabled(mod_name);
self.nikumaru_rec.load_counter(state, ctx)?;
self.current_menu = CurrentMenu::ChallengeConfirmMenu;
} }
} }
} }
MenuSelectionResult::Canceled => { MenuSelectionResult::Canceled => {
state.mod_path = None;
self.nikumaru_rec.load_counter(state, ctx)?;
self.current_menu = CurrentMenu::MainMenu; self.current_menu = CurrentMenu::MainMenu;
} }
_ => (), _ => (),
} }
} }
CurrentMenu::ChallengeConfirmMenu => match self.confirm_menu.tick(&mut self.controller, state) {
MenuSelectionResult::Selected(1, _) => {
state.reload_resources(ctx)?;
state.start_new_game(ctx)?;
} }
MenuSelectionResult::Selected(2, _) | MenuSelectionResult::Canceled => {
self.current_menu = CurrentMenu::ChallengesMenu;
}
_ => (),
},
}
self.confirm_menu.update_height();
self.confirm_menu.x = ((state.canvas_size.0 - self.confirm_menu.width as f32) / 2.0).floor() as isize;
self.confirm_menu.y = ((state.canvas_size.1 + 30.0 - self.confirm_menu.height as f32) / 2.0).floor() as isize;
self.tick += 1; self.tick += 1;
@ -287,11 +305,6 @@ impl Scene for TitleScene {
} }
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
if self.current_menu == CurrentMenu::StartGame || self.current_menu == CurrentMenu::LoadGame {
graphics::clear(ctx, Color::from_rgb(0, 0, 0));
return Ok(());
}
self.background.draw(state, ctx, &self.frame, &self.textures, &self.stage)?; self.background.draw(state, ctx, &self.frame, &self.textures, &self.stage)?;
{ {
@ -313,9 +326,9 @@ impl Scene for TitleScene {
match self.current_menu { match self.current_menu {
CurrentMenu::MainMenu => self.main_menu.draw(state, ctx)?, CurrentMenu::MainMenu => self.main_menu.draw(state, ctx)?,
CurrentMenu::ChallengesMenu => self.challenges_menu.draw(state, ctx)?, CurrentMenu::ChallengesMenu => self.challenges_menu.draw(state, ctx)?,
CurrentMenu::ChallengeConfirmMenu => self.confirm_menu.draw(state, ctx)?,
CurrentMenu::OptionMenu => self.settings_menu.draw(state, ctx)?, CurrentMenu::OptionMenu => self.settings_menu.draw(state, ctx)?,
CurrentMenu::SaveSelectMenu => self.save_select_menu.draw(state, ctx)?, CurrentMenu::SaveSelectMenu => self.save_select_menu.draw(state, ctx)?,
_ => {}
} }
Ok(()) Ok(())

View file

@ -6,15 +6,15 @@ use chrono::{Datelike, Local};
use crate::bmfont_renderer::BMFontRenderer; use crate::bmfont_renderer::BMFontRenderer;
use crate::caret::{Caret, CaretType}; use crate::caret::{Caret, CaretType};
use crate::common::{ControlFlags, Direction, FadeState}; use crate::common::{ControlFlags, Direction, FadeState};
use crate::components::draw_common::{Alignment, draw_number}; use crate::components::draw_common::{draw_number, Alignment};
use crate::engine_constants::EngineConstants; use crate::engine_constants::EngineConstants;
use crate::framework::{filesystem, graphics};
use crate::framework::backend::BackendTexture; use crate::framework::backend::BackendTexture;
use crate::framework::context::Context; use crate::framework::context::Context;
use crate::framework::error::GameResult; use crate::framework::error::GameResult;
use crate::framework::graphics::{create_texture_mutable, set_render_target}; use crate::framework::graphics::{create_texture_mutable, set_render_target};
use crate::framework::keyboard::ScanCode; use crate::framework::keyboard::ScanCode;
use crate::framework::vfs::OpenOptions; use crate::framework::vfs::OpenOptions;
use crate::framework::{filesystem, graphics};
#[cfg(feature = "hooks")] #[cfg(feature = "hooks")]
use crate::hooks::init_hooks; use crate::hooks::init_hooks;
use crate::input::touch_controls::TouchControls; use crate::input::touch_controls::TouchControls;
@ -23,8 +23,8 @@ use crate::npc::NPCTable;
use crate::profile::GameProfile; use crate::profile::GameProfile;
use crate::rng::XorShift; use crate::rng::XorShift;
use crate::scene::game_scene::GameScene; use crate::scene::game_scene::GameScene;
use crate::scene::Scene;
use crate::scene::title_scene::TitleScene; use crate::scene::title_scene::TitleScene;
use crate::scene::Scene;
#[cfg(feature = "scripting-lua")] #[cfg(feature = "scripting-lua")]
use crate::scripting::lua::LuaScriptingState; use crate::scripting::lua::LuaScriptingState;
use crate::scripting::tsc::credit_script::{CreditScript, CreditScriptVM}; use crate::scripting::tsc::credit_script::{CreditScript, CreditScriptVM};
@ -404,22 +404,23 @@ impl SharedGameState {
} }
pub fn save_game(&mut self, game_scene: &mut GameScene, ctx: &mut Context) -> GameResult { pub fn save_game(&mut self, game_scene: &mut GameScene, ctx: &mut Context) -> GameResult {
if let Ok(data) = filesystem::open_options( if let Some(save_path) = self.get_save_filename(self.save_slot) {
ctx, if let Ok(data) = filesystem::open_options(ctx, save_path, OpenOptions::new().write(true).create(true)) {
self.get_save_filename(self.save_slot),
OpenOptions::new().write(true).create(true),
) {
let profile = GameProfile::dump(self, game_scene); let profile = GameProfile::dump(self, game_scene);
profile.write_save(data)?; profile.write_save(data)?;
} else { } else {
log::warn!("Cannot open save file."); log::warn!("Cannot open save file.");
} }
} else {
log::info!("Mod has saves disabled.");
}
Ok(()) Ok(())
} }
pub fn load_or_start_game(&mut self, ctx: &mut Context) -> GameResult { pub fn load_or_start_game(&mut self, ctx: &mut Context) -> GameResult {
if let Ok(data) = filesystem::user_open(ctx, self.get_save_filename(self.save_slot)) { if let Some(save_path) = self.get_save_filename(self.save_slot) {
if let Ok(data) = filesystem::user_open(ctx, save_path) {
match GameProfile::load_from_save(data) { match GameProfile::load_from_save(data) {
Ok(profile) => { Ok(profile) => {
self.reset(); self.reset();
@ -440,6 +441,9 @@ impl SharedGameState {
} else { } else {
log::warn!("No save game found, starting new one..."); log::warn!("No save game found, starting new one...");
} }
} else {
log::info!("Mod has saves disabled.");
}
self.start_new_game(ctx) self.start_new_game(ctx)
} }
@ -554,20 +558,29 @@ impl SharedGameState {
} }
} }
pub fn get_save_filename(&mut self, slot: usize) -> String { pub fn get_save_filename(&mut self, slot: usize) -> Option<String> {
if let Some(mod_path) = &self.mod_path { if let Some(mod_path) = &self.mod_path {
let save_slot = self.mod_list.get_save_from_path(mod_path.to_string()); let save_slot = self.mod_list.get_save_from_path(mod_path.to_string());
if save_slot < 0 { if save_slot < 0 {
return "/ModSaveDump.dat".to_owned(); return None;
} else if save_slot > 0 { } else if save_slot > 0 {
return format!("/Mod{}_Profile{}.dat", save_slot, slot); return Some(format!("/Mod{}_Profile{}.dat", save_slot, slot));
} }
} }
if slot == 1 { if slot == 1 {
return "/Profile.dat".to_owned(); return Some("/Profile.dat".to_owned());
} else { } else {
return format!("/Profile{}.dat", slot); return Some(format!("/Profile{}.dat", slot));
}
}
pub fn get_290_filename(&self) -> String {
if let Some(mod_path) = &self.mod_path {
let name = self.mod_list.get_name_from_path(mod_path.to_string());
return format!("/{}.rec", name);
} else {
return "/290.rec".to_string();
} }
} }
} }