1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2025-11-28 15:27:27 +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::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::frame::Frame;
use crate::framework::context::Context;
@ -24,8 +24,8 @@ impl NikumaruCounter {
NikumaruCounter { tick: 0, shown: false }
}
fn load_time(&mut self, ctx: &mut Context) -> GameResult<u32> {
if let Ok(mut data) = filesystem::user_open(ctx, "/290.rec") {
fn load_time(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult<u32> {
if let Ok(mut data) = filesystem::user_open(ctx, state.get_290_filename()) {
let mut ticks: [u32; 4] = [0; 4];
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 {
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 random_list: [u8; 4] = [0; 4];
@ -78,16 +80,18 @@ impl NikumaruCounter {
Ok(())
}
pub fn load_counter(&mut self, ctx: &mut Context) -> GameResult {
self.tick = self.load_time(ctx)? as usize;
pub fn load_counter(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
self.tick = self.load_time(state, ctx)? as usize;
if self.tick > 0 {
self.shown = true;
} else {
self.shown = false;
}
Ok(())
}
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 {
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);
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)?;
save.current_map = loaded_save.current_map;
@ -122,7 +122,10 @@ impl SaveSelectMenu {
CurrentMenu::DeleteConfirm => match self.delete_confirm.tick(controller, state) {
MenuSelectionResult::Selected(1, _) => {
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.current_menu = CurrentMenu::SaveMenu;
}

View file

@ -171,4 +171,12 @@ impl ModList {
-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::framework::context::Context;
use crate::framework::error::GameResult;
use crate::framework::graphics;
use crate::input::combined_menu_controller::CombinedMenuController;
use crate::input::touch_controls::TouchControlType;
use crate::map::Map;
@ -25,8 +24,7 @@ enum CurrentMenu {
OptionMenu,
SaveSelectMenu,
ChallengesMenu,
StartGame,
LoadGame,
ChallengeConfirmMenu,
}
pub struct TitleScene {
@ -36,6 +34,7 @@ pub struct TitleScene {
main_menu: Menu,
save_select_menu: SaveSelectMenu,
challenges_menu: Menu,
confirm_menu: Menu,
settings_menu: SettingsMenu,
background: Background,
frame: Frame,
@ -74,6 +73,7 @@ impl TitleScene {
main_menu: Menu::new(0, 0, 100, 0),
save_select_menu: SaveSelectMenu::new(),
challenges_menu: Menu::new(0, 0, 150, 0),
confirm_menu: Menu::new(0, 0, 150, 0),
settings_menu,
background: Background::new(),
frame: Frame::new(),
@ -166,10 +166,15 @@ impl Scene for TitleScene {
}
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_trigger();
self.nikumaru_rec.load_counter(ctx)?;
self.nikumaru_rec.load_counter(state, ctx)?;
self.update_menu_cursor(state, ctx)?;
Ok(())
@ -236,62 +241,70 @@ impl Scene for TitleScene {
}
CurrentMenu::SaveSelectMenu => {
let cm = &mut self.current_menu;
let rm = if state.mod_path.is_none() { CurrentMenu::MainMenu } else { CurrentMenu::ChallengesMenu };
self.save_select_menu.tick(
&mut || {
*cm = CurrentMenu::MainMenu;
*cm = rm;
},
&mut self.controller,
state,
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 => {
let last_idx = self.challenges_menu.entries.len() - 1;
match self.challenges_menu.tick(&mut self.controller, state) {
MenuSelectionResult::Selected(idx, _) => {
if last_idx == idx {
state.mod_path = None;
self.nikumaru_rec.load_counter(state, ctx)?;
self.current_menu = CurrentMenu::MainMenu;
} else if let Some(mod_info) = state.mod_list.mods.get(idx) {
state.mod_path = Some(mod_info.path.clone());
if mod_info.save_slot >= 0 {
self.save_select_menu.init(state, ctx)?;
self.nikumaru_rec.load_counter(state, ctx)?;
self.current_menu = CurrentMenu::SaveSelectMenu;
} else {
state.reload_resources(ctx)?;
state.start_new_game(ctx)?;
let mod_name = mod_info.name.clone();
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 => {
state.mod_path = None;
self.nikumaru_rec.load_counter(state, ctx)?;
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;
Ok(())
}
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)?;
{
@ -313,9 +326,9 @@ impl Scene for TitleScene {
match self.current_menu {
CurrentMenu::MainMenu => self.main_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::SaveSelectMenu => self.save_select_menu.draw(state, ctx)?,
_ => {}
}
Ok(())

View file

@ -6,15 +6,15 @@ use chrono::{Datelike, Local};
use crate::bmfont_renderer::BMFontRenderer;
use crate::caret::{Caret, CaretType};
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::framework::{filesystem, graphics};
use crate::framework::backend::BackendTexture;
use crate::framework::context::Context;
use crate::framework::error::GameResult;
use crate::framework::graphics::{create_texture_mutable, set_render_target};
use crate::framework::keyboard::ScanCode;
use crate::framework::vfs::OpenOptions;
use crate::framework::{filesystem, graphics};
#[cfg(feature = "hooks")]
use crate::hooks::init_hooks;
use crate::input::touch_controls::TouchControls;
@ -23,8 +23,8 @@ use crate::npc::NPCTable;
use crate::profile::GameProfile;
use crate::rng::XorShift;
use crate::scene::game_scene::GameScene;
use crate::scene::Scene;
use crate::scene::title_scene::TitleScene;
use crate::scene::Scene;
#[cfg(feature = "scripting-lua")]
use crate::scripting::lua::LuaScriptingState;
use crate::scripting::tsc::credit_script::{CreditScript, CreditScriptVM};
@ -404,41 +404,45 @@ impl SharedGameState {
}
pub fn save_game(&mut self, game_scene: &mut GameScene, ctx: &mut Context) -> GameResult {
if let Ok(data) = filesystem::open_options(
ctx,
self.get_save_filename(self.save_slot),
OpenOptions::new().write(true).create(true),
) {
let profile = GameProfile::dump(self, game_scene);
profile.write_save(data)?;
if let Some(save_path) = self.get_save_filename(self.save_slot) {
if let Ok(data) = filesystem::open_options(ctx, save_path, OpenOptions::new().write(true).create(true)) {
let profile = GameProfile::dump(self, game_scene);
profile.write_save(data)?;
} else {
log::warn!("Cannot open save file.");
}
} else {
log::warn!("Cannot open save file.");
log::info!("Mod has saves disabled.");
}
Ok(())
}
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)) {
match GameProfile::load_from_save(data) {
Ok(profile) => {
self.reset();
let mut next_scene = GameScene::new(self, ctx, profile.current_map as usize)?;
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) {
Ok(profile) => {
self.reset();
let mut next_scene = GameScene::new(self, ctx, profile.current_map as usize)?;
profile.apply(self, &mut next_scene, ctx);
profile.apply(self, &mut next_scene, ctx);
#[cfg(feature = "scripting-lua")]
self.lua.reload_scripts(ctx)?;
#[cfg(feature = "scripting-lua")]
self.lua.reload_scripts(ctx)?;
self.next_scene = Some(Box::new(next_scene));
return Ok(());
}
Err(e) => {
log::warn!("Failed to load save game, starting new one: {}", e);
self.next_scene = Some(Box::new(next_scene));
return Ok(());
}
Err(e) => {
log::warn!("Failed to load save game, starting new one: {}", e);
}
}
} else {
log::warn!("No save game found, starting new one...");
}
} else {
log::warn!("No save game found, starting new one...");
log::info!("Mod has saves disabled.");
}
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 {
let save_slot = self.mod_list.get_save_from_path(mod_path.to_string());
if save_slot < 0 {
return "/ModSaveDump.dat".to_owned();
return None;
} 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 {
return "/Profile.dat".to_owned();
return Some("/Profile.dat".to_owned());
} 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();
}
}
}