macros: the move list deals BACK only where the moves can be read
The v0.4.3 residual: BACK was 263 of 797 macro starts and every one of them was over an open move list. A move list whose battler the seam cannot place binds no MOVE n at all -- move_slot_bound needs wBattleMon* -- so its pad was BACK alone, and the only thing that button does is close the list MOVE 1 on the menu underneath had just opened. That is section 12.10's pair with MOVE 1 standing where NEXT used to. So BACK is dealt on the move list only while battle.own reads, and MOVE 1 keeps the backstop it has over the top-level menu: with nothing readable the pad is MOVE 1 alone and its script confirms wherever the cursor stands, which is the press that ends a turn. With the moves readable the pad is unchanged.
This commit is contained in:
parent
3807fff422
commit
029a3446fb
2 changed files with 50 additions and 2 deletions
|
|
@ -526,7 +526,20 @@ pub fn scene_set(scene: Scene, state: &mut dyn MacroState) -> Vec<MacroKind> {
|
||||||
// between them. Two buttons that undo each other with nothing else changing are section
|
// between them. Two buttons that undo each other with nothing else changing are section
|
||||||
// 12.2's trap spread over two sub-states of one turn.
|
// 12.2's trap spread over two sub-states of one turn.
|
||||||
Scene::Battle { own_turn: true, .. } => match battle_menu(state) {
|
Scene::Battle { own_turn: true, .. } => match battle_menu(state) {
|
||||||
BattleMenu::Moves { .. } => vec![Move1, Move2, Move3, Move4, Back],
|
// The move list. `BACK` is a button here because there is a list to leave (12.9) --
|
||||||
|
// but only while the moves can be *read*: a battler the seam cannot place leaves all
|
||||||
|
// four `MOVE n` unbound, and a pad of `BACK` alone closes the list that `MOVE 1` on
|
||||||
|
// the menu underneath had just opened. That is 12.10's pair again, with `MOVE 1` in
|
||||||
|
// `NEXT`'s place. With nothing readable the pad is `MOVE 1` alone and its script
|
||||||
|
// confirms wherever the cursor stands, which is the press that ends the turn
|
||||||
|
// (section 12.11).
|
||||||
|
BattleMenu::Moves { .. } => {
|
||||||
|
if state.battle().and_then(|battle| battle.own).is_some() {
|
||||||
|
vec![Move1, Move2, Move3, Move4, Back]
|
||||||
|
} else {
|
||||||
|
vec![Move1]
|
||||||
|
}
|
||||||
|
}
|
||||||
BattleMenu::Party { .. } => vec![Switch, Back],
|
BattleMenu::Party { .. } => vec![Switch, Back],
|
||||||
// The bag, which is the fly's turn since 12.10. Its three answers: use the thing the
|
// The bag, which is the fly's turn since 12.10. Its three answers: use the thing the
|
||||||
// cursor is on (`ITEM`), throw the ball (`THROW BALL`), or leave the list (`BACK`).
|
// cursor is on (`ITEM`), throw the ball (`THROW BALL`), or leave the list (`BACK`).
|
||||||
|
|
@ -1643,7 +1656,14 @@ pub fn move_slot_bound(state: &mut dyn MacroState, kind: MacroKind) -> bool {
|
||||||
if index == 0 && matches!(battle.menu, BattleMenu::Main { .. }) {
|
if index == 0 && matches!(battle.menu, BattleMenu::Main { .. }) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let Some(own) = battle.own else { return false };
|
// And the same backstop over an **open move list** whose battler the seam cannot read
|
||||||
|
// (section 12.11). That frame used to deal `BACK` alone -- the only button on it closed the
|
||||||
|
// list `MOVE 1` on the menu underneath had just opened, which is 12.10's pair with `MOVE 1` in
|
||||||
|
// `NEXT`'s place. `MOVE 1`'s script over an open list confirms wherever the cursor stands, so
|
||||||
|
// it reads no move either, and confirming a move is what ends a turn.
|
||||||
|
let Some(own) = battle.own else {
|
||||||
|
return index == 0 && matches!(battle.menu, BattleMenu::Moves { cursor: Some(_), .. });
|
||||||
|
};
|
||||||
let holds = |slot: usize| -> Option<&Move> {
|
let holds = |slot: usize| -> Option<&Move> {
|
||||||
own.moves.get(slot).and_then(|entry| entry.as_ref()).filter(|entry| entry.id != 0)
|
own.moves.get(slot).and_then(|entry| entry.as_ref()).filter(|entry| entry.id != 0)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4318,6 +4318,34 @@ fn an_overworld_pad_is_never_one_button_that_undoes_itself() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Section 12.11: the move list deals `BACK` only where the moves can be read.
|
||||||
|
///
|
||||||
|
/// The v0.4.3 residual (`infra/docs/macros-traps.md`): `BACK` was 263 of 797 macro starts, every
|
||||||
|
/// one over an open move list, and 142 of the run's `NEXT` starts were on a move list whose cursor
|
||||||
|
/// the seam could not place. A move list the seam cannot read the battler for binds no `MOVE n` at
|
||||||
|
/// all, so its pad was `BACK` alone -- and the only thing that button does is close the list that
|
||||||
|
/// `MOVE 1` on the menu underneath had just opened. That is 12.10's pair with `MOVE 1` in `NEXT`'s
|
||||||
|
/// place. `MOVE 1` alone confirms wherever the cursor stands, which is the press that ends a turn.
|
||||||
|
#[test]
|
||||||
|
fn the_move_list_deals_back_only_where_the_moves_can_be_read() {
|
||||||
|
let mut world = World::battle();
|
||||||
|
world.list = List::Moves(3);
|
||||||
|
world.grid = false;
|
||||||
|
world.cursor_max = 2;
|
||||||
|
assert_eq!(pad_of(&mut world), ["BACK", "MOVE 1", "MOVE 2", "MOVE 3"]);
|
||||||
|
|
||||||
|
// The battler the seam cannot place: no active slot, so `battle.own` is `None`.
|
||||||
|
world.active = None;
|
||||||
|
let pad = pad_of(&mut world);
|
||||||
|
assert_eq!(pad, ["MOVE 1"], "one button, and it ends the turn: {pad:?}");
|
||||||
|
assert!(move_slot_bound(&mut world, MacroKind::Move1));
|
||||||
|
assert!(!move_slot_bound(&mut world, MacroKind::Move2));
|
||||||
|
// And it really presses: the cursor is confirmed where it stands, which is Struggle's own
|
||||||
|
// path (row 30a) and the only reading available here.
|
||||||
|
assert_eq!(run(&mut world, MacroKind::Move1).unwrap(), MacroAbort::Done);
|
||||||
|
assert_eq!(world.pulses.last(), Some(&buttons::A));
|
||||||
|
}
|
||||||
|
|
||||||
/// Row 37 of `infra/docs/macros-traps.md`: a tile the cartridge pushes the fly off is not a tile
|
/// Row 37 of `infra/docs/macros-traps.md`: a tile the cartridge pushes the fly off is not a tile
|
||||||
/// to stand on, and the ground beside a villager is not the villager's fault.
|
/// to stand on, and the ground beside a villager is not the villager's fault.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue