171 lines
6.4 KiB
Rust
171 lines
6.4 KiB
Rust
use crate::common::Rect;
|
|
use crate::entity::GameEntity;
|
|
use crate::framework::context::Context;
|
|
use crate::framework::error::GameResult;
|
|
use crate::game::frame::Frame;
|
|
use crate::game::shared_game_state::SharedGameState;
|
|
use crate::input::touch_controls::TouchControlType;
|
|
use crate::game::player::Player;
|
|
use crate::game::scripting::tsc::text_script::ScriptMode;
|
|
|
|
pub struct StageSelect {
|
|
pub current_teleport_slot: u8,
|
|
prev_teleport_slot: u8,
|
|
stage_select_text_y_pos: usize,
|
|
tick: usize,
|
|
}
|
|
|
|
impl StageSelect {
|
|
pub fn new() -> StageSelect {
|
|
StageSelect {
|
|
current_teleport_slot: 0,
|
|
prev_teleport_slot: 0,
|
|
stage_select_text_y_pos: 54,
|
|
tick: 0,
|
|
}
|
|
}
|
|
|
|
pub fn reset(&mut self) {
|
|
self.stage_select_text_y_pos = 54;
|
|
self.tick = 0;
|
|
}
|
|
}
|
|
|
|
impl GameEntity<(&mut Context, &Player, &Player)> for StageSelect {
|
|
fn tick(&mut self, state: &mut SharedGameState, (ctx, player1, player2): (&mut Context, &Player, &Player)) -> GameResult {
|
|
state.touch_controls.control_type = TouchControlType::None;
|
|
|
|
let slot_count = state.teleporter_slots.iter()
|
|
.filter(|&&(index, _event_num)| index != 0)
|
|
.count();
|
|
|
|
if slot_count <= self.current_teleport_slot as usize {
|
|
self.current_teleport_slot = 0;
|
|
}
|
|
|
|
if self.stage_select_text_y_pos > 46 {
|
|
self.stage_select_text_y_pos -= 1;
|
|
}
|
|
|
|
let left_pressed = player1.controller.trigger_left() || player2.controller.trigger_left();
|
|
let right_pressed = player1.controller.trigger_right() || player2.controller.trigger_right();
|
|
let mut ok_pressed = player1.controller.trigger_jump() || player1.controller.trigger_menu_ok()
|
|
|| player2.controller.trigger_jump() || player2.controller.trigger_menu_ok();
|
|
let mut cancel_pressed = player1.controller.trigger_shoot() || player2.controller.trigger_shoot();
|
|
|
|
if left_pressed {
|
|
if self.current_teleport_slot == 0 {
|
|
self.current_teleport_slot = slot_count.saturating_sub(1) as u8;
|
|
} else {
|
|
self.current_teleport_slot -= 1;
|
|
}
|
|
} else if right_pressed {
|
|
if self.current_teleport_slot == slot_count.saturating_sub(1) as u8 {
|
|
self.current_teleport_slot = 0;
|
|
} else {
|
|
self.current_teleport_slot += 1;
|
|
}
|
|
}
|
|
|
|
if self.prev_teleport_slot != self.current_teleport_slot {
|
|
self.prev_teleport_slot = self.current_teleport_slot;
|
|
state.sound_manager.play_sfx(1);
|
|
if let Some(&(index, _event_num)) = state.teleporter_slots.get(self.current_teleport_slot as usize) {
|
|
state.textscript_vm.start_script(1000 + index);
|
|
} else {
|
|
state.textscript_vm.start_script(1000);
|
|
}
|
|
}
|
|
|
|
if state.settings.touch_controls {
|
|
let slot_offset = ((state.canvas_size.0 - 40.0 * slot_count as f32) / 2.0).floor();
|
|
let mut slot_rect;
|
|
|
|
for i in 0..slot_count {
|
|
slot_rect = Rect::new_size(slot_offset as isize + i as isize * 40 - 2, 64 - 8, 36, 32);
|
|
|
|
if state.touch_controls.consume_click_in(slot_rect) {
|
|
if self.current_teleport_slot as usize == i {
|
|
ok_pressed = true;
|
|
} else {
|
|
state.sound_manager.play_sfx(1);
|
|
self.current_teleport_slot = i as u8;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
let (_, off_top, off_right, _) = crate::framework::graphics::screen_insets_scaled(ctx, state.scale);
|
|
slot_rect = Rect::new_size(state.canvas_size.0 as isize - 34 - off_right as isize, 8 + off_top as isize, 26, 26);
|
|
|
|
if state.touch_controls.consume_click_in(slot_rect) {
|
|
state.sound_manager.play_sfx(5);
|
|
cancel_pressed = true;
|
|
}
|
|
}
|
|
|
|
if ok_pressed || cancel_pressed {
|
|
self.reset();
|
|
state.textscript_vm.set_mode(ScriptMode::Map);
|
|
state.control_flags.set_tick_world(true);
|
|
state.control_flags.set_control_enabled(true);
|
|
state.control_flags.set_interactions_disabled(false);
|
|
|
|
if ok_pressed {
|
|
if let Some(&(_index, event_num)) = state.teleporter_slots.get(self.current_teleport_slot as usize) {
|
|
state.textscript_vm.start_script(event_num);
|
|
}
|
|
}
|
|
}
|
|
|
|
self.tick += 1;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context, _frame: &Frame) -> GameResult {
|
|
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "StageImage")?;
|
|
|
|
let slot_count = state.teleporter_slots.iter()
|
|
.filter(|&&(index, _event_num)| index != 0)
|
|
.count();
|
|
let slot_offset = ((state.canvas_size.0 - 40.0 * slot_count as f32) / 2.0).floor();
|
|
let mut slot_rect = Rect::new(0, 0, 0, 0);
|
|
|
|
for i in 0..slot_count {
|
|
let index = state.teleporter_slots[i].0;
|
|
|
|
slot_rect.left = 32 * (index as u16 % 8);
|
|
slot_rect.top = 16 * (index as u16 / 8);
|
|
slot_rect.right = slot_rect.left + 32;
|
|
slot_rect.bottom = slot_rect.top + 16;
|
|
|
|
batch.add_rect(slot_offset + i as f32 * 40.0, 64.0, &slot_rect);
|
|
}
|
|
|
|
batch.draw(ctx)?;
|
|
|
|
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "TextBox")?;
|
|
|
|
batch.add_rect((state.canvas_size.0 / 2.0) - 32.0, self.stage_select_text_y_pos as f32, &state.constants.textscript.stage_select_text);
|
|
if slot_count > 0 {
|
|
batch.add_rect(slot_offset + self.current_teleport_slot as f32 * 40.0, 64.0, &state.constants.textscript.cursor[self.tick / 2 % 2]);
|
|
}
|
|
|
|
batch.draw(ctx)?;
|
|
|
|
if state.settings.touch_controls {
|
|
let (_, off_top, off_right, _) = crate::framework::graphics::screen_insets_scaled(ctx, state.scale);
|
|
|
|
let close_rect = Rect { left: 110, top: 110, right: 128, bottom: 128 };
|
|
let batch = state.texture_set.get_or_load_batch(ctx, &state.constants, "builtin/touch")?;
|
|
|
|
batch.add_rect(state.canvas_size.0 - off_right - 30.0, 12.0 + off_top, &close_rect);
|
|
batch.draw(ctx)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|