diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml
index 8240a56801..88c5cabd28 100644
--- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml
+++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml
@@ -23,20 +23,16 @@ body:
label: Version
description: What version of pokeemerald-expansion are you using as a base?
options:
- - 1.9.3 (Latest release)
+ - 1.10.1 (Latest release)
- master (default, unreleased bugfixes)
- upcoming (Edge)
+ - 1.10.0
+ - 1.9.4
+ - 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- - 1.8.6
- - 1.8.5
- - 1.8.4
- - 1.8.3
- - 1.8.2
- - 1.8.1
- - 1.8.0
- - pre-1.8.0
+ - pre-1.9.0
validations:
required: true
- type: input
diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml
index 5688f8a7fb..e49c54e756 100644
--- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml
+++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml
@@ -23,20 +23,16 @@ body:
label: Version
description: What version of pokeemerald-expansion are you using as a base?
options:
- - 1.9.3 (Latest release)
+ - 1.10.1 (Latest release)
- master (default, unreleased bugfixes)
- upcoming (Edge)
+ - 1.10.0
+ - 1.9.4
+ - 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- - 1.8.6
- - 1.8.5
- - 1.8.4
- - 1.8.3
- - 1.8.2
- - 1.8.1
- - 1.8.0
- - pre-1.8.0
+ - pre-1.9.0
validations:
required: true
- type: input
diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml
index add0633d95..02bc0399b1 100644
--- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml
+++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml
@@ -23,20 +23,16 @@ body:
label: Version
description: What version of pokeemerald-expansion are you using as a base?
options:
- - 1.9.3 (Latest release)
+ - 1.10.1 (Latest release)
- master (default, unreleased bugfixes)
- upcoming (Edge)
+ - 1.10.0
+ - 1.9.4
+ - 1.9.3
- 1.9.2
- 1.9.1
- 1.9.0
- - 1.8.6
- - 1.8.5
- - 1.8.4
- - 1.8.3
- - 1.8.2
- - 1.8.1
- - 1.8.0
- - pre-1.8.0
+ - pre-1.9.0
validations:
required: true
- type: input
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 2259d399c9..f083a2a23f 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,5 +1,9 @@
+
+
+
+
## Description
@@ -13,7 +17,8 @@
## **People who collaborated with me in this PR**
-
+
+
## Feature(s) this PR does NOT handle:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bb9fec3e7e..963e05d7bc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
# Pokeemerald-Expansion Changelogs
+## 1.10.x
+- **[Version 1.10.1](docs/changelogs/1.10.x/1.10.1.md) - 🧹 Bugfix Release**
+- **[Version 1.10.0](docs/changelogs/1.10.x/1.10.0.md) - ✨ Feature Release**
+
## 1.9.x
+- **[Version 1.9.4](docs/changelogs/1.9.x/1.9.4.md) - 🧹 Bugfix Release**
+- **[Version 1.9.3](docs/changelogs/1.9.x/1.9.3.md) - 🧹 Bugfix Release**
- **[Version 1.9.2](docs/changelogs/1.9.x/1.9.2.md) - 🧹 Bugfix Release**
- **[Version 1.9.1](docs/changelogs/1.9.x/1.9.1.md) - 🧹 Bugfix Release**
- **[Version 1.9.0](docs/changelogs/1.9.x/1.9.0.md) - ✨ Feature Release**
diff --git a/INSTALL.md b/INSTALL.md
index fc1aeb5ba8..6e52559f67 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -1,564 +1,82 @@
# Instructions
+Install instructions for each supported operating system can be found in their respective directories under `docs/install/`.
+Lines to those can be found under each heading.
+This file only contains a short introduction to each supported system.
+If you run into trouble, ask for help on Discord (see [README.md](README.md)).
-These instructions explain how to set up the tools required to build **pokeemerald Expansion**, which assembles the source files into a ROM (pokeemerald.gba).
-
-These instructions come with notes which can be expanded by clicking the "Note..." text.
-In general, you should not need to open these unless if you get an error or if you need additional clarification.
-
-If you run into trouble, ask for help on Discord or IRC (see [README.md](README.md)).
+After completing the install instructions for your OS, proceed to [Building pokeemerald-expansion](#building-pokeemerald-expansion).
## Windows
-Windows has instructions for building with three possible terminals, providing 3 different options in case the user stumbles upon unexpected errors.
-- [Windows 10/11 (WSL1)](#windows-1011-wsl1) (**Fastest, highly recommended**, Windows 10 and 11 only)
-- [Windows (msys2)](#windows-msys2) (Second fastest)
-- [Windows (Cygwin)](#windows-cygwin) (Slowest)
-
-Unscientific benchmarks suggest **msys2 is 2x slower** than WSL1, and **Cygwin is 5-6x slower** than WSL1.
-
- Note for advanced users: WSL2...
-
-> WSL2 is an option and is even faster than WSL1 if files are stored on the WSL2 file system, but some tools may have trouble interacting
-> with the WSL2 file system over the network drive. For example, tools which use Qt versions before 5.15.2 such as porymap
-> may have problems with parsing the \\wsl$ network drive path.
-
-
-All of the Windows instructions assume that the default drive is C:\\. If this differs to your actual drive letter, then replace C with the correct drive letter when reading the instructions.
+**Windows needs one of the systems to build the project**
**A note of caution**: As Windows 7 and Windows 8 are officially unsupported by Microsoft, some maintainers are unwilling to maintain the Windows 7/8 instructions. Thus, these instructions may break in the future with fixes taking longer than fixes to the Windows 10/11 instructions.
-## Windows 10/11 (WSL1)
-WSL1 is the preferred terminal to build **pokeemerald Expansion**. The following instructions will explain how to install WSL1 (referred to interchangeably as WSL).
-- If WSL (Debian or Ubuntu) is **not installed**, then go to [Installing WSL1](#Installing-WSL1).
-- Otherwise, if WSL is installed, but it **hasn't previously been set up for another decompilation project**, then go to [Setting up WSL1](#Setting-up-WSL1).
-- Otherwise, **open WSL** and go to [Choosing where to store pokeemerald Expansion (WSL1)](#Choosing-where-to-store-pokeemerald-expansion-WSL1).
+On Windows, the project can be built using the following systems:
+- WSL2, fastest
+- WSL1, 7 times slower than WSL2
+- Msys2, 20 times slower than WSL2 (**NOTE**: Currently broken on pret upstream)
+- Cygwin, 30 timer slower than WSL2 (**NOTE**: Currently broken on pret upstream)
-### Installing WSL1
-1. Open [Windows Powershell **as Administrator**](https://i.imgur.com/QKmVbP9.png), and run the following commands (Right Click or Shift+Insert is paste in the Powershell).
+**NOTE**: Only WSL systems are recommended.
- ```powershell
- wsl --install -d Ubuntu --enable-wsl1
- ```
+[WSL Install instructions](docs/install/windows/WSL.md)
-2. Once the process finishes, restart your machine.
+[Msys2 Install instructions](docs/install/windows/MSYS2.md)
-3. Open Windows Powershell **as Administrator** again (after restarting), and run the following command to configure Ubuntu to use WSL1.
-
- ```powershell
- wsl --set-version Ubuntu 1
- ```
-
- Note...
-
- > WSL may open automatically after restarting, but you can ignore it for now.
-
-
-### Setting up WSL1
-Some tips before proceeding:
-- In WSL, Copy and Paste is either done via
- - **right-click** (selection + right click to Copy, right click with no selection to Paste)
- - **Ctrl+Shift+C/Ctrl+Shift+V** (enabled by right-clicking the title bar, going to Properties, then checking the checkbox next to "Use Ctrl+Shift+C/V as Copy/Paste").
-- Some of the commands that you'll run will ask for your WSL password and/or confirmation to perform the stated action. This is to be expected, just enter your WSL password and/or the yes action when necessary.
-
-1. Open **Ubuntu** (e.g. using Search).
-2. WSL/Ubuntu will set up its own installation when it runs for the first time. Once WSL/Ubuntu finishes installing, it will ask for a username and password (to be input in).
-
- Note...
-
- > When typing in the password, there will be no visible response, but the terminal will still read in input.
-
-
-3. Update WSL/Ubuntu before continuing. Do this by running the following command. These commands will likely take a long time to finish:
-
- ```bash
- sudo apt update && sudo apt upgrade
- ```
-
-> Note: If the repository you plan to build has an **[older revision of the INSTALL.md](https://github.com/pret/pokeemerald/blob/571c598/INSTALL.md)**, then follow the [legacy WSL1 instructions](docs/legacy_WSL1_INSTALL.md) from here.
-
-4. Certain packages are required to build pokeemerald Expansion. Install these packages by running the following command:
-
- ```bash
- sudo apt install build-essential binutils-arm-none-eabi gcc-arm-none-eabi libnewlib-arm-none-eabi git libpng-dev
- ```
-
- Note...
-
- > If the above command does not work, try the above command but replacing `apt` with `apt-get`.
-
- This will install GCC v10 on Ubuntu 22.04. pokeemerald Expansion works with GCC v10, but remote repositories and the RHH Team use GCC v13 for stricter error-checking. If you want to upgrade from v10 to v13, also follow the devkitpro install instructions.
-
-### Installing devkitARM on WSL1
-
-1. Change directory to somewhere you can download a package, such as **C:\Users\\_\_\Downloads** (the Downloads location for most users). To do so, enter this command, where *\ is your **Windows** username:
-
- ```bash
- cd /mnt/c/Users//Downloads
- ```
-
-2. Once the directory has been changed, run the following commands to install devkitARM.
-
- ```bash
- sudo apt install wget
- wget https://apt.devkitpro.org/install-devkitpro-pacman
- chmod +x ./install-devkitpro-pacman
- sudo ./install-devkitpro-pacman
- sudo dkp-pacman -S gba-dev
- ```
- The last command will ask for the selection of packages to install. Just press Enter to install all of them, followed by entering Y to proceed with the installation.
-
-3. Run the following command to set devkitPro related environment variables (alternatively, close and re-open WSL):
-
- ```bash
- source /etc/profile.d/devkit-env.sh
- ```
-
-devkitARM is now installed.
-
-### Installing Python on WSL1
-
-To install Python on WSL1, simply run the following commands:
-
-```bash
-sudo apt update && sudo apt upgrade
-sudo apt install python3
-```
-
-Python is now installed.
-
-### Choosing where to store pokeemerald Expansion (WSL1)
-WSL has its own file system that's not natively accessible from Windows, but Windows files *are* accessible from WSL. So you're going to want to store pokeemerald Expansion within Windows.
-
-For example, say you want to store pokeemerald Expansion in **C:\Users\\_\_\Desktop\decomps**. First, ensure that the folder already exists. Then, enter this command to **change directory** to said folder, where *\* is your **Windows** username:
-
-```bash
-cd /mnt/c/Users//Desktop/decomps
-```
-
-
- Notes...
-
-> Note 1: The Windows C:\ drive is called /mnt/c/ in WSL.
-> Note 2: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "/mnt/c/users//Desktop/decomp folder"`.
-> Note 3: Windows path names are case-insensitive so adhering to capitalization isn't needed
-
-
-If this works, then proceed to [Installation](#installation).
-
-Otherwise, ask for help on Discord or IRC (see [README.md](README.md)), or continue reading below for [Windows instructions using msys2](#windows-msys2).
-
-## Windows (msys2)
-
-- If devkitARM is **not installed**, then go to [Installing devkitARM](#installing-devkitarm).
-- If devkitARM is installed, but msys2 **hasn't previously been set up for another decompilation project**, then go to [Setting up msys2](#setting-up-msys2).
-- Otherwise, **open msys2** and go to [Choosing where to store pokeemerald Expansion (msys2)](#choosing-where-to-store-pokeemerald-expansion-msys2).
-
-### Installing devkitARM
-1. Download the devkitPro installer [here](https://github.com/devkitPro/installer/releases).
-2. Run the devkitPro installer. In the "Choose Components" screen, uncheck everything except GBA Development unless if you plan to install other devkitPro components for other purposes. Keep the install location as C:\devkitPro and leave the Start Menu option unchanged.
-
-### Setting up msys2
-
-Note that in msys2, Copy is Ctrl+Insert and Paste is Shift+Insert.
-
-1. Open msys2 at C:\devkitPro\msys2\msys2_shell.bat.
-
-2. Certain packages are required to build pokeemerald Expansion. Install these by running the following two commands:
-
- ```bash
- pacman -Sy msys2-keyring
- pacman -S make gcc zlib-devel git
- ```
-
- Note...
-
- > The commands will ask for confirmation, just enter the yes action when prompted.
-
-
-3. Download [libpng](https://sourceforge.net/projects/libpng/files/libpng16/1.6.37/libpng-1.6.37.tar.xz/download).
-
-4. Change directory to where libpng was downloaded. By default, msys2 will start in the current user's profile folder, located at **C:\Users\\_\_**, where *\* is your Windows username. In most cases, libpng should be saved within a subfolder of the profile folder. For example, if libpng was saved to **C:\Users\\_\_\Downloads** (the Downloads location for most users), enter this command:
-
- ```bash
- cd Downloads
- ```
-
-
- Notes...
-
- > Note 1: While not shown, msys uses forward slashes `/` instead of backwards slashes `\` as the directory separator.
- > Note 2: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "Downloads/My Downloads"`.
- > Note 3: Windows path names are case-insensitive so adhering to capitalization isn’t needed.
- > Note 4: If libpng was saved elsewhere, you will need to specify the full path to where libpng was downloaded, e.g. `cd c:/devkitpro/msys2` if it was saved there.
-
-
-5. Run the following commands to uncompress and install libpng.
-
- ```bash
- tar xf libpng-1.6.37.tar.xz
- cd libpng-1.6.37
- ./configure --prefix=/usr
- make check
- make install
- ```
-
-6. Then finally, run the following command to change back to the user profile folder.
-
- ```bash
- cd
- ```
-
-### Installing Python on msys2
-
-To install Python on msys2, simply run the following commands:
-
-```bash
-pacman -S mingw-w64-x86_64-python3
-```
-
-Python is now installed.
-
-### Choosing where to store pokeemerald Expansion (msys2)
-At this point, you can choose a folder to store pokeemerald Expansion into. If you're okay with storing pokeemerald Expansion in the user profile folder, then proceed to [Installation](#installation). Otherwise, you'll need to account for where pokeemerald Expansion is stored when changing directory to the pokeemerald-expansion folder.
-
-For example, if you want to store pokeemerald Expansion in **C:\Users\\_\_\Desktop\decomps** (where *\* is your **Windows** username), enter this command:
-
-```bash
-cd Desktop/decomps
-```
-
-If this works, then proceed to [Installation](#installation).
-
-Otherwise, ask for help on Discord or IRC (see [README.md](README.md)), or continue reading below for [Windows instructions using Cygwin](#windows-cygwin).
-
-## Windows (Cygwin)
-1. If devkitARM is **not installed**, then follow the instructions used to [install devkitARM](#installing-devkitarm) for the msys2 setup before continuing. *Remember to not continue following the msys2 instructions by mistake!*
-
-2.
- - If Cygwin is **not installed**, or does not have all of the required packages installed, then go to [Installing Cygwin](#installing-cygwin).
- - If Cygwin is installed, but **is not configured to work with devkitARM**, then go to [Configuring devkitARM for Cygwin](#configuring-devkitarm-for-cygwin).
- - Otherwise, **open Cygwin** and go to [Choosing where to store pokeemerald Expansion (Cygwin)](#choosing-where-to-store-pokeemerald-expansion-cygwin)
-
-### Installing Cygwin
-1. Download [Cygwin](https://cygwin.com/install.html): setup-x86_64.exe for 64-bit Windows, setup-x86.exe for 32-bit.
-
-2. Run the Cygwin setup. Within the Cygwin setup, leave the default settings until the "Choose A Download Site" screen.
-
-3. At "Choose a Download Site", select any mirror within the Available Download Sites.
-
-4. At "Select Packages", set the view to "Full" (top left) and search for the following packages:
- - `make`
- - `git`
- - `gcc-core`
- - `gcc-g++`
- - `libpng-devel`
-
- To quickly find these, use the search bar and type the name of each package. Ensure that the selected package name is the **exact** same as the one you're trying to download, e.g. `cmake` is **NOT** the same as `make`.
-
-5. For each package, double click on the text that says "**Skip**" next to each package to select the most recent version to install. If the text says anything other than "**Skip**", (e.g. Keep or a version number), then the package is or will be installed and you don't need to do anything.
-
-6. Once all required packages have been selected, finish the installation.
-
-### Configuring devkitARM for Cygwin
-
-Note that in Cygwin, Copy is Ctrl+Insert and Paste is Shift+Insert.
-
-1. Open **Cygwin**.
-
-2. Run the following commands to configure devkitPro to work with Cygwin.
-
- ```bash
- export DEVKITPRO=/cygdrive/c/devkitpro
- echo export DEVKITPRO=$DEVKITPRO >> ~/.bashrc
- export DEVKITARM=$DEVKITPRO/devkitARM
- echo export DEVKITARM=$DEVKITARM >> ~/.bashrc
- ```
-
-
- Note...
-
- > Replace the drive letter c with the actual drive letter if it is not c.
-
-
-### Choosing where to store pokeemerald Expansion (Cygwin)
-
-Cygwin has its own file system that's within Windows, at **C:\cygwin64\home\\_\_**. If you don't want to store pokeemerald Expansion there, you'll need to account for where ppokeemerald Expansion is stored when **changing directory** to the pokeemerald-expansion folder.
-
-For example, if you want to store pokeemerald Expansion in **C:\Users\\_\_\Desktop\decomps**, enter this command, where *\* is your **Windows** username:
-```bash
-cd c:/Users//Desktop/decomps
-```
-Note that the directory **must exist** in Windows. If you want to store pokeemerald Expansion in a dedicated folder that doesn't exist (e.g. the example provided above), then create the folder (e.g. using Windows Explorer) before executing the `cd` command.
-
-
- Notes...
-
-> Note 1: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "c:/users//Desktop/decomp folder"`.
-> Note 2: Windows path names are case-insensitive so adhering to capitalization isn't needed
-
-
-If this works, then proceed to [Installation](#installation). Otherwise, ask for help on Discord or IRC (see [README.md](README.md)).
-
-## macOS
-1. If the Xcode Command Line Tools are not installed, download the tools [here](https://developer.apple.com/xcode/resources/), open your Terminal, and run the following command:
-
- ```bash
- xcode-select --install
- ```
-
-2. - If libpng is **not installed**, then go to [Installing libpng (macOS)](#installing-libpng-macos).
- - If pkg-config is **not installed**, then go to [Installing pkg-config (macos)](#installing-pkg-config-macos).
- - If devkitARM is **not installed**, then go to [Installing devkitARM (macOS)](#installing-devkitarm-macos).
- - Otherwise, **open the Terminal** and go to [Choosing where to store pokeemerald Expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos)
-
-### Installing libpng (macOS)
-
- Note for advanced users...
-
-> This guide installs libpng via Homebrew as it is the easiest method, however advanced users can install libpng through other means if they so desire.
-
-
-1. Open the Terminal.
-2. If Homebrew is not installed, then install [Homebrew](https://brew.sh/) by following the instructions on the website.
-3. Run the following command to install libpng.
-
- ```bash
- brew install libpng
- ```
- libpng is now installed.
-
- Continue to [Installing pkg-config (macOS)](#installing-pkg-config-macos) if **pkg-config is not installed**. Otherwise, continue to [Installing devkitARM (macOS)](#installing-devkitarm-macos) if **devkitARM is not installed**.
-
- If both pkg-config and devkitARM are already installed, go to [Choosing where to store pokeemerald Expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos).
-
-### Installing pkg-config (macOS)
-
- Note for advanced users...
-
-> This guide installs pkg-config via Homebrew as it is the easiest method, however advanced users can install pkg-config through other means if they so desire.
-
-
-1. Open the Terminal.
-2. If Homebrew is not installed, then install [Homebrew](https://brew.sh/) by following the instructions on the website.
-3. Run the following command to install libpng.
-
- ```bash
- brew install pkg-config
- ```
- pkg-config is now installed.
-
- Continue to [Installing devkitARM (macOS)](#installing-devkitarm-macos) if **devkitARM is not installed**, otherwise, go to [Choosing where to store pokeemerald Expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos).
-
-### Installing devkitARM (macOS)
-1. Download the `devkitpro-pacman-installer.pkg` package from [here](https://github.com/devkitPro/pacman/releases).
-2. Open the package to install devkitPro pacman.
-3. In the Terminal, run the following commands to install devkitARM:
-
- ```bash
- sudo dkp-pacman -Sy
- sudo dkp-pacman -S gba-dev
- sudo dkp-pacman -S devkitarm-rules
- ```
-
- The command with gba-dev will ask for the selection of packages to install. Just press Enter to install all of them, followed by entering Y to proceed with the installation.
-
-4. After the tools are installed, devkitARM must now be made accessible from anywhere by the system. To do so, run the following commands:
-
- ```bash
- export DEVKITPRO=/opt/devkitpro
- echo "export DEVKITPRO=$DEVKITPRO" >> ~/.zshrc
- export DEVKITARM=$DEVKITPRO/devkitARM
- echo "export DEVKITARM=$DEVKITARM" >> ~/.zshrc
-
- echo "if [ -f ~/.zshrc ]; then . ~/.zshrc; fi" >> ~/.zprofile
- ```
- *Note: Starting with macOS 10.15, the default Unix shell is now zsh. If you migrated from an older version of macOS, you might still be using bash. You can check my running `echo $0` in the terminal.*
-
- If your terminal is using bash instead of zsh...
-
- ```bash
- export DEVKITPRO=/opt/devkitpro
- echo "export DEVKITPRO=$DEVKITPRO" >> ~/.bashrc
- export DEVKITARM=$DEVKITPRO/devkitARM
- echo "export DEVKITARM=$DEVKITARM" >> ~/.bashrc
-
- echo "if [ -f ~/.bashrc ]; then . ~/.bashrc; fi" >> ~/.bash_profile
- ```
-
-
-### Installing Python (macOS)
-1. Download the latest Python package from [here](https://www.python.org/downloads/).
-2. Open the package to install Python.
-
-Python is now installed.
-
-### Choosing where to store pokeemerald Expansion (macOS)
-At this point, you can choose a folder to store pokeemerald Expansion into. If you're okay with storing pokeemerald Expansion in the user folder, then proceed to [Installation](#installation). Otherwise, you'll need to account for where pokeemerald Expansion is stored when changing directory to the pokeemerald-expansion folder.
-
-For example, if you want to store pokeemerald Expansion in **~/Desktop/decomps**, enter this command to **change directory** to the desired folder:
-```bash
-cd Desktop/decomps
-```
-Note that the directory **must exist** in the folder system. If you want to store pokeemerald Expansion in a dedicated folder that doesn't exist (e.g. the example provided above), then create the folder (e.g. using Finder) before executing the `cd` command.
-
-
- Note...
-
-> Note: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "Desktop/decomp folder"`
-
-
-If this works, then proceed to [Installation](#installation). Otherwise, ask for help on Discord or IRC (see [README.md](README.md)).
+[Cygwin Install instructions](docs/install/windows/CYGWIN.md)
## Linux
-Open Terminal and enter the following commands, depending on which distro you're using.
+The project can be built on any Linux distribution.
+Distributions with instructions:
+- [Ubuntu](docs/install/linux/UBUNTU.md)
+- [Debian](docs/install/linux/DEBIAN.md)
+- [Arch Linux](docs/install/linux/ARCH_LINUX.md)
+- [NixOS](docs/install/linux/NIXOS.md)
-### Debian/Ubuntu-based distributions
-Run the following command to install the necessary packages:
-```bash
-sudo apt install build-essential binutils-arm-none-eabi gcc-arm-none-eabi libnewlib-arm-none-eabi git libpng-dev
-```
-Then proceed to [Choosing where to store pokeemerald Expansion (Linux)](#choosing-where-to-store-pokeemerald-expansion-linux).
-
- Note for legacy repos...
+Other distributions have to infer what to do from [general instructions](docs/install/linux/OTHERS.md).
-> If the repository you plan to build has an **[older revision of the INSTALL.md](https://github.com/pret/pokeemerald/blob/571c598/INSTALL.md)**,
-> then you will have to install devkitARM. Install all the above packages except for the arm-none-eabi packages, and follow the instructions to
-> [install devkitARM on Debian/Ubuntu-based distributions](#installing-devkitarm-on-debianubuntu-based-distributions).
-
+## Mac
+Some extra considerations exist to get the testing system working.
-### Installing devkitARM on Debian/Ubuntu-based distributions
+[Mac instructions](docs/install/mac/MAC_OS.md)
-1. Change directory to somewhere you can download a packages, like a Downloads folder. Then, run the following commands to install devkitARM:
+## ChromeOS
+Only tested on x86_64 based systems.
- ```bash
- wget https://apt.devkitpro.org/install-devkitpro-pacman
- chmod +x ./install-devkitpro-pacman
- sudo ./install-devkitpro-pacman
- sudo dkp-pacman -S gba-dev
- ```
- The last command will ask for the selection of packages to install. Just press Enter to install all of them, followed by entering Y to proceed with the installation.
+[Chrome OS instructions](docs/install/chromeos/CHROME_OS.md)
-4. Run the following command to set devkitPro related environment variables (alternatively, close and re-open the Terminal):
-
- ```bash
- source /etc/profile.d/devkit-env.sh
- ```
-
-devkitARM is now installed.
-
-### Arch Linux
-Run this command as root to install the necessary packages:
-```bash
-pacman -S base-devel arm-none-eabi-binutils arm-none-eabi-gcc arm-none-eabi-newlib git libpng
-```
-
-### Installing devkitARM on Arch Linux
-
-1. Follow [devkitPro's instructions](https://devkitpro.org/wiki/devkitPro_pacman#Customising_Existing_Pacman_Install) to configure `pacman` to download devkitPro packages.
-2. Install `gba-dev`: run the following command as root.
+# Building pokeemerald-expansion
+Follow these steps to build `pokeemerald-expansion`.
+1. Navigate to the directory you want to keep the project in, be aware of any system specific limitations.
+2. Download `pokeemerald-expansion` with `git`
```console
- pacman -S gba-dev
- ```
- This will ask for the selection of packages to install. Just press Enter to install all of them, followed by entering Y to proceed with the installation.
-
-3. Run the following command to set devkitPro related environment variables (alternatively, close and re-open the Terminal):
-
- ```bash
- source /etc/profile.d/devkit-env.sh
- ```
-
-devkitARM is now installed.
-
-Then proceed to [Choosing where to store pokeemerald Expansion (Linux)](#choosing-where-to-store-pokeemerald-expansion-linux).
-
-### NixOS
-Run the following command to start an interactive shell with the necessary packages:
-```bash
-nix-shell -p pkgsCross.arm-embedded.stdenv.cc git pkg-config libpng
-```
-Then proceed to [Choosing where to store pokeemerald Expansion (Linux)](#choosing-where-to-store-pokeemerald-expansion-linux).
-
-### NixOS
-Run the following command to start an interactive shell with the necessary packages:
-```bash
-nix-shell -p pkgsCross.arm-embedded.stdenv.cc git pkg-config libpng
-```
-Then proceed to [Choosing where to store pokeemerald Expansion (Linux)](#choosing-where-to-store-pokeemerald-expansion-linux).
-
-### Other distributions
-_(Specific instructions for other distributions would be greatly appreciated!)_
-
-1. Try to find the required software in its repositories:
- - `gcc`
- - `g++`
- - `make`
- - `git`
- - `libpng-dev`
-
-2. Follow the instructions [here](https://devkitpro.org/wiki/devkitPro_pacman) to install devkitPro pacman. As a reminder, the goal is to configure an existing pacman installation to recognize devkitPro's repositories.
-3. Once devkitPro pacman is configured, run the following commands:
-
- ```bash
- sudo pacman -Sy
- sudo pacman -S gba-dev
- ```
-
- The last command will ask for the selection of packages to install. Just press Enter to install all of them, followed by entering Y to proceed with the installation.
-
-### Installing Python in Linux
-Installing Python depends on your distribution, please refere to the instructions [here](https://docs.python-guide.org/starting/install3/linux/).
-
-### Choosing where to store pokeemerald Expansion (Linux)
-At this point, you can choose a folder to store pokeemerald Expansion into. If so, you'll have to account for the modified folder path when changing directory to the pokeemerald-expansion folder.
-
-If this works, then proceed to [Installation](#installation). Otherwise, ask for help on Discord or IRC (see [README.md](README.md)).
-
-## Installation
-
-
- Note for Windows users...
-
-> Consider adding an exception for the `pokeemerald-expansion` and/or `decomps` folder in Windows Security using
-> [these instructions](https://support.microsoft.com/help/4028485). This prevents Microsoft Defender from
-> scanning them which might improve performance while building.
-
-
-1. If pokeemerald Expansion is not already downloaded (some users may prefer to download pokeemerald Expansion via a git client like GitHub Desktop), run:
-
- ```bash
git clone https://github.com/rh-hideout/pokeemerald-expansion
```
+3. Navigate to the newly downloaded project.
-
- Note for WSL1...
+ ```console
+ cd pokeemerald-expansion
+ ```
+4. Build the project.
- > If you get an error stating `fatal: could not set 'core.filemode' to 'false'`, then run the following commands:
- > ```bash
- > cd
- > sudo umount /mnt/c
- > sudo mount -t drvfs C: /mnt/c -o metadata,noatime
- > cd
- > ```
- > Where *\* is the path of the folder [where you chose to store pokeemerald Expansion](#Choosing-where-to-store-pokeemerald-expansion-WSL1). Then run the `git clone` command again.
-
+ ```console
+ make
+ ```
+5. If everything worked correctly, something very similar to this should be seen.
-Now you're ready to build pokeemerald Expansion.
-
-## Build pokeemerald Expansion
-
-If you aren't in the pokeemerald-expansion directory already, then **change directory** to the pokeemerald-expansion folder:
-```bash
-cd pokeemerald-expansion
-```
-To build **pokeemerald.gba** (Note: to speed up builds, see [Parallel builds](#parallel-builds)):
-```bash
-make
-```
-If it has built successfully you will have the output file **pokeemerald.gba** in your project folder.
-
-Note for Windows...
-> If you switched terminals since the last build (e.g. from msys2 to WSL1), you must run `make clean-tools` once before any subsequent `make` commands.
-
+ ```console
+ arm-none-eabi-ld: warning: ../../pokeemerald.elf has a LOAD segment with RWX permissions
+ Memory region Used Size Region Size %age Used
+ EWRAM: 243354 B 256 KB 92.83%
+ IWRAM: 30492 B 32 KB 93.05%
+ ROM: 26072244 B 32 MB 77.70%
+ cd build/modern && arm-none-eabi-ld -T ../../ld_script_modern.ld --print-memory-usage -o ../../pokeemerald.elf | cat
+ tools/gbafix/gbafix pokeemerald.elf -t"POKEMON EMER" -cBPEE -m01 -r0 --silent
+ arm-none-eabi-objcopy -O binary pokeemerald.elf pokeemerald.gba
+ tools/gbafix/gbafix pokeemerald.gba -p --silent
+ ```
+ And the build ROM will be in the directory as `pokeemerald.gba`.
# Building guidance
@@ -592,9 +110,9 @@ To compile the `modern` target with this toolchain, the subdirectories `lib`, `i
### Building with debug info
-To build **pokeemerald.elf** with debug symbols under a modern toolchain:
+To build **pokeemerald.elf** with debug symbols and debug-compatible optimization under a modern toolchain:
```bash
-make DINFO=1
+make debug
```
# Useful additional tools
diff --git a/Makefile b/Makefile
index f38b551b0c..e7af566de4 100644
--- a/Makefile
+++ b/Makefile
@@ -121,7 +121,7 @@ CPPFLAGS := $(INCLUDE_CPP_ARGS) -Wno-trigraphs -DMODERN=1 -DTESTING=$(TEST)
ARMCC := $(PREFIX)gcc
PATH_ARMCC := PATH="$(PATH)" $(ARMCC)
CC1 := $(shell $(PATH_ARMCC) --print-prog-name=cc1) -quiet
-override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
+override CFLAGS += -mthumb -mthumb-interwork -O$(O_LEVEL) -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
ifeq ($(ANALYZE),1)
override CFLAGS += -fanalyzer
endif
@@ -346,10 +346,13 @@ endif
$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast
$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member
+$(C_BUILDDIR)/agb_flash.o: override CFLAGS += -fno-toplevel-reorder
$(C_BUILDDIR)/pokedex_plus_hgss.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
# Annoyingly we can't turn this on just for src/data/trainers.h
$(C_BUILDDIR)/data.o: CFLAGS += -fno-show-column -fno-diagnostics-show-caret
+$(TEST_BUILDDIR)/%.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init
+
# Dependency rules (for the *.c & *.s sources to .o files)
# Have to be explicit or else missing files won't be reported.
@@ -438,6 +441,7 @@ libagbsyscall:
@$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=1
# Elf from object files
+LDFLAGS = -Map ../../$(MAP)
$(ELF): $(LD_SCRIPT) $(LD_SCRIPT_DEPS) $(OBJS) libagbsyscall
@cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< --print-memory-usage -o ../../$@ $(OBJS_REL) $(LIB) | cat
@echo "cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -T ../../$< --print-memory-usage -o ../../$@ | cat"
diff --git a/README.md b/README.md
index facd5f5626..70317fac5c 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,58 @@
# pokeemerald-expansion
-### Important: DO NOT use GitHub's "Download Zip" option. Using this option will not download the commit history required to update your expansion version or merge other feature branches. Instead, please read [this guide](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub) to learn how to fork the repository and clone locally from there.
+pokeemerald-expansion is ***a romhack base*** based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. ***It is NOT a playable romhack,*** but it has multiple features available to romhackers so that they can create their own games, so it's not meant to be played on its own.
-## What is pokeemerald-expansion?
+## Should I use this or vanilla pokeemerald for my hack?
+The main advantage of using vanilla pokeemerald as a base is being able to link with other official GBA Pokémon games for battles and trading, pokeemerald-expansion can battle and trade with itself out of the box. If you don't mind losing full vanilla compatiblitity, we recommend using pokeemerald-expansion. Otherwise, use pret's pokeemerald. You'll still receive documentation improvements from pret, as we regurlarly incorporate pret's documentation changes.
-pokeemerald-expansion is a decomp hack base project based off pret's [pokeemerald](https://github.com/pret/pokeemerald) decompilation project. It's recommended that any new projects that plan on using it, to clone this repository instead of pret's vanilla repository, as we regurlarly incorporate pret's documentation changes. This is ***NOT*** a standalone romhack, and as such, most features will be unavailable and/or unbalanced if played as is.
+## Using pokeemerald-expansion
If you use pokeemerald-expansion in your hack, please add RHH (Rom Hacking Hideout) to your credits list. Optionally, you can list the version used, so it can help players know what features to expect.
You can phrase it as the following:
```
-Based off RHH's pokeemerald-expansion 1.9.3 https://github.com/rh-hideout/pokeemerald-expansion/
+Based off RHH's pokeemerald-expansion 1.10.1 https://github.com/rh-hideout/pokeemerald-expansion/
```
+#### Important: DO NOT use GitHub's "Download Zip" option. Using this option will not download the commit history required to update your expansion version or merge other feature branches. Instead, please read [this guide](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub) to learn how to fork the repository and clone locally from there.
+
+Please follow the instructions in `INSTALL.md` to get pokeemerald-expansion set up on your machine.
+
+### If I already have a project based on regular pokeemerald, can I use pokeemerald-expansion?
+Yes! Keep in mind that we keep up with pret's documentation of pokeemerald, which means that if your project a bit old, you might get merge conflicts that you need to solve manually.
+- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
+- Once you have your remote set up, run the command `git pull RHH master`.
+
+With this, you'll get the latest version of pokeemerald-expansion, plus a couple of bugfixes that haven't yet been released into the next patch version :)
+
+## Documentation
+[Please click here to visit our documentation page.](https://rh-hideout.github.io/pokeemerald-expansion/)
+
+## **How do I update my version of pokeemerald-expansion?**
+- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
+- Check your current version.
+ - You can check in the debug menu's `Utilities -> Expansion Version` option.
+ - If the option is not available, you possibly have version 1.6.2 or older. In that case, please check the [changelogs](docs/CHANGELOG.md) to determine your version based on the features available on your repository.
+- ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on. Check the [online documentation site](https://rh-hideout.github.io/pokeemerald-expansion/CHANGELOG.html) to see the latest versions of each step.)
+- Once you have your remote set up, run the command `git pull RHH expansion/X.Y.Z`, replacing X, Y and Z with the digits of the respective version you want to update to (eg, to update to 1.9.3, use `git pull RHH expansion/1.9.3`).
+ - ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on)
+- Alternatively, you can update to unreleased versions of the expansion.
+ - ***master (stable):*** It contains unreleased **bugfixes** that will come in the next patch version. To merge, use `git pull RHH master`.
+ - ***upcoming (unstable, with potential bugs):*** It contains unreleased **features** that will come in the next minor version. To merge, use `git pull RHH upcoming`.
+
+### Please consider crediting the entire [list of contributors](https://github.com/rh-hideout/pokeemerald-expansion/wiki/Credits) in your project, as they have all worked hard to develop this project :)
+
+## Who maintains the project?
+The project was originally started by DizzyEgg alongside other contributors. Now it is maintained by a team in the ROM Hacking Hideout's community called the "Expansion Senate". ROM Hacking Hideout (RHH for short) is a Discord-based ROM hacking community specialized in Pokémon romhacks. A lot of the discussion in regards of the development of the project happens there.
+
+[Click here to join the RHH Discord Server!](https://discord.gg/6CzjAG6GZk)
+
+## There's a bug in the project. How do I let you guys know?
+Please submit any issues with the project [here](https://github.com/rh-hideout/pokeemerald-expansion/issues) and make sure that the issue wasn't reported by someone else by searching using the filters. You may also join the Discord server to try getting more in-depth support from the team and other members of the server.
+
+## Can I contribute even if I'm not a member of ROM Hacking Hideout?
+Yes! Contributions are welcome via Pull Requests and they will be reviewed by maintainers in due time.
+Also, *please follow the Pull Request template and feel free to discuss how the reviews are being handled. **Communication is key!*** Don't feel discouraged if we take a bit to review your PR, we'll get to it.
+
## What features are included?
- ***IMPORTANT*❗❗ Read through these to learn what features you can toggle**:
- [Battle configurations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/config/battle.h)
@@ -156,46 +197,4 @@ Based off RHH's pokeemerald-expansion 1.9.3 https://github.com/rh-hideout/pokeem
- All bugfixes from pret included.
- Fixed overworld snow effect.
-There are some mechanics, moves and abilities that are missing and being developed. Check [the project's milestones](https://github.com/rh-hideout/pokeemerald-expansion/milestones) to see which ones.
-
-
-### [Documentation on features can be found here](https://github.com/rh-hideout/pokeemerald-expansion/wiki)
-
-## If I already have a project based on regular pokeemerald, can I use pokeemerald-expansion?
-Yes! Keep in mind that we keep up with pret's documentation of pokeemerald, which means that if your project a bit old, you might get merge conflicts that you need to solve manually.
-- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
-- Once you have your remote set up, run the command `git pull RHH master`.
-
-With this, you'll get the latest version of pokeemerald-expansion, plus a couple of bugfixes that haven't been released into the next patch version :)
-
-## **How do I update my version of pokeemerald-expansion?**
-- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
-- Check your current version.
- - You can check in the debug menu's `Utilities -> Expansion Version` option.
- - If the option is not available, you possibly have version 1.6.2 or older. In that case, please check the [changelogs](CHANGELOG.md) to determine your version based on the features available on your repository.
-- Once you have your remote set up, run the command `git pull RHH expansion/X.Y.Z`, replacing X, Y and Z with the digits of the respective version you want to update to (eg, to update to 1.9.3, use `git pull RHH expansion/1.9.3`).
- - ***Important:*** If you are several versions behind, we recommend updating one minor version at a time, skipping directly to the latest patch version (eg, 1.5.3 -> 1.6.2 -> 1.7.4 and so on)
-- Alternatively, you can update to unreleased versions of the expansion.
- - ***master (stable):*** It contains unreleased **bugfixes** that will come in the next patch version. To merge, use `git pull RHH master`.
- - ***upcoming (unstable, with potential bugs):*** It contains unreleased **features** that will come in the next minor version. To merge, use `git pull RHH upcoming`.
-
-### Please consider crediting the entire [list of contributors](https://github.com/rh-hideout/pokeemerald-expansion/wiki/Credits) in your project, as they have all worked hard to develop this project :)
-
-## There's a bug in the project. How do I let you guys know?
-Please submit any issues with the project [here](https://github.com/rh-hideout/pokeemerald-expansion/issues). Make sure that the issue wasn't reported by someone else by searching using the filters.
-
-## Can I contribute even if I'm not a member of ROM Hacking Hideout?
-
-Yes! Contributions are welcome via Pull Requests and they will be reviewed by maintainers. Don't feel discouraged if we take a bit to review your PR, we'll get to it.
-
-## Who maintains the project?
-
-The project was originally started by DizzyEgg alongside other contributors.
-
-The project has now gotten larger and DizzyEgg is now maintaining the project as part of the ROM Hacking Hideout community. Some members of this community are taking on larger roles to help maintain the project.
-
-## What is the ROM Hacking Hideout?
-
-A Discord-based ROM hacking community that has many members who hack using the disassembly and decompilation projects for Pokémon. Quite a few contributors to the original feature branches by DizzyEgg were members of ROM Hacking Hideout. You can call it RHH for short!
-
-[Click here to join the RHH Discord Server!](https://discord.gg/6CzjAG6GZk)
+There are some mechanics, moves and abilities that are missing and being developed. Check [the project's milestones](https://github.com/rh-hideout/pokeemerald-expansion/milestones) and our [issues page](https://github.com/rh-hideout/pokeemerald-expansion/issues) to see which ones.
diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc
index c63c2de542..80e9b36789 100644
--- a/asm/macros/battle_script.inc
+++ b/asm/macros/battle_script.inc
@@ -356,7 +356,7 @@
.byte 0x3a
.endm
- .macro healthbar_update battler:req
+ .macro absorbhealthbarupdate battler:req
.byte 0x3b
.byte \battler
.endm
@@ -798,9 +798,7 @@
2:
.endm
- .macro setmultihitcounter value:req
- .byte 0x8d
- .byte \value
+ .macro unused_0x8d
.endm
.macro initmultihitstring
@@ -834,7 +832,7 @@
.byte 0x94
.endm
- .macro unused_95
+ .macro copybidedmg
.byte 0x95
.endm
@@ -930,8 +928,9 @@
.4byte \failInstr
.endm
- .macro setdestinybond
+ .macro trysetdestinybond failInstr:req
.byte 0xaa
+ .4byte \failInstr
.endm
.macro trysetdestinybondtohappen
@@ -1104,7 +1103,7 @@
.byte 0xcc
.endm
- .macro cureifburnedparalysedorpoisoned failInstr:req
+ .macro curestatuswithmove failInstr:req
.byte 0xcd
.4byte \failInstr
.endm
@@ -1232,11 +1231,11 @@
.byte 0xe5
.endm
- .macro unused3
+ .macro unused_0xE6
.byte 0xe6
.endm
- .macro unused4
+ .macro unused_0xE7
.byte 0xe7
.endm
@@ -1427,11 +1426,6 @@
callnative BS_TryRevertWeatherForm
.endm
- .macro applysaltcure battler:req
- callnative BS_ApplySaltCure
- .byte \battler
- .endm
-
.macro trysetoctolock battler:req, failInstr:req
callnative BS_TrySetOctolock
.byte \battler
@@ -1526,8 +1520,8 @@
.4byte \jumpInstr
.endm
- .macro jumpifargument argument:req, jumpInstr:req
- callnative BS_JumpIfArgument
+ .macro jumpifmovepropertyargument argument:req, jumpInstr:req
+ callnative BS_JumpIfMovePropertyArgument
.byte \argument
.4byte \jumpInstr
.endm
@@ -1669,6 +1663,11 @@
callnative BS_DamageToQuarterTargetHP
.endm
+ .macro jumpifsleepclause jumpInstr:req
+ callnative BS_JumpIfSleepClause
+ .4byte \jumpInstr
+ .endm
+
.macro ficklebeamdamagecalculation
callnative BS_FickleBeamDamageCalculation
.endm
@@ -1761,6 +1760,27 @@
callnative BS_RemoveTerrain
.endm
+ .macro setmoveresultflags flags:req
+ callnative BS_SetMoveResultFlags
+ .2byte \flags
+ .endm
+
+ .macro clearmoveresultflags flags:req
+ callnative BS_ClearMoveResultFlags
+ .2byte \flags
+ .endm
+
+ .macro jumpifmoveresultflags flags:req failInstr:req
+ callnative BS_JumpIfMoveResultFlags
+ .2byte \flags
+ .4byte \failInstr
+ .endm
+
+ .macro jumpifcriticalhit failInstr:req
+ callnative BS_JumpIfCriticalHit
+ .4byte \failInstr
+ .endm
+
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
@@ -2006,9 +2026,10 @@
.4byte \jumpInstr
.endm
- .macro trypsychoshift failInstr:req
+ .macro trypsychoshift failInstr:req sleepClauseFailInstr:req
various BS_ATTACKER, VARIOUS_PSYCHO_SHIFT
.4byte \failInstr
+ .4byte \sleepClauseFailInstr
.endm
.macro curestatus battler:req
@@ -2216,11 +2237,6 @@
.4byte \jumpInstr
.endm
- .macro eeriespellppreduce failInstr:req
- various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE
- .4byte \failInstr
- .endm
-
.macro jumpifteamhealthy battler:req, jumpInstr:req
various \battler, VARIOUS_JUMP_IF_TEAM_HEALTHY
.4byte \jumpInstr
@@ -2400,7 +2416,7 @@
.endm
.macro jumpifmovehadnoeffect jumpInstr:req
- jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_NO_EFFECT, \jumpInstr
+ jumpifmoveresultflags MOVE_RESULT_NO_EFFECT, \jumpInstr
.endm
.macro jumpifside battler:req, side:req, equalJumpInstr:req
diff --git a/asm/macros/event.inc b/asm/macros/event.inc
index ede71eb19b..1a01779702 100644
--- a/asm/macros/event.inc
+++ b/asm/macros/event.inc
@@ -1226,6 +1226,13 @@
.4byte \products
.endm
+ @ Used as the endpoint for a Pokemart item list
+ .macro pokemartlistend
+ .2byte ITEM_NONE
+ release
+ end
+ .endm
+
@ Opens the Pokemart system and treats the list of items as decorations.
@ Products should be a list of .2byte decoration values preceded by an .align 2
.macro pokemartdecoration products:req
diff --git a/charmap.txt b/charmap.txt
index e8e43dc996..cd0972f84a 100644
--- a/charmap.txt
+++ b/charmap.txt
@@ -46,6 +46,8 @@ LV = 34
'=' = 35
';' = 36
V_D_ARROW = 38
+NBSP = 39
+'~' = 39
'¿' = 51
'¡' = 52
PK = 53
@@ -370,7 +372,7 @@ B_ATK_NAME_WITH_PREFIX = FD 0F
B_DEF_NAME_WITH_PREFIX = FD 10
B_EFF_NAME_WITH_PREFIX = FD 11 @ EFF = short for gEffectBattler
@ FD 12 - preiously gActiveBattler with prefix
-B_SCR_ACTIVE_NAME_WITH_PREFIX = FD 13
+B_SCR_NAME_WITH_PREFIX = FD 13
B_CURRENT_MOVE = FD 14
B_LAST_MOVE = FD 15
B_LAST_ITEM = FD 16
@@ -411,12 +413,13 @@ B_ATK_TEAM2 = FD 38
B_DEF_NAME = FD 39
B_DEF_TEAM1 = FD 3A
B_DEF_TEAM2 = FD 3B
+B_DEF_PARTNER_NAME = FD 3C
@ FD 3C - preiously gActiveBattler
@ FD 3D - preiously gActiveBattler without Illusion Check
B_ATK_NAME_WITH_PREFIX2 = FD 3E
B_DEF_NAME_WITH_PREFIX2 = FD 3F
B_EFF_NAME_WITH_PREFIX2 = FD 40
-B_SCR_ACTIVE_NAME_WITH_PREFIX2 = FD 41
+B_SCR_NAME_WITH_PREFIX2 = FD 41
B_TRAINER1_NAME_WITH_CLASS = FD 42
B_TRAINER2_NAME_WITH_CLASS = FD 43
B_PARTNER_NAME_WITH_CLASS = FD 44
@@ -465,6 +468,7 @@ FONT_SMALL_NARROW = FC 06 08
FONT_NARROWER = FC 06 0A
FONT_SMALL_NARROWER = FC 06 0B
FONT_SHORT_NARROW = FC 06 0C
+FONT_SHORT_NARROWER = FC 06 0D
@ colors
diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s
index 643ee2cd0e..5812084ebe 100644
--- a/data/battle_anim_scripts.s
+++ b/data/battle_anim_scripts.s
@@ -350,34 +350,27 @@ gBattleAnimMove_MetalBurst::
waitforvisualfinish
end
+@Credits: Skeli
gBattleAnimMove_UTurn::
- loadspritegfx ANIM_TAG_ROUND_SHADOW
+ loadspritegfx ANIM_TAG_SMALL_BUBBLES
+ loadspritegfx ANIM_TAG_RAZOR_LEAF
loadspritegfx ANIM_TAG_IMPACT
monbg ANIM_DEF_PARTNER
- setalpha 12, 8
- playsewithpan SE_M_FLY, SOUND_PAN_ATTACKER
- createsprite gFlyBallUpSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336
- playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_ATTACKER
- createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER
- jumpretfalse UTurnVisible
- createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20, TRUE
-UTurnContinue:
- delay 20
- createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1, 0
- createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 6, 0, 8, 1
- playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET
- waitforvisualfinish
- clearmonbg ANIM_DEF_PARTNER
- createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER
- jumpretfalse UTurnLast
+ splitbgprio ANIM_TARGET
+ setalpha 8, 8
invisible ANIM_ATTACKER
-UTurnLast:
- blendoff
+ playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER
+ createsprite gUTurnBallSpriteTemplate, ANIM_TARGET, 2, 0, 0, 21
waitforvisualfinish
+ playsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER
+ createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0x0, 0x0, 1, 2
+ createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1
+ createsprite gUTurnBallBackSpriteTemplate, ANIM_ATTACKER, 3, 4, 0, -16, 36
+ waitforvisualfinish
+ visible ANIM_ATTACKER
+ clearmonbg ANIM_TARGET
+ blendoff
end
-UTurnVisible:
- createsprite gFlyBallAttackSpriteTemplate, ANIM_ATTACKER, 2, 20, FALSE
- goto UTurnContinue
gBattleAnimMove_CloseCombat::
loadspritegfx ANIM_TAG_IMPACT
@@ -3666,7 +3659,7 @@ gBattleAnimMove_DarkVoid::
loopsewithpan SE_M_CONFUSE_RAY, SOUND_PAN_ATTACKER, 5, 2
delay 48
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, -768, 21, 0, 112 @Last is duration
- createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, -768, 21, 0, 112 @Last is duration
+ createsprite gSlideMonToOffsetPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, -768, 21, 0, 112 @Last is duration
delay 64
invisible ANIM_TARGET
invisible ANIM_DEF_PARTNER
@@ -3674,7 +3667,7 @@ gBattleAnimMove_DarkVoid::
createsprite gDarkVoidPurpleStarsTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_DEF_PARTNER, 0, 32, 60
waitforvisualfinish
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0, 16
- createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0, 16
+ createsprite gSlideMonToOriginalPosPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0, 16
delay 32
call UnsetPsychicBg
visible ANIM_TARGET
@@ -5561,44 +5554,40 @@ GrassPledgeMiddleFountain:
delay 4
return
+@Credits to Skeli
gBattleAnimMove_VoltSwitch::
- loadspritegfx ANIM_TAG_SPARK
+ loadspritegfx ANIM_TAG_SHADOW_BALL
+ loadspritegfx ANIM_TAG_IONS
loadspritegfx ANIM_TAG_SPARK_2
- loadspritegfx ANIM_TAG_THIN_RING
- monbg ANIM_ATTACKER
- setalpha 12, 8
- createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 0x3BDF, 8
- playsewithpan SE_M_CHARGE, SOUND_PAN_ATTACKER
+ playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_ATTACKER
+ createsprite gVoltSwitchSpriteTemplate, ANIM_TARGET, 3, 0, 0, 0, 0, 32, 20
+ delay 30
+ createvisualtask AnimTask_ShakeMon2 2, ANIM_TARGET, 3, 0, 8, 1
+ call VoltSwitchElectricFlashes
+ delay 2
+ playsewithpan SE_M_THUNDERBOLT, SOUND_PAN_ATTACKER
+ createsprite gVoltSwitchSpriteTemplate ANIM_TARGET, 3, 0, 0, 0, 0, 32, -20
delay 4
- createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 0x3BDF, 8
- delay 4
- createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 3, 45, 1
- createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 0x3BDF, 8
- delay 4
- createsprite gUproarRingSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 0, 0, 0x3BDF, 8
- delay 4
- call ElectricityEffect
- playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER
- createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER
- jumpretfalse VoltSwitchContinue
- createvisualtask AnimTask_IsTargetSameSide 1
- jumprettrue VoltSwitchAgainstPartner
- createvisualtask AnimTask_SlideOffScreen, 5, ANIM_ATTACKER, -2
-VoltSwitchContinue:
+ call VoltSwitchElectricFlashes
+ delay 18
+ createvisualtask AnimTask_ShakeMon2 2, ANIM_TARGET, 3, 0, 8, 1
+ call VoltSwitchElectricFlashes
+ delay 6
+ call VoltSwitchElectricFlashes
waitforvisualfinish
- clearmonbg ANIM_ATTACKER
- blendoff
- createvisualtask AnimTask_CanBattlerSwitch, 1, ANIM_ATTACKER
- jumpretfalse VoltSwitchLast
- invisible ANIM_ATTACKER
-VoltSwitchLast:
- delay 8
end
-@ Attacking the same side requires a change of direction
-@ why would you attack your partner though?!
-VoltSwitchAgainstPartner:
- createvisualtask AnimTask_SlideOffScreen, 5, ANIM_ATTACKER, 2
- goto VoltSwitchContinue
+
+VoltSwitchElectricFlashes:
+ playsewithpan SE_M_CHARGE, SOUND_PAN_TARGET
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 5, 0, 5, 0
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -5, 10, 5, 1
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 15, 20, 5, 2
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -15, -10, 5, 0
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 25, 0, 5, 1
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -8, 8, 5, 2
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, 2, -8, 5, 0
+ createsprite gElectricitySpriteTemplate, ANIM_TARGET, 2, -20, 15, 5, 1
+ return
gBattleAnimMove_StruggleBug::
loadspritegfx ANIM_TAG_MOVEMENT_WAVES
@@ -10093,7 +10082,6 @@ gBattleAnimMove_FloralHealing::
loadspritegfx ANIM_TAG_ORBS @circles
loadspritegfx ANIM_TAG_PINK_PETAL @pink particles
monbg ANIM_ATTACKER
- monbg ANIM_TARGET
playsewithpan SE_M_DETECT, SOUND_PAN_ATTACKER
call CIRCLES_LEAVES
call CIRCLES_LEAVES
@@ -10101,6 +10089,7 @@ gBattleAnimMove_FloralHealing::
panse SE_M_COMET_PUNCH, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 0x2, 0x0
playsewithpan SE_M_TWISTER, 0x0
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 0x46, 0x1, 0x40
+ clearmonbg ANIM_ATTACKER
delay 0x2
createsprite gFloralHealingWindLeavesTemplate, ANIM_ATTACKER, 2, 0x3c, 0x0, 0x40
delay 0x2
@@ -10123,6 +10112,7 @@ gBattleAnimMove_FloralHealing::
createsprite gSweetScentPetalSpriteTemplate, ANIM_ATTACKER, 2, 0x55, 0x0, 0x78
delay 0x2
loopsewithpan SE_M_POISON_POWDER, SOUND_PAN_TARGET, 0x12, 0xa
+ monbg ANIM_TARGET
call FloralHealingSpores
call FloralHealingSpores
call FloralHealingSpores
@@ -10133,7 +10123,6 @@ gBattleAnimMove_FloralHealing::
createsprite gGrantingStarsSpriteTemplate, ANIM_ATTACKER, 16, 0xc, 0xfffb, 0x1, 0x0, 0x20, 0x3c, 0x1
waitforvisualfinish
clearmonbg ANIM_TARGET
- clearmonbg ANIM_ATTACKER
end
FloralHealingSpores:
createsprite gFloralHealingFlowerTemplate, ANIM_ATTACKER, 2, 0x0, 0xffec, 0x55, 0x50, 0x0
@@ -33527,7 +33516,7 @@ gBattleAnimMove_ClangorousSoulblaze::
delay 0x2
createvisualtask AnimTask_StartSlidingBg, 0x5, 0x0, 0xFFE0, 0x1, 0xffff
createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0xfd00, 0xa, 0x0, 0x2a
- createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0xfd00, 0xa, 0x0, 0x2a
+ createsprite gSlideMonToOffsetPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0xfd00, 0xa, 0x0, 0x2a
delay 0x20
createvisualtask AnimTask_StartSlidingBg, 0x5, 0x0, 0x20, 0x1, 0xffff
delay 0xC
@@ -33719,7 +33708,7 @@ FINISH_SOULBLAZE:
call ResetFromWhiteScreen
blendoff
createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0x0, 0x10
- createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0x0, 0x10
+ createsprite gSlideMonToOriginalPosPartnerSpriteTemplate, ANIM_ATTACKER, 2, ANIM_DEF_PARTNER, 0x0, 0x10
waitforvisualfinish
end
ClangorousSoulblazeEnergySwirl:
@@ -34742,7 +34731,7 @@ gBattleAnimMove_GMaxTerror::
gBattleAnimMove_MaxPhantasm::
createvisualtask AnimTask_DynamaxGrowth, 0x5, 0x1, 0x1
waitforvisualfinish
- goto gBattleAnimMove_PhantomForce
+ goto gBattleAnimMove_ShadowBall
end
gBattleAnimMove_GMaxGravitas::
diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s
index 19328b7189..6d6dfe7b9c 100644
--- a/data/battle_scripts_1.s
+++ b/data/battle_scripts_1.s
@@ -26,7 +26,7 @@ BattleScript_DamageToQuarterTargetHP::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
damagetoquartertargethp
goto BattleScript_HitFromAtkAnimation
@@ -134,7 +134,11 @@ BattleScript_EffectTidyUp::
pause B_WAIT_TIME_MED
ppreduce
waitstate
+ saveattacker
+ savetarget
trytidyup FALSE, BattleScript_EffectTidyUpDoMoveAnimation
+ restoreattacker
+ restoretarget
goto BattleScript_EffectDragonDanceFromStatUp
BattleScript_EffectTidyUpDoMoveAnimation::
@@ -143,6 +147,8 @@ BattleScript_EffectTidyUpDoMoveAnimation::
trytidyup TRUE, NULL
printstring STRINGID_TIDYINGUPCOMPLETE
waitmessage B_WAIT_TIME_LONG
+ restoreattacker
+ restoretarget
goto BattleScript_EffectDragonDanceFromStatUp
BattleScript_EffectUpperHand::
@@ -205,7 +211,7 @@ BattleScript_FilletAwayTrySpeed::
printfromtable gStatUpStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_FilletAwayEnd::
- bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ clearmoveresultflags MOVE_RESULT_NO_EFFECT
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
goto BattleScript_MoveEnd
@@ -238,7 +244,7 @@ BattleScript_EffectDoodle_AfterCopy:
BattleScript_EffectGlaiveRush::
call BattleScript_EffectHit_Ret
- jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_TryFaintMon
+ jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_TryFaintMon
setglaiverush
goto BattleScript_TryFaintMon
@@ -298,12 +304,20 @@ BattleScript_CheckPrimalWeather:
jumpifhalfword CMP_COMMON_BITS, gBattleWeather, B_WEATHER_STRONG_WINDS, BattleScript_MysteriousAirCurrentBlowsOn
return
+BattleScript_MoveSwitchPursuit:
+ jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_MoveSwitchEnd
+ jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_MoveSwitchEnd
+ printstring STRINGID_PKMNWENTBACK
+ waitmessage B_WAIT_TIME_SHORT
+ jumpifnopursuitswitchdmg BattleScript_MoveSwitchOpenPartyScreen
+ end
+
BattleScript_MoveSwitch:
jumpifbattletype BATTLE_TYPE_ARENA, BattleScript_MoveSwitchEnd
jumpifcantswitch SWITCH_IGNORE_ESCAPE_PREVENTION | BS_ATTACKER, BattleScript_MoveSwitchEnd
printstring STRINGID_PKMNWENTBACK
waitmessage B_WAIT_TIME_SHORT
-BattleScript_MoveSwitchOpenPartyScreen:
+BattleScript_MoveSwitchOpenPartyScreen::
openpartyscreen BS_ATTACKER, BattleScript_MoveSwitchEnd
switchoutabilities BS_ATTACKER
waitstate
@@ -390,16 +404,10 @@ BattleScript_EffectHit_Pledge::
tryfaintmon BS_TARGET
return
-BattleScript_EffectSaltCure::
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- jumpiffainted BS_TARGET, TRUE, BattleScript_EffectSaltCure_End
- jumpifsubstituteblocks BattleScript_EffectSaltCure_End
- applysaltcure BS_TARGET
+BattleScript_MoveEffectSaltCure::
printstring STRINGID_TARGETISBEINGSALTCURED
waitmessage B_WAIT_TIME_LONG
-BattleScript_EffectSaltCure_End:
- goto BattleScript_MoveEnd
+ return
BattleScript_SaltCureExtraDamage::
playanimation BS_TARGET, B_ANIM_SALT_CURE_DAMAGE, NULL
@@ -407,13 +415,13 @@ BattleScript_SaltCureExtraDamage::
call BattleScript_HurtTarget_NoString
printstring STRINGID_TARGETISHURTBYSALTCURE
waitmessage B_WAIT_TIME_LONG
+ tryfaintmon BS_TARGET
end2
BattleScript_HurtTarget_NoString:
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
- tryfaintmon BS_TARGET
return
BattleScript_EffectCorrosiveGas::
@@ -434,7 +442,7 @@ BattleScript_EffectCorrosiveGas::
BattleScript_CorrosiveGasFail:
pause B_WAIT_TIME_SHORT
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
printstring STRINGID_NOEFFECTONTARGET
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -443,7 +451,7 @@ BattleScript_EffectTakeHeart::
attackcanceler
attackstring
ppreduce
- cureifburnedparalysedorpoisoned BattleScript_CalmMindTryToRaiseStats
+ curestatuswithmove BattleScript_CalmMindTryToRaiseStats
attackanimation
waitanimation
updatestatusicon BS_ATTACKER
@@ -717,7 +725,7 @@ BattleScript_SkyDropFlyingType:
goto BattleScript_MoveEnd
BattleScript_SkyDropChangedTarget:
pause B_WAIT_TIME_SHORT
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
resultmessage
waitmessage B_WAIT_TIME_LONG
makevisible BS_ATTACKER
@@ -864,7 +872,7 @@ BattleScript_EffectOctolock::
goto BattleScript_MoveEnd
BattleScript_OctolockEndTurn::
- playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE
+ playstatchangeanimation BS_TARGET, BIT_DEF | BIT_SPDEF, STAT_CHANGE_NEGATIVE
setstatchanger STAT_DEF, 1, TRUE
statbuffchange STAT_CHANGE_ALLOW_PTR | STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_OctolockTryLowerSpDef
printfromtable gStatDownStringIds
@@ -943,13 +951,10 @@ BattleScript_HyperspaceFuryRemoveProtect::
waitmessage B_WAIT_TIME_LONG
return
-BattleScript_EffectPlasmaFists::
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- orword gFieldStatuses, STATUS_FIELD_ION_DELUGE
+BattleScript_MoveEffectIonDeluge::
printstring STRINGID_IONDELUGEON
waitmessage B_WAIT_TIME_LONG
- goto BattleScript_MoveEnd
+ return
BattleScript_EffectSparklySwirl::
call BattleScript_EffectHit_Ret
@@ -960,41 +965,25 @@ BattleScript_EffectSparklySwirl::
waitstate
goto BattleScript_MoveEnd
-BattleScript_EffectFreezyFrost::
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- normalisebuffs
+BattleScript_MoveEffectHaze::
printstring STRINGID_STATCHANGESGONE
waitmessage B_WAIT_TIME_LONG
- goto BattleScript_MoveEnd
+ return
-BattleScript_EffectSappySeed::
- jumpifstatus3 BS_TARGET, STATUS3_LEECHSEED, BattleScript_EffectHit
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- jumpifhasnohp BS_TARGET, BattleScript_MoveEnd
- setseeded
- printfromtable gLeechSeedStringIds
+BattleScript_MoveEffectLeechSeed::
+ printstring STRINGID_PKMNSEEDED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
-BattleScript_EffectBaddyBad::
- jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_REFLECT, BattleScript_EffectHit
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- setreflect
+BattleScript_MoveEffectReflect::
printfromtable gReflectLightScreenSafeguardStringIds
waitmessage B_WAIT_TIME_LONG
- goto BattleScript_MoveEnd
+ return
-BattleScript_EffectGlitzyGlow::
- jumpifsideaffecting BS_ATTACKER, SIDE_STATUS_LIGHTSCREEN, BattleScript_EffectHit
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- setlightscreen
+BattleScript_MoveEffectLightScreen::
printfromtable gReflectLightScreenSafeguardStringIds
waitmessage B_WAIT_TIME_LONG
- goto BattleScript_MoveEnd
+ return
BattleScript_EffectStuffCheeks::
attackcanceler
@@ -1212,7 +1201,6 @@ BattleScript_StrengthSapLower:
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
- goto BattleScript_StrengthSapHp
@ Drain HP without lowering a stat
BattleScript_StrengthSapHp:
jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_StrengthSapManipulateDmg
@@ -1343,7 +1331,7 @@ BattleScript_EffectPartingShotTrySpAtk:
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectPartingShotSwitch:
moveendall
- goto BattleScript_MoveSwitch
+ goto BattleScript_MoveSwitchPursuit
BattleScript_EffectPowder::
attackcanceler
@@ -1639,7 +1627,7 @@ BattleScript_EffectPsychoShift::
BattleScript_EffectPsychoShiftCanWork:
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
jumpifsafeguard BattleScript_SafeguardProtected
- trypsychoshift BattleScript_ButItFailed
+ trypsychoshift BattleScript_ButItFailed, BattleScript_SleepClauseBlocked
attackanimation
waitanimation
copybyte gEffectBattler, gBattlerTarget
@@ -1797,7 +1785,7 @@ BattleScript_EffectFinalGambit::
ppreduce
critcalc
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
dmgtocurrattackerhp
adjustdamage
attackanimation
@@ -1809,13 +1797,13 @@ BattleScript_EffectFinalGambit::
datahpupdate BS_TARGET
resultmessage
waitmessage B_WAIT_TIME_LONG
- dmgtocurrattackerhp
- healthbarupdate BS_ATTACKER
- datahpupdate BS_ATTACKER
setadditionaleffects
- tryfaintmon BS_ATTACKER
tryfaintmon BS_TARGET
jumpifmovehadnoeffect BattleScript_MoveEnd
+ setatkhptozero
+ healthbarupdate BS_ATTACKER
+ datahpupdate BS_ATTACKER
+ tryfaintmon BS_ATTACKER
goto BattleScript_MoveEnd
BattleScript_EffectHitSwitchTarget::
@@ -2384,7 +2372,7 @@ BattleScript_EffectMetalBurst::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -2401,7 +2389,6 @@ BattleScript_EffectHealingWish::
storehealingwish BS_ATTACKER
.if B_HEALING_WISH_SWITCH <= GEN_4
openpartyscreen BS_ATTACKER, BattleScript_EffectHealingWishEnd
- switchoutabilities BS_ATTACKER
waitstate
switchhandleorder BS_ATTACKER, 2
returnatktoball
@@ -2742,9 +2729,9 @@ BattleScript_GravityLoopDrop:
printstring STRINGID_GRAVITYGROUNDING
waitmessage B_WAIT_TIME_LONG
BattleScript_GravityLoopEnd:
- moveendto MOVEEND_NEXT_TARGET
+ moveendcase MOVEEND_TARGET_VISIBLE
jumpifnexttargetvalid BattleScript_GravityLoop
- end
+ goto BattleScript_MoveEnd
BattleScript_EffectRoost::
attackcanceler
@@ -2786,7 +2773,11 @@ BattleScript_EffectHitEscape::
jumpifbattleend BattleScript_HitEscapeEnd
jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_HitEscapeEnd
jumpifemergencyexited BS_TARGET, BattleScript_HitEscapeEnd
- goto BattleScript_MoveSwitch
+ jumpiffainted BS_TARGET, FALSE, BattleScript_HitEscapeSwitch
+ setbyte sGIVEEXP_STATE, 0
+ getexp BS_TARGET
+BattleScript_HitEscapeSwitch:
+ goto BattleScript_MoveSwitchPursuit
BattleScript_HitEscapeEnd:
end
@@ -2860,7 +2851,7 @@ BattleScript_EffectNaturalGiftEnd:
goto BattleScript_MoveEnd
BattleScript_MakeMoveMissed::
- orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ setmoveresultflags MOVE_RESULT_MISSED
BattleScript_PrintMoveMissed::
attackstring
ppreduce
@@ -2893,6 +2884,7 @@ BattleScript_EffectSleep::
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed
+ jumpifsleepclause BattleScript_SleepClauseBlocked
jumpifterrainaffected BS_TARGET, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
@@ -2912,14 +2904,14 @@ BattleScript_ElectricTerrainPrevents::
pause B_WAIT_TIME_SHORT
printstring STRINGID_ELECTRICTERRAINPREVENTS
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_MistyTerrainPrevents::
pause B_WAIT_TIME_SHORT
printstring STRINGID_MISTYTERRAINPREVENTS
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_FlowerVeilProtectsRet::
@@ -2931,7 +2923,7 @@ BattleScript_FlowerVeilProtectsRet::
BattleScript_FlowerVeilProtects:
call BattleScript_FlowerVeilProtectsRet
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_SweetVeilProtectsRet::
@@ -2943,7 +2935,7 @@ BattleScript_SweetVeilProtectsRet::
BattleScript_SweetVeilProtects:
call BattleScript_SweetVeilProtectsRet
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_AromaVeilProtectsRet::
@@ -2955,7 +2947,7 @@ BattleScript_AromaVeilProtectsRet::
BattleScript_AromaVeilProtects:
call BattleScript_AromaVeilProtectsRet
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_PastelVeilProtectsRet::
@@ -2967,7 +2959,7 @@ BattleScript_PastelVeilProtectsRet::
BattleScript_PastelVeilProtects:
call BattleScript_PastelVeilProtectsRet
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_AbilityProtectsDoesntAffectRet::
@@ -2979,7 +2971,7 @@ BattleScript_AbilityProtectsDoesntAffectRet::
BattleScript_AbilityProtectsDoesntAffect:
call BattleScript_AbilityProtectsDoesntAffectRet
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_InsomniaProtects:
@@ -2987,7 +2979,7 @@ BattleScript_InsomniaProtects:
call BattleScript_AbilityPopUp
printstring STRINGID_PKMNSTAYEDAWAKEUSING
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_AlreadyAsleep::
@@ -2995,47 +2987,35 @@ BattleScript_AlreadyAsleep::
pause B_WAIT_TIME_SHORT
printstring STRINGID_PKMNALREADYASLEEP
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_WasntAffected::
pause B_WAIT_TIME_SHORT
printstring STRINGID_PKMNWASNTAFFECTED
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_CantMakeAsleep::
pause B_WAIT_TIME_SHORT
printfromtable gUproarAwakeStringIds
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
-BattleScript_EffectAbsorb::
- call BattleScript_EffectHit_Ret
- jumpifstatus3 BS_ATTACKER, STATUS3_HEAL_BLOCK, BattleScript_AbsorbHealBlock
- setdrainedhp
- manipulatedamage DMG_BIG_ROOT
- orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
- jumpifability BS_TARGET, ABILITY_LIQUID_OOZE, BattleScript_AbsorbLiquidOoze
- setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB
- goto BattleScript_AbsorbUpdateHp
-BattleScript_AbsorbLiquidOoze::
+BattleScript_EffectAbsorbLiquidOoze::
call BattleScript_AbilityPopUpTarget
- manipulatedamage DMG_CHANGE_SIGN
- setbyte cMULTISTRING_CHOOSER, B_MSG_ABSORB_OOZE
-BattleScript_AbsorbUpdateHp::
- healthbarupdate BS_ATTACKER
+ goto BattleScript_EffectAbsorb
+
+BattleScript_EffectAbsorb::
+ absorbhealthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
- jumpifmovehadnoeffect BattleScript_AbsorbTryFainting
printfromtable gAbsorbDrainStringIds
waitmessage B_WAIT_TIME_LONG
-BattleScript_AbsorbTryFainting::
tryfaintmon BS_ATTACKER
-BattleScript_AbsorbHealBlock::
- tryfaintmon BS_TARGET
- goto BattleScript_MoveEnd
+ bicword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_PASSIVE_DAMAGE
+ return
BattleScript_EffectExplosion::
attackcanceler
@@ -3106,7 +3086,7 @@ BattleScript_EffectMirrorMove::
pause B_WAIT_TIME_LONG
trymirrormove
ppreduce
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
printstring STRINGID_MIRRORMOVEFAILED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -3427,7 +3407,7 @@ BattleScript_EffectOHKO::
attackcanceler
attackstring
ppreduce
- accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
+ accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
typecalc
jumpifmovehadnoeffect BattleScript_HitFromAtkAnimation
tryKO BattleScript_KOFail
@@ -3445,7 +3425,7 @@ BattleScript_EffectSuperFang::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
damagetohalftargethp
goto BattleScript_HitFromAtkAnimation
@@ -3454,7 +3434,7 @@ BattleScript_EffectRecoilIfMiss::
accuracycheck BattleScript_MoveMissedDoDamage, ACC_CURR_MOVE
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
typecalc
- jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveMissedDoDamage
+ jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveMissedDoDamage
.endif
goto BattleScript_HitFromAtkString
BattleScript_MoveMissedDoDamage::
@@ -3465,7 +3445,7 @@ BattleScript_MoveMissedDoDamage::
resultmessage
waitmessage B_WAIT_TIME_LONG
.if B_CRASH_IF_TARGET_IMMUNE < GEN_4
- jumpifhalfword CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd
+ jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd
.endif
moveendcase MOVEEND_PROTECT_LIKE_EFFECT @ Spiky Shield's damage happens before recoil.
jumpifhasnohp BS_ATTACKER, BattleScript_MoveEnd
@@ -3480,18 +3460,18 @@ BattleScript_MoveMissedDoDamage::
manipulatedamage DMG_RECOIL_FROM_MISS
.endif
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
- bichalfword gMoveResultFlags, MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
+ clearmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
.else
- bichalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ clearmoveresultflags MOVE_RESULT_MISSED
.endif
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
tryfaintmon BS_ATTACKER
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
- orhalfword gMoveResultFlags, MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
+ setmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
.else
- orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ setmoveresultflags MOVE_RESULT_MISSED
.endif
goto BattleScript_MoveEnd
@@ -3678,7 +3658,7 @@ BattleScript_EffectParalyze::
jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
jumpifsafeguard BattleScript_SafeguardProtected
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
attackanimation
waitanimation
seteffectprimary MOVE_EFFECT_PARALYSIS
@@ -3882,26 +3862,39 @@ BattleScript_EffectDoNothing::
attackcanceler
attackstring
ppreduce
- jumpifmove MOVE_HOLD_HANDS, BattleScript_EffectHoldHands
attackanimation
waitanimation
- jumpifmove MOVE_CELEBRATE, BattleScript_EffectCelebrate
- jumpifmove MOVE_HAPPY_HOUR, BattleScript_EffectHappyHour
incrementgamestat GAME_STAT_USED_SPLASH
printstring STRINGID_BUTNOTHINGHAPPENED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
-BattleScript_EffectHoldHands:
+
+BattleScript_EffectHoldHands::
+ attackcanceler
+ attackstring
+ ppreduce
jumpifsideaffecting BS_TARGET, SIDE_STATUS_CRAFTY_SHIELD, BattleScript_ButItFailed
jumpifbyteequal gBattlerTarget, gBattlerAttacker, BattleScript_ButItFailed
attackanimation
waitanimation
goto BattleScript_MoveEnd
-BattleScript_EffectCelebrate:
+
+BattleScript_EffectCelebrate::
+ attackcanceler
+ attackstring
+ ppreduce
+ attackanimation
+ waitanimation
printstring STRINGID_CELEBRATEMESSAGE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
-BattleScript_EffectHappyHour:
+
+BattleScript_EffectHappyHour::
+ attackcanceler
+ attackstring
+ ppreduce
+ attackanimation
+ waitanimation
seteffectprimary MOVE_EFFECT_HAPPY_HOUR
goto BattleScript_MoveEnd
@@ -3924,7 +3917,7 @@ BattleScript_EffectLevelDamage::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
dmgtolevel
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -3935,7 +3928,7 @@ BattleScript_EffectPsywave::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
psywavedamageeffect
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -3947,7 +3940,7 @@ BattleScript_EffectCounter::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -3975,7 +3968,6 @@ BattleScript_EffectPainSplit::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
- copyword gBattleMoveDamage, sPAINSPLIT_HP
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
printstring STRINGID_SHAREDPAIN
@@ -4063,20 +4055,17 @@ BattleScript_EffectDestinyBond::
attackcanceler
attackstring
ppreduce
- setdestinybond
+ trysetdestinybond BattleScript_ButItFailed
attackanimation
waitanimation
printstring STRINGID_PKMNTRYINGTOTAKEFOE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
-BattleScript_EffectEerieSpell::
- call BattleScript_EffectHit_Ret
- tryfaintmon BS_TARGET
- eeriespellppreduce BattleScript_MoveEnd
+BattleScript_MoveEffectEerieSpell::
printstring STRINGID_PKMNREDUCEDPP
waitmessage B_WAIT_TIME_LONG
- goto BattleScript_MoveEnd
+ return
BattleScript_EffectSpite::
attackcanceler
@@ -4160,6 +4149,7 @@ BattleScript_EffectMinimize::
BattleScript_EffectCurse::
jumpiftype BS_ATTACKER, TYPE_GHOST, BattleScript_GhostCurse
attackcanceler
+ jumpiftype BS_ATTACKER, TYPE_GHOST, BattleScript_DoGhostCurse
attackstring
ppreduce
jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_SPEED, MIN_STAT_STAGE, BattleScript_CurseTrySpeed
@@ -4429,7 +4419,7 @@ BattleScript_EffectFixedDamageArg::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
setargtobattledamage
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -4574,7 +4564,7 @@ BattleScript_EffectMirrorCoat::
attackstring
ppreduce
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE
+ clearmoveresultflags MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -4630,7 +4620,7 @@ BattleScript_BeatUpLoop::
trydobeatup BattleScript_BeatUpEnd, BattleScript_ButItFailed
printstring STRINGID_PKMNATTACK
critcalc
- jumpifbyte CMP_NOT_EQUAL, gIsCriticalHit, TRUE, BattleScript_BeatUpAttack
+ jumpifcriticalhit BattleScript_BeatUpAttack
manipulatedamage DMG_DOUBLED
BattleScript_BeatUpAttack::
adjustdamage
@@ -4699,7 +4689,7 @@ BattleScript_FailedFromPpReduce::
ppreduce
BattleScript_ButItFailed::
pause B_WAIT_TIME_SHORT
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -4709,7 +4699,7 @@ BattleScript_RestoreAttackerButItFailed:
BattleScript_NotAffected::
pause B_WAIT_TIME_SHORT
- orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
+ setmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -4717,7 +4707,7 @@ BattleScript_NotAffected::
BattleScript_NotAffectedAbilityPopUp::
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUpTarget
- orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
+ setmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE
resultmessage
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -4787,7 +4777,6 @@ BattleScript_EffectSpitUp::
attackstring
ppreduce
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
- setbyte gIsCriticalHit, FALSE
damagecalc
adjustdamage
stockpiletobasedamage BattleScript_SpitUpFail
@@ -5121,7 +5110,7 @@ BattleScript_EffectBrickBreak::
damagecalc
adjustdamage
jumpifbyte CMP_EQUAL, sB_ANIM_TURN, 0, BattleScript_BrickBreakAnim
- bichalfword gMoveResultFlags, MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
+ clearmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
BattleScript_BrickBreakAnim::
attackanimation
waitanimation
@@ -5154,6 +5143,7 @@ BattleScript_EffectYawn::
jumpifflowerveil BattleScript_FlowerVeilProtects
jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect
+ jumpifsleepclause BattleScript_SleepClauseBlocked
jumpifsubstituteblocks BattleScript_ButItFailed
jumpifsafeguard BattleScript_SafeguardProtected
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
@@ -5179,12 +5169,10 @@ BattleScript_EffectEndeavor::
attackstring
ppreduce
setdamagetohealthdifference BattleScript_ButItFailed
- copyword gHpDealt, gBattleMoveDamage
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
typecalc
jumpifmovehadnoeffect BattleScript_HitFromAtkAnimation
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
- copyword gBattleMoveDamage, gHpDealt
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
adjustdamage
goto BattleScript_HitFromAtkAnimation
@@ -5230,7 +5218,7 @@ BattleScript_EffectRefresh::
attackcanceler
attackstring
ppreduce
- cureifburnedparalysedorpoisoned BattleScript_ButItFailed
+ curestatuswithmove BattleScript_ButItFailed
attackanimation
waitanimation
printstring STRINGID_PKMNSTATUSNORMAL
@@ -5308,7 +5296,7 @@ BattleScript_TickleEnd::
BattleScript_CantLowerMultipleStats::
pause B_WAIT_TIME_SHORT
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
printstring STRINGID_STATSWONTDECREASE2
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -5392,7 +5380,7 @@ BattleScript_CalmMindEnd::
BattleScript_CantRaiseMultipleStats::
pause B_WAIT_TIME_SHORT
- orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
printstring STRINGID_STATSWONTINCREASE2
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@@ -5767,25 +5755,14 @@ BattleScript_PrintFullBox::
BattleScript_ActionSwitch::
hpthresholds2 BS_ATTACKER
- saveattacker
printstring STRINGID_RETURNMON
- jumpifbattletype BATTLE_TYPE_DOUBLE, BattleScript_PursuitSwitchDmgSetMultihit
- setmultihit 1
- goto BattleScript_PursuitSwitchDmgLoop
-BattleScript_PursuitSwitchDmgSetMultihit::
- setmultihit 2
-BattleScript_PursuitSwitchDmgLoop::
jumpifnopursuitswitchdmg BattleScript_DoSwitchOut
- swapattackerwithtarget
- trysetdestinybondtohappen
- call BattleScript_PursuitDmgOnSwitchOut
- swapattackerwithtarget
+ end2
+
BattleScript_DoSwitchOut::
- decrementmultihit BattleScript_PursuitSwitchDmgLoop
switchoutabilities BS_ATTACKER
updatedynamax
waitstate
- restoreattacker
returnatktoball
waitstate
drawpartystatussummary BS_ATTACKER
@@ -5804,34 +5781,6 @@ BattleScript_DoSwitchOut::
moveendcase MOVEEND_MIRROR_MOVE
end2
-BattleScript_PursuitDmgOnSwitchOut::
- pause B_WAIT_TIME_SHORT
- orword gHitMarker, HITMARKER_OBEYS
- attackstring
- ppreduce
- critcalc
- damagecalc
- adjustdamage
- attackanimation
- waitanimation
- effectivenesssound
- hitanimation BS_TARGET
- waitstate
- healthbarupdate BS_TARGET
- datahpupdate BS_TARGET
- critmessage
- waitmessage B_WAIT_TIME_LONG
- resultmessage
- waitmessage B_WAIT_TIME_LONG
- tryfaintmon BS_TARGET
- moveendfromto MOVEEND_ABILITIES, MOVEEND_ATTACKER_INVISIBLE @ MOVEEND_CHOICE_MOVE has to be included
- jumpiffainted BS_TARGET, FALSE, BattleScript_PursuitDmgOnSwitchOutRet
- setbyte sGIVEEXP_STATE, 0
- getexp BS_TARGET
-BattleScript_PursuitDmgOnSwitchOutRet:
- bicword gHitMarker, HITMARKER_OBEYS
- return
-
BattleScript_Pausex20::
pause B_WAIT_TIME_SHORT
return
@@ -5950,8 +5899,7 @@ BattleScript_OverworldStatusStarts::
BattleScript_OverworldStatusStarts_TryActivations:
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TRICK_ROOM, BattleScript_TryRoomServiceLoop
- jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND_PLAYER, BattleScript_TryTailwindAbilitiesLoop
- jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND_OPPONENT, BattleScript_TryTailwindAbilitiesLoop
+ jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_SET_TAILWIND, BattleScript_TryTailwindAbilitiesLoop
return
BattleScript_OverworldWeatherStarts::
@@ -6044,33 +5992,32 @@ BattleScript_SafeguardEnds::
waitmessage B_WAIT_TIME_LONG
end2
-BattleScript_LeechSeedTurnDrain::
- playanimation BS_ATTACKER, B_ANIM_LEECH_SEED_DRAIN, sB_ANIM_ARG1
- orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
- healthbarupdate BS_ATTACKER
- datahpupdate BS_ATTACKER
- copyword gBattleMoveDamage, gHpDealt
- jumpifability BS_ATTACKER, ABILITY_LIQUID_OOZE, BattleScript_LeechSeedTurnPrintLiquidOoze
- setbyte cMULTISTRING_CHOOSER, B_MSG_LEECH_SEED_DRAIN
- jumpifstatus3 BS_TARGET, STATUS3_HEAL_BLOCK, BattleScript_LeechSeedHealBlock
- manipulatedamage DMG_BIG_ROOT
- goto BattleScript_LeechSeedTurnPrintAndUpdateHp
-BattleScript_LeechSeedTurnPrintLiquidOoze::
+BattleScript_LeechSeedTurnDrainLiquidOoze::
+ call BattleScript_LeechSeedTurnDrain
copybyte gBattlerAbility, gBattlerAttacker
call BattleScript_AbilityPopUp
- setbyte cMULTISTRING_CHOOSER, B_MSG_LEECH_SEED_OOZE
-BattleScript_LeechSeedTurnPrintAndUpdateHp::
- orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
+ goto BattleScript_LeechSeedTurnDrainGainHp
+
+BattleScript_LeechSeedTurnDrainHealBlock::
+ call BattleScript_LeechSeedTurnDrain
+ end2
+
+BattleScript_LeechSeedTurnDrainRecovery::
+ call BattleScript_LeechSeedTurnDrain
+BattleScript_LeechSeedTurnDrainGainHp:
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
printfromtable gLeechSeedStringIds
waitmessage B_WAIT_TIME_LONG
- tryfaintmon BS_ATTACKER
tryfaintmon BS_TARGET
end2
-BattleScript_LeechSeedHealBlock:
- setword gBattleMoveDamage, 0
- goto BattleScript_LeechSeedTurnPrintAndUpdateHp
+
+BattleScript_LeechSeedTurnDrain:
+ playanimation BS_ATTACKER, B_ANIM_LEECH_SEED_DRAIN, sB_ANIM_ARG1
+ healthbarupdate BS_ATTACKER
+ datahpupdate BS_ATTACKER
+ tryfaintmon BS_ATTACKER
+ return
BattleScript_BideStoringEnergy::
printstring STRINGID_PKMNSTORINGENERGY
@@ -6084,8 +6031,8 @@ BattleScript_BideAttack::
waitmessage B_WAIT_TIME_LONG
accuracycheck BattleScript_MoveMissed, ACC_CURR_MOVE
typecalc
- bichalfword gMoveResultFlags, MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
- copyword gBattleMoveDamage, sBIDE_DMG
+ clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE
+ copybidedmg
adjustdamage
setbyte sB_ANIM_TURN, 1
attackanimation
@@ -6404,18 +6351,14 @@ BattleScript_GulpMissileGulping::
datahpupdate BS_ATTACKER
tryfaintmon BS_ATTACKER
jumpiffainted BS_ATTACKER, TRUE, BattleScript_GulpMissileNoSecondEffectGulping
- jumpifholdeffect BS_ATTACKER, HOLD_EFFECT_CLEAR_AMULET, BattleScript_GulpMissileNoSecondEffectGulping
- jumpifability BS_ATTACKER, ABILITY_CLEAR_BODY, BattleScript_GulpMissileNoSecondEffectGulping
- jumpifability BS_ATTACKER, ABILITY_FULL_METAL_BODY, BattleScript_GulpMissileNoSecondEffectGulping
- jumpifability BS_ATTACKER, ABILITY_WHITE_SMOKE, BattleScript_GulpMissileNoSecondEffectGulping
- jumpifflowerveilattacker BattleScript_GulpMissileNoSecondEffectGulping
BattleScript_GulpMissileNoDmgGulping:
handleformchange BS_TARGET, 0
playanimation BS_TARGET, B_ANIM_FORM_CHANGE
waitanimation
swapattackerwithtarget @ to make gStatDownStringIds down below print the right battler
setstatchanger STAT_DEF, 1, TRUE
- statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_GulpMissileGorgingTargetDefenseCantGoLower
+ statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_GulpMissileGulpingEnd
+ jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_GulpMissileGulpingTargetDefenseCantGoLower
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatDownStringIds
@@ -6427,9 +6370,11 @@ BattleScript_GulpMissileNoSecondEffectGulping:
playanimation BS_TARGET, B_ANIM_FORM_CHANGE
waitanimation
return
-BattleScript_GulpMissileGorgingTargetDefenseCantGoLower:
+BattleScript_GulpMissileGulpingTargetDefenseCantGoLower:
printstring STRINGID_STATSWONTDECREASE
waitmessage B_WAIT_TIME_LONG
+BattleScript_GulpMissileGulpingEnd:
+ swapattackerwithtarget @ restore the battlers, just in case
return
BattleScript_SeedSowerActivates::
@@ -6641,14 +6586,14 @@ BattleScript_FutureAttackEnd::
moveendcase MOVEEND_RAGE
moveendcase MOVEEND_ABILITIES
moveendfromto MOVEEND_ITEM_EFFECTS_ALL, MOVEEND_UPDATE_LAST_MOVES
- setbyte gMoveResultFlags, 0
+ setmoveresultflags 0
end2
BattleScript_FutureAttackMiss::
pause B_WAIT_TIME_SHORT
- sethword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
resultmessage
waitmessage B_WAIT_TIME_LONG
- sethword gMoveResultFlags, 0
+ setmoveresultflags 0
end2
BattleScript_NoMovesLeft::
@@ -6773,7 +6718,7 @@ BattleScript_WishComesTrue::
playanimation BS_TARGET, B_ANIM_WISH_HEAL
printstring STRINGID_PKMNWISHCAMETRUE
waitmessage B_WAIT_TIME_LONG
- orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
+ orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
healthbarupdate BS_TARGET
datahpupdate BS_TARGET
printstring STRINGID_PKMNREGAINEDHEALTH
@@ -6922,7 +6867,7 @@ BattleScript_MagicCoatPrankster::
waitmessage B_WAIT_TIME_LONG
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ setmoveresultflags MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd
BattleScript_SnatchedMove::
@@ -6971,7 +6916,6 @@ BattleScript_MegaEvolution::
printstring STRINGID_MEGAEVOREACTING
BattleScript_MegaEvolutionAfterString:
waitmessage B_WAIT_TIME_LONG
- setbyte gIsCriticalHit, 0
handlemegaevo BS_SCRIPTING, 0
playanimation BS_SCRIPTING, B_ANIM_MEGA_EVOLUTION
waitanimation
@@ -6988,33 +6932,22 @@ BattleScript_WishMegaEvolution::
goto BattleScript_MegaEvolutionAfterString
BattleScript_PrimalReversion::
- call BattleScript_PrimalReversionRet
- end3
-
-BattleScript_PrimalReversionRestoreAttacker::
- call BattleScript_PrimalReversionRet
- copybyte gBattlerAttacker, sSAVED_BATTLER
- end3
-
-BattleScript_PrimalReversionRet::
flushtextbox
- setbyte gIsCriticalHit, 0
- handleprimalreversion BS_ATTACKER, 0
- handleprimalreversion BS_ATTACKER, 1
- playanimation BS_ATTACKER, B_ANIM_PRIMAL_REVERSION
+ handleprimalreversion BS_SCRIPTING, 0
+ handleprimalreversion BS_SCRIPTING, 1
+ playanimation BS_SCRIPTING, B_ANIM_PRIMAL_REVERSION
waitanimation
- handleprimalreversion BS_ATTACKER, 2
+ handleprimalreversion BS_SCRIPTING, 2
printstring STRINGID_PKMNREVERTEDTOPRIMAL
waitmessage B_WAIT_TIME_LONG
- switchinabilities BS_ATTACKER
- return
+ switchinabilities BS_SCRIPTING
+ end3
BattleScript_UltraBurst::
flushtextbox
trytrainerslidezmovemsg
printstring STRINGID_ULTRABURSTREACTING
waitmessage B_WAIT_TIME_LONG
- setbyte gIsCriticalHit, 0
handleultraburst BS_SCRIPTING, 0
playanimation BS_SCRIPTING, B_ANIM_ULTRA_BURST
waitanimation
@@ -7169,7 +7102,8 @@ BattleScript_CottonDownLoop:
jumpiffainted BS_TARGET, TRUE, BattleScript_CottonDownLoopIncrement
setstatchanger STAT_SPEED, 1, TRUE
jumpifbyteequal gBattlerTarget, gEffectBattler, BattleScript_CottonDownLoopIncrement
- statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED, BattleScript_CottonDownTargetSpeedCantGoLower
+ statbuffchange STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_CottonDownLoopIncrement
+ jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_CottonDownTargetSpeedCantGoLower
setgraphicalstatchangevalues
playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1
printfromtable gStatDownStringIds
@@ -7321,7 +7255,7 @@ BattleScript_PowderMoveNoEffectPrint:
BattleScript_PowderMoveNoEffectWaitMsg:
waitmessage B_WAIT_TIME_LONG
cancelmultiturnmoves BS_ATTACKER
- sethword gMoveResultFlags, MOVE_RESULT_FAILED
+ setmoveresultflags MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_MoveUsedFlinched::
@@ -7625,13 +7559,8 @@ BattleScript_AbilityPopUp:
return
BattleScript_AbilityPopUpScripting:
- .if B_ABILITY_POP_UP == TRUE
- showabilitypopup BS_SCRIPTING
- pause 40
- .endif
- recordability BS_SCRIPTING
- sethword sABILITY_OVERWRITE, 0
- return
+ copybyte gBattlerAbility, sBATTLER
+ goto BattleScript_AbilityPopUp
BattleScript_AbilityPopUpOverwriteThenNormal:
setbyte sFIXED_ABILITY_POPUP, TRUE
@@ -8253,7 +8182,7 @@ BattleScript_MoveHPDrain::
datahpupdate BS_TARGET
printstring STRINGID_PKMNRESTOREDHPUSING
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
+ setmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE
goto BattleScript_MoveEnd
BattleScript_MoveStatDrain_PPLoss::
@@ -8285,7 +8214,7 @@ BattleScript_MonMadeMoveUseless::
call BattleScript_AbilityPopUp
printstring STRINGID_PKMNSXMADEYUSELESS
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
+ setmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE
goto BattleScript_MoveEnd
BattleScript_FlashFireBoost_PPLoss::
@@ -8364,7 +8293,7 @@ BattleScript_SoundproofProtected::
call BattleScript_AbilityPopUp
printstring STRINGID_PKMNSXBLOCKSY
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE
+ setmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE
goto BattleScript_MoveEnd
BattleScript_IceFaceNullsDamage::
@@ -8403,7 +8332,6 @@ BattleScript_GrassyTerrainLoopIncrement::
addbyte gBattleCommunication, 1
jumpifbytenotequal gBattleCommunication, gBattlersCount, BattleScript_GrassyTerrainLoop
bicword gHitMarker, HITMARKER_IGNORE_BIDE | HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
- jumpifword CMP_COMMON_BITS, gFieldStatuses, STATUS_FIELD_TERRAIN_PERMANENT, BattleScript_GrassyTerrainHealEnd
BattleScript_GrassyTerrainHealEnd:
return
@@ -8413,7 +8341,7 @@ BattleScript_AbilityNoSpecificStatLoss::
printstring STRINGID_PKMNSXPREVENTSYLOSS
waitmessage B_WAIT_TIME_LONG
setbyte cMULTISTRING_CHOOSER, B_MSG_STAT_FELL_EMPTY
- orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ setmoveresultflags MOVE_RESULT_NO_EFFECT
return
BattleScript_StickyHoldActivates::
@@ -8438,7 +8366,7 @@ BattleScript_ProteanActivates::
BattleScript_TeraShellDistortingTypeMatchups::
pause B_WAIT_TIME_SHORTEST
- call BattleScript_AbilityPopUp
+ call BattleScript_AbilityPopUpScripting
printstring STRINGID_PKMNMADESHELLGLEAM
waitmessage B_WAIT_TIME_LONG
return
@@ -8523,7 +8451,7 @@ BattleScript_WeakArmorActivates::
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_FELL_EMPTY, BattleScript_WeakArmorActivatesSpeed
pause B_WAIT_TIME_SHORTEST
printfromtable gStatDownStringIds
- bichalfword gMoveResultFlags, MOVE_RESULT_MISSED @ Set by statbuffchange when stat can't be decreased
+ clearmoveresultflags MOVE_RESULT_MISSED @ Set by statbuffchange when stat can't be decreased
waitmessage B_WAIT_TIME_LONG
goto BattleScript_WeakArmorActivatesSpeed
BattleScript_WeakArmorDefAnim:
@@ -8542,7 +8470,7 @@ BattleScript_WeakArmorActivatesSpeed:
jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_ROSE_EMPTY, BattleScript_WeakArmorActivatesEnd
pause B_WAIT_TIME_SHORTEST
printstring STRINGID_TARGETSTATWONTGOHIGHER
- bichalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ clearmoveresultflags MOVE_RESULT_MISSED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_WeakArmorActivatesEnd
BattleScript_WeakArmorSpeedAnim:
@@ -8665,31 +8593,31 @@ BattleScript_RockyHelmetActivatesDmg:
BattleScript_SpikyShieldEffect::
jumpifabsent BS_ATTACKER, BattleScript_SpikyShieldRet
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
- bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ clearmoveresultflags MOVE_RESULT_NO_EFFECT
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER
printstring STRINGID_PKMNHURTSWITH
waitmessage B_WAIT_TIME_LONG
tryfaintmon BS_ATTACKER
- orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ setmoveresultflags MOVE_RESULT_MISSED
BattleScript_SpikyShieldRet::
return
BattleScript_KingsShieldEffect::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE
- bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ clearmoveresultflags MOVE_RESULT_NO_EFFECT
seteffectsecondary
copybyte sBATTLER, gBattlerTarget
copybyte gBattlerTarget, gBattlerAttacker
copybyte gBattlerAttacker, sBATTLER
- orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ setmoveresultflags MOVE_RESULT_MISSED
return
BattleScript_BanefulBunkerEffect::
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_STATUS_ABILITY_EFFECT | HITMARKER_PASSIVE_DAMAGE
- bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ clearmoveresultflags MOVE_RESULT_NO_EFFECT
seteffectsecondary
- orhalfword gMoveResultFlags, MOVE_RESULT_MISSED
+ setmoveresultflags MOVE_RESULT_MISSED
return
BattleScript_CuteCharmActivates::
@@ -8893,18 +8821,12 @@ BattleScript_GemActivates::
return
BattleScript_BerryReduceDmg::
- playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT
+ playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT
waitanimation
- setlastuseditem BS_TARGET
- printstring STRINGID_TARGETATEITEM
- waitmessage B_WAIT_TIME_LONG
- removeitem BS_TARGET
- return
-
-BattleScript_PrintBerryReduceString::
- waitmessage B_WAIT_TIME_LONG
+ setlastuseditem BS_SCRIPTING
printstring STRINGID_BERRYDMGREDUCES
waitmessage B_WAIT_TIME_LONG
+ removeitem BS_SCRIPTING
return
BattleScript_BerryCureConfusionEnd2::
@@ -9118,7 +9040,7 @@ BattleScript_BerryStatRaiseEnd2::
BattleScript_BerryStatRaiseEnd2_AbilityPopup:
call BattleScript_AbilityPopUp
BattleScript_BerryStatRaiseEnd2_Anim:
- statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_BerryStatRaiseEnd2_End
+ statbuffchange STAT_CHANGE_ALLOW_PTR | MOVE_EFFECT_AFFECTS_USER, BattleScript_BerryStatRaiseEnd2_End
setgraphicalstatchangevalues
playanimation BS_ATTACKER, B_ANIM_HELD_ITEM_EFFECT, sB_ANIM_ARG1
setbyte cMULTISTRING_CHOOSER, B_MSG_STAT_ROSE_ITEM
@@ -9532,7 +9454,7 @@ BattleScript_EffectHitSetRemoveTerrain::
accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE
attackstring
ppreduce
- jumpifargument ARG_TRY_REMOVE_TERRAIN_FAIL, BattleScript_RemoveTerrain
+ jumpifmovepropertyargument ARG_TRY_REMOVE_TERRAIN_FAIL, BattleScript_RemoveTerrain
critcalc
damagecalc
adjustdamage
@@ -9653,7 +9575,9 @@ BattleScript_EjectButtonActivates::
removeitem BS_SCRIPTING
makeinvisible BS_SCRIPTING
openpartyscreen BS_SCRIPTING, BattleScript_EjectButtonEnd
+ copybyte sSAVED_BATTLER, sBATTLER
switchoutabilities BS_SCRIPTING
+ copybyte sBATTLER, sSAVED_BATTLER
waitstate
switchhandleorder BS_SCRIPTING 0x2
returntoball BS_SCRIPTING, FALSE
@@ -9686,7 +9610,7 @@ BattleScript_DarkTypePreventsPrankster::
pause B_WAIT_TIME_SHORT
printstring STRINGID_ITDOESNTAFFECT
waitmessage B_WAIT_TIME_LONG
- orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ setmoveresultflags MOVE_RESULT_NO_EFFECT
goto BattleScript_MoveEnd
BattleScript_WellBakedBodyActivates::
@@ -9694,7 +9618,7 @@ BattleScript_WellBakedBodyActivates::
ppreduce
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUpTarget
- orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ setmoveresultflags MOVE_RESULT_NO_EFFECT
modifybattlerstatstage BS_TARGET, STAT_DEF, INCREASE, 1, BattleScript_WellBakedBodyEnd, ANIM_ON
BattleScript_WellBakedBodyEnd:
goto BattleScript_MoveEnd
@@ -9704,7 +9628,7 @@ BattleScript_WindRiderActivatesMoveEnd::
ppreduce
pause B_WAIT_TIME_SHORT
call BattleScript_AbilityPopUpTarget
- orhalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ setmoveresultflags MOVE_RESULT_NO_EFFECT
modifybattlerstatstage BS_TARGET, STAT_ATK, INCREASE, 1, BattleScript_WindRiderActivatesMoveEnd_End, ANIM_ON
BattleScript_WindRiderActivatesMoveEnd_End:
goto BattleScript_MoveEnd
@@ -9743,6 +9667,7 @@ BattleScript_PastelVeilEnd:
end3
BattleScript_NeutralizingGasExits::
+ saveattacker
savetarget
pause B_WAIT_TIME_SHORT
printstring STRINGID_NEUTRALIZINGGASOVER
@@ -9752,6 +9677,7 @@ BattleScript_NeutralizingGasExitsLoop:
switchinabilities BS_TARGET
addbyte gBattlerTarget, 1
jumpifbytenotequal gBattlerTarget, gBattlersCount, BattleScript_NeutralizingGasExitsLoop
+ restoreattacker
restoretarget
return
@@ -10091,6 +10017,10 @@ BattleScript_BerserkGeneRet_End:
end3
BattleScript_BoosterEnergyEnd2::
+ call BattleScript_BoosterEnergyRet
+ end2
+
+BattleScript_BoosterEnergyRet::
playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT, sB_ANIM_ARG1
call BattleScript_AbilityPopUpScripting
printstring STRINGID_BOOSTERENERGYACTIVATES
@@ -10098,7 +10028,7 @@ BattleScript_BoosterEnergyEnd2::
printstring STRINGID_STATWASHEIGHTENED
waitmessage B_WAIT_TIME_MED
removeitem BS_SCRIPTING
- end2
+ return
BattleScript_EffectSnow::
attackcanceler
@@ -10107,3 +10037,16 @@ BattleScript_EffectSnow::
call BattleScript_CheckPrimalWeather
setfieldweather ENUM_WEATHER_SNOW
goto BattleScript_MoveWeatherChange
+
+BattleScript_SleepClauseBlocked::
+ pause B_WAIT_TIME_SHORT
+ setmoveresultflags MOVE_RESULT_FAILED
+ printstring STRINGID_BLOCKEDBYSLEEPCLAUSE
+ waitmessage B_WAIT_TIME_LONG
+ goto BattleScript_MoveEnd
+
+BattleScript_SleepClausePreventsEnd::
+ pause B_WAIT_TIME_SHORT
+ printstring STRINGID_BLOCKEDBYSLEEPCLAUSE
+ waitmessage B_WAIT_TIME_LONG
+ end2
diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s
index b68a570664..aa9f1da369 100644
--- a/data/battle_scripts_2.s
+++ b/data/battle_scripts_2.s
@@ -48,7 +48,7 @@ BattleScript_UseItemMessage:
return
BattleScript_ItemRestoreHPRet:
- bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ clearmoveresultflags MOVE_RESULT_NO_EFFECT
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE
healthbarupdate BS_SCRIPTING
datahpupdate BS_SCRIPTING
@@ -69,7 +69,7 @@ BattleScript_ItemRestoreHPEnd:
BattleScript_ItemRestoreHP_Party::
jumpifbyte CMP_EQUAL, gBattleCommunication, TRUE, BattleScript_ItemRestoreHP_SendOutRevivedBattler
- bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT
+ clearmoveresultflags MOVE_RESULT_NO_EFFECT
printstring STRINGID_ITEMRESTOREDSPECIESHEALTH
waitmessage B_WAIT_TIME_LONG
return
diff --git a/data/maps/BattleFrontier_Mart/scripts.inc b/data/maps/BattleFrontier_Mart/scripts.inc
index 6afe6a0186..f118476cfe 100644
--- a/data/maps/BattleFrontier_Mart/scripts.inc
+++ b/data/maps/BattleFrontier_Mart/scripts.inc
@@ -28,9 +28,7 @@ BattleFrontier_Mart_Pokemart:
.2byte ITEM_ZINC
.2byte ITEM_CARBOS
.2byte ITEM_HP_UP
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
BattleFrontier_Mart_EventScript_OldMan::
msgbox BattleFrontier_Mart_Text_ChaperonGrandson, MSGBOX_NPC
diff --git a/data/maps/EverGrandeCity_PokemonLeague_1F/scripts.inc b/data/maps/EverGrandeCity_PokemonLeague_1F/scripts.inc
index c13e716975..37e691fa3b 100644
--- a/data/maps/EverGrandeCity_PokemonLeague_1F/scripts.inc
+++ b/data/maps/EverGrandeCity_PokemonLeague_1F/scripts.inc
@@ -45,9 +45,7 @@ EverGrandeCity_PokemonLeague_1F_Pokemart:
.2byte ITEM_FULL_HEAL
.2byte ITEM_REVIVE
.2byte ITEM_MAX_REPEL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
@ The door guards only check for FLAG_BADGE06_GET because Winonas badge is the only one that can be skipped
@ Its assumed the player has the remaining badges
diff --git a/data/maps/FallarborTown_Mart/scripts.inc b/data/maps/FallarborTown_Mart/scripts.inc
index 27c8cc1e70..507a6352d3 100644
--- a/data/maps/FallarborTown_Mart/scripts.inc
+++ b/data/maps/FallarborTown_Mart/scripts.inc
@@ -25,9 +25,7 @@ FallarborTown_Mart_Pokemart:
.2byte ITEM_X_DEFENSE
.2byte ITEM_DIRE_HIT
.2byte ITEM_GUARD_SPEC
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
FallarborTown_Mart_EventScript_Woman::
msgbox FallarborTown_Mart_Text_DecidingSkittyEvolve, MSGBOX_NPC
diff --git a/data/maps/FortreeCity_DecorationShop/scripts.inc b/data/maps/FortreeCity_DecorationShop/scripts.inc
index 4394312876..4da66f27b9 100644
--- a/data/maps/FortreeCity_DecorationShop/scripts.inc
+++ b/data/maps/FortreeCity_DecorationShop/scripts.inc
@@ -29,9 +29,7 @@ FortreeCity_DecorationShop_PokemartDecor_Desks:
.2byte DECOR_BRICK_DESK
.2byte DECOR_CAMP_DESK
.2byte DECOR_HARD_DESK
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
FortreeCity_DecorationShop_EventScript_ClerkChairs::
lock
@@ -53,9 +51,7 @@ FortreeCity_DecorationShop_PokemartDecor_Chairs:
.2byte DECOR_BRICK_CHAIR
.2byte DECOR_CAMP_CHAIR
.2byte DECOR_HARD_CHAIR
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
FortreeCity_DecorationShop_Text_MerchandiseSentToPC:
.string "Merchandise you buy here is sent to\n"
diff --git a/data/maps/FortreeCity_Mart/scripts.inc b/data/maps/FortreeCity_Mart/scripts.inc
index c37716bc85..0986e68c0c 100644
--- a/data/maps/FortreeCity_Mart/scripts.inc
+++ b/data/maps/FortreeCity_Mart/scripts.inc
@@ -23,9 +23,7 @@ FortreeCity_Mart_Pokemart:
.2byte ITEM_REVIVE
.2byte ITEM_SUPER_REPEL
.2byte ITEM_WOOD_MAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
FortreeCity_Mart_EventScript_Woman::
msgbox FortreeCity_Mart_Text_SuperRepelBetter, MSGBOX_NPC
diff --git a/data/maps/LavaridgeTown_HerbShop/scripts.inc b/data/maps/LavaridgeTown_HerbShop/scripts.inc
index dbe1b564ac..22e3851e9d 100644
--- a/data/maps/LavaridgeTown_HerbShop/scripts.inc
+++ b/data/maps/LavaridgeTown_HerbShop/scripts.inc
@@ -17,9 +17,7 @@ LavaridgeTown_HerbShop_Pokemart:
.2byte ITEM_ENERGY_ROOT
.2byte ITEM_HEAL_POWDER
.2byte ITEM_REVIVAL_HERB
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LavaridgeTown_HerbShop_EventScript_ExpertM::
msgbox LavaridgeTown_HerbShop_Text_HerbalMedicineWorksButMonWillDislike, MSGBOX_NPC
diff --git a/data/maps/LavaridgeTown_Mart/scripts.inc b/data/maps/LavaridgeTown_Mart/scripts.inc
index 001df31401..8df5d02dfc 100644
--- a/data/maps/LavaridgeTown_Mart/scripts.inc
+++ b/data/maps/LavaridgeTown_Mart/scripts.inc
@@ -22,9 +22,7 @@ LavaridgeTown_Mart_Pokemart:
.2byte ITEM_REVIVE
.2byte ITEM_SUPER_REPEL
.2byte ITEM_X_SPEED
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LavaridgeTown_Mart_EventScript_ExpertM::
msgbox LavaridgeTown_Mart_Text_XSpeedFirstStrike, MSGBOX_NPC
diff --git a/data/maps/LilycoveCity_DepartmentStore_2F/scripts.inc b/data/maps/LilycoveCity_DepartmentStore_2F/scripts.inc
index 478f5cfd31..0a502a4f0e 100644
--- a/data/maps/LilycoveCity_DepartmentStore_2F/scripts.inc
+++ b/data/maps/LilycoveCity_DepartmentStore_2F/scripts.inc
@@ -36,9 +36,7 @@ LilycoveCity_DepartmentStore_2F_Pokemart1:
.2byte ITEM_ICE_HEAL
.2byte ITEM_AWAKENING
.2byte ITEM_FLUFFY_TAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_2F_EventScript_ClerkRight::
lock
@@ -62,9 +60,7 @@ LilycoveCity_DepartmentStore_2F_Pokemart2:
.2byte ITEM_MAX_REPEL
.2byte ITEM_WAVE_MAIL
.2byte ITEM_MECH_MAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_2F_Text_LearnToUseItemsProperly:
.string "Learn to use items properly.\n"
diff --git a/data/maps/LilycoveCity_DepartmentStore_3F/scripts.inc b/data/maps/LilycoveCity_DepartmentStore_3F/scripts.inc
index 9189df1f50..8375f9b82a 100644
--- a/data/maps/LilycoveCity_DepartmentStore_3F/scripts.inc
+++ b/data/maps/LilycoveCity_DepartmentStore_3F/scripts.inc
@@ -19,9 +19,7 @@ LilycoveCity_DepartmentStore_3F_Pokemart_Vitamins:
.2byte ITEM_ZINC
.2byte ITEM_CARBOS
.2byte ITEM_HP_UP
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_3F_EventScript_ClerkRight::
lock
@@ -42,9 +40,7 @@ LilycoveCity_DepartmentStore_3F_Pokemart_StatBoosters:
.2byte ITEM_DIRE_HIT
.2byte ITEM_GUARD_SPEC
.2byte ITEM_X_ACCURACY
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_3F_EventScript_TriathleteM::
msgbox LilycoveCity_DepartmentStore_3F_Text_ItemsBestForTougheningPokemon, MSGBOX_NPC
diff --git a/data/maps/LilycoveCity_DepartmentStore_4F/scripts.inc b/data/maps/LilycoveCity_DepartmentStore_4F/scripts.inc
index 760abc600d..0d6403b206 100644
--- a/data/maps/LilycoveCity_DepartmentStore_4F/scripts.inc
+++ b/data/maps/LilycoveCity_DepartmentStore_4F/scripts.inc
@@ -29,9 +29,7 @@ LilycoveCity_DepartmentStore_4F_Pokemart_AttackTMs:
.2byte ITEM_TM_THUNDER
.2byte ITEM_TM_BLIZZARD
.2byte ITEM_TM_HYPER_BEAM
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_4F_EventScript_ClerkRight::
lock
@@ -49,9 +47,7 @@ LilycoveCity_DepartmentStore_4F_Pokemart_DefenseTMs:
.2byte ITEM_TM_SAFEGUARD
.2byte ITEM_TM_REFLECT
.2byte ITEM_TM_LIGHT_SCREEN
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_4F_Text_AttackOrDefenseTM:
.string "Hmm…\p"
diff --git a/data/maps/LilycoveCity_DepartmentStore_5F/scripts.inc b/data/maps/LilycoveCity_DepartmentStore_5F/scripts.inc
index a9683d13c9..f75a48e708 100644
--- a/data/maps/LilycoveCity_DepartmentStore_5F/scripts.inc
+++ b/data/maps/LilycoveCity_DepartmentStore_5F/scripts.inc
@@ -41,9 +41,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Dolls:
.2byte DECOR_SKITTY_DOLL
.2byte DECOR_SWABLU_DOLL
.2byte DECOR_GULPIN_DOLL
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_5F_EventScript_ClerkMidLeft::
lock
@@ -66,9 +64,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Cushions:
.2byte DECOR_GRASS_CUSHION
.2byte DECOR_FIRE_CUSHION
.2byte DECOR_WATER_CUSHION
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_5F_EventScript_ClerkMidRight::
lock
@@ -91,9 +87,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Posters:
.2byte DECOR_LONG_POSTER
.2byte DECOR_SEA_POSTER
.2byte DECOR_SKY_POSTER
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_5F_EventScript_ClerkFarRight::
lock
@@ -117,9 +111,7 @@ LilycoveCity_DepartmentStore_5F_Pokemart_Mats:
.2byte DECOR_GLITTER_MAT
.2byte DECOR_JUMP_MAT
.2byte DECOR_SPIN_MAT
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
LilycoveCity_DepartmentStore_5F_EventScript_PokefanF::
msgbox LilycoveCity_DepartmentStore_5F_Text_PlaceFullOfCuteDolls, MSGBOX_NPC
diff --git a/data/maps/MauvilleCity_Mart/scripts.inc b/data/maps/MauvilleCity_Mart/scripts.inc
index 751835caab..f7028c20f8 100644
--- a/data/maps/MauvilleCity_Mart/scripts.inc
+++ b/data/maps/MauvilleCity_Mart/scripts.inc
@@ -25,9 +25,7 @@ MauvilleCity_Mart_Pokemart:
.2byte ITEM_GUARD_SPEC
.2byte ITEM_DIRE_HIT
.2byte ITEM_X_ACCURACY
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
MauvilleCity_Mart_EventScript_ExpertM::
msgbox MauvilleCity_Mart_Text_ItemsToTemporarilyElevateStats, MSGBOX_NPC
diff --git a/data/maps/MossdeepCity_Mart/scripts.inc b/data/maps/MossdeepCity_Mart/scripts.inc
index 6618b6a6a3..cfe97d5e1f 100644
--- a/data/maps/MossdeepCity_Mart/scripts.inc
+++ b/data/maps/MossdeepCity_Mart/scripts.inc
@@ -22,9 +22,7 @@ MossdeepCity_Mart_Pokemart:
.2byte ITEM_MAX_REPEL
.2byte ITEM_X_ATTACK
.2byte ITEM_X_DEFENSE
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
MossdeepCity_Mart_EventScript_Woman::
msgbox MossdeepCity_Mart_Text_ReviveIsFantastic, MSGBOX_NPC
diff --git a/data/maps/OldaleTown_Mart/scripts.inc b/data/maps/OldaleTown_Mart/scripts.inc
index 0b3c7b1a34..1e1aacbb10 100644
--- a/data/maps/OldaleTown_Mart/scripts.inc
+++ b/data/maps/OldaleTown_Mart/scripts.inc
@@ -18,9 +18,7 @@ OldaleTown_Mart_Pokemart_Basic:
.2byte ITEM_ANTIDOTE
.2byte ITEM_PARALYZE_HEAL
.2byte ITEM_AWAKENING
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
OldaleTown_Mart_ExpandedItems::
pokemart OldaleTown_Mart_Pokemart_Expanded
@@ -35,9 +33,7 @@ OldaleTown_Mart_Pokemart_Expanded:
.2byte ITEM_ANTIDOTE
.2byte ITEM_PARALYZE_HEAL
.2byte ITEM_AWAKENING
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
OldaleTown_Mart_EventScript_Woman::
lock
diff --git a/data/maps/PetalburgCity_Mart/scripts.inc b/data/maps/PetalburgCity_Mart/scripts.inc
index acae50929d..54ca3aa6d8 100644
--- a/data/maps/PetalburgCity_Mart/scripts.inc
+++ b/data/maps/PetalburgCity_Mart/scripts.inc
@@ -25,9 +25,7 @@ PetalburgCity_Mart_Pokemart_Basic:
.2byte ITEM_X_ATTACK
.2byte ITEM_X_DEFENSE
.2byte ITEM_ORANGE_MAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
PetalburgCity_Mart_EventScript_ExpandedItems::
pokemart PetalburgCity_Mart_Pokemart_Expanded
@@ -50,9 +48,7 @@ PetalburgCity_Mart_Pokemart_Expanded:
.2byte ITEM_X_ATTACK
.2byte ITEM_X_DEFENSE
.2byte ITEM_ORANGE_MAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
PetalburgCity_Mart_EventScript_Woman::
msgbox PetalburgCity_Mart_Text_WeakWillGrowStronger, MSGBOX_NPC
diff --git a/data/maps/Route104_PrettyPetalFlowerShop/scripts.inc b/data/maps/Route104_PrettyPetalFlowerShop/scripts.inc
index 54b2dacef1..fec03cc681 100644
--- a/data/maps/Route104_PrettyPetalFlowerShop/scripts.inc
+++ b/data/maps/Route104_PrettyPetalFlowerShop/scripts.inc
@@ -59,9 +59,7 @@ Route104_PrettyPetalFlowerShop_Pokemart_Plants:
.2byte DECOR_COLORFUL_PLANT
.2byte DECOR_BIG_PLANT
.2byte DECOR_GORGEOUS_PLANT
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
Route104_PrettyPetalFlowerShop_EventScript_WailmerPailGirl::
lock
diff --git a/data/maps/RustboroCity_Mart/scripts.inc b/data/maps/RustboroCity_Mart/scripts.inc
index 65cc71baba..50acba60b4 100644
--- a/data/maps/RustboroCity_Mart/scripts.inc
+++ b/data/maps/RustboroCity_Mart/scripts.inc
@@ -28,9 +28,7 @@ RustboroCity_Mart_Pokemart_Basic:
.2byte ITEM_X_SPEED
.2byte ITEM_X_ATTACK
.2byte ITEM_X_DEFENSE
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
RustboroCity_Mart_EventScript_PokemartExpanded::
pokemart RustboroCity_Mart_Pokemart_Expanded
@@ -52,9 +50,7 @@ RustboroCity_Mart_Pokemart_Expanded:
.2byte ITEM_X_SPEED
.2byte ITEM_X_ATTACK
.2byte ITEM_X_DEFENSE
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
RustboroCity_Mart_EventScript_PokefanF::
msgbox RustboroCity_Mart_Text_BuyingHealsInCaseOfShroomish, MSGBOX_NPC
diff --git a/data/maps/SlateportCity/scripts.inc b/data/maps/SlateportCity/scripts.inc
index ae3910750e..5438a7f364 100644
--- a/data/maps/SlateportCity/scripts.inc
+++ b/data/maps/SlateportCity/scripts.inc
@@ -154,9 +154,7 @@ SlateportCity_Pokemart_EnergyGuru:
.2byte ITEM_ZINC
.2byte ITEM_CALCIUM
.2byte ITEM_HP_UP
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
SlateportCity_EventScript_EffortRibbonWoman::
lock
@@ -514,9 +512,7 @@ SlateportCity_PokemartDecor_Dolls:
.2byte DECOR_AZURILL_DOLL
.2byte DECOR_MARILL_DOLL
.2byte DECOR_SKITTY_DOLL
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
SlateportCity_EventScript_ComeBackWithSecretPower::
msgbox gText_ComeBackWithSecretPower, MSGBOX_DEFAULT
@@ -550,9 +546,7 @@ SlateportCity_PokemartDecor:
.2byte DECOR_A_NOTE_MAT
.2byte DECOR_B_NOTE_MAT
.2byte DECOR_C_HIGH_NOTE_MAT
- .2byte DECOR_NONE
- release
- end
+ pokemartlistend
SlateportCity_EventScript_PowerTMClerk::
lock
@@ -568,9 +562,7 @@ SlateportCity_EventScript_PowerTMClerk::
SlateportCity_Pokemart_PowerTMs:
.2byte ITEM_TM_HIDDEN_POWER
.2byte ITEM_TM_SECRET_POWER
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
@ Scene with Capt Sterns interview and Team Aqua announcing plans to steal Submarine
SlateportCity_EventScript_CaptStern::
diff --git a/data/maps/SlateportCity_Mart/scripts.inc b/data/maps/SlateportCity_Mart/scripts.inc
index a0c0a8612e..ce7dd45b86 100644
--- a/data/maps/SlateportCity_Mart/scripts.inc
+++ b/data/maps/SlateportCity_Mart/scripts.inc
@@ -22,9 +22,7 @@ SlateportCity_Mart_Pokemart:
.2byte ITEM_ESCAPE_ROPE
.2byte ITEM_REPEL
.2byte ITEM_HARBOR_MAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
SlateportCity_Mart_EventScript_BlackBelt::
msgbox SlateportCity_Mart_Text_SomeItemsOnlyAtMart, MSGBOX_NPC
diff --git a/data/maps/SootopolisCity_Mart/scripts.inc b/data/maps/SootopolisCity_Mart/scripts.inc
index 618f78c524..7b3171f67f 100644
--- a/data/maps/SootopolisCity_Mart/scripts.inc
+++ b/data/maps/SootopolisCity_Mart/scripts.inc
@@ -22,9 +22,7 @@ SootopolisCity_Mart_Pokemart:
.2byte ITEM_X_ATTACK
.2byte ITEM_X_DEFENSE
.2byte ITEM_SHADOW_MAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
SootopolisCity_Mart_EventScript_FatMan::
lock
diff --git a/data/maps/TrainerHill_Entrance/scripts.inc b/data/maps/TrainerHill_Entrance/scripts.inc
index efc63d6561..4efceaa1cc 100644
--- a/data/maps/TrainerHill_Entrance/scripts.inc
+++ b/data/maps/TrainerHill_Entrance/scripts.inc
@@ -267,9 +267,7 @@ TrainerHill_Entrance_Pokemart_Basic:
.2byte ITEM_DIRE_HIT
.2byte ITEM_GUARD_SPEC
.2byte ITEM_X_ACCURACY
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
TrainerHill_Entrance_EventScript_ExpandedPokemart::
pokemart TrainerHill_Entrance_Pokemart_Expanded
@@ -291,9 +289,7 @@ TrainerHill_Entrance_Pokemart_Expanded:
.2byte ITEM_DIRE_HIT
.2byte ITEM_GUARD_SPEC
.2byte ITEM_X_ACCURACY
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
TrainerHill_Entrance_Text_StillGettingReady:
.string "This is the TRAINER HILL where\n"
diff --git a/data/maps/VerdanturfTown_Mart/scripts.inc b/data/maps/VerdanturfTown_Mart/scripts.inc
index c809d6703a..3c6f77b3a5 100644
--- a/data/maps/VerdanturfTown_Mart/scripts.inc
+++ b/data/maps/VerdanturfTown_Mart/scripts.inc
@@ -24,9 +24,7 @@ VerdanturfTown_Mart_Pokemart:
.2byte ITEM_REPEL
.2byte ITEM_X_SP_ATK
.2byte ITEM_FLUFFY_TAIL
- .2byte ITEM_NONE
- release
- end
+ pokemartlistend
VerdanturfTown_Mart_EventScript_Boy::
msgbox VerdanturfTown_Mart_Text_XSpecialIsCrucial, MSGBOX_NPC
diff --git a/data/scripts/debug.inc b/data/scripts/debug.inc
index 4851c87c40..0be780609d 100644
--- a/data/scripts/debug.inc
+++ b/data/scripts/debug.inc
@@ -447,3 +447,135 @@ Debug_EventScript_EWRAMCounters::
Debug_EventScript_EWRAMCounters_Text::
.string "Follower Steps: {STR_VAR_1}.\n"
.string "Fishing Chain: {STR_VAR_2}.$"
+
+Debug_EventScript_FontTest_Text_1::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Angel Adept Blind Bodice Clique\n"
+ .string "Coast Dunce Docile Enact Eosin\l"
+ .string "Furlong Focal Gnome Gondola Human\l"
+ .string "Hoist Inlet Iodine Justin Jocose\l"
+ .string "Knoll Koala Linden Loads Milliner\l"
+ .string "Modal Number Nodule Onset Oddball\l"
+ .string "Pneumo Poncho Quanta Qophs Rhone\l"
+ .string "Roman Snout Sodium Tundra Tocsin\l"
+ .string "Uncle Udder Vulcan Vocal Whale\l"
+ .string "Woman Xmas Xenon Yunnan Young\l"
+ .string "Zloty Zodiac.$"
+
+Debug_EventScript_FontTest_Text_2::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Angel angel adept for the nuance loads\n"
+ .string "of the arena cocoa and quaalude. Blind\l"
+ .string "blind bodice for the submit oboe of the\l"
+ .string "club snob and abbot. Clique clique\l"
+ .string "coast for the pouch loco of the franc\l"
+ .string "assoc and accede. Dunce dunce docile\l"
+ .string "for the loudness mastodon of the\l"
+ .string "loud statehood and huddle.$"
+
+Debug_EventScript_FontTest_Text_3::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Enact enact eosin for the quench coed\n"
+ .string "of the pique canoe and bleep. Furlong\l"
+ .string "furlong focal for the genuflect\l"
+ .string "profound of the motif aloof and offers.\l"
+ .string "Gnome gnome gondola for the impugn\l"
+ .string "logos of the unplug analog and smuggle.\l"
+ .string "Human human hoist for the buddhist\l"
+ .string "alcohol of the riyadh caliph and\l"
+ .string "bathhouse.$"
+
+Debug_EventScript_FontTest_Text_4::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Inlet inlet iodine for the quince\n"
+ .string "champion of the ennui scampi and shiite.\l"
+ .string "Justin justin jocose for the djibouti\l"
+ .string "sojourn of the oranj raj and hajjis.\l"
+ .string "Knoll knoll koala for the banknote\l"
+ .string "lookout of the dybbuk outlook and\l"
+ .string "trekked. Linden linden loads for the\l"
+ .string "ulna monolog of the consul menthol and\l"
+ .string "shallot.$"
+
+Debug_EventScript_FontTest_Text_5::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Milliner milliner modal for the alumna\n"
+ .string "solomon of the album custom and summon.\l"
+ .string "Number number nodule for the unmade\l"
+ .string "economic of the shotgun bison and\l"
+ .string "tunnel. Onset onset oddball for the\l"
+ .string "abandon podium of the antiquo tempo\l"
+ .string "and moonlit. Pneumo pneumo poncho for\l"
+ .string "the dauphin opossum of the holdup\l"
+ .string "bishop and supplies.$"
+
+Debug_EventScript_FontTest_Text_6::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Quanta quanta qophs for the inquest\n"
+ .string "sheqel of the cinq coq and suqqu. Rhone\l"
+ .string "rhone roman for the burnt porous of the\l"
+ .string "lemur clamor and carrot. Snout snout\l"
+ .string "sodium for the ensnare bosom of the\l"
+ .string "genus pathos and missing. Tundra\l"
+ .string "tundra tocsin for the nutmeg isotope\l"
+ .string "of the peasant ingot and ottoman.$"
+
+Debug_EventScript_FontTest_Text_7::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Uncle uncle udder for the dunes cloud\n"
+ .string "of the hindu thou and continuum. Vulcan\l"
+ .string "vulcan vocal for the alluvial ovoid of\l"
+ .string "the yugoslav chekhov and revved. Whale\l"
+ .string "whale woman for the meanwhile blowout\l"
+ .string "of the forepaw meadow and glowworm.\l"
+ .string "Xmas xmas xenon for the bauxite\l"
+ .string "doxology of the tableaux equinox and\l"
+ .string "exxon.$"
+
+Debug_EventScript_FontTest_Text_8::
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "Yunnan yunnan young for the dynamo\n"
+ .string "coyote of the obloquy employ and\l"
+ .string "sayyid. Zloty zloty zodiac for the gizmo\l"
+ .string "ozone of the franz laissez and buzzing.$"
+
+
+Debug_EventScript_FontTest_Text_9:: @ Special thanks to Nintendo for this nice pangram to test other glyphs
+ .string "{FONT_SMALL_NARROWER}" @ Edit this to test your font
+ .string "42 × 138 = 5796.\n"
+ .string "Mr Jock, TV quiz PhD: bags 20% fewer\l"
+ .string "lynx at a café; voilà, they're “worth”\l"
+ .string "♂1/♀1 = ¥1. That's 10 + 9 - 8 = 11\l"
+ .string "Nintendo GBA can connect to a Nintendo\l"
+ .string "GameCube console! He claimed-though I don't\l"
+ .string "believe him-to have done so in an eyes-shut\l"
+ .string "state…?$"
+
+Debug_PrintFontTest::
+ msgbox Debug_EventScript_FontTest_Text_1, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_2, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_3, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_4, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_5, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_6, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_7, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_8, MSGBOX_DEFAULT
+ msgbox Debug_EventScript_FontTest_Text_9, MSGBOX_DEFAULT
+ releaseall
+ end
+
+Debug_EventScript_FontTest::
+ lockall
+ goto Debug_PrintFontTest
+@ goto_if_eq VAR_RESULT, 0, Debug_NoPokemon
+@ dynmultipush Debug_EventScript_InflictStatus1_Text_Single, 0
+@ dynmultipush Debug_EventScript_InflictStatus1_Text_PartyWide, 1
+@ dynmultipush Debug_EventScript_InflictStatus1_Text_Close, 2
+@ dynmultistack 0, 0, FALSE, 3 FALSE, 0, NULL
+@ switch VAR_RESULT
+@ case 0, Debug_EventScript_InflictStatus1_Single
+@ case 1, Debug_EventScript_InflictStatus1_Party
+@ case 2, Debug_EventScript_InflictStatus1_Close
+@Debug_EventScript_InflictStatus1_Close:
+@ releaseall
+@ end
diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md
index ac4698fdc3..fe13ea72ee 100644
--- a/docs/SUMMARY.md
+++ b/docs/SUMMARY.md
@@ -12,13 +12,18 @@
- [How to add a new move](tutorials/how_to_new_move.md)
- [How to add a new trainer class](tutorials/how_to_trainer_class.md)
- [How to add a new Pokémon]()
+ - [v1.10.x](tutorials/how_to_new_pokemon_1_10_0.md)
- [v1.9.x](tutorials/how_to_new_pokemon_1_9_0.md)
- [v1.8.x](tutorials/how_to_new_pokemon_1_8_0.md)
- [v1.7.x](tutorials/how_to_new_pokemon_1_7_0.md)
- [v1.6.x](tutorials/how_to_new_pokemon_1_6_0.md)
- [How to use the Testing System](tutorials/how_to_testing_system.md)
- [Changelog](./CHANGELOG.md)
+ - [1.10.x]()
+ - [Version 1.10.1](changelogs/1.10.x/1.10.1.md)
+ - [Version 1.10.0](changelogs/1.10.x/1.10.0.md)
- [1.9.x]()
+ - [Version 1.9.4](changelogs/1.9.x/1.9.4.md)
- [Version 1.9.3](changelogs/1.9.x/1.9.3.md)
- [Version 1.9.2](changelogs/1.9.x/1.9.2.md)
- [Version 1.9.1](changelogs/1.9.x/1.9.1.md)
@@ -64,3 +69,4 @@
- [Version 0.9.0](changelogs/0.9.x/0.9.0.md)
- [Team Procedures]()
- [How to make an Expansion version](team_procedures/expansion_versions.md)
+ - [Scope Guidelines](scope.md)
diff --git a/docs/changelogs/1.10.x/1.10.0.md b/docs/changelogs/1.10.x/1.10.0.md
new file mode 100644
index 0000000000..9cf2f9b41e
--- /dev/null
+++ b/docs/changelogs/1.10.x/1.10.0.md
@@ -0,0 +1,324 @@
+# Version 1.10.0
+
+```md
+## How to update
+- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
+- Once you have your remote set up, run the command `git pull RHH expansion/1.10.0`.
+```
+
+## 🌋 *REFACTORS* 🌋
+📜 = Uses a migration script.
+* Changes Evolution methods to Enums by @AlexOn1ine in [#4977](https://github.com/rh-hideout/pokeemerald-expansion/pull/4977)
+* Turn item hold effects into an enum by @Bassoonian in [#5498](https://github.com/rh-hideout/pokeemerald-expansion/pull/5498)
+* Change `GET_MOVE_TYPE` to a function by @AlexOn1ine in [#5090](https://github.com/rh-hideout/pokeemerald-expansion/pull/5090)
+* Created `COMPOUND_STRING`s for default player names by @fdeblasio in [#5037](https://github.com/rh-hideout/pokeemerald-expansion/pull/5037)
+* Removed agbcc by @mrgriffin in [#4994](https://github.com/rh-hideout/pokeemerald-expansion/pull/4994)
+* Refactor Frontier Brains by @fdeblasio in [#5027](https://github.com/rh-hideout/pokeemerald-expansion/pull/5027)
+* Removed all instances of `gBitTable[x]` by @hedara90 in [#5123](https://github.com/rh-hideout/pokeemerald-expansion/pull/5123)
+* Made `BuildColorMaps` redundant by using static tables by @pkmnsnfrn in [#5289](https://github.com/rh-hideout/pokeemerald-expansion/pull/5289)
+* Removed `FRONTIER_BRAIN_SPRITES` and updated `TRAINER_SPRITE`, `TRAINER_BACK_SPRITE`, and `TRAINER_CLASS` by @fdeblasio in [#5166](https://github.com/rh-hideout/pokeemerald-expansion/pull/5166)
+* Added `ShouldSwitch` result to `AiLogicData` by @Pawkkie and @AlexOn1ine had the idea! in [#5440](https://github.com/rh-hideout/pokeemerald-expansion/pull/5440)
+* Switch AI refactor + considers free switches by @Pawkkie in [#5379](https://github.com/rh-hideout/pokeemerald-expansion/pull/5379)
+* Refactor `ShouldSwitchIfAllBadMoves` by @Pawkkie in [#5452](https://github.com/rh-hideout/pokeemerald-expansion/pull/5452)
+* Updated Wring Out effects to match Eruption effects by @AsparagusEduardo in [#5549](https://github.com/rh-hideout/pokeemerald-expansion/pull/5549)
+ - Changed Wring Out/Crush Grip/Hard Press to use `power` instead of `argument` to determine its max power, just like how Eruption/Water Spout/Dragon Energy do it.
+ - Also:
+ - Renamed `EFFECT_VARY_POWER_BASED_ON_HP` to `EFFECT_POWER_BASED_ON_TARGET_HP`
+ - Renamed `EFFECT_ERUPTION` to `EFFECT_POWER_BASED_ON_USER_HP`
+* Update battle messages to Gen 5+ standards by @kittenchilly in [#3240](https://github.com/rh-hideout/pokeemerald-expansion/pull/3240)
+* Should switch refactor to facilitate switch prediction by @Pawkkie in [#5466](https://github.com/rh-hideout/pokeemerald-expansion/pull/5466)
+* Unwind `TRAINER_CLASS` macro by @SBird1337 in [#5611](https://github.com/rh-hideout/pokeemerald-expansion/pull/5611)
+* Refactors Absorb to use `Moveend` by @AlexOn1ine in [#5670](https://github.com/rh-hideout/pokeemerald-expansion/pull/5670)
+ * For new absorbing moves an argument should be added in `moves_info.h`
+* Changes name of `B_SCR_NAME_WITH_PREFIX` by @AlexOn1ine in [#5675](https://github.com/rh-hideout/pokeemerald-expansion/pull/5675)
+
+## 🧬 General 🧬
+### Added
+* Added performance counter by @hedara90 and @SBird1337 provided the actual code in [#5284](https://github.com/rh-hideout/pokeemerald-expansion/pull/5284)
+* Added debug build target by @u8-Salem in [#4817](https://github.com/rh-hideout/pokeemerald-expansion/pull/4817)
+* Added `AUTO_SCROLL_TEXT` and `NUM_FRAMES_AUTO_SCROLL_DELAY` by @pkmnsnfrn in [#5054](https://github.com/rh-hideout/pokeemerald-expansion/pull/5054)
+* Adds `SAVE_TYPE_ERROR_SCREEN` by @pkmnsnfrn in [#5188](https://github.com/rh-hideout/pokeemerald-expansion/pull/5188)
+* Move Relearner and Renaming From Summary Screen by @ravepossum in [#5513](https://github.com/rh-hideout/pokeemerald-expansion/pull/5513)
+* Automatic Line Breaks, somewhat even lines by @hedara90 and @AsparagusEduardo in [#5689](https://github.com/rh-hideout/pokeemerald-expansion/pull/5689)
+ - Automatically insert line breaks into a string with `BreakStringAutomatic`.
+ - This function does not modify strings with existing line breaks.
+ - Remove existing line breaks from a string with `StripLineBreaks`.
+
+### Changed
+* Removed agbcc by @mrgriffin in [#4994](https://github.com/rh-hideout/pokeemerald-expansion/pull/4994)
+* Removed all instances of `gBitTable[x]` by @hedara90 in [#5123](https://github.com/rh-hideout/pokeemerald-expansion/pull/5123)
+* Converted Mechadoll text to `COMPOUND_STRING`s by @fdeblasio in [#5276](https://github.com/rh-hideout/pokeemerald-expansion/pull/5276)
+* New terrain bgs by @TheTrueSadfish in [#5162](https://github.com/rh-hideout/pokeemerald-expansion/pull/5162)
+* Removed agbcc screenshots from `.gitignore` by @Bassoonian in [#5538](https://github.com/rh-hideout/pokeemerald-expansion/pull/5538)
+* Set default battle shadow to Gen3 by @hedara90 in [#5632](https://github.com/rh-hideout/pokeemerald-expansion/pull/5632)
+ - Note: Trainerslides don't work properly with Gen4 shadows.
+* Convert 3 variouses to `callnatives` by @AlexOn1ine in [#5646](https://github.com/rh-hideout/pokeemerald-expansion/pull/5646)
+
+## 🗺️ Overworld 🗺️
+### Added
+* FRLG+ whiteout message by @cawtds in [#4967](https://github.com/rh-hideout/pokeemerald-expansion/pull/4967)
+* Dynamic Move Types in Summary Screen/Battle by @Galaxeeh in [#5084](https://github.com/rh-hideout/pokeemerald-expansion/pull/5084)
+* Adds `OW_BERRY_IMMORTAL` by @pkmnsnfrn in [#5187](https://github.com/rh-hideout/pokeemerald-expansion/pull/5187)
+* (Default Off) Item Description Headers by @ghoulslash in [#4767](https://github.com/rh-hideout/pokeemerald-expansion/pull/4767)
+* RTC-based wild encounters by @hjk321 in [#5313](https://github.com/rh-hideout/pokeemerald-expansion/pull/5313)
+* Added `MB_X_Y_STAIR_WARP` metatile behaviors by @pkmnsnfrn in [#5278](https://github.com/rh-hideout/pokeemerald-expansion/pull/5278)
+* Added Sideways Stairs by @ghoulslash in [#4836](https://github.com/rh-hideout/pokeemerald-expansion/pull/4836)
+* Added `OW_UNION_DISABLE_CHECK` and `OW_FLAG_MOVE_UNION_ROOM_CHECK` by @pkmnsnfrn in [#5448](https://github.com/rh-hideout/pokeemerald-expansion/pull/5448)
+* Adds new scripting macros to increase developer quality of life by @pkmnsnfrn in [#5177](https://github.com/rh-hideout/pokeemerald-expansion/pull/5177)
+* Added more later gen fishing mechanics by @kittenchilly in [#5518](https://github.com/rh-hideout/pokeemerald-expansion/pull/5518)
+
+### Changed
+* Created PokeNav `COMPOUND_STRING`s by @fdeblasio in [#4983](https://github.com/rh-hideout/pokeemerald-expansion/pull/4983)
+* Added `I_REPEL_INCLUDE_FAINTED` config and behavior by @kittenchilly in [#5239](https://github.com/rh-hideout/pokeemerald-expansion/pull/5239)
+* RTC-based wild encounters follow up by @AlexOn1ine in [#5328](https://github.com/rh-hideout/pokeemerald-expansion/pull/5328)
+* Revert rtc based encounters by @AlexOn1ine in [#5331](https://github.com/rh-hideout/pokeemerald-expansion/pull/5331)
+* Made BuildColorMaps redundant by using static tables by @pkmnsnfrn in [#5289](https://github.com/rh-hideout/pokeemerald-expansion/pull/5289)
+* Added `OW_AUTO_SIGNPOST` and associated metatile behaviors by @pkmnsnfrn in [#5044](https://github.com/rh-hideout/pokeemerald-expansion/pull/5044)
+* Added support for overworld sprite gender differences + add all the sprites by @kittenchilly in [#5394](https://github.com/rh-hideout/pokeemerald-expansion/pull/5394)
+
+### Fixed
+* Added some null pointer checks by @tertu-m in [#5130](https://github.com/rh-hideout/pokeemerald-expansion/pull/5130)
+* Reset item flags on new game by @ghoulslash in [#5363](https://github.com/rh-hideout/pokeemerald-expansion/pull/5363)
+* Follower female fix by @hedara90 in [#5475](https://github.com/rh-hideout/pokeemerald-expansion/pull/5475)
+
+## 🐉 Pokémon 🐉
+### Added
+* Added config to change Vivillon's breeding form by @kittenchilly in [#4813](https://github.com/rh-hideout/pokeemerald-expansion/pull/4813)
+* Added back GBA sprites via config by @AsparagusEduardo and @AlexOn1ine for their help with script to migrate data from vanilla to our current `gSpeciesInfo` in [#5206](https://github.com/rh-hideout/pokeemerald-expansion/pull/5206)
+* Added config to disable gender differences by @AsparagusEduardo in [#5595](https://github.com/rh-hideout/pokeemerald-expansion/pull/5595)
+
+### Changed
+* Made perfect IV count into a granular setting by @AsparagusEduardo in [#5115](https://github.com/rh-hideout/pokeemerald-expansion/pull/5115)
+* Updated species defines by @pkmnsnfrn in [#5075](https://github.com/rh-hideout/pokeemerald-expansion/pull/5075)
+* Added support for overworld sprite gender differences + add all the sprites by @kittenchilly in [#5394](https://github.com/rh-hideout/pokeemerald-expansion/pull/5394)
+* Renamed folders and symbols to match species defines by @AsparagusEduardo in [#5581](https://github.com/rh-hideout/pokeemerald-expansion/pull/5581)
+ - Burmy and Wormadam footprints were in a `plant` subfolder. They have been moved to the species root folder
+ - Paldean Wooper's subfolder was named `wooper_paldean` instead of just `paldean`. This has been corrected.
+ - Zen Mode Galarian Darmanitan's folder was located in `darmanitan/galarian/zen_mode`. This has been corrected to `darmanitan/galar_zen`, alongside Galarian Standard Mode's `darmanitan/galar_standard`.
+ - Also updated Ogerpon's folders similarly.
+ - Renamed `SPECIES_PIKACHU_PARTNER_CAP` to `SPECIES_PIKACHU_PARTNER`.
+* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547)
+ - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1.
+
+### Fixed
+* Follower female fix by @hedara90 in [#5475](https://github.com/rh-hideout/pokeemerald-expansion/pull/5475)
+* Fixed some gba sprites by @SubzeroEclipse in [#5607](https://github.com/rh-hideout/pokeemerald-expansion/pull/5607)
+
+## ⚔️ Battle General ⚔️
+### Added
+* FRLG+ whiteout message by @cawtds in [#4967](https://github.com/rh-hideout/pokeemerald-expansion/pull/4967)
+* Added B_SHOW_TYPES and cleaned up IsDoubleBattle by @pkmnsnfrn in [#5131](https://github.com/rh-hideout/pokeemerald-expansion/pull/5131)
+* EV Caps and EV Items by @Flash1Lucky and @AlexOn1ine in [#5269](https://github.com/rh-hideout/pokeemerald-expansion/pull/5269)
+* Added in-battle shadows underneath all enemy battlers by @lhearachel in [#5178](https://github.com/rh-hideout/pokeemerald-expansion/pull/5178)
+* Added Gen 1 Crit Chance by @Pawkkie in [#5439](https://github.com/rh-hideout/pokeemerald-expansion/pull/5439)
+* Added battle flag that prevents running from wild Pokémon by @SarnPoke in [#5502](https://github.com/rh-hideout/pokeemerald-expansion/pull/5502)
+
+### Changed
+* Refactor Frontier Brains by @fdeblasio in [#5027](https://github.com/rh-hideout/pokeemerald-expansion/pull/5027)
+* Removed some hardcoding of move IDs + Gen4/5 Defog by @AsparagusEduardo in [#5156](https://github.com/rh-hideout/pokeemerald-expansion/pull/5156)
+* Convert 8 various to `callnatives` by @AsparagusEduardo in [#5172](https://github.com/rh-hideout/pokeemerald-expansion/pull/5172)
+* Anger Shell use `saveattacker` by @ghoulslash in [#5409](https://github.com/rh-hideout/pokeemerald-expansion/pull/5409)
+* Clean up Unseen Fist Check by @AlexOn1ine in [#5420](https://github.com/rh-hideout/pokeemerald-expansion/pull/5420)
+* Updated species defines by @pkmnsnfrn in [#5075](https://github.com/rh-hideout/pokeemerald-expansion/pull/5075)
+* Removes Crit Chance preproc by @AlexOn1ine in [#5520](https://github.com/rh-hideout/pokeemerald-expansion/pull/5520)
+* Update battle messages to Gen 5+ standards by @kittenchilly in [#3240](https://github.com/rh-hideout/pokeemerald-expansion/pull/3240)
+* More post-#3240 cleanup by @kittenchilly in [#5593](https://github.com/rh-hideout/pokeemerald-expansion/pull/5593)
+* Unwind `TRAINER_CLASS` macro by @SBird1337 in [#5611](https://github.com/rh-hideout/pokeemerald-expansion/pull/5611)
+* Removes redundant Decorate check by @AlexOn1ine in [#5696](https://github.com/rh-hideout/pokeemerald-expansion/pull/5696)
+* Changes target bit of Flower Shield by @AlexOn1ine in [#5698](https://github.com/rh-hideout/pokeemerald-expansion/pull/5698)
+
+### Fixed
+* Fixed a sprite issue with `B_SHOW_TYPES` by @pkmnsnfrn in [#5157](https://github.com/rh-hideout/pokeemerald-expansion/pull/5157)
+* Dynamic Move Display fixes by @Galaxeeh in [#5251](https://github.com/rh-hideout/pokeemerald-expansion/pull/5251)
+* Fixed a display issue with `B_SHOW_TYPES` by @pkmnsnfrn and @iriv24 in [#5201](https://github.com/rh-hideout/pokeemerald-expansion/pull/5201)
+* Fixed Gen 3 foreseen and Beat Up damage type by @hedara90 in [#5323](https://github.com/rh-hideout/pokeemerald-expansion/pull/5323)
+* Fixes Defog used by the wrong side when there is a Substitue and Screen by @AlexOn1ine in [#5381](https://github.com/rh-hideout/pokeemerald-expansion/pull/5381)
+* Fixes Hidden Power dynamic type bug by @AlexOn1ine in [#5463](https://github.com/rh-hideout/pokeemerald-expansion/pull/5463)
+* Display the correct shadow size when sending out a new Pokemon by @lhearachel in [#5618](https://github.com/rh-hideout/pokeemerald-expansion/pull/5618)
+* Fixed text wrap obtaining the incorrect glyph width by @AsparagusEduardo and @AlexOn1ine for their help verifying that the fix works with one of his custom strings in [#5620](https://github.com/rh-hideout/pokeemerald-expansion/pull/5620)
+* Improve line breaks/scrolls by @cawtds in [#5641](https://github.com/rh-hideout/pokeemerald-expansion/pull/5641)
+* Fixed Order Up + Tera Stellar breaking each other with Commander by @PhallenTree in [#5667](https://github.com/rh-hideout/pokeemerald-expansion/pull/5667)
+* Fixes wrong Id when AI chooses mon to switch in by @AlexOn1ine in [#5684](https://github.com/rh-hideout/pokeemerald-expansion/pull/5684)
+* Fixes Absorb regression caused by #5670 by @AlexOn1ine in [#5688](https://github.com/rh-hideout/pokeemerald-expansion/pull/5688)
+* Fixes heal blocked leeach seed in tests by @AlexOn1ine in [#5700](https://github.com/rh-hideout/pokeemerald-expansion/pull/5700)
+* Trainer class+name expansion fix for Battle Frontier by @hedara90 in [#5699](https://github.com/rh-hideout/pokeemerald-expansion/pull/5699)
+
+## 🤹 Moves 🤹
+### Changed
+* Added Population Bomb animation by @kittenchilly in [#5194](https://github.com/rh-hideout/pokeemerald-expansion/pull/5194)
+* Move battle anim arrays to C by @cawtds in [#5306](https://github.com/rh-hideout/pokeemerald-expansion/pull/5306)
+* Grass/Water Pledge Swamp Animation + Sea of Fire animation tweak by @SonikkuA-DatH in [#5325](https://github.com/rh-hideout/pokeemerald-expansion/pull/5325)
+* New animations for many moves more details in description by @TheTrueSadfish in [#5367](https://github.com/rh-hideout/pokeemerald-expansion/pull/5367)
+* Use move effect for some moves instead of ids by @AlexOn1ine in [#5433](https://github.com/rh-hideout/pokeemerald-expansion/pull/5433)
+* Adds Commander and Order Up by @AlexOn1ine in [#5246](https://github.com/rh-hideout/pokeemerald-expansion/pull/5246)
+* Heart Swap Move Animation by @SonikkuA-DatH in [#5460](https://github.com/rh-hideout/pokeemerald-expansion/pull/5460)
+* Update `shed_tail.c` by @Bassoonian in [#5494](https://github.com/rh-hideout/pokeemerald-expansion/pull/5494)
+* Added Ion Deluge animation by @kittenchilly in [#5467](https://github.com/rh-hideout/pokeemerald-expansion/pull/5467)
+* Updated Wring Out effects to match Eruption effects by @AsparagusEduardo in [#5549](https://github.com/rh-hideout/pokeemerald-expansion/pull/5549)
+ - Changed Wring Out/Crush Grip/Hard Press to use `power` instead of `argument` to determine its max power, just like how Eruption/Water Spout/Dragon Energy do it. Also:
+ - Renamed `EFFECT_VARY_POWER_BASED_ON_HP` to `EFFECT_POWER_BASED_ON_TARGET_HP`
+ - Renamed `EFFECT_ERUPTION` to `EFFECT_POWER_BASED_ON_USER_HP`
+* Refactors Absorb to use Moveend by @AlexOn1ine in [#5670](https://github.com/rh-hideout/pokeemerald-expansion/pull/5670)
+ * For new absorbing moves an argument should be added in `moves_info.h`
+
+### Fixed
+* Dark Void, Clangorous Soulblaze, vortex animation fixes by @TheTrueSadfish in [#5650](https://github.com/rh-hideout/pokeemerald-expansion/pull/5650)
+
+## 🎭 Abilities 🎭
+### Changed
+* Adds Commander and Order Up by @AlexOn1ine in [#5246](https://github.com/rh-hideout/pokeemerald-expansion/pull/5246)
+
+## 🧶 Items 🧶
+### Added
+* Adds `OW_BERRY_IMMORTAL` by @pkmnsnfrn in [#5187](https://github.com/rh-hideout/pokeemerald-expansion/pull/5187)
+* Added functionality to Poké Flute and Town Map by @kittenchilly and @LOuroboros basically did the Town Map implementation in [#5405](https://github.com/rh-hideout/pokeemerald-expansion/pull/5405)
+* Decouple Poke Ball ids from item ids by @AlexOn1ine in [#5560](https://github.com/rh-hideout/pokeemerald-expansion/pull/5560)
+
+### Changed
+* Consolidated the values of Rotom's moves and added Gen9 base form effect by @fdeblasio in [#5186](https://github.com/rh-hideout/pokeemerald-expansion/pull/5186)
+* Added `I_REPEL_INCLUDE_FAINTED` config and behavior by @kittenchilly in [#5239](https://github.com/rh-hideout/pokeemerald-expansion/pull/5239)
+
+### Fixed
+* Replace hardcoded flute check with consumability check by @Bassoonian in [#5508](https://github.com/rh-hideout/pokeemerald-expansion/pull/5508)
+
+## 🤖 Battle AI 🤖
+### Added
+* Adds config to show target of ingame partner by @AlexOn1ine in [#5307](https://github.com/rh-hideout/pokeemerald-expansion/pull/5307)
+* Switch AI refactor + considers free switches by @Pawkkie in [#5379](https://github.com/rh-hideout/pokeemerald-expansion/pull/5379)
+* New AI flag for marking the two last Pokémon as Ace Pokémon by @GhoulMage in [#5587](https://github.com/rh-hideout/pokeemerald-expansion/pull/5587)
+
+### Changed
+* Chilly Reception AI by @kittenchilly in [#5271](https://github.com/rh-hideout/pokeemerald-expansion/pull/5271)
+* Shed Tail AI by @SarnPoke and @AlexOn1ine, @Pawkkie in [#5275](https://github.com/rh-hideout/pokeemerald-expansion/pull/5275)
+* More missing AI logic by @kittenchilly in [#5279](https://github.com/rh-hideout/pokeemerald-expansion/pull/5279)
+* Adds basic trainer and smart trainer flags by @AlexOn1ine in [#5298](https://github.com/rh-hideout/pokeemerald-expansion/pull/5298)
+* `AI_FLAG_SETUP_FIRST_TURN` rename and clarifications by @Pawkkie in [#5310](https://github.com/rh-hideout/pokeemerald-expansion/pull/5310)
+* Added Composite AI Flags to Docs by @Pawkkie in [#5349](https://github.com/rh-hideout/pokeemerald-expansion/pull/5349)
+* AI frostbite score fixes and improvements by @Pawkkie and @kittenchilly for the suggestion! in [#5362](https://github.com/rh-hideout/pokeemerald-expansion/pull/5362)
+* Switch AI `hitsToKO` considers one shot prevention by @Pawkkie in [#5371](https://github.com/rh-hideout/pokeemerald-expansion/pull/5371)
+* Adds `CanEndureHit` AI function by @AlexOn1ine in [#5373](https://github.com/rh-hideout/pokeemerald-expansion/pull/5373)
+* Switch AI `hitsToKO` considers Disguise by @Pawkkie in [#5375](https://github.com/rh-hideout/pokeemerald-expansion/pull/5375)
+* Added `ShouldSwitch` result to `AiLogicData` by @Pawkkie and @AlexOn1ine had the idea! in [#5440](https://github.com/rh-hideout/pokeemerald-expansion/pull/5440)
+* Removes duplicate code in AI functions by @AlexOn1ine in [#5457](https://github.com/rh-hideout/pokeemerald-expansion/pull/5457)
+* Unify `GetBattlerAbility`/`TerrainAffected` to remove duplicate ai function by @AlexOn1ine in [#5497](https://github.com/rh-hideout/pokeemerald-expansion/pull/5497)
+* `ShouldSwitchIfGameStatePrompt` Tests by @Pawkkie in [#5462](https://github.com/rh-hideout/pokeemerald-expansion/pull/5462)
+* `AI_FLAG_ACE_POKEMON` takes into account separate trainers by @GhoulMage and @/uvula on Discord noted the weird behaviour. in [#5608](https://github.com/rh-hideout/pokeemerald-expansion/pull/5608)
+ - Fix for the AI not considering both trainers Ace Pokémons in double battles with `AI_FLAG_ACE_POKEMON`.
+* Moves that deal a Fixed amount don't need AI handling by @AlexOn1ine in [#5614](https://github.com/rh-hideout/pokeemerald-expansion/pull/5614)
+* Combines `CalculateMoveDamage` arguments into a struct by @AlexOn1ine in [#5570](https://github.com/rh-hideout/pokeemerald-expansion/pull/5570)
+
+### Fixed
+* AI burn score fixes and improvements by @Pawkkie and @iriv24 and @AlexOn1ine in [#5356](https://github.com/rh-hideout/pokeemerald-expansion/pull/5356)
+* Improve AI's Skill Swap handling in double battles by @Pawkkie in [#5360](https://github.com/rh-hideout/pokeemerald-expansion/pull/5360)
+* Refactor `ShouldSwitchIfAllBadMoves` by @Pawkkie in [#5452](https://github.com/rh-hideout/pokeemerald-expansion/pull/5452)
+* Should switch refactor to facilitate switch prediction by @Pawkkie in [#5466](https://github.com/rh-hideout/pokeemerald-expansion/pull/5466)
+* Fixes Switch in flag not restoring mons properly with test by @Pawkkie and @iriv24 for finding, @AlexOn1ine for fixing in [#5746](https://github.com/rh-hideout/pokeemerald-expansion/pull/5746)
+
+## 🧹 Other Cleanup 🧹
+* Removed metadata in AIF files by @SombrAbsol in [#4958](https://github.com/rh-hideout/pokeemerald-expansion/pull/4958)
+* Removed `gPaletteDecompressionBuffer` and unused palette functions/vars by @DizzyEggg in [#4841](https://github.com/rh-hideout/pokeemerald-expansion/pull/4841)
+* Changes Evolution methods to `enum`s by @AlexOn1ine in [#4977](https://github.com/rh-hideout/pokeemerald-expansion/pull/4977)
+* Doesn't compile on some compilers by @AlexOn1ine in [#5099](https://github.com/rh-hideout/pokeemerald-expansion/pull/5099)
+* Update `event.inc` to accomodate new `gDecompressionBuffer` name by @Bassoonian in [#5100](https://github.com/rh-hideout/pokeemerald-expansion/pull/5100)
+* Created `COMPOUND_STRING`s for default player names by @fdeblasio in [#5037](https://github.com/rh-hideout/pokeemerald-expansion/pull/5037)
+* Changed single-use berry blender strings to be `COMPOUND_STRING`s by @fdeblasio in [#4963](https://github.com/rh-hideout/pokeemerald-expansion/pull/4963)
+* Made perfect IV count into a granular setting by @AsparagusEduardo in [#5115](https://github.com/rh-hideout/pokeemerald-expansion/pull/5115)
+* Dynamic move type clean up by @AlexOn1ine in [#5132](https://github.com/rh-hideout/pokeemerald-expansion/pull/5132)
+* Refactor Frontier Brains by @fdeblasio in [#5027](https://github.com/rh-hideout/pokeemerald-expansion/pull/5027)
+* Removed some hardcoding of move IDs + Gen4/5 Defog by @AsparagusEduardo in [#5156](https://github.com/rh-hideout/pokeemerald-expansion/pull/5156)
+* Teatime animations use `B_WAIT_TIME_LONG` by @AsparagusEduardo in [#5173](https://github.com/rh-hideout/pokeemerald-expansion/pull/5173)
+* Created PokeNav `COMPOUND_STRING`s by @fdeblasio in [#4983](https://github.com/rh-hideout/pokeemerald-expansion/pull/4983)
+* Removed `gBitTable` usage again by @hedara90 in [#5193](https://github.com/rh-hideout/pokeemerald-expansion/pull/5193)
+* Removed support for the original LCG random number generator by @tertu-m in [#5078](https://github.com/rh-hideout/pokeemerald-expansion/pull/5078)
+* Deprecate MMBN Names by @pkmnsnfrn in [#5240](https://github.com/rh-hideout/pokeemerald-expansion/pull/5240)
+* Convert 8 various to `callnatives` by @AsparagusEduardo in [#5172](https://github.com/rh-hideout/pokeemerald-expansion/pull/5172)
+* Converted PC strings to `COMPOUND_STRING`s by @fdeblasio in [#5314](https://github.com/rh-hideout/pokeemerald-expansion/pull/5314)
+* Cleaned up duplicate dynamic type functions by @AsparagusEduardo in [#5338](https://github.com/rh-hideout/pokeemerald-expansion/pull/5338)
+* Removes redundant `moveTargetType` ai function by @AlexOn1ine in [#5354](https://github.com/rh-hideout/pokeemerald-expansion/pull/5354)
+* Made `BuildColorMaps` redundant by using static tables by @pkmnsnfrn in [#5289](https://github.com/rh-hideout/pokeemerald-expansion/pull/5289)
+* Some strings were switched by @AlexOn1ine in [#5374](https://github.com/rh-hideout/pokeemerald-expansion/pull/5374)
+* Switch AI hitsToKO considers Disguise by @Pawkkie in [#5375](https://github.com/rh-hideout/pokeemerald-expansion/pull/5375)
+* Cleaned up a bit of code with `GetBattlerPartyData` by @AlexOn1ine in [#5378](https://github.com/rh-hideout/pokeemerald-expansion/pull/5378)
+* Minor Gem check optimazation by @AlexOn1ine in [#5401](https://github.com/rh-hideout/pokeemerald-expansion/pull/5401)
+* Simplify HP Logic by @AreaZR in [#5403](https://github.com/rh-hideout/pokeemerald-expansion/pull/5403)
+* Anger Shell use `saveattacker` by @ghoulslash in [#5409](https://github.com/rh-hideout/pokeemerald-expansion/pull/5409)
+* Converted berry and PokeBlock strings to `COMPOUND_STRING`s by @fdeblasio in [#5324](https://github.com/rh-hideout/pokeemerald-expansion/pull/5324)
+* Merge item description branch history by @Bassoonian in [#5419](https://github.com/rh-hideout/pokeemerald-expansion/pull/5419)
+* Clean up Unseen Fist Check by @AlexOn1ine in [#5420](https://github.com/rh-hideout/pokeemerald-expansion/pull/5420)
+* Merge level_caps and ev_caps into one caps file by @kittenchilly in [#5429](https://github.com/rh-hideout/pokeemerald-expansion/pull/5429)
+* Removed trailing whitespace pass 10-2-2024 (Upcoming) by @kittenchilly in [#5456](https://github.com/rh-hideout/pokeemerald-expansion/pull/5456)
+* Fixed Commander test name by @Bassoonian in [#5458](https://github.com/rh-hideout/pokeemerald-expansion/pull/5458)
+* Updated species defines by @pkmnsnfrn in [#5075](https://github.com/rh-hideout/pokeemerald-expansion/pull/5075)
+* Adds padding in `AiLogicData` by @AlexOn1ine in [#5468](https://github.com/rh-hideout/pokeemerald-expansion/pull/5468)
+* Simplify `BS_FAINTED_MULTIPLE_1` double battle logic in openpartyscreen by @ghoulslash in [#5435](https://github.com/rh-hideout/pokeemerald-expansion/pull/5435)
+* Removes duplicate code in AI functions by @AlexOn1ine in [#5457](https://github.com/rh-hideout/pokeemerald-expansion/pull/5457)
+* `ShouldPivot` type cleanup by @Pawkkie in [#5441](https://github.com/rh-hideout/pokeemerald-expansion/pull/5441)
+* Turn item hold effects into an enum by @Bassoonian in [#5498](https://github.com/rh-hideout/pokeemerald-expansion/pull/5498)
+* Unify `GetBattlerAbility`/`TerrainAffected` to remove duplicate ai function by @AlexOn1ine in [#5497](https://github.com/rh-hideout/pokeemerald-expansion/pull/5497)
+* Clean up Shedinja code by @Bassoonian in [#5501](https://github.com/rh-hideout/pokeemerald-expansion/pull/5501)
+* Clean up `scrcmd` PR by @Bassoonian in [#5511](https://github.com/rh-hideout/pokeemerald-expansion/pull/5511)
+* Removes Crit Chance preproc by @AlexOn1ine in [#5520](https://github.com/rh-hideout/pokeemerald-expansion/pull/5520)
+* Removed agbcc screenshots from gitignore by @Bassoonian in [#5538](https://github.com/rh-hideout/pokeemerald-expansion/pull/5538)
+* Removed unnecessary `gBattlerAttacker` usage by @AlexOn1ine in [#5554](https://github.com/rh-hideout/pokeemerald-expansion/pull/5554)
+* Removed remaining line breaks from #3240 + Prefix wrap fix by @AsparagusEduardo in [#5556](https://github.com/rh-hideout/pokeemerald-expansion/pull/5556)
+* More post-#3240 cleanup by @kittenchilly in [#5593](https://github.com/rh-hideout/pokeemerald-expansion/pull/5593)
+* Renamed folders and symbols to match species defines by @AsparagusEduardo in [#5581](https://github.com/rh-hideout/pokeemerald-expansion/pull/5581)
+ - Also:
+ - Burmy and Wormadam footprints were in a `plant` subfolder. They have been moved to the species root folder
+ - Paldean Wooper's subfolder was named `wooper_paldean` instead of just `paldean`. This has been corrected.
+ - Zen Mode Galarian Darmanitan's folder was located in `darmanitan/galarian/zen_mode`. This has been corrected to `darmanitan/galar_zen`, alongside Galarian Standard Mode's `darmanitan/galar_standard`.
+ - Also updated Ogerpon's folders similarly.
+ - Renamed `SPECIES_PIKACHU_PARTNER_CAP` to `SPECIES_PIKACHU_PARTNER`.
+* Minor `BattleStruct` clean up by @AlexOn1ine in [#5585](https://github.com/rh-hideout/pokeemerald-expansion/pull/5585)
+* Fixed a ball update oversight by @Bassoonian in [#5609](https://github.com/rh-hideout/pokeemerald-expansion/pull/5609)
+* `AI_FLAG_ACE_POKEMON` takes into account separate trainers by @GhoulMage and @/uvula on Discord noted the weird behaviour in [#5608](https://github.com/rh-hideout/pokeemerald-expansion/pull/5608)
+ - Fix for the AI not considering both trainers Ace Pokémons in double battles with `AI_FLAG_ACE_POKEMON`.
+* Moves that deal a Fixed amount don't need AI handling by @AlexOn1ine in [#5614](https://github.com/rh-hideout/pokeemerald-expansion/pull/5614)
+* Combines `CalculateMoveDamage` arguments into a struct by @AlexOn1ine in [#5570](https://github.com/rh-hideout/pokeemerald-expansion/pull/5570)
+* Follow up for #5570 by @AlexOn1ine in [#5625](https://github.com/rh-hideout/pokeemerald-expansion/pull/5625)
+* `AI_CalcDamage` clean up by @AlexOn1ine in [#5629](https://github.com/rh-hideout/pokeemerald-expansion/pull/5629)
+* Convert 3 variouses to `callnatives` by @AlexOn1ine in [#5646](https://github.com/rh-hideout/pokeemerald-expansion/pull/5646)
+* Convert `gBattleStringsTable` to `COMPOUND_STRING`s by @AsparagusEduardo in [#5649](https://github.com/rh-hideout/pokeemerald-expansion/pull/5649)
+* Added merged placeholder text for trainer name with class by @kittenchilly in [#5622](https://github.com/rh-hideout/pokeemerald-expansion/pull/5622)
+* Cleans up Primal Reversion code by @AlexOn1ine in [#5659](https://github.com/rh-hideout/pokeemerald-expansion/pull/5659)
+* Critical Hit documentation and distorted match up struct switch by @AlexOn1ine in [#5665](https://github.com/rh-hideout/pokeemerald-expansion/pull/5665)
+* Changes name of `B_SCR_NAME_WITH_PREFIX` by @AlexOn1ine in [#5675](https://github.com/rh-hideout/pokeemerald-expansion/pull/5675)
+* Removes redundant Decorate check by @AlexOn1ine in [#5696](https://github.com/rh-hideout/pokeemerald-expansion/pull/5696)
+* Changes taget bit of Flower Shield by @AlexOn1ine in [#5698](https://github.com/rh-hideout/pokeemerald-expansion/pull/5698)
+* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547)
+ - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1.
+
+## 🧪 Test Runner 🧪
+### Changed
+* Fixed Commander test name by @Bassoonian in [#5458](https://github.com/rh-hideout/pokeemerald-expansion/pull/5458)
+* `ShouldSwitchIfGameStatePrompt` Tests by @Pawkkie in [#5462](https://github.com/rh-hideout/pokeemerald-expansion/pull/5462)
+* Added various tests, add `RNG_RANDOM_TARGET` by @ghoulslash in [#5438](https://github.com/rh-hideout/pokeemerald-expansion/pull/5438)
+* Added Costar Tests, Download Test for Doubles by @ghoulslash in [#5526](https://github.com/rh-hideout/pokeemerald-expansion/pull/5526)
+* Updated Wring Out effects to match Eruption effects by @AsparagusEduardo in [#5549](https://github.com/rh-hideout/pokeemerald-expansion/pull/5549)
+ - Changed Wring Out/Crush Grip/Hard Press to use `power` instead of `argument` to determine its max power, just like how Eruption/Water Spout/Dragon Energy do it. Also:
+ - Renamed `EFFECT_VARY_POWER_BASED_ON_HP` to `EFFECT_POWER_BASED_ON_TARGET_HP`
+ - Renamed `EFFECT_ERUPTION` to `EFFECT_POWER_BASED_ON_USER_HP`
+* Healer ability tests by @Pawkkie in [#5559](https://github.com/rh-hideout/pokeemerald-expansion/pull/5559)
+* Mark all tests as used by @mrgriffin in [#5531](https://github.com/rh-hideout/pokeemerald-expansion/pull/5531)
+
+### Fixed
+* Should switch refactor to facilitate switch prediction by @Pawkkie in [#5466](https://github.com/rh-hideout/pokeemerald-expansion/pull/5466)
+
+## 📚 Documentation 📚
+* `DoBattleIntro` state documentation by @AsparagusEduardo and @ShinyDragonHunter in [#5231](https://github.com/rh-hideout/pokeemerald-expansion/pull/5231)
+* Deprecate MMBN Names by @pkmnsnfrn in [#5240](https://github.com/rh-hideout/pokeemerald-expansion/pull/5240)
+* `AI_FLAG_SETUP_FIRST_TURN` Rename and Clarifications by @Pawkkie in [#5310](https://github.com/rh-hideout/pokeemerald-expansion/pull/5310)
+* Added Composite AI Flags to Docs by @Pawkkie in [#5349](https://github.com/rh-hideout/pokeemerald-expansion/pull/5349)
+* Updated the new pokemon tutorial for 1.10 by @hedara90 in [#5721](https://github.com/rh-hideout/pokeemerald-expansion/pull/5721)
+ - Some changes compared to previous.
+
+## New Contributors
+* @SombrAbsol made their first contribution in [#4958](https://github.com/rh-hideout/pokeemerald-expansion/pull/4958)
+* @Galaxeeh made their first contribution in [#5084](https://github.com/rh-hideout/pokeemerald-expansion/pull/5084)
+* @Flash1Lucky made their first contribution in [#5269](https://github.com/rh-hideout/pokeemerald-expansion/pull/5269)
+* @GhoulMage made their first contribution in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547)
+
+**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.9.4...expansion/1.10.0
+
+
+
diff --git a/docs/changelogs/1.10.x/1.10.1.md b/docs/changelogs/1.10.x/1.10.1.md
new file mode 100644
index 0000000000..4eb4ea8e0d
--- /dev/null
+++ b/docs/changelogs/1.10.x/1.10.1.md
@@ -0,0 +1,140 @@
+# Version 1.10.1
+
+```md
+## How to update
+- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
+- Once you have your remote set up, run the command `git pull RHH expansion/1.10.1`.
+```
+
+## 🧬 General 🧬
+### Added
+* Added `FONT_SHORT_NARROWER` by @AsparagusEduardo (commit originally by @agsmgmaster64) in [#5101](https://github.com/rh-hideout/pokeemerald-expansion/pull/5101)
+ * Narrower font tweaks and font fitting fixes by @kittenchilly in [#5782](https://github.com/rh-hideout/pokeemerald-expansion/pull/5782)
+
+### Changed
+* Adds Thief/Covet config to send stolen item to bag and Pickup config to pickup user's item in wild battles by @PhallenTree in [#5829](https://github.com/rh-hideout/pokeemerald-expansion/pull/5829)
+
+### Fixed
+* trainerproc: Fix showing incorrect error context by @mrgriffin in [#5769](https://github.com/rh-hideout/pokeemerald-expansion/pull/5769)
+* Fixes UB in caps.c by @AlexOn1ine in [#5878](https://github.com/rh-hideout/pokeemerald-expansion/pull/5878)
+
+## 🗺️ Overworld 🗺️
+### Fixed
+* Fix Off-by-One Error in Move Relearner by @iriv24 and @luckytyphlosion in [#5778](https://github.com/rh-hideout/pokeemerald-expansion/pull/5778)
+* Fix HGSS dex sort orders working incorrectly by @ravepossum in [#5790](https://github.com/rh-hideout/pokeemerald-expansion/pull/5790)
+* Egg cycle length fix by @hedara90 and @/BolaDeQueijo on discord discovered the issue. in [#5828](https://github.com/rh-hideout/pokeemerald-expansion/pull/5828)
+* Fixed givemon not respecting perfect IVs for species by @AsparagusEduardo in [#5873](https://github.com/rh-hideout/pokeemerald-expansion/pull/5873)
+ - Also removed redundant `RemoveIVIndexFromList` function in `src/daycare.c`, so it uses `src/pokemon.c`'s instead
+* Fix Script Scrollable Multichoice Arrow Positions by @ghoulslash in [#5884](https://github.com/rh-hideout/pokeemerald-expansion/pull/5884)
+
+## 🐉 Pokémon 🐉
+### Changed
+* Updated Ogerpon, Enamorus and Sinistcha sprites by @kittenchilly in [#5793](https://github.com/rh-hideout/pokeemerald-expansion/pull/5793)
+* New Enamorus-Incarnate sprite by @kittenchilly in [#5797](https://github.com/rh-hideout/pokeemerald-expansion/pull/5797)
+
+### Fixed
+* Fixes Wormadam define for teachable learnset script by @AlexOn1ine in [#5783](https://github.com/rh-hideout/pokeemerald-expansion/pull/5783)
+* Fix "PlantCloak" references by @AsparagusEduardo in [#5821](https://github.com/rh-hideout/pokeemerald-expansion/pull/5821)
+* Misc pokemon sprite fixes by @Cafeei in [#5846](https://github.com/rh-hideout/pokeemerald-expansion/pull/5846)
+
+## ⚔️ Battle General ⚔️
+### Changed
+* Adds Thief/Covet config to send stolen item to bag and Pickup config to pickup user's item in wild battles by @PhallenTree in [#5829](https://github.com/rh-hideout/pokeemerald-expansion/pull/5829)
+
+### Fixed
+* Fixes items preventing other switch in effects by @AlexOn1ine in [#5732](https://github.com/rh-hideout/pokeemerald-expansion/pull/5732)
+* Fix Pokemon with No Guard failing OHKO Moves into Semi-Invulnerable Pokemon by @iriv24 and @Cafeei in [#5779](https://github.com/rh-hideout/pokeemerald-expansion/pull/5779)
+* Fix move category and category icon when PSS is off by @ravepossum in [#5786](https://github.com/rh-hideout/pokeemerald-expansion/pull/5786)
+* Added the missing config to use new terrains by @hedara90 in [#5792](https://github.com/rh-hideout/pokeemerald-expansion/pull/5792)
+* Fixes Shed Tail substitute health by @AlexOn1ine in [#5826](https://github.com/rh-hideout/pokeemerald-expansion/pull/5826)
+* `B_LAST_USED_BALL` and `.importance` by @AERDU in [#5834](https://github.com/rh-hideout/pokeemerald-expansion/pull/5834)
+ - prevents `B_LAST_USED_BALL` from removing balls with `.importance = 1`
+* Fixes Quash-affected battlers having the wrong order for End Turn effects by @PhallenTree in [#5838](https://github.com/rh-hideout/pokeemerald-expansion/pull/5838)
+* Fixes Cotton Down and Gulp Missile not interacting correctly with stat reduction prevention effects by @PhallenTree in [#5841](https://github.com/rh-hideout/pokeemerald-expansion/pull/5841)
+* Fix Hit Escape moves giving Exp to the mon that switches in by @kittenchilly in [#5844](https://github.com/rh-hideout/pokeemerald-expansion/pull/5844)
+* Fixed Wish triggering Disguise by @AsparagusEduardo in [#5860](https://github.com/rh-hideout/pokeemerald-expansion/pull/5860)
+* Fixed `MOVE_EFFECT_FREEZE_OR_FROSTBITE` not being usable in battle scripts by @AsparagusEduardo in [#5859](https://github.com/rh-hideout/pokeemerald-expansion/pull/5859)
+* Fixed Ally Switch breaking Illusion by @AsparagusEduardo in [#5879](https://github.com/rh-hideout/pokeemerald-expansion/pull/5879)
+* Fixes gen3 Style Shadows out of place by @AlexOn1ine in [#5880](https://github.com/rh-hideout/pokeemerald-expansion/pull/5880)
+* Fix Salt Cure script by @ghoulslash in [#5895](https://github.com/rh-hideout/pokeemerald-expansion/pull/5895)
+* Fixes Eject Pack / Intimidate issue by @AlexOn1ine in [#5902](https://github.com/rh-hideout/pokeemerald-expansion/pull/5902)
+* Adds Generational config for Magic Guard (Fix for Gen4+) by @AlexOn1ine in [#5893](https://github.com/rh-hideout/pokeemerald-expansion/pull/5893)
+* Fixes Stance Change, Sleep Talk interaction by @AlexOn1ine in [#5909](https://github.com/rh-hideout/pokeemerald-expansion/pull/5909)
+* Fixes Round doubling it's BP if previous Round failed by @AlexOn1ine in [#5907](https://github.com/rh-hideout/pokeemerald-expansion/pull/5907)
+
+## 🤹 Moves 🤹
+### Fixed
+* Fixes absorb still draining HP when flinched by @AlexOn1ine in [#5814](https://github.com/rh-hideout/pokeemerald-expansion/pull/5814)
+* Fixes Tidy Up by @AlexOn1ine in [#5819](https://github.com/rh-hideout/pokeemerald-expansion/pull/5819)
+* Ally Switch extra battlerId tracking by @ghoulslash in [#5823](https://github.com/rh-hideout/pokeemerald-expansion/pull/5823)
+* Sheer Force fix and move effect cleanup by @AlexOn1ine in [#5812](https://github.com/rh-hideout/pokeemerald-expansion/pull/5812)
+* New U-turn animation to fix visibility by @AlexOn1ine in [#5910](https://github.com/rh-hideout/pokeemerald-expansion/pull/5910)
+
+## 🧶 Items 🧶
+### Fixed
+* Prevent Key Items that open other menus from causing a crash if registered and used from the field by @iriv24 in [#5810](https://github.com/rh-hideout/pokeemerald-expansion/pull/5810)
+* Fixes Clear Amulet displaying the wrong battler and Starting Status displaying the wrong message by @PhallenTree in [#5831](https://github.com/rh-hideout/pokeemerald-expansion/pull/5831)
+* Fixes Room Service lowering the opposite mon in specific scenario by @AlexOn1ine in [#5827](https://github.com/rh-hideout/pokeemerald-expansion/pull/5827)
+
+## 🤖 Battle AI 🤖
+### Fixed
+* Fixed ace switching bugs by @Pawkkie and @iriv24 for their diligent testing and debugging support in [#5922](https://github.com/rh-hideout/pokeemerald-expansion/pull/5922)
+
+## 🧹 Other Cleanup 🧹
+* Converted Stance Change to proper Form Change + Tests by @AsparagusEduardo in [#5749](https://github.com/rh-hideout/pokeemerald-expansion/pull/5749)
+* Removed testing strings for automatic line breaks by @hedara90 in [#5757](https://github.com/rh-hideout/pokeemerald-expansion/pull/5757)
+* Added NBSP and up+down arrows to all fonts by @hedara90 in [#5767](https://github.com/rh-hideout/pokeemerald-expansion/pull/5767)
+ - Use `~` or `{NBSP}` to insert a non-breaking space into a string.
+* Palette cleanup by @hedara90 in [#5661](https://github.com/rh-hideout/pokeemerald-expansion/pull/5661)
+ - Resized some move anim palettes from 256 to 16
+* Replace power checks with IS_MOVE_STATUS by @Bassoonian and @AsparagusEduardo in [#5820](https://github.com/rh-hideout/pokeemerald-expansion/pull/5820)
+* Changes Various defines to an Enum by @AsparagusEduardo in [#5840](https://github.com/rh-hideout/pokeemerald-expansion/pull/5840)
+* Fix `IS_MOVE_STATUS` regression by @Bassoonian in [#5848](https://github.com/rh-hideout/pokeemerald-expansion/pull/5848)
+* Remove unused various by @Bassoonian in [#5851](https://github.com/rh-hideout/pokeemerald-expansion/pull/5851)
+* Removed redundant call to FillPalBufferBlack in FRLG whiteout sequence by @AsparagusEduardo in [#5854](https://github.com/rh-hideout/pokeemerald-expansion/pull/5854)
+* Improve README.md by @AsparagusEduardo in [#5640](https://github.com/rh-hideout/pokeemerald-expansion/pull/5640)
+* Fix wrong value for NUM_MOVE_EFFECTS by @Bassoonian in [#5913](https://github.com/rh-hideout/pokeemerald-expansion/pull/5913)
+* Renamed OW type effectiveness function for clarity by @AsparagusEduardo in [#5917](https://github.com/rh-hideout/pokeemerald-expansion/pull/5917)
+ - Renamed `GetTypeEffectiveness` to `GetOverworldTypeEffectiveness`.
+
+## 🧪 Test Runner 🧪
+### Changed
+* Gravity fix + Sky Drop Test by @ghoulslash in [#5780](https://github.com/rh-hideout/pokeemerald-expansion/pull/5780)
+* Added missing Belch tests by @AsparagusEduardo in [#5881](https://github.com/rh-hideout/pokeemerald-expansion/pull/5881)
+* Added missing Move Effect TODO tests - Volume D by @AsparagusEduardo in [#5887](https://github.com/rh-hideout/pokeemerald-expansion/pull/5887)
+* Comment out Ally Switch Illusion test by @AsparagusEduardo in [#5901](https://github.com/rh-hideout/pokeemerald-expansion/pull/5901)
+* Fixed leaking tasks not showing up in summary by @AsparagusEduardo in [#5890](https://github.com/rh-hideout/pokeemerald-expansion/pull/5890)
+* Setting Battle configs during tests by @AsparagusEduardo and @SBird1337, @mrgriffin in [#5803](https://github.com/rh-hideout/pokeemerald-expansion/pull/5803)
+* Speed up tests in headless mode by @AsparagusEduardo and @SBird1337 for the original fast intro code. in [#5889](https://github.com/rh-hideout/pokeemerald-expansion/pull/5889)
+ - This introduced the config option `B_FAST_INTRO_NO_SLIDE` which removes the sliding into for battles.
+* Added missing Move Effect TODO tests - Volume E by @AsparagusEduardo in [#5915](https://github.com/rh-hideout/pokeemerald-expansion/pull/5915)
+
+### Fixed
+* Fix test `TIMEOUT` messaging in summary by @AsparagusEduardo in [#5772](https://github.com/rh-hideout/pokeemerald-expansion/pull/5772)
+* Fix octolock + defiant by @ghoulslash in [#5781](https://github.com/rh-hideout/pokeemerald-expansion/pull/5781)
+* Added missing tests + Fix Coaching/Crafty Shield interaction by @AsparagusEduardo in [#5796](https://github.com/rh-hideout/pokeemerald-expansion/pull/5796)
+* Fixed TODO tests not showing up when filtering by name by @AsparagusEduardo in [#5894](https://github.com/rh-hideout/pokeemerald-expansion/pull/5894)
+
+## 📚 Documentation 📚
+* Fixed changelog links to changelog 1.10 by @AsparagusEduardo in [#5758](https://github.com/rh-hideout/pokeemerald-expansion/pull/5758)
+* Added scope document and made changes to pull request template by @pkmnsnfrn and @Pawkkie and arguably the entire senate in [#5706](https://github.com/rh-hideout/pokeemerald-expansion/pull/5706)
+* Added instructions in PR template to make crediting people more clear by @pkmnsnfrn and @AsparagusEduardo made changes to my text in [#5755](https://github.com/rh-hideout/pokeemerald-expansion/pull/5755)
+* Fix website not showing the "How to add mon" 1.10 tutorial by @AsparagusEduardo in [#5813](https://github.com/rh-hideout/pokeemerald-expansion/pull/5813)
+* Install instructions by @hedara90 in [#5876](https://github.com/rh-hideout/pokeemerald-expansion/pull/5876)
+* Change install.md to mention make debug instead of DINFO=1 by @ravepossum in [#5882](https://github.com/rh-hideout/pokeemerald-expansion/pull/5882)
+* Backport changes from the wiki by @AsparagusEduardo in [#5900](https://github.com/rh-hideout/pokeemerald-expansion/pull/5900)
+* Improve README.md by @AsparagusEduardo in [#5640](https://github.com/rh-hideout/pokeemerald-expansion/pull/5640)
+
+## 📦 Branch Synchronisation 📦
+### pret
+* 20th of December in [#5845](https://github.com/rh-hideout/pokeemerald-expansion/pull/5845)
+ * Fix recorded battle link player loops by @AsparagusEduardo in [pret#2071](https://github.com/pret/pokeemerald/pull/2071)
+ * Added `POKEMART_LIST_END` to avoid users accidentally removing it by @AsparagusEduardo in [pret#1947](https://github.com/pret/pokeemerald/pull/1947)
+ * Fixed brace style inconsistencies by @AsparagusEduardo in [pret#2072](https://github.com/pret/pokeemerald/pull/2072)
+ * remove `sBirchSpeechPlatformBlackPal` by @DizzyEggg in [pret#2075](https://github.com/pret/pokeemerald/pull/2075)
+
+
+**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.10.0...expansion/1.10.1
+
+
+
diff --git a/docs/changelogs/1.9.x/1.9.4.md b/docs/changelogs/1.9.x/1.9.4.md
new file mode 100644
index 0000000000..2a41988bd4
--- /dev/null
+++ b/docs/changelogs/1.9.x/1.9.4.md
@@ -0,0 +1,201 @@
+# Version 1.9.4
+
+```md
+## How to update
+- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`.
+- Once you have your remote set up, run the command `git pull RHH expansion/1.9.4`.
+```
+
+## 🌋 IMPORTANT 🌋
+- This update integrates pret's latest Makefile changes, which rearranges the entire file in order to speed up compilation times overall. If you did any changes to it (such as installing Poryscript) and are having issues resolving the conflicts, keep expansion's version of Makefile and reapply your changes afterwards.
+
+## 🧬 General 🧬
+### Fixed
+* Fixed alignment errors in `EWRAM_INIT` and friends when using u8, u16, etc. by @aronson in [#5512](https://github.com/rh-hideout/pokeemerald-expansion/pull/5512)
+* Update test LD script to respect 4 byte data section alignment by @aronson in [#5517](https://github.com/rh-hideout/pokeemerald-expansion/pull/5517)
+* Fixed Missing `string_util.h` include in `mini_printf.c` by @mrgriffin in [#5572](https://github.com/rh-hideout/pokeemerald-expansion/pull/5572)
+* Fixed unnecessary dependency scanning for test build and test rom names by @ravepossum in [#5594](https://github.com/rh-hideout/pokeemerald-expansion/pull/5594)
+* Fixed makefile: dependencies for `map_group_count.h` by @SBird1337 in [#5648](https://github.com/rh-hideout/pokeemerald-expansion/pull/5648)
+ - Fixes an issue that caused the build to fail on updates to `src/debug.c` due to mismatched dependency.
+
+## 🗺️ Overworld 🗺️
+### Changed
+* Followers sprite fixes by @Cafeei in [#5669](https://github.com/rh-hideout/pokeemerald-expansion/pull/5669)
+* Follower fixes, Melmetal, Patrat, Woobat by @hedara90 in [#5685](https://github.com/rh-hideout/pokeemerald-expansion/pull/5685)
+* Fixed Farfetch'd overworld sprite by @hedara90 in [#5711](https://github.com/rh-hideout/pokeemerald-expansion/pull/5711)
+
+### Fixed
+* Fixed Berry mutations always generating a Persim Berry by @Bassoonian in [#5504](https://github.com/rh-hideout/pokeemerald-expansion/pull/5504)
+
+## 🐉 Pokémon 🐉
+### Changed
+* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547)
+ - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1.
+* PokeCommunity sprites batch (October) by @kittenchilly in [#5655](https://github.com/rh-hideout/pokeemerald-expansion/pull/5655)
+* Followers sprite fixes by @Cafeei in [#5669](https://github.com/rh-hideout/pokeemerald-expansion/pull/5669)
+* Follower fixes, Melmetal, Patrat, Woobat by @hedara90 in [#5685](https://github.com/rh-hideout/pokeemerald-expansion/pull/5685)
+* Fixed Farfetch'd overworld sprite by @hedara90 in [#5711](https://github.com/rh-hideout/pokeemerald-expansion/pull/5711)
+
+### Fixed
+* Fixed `P_FRIENDSHIP_EVO_THRESHOLD` not checking for Gen 8 by @kittenchilly in [#5503](https://github.com/rh-hideout/pokeemerald-expansion/pull/5503)
+* Fixed HGSS dex search printing wrong mon after selecting evos by @ravepossum in [#5552](https://github.com/rh-hideout/pokeemerald-expansion/pull/5552)
+* Fixed 64px uncompressed followers by @hedara90 in [#5601](https://github.com/rh-hideout/pokeemerald-expansion/pull/5601)
+* Deoxys Sprite/Animation Fixes by @SarnPoke in [#5603](https://github.com/rh-hideout/pokeemerald-expansion/pull/5603)
+* Fixes Aegislash not reverting back by @AlexOn1ine in [#5734](https://github.com/rh-hideout/pokeemerald-expansion/pull/5734)
+
+## ⚔️ Battle General ⚔️
+### Changed
+* Fixed damage calc modifiers by @AlexOn1ine in [#5604](https://github.com/rh-hideout/pokeemerald-expansion/pull/5604)
+
+### Fixed
+* Fixed Shiny Pokemon not being shiny after transforming with a gimmick by @hedara90 in [#5573](https://github.com/rh-hideout/pokeemerald-expansion/pull/5573)
+* Handle showdowns apostrophe the same way as ASCII apostrophe by @cawtds in [#5712](https://github.com/rh-hideout/pokeemerald-expansion/pull/5712)
+* Fixes Misty Terrain displaying wrong message by @AlexOn1ine in [#5742](https://github.com/rh-hideout/pokeemerald-expansion/pull/5742)
+* Fixes Dynamax dynamic move type by @AlexOn1ine in [#5739](https://github.com/rh-hideout/pokeemerald-expansion/pull/5739)
+
+## 🤹 Moves 🤹
+### Changed
+* Fixed damage calc modifiers by @AlexOn1ine in [#5604](https://github.com/rh-hideout/pokeemerald-expansion/pull/5604)
+* Updated ability popups for Skill Swap, Mummy/Lingering Aroma, Worry Seed, Simple Beam, fix Doodle/Role Play bugs by @PhallenTree in [#5493](https://github.com/rh-hideout/pokeemerald-expansion/pull/5493)
+
+### Fixed
+* Fixed Follow Me failing in Single Battles for Gen 6/7 config by @AsparagusEduardo in [#5542](https://github.com/rh-hideout/pokeemerald-expansion/pull/5542)
+* Fixed `AnimTask_HorizontalShake` uses for shaking screen in battle anims by @ghoulslash in [#5562](https://github.com/rh-hideout/pokeemerald-expansion/pull/5562)
+* Fixed weather genie move anims and Springtide Storm targets by @ravepossum in [#5553](https://github.com/rh-hideout/pokeemerald-expansion/pull/5553)
+* Fixes Magic Guard not preventing Salt Cure by @AlexOn1ine in [#5583](https://github.com/rh-hideout/pokeemerald-expansion/pull/5583)
+* Fixes Dragon Tail using the effect twice during a Parental Bond attack by @AlexOn1ine in [#5630](https://github.com/rh-hideout/pokeemerald-expansion/pull/5630)
+* Fixes Magic Coat message by @AlexOn1ine in [#5645](https://github.com/rh-hideout/pokeemerald-expansion/pull/5645)
+* Fixes Take heart by @AlexOn1ine in [#5658](https://github.com/rh-hideout/pokeemerald-expansion/pull/5658)
+* Fixed Floral Healing anim by @AlexOn1ine in [#5733](https://github.com/rh-hideout/pokeemerald-expansion/pull/5733)
+* Fixes Population Bomb / Triple Kick missing message by @AlexOn1ine in [#5747](https://github.com/rh-hideout/pokeemerald-expansion/pull/5747)
+* Changes Max Phantasm move anim script call by @AlexOn1ine in [#5737](https://github.com/rh-hideout/pokeemerald-expansion/pull/5737)
+* Fixes Partner targeting and Acupressure/Ally Switch interaction by @AlexOn1ine in [#5446](https://github.com/rh-hideout/pokeemerald-expansion/pull/5446)
+* Revival Blessing fixes + Using Lunar Blessing's animation by @ghoulslash in [#5490](https://github.com/rh-hideout/pokeemerald-expansion/pull/5490)
+* Fixed curse + Protean interaction by @hedara90 in [#5663](https://github.com/rh-hideout/pokeemerald-expansion/pull/5663)
+* Added Minimize interaction to Supercell Slam by @hedara90 in [#5713](https://github.com/rh-hideout/pokeemerald-expansion/pull/5713)
+
+## 🎭 Abilities 🎭
+### Changed
+* Fixed damage calc modifiers by @AlexOn1ine in [#5604](https://github.com/rh-hideout/pokeemerald-expansion/pull/5604)
+
+### Fixed
+* Adds tests and Costar fix from PR #5526 by @AlexOn1ine in [#5529](https://github.com/rh-hideout/pokeemerald-expansion/pull/5529)
+* Fixes Red Card / Eject Pack interaction with Emergency Exit by @AlexOn1ine in [#5657](https://github.com/rh-hideout/pokeemerald-expansion/pull/5657)
+* Fixed curse + Protean interaction by @hedara90 in [#5663](https://github.com/rh-hideout/pokeemerald-expansion/pull/5663)
+* Mimicry updates typing with `RemoveAllTerrains()` by @AERDU in [#5666](https://github.com/rh-hideout/pokeemerald-expansion/pull/5666)
+* Updated ability popups for Skill Swap, Mummy/Lingering Aroma, Worry Seed, Simple Beam, fix Doodle/Role Play bugs by @PhallenTree in [#5493](https://github.com/rh-hideout/pokeemerald-expansion/pull/5493)
+* Fixed curse + Protean interaction by @hedara90 in [#5663](https://github.com/rh-hideout/pokeemerald-expansion/pull/5663)
+* Fixes Ice Face regression by @AlexOn1ine in [#5678](https://github.com/rh-hideout/pokeemerald-expansion/pull/5678)
+* Fixes Neutralizing Gas crashes + adds missing interaction, Regenerator small fix by @PhallenTree in [#5694](https://github.com/rh-hideout/pokeemerald-expansion/pull/5694)
+
+## 🧶 Items 🧶
+### Changed
+* Removes duplicate Booster Energy code by @AlexOn1ine in [#5656](https://github.com/rh-hideout/pokeemerald-expansion/pull/5656)
+
+### Fixed
+* Fixes Red Card / Eject Pack interaction with Emergency Exit by @AlexOn1ine in [#5657](https://github.com/rh-hideout/pokeemerald-expansion/pull/5657)
+* Fixes Red Card / Eject Pack interaction by @AlexOn1ine in [#5724](https://github.com/rh-hideout/pokeemerald-expansion/pull/5724)
+* Fixes gems triggering on confusion damage by @AlexOn1ine in [#5723](https://github.com/rh-hideout/pokeemerald-expansion/pull/5723)
+* Fixes Kee Maranga and Enigma Berry by @AlexOn1ine in [#5727](https://github.com/rh-hideout/pokeemerald-expansion/pull/5727)
+* Fixes Blunder Policy by @AlexOn1ine in [#5722](https://github.com/rh-hideout/pokeemerald-expansion/pull/5722)
+* Fixes Rusted Shield/Sword allowed to be Knocked Off from Zamazenta/Zacian by @iriv24 in [#5750](https://github.com/rh-hideout/pokeemerald-expansion/pull/5750)
+
+## 🤖 Battle AI 🤖
+### Fixed
+* Fixed certain move data being cleared on turn end by @Pawkkie and @AlexOn1ine in [#5488](https://github.com/rh-hideout/pokeemerald-expansion/pull/5488)
+* Global is used instead of passed var by @AlexOn1ine in [#5546](https://github.com/rh-hideout/pokeemerald-expansion/pull/5546)
+* Fixes `dynamicMoveType` global not being reset during AI calcs by @AlexOn1ine in [#5628](https://github.com/rh-hideout/pokeemerald-expansion/pull/5628)
+
+## 🧹 Other Cleanup 🧹
+* Remove one redundant call of `SetAiLogicDataForTurn` in `DoBattleIntro` by @AlexOn1ine in [#5491](https://github.com/rh-hideout/pokeemerald-expansion/pull/5491)
+* Cleanup extraneous function in `battle_anim.h` by @hedara90 in [#5506](https://github.com/rh-hideout/pokeemerald-expansion/pull/5506)
+* Add newline to move relearner string by @Bassoonian in [#5523](https://github.com/rh-hideout/pokeemerald-expansion/pull/5523)
+* Fixed 10,000,000 Volt Thunderbolt name by @AsparagusEduardo in [#5533](https://github.com/rh-hideout/pokeemerald-expansion/pull/5533)
+* Added constant to expansion inclusive copyright magic number by @pkmnsnfrn in [#5413](https://github.com/rh-hideout/pokeemerald-expansion/pull/5413)
+* Centralise AI Tests trainer name by @Bassoonian in [#5532](https://github.com/rh-hideout/pokeemerald-expansion/pull/5532)
+* Remove now outdated information from readme by @Bassoonian in [#5548](https://github.com/rh-hideout/pokeemerald-expansion/pull/5548)
+* Changing `EVO_NONE` from `0xFFFE` to `0` by @GhoulMage in [#5547](https://github.com/rh-hideout/pokeemerald-expansion/pull/5547)
+ - There could be a case for out of bounds errors if arrays or iterations are happening where you're using + 1 or - 1, as `EVO_FRIENDSHIP` used to be the first index although it started with 1.
+* Shed Skin chance fix by @Pawkkie in [#5558](https://github.com/rh-hideout/pokeemerald-expansion/pull/5558)
+* Restore test file dependencies so they're rebuilt properly by @ravepossum in [#5617](https://github.com/rh-hideout/pokeemerald-expansion/pull/5617)
+* Improve `SEND_OUT` error message; require Speed for all battlers by @mrgriffin in [#5631](https://github.com/rh-hideout/pokeemerald-expansion/pull/5631)
+* Removes duplicate Booster Energy code by @AlexOn1ine in [#5656](https://github.com/rh-hideout/pokeemerald-expansion/pull/5656)
+* Wrong assumtion in dauntless_shield.c by @AlexOn1ine in [#5692](https://github.com/rh-hideout/pokeemerald-expansion/pull/5692)
+
+## 🧪 Test Runner 🧪
+### Added
+* Add curious medicine test by @ghoulslash in [#5540](https://github.com/rh-hideout/pokeemerald-expansion/pull/5540)
+* Tests: detect task leaks by @mrgriffin in [#5528](https://github.com/rh-hideout/pokeemerald-expansion/pull/5528)
+
+### Changed
+* Add text width tests for move, ability, item, and pokedex descriptions by @kittenchilly in [#5505](https://github.com/rh-hideout/pokeemerald-expansion/pull/5505)
+* Centralise AI Tests trainer name by @Bassoonian in [#5532](https://github.com/rh-hideout/pokeemerald-expansion/pull/5532)
+* Add basic Steam Engine, Guard Dog Tests by @ghoulslash in [#5569](https://github.com/rh-hideout/pokeemerald-expansion/pull/5569)
+* Fixed damage test by @GhoulMage and @mrgriffin for teaching me pokeemerald-expansion tests in [#5574](https://github.com/rh-hideout/pokeemerald-expansion/pull/5574)
+* Fallback `memmem` implementation by @mrgriffin in [#5561](https://github.com/rh-hideout/pokeemerald-expansion/pull/5561)
+* Hydra: Support `%p` in test summaries by @mrgriffin in [#5626](https://github.com/rh-hideout/pokeemerald-expansion/pull/5626)
+* Improve `SEND_OUT` error message; require Speed for all battlers by @mrgriffin in [#5631](https://github.com/rh-hideout/pokeemerald-expansion/pull/5631)
+* Check that `PASSES_RANDOMLY` affected a `Random` call by @mrgriffin in [#5635](https://github.com/rh-hideout/pokeemerald-expansion/pull/5635)
+* Wrong assumtion in dauntless_shield.c by @AlexOn1ine in [#5692](https://github.com/rh-hideout/pokeemerald-expansion/pull/5692)
+
+### Fixed
+* Update test LD script to respect 4 byte data section alignment by @aronson in [#5517](https://github.com/rh-hideout/pokeemerald-expansion/pull/5517)
+* Adds tests and Costar fix from PR #5526 by @AlexOn1ine in [#5529](https://github.com/rh-hideout/pokeemerald-expansion/pull/5529)
+* Fixed broken Starting Terrain test by @hedara90 in [#5582](https://github.com/rh-hideout/pokeemerald-expansion/pull/5582)
+
+## 📚 Documentation 📚
+* Add changelog header in PR template to aid automation by @AsparagusEduardo in [#5539](https://github.com/rh-hideout/pokeemerald-expansion/pull/5539)
+* Added compressed OW mon VRAM notice in config file by @AsparagusEduardo in [#5599](https://github.com/rh-hideout/pokeemerald-expansion/pull/5599)
+* Update `README.md` to link to `INSTALL.md` by @Pawkkie in [#5720](https://github.com/rh-hideout/pokeemerald-expansion/pull/5720)
+* Fixes minor move desc errors by @AlexOn1ine in [#5728](https://github.com/rh-hideout/pokeemerald-expansion/pull/5728)
+
+## 📦 Branch Synchronisation 📦
+### pret
+* 15th of October in [#5527](https://github.com/rh-hideout/pokeemerald-expansion/pull/5527)
+ * Slight storage system documentation by @luckytyphlosion in [pret#2024](https://github.com/pret/pokeemerald/pull/2024)
+ * Clean up defines lacking spaces by @Bassoonian in [pret#2025](https://github.com/pret/pokeemerald/pull/2025)
+ * UB fix in battle_transition.c by @cawtds in [pret#2007](https://github.com/pret/pokeemerald/pull/2007)
+ * preproc: support arbitrary expressions in enums by @mrgriffin in [pret#2026](https://github.com/pret/pokeemerald/pull/2026)
+ * [Build System Rewrite] Refactored `Makefile` by @Icedude907 in [pret#1950](https://github.com/pret/pokeemerald/pull/1950)
+ * Fixed incorrect point macros in contest_ai_script.inc by @NTx86 in [pret#2028](https://github.com/pret/pokeemerald/pull/2028)
+ * [Build System Rewrite] Massive build speed improvement via scaninc changes by @Icedude907 in [pret#1954](https://github.com/pret/pokeemerald/pull/1954)
+ * [Build System Rewrite] Improved audio rules by @Icedude907 in [pret#1957](https://github.com/pret/pokeemerald/pull/1957)
+ * Update INSTALL.md to state that Windows 8 is no longer supported by Microsoft by @luciofstars in [pret#2029](https://github.com/pret/pokeemerald/pull/2029)
+ * Update pull_request_template.md to include Discord username update by @luciofstars in [pret#2030](https://github.com/pret/pokeemerald/pull/2030)
+ * remove ScriptContext_Enable from secret_base.h by @DizzyEggg in [pret#2032](https://github.com/pret/pokeemerald/pull/2032)
+ * Remove gflib by @Kurausukun in [pret#2033](https://github.com/pret/pokeemerald/pull/2033)
+ * Minor toolchain fixes by @GriffinRichards in [pret#2031](https://github.com/pret/pokeemerald/pull/2031)
+ * Bugfix for cable car hikerGraphicsIds array by @Scyrous in [pret#2039](https://github.com/pret/pokeemerald/pull/2039)
+ * Remove explicit symbol sizes in sym_common.txt by @GriffinRichards in [pret#2038](https://github.com/pret/pokeemerald/pull/2038)
+ * Ignore mGBA screenshots by @Jaizu in [pret#2041](https://github.com/pret/pokeemerald/pull/2041)
+ * Replaced copyright magic numbers in intro.c with constants by @pkmnsnfrn in [pret#2035](https://github.com/pret/pokeemerald/pull/2035)
+ * Fixed typo: | should be || in Task_TryFieldPoisonWhiteOut by @AreaZR in [pret#2044](https://github.com/pret/pokeemerald/pull/2044)
+ * [preproc] support C23 enum underlying type syntax by @mrgriffin in [pret#2043](https://github.com/pret/pokeemerald/pull/2043)
+ * Fixed deleting files with dependency files by @mid-kid in [pret#2045](https://github.com/pret/pokeemerald/pull/2045)
+ * Remove unnecessary looping for rule generation and unroll macros by @mid-kid in [pret#2046](https://github.com/pret/pokeemerald/pull/2046)
+ * Get rid of common syms by @luckytyphlosion in [pret#2040](https://github.com/pret/pokeemerald/pull/2040)
+ * Bugfix for cable car hikerGraphicsIds array by @Scyrous in [pret#2039](https://github.com/pret/pokeemerald/pull/2039)
+ * UB fix in battle_transition.c by @cawtds in [pret#2007](https://github.com/pret/pokeemerald/pull/2007)
+ * Fixed typo: | should be || in Task_TryFieldPoisonWhiteOut by @AreaZR in [pret#2044](https://github.com/pret/pokeemerald/pull/2044)
+ * Get rid of common syms by @luckytyphlosion in [pret#2040](https://github.com/pret/pokeemerald/pull/2040)
+ * Fixed incorrect point macros in contest_ai_script.inc by @NTx86 in [pret#2028](https://github.com/pret/pokeemerald/pull/2028)
+* 5th of November in [#5644](https://github.com/rh-hideout/pokeemerald-expansion/pull/5644)
+ * Added define value for bard sound length by @fdeblasio in [pret#2052](https://github.com/pret/pokeemerald/pull/2052)
+ * Silence 'Nothing to be done for generated' messages by @GriffinRichards in [pret#2059](https://github.com/pret/pokeemerald/pull/2059)
+ * Lay out emerald version png horizontally by @GriffinRichards in [pret#2062](https://github.com/pret/pokeemerald/pull/2062)
+* 29 of November in [#5736](https://github.com/rh-hideout/pokeemerald-expansion/pull/5736)
+ * Remove usage of gHeap in sSpritePalettes_ContestantsTurnBlinkEffect by @Lactozilla in [pret#2064](https://github.com/pret/pokeemerald/pull/2064)
+ * BUGFIX: Fix Counter and Mirror Coat checking the wrong category by @surtr-games in [pret#2066](https://github.com/pret/pokeemerald/pull/2066)
+ * Add TRY_DRAW_SPOT_PIXEL by @GriffinRichards in [pret#2055](https://github.com/pret/pokeemerald/pull/2055)
+ * Added extra encoded character support by @AsparagusEduardo in [pret#2050](https://github.com/pret/pokeemerald/pull/2050)
+### merrp's followers
+* Merrp merge (12th of October) by @Bassoonian in [#5514](https://github.com/rh-hideout/pokeemerald-expansion/pull/5514)
+ - d80190fe105eee12bbf74ae29647ac909084d35c fix: Dig in Sealed Chamber no longer freezes follower.
+
+## New Contributors
+* @AERDU made their first contribution in [#5666](https://github.com/rh-hideout/pokeemerald-expansion/pull/5666)
+
+**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.9.3...expansion/1.9.4
+
+
+
diff --git a/docs/install/chromeos/CHROME_OS.md b/docs/install/chromeos/CHROME_OS.md
new file mode 100644
index 0000000000..7fa57e5968
--- /dev/null
+++ b/docs/install/chromeos/CHROME_OS.md
@@ -0,0 +1,14 @@
+# Instructions for ChromeOS
+
+1. Enable the Linux terminal by following the instructions on [this page](https://chromeos.dev/en/productivity/terminal). Be sure to allocate enough space for the Linux install.
+2. After the Linux terminal has finished installing, run the following command in the terminal to update and upgrade the Linux terminal:
+
+ ```console
+ sudo apt update && apt upgrade
+ ```
+3. Then install all dependencies by running the following command:
+
+ ```console
+ sudo apt install build-essential binutils-arm-none-eabi gcc-arm-none-eabi libnewlib-arm-none-eabi git libpng-dev python3
+ ```
+**NOTE**: The project must be kept in a directory inside the Linux filesystem, for example under `~/Decomps/pokeemerald-expansion`
diff --git a/docs/install/linux/ARCH_LINUX.md b/docs/install/linux/ARCH_LINUX.md
new file mode 100644
index 0000000000..1d69e5c39c
--- /dev/null
+++ b/docs/install/linux/ARCH_LINUX.md
@@ -0,0 +1,6 @@
+# Arch Linux instructions
+## Installing dependencies
+Run the following command from the command line:
+```console
+sudo pacman -S base-devel arm-none-eabi-binutils arm-none-eabi-gcc arm-none-eabi-newlib git libpng python
+```
diff --git a/docs/install/linux/DEBIAN.md b/docs/install/linux/DEBIAN.md
new file mode 100644
index 0000000000..a63d3f985e
--- /dev/null
+++ b/docs/install/linux/DEBIAN.md
@@ -0,0 +1,6 @@
+# Debian instructions
+## Installing dependencies
+Open a terminal and run the following command from the command line:
+```console
+sudo apt install build-essential binutils-arm-none-eabi gcc-arm-none-eabi libnewlib-arm-none-eabi git libpng-dev python3
+```
diff --git a/docs/install/linux/NIXOS.md b/docs/install/linux/NIXOS.md
new file mode 100644
index 0000000000..6c613466b6
--- /dev/null
+++ b/docs/install/linux/NIXOS.md
@@ -0,0 +1,5 @@
+# NixOS instructions
+Run the following command to start an interactive shell with the necessary packages:
+```bash
+nix-shell -p pkgsCross.arm-embedded.stdenv.cc git pkg-config libpng
+```
diff --git a/docs/install/linux/OTHERS.md b/docs/install/linux/OTHERS.md
new file mode 100644
index 0000000000..eb83331ed9
--- /dev/null
+++ b/docs/install/linux/OTHERS.md
@@ -0,0 +1,11 @@
+# Instructions for other distributions
+1. Try to find the required software in its repositories:
+ - `gcc`
+ - `g++`
+ - `arm-none-eabi-gcc`
+ - `arm-none-eabi-binutils`
+ - `arm-none-eabi-newlib`
+ - `make`
+ - `git`
+ - `libpng-dev`
+ - `python3`
diff --git a/docs/install/linux/UBUNTU.md b/docs/install/linux/UBUNTU.md
new file mode 100644
index 0000000000..41beb8067a
--- /dev/null
+++ b/docs/install/linux/UBUNTU.md
@@ -0,0 +1,6 @@
+# Ubuntu instructions
+## Installing dependencies
+Open a terminal and run the following command from the command line:
+```console
+sudo apt install build-essential binutils-arm-none-eabi gcc-arm-none-eabi libnewlib-arm-none-eabi git libpng-dev python3
+```
diff --git a/docs/install/mac/MAC_OS.md b/docs/install/mac/MAC_OS.md
new file mode 100644
index 0000000000..8ffa4df089
--- /dev/null
+++ b/docs/install/mac/MAC_OS.md
@@ -0,0 +1,93 @@
+# Instructions for macOS
+1. If the Xcode Command Line Tools are not installed, download the tools [here](https://developer.apple.com/xcode/resources/), open your Terminal, and run the following command:
+
+ ```bash
+ xcode-select --install
+ ```
+
+2. - If libpng is **not installed**, then go to [Installing libpng (macOS)](#installing-libpng-macos).
+ - If pkg-config is **not installed**, then go to [Installing pkg-config (macos)](#installing-pkg-config-macos).
+ - If devkitARM is **not installed**, then go to [Installing devkitARM (macOS)](#installing-devkitarm-macos).
+ - Otherwise, **open the Terminal** and go to [Choosing where to store pokeemerald-expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos)
+
+### Installing libpng (macOS)
+
+ Note for advanced users...
+
+> This guide installs libpng via Homebrew as it is the easiest method, however advanced users can install libpng through other means if they so desire.
+
+
+1. Open the Terminal.
+2. If Homebrew is not installed, then install [Homebrew](https://brew.sh/) by following the instructions on the website.
+3. Run the following command to install libpng.
+
+ ```bash
+ brew install libpng
+ ```
+ libpng is now installed.
+
+ Continue to [Installing pkg-config (macOS)](#installing-pkg-config-macos) if **pkg-config is not installed**. Otherwise, continue to [Installing devkitARM (macOS)](#installing-devkitarm-macos) if **devkitARM is not installed**.
+
+ If both pkg-config and devkitARM are already installed, go to [Choosing where to store pokeemerald-expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos).
+
+### Installing pkg-config (macOS)
+
+ Note for advanced users...
+
+> This guide installs pkg-config via Homebrew as it is the easiest method, however advanced users can install pkg-config through other means if they so desire.
+
+
+1. Open the Terminal.
+2. If Homebrew is not installed, then install [Homebrew](https://brew.sh/) by following the instructions on the website.
+3. Run the following command to install libpng.
+
+ ```bash
+ brew install pkg-config
+ ```
+ pkg-config is now installed.
+
+ Continue to [Installing devkitARM (macOS)](#installing-devkitarm-macos) if **devkitARM is not installed**, otherwise, go to [Choosing where to store pokeemerald-expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos).
+
+### Installing devkitARM (macOS)
+1. Download the `devkitpro-pacman-installer.pkg` package from [here](https://github.com/devkitPro/pacman/releases).
+2. Open the package to install devkitPro pacman.
+3. In the Terminal, run the following commands to install devkitARM:
+
+ ```bash
+ sudo dkp-pacman -Sy
+ sudo dkp-pacman -S gba-dev
+ sudo dkp-pacman -S devkitarm-rules
+ ```
+
+ The command with gba-dev will ask for the selection of packages to install. Just press Enter to install all of them, followed by entering Y to proceed with the installation.
+
+4. After the tools are installed, devkitARM must now be made accessible from anywhere by the system. To do so, run the following commands:
+
+ ```bash
+ export DEVKITPRO=/opt/devkitpro
+ echo "export DEVKITPRO=$DEVKITPRO" >> ~/.zshrc
+ export DEVKITARM=$DEVKITPRO/devkitARM
+ echo "export DEVKITARM=$DEVKITARM" >> ~/.zshrc
+
+ echo "if [ -f ~/.zshrc ]; then . ~/.zshrc; fi" >> ~/.zprofile
+ ```
+ *Note: Starting with macOS 10.15, the default Unix shell is now zsh. If you migrated from an older version of macOS, you might still be using bash. You can check my running `echo $0` in the terminal.*
+
+ If your terminal is using bash instead of zsh...
+
+ ```bash
+ export DEVKITPRO=/opt/devkitpro
+ echo "export DEVKITPRO=$DEVKITPRO" >> ~/.bashrc
+ export DEVKITARM=$DEVKITPRO/devkitARM
+ echo "export DEVKITARM=$DEVKITARM" >> ~/.bashrc
+
+ echo "if [ -f ~/.bashrc ]; then . ~/.bashrc; fi" >> ~/.bash_profile
+ ```
+
+
+### Installing Python (macOS)
+1. Download the latest Python package from [here](https://www.python.org/downloads/).
+2. Open the package to install Python.
+
+Python is now installed.
+
diff --git a/docs/install/windows/CYGWIN.md b/docs/install/windows/CYGWIN.md
new file mode 100644
index 0000000000..c9ca728c22
--- /dev/null
+++ b/docs/install/windows/CYGWIN.md
@@ -0,0 +1,4 @@
+# cygwin
+Don't, just don't.
+Currently doesn't work on current Expansion versions.
+This is a bug from upstream pret `pokeemerald`.
diff --git a/docs/install/windows/MSYS2.md b/docs/install/windows/MSYS2.md
new file mode 100644
index 0000000000..ce7176b912
--- /dev/null
+++ b/docs/install/windows/MSYS2.md
@@ -0,0 +1,4 @@
+# msys2
+Don't, just don't.
+Currently doesn't work on current Expansion versions.
+This is a bug from upstream pret `pokeemerald`.
diff --git a/docs/install/windows/WSL.md b/docs/install/windows/WSL.md
new file mode 100644
index 0000000000..9534966488
--- /dev/null
+++ b/docs/install/windows/WSL.md
@@ -0,0 +1,87 @@
+# Windows WSL instructions
+## Choosing WSL version
+If you must store your project on the Windows file system (under /mnt/c/), you should use WSL1.
+If you want the best performance and least amount of issues with Windows interfering with compiling the project, use WSL2 and store the project on the Linux file system (under ~/).
+## Installing WSL
+1. Open [Windows Powershell **as Administrator**](https://i.imgur.com/QKmVbP9.png), and run the following commands (Right Click or Shift+Insert is paste in the Powershell).
+
+ ```powershell
+ wsl --install -d Ubuntu --enable-wsl1
+ ```
+
+2. Once the process finishes, restart your machine.
+
+### WSL1
+3a. Open Windows Powershell **as Administrator** again (after restarting), and run the following command to configure Ubuntu to use WSL1.
+
+ ```powershell
+ wsl --set-version Ubuntu 1
+ ```
+### WSL2
+3a. Open Windows Powershell **as Administrator** again (after restarting), and run the following command to configure Ubuntu to use WSL2.
+
+ ```powershell
+ wsl --set-version Ubuntu 2
+ ```
+
+
+ Note...
+
+ > WSL may open automatically after restarting, but you can ignore it for now.
+
+
+## Installing dependencies
+Some tips before proceeding:
+- In WSL, Copy and Paste is either done via
+ - **right-click** (selection + right click to Copy, right click with no selection to Paste)
+ - **Ctrl+Shift+C/Ctrl+Shift+V** (enabled by right-clicking the title bar, going to Properties, then checking the checkbox next to "Use Ctrl+Shift+C/V as Copy/Paste").
+- Some of the commands that you'll run will ask for your WSL password and/or confirmation to perform the stated action. This is to be expected, just enter your WSL password and/or the yes action when necessary.
+
+1. Open **Ubuntu** (e.g. using Search).
+2. WSL/Ubuntu will set up its own installation when it runs for the first time. Once WSL/Ubuntu finishes installing, it will ask for a username and password (to be input in).
+
+ Note...
+
+ > When typing in the password, there will be no visible response, but the terminal will still read in input.
+
+
+3. Update WSL/Ubuntu before continuing. Do this by running the following command. These commands will likely take a long time to finish:
+
+ ```bash
+ sudo apt update && sudo apt upgrade
+ ```
+
+4. Certain packages are required to build pokeemerald Expansion. Install these packages by running the following command:
+
+ ```bash
+ sudo apt install build-essential binutils-arm-none-eabi gcc-arm-none-eabi libnewlib-arm-none-eabi git libpng-dev python3
+ ```
+
+## Choosing a location to store pokeemerald Expansion, WSL1
+WSL has its own file system that's not natively accessible from Windows, but Windows files *are* accessible from WSL. So you're going to want to store pokeemerald Expansion within Windows.
+
+For example, say you want to store pokeemerald Expansion in **C:\Users\\_\_\Desktop\decomps**. First, ensure that the folder already exists. Then, enter this command to **change directory** to said folder, where *\* is your **Windows** username:
+
+```bash
+cd /mnt/c/Users//Desktop/decomps
+```
+
+
+ Notes...
+
+> Note 1: The Windows C:\ drive is called /mnt/c/ in WSL.
+> Note 2: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "/mnt/c/users//Desktop/decomp folder"`.
+> Note 3: Windows path names are case-insensitive so adhering to capitalization isn't needed
+
+
+## Choosing a location to store pokeemerald Expansion, WSL2
+WSL has its own file system that's not natively accessible from Windows, but Windows files *are* accessible from WSL. But accessing files on the Windows file system with WSL2 is very slow, so you're going to want to store pokeemerald Expansion within WSL2.
+To access the files on the WSL filesystem from Windowsm, you have to open the WSL filesystem as a network attached storage in the file explorer, it should be at the bottom of the left sidebar as "Ubuntu".
+
+Thus you're going to make sure that you're in the WSL filesystem, then create the folder for decomps if it doesn't already exist, then move into that folder.
+
+```bash
+cd ~/
+mkdir decomps
+cd decomps
+```
diff --git a/docs/scope.md b/docs/scope.md
new file mode 100644
index 0000000000..1bec4f2db7
--- /dev/null
+++ b/docs/scope.md
@@ -0,0 +1,54 @@
+# Document Purpose
+
+This document is a guide for contributors and Senate to decide if a feature is within "scope" for pokeemerald-expansion. If a feature is not in scope, then it should not be merged. Even if an opened PR is within scope, this does not mean it will be merged, as acceptance criteria will often come down to the details of the implementation.
+
+# Definitions
+
+* **Showdown Supported (SS)**: A core series game who's metagame can be played on Showdown.
+ * Notably, this is every [core series game](https://bulbapedia.bulbagarden.net/wiki/Core_series#List_of_core_series_games) except Pokémon Legends: Arceus.
+* **Base Expansion Version**: "A .gba file built from an unmodified `master` or `upcoming` branch of `pokeemerald-expansion`.
+* **Vanilla Emerald Version**: A .gba file built from an unmodified `master` branch of pret's `pokeemerald`.
+
+# Guidelines
+
+A pull request meets the scope criteria if:
+* The feature does not belong to a category considered “not in scope” AND
+* The feature belongs to a category considered “in scope”
+
+## In Scope Categories
+
+1. **SS Species:** Adds Species that have appeared in a Showdown-supported title
+2. **SS Moves:** Adds Moves and Move Animations that have appeared in a Showdown-supported title
+3. **SS Abilities:** Adds Abilities that have appeared in a Showdown-supported title
+4. **SS Items:** Adds Items that have appeared in a Showdown-supported title
+5. **SS Gimmicks:** Adds Gimmicks that have appeared in a Showdown-supported title
+6. **SS Battle Types:** Adds Special Battle Types that have appeared in a Showdown-supported title
+7. **SS Battle Mechanics:** Adds mechanical battle changes that have appeared in a Showdown-supported title
+8. **Improve Battle AI:** Improve the Battle AI in a way that allows it to approach the skill and capability of a human competitive player
+9. **Base Link Compatibility:** Link compatibility with base
+10. **SS Overworld / Menu Updates:** Replicate overworld or menu changes from Showdown-supported Pokémon titles
+11. **Speed Up:** Speed up the player experience of features found in base
+12. **Compression:** Automatically compress assets
+13. **Novel Experience:** Adds a novel experience included in another Showdown Supported title
+15. **Helper Features:** Eases the addition or inclusion of any of the aforementioned
+
+## Not In Scope Categories
+
+1. **Non-SS Species**: Adds Species that have NOT appeared in a Showdown-supported title
+2. **Non-SS Moves**: Adds Moves and Move Animations that have NOT appeared in a Showdown-supported title
+3. **Non-SS Abilities**: Adds Abilities that have NOT appeared in a Showdown-supported title
+4. **Non-SS Items**: Adds Items that have NOT appeared in a Showdown-supported title
+5. **Non-SS Gimmicks**: Adds Gimmicks that have NOT appeared in a Showdown-supported title
+6. **Non-SS Battle Types**: Adds Special Battle Types that have NOT appeared in a Showdown-supported title
+7. **Duplicate Feature UI**: Adds functionality that duplicates the core functionality of an existing vanilla feature
+8. **Vanilla Link Compatibility**: Link compatibility with vanilla
+
+## Discussion Required Categories
+
+Pull Requests that fall into this category should be brought up to maintainers, who will discuss and vote as to whether or not the feature is considered in scope. Considerations for acceptance may include invasiveness of implementation, popularity, ease of maintenance, etc.
+
+1. **Developer Ease of Use:** Lowers barrier of entry for developers to use existing behavior
+2. **Fangame Features:** Adds a popular feature from other fangames
+3. **Popular Non-SS Features:** Exceptions can be made for uniquely popular or requested features (Drowsy, PLA Legend Plate, etc.)
+4. **External Program**: External programs like poryscript, porymoves, etc.
+
diff --git a/docs/tutorials/ai_flags.md b/docs/tutorials/ai_flags.md
index 7b77305c13..fcad6ed34f 100644
--- a/docs/tutorials/ai_flags.md
+++ b/docs/tutorials/ai_flags.md
@@ -165,3 +165,6 @@ AI always assumes it will roll the lowest possible result when comparing damage
## `AI_FLAG_SEQUENCE_SWITCHING`
AI will always switch out after a KO in exactly party order as defined in the trainer data (ie. slot 1, then 2, then 3, etc.). The AI will never switch out mid-battle unless forced to (Roar etc.). If the AI uses a move that requires a switch where it makes a decision about what to send in (U-Turn etc.), it will always switch out into the lowest available party index.
+
+## `AI_FLAG_WEIGH_ABILITY_PREDICTION`
+AI will predict the player's ability based to its aiRating. Without this flag the AI randomly assumes an ability with an even distribution between all possible abilities until one is confirmed. With this flag, it instead guesses proportionally to each ability's aiRating, making it far more likely to guess an ability like Water Absorb than Damp if both are options.
diff --git a/docs/tutorials/how_to_battle_script_command_macro.md b/docs/tutorials/how_to_battle_script_command_macro.md
index 042a87601d..2bbf503fbe 100644
--- a/docs/tutorials/how_to_battle_script_command_macro.md
+++ b/docs/tutorials/how_to_battle_script_command_macro.md
@@ -1,51 +1,47 @@
## How to add new Battle Script Commands/Macros
-To preface this tutorial, the battle engine upgrade has exhausted all battle script command IDs, and instead uses the `various` command to effectively add new commands. This is preferential to creating a secondary battle script command table like is done in the CFRU.
+To preface this tutorial, the battle engine upgrade has exhausted all battle script command IDs. Historically, we've used the `various` command to effectively add new commands. However, this has caused issues of maintainability and readability due to the massive switch needed for it. Thanks to the cleanup made by the team and contributors, we now are able to call an infinite amount of commands by using `callnative`. This is preferential to creating a secondary battle script command table like is done in the CFRU.
-In general, `gBattlescriptCurrInstr` tracks the current battle script position as a ROM address. Fortunately, we don't need to worry about ROM addresses when using the decomps, but it is important to understand because of how the `various` command is set up.
+In general, `gBattlescriptCurrInstr` tracks the current battle script position as a ROM address. Fortunately, we don't need to worry about ROM addresses when using the decomps, but it is important to understand because of how the `callnative` command is set up.
```
-.macro various battler:req, param1:req
- .byte 0x76
- .byte \battler
- .byte \param1
- .endm
+ .macro callnative func:req
+ .byte 0xff
+ .4byte \func
+ .endm
```
+`callnative` uses the last battle script command ID in order to pass a native function as an argument. Additional optional arguments are added recursively via a macro, so no need to worry about how they need to align to the amount of instructions to skip.
-`various` is 3 bytes in size, so if we wanted to advance to the next battle script command, we would write `gBattlescriptCurrInstr += 3`. Coincidentally, this is found at the end of `Cmd_Various` in `src/battle_script_commands.c`.
-
-Now, how might we add a custom various command case? Here are the steps. We will use `VARIOUS_SET_SIMPLE_BEAM` as an example.
-### 1. Add a definition to `include/constants/battle_script_commands.h`.
-
-For example, `#define VARIOUS_SET_SIMPLE_BEAM 39`
-
-### 2. Create a macro in `asm/macros/battle_script.inc`. For example:
+Now, how might we add a custom `callnative` command? Here are the steps. We will use `BS_TrySetOctolock` as an example.
+### 1. Create a macro in `asm/macros/battle_script.inc`. For example:
```c
-.macro setabilitysimple battler:req, ptr:req
- various \battler VARIOUS_SET_SIMPLE_BEAM
- .4byte \ptr
- .endm
+ .macro trysetoctolock battler:req, failInstr:req
+ callnative BS_TrySetOctolock
+ .byte \battler
+ .4byte \failInstr
+ .endm
```
-
-### 3. Add your new various command ID to `Cmd_Various`. For example:
+### 2. Add your new callnative command ID to `src/battle_script_commands.c`. For example:
```c
- case VARIOUS_SET_SIMPLE_BEAM:
- if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)
- || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE)
- {
- gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
- }
- else
- {
- gBattleMons[gBattlerTarget].ability = ABILITY_SIMPLE;
- RecordAbilityBattle(gActiveBattler, ABILITY_SIMPLE);
- gBattlescriptCurrInstr += 7;
- }
- return;
+void BS_TrySetOctolock(void)
+{
+ NATIVE_ARGS(u8 battler, const u8 *failInstr);
+ u32 battler = GetBattlerForBattleScript(cmd->battler);
+
+ if (gDisableStructs[battler].octolock)
+ {
+ gBattlescriptCurrInstr = cmd->failInstr;
+ }
+ else
+ {
+ gDisableStructs[battler].octolock = TRUE;
+ gBattleMons[battler].status2 |= STATUS2_ESCAPE_PREVENTION;
+ gDisableStructs[battler].battlerPreventingEscape = gBattlerAttacker;
+ gBattlescriptCurrInstr = cmd->nextInstr;
+ }
+}
```
-
-The macros' `battler` argument is the battler who will be affected/considered by your command. In our case, which battler we will try to give `ABILITY_SIMPLE`. Note that `gActiveBattler` is always set to this battler at the beginning of `Cmd_Various`.
-
-The `ptr` argument is an extra argument that, in this case, provides a battle script to jump to in the event that we fail to set `ABILITY_SIMPLE`. We must add the `.4byte \ptr` inside our macro. So now when we want to advance to the next battle script command in our script, we must increment `gBattlescriptCurrInstr` by `7` because our overall macro is 3 bytes for the various command, and 4 bytes for the pointer. *IMPORTANT* the `return` at the end of the switch case is required because remember that `various` always defaults to `gBattlescriptCurrInstr += 3` at the very end of the function, so if we included `gBattlescriptCurrInstr += 7` with a `break`, we would end up effectively doing `gBattlescriptCurrInstr += 10`.
-
-This behavior can be found under the `else` statement in the example above, corresponding to `ABILITY_SIMPLE` being correctly applied. If we are unable to set `ABILITY_SIMPLE`, however, notice the following `gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);`. This means we are jumping to the battle script provided by the pointer 3 bytes after our various command (which is the `ptr` argument described previously). We still must `return` or else we would actually jump to 3 bytes after the `ptr` battle script begins.
+Each of the arguments defined in the macro (`battler`, `failInstr`) need to be called at the start of the command using `NATIVE_ARGS`.
+The byte count in the macro should correspond to the type that will be used for the command (eg, `u8` is `byte`, while the pointer are `4byte`).
+These arguments can then be accessed as `cmd->battler` and `cmd->battler`.
+`gBattlescriptCurrInstr = cmd->nextInstr;` advances to the next instruction.
diff --git a/docs/tutorials/how_to_new_pokemon_1_10_0.md b/docs/tutorials/how_to_new_pokemon_1_10_0.md
new file mode 100644
index 0000000000..4d836fc7d3
--- /dev/null
+++ b/docs/tutorials/how_to_new_pokemon_1_10_0.md
@@ -0,0 +1,1181 @@
+
+This is a modified version of [the original tutorial about adding new Pokémon species available in Pokeemerald's wiki](https://github.com/pret/pokeemerald/wiki/How-to-add-a-new-Pokémon-species).
+
+Despite the persistent rumors about an incredibly strong third form of Mew hiding somewhere, it actually wasn't possible to catch it... OR WAS IT?
+In this tutorial, we will add a new Pokémon species to the game.
+
+## IMPORTANT: This tutorial applies to 1.10.x versions.
+- [Version 1.9.x](how_to_new_pokemon_1_9_0.md)
+- [Version 1.8.x](how_to_new_pokemon_1_8_0.md)
+- [Version 1.7.x](how_to_new_pokemon_1_7_0.md)
+- [Version 1.6.x](how_to_new_pokemon_1_6_0.md)
+
+# Changes compared to vanilla
+The main things that the Expansion changes are listed here.
+* Still Front Pics *(`gMonStillFrontPic_YourPokemon`)* and by extension `src/anim_mon_front_pics.c` have been removed.
+* `src/data/pokemon/cry_ids.h` doesn't exist anymore.
+* You have 6 icon palettes available instead of the base 3.
+* Most tables that use `SPECIES_x` as indexes have been moved to `gSpeciesInfo`.
+
+# Content
+* [Useful resources](#useful-resources)
+* [The Data - Part 1](#the-data---part-1)
+ * [1. Declare a species constant](#1-Declare-a-species-constant)
+ * [2. `SpeciesInfo`'s structure](#2-speciesinfos-structure)
+ * [3. Define its basic species information](#3-define-its-basic-species-information)
+ * [4. Species Name](#4-species-name)
+ * [5. Define its cry](#5-define-its-cry)
+ * [6. Define its Pokédex entry](#6-define-its-pokédex-entry)
+* [The Graphics](#the-graphics)
+ * [1. Edit the sprites](#1-edit-the-sprites)
+ * [2. Add the sprites to the rom](#2-add-the-sprites-to-the-rom)
+ * [3. Add the animations to the rom](#3-add-the-animations-to-the-rom)
+ * [4. Linking graphic information to our Pokémon](#4-linking-graphic-information-to-our-pokémon)
+* [The Data - Part 2](#the-data---part-2)
+ * [1. Species Flags](#1-species-flags)
+ * [2. Delimit the moveset](#2-delimit-the-moveset)
+ * [3. Define the Evolutions](#3-define-the-evolutions)
+ * [4. Make it appear!](#4-make-it-appear)
+* [Optional data](#optional-data)
+ * [1. Form tables](#1-form-tables)
+ * [2. Form change tables](#2-form-change-tables)
+ * [3. Gender differences](#3-gender-differences)
+ * [4. Overworld Data](#4-overworld-data)
+
+# Useful resources
+You can open a sprite debug menu by pressing `Select` in a Pokémon's summary screen outside of battle.
+
+
+
+
+# The Data - Part 1
+
+Our plan is as simple as it is brilliant: clone Mewtwo... and make it even stronger!
+
+## 1. Declare a species constant
+
+Our first step towards creating a new digital lifeform is to define its own species constant.
+
+Edit [include/constants/species.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/species.h):
+
+```diff
+ #define SPECIES_NONE 0
+ #define SPECIES_BULBASAUR 1
+ ...
+ #define SPECIES_MIMIKYU_BUSTED_TOTEM 1523
+ #define SPECIES_MIMIKYU_TOTEM_BUSTED SPECIES_MIMIKYU_BUSTED_TOTEM
++#define SPECIES_MEWTHREE 1524
+
+-#define SPECIES_EGG (SPECIES_MIMIKYU_BUSTED_TOTEM + 1)
++#define SPECIES_EGG (SPECIES_MEWTHREE + 1)
+
+ #define NUM_SPECIES SPECIES_EGG
+```
+This number is stored in a Pokémon's save structure. These should generally never change, otherwise your saved Pokémon species will change as well.
+
+We add this at the end so that no existing species change Id and so that we don't have to renumber everything after it.
+
+Now, let's see how it looks in-game!
+
+
+
+Hmmm, something's not right...
+
+Oh, I know! We need to add the rest of the data! Normally, the vanilla game would crash if we try to look up anything about Mewthree in this state, but the expansion defaults all of its data to `SPECIES_NONE`.
+
+Now, let's see what needs to be done.
+
+## 2. `SpeciesInfo`'s structure
+Now, to better understand Mewthree, we also need to understand Mew. Let's look at its data.
+```diff
+ [SPECIES_MEW] =
+ {
+ .baseHP = 100,
+ .baseAttack = 100,
+ .baseDefense = 100,
+ .baseSpeed = 100,
+ .baseSpAttack = 100,
+ .baseSpDefense = 100,
+ .types = MON_TYPES(TYPE_PSYCHIC),
+ .catchRate = 45,
+ #if P_UPDATED_EXP_YIELDS >= GEN_8
+ .expYield = 300,
+ #elif P_UPDATED_EXP_YIELDS >= GEN_5
+ .expYield = 270,
+ #else
+ .expYield = 64,
+ #endif
+ .evYield_HP = 3,
+ .itemCommon = ITEM_LUM_BERRY,
+ .itemRare = ITEM_LUM_BERRY,
+ .genderRatio = MON_GENDERLESS,
+ .eggCycles = 120,
+ .friendship = 100,
+ .growthRate = GROWTH_MEDIUM_SLOW,
+ .eggGroups = MON_EGG_GROUPS(EGG_GROUP_NO_EGGS_DISCOVERED),
+ .abilities = { ABILITY_SYNCHRONIZE, ABILITY_NONE, ABILITY_NONE },
+ .bodyColor = BODY_COLOR_PINK,
+ .speciesName = _("Mew"),
+ .cryId = CRY_MEW,
+ .natDexNum = NATIONAL_DEX_MEW,
+ .categoryName = _("New Species"),
+ .height = 4,
+ .weight = 40,
+ .description = COMPOUND_STRING(
+ "A Mew is said to possess the genes of all\n"
+ "Pokémon. It is capable of making itself\n"
+ "invisible at will, so it entirely avoids\n"
+ "notice even if it approaches people."),
+ .pokemonScale = 457,
+ .pokemonOffset = -2,
+ .trainerScale = 256,
+ .trainerOffset = 0,
+ .frontPic = gMonFrontPic_Mew,
+ .frontPicSize = P_GBA_STYLE_SPECIES_GFX ? MON_COORDS_SIZE(40, 40) : MON_COORDS_SIZE(64, 48),
+ .frontPicYOffset = P_GBA_STYLE_SPECIES_GFX ? 13 : 9,
+ .frontAnimFrames = sAnims_Mew,
+ .frontAnimId = P_GBA_STYLE_SPECIES_GFX ? ANIM_SWING_CONVEX : ANIM_ZIGZAG_SLOW,
+ .enemyMonElevation = P_GBA_STYLE_SPECIES_GFX ? 8 : 11,
+ .backPic = gMonBackPic_Mew,
+ .backPicSize = P_GBA_STYLE_SPECIES_GFX ? MON_COORDS_SIZE(48, 48) : MON_COORDS_SIZE(64, 64),
+ .backPicYOffset = P_GBA_STYLE_SPECIES_GFX ? 8 : 0,
+ .backAnimId = BACK_ANIM_CONCAVE_ARC_SMALL,
+ .palette = gMonPalette_Mew,
+ .shinyPalette = gMonShinyPalette_Mew,
+ .iconSprite = gMonIcon_Mew,
+ .iconPalIndex = 0,
+ SHADOW(0, 13, SHADOW_SIZE_S)
+ FOOTPRINT(Mew)
+ OVERWORLD(
+ sPicTable_Mew,
+ SIZE_32x32,
+ SHADOW_SIZE_M,
+ TRACKS_NONE,
+ gOverworldPalette_Mew,
+ gShinyOverworldPalette_Mew
+ )
+ .isMythical = TRUE,
+ .isFrontierBanned = TRUE,
+ .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT,
+ .levelUpLearnset = sMewLevelUpLearnset,
+ .teachableLearnset = sMewTeachableLearnset,
+ },
+```
+
+That's a lot of stuff! But don't worry, we'll go through it step by step throughout the tutorial
+(and it's miles better than having this same data through 20+ files like it used to be).
+
+We'll start by adding the self-explanatory data that's also present in pret's vanilla structure:
+
+## 3. Define its basic species information
+Edit [src/data/pokemon/species_info.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/species_info.h):
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ [SPECIES_NONE] = {0},
+ ...
+
+ [SPECIES_EGG] =
+ {
+ FRONT_PIC(Egg, 24, 24),
+ .frontPicYOffset = 20,
+ .backPic = gMonFrontPic_Egg,
+ .backPicSize = MON_COORDS_SIZE(24, 24),
+ .backPicYOffset = 20,
+ .palette = gMonPalette_Egg,
+ .shinyPalette = gMonPalette_Egg,
+ ICON(Egg, 1),
+ },
+
++ [SPECIES_MEWTHREE] =
++ {
++ .baseHP = 106,
++ .baseAttack = 150,
++ .baseDefense = 70,
++ .baseSpeed = 140,
++ .baseSpAttack = 194,
++ .baseSpDefense = 120,
++ .types = MON_TYPES(TYPE_PSYCHIC),
++ .catchRate = 3,
++ .expYield = 255,
++ .evYield_SpAttack = 3,
++ .genderRatio = MON_GENDERLESS,
++ .eggCycles = 120,
++ .friendship = 0,
++ .growthRate = GROWTH_SLOW,
++ .eggGroups = MON_EGG_GROUPS(EGG_GROUP_NO_EGGS_DISCOVERED),
++ .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE },
++ .bodyColor = BODY_COLOR_PURPLE,
++ },
+ };
+```
+
+The `.` is the structure reference operator in C to refer to the member object of the structure SpeciesInfo.
+
+- `baseHP`, `baseAttack`, `baseDefense`, `baseSpeed`, `baseSpAttack` and `baseSpDefense` are the base stats. They can't go higher than 255.
+- `types` is using the macro `MON_TYPES` as a helper function for formatting so that only one type has to be input for species with a single type.
+ - To add a species with 2 types, use the format `MON_TYPES(TYPE_PSYCHIC, TYPE_NORMAL)`.
+- `catchRate` is how likely it is to catch a Pokémon, the lower the value, the harder it is to catch. Legendaries generally have a catch rate of 3, so we put that here.
+- `expYield` is the base amount of experience that a Pokémon gives when defeated/caught. In vanilla, this value caps at 255, but we've increased it to a maximum of 65535 accomodate later gen's higher experience yields. (The highest official value is Blissey's with 608, so going beyond this point may cause exponential gains that could break the system 😱)
+ - If you noticed, Mew's had some `#if`s, `#elif`s and `#endif` around it. This is because its yield has changed over time, and we let you choose which ones you want. This is not relevant to our Mewthree however, so we can just put a single `.expYield = 255,` line here.
+- `evYield_HP`, `evYield_Attack`, `evYield_Defense`, `evYield_Speed`, `evYield_SpAttack` and `evYield_SpDefense` are how many EVs does the Pokémon give when they're caught. Each of these fields can have a value of 3 at most. Officially, no Pokémon give out more than 3 EVs total, with them being determined by their evolution stage (eg, Pichu, Pikachu and Raichu give 1, 2 and 3 Speed EVs respectively), and they tend to be associated with its higher stats. Since our Mewthree is a Special Attack monster, we'll be consistent and make it give out 3 Special Attack EVs, but you're always free to assign whatever you feel like :)
+ - Notice that the other `evYield` fields are not there. In C, numbers in a struct default to 0, so if we don't specify them, they'll be 0 all around! Less lines to worry about :D
+- `itemCommon` and `itemRare` are used to determine what items is the Pokémon holding when encountering it in the wild.
+ - 50% for `itemCommon` and 5% for `itemRare` (boosted to 60%/20% when the first mon in the party has Compound Eyes or Super Luck)
+ - If they're both set as the same item, the item has a 100% chance of appearing.
+- `genderRatio` is a fun one.
+ - There are 4 ways of handling this
+ - `PERCENT_FEMALE` is what most Pokémon use, where you define how likely it's gonna be female. It supports decimals, so you can put `PERCENT_FEMALE(12.5)` to have a 1 in 8 chance of your mon to be female.
+ - `MON_MALE` guarantees that all mon of this species will be male (eg. Tauros)
+ - `MON_FEMALE` guarantees that all mon of this species will be female (eg. Miltank)
+ - `MON_GENDERLESS` makes your species genderless, unable to breed with anything but Ditto to produce eggs. Most Legendaries are this, so we'll be chosing this as Mewthree's gender ratio.
+ - When working with evolution lines and don't want their genders to change after evolving, be sure that their gender ratios match their stages and evolution methods. Azurill is the only case where there's a mismatch, causing 1/3 of all Azurill to change from Female to Male.
+ - You might be wondering why some species have multiple defines for their genders, like `SPECIES_MEOWSTIC_(FE)MALE`. This is because those species have different stats and data from each other, so they're defined internally as different forms with `MON_MALE` and `MON_FEMALE` as gender ratios. If your species evolves depending on its gender and the evolutions have different stats, be sure to apply the correct evolution method!
+- `eggCycles` determines how fast an egg of this species will hatch. Doesn't matter much for evolved species or those that can't lay eggs, but we add the field here just in case.
+- `friendship` determines the amount of friendship of the mon when you catch it. Most Pokémon use `STANDARD_FRIENDSHIP`, but this creature of chaos does not want to be your friend, starting with 0.
+- `growthRate` determines the amounts of experience required to reach each level. Go [here](https://bulbapedia.bulbagarden.net/wiki/Experience) for more info.
+ - This should be consistent across evolution lines, otherwise levels could change upon evolution.
+- `eggGroups` are used for breed compatibility. Most Legendaries and Mythicals have the `EGG_GROUP_NO_EGGS_DISCOVERED` group, and so does our Mewthree. Go [here](https://bulbapedia.bulbagarden.net/wiki/Egg_Group) for more info.
+ - This is using the helper macro `MON_EGG_GROUPS`.
+- `abilities` determines the potential abilites of our species. Notice how I also set the ability to `ABILITY_INSOMNIA`, so our little monster doesn't even need to sleep anymore. You can find the abilities for example here [include/constants/abilities.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/abilities.h).
+ - When both slot 1 and 2 are defined as not being `ABILITY_NONE`, their starting ability will be decided on a coin flip using their personality. They can later be changed using an Ability Capsule.
+ - Certain Pokémon such as Zygarde and Rockruff have different forms to add additional abilities. As such, they cannot be changed using an Ability Capsule (though the Zygarde Cube can change Zygarde's ability by changing them to their corresponding form)
+ - The 3rd slot is for Hidden Abilities. If defined as `ABILITY_NONE`, it will default to Slot 1 (eg. Metapod doesn't have a Hidden Ability, but Caterpie and Butterfree do). Go [here](https://bulbapedia.bulbagarden.net/wiki/Ability#Hidden_Abilities) and [here](https://bulbapedia.bulbagarden.net/wiki/Ability_Patch) for more info.
+ - If the array is defined as `{ABILITY_1, ABILITY_2}`, the Hidden Ability is set as `ABILITY_NONE`.
+- `bodyColor` is used in the Pokédex as a search filter.
+- `noFlip` is used in to prevent front sprites from being flipped horizontally and cause weird issues, like Clawitzer's big claw changing sides.
+
+That's all the basic fields present in vanilla emerald, so now let's take a look at the new fields added by the expansion.
+
+## 4. Species Name
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ .bodyColor = BODY_COLOR_PURPLE,
++ .speciesName = _("Mewthree"),
+ },
+ };
+```
+The `_()` underscore function doesn't really exist - it's a convention borrowed from GNU gettext to let `preproc` know this is text to be converted to the custom encoding used by the Gen 3 Pokemon games.
+
+## 5. Define its cry
+
+Time for audio!
+We first need to convert an existing audio file to the format supported by the expansion.
+
+Most formats are supported for conversion, but for simplicity's sake, we're gonna use an mp3 file.
+
+Now, let's copy the file to the `sound/direct_sound_samples/cries` folder.
+Once that's done, let's run the following command:
+```
+ffmpeg -i sound/direct_sound_samples/cries/mewthree.mp3 -c:a pcm_s8 -ac 1 -ar 13379 sound/direct_sound_samples/cries/mewthree.aif
+```
+This will convert your audio file to .aif, which is what's read by the compiler.
+
+Let's add the cry to the ROM via [sound/direct_sound_data.inc](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/sound/direct_sound_data.inc).
+
+```diff
+.if P_FAMILY_PECHARUNT == TRUE
+ .align 2
+Cry_Pecharunt::
+ .incbin "sound/direct_sound_samples/cries/pecharunt.bin"
+.endif @ P_FAMILY_PECHARUNT
+
++ .align 2
++Cry_Mewthree::
++ .incbin "sound/direct_sound_samples/cries/mewthree.bin"
+
+```
+
+Then we add the cry ID to [include/constants/cries.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/cries.h):
+
+```diff
+enum {
+ CRY_NONE,
+ ...
+#if P_FAMILY_TERAPAGOS
+ CRY_TERAPAGOS,
+#endif //P_FAMILY_TERAPAGOS
+#if P_FAMILY_PECHARUNT
+ CRY_PECHARUNT,
+#endif //P_FAMILY_PECHARUNT
++ CRY_MEWTHREE,
+ CRY_COUNT,
+};
+```
+
+And then link it in [sound/cry_tables.inc](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/sound/cry_tables.inc). `cry_reverse` in particular is for reversed cries used by moves such as Growl. The order of these two tables should match the order of the cry IDs, otherwise they'll be shifted.
+
+```diff
+ cry Cry_Terapagos
+ cry Cry_Pecharunt
++ cry Cry_Mewthree
+```
+```diff
+ cry_reverse Cry_Terapagos
+ cry_reverse Cry_Pecharunt
++ cry_reverse Cry_Mewthree
+```
+
+Lastly, we add the cry to our species entry
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ .speciesName = _("Mewthree"),
++ .cryId = CRY_MEWTHREE,
+ },
+ };
+```
+
+And let's see how it sounds in-game:
+
+https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/4f7667db-4db9-4bfd-a8dd-ece26f09f327
+
+Good! Our monster now has a mighty roar!
+
+You can now delete the mp3 from the cries folder now once you made sure that the cry sounds like how you want it to.
+
+## 6. Define its Pokédex entry
+
+First, we will need to add new index constants for its Pokédex entry. The index constants are divided into the Hoenn Pokédex, which contains all Pokémon native to the Hoenn region, and the National Pokédex containing all known Pokémon, which can be received after entering the hall of fame for the first time.
+
+Edit [include/constants/pokedex.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/pokedex.h):
+
+```diff
+// National Pokedex order
+enum {
+ NATIONAL_DEX_NONE,
+ // Kanto
+ NATIONAL_DEX_BULBASAUR,
+...
+ NATIONAL_DEX_PECHARUNT,
++ NATIONAL_DEX_MEWTHREE,
+};
+```
+
+```diff
+ #define KANTO_DEX_COUNT NATIONAL_DEX_MEW
+ #define JOHTO_DEX_COUNT NATIONAL_DEX_CELEBI
+
+#if P_GEN_9_POKEMON == TRUE
+- #define NATIONAL_DEX_COUNT NATIONAL_DEX_PECHARUNT
++ #define NATIONAL_DEX_COUNT NATIONAL_DEX_MEWTHREE
+```
+
+Do keep in mind that if you intend to add your new species to the Hoenn Dex, you'll also want to add a `HOENN_DEX` constant for it and give it a `HOENN_TO_NATIONAL` member, like this:
+
+```diff
+// Hoenn Pokedex order
+enum {
+ HOENN_DEX_NONE,
+ HOENN_DEX_TREECKO,
+...
+ HOENN_DEX_DEOXYS,
++ HOENN_DEX_MEWTHREE,
+};
+
+- #define HOENN_DEX_COUNT (HOENN_DEX_DEOXYS + 1)
++ #define HOENN_DEX_COUNT (HOENN_DEX_MEWTHREE + 1)
+```
+
+Edit [src/pokemon.c](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/pokemon.c):
+
+```diff
+ const u16 sHoennToNationalOrder[NUM_SPECIES] = // Assigns Hoenn Dex Pokémon (Using National Dex Index)
+ {
+ HOENN_TO_NATIONAL(TREECKO),
+ ...
+ HOENN_TO_NATIONAL(DEOXYS),
++ HOENN_TO_NATIONAL(MEWTHREE),
+ };
+```
+
+Now we can add the number and entry to our Mewthree:
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ .cryId = CRY_MEWTHREE,
++ .natDexNum = NATIONAL_DEX_MEWTHREE,
++ .categoryName = _("New Species"),
++ .height = 15,
++ .weight = 330,
++ .description = COMPOUND_STRING(
++ "The rumors became true.\n"
++ "This is Mew's final form.\n"
++ "Its power level is over 9000.\n"
++ "Has science gone too far?"),
++ .pokemonScale = 256,
++ .pokemonOffset = 0,
++ .trainerScale = 290,
++ .trainerOffset = 2,
+ },
+ };
+```
+
+
+The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex.
+
+`height` and `weight` are specified in decimeters and hectograms respectively (which are meters and kilograms multiplied by 10, so 2.5 meters are 25 decimeters).
+
+In Pokémon Emerald, you can sort the Pokédex by name, height or weight. Apparently, the Pokémon order is hardcoded in the game files and not calculated from their data. Therefore we have to include our new Pokémon species at the right places. While the correct position for the alphabetical order is easy to find, it can become quite tedious for height and weight, so we added comments to the listings in order help out were they should fit.
+
+Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/pokedex_orders.h):
+
+```diff
+ const u16 gPokedexOrder_Alphabetical[] =
+ {
+ ...
+ NATIONAL_DEX_MEW,
++ NATIONAL_DEX_MEWTHREE,
+ NATIONAL_DEX_MEWTWO,
+ ...
+ };
+
+ const u16 gPokedexOrder_Weight[] =
+ {
+ ...
+ // 72.8 lbs / 33.0 kg
+ //NATIONAL_DEX_MEWTWO_MEGA_Y,
+ NATIONAL_DEX_ESCAVALIER,
+ NATIONAL_DEX_FRILLISH,
+ NATIONAL_DEX_DURANT,
+ NATIONAL_DEX_CINDERACE,
++ NATIONAL_DEX_MEWTHREE,
+ //NATIONAL_DEX_PERSIAN_ALOLAN,
+ NATIONAL_DEX_TOEDSCOOL,
+ // 73.4 lbs / 33.3 kg
+ NATIONAL_DEX_DUGTRIO,
+ ...
+ };
+
+ const u16 gPokedexOrder_Height[] =
+ {
+ ...
+ // 4'11" / 1.5m
+ ...
+ NATIONAL_DEX_GLIMMORA,
+ NATIONAL_DEX_WO_CHIEN,
+ NATIONAL_DEX_IRON_LEAVES,
+ NATIONAL_DEX_IRON_BOULDER,
++ NATIONAL_DEX_MEWTHREE,
+ // 5'03" / 1.6m
+ ...
+ };
+```
+
+
+
+# The Graphics
+We will start by copying the following files for *Mew* (not Mewtwo) and rename it to `mewthree`.
+```sh
+cp -r graphics/pokemon/mew/. graphics/pokemon/mewthree
+```
+We aren't copying Mewtwo's folder because he has those pesky Mega Evolutions that will get in the way of what we're doing, so our sample will need to be pure from the source.
+
+## 1. Edit the sprites
+Let's edit the sprites. Start your favourite image editor (I recommend Aseprite or its free alternative, Libresprite) and change `anim_front.png` and `back.png` to meet your expectations.
+
+__Make sure that you are using the indexed mode and you have limited yourself to 15 colors!__
+
+Put the RGB values of your colors into `normal.pal` between the first and the last color and the RGB values for the shiny version into `shiny.pal`.
+Edit `footprint.png` using two colors in indexed mode, black and white.
+Finally, edit `icon.png`.
+**Note**: the icon will use one of 6 predefined palettes instead of `normal.pal`.
+Open an icon sprite and load one of the palettes to find out which palette suits your icon sprite best.
+
+## 2. Add the sprites to the rom
+Sadly, just putting the image files into the graphics folder is not enough. To use the sprites we have to register them, which is kind of tedious.
+First, create constants for the file paths. You'll want to add the constants for your species after the constants for the last valid species.
+
+Edit [src/data/graphics/pokemon.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/graphics/pokemon.h):
+
+```diff
+#if P_FAMILY_PECHARUNT
+ const u32 gMonFrontPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/front.4bpp.lz");
+ const u32 gMonPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/normal.gbapal.lz");
+ const u32 gMonBackPic_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/back.4bpp.lz");
+ const u32 gMonShinyPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/shiny.gbapal.lz");
+ const u8 gMonIcon_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/icon.4bpp");
+#if P_FOOTPRINTS
+ const u8 gMonFootprint_Pecharunt[] = INCBIN_U8("graphics/pokemon/pecharunt/footprint.1bpp");
+#endif //P_FOOTPRINTS
+#if OW_POKEMON_OBJECT_EVENTS
+ const u32 gObjectEventPic_Pecharunt[] = INCBIN_COMP("graphics/pokemon/pecharunt/overworld.4bpp");
+#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
+ const u32 gOverworldPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/overworld_normal.gbapal.lz");
+ const u32 gShinyOverworldPalette_Pecharunt[] = INCBIN_U32("graphics/pokemon/pecharunt/overworld_shiny.gbapal.lz");
+#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
+#endif //OW_POKEMON_OBJECT_EVENTS
+#endif //P_FAMILY_PECHARUNT
+
+ const u32 gMonFrontPic_Egg[] = INCBIN_U32("graphics/pokemon/egg/anim_front.4bpp.lz");
+ const u32 gMonPalette_Egg[] = INCBIN_U32("graphics/pokemon/egg/normal.gbapal.lz");
+ const u8 gMonIcon_Egg[] = INCBIN_U8("graphics/pokemon/egg/icon.4bpp");
+
++ const u32 gMonFrontPic_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/anim_front.4bpp.lz");
++ const u32 gMonBackPic_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/back.4bpp.lz");
++ const u32 gMonPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/normal.gbapal.lz");
++ const u32 gMonShinyPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/shiny.gbapal.lz");
++ const u8 gMonIcon_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/icon.4bpp");
++ const u8 gMonFootprint_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/footprint.1bpp");
+```
+
+Please note that Pecharunt, the Pokémon that should be above your insertion for the time being, reads a `front.png` sprite instead of an `anim_front.png` sprite. This is because currently, Pecharunt lacks a 2nd frame. If the front sprite sheet of your species uses 2 frames, you should use `anim_front`.
+
+## 3. Add the animations to the rom
+
+You can define the animation order, in which the sprites will be shown. The first number is the sprite index (so 0 or 1) and the second number is the number of frames the sprite will be visible.
+
+Edit [src/data/pokemon_graphics/front_pic_anims.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon_graphics/front_pic_anims.h):
+
+```diff
+#if P_FAMILY_PECHARUNT
+PLACEHOLDER_ANIM_SINGLE_FRAME(Pecharunt);
+#endif //P_FAMILY_PECHARUNT
+
++static const union AnimCmd sAnim_Mewthree_1[] =
++{
++ ANIMCMD_FRAME(1, 30),
++ ANIMCMD_FRAME(0, 20),
++ ANIMCMD_END,
++};
+```
+
+```diff
+#if P_FAMILY_PECHARUNT
+SINGLE_ANIMATION(Pecharunt);
+#endif //P_FAMILY_PECHARUNT
++SINGLE_ANIMATION(Mewthree);
+SINGLE_ANIMATION(Egg);
+```
+
+You might be wondering what `PLACEHOLDER_ANIM_SINGLE_FRAME` is. Well, since Pecharun only has 1 frame, we use what's called a preprocessor *macro* to have in a single line what otherwise would've been this in the C file:
+```c
+static const union AnimCmd sAnim_Pecharunt_1[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+}
+```
+Instead, we can use the already established macro that does the same thing, replacing the value in parenthesis with what we want (in this case, `Pecharunt`):
+```c
+#define PLACEHOLDER_ANIM_SINGLE_FRAME(name) \
+static const union AnimCmd sAnim_##name##_1[] = \
+{ \
+ ANIMCMD_FRAME(0, 1), \
+ ANIMCMD_END, \
+}
+```
+
+## 4. Linking graphic information to our Pokémon
+Now that we have all the external data ready, we just need to add it to `gSpeciesInfo` plus the rest of the animation and graphical data that we want to use:
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ .pokemonScale = 256,
+ .pokemonOffset = 0,
+ .trainerScale = 290,
+ .trainerOffset = 2,
++ .frontPic = gMonFrontPic_Mewthree,
++ .frontPicSize = MON_COORDS_SIZE(64, 64),
++ .frontPicYOffset = 0,
++ .frontAnimFrames = sAnims_Mewthree,
++ .frontAnimId = ANIM_GROW_VIBRATE,
++ .frontAnimDelay = 15,
++ .enemyMonElevation = 6,
++ .backPic = gMonBackPic_Mewthree,
++ .backPicSize = MON_COORDS_SIZE(64, 64),
++ .backPicYOffset = 0,
++ .backAnimId = BACK_ANIM_CONCAVE_ARC_SMALL,
++ .palette = gMonPalette_Mewthree,
++ .shinyPalette = gMonShinyPalette_Mewthree,
+ .iconSprite = gMonIcon_Mewthree,
+ .iconPalIndex = 2,
++ FOOTPRINT(Mewthree)
+ },
+ };
+```
+Let's explain each of these:
+- `frontPic`:
+ - Used to reference the front sprite, so in this case, we call for `gMonFrontPic_Mewthree`.
+- `frontPicSize`:
+ - The two values (`width` and `height`) are used for defining the non-empty size of the front sprite, which is used in move animations. If you're unsure of the values, you can leave them both as 64.
+- `frontPicYOffset`:
+ - Used to define what Y position the sprite sits at. This is used to set where they'd be "grounded". For the shadow, see `enemyMonElevation`.
+- `frontAnimFrames`:
+ - We link our animation frame animations that we defined earlier here.
+- `frontAnimId`:
+ - Because you are limited to two frames, there are already [predefined front sprite animations](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/pokemon_animation.h), describing translations, rotations, scalings or color changes.
+- `frontAnimDelay`:
+ - Sets a delay in frame count between when the Pokémon appears and when the animation starts.
+- `enemyMonElevation`:
+ - Used to determine the altitude from the ground. Any value above 0 will show a shadow under the Pokémon, to signify that they're floating.
+- `backPic`:
+ - Used to reference the back sprite, so in this case, we call for `gMonBackPic_Mewthree`.
+- `backPicSize`:
+ - The two values (`width` and `height`) are used for defining the non-empty size of the back sprite, which is used in move animations. If you're unsure of the values, you can leave them both as 64.
+ - **NOTE**: Mew has a tarnary switch here in order to change values depending on if a config option is set for displaying th original Gen 3 sprites.
+- `backPicYOffset`:
+ - Used to define what Y position of the back sprite. When working with the animation debug menu, we recommend aligning the back sprite to the white background, as it was designed to properyly align with the real battle layout.
+- `backAnimId`:
+ - Like `frontAnimId` except for the back sprites and them being a single frame. The IDs listed [here](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/pokemon_animation.h) are used to represent 3 different animations that happen based on the the Pokémon's nature.
+- `palette`:
+ - Used to reference the non-shiny palette, so in this case, we call for `gMonPalette_Mewthree`.
+- `shinyPalette`:
+ - Used to reference the shiny palette, so in this case, we call for `gMonShinyPalette_Mewthree`.
+- `iconSprite`:
+ - Used to reference the icon sprite, so in this case, we call for `gMonIcon_Mewthree`.
+- `iconPalIndex`:
+ - Here, you can choose between the six icon palettes; 0, 1, 2, 3, 4 and 5. All of them located in `graphics/pokemon/icon_palettes`.
+- `FOOTPRINT`
+ - We made this single field into a macro so that they can be ignored when `P_FOOTPRINTS` is set to false. It's also why we don't have an "," after calling it like the other macros (we add it as part of the macro itself).
+ ```c
+ #if P_FOOTPRINTS
+ #define FOOTPRINT(sprite) .footprint = gMonFootprint_## sprite,
+ #else
+ #define FOOTPRINT(sprite)
+ #endif
+ ```
+
+# The Data - Part 2
+
+We're almost there just a bit left!
+
+## 1. Species Flags
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE },
+ .bodyColor = BODY_COLOR_PURPLE,
++ .isLegendary = TRUE,
++ .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT,
+ },
+ };
+```
+Each species flag provides properties to the species:
+- `isLegendary`:
+ - Does nothing.
+- `isMythical`:
+ - Is skipped during Pokédex evaluations.
+ - Unless it also has the `dexForceRequired` flag.
+ - Cannot obtain Gigantamax factor via `ToggleGigantamaxFactor`.
+- `isUltraBeast`:
+ - Beast Ball's multiplier is set to x5 for this species.
+ - All other ball multipliers are set to x0.1.
+- `isParadox` (previously `isParadoxForm`):
+ - Makes it so that Booster Energy cannot be knocked off.
+- `isTotem`:
+ - Does nothing.
+- `isMegaEvolution`:
+ - A Mega indicator is added to the battle box indicating that they're Mega Evolved.
+ - The species doesn't receive affection benefits.
+ - Required when adding new Mega Evolutions.
+- `isPrimalReversion`:
+ - A Primal Reversion indicator (Alpha or Omega for Kyogre/Groudon respectively) is added to the battle box indicating that they're Primal Reverted.
+ - Required when adding new Primal Reversions.
+- `isUltraBurst`:
+ - Required when adding new Ultra Burst forms.
+- `isGigantamax`:
+ - Used to determine if Gigantamax forms should have their GMax moves or not.
+ - Required when adding new Gigantamax forms.
+- `isAlolanForm`, `isGalarianForm`, `isHisuianForm`, `isPaldeanForm`:
+ - In the future, these will be used to determine breeding offspring from different based on their region.
+- `cannotBeTraded`:
+ - This species cannot be traded away (like Black/White Kyurem).
+- `perfectIVCount`:
+ - Guarantees that the number of IVs specified here will be perfect.
+- `tmIlliterate`:
+ - This species will be unable to learn the universal moves.
+- `isFrontierBanned`:
+ - This species will be unable to enter Battle Frontier facilities. Replaces `gFrontierBannedSpecies`.
+
+## 2. Delimit the moveset
+
+Let's begin with the moves that can be learned by leveling up.
+
+Append to [src/data/pokemon/level_up_learnsets/gen_9.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/level_up_learnsets/gen_9.h):
+**NOTE**: You can ignore the warning at the top of the file if you're just adding moves to Pokemon.
+
+```diff
+#if P_FAMILY_PECHARUNT
+static const struct LevelUpMove sPecharuntLevelUpLearnset[] = {
+ LEVEL_UP_MOVE( 1, MOVE_SMOG),
+ LEVEL_UP_MOVE( 1, MOVE_POISON_GAS),
+ LEVEL_UP_MOVE( 1, MOVE_MEMENTO),
+ LEVEL_UP_MOVE( 1, MOVE_ASTONISH),
+ LEVEL_UP_MOVE( 8, MOVE_WITHDRAW),
+ LEVEL_UP_MOVE(16, MOVE_DESTINY_BOND),
+ LEVEL_UP_MOVE(24, MOVE_FAKE_TEARS),
+ LEVEL_UP_MOVE(32, MOVE_PARTING_SHOT),
+ LEVEL_UP_MOVE(40, MOVE_SHADOW_BALL),
+ LEVEL_UP_MOVE(48, MOVE_MALIGNANT_CHAIN),
+ LEVEL_UP_MOVE(56, MOVE_TOXIC),
+ LEVEL_UP_MOVE(64, MOVE_NASTY_PLOT),
+ LEVEL_UP_MOVE(72, MOVE_RECOVER),
+ LEVEL_UP_END
+};
+#endif
+
++static const struct LevelUpMove sMewthreeLevelUpLearnset[] = {
++ LEVEL_UP_MOVE( 1, MOVE_CONFUSION),
++ LEVEL_UP_MOVE( 1, MOVE_DISABLE),
++ LEVEL_UP_MOVE(11, MOVE_BARRIER),
++ LEVEL_UP_MOVE(22, MOVE_SWIFT),
++ LEVEL_UP_MOVE(33, MOVE_PSYCH_UP),
++ LEVEL_UP_MOVE(44, MOVE_FUTURE_SIGHT),
++ LEVEL_UP_MOVE(55, MOVE_MIST),
++ LEVEL_UP_MOVE(66, MOVE_PSYCHIC),
++ LEVEL_UP_MOVE(77, MOVE_AMNESIA),
++ LEVEL_UP_MOVE(88, MOVE_RECOVER),
++ LEVEL_UP_MOVE(99, MOVE_SAFEGUARD),
++ LEVEL_UP_END
++};
+```
+**NOTE**: If `P_LVL_UP_LEARNSETS` is not set to something equal to `GEN_9`, the file to be edited will change to what's specified.
+
+Again, we need to register the learnset in `gSpeciesInfo`:
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ .palette = gMonPalette_Mewthree,
+ .shinyPalette = gMonShinyPalette_Mewthree,
+ .iconSprite = gMonIcon_Mewthree,
+ .iconPalIndex = 2,
++ .levelUpLearnset = sMewthreeLevelUpLearnset,
+ },
+ };
+```
+
+Next we need to specify which moves can be taught via TM, HM, or Move Tutor.
+
+Append to [src/data/pokemon/teachable_learnsets.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/teachable_learnsets.h):
+
+```diff
+#if P_FAMILY_PECHARUNT
+static const u16 sPecharuntTeachableLearnset[] = {
+ ...
+ MOVE_UNAVAILABLE,
+};
+#endif //P_FAMILY_PECHARUNT
+
++static const u16 sMewthreeTeachableLearnset[] = {
++ MOVE_FOCUS_PUNCH,
++ MOVE_WATER_PULSE,
++ MOVE_CALM_MIND,
++ MOVE_TOXIC,
++ MOVE_HAIL,
++ MOVE_BULK_UP,
++ MOVE_HIDDEN_POWER,
++ MOVE_SUNNY_DAY,
++ MOVE_TAUNT,
++ MOVE_ICE_BEAM,
++ MOVE_BLIZZARD,
++ MOVE_HYPER_BEAM,
++ MOVE_LIGHT_SCREEN,
++ MOVE_PROTECT,
++ MOVE_RAIN_DANCE,
++ MOVE_SAFEGUARD,
++ MOVE_FRUSTRATION,
++ MOVE_SOLAR_BEAM,
++ MOVE_IRON_TAIL,
++ MOVE_THUNDERBOLT,
++ MOVE_THUNDER,
++ MOVE_EARTHQUAKE,
++ MOVE_RETURN,
++ MOVE_PSYCHIC,
++ MOVE_SHADOW_BALL,
++ MOVE_BRICK_BREAK,
++ MOVE_DOUBLE_TEAM,
++ MOVE_REFLECT,
++ MOVE_SHOCK_WAVE,
++ MOVE_FLAMETHROWER,
++ MOVE_SANDSTORM,
++ MOVE_FIRE_BLAST,
++ MOVE_ROCK_TOMB,
++ MOVE_AERIAL_ACE,
++ MOVE_TORMENT,
++ MOVE_FACADE,
++ MOVE_SECRET_POWER,
++ MOVE_REST,
++ MOVE_SKILL_SWAP,
++ MOVE_SNATCH,
++ MOVE_STRENGTH,
++ MOVE_FLASH,
++ MOVE_ROCK_SMASH,
++ MOVE_MEGA_PUNCH,
++ MOVE_MEGA_KICK,
++ MOVE_BODY_SLAM,
++ MOVE_DOUBLE_EDGE,
++ MOVE_COUNTER,
++ MOVE_SEISMIC_TOSS,
++ MOVE_MIMIC,
++ MOVE_METRONOME,
++ MOVE_DREAM_EATER,
++ MOVE_THUNDER_WAVE,
++ MOVE_SUBSTITUTE,
++ MOVE_DYNAMIC_PUNCH,
++ MOVE_PSYCH_UP,
++ MOVE_SNORE,
++ MOVE_ICY_WIND,
++ MOVE_ENDURE,
++ MOVE_MUD_SLAP,
++ MOVE_ICE_PUNCH,
++ MOVE_SWAGGER,
++ MOVE_SLEEP_TALK,
++ MOVE_SWIFT,
++ MOVE_THUNDER_PUNCH,
++ MOVE_FIRE_PUNCH,
++ MOVE_UNAVAILABLE, // This is required to determine where the array ends.
++};
+#endif
+```
+
+_NOTE: At the top of this file, you will probably see this warning:_
+```
+//
+// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py`
+//
+```
+The expansion includes a tool called the learnset helper, which aims to automate the generation of valid teachable moves. At the time of writing, this tool only supports generating TM and Tutor learnsets. However, in the future it may be expanded to deal with level up learnsets and egg moves.
+
+Ignore the warning shown above the first time you're adding your teachable moves (as otherwise the compiler will complain about the array not existing), but in the future (if you're using the learnset helper) simply edit what teachable moves your Pokémon can learn in one of the JSON files found in `tools/learnset_helpers/porymoves_files`. It doesn't really matter which one you add your new Pokémon to, as the tool pulls from all of the files in this folder.
+
+The learnset helper is useful if you plan on changing and/or increasing the available TMs and Tutor moves in your game. As an example, Bulbasaur learns Rage by TM in Red/Blue/Yellow, but in Emerald this TM does not exist. But since `tools/learnset_helpers/porymoves_files/rby.json` defines "MOVE_RAGE" as a TM move for Bulbasaur, that move would automatically be added to the `sBulbasaurTeachableLearnset` array if you were to add a Rage TM at any point.
+
+The learnset helper can be toggled on/off in `include/config/pokemon.h`:
+```
+// Learnset helper toggles
+#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors.
+```
+
+Once more, we need to register the learnset in `gSpeciesInfo`:
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ FOOTPRINT(Mewthree)
+ .levelUpLearnset = sMewthreeLevelUpLearnset,
++ .teachableLearnset = sMewthreeTeachableLearnset,
+ },
+ };
+```
+
+If you want to create a Pokémon which can breed, you will need to edit [src/data/pokemon/egg_moves.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/pokemon/egg_moves.h).
+
+
+## 3. Define the Evolutions
+
+We want Mewthree to evolve from Mewtwo by reaching level 100.
+
+Edit `gSpeciesInfo`:
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTWO] =
+ {
+ ...
+ FOOTPRINT(Mewtwo)
+ .isLegendary = TRUE,
+ .levelUpLearnset = sMewtwoLevelUpLearnset,
+ .teachableLearnset = sMewtwoTeachableLearnset,
+ .formSpeciesIdTable = sMewtwoFormSpeciesIdTable,
+ .formChangeTable = sMewtwoFormChangeTable,
++ .evolutions = EVOLUTION({EVO_LEVEL, 100, SPECIES_MEWTHREE}),
+ },
+ };
+```
+
+## 4. Make it appear!
+Now Mewthree really does slumber in the games code - but we won't know until we make him appear somewhere! The legend tells that Mewthree is hiding somewhere in Petalburg Woods...
+
+Edit [src/data/wild_encounters.json](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/wild_encounters.json):
+
+```diff
+ {
+ "map": "MAP_PETALBURG_WOODS",
+ "base_label": "gPetalburgWoods",
+ "land_mons": {
+ "encounter_rate": 20,
+ "mons": [
+ {
+ "min_level": 5,
+ "max_level": 5,
+ "species": "SPECIES_POOCHYENA"
+ },
+ {
+ "min_level": 5,
+ "max_level": 5,
+ "species": "SPECIES_WURMPLE"
+ },
+ {
+ "min_level": 5,
+ "max_level": 5,
+ "species": "SPECIES_SHROOMISH"
+ },
+ {
+- "min_level": 6,
+- "max_level": 6,
+- "species": "SPECIES_POOCHYENA"
++ "min_level": 5,
++ "max_level": 5,
++ "species": "SPECIES_MEWTHREE"
+ },
+ ...
+ }
+```
+
+Congratulations, you have created your own personal pocket monster! You may call yourself a mad scientist now.
+
+# Optional data
+
+Now that you now have all the essential pieces to create a base species, there are some aspects that you might want to know if you want to do other stuff with your custom Pokémon.
+
+## 1. Form tables
+Found in `src/data/pokemon/form_species_tables.h`.
+
+These are introduced to have a reference of what forms correspond to what Species of Pokémon. For example, we have Pikachu's table:
+```c
+#if P_FAMILY_PIKACHU
+static const u16 sPikachuFormSpeciesIdTable[] = {
+ SPECIES_PIKACHU,
+ SPECIES_PIKACHU_COSPLAY,
+ SPECIES_PIKACHU_ROCK_STAR,
+ SPECIES_PIKACHU_BELLE,
+ SPECIES_PIKACHU_POP_STAR,
+ SPECIES_PIKACHU_PH_D,
+ SPECIES_PIKACHU_LIBRE,
+ SPECIES_PIKACHU_ORIGINAL_CAP,
+ SPECIES_PIKACHU_HOENN_CAP,
+ SPECIES_PIKACHU_SINNOH_CAP,
+ SPECIES_PIKACHU_UNOVA_CAP,
+ SPECIES_PIKACHU_KALOS_CAP,
+ SPECIES_PIKACHU_ALOLA_CAP,
+ SPECIES_PIKACHU_PARTNER_CAP,
+ SPECIES_PIKACHU_WORLD_CAP,
+ FORM_SPECIES_END,
+};
+#endif //P_FAMILY_PIKACHU
+```
+We register the table each form entry in `gSpeciesInfo`.
+
+```diff
+ [SPECIES_PIKACHU] =
+ {
+ ...
+ .teachableLearnset = sPikachuTeachableLearnset,
++ .formSpeciesIdTable = sPikachuFormSpeciesIdTable,
+ .evolutions = EVOLUTION({EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_RAICHU},
+ {EVO_NONE, 0, SPECIES_RAICHU_ALOLAN}),
+ },
+
+ [SPECIES_PIKACHU_COSPLAY] =
+ {
+ ...
+ .teachableLearnset = sPikachuTeachableLearnset,
++ .formSpeciesIdTable = sPikachuFormSpeciesIdTable,
+ },
+```
+...and so on.
+
+What this allows us to do is to be able to get all forms of a Pokémon in our code by using the `GetSpeciesFormTable` function.
+
+For example, in the HGSS dex, it lets us browse between the entries of every form available.:
+
+ 
+
+In addition, we have the `GET_BASE_SPECIES_ID` macro, which returns the first entry of the table (or return the species itself if it doesn't have a table registered). With this, you can check if a Pokémon is any form of a species. For example, making it so that the Light Ball affects all Pikachu forms:
+```c
+ case HOLD_EFFECT_LIGHT_BALL:
+ if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_PIKACHU && IS_MOVE_SPECIAL(move))
+ modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
+ break;
+```
+
+## 2. Form change tables
+Found in `src/data/pokemon/form_species_tables.h`.
+
+These tables, unlike the regular form tables, registers how Pokémon can switch between forms.
+
+```c
+#if P_FAMILY_GASTLY
+static const struct FormChange sGengarFormChangeTable[] = {
+ {FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GENGAR_MEGA, ITEM_GENGARITE},
+ {FORM_CHANGE_BATTLE_GIGANTAMAX, SPECIES_GENGAR_GIGANTAMAX},
+ {FORM_CHANGE_TERMINATOR},
+};
+#endif //P_FAMILY_GASTLY
+```
+The first value is the type of form change. In the case of Gengar, we have both Mega Evolution and Gigantamax form changes.
+
+The second value is the target form, to which the Pokémon will change into.
+
+Values after that are referred as arguments, and needs to be put there depends on the type of form change, detailed in `include/constants/form_change_types.h`.
+
+## 3. Gender differences
+
+
+You may have seen that there's a couple of duplicate fields with a "Female" suffix.
+```diff
+ [SPECIES_FRILLISH] =
+ {
+ ...
+ .frontPic = gMonFrontPic_Frillish,
++ .frontPicFemale = gMonFrontPic_FrillishF,
+ .frontPicSize = MON_COORDS_SIZE(56, 56),
++ .frontPicSizeFemale = MON_COORDS_SIZE(56, 56),
+ .frontPicYOffset = 5,
+ .frontAnimFrames = sAnims_Frillish,
+ .frontAnimId = ANIM_RISING_WOBBLE,
+ .backPic = gMonBackPic_Frillish,
++ .backPicFemale = gMonBackPic_FrillishF,
+ .backPicSize = MON_COORDS_SIZE(40, 56),
++ .backPicSizeFemale = MON_COORDS_SIZE(40, 56),
+ .backPicYOffset = 7,
+ .backAnimId = BACK_ANIM_CONVEX_DOUBLE_ARC,
+ .palette = gMonPalette_Frillish,
++ .paletteFemale = gMonPalette_FrillishF,
+ .shinyPalette = gMonShinyPalette_Frillish,
++ .shinyPaletteFemale = gMonShinyPalette_FrillishF,
+ .iconSprite = gMonIcon_Frillish,
++ .iconSpriteFemale = gMonIcon_FrillishF,
+ .iconPalIndex = 0,
++ .iconPalIndexFemale = 1,
+ FOOTPRINT(Frillish)
+ .levelUpLearnset = sFrillishLevelUpLearnset,
+ .teachableLearnset = sFrillishTeachableLearnset,
+ .evolutions = EVOLUTION({EVO_LEVEL, 40, SPECIES_JELLICENT}),
+ },
+```
+These are used to change the graphics of the Pokémon if they're female. If they're not registered, they default to the male values.
+
+However, `iconPalIndexFemale` is a special case, where it's *doesn't* read the male icon palette if its `iconSpriteFemale` is set, so if you're setting a female icon, be sure to set their palette index as well.
+
+## 4. Overworld Data
+
+
+If you have `OW_POKEMON_OBJECT_EVENTS` in your hack, you can add Overworld of your new species by following these steps:
+
+First, since you copied the contents from Mew's folder previously, you should also have copied its overworld sprites. Edit those to your liking, as we have done before, making sure to update the palettes
+
+Secondly, in [src/data/graphics/pokemon.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/graphics/pokemon.h), add the following:
+
+```diff
+ const u8 gMonIcon_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/icon.4bpp");
+ const u8 gMonFootprint_Mewthree[] = INCBIN_U8("graphics/pokemon/mewthree/footprint.1bpp");
++ const u32 gObjectEventPic_Mewthree[] = INCBIN_COMP("graphics/pokemon/mewthree/overworld.4bpp");
++ const u32 gOverworldPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/overworld_normal.gbapal.lz");
++ const u32 gShinyOverworldPalette_Mewthree[] = INCBIN_U32("graphics/pokemon/mewthree/overworld_shiny.gbapal.lz");
+```
+
+Thirdly, in [spritesheet_rules.mk](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/spritesheet_rules.mk)
+
+```diff
+$(POKEMONGFXDIR)/mewtwo/overworld.4bpp: %.4bpp: %.png
+ $(GFX) $< $@ -mwidth 4 -mheight 4
+
++$(POKEMONGFXDIR)/mewthree/overworld.4bpp: %.4bpp: %.png
++ $(GFX) $< $@ -mwidth 4 -mheight 4
+
+$(POKEMONGFXDIR)/mew/overworld.4bpp: %.4bpp: %.png
+ $(GFX) $< $@ -mwidth 4 -mheight 4
+```
+
+Fourthly, in [src/data/object_events/object_event_pic_tables_followers.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/object_events/object_event_pic_tables_followers.h):
+```diff
+#if P_FAMILY_PECHARUNT
+/*static const struct SpriteFrameImage sPicTable_Pecharunt[] = {
+ overworld_ascending_frames(gObjectEventPic_Pecharunt, 4, 4),
+};*/
+#endif //P_FAMILY_PECHARUNT
+
++static const struct SpriteFrameImage sPicTable_Mewthree[] = {
++ overworld_ascending_frames(gObjectEventPic_Mewthree, 4, 4),
++};
+```
+
+And finally, in `gSpeciesInfo`:
+
+```diff
+ const struct SpeciesInfo gSpeciesInfo[] =
+ {
+ ...
+ [SPECIES_MEWTHREE] =
+ {
+ ...
+ FOOTPRINT(Mewthree)
++ OVERWORLD(
++ sPicTable_Mewthree,
++ SIZE_32x32,
++ SHADOW_SIZE_M,
++ TRACKS_FOOT,
++ gOverworldPalette_Mewthree,
++ gShinyOverworldPalette_Mewthree
++ )
+ .levelUpLearnset = sMewthreeLevelUpLearnset,
+ .teachableLearnset = sMewthreeTeachableLearnset,
+ },
+ };
+```
+
+### Sprite Size
+Depending on your species, you might want to use different sizes for it. For example, certain species known for being big like Steelix use sprites that fit a 64x64 frame instead of 32x32, and as such have `SIZE_64x64` in their data instead of `SIZE_32x32` to accomodate for them.
+
+Also, in `spritesheet_rules.mk`, `-mwidth` and `-mheight` need to be set to 8 instead of 4 for such cases.
+
+### Shadows
+Gen 4 style shadows are defined by the `SHADOW` macro which takes the following arguments:
+ - X offset
+ - Y offset
+ - Shadow size
+You have 4 options for their shadow, between Small, Medium, Large and Extra Large:
+ - `SHADOW_SIZE_S`
+ - `SHADOW_SIZE_M`
+ - `SHADOW_SIZE_L`
+ - `SHADOW_SIZE_XL_BATTLE_ONLY`
+To make the Pokémon have no shadow, use the `NO_SHADOW` macro instead of `SHADOW`.
+
+### Tracks
+You have 4 options for the tracks that your species will leave behind on sand.
+ - `TRACKS_NONE`
+ - `TRACKS_FOOT` 
+ - `TRACKS_SLITHER` 
+ - `TRACKS_SPOT` 
+ - `TRACKS_BUG` 
+
+ ...though technically you can also use `TRACKS_BIKE_TIRE` if you wish to.
+
+
diff --git a/docs/tutorials/how_to_new_pokemon_1_9_0.md b/docs/tutorials/how_to_new_pokemon_1_9_0.md
index e64f8e6e66..aad3332873 100644
--- a/docs/tutorials/how_to_new_pokemon_1_9_0.md
+++ b/docs/tutorials/how_to_new_pokemon_1_9_0.md
@@ -839,6 +839,24 @@ static const u16 sPecharuntTeachableLearnset[] = {
#endif
```
+_NOTE: At the top of this file, you will probably see this warning:_
+```
+//
+// DO NOT MODIFY THIS FILE! It is auto-generated from tools/learnset_helpers/teachable.py`
+//
+```
+The expansion includes a tool called the learnset helper, which aims to automate the generation of valid teachable moves. At the time of writing, this tool only supports generating TM and Tutor learnsets. However, in the future it may be expanded to deal with level up learnsets and egg moves.
+
+Ignore the warning shown above the first time you're adding your teachable moves (as otherwise the compiler will complain about the array not existing), but in the future (if you're using the learnset helper) simply edit what teachable moves your Pokémon can learn in one of the JSON files found in `tools/learnset_helpers/porymoves_files`. It doesn't really matter which one you add your new Pokémon to, as the tool pulls from all of the files in this folder.
+
+The learnset helper is useful if you plan on changing and/or increasing the available TMs and Tutor moves in your game. As an example, Bulbasaur learns Rage by TM in Red/Blue/Yellow, but in Emerald this TM does not exist. But since `tools/learnset_helpers/porymoves_files/rby.json` defines "MOVE_RAGE" as a TM move for Bulbasaur, that move would automatically be added to the `sBulbasaurTeachableLearnset` array if you were to add a Rage TM at any point.
+
+The learnset helper can be toggled on/off in `include/config/pokemon.h`:
+```
+// Learnset helper toggles
+#define P_LEARNSET_HELPER_TEACHABLE TRUE // If TRUE, teachable_learnsets.h will be populated by tools/learnset_helpers/teachable.py using the included JSON files based on available TMs and tutors.
+```
+
Once more, we need to register the learnset in `gSpeciesInfo`:
```diff
diff --git a/docs/tutorials/how_to_testing_system.md b/docs/tutorials/how_to_testing_system.md
index c573dfbbf7..da11944e25 100644
--- a/docs/tutorials/how_to_testing_system.md
+++ b/docs/tutorials/how_to_testing_system.md
@@ -32,7 +32,7 @@ This can be translated to an automated test as follows:
```
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE);
+ ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE);
}
SINGLE_BATTLE_TEST("Stun Spore inflicts paralysis")
@@ -78,7 +78,7 @@ This can again be translated as follows:
SINGLE_BATTLE_TEST("Stun Spore does not affect Grass-types")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS);
PLAYER(SPECIES_ODDISH); // 1.
OPPONENT(SPECIES_ODDISH); // 2.
@@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Meditate raises Attack", s16 damage)
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -146,7 +146,7 @@ The overworld is not available, so it is only possible to test commands which do
### `ASSUME`
`ASSUME(cond)`
Causes the test to be skipped if `cond` is false. Used to document any prerequisites of the test, e.g. to test Burn reducing the Attack of a Pokémon we can observe the damage of a physical attack with and without the burn. To document that this test assumes the attack is physical we can use:
-`ASSUME(gMovesInfo[MOVE_WHATEVER].category == DAMAGE_CATEGORY_PHYSICAL);`
+`ASSUME(GetMoveCategory(MOVE_WHATEVER) == DAMAGE_CATEGORY_PHYSICAL);`
### `ASSUMPTIONS`
```
@@ -159,7 +159,7 @@ Should be placed immediately after any `#includes` and contain any `ASSUME` stat
```
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_POISON_STING].effect == EFFECT_POISON_HIT);
+ ASSUME(GetMoveEffect(MOVE_POISON_STING) == EFFECT_POISON_HIT);
}
```
@@ -201,7 +201,7 @@ SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage)
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -233,7 +233,7 @@ SINGLE_BATTLE_TEST("Paralysis has a 25% chance of skipping the turn")
All `BattleRandom` calls involving tag will return the same number, so this cannot be used to have two moves independently hit or miss, for example.
If the tag is not provided, runs the test 50 times and computes an approximate pass ratio.
-`PASSES_RANDOMLY(gMovesInfo[move].accuracy, 100);`
+`PASSES_RANDOMLY(GetMoveAccuracy(move), 100);`
Note that this mode of PASSES_RANDOMLY makes the tests run very slowly and should be avoided where possible. If the mechanic you are testing is missing its tag, you should add it.
### `GIVEN`
diff --git a/graphics/battle_anims/sprites/attack_order.png b/graphics/battle_anims/sprites/attack_order.png
index 18531b8304..624708545e 100644
Binary files a/graphics/battle_anims/sprites/attack_order.png and b/graphics/battle_anims/sprites/attack_order.png differ
diff --git a/graphics/battle_anims/sprites/aura_sphere.png b/graphics/battle_anims/sprites/aura_sphere.png
index 04c5030245..4ee16cd488 100644
Binary files a/graphics/battle_anims/sprites/aura_sphere.png and b/graphics/battle_anims/sprites/aura_sphere.png differ
diff --git a/graphics/battle_anims/sprites/blue_flare.pal b/graphics/battle_anims/sprites/blue_flare.pal
index 3b224c3459..87bb2254a3 100644
--- a/graphics/battle_anims/sprites/blue_flare.pal
+++ b/graphics/battle_anims/sprites/blue_flare.pal
@@ -1,6 +1,6 @@
JASC-PAL
0100
-256
+16
0 0 0
248 248 248
205 248 255
@@ -17,243 +17,3 @@ JASC-PAL
238 238 238
189 189 189
156 164 164
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
-0 0 0
diff --git a/graphics/battle_anims/sprites/dragon_pulse.png b/graphics/battle_anims/sprites/dragon_pulse.png
index cc6e28bc32..5a1f62321f 100644
Binary files a/graphics/battle_anims/sprites/dragon_pulse.png and b/graphics/battle_anims/sprites/dragon_pulse.png differ
diff --git a/graphics/battle_anims/sprites/embers.png b/graphics/battle_anims/sprites/embers.png
index 8bf2dd5aa6..c5799e7160 100644
Binary files a/graphics/battle_anims/sprites/embers.png and b/graphics/battle_anims/sprites/embers.png differ
diff --git a/graphics/battle_anims/sprites/fly.png b/graphics/battle_anims/sprites/fly.png
index dd1149de99..ff648a6e2e 100644
Binary files a/graphics/battle_anims/sprites/fly.png and b/graphics/battle_anims/sprites/fly.png differ
diff --git a/graphics/battle_anims/sprites/horn_hit_new.png b/graphics/battle_anims/sprites/horn_hit_new.png
index 9bdf61d7d9..0e1a9f2076 100644
Binary files a/graphics/battle_anims/sprites/horn_hit_new.png and b/graphics/battle_anims/sprites/horn_hit_new.png differ
diff --git a/graphics/battle_anims/sprites/mean_look.png b/graphics/battle_anims/sprites/mean_look.png
index 30e6eb5eea..ee9ad320b0 100644
Binary files a/graphics/battle_anims/sprites/mean_look.png and b/graphics/battle_anims/sprites/mean_look.png differ
diff --git a/graphics/battle_anims/sprites/poison_jab.png b/graphics/battle_anims/sprites/poison_jab.png
index e7871a2c9d..b03f4f8d7e 100644
Binary files a/graphics/battle_anims/sprites/poison_jab.png and b/graphics/battle_anims/sprites/poison_jab.png differ
diff --git a/graphics/battle_anims/sprites/power_gem.png b/graphics/battle_anims/sprites/power_gem.png
index 8d9ad469e3..439610c71b 100644
Binary files a/graphics/battle_anims/sprites/power_gem.png and b/graphics/battle_anims/sprites/power_gem.png differ
diff --git a/graphics/battle_anims/sprites/psycho_cut.png b/graphics/battle_anims/sprites/psycho_cut.png
index 3eb1de7d2a..f40d21f706 100644
Binary files a/graphics/battle_anims/sprites/psycho_cut.png and b/graphics/battle_anims/sprites/psycho_cut.png differ
diff --git a/graphics/battle_anims/sprites/stealth_rock.png b/graphics/battle_anims/sprites/stealth_rock.png
index 8b38ae1c17..9334a3419a 100644
Binary files a/graphics/battle_anims/sprites/stealth_rock.png and b/graphics/battle_anims/sprites/stealth_rock.png differ
diff --git a/graphics/battle_anims/sprites/stone_edge.png b/graphics/battle_anims/sprites/stone_edge.png
index 44f678d8db..80377da7ee 100644
Binary files a/graphics/battle_anims/sprites/stone_edge.png and b/graphics/battle_anims/sprites/stone_edge.png differ
diff --git a/graphics/battle_anims/sprites/wood_hammer.png b/graphics/battle_anims/sprites/wood_hammer.png
index 5768605f80..16e1749835 100644
Binary files a/graphics/battle_anims/sprites/wood_hammer.png and b/graphics/battle_anims/sprites/wood_hammer.png differ
diff --git a/graphics/birch_speech/bg2.pal b/graphics/birch_speech/bg2.pal
index 3457f9b455..33f619ee44 100644
--- a/graphics/birch_speech/bg2.pal
+++ b/graphics/birch_speech/bg2.pal
@@ -1,6 +1,6 @@
JASC-PAL
0100
-8
+16
255 255 164
255 255 106
222 222 90
@@ -9,3 +9,11 @@ JASC-PAL
123 123 49
90 90 32
57 57 16
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
diff --git a/graphics/fonts/latin_narrow.png b/graphics/fonts/latin_narrow.png
index 08652d45f4..434638ed17 100644
Binary files a/graphics/fonts/latin_narrow.png and b/graphics/fonts/latin_narrow.png differ
diff --git a/graphics/fonts/latin_narrower.png b/graphics/fonts/latin_narrower.png
index 22847ef099..19a6a98fb6 100644
Binary files a/graphics/fonts/latin_narrower.png and b/graphics/fonts/latin_narrower.png differ
diff --git a/graphics/fonts/latin_short.png b/graphics/fonts/latin_short.png
index 7eba3e748b..98ad3c5cc3 100644
Binary files a/graphics/fonts/latin_short.png and b/graphics/fonts/latin_short.png differ
diff --git a/graphics/fonts/latin_short_narrow.png b/graphics/fonts/latin_short_narrow.png
index cf48712719..6bf1bae0cf 100644
Binary files a/graphics/fonts/latin_short_narrow.png and b/graphics/fonts/latin_short_narrow.png differ
diff --git a/graphics/fonts/latin_short_narrower.png b/graphics/fonts/latin_short_narrower.png
new file mode 100644
index 0000000000..5c4f4c1d4d
Binary files /dev/null and b/graphics/fonts/latin_short_narrower.png differ
diff --git a/graphics/fonts/latin_small.png b/graphics/fonts/latin_small.png
index 371cd5a968..41bb38cff8 100644
Binary files a/graphics/fonts/latin_small.png and b/graphics/fonts/latin_small.png differ
diff --git a/graphics/fonts/latin_small_narrow.png b/graphics/fonts/latin_small_narrow.png
index 3a88def3ad..ff07b857d7 100644
Binary files a/graphics/fonts/latin_small_narrow.png and b/graphics/fonts/latin_small_narrow.png differ
diff --git a/graphics/fonts/latin_small_narrower.png b/graphics/fonts/latin_small_narrower.png
index a183bed7cc..c20fa4ae48 100644
Binary files a/graphics/fonts/latin_small_narrower.png and b/graphics/fonts/latin_small_narrower.png differ
diff --git a/graphics/pokemon/araquanid/icon.png b/graphics/pokemon/araquanid/icon.png
index fa13eba833..10676126a1 100644
Binary files a/graphics/pokemon/araquanid/icon.png and b/graphics/pokemon/araquanid/icon.png differ
diff --git a/graphics/pokemon/ariados/anim_front.png b/graphics/pokemon/ariados/anim_front.png
index 945c4d188f..82d947054b 100644
Binary files a/graphics/pokemon/ariados/anim_front.png and b/graphics/pokemon/ariados/anim_front.png differ
diff --git a/graphics/pokemon/audino/overworld.png b/graphics/pokemon/audino/overworld.png
index 27fdc5f6b7..082abdd270 100644
Binary files a/graphics/pokemon/audino/overworld.png and b/graphics/pokemon/audino/overworld.png differ
diff --git a/graphics/pokemon/bewear/icon.png b/graphics/pokemon/bewear/icon.png
index 5ceb073fbc..30cc966723 100644
Binary files a/graphics/pokemon/bewear/icon.png and b/graphics/pokemon/bewear/icon.png differ
diff --git a/graphics/pokemon/blacephalon/icon.png b/graphics/pokemon/blacephalon/icon.png
index bb1f9cdc31..c3fad2f3ef 100644
Binary files a/graphics/pokemon/blacephalon/icon.png and b/graphics/pokemon/blacephalon/icon.png differ
diff --git a/graphics/pokemon/boldore/overworld.png b/graphics/pokemon/boldore/overworld.png
index 013a09dcf3..e4c4cb5b11 100644
Binary files a/graphics/pokemon/boldore/overworld.png and b/graphics/pokemon/boldore/overworld.png differ
diff --git a/graphics/pokemon/bounsweet/icon.png b/graphics/pokemon/bounsweet/icon.png
index 80df38b9ad..5fa805deb0 100644
Binary files a/graphics/pokemon/bounsweet/icon.png and b/graphics/pokemon/bounsweet/icon.png differ
diff --git a/graphics/pokemon/brionne/icon.png b/graphics/pokemon/brionne/icon.png
index da33e8ee07..88cf5d01b4 100644
Binary files a/graphics/pokemon/brionne/icon.png and b/graphics/pokemon/brionne/icon.png differ
diff --git a/graphics/pokemon/bruxish/icon.png b/graphics/pokemon/bruxish/icon.png
index 00d049a5c6..eab625140e 100644
Binary files a/graphics/pokemon/bruxish/icon.png and b/graphics/pokemon/bruxish/icon.png differ
diff --git a/graphics/pokemon/bulbasaur/icon.png b/graphics/pokemon/bulbasaur/icon.png
index 7738836b9c..d8f508ee86 100644
Binary files a/graphics/pokemon/bulbasaur/icon.png and b/graphics/pokemon/bulbasaur/icon.png differ
diff --git a/graphics/pokemon/buzzwole/icon.png b/graphics/pokemon/buzzwole/icon.png
index 72e3270dac..c1126c081d 100644
Binary files a/graphics/pokemon/buzzwole/icon.png and b/graphics/pokemon/buzzwole/icon.png differ
diff --git a/graphics/pokemon/celesteela/icon.png b/graphics/pokemon/celesteela/icon.png
index 854c36851a..7722e43dac 100644
Binary files a/graphics/pokemon/celesteela/icon.png and b/graphics/pokemon/celesteela/icon.png differ
diff --git a/graphics/pokemon/charjabug/icon.png b/graphics/pokemon/charjabug/icon.png
index eb2f9206e9..6743ab6818 100644
Binary files a/graphics/pokemon/charjabug/icon.png and b/graphics/pokemon/charjabug/icon.png differ
diff --git a/graphics/pokemon/cinderace/gmax/icon.png b/graphics/pokemon/cinderace/gmax/icon.png
index 3d1f1e4237..791801bb65 100644
Binary files a/graphics/pokemon/cinderace/gmax/icon.png and b/graphics/pokemon/cinderace/gmax/icon.png differ
diff --git a/graphics/pokemon/comfey/icon.png b/graphics/pokemon/comfey/icon.png
index 916ac5c188..10d1a3fe5a 100644
Binary files a/graphics/pokemon/comfey/icon.png and b/graphics/pokemon/comfey/icon.png differ
diff --git a/graphics/pokemon/cosmoem/icon.png b/graphics/pokemon/cosmoem/icon.png
index ab4c13b8f2..c461bdadaf 100644
Binary files a/graphics/pokemon/cosmoem/icon.png and b/graphics/pokemon/cosmoem/icon.png differ
diff --git a/graphics/pokemon/cosmog/icon.png b/graphics/pokemon/cosmog/icon.png
index 6057034a9a..a74b399d12 100644
Binary files a/graphics/pokemon/cosmog/icon.png and b/graphics/pokemon/cosmog/icon.png differ
diff --git a/graphics/pokemon/cottonee/overworld.png b/graphics/pokemon/cottonee/overworld.png
index 15aec04067..55a0d48bad 100644
Binary files a/graphics/pokemon/cottonee/overworld.png and b/graphics/pokemon/cottonee/overworld.png differ
diff --git a/graphics/pokemon/cottonee/overworld_normal.pal b/graphics/pokemon/cottonee/overworld_normal.pal
index 76222db0ce..2af87bcf9f 100644
--- a/graphics/pokemon/cottonee/overworld_normal.pal
+++ b/graphics/pokemon/cottonee/overworld_normal.pal
@@ -3,17 +3,17 @@ JASC-PAL
16
152 208 160
110 110 110
-204 227 209
-208 241 229
-164 207 173
+198 212 159
+222 230 197
+165 173 132
64 128 16
92 224 48
74 176 49
47 46 47
-198 196 235
-137 162 175
+165 173 132
+123 132 107
238 238 247
137 117 107
-230 77 40
+230 132 0
0 0 0
0 0 0
diff --git a/graphics/pokemon/cottonee/overworld_shiny.pal b/graphics/pokemon/cottonee/overworld_shiny.pal
index bb3d8c85c8..d530eb0894 100644
--- a/graphics/pokemon/cottonee/overworld_shiny.pal
+++ b/graphics/pokemon/cottonee/overworld_shiny.pal
@@ -11,9 +11,9 @@ JASC-PAL
192 96 40
47 46 47
192 176 136
-137 162 175
+112 96 40
248 248 248
-137 117 107
-230 77 40
+138 106 91
+112 184 0
0 0 0
0 0 0
diff --git a/graphics/pokemon/crabominable/icon.png b/graphics/pokemon/crabominable/icon.png
index e3f32d5046..c3ae3235b6 100644
Binary files a/graphics/pokemon/crabominable/icon.png and b/graphics/pokemon/crabominable/icon.png differ
diff --git a/graphics/pokemon/crabrawler/icon.png b/graphics/pokemon/crabrawler/icon.png
index d28b81b6b6..47b3b34512 100644
Binary files a/graphics/pokemon/crabrawler/icon.png and b/graphics/pokemon/crabrawler/icon.png differ
diff --git a/graphics/pokemon/cutiefly/icon.png b/graphics/pokemon/cutiefly/icon.png
index 5e25a942da..25af39c74c 100644
Binary files a/graphics/pokemon/cutiefly/icon.png and b/graphics/pokemon/cutiefly/icon.png differ
diff --git a/graphics/pokemon/dartrix/icon.png b/graphics/pokemon/dartrix/icon.png
index 39fb8fddd0..bd378938d3 100644
Binary files a/graphics/pokemon/dartrix/icon.png and b/graphics/pokemon/dartrix/icon.png differ
diff --git a/graphics/pokemon/decidueye/icon.png b/graphics/pokemon/decidueye/icon.png
index 6078f20b83..8cb628c31f 100644
Binary files a/graphics/pokemon/decidueye/icon.png and b/graphics/pokemon/decidueye/icon.png differ
diff --git a/graphics/pokemon/deoxys/anim_front.png b/graphics/pokemon/deoxys/anim_front.png
index d2f3e99381..fc782931d1 100644
Binary files a/graphics/pokemon/deoxys/anim_front.png and b/graphics/pokemon/deoxys/anim_front.png differ
diff --git a/graphics/pokemon/deoxys/attack/anim_front.png b/graphics/pokemon/deoxys/attack/anim_front.png
index 0b43a9fe11..566e80eafd 100644
Binary files a/graphics/pokemon/deoxys/attack/anim_front.png and b/graphics/pokemon/deoxys/attack/anim_front.png differ
diff --git a/graphics/pokemon/deoxys/attack/normal.pal b/graphics/pokemon/deoxys/attack/normal.pal
index 246d4784a2..52ddbb8fc6 100644
--- a/graphics/pokemon/deoxys/attack/normal.pal
+++ b/graphics/pokemon/deoxys/attack/normal.pal
@@ -3,8 +3,8 @@ JASC-PAL
16
248 160 176
96 56 56
-248 112 72
-184 104 104
+255 115 74
+204 65 65
24 24 24
104 200 224
80 144 176
diff --git a/graphics/pokemon/deoxys/defense/anim_front.png b/graphics/pokemon/deoxys/defense/anim_front.png
index 2ee6e0c527..ce3cdad39c 100644
Binary files a/graphics/pokemon/deoxys/defense/anim_front.png and b/graphics/pokemon/deoxys/defense/anim_front.png differ
diff --git a/graphics/pokemon/deoxys/defense/normal.pal b/graphics/pokemon/deoxys/defense/normal.pal
index 8b37f5111e..4beda86136 100644
--- a/graphics/pokemon/deoxys/defense/normal.pal
+++ b/graphics/pokemon/deoxys/defense/normal.pal
@@ -3,9 +3,9 @@ JASC-PAL
16
248 160 176
96 56 56
-192 104 104
-248 112 72
-96 64 48
+204 65 65
+255 115 74
+68 28 89
240 176 144
104 200 224
80 144 176
diff --git a/graphics/pokemon/deoxys/defense/shiny.pal b/graphics/pokemon/deoxys/defense/shiny.pal
index c1f34410a4..3f285246c6 100644
--- a/graphics/pokemon/deoxys/defense/shiny.pal
+++ b/graphics/pokemon/deoxys/defense/shiny.pal
@@ -5,7 +5,7 @@ JASC-PAL
112 96 16
168 168 56
248 232 64
-96 64 48
+49 29 82
248 248 216
112 208 168
72 160 112
diff --git a/graphics/pokemon/deoxys/normal.pal b/graphics/pokemon/deoxys/normal.pal
index 59124c56a9..e11c277719 100644
--- a/graphics/pokemon/deoxys/normal.pal
+++ b/graphics/pokemon/deoxys/normal.pal
@@ -2,12 +2,12 @@ JASC-PAL
0100
16
248 160 176
-184 104 104
+204 65 65
248 176 144
-248 112 72
+255 115 74
96 56 56
104 200 224
-88 56 48
+68 28 89
56 80 96
80 144 176
152 96 176
diff --git a/graphics/pokemon/deoxys/shiny.pal b/graphics/pokemon/deoxys/shiny.pal
index 5bbc6b683a..621aac6d42 100644
--- a/graphics/pokemon/deoxys/shiny.pal
+++ b/graphics/pokemon/deoxys/shiny.pal
@@ -7,7 +7,7 @@ JASC-PAL
248 232 64
112 96 16
112 208 168
-112 96 16
+51 27 101
56 96 88
72 160 112
96 120 192
diff --git a/graphics/pokemon/deoxys/speed/anim_front.png b/graphics/pokemon/deoxys/speed/anim_front.png
index 947052f81d..1f2063bddf 100644
Binary files a/graphics/pokemon/deoxys/speed/anim_front.png and b/graphics/pokemon/deoxys/speed/anim_front.png differ
diff --git a/graphics/pokemon/deoxys/speed/normal.pal b/graphics/pokemon/deoxys/speed/normal.pal
index dad052e1da..ea1073a0ee 100644
--- a/graphics/pokemon/deoxys/speed/normal.pal
+++ b/graphics/pokemon/deoxys/speed/normal.pal
@@ -6,9 +6,9 @@ JASC-PAL
80 144 176
104 200 224
96 56 56
-248 112 72
+255 115 74
24 24 24
-192 104 104
+204 65 65
192 192 208
152 96 176
248 248 248
diff --git a/graphics/pokemon/dewpider/icon.png b/graphics/pokemon/dewpider/icon.png
index bcf5707d32..2cc98e2a36 100644
Binary files a/graphics/pokemon/dewpider/icon.png and b/graphics/pokemon/dewpider/icon.png differ
diff --git a/graphics/pokemon/dhelmise/icon.png b/graphics/pokemon/dhelmise/icon.png
index 07b0c4d180..fd7e83627f 100644
Binary files a/graphics/pokemon/dhelmise/icon.png and b/graphics/pokemon/dhelmise/icon.png differ
diff --git a/graphics/pokemon/diggersby/anim_front.png b/graphics/pokemon/diggersby/anim_front.png
index f2a0998e88..69c49c5276 100644
Binary files a/graphics/pokemon/diggersby/anim_front.png and b/graphics/pokemon/diggersby/anim_front.png differ
diff --git a/graphics/pokemon/diggersby/back.png b/graphics/pokemon/diggersby/back.png
index 36a4373816..a1cc29260d 100644
Binary files a/graphics/pokemon/diggersby/back.png and b/graphics/pokemon/diggersby/back.png differ
diff --git a/graphics/pokemon/diggersby/shiny.pal b/graphics/pokemon/diggersby/shiny.pal
index 5fd7727a42..f5f12f2cf0 100644
--- a/graphics/pokemon/diggersby/shiny.pal
+++ b/graphics/pokemon/diggersby/shiny.pal
@@ -6,7 +6,7 @@ JASC-PAL
120 120 112
160 160 144
8 8 8
-120 120 112
+84 84 78
48 48 56
232 232 232
240 152 168
diff --git a/graphics/pokemon/diglett/alola/icon.png b/graphics/pokemon/diglett/alola/icon.png
index 1b575078a3..ccde6cb2a3 100644
Binary files a/graphics/pokemon/diglett/alola/icon.png and b/graphics/pokemon/diglett/alola/icon.png differ
diff --git a/graphics/pokemon/drampa/icon.png b/graphics/pokemon/drampa/icon.png
index 5550dcb742..59428b634e 100644
Binary files a/graphics/pokemon/drampa/icon.png and b/graphics/pokemon/drampa/icon.png differ
diff --git a/graphics/pokemon/drilbur/overworld.png b/graphics/pokemon/drilbur/overworld.png
index 9d1c7ddcf8..981e575fc1 100644
Binary files a/graphics/pokemon/drilbur/overworld.png and b/graphics/pokemon/drilbur/overworld.png differ
diff --git a/graphics/pokemon/drilbur/overworld_normal.pal b/graphics/pokemon/drilbur/overworld_normal.pal
index 34ab39137a..9d33ec6250 100644
--- a/graphics/pokemon/drilbur/overworld_normal.pal
+++ b/graphics/pokemon/drilbur/overworld_normal.pal
@@ -5,7 +5,7 @@ JASC-PAL
40 40 40
40 40 40
11 11 11
-55 55 55
+43 43 43
55 55 55
87 87 87
0 0 0
diff --git a/graphics/pokemon/dugtrio/alola/icon.png b/graphics/pokemon/dugtrio/alola/icon.png
index 2a409cb8d0..3b10a41c6b 100644
Binary files a/graphics/pokemon/dugtrio/alola/icon.png and b/graphics/pokemon/dugtrio/alola/icon.png differ
diff --git a/graphics/pokemon/duraludon/overworld.png b/graphics/pokemon/duraludon/overworld.png
index 0c8228abcb..a7488c4960 100644
Binary files a/graphics/pokemon/duraludon/overworld.png and b/graphics/pokemon/duraludon/overworld.png differ
diff --git a/graphics/pokemon/emboar/overworld.png b/graphics/pokemon/emboar/overworld.png
index 06e17288d7..e647d062c3 100644
Binary files a/graphics/pokemon/emboar/overworld.png and b/graphics/pokemon/emboar/overworld.png differ
diff --git a/graphics/pokemon/emboar/overworld_normal.pal b/graphics/pokemon/emboar/overworld_normal.pal
index e9f672d506..e507a90ca9 100644
--- a/graphics/pokemon/emboar/overworld_normal.pal
+++ b/graphics/pokemon/emboar/overworld_normal.pal
@@ -6,14 +6,14 @@ JASC-PAL
5 5 5
48 48 48
111 40 1
-216 85 36
-188 82 31
+224 88 25
+184 80 32
119 19 12
-215 195 196
+240 240 240
230 49 41
-237 172 8
-180 139 32
+232 184 8
+176 136 32
123 90 8
-0 0 0
-0 0 0
+160 56 48
+64 64 64
0 0 0
diff --git a/graphics/pokemon/emboar/overworld_shiny.pal b/graphics/pokemon/emboar/overworld_shiny.pal
index 1c5459473d..8fa173f591 100644
--- a/graphics/pokemon/emboar/overworld_shiny.pal
+++ b/graphics/pokemon/emboar/overworld_shiny.pal
@@ -2,18 +2,18 @@ JASC-PAL
0100
16
152 208 160
-41 41 41
+32 32 32
5 5 5
-41 41 41
+48 48 48
117 70 5
229 130 31
-41 41 41
-41 41 41
-229 130 31
+168 96 40
+49 53 92
+240 240 240
128 152 224
151 195 221
128 152 224
-117 70 5
-0 0 0
-0 0 0
+64 72 144
+96 112 184
+61 61 61
0 0 0
diff --git a/graphics/pokemon/enamorus/anim_front.png b/graphics/pokemon/enamorus/anim_front.png
new file mode 100644
index 0000000000..e4b21fc52a
Binary files /dev/null and b/graphics/pokemon/enamorus/anim_front.png differ
diff --git a/graphics/pokemon/enamorus/back.png b/graphics/pokemon/enamorus/back.png
index 1b2b00e218..17668de576 100755
Binary files a/graphics/pokemon/enamorus/back.png and b/graphics/pokemon/enamorus/back.png differ
diff --git a/graphics/pokemon/enamorus/front.png b/graphics/pokemon/enamorus/front.png
deleted file mode 100755
index c679b07e57..0000000000
Binary files a/graphics/pokemon/enamorus/front.png and /dev/null differ
diff --git a/graphics/pokemon/enamorus/normal.pal b/graphics/pokemon/enamorus/normal.pal
index 08f6e5ebf1..b8986ffd46 100755
--- a/graphics/pokemon/enamorus/normal.pal
+++ b/graphics/pokemon/enamorus/normal.pal
@@ -2,18 +2,18 @@ JASC-PAL
0100
16
153 211 165
-74 74 74
+255 255 255
180 180 189
-252 252 252
+105 106 115
16 16 16
-118 50 58
-147 33 30
-224 116 156
-243 46 46
-174 74 87
-199 46 41
-243 84 143
-187 62 94
-255 197 60
-239 228 176
-0 0 0
+237 129 170
+185 81 133
+126 44 70
+255 203 81
+201 50 96
+157 36 61
+40 40 40
+177 109 135
+123 79 110
+82 50 75
+111 26 47
diff --git a/graphics/pokemon/enamorus/shiny.pal b/graphics/pokemon/enamorus/shiny.pal
index 180ae687e5..41b6650a75 100644
--- a/graphics/pokemon/enamorus/shiny.pal
+++ b/graphics/pokemon/enamorus/shiny.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-152 208 160
-74 74 74
-180 180 189
+153 211 165
255 255 255
-0 0 0
-131 57 82
-164 24 24
-230 131 164
-255 90 0
-189 82 106
-222 74 41
-255 139 238
-205 98 189
+194 184 173
+115 107 104
+16 16 16
+251 142 224
+198 83 185
+127 58 131
255 197 32
-0 0 0
-0 0 0
+246 81 4
+205 35 35
+40 40 40
+230 131 164
+189 82 106
+107 51 74
+140 29 49
diff --git a/graphics/pokemon/enamorus/therian/back.png b/graphics/pokemon/enamorus/therian/back.png
index a563156e4d..04a5286fc1 100644
Binary files a/graphics/pokemon/enamorus/therian/back.png and b/graphics/pokemon/enamorus/therian/back.png differ
diff --git a/graphics/pokemon/enamorus/therian/front.png b/graphics/pokemon/enamorus/therian/front.png
index 8ac7c93f06..e51457cf8e 100644
Binary files a/graphics/pokemon/enamorus/therian/front.png and b/graphics/pokemon/enamorus/therian/front.png differ
diff --git a/graphics/pokemon/enamorus/therian/normal.pal b/graphics/pokemon/enamorus/therian/normal.pal
index 096dfb36af..e2ddf78389 100644
--- a/graphics/pokemon/enamorus/therian/normal.pal
+++ b/graphics/pokemon/enamorus/therian/normal.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-156 213 164
-131 41 49
-213 106 156
+152 208 160
+112 48 56
+72 72 72
+144 32 24
+192 40 40
+240 40 40
+184 56 88
+168 72 80
+248 192 56
+240 80 136
+224 112 152
+176 176 184
16 16 16
-213 65 57
-74 74 74
-255 255 255
-180 180 189
-255 197 57
-123 164 131
-98 115 98
-148 197 156
-230 246 230
-49 57 49
-213 106 156
+248 248 248
+0 0 0
0 0 0
diff --git a/graphics/pokemon/enamorus/therian/shiny.pal b/graphics/pokemon/enamorus/therian/shiny.pal
index 58c5564621..a84be28f03 100644
--- a/graphics/pokemon/enamorus/therian/shiny.pal
+++ b/graphics/pokemon/enamorus/therian/shiny.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-156 213 164
-131 41 49
-213 106 156
+152 208 160
+112 56 80
+72 72 72
+136 32 32
+192 72 48
+240 88 16
+176 96 176
+168 80 104
+248 192 56
+232 128 224
+200 128 152
+176 176 184
16 16 16
-213 65 57
-74 74 74
-255 255 255
-180 180 189
-255 197 57
-123 164 131
-98 115 98
-148 197 156
-230 246 230
-49 57 49
-238 131 230
+248 248 248
+0 0 0
0 0 0
diff --git a/graphics/pokemon/exeggutor/alola/icon.png b/graphics/pokemon/exeggutor/alola/icon.png
index 723d0a4ead..49b788b715 100644
Binary files a/graphics/pokemon/exeggutor/alola/icon.png and b/graphics/pokemon/exeggutor/alola/icon.png differ
diff --git a/graphics/pokemon/farfetchd/overworld.png b/graphics/pokemon/farfetchd/overworld.png
index 46aec09764..63d29215b7 100644
Binary files a/graphics/pokemon/farfetchd/overworld.png and b/graphics/pokemon/farfetchd/overworld.png differ
diff --git a/graphics/pokemon/fezandipiti/back.png b/graphics/pokemon/fezandipiti/back.png
index 4583405047..4ca4925481 100644
Binary files a/graphics/pokemon/fezandipiti/back.png and b/graphics/pokemon/fezandipiti/back.png differ
diff --git a/graphics/pokemon/fezandipiti/front.png b/graphics/pokemon/fezandipiti/front.png
index fc841ec395..1ff68f5004 100644
Binary files a/graphics/pokemon/fezandipiti/front.png and b/graphics/pokemon/fezandipiti/front.png differ
diff --git a/graphics/pokemon/fezandipiti/normal.pal b/graphics/pokemon/fezandipiti/normal.pal
index ac9c005324..a34688fc3f 100644
--- a/graphics/pokemon/fezandipiti/normal.pal
+++ b/graphics/pokemon/fezandipiti/normal.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-152 208 160
-167 135 48
-118 61 41
-238 204 45
+16
+153 211 165
26 29 28
-78 73 71
45 45 45
-146 57 119
-202 103 162
-90 33 73
-192 78 22
-254 254 254
-164 175 176
-16 16 16
69 37 29
+118 61 41
+90 33 73
+78 73 71
+192 78 22
+146 57 119
+167 135 48
+238 204 45
+202 103 162
+179 177 162
+16 16 16
+254 254 254
+0 0 0
diff --git a/graphics/pokemon/fezandipiti/shiny.pal b/graphics/pokemon/fezandipiti/shiny.pal
index 673473f5c0..b8f4918787 100644
--- a/graphics/pokemon/fezandipiti/shiny.pal
+++ b/graphics/pokemon/fezandipiti/shiny.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-152 208 160
-167 135 48
-118 61 41
-238 204 45
+16
+153 211 165
26 29 28
-59 63 133
-36 40 99
-146 57 119
-202 103 162
-90 33 73
-192 78 22
-254 254 254
-164 175 176
-16 16 16
+51 48 101
69 37 29
+118 61 41
+90 33 73
+71 61 199
+192 78 22
+146 57 119
+167 135 48
+238 204 45
+202 103 162
+179 177 162
+16 16 16
+254 254 254
+0 0 0
diff --git a/graphics/pokemon/floette/eternal/icon.png b/graphics/pokemon/floette/eternal/icon.png
index 32f7face1f..4874a7720e 100644
Binary files a/graphics/pokemon/floette/eternal/icon.png and b/graphics/pokemon/floette/eternal/icon.png differ
diff --git a/graphics/pokemon/fomantis/icon.png b/graphics/pokemon/fomantis/icon.png
index 2604f517d2..d26f29932c 100644
Binary files a/graphics/pokemon/fomantis/icon.png and b/graphics/pokemon/fomantis/icon.png differ
diff --git a/graphics/pokemon/furfrou/dandy_trim/icon.png b/graphics/pokemon/furfrou/dandy_trim/icon.png
index a54f4fa4a4..4903feef71 100644
Binary files a/graphics/pokemon/furfrou/dandy_trim/icon.png and b/graphics/pokemon/furfrou/dandy_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/debutante_trim/icon.png b/graphics/pokemon/furfrou/debutante_trim/icon.png
index 02a350fb2e..57c08949a3 100644
Binary files a/graphics/pokemon/furfrou/debutante_trim/icon.png and b/graphics/pokemon/furfrou/debutante_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/diamond_trim/icon.png b/graphics/pokemon/furfrou/diamond_trim/icon.png
index 2acd3220d3..815332baf3 100644
Binary files a/graphics/pokemon/furfrou/diamond_trim/icon.png and b/graphics/pokemon/furfrou/diamond_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/heart_trim/icon.png b/graphics/pokemon/furfrou/heart_trim/icon.png
index e065e47667..d779ea9c2c 100644
Binary files a/graphics/pokemon/furfrou/heart_trim/icon.png and b/graphics/pokemon/furfrou/heart_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/kabuki_trim/icon.png b/graphics/pokemon/furfrou/kabuki_trim/icon.png
index b3cad982e8..6b3527207d 100644
Binary files a/graphics/pokemon/furfrou/kabuki_trim/icon.png and b/graphics/pokemon/furfrou/kabuki_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/la_reine_trim/icon.png b/graphics/pokemon/furfrou/la_reine_trim/icon.png
index 15aeb37e1b..6e9384aaf6 100644
Binary files a/graphics/pokemon/furfrou/la_reine_trim/icon.png and b/graphics/pokemon/furfrou/la_reine_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/matron_trim/icon.png b/graphics/pokemon/furfrou/matron_trim/icon.png
index 88384830e8..098b909623 100644
Binary files a/graphics/pokemon/furfrou/matron_trim/icon.png and b/graphics/pokemon/furfrou/matron_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/pharaoh_trim/icon.png b/graphics/pokemon/furfrou/pharaoh_trim/icon.png
index cecb8f1655..ec2f4c1df0 100644
Binary files a/graphics/pokemon/furfrou/pharaoh_trim/icon.png and b/graphics/pokemon/furfrou/pharaoh_trim/icon.png differ
diff --git a/graphics/pokemon/furfrou/star_trim/icon.png b/graphics/pokemon/furfrou/star_trim/icon.png
index acb3a5ed6c..551c32addf 100644
Binary files a/graphics/pokemon/furfrou/star_trim/icon.png and b/graphics/pokemon/furfrou/star_trim/icon.png differ
diff --git a/graphics/pokemon/geodude/alola/icon.png b/graphics/pokemon/geodude/alola/icon.png
index 1a5f969971..6a4cbd5158 100644
Binary files a/graphics/pokemon/geodude/alola/icon.png and b/graphics/pokemon/geodude/alola/icon.png differ
diff --git a/graphics/pokemon/gigalith/overworld.png b/graphics/pokemon/gigalith/overworld.png
index 8e5b2b7b35..d84932ecea 100644
Binary files a/graphics/pokemon/gigalith/overworld.png and b/graphics/pokemon/gigalith/overworld.png differ
diff --git a/graphics/pokemon/golem/alola/icon.png b/graphics/pokemon/golem/alola/icon.png
index e796f88842..ccaa2714e8 100644
Binary files a/graphics/pokemon/golem/alola/icon.png and b/graphics/pokemon/golem/alola/icon.png differ
diff --git a/graphics/pokemon/golisopod/icon.png b/graphics/pokemon/golisopod/icon.png
index 37ee080495..7ebe16a529 100644
Binary files a/graphics/pokemon/golisopod/icon.png and b/graphics/pokemon/golisopod/icon.png differ
diff --git a/graphics/pokemon/graveler/alola/icon.png b/graphics/pokemon/graveler/alola/icon.png
index c0a7557ca0..da15318b96 100644
Binary files a/graphics/pokemon/graveler/alola/icon.png and b/graphics/pokemon/graveler/alola/icon.png differ
diff --git a/graphics/pokemon/greninja/ash/icon.png b/graphics/pokemon/greninja/ash/icon.png
index df9595619f..dc10f4b59b 100644
Binary files a/graphics/pokemon/greninja/ash/icon.png and b/graphics/pokemon/greninja/ash/icon.png differ
diff --git a/graphics/pokemon/grimer/alola/icon.png b/graphics/pokemon/grimer/alola/icon.png
index 09d83cb95e..38ba79b2dc 100644
Binary files a/graphics/pokemon/grimer/alola/icon.png and b/graphics/pokemon/grimer/alola/icon.png differ
diff --git a/graphics/pokemon/grubbin/icon.png b/graphics/pokemon/grubbin/icon.png
index 96071bf8fb..4ff57b87c5 100644
Binary files a/graphics/pokemon/grubbin/icon.png and b/graphics/pokemon/grubbin/icon.png differ
diff --git a/graphics/pokemon/gumshoos/icon.png b/graphics/pokemon/gumshoos/icon.png
index ac2bd83928..6421d338e4 100644
Binary files a/graphics/pokemon/gumshoos/icon.png and b/graphics/pokemon/gumshoos/icon.png differ
diff --git a/graphics/pokemon/guzzlord/icon.png b/graphics/pokemon/guzzlord/icon.png
index 25e862d788..94ef70d8a2 100644
Binary files a/graphics/pokemon/guzzlord/icon.png and b/graphics/pokemon/guzzlord/icon.png differ
diff --git a/graphics/pokemon/hakamo_o/icon.png b/graphics/pokemon/hakamo_o/icon.png
index 4836770537..90986aa3d6 100644
Binary files a/graphics/pokemon/hakamo_o/icon.png and b/graphics/pokemon/hakamo_o/icon.png differ
diff --git a/graphics/pokemon/herdier/overworld.png b/graphics/pokemon/herdier/overworld.png
index 51e2a2207b..de47a0ba7f 100644
Binary files a/graphics/pokemon/herdier/overworld.png and b/graphics/pokemon/herdier/overworld.png differ
diff --git a/graphics/pokemon/herdier/overworld_shiny.pal b/graphics/pokemon/herdier/overworld_shiny.pal
index 4713003a78..0d9a690928 100644
--- a/graphics/pokemon/herdier/overworld_shiny.pal
+++ b/graphics/pokemon/herdier/overworld_shiny.pal
@@ -2,7 +2,7 @@ JASC-PAL
0100
16
152 208 160
-54 54 78
+56 56 56
0 0 0
64 64 64
96 72 24
diff --git a/graphics/pokemon/honedge/anim_front.png b/graphics/pokemon/honedge/anim_front.png
index 9a5dc75078..6376e2d1e2 100644
Binary files a/graphics/pokemon/honedge/anim_front.png and b/graphics/pokemon/honedge/anim_front.png differ
diff --git a/graphics/pokemon/honedge/back.png b/graphics/pokemon/honedge/back.png
index d9092fa13a..b1bc8634b0 100644
Binary files a/graphics/pokemon/honedge/back.png and b/graphics/pokemon/honedge/back.png differ
diff --git a/graphics/pokemon/honedge/normal.pal b/graphics/pokemon/honedge/normal.pal
index 51f60119df..d6a8a50995 100644
--- a/graphics/pokemon/honedge/normal.pal
+++ b/graphics/pokemon/honedge/normal.pal
@@ -3,17 +3,17 @@ JASC-PAL
16
152 208 160
8 48 56
-0 128 160
+36 103 149
16 16 16
80 64 40
-248 208 128
-176 152 88
+255 215 132
+181 158 90
136 104 56
-152 232 248
+102 225 253
96 192 216
80 88 88
168 168 168
216 216 216
-48 56 40
-152 128 80
-136 88 56
+99 84 80
+201 185 131
+167 139 110
diff --git a/graphics/pokemon/incineroar/icon.png b/graphics/pokemon/incineroar/icon.png
index 020c549ecb..a824082421 100644
Binary files a/graphics/pokemon/incineroar/icon.png and b/graphics/pokemon/incineroar/icon.png differ
diff --git a/graphics/pokemon/inteleon/gmax/icon.png b/graphics/pokemon/inteleon/gmax/icon.png
index a27bf3f1c8..334ce15440 100644
Binary files a/graphics/pokemon/inteleon/gmax/icon.png and b/graphics/pokemon/inteleon/gmax/icon.png differ
diff --git a/graphics/pokemon/jangmo_o/icon.png b/graphics/pokemon/jangmo_o/icon.png
index 0a8a2c2d03..bbc7db2945 100644
Binary files a/graphics/pokemon/jangmo_o/icon.png and b/graphics/pokemon/jangmo_o/icon.png differ
diff --git a/graphics/pokemon/kartana/icon.png b/graphics/pokemon/kartana/icon.png
index 7d0b82499e..bdf3ec3a51 100644
Binary files a/graphics/pokemon/kartana/icon.png and b/graphics/pokemon/kartana/icon.png differ
diff --git a/graphics/pokemon/komala/icon.png b/graphics/pokemon/komala/icon.png
index 6935e996ce..96af23fe18 100644
Binary files a/graphics/pokemon/komala/icon.png and b/graphics/pokemon/komala/icon.png differ
diff --git a/graphics/pokemon/kommo_o/icon.png b/graphics/pokemon/kommo_o/icon.png
index 3acaf53292..2a0ba757f8 100644
Binary files a/graphics/pokemon/kommo_o/icon.png and b/graphics/pokemon/kommo_o/icon.png differ
diff --git a/graphics/pokemon/liepard/overworld.png b/graphics/pokemon/liepard/overworld.png
index eb6611bf84..804cdb39d6 100644
Binary files a/graphics/pokemon/liepard/overworld.png and b/graphics/pokemon/liepard/overworld.png differ
diff --git a/graphics/pokemon/litten/icon.png b/graphics/pokemon/litten/icon.png
index 5602732b43..7867b32c69 100644
Binary files a/graphics/pokemon/litten/icon.png and b/graphics/pokemon/litten/icon.png differ
diff --git a/graphics/pokemon/lunala/icon.png b/graphics/pokemon/lunala/icon.png
index 036b9b3719..55002ed924 100644
Binary files a/graphics/pokemon/lunala/icon.png and b/graphics/pokemon/lunala/icon.png differ
diff --git a/graphics/pokemon/lurantis/icon.png b/graphics/pokemon/lurantis/icon.png
index 893f651b03..f77d4e1e48 100644
Binary files a/graphics/pokemon/lurantis/icon.png and b/graphics/pokemon/lurantis/icon.png differ
diff --git a/graphics/pokemon/lycanroc/dusk/icon.png b/graphics/pokemon/lycanroc/dusk/icon.png
index 65d8394f4e..7b860c14ce 100644
Binary files a/graphics/pokemon/lycanroc/dusk/icon.png and b/graphics/pokemon/lycanroc/dusk/icon.png differ
diff --git a/graphics/pokemon/lycanroc/icon.png b/graphics/pokemon/lycanroc/icon.png
index 8ae4313374..50a6a2e9d8 100644
Binary files a/graphics/pokemon/lycanroc/icon.png and b/graphics/pokemon/lycanroc/icon.png differ
diff --git a/graphics/pokemon/lycanroc/midnight/icon.png b/graphics/pokemon/lycanroc/midnight/icon.png
index f6b98c949d..33bdba204e 100644
Binary files a/graphics/pokemon/lycanroc/midnight/icon.png and b/graphics/pokemon/lycanroc/midnight/icon.png differ
diff --git a/graphics/pokemon/magearna/icon.png b/graphics/pokemon/magearna/icon.png
index cfb4c06647..6a421d6ada 100644
Binary files a/graphics/pokemon/magearna/icon.png and b/graphics/pokemon/magearna/icon.png differ
diff --git a/graphics/pokemon/magearna/original_color/icon.png b/graphics/pokemon/magearna/original_color/icon.png
index 5e97b3ccb3..0f1b1e9052 100644
Binary files a/graphics/pokemon/magearna/original_color/icon.png and b/graphics/pokemon/magearna/original_color/icon.png differ
diff --git a/graphics/pokemon/maractus/back.png b/graphics/pokemon/maractus/back.png
index bc83adca5c..66a6520840 100644
Binary files a/graphics/pokemon/maractus/back.png and b/graphics/pokemon/maractus/back.png differ
diff --git a/graphics/pokemon/mareanie/icon.png b/graphics/pokemon/mareanie/icon.png
index 7b7dc44fb2..7464483cfe 100644
Binary files a/graphics/pokemon/mareanie/icon.png and b/graphics/pokemon/mareanie/icon.png differ
diff --git a/graphics/pokemon/marowak/alola/icon.png b/graphics/pokemon/marowak/alola/icon.png
index 3ea2a868c3..d434c92fb7 100644
Binary files a/graphics/pokemon/marowak/alola/icon.png and b/graphics/pokemon/marowak/alola/icon.png differ
diff --git a/graphics/pokemon/marshadow/icon.png b/graphics/pokemon/marshadow/icon.png
index e7fb5674d3..b8d05ba299 100644
Binary files a/graphics/pokemon/marshadow/icon.png and b/graphics/pokemon/marshadow/icon.png differ
diff --git a/graphics/pokemon/maschiff/back.png b/graphics/pokemon/maschiff/back.png
index 6a6a45eb46..4891b2371a 100644
Binary files a/graphics/pokemon/maschiff/back.png and b/graphics/pokemon/maschiff/back.png differ
diff --git a/graphics/pokemon/maschiff/front.png b/graphics/pokemon/maschiff/front.png
index 05f724ec6d..c06b23028e 100644
Binary files a/graphics/pokemon/maschiff/front.png and b/graphics/pokemon/maschiff/front.png differ
diff --git a/graphics/pokemon/maschiff/normal.pal b/graphics/pokemon/maschiff/normal.pal
index 3c397173c3..7de2cd0927 100644
--- a/graphics/pokemon/maschiff/normal.pal
+++ b/graphics/pokemon/maschiff/normal.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-156 210 164
-255 255 255
-255 193 11
-180 178 180
-238 113 24
-255 157 90
-213 141 8
-106 36 32
-98 97 98
-213 117 106
-90 64 82
-172 85 74
-8 12 8
-65 44 57
-238 170 148
-164 97 49
+153 211 165
+36 30 33
+57 45 53
+71 37 41
+86 67 79
+121 117 100
+141 86 46
+199 121 35
+251 111 49
+129 67 75
+195 115 113
+253 201 67
+16 16 16
+253 242 223
+0 0 0
+0 0 0
diff --git a/graphics/pokemon/maschiff/shiny.pal b/graphics/pokemon/maschiff/shiny.pal
index 23f5bf0a74..cb13ff86a9 100644
--- a/graphics/pokemon/maschiff/shiny.pal
+++ b/graphics/pokemon/maschiff/shiny.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-156 210 164
-255 255 255
-120 98 112
-180 178 180
-238 113 24
-255 157 90
-81 65 73
-92 77 102
-98 97 98
-173 157 191
-90 64 82
-129 114 142
-8 12 8
-65 44 57
-201 195 216
-63 47 59
+153 211 165
+36 30 33
+57 45 53
+62 55 70
+86 67 79
+121 117 100
+63 50 58
+87 70 82
+251 111 49
+102 92 114
+171 139 201
+119 96 110
+16 16 16
+253 242 223
+0 0 0
+0 0 0
diff --git a/graphics/pokemon/melmetal/icon.png b/graphics/pokemon/melmetal/icon.png
index fa70c6b6b5..20382c2d80 100644
Binary files a/graphics/pokemon/melmetal/icon.png and b/graphics/pokemon/melmetal/icon.png differ
diff --git a/graphics/pokemon/melmetal/overworld.png b/graphics/pokemon/melmetal/overworld.png
index 4be020a5c6..e8097644ad 100644
Binary files a/graphics/pokemon/melmetal/overworld.png and b/graphics/pokemon/melmetal/overworld.png differ
diff --git a/graphics/pokemon/melmetal/overworld_normal.pal b/graphics/pokemon/melmetal/overworld_normal.pal
index 28e4593192..d9b329362b 100644
--- a/graphics/pokemon/melmetal/overworld_normal.pal
+++ b/graphics/pokemon/melmetal/overworld_normal.pal
@@ -1,7 +1,7 @@
JASC-PAL
0100
16
-255 255 255
+120 255 255
254 235 185
220 220 218
235 192 100
@@ -16,4 +16,4 @@ JASC-PAL
64 64 64
45 43 43
8 8 8
-0 0 0
+255 255 255
diff --git a/graphics/pokemon/melmetal/overworld_shiny.pal b/graphics/pokemon/melmetal/overworld_shiny.pal
index 6d1c75c9bb..4f5321a062 100644
--- a/graphics/pokemon/melmetal/overworld_shiny.pal
+++ b/graphics/pokemon/melmetal/overworld_shiny.pal
@@ -16,4 +16,4 @@ JASC-PAL
64 64 64
45 43 43
8 8 8
-0 0 0
+255 255 255
diff --git a/graphics/pokemon/meltan/icon.png b/graphics/pokemon/meltan/icon.png
index 17fb4f96bd..51da112566 100644
Binary files a/graphics/pokemon/meltan/icon.png and b/graphics/pokemon/meltan/icon.png differ
diff --git a/graphics/pokemon/meowth/alola/icon.png b/graphics/pokemon/meowth/alola/icon.png
index d4b80eb6b4..f2b5d00cbe 100644
Binary files a/graphics/pokemon/meowth/alola/icon.png and b/graphics/pokemon/meowth/alola/icon.png differ
diff --git a/graphics/pokemon/mimikyu/busted/icon.png b/graphics/pokemon/mimikyu/busted/icon.png
index 46bc430059..58272ef8fe 100644
Binary files a/graphics/pokemon/mimikyu/busted/icon.png and b/graphics/pokemon/mimikyu/busted/icon.png differ
diff --git a/graphics/pokemon/mimikyu/icon.png b/graphics/pokemon/mimikyu/icon.png
index 89c587683a..73d110ca70 100644
Binary files a/graphics/pokemon/mimikyu/icon.png and b/graphics/pokemon/mimikyu/icon.png differ
diff --git a/graphics/pokemon/minior/core/blue/icon.png b/graphics/pokemon/minior/core/blue/icon.png
index 85ee891517..60f670a1a8 100644
Binary files a/graphics/pokemon/minior/core/blue/icon.png and b/graphics/pokemon/minior/core/blue/icon.png differ
diff --git a/graphics/pokemon/minior/core/green/icon.png b/graphics/pokemon/minior/core/green/icon.png
index f724e86aeb..cf24afb332 100644
Binary files a/graphics/pokemon/minior/core/green/icon.png and b/graphics/pokemon/minior/core/green/icon.png differ
diff --git a/graphics/pokemon/minior/core/indigo/icon.png b/graphics/pokemon/minior/core/indigo/icon.png
index 4f2e531ced..17a625ccd9 100644
Binary files a/graphics/pokemon/minior/core/indigo/icon.png and b/graphics/pokemon/minior/core/indigo/icon.png differ
diff --git a/graphics/pokemon/minior/core/orange/icon.png b/graphics/pokemon/minior/core/orange/icon.png
index 40509d6b51..7418f1ec53 100644
Binary files a/graphics/pokemon/minior/core/orange/icon.png and b/graphics/pokemon/minior/core/orange/icon.png differ
diff --git a/graphics/pokemon/minior/core/red/icon.png b/graphics/pokemon/minior/core/red/icon.png
index 486dcdebd1..3d3880d7c3 100644
Binary files a/graphics/pokemon/minior/core/red/icon.png and b/graphics/pokemon/minior/core/red/icon.png differ
diff --git a/graphics/pokemon/minior/core/violet/icon.png b/graphics/pokemon/minior/core/violet/icon.png
index 4392bdf3b9..afa5589627 100644
Binary files a/graphics/pokemon/minior/core/violet/icon.png and b/graphics/pokemon/minior/core/violet/icon.png differ
diff --git a/graphics/pokemon/minior/core/yellow/icon.png b/graphics/pokemon/minior/core/yellow/icon.png
index f7dfb73362..ae71fd9a24 100644
Binary files a/graphics/pokemon/minior/core/yellow/icon.png and b/graphics/pokemon/minior/core/yellow/icon.png differ
diff --git a/graphics/pokemon/morelull/icon.png b/graphics/pokemon/morelull/icon.png
index 221ebe5457..1c50141e10 100644
Binary files a/graphics/pokemon/morelull/icon.png and b/graphics/pokemon/morelull/icon.png differ
diff --git a/graphics/pokemon/mudbray/icon.png b/graphics/pokemon/mudbray/icon.png
index 0447096ecb..92094f19ef 100644
Binary files a/graphics/pokemon/mudbray/icon.png and b/graphics/pokemon/mudbray/icon.png differ
diff --git a/graphics/pokemon/mudsdale/icon.png b/graphics/pokemon/mudsdale/icon.png
index 3146346ead..8b2f118fbf 100644
Binary files a/graphics/pokemon/mudsdale/icon.png and b/graphics/pokemon/mudsdale/icon.png differ
diff --git a/graphics/pokemon/muk/alola/icon.png b/graphics/pokemon/muk/alola/icon.png
index d598fd7283..676a7999ee 100644
Binary files a/graphics/pokemon/muk/alola/icon.png and b/graphics/pokemon/muk/alola/icon.png differ
diff --git a/graphics/pokemon/munna/overworld.png b/graphics/pokemon/munna/overworld.png
index 9dc2032145..605379190d 100644
Binary files a/graphics/pokemon/munna/overworld.png and b/graphics/pokemon/munna/overworld.png differ
diff --git a/graphics/pokemon/munna/overworld_shiny.pal b/graphics/pokemon/munna/overworld_shiny.pal
index 04fb73d163..8765308655 100644
--- a/graphics/pokemon/munna/overworld_shiny.pal
+++ b/graphics/pokemon/munna/overworld_shiny.pal
@@ -10,7 +10,7 @@ JASC-PAL
248 248 248
24 40 16
238 238 247
-208 24 80
+168 56 136
240 136 208
144 40 112
145 83 106
diff --git a/graphics/pokemon/musharna/overworld.png b/graphics/pokemon/musharna/overworld.png
index aef3207b7e..081e4187e5 100644
Binary files a/graphics/pokemon/musharna/overworld.png and b/graphics/pokemon/musharna/overworld.png differ
diff --git a/graphics/pokemon/musharna/overworld_normal.pal b/graphics/pokemon/musharna/overworld_normal.pal
index f1b11dd773..cfcbd413f1 100644
--- a/graphics/pokemon/musharna/overworld_normal.pal
+++ b/graphics/pokemon/musharna/overworld_normal.pal
@@ -2,18 +2,18 @@ JASC-PAL
0100
16
152 208 160
-109 75 80
-145 83 106
+122 77 104
+145 74 100
225 112 161
-175 112 140
-97 66 145
+168 80 112
+83 62 115
42 47 74
-140 137 175
-134 96 184
+144 120 216
+104 96 160
252 188 219
-247 207 182
-207 150 111
+248 192 200
+200 152 144
0 0 0
160 175 128
-0 0 0
+152 88 96
0 0 0
diff --git a/graphics/pokemon/musharna/overworld_shiny.pal b/graphics/pokemon/musharna/overworld_shiny.pal
index 6b5ab82193..01c9460d4a 100644
--- a/graphics/pokemon/musharna/overworld_shiny.pal
+++ b/graphics/pokemon/musharna/overworld_shiny.pal
@@ -2,18 +2,18 @@ JASC-PAL
0100
16
152 208 160
-109 75 80
-112 56 128
+88 72 128
+92 52 128
152 112 200
-175 112 140
+119 87 158
48 72 96
42 47 74
80 152 192
-64 120 192
+72 112 144
152 208 160
248 176 192
208 128 152
0 0 0
152 208 160
-0 0 0
+136 88 104
0 0 0
diff --git a/graphics/pokemon/naganadel/icon.png b/graphics/pokemon/naganadel/icon.png
index 23204c5d18..f1194b189e 100644
Binary files a/graphics/pokemon/naganadel/icon.png and b/graphics/pokemon/naganadel/icon.png differ
diff --git a/graphics/pokemon/necrozma/dawn_wings/icon.png b/graphics/pokemon/necrozma/dawn_wings/icon.png
index 25d24cb024..5644f23026 100644
Binary files a/graphics/pokemon/necrozma/dawn_wings/icon.png and b/graphics/pokemon/necrozma/dawn_wings/icon.png differ
diff --git a/graphics/pokemon/necrozma/dusk_mane/icon.png b/graphics/pokemon/necrozma/dusk_mane/icon.png
index c188b1e3ca..c60f222f76 100644
Binary files a/graphics/pokemon/necrozma/dusk_mane/icon.png and b/graphics/pokemon/necrozma/dusk_mane/icon.png differ
diff --git a/graphics/pokemon/necrozma/icon.png b/graphics/pokemon/necrozma/icon.png
index 1d4283fddc..603f1f4fa0 100644
Binary files a/graphics/pokemon/necrozma/icon.png and b/graphics/pokemon/necrozma/icon.png differ
diff --git a/graphics/pokemon/necrozma/ultra/icon.png b/graphics/pokemon/necrozma/ultra/icon.png
index 1c63345bc8..790be2e0c2 100644
Binary files a/graphics/pokemon/necrozma/ultra/icon.png and b/graphics/pokemon/necrozma/ultra/icon.png differ
diff --git a/graphics/pokemon/nihilego/icon.png b/graphics/pokemon/nihilego/icon.png
index 6e8f855d59..3be83cab2f 100644
Binary files a/graphics/pokemon/nihilego/icon.png and b/graphics/pokemon/nihilego/icon.png differ
diff --git a/graphics/pokemon/ninetales/alola/icon.png b/graphics/pokemon/ninetales/alola/icon.png
index 71ac99d5a7..f433689887 100644
Binary files a/graphics/pokemon/ninetales/alola/icon.png and b/graphics/pokemon/ninetales/alola/icon.png differ
diff --git a/graphics/pokemon/ogerpon/back.png b/graphics/pokemon/ogerpon/back.png
index 75f309fd67..8cd9136f9e 100644
Binary files a/graphics/pokemon/ogerpon/back.png and b/graphics/pokemon/ogerpon/back.png differ
diff --git a/graphics/pokemon/ogerpon/cornerstone/back.png b/graphics/pokemon/ogerpon/cornerstone/back.png
index 7e40fee557..ffface9d68 100644
Binary files a/graphics/pokemon/ogerpon/cornerstone/back.png and b/graphics/pokemon/ogerpon/cornerstone/back.png differ
diff --git a/graphics/pokemon/ogerpon/cornerstone/front.png b/graphics/pokemon/ogerpon/cornerstone/front.png
index 8e96be70e7..9b7f279238 100644
Binary files a/graphics/pokemon/ogerpon/cornerstone/front.png and b/graphics/pokemon/ogerpon/cornerstone/front.png differ
diff --git a/graphics/pokemon/ogerpon/cornerstone/normal.pal b/graphics/pokemon/ogerpon/cornerstone/normal.pal
index 852898a6b7..eb11f81f7e 100644
--- a/graphics/pokemon/ogerpon/cornerstone/normal.pal
+++ b/graphics/pokemon/ogerpon/cornerstone/normal.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-148 209 161
-0 0 0
-42 44 41
-21 158 7
-74 76 73
-61 113 53
-25 27 24
-109 99 108
-133 139 139
-53 134 168
-55 189 227
-194 139 62
-255 197 74
-212 230 247
-144 92 38
+16
+238 230 180
+49 49 49
+148 156 148
+16 16 16
+65 115 49
+90 172 49
+90 98 106
+41 41 41
+74 74 74
+0 213 255
+24 24 24
+0 148 180
+255 222 65
+255 255 255
+238 156 0
+139 98 57
diff --git a/graphics/pokemon/ogerpon/cornerstone/shiny.pal b/graphics/pokemon/ogerpon/cornerstone/shiny.pal
index c4956ce774..71dd9d6e9e 100644
--- a/graphics/pokemon/ogerpon/cornerstone/shiny.pal
+++ b/graphics/pokemon/ogerpon/cornerstone/shiny.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-148 209 161
-0 0 0
-42 44 41
-21 158 7
-74 76 73
-61 113 53
-25 27 24
-109 99 108
-133 139 139
-53 134 168
-55 189 227
-194 139 62
-255 197 74
-212 230 247
-124 162 56
+16
+238 230 180
+49 49 49
+148 156 148
+16 16 16
+65 115 49
+90 172 49
+90 98 106
+41 41 41
+74 74 74
+0 213 255
+24 24 24
+0 148 180
+255 222 65
+255 255 255
+164 205 24
+139 98 57
diff --git a/graphics/pokemon/ogerpon/front.png b/graphics/pokemon/ogerpon/front.png
index dec38ef0b8..6c2a769081 100644
Binary files a/graphics/pokemon/ogerpon/front.png and b/graphics/pokemon/ogerpon/front.png differ
diff --git a/graphics/pokemon/ogerpon/hearthflame/back.png b/graphics/pokemon/ogerpon/hearthflame/back.png
index d6d927f19d..73f95efbf2 100644
Binary files a/graphics/pokemon/ogerpon/hearthflame/back.png and b/graphics/pokemon/ogerpon/hearthflame/back.png differ
diff --git a/graphics/pokemon/ogerpon/hearthflame/front.png b/graphics/pokemon/ogerpon/hearthflame/front.png
index d8b9cb7b23..098041cf76 100644
Binary files a/graphics/pokemon/ogerpon/hearthflame/front.png and b/graphics/pokemon/ogerpon/hearthflame/front.png differ
diff --git a/graphics/pokemon/ogerpon/hearthflame/normal.pal b/graphics/pokemon/ogerpon/hearthflame/normal.pal
index 3f478af8aa..2ed9b8c050 100644
--- a/graphics/pokemon/ogerpon/hearthflame/normal.pal
+++ b/graphics/pokemon/ogerpon/hearthflame/normal.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-148 210 164
-0 0 0
-41 44 41
-16 157 0
-230 60 49
-57 113 49
-49 133 172
-131 28 24
-213 230 246
-255 198 74
-172 105 32
-156 153 172
-49 190 230
-164 52 49
-74 76 74
-189 137 90
+238 230 180
+74 74 74
+213 156 24
+255 222 65
+65 115 49
+90 172 49
+16 16 16
+41 41 41
+238 57 41
+156 16 16
+82 8 8
+255 255 255
+238 156 0
+123 106 49
+0 213 255
+139 98 57
diff --git a/graphics/pokemon/ogerpon/hearthflame/shiny.pal b/graphics/pokemon/ogerpon/hearthflame/shiny.pal
index fee0f8de7b..81f60abe80 100644
--- a/graphics/pokemon/ogerpon/hearthflame/shiny.pal
+++ b/graphics/pokemon/ogerpon/hearthflame/shiny.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-148 210 164
-0 0 0
-41 44 41
-16 157 0
-230 60 49
-57 113 49
-49 133 172
-131 28 24
-213 230 246
-255 198 74
-124 162 56
-156 153 172
-49 190 230
-164 52 49
-74 76 74
-189 137 90
+238 230 180
+74 74 74
+213 156 24
+255 222 65
+65 115 49
+90 172 49
+16 16 16
+41 41 41
+238 57 41
+156 16 16
+82 8 8
+255 255 255
+164 205 24
+123 106 49
+0 213 255
+139 98 57
diff --git a/graphics/pokemon/ogerpon/normal.pal b/graphics/pokemon/ogerpon/normal.pal
index a1ac4baf96..f578e22342 100644
--- a/graphics/pokemon/ogerpon/normal.pal
+++ b/graphics/pokemon/ogerpon/normal.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-148 209 161
-0 1 0
-42 44 41
-21 158 7
-27 70 15
-61 113 53
-17 106 68
-83 133 90
-74 76 73
-175 216 159
-251 253 250
-139 99 57
-0 164 153
-120 81 39
-219 157 92
+16
+238 230 180
+41 41 41
+65 115 49
+74 74 74
+8 164 156
+90 172 49
+16 16 16
+8 106 65
+180 222 164
+255 255 255
+98 164 24
+82 180 98
+238 156 0
+139 98 57
+255 222 65
+222 156 90
diff --git a/graphics/pokemon/ogerpon/shiny.pal b/graphics/pokemon/ogerpon/shiny.pal
index 08c751ebda..02b6d9c5ae 100644
--- a/graphics/pokemon/ogerpon/shiny.pal
+++ b/graphics/pokemon/ogerpon/shiny.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-148 209 161
-0 1 0
-42 44 41
-21 158 7
-27 70 15
-61 113 53
-17 106 68
-83 133 90
-74 76 73
-175 216 159
-251 253 250
-139 99 57
-0 164 153
-124 162 56
-219 157 92
+16
+238 230 180
+41 41 41
+65 115 49
+74 74 74
+8 164 156
+90 172 49
+16 16 16
+8 106 65
+180 222 164
+255 255 255
+98 164 24
+82 180 98
+164 205 24
+139 98 57
+255 222 65
+222 156 90
diff --git a/graphics/pokemon/ogerpon/wellspring/back.png b/graphics/pokemon/ogerpon/wellspring/back.png
index 87d82032f4..d90a8afe3e 100644
Binary files a/graphics/pokemon/ogerpon/wellspring/back.png and b/graphics/pokemon/ogerpon/wellspring/back.png differ
diff --git a/graphics/pokemon/ogerpon/wellspring/front.png b/graphics/pokemon/ogerpon/wellspring/front.png
index 77ffb489a5..556f9f2688 100644
Binary files a/graphics/pokemon/ogerpon/wellspring/front.png and b/graphics/pokemon/ogerpon/wellspring/front.png differ
diff --git a/graphics/pokemon/ogerpon/wellspring/normal.pal b/graphics/pokemon/ogerpon/wellspring/normal.pal
index db40508a52..b91b6ee255 100644
--- a/graphics/pokemon/ogerpon/wellspring/normal.pal
+++ b/graphics/pokemon/ogerpon/wellspring/normal.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-148 209 161
-0 0 0
-42 44 41
-21 158 7
-11 64 121
-61 113 53
-74 76 73
-15 90 170
-0 126 229
-53 134 168
-71 85 100
-55 189 227
-212 230 247
-147 91 33
-169 122 74
-152 155 171
+238 230 180
+65 115 49
+90 172 49
+16 16 16
+8 65 131
+41 41 41
+0 131 230
+74 74 74
+139 98 57
+8 90 180
+57 213 255
+205 222 255
+238 156 0
+255 222 65
+255 255 255
+156 205 222
diff --git a/graphics/pokemon/ogerpon/wellspring/shiny.pal b/graphics/pokemon/ogerpon/wellspring/shiny.pal
index 7c44d3352d..4f4e60c157 100644
--- a/graphics/pokemon/ogerpon/wellspring/shiny.pal
+++ b/graphics/pokemon/ogerpon/wellspring/shiny.pal
@@ -1,19 +1,19 @@
JASC-PAL
0100
16
-148 209 161
-0 0 0
-42 44 41
-21 158 7
-11 64 121
-61 113 53
-74 76 73
-15 90 170
-0 126 229
-53 134 168
-71 85 100
-55 189 227
-212 230 247
-124 162 56
-169 122 74
-152 155 171
+238 230 180
+65 115 49
+90 172 49
+16 16 16
+8 65 131
+41 41 41
+0 131 230
+74 74 74
+139 98 57
+8 90 180
+57 213 255
+205 222 255
+164 205 24
+255 222 65
+255 255 255
+156 205 222
diff --git a/graphics/pokemon/oranguru/icon.png b/graphics/pokemon/oranguru/icon.png
index da7abe984b..99b8c13f8f 100644
Binary files a/graphics/pokemon/oranguru/icon.png and b/graphics/pokemon/oranguru/icon.png differ
diff --git a/graphics/pokemon/oricorio/icon.png b/graphics/pokemon/oricorio/icon.png
index 80936904c0..a5f53870fe 100644
Binary files a/graphics/pokemon/oricorio/icon.png and b/graphics/pokemon/oricorio/icon.png differ
diff --git a/graphics/pokemon/oricorio/pau/icon.png b/graphics/pokemon/oricorio/pau/icon.png
index 98040bf38d..72a009bd55 100644
Binary files a/graphics/pokemon/oricorio/pau/icon.png and b/graphics/pokemon/oricorio/pau/icon.png differ
diff --git a/graphics/pokemon/oricorio/pom_pom/icon.png b/graphics/pokemon/oricorio/pom_pom/icon.png
index b60855f918..d757b0564a 100644
Binary files a/graphics/pokemon/oricorio/pom_pom/icon.png and b/graphics/pokemon/oricorio/pom_pom/icon.png differ
diff --git a/graphics/pokemon/oricorio/sensu/icon.png b/graphics/pokemon/oricorio/sensu/icon.png
index b8423c31fc..3491f6ee02 100644
Binary files a/graphics/pokemon/oricorio/sensu/icon.png and b/graphics/pokemon/oricorio/sensu/icon.png differ
diff --git a/graphics/pokemon/palossand/icon.png b/graphics/pokemon/palossand/icon.png
index 3131f2c205..80f64f8b00 100644
Binary files a/graphics/pokemon/palossand/icon.png and b/graphics/pokemon/palossand/icon.png differ
diff --git a/graphics/pokemon/palpitoad/overworld.png b/graphics/pokemon/palpitoad/overworld.png
index 3be06ec275..dda419e276 100644
Binary files a/graphics/pokemon/palpitoad/overworld.png and b/graphics/pokemon/palpitoad/overworld.png differ
diff --git a/graphics/pokemon/palpitoad/overworld_normal.pal b/graphics/pokemon/palpitoad/overworld_normal.pal
index 4d5d03566c..7116f735ee 100644
--- a/graphics/pokemon/palpitoad/overworld_normal.pal
+++ b/graphics/pokemon/palpitoad/overworld_normal.pal
@@ -14,6 +14,6 @@ JASC-PAL
191 147 121
239 215 196
138 79 63
-0 0 0
+224 224 224
0 0 0
0 0 0
diff --git a/graphics/pokemon/palpitoad/overworld_shiny.pal b/graphics/pokemon/palpitoad/overworld_shiny.pal
index 46d834cac6..cfd54885c9 100644
--- a/graphics/pokemon/palpitoad/overworld_shiny.pal
+++ b/graphics/pokemon/palpitoad/overworld_shiny.pal
@@ -5,15 +5,15 @@ JASC-PAL
0 0 0
96 96 94
65 65 65
-188 99 24
+248 168 16
15 87 72
38 39 41
40 168 168
8 192 208
-120 80 8
-222 196 194
+161 89 22
+176 136 128
222 196 194
96 96 94
-0 0 0
+224 224 224
0 0 0
0 0 0
diff --git a/graphics/pokemon/panpour/overworld.png b/graphics/pokemon/panpour/overworld.png
index e02358cf2d..698ec1737f 100644
Binary files a/graphics/pokemon/panpour/overworld.png and b/graphics/pokemon/panpour/overworld.png differ
diff --git a/graphics/pokemon/panpour/overworld_normal.pal b/graphics/pokemon/panpour/overworld_normal.pal
index 99ad9dc501..31d63b727e 100644
--- a/graphics/pokemon/panpour/overworld_normal.pal
+++ b/graphics/pokemon/panpour/overworld_normal.pal
@@ -2,7 +2,7 @@ JASC-PAL
0100
16
152 208 160
-0 57 115
+26 54 82
24 139 172
41 180 222
0 0 0
diff --git a/graphics/pokemon/pansage/overworld.png b/graphics/pokemon/pansage/overworld.png
index 6addd12e20..3e884320af 100644
Binary files a/graphics/pokemon/pansage/overworld.png and b/graphics/pokemon/pansage/overworld.png differ
diff --git a/graphics/pokemon/pansear/overworld.png b/graphics/pokemon/pansear/overworld.png
index 0962330b53..270f791802 100644
Binary files a/graphics/pokemon/pansear/overworld.png and b/graphics/pokemon/pansear/overworld.png differ
diff --git a/graphics/pokemon/passimian/icon.png b/graphics/pokemon/passimian/icon.png
index 6daf24ccb6..1eed7c5412 100644
Binary files a/graphics/pokemon/passimian/icon.png and b/graphics/pokemon/passimian/icon.png differ
diff --git a/graphics/pokemon/patrat/overworld.png b/graphics/pokemon/patrat/overworld.png
index ea2df04dc1..8b6a34f198 100644
Binary files a/graphics/pokemon/patrat/overworld.png and b/graphics/pokemon/patrat/overworld.png differ
diff --git a/graphics/pokemon/persian/alola/icon.png b/graphics/pokemon/persian/alola/icon.png
index 75348250d5..21ad48eb31 100644
Binary files a/graphics/pokemon/persian/alola/icon.png and b/graphics/pokemon/persian/alola/icon.png differ
diff --git a/graphics/pokemon/pheromosa/icon.png b/graphics/pokemon/pheromosa/icon.png
index 4ab3a02a4e..0ff38de888 100644
Binary files a/graphics/pokemon/pheromosa/icon.png and b/graphics/pokemon/pheromosa/icon.png differ
diff --git a/graphics/pokemon/pichu/spiky_eared/front.png b/graphics/pokemon/pichu/spiky_eared/front.png
deleted file mode 100644
index 15b9201a27..0000000000
Binary files a/graphics/pokemon/pichu/spiky_eared/front.png and /dev/null differ
diff --git a/graphics/pokemon/pichu/spiky_eared/icon.png b/graphics/pokemon/pichu/spiky_eared/icon.png
index acd0234e0f..dbb47c84da 100644
Binary files a/graphics/pokemon/pichu/spiky_eared/icon.png and b/graphics/pokemon/pichu/spiky_eared/icon.png differ
diff --git a/graphics/pokemon/pichu/spiky_eared/overworld.png b/graphics/pokemon/pichu/spiky_eared/overworld.png
index 7208db5108..36c1040003 100644
Binary files a/graphics/pokemon/pichu/spiky_eared/overworld.png and b/graphics/pokemon/pichu/spiky_eared/overworld.png differ
diff --git a/graphics/pokemon/pidove/overworld.png b/graphics/pokemon/pidove/overworld.png
index b55a13e390..020027d44e 100644
Binary files a/graphics/pokemon/pidove/overworld.png and b/graphics/pokemon/pidove/overworld.png differ
diff --git a/graphics/pokemon/pidove/overworld_normal.pal b/graphics/pokemon/pidove/overworld_normal.pal
index 704bb5f946..820bcb20cd 100644
--- a/graphics/pokemon/pidove/overworld_normal.pal
+++ b/graphics/pokemon/pidove/overworld_normal.pal
@@ -14,6 +14,6 @@ JASC-PAL
248 184 40
184 96 96
128 128 128
-172 172 172
+150 150 150
0 0 0
0 0 0
diff --git a/graphics/pokemon/pignite/overworld.png b/graphics/pokemon/pignite/overworld.png
index 9ea0862b2d..b6b97736b9 100644
Binary files a/graphics/pokemon/pignite/overworld.png and b/graphics/pokemon/pignite/overworld.png differ
diff --git a/graphics/pokemon/pignite/overworld_normal.pal b/graphics/pokemon/pignite/overworld_normal.pal
index 5cf1ee3ef0..1454fac04d 100644
--- a/graphics/pokemon/pignite/overworld_normal.pal
+++ b/graphics/pokemon/pignite/overworld_normal.pal
@@ -4,16 +4,16 @@ JASC-PAL
152 208 160
16 16 16
0 0 0
-82 49 41
+80 48 40
57 37 37
-189 90 49
+209 95 46
123 57 41
-232 106 43
-210 182 96
-24 32 40
-83 79 60
-0 0 0
-0 0 0
-0 0 0
-0 0 0
+232 112 40
+232 192 56
+56 32 32
+80 48 40
+232 232 248
+200 64 56
+72 72 72
+41 41 41
0 0 0
diff --git a/graphics/pokemon/pignite/overworld_shiny.pal b/graphics/pokemon/pignite/overworld_shiny.pal
index 21a3212914..8d967d10b7 100644
--- a/graphics/pokemon/pignite/overworld_shiny.pal
+++ b/graphics/pokemon/pignite/overworld_shiny.pal
@@ -6,14 +6,14 @@ JASC-PAL
0 0 0
48 56 72
42 48 55
-120 104 240
-101 69 51
+184 136 24
+120 88 40
232 160 32
-204 156 214
+160 144 232
42 48 55
48 56 72
-0 0 0
-0 0 0
-0 0 0
-0 0 0
+232 232 248
+212 121 189
+88 48 40
+56 32 32
0 0 0
diff --git a/graphics/pokemon/pikachu/alola/icon.png b/graphics/pokemon/pikachu/alola/icon.png
index b9ba5f757f..0634df1ad7 100644
Binary files a/graphics/pokemon/pikachu/alola/icon.png and b/graphics/pokemon/pikachu/alola/icon.png differ
diff --git a/graphics/pokemon/pikachu/belle/icon.png b/graphics/pokemon/pikachu/belle/icon.png
index b3c0f00b37..f19b289454 100644
Binary files a/graphics/pokemon/pikachu/belle/icon.png and b/graphics/pokemon/pikachu/belle/icon.png differ
diff --git a/graphics/pokemon/pikachu/cosplay/icon.png b/graphics/pokemon/pikachu/cosplay/icon.png
index c826dacab0..21d9172a1f 100644
Binary files a/graphics/pokemon/pikachu/cosplay/icon.png and b/graphics/pokemon/pikachu/cosplay/icon.png differ
diff --git a/graphics/pokemon/pikachu/hoenn/icon.png b/graphics/pokemon/pikachu/hoenn/icon.png
index e5f8bfe206..5b9cbb2ba6 100644
Binary files a/graphics/pokemon/pikachu/hoenn/icon.png and b/graphics/pokemon/pikachu/hoenn/icon.png differ
diff --git a/graphics/pokemon/pikachu/kalos/icon.png b/graphics/pokemon/pikachu/kalos/icon.png
index c903ea9f3f..2aae11d524 100644
Binary files a/graphics/pokemon/pikachu/kalos/icon.png and b/graphics/pokemon/pikachu/kalos/icon.png differ
diff --git a/graphics/pokemon/pikachu/libre/icon.png b/graphics/pokemon/pikachu/libre/icon.png
index c1163a1619..ef6e8f1553 100644
Binary files a/graphics/pokemon/pikachu/libre/icon.png and b/graphics/pokemon/pikachu/libre/icon.png differ
diff --git a/graphics/pokemon/pikachu/original/icon.png b/graphics/pokemon/pikachu/original/icon.png
index d84764b65c..d4b80f3dc7 100644
Binary files a/graphics/pokemon/pikachu/original/icon.png and b/graphics/pokemon/pikachu/original/icon.png differ
diff --git a/graphics/pokemon/pikachu/phd/icon.png b/graphics/pokemon/pikachu/phd/icon.png
index f0b66bccf8..3d228c4275 100644
Binary files a/graphics/pokemon/pikachu/phd/icon.png and b/graphics/pokemon/pikachu/phd/icon.png differ
diff --git a/graphics/pokemon/pikachu/pop_star/icon.png b/graphics/pokemon/pikachu/pop_star/icon.png
index eb9b49e70a..1775f78db1 100644
Binary files a/graphics/pokemon/pikachu/pop_star/icon.png and b/graphics/pokemon/pikachu/pop_star/icon.png differ
diff --git a/graphics/pokemon/pikachu/rock_star/icon.png b/graphics/pokemon/pikachu/rock_star/icon.png
index 2c8d144d60..89025f0f3e 100644
Binary files a/graphics/pokemon/pikachu/rock_star/icon.png and b/graphics/pokemon/pikachu/rock_star/icon.png differ
diff --git a/graphics/pokemon/pikachu/sinnoh/icon.png b/graphics/pokemon/pikachu/sinnoh/icon.png
index 081ee6aae3..fbd66b0525 100644
Binary files a/graphics/pokemon/pikachu/sinnoh/icon.png and b/graphics/pokemon/pikachu/sinnoh/icon.png differ
diff --git a/graphics/pokemon/pikachu/starter/icon.png b/graphics/pokemon/pikachu/starter/icon.png
index 891f0d1b3e..737fababd7 100644
Binary files a/graphics/pokemon/pikachu/starter/icon.png and b/graphics/pokemon/pikachu/starter/icon.png differ
diff --git a/graphics/pokemon/pikachu/unova/icon.png b/graphics/pokemon/pikachu/unova/icon.png
index b6427a5ec2..427a38c6d6 100644
Binary files a/graphics/pokemon/pikachu/unova/icon.png and b/graphics/pokemon/pikachu/unova/icon.png differ
diff --git a/graphics/pokemon/pikachu/world/icon.png b/graphics/pokemon/pikachu/world/icon.png
index 260e29cda2..58c4ed1f48 100644
Binary files a/graphics/pokemon/pikachu/world/icon.png and b/graphics/pokemon/pikachu/world/icon.png differ
diff --git a/graphics/pokemon/pikipek/icon.png b/graphics/pokemon/pikipek/icon.png
index 291e148f1a..9a65234d8d 100644
Binary files a/graphics/pokemon/pikipek/icon.png and b/graphics/pokemon/pikipek/icon.png differ
diff --git a/graphics/pokemon/pincurchin/anim_front.png b/graphics/pokemon/pincurchin/anim_front.png
index b8ed4964e4..ffc6bb6008 100644
Binary files a/graphics/pokemon/pincurchin/anim_front.png and b/graphics/pokemon/pincurchin/anim_front.png differ
diff --git a/graphics/pokemon/poipole/icon.png b/graphics/pokemon/poipole/icon.png
index dce46b073d..b1ab69e8fb 100644
Binary files a/graphics/pokemon/poipole/icon.png and b/graphics/pokemon/poipole/icon.png differ
diff --git a/graphics/pokemon/popplio/icon.png b/graphics/pokemon/popplio/icon.png
index c35b74d2d9..f2eb184651 100644
Binary files a/graphics/pokemon/popplio/icon.png and b/graphics/pokemon/popplio/icon.png differ
diff --git a/graphics/pokemon/primarina/icon.png b/graphics/pokemon/primarina/icon.png
index d642cf12b2..1b56f7690c 100644
Binary files a/graphics/pokemon/primarina/icon.png and b/graphics/pokemon/primarina/icon.png differ
diff --git a/graphics/pokemon/purrloin/overworld.png b/graphics/pokemon/purrloin/overworld.png
index dd0d58266e..b751a7f8ec 100644
Binary files a/graphics/pokemon/purrloin/overworld.png and b/graphics/pokemon/purrloin/overworld.png differ
diff --git a/graphics/pokemon/purrloin/overworld_shiny.pal b/graphics/pokemon/purrloin/overworld_shiny.pal
index f1c5b242d0..92ba9739bf 100644
--- a/graphics/pokemon/purrloin/overworld_shiny.pal
+++ b/graphics/pokemon/purrloin/overworld_shiny.pal
@@ -7,10 +7,10 @@ JASC-PAL
0 0 0
56 72 104
168 112 224
-216 216 56
-240 232 192
-232 232 248
+112 176 64
216 200 136
+232 232 248
+240 232 192
0 0 0
0 0 0
0 0 0
diff --git a/graphics/pokemon/pyukumuku/icon.png b/graphics/pokemon/pyukumuku/icon.png
index 2e3e04451d..9ef6147558 100644
Binary files a/graphics/pokemon/pyukumuku/icon.png and b/graphics/pokemon/pyukumuku/icon.png differ
diff --git a/graphics/pokemon/raichu/alola/icon.png b/graphics/pokemon/raichu/alola/icon.png
index d005cf7e1d..2098d83f95 100644
Binary files a/graphics/pokemon/raichu/alola/icon.png and b/graphics/pokemon/raichu/alola/icon.png differ
diff --git a/graphics/pokemon/raticate/alola/icon.png b/graphics/pokemon/raticate/alola/icon.png
index 4acd9d0404..072c5ca6e4 100644
Binary files a/graphics/pokemon/raticate/alola/icon.png and b/graphics/pokemon/raticate/alola/icon.png differ
diff --git a/graphics/pokemon/rattata/alola/icon.png b/graphics/pokemon/rattata/alola/icon.png
index b13e1e9bb9..87c40fa445 100644
Binary files a/graphics/pokemon/rattata/alola/icon.png and b/graphics/pokemon/rattata/alola/icon.png differ
diff --git a/graphics/pokemon/ribombee/icon.png b/graphics/pokemon/ribombee/icon.png
index 10117f1234..46f0ba787c 100644
Binary files a/graphics/pokemon/ribombee/icon.png and b/graphics/pokemon/ribombee/icon.png differ
diff --git a/graphics/pokemon/rockruff/icon.png b/graphics/pokemon/rockruff/icon.png
index 5df839ab5d..6a7816898e 100644
Binary files a/graphics/pokemon/rockruff/icon.png and b/graphics/pokemon/rockruff/icon.png differ
diff --git a/graphics/pokemon/rowlet/icon.png b/graphics/pokemon/rowlet/icon.png
index 433666f6e1..725a5884f7 100644
Binary files a/graphics/pokemon/rowlet/icon.png and b/graphics/pokemon/rowlet/icon.png differ
diff --git a/graphics/pokemon/salandit/icon.png b/graphics/pokemon/salandit/icon.png
index e0c6309c75..37fe8d7e75 100644
Binary files a/graphics/pokemon/salandit/icon.png and b/graphics/pokemon/salandit/icon.png differ
diff --git a/graphics/pokemon/salazzle/icon.png b/graphics/pokemon/salazzle/icon.png
index db4edf2fc3..e106d18c4d 100644
Binary files a/graphics/pokemon/salazzle/icon.png and b/graphics/pokemon/salazzle/icon.png differ
diff --git a/graphics/pokemon/sandshrew/alola/icon.png b/graphics/pokemon/sandshrew/alola/icon.png
index a1cc049bdb..ae93de08b6 100644
Binary files a/graphics/pokemon/sandshrew/alola/icon.png and b/graphics/pokemon/sandshrew/alola/icon.png differ
diff --git a/graphics/pokemon/sandslash/alola/icon.png b/graphics/pokemon/sandslash/alola/icon.png
index 88cea6049b..9df450d1ed 100644
Binary files a/graphics/pokemon/sandslash/alola/icon.png and b/graphics/pokemon/sandslash/alola/icon.png differ
diff --git a/graphics/pokemon/sandygast/icon.png b/graphics/pokemon/sandygast/icon.png
index 46167f5ab6..b402810942 100644
Binary files a/graphics/pokemon/sandygast/icon.png and b/graphics/pokemon/sandygast/icon.png differ
diff --git a/graphics/pokemon/shiinotic/icon.png b/graphics/pokemon/shiinotic/icon.png
index 510d61a97c..68adb4ff34 100644
Binary files a/graphics/pokemon/shiinotic/icon.png and b/graphics/pokemon/shiinotic/icon.png differ
diff --git a/graphics/pokemon/silvally/icon.png b/graphics/pokemon/silvally/icon.png
index 2ef6ae9ad7..954a4362b9 100644
Binary files a/graphics/pokemon/silvally/icon.png and b/graphics/pokemon/silvally/icon.png differ
diff --git a/graphics/pokemon/sinistcha/back.png b/graphics/pokemon/sinistcha/back.png
index dbb51bbf33..b9df7c5e4d 100644
Binary files a/graphics/pokemon/sinistcha/back.png and b/graphics/pokemon/sinistcha/back.png differ
diff --git a/graphics/pokemon/sinistcha/front.png b/graphics/pokemon/sinistcha/front.png
index 4131a22b9f..eeb1b7a71a 100644
Binary files a/graphics/pokemon/sinistcha/front.png and b/graphics/pokemon/sinistcha/front.png differ
diff --git a/graphics/pokemon/sinistcha/normal.pal b/graphics/pokemon/sinistcha/normal.pal
index 16008ccdf1..0697645151 100644
--- a/graphics/pokemon/sinistcha/normal.pal
+++ b/graphics/pokemon/sinistcha/normal.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-115 197 164
+16
+153 210 164
+37 27 27
76 58 58
+57 103 37
105 68 27
-147 138 68
-159 153 130
-219 210 145
-167 186 114
-45 33 33
-51 99 34
+106 91 32
93 158 74
120 196 99
-247 215 98
+160 151 80
+135 132 126
+167 186 114
+204 195 116
+247 218 103
+193 185 174
5 5 5
-208 210 193
-241 237 235
+230 225 219
diff --git a/graphics/pokemon/sinistcha/shiny.pal b/graphics/pokemon/sinistcha/shiny.pal
index c769e9d1a1..6b9d62ab8c 100644
--- a/graphics/pokemon/sinistcha/shiny.pal
+++ b/graphics/pokemon/sinistcha/shiny.pal
@@ -1,18 +1,19 @@
JASC-PAL
0100
-15
-115 197 164
+16
+153 210 164
+10 48 0
32 88 15
-105 68 27
-147 138 68
-159 153 130
-219 210 145
-167 186 114
-45 33 33
-51 99 34
+57 103 37
+143 133 51
+106 91 32
93 158 74
120 196 99
-247 215 98
+160 151 80
+135 132 126
+167 186 114
+204 195 116
+247 218 103
+193 185 174
5 5 5
-208 210 193
-241 237 235
+230 225 219
diff --git a/graphics/pokemon/solgaleo/icon.png b/graphics/pokemon/solgaleo/icon.png
index e7520c9bcf..62ed55d205 100644
Binary files a/graphics/pokemon/solgaleo/icon.png and b/graphics/pokemon/solgaleo/icon.png differ
diff --git a/graphics/pokemon/stakataka/icon.png b/graphics/pokemon/stakataka/icon.png
index ad79ba34d8..359b1a248c 100644
Binary files a/graphics/pokemon/stakataka/icon.png and b/graphics/pokemon/stakataka/icon.png differ
diff --git a/graphics/pokemon/steenee/icon.png b/graphics/pokemon/steenee/icon.png
index 80531a6315..eea2c5a42a 100644
Binary files a/graphics/pokemon/steenee/icon.png and b/graphics/pokemon/steenee/icon.png differ
diff --git a/graphics/pokemon/stufful/icon.png b/graphics/pokemon/stufful/icon.png
index de35247ae8..357d860f63 100644
Binary files a/graphics/pokemon/stufful/icon.png and b/graphics/pokemon/stufful/icon.png differ
diff --git a/graphics/pokemon/tapu_bulu/icon.png b/graphics/pokemon/tapu_bulu/icon.png
index 69261acb3f..9d329d8250 100644
Binary files a/graphics/pokemon/tapu_bulu/icon.png and b/graphics/pokemon/tapu_bulu/icon.png differ
diff --git a/graphics/pokemon/tapu_fini/icon.png b/graphics/pokemon/tapu_fini/icon.png
index fcd74bbd19..623e1d4287 100644
Binary files a/graphics/pokemon/tapu_fini/icon.png and b/graphics/pokemon/tapu_fini/icon.png differ
diff --git a/graphics/pokemon/tapu_koko/icon.png b/graphics/pokemon/tapu_koko/icon.png
index 73470d55ad..2c857e5aa2 100644
Binary files a/graphics/pokemon/tapu_koko/icon.png and b/graphics/pokemon/tapu_koko/icon.png differ
diff --git a/graphics/pokemon/tapu_lele/icon.png b/graphics/pokemon/tapu_lele/icon.png
index e92e3fd3f1..960eee6e17 100644
Binary files a/graphics/pokemon/tapu_lele/icon.png and b/graphics/pokemon/tapu_lele/icon.png differ
diff --git a/graphics/pokemon/tepig/overworld.png b/graphics/pokemon/tepig/overworld.png
index b600bd7e74..c78cfebc5b 100644
Binary files a/graphics/pokemon/tepig/overworld.png and b/graphics/pokemon/tepig/overworld.png differ
diff --git a/graphics/pokemon/togedemaru/icon.png b/graphics/pokemon/togedemaru/icon.png
index 2ccf7d60d5..8aab887881 100644
Binary files a/graphics/pokemon/togedemaru/icon.png and b/graphics/pokemon/togedemaru/icon.png differ
diff --git a/graphics/pokemon/torracat/icon.png b/graphics/pokemon/torracat/icon.png
index b266274f57..0b5f7a12e0 100644
Binary files a/graphics/pokemon/torracat/icon.png and b/graphics/pokemon/torracat/icon.png differ
diff --git a/graphics/pokemon/toucannon/icon.png b/graphics/pokemon/toucannon/icon.png
index 349c723761..ba9740d298 100644
Binary files a/graphics/pokemon/toucannon/icon.png and b/graphics/pokemon/toucannon/icon.png differ
diff --git a/graphics/pokemon/toxapex/icon.png b/graphics/pokemon/toxapex/icon.png
index 5de471d4f3..eed4abe4f4 100644
Binary files a/graphics/pokemon/toxapex/icon.png and b/graphics/pokemon/toxapex/icon.png differ
diff --git a/graphics/pokemon/trumbeak/icon.png b/graphics/pokemon/trumbeak/icon.png
index 7f13c97ae8..708e68f864 100644
Binary files a/graphics/pokemon/trumbeak/icon.png and b/graphics/pokemon/trumbeak/icon.png differ
diff --git a/graphics/pokemon/tsareena/icon.png b/graphics/pokemon/tsareena/icon.png
index f441195623..b436e30a21 100644
Binary files a/graphics/pokemon/tsareena/icon.png and b/graphics/pokemon/tsareena/icon.png differ
diff --git a/graphics/pokemon/turtonator/icon.png b/graphics/pokemon/turtonator/icon.png
index 4e1b8dbfa1..2ee4c8952a 100644
Binary files a/graphics/pokemon/turtonator/icon.png and b/graphics/pokemon/turtonator/icon.png differ
diff --git a/graphics/pokemon/tympole/overworld.png b/graphics/pokemon/tympole/overworld.png
index 9f9778553c..320809dc24 100644
Binary files a/graphics/pokemon/tympole/overworld.png and b/graphics/pokemon/tympole/overworld.png differ
diff --git a/graphics/pokemon/type_null/icon.png b/graphics/pokemon/type_null/icon.png
index e00748e138..ac03c60d4e 100644
Binary files a/graphics/pokemon/type_null/icon.png and b/graphics/pokemon/type_null/icon.png differ
diff --git a/graphics/pokemon/vikavolt/icon.png b/graphics/pokemon/vikavolt/icon.png
index 7a8f2cff4d..eff23d50aa 100644
Binary files a/graphics/pokemon/vikavolt/icon.png and b/graphics/pokemon/vikavolt/icon.png differ
diff --git a/graphics/pokemon/vivillon/archipelago/icon.png b/graphics/pokemon/vivillon/archipelago/icon.png
index 5dfb32bb60..82d2757589 100644
Binary files a/graphics/pokemon/vivillon/archipelago/icon.png and b/graphics/pokemon/vivillon/archipelago/icon.png differ
diff --git a/graphics/pokemon/vivillon/continental/icon.png b/graphics/pokemon/vivillon/continental/icon.png
index 482c27feba..725b181c8a 100644
Binary files a/graphics/pokemon/vivillon/continental/icon.png and b/graphics/pokemon/vivillon/continental/icon.png differ
diff --git a/graphics/pokemon/vivillon/elegant/icon.png b/graphics/pokemon/vivillon/elegant/icon.png
index fc23f4335a..bf2c9a50b6 100644
Binary files a/graphics/pokemon/vivillon/elegant/icon.png and b/graphics/pokemon/vivillon/elegant/icon.png differ
diff --git a/graphics/pokemon/vivillon/fancy/icon.png b/graphics/pokemon/vivillon/fancy/icon.png
index 2e75d4c340..1fa55125e6 100644
Binary files a/graphics/pokemon/vivillon/fancy/icon.png and b/graphics/pokemon/vivillon/fancy/icon.png differ
diff --git a/graphics/pokemon/vivillon/garden/icon.png b/graphics/pokemon/vivillon/garden/icon.png
index bcf56d0ef4..e487901f95 100644
Binary files a/graphics/pokemon/vivillon/garden/icon.png and b/graphics/pokemon/vivillon/garden/icon.png differ
diff --git a/graphics/pokemon/vivillon/high_plains/icon.png b/graphics/pokemon/vivillon/high_plains/icon.png
index 6e2313e901..d68ff6df4a 100644
Binary files a/graphics/pokemon/vivillon/high_plains/icon.png and b/graphics/pokemon/vivillon/high_plains/icon.png differ
diff --git a/graphics/pokemon/vivillon/icon.png b/graphics/pokemon/vivillon/icon.png
index b9d27d02ee..1c5015e07a 100644
Binary files a/graphics/pokemon/vivillon/icon.png and b/graphics/pokemon/vivillon/icon.png differ
diff --git a/graphics/pokemon/vivillon/jungle/icon.png b/graphics/pokemon/vivillon/jungle/icon.png
index e759b4f789..9b2923d543 100644
Binary files a/graphics/pokemon/vivillon/jungle/icon.png and b/graphics/pokemon/vivillon/jungle/icon.png differ
diff --git a/graphics/pokemon/vivillon/marine/icon.png b/graphics/pokemon/vivillon/marine/icon.png
index 69b2eab4de..b3673e5574 100644
Binary files a/graphics/pokemon/vivillon/marine/icon.png and b/graphics/pokemon/vivillon/marine/icon.png differ
diff --git a/graphics/pokemon/vivillon/modern/icon.png b/graphics/pokemon/vivillon/modern/icon.png
index dedc1aa19f..a28216c157 100644
Binary files a/graphics/pokemon/vivillon/modern/icon.png and b/graphics/pokemon/vivillon/modern/icon.png differ
diff --git a/graphics/pokemon/vivillon/monsoon/icon.png b/graphics/pokemon/vivillon/monsoon/icon.png
index 22fcc286d5..277798f860 100644
Binary files a/graphics/pokemon/vivillon/monsoon/icon.png and b/graphics/pokemon/vivillon/monsoon/icon.png differ
diff --git a/graphics/pokemon/vivillon/ocean/icon.png b/graphics/pokemon/vivillon/ocean/icon.png
index 47609a6b59..764a8cdcee 100644
Binary files a/graphics/pokemon/vivillon/ocean/icon.png and b/graphics/pokemon/vivillon/ocean/icon.png differ
diff --git a/graphics/pokemon/vivillon/poke_ball/icon.png b/graphics/pokemon/vivillon/poke_ball/icon.png
index 1ca199b96b..7be708eb95 100644
Binary files a/graphics/pokemon/vivillon/poke_ball/icon.png and b/graphics/pokemon/vivillon/poke_ball/icon.png differ
diff --git a/graphics/pokemon/vivillon/polar/icon.png b/graphics/pokemon/vivillon/polar/icon.png
index e523903873..5fc161cca5 100644
Binary files a/graphics/pokemon/vivillon/polar/icon.png and b/graphics/pokemon/vivillon/polar/icon.png differ
diff --git a/graphics/pokemon/vivillon/river/icon.png b/graphics/pokemon/vivillon/river/icon.png
index 5cb09d29bd..475ae4e9d9 100644
Binary files a/graphics/pokemon/vivillon/river/icon.png and b/graphics/pokemon/vivillon/river/icon.png differ
diff --git a/graphics/pokemon/vivillon/sandstorm/icon.png b/graphics/pokemon/vivillon/sandstorm/icon.png
index 40822af866..b428bf6e92 100644
Binary files a/graphics/pokemon/vivillon/sandstorm/icon.png and b/graphics/pokemon/vivillon/sandstorm/icon.png differ
diff --git a/graphics/pokemon/vivillon/savanna/icon.png b/graphics/pokemon/vivillon/savanna/icon.png
index cc12705dd8..7c58f606e6 100644
Binary files a/graphics/pokemon/vivillon/savanna/icon.png and b/graphics/pokemon/vivillon/savanna/icon.png differ
diff --git a/graphics/pokemon/vivillon/sun/icon.png b/graphics/pokemon/vivillon/sun/icon.png
index 95d3c84e5b..e14a22faad 100644
Binary files a/graphics/pokemon/vivillon/sun/icon.png and b/graphics/pokemon/vivillon/sun/icon.png differ
diff --git a/graphics/pokemon/vivillon/tundra/icon.png b/graphics/pokemon/vivillon/tundra/icon.png
index fa937ff7ca..6347455e81 100644
Binary files a/graphics/pokemon/vivillon/tundra/icon.png and b/graphics/pokemon/vivillon/tundra/icon.png differ
diff --git a/graphics/pokemon/vulpix/alola/icon.png b/graphics/pokemon/vulpix/alola/icon.png
index f49562751b..ccf5bbfcc1 100644
Binary files a/graphics/pokemon/vulpix/alola/icon.png and b/graphics/pokemon/vulpix/alola/icon.png differ
diff --git a/graphics/pokemon/watchog/overworld.png b/graphics/pokemon/watchog/overworld.png
index f2e9ff4733..e9184c7375 100644
Binary files a/graphics/pokemon/watchog/overworld.png and b/graphics/pokemon/watchog/overworld.png differ
diff --git a/graphics/pokemon/watchog/overworld_normal.pal b/graphics/pokemon/watchog/overworld_normal.pal
index 3e75b9e987..0bc0feda6b 100644
--- a/graphics/pokemon/watchog/overworld_normal.pal
+++ b/graphics/pokemon/watchog/overworld_normal.pal
@@ -2,8 +2,8 @@ JASC-PAL
0100
16
152 208 160
-90 41 57
-115 49 65
+88 40 56
+112 48 64
0 0 0
148 57 57
47 46 47
@@ -11,7 +11,7 @@ JASC-PAL
218 85 79
230 222 210
212 157 60
-16 16 16
+208 184 144
0 0 0
0 0 0
0 0 0
diff --git a/graphics/pokemon/watchog/overworld_shiny.pal b/graphics/pokemon/watchog/overworld_shiny.pal
index 0a5ae605c9..dba33393d8 100644
--- a/graphics/pokemon/watchog/overworld_shiny.pal
+++ b/graphics/pokemon/watchog/overworld_shiny.pal
@@ -3,15 +3,15 @@ JASC-PAL
16
152 208 160
90 41 57
-112 48 86
+112 40 88
0 0 0
-144 56 96
+160 56 104
47 46 47
-152 152 152
-212 118 77
+125 125 125
+240 72 72
193 223 190
-91 169 85
-16 16 16
+120 232 144
+216 192 128
0 0 0
0 0 0
0 0 0
diff --git a/graphics/pokemon/whimsicott/overworld.png b/graphics/pokemon/whimsicott/overworld.png
index 62057ff6f8..ed1c4db2cb 100644
Binary files a/graphics/pokemon/whimsicott/overworld.png and b/graphics/pokemon/whimsicott/overworld.png differ
diff --git a/graphics/pokemon/whimsicott/overworld_normal.pal b/graphics/pokemon/whimsicott/overworld_normal.pal
index c9e2ef3b00..8e9638c301 100644
--- a/graphics/pokemon/whimsicott/overworld_normal.pal
+++ b/graphics/pokemon/whimsicott/overworld_normal.pal
@@ -3,17 +3,17 @@ JASC-PAL
16
152 208 160
168 151 83
-106 84 64
+148 106 65
226 218 202
-41 66 22
-194 178 137
+82 57 41
194 178 137
+106 90 65
12 12 12
41 66 22
66 119 65
237 237 247
-106 84 64
-226 218 202
-0 0 0
-0 0 0
-0 0 0
+70 47 35
+201 189 165
+115 82 65
+230 131 0
+194 114 2
diff --git a/graphics/pokemon/whimsicott/overworld_shiny.pal b/graphics/pokemon/whimsicott/overworld_shiny.pal
index 1e09d1a78e..ad2e0b4543 100644
--- a/graphics/pokemon/whimsicott/overworld_shiny.pal
+++ b/graphics/pokemon/whimsicott/overworld_shiny.pal
@@ -2,18 +2,18 @@ JASC-PAL
0100
16
152 208 160
-110 94 94
-105 89 68
+152 152 128
+112 96 88
248 240 232
56 50 50
192 192 184
-194 178 137
+120 104 104
9 9 9
-35 86 194
-107 154 170
+40 97 130
+63 151 209
237 237 247
-82 57 41
+56 45 39
230 222 205
-0 0 0
-0 0 0
-0 0 0
+80 64 64
+232 168 0
+176 104 16
diff --git a/graphics/pokemon/wimpod/icon.png b/graphics/pokemon/wimpod/icon.png
index 77a8048895..732b7b9ac0 100644
Binary files a/graphics/pokemon/wimpod/icon.png and b/graphics/pokemon/wimpod/icon.png differ
diff --git a/graphics/pokemon/wishiwashi/icon.png b/graphics/pokemon/wishiwashi/icon.png
index 0b9df6baf4..2e2778650f 100644
Binary files a/graphics/pokemon/wishiwashi/icon.png and b/graphics/pokemon/wishiwashi/icon.png differ
diff --git a/graphics/pokemon/wishiwashi/school/icon.png b/graphics/pokemon/wishiwashi/school/icon.png
index 2cf411fd1b..a756cc5551 100644
Binary files a/graphics/pokemon/wishiwashi/school/icon.png and b/graphics/pokemon/wishiwashi/school/icon.png differ
diff --git a/graphics/pokemon/woobat/overworld.png b/graphics/pokemon/woobat/overworld.png
index 1d14a5c43d..18bff8d5c3 100644
Binary files a/graphics/pokemon/woobat/overworld.png and b/graphics/pokemon/woobat/overworld.png differ
diff --git a/graphics/pokemon/xerneas/icon.png b/graphics/pokemon/xerneas/icon.png
index 6d0b56b3b6..8e2a8cc8ff 100644
Binary files a/graphics/pokemon/xerneas/icon.png and b/graphics/pokemon/xerneas/icon.png differ
diff --git a/graphics/pokemon/xurkitree/icon.png b/graphics/pokemon/xurkitree/icon.png
index 26cce62f0a..4c044631de 100644
Binary files a/graphics/pokemon/xurkitree/icon.png and b/graphics/pokemon/xurkitree/icon.png differ
diff --git a/graphics/pokemon/yungoos/icon.png b/graphics/pokemon/yungoos/icon.png
index 657e0b6764..3001e64f11 100644
Binary files a/graphics/pokemon/yungoos/icon.png and b/graphics/pokemon/yungoos/icon.png differ
diff --git a/graphics/pokemon/zeraora/icon.png b/graphics/pokemon/zeraora/icon.png
index b8dadd7ba3..7df134703f 100644
Binary files a/graphics/pokemon/zeraora/icon.png and b/graphics/pokemon/zeraora/icon.png differ
diff --git a/graphics/pokemon/zygarde/10_percent/icon.png b/graphics/pokemon/zygarde/10_percent/icon.png
index c1fd251535..ab6354c985 100644
Binary files a/graphics/pokemon/zygarde/10_percent/icon.png and b/graphics/pokemon/zygarde/10_percent/icon.png differ
diff --git a/graphics/pokemon/zygarde/complete/icon.png b/graphics/pokemon/zygarde/complete/icon.png
index 454af5dcac..c7d6c8d010 100644
Binary files a/graphics/pokemon/zygarde/complete/icon.png and b/graphics/pokemon/zygarde/complete/icon.png differ
diff --git a/graphics_file_rules.mk b/graphics_file_rules.mk
index 39d634e19d..9f1be162f4 100644
--- a/graphics_file_rules.mk
+++ b/graphics_file_rules.mk
@@ -248,6 +248,9 @@ $(FONTGFXDIR)/small_narrower.latfont: $(FONTGFXDIR)/latin_small_narrower.png
$(FONTGFXDIR)/short_narrow.latfont: $(FONTGFXDIR)/latin_short_narrow.png
$(GFX) $< $@
+$(FONTGFXDIR)/short_narrower.latfont: $(FONTGFXDIR)/latin_short_narrower.png
+ $(GFX) $< $@
+
$(FONTGFXDIR)/small.hwjpnfont: $(FONTGFXDIR)/japanese_small.png
$(GFX) $< $@
diff --git a/include/battle.h b/include/battle.h
index f7b41b3dce..413380ccba 100644
--- a/include/battle.h
+++ b/include/battle.h
@@ -17,6 +17,7 @@
#include "battle_dynamax.h"
#include "battle_terastal.h"
#include "battle_gimmick.h"
+#include "move.h"
#include "random.h" // for rng_value_t
// Helper for accessing command arguments and advancing gBattlescriptCurrInstr.
@@ -70,20 +71,6 @@
// Special indicator value for shellBellDmg in SpecialStatus
#define IGNORE_SHELL_BELL 0xFFFF
-// For defining EFFECT_HIT etc. with battle TV scores and flags etc.
-struct __attribute__((packed, aligned(2))) BattleMoveEffect
-{
- const u8 *battleScript;
- u16 battleTvScore:3;
- u16 encourageEncore:1;
- u16 twoTurnEffect:1;
- u16 semiInvulnerableEffect:1;
- u16 usesProtectCounter:1;
- u16 padding:9;
-};
-
-#define GET_MOVE_BATTLESCRIPT(move) gBattleMoveEffects[gMovesInfo[move].effect].battleScript
-
struct ResourceFlags
{
u32 flags[MAX_BATTLERS_COUNT];
@@ -250,6 +237,9 @@ struct SpecialStatus
u8 emergencyExited:1;
u8 afterYou:1;
u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects.
+ u8 distortedTypeMatchups:1;
+ u8 teraShellAbilityDone:1;
+ u8 criticalHit:1;
};
struct SideTimer
@@ -823,13 +813,33 @@ struct BattleStruct
u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT];
u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values.
u8 boosterEnergyActivates;
- u8 distortedTypeMatchups;
u8 categoryOverride; // for Z-Moves and Max Moves
u8 commandingDondozo;
- u16 commanderActive[NUM_BATTLE_SIDES];
+ u16 commanderActive[MAX_BATTLERS_COUNT];
u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side
+ u8 redCardActivates:1;
+ u8 padding1:7;
u8 usedEjectItem;
- u8 usedMicleBerry;
+ u8 monCausingSleepClause[NUM_BATTLE_SIDES]; // Stores which pokemon on a given side is causing Sleep Clause to be active as the mon's index in the party
+ u8 sleepClauseEffectExempt:4; // Stores whether effect should be exempt from triggering Sleep Clause (Effect Spore)
+ u8 usedMicleBerry:4;
+ u8 pursuitTarget:4; // Each battler as a bit.
+ u8 pursuitSwitchByMove:1;
+ u8 pursuitStoredSwitch; // Stored id for the Pursuit target's switch
+ s32 battlerExpReward;
+
+ // Simultaneous hp reduction for spread moves
+ s32 moveDamage[MAX_BATTLERS_COUNT];
+ s32 critChance[MAX_BATTLERS_COUNT];
+ u16 moveResultFlags[MAX_BATTLERS_COUNT];
+ u8 missStringId[MAX_BATTLERS_COUNT];
+ u8 noResultString[MAX_BATTLERS_COUNT];
+ u8 doneDoublesSpreadHit:1;
+ u8 calculatedDamageDone:1;
+ u8 calculatedSpreadMoveAccuracy:1;
+ u8 printedStrongWindsWeakenedAttack:1;
+ u8 numSpreadTargets:2;
+ u8 padding2:2;
};
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
@@ -841,19 +851,49 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER
#define F_DYNAMIC_TYPE_IGNORE_PHYSICALITY (1 << 6) // If set, the dynamic type's physicality won't be used for certain move effects.
#define F_DYNAMIC_TYPE_SET (1 << 7) // Set for all dynamic types to distinguish a dynamic type of Normal (0) from no dynamic type.
-#define IS_MOVE_PHYSICAL(move)(GetBattleMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL)
-#define IS_MOVE_SPECIAL(move)(GetBattleMoveCategory(move) == DAMAGE_CATEGORY_SPECIAL)
-#define IS_MOVE_STATUS(move)(gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
+static inline bool32 IsBattleMovePhysical(u32 move)
+{
+ return GetBattleMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL;
+}
-#define IS_MOVE_RECOIL(move)(gMovesInfo[move].recoil > 0 || gMovesInfo[move].effect == EFFECT_RECOIL_IF_MISS)
+static inline bool32 IsBattleMoveSpecial(u32 move)
+{
+ return GetBattleMoveCategory(move) == DAMAGE_CATEGORY_SPECIAL;
+}
-#define BATTLER_MAX_HP(battlerId)(gBattleMons[battlerId].hp == gBattleMons[battlerId].maxHP)
-#define TARGET_TURN_DAMAGED ((gSpecialStatuses[gBattlerTarget].physicalDmg != 0 || gSpecialStatuses[gBattlerTarget].specialDmg != 0) || (gBattleStruct->enduredDamage & (1u << gBattlerTarget)))
-#define BATTLER_TURN_DAMAGED(battlerId) ((gSpecialStatuses[battlerId].physicalDmg != 0 || gSpecialStatuses[battlerId].specialDmg != 0) || (gBattleStruct->enduredDamage & (1u << battler)))
+static inline bool32 IsBattleMoveStatus(u32 move)
+{
+ return GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS;
+}
-#define IS_BATTLER_OF_TYPE(battlerId, type)((GetBattlerType(battlerId, 0, FALSE) == type || GetBattlerType(battlerId, 1, FALSE) == type || (GetBattlerType(battlerId, 2, FALSE) != TYPE_MYSTERY && GetBattlerType(battlerId, 2, FALSE) == type)))
-#define IS_BATTLER_OF_BASE_TYPE(battlerId, type)((GetBattlerType(battlerId, 0, TRUE) == type || GetBattlerType(battlerId, 1, TRUE) == type || (GetBattlerType(battlerId, 2, TRUE) != TYPE_MYSTERY && GetBattlerType(battlerId, 2, TRUE) == type)))
-#define IS_BATTLER_TYPELESS(battlerId)(GetBattlerType(battlerId, 0, FALSE) == TYPE_MYSTERY && GetBattlerType(battlerId, 1, FALSE) == TYPE_MYSTERY && GetBattlerType(battlerId, 2, FALSE) == TYPE_MYSTERY)
+static inline bool32 IsBattleMoveRecoil(u32 move)
+{
+ return GetMoveRecoil(move) > 0 || GetMoveEffect(move) == EFFECT_RECOIL_IF_MISS;
+}
+
+/* Checks if 'battlerId' is any of the types.
+ * Passing multiple types is more efficient than calling this multiple
+ * times with one type because it shares the 'GetBattlerTypes' result. */
+#define _IS_BATTLER_ANY_TYPE(battlerId, ignoreTera, ...) \
+ ({ \
+ u32 types[3]; \
+ GetBattlerTypes(battlerId, ignoreTera, types); \
+ RECURSIVELY(R_FOR_EACH(_IS_BATTLER_ANY_TYPE_HELPER, __VA_ARGS__)) FALSE; \
+ })
+
+#define _IS_BATTLER_ANY_TYPE_HELPER(type) (types[0] == type) || (types[1] == type) || (types[2] == type) ||
+
+#define IS_BATTLER_ANY_TYPE(battlerId, ...) _IS_BATTLER_ANY_TYPE(battlerId, FALSE, __VA_ARGS__)
+#define IS_BATTLER_OF_TYPE IS_BATTLER_ANY_TYPE
+#define IS_BATTLER_ANY_BASE_TYPE(battlerId, ...) _IS_BATTLER_ANY_TYPE(battlerId, TRUE, __VA_ARGS__)
+#define IS_BATTLER_OF_BASE_TYPE IS_BATTLER_ANY_BASE_TYPE
+
+#define IS_BATTLER_TYPELESS(battlerId) \
+ ({ \
+ u32 types[3]; \
+ GetBattlerTypes(battlerId, FALSE, types); \
+ types[0] == TYPE_MYSTERY && types[1] == TYPE_MYSTERY && types[2] == TYPE_MYSTERY; \
+ })
#define SET_BATTLER_TYPE(battlerId, type) \
{ \
@@ -891,6 +931,8 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER
#define SET_STATCHANGER(statId, stage, goesDown) (gBattleScripting.statChanger = (statId) + ((stage) << 3) + (goesDown << 7))
#define SET_STATCHANGER2(dst, statId, stage, goesDown)(dst = (statId) + ((stage) << 3) + (goesDown << 7))
+#define DO_ACCURACY_CHECK 2 // Don't skip the accuracy check before the move might be absorbed
+
// NOTE: The members of this struct have hard-coded offsets
// in include/constants/battle_script_commands.h
struct BattleScripting
@@ -1071,7 +1113,6 @@ extern u8 gChosenMovePos;
extern u16 gCurrentMove;
extern u16 gChosenMove;
extern u16 gCalledMove;
-extern s32 gBattleMoveDamage;
extern s32 gHpDealt;
extern s32 gBideDmg[MAX_BATTLERS_COUNT];
extern u16 gLastUsedItem;
@@ -1082,7 +1123,6 @@ extern u8 gBattlerFainted;
extern u8 gEffectBattler;
extern u8 gPotentialItemEffectBattler;
extern u8 gAbsentBattlerFlags;
-extern u8 gIsCriticalHit;
extern u8 gMultiHitCounter;
extern const u8 *gBattlescriptCurrInstr;
extern u8 gChosenActionByBattler[MAX_BATTLERS_COUNT];
@@ -1098,7 +1138,6 @@ extern u16 gLockedMoves[MAX_BATTLERS_COUNT];
extern u16 gLastUsedMove;
extern u8 gLastHitBy[MAX_BATTLERS_COUNT];
extern u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT];
-extern u16 gMoveResultFlags;
extern u32 gHitMarker;
extern u8 gBideTarget[MAX_BATTLERS_COUNT];
extern u32 gSideStatuses[NUM_BATTLE_SIDES];
@@ -1138,7 +1177,6 @@ extern u32 gFieldStatuses;
extern struct FieldTimer gFieldTimers;
extern u8 gBattlerAbility;
extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT];
-extern const struct BattleMoveEffect gBattleMoveEffects[];
extern void (*gPreBattleCallback1)(void);
extern void (*gBattleMainFunc)(void);
@@ -1155,6 +1193,18 @@ extern bool8 gLastUsedBallMenuPresent;
extern u8 gPartyCriticalHits[PARTY_SIZE];
extern u8 gCategoryIconSpriteId;
+static inline bool32 IsBattlerTurnDamaged(u32 battler)
+{
+ return gSpecialStatuses[battler].physicalDmg != 0
+ || gSpecialStatuses[battler].specialDmg != 0
+ || gBattleStruct->enduredDamage & (1u << battler);
+}
+
+static inline bool32 IsBattlerAtMaxHp(u32 battler)
+{
+ return gBattleMons[battler].hp == gBattleMons[battler].maxHP;
+}
+
static inline u32 GetBattlerPosition(u32 battler)
{
return gBattlerPositions[battler];
@@ -1186,5 +1236,29 @@ static inline bool32 IsDoubleBattle(void)
return gBattleTypeFlags & BATTLE_TYPE_DOUBLE;
}
+static inline bool32 IsSpreadMove(u32 moveTarget)
+{
+ return IsDoubleBattle() && (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY);
+}
+
+static inline bool32 IsDoubleSpreadMove(void)
+{
+ return gBattleStruct->numSpreadTargets > 1
+ && !(gHitMarker & (HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_UNABLE_TO_USE_MOVE))
+ && IsSpreadMove(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove));
+}
+
+static inline bool32 IsBattlerInvalidForSpreadMove(u32 battlerAtk, u32 battlerDef, u32 moveTarget)
+{
+ return battlerDef == battlerAtk
+ || !IsBattlerAlive(battlerDef)
+ || (battlerDef == BATTLE_PARTNER(battlerAtk) && (moveTarget == MOVE_TARGET_BOTH));
+}
+
+static inline bool32 MoveResultHasEffect(u32 battler)
+{
+ return !(gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_NO_EFFECT);
+}
+
#endif // GUARD_BATTLE_H
diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h
index c74cad2e78..7cfc28e5d6 100644
--- a/include/battle_ai_util.h
+++ b/include/battle_ai_util.h
@@ -44,7 +44,7 @@ void RestoreBattlerData(u32 battlerId);
u32 GetAIChosenMove(u32 battlerId);
u32 GetTotalBaseStat(u32 species);
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
-bool32 AtMaxHp(u32 battler);
+bool32 AI_BattlerAtMaxHp(u32 battler);
u32 GetHealthPercentage(u32 battler);
bool32 IsBattlerTrapped(u32 battler, bool32 switching);
s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered);
@@ -116,7 +116,7 @@ bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensiv
bool32 HasMoveWithCategory(u32 battler, u32 category);
bool32 HasMoveWithType(u32 battler, u32 type);
bool32 HasMoveEffect(u32 battlerId, u32 moveEffect);
-bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument);
+bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument);
bool32 HasMoveWithAdditionalEffect(u32 battlerId, u32 moveEffect);
bool32 HasMoveWithCriticalHitChance(u32 battlerId);
bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception);
@@ -185,6 +185,7 @@ bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove);
bool32 PartnerMoveIs(u32 battlerAtkPartner, u32 partnerMove, u32 moveCheck);
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, u32 move, u32 partnerMove);
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMove);
+bool32 PartnerMoveActivatesSleepClause(u32 move);
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move);
// party logic
diff --git a/include/battle_anim.h b/include/battle_anim.h
index 96ba0c52ab..ef933a1c08 100644
--- a/include/battle_anim.h
+++ b/include/battle_anim.h
@@ -464,6 +464,7 @@ void AnimElectricPuff(struct Sprite *sprite);
void AnimSparkElectricityFlashing(struct Sprite *sprite);
void AnimGrowingShockWaveOrb(struct Sprite *sprite);
void AnimElectricity(struct Sprite *);
+void AnimTask_VoltSwitch(struct Sprite* sprite);
extern const union AffineAnimCmd *const gAffineAnims_GrowingElectricOrb[];
extern const union AffineAnimCmd *const gAffineAnims_FlashingSpark[];
extern const union AnimCmd *const gAnims_ThunderboltOrb[];
diff --git a/include/battle_gfx_sfx_util.h b/include/battle_gfx_sfx_util.h
index 968f8d48dc..dd85b2658c 100644
--- a/include/battle_gfx_sfx_util.h
+++ b/include/battle_gfx_sfx_util.h
@@ -6,6 +6,7 @@ void FreeBattleSpritesData(void);
u16 ChooseMoveAndTargetInBattlePalace(u32 battler);
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite);
void SpriteCB_TrainerSlideIn(struct Sprite *sprite);
+void SpriteCB_TrainerSpawn(struct Sprite *sprite);
void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status);
bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId, u16 argument);
void InitAndLaunchSpecialAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId);
diff --git a/include/battle_main.h b/include/battle_main.h
index 7e3206c554..e8368f82d6 100644
--- a/include/battle_main.h
+++ b/include/battle_main.h
@@ -72,7 +72,7 @@ void SwapTurnOrder(u8 id1, u8 id2);
u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect);
u32 GetBattlerTotalSpeedStat(u32 battler);
s8 GetChosenMovePriority(u32 battlerId);
-s8 GetMovePriority(u32 battlerId, u16 move);
+s8 GetBattleMovePriority(u32 battlerId, u16 move);
s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMoves, u32 ability1, u32 ability2,
u32 holdEffectBattler1, u32 holdEffectBattler2, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenMoves);
diff --git a/include/battle_message.h b/include/battle_message.h
index 0b4570e389..914e97d5d6 100644
--- a/include/battle_message.h
+++ b/include/battle_message.h
@@ -10,6 +10,7 @@
max(POKEMON_NAME_LENGTH + 1, \
ABILITY_NAME_LENGTH + 1)))
#define BATTLE_MSG_MAX_WIDTH 208
+#define BATTLE_MSG_MAX_LINES 2
// for 0xFD
#define B_TXT_BUFF1 0x0
@@ -72,8 +73,8 @@
#define B_TXT_DEF_NAME 0x39
#define B_TXT_DEF_TEAM1 0x3A // Your/The opposing
#define B_TXT_DEF_TEAM2 0x3B // your/the opposing
-// #define B_TXT_SELECTION_NAME 0x3C - removed
-// #define B_TXT_SELECTION_NAME2 0x3D no Illusion check - removed
+#define B_TXT_DEF_PARTNER_NAME 0x3C
+// #define B_UNUSED_0x3D 0x3D
#define B_TXT_ATK_NAME_WITH_PREFIX2 0x3E //lowercase
#define B_TXT_DEF_NAME_WITH_PREFIX2 0x3F //lowercase
#define B_TXT_EFF_NAME_WITH_PREFIX2 0x40 //lowercase
diff --git a/include/battle_scripts.h b/include/battle_scripts.h
index 879c2f12c3..f4d97a5f66 100644
--- a/include/battle_scripts.h
+++ b/include/battle_scripts.h
@@ -46,6 +46,8 @@ extern const u8 BattleScript_PrintFailedToRunString[];
extern const u8 BattleScript_PrintCantEscapeFromBattle[];
extern const u8 BattleScript_PrintFullBox[];
extern const u8 BattleScript_ActionSwitch[];
+extern const u8 BattleScript_DoSwitchOut[];
+extern const u8 BattleScript_MoveSwitchOpenPartyScreen[];
extern const u8 BattleScript_Pausex20[];
extern const u8 BattleScript_LevelUp[];
extern const u8 BattleScript_RainContinuesOrEnds[];
@@ -65,7 +67,9 @@ extern const u8 BattleScript_OverworldTerrain[];
extern const u8 BattleScript_SideStatusWoreOff[];
extern const u8 BattleScript_SafeguardProtected[];
extern const u8 BattleScript_SafeguardEnds[];
-extern const u8 BattleScript_LeechSeedTurnDrain[];
+extern const u8 BattleScript_LeechSeedTurnDrainLiquidOoze[];
+extern const u8 BattleScript_LeechSeedTurnDrainHealBlock[];
+extern const u8 BattleScript_LeechSeedTurnDrainRecovery[];
extern const u8 BattleScript_BideStoringEnergy[];
extern const u8 BattleScript_BideAttack[];
extern const u8 BattleScript_BideNoEnergyToAttack[];
@@ -356,7 +360,6 @@ extern const u8 BattleScript_SelectingNotAllowedMoveThroatChopInPalace[];
extern const u8 BattleScript_ThroatChopEndTurn[];
extern const u8 BattleScript_GemActivates[];
extern const u8 BattleScript_BerryReduceDmg[];
-extern const u8 BattleScript_PrintBerryReduceString[];
extern const u8 BattleScript_WeaknessPolicy[];
extern const u8 BattleScript_TargetItemStatRaise[];
extern const u8 BattleScript_RockyHelmetActivates[];
@@ -438,7 +441,6 @@ extern const u8 BattleScript_AttackWeakenedByStrongWinds[];
extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[];
extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
extern const u8 BattleScript_PrimalReversion[];
-extern const u8 BattleScript_PrimalReversionRestoreAttacker[];
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace[];
@@ -516,8 +518,10 @@ extern const u8 BattleScript_AromaVeilProtectsRet[];
extern const u8 BattleScript_LowerAtkSpAtk[];
extern const u8 BattleScript_Terastallization[];
extern const u8 BattleScript_BoosterEnergyEnd2[];
+extern const u8 BattleScript_BoosterEnergyRet[];
extern const u8 BattleScript_TeraShellDistortingTypeMatchups[];
extern const u8 BattleScript_TeraFormChange[];
+extern const u8 BattleScript_SleepClausePreventsEnd[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];
@@ -561,6 +565,7 @@ extern const u8 BattleScript_MoveBlockedByDynamax[];
// Battle move scripts
extern const u8 BattleScript_EffectSleep[];
extern const u8 BattleScript_EffectAbsorb[];
+extern const u8 BattleScript_EffectAbsorbLiquidOoze[];
extern const u8 BattleScript_EffectExplosion[];
extern const u8 BattleScript_EffectDreamEater[];
extern const u8 BattleScript_EffectMirrorMove[];
@@ -621,6 +626,9 @@ extern const u8 BattleScript_EffectMimic[];
extern const u8 BattleScript_EffectMetronome[];
extern const u8 BattleScript_EffectLeechSeed[];
extern const u8 BattleScript_EffectDoNothing[];
+extern const u8 BattleScript_EffectHoldHands[];
+extern const u8 BattleScript_EffectCelebrate[];
+extern const u8 BattleScript_EffectHappyHour[];
extern const u8 BattleScript_EffectDisable[];
extern const u8 BattleScript_EffectLevelDamage[];
extern const u8 BattleScript_EffectPsywave[];
@@ -800,18 +808,18 @@ extern const u8 BattleScript_EffectGeomancy[];
extern const u8 BattleScript_EffectFairyLock[];
extern const u8 BattleScript_EffectAllySwitch[];
extern const u8 BattleScript_EffectRelicSong[];
-extern const u8 BattleScript_EffectEerieSpell[];
+extern const u8 BattleScript_MoveEffectEerieSpell[];
extern const u8 BattleScript_EffectJungleHealing[];
extern const u8 BattleScript_EffectCoaching[];
extern const u8 BattleScript_EffectDecorate[];
extern const u8 BattleScript_EffectRecoilHP25[];
extern const u8 BattleScript_EffectStuffCheeks[];
-extern const u8 BattleScript_EffectGlitzyGlow[];
-extern const u8 BattleScript_EffectBaddyBad[];
-extern const u8 BattleScript_EffectSappySeed[];
-extern const u8 BattleScript_EffectFreezyFrost[];
+extern const u8 BattleScript_MoveEffectLightScreen[];
+extern const u8 BattleScript_MoveEffectReflect[];
+extern const u8 BattleScript_MoveEffectLeechSeed[];
+extern const u8 BattleScript_MoveEffectHaze[];
extern const u8 BattleScript_EffectSparklySwirl[];
-extern const u8 BattleScript_EffectPlasmaFists[];
+extern const u8 BattleScript_MoveEffectIonDeluge[];
extern const u8 BattleScript_EffectHyperspaceFury[];
extern const u8 BattleScript_EffectAuraWheel[];
extern const u8 BattleScript_EffectPhotonGeyser[];
@@ -834,7 +842,7 @@ extern const u8 BattleScript_EffectRevivalBlessing[];
extern const u8 BattleScript_EffectSnow[];
extern const u8 BattleScript_EffectTakeHeart[];
extern const u8 BattleScript_EffectCorrosiveGas[];
-extern const u8 BattleScript_EffectSaltCure[];
+extern const u8 BattleScript_MoveEffectSaltCure[];
extern const u8 BattleScript_EffectChillyReception[];
extern const u8 BattleScript_EffectMaxMove[];
extern const u8 BattleScript_EffectGlaiveRush[];
diff --git a/include/battle_transition.h b/include/battle_transition.h
index eba514b09f..8bc80dc642 100644
--- a/include/battle_transition.h
+++ b/include/battle_transition.h
@@ -11,6 +11,7 @@ void GetBg0TilesDst(u16 **tilemap, u16 **tileset);
extern const struct SpritePalette gSpritePalette_Pokeball;
enum {
+ MUGSHOT_COLOR_NONE,
MUGSHOT_COLOR_PURPLE,
MUGSHOT_COLOR_GREEN,
MUGSHOT_COLOR_PINK,
diff --git a/include/battle_util.h b/include/battle_util.h
index e2dd9ac826..46c491a853 100644
--- a/include/battle_util.h
+++ b/include/battle_util.h
@@ -1,6 +1,8 @@
#ifndef GUARD_BATTLE_UTIL_H
#define GUARD_BATTLE_UTIL_H
+#include "move.h"
+
#define MOVE_LIMITATION_ZEROMOVE (1 << 0)
#define MOVE_LIMITATION_PP (1 << 1)
#define MOVE_LIMITATION_DISABLED (1 << 2)
@@ -65,16 +67,20 @@ enum {
#define ABILITYEFFECT_WATER_SPORT 253 // Only used if B_SPORT_TURNS >= GEN_6
// For the first argument of ItemBattleEffects, to deteremine which block of item effects to try
-#define ITEMEFFECT_ON_SWITCH_IN 0
-#define ITEMEFFECT_NORMAL 1
-#define ITEMEFFECT_DUMMY 2 // Unused, empty
-#define ITEMEFFECT_MOVE_END 3
-#define ITEMEFFECT_KINGSROCK 4
-#define ITEMEFFECT_TARGET 5
-#define ITEMEFFECT_ORBS 6
-#define ITEMEFFECT_LIFEORB_SHELLBELL 7
-#define ITEMEFFECT_USE_LAST_ITEM 8 // move end effects for just the battler, not whole field
-#define ITEMEFFECT_STATS_CHANGED 9 // For White Herb and Eject Pack
+enum ItemEffect
+{
+ ITEMEFFECT_NONE,
+ ITEMEFFECT_ON_SWITCH_IN,
+ ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN,
+ ITEMEFFECT_NORMAL,
+ ITEMEFFECT_MOVE_END,
+ ITEMEFFECT_KINGSROCK,
+ ITEMEFFECT_TARGET,
+ ITEMEFFECT_ORBS,
+ ITEMEFFECT_LIFEORB_SHELLBELL,
+ ITEMEFFECT_USE_LAST_ITEM, // move end effects for just the battler, not whole field
+ ITEMEFFECT_STATS_CHANGED, // For White Herb and Eject Pack
+};
#define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))
@@ -96,31 +102,37 @@ struct TypePower
enum
{
CANCELLER_FLAGS,
+ CANCELLER_STANCE_CHANGE_1,
CANCELLER_SKY_DROP,
+ CANCELLER_RECHARGE,
CANCELLER_ASLEEP,
CANCELLER_FROZEN,
+ CANCELLER_OBEDIENCE,
CANCELLER_TRUANT,
- CANCELLER_RECHARGE,
CANCELLER_FLINCH,
+ CANCELLER_IN_LOVE,
CANCELLER_DISABLED,
- CANCELLER_GRAVITY,
CANCELLER_HEAL_BLOCKED,
+ CANCELLER_GRAVITY,
+ CANCELLER_THROAT_CHOP,
CANCELLER_TAUNTED,
CANCELLER_IMPRISONED,
CANCELLER_CONFUSED,
CANCELLER_PARALYSED,
- CANCELLER_IN_LOVE,
CANCELLER_BIDE,
CANCELLER_THAW,
+ CANCELLER_STANCE_CHANGE_2,
+ CANCELLER_WEATHER_PRIMAL,
+ CANCELLER_DYNAMAX_BLOCKED,
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
- CANCELLER_THROAT_CHOP,
+ CANCELLER_PROTEAN,
+ CANCELLER_PSYCHIC_TERRAIN,
CANCELLER_EXPLODING_DAMP,
CANCELLER_MULTIHIT_MOVES,
CANCELLER_Z_MOVES,
+ CANCELLER_MULTI_TARGET_MOVES,
CANCELLER_END,
- CANCELLER_PSYCHIC_TERRAIN,
- CANCELLER_END2,
};
enum {
@@ -146,6 +158,12 @@ struct DamageCalculationData
u32 padding:2;
};
+enum SleepClauseBlock
+{
+ NOT_BLOCKED_BY_SLEEP_CLAUSE,
+ BLOCKED_BY_SLEEP_CLAUSE,
+};
+
void HandleAction_ThrowBall(void);
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
void HandleAction_UseMove(void);
@@ -185,9 +203,8 @@ u8 DoBattlerEndTurnEffects(void);
bool32 HandleWishPerishSongOnTurnEnd(void);
bool32 HandleFaintedMonActions(void);
void TryClearRageAndFuryCutter(void);
-u8 AtkCanceller_UnableToUseMove(u32 moveType);
+u32 AtkCanceller_MoveSuccessOrder(void);
void SetAtkCancellerForCalledMove(void);
-u8 AtkCanceller_UnableToUseMove2(void);
bool32 HasNoMonsToSwitch(u32 battler, u8 r1, u8 r2);
bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility);
u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef);
@@ -207,11 +224,11 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move);
bool32 CanBattlerEscape(u32 battler); // no ability check
void BattleScriptExecute(const u8 *BS_ptr);
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
-u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn);
+u32 ItemBattleEffects(enum ItemEffect, u32 battler, bool32 moveTurn);
void ClearVariousBattlerFlags(u32 battler);
void HandleAction_RunBattleScript(void);
u32 SetRandomTarget(u32 battler);
-u32 GetMoveTarget(u16 move, u8 setTarget);
+u32 GetBattleMoveTarget(u16 move, u8 setTarget);
u8 GetAttackerObedienceForAction();
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
u32 GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating);
@@ -230,7 +247,7 @@ s32 CalculateMoveDamageVars(struct DamageCalculationData *damageCalcData, u32 fi
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 defAbility, bool32 recordAbilities);
uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
uq4_12_t GetTypeModifier(u32 atkType, u32 defType);
-uq4_12_t GetTypeEffectiveness(struct Pokemon *mon, u8 moveType);
+uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, u8 moveType);
s32 GetStealthHazardDamage(u8 hazardType, u32 battler);
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
bool32 CanMegaEvolve(u32 battler);
@@ -264,7 +281,7 @@ void TryRestoreHeldItems(void);
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
void TrySaveExchangedItem(u32 battler, u16 stolenItem);
bool32 IsPartnerMonFromSameTrainer(u32 battler);
-u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
+u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemEffect caseID);
bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind);
@@ -285,12 +302,12 @@ bool32 IsGen6ExpShareEnabled(void);
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect);
bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance);
bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect);
-bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
+bool32 IsMoveEffectRemoveSpeciesType(u32 move, u32 moveEffect, u32 argument);
bool32 MoveHasChargeTurnAdditionalEffect(u32 move);
bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef);
bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef);
-bool32 CanBeSlept(u32 battler, u32 ability);
+bool32 CanBeSlept(u32 battler, u32 ability, enum SleepClauseBlock isBlockedBySleepClause);
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 CanBeBurned(u32 battler, u32 ability);
bool32 CanBeParalyzed(u32 battler, u32 ability);
@@ -299,6 +316,7 @@ bool32 CanGetFrostbite(u32 battler);
bool32 CanBeConfused(u32 battler);
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
u32 GetBattlerAffectionHearts(u32 battler);
+void TryToRevertMimicryAndFlags(void);
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
bool32 ChangeTypeBasedOnTerrain(u32 battler);
void RemoveConfusionStatus(u32 battler);
@@ -307,10 +325,18 @@ bool32 AreBattlersOfOppositeGender(u32 battler1, u32 battler2);
bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2);
u32 CalcSecondaryEffectChance(u32 battler, u32 battlerAbility, const struct AdditionalEffect *additionalEffect);
bool32 MoveEffectIsGuaranteed(u32 battler, u32 battlerAbility, const struct AdditionalEffect *additionalEffect);
-u8 GetBattlerType(u32 battler, u8 typeIndex, bool32 ignoreTera);
+void GetBattlerTypes(u32 battler, bool32 ignoreTera, u32 types[static 3]);
+u32 GetBattlerType(u32 battler, u32 typeIndex, bool32 ignoreTera);
bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon);
bool8 IsMonBannedFromSkyBattles(u16 species);
void RemoveBattlerType(u32 battler, u8 type);
-u32 GetMoveType(u32 move);
+u32 GetBattleMoveType(u32 move);
+void TryActivateSleepClause(u32 battler, u32 indexInParty);
+void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty);
+bool32 IsSleepClauseActiveForSide(u32 battlerSide);
+bool32 IsSleepClauseEnabled();
+void ClearDamageCalcResults(void);
+u32 DoesDestinyBondFail(u32 battler);
+bool32 IsMoveEffectBlockedByTarget(u32 ability);
#endif // GUARD_BATTLE_UTIL_H
diff --git a/include/config/battle.h b/include/config/battle.h
index 7467bd47f1..117e0cc31c 100644
--- a/include/config/battle.h
+++ b/include/config/battle.h
@@ -6,7 +6,7 @@
#define B_CRIT_MULTIPLIER GEN_LATEST // In Gen6+, critical hits multiply damage by 1.5 instead of 2.
#define B_PARALYSIS_SPEED GEN_LATEST // In Gen7+, Speed is decreased by 50% instead of 75%.
#define B_CONFUSION_SELF_DMG_CHANCE GEN_LATEST // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%.
-#define B_MULTI_HIT_CHANCE GEN_LATEST // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values.
+#define B_MULTI_HIT_CHANCE GEN_LATEST // In Gen5+, multi-hit moves have different %. See SetRandomMultiHitCounter for values.
#define B_WHITEOUT_MONEY GEN_LATEST // In Gen4+, the amount of money lost by losing a battle is determined by the amount of badges earned. Previously, it would cut the current money by half. (While this change was also in FRLG, for the sake of simplicity, setting this to GEN_3 will result in RSE behavior.)
#define B_LIGHT_BALL_ATTACK_BOOST GEN_LATEST // In Gen4+, Light Ball doubles the power of physical moves in addition to special moves.
#define B_SANDSTORM_SPDEF_BOOST GEN_LATEST // In Gen4+, Sandstorm weather multiplies the Sp. Defense of Rock-type Pokémon by x1.5.
@@ -125,6 +125,8 @@
#define B_POWDER_RAIN GEN_LATEST // In Gen7+, Powder doesn't damage the user of a Fire type move in heavy rain.
#define B_AFTER_YOU_TURN_ORDER GEN_LATEST // In Gen8+, After You doesn't fail if the turn order wouldn't change after use.
#define B_QUASH_TURN_ORDER GEN_LATEST // In Gen8+, Quash-affected battlers move according to speed order. Before Gen8, Quash-affected battlers move in the order they were affected by Quash.
+#define B_DESTINY_BOND_FAIL GEN_LATEST // In Gen7+, Destiny Bond fails if used repeatedly.
+#define B_PURSUIT_TARGET GEN_LATEST // In Gen4+, Pursuit attacks a switching opponent even if they weren't targeting them. Before Gen4, Pursuit only attacks a switching opponent that it originally targeted.
// Ability settings
#define B_ABILITY_WEATHER GEN_LATEST // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability.
@@ -154,6 +156,8 @@
#define B_ABILITY_TRIGGER_CHANCE GEN_LATEST // In Gen3, Shed Skin, Cute Charm, Flame Body, Static and Poison Point have a 1/3 chance to trigger. In Gen 4+ it's 30%.
// In Gen3, Effect Spore has a 10% chance to sleep, poison or paralyze, with an equal chance.
// In Gen4, it's 30%. In Gen5+ it has 11% to sleep, 9% chance to poison and 10% chance to paralyze.
+#define B_PICKUP_WILD GEN_LATEST // In Gen9+, Pickup allows its user to pickup its own used item at the end of the turn in wild battles.
+#define B_MAGIC_GUARD GEN_LATEST // In Gen4+, Magic Guard ignores immobilization caused by paralysis
// Item settings
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore HP activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.
@@ -163,6 +167,7 @@
#define B_MENTAL_HERB GEN_LATEST // In Gen5+, the Mental Herb cures Taunt, Encore, Torment, Heal Block, and Disable in addition to Infatuation from before.
#define B_TRAINERS_KNOCK_OFF_ITEMS TRUE // If TRUE, trainers can steal/swap your items (non-berries are restored after battle). In vanilla games trainers cannot steal items.
#define B_RETURN_STOLEN_NPC_ITEMS GEN_LATEST // In Gen5+, Thief and Covet no longer steal items from NPCs.
+#define B_STEAL_WILD_ITEMS GEN_LATEST // In Gen9, Thief and Covet steal a wild pokemon's item and send it to the bag. Before Gen9, the stolen item would be held by the Thief/Covet user.
#define B_RESTORE_HELD_BATTLE_ITEMS GEN_LATEST // In Gen9, all non-berry items are restored after battle.
#define B_SOUL_DEW_BOOST GEN_LATEST // In Gens3-6, Soul Dew boosts Latis' Sp. Atk and Sp. Def. In Gen7+ it boosts the power of their Psychic and Dragon type moves instead.
#define B_NET_BALL_MODIFIER GEN_LATEST // In Gen7+, Net Ball's catch multiplier is x5 instead of x3.
@@ -177,6 +182,7 @@
#define B_DREAM_BALL_MODIFIER GEN_LATEST // In Gen8+, Dream Ball's catch multiplier is x4 when the target is asleep or has the ability Comatose.
#define B_SPORT_BALL_MODIFIER GEN_LATEST // In Gen8+, Sport Ball's catch multiplier was reduced from x1.5 to x1.
#define B_SAFARI_BALL_MODIFIER GEN_LATEST // In Gen8+, Safari Ball's catch multiplier was reduced from x1.5 to x1.
+#define B_FRIEND_BALL_MODIFIER GEN_LATEST // In Gen8+, Friend Ball's friendship boost was reduced from 200 to 150.
#define B_SERENE_GRACE_BOOST GEN_LATEST // In Gen5+, Serene Grace boosts the added flinch chance of King's Rock and Razor Fang.
// Flag settings
@@ -192,6 +198,7 @@
#define B_FLAG_DYNAMAX_BATTLE 0 // If this flag is set, the ability to Dynamax in battle is enabled for all trainers.
#define B_FLAG_TERA_ORB_CHARGED 0 // If this flag is set, the Tera Orb is charged. It is automatically set upon healing and cleared upon Terastallizing once configured.
#define B_FLAG_TERA_ORB_NO_COST 0 // If this flag is set, the Tera Orb does not use up its charge upon Terastallization. In S/V, this occurs after an event with Terapagos.
+#define B_FLAG_SLEEP_CLAUSE 0 // If this flag is set, sleep clause is enabled; if the player / AI has already put a Pokémon on the opponent's side to sleep and it is still sleeping, another one can't be put to sleep. AI requires AI_FLAG_CHECK_BAD_MOVE to understand.
// Var Settings
// To use the following features in scripting, replace the 0s with the var ID you're assigning it to.
@@ -219,10 +226,12 @@
#define B_SECRET_POWER_ANIMATION GEN_LATEST // Secret Power's animations change depending on terrain and generation.
#define B_NATURE_POWER_MOVES GEN_LATEST // Nature Power calls different moves depending on terrain and generation. See sNaturePowerMoves.
#define B_CAMOUFLAGE_TYPES GEN_LATEST // Camouflage changes the user to different types depending on terrain and generation. See sTerrainToType.
+#define B_NEW_TERRAIN_BACKGROUNDS FALSE // If set to TRUE, uses new terrain backgrounds for Electric, Misty, Grassy and Psychic Terrain.
// Interface settings
#define B_ABILITY_POP_UP TRUE // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle.
-#define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end.
+#define B_FAST_INTRO_PKMN_TEXT TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end.
+#define B_FAST_INTRO_NO_SLIDE FALSE // If set to TRUE, the slide animation that happens at the beginning of the battle is skipped.
#define B_FAST_HP_DRAIN TRUE // If set to TRUE, HP bars will move faster.
#define B_FAST_EXP_GROW TRUE // If set to TRUE, EXP bars will move faster.
#define B_SHOW_TARGETS TRUE // If set to TRUE, all available targets, for moves hitting 2 or 3 Pokémon, will be shown before selecting a move.
@@ -255,6 +264,7 @@
#define B_OVERWORLD_FOG GEN_LATEST // In Gen8+, overworld Fog summons Misty Terrain in battle. In Gen4 only, overworld Fog summons the unique fog weather condition in battle.
#define B_TOXIC_REVERSAL GEN_LATEST // In Gen5+, bad poison will change to regular poison at the end of battles.
#define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball.
+#define B_SLEEP_CLAUSE FALSE // Enables Sleep Clause all the time in every case, overriding B_FLAG_SLEEP_CLAUSE. Use that for modularity.
// Animation Settings
#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle.
diff --git a/include/config/pokemon.h b/include/config/pokemon.h
index 23015614c0..0b5d3828ad 100644
--- a/include/config/pokemon.h
+++ b/include/config/pokemon.h
@@ -17,6 +17,7 @@
// GEN_1/2/3/4/5/6/7: Yellow, Crystal, RSE, HGSS, B2W2, ORAS, USUM learnsets respectively.
// GEN_8: Use the following priority: BDSP for Gen1-4 Pokémon, then LA for species introduced in that game, then SwSh for species present in those games. Otherwise, use GEN_7.
// GEN_9: SV For species present in those games. Otherwise use GEN_8.
+#define P_EVOLUTION_LEVEL_1_LEARN GEN_LATEST // In Gen 8+, Pokémon evolving while at level 1 do not get the chance to learn their level 1 moves, while before they did.
// Evolution settings
#define P_FRIENDSHIP_EVO_THRESHOLD GEN_LATEST // Since Gen 8, Pokémon that evolve by friendship evolve at or above 160 friendship instead of 220.
@@ -55,7 +56,7 @@
#define P_SHOW_TERA_TYPE GEN_8 // Since Gen 9, the Tera Type is shown on the summary screen.
#define P_TM_LITERACY GEN_LATEST // Since Gen 6, TM illiterate Pokémon can learn TMs that teach moves that are in their level-up learnsets.
#define P_CAN_FORGET_HIDDEN_MOVE FALSE // If TRUE, Pokémon can forget any move, even if it is a Hidden Move.
-#define P_EGG_CYCLE_LENGTH GEN_LATEST // Since Gen 8, egg cycles take half as many steps as before.
+#define P_EGG_CYCLE_LENGTH GEN_LATEST // Since Gen 8, egg cycles take half as many steps as before. Previous Gens have some varied step counts around 255.
#define P_ONLY_OBTAINABLE_SHINIES FALSE // If TRUE, Pokémon encountered in the Battle Pyramid won't be shiny.
#define P_NO_SHINIES_WITHOUT_POKEBALLS FALSE // If TRUE, Pokémon encountered when the player is out of Poké Balls won't be shiny
#define P_SHOW_DYNAMIC_TYPES FALSE // If TRUE, all moves with dynamic type changes will be reflected as their current type in battle/summary screens instead of just select ones like in vanilla.
diff --git a/include/config/test.h b/include/config/test.h
index 708c2ca581..cce97484df 100644
--- a/include/config/test.h
+++ b/include/config/test.h
@@ -1129,4 +1129,8 @@
#undef P_FAMILY_PECHARUNT
#define P_FAMILY_PECHARUNT TRUE
+// Flags
+#undef B_FLAG_SLEEP_CLAUSE
+#define B_FLAG_SLEEP_CLAUSE FLAG_SPECIAL_FLAG_UNUSED_0x4003
+
#endif // GUARD_CONFIG_TEST_H
diff --git a/include/constants/battle.h b/include/constants/battle.h
index 560448159a..1685b0e582 100644
--- a/include/constants/battle.h
+++ b/include/constants/battle.h
@@ -121,6 +121,8 @@
#define STATUS1_PSN_ANY (STATUS1_POISON | STATUS1_TOXIC_POISON)
#define STATUS1_ANY (STATUS1_SLEEP | STATUS1_POISON | STATUS1_BURN | STATUS1_FREEZE | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE)
+#define STATUS1_REFRESH (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE)
+
// Volatile status ailments
// These are removed after exiting the battle or switching out
#define STATUS2_CONFUSION (1 << 0 | 1 << 1 | 1 << 2)
@@ -264,7 +266,6 @@
#define STATUS_FIELD_PSYCHIC_TERRAIN (1 << 9)
#define STATUS_FIELD_ION_DELUGE (1 << 10)
#define STATUS_FIELD_FAIRY_LOCK (1 << 11)
-#define STATUS_FIELD_TERRAIN_PERMANENT (1 << 12) // Overworld thunderstorm generates electric terrain
#define STATUS_FIELD_TERRAIN_ANY (STATUS_FIELD_GRASSY_TERRAIN | STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_PSYCHIC_TERRAIN)
@@ -329,7 +330,11 @@
#define MOVE_EFFECT_TOXIC 6
#define MOVE_EFFECT_FROSTBITE 7
#define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_FROSTBITE // All above move effects apply primary status
-#define MOVE_EFFECT_FREEZE_OR_FROSTBITE (B_USE_FROSTBITE == TRUE ? MOVE_EFFECT_FROSTBITE : MOVE_EFFECT_FREEZE)
+#if B_USE_FROSTBITE == TRUE
+#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FROSTBITE
+#else
+#define MOVE_EFFECT_FREEZE_OR_FROSTBITE MOVE_EFFECT_FREEZE
+#endif
#define MOVE_EFFECT_CONFUSION 8
#define MOVE_EFFECT_FLINCH 9
#define MOVE_EFFECT_TRI_ATTACK 10
@@ -403,8 +408,16 @@
#define MOVE_EFFECT_PSYCHIC_NOISE 78
#define MOVE_EFFECT_TERA_BLAST 79
#define MOVE_EFFECT_ORDER_UP 80
+#define MOVE_EFFECT_ION_DELUGE 81
+#define MOVE_EFFECT_AROMATHERAPY 82 // No functionality yet
+#define MOVE_EFFECT_HAZE 83
+#define MOVE_EFFECT_LEECH_SEED 84
+#define MOVE_EFFECT_REFLECT 85
+#define MOVE_EFFECT_LIGHT_SCREEN 86
+#define MOVE_EFFECT_SALT_CURE 87
+#define MOVE_EFFECT_EERIE_SPELL 88
-#define NUM_MOVE_EFFECTS 81
+#define NUM_MOVE_EFFECTS 89
#define MOVE_EFFECT_AFFECTS_USER 0x2000
#define MOVE_EFFECT_CERTAIN 0x4000
@@ -505,9 +518,9 @@
#define MOVE_TARGET_FOES_AND_ALLY (1 << 5)
#define MOVE_TARGET_OPPONENTS_FIELD (1 << 6)
#define MOVE_TARGET_ALLY (1 << 7)
-#define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER)
+#define MOVE_TARGET_ALL_BATTLERS ((1 << 8) | MOVE_TARGET_USER) // No functionality for status moves
-// For the second argument of GetMoveTarget, when no target override is needed
+// For the second argument of GetBattleMoveTarget, when no target override is needed
#define NO_TARGET_OVERRIDE 0
// Constants for Parental Bond
@@ -525,15 +538,24 @@
// Constants for B_VAR_STARTING_STATUS
// Timer value controlled by B_VAR_STARTING_STATUS_TIMER
-#define STARTING_STATUS_NONE 0
-#define STARTING_STATUS_ELECTRIC_TERRAIN 1
-#define STARTING_STATUS_MISTY_TERRAIN 2
-#define STARTING_STATUS_GRASSY_TERRAIN 3
-#define STARTING_STATUS_PSYCHIC_TERRAIN 4
-#define STARTING_STATUS_TRICK_ROOM 5
-#define STARTING_STATUS_MAGIC_ROOM 6
-#define STARTING_STATUS_WONDER_ROOM 7
-#define STARTING_STATUS_TAILWIND_PLAYER 8
-#define STARTING_STATUS_TAILWIND_OPPONENT 9
+enum StartingStatus
+{
+ STARTING_STATUS_NONE,
+ STARTING_STATUS_ELECTRIC_TERRAIN,
+ STARTING_STATUS_MISTY_TERRAIN,
+ STARTING_STATUS_GRASSY_TERRAIN,
+ STARTING_STATUS_PSYCHIC_TERRAIN,
+ STARTING_STATUS_TRICK_ROOM,
+ STARTING_STATUS_MAGIC_ROOM,
+ STARTING_STATUS_WONDER_ROOM,
+ STARTING_STATUS_TAILWIND_PLAYER,
+ STARTING_STATUS_TAILWIND_OPPONENT,
+ STARTING_STATUS_RAINBOW_PLAYER,
+ STARTING_STATUS_RAINBOW_OPPONENT,
+ STARTING_STATUS_SEA_OF_FIRE_PLAYER,
+ STARTING_STATUS_SEA_OF_FIRE_OPPONENT,
+ STARTING_STATUS_SWAMP_PLAYER,
+ STARTING_STATUS_SWAMP_OPPONENT,
+};
#endif // GUARD_CONSTANTS_BATTLE_H
diff --git a/include/constants/battle_ai.h b/include/constants/battle_ai.h
index df6069ead9..ecde1e8668 100644
--- a/include/constants/battle_ai.h
+++ b/include/constants/battle_ai.h
@@ -26,35 +26,36 @@
// AI Flags. Most run specific functions to update score, new flags are used for internal logic in other scripts
// See docs/ai_flags.md for more details.
-#define AI_FLAG_CHECK_BAD_MOVE (1 << 0) // AI will avoid using moves that are likely to fail or be ineffective in the current situation.
-#define AI_FLAG_TRY_TO_FAINT (1 << 1) // AI will prioritize KOing the player's mon if able.
-#define AI_FLAG_CHECK_VIABILITY (1 << 2) // AI damaging moves and move effects to determine the best available move in the current situation.
+#define AI_FLAG_CHECK_BAD_MOVE (1 << 0) // AI will avoid using moves that are likely to fail or be ineffective in the current situation.
+#define AI_FLAG_TRY_TO_FAINT (1 << 1) // AI will prioritize KOing the player's mon if able.
+#define AI_FLAG_CHECK_VIABILITY (1 << 2) // AI damaging moves and move effects to determine the best available move in the current situation.
#define AI_FLAG_FORCE_SETUP_FIRST_TURN (1 << 3) // AI will prioritize using setup moves on the first turn at the expensve of all else. AI_FLAG_CHECK_VIABILITY will instead do this when the AI determines it makes sense.
-#define AI_FLAG_RISKY (1 << 4) // AI will generally behave more recklessly, prioritizing damage over accuracy, explosions, etc.
-#define AI_FLAG_PREFER_STRONGEST_MOVE (1 << 5) // AI adds score bonus to any move the AI has that either OHKOs or 2HKOs the player.
-#define AI_FLAG_PREFER_BATON_PASS (1 << 6) // AI prefers raising its own stats and setting for / using Baton Pass.
-#define AI_FLAG_DOUBLE_BATTLE (1 << 7) // Automatically set for double battles, handles AI behaviour with partner.
-#define AI_FLAG_HP_AWARE (1 << 8) // AI will favour certain move effects based on how much remaining HP it and the player's mon have.
-#define AI_FLAG_POWERFUL_STATUS (1 << 9) // AI prefers moves that set up field effects or side statuses, even if the user can faint the target.
+#define AI_FLAG_RISKY (1 << 4) // AI will generally behave more recklessly, prioritizing damage over accuracy, explosions, etc.
+#define AI_FLAG_PREFER_STRONGEST_MOVE (1 << 5) // AI adds score bonus to any move the AI has that either OHKOs or 2HKOs the player.
+#define AI_FLAG_PREFER_BATON_PASS (1 << 6) // AI prefers raising its own stats and setting for / using Baton Pass.
+#define AI_FLAG_DOUBLE_BATTLE (1 << 7) // Automatically set for double battles, handles AI behaviour with partner.
+#define AI_FLAG_HP_AWARE (1 << 8) // AI will favour certain move effects based on how much remaining HP it and the player's mon have.
+#define AI_FLAG_POWERFUL_STATUS (1 << 9) // AI prefers moves that set up field effects or side statuses, even if the user can faint the target.
// New, Trainer Handicap Flags
-#define AI_FLAG_NEGATE_UNAWARE (1 << 10) // AI is NOT aware of negating effects like wonder room, mold breaker, etc.
-#define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc.
+#define AI_FLAG_NEGATE_UNAWARE (1 << 10) // AI is NOT aware of negating effects like wonder room, mold breaker, etc.
+#define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc.
// New, Trainer Strategy Flags
-#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves.
-#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished.
-#define AI_FLAG_SMART_SWITCHING (1 << 14) // AI includes a lot more switching checks. Automatically includes AI_FLAG_SMART_MON_CHOICES.
-#define AI_FLAG_ACE_POKEMON (1 << 15) // AI has an Ace Pokemon. The last Pokemon in the party will not be used until it's the last one remaining.
-#define AI_FLAG_OMNISCIENT (1 << 16) // AI has full knowledge of player moves, abilities, hold items.
-#define AI_FLAG_SMART_MON_CHOICES (1 << 17) // AI will make smarter decisions when choosing which mon to send out mid-battle and after a KO, which are separate decisions. Automatically included by AI_FLAG_SMART_SWITCHING.
-#define AI_FLAG_CONSERVATIVE (1 << 18) // AI assumes all moves will low roll damage.
-#define AI_FLAG_SEQUENCE_SWITCHING (1 << 19) // AI switches in mons in exactly party order, and never switches mid-battle.
-#define AI_FLAG_DOUBLE_ACE_POKEMON (1 << 20) // AI has *two* Ace Pokémon. The last two Pokémons in the party won't be used unless they're the last ones remaining. Goes well in battles where the trainer ID equals to twins, couples, etc.
+#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves.
+#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished.
+#define AI_FLAG_SMART_SWITCHING (1 << 14) // AI includes a lot more switching checks. Automatically includes AI_FLAG_SMART_MON_CHOICES.
+#define AI_FLAG_ACE_POKEMON (1 << 15) // AI has an Ace Pokemon. The last Pokemon in the party will not be used until it's the last one remaining.
+#define AI_FLAG_OMNISCIENT (1 << 16) // AI has full knowledge of player moves, abilities, hold items.
+#define AI_FLAG_SMART_MON_CHOICES (1 << 17) // AI will make smarter decisions when choosing which mon to send out mid-battle and after a KO, which are separate decisions. Automatically included by AI_FLAG_SMART_SWITCHING.
+#define AI_FLAG_CONSERVATIVE (1 << 18) // AI assumes all moves will low roll damage.
+#define AI_FLAG_SEQUENCE_SWITCHING (1 << 19) // AI switches in mons in exactly party order, and never switches mid-battle.
+#define AI_FLAG_DOUBLE_ACE_POKEMON (1 << 20) // AI has *two* Ace Pokémon. The last two Pokémons in the party won't be used unless they're the last ones remaining. Goes well in battles where the trainer ID equals to twins, couples, etc.
+#define AI_FLAG_WEIGH_ABILITY_PREDICTION (1 << 21) // AI will predict player's ability based on aiRating
-#define AI_FLAG_COUNT 21
+#define AI_FLAG_COUNT 22
// The following options are enough to have a basic/smart trainer. Any other addtion could make the trainer worse/better depending on the flag
#define AI_FLAG_BASIC_TRAINER (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY)
-#define AI_FLAG_SMART_TRAINER (AI_FLAG_BASIC_TRAINER | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES)
+#define AI_FLAG_SMART_TRAINER (AI_FLAG_BASIC_TRAINER | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_WEIGH_ABILITY_PREDICTION)
// 'other' ai logic flags
#define AI_FLAG_DYNAMIC_FUNC (1 << 28) // Create custom AI functions for specific battles via "setdynamicaifunc" cmd
diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h
index b1472d0280..df752bf496 100644
--- a/include/constants/battle_move_effects.h
+++ b/include/constants/battle_move_effects.h
@@ -67,6 +67,9 @@ enum {
EFFECT_METRONOME,
EFFECT_LEECH_SEED,
EFFECT_DO_NOTHING,
+ EFFECT_HOLD_HANDS,
+ EFFECT_CELEBRATE,
+ EFFECT_HAPPY_HOUR,
EFFECT_DISABLE,
EFFECT_LEVEL_DAMAGE,
EFFECT_PSYWAVE,
@@ -282,7 +285,6 @@ enum {
EFFECT_ALLY_SWITCH,
EFFECT_RELIC_SONG,
EFFECT_BODY_PRESS,
- EFFECT_EERIE_SPELL,
EFFECT_JUNGLE_HEALING,
EFFECT_COACHING,
EFFECT_LASH_OUT,
@@ -293,12 +295,7 @@ enum {
EFFECT_RECOIL_HP_25,
EFFECT_STUFF_CHEEKS,
EFFECT_GRAV_APPLE,
- EFFECT_GLITZY_GLOW,
- EFFECT_BADDY_BAD,
- EFFECT_SAPPY_SEED,
- EFFECT_FREEZY_FROST,
EFFECT_SPARKLY_SWIRL,
- EFFECT_PLASMA_FISTS,
EFFECT_HYPERSPACE_FURY,
EFFECT_AURA_WHEEL,
EFFECT_PHOTON_GEYSER,
@@ -331,7 +328,6 @@ enum {
EFFECT_COLLISION_COURSE,
EFFECT_CORROSIVE_GAS,
EFFECT_POPULATION_BOMB,
- EFFECT_SALT_CURE,
EFFECT_CHILLY_RECEPTION,
EFFECT_MAX_MOVE,
EFFECT_GLAIVE_RUSH,
diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h
index 6b162dc487..bd1c61ec09 100644
--- a/include/constants/battle_script_commands.h
+++ b/include/constants/battle_script_commands.h
@@ -3,7 +3,7 @@
// The following correspond to the struct members of BattleScripting by adding their offset
#define sPAINSPLIT_HP (gBattleScripting + 0x00) // painSplitHp
-#define sBIDE_DMG (gBattleScripting + 0x04) // bideDmg
+#define sUNUSED_0x04 (gBattleScripting + 0x04) // unused_0x04
#define sMULTIHIT_STRING (gBattleScripting + 0x08) // multihitString
#define sEXP_CATCH (gBattleScripting + 0x0E) // expOnCatch
#define sUNUSED (gBattleScripting + 0x0F) // unused
@@ -88,148 +88,147 @@
#define CMP_COMMON_BITS 4
#define CMP_NO_COMMON_BITS 5
-// Cmd_various
-#define VARIOUS_CANCEL_MULTI_TURN_MOVES 0
-#define VARIOUS_IS_RUNNING_IMPOSSIBLE 1
-#define VARIOUS_GET_MOVE_TARGET 2
-#define VARIOUS_GET_BATTLER_FAINTED 3
-#define VARIOUS_RESET_SWITCH_IN_ABILITY_BITS 4
-#define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 5
-#define VARIOUS_RESET_PLAYER_FAINTED 6
-#define VARIOUS_PALACE_FLAVOR_TEXT 7
-#define VARIOUS_ARENA_JUDGMENT_WINDOW 8
-#define VARIOUS_ARENA_OPPONENT_MON_LOST 9
-#define VARIOUS_ARENA_PLAYER_MON_LOST 10
-#define VARIOUS_ARENA_BOTH_MONS_LOST 11
-#define VARIOUS_EMIT_YESNOBOX 12
-#define VARIOUS_DRAW_ARENA_REF_TEXT_BOX 13
-#define VARIOUS_ERASE_ARENA_REF_TEXT_BOX 14
-#define VARIOUS_ARENA_JUDGMENT_STRING 15
-#define VARIOUS_ARENA_WAIT_STRING 16
-#define VARIOUS_WAIT_CRY 17
-#define VARIOUS_RETURN_OPPONENT_MON1 18
-#define VARIOUS_RETURN_OPPONENT_MON2 19
-#define VARIOUS_VOLUME_DOWN 20
-#define VARIOUS_VOLUME_UP 21
-#define VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT 22
-#define VARIOUS_PALACE_TRY_ESCAPE_STATUS 23
-#define VARIOUS_SET_TELEPORT_OUTCOME 24
-#define VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC 25
-#define VARIOUS_STAT_TEXT_BUFFER 26
-#define VARIOUS_SWITCHIN_ABILITIES 27
-#define VARIOUS_INSTANT_HP_DROP 28
-#define VARIOUS_CLEAR_STATUS 29
-#define VARIOUS_RESTORE_PP 30
-#define VARIOUS_TRY_ACTIVATE_MOXIE 31
-#define VARIOUS_TRY_ACTIVATE_FELL_STINGER 32
-#define VARIOUS_PLAY_MOVE_ANIMATION 33
-#define VARIOUS_SET_LUCKY_CHANT 34
-#define VARIOUS_SUCKER_PUNCH_CHECK 35
-#define VARIOUS_SET_SIMPLE_BEAM 36
-#define VARIOUS_TRY_ENTRAINMENT 37
-#define VARIOUS_SET_LAST_USED_ABILITY 38
-#define VARIOUS_INVERT_STAT_STAGES 39
-#define VARIOUS_TRY_ME_FIRST 40
-#define VARIOUS_JUMP_IF_BATTLE_END 41
-#define VARIOUS_TRY_ELECTRIFY 42
-#define VARIOUS_TRY_REFLECT_TYPE 43
-#define VARIOUS_TRY_SOAK 44
-#define VARIOUS_HANDLE_MEGA_EVO 45
-#define VARIOUS_TRY_LAST_RESORT 46
-#define VARIOUS_SET_ARG_TO_BATTLE_DAMAGE 47
-#define VARIOUS_TRY_AUTOTOMIZE 48
-#define VARIOUS_ABILITY_POPUP 49
-#define VARIOUS_JUMP_IF_TARGET_ALLY 50
-#define VARIOUS_TRY_SYNCHRONOISE 51
-#define VARIOUS_PSYCHO_SHIFT 52
-#define VARIOUS_CURE_STATUS 53
-#define VARIOUS_POWER_TRICK 54
-#define VARIOUS_AFTER_YOU 55
-#define VARIOUS_BESTOW 56
-#define VARIOUS_JUMP_IF_NOT_GROUNDED 57
-#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 58
-#define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 59
-#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 60
-#define VARIOUS_SET_AURORA_VEIL 61
-#define VARIOUS_TRY_THIRD_TYPE 62
-#define VARIOUS_ACUPRESSURE 63
-#define VARIOUS_SET_POWDER 64
-#define VARIOUS_SPECTRAL_THIEF 65
-#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 66
-#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 67
-#define VARIOUS_JUMP_IF_ROAR_FAILS 68
-#define VARIOUS_TRY_INSTRUCT 69
-#define VARIOUS_JUMP_IF_NOT_BERRY 70
-#define VARIOUS_TRACE_ABILITY 71
-#define VARIOUS_UPDATE_NICK 72
-#define VARIOUS_TRY_ILLUSION_OFF 73
-#define VARIOUS_SET_SPRITEIGNORE0HP 74
-#define VARIOUS_HANDLE_FORM_CHANGE 75
-#define VARIOUS_GET_STAT_VALUE 76
-#define VARIOUS_JUMP_IF_FULL_HP 77
-#define VARIOUS_LOSE_TYPE 78
-#define VARIOUS_TRY_ACTIVATE_SOULHEART 79
-#define VARIOUS_TRY_ACTIVATE_RECEIVER 80
-#define VARIOUS_TRY_ACTIVATE_BEAST_BOOST 81
-#define VARIOUS_TRY_FRISK 82
-#define VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED 83
-#define VARIOUS_TRY_FAIRY_LOCK 84
-#define VARIOUS_JUMP_IF_NO_ALLY 85
-#define VARIOUS_POISON_TYPE_IMMUNITY 86
-#define VARIOUS_JUMP_IF_HOLD_EFFECT 87
-#define VARIOUS_INFATUATE_WITH_BATTLER 88
-#define VARIOUS_SET_LAST_USED_ITEM 89
-#define VARIOUS_PARALYZE_TYPE_IMMUNITY 90
-#define VARIOUS_JUMP_IF_ABSENT 91
-#define VARIOUS_DESTROY_ABILITY_POPUP 92
-#define VARIOUS_TOTEM_BOOST 93
-#define VARIOUS_TRY_ACTIVATE_GRIM_NEIGH 94
-#define VARIOUS_MOVEEND_ITEM_EFFECTS 95
-#define VARIOUS_TERRAIN_SEED 96
-#define VARIOUS_MAKE_INVISIBLE 97
-#define VARIOUS_ROOM_SERVICE 98
-#define VARIOUS_EERIE_SPELL_PP_REDUCE 99
-#define VARIOUS_JUMP_IF_TEAM_HEALTHY 100
-#define VARIOUS_TRY_HEAL_QUARTER_HP 101
-#define VARIOUS_JUMP_IF_PRANKSTER_BLOCKED 102
-#define VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER 103
-#define VARIOUS_GET_ROTOTILLER_TARGETS 104
-#define VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED 105
-#define VARIOUS_TRY_ACTIVATE_BATTLE_BOND 106
-#define VARIOUS_CONSUME_BERRY 107
-#define VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL 108
-#define VARIOUS_JUMP_IF_SPECIES 109
-#define VARIOUS_UPDATE_ABILITY_POPUP 110
-#define VARIOUS_JUMP_IF_WEATHER_AFFECTED 111
-#define VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED 112
-#define VARIOUS_SET_ATTACKER_STICKY_WEB_USER 113
-#define VARIOUS_TRY_NO_RETREAT 114
-#define VARIOUS_CHECK_POLTERGEIST 115
-#define VARIOUS_CUT_1_3_HP_RAISE_STATS 116
-#define VARIOUS_TRY_END_NEUTRALIZING_GAS 117
-#define VARIOUS_JUMP_IF_UNDER_200 118
-#define VARIOUS_SET_SKY_DROP 119
-#define VARIOUS_CLEAR_SKY_DROP 120
-#define VARIOUS_SKY_DROP_YAWN 121
-#define VARIOUS_CURE_CERTAIN_STATUSES 122
-#define VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES 123
-#define VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY 124
-#define VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT 125
-#define VARIOUS_SAVE_BATTLER_ITEM 126
-#define VARIOUS_RESTORE_BATTLER_ITEM 127
-#define VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM 128
-#define VARIOUS_SWAP_SIDE_STATUSES 129
-#define VARIOUS_SWAP_STATS 130
+enum CmdVarious
+{
+ VARIOUS_CANCEL_MULTI_TURN_MOVES,
+ VARIOUS_IS_RUNNING_IMPOSSIBLE,
+ VARIOUS_GET_MOVE_TARGET,
+ VARIOUS_GET_BATTLER_FAINTED,
+ VARIOUS_RESET_SWITCH_IN_ABILITY_BITS,
+ VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP,
+ VARIOUS_RESET_PLAYER_FAINTED,
+ VARIOUS_PALACE_FLAVOR_TEXT,
+ VARIOUS_ARENA_JUDGMENT_WINDOW,
+ VARIOUS_ARENA_OPPONENT_MON_LOST,
+ VARIOUS_ARENA_PLAYER_MON_LOST,
+ VARIOUS_ARENA_BOTH_MONS_LOST,
+ VARIOUS_EMIT_YESNOBOX,
+ VARIOUS_DRAW_ARENA_REF_TEXT_BOX,
+ VARIOUS_ERASE_ARENA_REF_TEXT_BOX,
+ VARIOUS_ARENA_JUDGMENT_STRING,
+ VARIOUS_ARENA_WAIT_STRING,
+ VARIOUS_WAIT_CRY,
+ VARIOUS_RETURN_OPPONENT_MON1,
+ VARIOUS_RETURN_OPPONENT_MON2,
+ VARIOUS_VOLUME_DOWN,
+ VARIOUS_VOLUME_UP,
+ VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT,
+ VARIOUS_PALACE_TRY_ESCAPE_STATUS,
+ VARIOUS_SET_TELEPORT_OUTCOME,
+ VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC,
+ VARIOUS_STAT_TEXT_BUFFER,
+ VARIOUS_SWITCHIN_ABILITIES,
+ VARIOUS_INSTANT_HP_DROP,
+ VARIOUS_CLEAR_STATUS,
+ VARIOUS_RESTORE_PP,
+ VARIOUS_TRY_ACTIVATE_MOXIE,
+ VARIOUS_TRY_ACTIVATE_FELL_STINGER,
+ VARIOUS_PLAY_MOVE_ANIMATION,
+ VARIOUS_SET_LUCKY_CHANT,
+ VARIOUS_SUCKER_PUNCH_CHECK,
+ VARIOUS_SET_SIMPLE_BEAM,
+ VARIOUS_TRY_ENTRAINMENT,
+ VARIOUS_SET_LAST_USED_ABILITY,
+ VARIOUS_INVERT_STAT_STAGES,
+ VARIOUS_TRY_ME_FIRST,
+ VARIOUS_JUMP_IF_BATTLE_END,
+ VARIOUS_TRY_ELECTRIFY,
+ VARIOUS_TRY_SOAK,
+ VARIOUS_TRY_LAST_RESORT,
+ VARIOUS_SET_ARG_TO_BATTLE_DAMAGE,
+ VARIOUS_TRY_AUTOTOMIZE,
+ VARIOUS_ABILITY_POPUP,
+ VARIOUS_JUMP_IF_TARGET_ALLY,
+ VARIOUS_TRY_SYNCHRONOISE,
+ VARIOUS_PSYCHO_SHIFT,
+ VARIOUS_CURE_STATUS,
+ VARIOUS_POWER_TRICK,
+ VARIOUS_AFTER_YOU,
+ VARIOUS_BESTOW,
+ VARIOUS_JUMP_IF_NOT_GROUNDED,
+ VARIOUS_HANDLE_TRAINER_SLIDE_MSG,
+ VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF,
+ VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON,
+ VARIOUS_SET_AURORA_VEIL,
+ VARIOUS_TRY_THIRD_TYPE,
+ VARIOUS_ACUPRESSURE,
+ VARIOUS_SET_POWDER,
+ VARIOUS_SPECTRAL_THIEF,
+ VARIOUS_GRAVITY_ON_AIRBORNE_MONS,
+ VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS,
+ VARIOUS_JUMP_IF_ROAR_FAILS,
+ VARIOUS_TRY_INSTRUCT,
+ VARIOUS_JUMP_IF_NOT_BERRY,
+ VARIOUS_TRACE_ABILITY,
+ VARIOUS_UPDATE_NICK,
+ VARIOUS_TRY_ILLUSION_OFF,
+ VARIOUS_SET_SPRITEIGNORE0HP,
+ VARIOUS_HANDLE_FORM_CHANGE,
+ VARIOUS_GET_STAT_VALUE,
+ VARIOUS_JUMP_IF_FULL_HP,
+ VARIOUS_LOSE_TYPE,
+ VARIOUS_TRY_ACTIVATE_SOULHEART,
+ VARIOUS_TRY_ACTIVATE_RECEIVER,
+ VARIOUS_TRY_ACTIVATE_BEAST_BOOST,
+ VARIOUS_TRY_FRISK,
+ VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED,
+ VARIOUS_TRY_FAIRY_LOCK,
+ VARIOUS_JUMP_IF_NO_ALLY,
+ VARIOUS_POISON_TYPE_IMMUNITY,
+ VARIOUS_JUMP_IF_HOLD_EFFECT,
+ VARIOUS_INFATUATE_WITH_BATTLER,
+ VARIOUS_SET_LAST_USED_ITEM,
+ VARIOUS_PARALYZE_TYPE_IMMUNITY,
+ VARIOUS_JUMP_IF_ABSENT,
+ VARIOUS_DESTROY_ABILITY_POPUP,
+ VARIOUS_TOTEM_BOOST,
+ VARIOUS_TRY_ACTIVATE_GRIM_NEIGH,
+ VARIOUS_MOVEEND_ITEM_EFFECTS,
+ VARIOUS_TERRAIN_SEED,
+ VARIOUS_MAKE_INVISIBLE,
+ VARIOUS_ROOM_SERVICE,
+ VARIOUS_JUMP_IF_TEAM_HEALTHY,
+ VARIOUS_TRY_HEAL_QUARTER_HP,
+ VARIOUS_JUMP_IF_PRANKSTER_BLOCKED,
+ VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER,
+ VARIOUS_GET_ROTOTILLER_TARGETS,
+ VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED,
+ VARIOUS_TRY_ACTIVATE_BATTLE_BOND,
+ VARIOUS_CONSUME_BERRY,
+ VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL,
+ VARIOUS_JUMP_IF_SPECIES,
+ VARIOUS_UPDATE_ABILITY_POPUP,
+ VARIOUS_JUMP_IF_WEATHER_AFFECTED,
+ VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED,
+ VARIOUS_SET_ATTACKER_STICKY_WEB_USER,
+ VARIOUS_TRY_NO_RETREAT,
+ VARIOUS_CHECK_POLTERGEIST,
+ VARIOUS_CUT_1_3_HP_RAISE_STATS,
+ VARIOUS_TRY_END_NEUTRALIZING_GAS,
+ VARIOUS_JUMP_IF_UNDER_200,
+ VARIOUS_SET_SKY_DROP,
+ VARIOUS_CLEAR_SKY_DROP,
+ VARIOUS_SKY_DROP_YAWN,
+ VARIOUS_CURE_CERTAIN_STATUSES,
+ VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES,
+ VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY,
+ VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT,
+ VARIOUS_SAVE_BATTLER_ITEM,
+ VARIOUS_RESTORE_BATTLER_ITEM,
+ VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM,
+ VARIOUS_SWAP_SIDE_STATUSES,
+ VARIOUS_SWAP_STATS,
+};
// Cmd_manipulatedamage
-#define DMG_CHANGE_SIGN 0
-#define DMG_RECOIL_FROM_MISS 1
-#define DMG_DOUBLED 2
-#define DMG_1_8_TARGET_HP 3
-#define DMG_FULL_ATTACKER_HP 4
-#define DMG_CURR_ATTACKER_HP 5
-#define DMG_BIG_ROOT 6
-#define DMG_RECOIL_FROM_IMMUNE 7 // Used to calculate recoil for the Gen 4 version of Jump Kick
+#define DMG_CHANGE_SIGN 1
+#define DMG_RECOIL_FROM_MISS 2
+#define DMG_DOUBLED 3
+#define DMG_1_8_TARGET_HP 4
+#define DMG_FULL_ATTACKER_HP 5
+#define DMG_CURR_ATTACKER_HP 6
+#define DMG_BIG_ROOT 7
+#define DMG_RECOIL_FROM_IMMUNE 8 // Used to calculate recoil for the Gen 4 version of Jump Kick
// Cmd_jumpifcantswitch
#define SWITCH_IGNORE_ESCAPE_PREVENTION (1 << 7)
@@ -263,6 +262,7 @@ enum MoveEndEffects
{
MOVEEND_SUM_DAMAGE,
MOVEEND_PROTECT_LIKE_EFFECT,
+ MOVEEND_ABSORB,
MOVEEND_RAGE,
MOVEEND_SYNCHRONIZE_TARGET,
MOVEEND_ABILITIES,
@@ -288,9 +288,9 @@ enum MoveEndEffects
MOVEEND_RECOIL,
MOVEEND_ITEM_EFFECTS_ATTACKER,
MOVEEND_MAGICIAN, // Occurs after final multi-hit strike, and after other items/abilities would activate
+ MOVEEND_RED_CARD, // Red Card triggers before Eject Pack
MOVEEND_EJECT_ITEMS,
MOVEEND_WHITE_HERB,
- MOVEEND_RED_CARD,
MOVEEND_LIFEORB_SHELLBELL, // Includes shell bell, throat spray, etc
MOVEEND_CHANGED_ITEMS,
MOVEEND_PICKPOCKET,
@@ -301,6 +301,7 @@ enum MoveEndEffects
MOVEEND_SAME_MOVE_TURNS,
MOVEEND_SET_EVOLUTION_TRACKER,
MOVEEND_CLEAR_BITS,
+ MOVEEND_PURSUIT_NEXT_ACTION,
MOVEEND_COUNT,
};
diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h
index 563e70fc06..463a7fdd81 100644
--- a/include/constants/battle_string_ids.h
+++ b/include/constants/battle_string_ids.h
@@ -531,201 +531,204 @@
#define STRINGID_LASERFOCUS 529
#define STRINGID_GEMACTIVATES 530
#define STRINGID_BERRYDMGREDUCES 531
-#define STRINGID_TARGETATEITEM 532
-#define STRINGID_AIRBALLOONFLOAT 533
-#define STRINGID_AIRBALLOONPOP 534
-#define STRINGID_INCINERATEBURN 535
-#define STRINGID_BUGBITE 536
-#define STRINGID_ILLUSIONWOREOFF 537
-#define STRINGID_ATTACKERCUREDTARGETSTATUS 538
-#define STRINGID_ATTACKERLOSTFIRETYPE 539
-#define STRINGID_HEALERCURE 540
-#define STRINGID_SCRIPTINGABILITYSTATRAISE 541
-#define STRINGID_RECEIVERABILITYTAKEOVER 542
-#define STRINGID_PKNMABSORBINGPOWER 543
-#define STRINGID_NOONEWILLBEABLETORUNAWAY 544
-#define STRINGID_DESTINYKNOTACTIVATES 545
-#define STRINGID_CLOAKEDINAFREEZINGLIGHT 546
-#define STRINGID_CLEARAMULETWONTLOWERSTATS 547
-#define STRINGID_FERVENTWISHREACHED 548
-#define STRINGID_AIRLOCKACTIVATES 549
-#define STRINGID_PRESSUREENTERS 550
-#define STRINGID_DARKAURAENTERS 551
-#define STRINGID_FAIRYAURAENTERS 552
-#define STRINGID_AURABREAKENTERS 553
-#define STRINGID_COMATOSEENTERS 554
-#define STRINGID_SCREENCLEANERENTERS 555
-#define STRINGID_FETCHEDPOKEBALL 556
-#define STRINGID_BATTLERABILITYRAISEDSTAT 557
-#define STRINGID_ASANDSTORMKICKEDUP 558
-#define STRINGID_PKMNSWILLPERISHIN3TURNS 559
-#define STRINGID_ABILITYRAISEDSTATDRASTICALLY 560
-#define STRINGID_AURAFLAREDTOLIFE 561
-#define STRINGID_ASONEENTERS 562
-#define STRINGID_CURIOUSMEDICINEENTERS 563
-#define STRINGID_CANACTFASTERTHANKSTO 564
-#define STRINGID_MICLEBERRYACTIVATES 565
-#define STRINGID_PKMNSHOOKOFFTHETAUNT 566
-#define STRINGID_PKMNGOTOVERITSINFATUATION 567
-#define STRINGID_ITEMCANNOTBEREMOVED 568
-#define STRINGID_STICKYBARBTRANSFER 569
-#define STRINGID_PKMNBURNHEALED 570
-#define STRINGID_REDCARDACTIVATE 571
-#define STRINGID_EJECTBUTTONACTIVATE 572
-#define STRINGID_ATKGOTOVERINFATUATION 573
-#define STRINGID_TORMENTEDNOMORE 574
-#define STRINGID_HEALBLOCKEDNOMORE 575
-#define STRINGID_ATTACKERBECAMEFULLYCHARGED 576
-#define STRINGID_ATTACKERBECAMEASHSPECIES 577
-#define STRINGID_EXTREMELYHARSHSUNLIGHT 578
-#define STRINGID_EXTREMESUNLIGHTFADED 579
-#define STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT 580
-#define STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED 581
-#define STRINGID_HEAVYRAIN 582
-#define STRINGID_HEAVYRAINLIFTED 583
-#define STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN 584
-#define STRINGID_NORELIEFROMHEAVYRAIN 585
-#define STRINGID_MYSTERIOUSAIRCURRENT 586
-#define STRINGID_STRONGWINDSDISSIPATED 587
-#define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 588
-#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 589
-#define STRINGID_STUFFCHEEKSCANTSELECT 590
-#define STRINGID_PKMNREVERTEDTOPRIMAL 591
-#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 592
-#define STRINGID_BUTHOOPACANTUSEIT 593
-#define STRINGID_BROKETHROUGHPROTECTION 594
-#define STRINGID_ABILITYALLOWSONLYMOVE 595
-#define STRINGID_SWAPPEDABILITIES 596
-#define STRINGID_PASTELVEILPROTECTED 597
-#define STRINGID_PASTELVEILENTERS 598
-#define STRINGID_BATTLERTYPECHANGEDTO 599
-#define STRINGID_BOTHCANNOLONGERESCAPE 600
-#define STRINGID_CANTESCAPEDUETOUSEDMOVE 601
-#define STRINGID_PKMNBECAMEWEAKERTOFIRE 602
-#define STRINGID_ABOUTTOUSEPOLTERGEIST 603
-#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 604
-#define STRINGID_NEUTRALIZINGGASENTERS 605
-#define STRINGID_NEUTRALIZINGGASOVER 606
-#define STRINGID_TARGETTOOHEAVY 607
-#define STRINGID_PKMNTOOKTARGETHIGH 608
-#define STRINGID_PKMNINSNAPTRAP 609
-#define STRINGID_METEORBEAMCHARGING 610
-#define STRINGID_HEATUPBEAK 611
-#define STRINGID_COURTCHANGE 612
-#define STRINGID_PLAYERLOSTTOENEMYTRAINER 613
-#define STRINGID_PLAYERPAIDPRIZEMONEY 614
-#define STRINGID_ZPOWERSURROUNDS 615
-#define STRINGID_ZMOVEUNLEASHED 616
-#define STRINGID_ZMOVERESETSSTATS 617
-#define STRINGID_ZMOVEALLSTATSUP 618
-#define STRINGID_ZMOVEZBOOSTCRIT 619
-#define STRINGID_ZMOVERESTOREHP 620
-#define STRINGID_ZMOVESTATUP 621
-#define STRINGID_ZMOVEHPTRAP 622
-#define STRINGID_ATTACKEREXPELLEDTHEPOISON 623
-#define STRINGID_ATTACKERSHOOKITSELFAWAKE 624
-#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 625
-#define STRINGID_ATTACKERHEALEDITSBURN 626
-#define STRINGID_ATTACKERMELTEDTHEICE 627
-#define STRINGID_TARGETTOUGHEDITOUT 628
-#define STRINGID_ATTACKERLOSTELECTRICTYPE 629
-#define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 630
-#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 631
-#define STRINGID_SUNLIGHTACTIVATEDABILITY 632
-#define STRINGID_STATWASHEIGHTENED 633
-#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 634
-#define STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT 635
-#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 636
-#define STRINGID_PKMNSABILITYPREVENTSABILITY 637
-#define STRINGID_PREPARESHELLTRAP 638
-#define STRINGID_SHELLTRAPDIDNTWORK 639
-#define STRINGID_SPIKESDISAPPEAREDFROMTEAM 640
-#define STRINGID_TOXICSPIKESDISAPPEAREDFROMTEAM 641
-#define STRINGID_STICKYWEBDISAPPEAREDFROMTEAM 642
-#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 643
-#define STRINGID_COULDNTFULLYPROTECT 644
-#define STRINGID_STOCKPILEDEFFECTWOREOFF 645
-#define STRINGID_PKMNREVIVEDREADYTOFIGHT 646
-#define STRINGID_ITEMRESTOREDSPECIESHEALTH 647
-#define STRINGID_ITEMCUREDSPECIESSTATUS 648
-#define STRINGID_ITEMRESTOREDSPECIESPP 649
-#define STRINGID_THUNDERCAGETRAPPED 650
-#define STRINGID_PKMNHURTBYFROSTBITE 651
-#define STRINGID_PKMNGOTFROSTBITE 652
-#define STRINGID_PKMNSITEMHEALEDFROSTBITE 653
-#define STRINGID_ATTACKERHEALEDITSFROSTBITE 654
-#define STRINGID_PKMNFROSTBITEHEALED 655
-#define STRINGID_PKMNFROSTBITEHEALED2 656
-#define STRINGID_PKMNFROSTBITEHEALEDBY 657
-#define STRINGID_MIRRORHERBCOPIED 658
-#define STRINGID_STARTEDSNOW 659
-#define STRINGID_SNOWCONTINUES 660
-#define STRINGID_SNOWSTOPPED 661
-#define STRINGID_SNOWWARNINGSNOW 662
-#define STRINGID_PKMNITEMMELTED 663
-#define STRINGID_ULTRABURSTREACTING 664
-#define STRINGID_ULTRABURSTCOMPLETED 665
-#define STRINGID_TEAMGAINEDEXP 666
-#define STRINGID_CURRENTMOVECANTSELECT 667
-#define STRINGID_TARGETISBEINGSALTCURED 668
-#define STRINGID_TARGETISHURTBYSALTCURE 669
-#define STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP 670
-#define STRINGID_SHARPSTEELFLOATS 671
-#define STRINGID_SHARPSTEELDMG 672
-#define STRINGID_PKMNBLEWAWAYSHARPSTEEL 673
-#define STRINGID_SHARPSTEELDISAPPEAREDFROMTEAM 674
-#define STRINGID_TEAMTRAPPEDWITHVINES 675
-#define STRINGID_PKMNHURTBYVINES 676
-#define STRINGID_TEAMCAUGHTINVORTEX 677
-#define STRINGID_PKMNHURTBYVORTEX 678
-#define STRINGID_TEAMSURROUNDEDBYFIRE 679
-#define STRINGID_PKMNBURNINGUP 680
-#define STRINGID_TEAMSURROUNDEDBYROCKS 681
-#define STRINGID_PKMNHURTBYROCKSTHROWN 682
-#define STRINGID_MOVEBLOCKEDBYDYNAMAX 683
-#define STRINGID_ZEROTOHEROTRANSFORMATION 684
-#define STRINGID_THETWOMOVESBECOMEONE 685
-#define STRINGID_ARAINBOWAPPEAREDONSIDE 686
-#define STRINGID_THERAINBOWDISAPPEARED 687
-#define STRINGID_WAITINGFORPARTNERSMOVE 688
-#define STRINGID_SEAOFFIREENVELOPEDSIDE 689
-#define STRINGID_HURTBYTHESEAOFFIRE 690
-#define STRINGID_THESEAOFFIREDISAPPEARED 691
-#define STRINGID_SWAMPENVELOPEDSIDE 692
-#define STRINGID_THESWAMPDISAPPEARED 693
-#define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 694
-#define STRINGID_HOSPITALITYRESTORATION 695
-#define STRINGID_ELECTROSHOTCHARGING 696
-#define STRINGID_ITEMWASUSEDUP 697
-#define STRINGID_ATTACKERLOSTITSTYPE 698
-#define STRINGID_SHEDITSTAIL 699
-#define STRINGID_CLOAKEDINAHARSHLIGHT 700
-#define STRINGID_SUPERSWEETAROMAWAFTS 701
-#define STRINGID_DIMENSIONSWERETWISTED 702
-#define STRINGID_BIZARREARENACREATED 703
-#define STRINGID_BIZARREAREACREATED 704
-#define STRINGID_TIDYINGUPCOMPLETE 705
-#define STRINGID_PKMNTERASTALLIZEDINTO 706
-#define STRINGID_BOOSTERENERGYACTIVATES 707
-#define STRINGID_FOGCREPTUP 708
-#define STRINGID_FOGISDEEP 709
-#define STRINGID_FOGLIFTED 710
-#define STRINGID_PKMNMADESHELLGLEAM 711
-#define STRINGID_FICKLEBEAMDOUBLED 712
-#define STRINGID_COMMANDERACTIVATES 713
-#define STRINGID_POKEFLUTECATCHY 714
-#define STRINGID_POKEFLUTE 715
-#define STRINGID_MONHEARINGFLUTEAWOKE 716
-#define STRINGID_SUNLIGHTISHARSH 717
-#define STRINGID_ITISHAILING 718
-#define STRINGID_ITISSNOWING 719
-#define STRINGID_ISCOVEREDWITHGRASS 720
-#define STRINGID_MISTSWIRLSAROUND 721
-#define STRINGID_ELECTRICCURRENTISRUNNING 722
-#define STRINGID_SEEMSWEIRD 723
-#define STRINGID_WAGGLINGAFINGER 724
+#define STRINGID_AIRBALLOONFLOAT 532
+#define STRINGID_AIRBALLOONPOP 533
+#define STRINGID_INCINERATEBURN 534
+#define STRINGID_BUGBITE 535
+#define STRINGID_ILLUSIONWOREOFF 536
+#define STRINGID_ATTACKERCUREDTARGETSTATUS 537
+#define STRINGID_ATTACKERLOSTFIRETYPE 538
+#define STRINGID_HEALERCURE 539
+#define STRINGID_SCRIPTINGABILITYSTATRAISE 540
+#define STRINGID_RECEIVERABILITYTAKEOVER 541
+#define STRINGID_PKNMABSORBINGPOWER 542
+#define STRINGID_NOONEWILLBEABLETORUNAWAY 543
+#define STRINGID_DESTINYKNOTACTIVATES 544
+#define STRINGID_CLOAKEDINAFREEZINGLIGHT 545
+#define STRINGID_CLEARAMULETWONTLOWERSTATS 546
+#define STRINGID_FERVENTWISHREACHED 547
+#define STRINGID_AIRLOCKACTIVATES 548
+#define STRINGID_PRESSUREENTERS 549
+#define STRINGID_DARKAURAENTERS 550
+#define STRINGID_FAIRYAURAENTERS 551
+#define STRINGID_AURABREAKENTERS 552
+#define STRINGID_COMATOSEENTERS 553
+#define STRINGID_SCREENCLEANERENTERS 554
+#define STRINGID_FETCHEDPOKEBALL 555
+#define STRINGID_BATTLERABILITYRAISEDSTAT 556
+#define STRINGID_ASANDSTORMKICKEDUP 557
+#define STRINGID_PKMNSWILLPERISHIN3TURNS 558
+#define STRINGID_ABILITYRAISEDSTATDRASTICALLY 559
+#define STRINGID_AURAFLAREDTOLIFE 560
+#define STRINGID_ASONEENTERS 561
+#define STRINGID_CURIOUSMEDICINEENTERS 562
+#define STRINGID_CANACTFASTERTHANKSTO 563
+#define STRINGID_MICLEBERRYACTIVATES 564
+#define STRINGID_PKMNSHOOKOFFTHETAUNT 565
+#define STRINGID_PKMNGOTOVERITSINFATUATION 566
+#define STRINGID_ITEMCANNOTBEREMOVED 567
+#define STRINGID_STICKYBARBTRANSFER 568
+#define STRINGID_PKMNBURNHEALED 569
+#define STRINGID_REDCARDACTIVATE 570
+#define STRINGID_EJECTBUTTONACTIVATE 571
+#define STRINGID_ATKGOTOVERINFATUATION 572
+#define STRINGID_TORMENTEDNOMORE 573
+#define STRINGID_HEALBLOCKEDNOMORE 574
+#define STRINGID_ATTACKERBECAMEFULLYCHARGED 575
+#define STRINGID_ATTACKERBECAMEASHSPECIES 576
+#define STRINGID_EXTREMELYHARSHSUNLIGHT 577
+#define STRINGID_EXTREMESUNLIGHTFADED 578
+#define STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT 579
+#define STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED 580
+#define STRINGID_HEAVYRAIN 581
+#define STRINGID_HEAVYRAINLIFTED 582
+#define STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN 583
+#define STRINGID_NORELIEFROMHEAVYRAIN 584
+#define STRINGID_MYSTERIOUSAIRCURRENT 585
+#define STRINGID_STRONGWINDSDISSIPATED 586
+#define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 587
+#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 588
+#define STRINGID_STUFFCHEEKSCANTSELECT 589
+#define STRINGID_PKMNREVERTEDTOPRIMAL 590
+#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 591
+#define STRINGID_BUTHOOPACANTUSEIT 592
+#define STRINGID_BROKETHROUGHPROTECTION 593
+#define STRINGID_ABILITYALLOWSONLYMOVE 594
+#define STRINGID_SWAPPEDABILITIES 595
+#define STRINGID_PASTELVEILPROTECTED 596
+#define STRINGID_PASTELVEILENTERS 597
+#define STRINGID_BATTLERTYPECHANGEDTO 598
+#define STRINGID_BOTHCANNOLONGERESCAPE 599
+#define STRINGID_CANTESCAPEDUETOUSEDMOVE 600
+#define STRINGID_PKMNBECAMEWEAKERTOFIRE 601
+#define STRINGID_ABOUTTOUSEPOLTERGEIST 602
+#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 603
+#define STRINGID_NEUTRALIZINGGASENTERS 604
+#define STRINGID_NEUTRALIZINGGASOVER 605
+#define STRINGID_TARGETTOOHEAVY 606
+#define STRINGID_PKMNTOOKTARGETHIGH 607
+#define STRINGID_PKMNINSNAPTRAP 608
+#define STRINGID_METEORBEAMCHARGING 609
+#define STRINGID_HEATUPBEAK 610
+#define STRINGID_COURTCHANGE 611
+#define STRINGID_PLAYERLOSTTOENEMYTRAINER 612
+#define STRINGID_PLAYERPAIDPRIZEMONEY 613
+#define STRINGID_ZPOWERSURROUNDS 614
+#define STRINGID_ZMOVEUNLEASHED 615
+#define STRINGID_ZMOVERESETSSTATS 616
+#define STRINGID_ZMOVEALLSTATSUP 617
+#define STRINGID_ZMOVEZBOOSTCRIT 618
+#define STRINGID_ZMOVERESTOREHP 619
+#define STRINGID_ZMOVESTATUP 620
+#define STRINGID_ZMOVEHPTRAP 621
+#define STRINGID_ATTACKEREXPELLEDTHEPOISON 622
+#define STRINGID_ATTACKERSHOOKITSELFAWAKE 623
+#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 624
+#define STRINGID_ATTACKERHEALEDITSBURN 625
+#define STRINGID_ATTACKERMELTEDTHEICE 626
+#define STRINGID_TARGETTOUGHEDITOUT 627
+#define STRINGID_ATTACKERLOSTELECTRICTYPE 628
+#define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 629
+#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 630
+#define STRINGID_SUNLIGHTACTIVATEDABILITY 631
+#define STRINGID_STATWASHEIGHTENED 632
+#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 633
+#define STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT 634
+#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 635
+#define STRINGID_PKMNSABILITYPREVENTSABILITY 636
+#define STRINGID_PREPARESHELLTRAP 637
+#define STRINGID_SHELLTRAPDIDNTWORK 638
+#define STRINGID_SPIKESDISAPPEAREDFROMTEAM 639
+#define STRINGID_TOXICSPIKESDISAPPEAREDFROMTEAM 640
+#define STRINGID_STICKYWEBDISAPPEAREDFROMTEAM 641
+#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 642
+#define STRINGID_COULDNTFULLYPROTECT 643
+#define STRINGID_STOCKPILEDEFFECTWOREOFF 644
+#define STRINGID_PKMNREVIVEDREADYTOFIGHT 645
+#define STRINGID_ITEMRESTOREDSPECIESHEALTH 646
+#define STRINGID_ITEMCUREDSPECIESSTATUS 647
+#define STRINGID_ITEMRESTOREDSPECIESPP 648
+#define STRINGID_THUNDERCAGETRAPPED 649
+#define STRINGID_PKMNHURTBYFROSTBITE 650
+#define STRINGID_PKMNGOTFROSTBITE 651
+#define STRINGID_PKMNSITEMHEALEDFROSTBITE 652
+#define STRINGID_ATTACKERHEALEDITSFROSTBITE 653
+#define STRINGID_PKMNFROSTBITEHEALED 654
+#define STRINGID_PKMNFROSTBITEHEALED2 655
+#define STRINGID_PKMNFROSTBITEHEALEDBY 656
+#define STRINGID_MIRRORHERBCOPIED 657
+#define STRINGID_STARTEDSNOW 658
+#define STRINGID_SNOWCONTINUES 659
+#define STRINGID_SNOWSTOPPED 660
+#define STRINGID_SNOWWARNINGSNOW 661
+#define STRINGID_PKMNITEMMELTED 662
+#define STRINGID_ULTRABURSTREACTING 663
+#define STRINGID_ULTRABURSTCOMPLETED 664
+#define STRINGID_TEAMGAINEDEXP 665
+#define STRINGID_CURRENTMOVECANTSELECT 666
+#define STRINGID_TARGETISBEINGSALTCURED 667
+#define STRINGID_TARGETISHURTBYSALTCURE 668
+#define STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP 669
+#define STRINGID_SHARPSTEELFLOATS 670
+#define STRINGID_SHARPSTEELDMG 671
+#define STRINGID_PKMNBLEWAWAYSHARPSTEEL 672
+#define STRINGID_SHARPSTEELDISAPPEAREDFROMTEAM 673
+#define STRINGID_TEAMTRAPPEDWITHVINES 674
+#define STRINGID_PKMNHURTBYVINES 675
+#define STRINGID_TEAMCAUGHTINVORTEX 676
+#define STRINGID_PKMNHURTBYVORTEX 677
+#define STRINGID_TEAMSURROUNDEDBYFIRE 678
+#define STRINGID_PKMNBURNINGUP 679
+#define STRINGID_TEAMSURROUNDEDBYROCKS 680
+#define STRINGID_PKMNHURTBYROCKSTHROWN 681
+#define STRINGID_MOVEBLOCKEDBYDYNAMAX 682
+#define STRINGID_ZEROTOHEROTRANSFORMATION 683
+#define STRINGID_THETWOMOVESBECOMEONE 684
+#define STRINGID_ARAINBOWAPPEAREDONSIDE 685
+#define STRINGID_THERAINBOWDISAPPEARED 686
+#define STRINGID_WAITINGFORPARTNERSMOVE 687
+#define STRINGID_SEAOFFIREENVELOPEDSIDE 688
+#define STRINGID_HURTBYTHESEAOFFIRE 689
+#define STRINGID_THESEAOFFIREDISAPPEARED 690
+#define STRINGID_SWAMPENVELOPEDSIDE 691
+#define STRINGID_THESWAMPDISAPPEARED 692
+#define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 693
+#define STRINGID_HOSPITALITYRESTORATION 694
+#define STRINGID_ELECTROSHOTCHARGING 695
+#define STRINGID_ITEMWASUSEDUP 696
+#define STRINGID_ATTACKERLOSTITSTYPE 697
+#define STRINGID_SHEDITSTAIL 698
+#define STRINGID_CLOAKEDINAHARSHLIGHT 699
+#define STRINGID_SUPERSWEETAROMAWAFTS 700
+#define STRINGID_DIMENSIONSWERETWISTED 701
+#define STRINGID_BIZARREARENACREATED 702
+#define STRINGID_BIZARREAREACREATED 703
+#define STRINGID_TIDYINGUPCOMPLETE 704
+#define STRINGID_PKMNTERASTALLIZEDINTO 705
+#define STRINGID_BOOSTERENERGYACTIVATES 706
+#define STRINGID_FOGCREPTUP 707
+#define STRINGID_FOGISDEEP 708
+#define STRINGID_FOGLIFTED 709
+#define STRINGID_PKMNMADESHELLGLEAM 710
+#define STRINGID_FICKLEBEAMDOUBLED 711
+#define STRINGID_COMMANDERACTIVATES 712
+#define STRINGID_POKEFLUTECATCHY 713
+#define STRINGID_POKEFLUTE 714
+#define STRINGID_MONHEARINGFLUTEAWOKE 715
+#define STRINGID_SUNLIGHTISHARSH 716
+#define STRINGID_ITISHAILING 717
+#define STRINGID_ITISSNOWING 718
+#define STRINGID_ISCOVEREDWITHGRASS 719
+#define STRINGID_MISTSWIRLSAROUND 720
+#define STRINGID_ELECTRICCURRENTISRUNNING 721
+#define STRINGID_SEEMSWEIRD 722
+#define STRINGID_WAGGLINGAFINGER 723
+#define STRINGID_BLOCKEDBYSLEEPCLAUSE 724
+#define STRINGID_SUPEREFFECTIVETWOFOES 725
+#define STRINGID_NOTVERYEFFECTIVETWOFOES 726
+#define STRINGID_ITDOESNTAFFECTTWOFOES 727
-#define BATTLESTRINGS_COUNT 725
+#define BATTLESTRINGS_COUNT 728
// This is the string id that gBattleStringsTable starts with.
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
@@ -1007,9 +1010,11 @@
#define B_MSG_SET_TRICK_ROOM 4
#define B_MSG_SET_MAGIC_ROOM 5
#define B_MSG_SET_WONDER_ROOM 6
-#define B_MSG_SET_TAILWIND_PLAYER 7
-#define B_MSG_SET_TAILWIND_OPPONENT 8
-#define B_MSG_STARTING_STATUS_COUNT 9
+#define B_MSG_SET_TAILWIND 7
+#define B_MSG_SET_RAINBOW 8
+#define B_MSG_SET_SEA_OF_FIRE 9
+#define B_MSG_SET_SWAMP 10
+#define B_MSG_STARTING_STATUS_COUNT 11
// gWrappedStringIds
diff --git a/include/constants/characters.h b/include/constants/characters.h
index 3725cecce0..6ac3c5224c 100644
--- a/include/constants/characters.h
+++ b/include/constants/characters.h
@@ -54,6 +54,7 @@
#define CHAR_SEMICOLON 0x36
#define CHAR_BARD_WORD_DELIMIT 0x37 // Empty space to separate words in Bard's song
#define CHAR_V_D_ARROW 0x38
+#define CHAR_NBSP 0x39
#define CHAR_INV_QUESTION_MARK 0x51
#define CHAR_INV_EXCL_MARK 0x52
#define CHAR_PK 0x53
diff --git a/include/constants/expansion.h b/include/constants/expansion.h
index 327a502e22..6b3a5ace78 100644
--- a/include/constants/expansion.h
+++ b/include/constants/expansion.h
@@ -1,9 +1,9 @@
#ifndef GUARD_CONSTANTS_EXPANSION_H
#define GUARD_CONSTANTS_EXPANSION_H
-// Last version: 1.9.3
+// Last version: 1.10.1
#define EXPANSION_VERSION_MAJOR 1
-#define EXPANSION_VERSION_MINOR 10
+#define EXPANSION_VERSION_MINOR 11
#define EXPANSION_VERSION_PATCH 0
// FALSE if this this version of Expansion is not a tagged commit, i.e.
diff --git a/include/constants/form_change_types.h b/include/constants/form_change_types.h
index 74bc16cf2f..8af9740cad 100644
--- a/include/constants/form_change_types.h
+++ b/include/constants/form_change_types.h
@@ -134,4 +134,14 @@
// param1: amount of days
#define FORM_CHANGE_DAYS_PASSED 23
+// Form change that activates before using a move.
+// param1: move to check
+// param2: ability to check, optional
+#define FORM_CHANGE_BATTLE_BEFORE_MOVE 24
+
+// Form change that activates before using a specific move category.
+// param1: move category to check
+// param2: ability to check, optional
+#define FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY 25
+
#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h
new file mode 100644
index 0000000000..557b34b653
--- /dev/null
+++ b/include/constants/generational_changes.h
@@ -0,0 +1,10 @@
+#ifndef GUARD_CONSTANTS_GENERATIONAL_CHANGES_H
+#define GUARD_CONSTANTS_GENERATIONAL_CHANGES_H
+
+enum GenConfigTag
+{
+ GEN_CONFIG_GALE_WINGS,
+ GEN_CONFIG_COUNT
+};
+
+#endif // GUARD_CONSTANTS_GENERATIONAL_CHANGES_H
diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h
index ab0f6b8453..86ddde5032 100644
--- a/include/constants/pokemon.h
+++ b/include/constants/pokemon.h
@@ -323,8 +323,9 @@ enum EvolutionMode {
// - Unown has 1 frame, presumably to avoid the work of animating all 28 of its forms
#define MAX_MON_PIC_FRAMES 2
-#define BATTLE_ALIVE_EXCEPT_BATTLER 0
-#define BATTLE_ALIVE_SIDE 1
+#define BATTLE_ALIVE_EXCEPT_BATTLER 0
+#define BATTLE_ALIVE_EXCEPT_BATTLER_SIDE 1
+#define BATTLE_ALIVE_SIDE 2
#define SKIP_FRONT_ANIM (1 << 7)
diff --git a/include/data.h b/include/data.h
index ef59aae569..8d90d679b3 100644
--- a/include/data.h
+++ b/include/data.h
@@ -88,7 +88,7 @@ struct Trainer
/*0x12*/ u8 trainerPic;
/*0x13*/ u8 trainerName[TRAINER_NAME_LENGTH + 1];
/*0x1E*/ bool8 doubleBattle:1;
- bool8 mugshotEnabled:1;
+ bool8 padding:1;
u8 startingStatus:6; // this trainer starts a battle with a given status. see include/constants/battle.h for values
/*0x1F*/ u8 mugshotColor;
/*0x20*/ u8 partySize;
@@ -235,7 +235,7 @@ static inline const u8 GetTrainerPartySizeFromId(u16 trainerId)
static inline const bool32 DoesTrainerHaveMugshot(u16 trainerId)
{
- return gTrainers[SanitizeTrainerId(trainerId)].mugshotEnabled;
+ return gTrainers[SanitizeTrainerId(trainerId)].mugshotColor;
}
static inline const u8 GetTrainerMugshotColorFromId(u16 trainerId)
diff --git a/include/fonts.h b/include/fonts.h
index a6be35db98..5e6a9ffad5 100644
--- a/include/fonts.h
+++ b/include/fonts.h
@@ -21,5 +21,7 @@ extern const u8 gFontSmallNarrowerLatinGlyphWidths[];
extern const u16 gFontSmallNarrowerLatinGlyphs[];
extern const u8 gFontShortNarrowLatinGlyphWidths[];
extern const u16 gFontShortNarrowLatinGlyphs[];
+extern const u8 gFontShortNarrowerLatinGlyphWidths[];
+extern const u16 gFontShortNarrowerLatinGlyphs[];
#endif // GUARD_FONTS_H
diff --git a/include/fpmath.h b/include/fpmath.h
index 6e3edd64e0..69265652e6 100644
--- a/include/fpmath.h
+++ b/include/fpmath.h
@@ -12,7 +12,8 @@ typedef u32 uq4_12_t;
// Converts a number to Q4.12 fixed-point format
#define Q_4_12(n) ((q4_12_t)((n) * 4096))
-#define UQ_4_12(n) ((uq4_12_t)((n) * 4096))
+#define UQ_4_12(n) ((uq4_12_t)((n) * 4096 + 0.5))
+#define UQ_4_12_FLOORED(n) ((uq4_12_t)((n) * 4096))
// Converts a number to Q24.8 fixed-point format
#define Q_24_8(n) ((s32)((n) << 8))
diff --git a/include/gba/defines.h b/include/gba/defines.h
index c54dac8c13..0bf7110810 100644
--- a/include/gba/defines.h
+++ b/include/gba/defines.h
@@ -13,6 +13,8 @@
#define COMMON_DATA __attribute__((section("common_data")))
#define UNUSED __attribute__((unused))
+#define ARM_FUNC __attribute__((target("arm")))
+
#if MODERN
#define NOINLINE __attribute__((noinline))
#else
diff --git a/include/generational_changes.h b/include/generational_changes.h
new file mode 100644
index 0000000000..5a726007c3
--- /dev/null
+++ b/include/generational_changes.h
@@ -0,0 +1,41 @@
+#ifndef GUARD_GENERATIONAL_CHANGES_H
+#define GUARD_GENERATIONAL_CHANGES_H
+
+#include "constants/generational_changes.h"
+#include "config/battle.h"
+
+static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] =
+{
+ [GEN_CONFIG_GALE_WINGS] = B_GALE_WINGS,
+};
+
+#if TESTING
+extern u8 *gGenerationalChangesTestOverride;
+#endif
+
+static inline u32 GetGenConfig(enum GenConfigTag configTag)
+{
+ if (configTag >= GEN_CONFIG_COUNT) return GEN_LATEST;
+#if TESTING
+ if (gGenerationalChangesTestOverride == NULL) return sGenerationalChanges[configTag];
+ return gGenerationalChangesTestOverride[configTag];
+#else
+ return sGenerationalChanges[configTag];
+#endif
+}
+
+static inline void SetGenConfig(enum GenConfigTag configTag, u32 value)
+{
+#if TESTING
+ if (configTag >= GEN_CONFIG_COUNT) return;
+ if (gGenerationalChangesTestOverride == NULL) return;
+ gGenerationalChangesTestOverride[configTag] = value;
+#endif
+}
+
+#if TESTING
+void TestInitConfigData(void);
+void TestFreeConfigData(void);
+#endif
+
+#endif // GUARD_GENERATIONAL_CHANGES_H
diff --git a/include/global.h b/include/global.h
index e2b49c0047..3e5e984547 100644
--- a/include/global.h
+++ b/include/global.h
@@ -819,8 +819,7 @@ struct DayCare
{
struct DaycareMon mons[DAYCARE_MON_COUNT];
u32 offspringPersonality;
- u8 stepCounter;
- //u8 padding[3];
+ u32 stepCounter;
};
struct LilycoveLadyQuiz
diff --git a/include/line_break.h b/include/line_break.h
new file mode 100644
index 0000000000..c423c9bf40
--- /dev/null
+++ b/include/line_break.h
@@ -0,0 +1,33 @@
+#ifndef GUARD_LINE_BREAK_H
+#define GUARD_LINE_BREAK_H
+
+#define BADNESS_UNFILLED 1 // Badness added per pixel diff from max width
+#define BADNESS_JAGGED 1 // Badness added per pixel diff from longest, squared per line
+#define BADNESS_RUNT 100 // Badness added if there's a runt
+#define BADNESS_OVERFLOW 100 // Badness added per pixel overflow, squared per line (not used)
+#define BADNESS_WIDE_SPACE 1 // Badness added per extra pixel width (not used)
+#define MAX_SPACE_WIDTH 5
+
+struct StringWord {
+ u32 startIndex:16;
+ u32 length:8;
+ u32 width:8;
+};
+
+struct StringLine {
+ struct StringWord *words;
+ u16 numWords;
+ u8 spaceWidth;
+ u8 extraSpaceWidth;
+};
+
+void StripLineBreaks(u8 *src);
+void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId);
+void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId);
+
+bool32 IsWordSplittingChar(const u8 *src, u32 index);
+u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth);
+void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str);
+bool32 StringHasManualBreaks(u8 *src);
+
+#endif // GUARD_LINE_BREAK_H
diff --git a/include/move.h b/include/move.h
new file mode 100644
index 0000000000..67206d9ba2
--- /dev/null
+++ b/include/move.h
@@ -0,0 +1,544 @@
+#ifndef GUARD_MOVES_H
+#define GUARD_MOVES_H
+
+#include "contest_effect.h"
+#include "constants/battle_move_effects.h"
+#include "constants/moves.h"
+
+// For defining EFFECT_HIT etc. with battle TV scores and flags etc.
+struct __attribute__((packed, aligned(2))) BattleMoveEffect
+{
+ const u8 *battleScript;
+ u16 battleTvScore:3;
+ u16 encourageEncore:1;
+ u16 twoTurnEffect:1;
+ u16 semiInvulnerableEffect:1;
+ u16 usesProtectCounter:1;
+ u16 padding:9;
+};
+
+#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__}
+#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ ))
+
+enum SheerForceBoost
+{
+ SHEER_FORCE_AUTO_BOOST, // This is the default state when a move has a move effect with a chance
+ SHEER_FORCE_BOOST, // If a move effect doesn't have an effect with a chance this can force a boost
+ SHEER_FORCE_NO_BOOST, // Prevents a Sheer Force boost
+};
+
+struct AdditionalEffect
+{
+ u16 moveEffect;
+ u8 self:1;
+ u8 onlyIfTargetRaisedStats:1;
+ u8 onChargeTurnOnly:1;
+ u8 sheerForceBoost:2; // Handles edge cases for Sheer Force
+ u8 padding:3;
+ u8 chance; // 0% = effect certain, primary effect
+};
+
+struct MoveInfo
+{
+ const u8 *name;
+ const u8 *description;
+ u16 effect;
+ u16 type:5; // Up to 32
+ u16 category:2;
+ u16 power:9; // up to 511
+ // end of word
+ u16 accuracy:7;
+ u16 target:9;
+ u8 pp;
+ union {
+ u8 effect;
+ u8 powerOverride;
+ } zMove;
+ // end of word
+ s32 priority:4;
+ u32 recoil:7;
+ u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
+ u32 criticalHitStage:2;
+ bool32 alwaysCriticalHit:1;
+ u32 numAdditionalEffects:2; // limited to 3 - don't want to get too crazy
+ // Flags
+ bool32 makesContact:1;
+ bool32 ignoresProtect:1;
+ bool32 magicCoatAffected:1;
+ bool32 snatchAffected:1;
+ bool32 ignoresKingsRock:1;
+ bool32 punchingMove:1;
+ bool32 bitingMove:1;
+ bool32 pulseMove:1;
+ bool32 soundMove:1;
+ bool32 ballisticMove:1;
+ bool32 powderMove:1;
+ bool32 danceMove:1;
+ // end of word
+ bool32 windMove:1;
+ bool32 slicingMove:1;
+ bool32 healingMove:1;
+ bool32 minimizeDoubleDamage:1;
+ bool32 ignoresTargetAbility:1;
+ bool32 ignoresTargetDefenseEvasionStages:1;
+ bool32 damagesUnderground:1;
+ bool32 damagesUnderwater:1;
+ bool32 damagesAirborne:1;
+ bool32 damagesAirborneDoubleDamage:1;
+ bool32 ignoreTypeIfFlyingAndUngrounded:1;
+ bool32 thawsUser:1;
+ bool32 ignoresSubstitute:1;
+ bool32 forcePressure:1;
+ bool32 cantUseTwice:1;
+ // Ban flags
+ bool32 gravityBanned:1;
+ bool32 mirrorMoveBanned:1;
+ bool32 meFirstBanned:1;
+ bool32 mimicBanned:1;
+ bool32 metronomeBanned:1;
+ bool32 copycatBanned:1;
+ bool32 assistBanned:1; // Matches same moves as copycatBanned + semi-invulnerable moves and Mirror Coat.
+ bool32 sleepTalkBanned:1;
+ bool32 instructBanned:1;
+ bool32 encoreBanned:1;
+ bool32 parentalBondBanned:1;
+ bool32 skyBattleBanned:1;
+ bool32 sketchBanned:1;
+ u32 padding:19;
+ // end of word
+
+ union {
+ struct {
+ u16 stringId;
+ u16 status;
+ } twoTurnAttack;
+ struct {
+ u16 side;
+ u16 property; // can be used to remove the hardcoded values
+ } protect;
+ u32 status;
+ u16 moveProperty;
+ u16 holdEffect;
+ u16 type;
+ u16 fixedDamage;
+ u16 absorbPercentage;
+ u16 maxEffect;
+ } argument;
+
+ // primary/secondary effects
+ const struct AdditionalEffect *additionalEffects;
+
+ // contest parameters
+ u8 contestEffect;
+ u8 contestCategory:3;
+ u8 contestComboStarterId;
+ u8 contestComboMoves[MAX_COMBO_MOVES];
+ const u8 *battleAnimScript;
+};
+
+extern const struct MoveInfo gMovesInfo[];
+extern const u8 gNotDoneYetDescription[];
+extern const struct BattleMoveEffect gBattleMoveEffects[];
+
+static inline u32 SanitizeMoveId(u32 moveId)
+{
+ if (moveId >= MOVES_COUNT_ALL)
+ return MOVE_NONE;
+ else
+ return moveId;
+}
+
+static inline const u8 *GetMoveName(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].name;
+}
+
+static inline const u8 *GetMoveDescription(u32 moveId)
+{
+ moveId = SanitizeMoveId(moveId);
+ if (gMovesInfo[moveId].effect == EFFECT_PLACEHOLDER)
+ return gNotDoneYetDescription;
+ return gMovesInfo[moveId].description;
+}
+
+static inline u32 GetMoveEffect(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].effect;
+}
+
+static inline u32 GetMoveType(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].type;
+}
+
+static inline u32 GetMoveCategory(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].category;
+}
+
+static inline u32 GetMovePower(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].power;
+}
+
+static inline u32 GetMoveAccuracy(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].accuracy;
+}
+
+static inline u32 GetMoveTarget(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].target;
+}
+
+static inline u32 GetMovePP(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].pp;
+}
+
+static inline u32 GetMoveZEffect(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].zMove.effect;
+}
+
+static inline u32 GetMoveZPowerOverride(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].zMove.powerOverride;
+}
+
+static inline s32 GetMovePriority(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].priority;
+}
+
+static inline u32 GetMoveRecoil(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].recoil;
+}
+
+static inline u32 GetMoveStrikeCount(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].strikeCount;
+}
+
+static inline u32 GetMoveCriticalHitStage(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].criticalHitStage;
+}
+
+static inline bool32 MoveAlwaysCrits(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].alwaysCriticalHit;
+}
+
+static inline u32 GetMoveAdditionalEffectCount(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].numAdditionalEffects;
+}
+
+static inline bool32 MoveMakesContact(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].makesContact;
+}
+
+static inline bool32 MoveIgnoresProtect(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ignoresProtect;
+}
+
+static inline bool32 MoveCanBeBouncedBack(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].magicCoatAffected;
+}
+
+static inline bool32 MoveCanBeSnatched(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].snatchAffected;
+}
+
+static inline bool32 MoveIgnoresKingsRock(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ignoresKingsRock;
+}
+
+static inline bool32 IsPunchingMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].punchingMove;
+}
+
+static inline bool32 IsBitingMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].bitingMove;
+}
+
+static inline bool32 IsPulseMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].pulseMove;
+}
+
+static inline bool32 IsSoundMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].soundMove;
+}
+
+static inline bool32 IsBallisticMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ballisticMove;
+}
+
+static inline bool32 IsPowderMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].powderMove;
+}
+
+static inline bool32 IsDanceMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].danceMove;
+}
+
+static inline bool32 IsWindMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].windMove;
+}
+
+static inline bool32 IsSlicingMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].slicingMove;
+}
+
+static inline bool32 IsHealingMove(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].healingMove;
+}
+
+static inline bool32 MoveIncreasesPowerToMinimizedTargets(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].minimizeDoubleDamage;
+}
+
+static inline bool32 MoveIgnoresTargetAbility(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ignoresTargetAbility;
+}
+
+static inline bool32 MoveIgnoresDefenseEvasionStages(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ignoresTargetDefenseEvasionStages;
+}
+
+static inline bool32 MoveDamagesUnderground(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].damagesUnderground;
+}
+
+static inline bool32 MoveDamagesUnderWater(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].damagesUnderwater;
+}
+
+static inline bool32 MoveDamagesAirborne(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].damagesAirborne;
+}
+
+static inline bool32 MoveDamagesAirborneDoubleDamage(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].damagesAirborneDoubleDamage;
+}
+
+static inline bool32 MoveIgnoresTypeIfFlyingAndUngrounded(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ignoreTypeIfFlyingAndUngrounded;
+}
+
+static inline bool32 MoveThawsUser(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].thawsUser;
+}
+
+static inline bool32 MoveIgnoresSubstitute(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].ignoresSubstitute;
+}
+
+static inline bool32 MoveForcesPressure(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].forcePressure;
+}
+
+static inline bool32 MoveCantBeUsedTwice(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].cantUseTwice;
+}
+
+static inline bool32 IsMoveGravityBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].gravityBanned;
+}
+
+static inline bool32 IsMoveMirrorMoveBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].mirrorMoveBanned;
+}
+
+static inline bool32 IsMoveMeFirstBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].meFirstBanned;
+}
+
+static inline bool32 IsMoveMimicBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].mimicBanned;
+}
+
+static inline bool32 IsMoveMetronomeBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].metronomeBanned;
+}
+
+static inline bool32 IsMoveCopycatBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].copycatBanned;
+}
+
+static inline bool32 IsMoveAssistBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].assistBanned;
+}
+
+static inline bool32 IsMoveSleepTalkBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].sleepTalkBanned;
+}
+
+static inline bool32 IsMoveInstructBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].instructBanned;
+}
+
+static inline bool32 IsMoveEncoreBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].encoreBanned;
+}
+
+static inline bool32 IsMoveParentalBondBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].parentalBondBanned;
+}
+
+static inline bool32 IsMoveSkyBattleBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].skyBattleBanned;
+}
+
+static inline bool32 IsMoveSketchBanned(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].sketchBanned;
+}
+
+static inline u32 GetMoveTwoTurnAttackStringId(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.stringId;
+}
+
+static inline u32 GetMoveTwoTurnAttackStatus(u32 moveId)
+{
+ return UNCOMPRESS_BITS(gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.status);
+}
+
+static inline u32 GetMoveTwoTurnAttackWeather(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.twoTurnAttack.status;
+}
+
+static inline u32 GetMoveProtectSide(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.protect.side;
+}
+
+static inline u32 GetMoveEffectArg_Status(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.status;
+}
+
+static inline u32 GetMoveEffectArg_MoveProperty(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.moveProperty;
+}
+
+static inline u32 GetMoveEffectArg_HoldEffect(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.holdEffect;
+}
+
+static inline u32 GetMoveArgType(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.type;
+}
+
+static inline u32 GetMoveFixedDamage(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.fixedDamage;
+}
+
+static inline u32 GetMoveAbsorbPercentage(u32 moveId)
+{
+ moveId = SanitizeMoveId(moveId);
+ if (gMovesInfo[moveId].argument.absorbPercentage == 0)
+ return 50;
+ return gMovesInfo[moveId].argument.absorbPercentage;
+}
+
+static inline u32 GetMoveMaxEffect(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].argument.maxEffect;
+}
+
+static inline const struct AdditionalEffect *GetMoveAdditionalEffectById(u32 moveId, u32 effect)
+{
+ return &gMovesInfo[SanitizeMoveId(moveId)].additionalEffects[effect];
+}
+
+static inline u32 GetMoveContestEffect(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].contestEffect;
+}
+
+static inline u32 GetMoveContestCategory(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].contestCategory;
+}
+
+static inline u32 GetMoveContestComboStarter(u32 moveId)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].contestComboStarterId;
+}
+
+static inline u32 GetMoveContestComboMoves(u32 moveId, u32 comboMove)
+{
+ return gMovesInfo[SanitizeMoveId(moveId)].contestComboMoves[comboMove];
+}
+
+static inline const u8 *GetMoveAnimationScript(u32 moveId)
+{
+ moveId = SanitizeMoveId(moveId);
+ if (gMovesInfo[moveId].battleAnimScript == NULL)
+ {
+ DebugPrintfLevel(MGBA_LOG_WARN, "No animation for moveId=%u", moveId);
+ return gMovesInfo[MOVE_NONE].battleAnimScript;
+ }
+ return gMovesInfo[moveId].battleAnimScript;
+}
+
+static inline const u8 *GetMoveBattleScript(u32 moveId)
+{
+ moveId = SanitizeMoveId(moveId);
+ if (gBattleMoveEffects[gMovesInfo[moveId].effect].battleScript == NULL)
+ {
+ DebugPrintfLevel(MGBA_LOG_WARN, "No effect for moveId=%u", moveId);
+ return gBattleMoveEffects[EFFECT_PLACEHOLDER].battleScript;
+ }
+ return gBattleMoveEffects[gMovesInfo[moveId].effect].battleScript;
+}
+
+#endif // GUARD_MOVES_H
diff --git a/include/pokemon.h b/include/pokemon.h
index 8a618f5fe1..f855b27ea5 100644
--- a/include/pokemon.h
+++ b/include/pokemon.h
@@ -479,103 +479,6 @@ struct SpeciesInfo /*0xC4*/
#endif //OW_POKEMON_OBJECT_EVENTS
};
-struct MoveInfo
-{
- const u8 *name;
- const u8 *description;
- u16 effect;
- u16 type:5;
- u16 category:2;
- u16 power:9; // up to 511
- u16 accuracy:7;
- u16 target:9;
- u8 pp;
- union {
- u8 effect;
- u8 powerOverride;
- } zMove;
-
- s32 priority:4;
- u32 recoil:7;
- u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
- u32 criticalHitStage:2;
- u32 alwaysCriticalHit:1;
- u32 numAdditionalEffects:2; // limited to 3 - don't want to get too crazy
- // 12 bits left to complete this word - continues into flags
-
- // Flags
- u32 makesContact:1;
- u32 ignoresProtect:1;
- u32 magicCoatAffected:1;
- u32 snatchAffected:1;
- u32 ignoresKingsRock:1;
- u32 punchingMove:1;
- u32 bitingMove:1;
- u32 pulseMove:1;
- u32 soundMove:1;
- u32 ballisticMove:1;
- u32 powderMove:1;
- u32 danceMove:1;
- u32 windMove:1;
- u32 slicingMove:1; // end of word
- u32 healingMove:1;
- u32 minimizeDoubleDamage:1;
- u32 ignoresTargetAbility:1;
- u32 ignoresTargetDefenseEvasionStages:1;
- u32 damagesUnderground:1;
- u32 damagesUnderwater:1;
- u32 damagesAirborne:1;
- u32 damagesAirborneDoubleDamage:1;
- u32 ignoreTypeIfFlyingAndUngrounded:1;
- u32 thawsUser:1;
- u32 ignoresSubstitute:1;
- u32 forcePressure:1;
- u32 cantUseTwice:1;
-
- // Ban flags
- u32 gravityBanned:1;
- u32 mirrorMoveBanned:1;
- u32 meFirstBanned:1;
- u32 mimicBanned:1;
- u32 metronomeBanned:1;
- u32 copycatBanned:1;
- u32 assistBanned:1; // Matches same moves as copycatBanned + semi-invulnerable moves and Mirror Coat.
- u32 sleepTalkBanned:1;
- u32 instructBanned:1;
- u32 encoreBanned:1;
- u32 parentalBondBanned:1;
- u32 skyBattleBanned:1;
- u32 sketchBanned:1;
- u32 padding:5; // end of word
-
- u32 argument;
-
- // primary/secondary effects
- const struct AdditionalEffect *additionalEffects;
-
- // contest parameters
- u8 contestEffect;
- u8 contestCategory:3;
- u8 contestComboStarterId;
- u8 contestComboMoves[MAX_COMBO_MOVES];
- const u8 *battleAnimScript;
-};
-
-#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__}
-#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ ))
-
-// Just a hack to make a move boosted by Sheer Force despite having no secondary effects affected
-#define SHEER_FORCE_HACK { .moveEffect = 0, .chance = 100, }
-
-struct AdditionalEffect
-{
- u16 moveEffect;
- u8 self:1;
- u8 onlyIfTargetRaisedStats:1;
- u8 onChargeTurnOnly:1;
- u8 chance; // 0% = effect certain, primary effect
-};
-
struct Ability
{
u8 name[ABILITY_NAME_LENGTH + 1];
@@ -705,7 +608,6 @@ extern struct Pokemon gEnemyParty[PARTY_SIZE];
extern struct SpriteTemplate gMultiuseSpriteTemplate;
extern u16 gFollowerSteps;
-extern const struct MoveInfo gMovesInfo[];
extern const u8 gFacilityClassToPicIndex[];
extern const u8 gFacilityClassToTrainerClass[];
extern const struct SpeciesInfo gSpeciesInfo[];
@@ -885,6 +787,7 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
+void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
bool32 SpeciesHasGenderDifferences(u16 species);
bool32 TryFormChange(u32 monId, u32 side, u16 method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
@@ -898,8 +801,6 @@ u16 GetCryIdBySpecies(u16 species);
u16 GetSpeciesPreEvolution(u16 species);
void HealPokemon(struct Pokemon *mon);
void HealBoxPokemon(struct BoxPokemon *boxMon);
-const u8 *GetMoveName(u16 moveId);
-const u8 *GetMoveAnimationScript(u16 moveId);
void UpdateDaysPassedSinceFormChange(u16 days);
void TrySetDayLimitToFormChange(struct Pokemon *mon);
u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler);
diff --git a/include/pokemon_summary_screen.h b/include/pokemon_summary_screen.h
index fe299c48b4..1f286698a5 100755
--- a/include/pokemon_summary_screen.h
+++ b/include/pokemon_summary_screen.h
@@ -5,7 +5,6 @@
extern u8 gLastViewedMonIndex;
-extern const u8 gNotDoneYetDescription[];
extern const struct SpriteTemplate gSpriteTemplate_MoveTypes;
extern const struct CompressedSpriteSheet gSpriteSheet_MoveTypes;
extern const struct CompressedSpriteSheet gSpriteSheet_CategoryIcons;
diff --git a/include/random.h b/include/random.h
index 7f9ddefe3f..886094733a 100644
--- a/include/random.h
+++ b/include/random.h
@@ -174,6 +174,7 @@ enum RandomTag
RNG_AI_SWITCH_SE_DEFENSIVE,
RNG_SHELL_SIDE_ARM,
RNG_RANDOM_TARGET,
+ RNG_AI_PREDICT_ABILITY,
RNG_HEALER,
RNG_DEXNAV_ENCOUNTER_LEVEL,
};
diff --git a/include/recorded_battle.h b/include/recorded_battle.h
index c64a665b74..0945eefe92 100644
--- a/include/recorded_battle.h
+++ b/include/recorded_battle.h
@@ -2,6 +2,7 @@
#define GUARD_RECORDED_BATTLE_H
#include "constants/battle.h"
+#include "link.h"
#include "random.h"
#define BATTLER_RECORD_SIZE 664
@@ -10,13 +11,13 @@ struct RecordedBattleSave
{
struct Pokemon playerParty[PARTY_SIZE];
struct Pokemon opponentParty[PARTY_SIZE];
- u8 playersName[MAX_BATTLERS_COUNT][PLAYER_NAME_LENGTH + 1];
- u8 playersGender[MAX_BATTLERS_COUNT];
- u32 playersTrainerId[MAX_BATTLERS_COUNT];
- u8 playersLanguage[MAX_BATTLERS_COUNT];
+ u8 playersName[MAX_LINK_PLAYERS][PLAYER_NAME_LENGTH + 1];
+ u8 playersGender[MAX_LINK_PLAYERS];
+ u32 playersTrainerId[MAX_LINK_PLAYERS];
+ u8 playersLanguage[MAX_LINK_PLAYERS];
rng_value_t rngSeed;
u32 battleFlags;
- u8 playersBattlers[MAX_BATTLERS_COUNT];
+ u8 playersBattlers[MAX_LINK_PLAYERS];
u16 opponentA;
u16 opponentB;
u16 partnerId;
diff --git a/include/strings.h b/include/strings.h
index e09f719d22..06a3a658a2 100644
--- a/include/strings.h
+++ b/include/strings.h
@@ -177,12 +177,7 @@ extern const u8 gMenuText_Toss[];
extern const u8 gMenuText_Give[];
extern const u8 gMenuText_Give2[];
extern const u8 gMenuText_Register[];
-extern const u8 gMenuText_Check[];
-extern const u8 gMenuText_Walk[];
-extern const u8 gMenuText_Deselect[];
-extern const u8 gMenuText_CheckTag[];
extern const u8 gMenuText_Confirm[];
-extern const u8 gMenuText_Show[];
extern const u8 gMenuText_Give2[];
extern const u8 gText_EggNickname[];
@@ -319,15 +314,10 @@ extern const u8 gText_ThrewAwayVar2Var1s[];
extern const u8 gText_CantWriteMail[];
extern const u8 gText_NoPokemon[];
extern const u8 gText_Var1CantBeHeld[];
-extern const u8 gText_Var1CantBeHeldHere[];
extern const u8 gText_CantBuyKeyItem[];
extern const u8 gText_HowManyToSell[];
extern const u8 gText_ICanPayVar1[];
extern const u8 gText_TurnedOverVar1ForVar2[];
-extern const u8 gText_DepositHowManyVar1[];
-extern const u8 gText_CantStoreImportantItems[];
-extern const u8 gText_DepositedVar2Var1s[];
-extern const u8 gText_NoRoomForItems[];
extern const u8 gText_ThreeDashes[];
extern const u8 *const gPocketNamesStringsTable[];
@@ -451,28 +441,12 @@ extern const u8 gBirchDexRatingText_LessThan190[];
extern const u8 gBirchDexRatingText_LessThan200[];
extern const u8 gBirchDexRatingText_DexCompleted[];
-// player pc text
+// player PC text
extern const u8 gText_WhatWouldYouLike[];
extern const u8 gText_NoMailHere[];
-
-extern const u8 gText_TakeOutItemsFromPC[];
-extern const u8 gText_StoreItemsInPC[];
-extern const u8 gText_ThrowAwayItemsInPC[];
extern const u8 gText_GoBackPrevMenu[];
-
-extern const u8 gText_ItemStorage[];
-extern const u8 gText_Mailbox[];
-extern const u8 gText_Decoration[];
-extern const u8 gText_TurnOff[];
-
-extern const u8 gText_WithdrawItem[];
-extern const u8 gText_DepositItem[];
-extern const u8 gText_TossItem[];
extern const u8 gText_Cancel[];
-extern const u8 gText_Read[];
-extern const u8 gText_MoveToBag[];
-extern const u8 gText_Give2[];
extern const u8 gText_Cancel2[];
extern const u8 gText_NoItems[];
@@ -482,12 +456,8 @@ extern const u8 gText_BagIsFull[];
extern const u8 gText_MailToBagMessageErased[];
extern const u8 gText_GoBackPrevMenu[];
-extern const u8 gText_WithdrawHowManyItems[];
-extern const u8 gText_WithdrawXItems[];
extern const u8 gText_TossHowManyVar1s[];
extern const u8 gText_ThrewAwayVar2Var1s[];
-extern const u8 gText_NoRoomInBag[];
-extern const u8 gText_TooImportantToToss[];
extern const u8 gText_ConfirmTossItems[];
extern const u8 gText_MoveVar1Where[];
@@ -510,16 +480,6 @@ extern const u8 gText_HealthboxGender_None[];
extern const u8 gText_HealthboxGender_Male[];
extern const u8 gText_HealthboxGender_Female[];
-extern const u8 gText_99TimesPlus[];
-extern const u8 gText_1MinutePlus[];
-extern const u8 gText_SpaceSeconds[];
-extern const u8 gText_SpaceTimes[];
-
-extern const u8 gText_BigGuy[];
-extern const u8 gText_BigGirl[];
-extern const u8 gText_Son[];
-extern const u8 gText_Daughter[];
-
// Multichoice strings
extern const u8 gText_Exit[];
extern const u8 gText_1F[];
@@ -540,73 +500,6 @@ extern const u8 gText_B4F[];
extern const u8 gText_Rooftop[];
extern const u8 gText_ElevatorNowOn[];
-extern const u8 gText_BlueFlute[];
-extern const u8 gText_YellowFlute[];
-extern const u8 gText_RedFlute[];
-extern const u8 gText_WhiteFlute[];
-extern const u8 gText_BlackFlute[];
-extern const u8 gText_PrettyChair[];
-extern const u8 gText_PrettyDesk[];
-
-extern const u8 gText_0Pts[];
-extern const u8 gText_10Pts[];
-extern const u8 gText_20Pts[];
-extern const u8 gText_30Pts[];
-extern const u8 gText_40Pts[];
-extern const u8 gText_50Pts[];
-extern const u8 gText_60Pts[];
-extern const u8 gText_70Pts[];
-extern const u8 gText_80Pts[];
-extern const u8 gText_90Pts[];
-extern const u8 gText_100Pts[];
-extern const u8 gText_QuestionMark[];
-
-extern const u8 gText_KissPoster16BP[];
-extern const u8 gText_KissCushion32BP[];
-extern const u8 gText_SmoochumDoll32BP[];
-extern const u8 gText_TogepiDoll48BP[];
-extern const u8 gText_MeowthDoll48BP[];
-extern const u8 gText_ClefairyDoll48BP[];
-extern const u8 gText_DittoDoll48BP[];
-extern const u8 gText_CyndaquilDoll80BP[];
-extern const u8 gText_ChikoritaDoll80BP[];
-extern const u8 gText_TotodileDoll80BP[];
-
-extern const u8 gText_LaprasDoll128BP[];
-extern const u8 gText_SnorlaxDoll128BP[];
-extern const u8 gText_VenusaurDoll256BP[];
-extern const u8 gText_CharizardDoll256BP[];
-extern const u8 gText_BlastoiseDoll256BP[];
-
-extern const u8 gText_Protein1BP[];
-extern const u8 gText_Calcium1BP[];
-extern const u8 gText_Iron1BP[];
-extern const u8 gText_Zinc1BP[];
-extern const u8 gText_Carbos1BP[];
-extern const u8 gText_HpUp1BP[];
-
-extern const u8 gText_Leftovers48BP[];
-extern const u8 gText_WhiteHerb48BP[];
-extern const u8 gText_QuickClaw48BP[];
-extern const u8 gText_MentalHerb48BP[];
-extern const u8 gText_BrightPowder64BP[];
-extern const u8 gText_ChoiceBand64BP[];
-extern const u8 gText_KingsRock64BP[];
-extern const u8 gText_FocusBand64BP[];
-extern const u8 gText_ScopeLens64BP[];
-
-extern const u8 gText_EnergyPowder50[];
-extern const u8 gText_EnergyRoot80[];
-extern const u8 gText_HealPowder50[];
-extern const u8 gText_RevivalHerb300[];
-extern const u8 gText_Protein1000[];
-extern const u8 gText_Iron1000[];
-extern const u8 gText_Carbos1000[];
-extern const u8 gText_Calcium1000[];
-extern const u8 gText_Zinc1000[];
-extern const u8 gText_HPUp1000[];
-extern const u8 gText_PPUp3000[];
-
extern const u8 gText_BattleTower2[];
extern const u8 gText_BattleDome[];
extern const u8 gText_BattlePalace[];
@@ -617,28 +510,6 @@ extern const u8 gText_BattlePyramid[];
extern const u8 gText_RankingHall[];
extern const u8 gText_ExchangeService[];
-// Battle Frontier Move Tutors
-extern const u8 gText_Softboiled16BP[];
-extern const u8 gText_SeismicToss24BP[];
-extern const u8 gText_DreamEater24BP[];
-extern const u8 gText_MegaPunch24BP[];
-extern const u8 gText_MegaKick48BP[];
-extern const u8 gText_BodySlam48BP[];
-extern const u8 gText_RockSlide48BP[];
-extern const u8 gText_Counter48BP[];
-extern const u8 gText_ThunderWave48BP[];
-extern const u8 gText_SwordsDance48BP[];
-extern const u8 gText_DefenseCurl16BP[];
-extern const u8 gText_Snore24BP[];
-extern const u8 gText_MudSlap24BP[];
-extern const u8 gText_Swift24BP[];
-extern const u8 gText_IcyWind24BP[];
-extern const u8 gText_Endure48BP[];
-extern const u8 gText_PsychUp48BP[];
-extern const u8 gText_IcePunch48BP[];
-extern const u8 gText_ThunderPunch48BP[];
-extern const u8 gText_FirePunch48BP[];
-
extern const u8 gText_SlateportCity[];
extern const u8 gText_BattleFrontier[];
extern const u8 gText_SouthernIsland[];
@@ -817,26 +688,12 @@ extern const u8 gText_Gabby[];
extern const u8 gText_Anna[];
extern const u8 gText_DadsAdvice[];
-extern const u8 gText_CantDismountBike[];
-extern const u8 gText_ItemFinderNothing[];
-extern const u8 gText_ItemFinderNearby[];
-extern const u8 gText_ItemFinderOnTop[];
-extern const u8 gText_CoinCase[];
-extern const u8 gText_PowderQty[];
-extern const u8 gText_BootedUpHM[];
-extern const u8 gText_BootedUpTM[];
-extern const u8 gText_TMHMContainedVar1[];
extern const u8 gText_PlayerUsedVar2[];
extern const u8 gText_RepelEffectsLingered[];
extern const u8 gText_LureEffectsLingered[];
-extern const u8 gText_UsedVar2WildLured[];
-extern const u8 gText_UsedVar2WildRepelled[];
extern const u8 gText_BoxFull[];
extern const u8 gText_WontHaveEffect[];
extern const u8 gText_NextFusionMon[];
-extern const u8 gText_PlayedPokeFluteCatchy[];
-extern const u8 gText_PlayedPokeFlute[];
-extern const u8 gText_PokeFluteAwakenedMon[];
extern const u8 gText_LevelSymbol[];
extern const u8 gText_PkmnInfo[];
@@ -935,31 +792,13 @@ extern const u8 gText_SomeonesPC[];
extern const u8 gText_PlayersPC[];
extern const u8 gText_WhichPCShouldBeAccessed[];
-extern const u8 gText_Petalburg[];
-extern const u8 gText_Slateport[];
-extern const u8 gText_Enter2[];
extern const u8 gText_Info2[];
-extern const u8 gText_WhatsAContest[];
-extern const u8 gText_TypesOfContests[];
-extern const u8 gText_Ranks[];
extern const u8 gText_Decoration2[];
extern const u8 gText_PackUp[];
extern const u8 gText_Registry[];
extern const u8 gText_Information[];
-extern const u8 gText_Mach[];
-extern const u8 gText_Acro[];
-extern const u8 gText_Psn[];
-extern const u8 gText_Par[];
-extern const u8 gText_Slp[];
-extern const u8 gText_Brn[];
-extern const u8 gText_Frz[];
-extern const u8 gText_Dewford[];
-extern const u8 gText_SawIt[];
-extern const u8 gText_NotYet[];
extern const u8 gText_Yes[];
extern const u8 gText_No[];
-extern const u8 gText_Challenge[];
-extern const u8 gText_Info3[];
// Pokédex strings
extern const u8 gText_SearchForPkmnBasedOnParameters[];
@@ -1010,41 +849,7 @@ extern const u8 gText_DexEmptyString[];
extern const u8 gText_DexSearchDontSpecify[];
extern const u8 gText_DexSearchTypeNone[];
-extern const u8 gText_FreshWaterAndPrice[];
-extern const u8 gText_SodaPopAndPrice[];
-extern const u8 gText_LemonadeAndPrice[];
-extern const u8 gText_HowToRide[];
-extern const u8 gText_HowToTurn[];
-extern const u8 gText_SandySlopes[];
-extern const u8 gText_Wheelies[];
-extern const u8 gText_BunnyHops[];
-extern const u8 gText_Jump[];
-extern const u8 gText_Satisfied[];
-extern const u8 gText_Dissatisfied[];
-extern const u8 gText_DeepSeaTooth[];
-extern const u8 gText_DeepSeaScale[];
-extern const u8 gText_BlueFlute2[];
-extern const u8 gText_YellowFlute2[];
-extern const u8 gText_RedFlute2[];
-extern const u8 gText_WhiteFlute2[];
-extern const u8 gText_BlackFlute2[];
-extern const u8 gText_GlassChair[];
-extern const u8 gText_GlassDesk[];
-extern const u8 gText_TreeckoDollAndPrice[];
-extern const u8 gText_TorchicDollAndPrice[];
-extern const u8 gText_MudkipDollAndPrice[];
-extern const u8 gText_TM32AndPrice[];
-extern const u8 gText_TM29AndPrice[];
-extern const u8 gText_TM35AndPrice[];
-extern const u8 gText_TM24AndPrice[];
-extern const u8 gText_TM13AndPrice[];
-extern const u8 gText_50CoinsAndPrice[];
-extern const u8 gText_500CoinsAndPrice[];
-extern const u8 gText_Excellent2[];
-extern const u8 gText_NotSoGood[];
extern const u8 gText_LilycoveCity[];
-extern const u8 gText_Right[];
-extern const u8 gText_Left[];
extern const u8 gText_RedShard[];
extern const u8 gText_YellowShard[];
extern const u8 gText_BlueShard[];
@@ -1055,79 +860,20 @@ extern const u8 gText_ReadyToStart[];
extern const u8 gText_Record2[];
extern const u8 gText_Rest[];
extern const u8 gText_Retire[];
-extern const u8 gText_RedTent[];
-extern const u8 gText_BlueTent[];
extern const u8 gText_TradeCenter[];
extern const u8 gText_Colosseum[];
extern const u8 gText_RecordCorner[];
-extern const u8 gText_SingleBattle[];
-extern const u8 gText_DoubleBattle[];
-extern const u8 gText_MultiBattle[];
extern const u8 gText_BerryCrush3[];
-extern const u8 gText_PokemonJump[];
-extern const u8 gText_DodrioBerryPicking[];
-extern const u8 gText_JoinGroup[];
-extern const u8 gText_BecomeLeader[];
-extern const u8 gText_NormalRank[];
-extern const u8 gText_SuperRank[];
-extern const u8 gText_HyperRank[];
-extern const u8 gText_MasterRank[];
-extern const u8 gText_BattleBag[];
-extern const u8 gText_HeldItem[];
-extern const u8 gText_LinkContest[];
-extern const u8 gText_AboutE_Mode[];
-extern const u8 gText_AboutG_Mode[];
-extern const u8 gText_E_Mode[];
-extern const u8 gText_G_Mode[];
extern const u8 gText_Blank[];
-extern const u8 gText_5BP[];
-extern const u8 gText_10BP[];
-extern const u8 gText_15BP[];
-extern const u8 gText_ClawFossil[];
-extern const u8 gText_RootFossil[];
-extern const u8 gText_No4[];
-extern const u8 gText_TwoStyles[];
-extern const u8 gText_Lv50_3[];
-extern const u8 gText_OpenLevel2[];
-extern const u8 gText_MonTypeAndNo[];
-extern const u8 gText_HoldItems[];
-extern const u8 gText_Symbols2[];
-extern const u8 gText_Record3[];
-extern const u8 gText_BattlePts[];
extern const u8 gText_BattleRules[];
extern const u8 gText_JudgeMind[];
extern const u8 gText_JudgeSkill[];
extern const u8 gText_JudgeBody[];
-extern const u8 gText_TowerInfo[];
-extern const u8 gText_BattleMon[];
-extern const u8 gText_BattleSalon[];
-extern const u8 gText_MultiLink2[];
-extern const u8 gText_Matchup[];
-extern const u8 gText_TourneyTree[];
-extern const u8 gText_DoubleKO[];
extern const u8 gText_BasicRules[];
extern const u8 gText_SwapPartners[];
extern const u8 gText_SwapNumber[];
extern const u8 gText_SwapNotes[];
-extern const u8 gText_OpenLevel3[];
-extern const u8 gText_PyramidPokemon[];
-extern const u8 gText_PyramidTrainers[];
-extern const u8 gText_PyramidMaze[];
-extern const u8 gText_BattleBag2[];
-extern const u8 gText_PokenavAndBag[];
-extern const u8 gText_HeldItems[];
-extern const u8 gText_PokemonOrder[];
extern const u8 gText_GoOn[];
-extern const u8 gText_Red[];
-extern const u8 gText_Blue[];
-extern const u8 gText_IllBattleNow[];
-extern const u8 gText_IWon[];
-extern const u8 gText_ILost[];
-extern const u8 gText_IWontTell[];
-extern const u8 gText_CaveOfOrigin[];
-extern const u8 gText_MtPyre[];
-extern const u8 gText_SkyPillar[];
-extern const u8 gText_DontRemember[];
extern const u8 gText_BattlePokemon[];
extern const u8 gText_NormalTagMatch[];
extern const u8 gText_VarietyTagMatch[];
@@ -1151,19 +897,6 @@ extern const u8 CableClub_Text_YouMayBattleHere[];
extern const u8 CableClub_Text_CanMixRecords[];
extern const u8 CableClub_Text_CanMakeBerryPowder[];
-// Rotom Catalog text
-extern const u8 gText_LightBulb[];
-extern const u8 gText_MicrowaveOven[];
-extern const u8 gText_WashingMachine[];
-extern const u8 gText_Refrigerator[];
-extern const u8 gText_ElectricFan[];
-extern const u8 gText_LawnMower[];
-extern const u8 gText_Exit[];
-
-// Zygarde Cube text
-extern const u8 gText_ChangeForm[];
-extern const u8 gText_ChangeAbility[];
-
// Frontier records.
extern const u8 gText_WinStreak[];
extern const u8 gText_Record[];
@@ -1888,21 +1621,8 @@ extern const u8 gText_NotAble2[];
extern const u8 gText_Learned[];
extern const u8 gText_Have[];
extern const u8 gText_DontHave[];
-extern const u8 gText_Take[];
-extern const u8 gText_Mail[];
-extern const u8 gText_Take2[];
-extern const u8 gText_Read2[];
extern const u8 gText_Cancel2[];
-extern const u8 gText_Shift[];
-extern const u8 gText_SendOut[];
-extern const u8 gText_Enter[];
-extern const u8 gText_NoEntry[];
-extern const u8 gText_Store[];
extern const u8 gText_Register[];
-extern const u8 gText_Trade4[];
-extern const u8 gText_Summary5[];
-extern const u8 gText_Switch2[];
-extern const u8 gText_Item[];
extern const u8 gText_NotPkmnOtherTrainerWants[];
extern const u8 gText_ThatIsntAnEgg[];
extern const u8 gText_OtherTrainersPkmnCantBeTraded[];
@@ -2698,9 +2418,6 @@ extern const u8 gText_ExpShareOff[];
extern const u8 gText_BasePointsResetToZero[];
-extern const u8 gText_Fertilize[];
-extern const u8 gText_PlantBerry[];
-
// Map name pop-up
extern const u8 gText_AM[];
extern const u8 gText_PM[];
diff --git a/include/test/battle.h b/include/test/battle.h
index 1a7cb070de..1c044fd6e2 100644
--- a/include/test/battle.h
+++ b/include/test/battle.h
@@ -29,7 +29,7 @@
*
* ASSUMPTIONS
* {
- * ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE);
+ * ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE);
* }
*
* SINGLE_BATTLE_TEST("Stun Spore inflicts paralysis")
@@ -87,7 +87,7 @@
* SINGLE_BATTLE_TEST("Stun Spore does not affect Grass-types")
* {
* GIVEN {
- * ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ * ASSUME(IsPowderMove(MOVE_STUN_SPORE));
* ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS);
* PLAYER(SPECIES_ODDISH); // 1.
* OPPONENT(SPECIES_ODDISH); // 2.
@@ -129,7 +129,7 @@
* PARAMETRIZE { raiseAttack = FALSE; }
* PARAMETRIZE { raiseAttack = TRUE; }
* GIVEN {
- * ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ * ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
* PLAYER(SPECIES_WOBBUFFET);
* OPPONENT(SPECIES_WOBBUFFET);
* } WHEN {
@@ -176,7 +176,7 @@
* Pokémon we can observe the damage of a physical attack with and
* without the burn. To document that this test assumes the attack is
* physical we can use:
- * ASSUME(gMovesInfo[MOVE_WHATEVER].category == DAMAGE_CATEGORY_PHYSICAL);
+ * ASSUME(GetMoveCategory(MOVE_WHATEVER) == DAMAGE_CATEGORY_PHYSICAL);
*
* ASSUMPTIONS
* Should be placed immediately after any #includes and contain any
@@ -186,7 +186,7 @@
* move_effect_poison_hit.c should be:
* ASSUMPTIONS
* {
- * ASSUME(gMovesInfo[MOVE_POISON_STING].effect == EFFECT_POISON_HIT);
+ * ASSUME(GetMoveEffect(MOVE_POISON_STING) == EFFECT_POISON_HIT);
* }
*
* SINGLE_BATTLE_TEST(name, results...) and DOUBLE_BATTLE_TEST(name, results...)
@@ -228,7 +228,7 @@
* PARAMETRIZE { hp = 99; }
* PARAMETRIZE { hp = 33; }
* GIVEN {
- * ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ * ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
* PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); MaxHP(99); HP(hp); }
* OPPONENT(SPECIES_WOBBUFFET);
* } WHEN {
@@ -265,7 +265,7 @@
*
* If the tag is not provided, runs the test 50 times and computes an
* approximate pass ratio.
- * PASSES_RANDOMLY(gMovesInfo[move].accuracy, 100);
+ * PASSES_RANDOMLY(GetMoveAccuracy(move), 100);
* Note that this mode of PASSES_RANDOMLY makes the tests run very
* slowly and should be avoided where possible. If the mechanic you are
* testing is missing its tag, you should add it.
@@ -287,6 +287,16 @@
* GIVEN {
* FLAG_SET(FLAG_SYS_EXAMPLE_FLAG);
*
+ * WITH_CONFIG(configTag, value)
+ * Runs the test with a specified config override. `configTag` must be
+ * of `enum GenConfigTag`
+ * Example:
+ * GIVEN {
+ * WITH_CONFIG(GEN_CONFIG_GALE_WINGS, GEN_6);
+ * }
+ * The `value` may be inferred from a local variable, e.g. set by
+ * PARAMETRIZE.
+ *
* PLAYER(species) and OPPONENT(species)
* Adds the species to the player's or opponent's party respectively.
* The Pokémon can be further customized with the following functions:
@@ -488,6 +498,7 @@
#include "battle.h"
#include "battle_anim.h"
#include "data.h"
+#include "generational_changes.h"
#include "item.h"
#include "random.h"
#include "recorded_battle.h"
@@ -716,6 +727,7 @@ struct BattleTestRunnerState
u16 observedRatio;
u16 trialRatio;
bool8 runRandomly:1;
+ bool8 didRunRandomly:1;
bool8 runGiven:1;
bool8 runWhen:1;
bool8 runScene:1;
@@ -741,7 +753,7 @@ extern struct BattleTestRunnerState *const gBattleTestRunnerState;
/* Test */
#define TO_DO_BATTLE_TEST(_name) \
- TEST("TODO: " _name) \
+ TEST(_name) \
{ \
TO_DO; \
}
@@ -821,6 +833,7 @@ struct moveWithPP {
#define AI_LOG AILogScores(__LINE__)
#define FLAG_SET(flagId) SetFlagForTest(__LINE__, flagId)
+#define WITH_CONFIG(configTag, value) TestSetConfig(__LINE__, configTag, value)
#define PLAYER(species) for (OpenPokemon(__LINE__, B_SIDE_PLAYER, species); gBattleTestRunnerState->data.currentMon; ClosePokemon(__LINE__))
#define OPPONENT(species) for (OpenPokemon(__LINE__, B_SIDE_OPPONENT, species); gBattleTestRunnerState->data.currentMon; ClosePokemon(__LINE__))
@@ -854,6 +867,7 @@ struct moveWithPP {
#define Shadow(isShadow) Shadow_(__LINE__, shadow)
void SetFlagForTest(u32 sourceLine, u16 flagId);
+void TestSetConfig(u32 sourceLine, enum GenConfigTag configTag, u32 value);
void ClearFlagAfterTest(void);
void OpenPokemon(u32 sourceLine, u32 side, u32 species);
void ClosePokemon(u32 sourceLine);
diff --git a/include/test/test.h b/include/test/test.h
index 1a9d8a237e..ccfc589c21 100644
--- a/include/test/test.h
+++ b/include/test/test.h
@@ -95,7 +95,7 @@ s32 Test_MgbaPrintf(const char *fmt, ...);
#define ASSUMPTIONS \
static void Assumptions(void); \
- __attribute__((section(".tests"), used)) static const struct Test sAssumptions = \
+ __attribute__((section(".tests"), used, no_reorder)) static const struct Test sAssumptions = \
{ \
.name = "ASSUMPTIONS: " __FILE__, \
.filename = __FILE__, \
diff --git a/include/text.h b/include/text.h
index 55500868dc..a148410c2f 100644
--- a/include/text.h
+++ b/include/text.h
@@ -21,6 +21,7 @@ enum {
FONT_NARROWER,
FONT_SMALL_NARROWER,
FONT_SHORT_NARROW,
+ FONT_SHORT_NARROWER,
};
// Return values for font functions
diff --git a/map_data_rules.mk b/map_data_rules.mk
index ecad6d3bd3..6712698272 100755
--- a/map_data_rules.mk
+++ b/map_data_rules.mk
@@ -22,12 +22,10 @@ $(DATA_ASM_BUILDDIR)/maps.o: $(DATA_ASM_SUBDIR)/maps.s $(LAYOUTS_DIR)/layouts.in
$(DATA_ASM_BUILDDIR)/map_events.o: $(DATA_ASM_SUBDIR)/map_events.s $(MAPS_DIR)/events.inc $(MAP_EVENTS)
$(PREPROC) $< charmap.txt | $(CPP) -I include - | $(PREPROC) -ie $< charmap.txt | $(AS) $(ASFLAGS) -o $@
-$(DATA_SRC_SUBDIR)/map_group_count.h: $(MAPS_DIR)/headers.inc ;
-
$(MAPS_OUTDIR)/%/header.inc $(MAPS_OUTDIR)/%/events.inc $(MAPS_OUTDIR)/%/connections.inc: $(MAPS_DIR)/%/map.json
$(MAPJSON) map emerald $< $(LAYOUTS_DIR)/layouts.json $(@D)
-$(MAPS_OUTDIR)/connections.inc $(MAPS_OUTDIR)/groups.inc $(MAPS_OUTDIR)/events.inc $(MAPS_OUTDIR)/headers.inc $(INCLUDECONSTS_OUTDIR)/map_groups.h: $(MAPS_DIR)/map_groups.json
+$(MAPS_OUTDIR)/connections.inc $(MAPS_OUTDIR)/groups.inc $(MAPS_OUTDIR)/events.inc $(MAPS_OUTDIR)/headers.inc $(INCLUDECONSTS_OUTDIR)/map_groups.h $(DATA_SRC_SUBDIR)/map_group_count.h: $(MAPS_DIR)/map_groups.json
$(MAPJSON) groups emerald $< $(MAPS_OUTDIR) $(INCLUDECONSTS_OUTDIR)
$(LAYOUTS_OUTDIR)/layouts.inc $(LAYOUTS_OUTDIR)/layouts_table.inc $(INCLUDECONSTS_OUTDIR)/layouts.h: $(LAYOUTS_DIR)/layouts.json
diff --git a/src/AgbRfu_LinkManager.c b/src/AgbRfu_LinkManager.c
index d696c01d3c..b53b69c48b 100644
--- a/src/AgbRfu_LinkManager.c
+++ b/src/AgbRfu_LinkManager.c
@@ -59,7 +59,9 @@ void rfu_LMAN_REQ_sendData(bool8 clockChangeFlag)
clockChangeFlag = FALSE;
}
else
+ {
lman.parentAck_flag = 0;
+ }
rfu_REQ_sendData(clockChangeFlag);
}
diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c
index 3c031de092..828b7b7c94 100644
--- a/src/battle_ai_main.c
+++ b/src/battle_ai_main.c
@@ -278,7 +278,7 @@ u32 BattleAI_ChooseMoveOrAction(void)
ret = ChooseMoveOrAction_Doubles(sBattler_AI);
// Clear protect structures, some flags may be set during AI calcs
- // e.g. pranksterElevated from GetMovePriority
+ // e.g. pranksterElevated from GetBattleMovePriority
memset(&gProtectStructs, 0, MAX_BATTLERS_COUNT * sizeof(struct ProtectStruct));
#if TESTING
TestRunner_Battle_CheckAiMoveScores(sBattler_AI);
@@ -399,7 +399,7 @@ static u32 Ai_SetMoveAccuracy(struct AiLogicData *aiData, u32 battlerAtk, u32 ba
u32 accuracy;
u32 abilityAtk = aiData->abilities[battlerAtk];
u32 abilityDef = aiData->abilities[battlerDef];
- if (abilityAtk == ABILITY_NO_GUARD || abilityDef == ABILITY_NO_GUARD || gMovesInfo[move].accuracy == 0) // Moves with accuracy 0 or no guard ability always hit.
+ if (abilityAtk == ABILITY_NO_GUARD || abilityDef == ABILITY_NO_GUARD || GetMoveAccuracy(move) == 0) // Moves with accuracy 0 or no guard ability always hit.
accuracy = 100;
else
accuracy = GetTotalAccuracy(battlerAtk, battlerDef, move, abilityAtk, abilityDef, aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef]);
@@ -431,9 +431,9 @@ static void SetBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u3
u8 effectiveness = AI_EFFECTIVENESS_x0;
move = moves[moveIndex];
- if (move != 0
- && move != 0xFFFF
- //&& gMovesInfo[move].power != 0 /* we want to get effectiveness and accuracy of status moves */
+ if (move != MOVE_NONE
+ && move != MOVE_UNAVAILABLE
+ //&& !IsBattleMoveStatus(move) /* we want to get effectiveness and accuracy of status moves */
&& !(aiData->moveLimitations[battlerAtk] & (1u << moveIndex)))
{
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE, weather, rollType);
@@ -661,7 +661,8 @@ static inline bool32 ShouldConsiderMoveForBattler(u32 battlerAi, u32 battlerDef,
{
if (battlerAi == BATTLE_PARTNER(battlerDef))
{
- if (gMovesInfo[move].target == MOVE_TARGET_BOTH || gMovesInfo[move].target == MOVE_TARGET_OPPONENTS_FIELD)
+ u32 target = GetBattlerMoveTargetType(battlerAi, move);
+ if (target == MOVE_TARGET_BOTH || target == MOVE_TARGET_OPPONENTS_FIELD)
return FALSE;
}
return TRUE;
@@ -707,8 +708,8 @@ static inline void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u3
static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
// move data
- s8 atkPriority = GetMovePriority(battlerAtk, move);
- u32 moveEffect = gMovesInfo[move].effect;
+ s8 atkPriority = GetBattleMovePriority(battlerAtk, move);
+ u32 moveEffect = GetMoveEffect(move);
s32 moveType;
u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move);
struct AiLogicData *aiData = AI_DATA;
@@ -722,9 +723,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
return score;
SetTypeBeforeUsingMove(move, battlerAtk);
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
- if (gMovesInfo[move].powderMove && !IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef]))
+ if (IsPowderMove(move) && !IsAffectedByPowder(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef]))
RETURN_SCORE_MINUS(10);
if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move))
@@ -799,11 +800,11 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
RETURN_SCORE_MINUS(20);
break;
case ABILITY_JUSTIFIED:
- if (moveType == TYPE_DARK && !IS_MOVE_STATUS(move))
+ if (moveType == TYPE_DARK && !IsBattleMoveStatus(move))
RETURN_SCORE_MINUS(10);
break;
case ABILITY_RATTLED:
- if (!IS_MOVE_STATUS(move)
+ if (!IsBattleMoveStatus(move)
&& (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG))
RETURN_SCORE_MINUS(10);
break;
@@ -820,7 +821,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
RETURN_SCORE_MINUS(10);
break;
case ABILITY_MAGIC_BOUNCE:
- if (gMovesInfo[move].magicCoatAffected)
+ if (MoveCanBeBouncedBack(move))
RETURN_SCORE_MINUS(20);
break;
case ABILITY_CONTRARY:
@@ -889,7 +890,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
RETURN_SCORE_MINUS(20);
break;
case ABILITY_MAGIC_BOUNCE:
- if (gMovesInfo[move].magicCoatAffected && moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD))
+ if (MoveCanBeBouncedBack(move) && moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD))
RETURN_SCORE_MINUS(20);
break;
case ABILITY_SWEET_VEIL:
@@ -910,7 +911,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
// gen7+ dark type mons immune to priority->elevated moves from prankster
if (B_PRANKSTER_DARK_TYPES >= GEN_7 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK)
- && aiData->abilities[battlerAtk] == ABILITY_PRANKSTER && IS_MOVE_STATUS(move)
+ && aiData->abilities[battlerAtk] == ABILITY_PRANKSTER && IsBattleMoveStatus(move)
&& !(moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER)))
RETURN_SCORE_MINUS(10);
@@ -936,7 +937,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
// the following checks apply to any target (including user)
// throat chop check
- if (gDisableStructs[battlerAtk].throatChopTimer && gMovesInfo[move].soundMove)
+ if (gDisableStructs[battlerAtk].throatChopTimer && IsSoundMove(move))
return 0; // Can't even select move at all
// heal block check
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move))
@@ -955,7 +956,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
RETURN_SCORE_MINUS(30);
}
- if (!IS_MOVE_STATUS(move))
+ if (!IsBattleMoveStatus(move))
{
if (weather & B_WEATHER_SUN_PRIMAL)
{
@@ -974,7 +975,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
switch (moveEffect)
{
case EFFECT_HIT: // only applies to Vital Throw
- if (gMovesInfo[move].priority < 0 && AI_IsFaster(battlerAtk, battlerDef, move) && aiData->hpPercents[battlerAtk] < 40)
+ if (GetBattleMovePriority(battlerAtk, move) < 0 && AI_IsFaster(battlerAtk, battlerDef, move) && aiData->hpPercents[battlerAtk] < 40)
ADJUST_SCORE(-2); // don't want to move last
break;
default:
@@ -982,6 +983,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_SLEEP:
if (!AI_CanPutToSleep(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove))
ADJUST_SCORE(-10);
+ if (PartnerMoveActivatesSleepClause(aiData->partnerMove))
+ ADJUST_SCORE(-20);
break;
case EFFECT_EXPLOSION:
if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_WILL_SUICIDE))
@@ -1661,7 +1664,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
else
{
- if (AtMaxHp(battlerAtk))
+ if (AI_BattlerAtMaxHp(battlerAtk))
ADJUST_SCORE(-10);
else if (aiData->hpPercents[battlerAtk] >= 80)
ADJUST_SCORE(-5); // do it if nothing better
@@ -1694,7 +1697,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (!isDoubleBattle
|| !IsBattlerAlive(BATTLE_PARTNER(battlerAtk))
|| PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove)
- || (aiData->partnerMove != MOVE_NONE && IS_MOVE_STATUS(aiData->partnerMove))
+ || (aiData->partnerMove != MOVE_NONE && IsBattleMoveStatus(aiData->partnerMove))
|| *(gBattleStruct->monToSwitchIntoId + BATTLE_PARTNER(battlerAtk)) != PARTY_SIZE) //Partner is switching out.
ADJUST_SCORE(-10);
break;
@@ -1790,17 +1793,17 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
break;
case EFFECT_CONVERSION:
//Check first move type
- if (IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[gBattleMons[battlerAtk].moves[0]].type))
+ if (IS_BATTLER_OF_TYPE(battlerAtk, GetMoveType(gBattleMons[battlerAtk].moves[0])))
ADJUST_SCORE(-10);
break;
case EFFECT_REST:
- if (!CanBeSlept(battlerAtk, aiData->abilities[battlerAtk]))
+ if (!CanBeSlept(battlerAtk, aiData->abilities[battlerAtk], NOT_BLOCKED_BY_SLEEP_CLAUSE))
ADJUST_SCORE(-10);
//fallthrough
case EFFECT_RESTORE_HP:
case EFFECT_SOFTBOILED:
case EFFECT_ROOST:
- if (AtMaxHp(battlerAtk))
+ if (AI_BattlerAtMaxHp(battlerAtk))
ADJUST_SCORE(-10);
else if (aiData->hpPercents[battlerAtk] >= 90)
ADJUST_SCORE(-9); //No point in healing, but should at least do it if nothing better
@@ -1810,7 +1813,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_MOONLIGHT:
if ((AI_GetWeather(aiData) & (B_WEATHER_RAIN | B_WEATHER_SANDSTORM | B_WEATHER_HAIL | B_WEATHER_SNOW | B_WEATHER_FOG)))
ADJUST_SCORE(-3);
- else if (AtMaxHp(battlerAtk))
+ else if (AI_BattlerAtMaxHp(battlerAtk))
ADJUST_SCORE(-10);
else if (aiData->hpPercents[battlerAtk] >= 90)
ADJUST_SCORE(-9); //No point in healing, but should at least do it if nothing better
@@ -1820,7 +1823,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
else if (battlerDef == BATTLE_PARTNER(battlerAtk))
break; //Always heal your ally
- else if (AtMaxHp(battlerAtk))
+ else if (AI_BattlerAtMaxHp(battlerAtk))
ADJUST_SCORE(-10);
else if (aiData->hpPercents[battlerAtk] >= 90)
ADJUST_SCORE(-8); //No point in healing, but should at least do it if nothing better
@@ -1873,13 +1876,15 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_DESTINY_BOND:
+ if (DoesDestinyBondFail(battlerAtk))
+ ADJUST_SCORE(-10);
if (gBattleMons[battlerDef].status2 & STATUS2_DESTINY_BOND)
ADJUST_SCORE(-10);
else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
ADJUST_SCORE(-10);
break;
case EFFECT_HEAL_BELL:
- if (!AnyPartyMemberStatused(battlerAtk, gMovesInfo[move].soundMove) || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
+ if (!AnyPartyMemberStatused(battlerAtk, IsSoundMove(move)) || PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
ADJUST_SCORE(-10);
break;
case EFFECT_ENDURE:
@@ -1981,7 +1986,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (isDoubleBattle)
{
- if (IsHazardMoveEffect(gMovesInfo[aiData->partnerMove].effect) // partner is going to set up hazards
+ if (IsHazardMoveEffect(GetMoveEffect(aiData->partnerMove)) // partner is going to set up hazards
&& AI_IsFaster(BATTLE_PARTNER(battlerAtk), battlerAtk, aiData->partnerMove)) // partner is going to set up before the potential Defog
{
ADJUST_SCORE(-10);
@@ -2011,7 +2016,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_SEMI_INVULNERABLE:
if (predictedMove != MOVE_NONE
&& AI_IsSlower(battlerAtk, battlerDef, move)
- && gMovesInfo[predictedMove].effect == EFFECT_SEMI_INVULNERABLE)
+ && GetMoveEffect(predictedMove) == EFFECT_SEMI_INVULNERABLE)
ADJUST_SCORE(-10); // Don't Fly/dig/etc if opponent is going to fly/dig/etc after you
if (BattlerWillFaintFromWeather(battlerAtk, aiData->abilities[battlerAtk])
@@ -2077,6 +2082,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
else if (!AI_CanPutToSleep(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove))
ADJUST_SCORE(-10);
+ if (PartnerMoveActivatesSleepClause(aiData->partnerMove))
+ ADJUST_SCORE(-20);
break;
case EFFECT_SKILL_SWAP:
if (aiData->abilities[battlerAtk] == ABILITY_NONE || aiData->abilities[battlerDef] == ABILITY_NONE
@@ -2241,7 +2248,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (isDoubleBattle && gBattleMons[BATTLE_PARTNER(battlerAtk)].hp > 0)
{
if (aiData->partnerMove != MOVE_NONE
- && gMovesInfo[aiData->partnerMove].effect == EFFECT_PLEDGE
+ && GetMoveEffect(aiData->partnerMove) == EFFECT_PLEDGE
&& move != aiData->partnerMove) // Different pledge moves
{
if (gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & (STATUS1_SLEEP | STATUS1_FREEZE))
@@ -2350,12 +2357,15 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_SOAK:
+ {
+ u32 types[3];
+ GetBattlerTypes(battlerDef, FALSE, types);
+ // TODO: Use the type of the move like 'VARIOUS_TRY_SOAK'?
if (PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove)
- || (GetBattlerType(battlerDef, 0, FALSE) == TYPE_WATER
- && GetBattlerType(battlerDef, 1, FALSE) == TYPE_WATER
- && GetBattlerType(battlerDef, 2, FALSE) == TYPE_MYSTERY))
+ || (types[0] == TYPE_WATER && types[1] == TYPE_WATER && types[2] == TYPE_MYSTERY))
ADJUST_SCORE(-10); // target is already water-only
break;
+ }
case EFFECT_THIRD_TYPE:
switch (move)
{
@@ -2381,7 +2391,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)
return 0; // cannot even select
- if (AtMaxHp(battlerDef))
+ if (AI_BattlerAtMaxHp(battlerDef))
ADJUST_SCORE(-10);
else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2)
ADJUST_SCORE(-5);
@@ -2412,6 +2422,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_DO_NOTHING:
+ case EFFECT_HOLD_HANDS:
+ case EFFECT_CELEBRATE:
+ case EFFECT_HAPPY_HOUR:
ADJUST_SCORE(-10);
break;
case EFFECT_INSTRUCT:
@@ -2423,7 +2436,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
instructedMove = gLastMoves[battlerDef];
if (instructedMove == MOVE_NONE
- || gMovesInfo[instructedMove].instructBanned
+ || IsMoveInstructBanned(instructedMove)
|| MoveHasAdditionalEffectSelf(instructedMove, MOVE_EFFECT_RECHARGE)
|| IsZMove(instructedMove)
|| (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF)
@@ -2470,7 +2483,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_SUCKER_PUNCH:
if (predictedMove != MOVE_NONE)
{
- if (IS_MOVE_STATUS(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move)) // Opponent going first
+ if (IsBattleMoveStatus(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move)) // Opponent going first
ADJUST_SCORE(-10);
}
break;
@@ -2511,8 +2524,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-4);
break;
//TODO
- //case EFFECT_PLASMA_FISTS:
- //break;
//case EFFECT_SHELL_TRAP:
//break;
//case EFFECT_BEAK_BLAST:
@@ -2547,8 +2558,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_JUNGLE_HEALING:
- if (AtMaxHp(battlerAtk)
- && AtMaxHp(BATTLE_PARTNER(battlerAtk))
+ if (AI_BattlerAtMaxHp(battlerAtk)
+ && AI_BattlerAtMaxHp(BATTLE_PARTNER(battlerAtk))
&& !(gBattleMons[battlerAtk].status1 & STATUS1_ANY)
&& !(gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY))
ADJUST_SCORE(-10);
@@ -2571,7 +2582,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
break;
case EFFECT_UPPER_HAND:
- if (predictedMove == MOVE_NONE || IS_MOVE_STATUS(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move) || GetMovePriority(battlerDef, predictedMove) < 1 || GetMovePriority(battlerDef, predictedMove) > 3) // Opponent going first or not using priority move
+ if (predictedMove == MOVE_NONE || IsBattleMoveStatus(predictedMove) || AI_IsSlower(battlerAtk, battlerDef, move) || GetBattleMovePriority(battlerDef, predictedMove) < 1 || GetBattleMovePriority(battlerDef, predictedMove) > 3) // Opponent going first or not using priority move
ADJUST_SCORE(-10);
break;
case EFFECT_PLACEHOLDER:
@@ -2607,10 +2618,10 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef))
return score;
- if (gMovesInfo[move].power == 0)
- return score; // can't make anything faint with no power
+ if (IsBattleMoveStatus(move))
+ return score; // status moves aren't accounted here
- if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, movesetIndex, 0) && gMovesInfo[move].effect != EFFECT_EXPLOSION)
+ if (CanIndexMoveFaintTarget(battlerAtk, battlerDef, movesetIndex, 0) && GetMoveEffect(move) != EFFECT_EXPLOSION)
{
if (AI_IsFaster(battlerAtk, battlerDef, move))
ADJUST_SCORE(FAST_KILL);
@@ -2619,7 +2630,7 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
else if (CanTargetFaintAi(battlerDef, battlerAtk)
&& GetWhichBattlerFasterOrTies(battlerAtk, battlerDef, TRUE) != AI_IS_FASTER
- && GetMovePriority(battlerAtk, move) > 0)
+ && GetBattleMovePriority(battlerAtk, move) > 0)
{
ADJUST_SCORE(LAST_CHANCE);
}
@@ -2631,29 +2642,30 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
// move data
- u32 moveType = gMovesInfo[move].type;
- u32 effect = gMovesInfo[move].effect;
+ u32 moveType = GetMoveType(move);
+ u32 effect = GetMoveEffect(move);
u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move);
// ally data
u32 battlerAtkPartner = BATTLE_PARTNER(battlerAtk);
struct AiLogicData *aiData = AI_DATA;
u32 atkPartnerAbility = aiData->abilities[BATTLE_PARTNER(battlerAtk)];
u32 atkPartnerHoldEffect = aiData->holdEffects[BATTLE_PARTNER(battlerAtk)];
- bool32 partnerProtecting = (gMovesInfo[aiData->partnerMove].effect == EFFECT_PROTECT);
+ u32 partnerEffect = GetMoveEffect(aiData->partnerMove);
+ bool32 partnerProtecting = (partnerEffect == EFFECT_PROTECT);
bool32 attackerHasBadAbility = (gAbilitiesInfo[aiData->abilities[battlerAtk]].aiRating < 0);
bool32 partnerHasBadAbility = (gAbilitiesInfo[atkPartnerAbility].aiRating < 0);
u32 predictedMove = aiData->lastUsedMove[battlerDef];
SetTypeBeforeUsingMove(move, battlerAtk);
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
// check what effect partner is using
if (aiData->partnerMove != 0)
{
- switch (gMovesInfo[aiData->partnerMove].effect)
+ switch (partnerEffect)
{
case EFFECT_HELPING_HAND:
- if (IS_MOVE_STATUS(move))
+ if (IsBattleMoveStatus(move))
ADJUST_SCORE(-7);
break;
case EFFECT_PERISH_SONG:
@@ -2677,7 +2689,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
} // check partner move effect
// Adjust for always crit moves
- if (gMovesInfo[aiData->partnerMove].alwaysCriticalHit && aiData->abilities[battlerAtk] == ABILITY_ANGER_POINT)
+ if (MoveAlwaysCrits(aiData->partnerMove) && aiData->abilities[battlerAtk] == ABILITY_ANGER_POINT)
{
if (AI_IsSlower(battlerAtk, battlerAtkPartner, move)) // Partner moving first
{
@@ -2685,7 +2697,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (IsAttackBoostMoveEffect(effect))
ADJUST_SCORE(-3);
// encourage moves hitting multiple opponents
- if (!IS_MOVE_STATUS(move) && (moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
+ if (!IsBattleMoveStatus(move) && (moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
ADJUST_SCORE(GOOD_EFFECT);
}
}
@@ -2714,7 +2726,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-5);
else if (atkPartnerHoldEffect == HOLD_EFFECT_SCOPE_LENS
|| IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_DRAGON)
- || gMovesInfo[aiData->partnerMove].criticalHitStage > 0
+ || GetMoveCriticalHitStage(aiData->partnerMove) > 0
|| HasMoveWithCriticalHitChance(battlerAtkPartner))
ADJUST_SCORE(GOOD_EFFECT);
break;
@@ -2767,7 +2779,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
switch (atkPartnerAbility)
{
case ABILITY_ANGER_POINT:
- if (gMovesInfo[move].alwaysCriticalHit == TRUE
+ if (MoveAlwaysCrits(move)
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)
&& AI_IsFaster(battlerAtk, battlerAtkPartner, move)
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
@@ -2838,7 +2850,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
break;
case ABILITY_JUSTIFIED:
if (moveType == TYPE_DARK
- && !IS_MOVE_STATUS(move)
+ && !IsBattleMoveStatus(move)
&& HasMoveWithCategory(battlerAtkPartner, DAMAGE_CATEGORY_PHYSICAL)
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
@@ -2847,7 +2859,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
}
break;
case ABILITY_RATTLED:
- if (!IS_MOVE_STATUS(move)
+ if (!IsBattleMoveStatus(move)
&& (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG)
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPEED)
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
@@ -2904,7 +2916,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_BEAT_UP:
if (atkPartnerAbility == ABILITY_JUSTIFIED
&& moveType == TYPE_DARK
- && !IS_MOVE_STATUS(move)
+ && !IsBattleMoveStatus(move)
&& HasMoveWithCategory(battlerAtkPartner, DAMAGE_CATEGORY_PHYSICAL)
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0))
@@ -2974,7 +2986,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
instructedMove = gLastMoves[battlerAtkPartner];
if (instructedMove != MOVE_NONE
- && !IS_MOVE_STATUS(instructedMove)
+ && !IsBattleMoveStatus(instructedMove)
&& (GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves
{
RETURN_SCORE_PLUS(WEAK_EFFECT);
@@ -2985,7 +2997,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (AI_IsSlower(battlerAtkPartner, FOE(battlerAtkPartner), aiData->partnerMove) // Opponent mon 1 goes before partner
|| AI_IsSlower(battlerAtkPartner, BATTLE_PARTNER(FOE(battlerAtkPartner)), aiData->partnerMove)) // Opponent mon 2 goes before partner
{
- if (gMovesInfo[aiData->partnerMove].effect == EFFECT_COUNTER || gMovesInfo[aiData->partnerMove].effect == EFFECT_MIRROR_COAT)
+ if (partnerEffect == EFFECT_COUNTER || partnerEffect == EFFECT_MIRROR_COAT)
break; // These moves need to go last
RETURN_SCORE_PLUS(WEAK_EFFECT);
}
@@ -3059,7 +3071,7 @@ static inline bool32 ShouldUseSpreadDamageMove(u32 battlerAtk, u32 move, u32 mov
return (IsDoubleBattle()
&& noOfHitsToFaintPartner != 0 // Immunity check
&& IsBattlerAlive(partnerBattler)
- && gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY
+ && GetBattlerMoveTargetType(battlerAtk, move) == MOVE_TARGET_FOES_AND_ALLY
&& !(noOfHitsToFaintPartner < 4 && hitsToFaintOpposingBattler == 1)
&& noOfHitsToFaintPartner < 7);
}
@@ -3078,7 +3090,7 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (moves[i] != MOVE_NONE && gMovesInfo[moves[i]].power)
+ if (moves[i] != MOVE_NONE && GetMovePower(moves[i]) != 0)
{
noOfHits[i] = GetNoOfHitsToKOBattler(battlerAtk, battlerDef, i);
if (ShouldUseSpreadDamageMove(battlerAtk,moves[i], i, noOfHits[i]))
@@ -3170,27 +3182,28 @@ static s32 AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef, u32 currId)
static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
{
// move data
- u32 moveEffect = gMovesInfo[move].effect;
+ u32 moveEffect = GetMoveEffect(move);
struct AiLogicData *aiData = AI_DATA;
u32 movesetIndex = AI_THINKING_STRUCT->movesetIndex;
u32 effectiveness = aiData->effectiveness[battlerAtk][battlerDef][movesetIndex];
s32 score = 0;
u32 predictedMove = aiData->lastUsedMove[battlerDef];
+ u32 predictedType = GetMoveType(predictedMove);
u32 predictedMoveSlot = GetMoveSlot(GetMovesArray(battlerDef), predictedMove);
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
u32 i;
// The AI should understand that while Dynamaxed, status moves function like Protect.
- if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX && gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
+ if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX && GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS)
moveEffect = EFFECT_PROTECT;
// check status move preference
- if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0)
+ if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_PREFER_STATUS_MOVES && IsBattleMoveStatus(move) && effectiveness != AI_EFFECTIVENESS_x0)
ADJUST_SCORE(10);
// check thawing moves
- if ((gBattleMons[battlerAtk].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE)) && gMovesInfo[move].thawsUser)
+ if ((gBattleMons[battlerAtk].status1 & (STATUS1_FREEZE | STATUS1_FROSTBITE)) && MoveThawsUser(move))
ADJUST_SCORE(10);
// check burn / frostbite
@@ -3379,7 +3392,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
score += AI_TryToClearStats(battlerAtk, battlerDef, isDoubleBattle);
break;
case EFFECT_ROAR:
- if ((gMovesInfo[move].soundMove && aiData->abilities[battlerDef] == ABILITY_SOUNDPROOF)
+ if ((IsSoundMove(move) && aiData->abilities[battlerDef] == ABILITY_SOUNDPROOF)
|| aiData->abilities[battlerDef] == ABILITY_SUCTION_CUPS)
break;
else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
@@ -3395,7 +3408,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(-2);
break;
case EFFECT_CONVERSION:
- if (!IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[gBattleMons[battlerAtk].moves[0]].type))
+ if (!IS_BATTLER_OF_TYPE(battlerAtk, GetMoveType(gBattleMons[battlerAtk].moves[0])))
ADJUST_SCORE(WEAK_EFFECT);
break;
case EFFECT_SWALLOW:
@@ -3451,7 +3464,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
}
break;
case EFFECT_REST:
- if (!(CanBeSlept(battlerAtk, aiData->abilities[battlerAtk])))
+ if (!(CanBeSlept(battlerAtk, aiData->abilities[battlerAtk], NOT_BLOCKED_BY_SLEEP_CLAUSE)))
{
break;
}
@@ -3513,6 +3526,9 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_DO_NOTHING:
+ case EFFECT_HOLD_HANDS:
+ case EFFECT_CELEBRATE:
+ case EFFECT_HAPPY_HOUR:
//todo - check z splash, z celebrate, z happy hour (lol)
break;
case EFFECT_TELEPORT: // Either remove or add better logic
@@ -3569,7 +3585,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
break;
else if (gDisableStructs[battlerDef].encoreTimer == 0
&& (B_MENTAL_HERB < GEN_5 || aiData->holdEffects[battlerDef] != HOLD_EFFECT_MENTAL_HERB)
- && (gBattleMoveEffects[gMovesInfo[gLastMoves[battlerDef]].effect].encourageEncore))
+ && (gBattleMoveEffects[GetMoveEffect(gLastMoves[battlerDef])].encourageEncore))
ADJUST_SCORE(BEST_EFFECT);
break;
case EFFECT_SLEEP_TALK:
@@ -3617,7 +3633,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
switch (move)
{
case MOVE_QUICK_GUARD:
- if (predictedMove != MOVE_NONE && gMovesInfo[predictedMove].priority > 0)
+ if (predictedMove != MOVE_NONE && GetMovePriority(predictedMove) > 0)
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_WIDE_GUARD:
@@ -3632,13 +3648,13 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
}
break;
case MOVE_CRAFTY_SHIELD:
- if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
+ if (predictedMove != MOVE_NONE && IsBattleMoveStatus(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_MAT_BLOCK:
if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE
- && !IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
+ && !IsBattleMoveStatus(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_KINGS_SHIELD:
@@ -3786,10 +3802,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
case EFFECT_SEMI_INVULNERABLE:
if (predictedMove != MOVE_NONE && !isDoubleBattle)
{
+ u32 predictedEffect = GetMoveEffect(predictedMove);
if ((AI_IsFaster(battlerAtk, battlerDef, move))
- && (gMovesInfo[predictedMove].effect == EFFECT_EXPLOSION || gMovesInfo[predictedMove].effect == EFFECT_PROTECT))
+ && (predictedEffect == EFFECT_EXPLOSION || predictedEffect == EFFECT_PROTECT))
ADJUST_SCORE(GOOD_EFFECT);
- else if (gMovesInfo[predictedMove].effect == EFFECT_SEMI_INVULNERABLE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
+ else if (predictedEffect == EFFECT_SEMI_INVULNERABLE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE))
ADJUST_SCORE(GOOD_EFFECT);
}
break;
@@ -3861,7 +3878,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
{
if (isDoubleBattle)
{
- if (IsHazardMoveEffect(gMovesInfo[aiData->partnerMove].effect) // Partner is going to set up hazards
+ if (IsHazardMoveEffect(GetMoveEffect(aiData->partnerMove)) // Partner is going to set up hazards
&& AI_IsSlower(battlerAtk, BATTLE_PARTNER(battlerAtk), move)) // Partner going first
break; // Don't use Defog if partner is going to set up hazards
}
@@ -3882,7 +3899,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
&& IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))
{
u32 predictedMoveOnPartner = gLastMoves[BATTLE_PARTNER(battlerAtk)];
- if (predictedMoveOnPartner != MOVE_NONE && !IS_MOVE_STATUS(predictedMoveOnPartner))
+ if (predictedMoveOnPartner != MOVE_NONE && !IsBattleMoveStatus(predictedMoveOnPartner))
ADJUST_SCORE(GOOD_EFFECT);
}
break;
@@ -3893,7 +3910,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_SPDEF));
break;
case EFFECT_TAUNT:
- if (IS_MOVE_STATUS(predictedMove))
+ if (IsBattleMoveStatus(predictedMove))
ADJUST_SCORE(GOOD_EFFECT);
else if (HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_STATUS))
ADJUST_SCORE(DECENT_EFFECT);
@@ -3957,7 +3974,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT); // Force 'em out next turn
break;
default:
- if (gMovesInfo[move].effect != EFFECT_BESTOW && aiData->items[battlerAtk] == ITEM_NONE && aiData->items[battlerDef] != ITEM_NONE)
+ if (GetMoveEffect(move) != EFFECT_BESTOW && aiData->items[battlerAtk] == ITEM_NONE && aiData->items[battlerDef] != ITEM_NONE)
{
switch (aiData->holdEffects[battlerDef])
{
@@ -4018,7 +4035,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(GOOD_EFFECT);
break;
case EFFECT_MAGIC_COAT:
- if (IS_MOVE_STATUS(predictedMove) && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH))
+ if (IsBattleMoveStatus(predictedMove) && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH))
ADJUST_SCORE(GOOD_EFFECT);
break;
case EFFECT_RECYCLE:
@@ -4098,7 +4115,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
case EFFECT_GRUDGE:
break;
case EFFECT_SNATCH:
- if (predictedMove != MOVE_NONE && gMovesInfo[predictedMove].snatchAffected)
+ if (predictedMove != MOVE_NONE && MoveCanBeSnatched(predictedMove))
ADJUST_SCORE(GOOD_EFFECT); // Steal move
break;
case EFFECT_MUD_SPORT:
@@ -4265,7 +4282,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
if ((aiData->abilities[battlerAtk] == ABILITY_VOLT_ABSORB
|| aiData->abilities[battlerAtk] == ABILITY_MOTOR_DRIVE
|| (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD))
- && gMovesInfo[predictedMove].type == TYPE_NORMAL)
+ && predictedType == TYPE_NORMAL)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_FLING:
@@ -4296,7 +4313,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_POWDER:
- if (predictedMove != MOVE_NONE && !IS_MOVE_STATUS(predictedMove) && gMovesInfo[predictedMove].type == TYPE_FIRE)
+ if (predictedMove != MOVE_NONE && !IsBattleMoveStatus(predictedMove) && predictedType == TYPE_FIRE)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_TELEKINESIS:
@@ -4312,7 +4329,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_SOAK:
- if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || (HasMoveEffect(battlerAtk, EFFECT_SUPER_EFFECTIVE_ON_ARG) && gMovesInfo[move].argument == TYPE_WATER) )
+ if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || (HasMoveEffect(battlerAtk, EFFECT_SUPER_EFFECTIVE_ON_ARG) && GetMoveArgType(move) == TYPE_WATER) )
ADJUST_SCORE(DECENT_EFFECT); // Get some super effective moves
break;
case EFFECT_THIRD_TYPE:
@@ -4354,7 +4371,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
{
if (AI_IsFaster(battlerAtk, battlerDef, move)) // Attacker goes first
{
- if (gMovesInfo[predictedMove].type == TYPE_GROUND)
+ if (predictedType == TYPE_GROUND)
ADJUST_SCORE(GOOD_EFFECT); // Cause the enemy's move to fail
break;
}
@@ -4368,7 +4385,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
break;
case EFFECT_CAMOUFLAGE:
if (predictedMove != MOVE_NONE && AI_IsFaster(battlerAtk, battlerDef, move) // Attacker goes first
- && !IS_MOVE_STATUS(move) && AI_GetMoveEffectiveness(predictedMove, battlerDef, battlerAtk) != AI_EFFECTIVENESS_x0)
+ && !IsBattleMoveStatus(move) && AI_GetMoveEffectiveness(predictedMove, battlerDef, battlerAtk) != AI_EFFECTIVENESS_x0)
ADJUST_SCORE(DECENT_EFFECT);
break;
case EFFECT_TOXIC_THREAD:
@@ -4399,7 +4416,13 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
break;
case EFFECT_REVIVAL_BLESSING:
if (GetFirstFaintedPartyIndex(battlerAtk) != PARTY_SIZE)
+ {
ADJUST_SCORE(DECENT_EFFECT);
+ if (AI_DATA->shouldSwitch & (1u << battlerAtk)) // Bad matchup
+ ADJUST_SCORE(WEAK_EFFECT);
+ if (AI_DATA->mostSuitableMonId[battlerAtk] != PARTY_SIZE) // Good mon to send in after
+ ADJUST_SCORE(WEAK_EFFECT);
+ }
break;
//case EFFECT_EXTREME_EVOBOOST: // TODO
//break;
@@ -4416,34 +4439,32 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|| gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY)
ADJUST_SCORE(GOOD_EFFECT);
break;
- case EFFECT_SALT_CURE:
- if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_WATER) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL))
- ADJUST_SCORE(DECENT_EFFECT);
- break;
} // move effect checks
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
// check move additional effects that are likely to happen
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ for (i = 0; i < additionalEffectCount; i++)
{
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
// Only consider effects with a guaranteed chance to happen
- if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], &gMovesInfo[move].additionalEffects[i]))
+ if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], additionalEffect))
continue;
// Consider move effects that target self
- if (gMovesInfo[move].additionalEffects[i].self)
+ if (additionalEffect->self)
{
u32 StageStatId;
if (aiData->abilities[battlerAtk] != ABILITY_CONTRARY)
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_ATK_PLUS_1:
case MOVE_EFFECT_DEF_PLUS_1:
case MOVE_EFFECT_SPD_PLUS_1:
case MOVE_EFFECT_SP_ATK_PLUS_1:
case MOVE_EFFECT_SP_DEF_PLUS_1:
- StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
+ StageStatId = STAT_CHANGE_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_PLUS_1;
ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId));
break;
case MOVE_EFFECT_ATK_PLUS_2:
@@ -4451,7 +4472,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
case MOVE_EFFECT_SPD_PLUS_2:
case MOVE_EFFECT_SP_ATK_PLUS_2:
case MOVE_EFFECT_SP_DEF_PLUS_2:
- StageStatId = STAT_CHANGE_ATK_2 + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_PLUS_1;
+ StageStatId = STAT_CHANGE_ATK_2 + additionalEffect->moveEffect - MOVE_EFFECT_ATK_PLUS_1;
ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, StageStatId));
break;
case MOVE_EFFECT_ACC_PLUS_1:
@@ -4471,14 +4492,14 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
}
else
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_ATK_MINUS_1:
case MOVE_EFFECT_DEF_MINUS_1:
case MOVE_EFFECT_SPD_MINUS_1:
case MOVE_EFFECT_SP_ATK_MINUS_1:
case MOVE_EFFECT_SP_DEF_MINUS_1:
- StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1;
+ StageStatId = STAT_CHANGE_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1;
ADJUST_SCORE(IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId));
break;
case MOVE_EFFECT_ATK_MINUS_2:
@@ -4486,7 +4507,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
case MOVE_EFFECT_SPD_MINUS_2:
case MOVE_EFFECT_SP_ATK_MINUS_2:
case MOVE_EFFECT_SP_DEF_MINUS_2:
- StageStatId = STAT_CHANGE_ATK + gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2;
+ StageStatId = STAT_CHANGE_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2;
ADJUST_SCORE(IncreaseStatUpScoreContrary(battlerAtk, battlerDef, StageStatId));
break;
case MOVE_EFFECT_ACC_MINUS_1:
@@ -4515,7 +4536,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
}
else // consider move effects that hinder the target
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_FLINCH:
score += ShouldTryToFlinch(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move);
@@ -4648,11 +4669,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
}
break;
case MOVE_EFFECT_FEINT:
- if (gMovesInfo[predictedMove].effect == EFFECT_PROTECT)
+ if (GetMoveEffect(predictedMove) == EFFECT_PROTECT)
ADJUST_SCORE(GOOD_EFFECT);
break;
case MOVE_EFFECT_THROAT_CHOP:
- if (gMovesInfo[GetBestDmgMoveFromBattler(battlerDef, battlerAtk)].soundMove)
+ if (IsSoundMove(GetBestDmgMoveFromBattler(battlerDef, battlerAtk)))
{
if (AI_IsFaster(battlerAtk, battlerDef, move))
ADJUST_SCORE(GOOD_EFFECT);
@@ -4664,6 +4685,11 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
if (!HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) && ShouldTrap(battlerAtk, battlerDef, move))
ADJUST_SCORE(BEST_EFFECT);
break;
+ case MOVE_EFFECT_SALT_CURE:
+ if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_WATER) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL))
+ ADJUST_SCORE(DECENT_EFFECT);
+ break;
+
}
}
}
@@ -4678,7 +4704,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef))
return score;
- if (gMovesInfo[move].power)
+ if (GetMovePower(move) != 0)
{
if (GetNoOfHitsToKOBattler(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex) == 0)
ADJUST_AND_RETURN_SCORE(NO_DAMAGE_OR_FAILS); // No point in checking the move further so return early
@@ -4707,13 +4733,13 @@ static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32
if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_SMART_SWITCHING
&& AI_IsSlower(battlerAtk, battlerDef, move)
&& CanTargetFaintAi(battlerDef, battlerAtk)
- && GetMovePriority(battlerAtk, move) == 0)
+ && GetBattleMovePriority(battlerAtk, move) == 0)
{
RETURN_SCORE_MINUS(20); // No point in setting up if you will faint. Should just switch if possible..
}
// check effects to prioritize first turn
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_ATTACK_UP:
case EFFECT_ATTACK_UP_USER_ALLY:
@@ -4805,9 +4831,11 @@ static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32
{
// TEMPORARY - should applied to all moves regardless of EFFECT
// Consider move effects
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < additionalEffectCount; i++)
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_STEALTH_ROCK:
case MOVE_EFFECT_SPIKES:
@@ -4834,11 +4862,11 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef))
return score;
- if (gMovesInfo[move].criticalHitStage > 0)
+ if (GetMoveCriticalHitStage(move) > 0)
ADJUST_SCORE(DECENT_EFFECT);
// +3 Score
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_COUNTER:
if (gSpeciesInfo[gBattleMons[battlerDef].species].baseAttack >= gSpeciesInfo[gBattleMons[battlerDef].species].baseSpAttack + 10)
@@ -4877,9 +4905,11 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
// TEMPORARY - should applied to all moves regardless of EFFECT
// Consider move effects
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < additionalEffectCount; i++)
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_ALL_STATS_UP:
if (Random() & 1)
@@ -4916,12 +4946,14 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor
{
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)
|| CountUsablePartyMons(battlerAtk) == 0
- || gMovesInfo[move].power != 0
+ || !IsBattleMoveStatus(move)
|| !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS)
|| IsBattlerTrapped(battlerAtk, TRUE))
return score;
- if (IsStatRaisingEffect(gMovesInfo[move].effect))
+ u32 effect = GetMoveEffect(move);
+
+ if (IsStatRaisingEffect(effect))
{
if (gBattleResults.battleTurnCounter == 0)
ADJUST_SCORE(GOOD_EFFECT);
@@ -4932,7 +4964,7 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor
}
// other specific checks
- switch (gMovesInfo[move].effect)
+ switch (effect)
{
case EFFECT_INGRAIN:
if (!(gStatuses3[battlerAtk] & STATUS3_ROOTED))
@@ -4964,11 +4996,11 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor
static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
- u32 effect = gMovesInfo[move].effect;
+ u32 effect = GetMoveEffect(move);
u32 moveType = 0;
SetTypeBeforeUsingMove(move, battlerAtk);
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef))
{
@@ -5146,7 +5178,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
else
{
// low HP
- if (IS_MOVE_STATUS(move))
+ if (IsBattleMoveStatus(move))
ADJUST_SCORE(-2); // don't use status moves if target is at low health
}
}
@@ -5156,9 +5188,9 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
static s32 AI_PowerfulStatus(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
- u32 moveEffect = gMovesInfo[move].effect;
+ u32 moveEffect = GetMoveEffect(move);
- if (gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS || gMovesInfo[AI_DATA->partnerMove].effect == moveEffect)
+ if (GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS || GetMoveEffect(AI_DATA->partnerMove) == moveEffect)
return score;
switch (moveEffect)
diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c
index 47f5cae740..7de2e897a5 100644
--- a/src/battle_ai_switch_items.c
+++ b/src/battle_ai_switch_items.c
@@ -108,7 +108,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
for (i = 0; i < MAX_MON_MOVES; i++)
{
aiMove = gBattleMons[battler].moves[i];
- aiMoveEffect = gMovesInfo[aiMove].effect;
+ aiMoveEffect = GetMoveEffect(aiMove);
if (aiMove != MOVE_NONE)
{
// Check if mon has an "important" status move
@@ -122,8 +122,8 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
hasStatusMove = TRUE;
}
- // Only check damage if move has power
- if (gMovesInfo[aiMove].power != 0)
+ // Only check damage if it's a damaging move
+ if (!IsBattleMoveStatus(aiMove))
{
// Check if mon has a super effective move
if (AI_GetMoveEffectiveness(aiMove, battler, opposingBattler) >= AI_EFFECTIVENESS_x2)
@@ -156,7 +156,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
for (i = 0; i < MAX_MON_MOVES; i++)
{
playerMove = gBattleMons[opposingBattler].moves[i];
- if (playerMove != MOVE_NONE && gMovesInfo[playerMove].power != 0)
+ if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove))
{
damageTaken = AI_CalcDamage(playerMove, opposingBattler, battler, &effectiveness, FALSE, weather, DMG_ROLL_HIGHEST).expected;
if (damageTaken > maxDamageTaken)
@@ -332,7 +332,9 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
u16 monAbility;
u32 opposingBattler = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(battler)));
u32 incomingMove = AI_DATA->lastUsedMove[opposingBattler];
+ u32 incomingType = GetMoveType(incomingMove);
u32 predictedMove = incomingMove; // Update for move prediction
+ u32 predictedType = GetMoveType(predictedMove);
bool32 isOpposingBattlerChargingOrInvulnerable = (IsSemiInvulnerable(opposingBattler, incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove));
s32 i, j;
@@ -356,31 +358,36 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
}
// Create an array of possible absorb abilities so the AI considers all of them
- if (gMovesInfo[predictedMove].type == TYPE_FIRE)
+ if (predictedType == TYPE_FIRE)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_FLASH_FIRE;
}
- else if (gMovesInfo[predictedMove].type == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_WATER))
+ else if (predictedType == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_WATER))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WATER_ABSORB;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_DRY_SKIN;
if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_STORM_DRAIN;
}
- else if (gMovesInfo[predictedMove].type == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_ELECTRIC))
+ else if (predictedType == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_ELECTRIC))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_VOLT_ABSORB;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_MOTOR_DRIVE;
if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LIGHTNING_ROD;
}
- else if (gMovesInfo[predictedMove].type == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_GRASS))
+ else if (predictedType == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GRASS))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SAP_SIPPER;
}
- else if (gMovesInfo[predictedMove].type == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && gMovesInfo[incomingMove].type == TYPE_GROUND))
+ else if (predictedType == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GROUND))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_EARTH_EATER;
+ absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LEVITATE;
+ }
+ else if (IsSoundMove(predictedMove) || (isOpposingBattlerChargingOrInvulnerable && IsSoundMove(incomingMove)))
+ {
+ absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SOUNDPROOF;
}
else
{
@@ -497,7 +504,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
{
//Yawn
if (gStatuses3[battler] & STATUS3_YAWN
- && CanBeSlept(battler, monAbility)
+ && CanBeSlept(battler, monAbility, BLOCKED_BY_SLEEP_CLAUSE)
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / 3)
{
switchMon = TRUE;
@@ -697,7 +704,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 perc
return FALSE;
if (gLastHitBy[battler] == 0xFF)
return FALSE;
- if (IS_MOVE_STATUS(gLastLandedMoves[battler]))
+ if (IsBattleMoveStatus(gLastLandedMoves[battler]))
return FALSE;
if (IsDoubleBattle())
@@ -737,7 +744,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 perc
species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
monAbility = GetMonAbility(&party[i]);
CalcPartyMonTypeEffectivenessMultiplier(gLastLandedMoves[battler], species, monAbility);
- if (gMoveResultFlags & flags)
+ if (gBattleStruct->moveResultFlags[BATTLE_OPPOSITE(battler)] & flags)
{
battlerIn1 = gLastHitBy[battler];
@@ -807,9 +814,10 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler)
for (j = 0; j < MAX_MON_MOVES; j++)
{
aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL);
+ u32 aiEffect = GetMoveEffect(aiMove);
if (MoveHasAdditionalEffectSelf(aiMove, MOVE_EFFECT_RAPID_SPIN)
- || (B_DEFOG_EFFECT_CLEARING >= GEN_6 && gMovesInfo[aiMove].effect == EFFECT_DEFOG)
- || gMovesInfo[aiMove].effect == EFFECT_TIDY_UP)
+ || (B_DEFOG_EFFECT_CLEARING >= GEN_6 && aiEffect == EFFECT_DEFOG)
+ || aiEffect == EFFECT_TIDY_UP)
{
// Have a mon that can clear the hazards, so switching out is okay
return TRUE;
@@ -836,7 +844,7 @@ static bool32 ShouldSwitchIfEncored(u32 battler)
return FALSE;
// Switch out if status move
- if (gMovesInfo[encoredMove].category == DAMAGE_CATEGORY_STATUS)
+ if (GetMoveCategory(encoredMove) == DAMAGE_CATEGORY_STATUS)
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
// Stay in if effective move
@@ -856,7 +864,7 @@ static bool32 ShouldSwitchIfBadChoiceLock(u32 battler)
if (HOLD_EFFECT_CHOICE(holdEffect) && gBattleMons[battler].ability != ABILITY_KLUTZ)
{
- if (gMovesInfo[gLastUsedMove].category == DAMAGE_CATEGORY_STATUS)
+ if (GetMoveCategory(gLastUsedMove) == DAMAGE_CATEGORY_STATUS)
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
}
@@ -917,7 +925,6 @@ bool32 ShouldSwitch(u32 battler)
struct Pokemon *party;
s32 i;
s32 availableToSwitch;
- bool32 hasAceMon = FALSE;
if (gBattleMons[battler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
return FALSE;
@@ -965,21 +972,13 @@ bool32 ShouldSwitch(u32 battler)
if (i == gBattleStruct->monToSwitchIntoId[battlerIn2])
continue;
if (IsAceMon(battler, i))
- {
- hasAceMon = TRUE;
continue;
- }
availableToSwitch++;
}
if (availableToSwitch == 0)
- {
- if (hasAceMon) // If the ace mon is the only available mon, use it
- availableToSwitch++;
- else
return FALSE;
- }
// NOTE: The sequence of the below functions matter! Do not change unless you have carefully considered the outcome.
// Since the order is sequencial, and some of these functions prompt switch to specific party members.
@@ -1228,7 +1227,6 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
u32 aiMove;
- gMoveResultFlags = 0;
// If we couldn't find the best mon in terms of typing, find the one that deals most damage.
for (i = firstId; i < lastId; i++)
{
@@ -1238,7 +1236,7 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
for (j = 0; j < MAX_MON_MOVES; j++)
{
aiMove = AI_DATA->switchinCandidate.battleMon.moves[j];
- if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0)
+ if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove))
{
aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j);
dmg = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE, rollType);
@@ -1285,10 +1283,10 @@ static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon
{
// Stealth Rock
if ((hazardFlags & SIDE_STATUS_STEALTH_ROCK) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS)
- hazardDamage += GetStealthHazardDamageByTypesAndHP(gMovesInfo[MOVE_STEALTH_ROCK].type, defType1, defType2, battleMon->maxHP);
+ hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_STEALTH_ROCK), defType1, defType2, battleMon->maxHP);
// G-Max Steelsurge
if ((hazardFlags & SIDE_STATUS_STEELSURGE) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS)
- hazardDamage += GetStealthHazardDamageByTypesAndHP(gMovesInfo[MOVE_G_MAX_STEELSURGE].type, defType1, defType2, battleMon->maxHP);
+ hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_G_MAX_STEELSURGE), defType1, defType2, battleMon->maxHP);
// Spikes
if ((hazardFlags & SIDE_STATUS_SPIKES) && IsMonGrounded(heldItemEffect, ability, defType1, defType2))
{
@@ -1694,7 +1692,7 @@ static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattle
for (i = 0; i < MAX_MON_MOVES; i++)
{
playerMove = gBattleMons[opposingBattler].moves[i];
- if (playerMove != MOVE_NONE && gMovesInfo[playerMove].power != 0)
+ if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove))
{
damageTaken = AI_CalcPartyMonDamage(playerMove, opposingBattler, battler, battleMon, FALSE, DMG_ROLL_HIGHEST);
if (damageTaken > maxDamageTaken)
@@ -1730,7 +1728,7 @@ static inline bool32 IsFreeSwitch(bool32 isSwitchAfterKO, u32 battlerSwitchingOu
// Switch out effects
if (!IsDoubleBattle()) // Not handling doubles' additional complexity
{
- if (IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect) && movedSecond)
+ if (IsSwitchOutEffect(GetMoveEffect(gLastUsedMove)) && movedSecond)
return TRUE;
if (AI_DATA->ejectButtonSwitch)
return TRUE;
@@ -1771,7 +1769,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
{
int revengeKillerId = PARTY_SIZE, slowRevengeKillerId = PARTY_SIZE, fastThreatenId = PARTY_SIZE, slowThreatenId = PARTY_SIZE, damageMonId = PARTY_SIZE;
int batonPassId = PARTY_SIZE, typeMatchupId = PARTY_SIZE, typeMatchupEffectiveId = PARTY_SIZE, defensiveMonId = PARTY_SIZE, aceMonId = PARTY_SIZE, trapperId = PARTY_SIZE;
- int i, j, aliveCount = 0, bits = 0;
+ int i, j, aliveCount = 0, bits = 0, aceMonCount = 0;
s32 defensiveMonHitKOThreshold = 3; // 3HKO threshold that candidate defensive mons must exceed
s32 playerMonHP = gBattleMons[opposingBattler].hp, maxDamageDealt = 0, damageDealt = 0;
u32 aiMove, hitsToKOAI, maxHitsToKO = 0;
@@ -1794,6 +1792,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
else if (IsAceMon(battler, i))
{
aceMonId = i;
+ aceMonCount++;
continue;
}
else
@@ -1822,7 +1821,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
{
aiMove = AI_DATA->switchinCandidate.battleMon.moves[j];
- if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0)
+ if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove))
{
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_CONSERVATIVE)
damageDealt = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE, DMG_ROLL_LOWEST);
@@ -1852,7 +1851,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
}
// Check for mon with resistance and super effective move for best type matchup mon with effective move
- if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0)
+ if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove))
{
if (typeMatchup < bestResistEffective)
{
@@ -1867,7 +1866,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
}
// If a self destruction move doesn't OHKO, don't factor it into revenge killing
- if (gMovesInfo[aiMove].effect == EFFECT_EXPLOSION && damageDealt < playerMonHP)
+ if (GetMoveEffect(aiMove) == EFFECT_EXPLOSION && damageDealt < playerMonHP)
continue;
// Check that mon isn't one shot and set best damage mon
@@ -1940,7 +1939,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
else if (batonPassId != PARTY_SIZE) return batonPassId;
}
// If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon.
- if (aceMonId != PARTY_SIZE && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect))
+ if (aceMonId != PARTY_SIZE && CountUsablePartyMons(battler) <= aceMonCount && IsSwitchOutEffect(GetMoveEffect(gLastUsedMove)))
return aceMonId;
return PARTY_SIZE;
@@ -2018,7 +2017,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd)
// This all handled by the GetBestMonIntegrated function if the AI_FLAG_SMART_MON_CHOICES flag is set
else
{
- s32 i, aliveCount = 0;
+ s32 i, aliveCount = 0, aceMonCount = 0;
u32 invalidMons = 0, aceMonId = PARTY_SIZE;
// Get invalid slots ids.
for (i = firstId; i < lastId; i++)
@@ -2035,6 +2034,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd)
else if (IsAceMon(battler, i)) // Save Ace Pokemon for last.
{
aceMonId = i;
+ aceMonCount++;
invalidMons |= 1u << i;
}
else
@@ -2054,8 +2054,8 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd)
if (bestMonId != PARTY_SIZE)
return bestMonId;
- // If ace mon is the last available Pokemon and switch move was used - switch to the mon.
- if (aceMonId != PARTY_SIZE)
+ // If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon.
+ if (aceMonId != PARTY_SIZE && CountUsablePartyMons(battler) <= aceMonCount && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect))
return aceMonId;
return PARTY_SIZE;
diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c
index 0277d7fd07..798713ef59 100644
--- a/src/battle_ai_util.c
+++ b/src/battle_ai_util.c
@@ -11,6 +11,7 @@
#include "event_data.h"
#include "data.h"
#include "item.h"
+#include "move.h"
#include "pokemon.h"
#include "random.h"
#include "recorded_battle.h"
@@ -22,16 +23,6 @@
#include "constants/moves.h"
#include "constants/items.h"
-#define CHECK_MOVE_FLAG(flag) \
- s32 i; \
- u16 *moves = GetMovesArray(battler); \
- for (i = 0; i < MAX_MON_MOVES; i++) \
- { \
- if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].flag) \
- return TRUE; \
- } \
- return FALSE
-
static u32 AI_GetEffectiveness(uq4_12_t multiplier);
// Functions
@@ -102,6 +93,15 @@ bool32 IsAiBattlerAware(u32 battlerId)
return BattlerHasAi(battlerId);
}
+bool32 IsAiBattlerPredictingAbility(u32 battlerId)
+{
+ if (AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_LEFT] & AI_FLAG_WEIGH_ABILITY_PREDICTION
+ || AI_THINKING_STRUCT->aiFlags[B_POSITION_OPPONENT_RIGHT] & AI_FLAG_WEIGH_ABILITY_PREDICTION)
+ return TRUE;
+
+ return BattlerHasAi(battlerId);
+}
+
void ClearBattlerMoveHistory(u32 battlerId)
{
memset(BATTLE_HISTORY->usedMoves[battlerId], 0, sizeof(BATTLE_HISTORY->usedMoves[battlerId]));
@@ -281,7 +281,7 @@ u32 GetHealthPercentage(u32 battlerId)
return (u32)((100 * gBattleMons[battlerId].hp) / gBattleMons[battlerId].maxHP);
}
-bool32 AtMaxHp(u32 battlerId)
+bool32 AI_BattlerAtMaxHp(u32 battlerId)
{
if (AI_DATA->hpPercents[battlerId] == 100)
return TRUE;
@@ -329,9 +329,10 @@ bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler)
for (i = 0; i < MAX_MON_MOVES; i++)
{
u32 move = gBattleResources->battleHistory->usedMoves[opposingBattler][i];
- if (gMovesInfo[move].effect == EFFECT_PROTECT && move != MOVE_ENDURE)
+ u32 effect = GetMoveEffect(move);
+ if (effect == EFFECT_PROTECT && move != MOVE_ENDURE)
return TRUE;
- if (gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE && AI_IsSlower(battlerAI, opposingBattler, GetAIChosenMove(battlerAI)))
+ if (effect == EFFECT_SEMI_INVULNERABLE && AI_IsSlower(battlerAI, opposingBattler, GetAIChosenMove(battlerAI)))
return TRUE;
}
return FALSE;
@@ -364,7 +365,7 @@ bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, u32 category)
&& !(unusable & (1u << i)))
{
SetTypeBeforeUsingMove(moves[i], attacker);
- moveType = GetMoveType(moves[i]);
+ moveType = GetBattleMoveType(moves[i]);
if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, AI_DATA->abilities[target], FALSE) != 0)
usable |= 1u << i;
}
@@ -441,7 +442,7 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy
if (CanAbilityAbsorbMove(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, moveType))
return TRUE;
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_DREAM_EATER:
if (!AI_IsBattlerAsleepOrComatose(battlerDef))
@@ -461,11 +462,11 @@ bool32 IsDamageMoveUnusable(u32 battlerAtk, u32 battlerDef, u32 move, u32 moveTy
return TRUE;
break;
case EFFECT_FAIL_IF_NOT_ARG_TYPE:
- if (!IS_BATTLER_OF_TYPE(battlerAtk, gMovesInfo[move].argument))
+ if (!IS_BATTLER_OF_TYPE(battlerAtk, GetMoveArgType(move)))
return TRUE;
break;
case EFFECT_HIT_SET_REMOVE_TERRAIN:
- if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) && gMovesInfo[move].argument == ARG_TRY_REMOVE_TERRAIN_FAIL)
+ if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) && GetMoveEffectArg_MoveProperty(move) == ARG_TRY_REMOVE_TERRAIN_FAIL)
return TRUE;
break;
case EFFECT_POLTERGEIST:
@@ -503,7 +504,7 @@ static inline s32 GetDamageByRollType(s32 dmg, enum DamageRollType rollType)
static inline void SetMoveDamageCategory(u32 battlerAtk, u32 battlerDef, u32 move)
{
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_PHOTON_GEYSER:
gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(battlerAtk) == DAMAGE_CATEGORY_PHYSICAL);
@@ -526,14 +527,14 @@ static inline void SetMoveDamageCategory(u32 battlerAtk, u32 battlerDef, u32 mov
static inline s32 SetFixedMoveBasePower(u32 battlerAtk, u32 move)
{
s32 fixedBasePower = 0, n = 0;
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_ROLLOUT:
n = gDisableStructs[battlerAtk].rolloutTimer - 1;
- fixedBasePower = CalcRolloutBasePower(battlerAtk, gMovesInfo[move].power, n < 0 ? 5 : n);
+ fixedBasePower = CalcRolloutBasePower(battlerAtk, GetMovePower(move), n < 0 ? 5 : n);
break;
case EFFECT_FURY_CUTTER:
- fixedBasePower = CalcFuryCutterBasePower(gMovesInfo[move].power, min(gDisableStructs[battlerAtk].furyCutterCounter + 1, 5));
+ fixedBasePower = CalcFuryCutterBasePower(GetMovePower(move), min(gDisableStructs[battlerAtk].furyCutterCounter + 1, 5));
break;
default:
fixedBasePower = 0;
@@ -545,10 +546,11 @@ static inline s32 SetFixedMoveBasePower(u32 battlerAtk, u32 move)
static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCalcData, s32 *expectedDamage, s32 *minimumDamage, u32 holdEffectAtk, u32 abilityAtk)
{
u32 move = damageCalcData->move;
+ u32 effect = GetMoveEffect(move);
s32 expected = *expectedDamage;
s32 minimum = *minimumDamage;
- switch (gMovesInfo[move].effect)
+ switch (effect)
{
case EFFECT_LEVEL_DAMAGE:
expected = minimum = gBattleMons[damageCalcData->battlerAtk].level * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
@@ -557,7 +559,7 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal
expected = minimum = gBattleMons[damageCalcData->battlerAtk].level * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
break;
case EFFECT_FIXED_DAMAGE_ARG:
- expected = minimum = gMovesInfo[move].argument * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
+ expected = minimum = GetMoveFixedDamage(move) * (abilityAtk == ABILITY_PARENTAL_BOND ? 2 : 1);
break;
case EFFECT_MULTI_HIT:
if (move == MOVE_WATER_SHURIKEN && gBattleMons[damageCalcData->battlerAtk].species == SPECIES_GRENINJA_ASH)
@@ -611,10 +613,11 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal
}
// Handle other multi-strike moves
- if (gMovesInfo[move].strikeCount > 1 && gMovesInfo[move].effect != EFFECT_TRIPLE_KICK)
+ u32 strikeCount = GetMoveStrikeCount(move);
+ if (strikeCount > 1 && effect != EFFECT_TRIPLE_KICK)
{
- expected *= gMovesInfo[move].strikeCount;
- minimum *= gMovesInfo[move].strikeCount;
+ expected *= strikeCount;
+ minimum *= strikeCount;
}
if (expected == 0)
@@ -630,7 +633,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
{
struct SimulatedDamage simDamage;
s32 moveType;
- u32 moveEffect = gMovesInfo[move].effect;
+ u32 moveEffect = GetMoveEffect(move);
uq4_12_t effectivenessMultiplier;
bool32 isDamageMoveUnusable = FALSE;
bool32 toggledGimmick = FALSE;
@@ -654,13 +657,14 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
SetMoveDamageCategory(battlerAtk, battlerDef, move);
SetTypeBeforeUsingMove(move, battlerAtk);
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
effectivenessMultiplier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, aiData->abilities[battlerDef], FALSE);
- if (gMovesInfo[move].power)
+ u32 movePower = GetMovePower(move);
+ if (movePower)
isDamageMoveUnusable = IsDamageMoveUnusable(battlerAtk, battlerDef, move, moveType);
- if (gMovesInfo[move].power && !isDamageMoveUnusable)
+ if (movePower && !isDamageMoveUnusable)
{
s32 critChanceIndex, fixedBasePower;
@@ -714,7 +718,7 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u
s32 nonCritDmg = 0;
if (moveEffect == EFFECT_TRIPLE_KICK)
{
- for (gMultiHitCounter = gMovesInfo[move].strikeCount; gMultiHitCounter > 0; gMultiHitCounter--) // The global is used to simulate actual damage done
+ for (gMultiHitCounter = GetMoveStrikeCount(move); gMultiHitCounter > 0; gMultiHitCounter--) // The global is used to simulate actual damage done
{
nonCritDmg += CalculateMoveDamageVars(&damageCalcData, fixedBasePower,
effectivenessMultiplier, weather,
@@ -776,7 +780,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
u32 abilityDef = AI_DATA->abilities[battlerDef];
u32 abilityAtk = AI_DATA->abilities[battlerAtk];
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_HIT_ESCAPE:
if (CountUsablePartyMons(battlerAtk) != 0 && ShouldPivot(battlerAtk, battlerDef, abilityDef, move, AI_THINKING_STRUCT->movesetIndex))
@@ -789,12 +793,14 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
}
// check ADDITIONAL_EFFECTS
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < additionalEffectCount; i++)
{
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
// Consider move effects that target self
- if (gMovesInfo[move].additionalEffects[i].self)
+ if (additionalEffect->self)
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_ATK_PLUS_1:
case MOVE_EFFECT_ATK_PLUS_2:
@@ -837,7 +843,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
}
else // consider move effects that hinder the target
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_POISON:
case MOVE_EFFECT_TOXIC:
@@ -871,7 +877,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
case MOVE_EFFECT_SP_DEF_MINUS_1:
case MOVE_EFFECT_ACC_MINUS_1:
case MOVE_EFFECT_EVS_MINUS_1:
- if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
+ if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1)) && noOfHitsToKo != 1)
return TRUE;
break;
case MOVE_EFFECT_ATK_MINUS_2:
@@ -881,7 +887,7 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3
case MOVE_EFFECT_SP_DEF_MINUS_2:
case MOVE_EFFECT_ACC_MINUS_2:
case MOVE_EFFECT_EVS_MINUS_2:
- if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (gMovesInfo[move].additionalEffects[i].moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
+ if (ShouldLowerStat(battlerDef, abilityDef, STAT_ATK + (additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2)) && noOfHitsToKo != 1)
return TRUE;
break;
}
@@ -898,10 +904,10 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
u8 i;
// recoil
- if (gMovesInfo[move].recoil > 0 && AI_IsDamagedByRecoil(battlerAtk))
+ if (GetMoveRecoil(move) > 0 && AI_IsDamagedByRecoil(battlerAtk))
return TRUE;
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_MAX_HP_50_RECOIL:
case EFFECT_MIND_BLOWN:
@@ -914,9 +920,11 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
break;
default:
{
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < additionalEffectCount; i++)
{
- switch (gMovesInfo[move].additionalEffects[i].moveEffect)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ switch (additionalEffect->moveEffect)
{
case MOVE_EFFECT_ATK_MINUS_1:
case MOVE_EFFECT_DEF_MINUS_1:
@@ -935,12 +943,12 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
case MOVE_EFFECT_V_CREATE:
case MOVE_EFFECT_ATK_DEF_DOWN:
case MOVE_EFFECT_DEF_SPDEF_DOWN:
- if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk != ABILITY_CONTRARY)
+ if ((additionalEffect->self && abilityAtk != ABILITY_CONTRARY)
|| (noOfHitsToKo != 1 && abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move)))
return TRUE;
break;
case MOVE_EFFECT_RECHARGE:
- return gMovesInfo[move].additionalEffects[i].self;
+ return additionalEffect->self;
case MOVE_EFFECT_ATK_PLUS_1:
case MOVE_EFFECT_DEF_PLUS_1:
case MOVE_EFFECT_SPD_PLUS_1:
@@ -956,7 +964,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
case MOVE_EFFECT_EVS_PLUS_2:
case MOVE_EFFECT_ACC_PLUS_2:
case MOVE_EFFECT_ALL_STATS_UP:
- if ((gMovesInfo[move].additionalEffects[i].self && abilityAtk == ABILITY_CONTRARY)
+ if ((additionalEffect->self && abilityAtk == ABILITY_CONTRARY)
|| (noOfHitsToKo != 1 && !(abilityDef == ABILITY_CONTRARY && !DoesBattlerIgnoreAbilityChecks(abilityAtk, move))))
return TRUE;
break;
@@ -980,9 +988,11 @@ s32 AI_WhichMoveBetter(u32 move1, u32 move2, u32 battlerAtk, u32 battlerDef, s32
&& (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_ROCKY_HELMET
|| defAbility == ABILITY_IRON_BARBS || defAbility == ABILITY_ROUGH_SKIN))
{
- if (gMovesInfo[move1].makesContact && !gMovesInfo[move2].makesContact)
+ bool32 moveContact1 = MoveMakesContact(move1);
+ bool32 moveContact2 = MoveMakesContact(move2);
+ if (moveContact1 && !moveContact2)
return -1;
- if (gMovesInfo[move2].makesContact && !gMovesInfo[move1].makesContact)
+ if (moveContact2 && !moveContact1)
return 1;
}
@@ -1041,7 +1051,7 @@ uq4_12_t AI_GetTypeEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef)
gBattleStruct->dynamicMoveType = 0;
SetTypeBeforeUsingMove(move, battlerAtk);
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
typeEffectiveness = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], FALSE);
RestoreBattlerData(battlerAtk);
@@ -1052,7 +1062,6 @@ uq4_12_t AI_GetTypeEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef)
u32 AI_GetMoveEffectiveness(u32 move, u32 battlerAtk, u32 battlerDef)
{
- gMoveResultFlags = 0;
return AI_GetEffectiveness(AI_GetTypeEffectiveness(move, battlerAtk, battlerDef));
}
@@ -1094,7 +1103,7 @@ s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler, u32 moveConsidered)
u32 abilityAI = AI_DATA->abilities[battlerAI];
u32 abilityPlayer = AI_DATA->abilities[battler];
- if (GetMovePriority(battlerAI, moveConsidered) > 0)
+ if (GetBattleMovePriority(battlerAI, moveConsidered) > 0)
return AI_IS_FASTER;
speedBattlerAI = GetBattlerTotalSpeedStatArgs(battlerAI, abilityAI, holdEffectAI);
@@ -1134,9 +1143,10 @@ s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler, u32 moveConsidered)
static bool32 CanEndureHit(u32 battler, u32 battlerTarget, u32 move)
{
- if (!BATTLER_MAX_HP(battlerTarget) || gMovesInfo[move].effect == EFFECT_MULTI_HIT)
+ u32 effect = GetMoveEffect(move);
+ if (!AI_BattlerAtMaxHp(battlerTarget) || effect == EFFECT_MULTI_HIT)
return FALSE;
- if (gMovesInfo[move].strikeCount > 1 && !(gMovesInfo[move].effect == EFFECT_DRAGON_DARTS && IsValidDoubleBattle(battlerTarget)))
+ if (GetMoveStrikeCount(move) > 1 && !(effect == EFFECT_DRAGON_DARTS && IsValidDoubleBattle(battlerTarget)))
return FALSE;
if (AI_DATA->holdEffects[battlerTarget] == HOLD_EFFECT_FOCUS_SASH)
return TRUE;
@@ -1333,6 +1343,8 @@ s32 AI_DecideKnownAbilityForTurn(u32 battlerId)
u32 validAbilities[NUM_ABILITY_SLOTS];
u8 i, numValidAbilities = 0;
u32 knownAbility = AI_GetBattlerAbility(battlerId);
+ u32 indexAbility;
+ u32 abilityAiRatings[NUM_ABILITY_SLOTS] = {0};
// We've had ability overwritten by e.g. Worry Seed. It is not part of AI_PARTY in case of switching
if (gBattleStruct->overwrittenAbilities[battlerId])
@@ -1355,10 +1367,17 @@ s32 AI_DecideKnownAbilityForTurn(u32 battlerId)
for (i = 0; i < NUM_ABILITY_SLOTS; i++)
{
- if (gSpeciesInfo[gBattleMons[battlerId].species].abilities[i] != ABILITY_NONE)
- validAbilities[numValidAbilities++] = gSpeciesInfo[gBattleMons[battlerId].species].abilities[i];
+ indexAbility = gSpeciesInfo[gBattleMons[battlerId].species].abilities[i];
+ if (indexAbility != ABILITY_NONE)
+ {
+ abilityAiRatings[numValidAbilities] = gAbilitiesInfo[indexAbility].aiRating;
+ validAbilities[numValidAbilities++] = indexAbility;
+ }
}
+ if (numValidAbilities > 0 && IsAiBattlerPredictingAbility(battlerId))
+ return validAbilities[RandomWeighted(RNG_AI_PREDICT_ABILITY, abilityAiRatings[0], abilityAiRatings[1], abilityAiRatings[2])];
+
if (numValidAbilities > 0)
return validAbilities[RandomUniform(RNG_AI_ABILITY, 0, numValidAbilities - 1)];
@@ -1392,7 +1411,7 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move)
if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE)
return FALSE; // AI handicap flag: doesn't understand ability suppression concept
- if (IsMoldBreakerTypeAbility(sBattler_AI, atkAbility) || gMovesInfo[move].ignoresTargetAbility)
+ if (IsMoldBreakerTypeAbility(sBattler_AI, atkAbility) || MoveIgnoresTargetAbility(move))
return TRUE;
return FALSE;
@@ -1493,11 +1512,11 @@ bool32 IsSemiInvulnerable(u32 battlerDef, u32 move)
return TRUE;
else if (gBattleStruct->commandingDondozo & (1u << battlerDef))
return TRUE;
- else if (!gMovesInfo[move].damagesAirborne && gStatuses3[battlerDef] & STATUS3_ON_AIR)
+ else if (!MoveDamagesAirborne(move) && gStatuses3[battlerDef] & STATUS3_ON_AIR)
return TRUE;
- else if (!gMovesInfo[move].damagesUnderwater && gStatuses3[battlerDef] & STATUS3_UNDERWATER)
+ else if (!MoveDamagesUnderWater(move) && gStatuses3[battlerDef] & STATUS3_UNDERWATER)
return TRUE;
- else if (!gMovesInfo[move].damagesUnderground && gStatuses3[battlerDef] & STATUS3_UNDERGROUND)
+ else if (!MoveDamagesUnderground(move) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND)
return TRUE;
else
return FALSE;
@@ -1518,22 +1537,23 @@ bool32 IsMoveEncouragedToHit(u32 battlerAtk, u32 battlerDef, u32 move)
if (AI_DATA->abilities[battlerDef] == ABILITY_NO_GUARD || AI_DATA->abilities[battlerAtk] == ABILITY_NO_GUARD)
return TRUE;
- if (B_TOXIC_NEVER_MISS >= GEN_6 && gMovesInfo[move].effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON))
+ u32 effect = GetMoveEffect(move);
+ if (B_TOXIC_NEVER_MISS >= GEN_6 && effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON))
return TRUE;
// discouraged from hitting
weather = AI_GetWeather(AI_DATA);
- if ((weather & B_WEATHER_SUN) && gMovesInfo[move].effect == EFFECT_THUNDER)
+ if ((weather & B_WEATHER_SUN) && effect == EFFECT_THUNDER)
return FALSE;
// increased accuracy but don't always hit
- if ((weather & B_WEATHER_RAIN) && gMovesInfo[move].effect == EFFECT_THUNDER)
+ if ((weather & B_WEATHER_RAIN) && effect == EFFECT_THUNDER)
return TRUE;
- if ((weather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && gMovesInfo[move].effect == EFFECT_BLIZZARD)
+ if ((weather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && effect == EFFECT_BLIZZARD)
return TRUE;
- if (B_MINIMIZE_DMG_ACC >= GEN_6 && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) && gMovesInfo[move].minimizeDoubleDamage)
+ if (B_MINIMIZE_DMG_ACC >= GEN_6 && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) && MoveIncreasesPowerToMinimizedTargets(move))
return TRUE;
- if (gMovesInfo[move].accuracy == 0)
+ if (GetMoveAccuracy(move) == 0)
return TRUE;
return FALSE;
@@ -1547,7 +1567,7 @@ bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbil
gPotentialItemEffectBattler = battlerDef;
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < AI_DATA->holdEffectParams[battlerDef])
return FALSE; //probabilistically speaking, focus band should activate so dont OHKO
- else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && AtMaxHp(battlerDef))
+ else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && AI_BattlerAtMaxHp(battlerDef))
return FALSE;
if (!DoesBattlerIgnoreAbilityChecks(atkAbility, move) && defAbility == ABILITY_STURDY)
@@ -1583,9 +1603,7 @@ bool32 ShouldSetSandstorm(u32 battler, u32 ability, u32 holdEffect)
|| ability == ABILITY_OVERCOAT
|| ability == ABILITY_MAGIC_GUARD
|| holdEffect == HOLD_EFFECT_SAFETY_GOGGLES
- || IS_BATTLER_OF_TYPE(battler, TYPE_ROCK)
- || IS_BATTLER_OF_TYPE(battler, TYPE_STEEL)
- || IS_BATTLER_OF_TYPE(battler, TYPE_GROUND)
+ || IS_BATTLER_ANY_TYPE(battler, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)
|| HasMoveEffect(battler, EFFECT_SHORE_UP)
|| HasMoveEffect(battler, EFFECT_WEATHER_BALL))
{
@@ -1697,7 +1715,7 @@ void ProtectChecks(u32 battlerAtk, u32 battlerDef, u32 move, u32 predictedMove,
if (uses == 0)
{
- if (predictedMove != MOVE_NONE && predictedMove != 0xFFFF && !IS_MOVE_STATUS(predictedMove))
+ if (predictedMove != MOVE_NONE && predictedMove != 0xFFFF && !IsBattleMoveStatus(predictedMove))
ADJUST_SCORE_PTR(DECENT_EFFECT);
else if (Random() % 256 < 100)
ADJUST_SCORE_PTR(WEAK_EFFECT);
@@ -1961,7 +1979,7 @@ bool32 HasOnlyMovesWithCategory(u32 battlerId, u32 category, bool32 onlyOffensiv
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (onlyOffensive && IS_MOVE_STATUS(moves[i]))
+ if (onlyOffensive && IsBattleMoveStatus(moves[i]))
continue;
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetBattleMoveCategory(moves[i]) != category)
return FALSE;
@@ -1990,7 +2008,7 @@ bool32 HasMoveWithType(u32 battler, u32 type)
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].type == type)
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetMoveType(moves[i]) == type)
return TRUE;
}
@@ -2005,14 +2023,14 @@ bool32 HasMoveEffect(u32 battlerId, u32 effect)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
- && gMovesInfo[moves[i]].effect == effect)
+ && GetMoveEffect(moves[i]) == effect)
return TRUE;
}
return FALSE;
}
-bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument)
+bool32 IsPowerBasedOnStatus(u32 battlerId, u32 effect, u32 argument)
{
s32 i;
u16 *moves = GetMovesArray(battlerId);
@@ -2020,8 +2038,8 @@ bool32 HasMoveEffectANDArg(u32 battlerId, u32 effect, u32 argument)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
- && gMovesInfo[moves[i]].effect == effect
- && (gMovesInfo[moves[i]].argument & argument))
+ && GetMoveEffect(moves[i]) == effect
+ && (GetMoveEffectArg_Status(moves[i]) & argument))
return TRUE;
}
@@ -2051,7 +2069,7 @@ bool32 HasMoveWithCriticalHitChance(u32 battlerId)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
- && gMovesInfo[moves[i]].criticalHitStage > 0)
+ && GetMoveCriticalHitStage(moves[i]) > 0)
return TRUE;
}
@@ -2066,7 +2084,7 @@ bool32 HasMoveWithMoveEffectExcept(u32 battlerId, u32 moveEffect, u32 exception)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
- && gMovesInfo[moves[i]].effect != exception
+ && GetMoveEffect(moves[i]) != exception
&& MoveHasAdditionalEffect(moves[i], moveEffect))
return TRUE;
}
@@ -2112,9 +2130,11 @@ bool32 HasMoveThatLowersOwnStats(u32 battlerId)
aiMove = moves[i];
if (aiMove != MOVE_NONE && aiMove != MOVE_UNAVAILABLE)
{
- for (j = 0; j < gMovesInfo[aiMove].numAdditionalEffects; j++)
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(aiMove);
+ for (j = 0; j < additionalEffectCount; j++)
{
- if (IsSelfStatLoweringEffect(gMovesInfo[aiMove].additionalEffects[j].moveEffect) && gMovesInfo[aiMove].additionalEffects[j].self)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(aiMove, j);
+ if (IsSelfStatLoweringEffect(additionalEffect->moveEffect) && additionalEffect->self)
return TRUE;
}
}
@@ -2135,9 +2155,9 @@ bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool
if (!((1u << i) & moveLimitations))
{
- if (ignoreStatus && IS_MOVE_STATUS(moves[i]))
+ if (ignoreStatus && IsBattleMoveStatus(moves[i]))
continue;
- else if ((!IS_MOVE_STATUS(moves[i]) && gMovesInfo[moves[i]].accuracy == 0)
+ else if ((!IsBattleMoveStatus(moves[i]) && GetMoveAccuracy(moves[i]) == 0)
|| GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD))
continue;
@@ -2161,7 +2181,7 @@ bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef)
break;
if (!((1u << i) & moveLimitations))
{
- if (gMovesInfo[moves[i]].effect == EFFECT_SLEEP
+ if (GetMoveEffect(moves[i]) == EFFECT_SLEEP
&& AI_DATA->moveAccuracy[battlerAtk][battlerDef][i] < 85)
return TRUE;
}
@@ -2169,11 +2189,6 @@ bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef)
return FALSE;
}
-bool32 IsHealingMove(u32 move)
-{
- return gMovesInfo[move].healingMove;
-}
-
bool32 HasHealingEffect(u32 battlerId)
{
s32 i;
@@ -2190,7 +2205,7 @@ bool32 HasHealingEffect(u32 battlerId)
bool32 IsTrappingMove(u32 move)
{
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_MEAN_LOOK:
case EFFECT_FAIRY_LOCK:
@@ -2218,7 +2233,14 @@ bool32 HasTrappingMoveEffect(u32 battler)
bool32 HasThawingMove(u32 battler)
{
- CHECK_MOVE_FLAG(thawsUser);
+ s32 i;
+ u16 *moves = GetMovesArray(battler);
+ for (i = 0; i < MAX_MON_MOVES; i++)
+ {
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveThawsUser(moves[i]))
+ return TRUE;
+ }
+ return FALSE;
}
bool32 IsUngroundingEffect(u32 effect)
@@ -2371,6 +2393,34 @@ bool32 IsSwitchOutEffect(u32 effect)
}
}
+static inline bool32 IsMoveSleepClauseTrigger(u32 move)
+{
+ u32 i, effect = GetMoveEffect(move);
+
+ // Sleeping effects like Sleep Powder, Yawn, Dark Void, etc.
+ switch (effect)
+ {
+ case EFFECT_SLEEP:
+ case EFFECT_YAWN:
+ case EFFECT_DARK_VOID:
+ return TRUE;
+ }
+
+ // Sleeping effects like G-Max Befuddle, G-Max Snooze, etc.
+ u32 additionalEffectCount = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < additionalEffectCount; i++)
+ {
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ switch (additionalEffect->moveEffect)
+ {
+ case MAX_EFFECT_EFFECT_SPORE_FOES:
+ case MAX_EFFECT_YAWN_FOE:
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
bool32 HasDamagingMove(u32 battlerId)
{
u32 i;
@@ -2378,7 +2428,7 @@ bool32 HasDamagingMove(u32 battlerId)
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].power != 0)
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !IsBattleMoveStatus(moves[i]))
return TRUE;
}
@@ -2393,7 +2443,7 @@ bool32 HasDamagingMoveOfType(u32 battlerId, u32 type)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
- && gMovesInfo[moves[i]].type == type && gMovesInfo[moves[i]].power != 0)
+ && GetMoveType(moves[i]) == type && !IsBattleMoveStatus(moves[i]))
return TRUE;
}
@@ -2402,7 +2452,14 @@ bool32 HasDamagingMoveOfType(u32 battlerId, u32 type)
bool32 HasSubstituteIgnoringMove(u32 battler)
{
- CHECK_MOVE_FLAG(ignoresSubstitute);
+ s32 i;
+ u16 *moves = GetMovesArray(battler);
+ for (i = 0; i < MAX_MON_MOVES; i++)
+ {
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveIgnoresSubstitute(moves[i]))
+ return TRUE;
+ }
+ return FALSE;
}
bool32 HasHighCritRatioMove(u32 battler)
@@ -2412,7 +2469,7 @@ bool32 HasHighCritRatioMove(u32 battler)
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && gMovesInfo[moves[i]].criticalHitStage > 0)
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetMoveCriticalHitStage(moves[i]) > 0)
return TRUE;
}
@@ -2421,22 +2478,36 @@ bool32 HasHighCritRatioMove(u32 battler)
bool32 HasMagicCoatAffectedMove(u32 battler)
{
- CHECK_MOVE_FLAG(magicCoatAffected);
+ s32 i;
+ u16 *moves = GetMovesArray(battler);
+ for (i = 0; i < MAX_MON_MOVES; i++)
+ {
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveCanBeBouncedBack(moves[i]))
+ return TRUE;
+ }
+ return FALSE;
}
bool32 HasSnatchAffectedMove(u32 battler)
{
- CHECK_MOVE_FLAG(snatchAffected);
+ s32 i;
+ u16 *moves = GetMovesArray(battler);
+ for (i = 0; i < MAX_MON_MOVES; i++)
+ {
+ if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && MoveCanBeSnatched(moves[i]))
+ return TRUE;
+ }
+ return FALSE;
}
bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, u32 move)
{
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_SOLAR_BEAM:
case EFFECT_TWO_TURNS_ATTACK:
return !(AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_POWER_HERB
- || (AI_GetWeather(AI_DATA) & gMovesInfo[move].argument));
+ || (AI_GetWeather(AI_DATA) & GetMoveTwoTurnAttackWeather(move)));
default:
return FALSE;
}
@@ -2524,9 +2595,7 @@ static u32 GetPoisonDamage(u32 battlerId)
static bool32 BattlerAffectedBySandstorm(u32 battlerId, u32 ability)
{
- if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_ROCK)
- && !IS_BATTLER_OF_TYPE(battlerId, TYPE_GROUND)
- && !IS_BATTLER_OF_TYPE(battlerId, TYPE_STEEL)
+ if (!IS_BATTLER_ANY_TYPE(battlerId, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)
&& ability != ABILITY_SAND_VEIL
&& ability != ABILITY_SAND_FORCE
&& ability != ABILITY_SAND_RUSH
@@ -2675,7 +2744,7 @@ static bool32 PartyBattlerShouldAvoidHazards(u32 currBattler, u32 switchBattler)
return FALSE;
if (flags & SIDE_STATUS_STEALTH_ROCK)
- hazardDamage += GetStealthHazardDamageByTypesAndHP(gMovesInfo[MOVE_STEALTH_ROCK].type, type1, type2, maxHp);
+ hazardDamage += GetStealthHazardDamageByTypesAndHP(GetMoveType(MOVE_STEALTH_ROCK), type1, type2, maxHp);
if (flags & SIDE_STATUS_SPIKES && ((type1 != TYPE_FLYING && type2 != TYPE_FLYING
&& ability != ABILITY_LEVITATE && holdEffect != HOLD_EFFECT_AIR_BALLOON)
@@ -2721,8 +2790,8 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov
if (CanTargetFaintAi(battlerDef, battlerAtk))
return SHOULD_PIVOT; // Won't get the two turns, pivot
- if (!IS_MOVE_STATUS(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk))
- || (AtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
+ if (!IsBattleMoveStatus(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk))
+ || (AI_BattlerAtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
|| (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY)
|| defAbility == ABILITY_MULTISCALE
|| defAbility == ABILITY_SHADOW_SHIELD))))
@@ -2730,7 +2799,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov
}
else if (!hasStatBoost)
{
- if (!IS_MOVE_STATUS(move) && (AtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
+ if (!IsBattleMoveStatus(move) && (AI_BattlerAtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
|| (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY)
|| defAbility == ABILITY_MULTISCALE
|| defAbility == ABILITY_SHADOW_SHIELD)))
@@ -2777,7 +2846,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov
{
if (CanTargetFaintAi(battlerDef, battlerAtk))
{
- if (gMovesInfo[move].effect == EFFECT_TELEPORT)
+ if (GetMoveEffect(move) == EFFECT_TELEPORT)
return DONT_PIVOT; // If you're going to faint because you'll go second, use a different move
else
return CAN_TRY_PIVOT; // You're probably going to faint anyways so if for some reason you don't, better switch
@@ -2807,9 +2876,9 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov
else if (CanAIFaintTarget(battlerAtk, battlerDef, 2))
{
// can knock out foe in 2 hits
- if (IS_MOVE_STATUS(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) //Damaging move
+ if (IsBattleMoveStatus(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) //Damaging move
//&& (switchScore >= SWITCHING_INCREASE_RESIST_ALL_MOVES + SWITCHING_INCREASE_KO_FOE //remove hazards
- || (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH && AtMaxHp(battlerDef))))
+ || (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH && AI_BattlerAtMaxHp(battlerDef))))
return DONT_PIVOT; // Pivot to break the sash
else
return CAN_TRY_PIVOT;
@@ -2902,7 +2971,7 @@ bool32 IsBattlerIncapacitated(u32 battler, u32 ability)
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 partnerMove)
{
- if (!CanBeSlept(battlerDef, defAbility)
+ if (!CanBeSlept(battlerDef, defAbility, BLOCKED_BY_SLEEP_CLAUSE)
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep
return FALSE;
@@ -2931,7 +3000,7 @@ bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u3
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
return FALSE;
- else if (defAbility != ABILITY_CORROSION && (IS_BATTLER_OF_TYPE(battlerDef, TYPE_POISON) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL)))
+ else if (defAbility != ABILITY_CORROSION && IS_BATTLER_ANY_TYPE(battlerDef, TYPE_POISON, TYPE_STEEL))
return FALSE;
else if (IsValidDoubleBattle(battlerAtk) && AI_DATA->abilities[BATTLE_PARTNER(battlerDef)] == ABILITY_PASTEL_VEIL)
return FALSE;
@@ -2963,7 +3032,7 @@ bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, u32 move, u32 ability)
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 battlerAtkPartner, u32 move, u32 partnerMove)
{
- if (gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY
+ if (GetBattlerMoveTargetType(battlerAtk, move) == MOVE_TARGET_FOES_AND_ALLY
&& AI_CanBeConfused(battlerAtk, battlerDef, move, defAbility)
&& !AI_CanBeConfused(battlerAtk, BATTLE_PARTNER(battlerDef), move, AI_DATA->abilities[BATTLE_PARTNER(battlerDef)]))
return FALSE;
@@ -3190,8 +3259,7 @@ bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, u32 move, s32 damage)
if (move == 0xFFFF || AI_IsFaster(battlerAtk, battlerDef, move))
{
// using item or user goes first
- u32 healPercent = (gMovesInfo[move].argument == 0) ? 50 : gMovesInfo[move].argument;
- s32 healDmg = (healPercent * damage) / 100;
+ s32 healDmg = (GetMoveAbsorbPercentage(move) * damage) / 100;
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK)
healDmg = 0;
@@ -3292,7 +3360,7 @@ bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, u32
if (!IsDoubleBattle())
return FALSE;
- if (gMovesInfo[move].effect == gMovesInfo[partnerMove].effect
+ if (GetMoveEffect(move) == GetMoveEffect(partnerMove)
&& partnerMove != MOVE_NONE
&& gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef)
{
@@ -3307,7 +3375,7 @@ bool32 PartnerHasSameMoveEffectWithoutTarget(u32 battlerAtkPartner, u32 move, u3
if (!IsDoubleBattle())
return FALSE;
- if (gMovesInfo[move].effect == gMovesInfo[partnerMove].effect
+ if (GetMoveEffect(move) == GetMoveEffect(partnerMove)
&& partnerMove != MOVE_NONE)
return TRUE;
return FALSE;
@@ -3319,27 +3387,29 @@ bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef
if (!IsDoubleBattle())
return FALSE;
+ u32 partnerEffect = GetMoveEffect(partnerMove);
if (partnerMove != MOVE_NONE
&& gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef
- && (gMovesInfo[partnerMove].effect == EFFECT_SLEEP
- || gMovesInfo[partnerMove].effect == EFFECT_POISON
- || gMovesInfo[partnerMove].effect == EFFECT_TOXIC
- || gMovesInfo[partnerMove].effect == EFFECT_PARALYZE
- || gMovesInfo[partnerMove].effect == EFFECT_WILL_O_WISP
- || gMovesInfo[partnerMove].effect == EFFECT_YAWN))
+ && (partnerEffect == EFFECT_SLEEP
+ || partnerEffect == EFFECT_POISON
+ || partnerEffect == EFFECT_TOXIC
+ || partnerEffect == EFFECT_PARALYZE
+ || partnerEffect == EFFECT_WILL_O_WISP
+ || partnerEffect == EFFECT_YAWN))
return TRUE;
return FALSE;
}
bool32 IsMoveEffectWeather(u32 move)
{
+ u32 effect = GetMoveEffect(move);
if (move != MOVE_NONE
- && (gMovesInfo[move].effect == EFFECT_SUNNY_DAY
- || gMovesInfo[move].effect == EFFECT_RAIN_DANCE
- || gMovesInfo[move].effect == EFFECT_SANDSTORM
- || gMovesInfo[move].effect == EFFECT_HAIL
- || gMovesInfo[move].effect == EFFECT_SNOWSCAPE
- || gMovesInfo[move].effect == EFFECT_CHILLY_RECEPTION))
+ && (effect == EFFECT_SUNNY_DAY
+ || effect == EFFECT_RAIN_DANCE
+ || effect == EFFECT_SANDSTORM
+ || effect == EFFECT_HAIL
+ || effect == EFFECT_SNOWSCAPE
+ || effect == EFFECT_CHILLY_RECEPTION))
return TRUE;
return FALSE;
}
@@ -3350,11 +3420,12 @@ bool32 PartnerMoveEffectIsTerrain(u32 battlerAtkPartner, u32 partnerMove)
if (!IsDoubleBattle())
return FALSE;
+ u32 partnerEffect = GetMoveEffect(partnerMove);
if (partnerMove != MOVE_NONE
- && (gMovesInfo[partnerMove].effect == EFFECT_GRASSY_TERRAIN
- || gMovesInfo[partnerMove].effect == EFFECT_MISTY_TERRAIN
- || gMovesInfo[partnerMove].effect == EFFECT_ELECTRIC_TERRAIN
- || gMovesInfo[partnerMove].effect == EFFECT_PSYCHIC_TERRAIN))
+ && (partnerEffect == EFFECT_GRASSY_TERRAIN
+ || partnerEffect == EFFECT_MISTY_TERRAIN
+ || partnerEffect == EFFECT_ELECTRIC_TERRAIN
+ || partnerEffect == EFFECT_PSYCHIC_TERRAIN))
return TRUE;
return FALSE;
@@ -3392,12 +3463,19 @@ bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, u32 move, u32 partnerMov
return FALSE;
}
+bool32 PartnerMoveActivatesSleepClause(u32 partnerMove)
+{
+ if (!IsDoubleBattle() || !IsSleepClauseEnabled())
+ return FALSE;
+ return IsMoveSleepClauseTrigger(partnerMove);
+}
+
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move)
{
u32 i;
s32 firstId, lastId;
struct Pokemon* party;
- bool32 hasStatus = AnyPartyMemberStatused(battlerAtk, gMovesInfo[move].soundMove);
+ bool32 hasStatus = AnyPartyMemberStatused(battlerAtk, IsSoundMove(move));
bool32 needHealing = FALSE;
GetAIPartyIndexes(battlerAtk, &firstId, &lastId);
@@ -3424,7 +3502,7 @@ bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move)
if (!IsDoubleBattle())
{
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_WISH:
if (needHealing)
@@ -3437,7 +3515,7 @@ bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, u32 move)
}
else
{
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_WISH:
return ShouldRecover(battlerAtk, battlerDef, move, 50); // Switch recovery isn't good idea in doubles
@@ -3507,6 +3585,7 @@ u32 AI_WhoStrikesFirstPartyMon(u32 battlerAtk, u32 battlerDef, struct BattlePoke
SetBattlerAiData(battlerAtk, AI_DATA);
u32 aiMonFaster = AI_IsFaster(battlerAtk, battlerDef, moveConsidered);
FreeRestoreBattleMons(savedBattleMons);
+ SetBattlerAiData(battlerAtk, AI_DATA);
return aiMonFaster;
}
@@ -3579,7 +3658,7 @@ bool32 PartyHasMoveCategory(u32 battlerId, u32 category)
if (pp > 0 && move != MOVE_NONE)
{
//TODO - handle photon geyser, light that burns the sky
- if (gMovesInfo[move].category == category)
+ if (GetMoveCategory(move) == category)
return TRUE;
}
}
@@ -3800,7 +3879,7 @@ void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_STALL && HasMoveEffect(battlerAtk, EFFECT_PROTECT))
ADJUST_SCORE_PTR(WEAK_EFFECT); // stall tactic
- if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY)
+ if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PSN_ANY)
|| HasMoveEffect(battlerAtk, EFFECT_VENOM_DRENCH)
|| AI_DATA->abilities[battlerAtk] == ABILITY_MERCILESS)
ADJUST_SCORE_PTR(DECENT_EFFECT);
@@ -3821,14 +3900,14 @@ void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|| (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects physical attacker
&& gSpeciesInfo[gBattleMons[battlerDef].species].baseAttack >= gSpeciesInfo[gBattleMons[battlerDef].species].baseSpAttack + 10))
{
- if (gMovesInfo[GetBestDmgMoveFromBattler(battlerDef, battlerAtk)].category == DAMAGE_CATEGORY_PHYSICAL)
+ if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk)) == DAMAGE_CATEGORY_PHYSICAL)
ADJUST_SCORE_PTR(DECENT_EFFECT);
else
ADJUST_SCORE_PTR(WEAK_EFFECT);
}
- if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)
- || HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN))
+ if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN)
+ || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_BURN))
ADJUST_SCORE_PTR(WEAK_EFFECT);
}
}
@@ -3845,7 +3924,7 @@ void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
u32 defSpeed = AI_DATA->speedStats[battlerDef];
if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe
- || HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS)
+ || IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_PARALYSIS)
|| (HasMoveWithMoveEffectExcept(battlerAtk, MOVE_EFFECT_FLINCH, EFFECT_FIRST_TURN_ONLY)) // filter out Fake Out
|| gBattleMons[battlerDef].status2 & STATUS2_INFATUATION
|| gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
@@ -3870,8 +3949,8 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
&& !(HasMoveEffect(battlerDef, EFFECT_SNORE) || HasMoveEffect(battlerDef, EFFECT_SLEEP_TALK)))
ADJUST_SCORE_PTR(WEAK_EFFECT);
- if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)
- || HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP))
+ if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP)
+ || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_SLEEP))
ADJUST_SCORE_PTR(WEAK_EFFECT);
}
@@ -3905,21 +3984,21 @@ void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score
|| (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_OMNISCIENT) // Not Omniscient but expects special attacker
&& gSpeciesInfo[gBattleMons[battlerDef].species].baseSpAttack >= gSpeciesInfo[gBattleMons[battlerDef].species].baseAttack + 10))
{
- if (gMovesInfo[GetBestDmgMoveFromBattler(battlerDef, battlerAtk)].category == DAMAGE_CATEGORY_SPECIAL)
+ if (GetMoveCategory(GetBestDmgMoveFromBattler(battlerDef, battlerAtk)) == DAMAGE_CATEGORY_SPECIAL)
ADJUST_SCORE_PTR(DECENT_EFFECT);
else
ADJUST_SCORE_PTR(WEAK_EFFECT);
}
- if (HasMoveEffectANDArg(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)
- || HasMoveEffectANDArg(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE))
+ if (IsPowerBasedOnStatus(battlerAtk, EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE)
+ || IsPowerBasedOnStatus(BATTLE_PARTNER(battlerAtk), EFFECT_DOUBLE_POWER_ON_ARG_STATUS, STATUS1_FROSTBITE))
ADJUST_SCORE_PTR(WEAK_EFFECT);
}
}
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move)
{
- if (gMovesInfo[move].makesContact
+ if (MoveMakesContact(move)
&& ability != ABILITY_LONG_REACH
&& holdEffect != HOLD_EFFECT_PROTECTIVE_PADS)
return TRUE;
@@ -3942,22 +4021,22 @@ bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove)
struct SimulatedDamage dmg;
if (gBattleMons[battlerDef].ability == ABILITY_DISGUISE
- && !gMovesInfo[zMove].ignoresTargetAbility
+ && !MoveIgnoresTargetAbility(zMove)
&& (gBattleMons[battlerDef].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battlerDef].species == SPECIES_MIMIKYU_TOTEM_DISGUISED))
return FALSE; // Don't waste a Z-Move busting disguise
if (gBattleMons[battlerDef].ability == ABILITY_ICE_FACE
- && !gMovesInfo[zMove].ignoresTargetAbility
- && gBattleMons[battlerDef].species == SPECIES_EISCUE_ICE && IS_MOVE_PHYSICAL(chosenMove))
+ && !MoveIgnoresTargetAbility(zMove)
+ && gBattleMons[battlerDef].species == SPECIES_EISCUE_ICE && IsBattleMovePhysical(chosenMove))
return FALSE; // Don't waste a Z-Move busting Ice Face
- if (IS_MOVE_STATUS(chosenMove) && !IS_MOVE_STATUS(zMove))
+ if (IsBattleMoveStatus(chosenMove) && !IsBattleMoveStatus(zMove))
return FALSE;
- else if (!IS_MOVE_STATUS(chosenMove) && IS_MOVE_STATUS(zMove))
+ else if (!IsBattleMoveStatus(chosenMove) && IsBattleMoveStatus(zMove))
return FALSE;
dmg = AI_CalcDamageSaveBattlers(chosenMove, battlerAtk, battlerDef, &effectiveness, FALSE, DMG_ROLL_DEFAULT);
- if (!IS_MOVE_STATUS(chosenMove) && dmg.minimum >= gBattleMons[battlerDef].hp)
+ if (!IsBattleMoveStatus(chosenMove) && dmg.minimum >= gBattleMons[battlerDef].hp)
return FALSE; // don't waste damaging z move if can otherwise faint target
return TRUE;
@@ -4060,7 +4139,7 @@ bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, st
|| partnerAbility == ABILITY_WHITE_SMOKE
|| partnerHoldEffect == HOLD_EFFECT_CLEAR_AMULET);
- switch (gMovesInfo[aiData->partnerMove].effect)
+ switch (GetMoveEffect(aiData->partnerMove))
{
case EFFECT_DEFENSE_UP:
case EFFECT_DEFENSE_UP_2:
@@ -4078,12 +4157,13 @@ bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, st
void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
{
- if (gMovesInfo[move].effect == EFFECT_SUBSTITUTE) // Substitute specific
+ u32 effect = GetMoveEffect(move);
+ if (effect == EFFECT_SUBSTITUTE) // Substitute specific
{
if (HasAnyKnownMove(battlerDef) && GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 4)
ADJUST_SCORE_PTR(GOOD_EFFECT);
}
- else if (gMovesInfo[move].effect == EFFECT_SHED_TAIL) // Shed Tail specific
+ else if (effect == EFFECT_SHED_TAIL) // Shed Tail specific
{
if ((ShouldPivot(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_THINKING_STRUCT->movesetIndex))
&& (HasAnyKnownMove(battlerDef) && (GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 2)))
diff --git a/src/battle_anim.c b/src/battle_anim.c
index b036f83cbf..3e079647d2 100644
--- a/src/battle_anim.c
+++ b/src/battle_anim.c
@@ -2230,7 +2230,7 @@ static void Cmd_jumpifmovetypeequal(void)
{
const u8 *type = sBattleAnimScriptPtr + 1;
sBattleAnimScriptPtr += 2;
- if (*type != GetMoveType(gCurrentMove))
+ if (*type != GetBattleMoveType(gCurrentMove))
sBattleAnimScriptPtr += 4;
else
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c
index d5efe499eb..a3104122d1 100644
--- a/src/battle_anim_effects_1.c
+++ b/src/battle_anim_effects_1.c
@@ -5413,7 +5413,9 @@ static void AnimMilkBottle_Step1(struct Sprite *sprite)
sprite->data[6]++;
}
else if (sprite->data[7] > 0)
+ {
sprite->data[7]--;
+ }
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(sprite->data[6], sprite->data[7]));
if (sprite->data[6] == 16 && sprite->data[7] == 0)
@@ -6642,6 +6644,79 @@ static void ReloadBattlerSprites(u32 battler, struct Pokemon *party)
}
}
+static void TrySwapSkyDropTargets(u32 battlerAtk, u32 battlerPartner)
+{
+ u32 i, temp;
+
+ // battlerAtk is using Ally Switch
+ // check if our partner is the target of sky drop
+ // If so, change that index to battlerAtk
+ for (i = 0; i < gBattlersCount; i++) {
+ if (gBattleStruct->skyDropTargets[i] == battlerPartner) {
+ gBattleStruct->skyDropTargets[i] = battlerAtk;
+ break;
+ }
+ }
+
+ // Then swap our own sky drop targets with the partner in case our partner is mid-skydrop
+ SWAP(gBattleStruct->skyDropTargets[battlerAtk], gBattleStruct->skyDropTargets[battlerPartner], temp);
+}
+
+#define TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, side, field) \
+ if (gSideTimers[side].field == battlerAtk) \
+ gSideTimers[side].field = battlerPartner; \
+ else if (gSideTimers[side].field == battlerPartner) \
+ gSideTimers[side].field = battlerAtk;
+
+static void TrySwapStickyWebBattlerId(u32 battlerAtk, u32 battlerPartner)
+{
+ u32 atkSide = GetBattlerSide(battlerAtk);
+ u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
+
+ // not all of these are needed to be swapped, but are done so to be robust to anything in the future that might care about them
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, reflectBattlerId);
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, lightscreenBattlerId);
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, mistBattlerId);
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, safeguardBattlerId);
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, auroraVeilBattlerId);
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, tailwindBattlerId);
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, atkSide, luckyChantBattlerId);
+
+ // if we've set sticky web on the opposing side, need to swap stickyWebBattlerId for mirror armor
+ TRY_SIDE_TIMER_BATTLER_ID_SWAP(battlerAtk, battlerPartner, oppSide, stickyWebBattlerId);
+}
+#undef TRY_SIDE_TIMER_BATTLER_ID_SWAP
+
+static void TrySwapWishBattlerIds(u32 battlerAtk, u32 battlerPartner)
+{
+ u32 i, temp;
+ u32 oppSide = GetBattlerSide(BATTLE_OPPOSITE(battlerAtk));
+
+ // if used future sight on opposing side, properly track who used it
+ if (gSideStatuses[oppSide] & SIDE_STATUS_FUTUREATTACK) {
+ for (i = 0; i < gBattlersCount; i++) {
+ if (IsAlly(i,battlerAtk))
+ continue; // only on opposing side
+ if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerAtk) {
+ // if target was attacked with future sight from us, now they'll be the partner slot
+ gWishFutureKnock.futureSightBattlerIndex[i] = battlerPartner;
+ gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerPartner];
+ break;
+ } else if (gWishFutureKnock.futureSightBattlerIndex[i] == battlerPartner) {
+ gWishFutureKnock.futureSightBattlerIndex[i] = battlerAtk;
+ gWishFutureKnock.futureSightPartyIndex[i] = gBattlerPartyIndexes[battlerAtk];
+ break;
+ }
+ }
+ }
+
+ // swap wish party indices
+ if (gWishFutureKnock.wishCounter[battlerAtk] > 0
+ || gWishFutureKnock.wishCounter[battlerPartner] > 0) {
+ SWAP(gWishFutureKnock.wishPartyId[battlerAtk], gWishFutureKnock.wishPartyId[battlerPartner], temp);
+ }
+}
+
static void AnimTask_AllySwitchDataSwap(u8 taskId)
{
s32 i, j;
@@ -6661,6 +6736,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
SwapStructData(&gSpecialStatuses[battlerAtk], &gSpecialStatuses[battlerPartner], data, sizeof(struct SpecialStatus));
SwapStructData(&gProtectStructs[battlerAtk], &gProtectStructs[battlerPartner], data, sizeof(struct ProtectStruct));
SwapStructData(&gBattleSpritesDataPtr->battlerData[battlerAtk], &gBattleSpritesDataPtr->battlerData[battlerPartner], data, sizeof(struct BattleSpriteInfo));
+ SwapStructData(&gBattleStruct->illusion[battlerAtk], &gBattleStruct->illusion[battlerPartner], data, sizeof(struct Illusion));
SWAP(gBattleSpritesDataPtr->battlerData[battlerAtk].invisible, gBattleSpritesDataPtr->battlerData[battlerPartner].invisible, temp);
SWAP(gTransformedPersonalities[battlerAtk], gTransformedPersonalities[battlerPartner], temp);
@@ -6684,6 +6760,7 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
break;
}
SWAP(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], temp);
+ SWAP(gActionsByTurnOrder[i], gActionsByTurnOrder[j], temp);
break;
}
}
@@ -6692,6 +6769,10 @@ static void AnimTask_AllySwitchDataSwap(u8 taskId)
SwitchTwoBattlersInParty(battlerAtk, battlerPartner);
SWAP(gBattlerPartyIndexes[battlerAtk], gBattlerPartyIndexes[battlerPartner], temp);
+ TrySwapSkyDropTargets(battlerAtk, battlerPartner);
+ TrySwapStickyWebBattlerId(battlerAtk, battlerPartner);
+ TrySwapWishBattlerIds(battlerAtk, battlerPartner);
+
// For Snipe Shot and abilities Stalwart/Propeller Tail - keep the original target.
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
diff --git a/src/battle_anim_effects_2.c b/src/battle_anim_effects_2.c
index 0a94cad2dc..e751a1ca51 100755
--- a/src/battle_anim_effects_2.c
+++ b/src/battle_anim_effects_2.c
@@ -2266,7 +2266,9 @@ static void AnimTask_Splash_Step(u8 taskId)
task->data[4] -= 2;
}
else
+ {
task->data[1]++;
+ }
break;
case 3:
if (!RunAffineAnimFromTaskData(task))
@@ -3023,7 +3025,9 @@ static void AnimTask_SpeedDust_Step(u8 taskId)
task->data[8] = 1;
}
else
+ {
task->data[8] = 2;
+ }
}
}
break;
diff --git a/src/battle_anim_electric.c b/src/battle_anim_electric.c
index 64114227e1..6e7c1c1e0c 100644
--- a/src/battle_anim_electric.c
+++ b/src/battle_anim_electric.c
@@ -589,6 +589,17 @@ const struct SpriteTemplate gIonSpriteTemplate =
.callback = AnimIon,
};
+const struct SpriteTemplate gVoltSwitchSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SHADOW_BALL,
+ .paletteTag = ANIM_TAG_IONS,
+ .oam = &gOamData_AffineNormal_ObjNormal_32x32,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gAffineAnims_ShadowBall,
+ .callback = AnimTask_VoltSwitch,
+};
+
// functions
static void AnimLightning(struct Sprite *sprite)
{
@@ -731,7 +742,9 @@ static void AnimZapCannonSpark_Step(struct Sprite *sprite)
sprite->invisible ^= 1;
}
else
+ {
DestroyAnimSprite(sprite);
+ }
}
static void AnimThunderboltOrb_Step(struct Sprite *sprite)
@@ -1013,7 +1026,9 @@ static void AnimTask_ElectricChargingParticles_Step(u8 taskId)
}
}
else if(task->data[7] == 0)
+ {
DestroyAnimVisualTask(taskId);
+ }
}
static void AnimElectricChargingParticles_Step(struct Sprite *sprite)
@@ -1134,7 +1149,9 @@ void AnimTask_VoltTackleAttackerReappear(u8 taskId)
gSprites[task->data[15]].x2 = task->data[14];
}
else
+ {
task->data[0]++;
+ }
}
break;
@@ -1523,3 +1540,52 @@ static void AnimIon_Step(struct Sprite *sprite)
if (sprite->animEnded)
DestroySprite(sprite);
}
+
+//Volt Switch//
+
+//Launches the projectiles for Volt Switch
+//arg 0: initial x pixel offset
+//arg 1: initial y pixel offset
+//arg 2: target x pixel offset
+//arg 3: target y pixel offset
+//arg 4: duration
+//arg 5: wave amplitude
+static void VoltSwitch_Step(struct Sprite* sprite)
+{
+ sprite->invisible = FALSE;
+
+ if (TranslateAnimHorizontalArc(sprite))
+ {
+ //Merge coords into one
+ sprite->x += sprite->x2;
+ sprite->y += sprite->y2;
+ sprite->x2 = 0;
+ sprite->y2 = 0;
+
+ //Come straight back to the attacker
+ sprite->data[0] = 0x14; //Duration
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ }
+}
+
+void AnimTask_VoltSwitch(struct Sprite* sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 0);
+
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ else
+ sprite->y += 10; //Move slightly down
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; //Target X
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3]; //Target Y
+ sprite->data[5] = gBattleAnimArgs[5];
+ InitAnimArcTranslation(sprite);
+
+ sprite->callback = VoltSwitch_Step;
+}
diff --git a/src/battle_anim_flying.c b/src/battle_anim_flying.c
index 42c99740d3..8b613ad677 100644
--- a/src/battle_anim_flying.c
+++ b/src/battle_anim_flying.c
@@ -363,7 +363,6 @@ static void AnimEllipticalGustCentered(struct Sprite *sprite)
InitSpritePosToAnimTargetsCentre(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
-
sprite->y += 20;
sprite->data[1] = 191;
sprite->callback = AnimEllipticalGust_Step;
diff --git a/src/battle_anim_ghost.c b/src/battle_anim_ghost.c
index e583e44635..f848cd794a 100644
--- a/src/battle_anim_ghost.c
+++ b/src/battle_anim_ghost.c
@@ -346,7 +346,9 @@ static void AnimConfuseRayBallBounce_Step2(struct Sprite *sprite)
sprite->callback = DestroyAnimSpriteAndDisableBlend;
}
else
+ {
UpdateConfuseRayBallBlend(sprite);
+ }
}
static void UpdateConfuseRayBallBlend(struct Sprite *sprite)
diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c
index 04fd111a84..240e43b713 100644
--- a/src/battle_anim_mon_movement.c
+++ b/src/battle_anim_mon_movement.c
@@ -15,8 +15,10 @@ static void ReverseHorizontalLungeDirection(struct Sprite *sprite);
static void DoVerticalDip(struct Sprite *sprite);
static void ReverseVerticalDipDirection(struct Sprite *sprite);
static void SlideMonToOriginalPos(struct Sprite *sprite);
+static void SlideMonToOriginalPosPartner(struct Sprite *sprite);
static void SlideMonToOriginalPos_Step(struct Sprite *sprite);
static void SlideMonToOffset(struct Sprite *sprite);
+static void SlideMonToOffsetPartner(struct Sprite *sprite);
static void SlideMonToOffsetAndBack(struct Sprite *sprite);
static void SlideMonToOffsetAndBack_End(struct Sprite *sprite);
static void AnimTask_WindUpLunge_Step1(u8 taskId);
@@ -63,6 +65,17 @@ const struct SpriteTemplate gSlideMonToOriginalPosSpriteTemplate =
.callback = SlideMonToOriginalPos,
};
+const struct SpriteTemplate gSlideMonToOriginalPosPartnerSpriteTemplate =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SlideMonToOriginalPosPartner,
+};
+
const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate =
{
.tileTag = 0,
@@ -74,6 +87,17 @@ const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate =
.callback = SlideMonToOffset,
};
+const struct SpriteTemplate gSlideMonToOffsetPartnerSpriteTemplate =
+{
+ .tileTag = 0,
+ .paletteTag = 0,
+ .oam = &gDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SlideMonToOffsetPartner,
+};
+
const struct SpriteTemplate gSlideMonToOffsetAndBackSpriteTemplate =
{
.tileTag = 0,
@@ -487,7 +511,41 @@ static void ReverseVerticalDipDirection(struct Sprite *sprite)
// arg 2: duration
static void SlideMonToOriginalPos(struct Sprite *sprite)
{
- u32 monSpriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+ u32 monSpriteId;
+ if (!gBattleAnimArgs[0])
+ monSpriteId = gBattlerSpriteIds[gBattleAnimAttacker];
+ else
+ monSpriteId = gBattlerSpriteIds[gBattleAnimTarget];
+
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gSprites[monSpriteId].x + gSprites[monSpriteId].x2;
+ sprite->data[2] = gSprites[monSpriteId].x;
+ sprite->data[3] = gSprites[monSpriteId].y + gSprites[monSpriteId].y2;
+ sprite->data[4] = gSprites[monSpriteId].y;
+ InitSpriteDataForLinearTranslation(sprite);
+ sprite->data[3] = 0;
+ sprite->data[4] = 0;
+ sprite->data[5] = gSprites[monSpriteId].x2;
+ sprite->data[6] = gSprites[monSpriteId].y2;
+ sprite->invisible = TRUE;
+
+ if (gBattleAnimArgs[1] == 1)
+ sprite->data[2] = 0;
+ else if (gBattleAnimArgs[1] == 2)
+ sprite->data[1] = 0;
+
+ sprite->data[7] = gBattleAnimArgs[1];
+ sprite->data[7] |= monSpriteId << 8;
+ sprite->callback = SlideMonToOriginalPos_Step;
+}
+
+static void SlideMonToOriginalPosPartner(struct Sprite *sprite)
+{
+ u32 monSpriteId;
+ if (!gBattleAnimArgs[0])
+ monSpriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)];
+ else
+ monSpriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)];
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gSprites[monSpriteId].x + gSprites[monSpriteId].x2;
@@ -550,9 +608,48 @@ static void SlideMonToOriginalPos_Step(struct Sprite *sprite)
// arg 4: duration
static void SlideMonToOffset(struct Sprite *sprite)
{
- u8 monSpriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]);
+ u8 battler;
+ u8 monSpriteId;
+ if (!gBattleAnimArgs[0])
+ battler = gBattleAnimAttacker;
+ else
+ battler = gBattleAnimTarget;
- if (GetBattlerSide(gBattleAnimArgs[0]) != B_SIDE_PLAYER)
+ monSpriteId = gBattlerSpriteIds[battler];
+ if (GetBattlerSide(battler) != B_SIDE_PLAYER)
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ if (gBattleAnimArgs[3] == 1)
+ {
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ }
+ }
+
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = gSprites[monSpriteId].x;
+ sprite->data[2] = gSprites[monSpriteId].x + gBattleAnimArgs[1];
+ sprite->data[3] = gSprites[monSpriteId].y;
+ sprite->data[4] = gSprites[monSpriteId].y + gBattleAnimArgs[2];
+ InitSpriteDataForLinearTranslation(sprite);
+ sprite->data[3] = 0;
+ sprite->data[4] = 0;
+ sprite->data[5] = monSpriteId;
+ sprite->invisible = TRUE;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = TranslateSpriteLinearByIdFixedPoint;
+}
+
+static void SlideMonToOffsetPartner(struct Sprite *sprite)
+{
+ u8 battler;
+ u8 monSpriteId;
+ if (!gBattleAnimArgs[0])
+ battler = BATTLE_PARTNER(gBattleAnimAttacker);
+ else
+ battler = BATTLE_PARTNER(gBattleAnimTarget);
+
+ monSpriteId = gBattlerSpriteIds[battler];
+ if (GetBattlerSide(battler) != B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
if (gBattleAnimArgs[3] == 1)
diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c
index 50bb83305f..7308a9d6fd 100644
--- a/src/battle_anim_new.c
+++ b/src/battle_anim_new.c
@@ -4380,6 +4380,29 @@ const struct SpriteTemplate gSpriteTemplate_FlipTurnBack = {
.callback = AnimAbsorptionOrb
};
+// U-Turn
+const struct SpriteTemplate gUTurnBallSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SMALL_BUBBLES,
+ .paletteTag = ANIM_TAG_RAZOR_LEAF,
+ .oam = &gOamData_AffineOff_ObjNormal_16x16,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gAffineAnims_ShadowBall,
+ .callback = AnimShadowBall,
+};
+
+const struct SpriteTemplate gUTurnBallBackSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SMALL_BUBBLES,
+ .paletteTag = ANIM_TAG_RAZOR_LEAF,
+ .oam = &gOamData_AffineOff_ObjNormal_16x16,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gAffineAnims_ShadowBall,
+ .callback = AnimAbsorptionOrb,
+};
+
// wicked blow
static const union AffineAnimCmd sSpriteAffineAnim_DrainPunchFist[] = {
AFFINEANIMCMD_FRAME(256, 256, 0, 1), //Double sprite size
@@ -9244,19 +9267,19 @@ void AnimTask_DynamaxGrowth(u8 taskId) // from CFRU
void AnimTask_GetWeatherToSet(u8 taskId)
{
- switch (gMovesInfo[gCurrentMove].argument)
+ switch (GetMoveMaxEffect(gCurrentMove))
{
case MAX_EFFECT_SUN:
- gBattleAnimArgs[ARG_RET_ID] = 1;
+ gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SUN;
break;
case MAX_EFFECT_RAIN:
- gBattleAnimArgs[ARG_RET_ID] = 2;
+ gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_RAIN;
break;
case MAX_EFFECT_SANDSTORM:
- gBattleAnimArgs[ARG_RET_ID] = 3;
+ gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_SANDSTORM;
break;
case MAX_EFFECT_HAIL:
- gBattleAnimArgs[ARG_RET_ID] = 4;
+ gBattleAnimArgs[ARG_RET_ID] = ANIM_WEATHER_HAIL;
break;
}
DestroyAnimVisualTask(taskId);
diff --git a/src/battle_anim_rock.c b/src/battle_anim_rock.c
index 354fb21014..ec7bc535df 100644
--- a/src/battle_anim_rock.c
+++ b/src/battle_anim_rock.c
@@ -478,14 +478,15 @@ void AnimRockFragment(struct Sprite *sprite)
// Swirls particle in vortex. Used for moves like Fire Spin or Sand Tomb
void AnimParticleInVortex(struct Sprite *sprite)
{
- if (IsDoubleBattle() //got a little lazy here will fix later
- && (gAnimMoveIndex == MOVE_BLEAKWIND_STORM
+ if (IsDoubleBattle()
+ && (gAnimMoveIndex == MOVE_BLEAKWIND_STORM
|| gAnimMoveIndex == MOVE_SANDSEAR_STORM
|| gAnimMoveIndex == MOVE_SPRINGTIDE_STORM
|| gAnimMoveIndex == MOVE_WILDBOLT_STORM))
InitSpritePosToAnimTargetsCentre(sprite, FALSE);
else
- InitSpritePosToAnimTarget(sprite, FALSE);
+ InitSpritePosToAnimBattler(gBattleAnimArgs[6], sprite, FALSE);
+
sprite->data[0] = gBattleAnimArgs[3];
sprite->data[1] = gBattleAnimArgs[2];
sprite->data[2] = gBattleAnimArgs[4];
diff --git a/src/battle_anim_throw.c b/src/battle_anim_throw.c
index 611d12be56..a8c6e4077e 100644
--- a/src/battle_anim_throw.c
+++ b/src/battle_anim_throw.c
@@ -1339,7 +1339,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF;
}
else
+ {
gBattleSpritesDataPtr->animationData->ballSubpx += 176;
+ }
sprite->sTimer++;
sprite->affineAnimPaused = FALSE;
@@ -1364,7 +1366,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
ChangeSpriteAffineAnim(sprite, BALL_ROTATE_RIGHT);
}
else
+ {
sprite->affineAnimPaused = TRUE;
+ }
break;
case BALL_ROLL_2:
if (gBattleSpritesDataPtr->animationData->ballSubpx > 255)
@@ -1373,7 +1377,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF;
}
else
+ {
gBattleSpritesDataPtr->animationData->ballSubpx += 176;
+ }
sprite->sTimer++;
sprite->affineAnimPaused = FALSE;
@@ -1408,7 +1414,9 @@ static void SpriteCB_Ball_Wobble_Step(struct Sprite *sprite)
gBattleSpritesDataPtr->animationData->ballSubpx &= 0xFF;
}
else
+ {
gBattleSpritesDataPtr->animationData->ballSubpx += 176;
+ }
sprite->sTimer++;
sprite->affineAnimPaused = FALSE;
@@ -1598,7 +1606,9 @@ static void SpriteCB_Ball_FadeOut(struct Sprite *sprite)
static void DestroySpriteAfterOneFrame(struct Sprite *sprite)
{
if (sprite->sFrame == 0)
+ {
sprite->sFrame = -1;
+ }
else
{
FreeSpriteOamMatrix(sprite);
@@ -1618,7 +1628,9 @@ static void MakeCaptureStars(struct Sprite *sprite)
u8 subpriority;
if (sprite->subpriority)
+ {
subpriority = sprite->subpriority - 1;
+ }
else
{
subpriority = 0;
@@ -2555,7 +2567,9 @@ static void SpriteCB_ShinyStars_Diagonal(struct Sprite *sprite)
{
// Delayed four frames to de-sync from encircling stars
if (sprite->sTimer < 4)
+ {
sprite->sTimer++;
+ }
else
{
sprite->invisible = FALSE;
diff --git a/src/battle_arena.c b/src/battle_arena.c
index b292ff8837..ff406a37df 100644
--- a/src/battle_arena.c
+++ b/src/battle_arena.c
@@ -360,20 +360,21 @@ void BattleArena_AddMindPoints(u8 battler)
// All moves with power != 0 give 1 point, with the following exceptions:
// - Counter, Mirror Coat, and Bide give 0 points
// - Fake Out subtracts 1 point
-// All moves with power == 0 give 0 points, with the following exceptions:
+// All status moves give 0 points, with the following exceptions:
// - Protect, Detect, and Endure subtract 1 point
+ u32 effect = GetMoveEffect(gCurrentMove);
- if (gMovesInfo[gCurrentMove].effect == EFFECT_FIRST_TURN_ONLY
- || gMovesInfo[gCurrentMove].effect == EFFECT_PROTECT
- || gMovesInfo[gCurrentMove].effect == EFFECT_ENDURE)
+ if (effect == EFFECT_FIRST_TURN_ONLY
+ || effect == EFFECT_PROTECT
+ || effect == EFFECT_ENDURE)
{
gBattleStruct->arenaMindPoints[battler]--;
}
- else if (gMovesInfo[gCurrentMove].power != 0
- && gMovesInfo[gCurrentMove].effect != EFFECT_COUNTER
- && gMovesInfo[gCurrentMove].effect != EFFECT_MIRROR_COAT
- && gMovesInfo[gCurrentMove].effect != EFFECT_METAL_BURST
- && gMovesInfo[gCurrentMove].effect != EFFECT_BIDE)
+ else if (!IsBattleMoveStatus(gCurrentMove)
+ && effect != EFFECT_COUNTER
+ && effect != EFFECT_MIRROR_COAT
+ && effect != EFFECT_METAL_BURST
+ && effect != EFFECT_BIDE)
{
gBattleStruct->arenaMindPoints[battler]++;
}
@@ -391,20 +392,20 @@ void BattleArena_AddSkillPoints(u8 battler)
*failedMoveBits &= ~((1u << battler));
skillPoints[battler] -= 2;
}
- else if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ else if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
{
- if (!(gMoveResultFlags & MOVE_RESULT_MISSED) || gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED)
+ if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_MISSED) || gBattleCommunication[MISS_TYPE] != B_MSG_PROTECTED)
skillPoints[battler] -= 2;
}
- else if ((gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) && (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE))
+ else if ((gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_SUPER_EFFECTIVE) && (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NOT_VERY_EFFECTIVE))
{
skillPoints[battler] += 1;
}
- else if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE)
+ else if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_SUPER_EFFECTIVE)
{
skillPoints[battler] += 2;
}
- else if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE)
+ else if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NOT_VERY_EFFECTIVE)
{
skillPoints[battler] -= 1;
}
diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c
index ef12589681..898a59c2ee 100644
--- a/src/battle_controller_opponent.c
+++ b/src/battle_controller_opponent.c
@@ -185,7 +185,9 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
}
else
+ {
return;
+ }
}
else if (gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim)
{
@@ -198,13 +200,17 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
}
else
+ {
return;
+ }
}
- gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
- gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
+ gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim = FALSE;
+ gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
}
else
+ {
return;
+ }
gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
gBattlerControllerFuncs[battler] = Intro_DelayAndEnd;
@@ -274,7 +280,9 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
m4aMPlayContinue(&gMPlayInfo_BGM);
}
else
+ {
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100);
+ }
}
gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = TRUE;
bgmRestored = TRUE;
@@ -601,7 +609,7 @@ static void OpponentHandleChooseMove(u32 battler)
} while (!CanTargetBattler(battler, target, move));
// Don't bother to loop through table if the move can't attack ally
- if (B_WILD_NATURAL_ENEMIES == TRUE && !(gMovesInfo[move].target & MOVE_TARGET_BOTH))
+ if (B_WILD_NATURAL_ENEMIES == TRUE && !(GetBattlerMoveTargetType(battler, move) & MOVE_TARGET_BOTH))
{
u16 i, speciesAttacker, speciesTarget, isPartnerEnemy = FALSE;
static const u16 naturalEnemies[][2] =
@@ -648,6 +656,22 @@ static void OpponentHandleChooseItem(u32 battler)
OpponentBufferExecCompleted(battler);
}
+static inline bool32 IsAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler)
+{
+ return AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON
+ && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1)
+ && CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle;
+}
+
+static inline bool32 IsDoubleAcePokemon(u32 chosenMonId, u32 pokemonInBattle, u32 battler)
+{
+ return AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON
+ && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1)
+ && (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2)
+ && CountAIAliveNonEggMonsExcept(PARTY_SIZE) != pokemonInBattle
+ && CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) != pokemonInBattle;
+}
+
static void OpponentHandleChoosePokemon(u32 battler)
{
s32 chosenMonId;
@@ -680,20 +704,14 @@ static void OpponentHandleChoosePokemon(u32 battler)
GetAIPartyIndexes(battler, &firstId, &lastId);
for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--)
{
- if (!IsValidForBattle(&gEnemyParty[chosenMonId]))
- continue;
- if (chosenMonId == gBattlerPartyIndexes[battler1]
+ if (!IsValidForBattle(&gEnemyParty[chosenMonId])
+ || chosenMonId == gBattlerPartyIndexes[battler1]
|| chosenMonId == gBattlerPartyIndexes[battler2])
continue;
- if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON)
- && ((chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1) || CountAIAliveNonEggMonsExcept(PARTY_SIZE) == pokemonInBattle))
- continue;
- if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_DOUBLE_ACE_POKEMON)
- && (((chosenMonId == CalculateEnemyPartyCountInSide(battler) - 1) || (chosenMonId == CalculateEnemyPartyCountInSide(battler) - 2))
- || (CountAIAliveNonEggMonsExcept(PARTY_SIZE) == pokemonInBattle || CountAIAliveNonEggMonsExcept(PARTY_SIZE-1) == pokemonInBattle)))
- continue;
- // mon is valid
- break;
+
+ if (!IsAcePokemon(chosenMonId, pokemonInBattle, battler)
+ && !IsDoubleAcePokemon(chosenMonId, pokemonInBattle, battler))
+ break;
}
}
gBattleStruct->monToSwitchIntoId[battler] = chosenMonId;
@@ -709,7 +727,6 @@ static void OpponentHandleChoosePokemon(u32 battler)
#endif // TESTING
BtlController_EmitChosenMonReturnValue(battler, BUFFER_B, chosenMonId, NULL);
OpponentBufferExecCompleted(battler);
-
}
static u8 CountAIAliveNonEggMonsExcept(u8 slotToIgnore)
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index 87b1cd5ca4..1eac4dbe26 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -31,6 +31,7 @@
#include "text.h"
#include "util.h"
#include "window.h"
+#include "line_break.h"
#include "constants/battle_anim.h"
#include "constants/battle_move_effects.h"
#include "constants/battle_partner.h"
@@ -679,13 +680,13 @@ void HandleInputChooseMove(u32 battler)
if (gBattleStruct->zmove.viewing)
{
gBattleStruct->zmove.viewing = FALSE;
- if (gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].category != DAMAGE_CATEGORY_STATUS)
+ if (GetMoveCategory(moveInfo->moves[gMoveSelectionCursor[battler]]) != DAMAGE_CATEGORY_STATUS)
moveTarget = MOVE_TARGET_SELECTED; //damaging z moves always have selected target
}
// Status moves turn into Max Guard when Dynamaxed, targets user.
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX))
- moveTarget = gMovesInfo[GetMaxMove(battler, moveInfo->moves[gMoveSelectionCursor[battler]])].target;
+ moveTarget = GetMoveTarget(GetMaxMove(battler, moveInfo->moves[gMoveSelectionCursor[battler]]));
if (moveTarget & MOVE_TARGET_USER)
gMultiUsePlayerCursor = battler;
@@ -1714,7 +1715,7 @@ static void MoveSelectionDisplayMoveType(u32 battler)
u32 speciesId;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType);
- type = gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].type;
+ type = GetMoveType(moveInfo->moves[gMoveSelectionCursor[battler]]);
if (moveInfo->moves[gMoveSelectionCursor[battler]] == MOVE_TERA_BLAST)
{
@@ -1730,7 +1731,7 @@ static void MoveSelectionDisplayMoveType(u32 battler)
|| speciesId == SPECIES_OGERPON_CORNERSTONE || speciesId == SPECIES_OGERPON_CORNERSTONE_TERA)
type = gBattleMons[battler].types[1];
}
- else if (gMovesInfo[moveInfo->moves[gMoveSelectionCursor[battler]]].category == DAMAGE_CATEGORY_STATUS
+ else if (GetMoveCategory(moveInfo->moves[gMoveSelectionCursor[battler]]) == DAMAGE_CATEGORY_STATUS
&& (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX)))
{
type = TYPE_NORMAL; // Max Guard is always a Normal-type move
@@ -1756,9 +1757,8 @@ static void MoveSelectionDisplayMoveDescription(u32 battler)
{
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[battler][4]);
u16 move = moveInfo->moves[gMoveSelectionCursor[battler]];
- u16 pwr = gMovesInfo[move].power;
- u16 acc = gMovesInfo[move].accuracy;
- u8 cat = gMovesInfo[move].category;
+ u16 pwr = GetMovePower(move);
+ u16 acc = GetMoveAccuracy(move);
u8 pwr_num[3], acc_num[3];
u8 cat_desc[7] = _("CAT: ");
@@ -1786,16 +1786,13 @@ static void MoveSelectionDisplayMoveDescription(u32 battler)
StringAppend(gDisplayedStringBattle, acc_desc);
StringAppend(gDisplayedStringBattle, acc_num);
StringAppend(gDisplayedStringBattle, gText_NewLine);
- if (gMovesInfo[move].effect == EFFECT_PLACEHOLDER)
- StringAppend(gDisplayedStringBattle, gNotDoneYetDescription);
- else
- StringAppend(gDisplayedStringBattle, gMovesInfo[move].description);
+ StringAppend(gDisplayedStringBattle, GetMoveDescription(move));
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_DESCRIPTION);
if (gCategoryIconSpriteId == 0xFF)
gCategoryIconSpriteId = CreateSprite(&gSpriteTemplate_CategoryIcons, 38, 64, 1);
- StartSpriteAnim(&gSprites[gCategoryIconSpriteId], cat);
+ StartSpriteAnim(&gSprites[gCategoryIconSpriteId], GetBattleMoveCategory(move));
CopyWindowToVram(B_WIN_MOVE_DESCRIPTION, COPYWIN_FULL);
}
@@ -2044,13 +2041,15 @@ static void PlayerHandleChooseAction(u32 battler)
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo);
+ BreakStringAutomatic(gDisplayedStringBattle, WindowWidthPx(B_WIN_ACTION_PROMPT), 2, FONT_NORMAL);
if (B_SHOW_PARTNER_TARGET && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && IsBattlerAlive(B_POSITION_PLAYER_RIGHT))
{
StringCopy(gStringVar1, COMPOUND_STRING("Partner will use:\n"));
u32 move = gBattleMons[B_POSITION_PLAYER_RIGHT].moves[*(gBattleStruct->chosenMovePositions + B_POSITION_PLAYER_RIGHT)];
- StringAppend(gStringVar1, gMovesInfo[move].name);
- if (gMovesInfo[move].target == MOVE_TARGET_SELECTED)
+ StringAppend(gStringVar1, GetMoveName(move));
+ u32 moveTarget = GetBattlerMoveTargetType(B_POSITION_PLAYER_RIGHT, move);
+ if (moveTarget == MOVE_TARGET_SELECTED)
{
if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_OPPONENT_LEFT)
StringAppend(gStringVar1, COMPOUND_STRING(" -{UP_ARROW}"));
@@ -2061,15 +2060,15 @@ static void PlayerHandleChooseAction(u32 battler)
else if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_PLAYER_RIGHT)
StringAppend(gStringVar1, COMPOUND_STRING(" {DOWN_ARROW}-"));
}
- else if (gMovesInfo[move].target == MOVE_TARGET_BOTH)
+ else if (moveTarget == MOVE_TARGET_BOTH)
{
StringAppend(gStringVar1, COMPOUND_STRING(" {UP_ARROW}{UP_ARROW}"));
}
- else if (gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY)
+ else if (moveTarget == MOVE_TARGET_FOES_AND_ALLY)
{
StringAppend(gStringVar1, COMPOUND_STRING(" {V_D_ARROW}{UP_ARROW}"));
}
- else if (gMovesInfo[move].target == MOVE_TARGET_ALL_BATTLERS)
+ else if (moveTarget == MOVE_TARGET_ALL_BATTLERS)
{
StringAppend(gStringVar1, COMPOUND_STRING(" {V_D_ARROW}{V_D_ARROW}"));
}
diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c
index f987c333ce..81170ec9de 100644
--- a/src/battle_controller_player_partner.c
+++ b/src/battle_controller_player_partner.c
@@ -353,10 +353,11 @@ static void PlayerPartnerHandleChooseMove(u32 battler)
chosenMoveId = gBattleStruct->aiMoveOrAction[battler];
gBattlerTarget = gBattleStruct->aiChosenTarget[battler];
+ u32 moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveId]);
- if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
+ if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED))
gBattlerTarget = battler;
- else if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH)
+ else if (moveTarget & MOVE_TARGET_BOTH)
{
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (gAbsentBattlerFlags & (1u << gBattlerTarget))
diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c
index b85157f246..932ce47fd9 100644
--- a/src/battle_controller_safari.c
+++ b/src/battle_controller_safari.c
@@ -20,6 +20,7 @@
#include "text.h"
#include "util.h"
#include "window.h"
+#include "line_break.h"
#include "constants/battle_anim.h"
#include "constants/songs.h"
#include "constants/trainers.h"
@@ -298,6 +299,7 @@ static void SafariHandleChooseAction(u32 battler)
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo2);
+ BreakStringAutomatic(gDisplayedStringBattle, WindowWidthPx(B_WIN_ACTION_PROMPT), 2, FONT_NORMAL);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
}
diff --git a/src/battle_controllers.c b/src/battle_controllers.c
index 553eb7a85c..d5a7290c63 100644
--- a/src/battle_controllers.c
+++ b/src/battle_controllers.c
@@ -1113,7 +1113,7 @@ void BtlController_EmitPrintString(u32 battler, u32 bufferId, u16 stringID)
stringInfo->bakScriptPartyIdx = gBattleStruct->scriptPartyIdx;
stringInfo->hpScale = gBattleStruct->hpScale;
stringInfo->itemEffectBattler = gPotentialItemEffectBattler;
- stringInfo->moveType = gMovesInfo[gCurrentMove].type;
+ stringInfo->moveType = GetMoveType(gCurrentMove);
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
stringInfo->abilities[i] = gBattleMons[i].ability;
@@ -2542,7 +2542,10 @@ void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 is
gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH;
gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2;
}
- gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn;
+ if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless)
+ gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSpawn;
+ else
+ gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn;
gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic;
}
diff --git a/src/battle_debug.c b/src/battle_debug.c
index b03ef194f0..b0e1e23add 100644
--- a/src/battle_debug.c
+++ b/src/battle_debug.c
@@ -1982,7 +1982,7 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus,
*(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_DAMAGE_NON_TYPES;
else
*(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_DAMAGE_NON_TYPES;
- sideTimer->damageNonTypesType = gMovesInfo[gCurrentMove].type;
+ sideTimer->damageNonTypesType = GetMoveType(gCurrentMove);
}
return &sideTimer->damageNonTypesTimer;
case LIST_SIDE_RAINBOW:
diff --git a/src/battle_dome.c b/src/battle_dome.c
index 1d79333290..19c5086523 100644
--- a/src/battle_dome.c
+++ b/src/battle_dome.c
@@ -2395,13 +2395,13 @@ static int GetTypeEffectivenessPoints(int move, int targetSpecies, int mode)
int defType1, defType2, defAbility, moveType;
int typePower = TYPE_x1;
- if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || IS_MOVE_STATUS(move))
+ if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || IsBattleMoveStatus(move))
return 0;
defType1 = gSpeciesInfo[targetSpecies].types[0];
defType2 = gSpeciesInfo[targetSpecies].types[1];
defAbility = gSpeciesInfo[targetSpecies].abilities[0];
- moveType = gMovesInfo[move].type;
+ moveType = GetMoveType(move);
if (defAbility == ABILITY_LEVITATE && moveType == TYPE_GROUND)
{
@@ -3890,7 +3890,7 @@ static bool32 IsDomeHealingMove(u32 move)
if (IsHealingMove(move))
return TRUE;
// Check extra effects not considered plain healing by AI
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_INGRAIN:
case EFFECT_REFRESH:
@@ -3949,9 +3949,9 @@ static bool32 IsDomeRiskyMoveEffect(u32 effect)
static bool32 IsDomeLuckyMove(u32 move)
{
- if (gMovesInfo[move].accuracy <= 50)
+ if (GetMoveAccuracy(move) <= 50)
return TRUE;
- switch(gMovesInfo[move].effect)
+ switch(GetMoveEffect(move))
{
case EFFECT_COUNTER:
case EFFECT_OHKO: // Technically redundant because of the above accuracy check
@@ -3982,10 +3982,10 @@ static bool32 IsDomePopularMove(u32 move)
if (i == NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES)
return FALSE;
// Filter in TMs/HMs
- if (gMovesInfo[move].power >= 90)
+ if (GetMovePower(move) >= 90)
return TRUE;
- switch(gMovesInfo[move].effect)
+ switch(GetMoveEffect(move))
{
case EFFECT_PROTECT:
case EFFECT_MAT_BLOCK:
@@ -4000,7 +4000,7 @@ static bool32 IsDomePopularMove(u32 move)
static bool32 IsDomeStatusMoveEffect(u32 move)
{
- switch(gMovesInfo[move].effect)
+ switch(GetMoveEffect(move))
{
case EFFECT_SLEEP:
case EFFECT_CONFUSE:
@@ -4294,24 +4294,26 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
{
for (k = 0; k < NUM_MOVE_POINT_TYPES; k++)
{
- u16 move;
+ u32 move;
if (trainerId == TRAINER_FRONTIER_BRAIN)
move = GetFrontierBrainMonMove(i, j);
else if (trainerId == TRAINER_PLAYER)
move = gSaveBlock2Ptr->frontier.domePlayerPartyData[i].moves[j];
else
move = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].moves[j];
+ u32 effect = GetMoveEffect(move);
+ u32 accuracy = GetMoveAccuracy(move);
switch (k)
{
case MOVE_POINTS_COMBO:
- allocatedArray[k] = IsDomeComboMoveEffect(gMovesInfo[move].effect) ? 1 : 0;
+ allocatedArray[k] = IsDomeComboMoveEffect(effect) ? 1 : 0;
break;
case MOVE_POINTS_STAT_RAISE:
- allocatedArray[k] = IsStatRaisingEffect(gMovesInfo[move].effect) ? 1 : 0;
+ allocatedArray[k] = IsStatRaisingEffect(effect) ? 1 : 0;
break;
case MOVE_POINTS_STAT_LOWER:
- allocatedArray[k] = IsStatLoweringEffect(gMovesInfo[move].effect) ? 1 : 0;
+ allocatedArray[k] = IsStatLoweringEffect(effect) ? 1 : 0;
break;
case MOVE_POINTS_RARE:
allocatedArray[k] = IsDomeRareMove(move) ? 1 : 0;
@@ -4320,22 +4322,22 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
allocatedArray[k] = IsDomeHealingMove(move) ? 1 : 0;
break;
case MOVE_POINTS_RISKY:
- allocatedArray[k] = IsDomeRiskyMoveEffect(gMovesInfo[move].effect) ? 1 : 0;
+ allocatedArray[k] = IsDomeRiskyMoveEffect(effect) ? 1 : 0;
break;
case MOVE_POINTS_STATUS:
allocatedArray[k] = IsDomeStatusMoveEffect(move);
break;
case MOVE_POINTS_DMG:
- allocatedArray[k] = (gMovesInfo[move].power != 0) ? 1 : 0;
+ allocatedArray[k] = (!IsBattleMoveStatus(move)) ? 1 : 0;
break;
case MOVE_POINTS_DEF:
- allocatedArray[k] = IsDomeDefensiveMoveEffect(gMovesInfo[move].effect) ? 1 : 0;
+ allocatedArray[k] = IsDomeDefensiveMoveEffect(effect) ? 1 : 0;
break;
case MOVE_POINTS_ACCURATE:
- allocatedArray[k] = (gMovesInfo[move].accuracy == 0 || gMovesInfo[move].accuracy == 100) ? 1 : 0;
+ allocatedArray[k] = (accuracy == 0 || accuracy == 100) ? 1 : 0;
break;
case MOVE_POINTS_POWERFUL:
- allocatedArray[k] = (gMovesInfo[move].power >= 100) ? 1 : 0;
+ allocatedArray[k] = (GetMovePower(move) >= 100) ? 1 : 0;
break;
case MOVE_POINTS_POPULAR:
allocatedArray[k] = IsDomePopularMove(move) ? 1 : 0;
@@ -4344,10 +4346,10 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
allocatedArray[k] = IsDomeLuckyMove(move) ? 1 : 0;
break;
case MOVE_POINTS_STRONG:
- allocatedArray[k] = (gMovesInfo[move].power >= 90) ? 1 : 0;
+ allocatedArray[k] = (GetMovePower(move) >= 90) ? 1 : 0;
break;
case MOVE_POINTS_LOW_PP:
- allocatedArray[k] = (gMovesInfo[move].pp <= 5) ? 1 : 0;
+ allocatedArray[k] = (GetMovePP(move) <= 5) ? 1 : 0;
break;
case MOVE_POINTS_EFFECT:
allocatedArray[k] = MoveIsAffectedBySheerForce(move);
@@ -5107,12 +5109,12 @@ static u16 GetWinningMove(int winnerTournamentId, int loserTournamentId, u8 roun
else
moveIds[i * MAX_MON_MOVES + j] = gFacilityTrainerMons[DOME_MONS[winnerTournamentId][i]].moves[j];
- movePower = gMovesInfo[moveIds[i * MAX_MON_MOVES + j]].power;
- if (movePower == 0)
+ movePower = GetMovePower(moveIds[i * MAX_MON_MOVES + j]);
+ if (IsBattleMoveStatus(moveIds[i * MAX_MON_MOVES + j]))
movePower = 40;
else if (movePower == 1)
movePower = 60;
- else if (gMovesInfo[moveIds[i * MAX_MON_MOVES + j]].effect == EFFECT_EXPLOSION)
+ else if (GetMoveEffect(moveIds[i * MAX_MON_MOVES + j]) == EFFECT_EXPLOSION)
movePower /= 2;
for (k = 0; k < FRONTIER_PARTY_SIZE; k++)
diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c
index fae0e8377a..c57151ac37 100644
--- a/src/battle_dynamax.c
+++ b/src/battle_dynamax.c
@@ -151,7 +151,7 @@ u16 GetNonDynamaxHP(u32 battler)
return gBattleMons[battler].hp;
else
{
- u16 mult = UQ_4_12(1.0/1.5); // placeholder
+ u16 mult = UQ_4_12_FLOORED(1.0/1.5); // placeholder
u16 hp = UQ_4_12_TO_INT((gBattleMons[battler].hp * mult) + UQ_4_12_ROUND);
return hp;
}
@@ -164,7 +164,7 @@ u16 GetNonDynamaxMaxHP(u32 battler)
return gBattleMons[battler].maxHP;
else
{
- u16 mult = UQ_4_12(1.0/1.5); // placeholder
+ u16 mult = UQ_4_12_FLOORED(1.0/1.5); // placeholder
u16 maxHP = UQ_4_12_TO_INT((gBattleMons[battler].maxHP * mult) + UQ_4_12_ROUND);
return maxHP;
}
@@ -202,7 +202,7 @@ void UndoDynamax(u32 battler)
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX)
{
struct Pokemon *mon = (side == B_SIDE_PLAYER) ? &gPlayerParty[monId] : &gEnemyParty[monId];
- u16 mult = UQ_4_12(1.0/1.5); // placeholder
+ u16 mult = UQ_4_12_FLOORED(1.0/1.5); // placeholder
gBattleMons[battler].hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * mult + 1) + UQ_4_12_ROUND); // round up
SetMonData(mon, MON_DATA_HP, &gBattleMons[battler].hp);
CalculateMonStats(mon);
@@ -240,7 +240,7 @@ bool32 IsMoveBlockedByMaxGuard(u32 move)
bool32 IsMoveBlockedByDynamax(u32 move)
{
// TODO: Certain moves are banned in raids.
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_HEAT_CRASH:
case EFFECT_LOW_KICK:
@@ -280,7 +280,10 @@ static u16 GetTypeBasedMaxMove(u32 battler, u32 type)
// Returns the appropriate Max Move or G-Max Move for a battler to use.
u16 GetMaxMove(u32 battler, u32 baseMove)
{
- u32 move = baseMove;
+ u32 moveType;
+ SetTypeBeforeUsingMove(baseMove, battler);
+ moveType = GetBattleMoveType(baseMove);
+
if (baseMove == MOVE_NONE) // for move display
{
return MOVE_NONE;
@@ -289,20 +292,14 @@ u16 GetMaxMove(u32 battler, u32 baseMove)
{
return MOVE_STRUGGLE;
}
- else if (gMovesInfo[baseMove].category == DAMAGE_CATEGORY_STATUS)
+ else if (GetMoveCategory(baseMove) == DAMAGE_CATEGORY_STATUS)
{
- move = MOVE_MAX_GUARD;
- }
- else if (gBattleStruct->dynamicMoveType)
- {
- move = GetTypeBasedMaxMove(battler, gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK);
+ return MOVE_MAX_GUARD;
}
else
{
- move = GetTypeBasedMaxMove(battler, gMovesInfo[baseMove].type);
+ return GetTypeBasedMaxMove(battler, moveType);
}
-
- return move;
}
// First value is for Fighting, Poison and Multi-Attack. The second is for everything else.
@@ -323,7 +320,7 @@ u8 GetMaxMovePower(u32 move)
{
u8 tier;
// G-Max Drum Solo, G-Max Hydrosnipe, and G-Max Fireball always have 160 base power.
- if (gMovesInfo[GetMaxMove(gBattlerAttacker, move)].argument == MAX_EFFECT_FIXED_POWER)
+ if (GetMoveMaxEffect(GetMaxMove(gBattlerAttacker, move)) == MAX_EFFECT_FIXED_POWER)
return 160;
// Exceptions to all other rules below:
@@ -336,8 +333,9 @@ u8 GetMaxMovePower(u32 move)
}
tier = GetMaxPowerTier(move);
- if (gMovesInfo[move].type == TYPE_FIGHTING
- || gMovesInfo[move].type == TYPE_POISON
+ u32 moveType = GetMoveType(move);
+ if (moveType == TYPE_FIGHTING
+ || moveType == TYPE_POISON
|| move == MOVE_MULTI_ATTACK)
{
switch (tier)
@@ -372,9 +370,10 @@ u8 GetMaxMovePower(u32 move)
static u8 GetMaxPowerTier(u32 move)
{
- if (gMovesInfo[move].strikeCount >= 2 && gMovesInfo[move].strikeCount <= 5)
+ u32 strikeCount = GetMoveStrikeCount(move);
+ if (strikeCount >= 2 && strikeCount <= 5)
{
- switch(gMovesInfo[move].power)
+ switch(GetMovePower(move))
{
case 0 ... 25: return MAX_POWER_TIER_2;
case 26 ... 30: return MAX_POWER_TIER_3;
@@ -385,7 +384,7 @@ static u8 GetMaxPowerTier(u32 move)
}
}
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_BIDE:
case EFFECT_SUPER_FANG:
@@ -421,7 +420,7 @@ static u8 GetMaxPowerTier(u32 move)
case EFFECT_LOW_KICK:
return MAX_POWER_TIER_7;
case EFFECT_MULTI_HIT:
- switch(gMovesInfo[move].power)
+ switch(GetMovePower(move))
{
case 0 ... 15: return MAX_POWER_TIER_1;
case 16 ... 18: return MAX_POWER_TIER_2;
@@ -431,7 +430,7 @@ static u8 GetMaxPowerTier(u32 move)
}
}
- switch (gMovesInfo[move].power)
+ switch (GetMovePower(move))
{
case 0 ... 40: return MAX_POWER_TIER_1;
case 45 ... 50: return MAX_POWER_TIER_2;
@@ -473,7 +472,7 @@ void ChooseDamageNonTypesString(u8 type)
// Returns the status effect that should be applied by a G-Max Move.
static u32 GetMaxMoveStatusEffect(u32 move)
{
- u8 maxEffect = gMovesInfo[move].argument;
+ u8 maxEffect = GetMoveMaxEffect(move);
switch (maxEffect)
{
// Status 1
@@ -525,10 +524,10 @@ void BS_SetMaxMoveEffect(void)
{
NATIVE_ARGS();
u16 effect = 0;
- u8 maxEffect = gMovesInfo[gCurrentMove].argument;
+ u8 maxEffect = GetMoveMaxEffect(gCurrentMove);
// Don't continue if the move didn't land.
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
{
gBattlescriptCurrInstr = cmd->nextInstr;
return;
@@ -544,7 +543,7 @@ void BS_SetMaxMoveEffect(void)
if (!NoAliveMonsForEitherParty())
{
// Max Effects are ordered by stat ID.
- SET_STATCHANGER(gMovesInfo[gCurrentMove].argument, 1, FALSE);
+ SET_STATCHANGER(maxEffect, 1, FALSE);
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_EffectRaiseStatAllies;
effect++;
@@ -572,7 +571,7 @@ void BS_SetMaxMoveEffect(void)
break;
default:
// Max Effects are ordered by stat ID.
- statId = gMovesInfo[gCurrentMove].argument - MAX_EFFECT_LOWER_ATTACK + 1;
+ statId = maxEffect - MAX_EFFECT_LOWER_ATTACK + 1;
break;
}
SET_STATCHANGER(statId, stage, TRUE);
@@ -621,7 +620,7 @@ void BS_SetMaxMoveEffect(void)
case MAX_EFFECT_PSYCHIC_TERRAIN:
{
u32 statusFlag = 0;
- switch (gMovesInfo[gCurrentMove].argument)
+ switch (GetMoveEffectArg_MoveProperty(gCurrentMove))
{
case MAX_EFFECT_MISTY_TERRAIN:
statusFlag = STATUS_FIELD_MISTY_TERRAIN;
@@ -662,11 +661,12 @@ void BS_SetMaxMoveEffect(void)
u8 side = GetBattlerSide(gBattlerTarget);
if (!(gSideStatuses[side] & SIDE_STATUS_DAMAGE_NON_TYPES))
{
+ u32 moveType = GetMoveType(gCurrentMove);
gSideStatuses[side] |= SIDE_STATUS_DAMAGE_NON_TYPES;
gSideTimers[side].damageNonTypesTimer = 5; // damage is dealt for 4 turns, ends on 5th
- gSideTimers[side].damageNonTypesType = gMovesInfo[gCurrentMove].type;
+ gSideTimers[side].damageNonTypesType = moveType;
BattleScriptPush(gBattlescriptCurrInstr + 1);
- ChooseDamageNonTypesString(gMovesInfo[gCurrentMove].type);
+ ChooseDamageNonTypesString(moveType);
gBattlescriptCurrInstr = BattleScript_DamageNonTypesStarts;
effect++;
}
@@ -762,7 +762,7 @@ void BS_SetMaxMoveEffect(void)
{
static const u8 sSnoozeEffects[] = {TRUE, FALSE};
if (!(gStatuses3[gBattlerTarget] & STATUS3_YAWN)
- && CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget))
+ && CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE)
&& RandomElement(RNG_G_MAX_SNOOZE, sSnoozeEffects)) // 50% chance of success
{
gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2);
@@ -884,12 +884,14 @@ void BS_TrySetStatus1(void)
}
break;
case STATUS1_SLEEP:
- if (CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget)))
+ if (CanBeSlept(gBattlerTarget, GetBattlerAbility(gBattlerTarget), BLOCKED_BY_SLEEP_CLAUSE))
{
if (B_SLEEP_TURNS >= GEN_5)
gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 3) + 2);
else
gBattleMons[gBattlerTarget].status1 |= STATUS1_SLEEP_TURN((Random() % 4) + 3);
+
+ TryActivateSleepClause(gBattlerTarget, gBattlerPartyIndexes[gBattlerTarget]);
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
effect++;
}
@@ -978,10 +980,10 @@ void BS_TrySetStatus2(void)
void BS_HealOneSixth(void)
{
NATIVE_ARGS(const u8* failInstr);
- gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 6;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].maxHP / 6;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] *= -1;
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
gBattlescriptCurrInstr = cmd->failInstr; // fail
diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c
index e2a583dcc9..1aeeb8afd6 100644
--- a/src/battle_gfx_sfx_util.c
+++ b/src/battle_gfx_sfx_util.c
@@ -329,7 +329,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move)
case MOVE_TARGET_RANDOM:
case MOVE_TARGET_BOTH:
case MOVE_TARGET_FOES_AND_ALLY:
- if (IS_MOVE_STATUS(move))
+ if (IsBattleMoveStatus(move))
return PALACE_MOVE_GROUP_SUPPORT;
else
return PALACE_MOVE_GROUP_ATTACK;
@@ -435,6 +435,18 @@ void SpriteCB_TrainerSlideIn(struct Sprite *sprite)
}
}
+void SpriteCB_TrainerSpawn(struct Sprite *sprite)
+{
+ if (!(gIntroSlideFlags & 1))
+ {
+ sprite->x2 = 0;
+ if (sprite->y2 != 0)
+ sprite->callback = SpriteCB_TrainerSlideVertical;
+ else
+ sprite->callback = SpriteCallbackDummy;
+ }
+}
+
// Slide up to 0 if necessary (used by multi battle intro)
static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite)
{
@@ -754,13 +766,21 @@ bool8 BattleLoadAllHealthBoxesGfx(u8 state)
LoadCompressedSpriteSheet(&sSpriteSheet_SinglesPlayerHealthbox);
}
else if (state == 3)
+ {
LoadCompressedSpriteSheet(&sSpriteSheet_SinglesOpponentHealthbox);
+ }
else if (state == 4)
+ {
LoadCompressedSpriteSheet(&sSpriteSheets_HealthBar[GetBattlerPosition(0)]);
+ }
else if (state == 5)
+ {
LoadCompressedSpriteSheet(&sSpriteSheets_HealthBar[GetBattlerPosition(1)]);
+ }
else
+ {
retVal = TRUE;
+ }
}
else
{
@@ -1035,7 +1055,8 @@ void LoadBattleMonGfxAndAnimate(u8 battler, bool8 loadMonSprite, u8 spriteId)
void TrySetBehindSubstituteSpriteBit(u8 battler, u16 move)
{
- if (gMovesInfo[move].effect == EFFECT_SUBSTITUTE || gMovesInfo[move].effect == EFFECT_SHED_TAIL)
+ u32 effect = GetMoveEffect(move);
+ if (effect == EFFECT_SUBSTITUTE || effect == EFFECT_SHED_TAIL)
gBattleSpritesDataPtr->battlerData[battler].behindSubstitute = 1;
}
@@ -1177,7 +1198,7 @@ void CreateEnemyShadowSprite(u32 battler)
{
gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteIdPrimary = CreateSprite(&gSpriteTemplate_EnemyShadow,
GetBattlerSpriteCoord(battler, BATTLER_COORD_X),
- GetBattlerSpriteCoord(battler, BATTLER_COORD_Y),
+ GetBattlerSpriteCoord(battler, BATTLER_COORD_Y) + 29,
0xC8);
if (gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteIdPrimary < MAX_SPRITES)
{
@@ -1239,9 +1260,11 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite)
return;
}
- s8 xOffset = 0, yOffset = 0, size = SHADOW_SIZE_S;
+ s8 xOffset = 0, UNUSED yOffset = 0, size = SHADOW_SIZE_S;
if (gAnimScriptActive || battlerSprite->invisible)
+ {
invisible = TRUE;
+ }
else if (transformSpecies != SPECIES_NONE)
{
xOffset = gSpeciesInfo[transformSpecies].enemyShadowXOffset;
@@ -1259,21 +1282,19 @@ void SpriteCB_EnemyShadow(struct Sprite *shadowSprite)
yOffset = gSpeciesInfo[species].enemyShadowYOffset + 16;
size = gSpeciesInfo[species].enemyShadowSize;
}
- else
- {
- yOffset = 29;
- }
if (gBattleSpritesDataPtr->battlerData[battler].behindSubstitute)
invisible = TRUE;
shadowSprite->x = battlerSprite->x + xOffset;
shadowSprite->x2 = battlerSprite->x2;
- shadowSprite->y = battlerSprite->y + yOffset;
shadowSprite->invisible = invisible;
if (B_ENEMY_MON_SHADOW_STYLE >= GEN_4 && P_GBA_STYLE_SPECIES_GFX == FALSE)
+ {
shadowSprite->oam.tileNum = shadowSprite->tBaseTileNum + (8 * size);
+ shadowSprite->y = battlerSprite->y + yOffset;
+ }
}
#undef tBattlerId
diff --git a/src/battle_intro.c b/src/battle_intro.c
index a6b1607285..b951c163c8 100644
--- a/src/battle_intro.c
+++ b/src/battle_intro.c
@@ -8,6 +8,7 @@
#include "main.h"
#include "scanline_effect.h"
#include "task.h"
+#include "test_runner.h"
#include "trig.h"
#include "constants/battle_partner.h"
#include "constants/trainers.h"
@@ -17,6 +18,7 @@ static void BattleIntroSlide2(u8);
static void BattleIntroSlide3(u8);
static void BattleIntroSlideLink(u8);
static void BattleIntroSlidePartner(u8);
+static void BattleIntroNoSlide(u8);
static const u8 sBattleAnimBgCnts[] = {REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT};
@@ -149,9 +151,59 @@ static void BattleIntroSlideEnd(u8 taskId)
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
}
+static void BattleIntroNoSlide(u8 taskId)
+{
+ switch (gTasks[taskId].tState)
+ {
+ case 0:
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ gTasks[taskId].data[2] = 16;
+ gTasks[taskId].tState++;
+ gIntroSlideFlags &= ~1;
+ }
+ else
+ {
+ gTasks[taskId].data[2] = 1;
+ gTasks[taskId].tState++;
+ gIntroSlideFlags &= ~1;
+ }
+ break;
+ case 1:
+ gTasks[taskId].data[2]--;
+ if (gTasks[taskId].data[2] == 0)
+ {
+ gTasks[taskId].tState++;
+ SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
+ gScanlineEffect.state = 3;
+ }
+ break;
+ case 2:
+ gBattle_WIN0V -= 0xFF * 2;
+ if ((gBattle_WIN0V & 0xFF00) == 0)
+ {
+ gTasks[taskId].tState++;
+ }
+ break;
+ case 3:
+ gTasks[taskId].tState++;
+ CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE);
+ SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
+ SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0);
+ SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512);
+ SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
+ break;
+ case 4:
+ BattleIntroSlideEnd(taskId);
+ break;
+ }
+}
+
static void BattleIntroSlide1(u8 taskId)
{
int i;
+ if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless)
+ return BattleIntroNoSlide(taskId);
gBattle_BG1_X += 6;
switch (gTasks[taskId].tState)
@@ -237,6 +289,8 @@ static void BattleIntroSlide1(u8 taskId)
static void BattleIntroSlide2(u8 taskId)
{
int i;
+ if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless)
+ return BattleIntroNoSlide(taskId);
switch (gTasks[taskId].tTerrain)
{
@@ -349,6 +403,8 @@ static void BattleIntroSlide2(u8 taskId)
static void BattleIntroSlide3(u8 taskId)
{
int i;
+ if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless)
+ return BattleIntroNoSlide(taskId);
gBattle_BG1_X += 8;
switch (gTasks[taskId].tState)
diff --git a/src/battle_main.c b/src/battle_main.c
index bbde7bb357..9095ac34cd 100644
--- a/src/battle_main.c
+++ b/src/battle_main.c
@@ -25,6 +25,7 @@
#include "event_data.h"
#include "evolution_scene.h"
#include "field_weather.h"
+#include "generational_changes.h"
#include "graphics.h"
#include "gpu_regs.h"
#include "international_string_util.h"
@@ -163,7 +164,6 @@ EWRAM_DATA u8 gChosenMovePos = 0;
EWRAM_DATA u16 gCurrentMove = 0;
EWRAM_DATA u16 gChosenMove = 0;
EWRAM_DATA u16 gCalledMove = 0;
-EWRAM_DATA s32 gBattleMoveDamage = 0;
EWRAM_DATA s32 gHpDealt = 0;
EWRAM_DATA s32 gBideDmg[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u16 gLastUsedItem = 0;
@@ -174,7 +174,6 @@ EWRAM_DATA u8 gBattlerFainted = 0;
EWRAM_DATA u8 gEffectBattler = 0;
EWRAM_DATA u8 gPotentialItemEffectBattler = 0;
EWRAM_DATA u8 gAbsentBattlerFlags = 0;
-EWRAM_DATA u8 gIsCriticalHit = FALSE;
EWRAM_DATA u8 gMultiHitCounter = 0;
EWRAM_DATA const u8 *gBattlescriptCurrInstr = NULL;
EWRAM_DATA u8 gChosenActionByBattler[MAX_BATTLERS_COUNT] = {0};
@@ -190,7 +189,6 @@ EWRAM_DATA u16 gLockedMoves[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u16 gLastUsedMove = 0;
EWRAM_DATA u8 gLastHitBy[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT] = {0};
-EWRAM_DATA u16 gMoveResultFlags = 0;
EWRAM_DATA u32 gHitMarker = 0;
EWRAM_DATA u8 gBideTarget[MAX_BATTLERS_COUNT] = {0};
EWRAM_DATA u32 gSideStatuses[NUM_BATTLE_SIDES] = {0};
@@ -487,21 +485,24 @@ static void CB2_InitBattleInternal(void)
else
{
gBattle_WIN0V = WIN_RANGE(DISPLAY_HEIGHT / 2, DISPLAY_HEIGHT / 2 + 1);
- ScanlineEffect_Clear();
-
- for (i = 0; i < DISPLAY_HEIGHT / 2; i++)
+ if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless)
{
- gScanlineEffectRegBuffers[0][i] = 0xF0;
- gScanlineEffectRegBuffers[1][i] = 0xF0;
- }
+ ScanlineEffect_Clear();
- for (; i < DISPLAY_HEIGHT; i++)
- {
- gScanlineEffectRegBuffers[0][i] = 0xFF10;
- gScanlineEffectRegBuffers[1][i] = 0xFF10;
- }
+ for (i = 0; i < DISPLAY_HEIGHT / 2; i++)
+ {
+ gScanlineEffectRegBuffers[0][i] = 0xF0;
+ gScanlineEffectRegBuffers[1][i] = 0xF0;
+ }
- ScanlineEffect_SetParams(sIntroScanlineParams16Bit);
+ for (; i < DISPLAY_HEIGHT; i++)
+ {
+ gScanlineEffectRegBuffers[0][i] = 0xFF10;
+ gScanlineEffectRegBuffers[1][i] = 0xFF10;
+ }
+
+ ScanlineEffect_SetParams(sIntroScanlineParams16Bit);
+ }
}
ResetPaletteFade();
@@ -532,7 +533,8 @@ static void CB2_InitBattleInternal(void)
LoadBattleTextboxAndBackground();
ResetSpriteData();
ResetTasks();
- DrawBattleEntryBackground();
+ if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless)
+ DrawBattleEntryBackground();
FreeAllSpritePalettes();
gReservedSpritePaletteCount = MAX_BATTLERS_COUNT;
SetVBlankCallback(VBlankCB_Battle);
@@ -1521,7 +1523,9 @@ static void CB2_HandleStartMultiBattle(void)
gBattleCommunication[MULTIUSE_STATE]++;
}
else
+ {
break;
+ }
// fall through
case 3:
if (IsLinkTaskFinished())
@@ -1908,8 +1912,9 @@ void CustomTrainerPartyAssignMoves(struct Pokemon *mon, const struct TrainerMon
for (j = 0; j < MAX_MON_MOVES; ++j)
{
+ u32 pp = GetMovePP(partyEntry->moves[j]);
SetMonData(mon, MON_DATA_MOVE1 + j, &partyEntry->moves[j]);
- SetMonData(mon, MON_DATA_PP1 + j, &gMovesInfo[partyEntry->moves[j]].pp);
+ SetMonData(mon, MON_DATA_PP1 + j, &pp);
}
}
@@ -2648,17 +2653,24 @@ void SpriteCB_WildMon(struct Sprite *sprite)
{
sprite->callback = SpriteCB_MoveWildMonToRight;
StartSpriteAnimIfDifferent(sprite, 0);
- if (WILD_DOUBLE_BATTLE)
- BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8));
- else
- BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8));
+ if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless)
+ {
+ if (WILD_DOUBLE_BATTLE)
+ BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8));
+ else
+ BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8));
+ }
}
static void SpriteCB_MoveWildMonToRight(struct Sprite *sprite)
{
if ((gIntroSlideFlags & 1) == 0)
{
- sprite->x2 += 2;
+ if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless)
+ sprite->x2 += 2;
+ else
+ sprite->x2 = 0;
+
if (sprite->x2 == 0)
{
sprite->callback = SpriteCB_WildMonShowHealthbox;
@@ -2674,10 +2686,13 @@ static void SpriteCB_WildMonShowHealthbox(struct Sprite *sprite)
SetHealthboxSpriteVisible(gHealthboxSpriteIds[sprite->sBattler]);
sprite->callback = SpriteCB_WildMonAnimate;
StartSpriteAnimIfDifferent(sprite, 0);
- if (WILD_DOUBLE_BATTLE)
- BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8));
- else
- BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8));
+ if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless)
+ {
+ if (WILD_DOUBLE_BATTLE)
+ BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8));
+ else
+ BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8));
+ }
}
}
@@ -3081,7 +3096,6 @@ static void BattleStartClearSetData(void)
gBattleCommunication[i] = 0;
gPauseCounterBattle = 0;
- gBattleMoveDamage = 0;
gIntroSlideFlags = 0;
gLeveledUpInBattle = 0;
gAbsentBattlerFlags = 0;
@@ -3119,18 +3133,29 @@ static void BattleStartClearSetData(void)
gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
gBattleStruct->categoryOverride = FALSE; // used for Z-Moves and Max Moves
+ gBattleStruct->pursuitTarget = 0;
+ gBattleStruct->pursuitSwitchByMove = FALSE;
+ gBattleStruct->pursuitStoredSwitch = 0;
gSelectedMonPartyId = PARTY_SIZE; // Revival Blessing
gCategoryIconSpriteId = 0xFF;
+
+ if(IsSleepClauseEnabled())
+ {
+ // If monCausingSleepClause[side] equals PARTY_SIZE, Sleep Clause is not active for the given side.
+ gBattleStruct->monCausingSleepClause[B_SIDE_PLAYER] = PARTY_SIZE;
+ gBattleStruct->monCausingSleepClause[B_SIDE_OPPONENT] = PARTY_SIZE;
+ }
}
void SwitchInClearSetData(u32 battler)
{
s32 i;
+ u32 effect = GetMoveEffect(gCurrentMove);
struct DisableStruct disableStructCopy = gDisableStructs[battler];
ClearIllusionMon(battler);
- if (gMovesInfo[gCurrentMove].effect != EFFECT_BATON_PASS)
+ if (effect != EFFECT_BATON_PASS)
{
for (i = 0; i < NUM_BATTLE_STATS; i++)
gBattleMons[battler].statStages[i] = DEFAULT_STAT_STAGE;
@@ -3145,7 +3170,7 @@ void SwitchInClearSetData(u32 battler)
}
}
}
- if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
+ if (effect == EFFECT_BATON_PASS)
{
gBattleMons[battler].status2 &= (STATUS2_CONFUSION | STATUS2_FOCUS_ENERGY_ANY | STATUS2_SUBSTITUTE | STATUS2_ESCAPE_PREVENTION | STATUS2_CURSED);
gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED
@@ -3187,7 +3212,7 @@ void SwitchInClearSetData(u32 battler)
memset(&gDisableStructs[battler], 0, sizeof(struct DisableStruct));
- if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
+ if (effect == EFFECT_BATON_PASS)
{
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
gDisableStructs[battler].battlerWithSureHit = disableStructCopy.battlerWithSureHit;
@@ -3195,13 +3220,13 @@ void SwitchInClearSetData(u32 battler)
gDisableStructs[battler].battlerPreventingEscape = disableStructCopy.battlerPreventingEscape;
gDisableStructs[battler].embargoTimer = disableStructCopy.embargoTimer;
}
- else if (gMovesInfo[gCurrentMove].effect == EFFECT_SHED_TAIL)
+ else if (effect == EFFECT_SHED_TAIL)
{
gBattleMons[battler].status2 |= STATUS2_SUBSTITUTE;
gDisableStructs[battler].substituteHP = disableStructCopy.substituteHP;
}
- gMoveResultFlags = 0;
+ gBattleStruct->moveResultFlags[battler] = 0;
gDisableStructs[battler].isFirstTurn = 2;
gDisableStructs[battler].truantSwitchInHack = disableStructCopy.truantSwitchInHack;
gLastMoves[battler] = MOVE_NONE;
@@ -3223,6 +3248,13 @@ void SwitchInClearSetData(u32 battler)
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
gBattleStruct->canPickupItem &= ~(1u << battler);
+ if (gBattleStruct->pursuitTarget & (1u << battler))
+ {
+ gBattleStruct->pursuitTarget = 0;
+ gBattleStruct->pursuitSwitchByMove = FALSE;
+ gBattleStruct->pursuitStoredSwitch = 0;
+ }
+
for (i = 0; i < ARRAY_COUNT(gSideTimers); i++)
{
// Switched into sticky web user slot, so reset stored battler ID
@@ -3353,6 +3385,13 @@ const u8* FaintClearSetData(u32 battler)
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
+
+ if (gBattleStruct->pursuitTarget & (1u << battler))
+ {
+ gBattleStruct->pursuitTarget = 0;
+ gBattleStruct->pursuitSwitchByMove = FALSE;
+ gBattleStruct->pursuitStoredSwitch = 0;
+ }
gBattleStruct->palaceFlags &= ~(1u << battler);
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
@@ -3559,7 +3598,7 @@ static void DoBattleIntro(void)
}
else // Skip party summary since it is a wild battle.
{
- if (B_FAST_INTRO == TRUE)
+ if (B_FAST_INTRO_PKMN_TEXT == TRUE)
gBattleStruct->introState = BATTLE_INTRO_STATE_INTRO_TEXT; // Don't wait for sprite, print message at the same time.
else
gBattleStruct->introState++; // Wait for sprite to load.
@@ -3631,7 +3670,7 @@ static void DoBattleIntro(void)
}
else
{
- if (B_FAST_INTRO == TRUE)
+ if (B_FAST_INTRO_PKMN_TEXT == TRUE)
gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT;
else
gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM;
@@ -3670,7 +3709,7 @@ static void DoBattleIntro(void)
BtlController_EmitIntroTrainerBallThrow(battler, BUFFER_A);
MarkBattlerForControllerExec(battler);
}
- if (B_FAST_INTRO == TRUE
+ if (B_FAST_INTRO_PKMN_TEXT == TRUE
&& !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK)))
gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; // Print at the same time as trainer sends out second mon.
else
@@ -3693,7 +3732,7 @@ static void DoBattleIntro(void)
battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
// A hack that makes fast intro work in trainer battles too.
- if (B_FAST_INTRO == TRUE
+ if (B_FAST_INTRO_PKMN_TEXT == TRUE
&& gBattleTypeFlags & BATTLE_TYPE_TRAINER
&& !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK))
&& gSprites[gHealthboxSpriteIds[battler ^ BIT_SIDE]].callback == SpriteCallbackDummy)
@@ -3901,7 +3940,7 @@ static void TryDoEventsBeforeFirstTurn(void)
case FIRST_TURN_EVENTS_ITEM_EFFECTS:
while (gBattleStruct->switchInBattlerCounter < gBattlersCount) // From fastest to slowest
{
- if (ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, gBattlerByTurnOrder[gBattleStruct->switchInBattlerCounter++], FALSE))
+ if (ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN, gBattlerByTurnOrder[gBattleStruct->switchInBattlerCounter++], FALSE))
return;
}
gBattleStruct->switchInBattlerCounter = 0;
@@ -3945,7 +3984,6 @@ static void TryDoEventsBeforeFirstTurn(void)
gBattleScripting.moveendState = 0;
gBattleStruct->faintedActionsState = 0;
gBattleStruct->turnCountersTracker = 0;
- gMoveResultFlags = 0;
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
SetShellSideArmCategory();
@@ -3984,7 +4022,6 @@ static void HandleEndTurn_ContinueBattle(void)
gBattleStruct->wishPerishSongState = 0;
gBattleStruct->wishPerishSongBattlerId = 0;
gBattleStruct->turnCountersTracker = 0;
- gMoveResultFlags = 0;
}
}
@@ -4016,8 +4053,6 @@ void BattleTurnPassed(void)
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
gBattleScripting.moveendState = 0;
- gBattleMoveDamage = 0;
- gMoveResultFlags = 0;
for (i = 0; i < 5; i++)
gBattleCommunication[i] = 0;
@@ -4832,35 +4867,35 @@ s8 GetChosenMovePriority(u32 battler)
else
move = gBattleMons[battler].moves[*(gBattleStruct->chosenMovePositions + battler)];
- return GetMovePriority(battler, move);
+ return GetBattleMovePriority(battler, move);
}
-s8 GetMovePriority(u32 battler, u16 move)
+s8 GetBattleMovePriority(u32 battler, u16 move)
{
s8 priority;
u16 ability = GetBattlerAbility(battler);
- if (GetActiveGimmick(battler) == GIMMICK_Z_MOVE && gMovesInfo[move].power != 0)
+ if (GetActiveGimmick(battler) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move))
move = GetUsableZMove(battler, move);
- priority = gMovesInfo[move].priority;
+ priority = GetMovePriority(move);
// Max Guard check
- if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
- return gMovesInfo[MOVE_MAX_GUARD].priority;
+ if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX && GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS)
+ return GetMovePriority(MOVE_MAX_GUARD);
if (ability == ABILITY_GALE_WINGS
- && (B_GALE_WINGS < GEN_7 || BATTLER_MAX_HP(battler))
- && gMovesInfo[move].type == TYPE_FLYING)
+ && (GetGenConfig(GEN_CONFIG_GALE_WINGS) < GEN_7 || IsBattlerAtMaxHp(battler))
+ && GetMoveType(move) == TYPE_FLYING)
{
priority++;
}
- else if (ability == ABILITY_PRANKSTER && IS_MOVE_STATUS(move))
+ else if (ability == ABILITY_PRANKSTER && IsBattleMoveStatus(move))
{
gProtectStructs[battler].pranksterElevated = 1;
priority++;
}
- else if (gMovesInfo[move].effect == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battler) && GetActiveGimmick(gBattlerAttacker) != GIMMICK_DYNAMAX && !IsGimmickSelected(battler, GIMMICK_DYNAMAX))
+ else if (GetMoveEffect(move) == EFFECT_GRASSY_GLIDE && gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && IsBattlerGrounded(battler) && GetActiveGimmick(gBattlerAttacker) != GIMMICK_DYNAMAX && !IsGimmickSelected(battler, GIMMICK_DYNAMAX))
{
priority++;
}
@@ -4886,8 +4921,8 @@ s32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
// Lagging Tail - always last
bool32 battler1HasQuickEffect = gProtectStructs[battler1].quickDraw || gProtectStructs[battler1].usedCustapBerry;
bool32 battler2HasQuickEffect = gProtectStructs[battler2].quickDraw || gProtectStructs[battler2].usedCustapBerry;
- bool32 battler1HasStallingAbility = ability1 == ABILITY_STALL || (ability1 == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gChosenMoveByBattler[battler1]));
- bool32 battler2HasStallingAbility = ability2 == ABILITY_STALL || (ability2 == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gChosenMoveByBattler[battler2]));
+ bool32 battler1HasStallingAbility = ability1 == ABILITY_STALL || (ability1 == ABILITY_MYCELIUM_MIGHT && IsBattleMoveStatus(gChosenMoveByBattler[battler1]));
+ bool32 battler2HasStallingAbility = ability2 == ABILITY_STALL || (ability2 == ABILITY_MYCELIUM_MIGHT && IsBattleMoveStatus(gChosenMoveByBattler[battler2]));
if (battler1HasQuickEffect && !battler2HasQuickEffect)
strikesFirst = 1;
@@ -5166,7 +5201,11 @@ static void TurnValuesCleanUp(bool8 var0)
gSideTimers[B_SIDE_OPPONENT].followmeTimer = 0;
gBattleStruct->usedEjectItem = 0;
+ gBattleStruct->pursuitTarget = 0;
+ gBattleStruct->pursuitSwitchByMove = FALSE;
+ gBattleStruct->pursuitStoredSwitch = 0;
gBattleStruct->pledgeMove = FALSE; // combined pledge move may not have been used due to a canceller
+ ClearDamageCalcResults();
}
void SpecialStatusesClear(void)
@@ -5181,11 +5220,26 @@ static void PopulateArrayWithBattlers(u8 *battlers)
battlers[i] = i;
}
+static bool32 TryActivateGimmick(u32 battler)
+{
+ if ((gBattleStruct->gimmick.toActivate & (1u << battler)) && !(gProtectStructs[battler].noValidMoves))
+ {
+ gBattlerAttacker = gBattleScripting.battler = battler;
+ gBattleStruct->gimmick.toActivate &= ~(1u << battler);
+ if (gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick != NULL)
+ {
+ gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick(battler);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static bool32 TryDoGimmicksBeforeMoves(void)
{
if (!(gHitMarker & HITMARKER_RUN) && gBattleStruct->gimmick.toActivate)
{
- u32 i, battler;
+ u32 i;
u8 order[MAX_BATTLERS_COUNT];
PopulateArrayWithBattlers(order);
@@ -5193,16 +5247,8 @@ static bool32 TryDoGimmicksBeforeMoves(void)
for (i = 0; i < gBattlersCount; i++)
{
// Search through each battler and activate their gimmick if they have one prepared.
- if ((gBattleStruct->gimmick.toActivate & (1u << order[i])) && !(gProtectStructs[order[i]].noValidMoves))
- {
- battler = gBattlerAttacker = gBattleScripting.battler = order[i];
- gBattleStruct->gimmick.toActivate &= ~(1u << battler);
- if (gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick != NULL)
- {
- gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick(battler);
- return TRUE;
- }
- }
+ if (TryActivateGimmick(order[i]))
+ return TRUE;
}
}
@@ -5229,7 +5275,7 @@ static bool32 TryDoMoveEffectsBeforeMoves(void)
{
gBattleStruct->focusPunchBattlers |= 1u << battlers[i];
gBattlerAttacker = battlers[i];
- switch (gMovesInfo[gChosenMoveByBattler[gBattlerAttacker]].effect)
+ switch (GetMoveEffect(gChosenMoveByBattler[gBattlerAttacker]))
{
case EFFECT_FOCUS_PUNCH:
BattleScriptExecute(BattleScript_FocusPunchSetUp);
@@ -5252,7 +5298,7 @@ static bool32 TryDoMoveEffectsBeforeMoves(void)
static void TryChangeTurnOrder(void)
{
u32 i, j;
- for (i = 0; i < gBattlersCount - 1; i++)
+ for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++)
{
for (j = i + 1; j < gBattlersCount; j++)
{
@@ -5278,7 +5324,7 @@ static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2)
// Battler 1
// Quick Draw
- if (ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && gBattleStruct->quickDrawRandom[battler1])
+ if (ability1 == ABILITY_QUICK_DRAW && !IsBattleMoveStatus(gChosenMoveByBattler[battler1]) && gBattleStruct->quickDrawRandom[battler1])
gProtectStructs[battler1].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler1].quickDraw
@@ -5288,7 +5334,7 @@ static void TryChangingTurnOrderEffects(u32 battler1, u32 battler2)
// Battler 2
// Quick Draw
- if (ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && gBattleStruct->quickDrawRandom[battler2])
+ if (ability2 == ABILITY_QUICK_DRAW && !IsBattleMoveStatus(gChosenMoveByBattler[battler2]) && gBattleStruct->quickDrawRandom[battler2])
gProtectStructs[battler2].quickDraw = TRUE;
// Quick Claw and Custap Berry
if (!gProtectStructs[battler2].quickDraw
@@ -5370,11 +5416,19 @@ static void RunTurnActionsFunctions(void)
// Mega Evolve / Focus Punch-like moves after switching, items, running, but before using a move.
if (gCurrentActionFuncId == B_ACTION_USE_MOVE && !gBattleStruct->effectsBeforeUsingMoveDone)
{
- if (TryDoGimmicksBeforeMoves())
- return;
- else if (TryDoMoveEffectsBeforeMoves())
- return;
- gBattleStruct->effectsBeforeUsingMoveDone = TRUE;
+ if (!gBattleStruct->pursuitTarget)
+ {
+ if (TryDoGimmicksBeforeMoves())
+ return;
+ else if (TryDoMoveEffectsBeforeMoves())
+ return;
+ gBattleStruct->effectsBeforeUsingMoveDone = TRUE;
+ }
+ else
+ {
+ if (TryActivateGimmick(gBattlerByTurnOrder[gCurrentTurnActionNumber]))
+ return;
+ }
}
*(&gBattleStruct->savedTurnActionNumber) = gCurrentTurnActionNumber;
@@ -5779,7 +5833,7 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility)
{
u32 ateType;
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_TERA_BLAST:
if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA)
@@ -5831,8 +5885,8 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility)
// NULL can be passed to ateBoost to avoid applying ate-ability boosts when opening the summary screen in-battle.
u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost)
{
- u32 moveType = gMovesInfo[move].type;
- u32 moveEffect = gMovesInfo[move].effect;
+ u32 moveType = GetMoveType(move);
+ u32 moveEffect = GetMoveEffect(move);
u32 species, heldItem, holdEffect, ability, type1, type2, type3;
if (move == MOVE_STRUGGLE)
@@ -5927,7 +5981,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost)
}
break;
case EFFECT_CHANGE_TYPE_ON_ITEM:
- if (holdEffect == gMovesInfo[move].argument)
+ if (holdEffect == GetMoveEffectArg_HoldEffect(move))
return ItemId_GetSecondaryId(heldItem);
break;
case EFFECT_REVELATION_DANCE:
@@ -6035,7 +6089,7 @@ u32 GetDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler, u8 *ateBoost)
*ateBoost = TRUE;
return TYPE_NORMAL;
}
- else if (gMovesInfo[move].soundMove && ability == ABILITY_LIQUID_VOICE)
+ else if (IsSoundMove(move) && ability == ABILITY_LIQUID_VOICE)
{
return TYPE_WATER;
}
@@ -6064,13 +6118,13 @@ void SetTypeBeforeUsingMove(u32 move, u32 battler)
if (moveType != TYPE_NONE)
gBattleStruct->dynamicMoveType = moveType | F_DYNAMIC_TYPE_SET;
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
if ((gFieldStatuses & STATUS_FIELD_ION_DELUGE && moveType == TYPE_NORMAL)
|| gStatuses4[battler] & STATUS4_ELECTRIFIED)
gBattleStruct->dynamicMoveType = TYPE_ELECTRIC | F_DYNAMIC_TYPE_SET;
// Check if a gem should activate.
- if (holdEffect == HOLD_EFFECT_GEMS && GetMoveType(move) == ItemId_GetSecondaryId(heldItem))
+ if (holdEffect == HOLD_EFFECT_GEMS && GetBattleMoveType(move) == ItemId_GetSecondaryId(heldItem))
{
gSpecialStatuses[battler].gemParam = GetBattlerHoldEffectParam(battler);
gSpecialStatuses[battler].gemBoost = TRUE;
diff --git a/src/battle_message.c b/src/battle_message.c
index e1eebf74e5..998c8f8185 100644
--- a/src/battle_message.c
+++ b/src/battle_message.c
@@ -22,6 +22,7 @@
#include "text.h"
#include "trainer_hill.h"
#include "window.h"
+#include "line_break.h"
#include "constants/abilities.h"
#include "constants/battle_dome.h"
#include "constants/battle_string_ids.h"
@@ -48,9 +49,6 @@ struct BattleWindowText
u8 shadowColor;
};
-static void ChooseMoveUsedParticle(u8 *textPtr);
-static void ChooseTypeOfMoveUsedString(u8 *dst);
-
#if TESTING
EWRAM_DATA u16 sBattlerAbilities[MAX_BATTLERS_COUNT] = {0};
#else
@@ -192,30 +190,30 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
#else
[STRINGID_PLAYERWHITEOUT2] = COMPOUND_STRING("You were overwhelmed by your defeat!{PAUSE_UNTIL_PRESS}"),
#endif
- [STRINGID_PREVENTSESCAPE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} prevents escape with {B_SCR_ACTIVE_ABILITY}!\p"),
+ [STRINGID_PREVENTSESCAPE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} prevents escape with {B_SCR_ACTIVE_ABILITY}!\p"),
[STRINGID_HITXTIMES] = COMPOUND_STRING("The Pokémon was hit {B_BUFF1} time(s)!"), //SV has dynamic plural here
[STRINGID_PKMNFELLASLEEP] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} fell asleep!"),
- [STRINGID_PKMNMADESLEEP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} made {B_EFF_NAME_WITH_PREFIX2} sleep!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNMADESLEEP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} made {B_EFF_NAME_WITH_PREFIX2} sleep!"), //not in gen 5+, ability popup
[STRINGID_PKMNALREADYASLEEP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already asleep!"),
[STRINGID_PKMNALREADYASLEEP2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is already asleep!"),
[STRINGID_PKMNWASNTAFFECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} wasn't affected!"), //not in gen 5+, ability popup
[STRINGID_PKMNWASPOISONED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was poisoned!"),
- [STRINGID_PKMNPOISONEDBY] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was poisoned by {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNPOISONEDBY] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was poisoned by {B_SCR_NAME_WITH_PREFIX2}'s {B_BUFF1}!"), //not in gen 5+, ability popup
[STRINGID_PKMNHURTBYPOISON] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by its poisoning!"),
[STRINGID_PKMNALREADYPOISONED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already poisoned!"),
[STRINGID_PKMNBADLYPOISONED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was badly poisoned!"),
[STRINGID_PKMNENERGYDRAINED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} had its energy drained!"),
[STRINGID_PKMNWASBURNED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was burned!"),
- [STRINGID_PKMNBURNEDBY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} burned {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNBURNEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} burned {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
[STRINGID_PKMNHURTBYBURN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by its burn!"),
[STRINGID_PKMNWASFROZEN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} was frozen solid!"),
- [STRINGID_PKMNFROZENBY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} froze {B_EFF_NAME_WITH_PREFIX2} solid!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNFROZENBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} froze {B_EFF_NAME_WITH_PREFIX2} solid!"), //not in gen 5+, ability popup
[STRINGID_PKMNISFROZEN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is frozen solid!"),
[STRINGID_PKMNWASDEFROSTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} thawed out!"),
[STRINGID_PKMNWASDEFROSTED2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} thawed out!"),
[STRINGID_PKMNWASDEFROSTEDBY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} melted the ice!"),
[STRINGID_PKMNWASPARALYZED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} is paralyzed, so it may be unable to move!"),
- [STRINGID_PKMNWASPARALYZEDBY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} paralyzed {B_EFF_NAME_WITH_PREFIX2}, so it may be unable to move!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNWASPARALYZEDBY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} paralyzed {B_EFF_NAME_WITH_PREFIX2}, so it may be unable to move!"), //not in gen 5+, ability popup
[STRINGID_PKMNISPARALYZED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} couldn't move because it's paralyzed!"),
[STRINGID_PKMNISALREADYPARALYZED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already paralyzed!"),
[STRINGID_PKMNHEALEDPARALYSIS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was cured of paralysis!"),
@@ -229,7 +227,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNWASCONFUSED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} became confused!"),
[STRINGID_PKMNALREADYCONFUSED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already confused!"),
[STRINGID_PKMNFELLINLOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} fell in love!"),
- [STRINGID_PKMNINLOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is in love with {B_SCR_ACTIVE_NAME_WITH_PREFIX2}!"),
+ [STRINGID_PKMNINLOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is in love with {B_SCR_NAME_WITH_PREFIX2}!"),
[STRINGID_PKMNIMMOBILIZEDBYLOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is immobilized by love!"),
[STRINGID_PKMNBLOWNAWAY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was blown away!"), //unused
[STRINGID_PKMNCHANGEDTYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} transformed into the {B_BUFF1} type!"),
@@ -239,7 +237,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNRAISEDSPDEF] = COMPOUND_STRING("Light Screen made {B_ATK_TEAM2} team stronger against special moves!"),
[STRINGID_PKMNRAISEDDEF] = COMPOUND_STRING("Reflect made {B_ATK_TEAM2} team stronger against physical moves!"),
[STRINGID_PKMNCOVEREDBYVEIL] = COMPOUND_STRING("{B_ATK_TEAM1} team cloaked itself in a mystical veil!"),
- [STRINGID_PKMNUSEDSAFEGUARD] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected by Safeguard!"),
+ [STRINGID_PKMNUSEDSAFEGUARD] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is protected by Safeguard!"),
[STRINGID_PKMNSAFEGUARDEXPIRED] = COMPOUND_STRING("{B_ATK_TEAM1} team is no longer protected by Safeguard!"),
[STRINGID_PKMNWENTTOSLEEP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} went to sleep!"), //not in gen 5+
[STRINGID_PKMNSLEPTHEALTHY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} slept and restored its HP!"),
@@ -257,7 +255,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNFREEDFROM] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was freed from {B_BUFF1}!"),
[STRINGID_PKMNCRASHED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} kept going and crashed!"),
[STRINGID_PKMNSHROUDEDINMIST] = gText_PkmnShroudedInMist,
- [STRINGID_PKMNPROTECTEDBYMIST] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is protected by the mist!"),
+ [STRINGID_PKMNPROTECTEDBYMIST] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is protected by the mist!"),
[STRINGID_PKMNGETTINGPUMPED] = gText_PkmnGettingPumped,
[STRINGID_PKMNHITWITHRECOIL] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was damaged by the recoil!"),
[STRINGID_PKMNPROTECTEDITSELF2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} protected itself!"),
@@ -268,7 +266,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNSAPPEDBYLEECHSEED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s health is sapped by Leech Seed!"),
[STRINGID_PKMNFASTASLEEP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is fast asleep."),
[STRINGID_PKMNWOKEUP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} woke up!"),
- [STRINGID_PKMNUPROARKEPTAWAKE] = COMPOUND_STRING("But the uproar kept {B_SCR_ACTIVE_NAME_WITH_PREFIX2} awake!"),
+ [STRINGID_PKMNUPROARKEPTAWAKE] = COMPOUND_STRING("But the uproar kept {B_SCR_NAME_WITH_PREFIX2} awake!"),
[STRINGID_PKMNWOKEUPINUPROAR] = COMPOUND_STRING("The uproar woke {B_ATK_NAME_WITH_PREFIX2}!"),
[STRINGID_PKMNCAUSEDUPROAR] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} caused an uproar!"),
[STRINGID_PKMNMAKINGUPROAR] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is making an uproar!"),
@@ -308,7 +306,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNLAIDCURSE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cut its own HP and put a curse on {B_DEF_NAME_WITH_PREFIX2}!"),
[STRINGID_PKMNAFFLICTEDBYCURSE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is afflicted by the curse!"),
[STRINGID_SPIKESSCATTERED] = COMPOUND_STRING("Spikes were scattered on the ground all around {B_DEF_TEAM2} team!"),
- [STRINGID_PKMNHURTBYSPIKES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was hurt by the spikes!"),
+ [STRINGID_PKMNHURTBYSPIKES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was hurt by the spikes!"),
[STRINGID_PKMNIDENTIFIED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was identified!"),
[STRINGID_PKMNPERISHCOUNTFELL] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s perish count fell to {B_BUFF1}!"),
[STRINGID_PKMNBRACEDITSELF] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} braced itself!"),
@@ -351,9 +349,9 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNSHROUDEDITSELF] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} shrouded itself with Magic Coat!"),
[STRINGID_PKMNMOVEBOUNCED] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} bounced the {B_CURRENT_MOVE} back!"),
[STRINGID_PKMNWAITSFORTARGET] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} waits for a target to make a move!"),
- [STRINGID_PKMNSNATCHEDMOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} snatched {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s move!"),
- [STRINGID_PKMNMADEITRAIN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it rain!"), //not in gen 5+, ability popup
- [STRINGID_PKMNRAISEDSPEED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its Speed!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSNATCHEDMOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} snatched {B_SCR_NAME_WITH_PREFIX2}'s move!"),
+ [STRINGID_PKMNMADEITRAIN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it rain!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNRAISEDSPEED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its Speed!"), //not in gen 5+, ability popup
[STRINGID_PKMNPROTECTEDBY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was protected by {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_PKMNPREVENTSUSAGE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents {B_ATK_NAME_WITH_PREFIX2} from using {B_CURRENT_MOVE}!"), //I don't see this in SV text
[STRINGID_PKMNRESTOREDHPUSING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} restored HP using its {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
@@ -364,8 +362,8 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNPREVENTSCONFUSIONWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents confusion!"), //not in gen 5+, ability popup
[STRINGID_PKMNRAISEDFIREPOWERWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} raised the power of Fire-type moves!"), //not in gen 5+, ability popup
[STRINGID_PKMNANCHORSITSELFWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} anchors itself with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
- [STRINGID_PKMNCUTSATTACKWITH] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cuts {B_DEF_NAME_WITH_PREFIX2}'s Attack!"), //not in gen 5+, ability popup
- [STRINGID_PKMNPREVENTSSTATLOSSWITH] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents stat loss!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNCUTSATTACKWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cuts {B_DEF_NAME_WITH_PREFIX2}'s Attack!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNPREVENTSSTATLOSSWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents stat loss!"), //not in gen 5+, ability popup
[STRINGID_PKMNHURTSWITH] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1}!"),
[STRINGID_PKMNTRACED] = COMPOUND_STRING("It traced {B_BUFF1}'s {B_BUFF2}!"),
[STRINGID_STATSHARPLY] = gText_StatSharply,
@@ -450,30 +448,30 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNIGNOREDX] = COMPOUND_STRING("{B_OPPONENT_MON1_NAME} completely ignored the {B_BUFF1}!"), //safari
[STRINGID_THREWPOKEBLOCKATPKMN] = COMPOUND_STRING("{B_PLAYER_NAME} threw a {POKEBLOCK} at the {B_OPPONENT_MON1_NAME}!"), //safari
[STRINGID_OUTOFSAFARIBALLS] = COMPOUND_STRING("{PLAY_SE SE_DING_DONG}ANNOUNCER: You're out of Safari Balls! Game over!\p"), //safari
- [STRINGID_PKMNSITEMCUREDPARALYSIS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its paralysis!"),
- [STRINGID_PKMNSITEMCUREDPOISON] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its poison!"),
- [STRINGID_PKMNSITEMHEALEDBURN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its burn!"),
- [STRINGID_PKMNSITEMDEFROSTEDIT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} defrosted it!"),
- [STRINGID_PKMNSITEMWOKEIT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} woke it up!"),
- [STRINGID_PKMNSITEMSNAPPEDOUT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} snapped it out of its confusion!"),
- [STRINGID_PKMNSITEMCUREDPROBLEM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its {B_BUFF1} problem!"),
- [STRINGID_PKMNSITEMRESTOREDHEALTH] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored its health using its {B_LAST_ITEM}!"),
- [STRINGID_PKMNSITEMRESTOREDPP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored PP to its move {B_BUFF1} using its {B_LAST_ITEM}!"),
- [STRINGID_PKMNSITEMRESTOREDSTATUS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} returned its stats to normal using its {B_LAST_ITEM}!"),
- [STRINGID_PKMNSITEMRESTOREDHPALITTLE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored a little HP using its {B_LAST_ITEM}!"),
+ [STRINGID_PKMNSITEMCUREDPARALYSIS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its paralysis!"),
+ [STRINGID_PKMNSITEMCUREDPOISON] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its poison!"),
+ [STRINGID_PKMNSITEMHEALEDBURN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its burn!"),
+ [STRINGID_PKMNSITEMDEFROSTEDIT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} defrosted it!"),
+ [STRINGID_PKMNSITEMWOKEIT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} woke it up!"),
+ [STRINGID_PKMNSITEMSNAPPEDOUT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} snapped it out of its confusion!"),
+ [STRINGID_PKMNSITEMCUREDPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its {B_BUFF1} problem!"),
+ [STRINGID_PKMNSITEMRESTOREDHEALTH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored its health using its {B_LAST_ITEM}!"),
+ [STRINGID_PKMNSITEMRESTOREDPP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored PP to its move {B_BUFF1} using its {B_LAST_ITEM}!"),
+ [STRINGID_PKMNSITEMRESTOREDSTATUS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} returned its stats to normal using its {B_LAST_ITEM}!"),
+ [STRINGID_PKMNSITEMRESTOREDHPALITTLE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored a little HP using its {B_LAST_ITEM}!"),
[STRINGID_ITEMALLOWSONLYYMOVE] = COMPOUND_STRING("{B_LAST_ITEM} only allows the use of {B_CURRENT_MOVE}!\p"),
[STRINGID_PKMNHUNGONWITHX] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} hung on using its {B_LAST_ITEM}!"),
[STRINGID_EMPTYSTRING3] = gText_EmptyString3,
[STRINGID_PKMNSXPREVENTSBURNS] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY} prevents burns!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXBLOCKSY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXRESTOREDHPALITTLE2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} restored its HP a little!"), //not in gen 5+, ability popup
- [STRINGID_PKMNSXWHIPPEDUPSANDSTORM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} whipped up a sandstorm!"), //not in gen 5+, ability popup
- [STRINGID_PKMNSXPREVENTSYLOSS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_BUFF1} loss!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXWHIPPEDUPSANDSTORM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} whipped up a sandstorm!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXPREVENTSYLOSS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_BUFF1} loss!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXINFATUATEDY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} infatuated {B_ATK_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXMADEYINEFFECTIVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made {B_CURRENT_MOVE} ineffective!"), //not in gen 5+, ability popup
- [STRINGID_PKMNSXCUREDYPROBLEM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXCUREDYPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup
[STRINGID_ITSUCKEDLIQUIDOOZE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} sucked up the liquid ooze!"),
- [STRINGID_PKMNTRANSFORMED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} transformed!"),
+ [STRINGID_PKMNTRANSFORMED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} transformed!"),
[STRINGID_ELECTRICITYWEAKENED] = COMPOUND_STRING("Electricity's power was weakened!"),
[STRINGID_FIREWEAKENED] = COMPOUND_STRING("Fire's power was weakened!"),
[STRINGID_PKMNHIDUNDERWATER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} hid underwater!"),
@@ -483,14 +481,14 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PLAYERDEFEATEDTRAINER1] = sText_PlayerDefeatedLinkTrainerTrainer1,
[STRINGID_SOOTHINGAROMA] = COMPOUND_STRING("A soothing aroma wafted through the area!"),
[STRINGID_ITEMSCANTBEUSEDNOW] = COMPOUND_STRING("Items can't be used now.{PAUSE 64}"), //not in gen 5+, i think
- [STRINGID_FORXCOMMAYZ] = COMPOUND_STRING("For {B_SCR_ACTIVE_NAME_WITH_PREFIX2}, {B_LAST_ITEM} {B_BUFF1}"), //not in gen 5+, expansion doesn't use anymore
- [STRINGID_USINGITEMSTATOFPKMNROSE] = COMPOUND_STRING("Using {B_LAST_ITEM}, the {B_BUFF1} of {B_SCR_ACTIVE_NAME_WITH_PREFIX2} {B_BUFF2}"), //todo: update this, will require code changes
- [STRINGID_PKMNUSEDXTOGETPUMPED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used the {B_LAST_ITEM} to get pumped!"),
+ [STRINGID_FORXCOMMAYZ] = COMPOUND_STRING("For {B_SCR_NAME_WITH_PREFIX2}, {B_LAST_ITEM} {B_BUFF1}"), //not in gen 5+, expansion doesn't use anymore
+ [STRINGID_USINGITEMSTATOFPKMNROSE] = COMPOUND_STRING("Using {B_LAST_ITEM}, the {B_BUFF1} of {B_SCR_NAME_WITH_PREFIX2} {B_BUFF2}"), //todo: update this, will require code changes
+ [STRINGID_PKMNUSEDXTOGETPUMPED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used the {B_LAST_ITEM} to get pumped!"),
[STRINGID_PKMNSXMADEYUSELESS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made {B_CURRENT_MOVE} useless!"), //not in gen 5+, ability popup
[STRINGID_PKMNTRAPPEDBYSANDTOMB] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} became trapped by the quicksand!"),
[STRINGID_EMPTYSTRING4] = COMPOUND_STRING(""),
[STRINGID_ABOOSTED] = COMPOUND_STRING(" a boosted"),
- [STRINGID_PKMNSXINTENSIFIEDSUN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} intensified the sun's rays!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXINTENSIFIEDSUN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} intensified the sun's rays!"), //not in gen 5+, ability popup
[STRINGID_PKMNMAKESGROUNDMISS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} makes Ground-type moves miss with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_YOUTHROWABALLNOWRIGHT] = COMPOUND_STRING("You throw a Ball now, right? I… I'll do my best!"),
[STRINGID_PKMNSXTOOKATTACK] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} took the attack!"), //In gen 5+ but without naming the ability
@@ -500,35 +498,35 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNFLEDUSINGITS] = COMPOUND_STRING("{PLAY_SE SE_FLEE}{B_ATK_NAME_WITH_PREFIX} fled using its {B_LAST_ITEM}!\p"),
[STRINGID_PKMNFLEDUSING] = COMPOUND_STRING("{PLAY_SE SE_FLEE}{B_ATK_NAME_WITH_PREFIX} fled using {B_ATK_ABILITY}!\p"), //not in gen 5+
[STRINGID_PKMNWASDRAGGEDOUT] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was dragged out!\p"),
- [STRINGID_PREVENTEDFROMWORKING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevented {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s {B_BUFF1} from working!"), //unused
- [STRINGID_PKMNSITEMNORMALIZEDSTATUS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} normalized its status!"),
+ [STRINGID_PREVENTEDFROMWORKING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevented {B_SCR_NAME_WITH_PREFIX2}'s {B_BUFF1} from working!"), //unused
+ [STRINGID_PKMNSITEMNORMALIZEDSTATUS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} normalized its status!"),
[STRINGID_TRAINER1USEDITEM] = COMPOUND_STRING("{B_ATK_TRAINER_NAME_WITH_CLASS} used {B_LAST_ITEM}!"),
[STRINGID_BOXISFULL] = COMPOUND_STRING("The Box is full! You can't catch any more!\p"),
[STRINGID_PKMNAVOIDEDATTACK] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} avoided the attack!"),
- [STRINGID_PKMNSXMADEITINEFFECTIVE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it ineffective!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXMADEITINEFFECTIVE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} made it ineffective!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXPREVENTSFLINCHING] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY} prevents flinching!"), //not in gen 5+, ability popup
[STRINGID_PKMNALREADYHASBURN] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is already burned!"),
[STRINGID_STATSWONTDECREASE2] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s stats won't go any lower!"),
- [STRINGID_PKMNSXBLOCKSY2] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXBLOCKSY2] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} blocks {B_CURRENT_MOVE}!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXWOREOFF] = COMPOUND_STRING("{B_ATK_TEAM1} team's {B_BUFF1} wore off!"),
[STRINGID_PKMNRAISEDDEFALITTLE] = COMPOUND_STRING("{B_ATK_PREFIX1}'s {B_CURRENT_MOVE} raised DEFENSE a little!"), //expansion doesn't use anymore
[STRINGID_PKMNRAISEDSPDEFALITTLE] = COMPOUND_STRING("{B_ATK_PREFIX1}'s {B_CURRENT_MOVE} raised SP. DEF a little!"), //expansion doesn't use anymore
[STRINGID_THEWALLSHATTERED] = COMPOUND_STRING("The wall shattered!"), //not in gen5+, uses "your teams light screen wore off!" etc instead
[STRINGID_PKMNSXPREVENTSYSZ] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} prevents {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY} from working!"),
- [STRINGID_PKMNSXCUREDITSYPROBLEM] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXCUREDITSYPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup
[STRINGID_ATTACKERCANTESCAPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can't escape!"),
[STRINGID_PKMNOBTAINEDX] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} obtained {B_BUFF1}."),
[STRINGID_PKMNOBTAINEDX2] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} obtained {B_BUFF2}."),
[STRINGID_PKMNOBTAINEDXYOBTAINEDZ] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} obtained {B_BUFF1}.\p{B_DEF_NAME_WITH_PREFIX} obtained {B_BUFF2}."),
[STRINGID_BUTNOEFFECT] = COMPOUND_STRING("But it had no effect!"),
- [STRINGID_PKMNSXHADNOEFFECTONY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} had no effect on {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
+ [STRINGID_PKMNSXHADNOEFFECTONY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} had no effect on {B_EFF_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
[STRINGID_TWOENEMIESDEFEATED] = sText_TwoInGameTrainersDefeated,
[STRINGID_TRAINER2LOSETEXT] = COMPOUND_STRING("{B_TRAINER2_LOSE_TEXT}"),
[STRINGID_PKMNINCAPABLEOFPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} appears incapable of using its power!"),
- [STRINGID_GLINTAPPEARSINEYE] = COMPOUND_STRING("A glint appears in {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s eyes!"),
- [STRINGID_PKMNGETTINGINTOPOSITION] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is getting into position!"),
- [STRINGID_PKMNBEGANGROWLINGDEEPLY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} began growling deeply!"),
- [STRINGID_PKMNEAGERFORMORE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is eager for more!"),
+ [STRINGID_GLINTAPPEARSINEYE] = COMPOUND_STRING("A glint appears in {B_SCR_NAME_WITH_PREFIX2}'s eyes!"),
+ [STRINGID_PKMNGETTINGINTOPOSITION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is getting into position!"),
+ [STRINGID_PKMNBEGANGROWLINGDEEPLY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} began growling deeply!"),
+ [STRINGID_PKMNEAGERFORMORE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is eager for more!"),
[STRINGID_DEFEATEDOPPONENTBYREFEREE] = COMPOUND_STRING("{B_PLAYER_MON1_NAME} defeated the opponent {B_OPPONENT_MON1_NAME} in a REFEREE's decision!"),
[STRINGID_LOSTTOOPPONENTBYREFEREE] = COMPOUND_STRING("{B_PLAYER_MON1_NAME} lost to the opponent {B_OPPONENT_MON1_NAME} in a REFEREE's decision!"),
[STRINGID_TIEDOPPONENTBYREFEREE] = COMPOUND_STRING("{B_PLAYER_MON1_NAME} tied the opponent {B_OPPONENT_MON1_NAME} in a REFEREE's decision!"),
@@ -584,7 +582,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_KINDOFFER] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} took the kind offer!"),
[STRINGID_RESETSTARGETSSTATLEVELS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s stat changes were removed!"),
[STRINGID_EMPTYSTRING6] = sText_EmptyString4,
- [STRINGID_ALLYSWITCHPOSITION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} and {B_SCR_ACTIVE_NAME_WITH_PREFIX2} switched places!"),
+ [STRINGID_ALLYSWITCHPOSITION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} and {B_SCR_NAME_WITH_PREFIX2} switched places!"),
[STRINGID_RESTORETARGETSHEALTH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s HP was restored!"),
[STRINGID_TOOKPJMNINTOTHESKY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} took {B_DEF_NAME_WITH_PREFIX2} into the sky!"),
[STRINGID_FREEDFROMSKYDROP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was freed from the Sky Drop!"),
@@ -613,15 +611,15 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_ATTACKERABILITYSTATRAISE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} raised its {B_BUFF1}!"),
[STRINGID_POISONHEALHPUP] = COMPOUND_STRING("The poisoning healed {B_ATK_NAME_WITH_PREFIX2} a little bit!"), //don't think this message is displayed anymore
[STRINGID_BADDREAMSDMG] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is tormented!"),
- [STRINGID_MOLDBREAKERENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} breaks the mold!"),
- [STRINGID_TERAVOLTENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a bursting aura!"),
- [STRINGID_TURBOBLAZEENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a blazing aura!"),
- [STRINGID_SLOWSTARTENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is slow to get going!"),
+ [STRINGID_MOLDBREAKERENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} breaks the mold!"),
+ [STRINGID_TERAVOLTENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a bursting aura!"),
+ [STRINGID_TURBOBLAZEENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a blazing aura!"),
+ [STRINGID_SLOWSTARTENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is slow to get going!"),
[STRINGID_SLOWSTARTEND] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} finally got its act together!"),
[STRINGID_SOLARPOWERHPDROP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} takes its toll!"), //don't think this message is displayed anymore
[STRINGID_AFTERMATHDMG] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt!"),
- [STRINGID_ANTICIPATIONACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shuddered!"),
- [STRINGID_FOREWARNACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_ACTIVE_NAME_WITH_PREFIX2} to {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1}!"),
+ [STRINGID_ANTICIPATIONACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} shuddered!"),
+ [STRINGID_FOREWARNACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_ABILITY} alerted {B_SCR_NAME_WITH_PREFIX2} to {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1}!"),
[STRINGID_ICEBODYHPGAIN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} healed it a little bit!"), //don't think this message is displayed anymore
[STRINGID_SNOWWARNINGHAIL] = COMPOUND_STRING("It started to hail!"),
[STRINGID_FRISKACTIVATES] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} frisked {B_DEF_NAME_WITH_PREFIX2} and found its {B_LAST_ITEM}!"),
@@ -630,11 +628,11 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_LASTABILITYRAISEDSTAT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} raised its {B_BUFF1}!"),
[STRINGID_MAGICBOUNCEACTIVATES] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} bounced the {B_ATK_NAME_WITH_PREFIX2} back!"),
[STRINGID_PROTEANTYPECHANGE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY} transformed it into the {B_BUFF1} type!"),
- [STRINGID_SYMBIOSISITEMPASS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} passed its {B_LAST_ITEM} to {B_ATK_NAME_WITH_PREFIX2} through {B_LAST_ABILITY}!"),
- [STRINGID_STEALTHROCKDMG] = COMPOUND_STRING("Pointed stones dug into {B_SCR_ACTIVE_NAME_WITH_PREFIX2}!"),
+ [STRINGID_SYMBIOSISITEMPASS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} passed its {B_LAST_ITEM} to {B_ATK_NAME_WITH_PREFIX2} through {B_LAST_ABILITY}!"),
+ [STRINGID_STEALTHROCKDMG] = COMPOUND_STRING("Pointed stones dug into {B_SCR_NAME_WITH_PREFIX2}!"),
[STRINGID_TOXICSPIKESABSORBED] = COMPOUND_STRING("The poison spikes disappeared from the ground around {B_ATK_TEAM2} team!"),
- [STRINGID_TOXICSPIKESPOISONED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was poisoned!"),
- [STRINGID_STICKYWEBSWITCHIN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was caught in a sticky web!"),
+ [STRINGID_TOXICSPIKESPOISONED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was poisoned!"),
+ [STRINGID_STICKYWEBSWITCHIN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was caught in a sticky web!"),
[STRINGID_HEALINGWISHCAMETRUE] = COMPOUND_STRING("The healing wish came true for {B_ATK_NAME_WITH_PREFIX2}!"),
[STRINGID_HEALINGWISHHEALED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} regained health!"),
[STRINGID_LUNARDANCECAMETRUE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became cloaked in mystical moonlight!"),
@@ -666,7 +664,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_SEVERELY] = gText_severely,
[STRINGID_INFESTATION] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} has been afflicted with an infestation by {B_ATK_NAME_WITH_PREFIX2}!"),
[STRINGID_NOEFFECTONTARGET] = COMPOUND_STRING("It won't have any effect on {B_DEF_NAME_WITH_PREFIX2}!"),
- [STRINGID_BURSTINGFLAMESHIT] = COMPOUND_STRING("The bursting flames hit {B_SCR_ACTIVE_NAME_WITH_PREFIX2}!"),
+ [STRINGID_BURSTINGFLAMESHIT] = COMPOUND_STRING("The bursting flames hit {B_SCR_NAME_WITH_PREFIX2}!"),
[STRINGID_BESTOWITEMGIVING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} received {B_LAST_ITEM} from {B_ATK_NAME_WITH_PREFIX2}!"),
[STRINGID_THIRDTYPEADDED] = COMPOUND_STRING("{B_BUFF1} type was added to {B_DEF_NAME_WITH_PREFIX2}!"),
[STRINGID_FELLFORFEINT] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} fell for the feint!"),
@@ -690,48 +688,47 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PKMNCANTUSEMOVETHROATCHOP] = COMPOUND_STRING("The effects of Throat Chop prevent {B_ATK_NAME_WITH_PREFIX2} from using certain moves!\p"),
[STRINGID_LASERFOCUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} concentrated intensely!"),
[STRINGID_GEMACTIVATES] = COMPOUND_STRING("The {B_LAST_ITEM} strengthened {B_ATK_NAME_WITH_PREFIX2}'s power!"),
- [STRINGID_BERRYDMGREDUCES] = COMPOUND_STRING("The {B_LAST_ITEM} weakened the damage to {B_DEF_NAME_WITH_PREFIX2}!"),
- [STRINGID_TARGETATEITEM] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} ate its {B_LAST_ITEM}!"),
- [STRINGID_AIRBALLOONFLOAT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} floats in the air with its Air Balloon!"),
+ [STRINGID_BERRYDMGREDUCES] = COMPOUND_STRING("The {B_LAST_ITEM} weakened the damage to {B_SCR_NAME_WITH_PREFIX2}!"),
+ [STRINGID_AIRBALLOONFLOAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} floats in the air with its Air Balloon!"),
[STRINGID_AIRBALLOONPOP] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s Air Balloon popped!"),
[STRINGID_INCINERATEBURN] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_LAST_ITEM} was burnt up!"),
[STRINGID_BUGBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} stole and ate its target's {B_LAST_ITEM}!"),
[STRINGID_ILLUSIONWOREOFF] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s illusion wore off!"),
[STRINGID_ATTACKERCUREDTARGETSTATUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured {B_DEF_NAME_WITH_PREFIX2}'s problem!"),
[STRINGID_ATTACKERLOSTFIRETYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} burned itself out!"),
- [STRINGID_HEALERCURE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} cured {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s problem!"),
- [STRINGID_SCRIPTINGABILITYSTATRAISE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"),
- [STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} was taken over!"),
+ [STRINGID_HEALERCURE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ABILITY} cured {B_SCR_NAME_WITH_PREFIX2}'s problem!"),
+ [STRINGID_SCRIPTINGABILITYSTATRAISE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"),
+ [STRINGID_RECEIVERABILITYTAKEOVER] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} was taken over!"),
[STRINGID_PKNMABSORBINGPOWER] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is absorbing power!"),
[STRINGID_NOONEWILLBEABLETORUNAWAY] = COMPOUND_STRING("No one will be able to run away during the next turn!"),
- [STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"),
+ [STRINGID_DESTINYKNOTACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} fell in love because of the {B_LAST_ITEM}!"),
[STRINGID_CLOAKEDINAFREEZINGLIGHT] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became cloaked in a freezing light!"),
- [STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("The effects of the {B_LAST_ITEM} held by {B_DEF_NAME_WITH_PREFIX2} prevents its stats from being lowered!"),
+ [STRINGID_CLEARAMULETWONTLOWERSTATS] = COMPOUND_STRING("The effects of the {B_LAST_ITEM} held by {B_SCR_NAME_WITH_PREFIX2} prevents its stats from being lowered!"),
[STRINGID_FERVENTWISHREACHED] = COMPOUND_STRING("{B_ATK_TRAINER_NAME}'s fervent wish has reached {B_ATK_NAME_WITH_PREFIX2}!"),
[STRINGID_AIRLOCKACTIVATES] = COMPOUND_STRING("The effects of the weather disappeared."),
- [STRINGID_PRESSUREENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is exerting its pressure!"),
- [STRINGID_DARKAURAENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a dark aura!"),
- [STRINGID_FAIRYAURAENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is radiating a fairy aura!"),
- [STRINGID_AURABREAKENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} reversed all other Pokémon's auras!"),
- [STRINGID_COMATOSEENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is drowsing!"),
+ [STRINGID_PRESSUREENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is exerting its pressure!"),
+ [STRINGID_DARKAURAENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a dark aura!"),
+ [STRINGID_FAIRYAURAENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is radiating a fairy aura!"),
+ [STRINGID_AURABREAKENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} reversed all other Pokémon's auras!"),
+ [STRINGID_COMATOSEENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is drowsing!"),
[STRINGID_SCREENCLEANERENTERS] = COMPOUND_STRING("All screens on the field were cleansed!"),
- [STRINGID_FETCHEDPOKEBALL] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} found a {B_LAST_ITEM}!"),
- [STRINGID_BATTLERABILITYRAISEDSTAT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"),
+ [STRINGID_FETCHEDPOKEBALL] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} found a {B_LAST_ITEM}!"),
+ [STRINGID_BATTLERABILITYRAISEDSTAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} raised its {B_BUFF1}!"),
[STRINGID_ASANDSTORMKICKEDUP] = COMPOUND_STRING("A sandstorm kicked up!"),
[STRINGID_PKMNSWILLPERISHIN3TURNS] = COMPOUND_STRING("Both Pokémon will perish in three turns!"), //don't think this message is displayed anymore
[STRINGID_ABILITYRAISEDSTATDRASTICALLY] = COMPOUND_STRING("{B_DEF_ABILITY} raised {B_DEF_NAME_WITH_PREFIX2}'s {B_BUFF1} drastically!"),
[STRINGID_AURAFLAREDTOLIFE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s aura flared to life!"),
- [STRINGID_ASONEENTERS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two Abilities!"),
+ [STRINGID_ASONEENTERS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} has two Abilities!"),
[STRINGID_CURIOUSMEDICINEENTERS] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s stat changes were removed!"),
[STRINGID_CANACTFASTERTHANKSTO] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can act faster than normal, thanks to its {B_BUFF1}!"),
- [STRINGID_MICLEBERRYACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its next move using {B_LAST_ITEM}!"),
- [STRINGID_PKMNSHOOKOFFTHETAUNT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shook off the taunt!"),
- [STRINGID_PKMNGOTOVERITSINFATUATION] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} got over its infatuation!"),
+ [STRINGID_MICLEBERRYACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted the accuracy of its next move using {B_LAST_ITEM}!"),
+ [STRINGID_PKMNSHOOKOFFTHETAUNT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} shook off the taunt!"),
+ [STRINGID_PKMNGOTOVERITSINFATUATION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} got over its infatuation!"),
[STRINGID_ITEMCANNOTBEREMOVED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s item cannot be removed!"),
[STRINGID_STICKYBARBTRANSFER] = COMPOUND_STRING("The {B_LAST_ITEM} attached itself to {B_ATK_NAME_WITH_PREFIX2}!"),
[STRINGID_PKMNBURNHEALED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s burn was cured!"),
- [STRINGID_REDCARDACTIVATE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} held up its Red Card against {B_ATK_NAME_WITH_PREFIX2}!"),
- [STRINGID_EJECTBUTTONACTIVATE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is switched out with the {B_LAST_ITEM}!"),
+ [STRINGID_REDCARDACTIVATE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} held up its Red Card against {B_ATK_NAME_WITH_PREFIX2}!"),
+ [STRINGID_EJECTBUTTONACTIVATE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is switched out with the {B_LAST_ITEM}!"),
[STRINGID_ATKGOTOVERINFATUATION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} got over its infatuation!"),
[STRINGID_TORMENTEDNOMORE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is no longer tormented!"),
[STRINGID_HEALBLOCKEDNOMORE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is cured of its heal block!"),
@@ -750,7 +747,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_MYSTERIOUSAIRCURRENTBLOWSON] = COMPOUND_STRING("The mysterious strong winds blow on regardless!"),
[STRINGID_ATTACKWEAKENEDBSTRONGWINDS] = COMPOUND_STRING("The mysterious strong winds weakened the attack!"),
[STRINGID_STUFFCHEEKSCANTSELECT] = COMPOUND_STRING("It can't use the move because it doesn't have a Berry!\p"),
- [STRINGID_PKMNREVERTEDTOPRIMAL] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s Primal Reversion! It reverted to its primal state!"),
+ [STRINGID_PKMNREVERTEDTOPRIMAL] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s Primal Reversion! It reverted to its primal state!"),
[STRINGID_BUTPOKEMONCANTUSETHEMOVE] = COMPOUND_STRING("But {B_ATK_NAME_WITH_PREFIX2} can't use the move!"),
[STRINGID_BUTHOOPACANTUSEIT] = COMPOUND_STRING("But {B_ATK_NAME_WITH_PREFIX2} can't use it the way it is now!"),
[STRINGID_BROKETHROUGHPROTECTION] = COMPOUND_STRING("It broke through {B_DEF_NAME_WITH_PREFIX2}'s protection!"),
@@ -758,7 +755,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_SWAPPEDABILITIES] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} swapped Abilities with its target!"),
[STRINGID_PASTELVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is protected by a pastel veil!"),
[STRINGID_PASTELVEILENTERS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was cured of its poisoning!"),
- [STRINGID_BATTLERTYPECHANGEDTO] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s type changed to {B_BUFF1}!"),
+ [STRINGID_BATTLERTYPECHANGEDTO] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s type changed to {B_BUFF1}!"),
[STRINGID_BOTHCANNOLONGERESCAPE] = COMPOUND_STRING("Neither Pokémon can run away!"),
[STRINGID_CANTESCAPEDUETOUSEDMOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can no longer escape because it used No Retreat!"),
[STRINGID_PKMNBECAMEWEAKERTOFIRE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} became weaker to fire!"),
@@ -776,12 +773,12 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_PLAYERPAIDPRIZEMONEY] = COMPOUND_STRING("You gave ¥{B_BUFF1} to the winner…\pYou were overwhelmed by your defeat!{PAUSE_UNTIL_PRESS}"),
[STRINGID_ZPOWERSURROUNDS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} surrounded itself with its Z-Power!"),
[STRINGID_ZMOVEUNLEASHED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} unleashes its full-force Z-Move!"),
- [STRINGID_ZMOVERESETSSTATS] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} returned its decreased stats to normal using its Z-Power!"),
- [STRINGID_ZMOVEALLSTATSUP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"),
- [STRINGID_ZMOVEZBOOSTCRIT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its critical-hit ratio using its Z-Power!"),
- [STRINGID_ZMOVERESTOREHP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} restored its HP using its Z-Power!"),
- [STRINGID_ZMOVESTATUP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"),
- [STRINGID_ZMOVEHPTRAP] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s HP was restored by the Z-Power!"),
+ [STRINGID_ZMOVERESETSSTATS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} returned its decreased stats to normal using its Z-Power!"),
+ [STRINGID_ZMOVEALLSTATSUP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"),
+ [STRINGID_ZMOVEZBOOSTCRIT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted its critical-hit ratio using its Z-Power!"),
+ [STRINGID_ZMOVERESTOREHP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored its HP using its Z-Power!"),
+ [STRINGID_ZMOVESTATUP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} boosted its stats using its Z-Power!"),
+ [STRINGID_ZMOVEHPTRAP] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s HP was restored by the Z-Power!"),
[STRINGID_ATTACKEREXPELLEDTHEPOISON] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} managed to expel the poison so you wouldn't worry!"),
[STRINGID_ATTACKERSHOOKITSELFAWAKE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} shook itself awake so you wouldn't worry!"),
[STRINGID_ATTACKERBROKETHROUGHPARALYSIS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} gathered all its energy to break through its paralysis so you wouldn't worry!"),
@@ -791,12 +788,12 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_ATTACKERLOSTELECTRICTYPE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} used up all its electricity!"),
[STRINGID_ATTACKERSWITCHEDSTATWITHTARGET] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} switched {B_BUFF1} with its target!"),
[STRINGID_BEINGHITCHARGEDPKMNWITHPOWER] = COMPOUND_STRING("Being hit by {B_CURRENT_MOVE} charged {B_DEF_NAME_WITH_PREFIX2} with power!"),
- [STRINGID_SUNLIGHTACTIVATEDABILITY] = COMPOUND_STRING("The harsh sunlight activated {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s Protosynthesis!"),
- [STRINGID_STATWASHEIGHTENED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"),
- [STRINGID_ELECTRICTERRAINACTIVATEDABILITY] = COMPOUND_STRING("The Electric Terrain activated {B_SCR_ACTIVE_NAME_WITH_PREFIX2}'s Quark Drive!"),
- [STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} weakened the {B_BUFF1} of all surrounding Pokémon!\p"),
- [STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} gained strength from the fallen!"),
- [STRINGID_PKMNSABILITYPREVENTSABILITY] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY} from working!"), //not in gen 5+, ability popup
+ [STRINGID_SUNLIGHTACTIVATEDABILITY] = COMPOUND_STRING("The harsh sunlight activated {B_SCR_NAME_WITH_PREFIX2}'s Protosynthesis!"),
+ [STRINGID_STATWASHEIGHTENED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_BUFF1} was heightened!"),
+ [STRINGID_ELECTRICTERRAINACTIVATEDABILITY] = COMPOUND_STRING("The Electric Terrain activated {B_SCR_NAME_WITH_PREFIX2}'s Quark Drive!"),
+ [STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} weakened the {B_BUFF1} of all surrounding Pokémon!\p"),
+ [STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} gained strength from the fallen!"),
+ [STRINGID_PKMNSABILITYPREVENTSABILITY] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY} prevents {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY} from working!"), //not in gen 5+, ability popup
[STRINGID_PREPARESHELLTRAP] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} set a shell trap!"),
[STRINGID_SHELLTRAPDIDNTWORK] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s shell trap didn't work!"),
[STRINGID_SPIKESDISAPPEAREDFROMTEAM] = COMPOUND_STRING("The spikes disappeared from the ground around {B_ATK_TEAM2} team!"),
@@ -812,12 +809,12 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_THUNDERCAGETRAPPED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} trapped {B_DEF_NAME_WITH_PREFIX2}!"),
[STRINGID_PKMNHURTBYFROSTBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} was hurt by its frostbite!"),
[STRINGID_PKMNGOTFROSTBITE] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX} got frostbite!"),
- [STRINGID_PKMNSITEMHEALEDFROSTBITE] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its frostbite!"),
+ [STRINGID_PKMNSITEMHEALEDFROSTBITE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_LAST_ITEM} cured its frostbite!"),
[STRINGID_ATTACKERHEALEDITSFROSTBITE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} cured its frostbite through sheer determination so you wouldn't worry!"),
[STRINGID_PKMNFROSTBITEHEALED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s frostbite was cured!"),
[STRINGID_PKMNFROSTBITEHEALED2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s frostbite was cured!"),
[STRINGID_PKMNFROSTBITEHEALEDBY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_CURRENT_MOVE} cured its frostbite!"),
- [STRINGID_MIRRORHERBCOPIED] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used its Mirror Herb to mirror its opponent's stat changes!"),
+ [STRINGID_MIRRORHERBCOPIED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used its Mirror Herb to mirror its opponent's stat changes!"),
[STRINGID_STARTEDSNOW] = COMPOUND_STRING("It started to snow!"),
[STRINGID_SNOWCONTINUES] = COMPOUND_STRING("Snow continues to fall."), //not in gen 5+ (lol)
[STRINGID_SNOWSTOPPED] = COMPOUND_STRING("The snow stopped."),
@@ -843,7 +840,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_TEAMSURROUNDEDBYROCKS] = COMPOUND_STRING("{B_DEF_TEAM1} Pokémon became surrounded by rocks!"),
[STRINGID_PKMNHURTBYROCKSTHROWN] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is hurt by rocks thrown out by G-Max Volcalith!"),
[STRINGID_MOVEBLOCKEDBYDYNAMAX] = COMPOUND_STRING("The move was blocked by the power of Dynamax!"),
- [STRINGID_ZEROTOHEROTRANSFORMATION] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} underwent a heroic transformation!"),
+ [STRINGID_ZEROTOHEROTRANSFORMATION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} underwent a heroic transformation!"),
[STRINGID_THETWOMOVESBECOMEONE] = COMPOUND_STRING("The two moves have become one! It's a combined move!{PAUSE 16}"),
[STRINGID_ARAINBOWAPPEAREDONSIDE] = COMPOUND_STRING("A rainbow appeared in the sky on {B_ATK_TEAM2} team's side!"),
[STRINGID_THERAINBOWDISAPPEARED] = COMPOUND_STRING("The rainbow on {B_ATK_TEAM2} team's side disappeared!"),
@@ -866,13 +863,13 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_BIZARREAREACREATED] = COMPOUND_STRING("A bizarre area was created in which Defense and Sp. Def stats are swapped!"),
[STRINGID_TIDYINGUPCOMPLETE] = COMPOUND_STRING("Tidying up complete!"),
[STRINGID_PKMNTERASTALLIZEDINTO] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} terastallized into the {B_BUFF1} type!"),
- [STRINGID_BOOSTERENERGYACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} used its {B_LAST_ITEM} to activate {B_SCR_ACTIVE_ABILITY}!"),
+ [STRINGID_BOOSTERENERGYACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used its {B_LAST_ITEM} to activate {B_SCR_ACTIVE_ABILITY}!"),
[STRINGID_FOGCREPTUP] = COMPOUND_STRING("Fog crept up as thick as soup!"),
[STRINGID_FOGISDEEP] = COMPOUND_STRING("The fog is deep…"),
[STRINGID_FOGLIFTED] = COMPOUND_STRING("The fog lifted."),
[STRINGID_PKMNMADESHELLGLEAM] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} made its shell gleam! It's distorting type matchups!"),
[STRINGID_FICKLEBEAMDOUBLED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is going all out for this attack!"),
- [STRINGID_COMMANDERACTIVATES] = COMPOUND_STRING("{B_SCR_ACTIVE_NAME_WITH_PREFIX} was swallowed by Dondozo and became Dondozo's commander!"),
+ [STRINGID_COMMANDERACTIVATES] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} was swallowed by Dondozo and became Dondozo's commander!"),
[STRINGID_POKEFLUTECATCHY] = COMPOUND_STRING("{B_PLAYER_NAME} played the {B_LAST_ITEM}.\pNow, that's a catchy tune!"),
[STRINGID_POKEFLUTE] = COMPOUND_STRING("{B_PLAYER_NAME} played the {B_LAST_ITEM}."),
[STRINGID_MONHEARINGFLUTEAWOKE] = COMPOUND_STRING("The Pokémon hearing the flute awoke!"),
@@ -884,6 +881,10 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
[STRINGID_ELECTRICCURRENTISRUNNING] = COMPOUND_STRING("An electric current is running across the battlefield!"),
[STRINGID_SEEMSWEIRD] = COMPOUND_STRING("The battlefield seems weird!"),
[STRINGID_WAGGLINGAFINGER] = COMPOUND_STRING("Waggling a finger let it use {B_CURRENT_MOVE}!"),
+ [STRINGID_BLOCKEDBYSLEEPCLAUSE] = COMPOUND_STRING("Sleep Clause kept {B_DEF_NAME_WITH_PREFIX2} awake!"),
+ [STRINGID_SUPEREFFECTIVETWOFOES] = COMPOUND_STRING("It's super effective on {B_DEF_NAME_WITH_PREFIX2} and {B_DEF_PARTNER_NAME}!"),
+ [STRINGID_NOTVERYEFFECTIVETWOFOES] = COMPOUND_STRING("It's not very effective on {B_DEF_NAME_WITH_PREFIX2} and {B_DEF_PARTNER_NAME}!"),
+ [STRINGID_ITDOESNTAFFECTTWOFOES] = COMPOUND_STRING("It doesn't affect {B_DEF_NAME_WITH_PREFIX2} and {B_DEF_PARTNER_NAME}…"),
};
const u16 gTrainerUsedItemStringIds[] =
@@ -914,15 +915,17 @@ const u16 gMentalHerbCureStringIds[] =
const u16 gStartingStatusStringIds[B_MSG_STARTING_STATUS_COUNT] =
{
- [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY,
- [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC,
- [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC,
- [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY,
- [B_MSG_SET_TRICK_ROOM] = STRINGID_DIMENSIONSWERETWISTED,
- [B_MSG_SET_MAGIC_ROOM] = STRINGID_BIZARREARENACREATED,
- [B_MSG_SET_WONDER_ROOM] = STRINGID_BIZARREAREACREATED,
- [B_MSG_SET_TAILWIND_PLAYER] = STRINGID_TAILWINDBLEW,
- [B_MSG_SET_TAILWIND_OPPONENT] = STRINGID_TAILWINDBLEW,
+ [B_MSG_TERRAIN_SET_MISTY] = STRINGID_TERRAINBECOMESMISTY,
+ [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_TERRAINBECOMESELECTRIC,
+ [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_TERRAINBECOMESPSYCHIC,
+ [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_TERRAINBECOMESGRASSY,
+ [B_MSG_SET_TRICK_ROOM] = STRINGID_DIMENSIONSWERETWISTED,
+ [B_MSG_SET_MAGIC_ROOM] = STRINGID_BIZARREARENACREATED,
+ [B_MSG_SET_WONDER_ROOM] = STRINGID_BIZARREAREACREATED,
+ [B_MSG_SET_TAILWIND] = STRINGID_TAILWINDBLEW,
+ [B_MSG_SET_RAINBOW] = STRINGID_ARAINBOWAPPEAREDONSIDE,
+ [B_MSG_SET_SEA_OF_FIRE] = STRINGID_SEAOFFIREENVELOPEDSIDE,
+ [B_MSG_SET_SWAMP] = STRINGID_SWAMPENVELOPEDSIDE,
};
const u16 gTerrainStringIds[B_MSG_TERRAIN_COUNT] =
@@ -1285,7 +1288,10 @@ const u16 gWeatherStartsStringIds[] =
const u16 gTerrainStartsStringIds[] =
{
- STRINGID_MISTSWIRLSAROUND, STRINGID_ELECTRICCURRENTISRUNNING, STRINGID_ISCOVEREDWITHGRASS, STRINGID_SEEMSWEIRD,
+ [B_MSG_TERRAIN_SET_MISTY] = STRINGID_MISTSWIRLSAROUND,
+ [B_MSG_TERRAIN_SET_ELECTRIC] = STRINGID_ELECTRICCURRENTISRUNNING,
+ [B_MSG_TERRAIN_SET_PSYCHIC] = STRINGID_SEEMSWEIRD,
+ [B_MSG_TERRAIN_SET_GRASSY] = STRINGID_ISCOVEREDWITHGRASS,
};
const u16 gPrimalWeatherBlocksStringIds[] =
@@ -1402,8 +1408,8 @@ const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!");
const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p");
const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p");
const u8 gText_EllipsisQuestionMark[] = _("……?\p");
-const u8 gText_WhatWillPkmnDo[] = _("What will\n{B_BUFF1} do?");
-const u8 gText_WhatWillPkmnDo2[] = _("What will\n{B_PLAYER_NAME} do?");
+const u8 gText_WhatWillPkmnDo[] = _("What will {B_BUFF1} do?");
+const u8 gText_WhatWillPkmnDo2[] = _("What will {B_PLAYER_NAME} do?");
const u8 gText_WhatWillWallyDo[] = _("What will\nWALLY do?");
const u8 gText_LinkStandby[] = _("{PAUSE 16}Link standby…");
const u8 gText_BattleMenu[] = _("Battle{CLEAR_TO 56}Bag\nPokémon{CLEAR_TO 56}Run");
@@ -2421,8 +2427,7 @@ static void GetBattlerNick(u32 battler, u8 *dst)
} \
} \
GetBattlerNick(battler, text); \
- toCpy = text; \
- dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize);
+ toCpy = text;
#define HANDLE_NICKNAME_STRING_LOWERCASE(battler) \
if (GetBattlerSide(battler) != B_SIDE_PLAYER) \
@@ -2439,8 +2444,7 @@ static void GetBattlerNick(u32 battler, u8 *dst)
} \
} \
GetBattlerNick(battler, text); \
- toCpy = text; \
- dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize);
+ toCpy = text;
static const u8 *BattleStringGetOpponentNameByTrainerId(u16 trainerId, u8 *text, u8 multiplayerId, u8 battler)
{
@@ -2589,17 +2593,10 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
{
u32 dstID = 0; // if they used dstID, why not use srcID as well?
const u8 *toCpy = NULL;
- u32 lastValidSkip = 0;
- u32 toCpyWidth = 0;
- u32 dstWidth = 0;
- // This buffer may hold either the name of a trainer, Pokémon, or item.
u8 text[max(max(max(32, TRAINER_NAME_LENGTH + 1), POKEMON_NAME_LENGTH + 1), ITEM_NAME_LENGTH)];
u8 *textStart = &text[0];
u8 multiplayerId;
u8 fontId = FONT_NORMAL;
- s16 letterSpacing = 0;
- u32 lineNum = 1;
- u32 displayedLineNums = 1;
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK)
multiplayerId = gRecordedBattleMultiplayerId;
@@ -2617,11 +2614,14 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
while (*src != EOS)
{
toCpy = NULL;
- dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize);
if (*src == PLACEHOLDER_BEGIN)
{
src++;
+ u32 classLength = 0;
+ u32 nameLength = 0;
+ const u8 *classString;
+ const u8 *nameString;
switch (*src)
{
case B_TXT_BUFF1:
@@ -2644,7 +2644,9 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
toCpy = gStringVar2;
}
else
+ {
toCpy = gBattleTextBuff2;
+ }
break;
case B_TXT_BUFF3:
if (gBattleTextBuff3[0] == B_BUFF_PLACEHOLDER_BEGIN)
@@ -2653,7 +2655,9 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
toCpy = gStringVar3;
}
else
+ {
toCpy = gBattleTextBuff3;
+ }
break;
case B_TXT_COPY_VAR_1:
toCpy = gStringVar1;
@@ -2712,6 +2716,10 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
GetBattlerNick(gBattlerTarget, text);
toCpy = text;
break;
+ case B_TXT_DEF_PARTNER_NAME: // partner target name
+ GetBattlerNick(BATTLE_PARTNER(gBattlerTarget), text);
+ toCpy = text;
+ break;
case B_TXT_EFF_NAME_WITH_PREFIX: // effect battler name with prefix
HANDLE_NICKNAME_STRING_CASE(gEffectBattler)
break;
@@ -2762,7 +2770,9 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
toCpy = text;
}
else
+ {
toCpy = sText_EnigmaBerry;
+ }
}
}
else
@@ -2800,9 +2810,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
break;
case B_TXT_TRAINER1_NAME_WITH_CLASS: // trainer1 name with trainer class
toCpy = textStart;
- textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A));
- textStart = StringAppend(textStart, gText_Space2);
- textStart = StringAppend(textStart, BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)));
+ classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
+ while (classString[classLength] != EOS)
+ {
+ textStart[classLength] = classString[classLength];
+ classLength++;
+ }
+ textStart[classLength] = CHAR_SPACE;
+ textStart += classLength + 1;
+ nameString = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_A, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT));
+ if (nameString != textStart)
+ {
+ while (nameString[nameLength] != EOS)
+ {
+ textStart[nameLength] = nameString[nameLength];
+ nameLength++;
+ }
+ textStart[nameLength] = EOS;
+ }
break;
case B_TXT_LINK_PLAYER_NAME: // link player name
toCpy = gLinkPlayers[multiplayerId].name;
@@ -2922,9 +2947,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
break;
case B_TXT_TRAINER2_NAME_WITH_CLASS:
toCpy = textStart;
- textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B));
- textStart = StringAppend(textStart, gText_Space2);
- textStart = StringAppend(textStart, BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)));
+ classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
+ while (classString[classLength] != EOS)
+ {
+ textStart[classLength] = classString[classLength];
+ classLength++;
+ }
+ textStart[classLength] = CHAR_SPACE;
+ textStart += classLength + 1;
+ nameString = BattleStringGetOpponentNameByTrainerId(gTrainerBattleOpponent_B, textStart, multiplayerId, GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT));
+ if (nameString != textStart)
+ {
+ while (nameString[nameLength] != EOS)
+ {
+ textStart[nameLength] = nameString[nameLength];
+ nameLength++;
+ }
+ textStart[nameLength] = EOS;
+ }
break;
case B_TXT_TRAINER2_LOSE_TEXT:
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
@@ -2962,9 +3002,24 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
break;
case B_TXT_PARTNER_NAME_WITH_CLASS:
toCpy = textStart;
- textStart = StringCopy(textStart, gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name);
- textStart = StringAppend(textStart, gText_Space2);
- textStart = StringAppend(textStart, BattleStringGetPlayerName(textStart, GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)));
+ classString = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name;
+ while (classString[classLength] != EOS)
+ {
+ textStart[classLength] = classString[classLength];
+ classLength++;
+ }
+ textStart[classLength] = CHAR_SPACE;
+ textStart += classLength + 1;
+ nameString = BattleStringGetPlayerName(textStart, GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT));
+ if (nameString != textStart)
+ {
+ while (nameString[nameLength] != EOS)
+ {
+ textStart[nameLength] = nameString[nameLength];
+ nameLength++;
+ }
+ textStart[nameLength] = EOS;
+ }
break;
case B_TXT_ATK_TRAINER_NAME:
toCpy = BattleStringGetTrainerName(text, multiplayerId, gBattlerAttacker);
@@ -2995,24 +3050,42 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
}
else
{
+ classString = NULL;
switch (GetBattlerPosition(gBattlerAttacker))
{
case B_POSITION_PLAYER_RIGHT:
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
- textStart = StringCopy(textStart, gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name);
+ classString = gTrainerClasses[GetFrontierOpponentClass(gPartnerTrainerId)].name;
break;
case B_POSITION_OPPONENT_LEFT:
- textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A));
+ classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
break;
case B_POSITION_OPPONENT_RIGHT:
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS && !BATTLE_TWO_VS_ONE_OPPONENT)
- textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B));
+ classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_B);
else
- textStart = StringCopy(textStart, BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A));
+ classString = BattleStringGetOpponentClassByTrainerId(gTrainerBattleOpponent_A);
break;
}
- textStart = StringAppend(textStart, gText_Space2);
- textStart = StringAppend(textStart, BattleStringGetTrainerName(textStart, multiplayerId, gBattlerAttacker));
+ classLength = 0;
+ nameLength = 0;
+ while (classString[classLength] != EOS)
+ {
+ textStart[classLength] = classString[classLength];
+ classLength++;
+ }
+ textStart[classLength] = CHAR_SPACE;
+ textStart += 1 + classLength;
+ nameString = BattleStringGetTrainerName(textStart, multiplayerId, gBattlerAttacker);
+ if (nameString != textStart)
+ {
+ while (nameString[nameLength] != EOS)
+ {
+ textStart[nameLength] = nameString[nameLength];
+ nameLength++;
+ }
+ textStart[nameLength] = EOS;
+ }
}
break;
case B_TXT_ATK_TEAM1:
@@ -3055,21 +3128,12 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
if (toCpy != NULL)
{
- toCpyWidth = GetStringLineWidth(fontId, toCpy, letterSpacing, 1, dstSize);
-
- if (dstWidth + toCpyWidth > BATTLE_MSG_MAX_WIDTH)
- {
- dst[lastValidSkip] = displayedLineNums == 1 ? CHAR_NEWLINE : CHAR_PROMPT_SCROLL;
- dstWidth = GetStringLineWidth(fontId, dst, letterSpacing, lineNum, dstSize);
- if (displayedLineNums == 1)
- displayedLineNums++;
- else
- displayedLineNums = 1;
- lineNum++;
- }
while (*toCpy != EOS)
{
- dst[dstID] = *toCpy;
+ if (*toCpy == CHAR_SPACE)
+ dst[dstID] = CHAR_NBSP;
+ else
+ dst[dstID] = *toCpy;
dstID++;
toCpy++;
}
@@ -3086,31 +3150,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
}
else
{
- toCpyWidth = GetGlyphWidth(*src, FALSE, fontId);
dst[dstID] = *src;
- if (dstWidth + toCpyWidth > BATTLE_MSG_MAX_WIDTH)
- {
- dst[lastValidSkip] = displayedLineNums == 1 ? CHAR_NEWLINE : CHAR_PROMPT_SCROLL;
- if (displayedLineNums == 1)
- displayedLineNums++;
- else
- displayedLineNums = 1;
- lineNum++;
- dstWidth = 0;
- }
- switch (*src)
- {
- case CHAR_PROMPT_CLEAR:
- case CHAR_PROMPT_SCROLL:
- displayedLineNums = 1;
- case CHAR_NEWLINE:
- lineNum++;
- dstWidth = 0;
- //fallthrough
- case CHAR_SPACE:
- lastValidSkip = dstID;
- break;
- }
dstID++;
}
src++;
@@ -3119,6 +3159,8 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
dst[dstID] = *src;
dstID++;
+ BreakStringAutomatic(dst, BATTLE_MSG_MAX_WIDTH, BATTLE_MSG_MAX_WIDTH, fontId);
+
return dstID;
}
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 9ea2920bb9..dae6401cd0 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -47,6 +47,7 @@
#include "pokenav.h"
#include "menu_specialized.h"
#include "data.h"
+#include "move.h"
#include "constants/abilities.h"
#include "constants/battle_anim.h"
#include "constants/battle_move_effects.h"
@@ -329,6 +330,7 @@ static void BestowItem(u32 battlerAtk, u32 battlerDef);
static bool8 IsFinalStrikeEffect(u32 moveEffect);
static void TryUpdateRoundTurnOrder(void);
static bool32 ChangeOrderTargetAfterAttacker(void);
+static bool32 SetTargetToNextPursuiter(u32 battlerDef);
void ApplyExperienceMultipliers(s32 *expAmount, u8 expGetterMonId, u8 faintedBattler);
static void RemoveAllWeather(void);
static void RemoveAllTerrains(void);
@@ -397,7 +399,7 @@ static void Cmd_bichalfword(void);
static void Cmd_bicword(void);
static void Cmd_pause(void);
static void Cmd_waitstate(void);
-static void Cmd_healthbar_update(void);
+static void Cmd_absorb(void);
static void Cmd_return(void);
static void Cmd_end(void);
static void Cmd_end2(void);
@@ -479,7 +481,7 @@ static void Cmd_statbuffchange(void);
static void Cmd_normalisebuffs(void);
static void Cmd_setbide(void);
static void Cmd_twoturnmoveschargestringandanimation(void);
-static void Cmd_setmultihitcounter(void);
+static void Cmd_unused_0x8d(void);
static void Cmd_initmultihitstring(void);
static void Cmd_forcerandomswitch(void);
static void Cmd_tryconversiontypechange(void);
@@ -487,7 +489,7 @@ static void Cmd_givepaydaymoney(void);
static void Cmd_setlightscreen(void);
static void Cmd_tryKO(void);
static void Cmd_damagetohalftargethp(void);
-static void Cmd_unused_95(void);
+static void Cmd_copybidedmg(void);
static void Cmd_unused_96(void);
static void Cmd_tryinfatuating(void);
static void Cmd_updatestatusicon(void);
@@ -508,7 +510,7 @@ static void Cmd_settypetorandomresistance(void);
static void Cmd_setalwayshitflag(void);
static void Cmd_copymovepermanently(void);
static void Cmd_trychoosesleeptalkmove(void);
-static void Cmd_setdestinybond(void);
+static void Cmd_trysetdestinybond(void);
static void Cmd_trysetdestinybondtohappen(void);
static void Cmd_settailwind(void);
static void Cmd_tryspiteppreduce(void);
@@ -543,7 +545,7 @@ static void Cmd_trymemento(void);
static void Cmd_setforcedtarget(void);
static void Cmd_setcharge(void);
static void Cmd_callterrainattack(void);
-static void Cmd_cureifburnedparalysedorpoisoned(void);
+static void Cmd_curestatuswithmove(void);
static void Cmd_settorment(void);
static void Cmd_jumpifnodamage(void);
static void Cmd_settaunt(void);
@@ -568,8 +570,8 @@ static void Cmd_switchoutabilities(void);
static void Cmd_jumpifhasnohp(void);
static void Cmd_jumpifnotcurrentmoveargtype(void);
static void Cmd_pickup(void);
-static void Cmd_unused3(void);
-static void Cmd_unused4(void);
+static void Cmd_unused_0xE6(void);
+static void Cmd_unused_0xE7(void);
static void Cmd_settypebasedhalvers(void);
static void Cmd_jumpifsubstituteblocks(void);
static void Cmd_tryrecycleitem(void);
@@ -656,7 +658,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_bicword, //0x38
Cmd_pause, //0x39
Cmd_waitstate, //0x3A
- Cmd_healthbar_update, //0x3B
+ Cmd_absorb, //0x3B
Cmd_return, //0x3C
Cmd_end, //0x3D
Cmd_end2, //0x3E
@@ -738,7 +740,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_normalisebuffs, //0x8A
Cmd_setbide, //0x8B
Cmd_twoturnmoveschargestringandanimation, //0x8C
- Cmd_setmultihitcounter, //0x8D
+ Cmd_unused_0x8d, //0x8D
Cmd_initmultihitstring, //0x8E
Cmd_forcerandomswitch, //0x8F
Cmd_tryconversiontypechange, //0x90
@@ -746,7 +748,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_setlightscreen, //0x92
Cmd_tryKO, //0x93
Cmd_damagetohalftargethp, //0x94
- Cmd_unused_95, //0x95
+ Cmd_copybidedmg, //0x95
Cmd_unused_96, //0x96
Cmd_tryinfatuating, //0x97
Cmd_updatestatusicon, //0x98
@@ -767,7 +769,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_setalwayshitflag, //0xA7
Cmd_copymovepermanently, //0xA8
Cmd_trychoosesleeptalkmove, //0xA9
- Cmd_setdestinybond, //0xAA
+ Cmd_trysetdestinybond, //0xAA
Cmd_trysetdestinybondtohappen, //0xAB
Cmd_settailwind, //0xAC
Cmd_tryspiteppreduce, //0xAD
@@ -802,7 +804,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_setforcedtarget, //0xCA
Cmd_setcharge, //0xCB
Cmd_callterrainattack, //0xCC
- Cmd_cureifburnedparalysedorpoisoned, //0xCD
+ Cmd_curestatuswithmove, //0xCD
Cmd_settorment, //0xCE
Cmd_jumpifnodamage, //0xCF
Cmd_settaunt, //0xD0
@@ -827,8 +829,8 @@ void (* const gBattleScriptingCommandsTable[])(void) =
Cmd_jumpifhasnohp, //0xE3
Cmd_jumpifnotcurrentmoveargtype, //0xE4
Cmd_pickup, //0xE5
- Cmd_unused3, //0xE6
- Cmd_unused4, //0xE7
+ Cmd_unused_0xE6, //0xE6
+ Cmd_unused_0xE7, //0xE7
Cmd_settypebasedhalvers, //0xE8
Cmd_jumpifsubstituteblocks, //0xE9
Cmd_tryrecycleitem, //0xEA
@@ -1102,7 +1104,7 @@ static const u8 sTerrainToType[BATTLE_TERRAIN_COUNT] =
static bool32 NoTargetPresent(u8 battler, u32 move)
{
if (!IsBattlerAlive(gBattlerTarget))
- gBattlerTarget = GetMoveTarget(move, NO_TARGET_OVERRIDE);
+ gBattlerTarget = GetBattleMoveTarget(move, NO_TARGET_OVERRIDE);
switch (GetBattlerMoveTargetType(battler, move))
{
@@ -1125,35 +1127,6 @@ static bool32 NoTargetPresent(u8 battler, u32 move)
return FALSE;
}
-// TODO: Convert this to a proper FORM_CHANGE type.
-static bool32 TryAegiFormChange(void)
-{
- // Only Aegislash with Stance Change can transform, transformed mons cannot.
- if (GetBattlerAbility(gBattlerAttacker) != ABILITY_STANCE_CHANGE
- || gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
- return FALSE;
-
- switch (gBattleMons[gBattlerAttacker].species)
- {
- default:
- return FALSE;
- case SPECIES_AEGISLASH_SHIELD: // Shield -> Blade
- if (IS_MOVE_STATUS(gCurrentMove))
- return FALSE;
- gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE;
- break;
- case SPECIES_AEGISLASH_BLADE: // Blade -> Shield
- if (gCurrentMove != MOVE_KINGS_SHIELD)
- return FALSE;
- gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_SHIELD;
- break;
- }
-
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_AttackerFormChange;
- return TRUE;
-}
-
bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType)
{
if ((ability == ABILITY_PROTEAN || ability == ABILITY_LIBERO)
@@ -1171,12 +1144,12 @@ bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType)
bool32 ShouldTeraShellDistortTypeMatchups(u32 move, u32 battlerDef)
{
- if (!(gBattleStruct->distortedTypeMatchups & (1u << battlerDef))
- && GetBattlerAbility(battlerDef) == ABILITY_TERA_SHELL
+ if (!gSpecialStatuses[battlerDef].distortedTypeMatchups
&& gBattleMons[battlerDef].species == SPECIES_TERAPAGOS_TERASTAL
- && !IS_MOVE_STATUS(move)
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[battlerDef].hp == gBattleMons[battlerDef].maxHP)
+ && gBattleMons[battlerDef].hp == gBattleMons[battlerDef].maxHP
+ && !IsBattleMoveStatus(move)
+ && MoveResultHasEffect(battlerDef)
+ && GetBattlerAbility(battlerDef) == ABILITY_TERA_SHELL)
return TRUE;
return FALSE;
@@ -1184,7 +1157,7 @@ bool32 ShouldTeraShellDistortTypeMatchups(u32 move, u32 battlerDef)
bool32 IsMoveNotAllowedInSkyBattles(u32 move)
{
- return ((gBattleStruct->isSkyBattle) && (gMovesInfo[gCurrentMove].skyBattleBanned));
+ return (gBattleStruct->isSkyBattle && IsMoveSkyBattleBanned(gCurrentMove));
}
static void Cmd_attackcanceler(void)
@@ -1192,8 +1165,6 @@ static void Cmd_attackcanceler(void)
CMD_ARGS();
s32 i;
- u16 attackerAbility = GetBattlerAbility(gBattlerAttacker);
- u32 moveType = GetMoveType(gCurrentMove);
if (gBattleStruct->usedEjectItem & (1u << gBattlerAttacker))
{
@@ -1202,48 +1173,22 @@ static void Cmd_attackcanceler(void)
return;
}
- // Weight-based moves are blocked by Dynamax.
- if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove))
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax;
- return;
- }
-
if (gBattleOutcome != 0)
{
gCurrentActionFuncId = B_ACTION_FINISHED;
return;
}
- if (!IsBattlerAlive(gBattlerAttacker) && gMovesInfo[gCurrentMove].effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
+ u32 effect = GetMoveEffect(gCurrentMove);
+
+ if (!IsBattlerAlive(gBattlerAttacker) && effect != EFFECT_EXPLOSION && !(gHitMarker & HITMARKER_NO_ATTACKSTRING))
{
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
gBattlescriptCurrInstr = BattleScript_MoveEnd;
return;
}
- if (B_STANCE_CHANGE_FAIL < GEN_7 && TryAegiFormChange())
+ if (AtkCanceller_MoveSuccessOrder())
return;
- if (AtkCanceller_UnableToUseMove(moveType))
- return;
-
- if (WEATHER_HAS_EFFECT && gMovesInfo[gCurrentMove].power)
- {
- if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
- return;
- }
- else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
- return;
- }
- }
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND
@@ -1257,22 +1202,6 @@ static void Cmd_attackcanceler(void)
return;
}
- // Check Protean activation.
- if (ProteanTryChangeType(gBattlerAttacker, attackerAbility, gCurrentMove, moveType))
- {
- if (B_PROTEAN_LIBERO == GEN_9)
- gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE;
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
- gBattlerAbility = gBattlerAttacker;
- BattleScriptPushCursor();
- PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker);
- gBattleCommunication[MSG_DISPLAY] = 1;
- gBattlescriptCurrInstr = BattleScript_ProteanActivates;
- return;
- }
-
- if (AtkCanceller_UnableToUseMove2())
- return;
if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0))
return;
if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE
@@ -1280,82 +1209,36 @@ static void Cmd_attackcanceler(void)
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
{
gBattlescriptCurrInstr = BattleScript_NoPPForMove;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
return;
}
- if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryAegiFormChange())
- return;
gHitMarker &= ~HITMARKER_ALLOW_NO_PP;
- if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
- {
- switch (gBattleStruct->obedienceResult)
- {
- case OBEYS:
- break;
- case DISOBEYS_LOAFS:
- // Randomly select, then print a disobedient string
- // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
- gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
- gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- return;
- case DISOBEYS_HITS_SELF:
- gBattlerTarget = gBattlerAttacker;
- struct DamageCalculationData damageCalcData;
- damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker;
- damageCalcData.move = MOVE_NONE;
- damageCalcData.moveType = TYPE_MYSTERY;
- damageCalcData.isCrit = FALSE;
- damageCalcData.randomFactor = FALSE;
- damageCalcData.updateFlags = TRUE;
- gBattleMoveDamage = CalculateMoveDamage(&damageCalcData, 40);
- gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- gHitMarker |= HITMARKER_OBEYS;
- return;
- case DISOBEYS_FALL_ASLEEP:
- gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- return;
- case DISOBEYS_WHILE_ASLEEP:
- gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- return;
- case DISOBEYS_RANDOM_MOVE:
- gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
- SetAtkCancellerForCalledMove();
- gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
- gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
- gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
- gHitMarker |= HITMARKER_OBEYS;
- return;
- }
- }
-
- gHitMarker |= HITMARKER_OBEYS;
// Check if no available target present on the field or if Sky Battles ban the move
if ((NoTargetPresent(gBattlerAttacker, gCurrentMove)
- && (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
+ && (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|| (IsMoveNotAllowedInSkyBattles(gCurrentMove)))
{
- if (gMovesInfo[gCurrentMove].effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
+ if (effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem;
else
gBattlescriptCurrInstr = BattleScript_FailedFromAtkString;
- if (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
+ if (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
CancelMultiTurnMoves(gBattlerAttacker);
return;
}
+ u32 isBounceable = MoveCanBeBouncedBack(gCurrentMove);
if (gProtectStructs[gBattlerTarget].bounceMove
- && gMovesInfo[gCurrentMove].magicCoatAffected
+ && isBounceable
&& !gBattleStruct->bouncedMoveIsUsed)
{
gBattleStruct->bouncedMoveIsUsed = TRUE;
// Edge case for bouncing a powder move against a grass type pokemon.
+
+ ClearDamageCalcResults();
SetAtkCancellerForCalledMove();
if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE))
{
@@ -1370,7 +1253,7 @@ static void Cmd_attackcanceler(void)
}
return;
}
- else if (gMovesInfo[gCurrentMove].magicCoatAffected && !gBattleStruct->bouncedMoveIsUsed)
+ else if (isBounceable && !gBattleStruct->bouncedMoveIsUsed)
{
u32 battler = gBattlerTarget;
@@ -1380,7 +1263,7 @@ static void Cmd_attackcanceler(void)
gBattleStruct->bouncedMoveIsUsed = TRUE;
}
else if (IsDoubleBattle()
- && gMovesInfo[gCurrentMove].target == MOVE_TARGET_OPPONENTS_FIELD
+ && GetBattlerMoveTargetType(battler, gCurrentMove) == MOVE_TARGET_OPPONENTS_FIELD
&& GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) == ABILITY_MAGIC_BOUNCE)
{
gBattlerTarget = battler = BATTLE_PARTNER(gBattlerTarget);
@@ -1389,8 +1272,8 @@ static void Cmd_attackcanceler(void)
if (gBattleStruct->bouncedMoveIsUsed)
{
- // Edge case for bouncing a powder move against a grass type pokemon.
- SetAtkCancellerForCalledMove();
+ ClearDamageCalcResults();
+ SetAtkCancellerForCalledMove(); // Edge case for bouncing a powder move against a grass type pokemon.
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicBounce;
gBattlerAbility = battler;
@@ -1399,8 +1282,7 @@ static void Cmd_attackcanceler(void)
}
// Z-moves and Max Moves bypass protection, but deal reduced damage (factored in AccumulateOtherModifiers)
- if ((IsZMove(gCurrentMove) || IsMaxMove(gCurrentMove))
- && IS_BATTLER_PROTECTED(gBattlerTarget))
+ if ((IsZMove(gCurrentMove) || IsMaxMove(gCurrentMove)) && IS_BATTLER_PROTECTED(gBattlerTarget))
{
BattleScriptPush(cmd->nextInstr);
gBattlescriptCurrInstr = BattleScript_CouldntFullyProtect;
@@ -1409,7 +1291,7 @@ static void Cmd_attackcanceler(void)
for (i = 0; i < gBattlersCount; i++)
{
- if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && gMovesInfo[gCurrentMove].snatchAffected)
+ if ((gProtectStructs[gBattlerByTurnOrder[i]].stealMove) && MoveCanBeSnatched(gCurrentMove))
{
gProtectStructs[gBattlerByTurnOrder[i]].stealMove = FALSE;
gBattleStruct->snatchedMoveIsUsed = TRUE;
@@ -1438,14 +1320,14 @@ static void Cmd_attackcanceler(void)
}
else if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove)
&& (gCurrentMove != MOVE_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
- && (!gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
- && gMovesInfo[gCurrentMove].effect != EFFECT_SUCKER_PUNCH
- && gMovesInfo[gCurrentMove].effect != EFFECT_UPPER_HAND)
+ && (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
+ && effect != EFFECT_SUCKER_PUNCH
+ && effect != EFFECT_UPPER_HAND)
{
if (IsMoveMakingContact(gCurrentMove, gBattlerAttacker))
gProtectStructs[gBattlerAttacker].touchedProtectLike = TRUE;
CancelMultiTurnMoves(gBattlerAttacker);
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gLastLandedMoves[gBattlerTarget] = 0;
gLastHitByType[gBattlerTarget] = 0;
@@ -1471,7 +1353,7 @@ static void Cmd_attackcanceler(void)
static bool32 JumpIfMoveFailed(u8 adder, u16 move)
{
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (!MoveResultHasEffect(gBattlerTarget))
{
gLastLandedMoves[gBattlerTarget] = 0;
gLastHitByType[gBattlerTarget] = 0;
@@ -1494,7 +1376,7 @@ static void Cmd_unused5(void)
if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove))
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
JumpIfMoveFailed(sizeof(*cmd), MOVE_NONE);
gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED;
}
@@ -1504,103 +1386,97 @@ static void Cmd_unused5(void)
}
}
-static bool8 JumpIfMoveAffectedByProtect(u16 move)
+static bool32 JumpIfMoveAffectedByProtect(u32 move, u32 battler, u32 shouldJump)
{
- bool8 affected = FALSE;
- if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, move))
+ bool32 affected = IsBattlerProtected(gBattlerAttacker, battler, move);
+ if (affected)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- JumpIfMoveFailed(7, move);
- gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED;
- affected = TRUE;
+ gBattleStruct->moveResultFlags[battler] |= MOVE_RESULT_MISSED;
+ if (shouldJump)
+ JumpIfMoveFailed(7, move);
}
return affected;
}
-static bool32 AccuracyCalcHelper(u16 move)
+static bool32 AccuracyCalcHelper(u32 move, u32 battler)
{
- if ((gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
- || (B_TOXIC_NEVER_MISS >= GEN_6 && gMovesInfo[move].effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON))
- || gStatuses4[gBattlerTarget] & STATUS4_GLAIVE_RUSH)
+ u32 effect = FALSE;
+ u32 ability = ABILITY_NONE;
+ u32 moveEffect = GetMoveEffect(move);
+
+ if ((gStatuses3[battler] & STATUS3_ALWAYS_HITS && gDisableStructs[battler].battlerWithSureHit == gBattlerAttacker)
+ || (B_TOXIC_NEVER_MISS >= GEN_6 && moveEffect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_POISON))
+ || gStatuses4[battler] & STATUS4_GLAIVE_RUSH)
{
- JumpIfMoveFailed(7, move);
- return TRUE;
+ effect = TRUE;
}
// If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits.
else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD
- && !(gStatuses3[gBattlerTarget] & STATUS3_COMMANDER)
- && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
+ && !(gStatuses3[battler] & STATUS3_COMMANDER)
+ && (moveEffect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battler] == 0xFF))
{
- if (!JumpIfMoveFailed(7, move))
- RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
- return TRUE;
+ effect = TRUE;
+ ability = ABILITY_NO_GUARD;
}
// If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits.
- else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD
- && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF))
+ else if (GetBattlerAbility(battler) == ABILITY_NO_GUARD
+ && (moveEffect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[battler] == 0xFF))
{
- if (!JumpIfMoveFailed(7, move))
- RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD);
- return TRUE;
+ effect = TRUE;
+ ability = ABILITY_NO_GUARD;
}
// If the target is under the effects of Telekinesis, and the move isn't a OH-KO move, move hits.
- else if (gStatuses3[gBattlerTarget] & STATUS3_TELEKINESIS
- && !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE)
- && gMovesInfo[move].effect != EFFECT_OHKO)
+ else if (gStatuses3[battler] & STATUS3_TELEKINESIS
+ && !(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE)
+ && moveEffect != EFFECT_OHKO)
{
- JumpIfMoveFailed(7, move);
- return TRUE;
+ effect = TRUE;
}
-
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !(gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE))
+ else if (gBattleStruct->pursuitTarget & (1u << battler))
{
- JumpIfMoveFailed(7, move);
- return TRUE;
+ effect = TRUE;
}
-
- if ((gStatuses3[gBattlerTarget] & STATUS3_COMMANDER)
- || (gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE)
- || ((gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) && !(gMovesInfo[move].damagesAirborne || gMovesInfo[move].damagesAirborneDoubleDamage))
- || ((gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) && !gMovesInfo[move].damagesUnderground)
- || ((gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER) && !gMovesInfo[move].damagesUnderwater))
+ else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE))
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- JumpIfMoveFailed(7, move);
- return TRUE;
+ effect = TRUE;
+ }
+ else if ((gStatuses3[battler] & STATUS3_COMMANDER)
+ || (gStatuses3[battler] & STATUS3_PHANTOM_FORCE)
+ || ((gStatuses3[battler] & STATUS3_ON_AIR) && !(MoveDamagesAirborne(move) || MoveDamagesAirborneDoubleDamage(move)))
+ || ((gStatuses3[battler] & STATUS3_UNDERGROUND) && !MoveDamagesUnderground(move))
+ || ((gStatuses3[battler] & STATUS3_UNDERWATER) && !MoveDamagesUnderWater(move)))
+ {
+ gBattleStruct->moveResultFlags[battler] |= MOVE_RESULT_MISSED;
+ effect = TRUE;
}
if (WEATHER_HAS_EFFECT)
{
- if ((gMovesInfo[move].effect == EFFECT_THUNDER || gMovesInfo[move].effect == EFFECT_RAIN_ALWAYS_HIT)
- && IsBattlerWeatherAffected(gBattlerTarget, B_WEATHER_RAIN))
- {
- // thunder/hurricane/genie moves ignore acc checks in rain unless target is holding utility umbrella
- JumpIfMoveFailed(7, move);
- return TRUE;
- }
- else if ((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && gMovesInfo[move].effect == EFFECT_BLIZZARD)
- {
- // Blizzard ignores acc checks in Hail in Gen4+
- JumpIfMoveFailed(7, move);
- return TRUE;
- }
+ if ((moveEffect == EFFECT_THUNDER || moveEffect == EFFECT_RAIN_ALWAYS_HIT)
+ && IsBattlerWeatherAffected(battler, B_WEATHER_RAIN))
+ effect = TRUE;
+ else if ((gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)) && moveEffect == EFFECT_BLIZZARD)
+ effect = TRUE;
+
+ if (effect)
+ return effect;
}
if (B_MINIMIZE_DMG_ACC >= GEN_6
- && (gStatuses3[gBattlerTarget] & STATUS3_MINIMIZED)
- && gMovesInfo[move].minimizeDoubleDamage)
+ && (gStatuses3[battler] & STATUS3_MINIMIZED)
+ && MoveIncreasesPowerToMinimizedTargets(move))
{
- JumpIfMoveFailed(7, move);
- return TRUE;
+ effect = TRUE;
+ }
+ else if (GetMoveAccuracy(move) == 0)
+ {
+ effect = TRUE;
}
- if (gMovesInfo[move].accuracy == 0)
- {
- JumpIfMoveFailed(7, move);
- return TRUE;
- }
+ if (ability != ABILITY_NONE)
+ RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD);
- return FALSE;
+ return effect;
}
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u32 defAbility, u32 atkHoldEffect, u32 defHoldEffect)
@@ -1618,7 +1494,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
if (atkAbility == ABILITY_UNAWARE || atkAbility == ABILITY_KEEN_EYE || atkAbility == ABILITY_MINDS_EYE
|| (B_ILLUMINATE_EFFECT >= GEN_9 && atkAbility == ABILITY_ILLUMINATE))
evasionStage = DEFAULT_STAT_STAGE;
- if (gMovesInfo[move].ignoresTargetDefenseEvasionStages)
+ if (MoveIgnoresDefenseEvasionStages(move))
evasionStage = DEFAULT_STAT_STAGE;
if (defAbility == ABILITY_UNAWARE)
accStage = DEFAULT_STAT_STAGE;
@@ -1633,12 +1509,12 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
if (buff > MAX_STAT_STAGE)
buff = MAX_STAT_STAGE;
- moveAcc = gMovesInfo[move].accuracy;
+ moveAcc = GetMoveAccuracy(move);
// Check Thunder and Hurricane on sunny weather.
- if (IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && gMovesInfo[move].effect == EFFECT_THUNDER)
+ if (IsBattlerWeatherAffected(battlerDef, B_WEATHER_SUN) && GetMoveEffect(move) == EFFECT_THUNDER)
moveAcc = 50;
// Check Wonder Skin.
- if (defAbility == ABILITY_WONDER_SKIN && IS_MOVE_STATUS(move) && moveAcc > 50)
+ if (defAbility == ABILITY_WONDER_SKIN && IsBattleMoveStatus(move) && moveAcc > 50)
moveAcc = 50;
calc = gAccuracyStageRatios[buff].dividend * moveAcc;
@@ -1654,7 +1530,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
calc = (calc * 110) / 100; // 1.1 victory star boost
break;
case ABILITY_HUSTLE:
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
calc = (calc * 80) / 100; // 1.2 hustle loss
break;
}
@@ -1727,21 +1603,24 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u
static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u8 *failInstr, u16 move)
{
- u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
- u32 abilityAtk = GetBattlerAbility(gBattlerAttacker);
- u32 abilityDef = GetBattlerAbility(gBattlerTarget);
- u32 holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
+ u32 abilityAtk;
+ u32 holdEffectAtk;
if (move == ACC_CURR_MOVE)
move = gCurrentMove;
+ u32 effect = GetMoveEffect(move);
+
+ abilityAtk = GetBattlerAbility(gBattlerAttacker);
+ holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
+
if (move == NO_ACC_CALC_CHECK_LOCK_ON)
{
if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker)
gBattlescriptCurrInstr = nextInstr;
else if (gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE))
gBattlescriptCurrInstr = failInstr;
- else if (!JumpIfMoveAffectedByProtect(gCurrentMove))
+ else if (!JumpIfMoveAffectedByProtect(gCurrentMove, gBattlerTarget, TRUE))
gBattlescriptCurrInstr = nextInstr;
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX)
{
@@ -1754,58 +1633,68 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
else if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT
|| (gSpecialStatuses[gBattlerAttacker].multiHitOn
&& (abilityAtk == ABILITY_SKILL_LINK || holdEffectAtk == HOLD_EFFECT_LOADED_DICE
- || !(gMovesInfo[move].effect == EFFECT_TRIPLE_KICK || gMovesInfo[move].effect == EFFECT_POPULATION_BOMB))))
+ || !(effect == EFFECT_TRIPLE_KICK || effect == EFFECT_POPULATION_BOMB))))
{
// No acc checks for second hit of Parental Bond or multi hit moves, except Triple Kick/Triple Axel/Population Bomb
gBattlescriptCurrInstr = nextInstr;
}
else
{
- u32 accuracy;
- u32 type = GetMoveType(move);
+ u32 moveType = GetBattleMoveType(move);
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move);
+ bool32 calcSpreadMove = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(move);
- if (JumpIfMoveAffectedByProtect(move))
- return;
- if (AccuracyCalcHelper(move))
- return;
-
- accuracy = GetTotalAccuracy(
- gBattlerAttacker,
- gBattlerTarget,
- move,
- abilityAtk,
- abilityDef,
- holdEffectAtk,
- GetBattlerHoldEffect(gBattlerTarget, TRUE)
- );
-
- if (!RandomPercentage(RNG_ACCURACY, accuracy))
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY)
- gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks
+ if (gBattleStruct->calculatedSpreadMoveAccuracy)
+ break;
- if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS
- && !recalcDragonDarts // So we don't jump back and forth between targets
- && CanTargetPartner(gBattlerAttacker, gBattlerTarget)
- && !TargetFullyImmuneToCurrMove(gBattlerAttacker, BATTLE_PARTNER(gBattlerTarget)))
+ if ((!calcSpreadMove && battlerDef != gBattlerTarget)
+ || IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
+ || (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK))
+ continue;
+
+ if (JumpIfMoveAffectedByProtect(move, battlerDef, FALSE) || AccuracyCalcHelper(move, battlerDef))
+ continue;
+
+ u32 accuracy = GetTotalAccuracy(gBattlerAttacker,
+ battlerDef,
+ move,
+ abilityAtk,
+ GetBattlerAbility(battlerDef),
+ holdEffectAtk,
+ GetBattlerHoldEffect(battlerDef, TRUE));
+
+ if (!RandomPercentage(RNG_ACCURACY, accuracy))
{
- // Smart target to partner if miss
- gBattlerTarget = BATTLE_PARTNER(gBattlerTarget);
- gMoveResultFlags &= ~MOVE_RESULT_MISSED;
- AccuracyCheck(TRUE, nextInstr, failInstr, move);
- return;
+ gBattleStruct->moveResultFlags[battlerDef] = MOVE_RESULT_MISSED;
+ gBattleStruct->missStringId[battlerDef] = gBattleCommunication[MISS_TYPE] = B_MSG_MISSED;
+
+ if (holdEffectAtk == HOLD_EFFECT_BLUNDER_POLICY)
+ gBattleStruct->blunderPolicy = TRUE; // Only activates from missing through acc/evasion checks
+
+ if (effect == EFFECT_DRAGON_DARTS
+ && !recalcDragonDarts // So we don't jump back and forth between targets
+ && CanTargetPartner(gBattlerAttacker, battlerDef)
+ && !TargetFullyImmuneToCurrMove(gBattlerAttacker, BATTLE_PARTNER(battlerDef)))
+ {
+ // Smart target to partner if miss
+ gBattlerTarget = BATTLE_PARTNER(battlerDef);
+ AccuracyCheck(TRUE, nextInstr, failInstr, move);
+ return;
+ }
+
+ if (GetMovePower(move) != 0)
+ CalcTypeEffectivenessMultiplier(move, moveType, gBattlerAttacker, battlerDef, GetBattlerAbility(battlerDef), TRUE);
}
-
- if (IsDoubleBattle() &&
- (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
- gBattleCommunication[MISS_TYPE] = B_MSG_AVOIDED_ATK;
- else
- gBattleCommunication[MISS_TYPE] = B_MSG_MISSED;
-
- if (gMovesInfo[move].power)
- CalcTypeEffectivenessMultiplier(move, type, gBattlerAttacker, gBattlerTarget, abilityDef, TRUE);
}
+
+ if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_MISSED)
+ gBattleStruct->moveResultFlags[gBattlerTarget] = MOVE_RESULT_MISSED;
+
+ if (calcSpreadMove)
+ gBattleStruct->calculatedSpreadMoveAccuracy = TRUE;
+
JumpIfMoveFailed(7, move);
}
}
@@ -1852,7 +1741,7 @@ static void Cmd_ppreduce(void)
if (moveTarget == MOVE_TARGET_BOTH
|| moveTarget == MOVE_TARGET_FOES_AND_ALLY
|| moveTarget == MOVE_TARGET_ALL_BATTLERS
- || gMovesInfo[gCurrentMove].forcePressure)
+ || MoveForcesPressure(gCurrentMove))
{
for (i = 0; i < gBattlersCount; i++)
{
@@ -1890,14 +1779,6 @@ static void Cmd_ppreduce(void)
gHitMarker &= ~HITMARKER_NO_PPDEDUCT;
gBattlescriptCurrInstr = cmd->nextInstr;
-
- if (ShouldTeraShellDistortTypeMatchups(gCurrentMove, gBattlerTarget))
- {
- gBattleStruct->distortedTypeMatchups |= 1u << gBattlerTarget;
- gBattlerAbility = gBattlerTarget;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_TeraShellDistortingTypeMatchups;
- }
}
// The chance is 1/N for each stage.
@@ -1950,25 +1831,27 @@ static inline u32 GetHoldEffectCritChanceIncrease(u32 battler, u32 holdEffect)
return critStageIncrease;
}
+#define CRITICAL_HIT_BLOCKED -1
+#define CRITICAL_HIT_ALWAYS -2
s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility, u32 abilityAtk, u32 abilityDef, u32 holdEffectAtk)
{
s32 critChance = 0;
if (gSideStatuses[battlerDef] & SIDE_STATUS_LUCKY_CHANT)
{
- critChance = -1;
+ critChance = CRITICAL_HIT_BLOCKED;
}
else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS
- || gMovesInfo[move].alwaysCriticalHit
- || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY))
+ || MoveAlwaysCrits(move)
+ || (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY))
{
- critChance = -2;
+ critChance = CRITICAL_HIT_ALWAYS;
}
else
{
critChance = 2 * ((gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) != 0)
+ 1 * ((gBattleMons[battlerAtk].status2 & STATUS2_DRAGON_CHEER) != 0)
- + gMovesInfo[move].criticalHitStage
+ + GetMoveCriticalHitStage(move)
+ GetHoldEffectCritChanceIncrease(battlerAtk, holdEffectAtk)
+ 2 * (B_AFFECTION_MECHANICS == TRUE && GetBattlerAffectionHearts(battlerAtk) == AFFECTION_FIVE_HEARTS)
+ (abilityAtk == ABILITY_SUPER_LUCK)
@@ -1978,21 +1861,23 @@ s32 CalcCritChanceStageArgs(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
critChance = ARRAY_COUNT(sCriticalHitOdds) - 1;
}
- if (critChance != -1 && (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR))
+ if (critChance != CRITICAL_HIT_BLOCKED && (abilityDef == ABILITY_BATTLE_ARMOR || abilityDef == ABILITY_SHELL_ARMOR))
{
// Record ability only if move had 100% chance to get a crit
if (recordAbility)
{
- if (critChance == -2)
+ if (critChance == CRITICAL_HIT_ALWAYS)
RecordAbilityBattle(battlerDef, abilityDef);
else if (GetCriticalHitOdds(critChance) == 1)
RecordAbilityBattle(battlerDef, abilityDef);
}
- critChance = -1;
+ critChance = CRITICAL_HIT_BLOCKED;
}
return critChance;
}
+#undef CRIT_BLOCKED
+#undef ALWAYS_CRITS
s32 CalcCritChanceStage(u32 battlerAtk, u32 battlerDef, u32 move, bool32 recordAbility)
{
@@ -2020,7 +1905,7 @@ s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
u32 farfetchdLeekScaler = 8;
s32 critChance = 0;
- s32 moveCritStage = gMovesInfo[gCurrentMove].criticalHitStage;
+ s32 moveCritStage = GetMoveCriticalHitStage(gCurrentMove);
s32 bonusCritStage = gBattleStruct->bonusCritStages[battlerAtk]; // G-Max Chi Strike
u32 abilityAtk = GetBattlerAbility(battlerAtk);
u32 abilityDef = GetBattlerAbility(battlerDef);
@@ -2064,7 +1949,7 @@ s32 CalcCritChanceStageGen1(u32 battlerAtk, u32 battlerDef, u32 move, bool32 rec
// Guaranteed crits
else if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS
- || gMovesInfo[move].alwaysCriticalHit == TRUE
+ || MoveAlwaysCrits(move)
|| (abilityAtk == ABILITY_MERCILESS && gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY))
{
critChance = -2;
@@ -2085,62 +1970,119 @@ static void Cmd_critcalc(void)
{
CMD_ARGS();
- u16 partySlot;
- s32 critChance;
-
- if (B_CRIT_CHANCE == GEN_1)
- critChance = CalcCritChanceStageGen1(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE);
- else
- critChance = CalcCritChanceStage(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE);
-
+ u32 partySlot = gBattlerPartyIndexes[gBattlerAttacker];
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+ bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(gCurrentMove);
gPotentialItemEffectBattler = gBattlerAttacker;
- if (gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE))
- gIsCriticalHit = FALSE;
- else if (critChance == -1)
- gIsCriticalHit = FALSE;
- else if (critChance == -2)
- gIsCriticalHit = TRUE;
- else
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
+ if (gBattleStruct->calculatedDamageDone)
+ break;
+
+ if (!calcSpreadMoveDamage && battlerDef != gBattlerTarget)
+ continue;
+
+ if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
+ || gBattleStruct->noResultString[battlerDef]
+ || gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
+ continue;
+
if (B_CRIT_CHANCE == GEN_1)
- {
- u8 critRoll = RandomUniform(RNG_CRITICAL_HIT, 1, 256);
- if (critRoll <= critChance)
- gIsCriticalHit = 1;
- else
- gIsCriticalHit = 0;
- }
+ gBattleStruct->critChance[battlerDef] = CalcCritChanceStageGen1(gBattlerAttacker, battlerDef, gCurrentMove, TRUE);
else
- gIsCriticalHit = RandomChance(RNG_CRITICAL_HIT, 1, GetCriticalHitOdds(critChance));
+ gBattleStruct->critChance[battlerDef] = CalcCritChanceStage(gBattlerAttacker, battlerDef, gCurrentMove, TRUE);
+
+ if (gBattleTypeFlags & (BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_FIRST_BATTLE))
+ gSpecialStatuses[battlerDef].criticalHit = FALSE;
+ else if (gBattleStruct->critChance[battlerDef] == -1)
+ gSpecialStatuses[battlerDef].criticalHit = FALSE;
+ else if (gBattleStruct->critChance[battlerDef] == -2)
+ gSpecialStatuses[battlerDef].criticalHit = TRUE;
+ else
+ {
+ if (B_CRIT_CHANCE == GEN_1)
+ {
+ u32 critRoll = RandomUniform(RNG_CRITICAL_HIT, 1, 256);
+ if (critRoll <= gBattleStruct->critChance[battlerDef])
+ gSpecialStatuses[battlerDef].criticalHit = TRUE;
+ else
+ gSpecialStatuses[battlerDef].criticalHit = FALSE;
+ }
+ else
+ {
+ gSpecialStatuses[battlerDef].criticalHit = RandomChance(RNG_CRITICAL_HIT, 1, GetCriticalHitOdds(gBattleStruct->critChance[battlerDef]));
+ }
+ }
+
+ // Counter for EVO_CRITICAL_HITS.
+ if (gSpecialStatuses[battlerDef].criticalHit && GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER
+ && !(gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(gBattlerAttacker) == B_POSITION_PLAYER_LEFT))
+ gPartyCriticalHits[partySlot]++;
}
- // Counter for EVO_CRITICAL_HITS.
- partySlot = gBattlerPartyIndexes[gBattlerAttacker];
- if (gIsCriticalHit && GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER
- && !(gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(gBattlerAttacker) == B_POSITION_PLAYER_LEFT))
- gPartyCriticalHits[partySlot]++;
-
gBattlescriptCurrInstr = cmd->nextInstr;
}
+static inline void GetShellSideArmCategory(u32 battlerDef)
+{
+ if (GetMoveEffect(gCurrentMove) == EFFECT_SHELL_SIDE_ARM)
+ gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[gBattlerAttacker][battlerDef] != GetMoveCategory(gCurrentMove));
+}
+
static void Cmd_damagecalc(void)
{
CMD_ARGS();
- if (gMovesInfo[gCurrentMove].effect == EFFECT_SHELL_SIDE_ARM)
- gBattleStruct->swapDamageCategory = (gBattleStruct->shellSideArmCategory[gBattlerAttacker][gBattlerTarget] != gMovesInfo[gCurrentMove].category);
+ if (gBattleStruct->calculatedDamageDone)
+ {
+ gBattlescriptCurrInstr = cmd->nextInstr;
+ return;
+ }
+
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
struct DamageCalculationData damageCalcData;
damageCalcData.battlerAtk = gBattlerAttacker;
- damageCalcData.battlerDef = gBattlerTarget;
damageCalcData.move = gCurrentMove;
- damageCalcData.moveType = GetMoveType(gCurrentMove);
- damageCalcData.isCrit = gIsCriticalHit;
+ damageCalcData.moveType = GetBattleMoveType(gCurrentMove);
damageCalcData.randomFactor = TRUE;
damageCalcData.updateFlags = TRUE;
- gBattleMoveDamage = CalculateMoveDamage(&damageCalcData, 0);
+ if (IsSpreadMove(moveTarget))
+ {
+ u32 battlerDef;
+ for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
+ || gBattleStruct->noResultString[battlerDef]
+ || gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT)
+ continue;
+
+ if (ShouldTeraShellDistortTypeMatchups(gCurrentMove, battlerDef))
+ {
+ gSpecialStatuses[battlerDef].distortedTypeMatchups = TRUE;
+ gSpecialStatuses[battlerDef].teraShellAbilityDone = TRUE;
+ }
+ GetShellSideArmCategory(battlerDef);
+ damageCalcData.battlerDef = battlerDef;
+ damageCalcData.isCrit = gSpecialStatuses[battlerDef].criticalHit;
+ gBattleStruct->moveDamage[battlerDef] = CalculateMoveDamage(&damageCalcData, 0);
+ }
+ }
+ else
+ {
+ if (ShouldTeraShellDistortTypeMatchups(gCurrentMove, gBattlerTarget))
+ {
+ gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = TRUE;
+ gSpecialStatuses[gBattlerTarget].teraShellAbilityDone = TRUE;
+ }
+ GetShellSideArmCategory(gBattlerTarget);
+ damageCalcData.battlerDef = gBattlerTarget;
+ damageCalcData.isCrit = gSpecialStatuses[gBattlerTarget].criticalHit;
+ gBattleStruct->moveDamage[gBattlerTarget] = CalculateMoveDamage(&damageCalcData, 0);
+ }
+
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -2148,8 +2090,11 @@ static void Cmd_typecalc(void)
{
CMD_ARGS();
- u32 moveType = GetMoveType(gCurrentMove);
- CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget), TRUE);
+ if (!IsSpreadMove(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove))) // Handled in CANCELLER_MULTI_TARGET_MOVES for Spread Moves
+ {
+ u32 moveType = GetBattleMoveType(gCurrentMove);
+ CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget), TRUE);
+ }
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -2159,134 +2104,127 @@ static void Cmd_adjustdamage(void)
CMD_ARGS();
u8 holdEffect, param;
- u32 affectionScore = GetBattlerAffectionHearts(gBattlerTarget);
+ u32 battlerDef;
u32 rand = Random() % 100;
- u32 moveType = GetMoveType(gCurrentMove);
+ u32 affectionScore = GetBattlerAffectionHearts(gBattlerTarget);
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+ u32 moveEffect = GetMoveEffect(gCurrentMove);
+ bool32 calcSpreadMoveDamage = IsSpreadMove(moveTarget) && !IsBattleMoveStatus(gCurrentMove);
- if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
- goto END;
- if (DoesDisguiseBlockMove(gBattlerTarget, gCurrentMove))
+ for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
- gBattleStruct->enduredDamage |= 1u << gBattlerTarget;
- goto END;
- }
- if (GetBattlerAbility(gBattlerTarget) == ABILITY_ICE_FACE && IS_MOVE_PHYSICAL(gCurrentMove) && gBattleMons[gBattlerTarget].species == SPECIES_EISCUE)
- {
- // Damage deals typeless 0 HP.
- gMoveResultFlags &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE);
- gBattleMoveDamage = 0;
- RecordAbilityBattle(gBattlerTarget, ABILITY_ICE_FACE);
- gBattleResources->flags->flags[gBattlerTarget] |= RESOURCE_FLAG_ICE_FACE;
- // Form change will be done after attack animation in Cmd_resultmessage.
- goto END;
- }
- if (gBattleMons[gBattlerTarget].hp > gBattleMoveDamage)
- goto END;
+ if (gBattleStruct->calculatedDamageDone)
+ break;
- holdEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE);
- param = GetBattlerHoldEffectParam(gBattlerTarget);
+ if (!calcSpreadMoveDamage && battlerDef != gBattlerTarget)
+ continue;
- gPotentialItemEffectBattler = gBattlerTarget;
+ if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
+ || gBattleStruct->noResultString[battlerDef])
+ continue;
- if (holdEffect == HOLD_EFFECT_FOCUS_BAND && rand < param)
- {
- RecordItemEffectBattle(gBattlerTarget, holdEffect);
- gSpecialStatuses[gBattlerTarget].focusBanded = TRUE;
- }
- else if (B_STURDY >= GEN_5 && GetBattlerAbility(gBattlerTarget) == ABILITY_STURDY && BATTLER_MAX_HP(gBattlerTarget))
- {
- RecordAbilityBattle(gBattlerTarget, ABILITY_STURDY);
- gSpecialStatuses[gBattlerTarget].sturdied = TRUE;
- }
- else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && BATTLER_MAX_HP(gBattlerTarget))
- {
- RecordItemEffectBattle(gBattlerTarget, holdEffect);
- gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
- }
- else if (B_AFFECTION_MECHANICS == TRUE && GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER && affectionScore >= AFFECTION_THREE_HEARTS)
- {
- if ((affectionScore == AFFECTION_FIVE_HEARTS && rand < 20)
- || (affectionScore == AFFECTION_FOUR_HEARTS && rand < 15)
- || (affectionScore == AFFECTION_THREE_HEARTS && rand < 10))
- gSpecialStatuses[gBattlerTarget].affectionEndured = TRUE;
+ if (DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove))
+ goto END;
+
+ if (DoesDisguiseBlockMove(battlerDef, gCurrentMove))
+ {
+ gBattleStruct->enduredDamage |= 1u << battlerDef;
+ goto END;
+ }
+ if (GetBattlerAbility(battlerDef) == ABILITY_ICE_FACE && IsBattleMovePhysical(gCurrentMove) && gBattleMons[battlerDef].species == SPECIES_EISCUE)
+ {
+ // Damage deals typeless 0 HP.
+ gBattleStruct->moveResultFlags[battlerDef] &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE);
+ gBattleStruct->moveDamage[battlerDef] = 0;
+ RecordAbilityBattle(gBattlerTarget, ABILITY_ICE_FACE);
+ gBattleResources->flags->flags[battlerDef] |= RESOURCE_FLAG_ICE_FACE;
+ // Form change will be done after attack animation in Cmd_resultmessage.
+ goto END;
+ }
+ if (gBattleMons[gBattlerTarget].hp > gBattleStruct->moveDamage[battlerDef])
+ goto END;
+
+ holdEffect = GetBattlerHoldEffect(battlerDef, TRUE);
+ param = GetBattlerHoldEffectParam(battlerDef);
+
+ gPotentialItemEffectBattler = battlerDef;
+
+ if (holdEffect == HOLD_EFFECT_FOCUS_BAND && rand < param)
+ {
+ RecordItemEffectBattle(battlerDef, holdEffect);
+ gSpecialStatuses[battlerDef].focusBanded = TRUE;
+ }
+ else if (B_STURDY >= GEN_5 && GetBattlerAbility(battlerDef) == ABILITY_STURDY && IsBattlerAtMaxHp(battlerDef))
+ {
+ RecordAbilityBattle(battlerDef, ABILITY_STURDY);
+ gSpecialStatuses[battlerDef].sturdied = TRUE;
+ }
+ else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && IsBattlerAtMaxHp(battlerDef))
+ {
+ RecordItemEffectBattle(battlerDef, holdEffect);
+ gSpecialStatuses[battlerDef].focusSashed = TRUE;
+ }
+ else if (B_AFFECTION_MECHANICS == TRUE && GetBattlerSide(battlerDef) == B_SIDE_PLAYER && affectionScore >= AFFECTION_THREE_HEARTS)
+ {
+ if ((affectionScore == AFFECTION_FIVE_HEARTS && rand < 20)
+ || (affectionScore == AFFECTION_FOUR_HEARTS && rand < 15)
+ || (affectionScore == AFFECTION_THREE_HEARTS && rand < 10))
+ gSpecialStatuses[battlerDef].affectionEndured = TRUE;
+ }
+
+ if (moveEffect != EFFECT_FALSE_SWIPE
+ && !gProtectStructs[battlerDef].endured
+ && !gSpecialStatuses[battlerDef].focusBanded
+ && !gSpecialStatuses[battlerDef].focusSashed
+ && (B_AFFECTION_MECHANICS == FALSE || !gSpecialStatuses[battlerDef].affectionEndured)
+ && !gSpecialStatuses[battlerDef].sturdied)
+ goto END;
+
+ // Handle reducing the dmg to 1 hp.
+ gBattleStruct->moveDamage[battlerDef] = gBattleMons[battlerDef].hp - 1;
+ gBattleStruct->enduredDamage |= 1u << battlerDef;
+
+ if (gProtectStructs[battlerDef].endured)
+ {
+ gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_FOE_ENDURED;
+ }
+ else if (gSpecialStatuses[battlerDef].focusBanded || gSpecialStatuses[battlerDef].focusSashed)
+ {
+ gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_FOE_HUNG_ON;
+ gLastUsedItem = gBattleMons[battlerDef].item;
+ gSpecialStatuses[battlerDef].focusBanded = FALSE;
+ gSpecialStatuses[battlerDef].focusSashed = FALSE;
+ }
+ else if (gSpecialStatuses[battlerDef].sturdied)
+ {
+ gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_STURDIED;
+ gLastUsedAbility = ABILITY_STURDY;
+ }
+ else if (B_AFFECTION_MECHANICS == TRUE && gSpecialStatuses[battlerDef].affectionEndured)
+ {
+ gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_FOE_ENDURED_AFFECTION;
+ }
+
+ END:
+ if (!(gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT) && gBattleStruct->moveDamage[battlerDef] >= 1)
+ gSpecialStatuses[gBattlerAttacker].damagedMons |= 1u << battlerDef;
}
- if (gMovesInfo[gCurrentMove].effect != EFFECT_FALSE_SWIPE
- && !gProtectStructs[gBattlerTarget].endured
- && !gSpecialStatuses[gBattlerTarget].focusBanded
- && !gSpecialStatuses[gBattlerTarget].focusSashed
- && (B_AFFECTION_MECHANICS == FALSE || !gSpecialStatuses[gBattlerTarget].affectionEndured)
- && !gSpecialStatuses[gBattlerTarget].sturdied)
- goto END;
-
- // Handle reducing the dmg to 1 hp.
- gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
- gBattleStruct->enduredDamage |= 1u << gBattlerTarget;
-
- if (gProtectStructs[gBattlerTarget].endured)
- {
- gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
- }
- else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
- {
- gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
- gLastUsedItem = gBattleMons[gBattlerTarget].item;
- gSpecialStatuses[gBattlerTarget].focusBanded = FALSE;
- gSpecialStatuses[gBattlerTarget].focusSashed = FALSE;
-
- }
- else if (gSpecialStatuses[gBattlerTarget].sturdied)
- {
- gMoveResultFlags |= MOVE_RESULT_STURDIED;
- gLastUsedAbility = ABILITY_STURDY;
- }
- else if (B_AFFECTION_MECHANICS == TRUE && gSpecialStatuses[gBattlerTarget].affectionEndured)
- {
- gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED_AFFECTION;
- }
-
-END:
+ if (calcSpreadMoveDamage)
+ gBattleStruct->calculatedDamageDone = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMoveDamage >= 1)
- gSpecialStatuses[gBattlerAttacker].damagedMons |= (1 << (gBattlerTarget));
-
- // Check gems and damage reducing berries.
- if (gSpecialStatuses[gBattlerTarget].berryReduced
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gBattleMons[gBattlerTarget].item)
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_BerryReduceDmg;
- gLastUsedItem = gBattleMons[gBattlerTarget].item;
- }
if (gSpecialStatuses[gBattlerAttacker].gemBoost
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ && MoveResultHasEffect(gBattlerTarget)
+ && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gBattleMons[gBattlerAttacker].item
- && gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE
+ && moveEffect != EFFECT_PLEDGE
&& gCurrentMove != MOVE_STRUGGLE)
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_GemActivates;
gLastUsedItem = gBattleMons[gBattlerAttacker].item;
}
-
- // B_WEATHER_STRONG_WINDS prints a string when it's about to reduce the power
- // of a move that is Super Effective against a Flying-type Pokémon.
- if (gBattleWeather & B_WEATHER_STRONG_WINDS)
- {
- if ((GetBattlerType(gBattlerTarget, 0, FALSE) == TYPE_FLYING
- && GetTypeModifier(moveType, GetBattlerType(gBattlerTarget, 0, FALSE)) >= UQ_4_12(2.0))
- || (GetBattlerType(gBattlerTarget, 1, FALSE) == TYPE_FLYING
- && GetTypeModifier(moveType, GetBattlerType(gBattlerTarget, 1, FALSE)) >= UQ_4_12(2.0))
- || (GetBattlerType(gBattlerTarget, 2, FALSE) == TYPE_FLYING
- && GetTypeModifier(moveType, GetBattlerType(gBattlerTarget, 2, FALSE)) >= UQ_4_12(2.0)))
- {
- gBattlerAbility = gBattlerTarget;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_AttackWeakenedByStrongWinds;
- }
- }
}
static void Cmd_multihitresultmessage(void)
@@ -2296,21 +2234,22 @@ static void Cmd_multihitresultmessage(void)
if (gBattleControllerExecFlags)
return;
- if (!(gMoveResultFlags & MOVE_RESULT_FAILED) && !(gMoveResultFlags & MOVE_RESULT_FOE_ENDURED))
+ if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED)
+ && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FOE_ENDURED))
{
- if (gMoveResultFlags & MOVE_RESULT_STURDIED)
+ if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_STURDIED)
{
- gMoveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON);
+ gBattleStruct->moveResultFlags[gBattlerTarget] &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON);
gSpecialStatuses[gBattlerTarget].sturdied = FALSE; // Delete this line to make Sturdy last for the duration of the whole move turn.
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SturdiedMsg;
return;
}
- else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON)
+ else if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FOE_HUNG_ON)
{
gLastUsedItem = gBattleMons[gBattlerTarget].item;
gPotentialItemEffectBattler = gBattlerTarget;
- gMoveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON);
+ gBattleStruct->moveResultFlags[gBattlerTarget] &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_HUNG_ON);
gSpecialStatuses[gBattlerTarget].focusBanded = FALSE; // Delete this line to make Focus Band last for the duration of the whole move turn.
gSpecialStatuses[gBattlerTarget].focusSashed = FALSE; // Delete this line to make Focus Sash last for the duration of the whole move turn.
BattleScriptPushCursor();
@@ -2319,33 +2258,172 @@ static void Cmd_multihitresultmessage(void)
}
}
gBattlescriptCurrInstr = cmd->nextInstr;
+}
- // Print berry reducing message after result message.
- if (gSpecialStatuses[gBattlerTarget].berryReduced
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+static inline bool32 DoesBattlerNegateDamage(u32 battler)
+{
+ u32 species = gBattleMons[battler].species;
+ u32 ability = GetBattlerAbility(battler);
+
+ if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
+ return FALSE;
+ if (ability == ABILITY_DISGUISE && species == SPECIES_MIMIKYU)
+ return TRUE;
+ if (ability == ABILITY_ICE_FACE && species == SPECIES_EISCUE && GetBattleMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_PHYSICAL)
+ return TRUE;
+
+ return FALSE;
+}
+
+static u32 UpdateEffectivenessResultFlagsForDoubleSpreadMoves(u32 resultFlags)
+{
+ // Only play the "best" sound
+ for (u32 sound = 0; sound < 3; sound++)
{
- gBattleStruct->ateBerry[gBattlerTarget & BIT_SIDE] |= 1u << gBattlerPartyIndexes[gBattlerTarget];
- gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString;
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if ((gBattleStruct->moveResultFlags[battlerDef] & (MOVE_RESULT_MISSED | MOVE_RESULT_NO_EFFECT)
+ || gBattleStruct->noResultString[battlerDef]))
+ continue;
+
+ switch (sound)
+ {
+ case 0:
+ if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_SUPER_EFFECTIVE
+ && !DoesBattlerNegateDamage(battlerDef))
+ return gBattleStruct->moveResultFlags[battlerDef];
+ break;
+ case 1:
+ if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NOT_VERY_EFFECTIVE
+ && !DoesBattlerNegateDamage(battlerDef))
+ return gBattleStruct->moveResultFlags[battlerDef];
+ break;
+ case 2:
+ if (DoesBattlerNegateDamage(battlerDef))
+ return 0; //Normal effectiveness
+ return gBattleStruct->moveResultFlags[battlerDef];
+ }
+ }
}
+
+ return resultFlags;
+}
+
+static inline bool32 TryStrongWindsWeakenAttack(u32 battlerDef, u32 moveType)
+{
+ if (gBattleWeather & B_WEATHER_STRONG_WINDS && WEATHER_HAS_EFFECT)
+ {
+ if (GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS
+ && IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING)
+ && gTypeEffectivenessTable[moveType][TYPE_FLYING] >= UQ_4_12(2.0)
+ && !gBattleStruct->printedStrongWindsWeakenedAttack)
+ {
+ gBattleStruct->printedStrongWindsWeakenedAttack = TRUE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_AttackWeakenedByStrongWinds;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static inline bool32 TryTeraShellDistortTypeMatchups(u32 battlerDef)
+{
+ if (gSpecialStatuses[battlerDef].teraShellAbilityDone)
+ {
+ gSpecialStatuses[battlerDef].teraShellAbilityDone = FALSE;
+ gBattleScripting.battler = battlerDef;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_TeraShellDistortingTypeMatchups;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// According to Gen5 Weakness berry activation happens after the attackanimation.
+// It doesn't have any impact on gameplay and is only a visual thing which can be adjusted later.
+static inline bool32 TryActivateWeakenessBerry(u32 battlerDef)
+{
+ if (gSpecialStatuses[battlerDef].berryReduced && gBattleMons[battlerDef].item != ITEM_NONE)
+ {
+ gSpecialStatuses[battlerDef].berryReduced = FALSE;
+ gBattleScripting.battler = battlerDef;
+ gLastUsedItem = gBattleMons[battlerDef].item;
+ gBattleStruct->ateBerry[battlerDef & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battlerDef];
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_BerryReduceDmg;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static bool32 ProcessPreAttackAnimationFuncs(void)
+{
+ u32 moveType = GetBattleMoveType(gCurrentMove);
+ if (IsDoubleSpreadMove())
+ {
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+ if (!gBattleStruct->printedStrongWindsWeakenedAttack)
+ {
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
+ || (battlerDef == BATTLE_PARTNER(gBattlerAttacker) && !(moveTarget & MOVE_TARGET_FOES_AND_ALLY))
+ || (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK))
+ continue;
+
+ if (TryStrongWindsWeakenAttack(battlerDef, moveType))
+ return TRUE;
+ }
+ }
+
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if (IsBattlerInvalidForSpreadMove(gBattlerAttacker, battlerDef, moveTarget)
+ || (battlerDef == BATTLE_PARTNER(gBattlerAttacker) && !(moveTarget & MOVE_TARGET_FOES_AND_ALLY))
+ || (gBattleStruct->noResultString[battlerDef] && gBattleStruct->noResultString[battlerDef] != DO_ACCURACY_CHECK))
+ continue;
+
+ if (TryTeraShellDistortTypeMatchups(battlerDef))
+ return TRUE;
+ if (TryActivateWeakenessBerry(battlerDef))
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (TryStrongWindsWeakenAttack(gBattlerTarget, moveType))
+ return TRUE;
+ if (TryTeraShellDistortTypeMatchups(gBattlerTarget))
+ return TRUE;
+ if (TryActivateWeakenessBerry(gBattlerTarget))
+ return TRUE;
+ }
+
+ return FALSE;
}
static void Cmd_attackanimation(void)
{
CMD_ARGS();
- u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
-
- if (gBattleControllerExecFlags)
+ if (gBattleControllerExecFlags || ProcessPreAttackAnimationFuncs())
return;
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+ u32 moveResultFlags = gBattleStruct->moveResultFlags[gBattlerTarget];
+
+ if (IsDoubleSpreadMove())
+ moveResultFlags = UpdateEffectivenessResultFlagsForDoubleSpreadMoves(gBattleStruct->moveResultFlags[gBattlerTarget]);
+
if ((gHitMarker & (HITMARKER_NO_ANIMATIONS | HITMARKER_DISABLE_ANIMATION))
&& gCurrentMove != MOVE_TRANSFORM
&& gCurrentMove != MOVE_SUBSTITUTE
&& gCurrentMove != MOVE_ALLY_SWITCH
// In a wild double battle gotta use the teleport animation if two wild pokemon are alive.
- && !(gMovesInfo[gCurrentMove].effect == EFFECT_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))))
+ && !(GetMoveEffect(gCurrentMove) == EFFECT_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker))))
{
BattleScriptPush(cmd->nextInstr);
gBattlescriptCurrInstr = BattleScript_Pausex20;
@@ -2368,23 +2446,34 @@ static void Cmd_attackanimation(void)
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ if (!(moveResultFlags & MOVE_RESULT_NO_EFFECT))
{
- u8 multihit;
-
+ u32 multihit;
if (gBattleMons[gBattlerTarget].status2 & STATUS2_SUBSTITUTE)
+ {
multihit = gMultiHitCounter;
+ }
else if (gMultiHitCounter != 0 && gMultiHitCounter != 1)
{
- if (gBattleMons[gBattlerTarget].hp <= gBattleMoveDamage)
+ if (gBattleMons[gBattlerTarget].hp <= gBattleStruct->moveDamage[gBattlerTarget])
multihit = 1;
else
multihit = gMultiHitCounter;
}
else
+ {
multihit = gMultiHitCounter;
+ }
- BtlController_EmitMoveAnimation(gBattlerAttacker, BUFFER_A, gCurrentMove, gBattleScripting.animTurn, gBattleMovePower, gBattleMoveDamage, gBattleMons[gBattlerAttacker].friendship, &gDisableStructs[gBattlerAttacker], multihit);
+ BtlController_EmitMoveAnimation(gBattlerAttacker,
+ BUFFER_A,
+ gCurrentMove,
+ gBattleScripting.animTurn,
+ gBattleMovePower,
+ gBattleStruct->moveDamage[gBattlerTarget],
+ gBattleMons[gBattlerAttacker].friendship,
+ &gDisableStructs[gBattlerAttacker],
+ multihit);
gBattleScripting.animTurn++;
gBattleScripting.animTargetsHit++;
MarkBattlerForControllerExec(gBattlerAttacker);
@@ -2406,32 +2495,71 @@ static void Cmd_waitanimation(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
+static void DoublesHPBarReduction(void)
+{
+ if (gBattleStruct->doneDoublesSpreadHit
+ || gHitMarker & (HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE))
+ return;
+
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT
+ || gBattleStruct->moveDamage[battlerDef] == 0
+ || gBattleStruct->noResultString[battlerDef]
+ || DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove)
+ || DoesDisguiseBlockMove(battlerDef, gCurrentMove))
+ continue;
+
+ s32 currDmg = gBattleStruct->moveDamage[battlerDef];
+ s32 healthValue = min(currDmg, 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign
+ BtlController_EmitHealthBarUpdate(battlerDef, BUFFER_A, healthValue);
+ MarkBattlerForControllerExec(battlerDef);
+
+ if (GetBattlerSide(battlerDef) == B_SIDE_PLAYER && currDmg > 0)
+ gBattleResults.playerMonWasDamaged = TRUE;
+ }
+
+ gBattleStruct->doneDoublesSpreadHit = TRUE;
+}
+
static void Cmd_healthbarupdate(void)
{
CMD_ARGS(u8 battler);
+ u32 battler = GetBattlerForBattleScript(cmd->battler);
if (gBattleControllerExecFlags)
return;
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || (gHitMarker & HITMARKER_PASSIVE_DAMAGE))
+ if (MoveResultHasEffect(battler) || (gHitMarker & HITMARKER_PASSIVE_DAMAGE))
{
- u32 battler = GetBattlerForBattleScript(cmd->battler);
-
if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && gDisableStructs[battler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE))
{
PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, battler);
+ if (IsDoubleSpreadMove())
+ DoublesHPBarReduction();
}
else if (!DoesDisguiseBlockMove(battler, gCurrentMove))
{
- s16 healthValue = min(gBattleMoveDamage, 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign
+ if (IsDoubleSpreadMove())
+ {
+ DoublesHPBarReduction();
+ }
+ else
+ {
+ s16 healthValue = min(gBattleStruct->moveDamage[battler], 10000); // Max damage (10000) not present in R/S, ensures that huge damage values don't change sign
- BtlController_EmitHealthBarUpdate(battler, BUFFER_A, healthValue);
- MarkBattlerForControllerExec(battler);
+ BtlController_EmitHealthBarUpdate(battler, BUFFER_A, healthValue);
+ MarkBattlerForControllerExec(battler);
- if (GetBattlerSide(battler) == B_SIDE_PLAYER && gBattleMoveDamage > 0)
- gBattleResults.playerMonWasDamaged = TRUE;
+ if (GetBattlerSide(battler) == B_SIDE_PLAYER && gBattleStruct->moveDamage[battler] > 0)
+ gBattleResults.playerMonWasDamaged = TRUE;
+ }
}
}
+ else if (IsDoubleSpreadMove())
+ {
+ DoublesHPBarReduction();
+ }
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -2441,22 +2569,21 @@ static void Cmd_datahpupdate(void)
{
CMD_ARGS(u8 battler);
- u32 battler;
-
if (gBattleControllerExecFlags)
return;
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || (gHitMarker & HITMARKER_PASSIVE_DAMAGE))
+ u32 battler = GetBattlerForBattleScript(cmd->battler);
+
+ if (MoveResultHasEffect(battler) || (gHitMarker & HITMARKER_PASSIVE_DAMAGE))
{
- battler = GetBattlerForBattleScript(cmd->battler);
if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && gDisableStructs[battler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE))
{
- if (gDisableStructs[battler].substituteHP >= gBattleMoveDamage)
+ if (gDisableStructs[battler].substituteHP >= gBattleStruct->moveDamage[battler])
{
if (gSpecialStatuses[battler].shellBellDmg == 0)
- gSpecialStatuses[battler].shellBellDmg = gBattleMoveDamage;
- gDisableStructs[battler].substituteHP -= gBattleMoveDamage;
- gHpDealt = gBattleMoveDamage;
+ gSpecialStatuses[battler].shellBellDmg = gBattleStruct->moveDamage[battler];
+ gDisableStructs[battler].substituteHP -= gBattleStruct->moveDamage[battler];
+ gHpDealt = gBattleStruct->moveDamage[battler];
}
else
{
@@ -2486,7 +2613,7 @@ static void Cmd_datahpupdate(void)
else
gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED;
if (B_DISGUISE_HP_LOSS >= GEN_8)
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
BattleScriptPush(cmd->nextInstr);
gBattlescriptCurrInstr = BattleScript_TargetFormChange;
return;
@@ -2494,10 +2621,10 @@ static void Cmd_datahpupdate(void)
else
{
gHitMarker &= ~HITMARKER_IGNORE_SUBSTITUTE;
- if (gBattleMoveDamage < 0)
+ if (gBattleStruct->moveDamage[battler] < 0)
{
// Negative damage is HP gain
- gBattleMons[battler].hp += -gBattleMoveDamage;
+ gBattleMons[battler].hp += -gBattleStruct->moveDamage[battler];
if (gBattleMons[battler].hp > gBattleMons[battler].maxHP)
gBattleMons[battler].hp = gBattleMons[battler].maxHP;
}
@@ -2509,7 +2636,7 @@ static void Cmd_datahpupdate(void)
}
else
{
- gBideDmg[battler] += gBattleMoveDamage;
+ gBideDmg[battler] += gBattleStruct->moveDamage[battler];
if (cmd->battler == BS_TARGET)
gBideTarget[battler] = gBattlerAttacker;
else
@@ -2517,10 +2644,10 @@ static void Cmd_datahpupdate(void)
}
// Deal damage to the battler
- if (gBattleMons[battler].hp > gBattleMoveDamage)
+ if (gBattleMons[battler].hp > gBattleStruct->moveDamage[battler])
{
- gBattleMons[battler].hp -= gBattleMoveDamage;
- gHpDealt = gBattleMoveDamage;
+ gBattleMons[battler].hp -= gBattleStruct->moveDamage[battler];
+ gHpDealt = gBattleStruct->moveDamage[battler];
}
else
{
@@ -2532,10 +2659,12 @@ static void Cmd_datahpupdate(void)
if (gSpecialStatuses[battler].shellBellDmg == 0 && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE))
gSpecialStatuses[battler].shellBellDmg = gHpDealt;
+ u32 effect = GetMoveEffect(gCurrentMove);
+
// Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat, they are
// used in combination as general damage trackers for other purposes. specialDmg is additionally used
// to help determine if a fire move should defrost the target.
- if (IS_MOVE_PHYSICAL(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && gMovesInfo[gCurrentMove].effect != EFFECT_PAIN_SPLIT)
+ if (IsBattleMovePhysical(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && effect != EFFECT_PAIN_SPLIT)
{
gProtectStructs[battler].physicalDmg = gHpDealt;
gSpecialStatuses[battler].physicalDmg = gHpDealt;
@@ -2550,7 +2679,7 @@ static void Cmd_datahpupdate(void)
gSpecialStatuses[battler].physicalBattlerId = gBattlerTarget;
}
}
- else if (!IS_MOVE_PHYSICAL(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && gMovesInfo[gCurrentMove].effect != EFFECT_PAIN_SPLIT)
+ else if (!IsBattleMovePhysical(gCurrentMove) && !(gHitMarker & HITMARKER_PASSIVE_DAMAGE) && effect != EFFECT_PAIN_SPLIT)
{
// Record special damage/attacker for Mirror Coat
gProtectStructs[battler].specialDmg = gHpDealt;
@@ -2568,7 +2697,6 @@ static void Cmd_datahpupdate(void)
}
}
gHitMarker &= ~HITMARKER_PASSIVE_DAMAGE;
-
// Send updated HP
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HP_BATTLE, 0, sizeof(gBattleMons[battler].hp), &gBattleMons[battler].hp);
MarkBattlerForControllerExec(battler);
@@ -2590,7 +2718,7 @@ static void Cmd_critmessage(void)
if (gBattleControllerExecFlags == 0)
{
- if (gIsCriticalHit == TRUE && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ if (gSpecialStatuses[gBattlerTarget].criticalHit && MoveResultHasEffect(gBattlerTarget))
{
PrepareStringBattle(STRINGID_CRITICALHIT, gBattlerAttacker);
@@ -2611,9 +2739,25 @@ static void Cmd_effectivenesssound(void)
if (gBattleControllerExecFlags)
return;
- if (!(gMoveResultFlags & MOVE_RESULT_MISSED))
+ u32 moveResultFlags = gBattleStruct->moveResultFlags[gBattlerTarget];
+
+ if (IsDoubleSpreadMove())
{
- switch (gMoveResultFlags & ~MOVE_RESULT_MISSED)
+ if (gBattleStruct->doneDoublesSpreadHit
+ || !gBattleStruct->calculatedDamageDone //The attack animation didn't play yet - only play sound after animation
+ || GetBattleMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_STATUS) //To handle Dark Void missing basically
+ {
+ gBattlescriptCurrInstr = cmd->nextInstr;
+ return;
+ }
+ moveResultFlags = UpdateEffectivenessResultFlagsForDoubleSpreadMoves(gBattleStruct->moveResultFlags[gBattlerTarget]);
+ }
+ else if (MoveResultHasEffect(gBattlerTarget) && DoesBattlerNegateDamage(gBattlerTarget))
+ moveResultFlags = 0;
+
+ if (!(moveResultFlags & MOVE_RESULT_MISSED))
+ {
+ switch (moveResultFlags & ~MOVE_RESULT_MISSED)
{
case MOVE_RESULT_SUPER_EFFECTIVE:
BtlController_EmitPlaySE(gBattlerTarget, BUFFER_A, SE_SUPER_EFFECTIVE);
@@ -2632,17 +2776,17 @@ static void Cmd_effectivenesssound(void)
case MOVE_RESULT_FOE_HUNG_ON:
case MOVE_RESULT_STURDIED:
default:
- if (gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE)
+ if (moveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE)
{
BtlController_EmitPlaySE(gBattlerTarget, BUFFER_A, SE_SUPER_EFFECTIVE);
MarkBattlerForControllerExec(gBattlerTarget);
}
- else if (gMoveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE)
+ else if (moveResultFlags & MOVE_RESULT_NOT_VERY_EFFECTIVE)
{
BtlController_EmitPlaySE(gBattlerTarget, BUFFER_A, SE_NOT_EFFECTIVE);
MarkBattlerForControllerExec(gBattlerTarget);
}
- else if (!(gMoveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)))
+ else if (!(moveResultFlags & (MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)))
{
BtlController_EmitPlaySE(gBattlerTarget, BUFFER_A, SE_EFFECTIVE);
MarkBattlerForControllerExec(gBattlerTarget);
@@ -2653,11 +2797,27 @@ static void Cmd_effectivenesssound(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
+static inline bool32 ShouldPrintTwoFoesMessage(u32 moveResult)
+{
+ return gBattlerTarget == BATTLE_OPPOSITE(gBattlerAttacker)
+ && gBattleStruct->moveResultFlags[BATTLE_PARTNER(gBattlerTarget)] & moveResult
+ && !gBattleStruct->noResultString[BATTLE_PARTNER(gBattlerTarget)];
+}
+
+static inline bool32 ShouldRelyOnTwoFoesMessage(u32 moveResult)
+{
+ return gBattlerTarget == BATTLE_PARTNER(BATTLE_OPPOSITE(gBattlerAttacker))
+ && gBattleStruct->moveResultFlags[BATTLE_OPPOSITE(gBattlerAttacker)] & moveResult
+ && !(gBattleStruct->moveResultFlags[BATTLE_OPPOSITE(gBattlerAttacker)] & MOVE_RESULT_MISSED && gBattleStruct->missStringId[BATTLE_OPPOSITE(gBattlerAttacker)] > B_MSG_AVOIDED_ATK)
+ && !gBattleStruct->noResultString[BATTLE_OPPOSITE(gBattlerAttacker)];
+}
+
static void Cmd_resultmessage(void)
{
CMD_ARGS();
u32 stringId = 0;
+ u16 *moveResultFlags = &gBattleStruct->moveResultFlags[gBattlerTarget];
if (gBattleControllerExecFlags)
return;
@@ -2674,31 +2834,62 @@ static void Cmd_resultmessage(void)
return;
}
- if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK))
+ if (*moveResultFlags & MOVE_RESULT_MISSED
+ && (!(*moveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleStruct->missStringId[gBattlerTarget] > B_MSG_AVOIDED_ATK))
{
- if (gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK) // Wonder Guard or Levitate - show the ability pop-up
- CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, (IsDoubleBattle()) != 0);
- stringId = gMissStringIds[gBattleCommunication[MISS_TYPE]];
+ if (gMultiHitCounter && gMultiHitCounter < GetMoveStrikeCount(gCurrentMove))
+ {
+ gMultiHitCounter = 0;
+ *moveResultFlags &= ~MOVE_RESULT_MISSED;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings;
+ return;
+ }
+
+ if (gBattleStruct->missStringId[gBattlerTarget] > B_MSG_AVOIDED_ATK) // Wonder Guard or Levitate - show the ability pop-up
+ CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, IsDoubleBattle());
gBattleCommunication[MSG_DISPLAY] = 1;
+ stringId = gMissStringIds[gBattleStruct->missStringId[gBattlerTarget]];
}
else
{
gBattleCommunication[MSG_DISPLAY] = 1;
- switch (gMoveResultFlags & ~MOVE_RESULT_MISSED)
+ switch (*moveResultFlags & ~MOVE_RESULT_MISSED)
{
case MOVE_RESULT_SUPER_EFFECTIVE:
- if (!gMultiHitCounter) // Don't print effectiveness on each hit in a multi hit attack
+ if (IsDoubleSpreadMove())
+ {
+ if (ShouldPrintTwoFoesMessage(MOVE_RESULT_SUPER_EFFECTIVE))
+ stringId = STRINGID_SUPEREFFECTIVETWOFOES;
+ else if (ShouldRelyOnTwoFoesMessage(MOVE_RESULT_SUPER_EFFECTIVE))
+ stringId = 0; // Was handled or will be handled as a double string
+ else
+ stringId = STRINGID_SUPEREFFECTIVE;
+ }
+ else if (!gMultiHitCounter) // Don't print effectiveness on each hit in a multi hit attack
+ {
+ stringId = STRINGID_SUPEREFFECTIVE;
+ }
+ if (stringId) // Signal for the trainer slide-in system
{
- // Signal for the trainer slide-in system.
if (GetBattlerSide(gBattlerTarget) != B_SIDE_PLAYER && gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState != 2)
gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState = 1;
-
- stringId = STRINGID_SUPEREFFECTIVE;
}
break;
case MOVE_RESULT_NOT_VERY_EFFECTIVE:
- if (!gMultiHitCounter)
+ if (IsDoubleSpreadMove())
+ {
+ if (ShouldPrintTwoFoesMessage(MOVE_RESULT_NOT_VERY_EFFECTIVE))
+ stringId = STRINGID_NOTVERYEFFECTIVETWOFOES;
+ else if (ShouldRelyOnTwoFoesMessage(MOVE_RESULT_NOT_VERY_EFFECTIVE))
+ stringId = 0; // Was handled or will be handled as a double string
+ else
+ stringId = STRINGID_NOTVERYEFFECTIVE; // Needs a string
+ }
+ else if (!gMultiHitCounter)
+ {
stringId = STRINGID_NOTVERYEFFECTIVE;
+ }
break;
case MOVE_RESULT_ONE_HIT_KO:
stringId = STRINGID_ONEHITKO;
@@ -2710,86 +2901,85 @@ static void Cmd_resultmessage(void)
stringId = STRINGID_BUTITFAILED;
break;
case MOVE_RESULT_DOESNT_AFFECT_FOE:
- stringId = STRINGID_ITDOESNTAFFECT;
+ if (IsDoubleSpreadMove())
+ {
+ if (ShouldPrintTwoFoesMessage(MOVE_RESULT_DOESNT_AFFECT_FOE))
+ {
+ stringId = STRINGID_ITDOESNTAFFECTTWOFOES;
+ }
+ else if (ShouldRelyOnTwoFoesMessage(MOVE_RESULT_DOESNT_AFFECT_FOE))
+ {
+ stringId = 0; // Was handled or will be handled as a double string
+ }
+ else
+ stringId = STRINGID_ITDOESNTAFFECT;
+ }
+ else
+ {
+ stringId = STRINGID_ITDOESNTAFFECT;
+ }
break;
case MOVE_RESULT_FOE_HUNG_ON:
gLastUsedItem = gBattleMons[gBattlerTarget].item;
gPotentialItemEffectBattler = gBattlerTarget;
- gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
+ *moveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_HangedOnMsg;
return;
default:
- if (gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE)
+ if (*moveResultFlags & MOVE_RESULT_ONE_HIT_KO)
{
- stringId = STRINGID_ITDOESNTAFFECT;
- }
- else if (gMoveResultFlags & MOVE_RESULT_ONE_HIT_KO)
- {
- gMoveResultFlags &= ~MOVE_RESULT_ONE_HIT_KO;
- gMoveResultFlags &= ~MOVE_RESULT_SUPER_EFFECTIVE;
- gMoveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE;
+ *moveResultFlags &= ~MOVE_RESULT_ONE_HIT_KO;
+ *moveResultFlags &= ~MOVE_RESULT_SUPER_EFFECTIVE;
+ *moveResultFlags &= ~MOVE_RESULT_NOT_VERY_EFFECTIVE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_OneHitKOMsg;
return;
}
- else if (gMoveResultFlags & MOVE_RESULT_STURDIED)
+ else if (*moveResultFlags & MOVE_RESULT_STURDIED)
{
- gMoveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
+ *moveResultFlags &= ~(MOVE_RESULT_STURDIED | MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
gSpecialStatuses[gBattlerTarget].sturdied = FALSE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SturdiedMsg;
return;
}
- else if (gMoveResultFlags & MOVE_RESULT_FOE_ENDURED)
+ else if (*moveResultFlags & MOVE_RESULT_FOE_ENDURED)
{
- gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
+ *moveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EnduredMsg;
return;
}
- else if (gMoveResultFlags & MOVE_RESULT_FOE_HUNG_ON)
+ else if (*moveResultFlags & MOVE_RESULT_FOE_HUNG_ON)
{
gLastUsedItem = gBattleMons[gBattlerTarget].item;
gPotentialItemEffectBattler = gBattlerTarget;
- gMoveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
+ *moveResultFlags &= ~(MOVE_RESULT_FOE_ENDURED | MOVE_RESULT_FOE_HUNG_ON);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_HangedOnMsg;
return;
}
- else if (gMoveResultFlags & MOVE_RESULT_FAILED)
+ else if (*moveResultFlags & MOVE_RESULT_FAILED)
{
stringId = STRINGID_BUTITFAILED;
}
- else if (B_AFFECTION_MECHANICS == TRUE && (gMoveResultFlags & MOVE_RESULT_FOE_ENDURED_AFFECTION))
+ else if (B_AFFECTION_MECHANICS == TRUE && (*moveResultFlags & MOVE_RESULT_FOE_ENDURED_AFFECTION))
{
gSpecialStatuses[gBattlerTarget].affectionEndured = FALSE;
- gMoveResultFlags &= ~MOVE_RESULT_FOE_ENDURED_AFFECTION;
+ *moveResultFlags &= ~MOVE_RESULT_FOE_ENDURED_AFFECTION;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AffectionBasedEndurance;
return;
}
- else
- {
- gBattleCommunication[MSG_DISPLAY] = 0;
- }
}
}
-
if (stringId)
PrepareStringBattle(stringId, gBattlerAttacker);
+ else
+ gBattleCommunication[MSG_DISPLAY] = 0;
gBattlescriptCurrInstr = cmd->nextInstr;
-
- // Print berry reducing message after result message.
- if (gSpecialStatuses[gBattlerTarget].berryReduced
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
- {
- gBattleStruct->ateBerry[gBattlerTarget & BIT_SIDE] |= 1u << gBattlerPartyIndexes[gBattlerTarget];
- gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString;
- }
}
static void Cmd_printstring(void)
@@ -2830,6 +3020,8 @@ static void Cmd_waitmessage(void)
else
{
u16 toWait = cmd->time;
+ if (gTestRunnerHeadless)
+ gPauseCounterBattle = toWait;
if (++gPauseCounterBattle >= toWait)
{
gPauseCounterBattle = 0;
@@ -2896,17 +3088,26 @@ static void CheckSetUnburden(u8 battler)
void StealTargetItem(u8 battlerStealer, u8 battlerItem)
{
gLastUsedItem = gBattleMons[battlerItem].item;
- gBattleMons[battlerItem].item = 0;
+ gBattleMons[battlerItem].item = ITEM_NONE;
- RecordItemEffectBattle(battlerItem, 0);
- RecordItemEffectBattle(battlerStealer, ItemId_GetHoldEffect(gLastUsedItem));
- gBattleMons[battlerStealer].item = gLastUsedItem;
+ if (B_STEAL_WILD_ITEMS >= GEN_9
+ && !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))
+ && MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_STEAL_ITEM)
+ && battlerStealer == gBattlerAttacker) // ensure that Pickpocket isn't activating this
+ {
+ AddBagItem(gLastUsedItem, 1);
+ }
+ else
+ {
+ RecordItemEffectBattle(battlerStealer, ItemId_GetHoldEffect(gLastUsedItem));
+ gBattleMons[battlerStealer].item = gLastUsedItem;
+ gBattleResources->flags->flags[battlerStealer] &= ~RESOURCE_FLAG_UNBURDEN;
+ BtlController_EmitSetMonData(battlerStealer, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gLastUsedItem), &gLastUsedItem); // set attacker item
+ MarkBattlerForControllerExec(battlerStealer);
+ }
+ RecordItemEffectBattle(battlerItem, ITEM_NONE);
CheckSetUnburden(battlerItem);
- gBattleResources->flags->flags[battlerStealer] &= ~RESOURCE_FLAG_UNBURDEN;
-
- BtlController_EmitSetMonData(battlerStealer, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gLastUsedItem), &gLastUsedItem); // set attacker item
- MarkBattlerForControllerExec(battlerStealer);
BtlController_EmitSetMonData(battlerItem, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].item), &gBattleMons[battlerItem].item); // remove target item
MarkBattlerForControllerExec(battlerItem);
@@ -2935,7 +3136,8 @@ void SetMoveEffect(bool32 primary, bool32 certain)
bool32 statusChanged = FALSE;
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
u32 flags = 0;
- u16 battlerAbility;
+ u32 battlerAbility;
+ u32 side;
bool8 activateAfterFaint = FALSE;
// NULL move effect
@@ -2987,15 +3189,9 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gBattleScripting.moveEffect &= ~MOVE_EFFECT_CERTAIN;
if (!primary && affectsUser != MOVE_EFFECT_AFFECTS_USER
- && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
- && (battlerAbility == ABILITY_SHIELD_DUST || GetBattlerHoldEffect(gEffectBattler, TRUE) == HOLD_EFFECT_COVERT_CLOAK))
- {
- if (battlerAbility == ABILITY_SHIELD_DUST)
- RecordAbilityBattle(gEffectBattler, battlerAbility);
- else
- RecordItemEffectBattle(gEffectBattler, HOLD_EFFECT_COVERT_CLOAK);
+ && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
+ && IsMoveEffectBlockedByTarget(battlerAbility))
INCREMENT_RESET_RETURN
- }
if (gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_SAFEGUARD && !(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
&& !primary && gBattleScripting.moveEffect <= MOVE_EFFECT_CONFUSION)
@@ -3003,7 +3199,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
if (!(gHitMarker & HITMARKER_STATUS_ABILITY_EFFECT)
&& TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
- && !(gMovesInfo[gCurrentMove].effect == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker])
+ && !(GetMoveEffect(gCurrentMove) == EFFECT_ORDER_UP && gBattleStruct->commanderActive[gBattlerAttacker])
&& !primary
&& gBattleScripting.moveEffect != MOVE_EFFECT_CHARGING)
INCREMENT_RESET_RETURN
@@ -3033,7 +3229,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
if (i != gBattlersCount)
break;
- if (!CanBeSlept(gEffectBattler, GetBattlerAbility(gEffectBattler)))
+ if (!CanBeSlept(gEffectBattler, GetBattlerAbility(gEffectBattler), BLOCKED_BY_SLEEP_CLAUSE) && !(gBattleStruct->sleepClauseEffectExempt & (1u << gEffectBattler)))
break;
cancelMultiTurnMovesResult = CancelMultiTurnMoves(gEffectBattler);
@@ -3110,7 +3306,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
{
- u32 moveType = GetMoveType(gCurrentMove);
+ u32 moveType = GetBattleMoveType(gCurrentMove);
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
break;
}
@@ -3123,7 +3319,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
case STATUS1_FREEZE:
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
{
- u32 moveType = GetMoveType(gCurrentMove);
+ u32 moveType = GetBattleMoveType(gCurrentMove);
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
break;
}
@@ -3158,11 +3354,13 @@ void SetMoveEffect(bool32 primary, bool32 certain)
RESET_RETURN
}
else
+ {
break;
+ }
}
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
{
- u32 moveType = GetMoveType(gCurrentMove);
+ u32 moveType = GetBattleMoveType(gCurrentMove);
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
break;
}
@@ -3226,13 +3424,13 @@ void SetMoveEffect(bool32 primary, bool32 certain)
}
else
{
- gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_DOESNT_AFFECT_FOE;
}
break;
case STATUS1_FROSTBITE:
if (B_STATUS_TYPE_IMMUNITY == GEN_1)
{
- u32 moveType = GetMoveType(gCurrentMove);
+ u32 moveType = GetBattleMoveType(gCurrentMove);
if (primary == FALSE && certain == FALSE && IS_BATTLER_OF_TYPE(gEffectBattler, moveType))
break;
}
@@ -3252,6 +3450,8 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 1, 3));
else
gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN(1 + RandomUniform(RNG_SLEEP_TURNS, 2, 5));
+
+ TryActivateSleepClause(gEffectBattler, gBattlerPartyIndexes[gEffectBattler]);
}
else
{
@@ -3385,8 +3585,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
// For a move that hits multiple targets (i.e. Make it Rain)
// we only want to print the message on the final hit
- if (!((moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY)
- && GetNextTarget(moveTarget, TRUE) != MAX_BATTLERS_COUNT))
+ if (!(IsSpreadMove(moveTarget) && GetNextTarget(moveTarget, TRUE) != MAX_BATTLERS_COUNT))
{
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectPayDay;
@@ -3588,8 +3787,13 @@ void SetMoveEffect(bool32 primary, bool32 certain)
else
{
StealTargetItem(gBattlerAttacker, gBattlerTarget); // Attacker steals target item
- gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
- gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
+
+ if (!(B_STEAL_WILD_ITEMS >= GEN_9
+ && !(gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE))))
+ {
+ gBattleMons[gBattlerAttacker].item = ITEM_NONE; // Item assigned later on with thief (see MOVEEND_CHANGED_ITEMS)
+ gBattleStruct->changedItems[gBattlerAttacker] = gLastUsedItem; // Stolen item to be assigned later
+ }
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_ItemSteal;
}
@@ -3630,11 +3834,11 @@ void SetMoveEffect(bool32 primary, bool32 certain)
}
break;
case MOVE_EFFECT_RECOIL_HP_25: // Struggle
- gBattleMoveDamage = (gBattleMons[gEffectBattler].maxHP) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gEffectBattler] = (gBattleMons[gEffectBattler].maxHP) / 4;
+ if (gBattleStruct->moveDamage[gEffectBattler] == 0)
+ gBattleStruct->moveDamage[gEffectBattler] = 1;
if (GetBattlerAbility(gEffectBattler) == ABILITY_PARENTAL_BOND)
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[gEffectBattler] *= 2;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
@@ -3668,13 +3872,14 @@ void SetMoveEffect(bool32 primary, bool32 certain)
break;
case MOVE_EFFECT_FLAME_BURST:
if (IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget))
- && !(gStatuses3[BATTLE_PARTNER(gBattlerTarget)] & STATUS3_SEMI_INVULNERABLE)
- && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD)
+ && !(gStatuses3[BATTLE_PARTNER(gBattlerTarget)] & STATUS3_SEMI_INVULNERABLE)
+ && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD)
{
- gBattleScripting.savedBattler = BATTLE_PARTNER(gBattlerTarget);
- gBattleMoveDamage = gBattleMons[BATTLE_PARTNER(gBattlerTarget)].maxHP / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ i = BATTLE_PARTNER(gBattlerTarget);
+ gBattleScripting.savedBattler = i;
+ gBattleStruct->moveDamage[i] = gBattleMons[i].maxHP / 16;
+ if (gBattleStruct->moveDamage[i] == 0)
+ gBattleStruct->moveDamage[i] = 1;
gBattlescriptCurrInstr = BattleScript_MoveEffectFlameBurst;
}
break;
@@ -3809,9 +4014,11 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gBattleMons[gBattlerAttacker].status2 |= STATUS2_ESCAPE_PREVENTION;
break;
case MOVE_EFFECT_REMOVE_ARG_TYPE:
+ {
+ u32 type = GetMoveArgType(gCurrentMove);
// This seems unnecessary but is done to make it work properly with Parental Bond
BattleScriptPush(gBattlescriptCurrInstr + 1);
- switch (gMovesInfo[gCurrentMove].argument)
+ switch (type)
{
case TYPE_FIRE: // Burn Up
gBattlescriptCurrInstr = BattleScript_RemoveFireType;
@@ -3823,8 +4030,9 @@ void SetMoveEffect(bool32 primary, bool32 certain)
gBattlescriptCurrInstr = BattleScript_RemoveGenericType;
break;
}
- RemoveBattlerType(gEffectBattler, gMovesInfo[gCurrentMove].argument);
+ RemoveBattlerType(gEffectBattler, type);
break;
+ }
case MOVE_EFFECT_ROUND:
TryUpdateRoundTurnOrder(); // If another Pokémon uses Round before the user this turn, the user will use Round directly after it
gBattlescriptCurrInstr++;
@@ -4016,6 +4224,117 @@ void SetMoveEffect(bool32 primary, bool32 certain)
}
}
break;
+ case MOVE_EFFECT_ION_DELUGE:
+ if (!(gFieldStatuses & STATUS_FIELD_ION_DELUGE))
+ {
+ gFieldStatuses |= STATUS_FIELD_ION_DELUGE;
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectIonDeluge;
+ }
+ break;
+ // TODO: The moves aromatherapy and heal bell need a refactor first
+ // case MOVE_EFFECT_AROMATHERAPY:
+ // break;
+ case MOVE_EFFECT_HAZE:
+ for (i = 0; i < gBattlersCount; i++)
+ TryResetBattlerStatChanges(i);
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectHaze;
+ break;
+ case MOVE_EFFECT_LEECH_SEED:
+ if (!IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) && !(gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED))
+ {
+ gStatuses3[gBattlerTarget] |= gBattlerAttacker;
+ gStatuses3[gBattlerTarget] |= STATUS3_LEECHSEED;
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectLeechSeed;
+ }
+ break;
+ case MOVE_EFFECT_REFLECT:
+ side = GetBattlerSide(gBattlerAttacker);
+ if (!(gSideStatuses[side] & SIDE_STATUS_REFLECT))
+ {
+ gSideStatuses[side] |= SIDE_STATUS_REFLECT;
+ if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
+ gSideTimers[side].reflectTimer = 8;
+ else
+ gSideTimers[side].reflectTimer = 5;
+ gSideTimers[side].reflectBattlerId = gBattlerAttacker;
+
+ if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE;
+ else
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE;
+
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectReflect;
+ }
+ break;
+ case MOVE_EFFECT_LIGHT_SCREEN:
+ side = GetBattlerSide(gBattlerAttacker);
+ if (!(gSideStatuses[side] & SIDE_STATUS_LIGHTSCREEN))
+ {
+ gSideStatuses[side] |= SIDE_STATUS_LIGHTSCREEN;
+ if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LIGHT_CLAY)
+ gSideTimers[side].lightscreenTimer = 8;
+ else
+ gSideTimers[side].lightscreenTimer = 5;
+ gSideTimers[side].lightscreenBattlerId = gBattlerAttacker;
+
+ if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2)
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE;
+ else
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE;
+
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectLightScreen;
+ }
+ break;
+ case MOVE_EFFECT_SALT_CURE:
+ if (!(gStatuses4[gBattlerTarget] & STATUS4_SALT_CURE))
+ {
+ gStatuses4[gBattlerTarget] |= STATUS4_SALT_CURE;
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectSaltCure;
+ }
+ break;
+ case MOVE_EFFECT_EERIE_SPELL:
+ if (gLastMoves[gBattlerTarget] != MOVE_NONE && gLastMoves[gBattlerTarget] != 0xFFFF)
+ {
+ u32 i;
+
+ for (i = 0; i < MAX_MON_MOVES; i++)
+ {
+ if (gLastMoves[gBattlerTarget] == gBattleMons[gBattlerTarget].moves[i])
+ break;
+ }
+
+ if (i != MAX_MON_MOVES && gBattleMons[gBattlerTarget].pp[i] != 0)
+ {
+ u32 ppToDeduct = 3;
+
+ if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct)
+ ppToDeduct = gBattleMons[gBattlerTarget].pp[i];
+
+ PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget])
+ ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1);
+ PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
+ gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct;
+ if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i))
+ && !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED))
+ {
+ BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]);
+ MarkBattlerForControllerExec(gBattlerTarget);
+ }
+
+ if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)
+ CancelMultiTurnMoves(gBattlerTarget);
+
+ BattleScriptPush(gBattlescriptCurrInstr + 1);
+ gBattlescriptCurrInstr = BattleScript_MoveEffectEerieSpell;
+ }
+ }
+ break;
}
}
}
@@ -4025,11 +4344,12 @@ void SetMoveEffect(bool32 primary, bool32 certain)
static bool32 CanApplyAdditionalEffect(const struct AdditionalEffect *additionalEffect)
{
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+
// Self-targeting move effects only apply after the last mon has been hit
- u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
if (additionalEffect->self
- && (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY)
- && GetNextTarget(moveTarget, TRUE) != MAX_BATTLERS_COUNT)
+ && IsSpreadMove(moveTarget)
+ && GetNextTarget(moveTarget, TRUE) != MAX_BATTLERS_COUNT)
return FALSE;
// Certain move effects only apply if the target raised stats this turn (e.g. Burning Jealousy)
@@ -4047,12 +4367,13 @@ static void Cmd_setadditionaleffects(void)
{
CMD_ARGS();
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ if (MoveResultHasEffect(gBattlerTarget))
{
- if (gMovesInfo[gCurrentMove].numAdditionalEffects > gBattleStruct->additionalEffectsCounter)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(gCurrentMove);
+ if (numAdditionalEffects > gBattleStruct->additionalEffectsCounter)
{
u32 percentChance;
- const struct AdditionalEffect *additionalEffect = &gMovesInfo[gCurrentMove].additionalEffects[gBattleStruct->additionalEffectsCounter];
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(gCurrentMove, gBattleStruct->additionalEffectsCounter);
const u8 *currentPtr = gBattlescriptCurrInstr;
// Various checks for if this move effect can be applied this turn
@@ -4078,7 +4399,7 @@ static void Cmd_setadditionaleffects(void)
// Call setadditionaleffects again in the case of a move with multiple effects
gBattleStruct->additionalEffectsCounter++;
- if (gMovesInfo[gCurrentMove].numAdditionalEffects > gBattleStruct->additionalEffectsCounter)
+ if (numAdditionalEffects > gBattleStruct->additionalEffectsCounter)
gBattleScripting.moveEffect = MOVE_EFFECT_CONTINUE;
else
gBattleScripting.moveEffect = gBattleStruct->additionalEffectsCounter = 0;
@@ -4153,6 +4474,15 @@ static void Cmd_tryfaintmon(void)
}
else
{
+ if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS
+ && !(gAbsentBattlerFlags & (1u << battler))
+ && !IsBattlerAlive(battler))
+ {
+ gBattleMons[battler].ability = ABILITY_NONE;
+ BattleScriptPush(gBattlescriptCurrInstr);
+ gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
+ return;
+ }
if (cmd->battler == BS_ATTACKER)
{
destinyBondBattler = gBattlerTarget;
@@ -4189,7 +4519,7 @@ static void Cmd_tryfaintmon(void)
{
gHitMarker &= ~HITMARKER_DESTINYBOND;
BattleScriptPush(gBattlescriptCurrInstr);
- gBattleMoveDamage = gBattleMons[destinyBondBattler].hp;
+ gBattleStruct->moveDamage[destinyBondBattler] = gBattleMons[destinyBondBattler].hp;
gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife;
}
if ((gStatuses3[gBattlerTarget] & STATUS3_GRUDGE)
@@ -4208,6 +4538,8 @@ static void Cmd_tryfaintmon(void)
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex])
}
+
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
}
else
{
@@ -4555,13 +4887,13 @@ static void Cmd_getexp(void)
|| GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPECIES_OR_EGG) == SPECIES_EGG)
{
gBattleScripting.getexpState = 5;
- gBattleMoveDamage = 0; // used for exp
+ gBattleStruct->battlerExpReward = 0;
}
else if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && *expMonId >= 3)
|| GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL) == MAX_LEVEL)
{
gBattleScripting.getexpState = 5;
- gBattleMoveDamage = 0; // used for exp
+ gBattleStruct->battlerExpReward = 0;
if (B_MAX_LEVEL_EV_GAINS >= GEN_5)
MonGainEVs(&gPlayerParty[*expMonId], gBattleMons[gBattlerFainted].species);
}
@@ -4582,28 +4914,28 @@ static void Cmd_getexp(void)
if (IsValidForBattle(&gPlayerParty[*expMonId]))
{
if (wasSentOut)
- gBattleMoveDamage = GetSoftLevelCapExpValue(gPlayerParty[*expMonId].level, gBattleStruct->expValue);
+ gBattleStruct->battlerExpReward = GetSoftLevelCapExpValue(gPlayerParty[*expMonId].level, gBattleStruct->expValue);
else
- gBattleMoveDamage = 0;
+ gBattleStruct->battlerExpReward = 0;
if ((holdEffect == HOLD_EFFECT_EXP_SHARE || IsGen6ExpShareEnabled())
- && (B_SPLIT_EXP < GEN_6 || gBattleMoveDamage == 0)) // only give exp share bonus in later gens if the mon wasn't sent out
+ && (B_SPLIT_EXP < GEN_6 || gBattleStruct->battlerExpReward == 0)) // only give exp share bonus in later gens if the mon wasn't sent out
{
- gBattleMoveDamage += GetSoftLevelCapExpValue(gPlayerParty[*expMonId].level, gBattleStruct->expShareExpValue);;
+ gBattleStruct->battlerExpReward += GetSoftLevelCapExpValue(gPlayerParty[*expMonId].level, gBattleStruct->expShareExpValue);;
}
- ApplyExperienceMultipliers(&gBattleMoveDamage, *expMonId, gBattlerFainted);
+ ApplyExperienceMultipliers(&gBattleStruct->battlerExpReward, *expMonId, gBattlerFainted);
- if (B_EXP_CAP_TYPE == EXP_CAP_HARD && gBattleMoveDamage != 0)
+ if (B_EXP_CAP_TYPE == EXP_CAP_HARD && gBattleStruct->battlerExpReward != 0)
{
u32 growthRate = gSpeciesInfo[GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPECIES)].growthRate;
u32 currentExp = GetMonData(&gPlayerParty[*expMonId], MON_DATA_EXP);
u32 levelCap = GetCurrentLevelCap();
if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL) >= levelCap)
- gBattleMoveDamage = 0;
- else if (gExperienceTables[growthRate][levelCap] < currentExp + gBattleMoveDamage)
- gBattleMoveDamage = gExperienceTables[growthRate][levelCap] - currentExp;
+ gBattleStruct->battlerExpReward = 0;
+ else if (gExperienceTables[growthRate][levelCap] < currentExp + gBattleStruct->battlerExpReward)
+ gBattleStruct->battlerExpReward = gExperienceTables[growthRate][levelCap] - currentExp;
}
if (IsTradedMon(&gPlayerParty[*expMonId]))
@@ -4624,13 +4956,10 @@ static void Cmd_getexp(void)
{
if (gBattlerPartyIndexes[2] == *expMonId && !(gAbsentBattlerFlags & 4))
gBattleStruct->expGetterBattlerId = 2;
+ else if (!(gAbsentBattlerFlags & 1))
+ gBattleStruct->expGetterBattlerId = 0;
else
- {
- if (!(gAbsentBattlerFlags & 1))
- gBattleStruct->expGetterBattlerId = 0;
- else
- gBattleStruct->expGetterBattlerId = 2;
- }
+ gBattleStruct->expGetterBattlerId = 2;
}
else
{
@@ -4640,7 +4969,7 @@ static void Cmd_getexp(void)
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattleStruct->expGetterBattlerId, *expMonId);
// buffer 'gained' or 'gained a boosted'
PREPARE_STRING_BUFFER(gBattleTextBuff2, i);
- PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 6, gBattleMoveDamage);
+ PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 6, gBattleStruct->battlerExpReward);
if (wasSentOut || holdEffect == HOLD_EFFECT_EXP_SHARE)
{
@@ -4672,7 +5001,7 @@ static void Cmd_getexp(void)
gBattleResources->beforeLvlUp->stats[STAT_SPATK] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPATK);
gBattleResources->beforeLvlUp->stats[STAT_SPDEF] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPDEF);
- BtlController_EmitExpUpdate(gBattleStruct->expGetterBattlerId, BUFFER_A, *expMonId, gBattleMoveDamage);
+ BtlController_EmitExpUpdate(gBattleStruct->expGetterBattlerId, BUFFER_A, *expMonId, gBattleStruct->battlerExpReward);
MarkBattlerForControllerExec(gBattleStruct->expGetterBattlerId);
}
gBattleScripting.getexpState++;
@@ -4694,7 +5023,7 @@ static void Cmd_getexp(void)
BattleScriptPushCursor();
gLeveledUpInBattle |= 1 << *expMonId;
gBattlescriptCurrInstr = BattleScript_LevelUp;
- gBattleMoveDamage = T1_READ_32(&gBattleResources->bufferB[expBattler][2]);
+ gBattleStruct->battlerExpReward = T1_READ_32(&gBattleResources->bufferB[expBattler][2]);
AdjustFriendship(&gPlayerParty[*expMonId], FRIENDSHIP_EVENT_GROW_LEVEL);
// update battle mon structure after level up
@@ -4714,13 +5043,13 @@ static void Cmd_getexp(void)
}
else
{
- gBattleMoveDamage = 0;
+ gBattleStruct->battlerExpReward = 0;
gBattleScripting.getexpState = 5;
}
}
break;
case 5: // looper increment
- if (gBattleMoveDamage) // there is exp to give, goto case 3 that gives exp
+ if (gBattleStruct->battlerExpReward) // there is exp to give, goto case 3 that gives exp
{
gBattleScripting.getexpState = 3;
}
@@ -4858,8 +5187,6 @@ static void Cmd_checkteamslost(void)
static void MoveValuesCleanUp(void)
{
- gMoveResultFlags = 0;
- gIsCriticalHit = FALSE;
gBattleScripting.moveEffect = 0;
gBattleCommunication[MISS_TYPE] = 0;
if (!gMultiHitCounter)
@@ -5196,6 +5523,8 @@ static void Cmd_pause(void)
if (gBattleControllerExecFlags == 0)
{
u16 value = cmd->frames;
+ if (gTestRunnerHeadless)
+ gPauseCounterBattle = value;
if (++gPauseCounterBattle >= value)
{
gPauseCounterBattle = 0;
@@ -5212,18 +5541,20 @@ static void Cmd_waitstate(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
-static void Cmd_healthbar_update(void)
+static void Cmd_absorb(void)
{
CMD_ARGS(u8 battler);
- u32 battler;
- if (cmd->battler == BS_TARGET)
- battler = gBattlerTarget;
- else
- battler = gBattlerAttacker;
+ if (gBattleControllerExecFlags)
+ return;
- BtlController_EmitHealthBarUpdate(battler, BUFFER_A, gBattleMoveDamage);
+ u32 battler = GetBattlerForBattleScript(cmd->battler);
+ BtlController_EmitHealthBarUpdate(battler, BUFFER_A, gBattleStruct->moveDamage[battler]);
MarkBattlerForControllerExec(battler);
+
+ if (GetBattlerSide(battler) == B_SIDE_PLAYER && gBattleStruct->moveDamage[battler] > 0)
+ gBattleResults.playerMonWasDamaged = TRUE;
+
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -5239,7 +5570,6 @@ static void Cmd_end(void)
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
BattleArena_AddSkillPoints(gBattlerAttacker);
- gMoveResultFlags = 0;
gCurrentActionFuncId = B_ACTION_TRY_FINISH;
}
@@ -5612,7 +5942,9 @@ static void Cmd_moveend(void)
endState = cmd->endState;
holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
- moveType = GetMoveType(gCurrentMove);
+ moveType = GetBattleMoveType(gCurrentMove);
+
+ u32 moveEffect = GetMoveEffect(gCurrentMove);
do
{
@@ -5626,13 +5958,13 @@ static void Cmd_moveend(void)
if (gProtectStructs[gBattlerAttacker].touchedProtectLike)
{
if (gProtectStructs[gBattlerTarget].spikyShielded
- && gMovesInfo[gCurrentMove].effect != EFFECT_COUNTER
+ && moveEffect != EFFECT_COUNTER
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SPIKY_SHIELD);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_SpikyShieldEffect;
@@ -5661,7 +5993,8 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_BanefulBunkerEffect;
effect = 1;
}
- else if (gProtectStructs[gBattlerTarget].obstructed && gMovesInfo[gCurrentMove].effect != EFFECT_SUCKER_PUNCH && gMovesInfo[gCurrentMove].effect != EFFECT_UPPER_HAND)
+ else if (gProtectStructs[gBattlerTarget].obstructed
+ && moveEffect != EFFECT_SUCKER_PUNCH && moveEffect != EFFECT_UPPER_HAND)
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
i = gBattlerAttacker;
@@ -5695,7 +6028,7 @@ static void Cmd_moveend(void)
// Not strictly a protect effect, but works the same way
else if (gProtectStructs[gBattlerTarget].beakBlastCharge
&& CanBeBurned(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ && MoveResultHasEffect(gBattlerTarget))
{
gProtectStructs[gBattlerAttacker].touchedProtectLike = FALSE;
gBattleMons[gBattlerAttacker].status1 = STATUS1_BURN;
@@ -5708,14 +6041,48 @@ static void Cmd_moveend(void)
}
gBattleScripting.moveendState++;
break;
+ case MOVEEND_ABSORB:
+ if (moveEffect == EFFECT_ABSORB
+ && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
+ && IsBattlerTurnDamaged(gBattlerTarget))
+ {
+ if (gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealingMove(gCurrentMove))
+ {
+ gBattleScripting.moveendState++;
+ break;
+ }
+ else if (IsBattlerAlive(gBattlerAttacker) && MoveResultHasEffect(gBattlerTarget))
+ {
+ gBattleStruct->moveDamage[gBattlerAttacker] = max(1, (gBattleStruct->moveDamage[gBattlerTarget] * GetMoveAbsorbPercentage(gCurrentMove) / 100));
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]);
+ gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE;
+ effect = TRUE;
+ if (GetBattlerAbility(gBattlerTarget) == ABILITY_LIQUID_OOZE)
+ {
+ gBattleStruct->moveDamage[gBattlerAttacker] *= -1;
+ gHitMarker |= HITMARKER_PASSIVE_DAMAGE;
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB_OOZE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_EffectAbsorbLiquidOoze;
+ }
+ else
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_ABSORB;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_EffectAbsorb;
+ }
+ }
+ }
+ gBattleScripting.moveendState++;
+ break;
case MOVEEND_RAGE: // rage check
if (gBattleMons[gBattlerTarget].status2 & STATUS2_RAGE
&& IsBattlerAlive(gBattlerTarget)
&& gBattlerAttacker != gBattlerTarget
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
- && gMovesInfo[gCurrentMove].power != 0
+ && MoveResultHasEffect(gBattlerTarget)
+ && IsBattlerTurnDamaged(gBattlerTarget)
+ && !IsBattleMoveStatus(gCurrentMove)
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
SET_STATCHANGER(STAT_ATK, 1, FALSE);
@@ -5730,7 +6097,7 @@ static void Cmd_moveend(void)
&& IsBattlerAlive(gBattlerTarget)
&& gBattlerAttacker != gBattlerTarget
&& (moveType == TYPE_FIRE || CanBurnHitThaw(gCurrentMove))
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ && MoveResultHasEffect(gBattlerTarget))
{
gBattleMons[gBattlerTarget].status1 &= ~STATUS1_FREEZE;
BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].status1), &gBattleMons[gBattlerTarget].status1);
@@ -5742,8 +6109,8 @@ static void Cmd_moveend(void)
if (gBattleMons[gBattlerTarget].status1 & STATUS1_FROSTBITE
&& IsBattlerAlive(gBattlerTarget)
&& gBattlerAttacker != gBattlerTarget
- && gMovesInfo[originallyUsedMove].thawsUser
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ && MoveThawsUser(originallyUsedMove)
+ && MoveResultHasEffect(gBattlerTarget))
{
gBattleMons[gBattlerTarget].status1 &= ~STATUS1_FROSTBITE;
BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gBattlerTarget].status1), &gBattleMons[gBattlerTarget].status1);
@@ -5755,41 +6122,43 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_RECOIL:
+ {
+ u32 moveRecoil = GetMoveRecoil(gCurrentMove);
if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
{
gBattleScripting.moveendState++;
break;
}
- else if (gMovesInfo[gCurrentMove].recoil > 0
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ else if (moveRecoil > 0
+ && MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& gBattleScripting.savedDmg != 0) // Some checks may be redundant alongside this one
{
- gBattleMoveDamage = max(1, gBattleScripting.savedDmg * max(1, gMovesInfo[gCurrentMove].recoil) / 100);
+ gBattleStruct->moveDamage[gBattlerAttacker] = max(1, gBattleScripting.savedDmg * max(1, moveRecoil) / 100);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
effect = TRUE;
}
- else if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION && !IsAbilityOnField(ABILITY_DAMP))
+ else if (moveEffect == EFFECT_EXPLOSION && !IsAbilityOnField(ABILITY_DAMP))
{
- gBattleMoveDamage = 0;
+ gBattleStruct->moveDamage[gBattlerAttacker] = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_FaintAttackerForExplosion;
effect = TRUE;
}
- else if ((gMovesInfo[gCurrentMove].effect == EFFECT_MAX_HP_50_RECOIL
- || gMovesInfo[gCurrentMove].effect == EFFECT_MIND_BLOWN)
+ else if ((moveEffect == EFFECT_MAX_HP_50_RECOIL || moveEffect == EFFECT_MIND_BLOWN)
&& IsBattlerAlive(gBattlerAttacker)
- && !(gMoveResultFlags & MOVE_RESULT_FAILED)
+ && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
+ gBattleStruct->moveDamage[gBattlerAttacker] = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MaxHp50Recoil;
effect = TRUE;
}
gBattleScripting.moveendState++;
break;
+ }
case MOVEEND_ITEM_EFFECTS_ATTACKER:
if (ItemBattleEffects(ITEMEFFECT_MOVE_END, gBattlerAttacker, FALSE))
effect = TRUE;
@@ -5835,9 +6204,8 @@ static void Cmd_moveend(void)
&& gChosenMove != MOVE_STRUGGLE
&& (*choicedMoveAtk == MOVE_NONE || *choicedMoveAtk == MOVE_UNAVAILABLE))
{
- if ((gMovesInfo[gChosenMove].effect == EFFECT_BATON_PASS
- || gMovesInfo[gChosenMove].effect == EFFECT_HEALING_WISH)
- && !(gMoveResultFlags & MOVE_RESULT_FAILED))
+ if ((moveEffect == EFFECT_BATON_PASS || moveEffect == EFFECT_HEALING_WISH)
+ && !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED))
{
gBattleScripting.moveendState++;
break;
@@ -5904,22 +6272,27 @@ static void Cmd_moveend(void)
}
break;
case MOVE_EFFECT_REMOVE_STATUS: // Smelling salts, Wake-Up Slap, Sparkling Aria
- if ((gBattleMons[gBattlerTarget].status1 & gMovesInfo[gCurrentMove].argument)
+ {
+ u32 argStatus = GetMoveEffectArg_Status(gCurrentMove);
+ if ((gBattleMons[gBattlerTarget].status1 & argStatus)
&& IsBattlerAlive(gBattlerTarget)
- && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))
+ && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)
+ && (gBattleStruct->numSpreadTargets > 1 || !IsMoveEffectBlockedByTarget(GetBattlerAbility(gBattlerTarget))))
{
- gBattleMons[gBattlerTarget].status1 &= ~(gMovesInfo[gCurrentMove].argument);
+ gBattleMons[gBattlerTarget].status1 &= ~(argStatus);
BtlController_EmitSetMonData(gBattlerTarget, 0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerTarget].status1);
MarkBattlerForControllerExec(gBattlerTarget);
effect = TRUE;
BattleScriptPush(gBattlescriptCurrInstr);
- switch (gMovesInfo[gCurrentMove].argument)
+
+ switch (argStatus)
{
case STATUS1_PARALYSIS:
gBattlescriptCurrInstr = BattleScript_TargetPRLZHeal;
break;
case STATUS1_SLEEP:
+ TryDeactivateSleepClause(GetBattlerSide(gBattlerTarget), gBattlerPartyIndexes[gBattlerTarget]);
gBattlescriptCurrInstr = BattleScript_TargetWokeUp;
break;
case STATUS1_BURN:
@@ -5940,6 +6313,7 @@ static void Cmd_moveend(void)
}
break; // MOVE_EFFECT_REMOVE_STATUS
}
+ }
gBattleStruct->moveEffect2 = 0;
gBattleScripting.moveendState++;
break; // MOVEEND_MOVE_EFFECTS2
@@ -5968,7 +6342,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_ATTACKER_VISIBLE: // make attacker sprite visible
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT
+ if (!MoveResultHasEffect(gBattlerTarget)
|| !(gStatuses3[gBattlerAttacker] & (STATUS3_SEMI_INVULNERABLE))
|| WasUnableToUseMove(gBattlerAttacker))
{
@@ -5995,9 +6369,9 @@ static void Cmd_moveend(void)
break;
case MOVEEND_NUM_HITS:
if (gBattlerAttacker != gBattlerTarget
- && gMovesInfo[gCurrentMove].category != DAMAGE_CATEGORY_STATUS
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED)
+ && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS
+ && MoveResultHasEffect(gBattlerTarget)
+ && IsBattlerTurnDamaged(gBattlerTarget))
{
gBattleStruct->timesGotHit[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]]++;
}
@@ -6039,7 +6413,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_UPDATE_LAST_MOVES:
- if ((gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE))
+ if ((gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE))
|| (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED))
|| gProtectStructs[gBattlerAttacker].prlzImmobility)
gBattleStruct->lastMoveFailed |= 1u << gBattlerAttacker;
@@ -6047,7 +6421,7 @@ static void Cmd_moveend(void)
gBattleStruct->lastMoveFailed &= ~(1u << gBattlerAttacker);
// Set ShellTrap to activate after the attacker's turn if target was hit by a physical move.
- if (gMovesInfo[gChosenMoveByBattler[gBattlerTarget]].effect == EFFECT_SHELL_TRAP
+ if (GetMoveEffect(gChosenMoveByBattler[gBattlerTarget]) == EFFECT_SHELL_TRAP
&& gBattlerTarget != gBattlerAttacker
&& GetBattlerSide(gBattlerTarget) != GetBattlerSide(gBattlerAttacker)
&& gProtectStructs[gBattlerTarget].physicalDmg
@@ -6080,10 +6454,10 @@ static void Cmd_moveend(void)
gBattleStruct->dynamax.lastUsedBaseMove = gBattleStruct->dynamax.baseMoves[gBattlerAttacker];
}
}
+ u32 originalEffect = GetMoveEffect(originallyUsedMove);
if (!(gAbsentBattlerFlags & (1u << gBattlerAttacker))
&& !(gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker))
- && gMovesInfo[originallyUsedMove].effect != EFFECT_BATON_PASS
- && gMovesInfo[originallyUsedMove].effect != EFFECT_HEALING_WISH)
+ && originalEffect != EFFECT_BATON_PASS && originalEffect != EFFECT_HEALING_WISH)
{
if (gHitMarker & HITMARKER_OBEYS)
{
@@ -6092,7 +6466,7 @@ static void Cmd_moveend(void)
gLastMoves[gBattlerAttacker] = gChosenMove;
RecordKnownMove(gBattlerAttacker, gChosenMove);
gLastResultingMoves[gBattlerAttacker] = gCurrentMove;
- gLastUsedMoveType[gBattlerAttacker] = GetMoveType(gCurrentMove);
+ gLastUsedMoveType[gBattlerAttacker] = GetBattleMoveType(gCurrentMove);
}
}
else
@@ -6105,7 +6479,7 @@ static void Cmd_moveend(void)
if (!(gHitMarker & HITMARKER_FAINTED(gBattlerTarget)))
gLastHitBy[gBattlerTarget] = gBattlerAttacker;
- if (gHitMarker & HITMARKER_OBEYS && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ if (gHitMarker & HITMARKER_OBEYS && MoveResultHasEffect(gBattlerTarget))
{
if (gChosenMove == MOVE_UNAVAILABLE)
{
@@ -6114,7 +6488,7 @@ static void Cmd_moveend(void)
else
{
gLastLandedMoves[gBattlerTarget] = gCurrentMove;
- gLastHitByType[gBattlerTarget] = GetMoveType(gCurrentMove);
+ gLastHitByType[gBattlerTarget] = GetBattleMoveType(gCurrentMove);
}
}
else
@@ -6127,11 +6501,11 @@ static void Cmd_moveend(void)
case MOVEEND_MIRROR_MOVE: // mirror move
if (!(gAbsentBattlerFlags & (1u << gBattlerAttacker))
&& !(gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker))
- && !gMovesInfo[originallyUsedMove].mirrorMoveBanned
+ && !IsMoveMirrorMoveBanned(originallyUsedMove)
&& gHitMarker & HITMARKER_OBEYS
&& gBattlerAttacker != gBattlerTarget
&& !(gHitMarker & HITMARKER_FAINTED(gBattlerTarget))
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ && MoveResultHasEffect(gBattlerTarget))
{
gBattleStruct->lastTakenMove[gBattlerTarget] = gChosenMove;
gBattleStruct->lastTakenMoveFrom[gBattlerTarget][gBattlerAttacker] = gChosenMove;
@@ -6143,7 +6517,7 @@ static void Cmd_moveend(void)
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
// Set a flag if move hits either target (for throat spray that can't check damage)
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ && MoveResultHasEffect(gBattlerTarget))
gProtectStructs[gBattlerAttacker].targetAffected = TRUE;
gBattleStruct->targetsDone[gBattlerAttacker] |= 1u << gBattlerTarget;
@@ -6164,10 +6538,10 @@ static void Cmd_moveend(void)
MoveValuesCleanUp();
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
- if (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION)
+ if (moveEffect == EFFECT_EXPLOSION)
BattleScriptPush(gBattleMoveEffects[EFFECT_HIT].battleScript); // Edge case for Explosion not changing targets
else
- BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove));
+ BattleScriptPush(GetMoveBattleScript(gCurrentMove));
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
@@ -6189,7 +6563,7 @@ static void Cmd_moveend(void)
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
MoveValuesCleanUp();
- BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove));
+ BattleScriptPush(GetMoveBattleScript(gCurrentMove));
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
@@ -6204,20 +6578,20 @@ static void Cmd_moveend(void)
}
case MOVEEND_MULTIHIT_MOVE:
{
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
- && gMultiHitCounter
- && !(gMovesInfo[gCurrentMove].effect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case
+ if (MoveResultHasEffect(gBattlerTarget)
+ && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
+ && gMultiHitCounter
+ && !(moveEffect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case
{
gMultiHitCounter--;
- if (!IsBattlerAlive(gBattlerTarget) && gMovesInfo[gCurrentMove].effect != EFFECT_DRAGON_DARTS)
+ if (!IsBattlerAlive(gBattlerTarget) && moveEffect != EFFECT_DRAGON_DARTS)
gMultiHitCounter = 0;
gBattleScripting.multihitString[4]++;
if (gMultiHitCounter == 0)
{
BattleScriptPushCursor();
- if (gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty())
+ if (GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty())
gBattlescriptCurrInstr = BattleScript_ScaleShot;
else
gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings;
@@ -6225,8 +6599,8 @@ static void Cmd_moveend(void)
}
else
{
- if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS
- && gBattleStruct->moveTarget[gBattlerAttacker] == gBattlerTarget // Haven't already changed targets
+ if (moveEffect == EFFECT_DRAGON_DARTS
+ && !(gBattleStruct->moveResultFlags[BATTLE_PARTNER(gBattlerTarget)] & MOVE_RESULT_MISSED) // didn't miss the other target
&& CanTargetPartner(gBattlerAttacker, gBattlerTarget)
&& !TargetFullyImmuneToCurrMove(gBattlerAttacker, BATTLE_PARTNER(gBattlerTarget)))
gBattlerTarget = BATTLE_PARTNER(gBattlerTarget); // Target the partner in doubles for second hit.
@@ -6247,7 +6621,7 @@ static void Cmd_moveend(void)
gSpecialStatuses[gBattlerTarget].focusSashed = 0; // Delete this line to make Focus Sash last for the duration of the whole move turn.
gSpecialStatuses[gBattlerAttacker].multiHitOn = TRUE;
MoveValuesCleanUp();
- BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove));
+ BattleScriptPush(GetMoveBattleScript(gCurrentMove));
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
return;
}
@@ -6278,12 +6652,12 @@ static void Cmd_moveend(void)
&& gBattleMons[gBattlerAttacker].item == ITEM_NONE
&& gBattleMons[gBattlerTarget].item != ITEM_NONE
&& IsBattlerAlive(gBattlerAttacker)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
&& !gSpecialStatuses[gBattlerAttacker].gemBoost // In base game, gems are consumed after magician would activate.
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & (1u << gBattlerPartyIndexes[gBattlerTarget]))
&& !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ && MoveResultHasEffect(gBattlerTarget)
&& (GetBattlerAbility(gBattlerTarget) != ABILITY_STICKY_HOLD || !IsBattlerAlive(gBattlerTarget)))
{
StealTargetItem(gBattlerAttacker, gBattlerTarget);
@@ -6324,7 +6698,7 @@ static void Cmd_moveend(void)
continue;
// Since we check if battler was damaged, we don't need to check move result.
// In fact, doing so actually prevents multi-target moves from activating eject button properly
- if (!BATTLER_TURN_DAMAGED(battler))
+ if (!IsBattlerTurnDamaged(battler))
continue;
}
else if (ejectPackBattlers & (1u << battler))
@@ -6340,12 +6714,12 @@ static void Cmd_moveend(void)
if (IsBattlerAlive(battler)
&& CountUsablePartyMons(battler) > 0 // Has mon to switch into
// Does not activate if attacker used Parting Shot and can switch out
- && !(gMovesInfo[gCurrentMove].effect == EFFECT_HIT_SWITCH_TARGET && CanBattlerSwitch(gBattlerAttacker))
+ && !(moveEffect == EFFECT_HIT_SWITCH_TARGET && CanBattlerSwitch(gBattlerAttacker))
)
{
gBattleScripting.battler = battler;
gLastUsedItem = gBattleMons[battler].item;
- if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
+ if (moveEffect == EFFECT_HIT_ESCAPE)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
effect = TRUE;
BattleScriptPushCursor();
@@ -6357,11 +6731,13 @@ static void Cmd_moveend(void)
}
else // Eject Pack
{
- gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
- AI_DATA->ejectPackSwitch = TRUE;
- // Are these 2 lines below needed?
+ if (!(gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT))
+ {
+ gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
+ AI_DATA->ejectPackSwitch = TRUE;
+ gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
+ }
gProtectStructs[battler].statFell = FALSE;
- gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
}
break; // Only the fastest Eject item activates
}
@@ -6394,7 +6770,7 @@ static void Cmd_moveend(void)
redCardBattlers |= (1u << i);
}
if (redCardBattlers
- && (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
+ && (moveEffect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed)
&& IsBattlerAlive(gBattlerAttacker)
&& !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_GUARD_DOG)
@@ -6411,14 +6787,15 @@ static void Cmd_moveend(void)
if (redCardBattlers & (1u << battler)
&& IsBattlerAlive(battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
- && BATTLER_TURN_DAMAGED(battler)
+ && IsBattlerTurnDamaged(battler)
&& CanBattlerSwitch(gBattlerAttacker))
{
gLastUsedItem = gBattleMons[battler].item;
SaveBattlerTarget(battler); // save battler with red card
gBattleScripting.battler = battler;
gEffectBattler = gBattlerAttacker;
- if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE)
+ gBattleStruct->redCardActivates = TRUE;
+ if (moveEffect == EFFECT_HIT_ESCAPE)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
BattleScriptPushCursor();
if (gBattleStruct->commanderActive[gBattlerAttacker] != SPECIES_NONE)
@@ -6449,7 +6826,7 @@ static void Cmd_moveend(void)
&& !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerAttacker)] & (1u << gBattlerPartyIndexes[gBattlerAttacker])) // But not knocked off
&& !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) // Pickpocket doesn't activate for sheer force
&& IsMoveMakingContact(gCurrentMove, gBattlerAttacker) // Pickpocket requires contact
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) // Obviously attack needs to have worked
+ && MoveResultHasEffect(gBattlerTarget)) // Obviously attack needs to have worked
{
u8 battlers[4] = {0, 1, 2, 3};
SortBattlersBySpeed(battlers, FALSE); // Pickpocket activates for fastest mon without item
@@ -6459,7 +6836,7 @@ static void Cmd_moveend(void)
// Attacker is mon who made contact, battler is mon with pickpocket
if (battler != gBattlerAttacker // Cannot pickpocket yourself
&& GetBattlerAbility(battler) == ABILITY_PICKPOCKET // Target must have pickpocket ability
- && BATTLER_TURN_DAMAGED(battler) // Target needs to have been damaged
+ && IsBattlerTurnDamaged(battler) // Target needs to have been damaged
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) // Subsitute unaffected
&& IsBattlerAlive(battler) // Battler must be alive to pickpocket
&& gBattleMons[battler].item == ITEM_NONE // Pickpocketer can't have an item already
@@ -6481,7 +6858,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_DANCER: // Special case because it's so annoying
- if (gMovesInfo[gCurrentMove].danceMove && !gBattleStruct->snatchedMoveIsUsed)
+ if (IsDanceMove(gCurrentMove) && !gBattleStruct->snatchedMoveIsUsed)
{
u32 battler, nextDancer = 0;
bool32 hasDancerTriggered = FALSE;
@@ -6496,7 +6873,7 @@ static void Cmd_moveend(void)
}
}
- if (!(gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)
+ if (!(gBattleStruct->moveResultFlags[gBattlerTarget] & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)
|| (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE && !hasDancerTriggered)
|| (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove && gBattleStruct->bouncedMoveIsUsed)))
{ // Dance move succeeds
@@ -6517,6 +6894,8 @@ static void Cmd_moveend(void)
}
if (nextDancer && AbilityBattleEffects(ABILITYEFFECT_MOVE_END_OTHER, nextDancer & 0x3, 0, 0, 0))
effect = TRUE;
+
+ ClearDamageCalcResults();
}
}
gBattleScripting.moveendState++;
@@ -6524,6 +6903,11 @@ static void Cmd_moveend(void)
case MOVEEND_EMERGENCY_EXIT: // Special case, because moves hitting multiple opponents stop after switching out
for (i = 0; i < gBattlersCount; i++)
{
+ if (gBattleStruct->redCardActivates)
+ {
+ gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_EMERGENCY_EXIT;
+ continue;
+ }
if (gBattleResources->flags->flags[i] & RESOURCE_FLAG_EMERGENCY_EXIT)
{
gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_EMERGENCY_EXIT;
@@ -6568,7 +6952,7 @@ static void Cmd_moveend(void)
gBattleScripting.moveendState++;
break;
case MOVEEND_SAME_MOVE_TURNS:
- if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (gCurrentMove != gLastResultingMoves[gBattlerAttacker] || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
gBattleStruct->sameMoveTurns[gBattlerAttacker] = 0;
else if (gCurrentMove == gLastResultingMoves[gBattlerAttacker] && gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT)
gBattleStruct->sameMoveTurns[gBattlerAttacker]++;
@@ -6588,7 +6972,7 @@ static void Cmd_moveend(void)
if (B_RAMPAGE_CANCELLING >= GEN_5
&& MoveHasAdditionalEffectSelf(gCurrentMove, MOVE_EFFECT_THRASH) // If we're rampaging
- && (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) // And it is unusable
+ && !MoveResultHasEffect(gBattlerTarget) // And it is unusable
&& (gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE) != STATUS2_LOCK_CONFUSE_TURN(1)) // And won't end this turn
CancelMultiTurnMoves(gBattlerAttacker); // Cancel it
@@ -6617,6 +7001,7 @@ static void Cmd_moveend(void)
gSpecialStatuses[gBattlerAttacker].damagedMons = 0;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = 0;
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
+ gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE;
gBattleScripting.moveEffect = 0;
gBattleStruct->hitSwitchTargetFailed = FALSE;
gBattleStruct->isAtkCancelerForCalledMove = FALSE;
@@ -6628,7 +7013,7 @@ static void Cmd_moveend(void)
gBattleStruct->additionalEffectsCounter = 0;
gBattleStruct->poisonPuppeteerConfusion = FALSE;
gBattleStruct->fickleBeamBoosted = FALSE;
- gBattleStruct->distortedTypeMatchups = 0;
+ gBattleStruct->redCardActivates = FALSE;
gBattleStruct->usedMicleBerry &= ~(1u << gBattlerAttacker);
if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
gBattleStruct->pledgeMove = FALSE;
@@ -6637,6 +7022,7 @@ static void Cmd_moveend(void)
if (B_CHARGE <= GEN_8 || moveType == TYPE_ELECTRIC)
gStatuses3[gBattlerAttacker] &= ~(STATUS3_CHARGED_UP);
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
+ ClearDamageCalcResults();
for (i = 0; i < gBattlersCount; i++)
{
@@ -6649,6 +7035,32 @@ static void Cmd_moveend(void)
}
}
+ gBattleScripting.moveendState++;
+ break;
+ case MOVEEND_PURSUIT_NEXT_ACTION:
+ if (gBattleStruct->pursuitTarget & (1u << gBattlerTarget))
+ {
+ u32 storedTarget = gBattlerTarget;
+ if (SetTargetToNextPursuiter(gBattlerTarget))
+ {
+ ChangeOrderTargetAfterAttacker();
+ *(gBattleStruct->moveTarget + gBattlerTarget) = storedTarget;
+ gBattlerTarget = storedTarget;
+ }
+ else if (IsBattlerAlive(gBattlerTarget))
+ {
+ gBattlerAttacker = gBattlerTarget;
+ if (gBattleStruct->pursuitSwitchByMove)
+ gBattlescriptCurrInstr = BattleScript_MoveSwitchOpenPartyScreen;
+ else
+ gBattlescriptCurrInstr = BattleScript_DoSwitchOut;
+ *(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = gBattleStruct->pursuitStoredSwitch;
+ gBattleStruct->pursuitTarget = 0;
+ gBattleStruct->pursuitSwitchByMove = FALSE;
+ gBattleStruct->pursuitStoredSwitch = 0;
+ effect = TRUE;
+ }
+ }
gBattleScripting.moveendState++;
break;
case MOVEEND_COUNT:
@@ -6778,7 +7190,7 @@ static void Cmd_switchindataupdate(void)
gBattleMons[battler].item = ITEM_NONE;
}
- if (gMovesInfo[gCurrentMove].effect == EFFECT_BATON_PASS)
+ if (GetMoveEffect(gCurrentMove) == EFFECT_BATON_PASS)
{
for (i = 0; i < NUM_BATTLE_STATS; i++)
{
@@ -7351,9 +7763,9 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
&& IsBattlerGrounded(battler))
{
u8 spikesDmg = (5 - gSideTimers[GetBattlerSide(battler)].spikesAmount) * 2;
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / (spikesDmg);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (spikesDmg);
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
gDisableStructs[battler].spikesDone = TRUE;
SetDmgHazardsBattlescript(battler, B_MSG_PKMNHURTBYSPIKES);
@@ -7364,9 +7776,9 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
&& GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD)
{
gDisableStructs[battler].stealthRockDone = TRUE;
- gBattleMoveDamage = GetStealthHazardDamage(gMovesInfo[MOVE_STEALTH_ROCK].type, battler);
+ gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(GetMoveType(MOVE_STEALTH_ROCK), battler);
- if (gBattleMoveDamage != 0)
+ if (gBattleStruct->moveDamage[battler] != 0)
SetDmgHazardsBattlescript(battler, B_MSG_STEALTHROCKDMG);
}
else if (!(gDisableStructs[battler].toxicSpikesDone)
@@ -7423,15 +7835,15 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
&& GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD)
{
gDisableStructs[battler].steelSurgeDone = TRUE;
- gBattleMoveDamage = GetStealthHazardDamage(gMovesInfo[MOVE_G_MAX_STEELSURGE].type, battler);
+ gBattleStruct->moveDamage[battler] = GetStealthHazardDamage(GetMoveType(MOVE_G_MAX_STEELSURGE), battler);
- if (gBattleMoveDamage != 0)
+ if (gBattleStruct->moveDamage[battler] != 0)
SetDmgHazardsBattlescript(battler, B_MSG_SHARPSTEELDMG);
}
else if (gBattleMons[battler].hp != gBattleMons[battler].maxHP && gBattleStruct->zmove.healReplacement)
{
gBattleStruct->zmove.healReplacement = FALSE;
- gBattleMoveDamage = -1 * (gBattleMons[battler].maxHP);
+ gBattleStruct->moveDamage[battler] = -1 * (gBattleMons[battler].maxHP);
gBattleScripting.battler = battler;
BattleScriptPushCursor();
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_HP_TRAP;
@@ -7469,7 +7881,6 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
break;
case ABILITY_FORECAST:
case ABILITY_FLOWER_GIFT:
- case ABILITY_ICE_FACE:
case ABILITY_PROTOSYNTHESIS:
if (AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, i, 0, 0, 0))
return TRUE;
@@ -7833,21 +8244,41 @@ static void Cmd_hitanimation(void)
{
CMD_ARGS(u8 battler);
- u32 battler = GetBattlerForBattleScript(cmd->battler);
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (!IsDoubleSpreadMove())
{
- gBattlescriptCurrInstr = cmd->nextInstr;
+ u32 battler = GetBattlerForBattleScript(cmd->battler);
+
+ if (MoveResultHasEffect(battler))
+ {
+ if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)
+ || !(DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove))
+ || gDisableStructs[battler].substituteHP == 0)
+ {
+ BtlController_EmitHitAnimation(battler, BUFFER_A);
+ MarkBattlerForControllerExec(battler);
+ }
+ }
}
- else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)) || gDisableStructs[battler].substituteHP == 0)
+ else if (!gBattleStruct->doneDoublesSpreadHit)
{
- BtlController_EmitHitAnimation(battler, BUFFER_A);
- MarkBattlerForControllerExec(battler);
- gBattlescriptCurrInstr = cmd->nextInstr;
- }
- else
- {
- gBattlescriptCurrInstr = cmd->nextInstr;
+ u32 battlerDef;
+ for (battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT
+ || gBattleStruct->noResultString[battlerDef])
+ continue;
+
+ if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)
+ || !(DoesSubstituteBlockMove(gBattlerAttacker, battlerDef, gCurrentMove))
+ || gDisableStructs[battlerDef].substituteHP == 0)
+ {
+ BtlController_EmitHitAnimation(battlerDef, BUFFER_A);
+ MarkBattlerForControllerExec(battlerDef);
+ }
+ }
}
+
+ gBattlescriptCurrInstr = cmd->nextInstr;
}
static u32 GetTrainerMoneyToGive(u16 trainerId)
@@ -8028,7 +8459,7 @@ static void Cmd_jumptocalledmove(void)
else
gChosenMove = gCurrentMove = gCalledMove;
- gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove);
+ gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove);
}
static void Cmd_statusanimation(void)
@@ -8166,12 +8597,12 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId)
&& GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH
&& !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)
&& gBattleStruct->ateBerry[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler])
- && !BATTLER_MAX_HP(battler))
+ && !IsBattlerAtMaxHp(battler))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 3;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 3;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
gBattlerAbility = battler;
BattleScriptPush(gBattlescriptCurrInstr + 2);
gBattlescriptCurrInstr = BattleScript_CheekPouchActivates;
@@ -8239,7 +8670,7 @@ static void Cmd_removeitem(void)
// Popped Air Balloon cannot be restored by any means.
// Corroded items cannot be restored either.
if (GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_AIR_BALLOON
- && gMovesInfo[gCurrentMove].effect != EFFECT_CORROSIVE_GAS)
+ && GetMoveEffect(gCurrentMove) != EFFECT_CORROSIVE_GAS)
gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = itemId; // Remember if switched out
gBattleMons[battler].item = ITEM_NONE;
@@ -8667,8 +9098,8 @@ static void Cmd_useitemonopponent(void)
static bool32 HasAttackerFaintedTarget(void)
{
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gMovesInfo[gCurrentMove].power != 0
+ if (MoveResultHasEffect(gBattlerTarget)
+ && !IsBattleMoveStatus(gCurrentMove)
&& (gLastHitBy[gBattlerTarget] == 0xFF || gLastHitBy[gBattlerTarget] == gBattlerAttacker)
&& gBattleStruct->moveTarget[gBattlerAttacker] == gBattlerTarget
&& gBattlerTarget != gBattlerAttacker
@@ -8682,7 +9113,7 @@ static bool32 HasAttackerFaintedTarget(void)
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget)
{
return GetBattlerAbility(battlerAttacker) == ABILITY_CORROSION
- || (!IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL) && !IS_BATTLER_OF_TYPE(battlerTarget, TYPE_POISON));
+ || !IS_BATTLER_ANY_TYPE(battlerTarget, TYPE_POISON, TYPE_STEEL);
}
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget)
@@ -8752,6 +9183,7 @@ static void RemoveAllTerrains(void)
break;
}
gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain
+ TryToRevertMimicryAndFlags();
}
#define DEFOG_CLEAR(status, structField, battlescript, move)\
@@ -8826,8 +9258,8 @@ static bool32 TryDefogClear(u32 battlerAtk, bool32 clear)
static bool32 TryTidyUpClear(u32 battlerAtk, bool32 clear)
{
- s32 i;
- u8 saveBattler = gBattlerAttacker;
+ u32 i;
+ u32 saveBattler = gBattlerAttacker;
for (i = 0; i < NUM_BATTLE_SIDES; i++)
{
@@ -8930,11 +9362,11 @@ static bool32 IsElectricAbilityAffected(u32 battler, u32 ability)
u32 moveType;
if (gBattleStruct->dynamicMoveType == 0)
- moveType = gMovesInfo[gCurrentMove].type;
+ moveType = GetMoveType(gCurrentMove);
else if (!(gBattleStruct->dynamicMoveType & F_DYNAMIC_TYPE_IGNORE_PHYSICALITY))
moveType = gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK;
else
- moveType = gMovesInfo[gCurrentMove].type;
+ moveType = GetMoveType(gCurrentMove);
if (moveType == TYPE_ELECTRIC
&& (ability != ABILITY_LIGHTNING_ROD || B_REDIRECT_ABILITY_IMMUNITY >= GEN_5)
@@ -9116,13 +9548,14 @@ static void Cmd_various(void)
s32 i;
u8 data[10];
u32 battler, bits;
+ enum CmdVarious variousId = cmd->id;
if (gBattleControllerExecFlags)
return;
battler = GetBattlerForBattleScript(cmd->battler);
- switch (cmd->id)
+ switch (variousId)
{
// Roar will fail in a double wild battle when used by the player against one of the two alive wild mons.
// Also when an opposing wild mon uses it againt its partner.
@@ -9227,16 +9660,16 @@ static void Cmd_various(void)
{
VARIOUS_ARGS(u8 stat);
i = cmd->stat;
- gBattleMoveDamage = *(u16 *)(&gBattleMons[battler].attack) + (i - 1);
- gBattleMoveDamage *= gStatStageRatios[gBattleMons[battler].statStages[i]][0];
- gBattleMoveDamage /= gStatStageRatios[gBattleMons[battler].statStages[i]][1];
+ gBattleStruct->moveDamage[gBattlerAttacker] = *(u16 *)(&gBattleMons[battler].attack) + (i - 1);
+ gBattleStruct->moveDamage[gBattlerAttacker] *= gStatStageRatios[gBattleMons[battler].statStages[i]][0];
+ gBattleStruct->moveDamage[gBattlerAttacker] /= gStatStageRatios[gBattleMons[battler].statStages[i]][1];
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_JUMP_IF_FULL_HP:
{
VARIOUS_ARGS(const u8 *jumpInstr);
- if (BATTLER_MAX_HP(battler))
+ if (IsBattlerAtMaxHp(battler))
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -9338,7 +9771,7 @@ static void Cmd_various(void)
{
VARIOUS_ARGS(const u8 *failInstr);
if ((gStatuses3[battler] & (STATUS3_SEMI_INVULNERABLE | STATUS3_HEAL_BLOCK))
- || BATTLER_MAX_HP(battler)
+ || IsBattlerAtMaxHp(battler)
|| !gBattleMons[battler].hp
|| !(IsBattlerGrounded(battler)))
{
@@ -9346,10 +9779,10 @@ static void Cmd_various(void)
}
else
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -9438,7 +9871,7 @@ static void Cmd_various(void)
case VARIOUS_GET_MOVE_TARGET:
{
VARIOUS_ARGS();
- gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
break;
}
case VARIOUS_GET_BATTLER_FAINTED:
@@ -9823,7 +10256,7 @@ static void Cmd_various(void)
case VARIOUS_TRY_ACTIVATE_FELL_STINGER:
{
VARIOUS_ARGS();
- if (gMovesInfo[gCurrentMove].effect == EFFECT_FELL_STINGER
+ if (GetMoveEffect(gCurrentMove) == EFFECT_FELL_STINGER
&& HasAttackerFaintedTarget()
&& !NoAliveMonsForEitherParty()
&& CompareStat(gBattlerAttacker, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
@@ -9867,7 +10300,7 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = cmd->failInstr;
else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
gBattlescriptCurrInstr = cmd->failInstr;
- else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]))
+ else if (IsBattleMoveStatus(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]))
gBattlescriptCurrInstr = cmd->failInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -9949,12 +10382,12 @@ static void Cmd_various(void)
{
VARIOUS_ARGS(const u8 *failInstr);
u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]];
- if (IS_MOVE_STATUS(move) || gMovesInfo[move].meFirstBanned
+ if (IsBattleMoveStatus(move) || IsMoveMeFirstBanned(move)
|| GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget))
gBattlescriptCurrInstr = cmd->failInstr;
else
{
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(move))
+ if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move))
{
gBattleStruct->zmove.baseMoves[gBattlerAttacker] = move;
gCalledMove = GetTypeBasedZMove(move);
@@ -9964,7 +10397,7 @@ static void Cmd_various(void)
gCalledMove = move;
}
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
- gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
+ gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
gStatuses3[gBattlerAttacker] |= STATUS3_ME_FIRST;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -9996,16 +10429,18 @@ static void Cmd_various(void)
case VARIOUS_TRY_SOAK:
{
VARIOUS_ARGS(const u8 *failInstr);
- if ((GetBattlerType(gBattlerTarget, 0, FALSE) == gMovesInfo[gCurrentMove].type
- && GetBattlerType(gBattlerTarget, 1, FALSE) == gMovesInfo[gCurrentMove].type)
- || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA)
+ u32 types[3];
+ GetBattlerTypes(gBattlerTarget, FALSE, types);
+ u32 moveType = GetMoveType(gCurrentMove);
+ if ((types[0] == moveType && types[1] == moveType)
+ || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
- SET_BATTLER_TYPE(gBattlerTarget, gMovesInfo[gCurrentMove].type);
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, gMovesInfo[gCurrentMove].type);
+ SET_BATTLER_TYPE(gBattlerTarget, moveType);
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
gBattlescriptCurrInstr = cmd->nextInstr;
}
return;
@@ -10050,7 +10485,7 @@ static void Cmd_various(void)
case VARIOUS_SET_ARG_TO_BATTLE_DAMAGE:
{
VARIOUS_ARGS();
- gBattleMoveDamage = gMovesInfo[gCurrentMove].argument;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetMoveFixedDamage(gCurrentMove);
break;
}
case VARIOUS_TRY_AUTOTOMIZE:
@@ -10072,8 +10507,8 @@ static void Cmd_various(void)
VARIOUS_ARGS(const u8 *failInstr);
u16 move = gLastPrintedMoves[gBattlerTarget];
if (move == MOVE_NONE || move == MOVE_UNAVAILABLE || MoveHasAdditionalEffectSelf(move, MOVE_EFFECT_RECHARGE)
- || gMovesInfo[move].instructBanned
- || gBattleMoveEffects[gMovesInfo[move].effect].twoTurnEffect
+ || IsMoveInstructBanned(move)
+ || gBattleMoveEffects[GetMoveEffect(move)].twoTurnEffect
|| (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)
|| IsZMove(move)
|| IsMaxMove(move))
@@ -10145,7 +10580,7 @@ static void Cmd_various(void)
}
case VARIOUS_PSYCHO_SHIFT:
{
- VARIOUS_ARGS(const u8 *failInstr);
+ VARIOUS_ARGS(const u8 *failInstr, const u8 *sleepClauseFailInstr);
u32 targetAbility = GetBattlerAbility(gBattlerTarget);
// Psycho shift works
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget, targetAbility))
@@ -10156,10 +10591,15 @@ static void Cmd_various(void)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && CanBeParalyzed(gBattlerTarget, targetAbility))
gBattleCommunication[MULTISTRING_CHOOSER] = 3;
- else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerTarget, targetAbility))
+ else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) && CanBeSlept(gBattlerTarget, targetAbility, BLOCKED_BY_SLEEP_CLAUSE))
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
else if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE) && CanGetFrostbite(gBattlerTarget))
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
+ else if (IsSleepClauseActiveForSide(GetBattlerSide(battler)))
+ {
+ gBattlescriptCurrInstr = cmd->sleepClauseFailInstr;
+ return;
+ }
else
{
gBattlescriptCurrInstr = cmd->failInstr;
@@ -10170,11 +10610,16 @@ static void Cmd_various(void)
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
gBattlescriptCurrInstr = cmd->nextInstr;
+ TryActivateSleepClause(battler, gBattlerPartyIndexes[battler]);
return;
}
case VARIOUS_CURE_STATUS:
{
VARIOUS_ARGS();
+
+ if (gBattleMons[battler].status1 & STATUS1_SLEEP)
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
+
gBattleMons[battler].status1 = 0;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
@@ -10245,6 +10690,7 @@ static void Cmd_various(void)
{
gBattlerSpriteIds[BATTLE_PARTNER(battler)] = gBattleScripting.savedDmg >> 8;
gBattlerSpriteIds[battler] = gBattleScripting.savedDmg & 0xFF;
+ gBattleScripting.savedDmg = 0;
if (IsBattlerAlive(battler))
{
SetBattlerShadowSpriteCallback(battler, gBattleMons[battler].species);
@@ -10290,7 +10736,7 @@ static void Cmd_various(void)
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_AURORA_VEIL
|| !(WEATHER_HAS_EFFECT && gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)))
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
}
else
@@ -10312,14 +10758,15 @@ static void Cmd_various(void)
case VARIOUS_TRY_THIRD_TYPE:
{
VARIOUS_ARGS(const u8 *failInstr);
- if (IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument) || GetActiveGimmick(battler) == GIMMICK_TERA)
+ u32 type = GetMoveArgType(gCurrentMove);
+ if (IS_BATTLER_OF_TYPE(battler, type) || GetActiveGimmick(battler) == GIMMICK_TERA)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
- gBattleMons[battler].types[2] = gMovesInfo[gCurrentMove].argument;
- PREPARE_TYPE_BUFFER(gBattleTextBuff1, gMovesInfo[gCurrentMove].argument);
+ gBattleMons[battler].types[2] = type;
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, type);
gBattlescriptCurrInstr = cmd->nextInstr;
}
return;
@@ -10399,16 +10846,16 @@ static void Cmd_various(void)
switch (GetBattlerHoldEffectParam(battler))
{
case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, FALSE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_PARAM_GRASSY_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, FALSE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, item, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_PARAM_MISTY_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, FALSE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, FALSE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, item, ITEMEFFECT_NONE);
break;
}
@@ -10428,53 +10875,6 @@ static void Cmd_various(void)
MarkBattlerForControllerExec(battler);
break;
}
- case VARIOUS_EERIE_SPELL_PP_REDUCE:
- {
- VARIOUS_ARGS(const u8 *failInstr);
- if (gLastMoves[battler] != 0 && gLastMoves[battler] != 0xFFFF)
- {
- s32 i;
-
- for (i = 0; i < MAX_MON_MOVES; i++)
- {
- if (gLastMoves[battler] == gBattleMons[battler].moves[i])
- break;
- }
-
- if (i != MAX_MON_MOVES && gBattleMons[battler].pp[i] != 0)
- {
- s32 ppToDeduct = 3;
-
- if (gBattleMons[battler].pp[i] < ppToDeduct)
- ppToDeduct = gBattleMons[battler].pp[i];
-
- PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[battler])
- ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1);
- PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct)
- gBattleMons[battler].pp[i] -= ppToDeduct;
- if (!(gDisableStructs[battler].mimickedMoves & (1u << i))
- && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
- {
- BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[battler].pp[i]), &gBattleMons[battler].pp[i]);
- MarkBattlerForControllerExec(battler);
- }
-
- if (gBattleMons[battler].pp[i] == 0 && gBattleStruct->skyDropTargets[battler] == 0xFF)
- CancelMultiTurnMoves(battler);
-
- gBattlescriptCurrInstr = cmd->nextInstr; // continue
- }
- else
- {
- gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp
- }
- }
- else
- {
- gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp
- }
- return;
- }
case VARIOUS_JUMP_IF_TEAM_HEALTHY:
{
VARIOUS_ARGS(const u8 *jumpInstr);
@@ -10499,10 +10899,10 @@ static void Cmd_various(void)
case VARIOUS_TRY_HEAL_QUARTER_HP:
{
VARIOUS_ARGS(const u8 *failInstr);
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
if (gBattleMons[battler].hp == gBattleMons[battler].maxHP)
gBattlescriptCurrInstr = cmd->failInstr; // fail
@@ -10786,7 +11186,7 @@ static void Cmd_various(void)
}
if (atLeastOneStatBoosted && gBattleMons[gBattlerAttacker].hp > hpFraction)
{
- gBattleMoveDamage = hpFraction;
+ gBattleStruct->moveDamage[gBattlerAttacker] = hpFraction;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
@@ -10965,9 +11365,10 @@ static void Cmd_various(void)
static void TryResetProtectUseCounter(u32 battler)
{
u32 lastMove = gLastResultingMoves[battler];
+ u32 lastEffect = GetMoveEffect(lastMove);
if (lastMove == MOVE_UNAVAILABLE
- || (!gBattleMoveEffects[gMovesInfo[lastMove].effect].usesProtectCounter
- && (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && gMovesInfo[lastMove].effect != EFFECT_ALLY_SWITCH)))
+ || (!gBattleMoveEffects[lastEffect].usesProtectCounter
+ && (B_ALLY_SWITCH_FAIL_CHANCE >= GEN_9 && lastEffect != EFFECT_ALLY_SWITCH)))
gDisableStructs[battler].protectUses = 0;
}
@@ -10986,9 +11387,9 @@ static void Cmd_setprotectlike(void)
|| (gCurrentMove == MOVE_WIDE_GUARD && B_WIDE_GUARD != GEN_5)
|| (gCurrentMove == MOVE_QUICK_GUARD && B_QUICK_GUARD != GEN_5))
{
- if (!gMovesInfo[gCurrentMove].argument) // Protects one mon only.
+ if (!GetMoveProtectSide(gCurrentMove)) // Protects one mon only.
{
- if (gMovesInfo[gCurrentMove].effect == EFFECT_ENDURE)
+ if (GetMoveEffect(gCurrentMove) == EFFECT_ENDURE)
{
gProtectStructs[gBattlerAttacker].endured = TRUE;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BRACED_ITSELF;
@@ -11074,7 +11475,7 @@ static void Cmd_setprotectlike(void)
{
gDisableStructs[gBattlerAttacker].protectUses = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PROTECT_FAILED;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
}
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -11087,7 +11488,7 @@ static void Cmd_tryexplosion(void)
if (gBattleControllerExecFlags)
return;
- gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp;
+ gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp;
BtlController_EmitHealthBarUpdate(gBattlerAttacker, BUFFER_A, INSTANT_HP_BAR_DROP);
MarkBattlerForControllerExec(gBattlerAttacker);
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -11136,10 +11537,10 @@ static void Cmd_tryhealhalfhealth(void)
if (cmd->battler == BS_ATTACKER)
gBattlerTarget = gBattlerAttacker;
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] *= -1;
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
gBattlescriptCurrInstr = failInstr;
@@ -11151,7 +11552,7 @@ static void SetMoveForMirrorMove(u32 move)
{
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
// Edge case, we used Z Mirror Move, got the stat boost and now need to use the Z-move
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(move))
+ if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(move))
{
gBattleStruct->zmove.baseMoves[gBattlerAttacker] = move;
gCurrentMove = GetTypeBasedZMove(move);
@@ -11162,8 +11563,8 @@ static void SetMoveForMirrorMove(u32 move)
}
SetAtkCancellerForCalledMove();
- gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
- gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove);
+ gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove);
}
static void Cmd_trymirrormove(void)
@@ -11210,7 +11611,7 @@ static void Cmd_setfieldweather(void)
if (!TryChangeBattleWeather(gBattlerAttacker, weather, FALSE))
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEATHER_FAILED;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
@@ -11244,7 +11645,7 @@ static void Cmd_setreflect(void)
if (gSideStatuses[GetBattlerSide(gBattlerAttacker)] & SIDE_STATUS_REFLECT)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SIDE_STATUS_FAILED;
}
else
@@ -11268,14 +11669,14 @@ static void Cmd_setseeded(void)
{
CMD_ARGS();
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED)
+ if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT || gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_MISS;
}
else if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS))
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_FAIL;
}
else
@@ -11288,6 +11689,7 @@ static void Cmd_setseeded(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
+// TODO: Needs tests for everything
static void Cmd_manipulatedamage(void)
{
CMD_ARGS(u8 mode);
@@ -11295,44 +11697,44 @@ static void Cmd_manipulatedamage(void)
switch (cmd->mode)
{
case DMG_CHANGE_SIGN:
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[gBattlerAttacker] *= -1;
break;
case DMG_RECOIL_FROM_MISS:
if (B_RECOIL_IF_MISS_DMG >= GEN_5)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
}
else if (B_RECOIL_IF_MISS_DMG == GEN_4)
{
- if ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleMoveDamage)
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
+ if ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleStruct->moveDamage[gBattlerTarget])
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
}
else
{
- gBattleMoveDamage /= 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget] /= 2;
}
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
break;
case DMG_DOUBLED:
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[gBattlerTarget] *= 2;
break;
case DMG_1_8_TARGET_HP:
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerTarget) / 8;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
break;
case DMG_FULL_ATTACKER_HP:
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker);
- break;
- case DMG_CURR_ATTACKER_HP:
- gBattleMoveDamage = GetNonDynamaxHP(gBattlerAttacker);
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerAttacker);
break;
case DMG_BIG_ROOT:
- gBattleMoveDamage = GetDrainedBigRootHp(gBattlerAttacker, gBattleMoveDamage);
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]);
+ break;
+ case DMG_CURR_ATTACKER_HP:
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerAttacker);
break;
case DMG_RECOIL_FROM_IMMUNE:
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
break;
}
@@ -11345,7 +11747,7 @@ static void Cmd_trysetrest(void)
const u8 *failInstr = cmd->failInstr;
gBattlerTarget = gBattlerAttacker;
- gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP * (-1);
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].maxHP * (-1);
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
{
@@ -11447,7 +11849,7 @@ static void Cmd_stockpile(void)
case 0:
if (gDisableStructs[gBattlerAttacker].stockpileCounter >= 3)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_CANT_STOCKPILE;
}
else
@@ -11460,7 +11862,7 @@ static void Cmd_stockpile(void)
}
break;
case 1: // Save def/sp def stats.
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ if (MoveResultHasEffect(gBattlerTarget))
{
gDisableStructs[gBattlerAttacker].stockpileDef += gBattleMons[gBattlerAttacker].statStages[STAT_DEF] - gDisableStructs[gBattlerAttacker].stockpileBeforeDef;
gDisableStructs[gBattlerAttacker].stockpileSpDef += gBattleMons[gBattlerAttacker].statStages[STAT_SPDEF] - gDisableStructs[gBattlerAttacker].stockpileBeforeSpDef;
@@ -11517,19 +11919,19 @@ static void Cmd_stockpiletohpheal(void)
{
if (gDisableStructs[gBattlerAttacker].stockpileCounter > 0)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / (1 << (3 - gDisableStructs[gBattlerAttacker].stockpileCounter));
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / (1 << (3 - gDisableStructs[gBattlerAttacker].stockpileCounter));
gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter;
gBattleStruct->moveEffect2 = MOVE_EFFECT_STOCKPILE_WORE_OFF;
}
else // Snatched move
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
gBattleScripting.animTurn = 1;
}
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] *= -1;
gBattlescriptCurrInstr = cmd->nextInstr;
gBattlerTarget = gBattlerAttacker;
@@ -11542,13 +11944,10 @@ static void Cmd_setdrainedhp(void)
{
CMD_ARGS();
- if (gMovesInfo[gCurrentMove].argument != 0)
- gBattleMoveDamage = (gHpDealt * gMovesInfo[gCurrentMove].argument / 100);
- else
- gBattleMoveDamage = (gHpDealt / 2);
+ gBattleStruct->moveDamage[gBattlerAttacker] = (gHpDealt * GetMoveAbsorbPercentage(gCurrentMove) / 100);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -11690,7 +12089,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
return STAT_CHANGE_DIDNT_WORK;
}
else if (gCurrentMove != MOVE_CURSE
- && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(gCurrentMove))
+ && notProtectAffected != TRUE && JumpIfMoveAffectedByProtect(gCurrentMove, gBattlerTarget, TRUE))
{
gBattlescriptCurrInstr = BattleScript_ButItFailed;
return STAT_CHANGE_DIDNT_WORK;
@@ -11891,7 +12290,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr
gBattleMons[battler].statStages[statId] = MAX_STAT_STAGE;
if (gBattleCommunication[MULTISTRING_CHOOSER] == B_MSG_STAT_WONT_INCREASE && flags & STAT_CHANGE_ALLOW_PTR)
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
if (gBattleCommunication[MULTISTRING_CHOOSER] == B_MSG_STAT_WONT_INCREASE && !(flags & STAT_CHANGE_ALLOW_PTR))
return STAT_CHANGE_DIDNT_WORK;
@@ -11907,7 +12306,10 @@ static void Cmd_statbuffchange(void)
const u8 *ptrBefore = gBattlescriptCurrInstr;
const u8 *failInstr = cmd->failInstr;
- if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), GET_STAT_BUFF_ID(gBattleScripting.statChanger), flags, failInstr) == STAT_CHANGE_WORKED)
+ if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger),
+ GET_STAT_BUFF_ID(gBattleScripting.statChanger),
+ flags,
+ failInstr) == STAT_CHANGE_WORKED)
gBattlescriptCurrInstr = cmd->nextInstr;
else if (gBattlescriptCurrInstr == ptrBefore) // Prevent infinite looping.
gBattlescriptCurrInstr = failInstr;
@@ -11960,40 +12362,15 @@ static void Cmd_twoturnmoveschargestringandanimation(void)
{
CMD_ARGS(const u8 *animationThenStringPtr);
- gBattleScripting.savedStringId = LOHALF(gMovesInfo[gCurrentMove].argument);
+ gBattleScripting.savedStringId = GetMoveTwoTurnAttackStringId(gCurrentMove);
if (B_UPDATED_MOVE_DATA < GEN_5 || MoveHasChargeTurnAdditionalEffect(gCurrentMove))
gBattlescriptCurrInstr = cmd->animationThenStringPtr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
}
-static void Cmd_setmultihitcounter(void)
+static void Cmd_unused_0x8d(void)
{
- CMD_ARGS(u8 value);
-
- if (cmd->value)
- {
- gMultiHitCounter = cmd->value;
- }
- else
- {
- if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK)
- {
- gMultiHitCounter = 5;
- }
- else
- {
- // WARNING: These seem to be unused, see SetRandomMultiHitCounter.
- if (B_MULTI_HIT_CHANCE >= GEN_5)
- // 35%: 2 hits, 35%: 3 hits, 15% 4 hits, 15% 5 hits.
- gMultiHitCounter = RandomWeighted(RNG_HITS, 0, 0, 7, 7, 3, 3);
- else
- // 37.5%: 2 hits, 37.5%: 3 hits, 12.5% 4 hits, 12.5% 5 hits.
- gMultiHitCounter = RandomWeighted(RNG_HITS, 0, 0, 3, 3, 1, 1);
- }
- }
-
- gBattlescriptCurrInstr = cmd->nextInstr;
}
static void Cmd_initmultihitstring(void)
@@ -12214,7 +12591,7 @@ static void Cmd_tryconversiontypechange(void)
{
if (gBattleMons[gBattlerAttacker].moves[moveChecked] != MOVE_NONE)
{
- moveType = gMovesInfo[gBattleMons[gBattlerAttacker].moves[moveChecked]].type;
+ moveType = GetMoveType(gBattleMons[gBattlerAttacker].moves[moveChecked]);
break;
}
}
@@ -12242,7 +12619,7 @@ static void Cmd_tryconversiontypechange(void)
for (moveChecked = 0; moveChecked < validMoves; moveChecked++)
{
- moveType = gMovesInfo[gBattleMons[gBattlerAttacker].moves[moveChecked]].type;
+ moveType = GetMoveType(gBattleMons[gBattlerAttacker].moves[moveChecked]);
if (moveType == TYPE_MYSTERY)
{
@@ -12269,7 +12646,7 @@ static void Cmd_tryconversiontypechange(void)
{
while ((moveChecked = MOD(Random(), MAX_MON_MOVES)) >= validMoves);
- moveType = gMovesInfo[gBattleMons[gBattlerAttacker].moves[moveChecked]].type;
+ moveType = GetMoveType(gBattleMons[gBattlerAttacker].moves[moveChecked]);
if (moveType == TYPE_MYSTERY)
{
@@ -12315,7 +12692,7 @@ static void Cmd_setlightscreen(void)
if (gSideStatuses[GetBattlerSide(gBattlerAttacker)] & SIDE_STATUS_LIGHTSCREEN)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SIDE_STATUS_FAILED;
}
else
@@ -12347,7 +12724,7 @@ static void Cmd_tryKO(void)
// Dynamaxed Pokemon cannot be hit by OHKO moves.
if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX))
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_UNAFFECTED;
gBattlescriptCurrInstr = cmd->failInstr;
return;
@@ -12360,7 +12737,7 @@ static void Cmd_tryKO(void)
gSpecialStatuses[gBattlerTarget].focusBanded = TRUE;
RecordItemEffectBattle(gBattlerTarget, holdEffect);
}
- else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && BATTLER_MAX_HP(gBattlerTarget))
+ else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && IsBattlerAtMaxHp(gBattlerTarget))
{
gSpecialStatuses[gBattlerTarget].focusSashed = TRUE;
RecordItemEffectBattle(gBattlerTarget, holdEffect);
@@ -12368,7 +12745,7 @@ static void Cmd_tryKO(void)
if (targetAbility == ABILITY_STURDY)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gLastUsedAbility = ABILITY_STURDY;
gBattlescriptCurrInstr = BattleScript_SturdyPreventsOHKO;
gBattlerAbility = gBattlerTarget;
@@ -12385,7 +12762,7 @@ static void Cmd_tryKO(void)
}
else
{
- u16 odds = gMovesInfo[gCurrentMove].accuracy + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
+ u16 odds = GetMoveAccuracy(gCurrentMove) + (gBattleMons[gBattlerAttacker].level - gBattleMons[gBattlerTarget].level);
if (B_SHEER_COLD_ACC >= GEN_7 && gCurrentMove == MOVE_SHEER_COLD && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ICE))
odds -= 10;
if (RandomPercentage(RNG_ACCURACY, odds) && gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
@@ -12396,30 +12773,30 @@ static void Cmd_tryKO(void)
{
if (gProtectStructs[gBattlerTarget].endured)
{
- gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
- gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].hp - 1;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FOE_ENDURED;
}
else if (gSpecialStatuses[gBattlerTarget].focusBanded || gSpecialStatuses[gBattlerTarget].focusSashed)
{
- gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
- gMoveResultFlags |= MOVE_RESULT_FOE_HUNG_ON;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].hp - 1;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FOE_HUNG_ON;
gLastUsedItem = gBattleMons[gBattlerTarget].item;
}
else if (B_AFFECTION_MECHANICS == TRUE && gSpecialStatuses[gBattlerTarget].affectionEndured)
{
- gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1;
- gMoveResultFlags |= MOVE_RESULT_FOE_ENDURED_AFFECTION;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].hp - 1;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FOE_ENDURED_AFFECTION;
}
else
{
- gBattleMoveDamage = gBattleMons[gBattlerTarget].hp;
- gMoveResultFlags |= MOVE_RESULT_ONE_HIT_KO;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerTarget].hp;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_ONE_HIT_KO;
}
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_MISS;
else
@@ -12434,15 +12811,18 @@ static void Cmd_damagetohalftargethp(void)
{
CMD_ARGS();
- gBattleMoveDamage = GetNonDynamaxHP(gBattlerTarget) / 2;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) / 2;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
-static void Cmd_unused_95(void)
+static void Cmd_copybidedmg(void)
{
+ CMD_ARGS();
+ gBattleStruct->moveDamage[gBattlerTarget] = gBideDmg[gBattlerAttacker] * 2;
+ gBattlescriptCurrInstr = cmd->nextInstr;
}
static void Cmd_unused_96(void)
@@ -12528,7 +12908,7 @@ static void Cmd_setmist(void)
if (gSideTimers[GetBattlerSide(gBattlerAttacker)].mistTimer)
{
- gMoveResultFlags |= MOVE_RESULT_FAILED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MIST_FAILED;
}
else
@@ -12545,14 +12925,15 @@ static void Cmd_setfocusenergy(void)
{
CMD_ARGS(u8 battler);
u8 battler = GetBattlerForBattleScript(cmd->battler);
+ u32 effect = GetMoveEffect(gCurrentMove);
- if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & (1u << battler))))
+ if ((effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & (1u << battler))))
|| gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
{
- gMoveResultFlags |= MOVE_RESULT_FAILED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FOCUS_ENERGY_FAILED;
}
- else if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && !IS_BATTLER_OF_TYPE(battler, TYPE_DRAGON))
+ else if (effect == EFFECT_DRAGON_CHEER && !IS_BATTLER_OF_TYPE(battler, TYPE_DRAGON))
{
gBattleMons[battler].status2 |= STATUS2_DRAGON_CHEER;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED;
@@ -12575,7 +12956,7 @@ static void Cmd_transformdataexecution(void)
|| gBattleStruct->illusion[gBattlerTarget].on
|| gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER)
{
- gMoveResultFlags |= MOVE_RESULT_FAILED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_FAILED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TRANSFORM_FAILED;
}
else
@@ -12606,8 +12987,9 @@ static void Cmd_transformdataexecution(void)
gBattleStruct->overwrittenAbilities[gBattlerAttacker] = GetBattlerAbility(gBattlerTarget);
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].pp < 5)
- gBattleMons[gBattlerAttacker].pp[i] = gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].pp;
+ u32 pp = GetMovePP(gBattleMons[gBattlerAttacker].moves[i]);
+ if (pp < 5)
+ gBattleMons[gBattlerAttacker].pp[i] = pp;
else
gBattleMons[gBattlerAttacker].pp[i] = 5;
}
@@ -12626,7 +13008,7 @@ static void Cmd_setsubstitute(void)
{
CMD_ARGS();
- u32 factor = gMovesInfo[gCurrentMove].effect == EFFECT_SHED_TAIL ? 2 : 4;
+ u32 factor = GetMoveEffect(gCurrentMove) == EFFECT_SHED_TAIL ? 2 : 4;
u32 hp;
if (factor == 2)
@@ -12639,18 +13021,21 @@ static void Cmd_setsubstitute(void)
if (gBattleMons[gBattlerAttacker].hp <= hp)
{
- gBattleMoveDamage = 0;
+ gBattleStruct->moveDamage[gBattlerAttacker] = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SUBSTITUTE_FAILED;
}
else
{
- gBattleMoveDamage = hp;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = hp; // one bit value will only work for Pokémon which max hp can go to 1020(which is more than possible in games)
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
gBattleMons[gBattlerAttacker].status2 |= STATUS2_SUBSTITUTE;
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_WRAPPED;
- gDisableStructs[gBattlerAttacker].substituteHP = gBattleMoveDamage;
+ if (factor == 2)
+ gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker] / 2;
+ else
+ gDisableStructs[gBattlerAttacker].substituteHP = gBattleStruct->moveDamage[gBattlerAttacker];
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SUBSTITUTE;
gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE;
}
@@ -12662,7 +13047,7 @@ static void Cmd_mimicattackcopy(void)
{
CMD_ARGS(const u8 *failInstr);
- if ((gMovesInfo[gLastMoves[gBattlerTarget]].mimicBanned)
+ if ((IsMoveMimicBanned(gLastMoves[gBattlerTarget]))
|| (gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
|| gLastMoves[gBattlerTarget] == MOVE_NONE
|| gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE)
@@ -12683,8 +13068,9 @@ static void Cmd_mimicattackcopy(void)
{
gChosenMove = 0xFFFF;
gBattleMons[gBattlerAttacker].moves[gCurrMovePos] = gLastMoves[gBattlerTarget];
- if (gMovesInfo[gLastMoves[gBattlerTarget]].pp < 5)
- gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = gMovesInfo[gLastMoves[gBattlerTarget]].pp;
+ u32 pp = GetMovePP(gLastMoves[gBattlerTarget]);
+ if (pp < 5)
+ gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = pp;
else
gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = 5;
@@ -12702,8 +13088,8 @@ static void Cmd_mimicattackcopy(void)
static bool32 InvalidMetronomeMove(u32 move)
{
- return gMovesInfo[move].effect == EFFECT_PLACEHOLDER
- || gMovesInfo[move].metronomeBanned;
+ return GetMoveEffect(move) == EFFECT_PLACEHOLDER
+ || IsMoveMetronomeBanned(move);
}
static void Cmd_metronome(void)
@@ -12733,15 +13119,15 @@ static void Cmd_metronome(void)
gCurrentMove = RandomUniformExcept(RNG_METRONOME, 1, moveCount - 1, InvalidMetronomeMove);
SetAtkCancellerForCalledMove();
PrepareStringBattle(STRINGID_WAGGLINGAFINGER, gBattlerAttacker);
- gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove);
- gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove);
+ gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
}
static void Cmd_dmgtolevel(void)
{
CMD_ARGS();
- gBattleMoveDamage = gBattleMons[gBattlerAttacker].level;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerAttacker].level;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -12750,7 +13136,7 @@ static void Cmd_psywavedamageeffect(void)
CMD_ARGS();
s32 randDamage = B_PSYWAVE_DMG >= GEN_6 ? (Random() % 101) : ((Random() % 11) * 10);
- gBattleMoveDamage = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -12765,7 +13151,7 @@ static void Cmd_counterdamagecalculator(void)
&& sideAttacker != sideTarget
&& gBattleMons[gProtectStructs[gBattlerAttacker].physicalBattlerId].hp)
{
- gBattleMoveDamage = gProtectStructs[gBattlerAttacker].physicalDmg * 2;
+ gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].physicalDmg * 2;
if (IsAffectedByFollowMe(gBattlerAttacker, sideTarget, gCurrentMove))
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
@@ -12792,7 +13178,7 @@ static void Cmd_mirrorcoatdamagecalculator(void)
&& sideAttacker != sideTarget
&& gBattleMons[gProtectStructs[gBattlerAttacker].specialBattlerId].hp)
{
- gBattleMoveDamage = gProtectStructs[gBattlerAttacker].specialDmg * 2;
+ gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].specialDmg * 2;
if (IsAffectedByFollowMe(gBattlerAttacker, sideTarget, gCurrentMove))
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
@@ -12861,7 +13247,7 @@ static void Cmd_trysetencore(void)
}
}
- if ((gMovesInfo[gLastMoves[gBattlerTarget]].encoreBanned)
+ if ((IsMoveEncoreBanned(gLastMoves[gBattlerTarget]))
|| gLastMoves[gBattlerTarget] == MOVE_NONE
|| gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE)
{
@@ -12893,17 +13279,11 @@ static void Cmd_painsplitdmgcalc(void)
if (!(DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)))
{
s32 hpDiff = (gBattleMons[gBattlerAttacker].hp + GetNonDynamaxHP(gBattlerTarget)) / 2;
- s32 painSplitHp = gBattleMoveDamage = GetNonDynamaxHP(gBattlerTarget) - hpDiff;
- u8 *storeLoc = (void *)(&gBattleScripting.painSplitHp);
- storeLoc[0] = (painSplitHp);
- storeLoc[1] = (painSplitHp & 0x0000FF00) >> 8;
- storeLoc[2] = (painSplitHp & 0x00FF0000) >> 16;
- storeLoc[3] = (painSplitHp & 0xFF000000) >> 24;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) - hpDiff;
+ gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp - hpDiff;
- gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp - hpDiff;
gSpecialStatuses[gBattlerTarget].shellBellDmg = IGNORE_SHELL_BELL;
-
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
@@ -12926,7 +13306,7 @@ static void Cmd_settypetorandomresistance(void)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
- else if (gBattleMoveEffects[gMovesInfo[gLastLandedMoves[gBattlerAttacker]].effect].twoTurnEffect
+ else if (gBattleMoveEffects[GetMoveEffect(gLastLandedMoves[gBattlerAttacker])].twoTurnEffect
&& gBattleMons[gLastHitBy[gBattlerAttacker]].status2 & STATUS2_MULTIPLETURNS)
{
gBattlescriptCurrInstr = cmd->failInstr;
@@ -13055,7 +13435,7 @@ static void Cmd_copymovepermanently(void)
if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED)
&& gLastPrintedMoves[gBattlerTarget] != MOVE_UNAVAILABLE
- && !gMovesInfo[gLastPrintedMoves[gBattlerTarget]].sketchBanned)
+ && !IsMoveSketchBanned(gLastPrintedMoves[gBattlerTarget]))
{
s32 i;
@@ -13076,7 +13456,7 @@ static void Cmd_copymovepermanently(void)
struct MovePpInfo movePpData;
gBattleMons[gBattlerAttacker].moves[gCurrMovePos] = gLastPrintedMoves[gBattlerTarget];
- gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = gMovesInfo[gLastPrintedMoves[gBattlerTarget]].pp;
+ gBattleMons[gBattlerAttacker].pp[gCurrMovePos] = GetMovePP(gLastPrintedMoves[gBattlerTarget]);
for (i = 0; i < MAX_MON_MOVES; i++)
{
@@ -13107,8 +13487,8 @@ static void Cmd_trychoosesleeptalkmove(void)
for (i = 0; i < MAX_MON_MOVES; i++)
{
- if (gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].sleepTalkBanned
- || gBattleMoveEffects[gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].effect].twoTurnEffect)
+ if (IsMoveSleepTalkBanned(gBattleMons[gBattlerAttacker].moves[i])
+ || gBattleMoveEffects[GetMoveEffect(gBattleMons[gBattlerAttacker].moves[i])].twoTurnEffect)
{
unusableMovesBits |= (1 << (i));
}
@@ -13128,7 +13508,7 @@ static void Cmd_trychoosesleeptalkmove(void)
movePosition = MOD(Random(), MAX_MON_MOVES);
} while ((1u << movePosition) & unusableMovesBits);
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[movePosition]))
+ if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(gBattleMons[gBattlerAttacker].moves[movePosition]))
{
gBattleStruct->zmove.baseMoves[gBattlerAttacker] = gBattleMons[gBattlerAttacker].moves[movePosition];
gCalledMove = GetTypeBasedZMove(gBattleMons[gBattlerAttacker].moves[movePosition]);
@@ -13139,17 +13519,23 @@ static void Cmd_trychoosesleeptalkmove(void)
}
gCurrMovePos = movePosition;
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
- gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
+ gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
gBattlescriptCurrInstr = cmd->failInstr;
}
}
-static void Cmd_setdestinybond(void)
+static void Cmd_trysetdestinybond(void)
{
- CMD_ARGS();
-
- gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND;
- gBattlescriptCurrInstr = cmd->nextInstr;
+ CMD_ARGS(const u8 *failInstr);
+ if (DoesDestinyBondFail(gBattlerAttacker))
+ {
+ gBattlescriptCurrInstr = cmd->failInstr;
+ }
+ else
+ {
+ gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND;
+ gBattlescriptCurrInstr = cmd->nextInstr;
+ }
}
static void TrySetDestinyBondToHappen(void)
@@ -13222,7 +13608,7 @@ static void Cmd_tryspiteppreduce(void)
{
s32 ppToDeduct = B_PP_REDUCED_BY_SPITE >= GEN_4 ? 4 : (Random() & 3) + 2;
// G-Max Depletion only deducts 2 PP.
- if (IsMaxMove(gCurrentMove) && gMovesInfo[gCurrentMove].argument == MAX_EFFECT_SPITE)
+ if (IsMaxMove(gCurrentMove) && GetMoveMaxEffect(gCurrentMove) == MAX_EFFECT_SPITE)
ppToDeduct = 2;
if (gBattleMons[gBattlerTarget].pp[i] < ppToDeduct)
@@ -13268,12 +13654,11 @@ static void Cmd_healpartystatus(void)
u32 zero = 0;
u32 partner = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker)));
u8 toHeal = 0;
+ struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
+ s32 i;
if (gCurrentMove == MOVE_HEAL_BELL)
{
- struct Pokemon *party = GetBattlerParty(gBattlerAttacker);
- s32 i;
-
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_BELL;
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF
@@ -13339,7 +13724,10 @@ static void Cmd_healpartystatus(void)
}
if (ability != ABILITY_SOUNDPROOF)
+ {
toHeal |= (1 << i);
+ TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), i);
+ }
}
}
}
@@ -13348,6 +13736,11 @@ static void Cmd_healpartystatus(void)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SOOTHING_AROMA;
toHeal = (1 << PARTY_SIZE) - 1;
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), i);
+ }
+
gBattleMons[gBattlerAttacker].status1 = 0;
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
@@ -13380,9 +13773,9 @@ static void Cmd_cursetarget(void)
else
{
gBattleMons[gBattlerTarget].status2 |= STATUS2_CURSED;
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -13447,7 +13840,7 @@ static void Cmd_handlerollout(void)
{
CMD_ARGS();
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (!MoveResultHasEffect(gBattlerTarget))
{
CancelMultiTurnMoves(gBattlerAttacker);
gBattlescriptCurrInstr = BattleScript_MoveMissedPause;
@@ -13485,7 +13878,7 @@ static void Cmd_handlefurycutter(void)
{
CMD_ARGS();
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (!MoveResultHasEffect(gBattlerTarget))
{
gDisableStructs[gBattlerAttacker].furyCutterCounter = 0;
gBattlescriptCurrInstr = BattleScript_MoveMissedPause;
@@ -13553,10 +13946,11 @@ static void Cmd_presentdamagecalculation(void)
}
else
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerTarget) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ // TODO: Check if this is correct
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerTarget) / 4;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] *= -1;
gBattleStruct->presentBasePower = 0;
}
}
@@ -13571,7 +13965,7 @@ static void Cmd_presentdamagecalculation(void)
}
else
{
- gMoveResultFlags &= ~MOVE_RESULT_DOESNT_AFFECT_FOE;
+ gBattleStruct->moveResultFlags[gBattlerTarget] &= ~MOVE_RESULT_DOESNT_AFFECT_FOE;
gBattlescriptCurrInstr = BattleScript_PresentHealTarget;
}
}
@@ -13582,7 +13976,7 @@ static void Cmd_setsafeguard(void)
if (gSideStatuses[GetBattlerSide(gBattlerAttacker)] & SIDE_STATUS_SAFEGUARD)
{
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SIDE_STATUS_FAILED;
}
else
@@ -13651,45 +14045,44 @@ static void Cmd_magnitudedamagecalculation(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
+static bool32 SetTargetToNextPursuiter(u32 battlerDef)
+{
+ u32 i;
+ for (i = gCurrentTurnActionNumber + 1; i < gBattlersCount; i++)
+ {
+ u32 battler = gBattlerByTurnOrder[i];
+ if (gChosenActionByBattler[battler] == B_ACTION_USE_MOVE
+ && GetMoveEffect(gChosenMoveByBattler[battler]) == EFFECT_PURSUIT
+ && IsBattlerAlive(battlerDef)
+ && IsBattlerAlive(battler)
+ && GetBattlerSide(battler) != GetBattlerSide(battlerDef)
+ && (B_PURSUIT_TARGET >= GEN_4 || *(gBattleStruct->moveTarget + battler) == battlerDef)
+ && !IsGimmickSelected(battler, GIMMICK_Z_MOVE)
+ && !IsGimmickSelected(battler, GIMMICK_DYNAMAX)
+ && GetActiveGimmick(battler) != GIMMICK_DYNAMAX)
+ {
+ gBattlerTarget = battler;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static void Cmd_jumpifnopursuitswitchdmg(void)
{
CMD_ARGS(const u8 *jumpInstr);
- if (gMultiHitCounter == 1)
- {
- if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
- else
- gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
- }
- else
- {
- if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
- gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
- else
- gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
- }
+ u32 savedTarget = gBattlerTarget;
- if (gChosenActionByBattler[gBattlerTarget] == B_ACTION_USE_MOVE
- && gBattlerAttacker == *(gBattleStruct->moveTarget + gBattlerTarget)
- && !(gBattleMons[gBattlerTarget].status1 & (STATUS1_SLEEP | STATUS1_FREEZE))
- && gBattleMons[gBattlerAttacker].hp
- && !gDisableStructs[gBattlerTarget].truantCounter
- && gMovesInfo[gChosenMoveByBattler[gBattlerTarget]].effect == EFFECT_PURSUIT)
+ if (SetTargetToNextPursuiter(gBattlerAttacker))
{
- s32 i;
-
- for (i = 0; i < gBattlersCount; i++)
- {
- if (gBattlerByTurnOrder[i] == gBattlerTarget)
- gActionsByTurnOrder[i] = B_ACTION_TRY_FINISH;
- }
-
- gCurrentMove = gChosenMove = gChosenMoveByBattler[gBattlerTarget];
- gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerTarget);
+ ChangeOrderTargetAfterAttacker();
+ gBattleStruct->pursuitTarget = 1u << gBattlerAttacker;
+ gBattleStruct->pursuitSwitchByMove = gActionsByTurnOrder[gCurrentTurnActionNumber] == B_ACTION_USE_MOVE;
+ gBattleStruct->pursuitStoredSwitch = gBattleStruct->monToSwitchIntoId[gBattlerAttacker];
+ *(gBattleStruct->moveTarget + gBattlerTarget) = gBattlerAttacker;
+ gBattlerTarget = savedTarget;
gBattlescriptCurrInstr = cmd->nextInstr;
- gBattleScripting.animTurn = 1;
- gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
}
else
{
@@ -13713,9 +14106,9 @@ static void Cmd_halvehp(void)
if (gBattleMons[gBattlerAttacker].hp > halfHp)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -13821,23 +14214,23 @@ static void Cmd_recoverbasedonsunlight(void)
if (gCurrentMove == MOVE_SHORE_UP)
{
if (WEATHER_HAS_EFFECT && gBattleWeather & B_WEATHER_SANDSTORM)
- gBattleMoveDamage = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30;
+ gBattleStruct->moveDamage[gBattlerAttacker] = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30;
else
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
}
else
{
if (!(gBattleWeather & B_WEATHER_ANY) || !WEATHER_HAS_EFFECT || GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_UTILITY_UMBRELLA)
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
else if (gBattleWeather & B_WEATHER_SUN)
- gBattleMoveDamage = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30;
+ gBattleStruct->moveDamage[gBattlerAttacker] = 20 * GetNonDynamaxMaxHP(gBattlerAttacker) / 30;
else // not sunny weather
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
}
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] *= -1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -13932,26 +14325,31 @@ static void Cmd_trydobeatup(void)
&& !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS))
break;
}
+
if (gBattleCommunication[0] < PARTY_SIZE)
{
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattleCommunication[0])
gBattlescriptCurrInstr = cmd->nextInstr;
- gBattleMoveDamage = gSpeciesInfo[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack;
- gBattleMoveDamage *= gMovesInfo[gCurrentMove].power;
- gBattleMoveDamage *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2);
- gBattleMoveDamage /= gSpeciesInfo[gBattleMons[gBattlerTarget].species].baseDefense;
- gBattleMoveDamage = (gBattleMoveDamage / 50) + 2;
+ gBattleStruct->moveDamage[gBattlerTarget] = gSpeciesInfo[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack;
+ gBattleStruct->moveDamage[gBattlerTarget] *= GetMovePower(gCurrentMove);
+ gBattleStruct->moveDamage[gBattlerTarget] *= (GetMonData(&party[gBattleCommunication[0]], MON_DATA_LEVEL) * 2 / 5 + 2);
+ gBattleStruct->moveDamage[gBattlerTarget] /= gSpeciesInfo[gBattleMons[gBattlerTarget].species].baseDefense;
+ gBattleStruct->moveDamage[gBattlerTarget] = (gBattleStruct->moveDamage[gBattlerTarget] / 50) + 2;
if (gProtectStructs[gBattlerAttacker].helpingHand)
- gBattleMoveDamage = gBattleMoveDamage * 15 / 10;
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleStruct->moveDamage[gBattlerTarget] * 15 / 10;
gBattleCommunication[0]++;
}
else if (beforeLoop != 0)
+ {
gBattlescriptCurrInstr = cmd->endInstr;
+ }
else
+ {
gBattlescriptCurrInstr = cmd->failInstr;
+ }
}
#endif
}
@@ -13960,9 +14358,9 @@ static void Cmd_setsemiinvulnerablebit(void)
{
CMD_ARGS(bool8 clear);
- if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == TRUE)
+ if (gBattleMoveEffects[GetMoveEffect(gCurrentMove)].semiInvulnerableEffect == TRUE)
{
- u32 semiInvulnerableEffect = UNCOMPRESS_BITS(HIHALF(gMovesInfo[gCurrentMove].argument));
+ u32 semiInvulnerableEffect = GetMoveTwoTurnAttackStatus(gCurrentMove);
if (cmd->clear)
gStatuses3[gBattlerAttacker] &= ~semiInvulnerableEffect;
else
@@ -13975,7 +14373,7 @@ static void Cmd_setsemiinvulnerablebit(void)
static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffects)
{
// Semi-invulnerable moves cannot skip their charge turn (except with Power Herb)
- if (gBattleMoveEffects[gMovesInfo[gCurrentMove].effect].semiInvulnerableEffect == TRUE)
+ if (gBattleMoveEffects[GetMoveEffect(gCurrentMove)].semiInvulnerableEffect == TRUE)
return FALSE;
// If this move has charge turn effects, it must charge, activate them, then try to fire
@@ -13986,7 +14384,7 @@ static bool32 CheckIfCanFireTwoTurnMoveNow(u8 battler, bool8 checkChargeTurnEffe
// Certain two-turn moves may fire on the first turn in the right weather (Solar Beam, Electro Shot)
// By default, all two-turn moves have the option of adding weather to their argument
- if (IsBattlerWeatherAffected(battler, HIHALF(gMovesInfo[gCurrentMove].argument)))
+ if (IsBattlerWeatherAffected(battler, GetMoveTwoTurnAttackWeather(gCurrentMove)))
return TRUE;
return FALSE;
@@ -14043,7 +14441,7 @@ static void Cmd_trymemento(void)
else
{
// Success, drop user's HP bar to 0
- gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp;
+ gBattleStruct->moveDamage[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp;
BtlController_EmitHealthBarUpdate(gBattlerAttacker, BUFFER_A, INSTANT_HP_BAR_DROP);
MarkBattlerForControllerExec(gBattlerAttacker);
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -14057,7 +14455,7 @@ static void Cmd_setforcedtarget(void)
gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 1;
gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget = gBattlerTarget;
- gSideTimers[GetBattlerSide(gBattlerTarget)].followmePowder = gMovesInfo[gCurrentMove].powderMove;
+ gSideTimers[GetBattlerSide(gBattlerTarget)].followmePowder = IsPowderMove(gCurrentMove);
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -14082,8 +14480,8 @@ static void Cmd_callterrainattack(void)
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
gCurrentMove = GetNaturePowerMove(gBattlerAttacker);
- gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
- BattleScriptPush(GET_MOVE_BATTLESCRIPT(gCurrentMove));
+ gBattlerTarget = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ BattleScriptPush(GetMoveBattleScript(gCurrentMove));
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -14110,13 +14508,21 @@ u32 GetNaturePowerMove(u32 battler)
return move;
}
-// Refresh
-static void Cmd_cureifburnedparalysedorpoisoned(void)
+static void Cmd_curestatuswithmove(void)
{
CMD_ARGS(const u8 *failInstr);
+ u32 shouldHeal;
- if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON | STATUS1_FROSTBITE))
+ if (GetMoveEffect(gCurrentMove) == EFFECT_REFRESH)
+ shouldHeal = gBattleMons[gBattlerAttacker].status1 & STATUS1_REFRESH;
+ else // Take Heart
+ shouldHeal = gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY;
+
+ if (shouldHeal)
{
+ if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
+ TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]);
+
gBattleMons[gBattlerAttacker].status1 = 0;
gBattlescriptCurrInstr = cmd->nextInstr;
BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gBattlerAttacker].status1), &gBattleMons[gBattlerAttacker].status1);
@@ -14332,7 +14738,7 @@ static void Cmd_trycopyability(void)
if (gBattleMons[battler].ability == defAbility
|| defAbility == ABILITY_NONE
|| gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed
- || (IsBattlerAlive(BATTLE_PARTNER(battler)) && gAbilitiesInfo[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed && gMovesInfo[gCurrentMove].effect == EFFECT_DOODLE)
+ || (IsBattlerAlive(BATTLE_PARTNER(battler)) && gAbilitiesInfo[gBattleMons[BATTLE_PARTNER(battler)].ability].cantBeSuppressed && GetMoveEffect(gCurrentMove) == EFFECT_DOODLE)
|| gAbilitiesInfo[defAbility].cantBeCopied)
{
gBattlescriptCurrInstr = cmd->failInstr;
@@ -14369,16 +14775,16 @@ static void Cmd_trywish(void)
if (B_WISH_HP_SOURCE >= GEN_5)
{
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
- gBattleMoveDamage = max(1, GetMonData(&gPlayerParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2);
+ gBattleStruct->moveDamage[gBattlerTarget] = max(1, GetMonData(&gPlayerParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2);
else
- gBattleMoveDamage = max(1, GetMonData(&gEnemyParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2);
+ gBattleStruct->moveDamage[gBattlerTarget] = max(1, GetMonData(&gEnemyParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2);
}
else
{
- gBattleMoveDamage = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 2);
+ gBattleStruct->moveDamage[gBattlerTarget] = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 2);
}
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[gBattlerTarget] *= -1;
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
gBattlescriptCurrInstr = cmd->failInstr;
else
@@ -14461,7 +14867,7 @@ static void Cmd_setdamagetohealthdifference(void)
}
else
{
- gBattleMoveDamage = GetNonDynamaxHP(gBattlerTarget) - gBattleMons[gBattlerAttacker].hp;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) - gBattleMons[gBattlerAttacker].hp;
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@@ -14486,7 +14892,7 @@ static void Cmd_setroom(void)
{
CMD_ARGS();
- switch (gMovesInfo[gCurrentMove].effect)
+ switch (GetMoveEffect(gCurrentMove))
{
case EFFECT_TRICK_ROOM:
HandleRoomMove(STATUS_FIELD_TRICK_ROOM, &gFieldTimers.trickRoomTimer, 0);
@@ -14522,7 +14928,7 @@ static void Cmd_tryswapabilities(void)
}
else
{
- if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX))
+ if (!MoveResultHasEffect(gBattlerTarget) || (GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX))
{
gBattlescriptCurrInstr = cmd->failInstr;
}
@@ -14651,7 +15057,7 @@ static void Cmd_assistattackselect(void)
{
u16 move = GetMonData(&party[monId], MON_DATA_MOVE1 + moveId);
- if (gMovesInfo[move].assistBanned)
+ if (IsMoveAssistBanned(move))
continue;
validMoves[chooseableMovesNo++] = move;
@@ -14663,7 +15069,7 @@ static void Cmd_assistattackselect(void)
{
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
gCalledMove = validMoves[Random() % chooseableMovesNo];
- gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
+ gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
@@ -14725,6 +15131,9 @@ static void Cmd_switchoutabilities(void)
switch (GetBattlerAbility(battler))
{
case ABILITY_NATURAL_CURE:
+ if (gBattleMons[battler].status1 & STATUS1_SLEEP)
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
+
gBattleMons[battler].status1 = 0;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE,
1u << *(gBattleStruct->battlerPartyIndexes + battler),
@@ -14733,17 +15142,19 @@ static void Cmd_switchoutabilities(void)
MarkBattlerForControllerExec(battler);
break;
case ABILITY_REGENERATOR:
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 3;
- gBattleMoveDamage += gBattleMons[battler].hp;
- if (gBattleMoveDamage > gBattleMons[battler].maxHP)
- gBattleMoveDamage = gBattleMons[battler].maxHP;
+ {
+ u32 regenerate = GetNonDynamaxMaxHP(battler) / 3;
+ regenerate += gBattleMons[battler].hp;
+ if (regenerate > gBattleMons[battler].maxHP)
+ regenerate = gBattleMons[battler].maxHP;
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HP_BATTLE,
1u << *(gBattleStruct->battlerPartyIndexes + battler),
- sizeof(gBattleMoveDamage),
- &gBattleMoveDamage);
+ sizeof(regenerate),
+ ®enerate);
MarkBattlerForControllerExec(battler);
break;
}
+ }
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -14767,8 +15178,9 @@ static void Cmd_jumpifnotcurrentmoveargtype(void)
u8 battler = GetBattlerForBattleScript(cmd->battler);
const u8 *failInstr = cmd->failInstr;
+ u32 type = GetMoveArgType(gCurrentMove);
- if (!IS_BATTLER_OF_TYPE(battler, gMovesInfo[gCurrentMove].argument))
+ if (!IS_BATTLER_OF_TYPE(battler, type))
gBattlescriptCurrInstr = failInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -14847,11 +15259,11 @@ static void Cmd_pickup(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
-static void Cmd_unused3(void)
+static void Cmd_unused_0xE6(void)
{
}
-static void Cmd_unused4(void)
+static void Cmd_unused_0xE7(void)
{
}
@@ -14862,7 +15274,7 @@ static void Cmd_settypebasedhalvers(void)
bool8 worked = FALSE;
- if (gMovesInfo[gCurrentMove].effect == EFFECT_MUD_SPORT)
+ if (GetMoveEffect(gCurrentMove) == EFFECT_MUD_SPORT)
{
if (B_SPORT_TURNS >= GEN_6)
{
@@ -14917,7 +15329,7 @@ bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, u32 move)
{
if (!(gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE))
return FALSE;
- else if (gMovesInfo[move].ignoresSubstitute)
+ else if (MoveIgnoresSubstitute(move))
return FALSE;
else if (GetBattlerAbility(battlerAtk) == ABILITY_INFILTRATOR)
return FALSE;
@@ -14929,7 +15341,7 @@ bool32 DoesDisguiseBlockMove(u32 battler, u32 move)
{
if (!(gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED || gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED)
|| gBattleMons[battler].status2 & STATUS2_TRANSFORMED
- || (!gProtectStructs[battler].confusionSelfDmg && (IS_MOVE_STATUS(move) || gHitMarker & HITMARKER_PASSIVE_DAMAGE))
+ || (!gProtectStructs[battler].confusionSelfDmg && (IsBattleMoveStatus(move) || gHitMarker & HITMARKER_PASSIVE_DAMAGE))
|| gHitMarker & HITMARKER_IGNORE_DISGUISE
|| GetBattlerAbility(battler) != ABILITY_DISGUISE)
return FALSE;
@@ -15028,7 +15440,7 @@ static void Cmd_pursuitdoubles(void)
if (IsDoubleBattle()
&& !(gAbsentBattlerFlags & (1u << battler))
&& gChosenActionByBattler[battler] == B_ACTION_USE_MOVE
- && gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT)
+ && GetMoveEffect(gChosenMoveByBattler[battler]) == EFFECT_PURSUIT)
{
gActionsByTurnOrder[battler] = B_ACTION_TRY_FINISH;
gCurrentMove = gChosenMoveByBattler[battler];
@@ -15072,7 +15484,7 @@ static void Cmd_removelightscreenreflect(void)
side = GetBattlerSide(gBattlerAttacker) ^ BIT_SIDE;
if (B_BRICK_BREAK >= GEN_5)
- failed = (gMoveResultFlags & MOVE_RESULT_NO_EFFECT);
+ failed = !MoveResultHasEffect(gBattlerTarget);
else
failed = FALSE;
@@ -15169,7 +15581,7 @@ static void Cmd_handleballthrow(void)
ballMultiplier = 150;
break;
case BALL_NET:
- if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG))
+ if (IS_BATTLER_ANY_TYPE(gBattlerTarget, TYPE_WATER, TYPE_BUG))
ballMultiplier = B_NET_BALL_MODIFIER >= GEN_7 ? 350 : 300;
break;
case BALL_DIVE:
@@ -15341,13 +15753,18 @@ static void Cmd_handleballthrow(void)
else
gBattleCommunication[MULTISTRING_CHOOSER] = 1;
- if (gLastUsedItem == BALL_HEAL)
+ if (ballId == BALL_HEAL)
{
MonRestorePP(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]]);
HealStatusConditions(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], STATUS1_ANY, gBattlerTarget);
gBattleMons[gBattlerTarget].hp = gBattleMons[gBattlerTarget].maxHP;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HP, &gBattleMons[gBattlerTarget].hp);
}
+ else if (ballId == BALL_FRIEND)
+ {
+ u32 friendship = (B_FRIEND_BALL_MODIFIER >= GEN_8 ? 150 : 200);
+ SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_FRIENDSHIP, &friendship);
+ }
}
else // mon may be caught, calculate shakes
{
@@ -15402,6 +15819,11 @@ static void Cmd_handleballthrow(void)
gBattleMons[gBattlerTarget].hp = gBattleMons[gBattlerTarget].maxHP;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HP, &gBattleMons[gBattlerTarget].hp);
}
+ else if (ballId == BALL_FRIEND)
+ {
+ u32 friendship = (B_FRIEND_BALL_MODIFIER >= GEN_8 ? 150 : 200);
+ SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_FRIENDSHIP, &friendship);
+ }
}
else // not caught
{
@@ -15678,7 +16100,7 @@ static void Cmd_subattackerhpbydmg(void)
{
CMD_ARGS();
- gBattleMons[gBattlerAttacker].hp -= gBattleMoveDamage;
+ gBattleMons[gBattlerAttacker].hp -= gBattleStruct->moveDamage[gBattlerTarget];
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -15918,7 +16340,7 @@ void BS_CalcMetalBurstDmg(void)
&& sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBattlerId))
&& gBattleMons[gProtectStructs[gBattlerAttacker].physicalBattlerId].hp)
{
- gBattleMoveDamage = gProtectStructs[gBattlerAttacker].physicalDmg * 150 / 100;
+ gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].physicalDmg * 150 / 100;
if (IsAffectedByFollowMe(gBattlerAttacker, sideTarget, gCurrentMove))
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
@@ -15931,7 +16353,7 @@ void BS_CalcMetalBurstDmg(void)
&& sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId))
&& gBattleMons[gProtectStructs[gBattlerAttacker].specialBattlerId].hp)
{
- gBattleMoveDamage = gProtectStructs[gBattlerAttacker].specialDmg * 150 / 100;
+ gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].specialDmg * 150 / 100;
if (IsAffectedByFollowMe(gBattlerAttacker, sideTarget, gCurrentMove))
gBattlerTarget = gSideTimers[sideTarget].followmeTarget;
@@ -16028,10 +16450,10 @@ static bool32 CriticalCapture(u32 odds)
bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler)
{
if (move != MOVE_NONE && move != MOVE_UNAVAILABLE && move != MOVE_STRUGGLE
- && !gMovesInfo[move].parentalBondBanned
- && gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS
- && gMovesInfo[move].strikeCount < 2
- && gMovesInfo[move].effect != EFFECT_MULTI_HIT)
+ && !IsMoveParentalBondBanned(move)
+ && GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS
+ && GetMoveStrikeCount(move) < 2
+ && GetMoveEffect(move) != EFFECT_MULTI_HIT)
{
if (IsDoubleBattle())
{
@@ -16086,9 +16508,11 @@ static bool8 CanBurnHitThaw(u16 move)
if (B_BURN_HIT_THAW >= GEN_6)
{
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < numAdditionalEffects; i++)
{
- if (gMovesInfo[move].additionalEffects[i].moveEffect == MOVE_EFFECT_BURN)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ if (additionalEffect->moveEffect == MOVE_EFFECT_BURN)
return TRUE;
}
}
@@ -16314,7 +16738,7 @@ void BS_ItemRestoreHP(void)
// Heal is applied as move damage if battler is active.
if (battler != MAX_BATTLERS_COUNT && hp != 0)
{
- gBattleMoveDamage = -healAmount;
+ gBattleStruct->moveDamage[gBattlerAttacker] = -healAmount;
gBattlescriptCurrInstr = cmd->restoreBattlerInstr;
}
else
@@ -16526,11 +16950,11 @@ void BS_ApplySaltCure(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
-void BS_JumpIfArgument(void)
+void BS_JumpIfMovePropertyArgument(void)
{
NATIVE_ARGS(u8 argument, const u8 *jumpInstr);
- if (gMovesInfo[gCurrentMove].argument == cmd->argument)
+ if (GetMoveEffectArg_MoveProperty(gCurrentMove) == cmd->argument)
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -16541,7 +16965,7 @@ void BS_SetRemoveTerrain(void)
NATIVE_ARGS(const u8 *jumpInstr);
u32 statusFlag = 0;
- switch (gMovesInfo[gCurrentMove].effect)
+ switch (GetMoveEffect(gCurrentMove))
{
case EFFECT_MISTY_TERRAIN:
statusFlag = STATUS_FIELD_MISTY_TERRAIN;
@@ -16560,7 +16984,7 @@ void BS_SetRemoveTerrain(void)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
break;
case EFFECT_HIT_SET_REMOVE_TERRAIN:
- switch (gMovesInfo[gCurrentMove].argument)
+ switch (GetMoveEffectArg_MoveProperty(gCurrentMove))
{
case ARG_SET_PSYCHIC_TERRAIN: // Genesis Supernova
statusFlag = STATUS_FIELD_PSYCHIC_TERRAIN;
@@ -16594,7 +17018,7 @@ void BS_SetRemoveTerrain(void)
{
u32 atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE);
- gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT);
+ gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
gFieldStatuses |= statusFlag;
gFieldTimers.terrainTimer = (atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) ? 8 : 5;
gBattlescriptCurrInstr = cmd->nextInstr;
@@ -16616,9 +17040,8 @@ void BS_TryReflectType(void)
{
NATIVE_ARGS(const u8 *failInstr);
u16 targetBaseSpecies = GET_BASE_SPECIES_ID(gBattleMons[gBattlerTarget].species);
- u8 targetType1 = GetBattlerType(gBattlerTarget, 0, FALSE);
- u8 targetType2 = GetBattlerType(gBattlerTarget, 1, FALSE);
- u8 targetType3 = GetBattlerType(gBattlerTarget, 2, FALSE);
+ u32 targetTypes[3];
+ GetBattlerTypes(gBattlerTarget, FALSE, targetTypes);
if (targetBaseSpecies == SPECIES_ARCEUS || targetBaseSpecies == SPECIES_SILVALLY)
{
@@ -16632,32 +17055,32 @@ void BS_TryReflectType(void)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
- else if (targetType1 == TYPE_MYSTERY && targetType2 == TYPE_MYSTERY && targetType3 != TYPE_MYSTERY)
+ else if (targetTypes[0] == TYPE_MYSTERY && targetTypes[1] == TYPE_MYSTERY && targetTypes[2] != TYPE_MYSTERY)
{
gBattleMons[gBattlerAttacker].types[0] = TYPE_NORMAL;
gBattleMons[gBattlerAttacker].types[1] = TYPE_NORMAL;
- gBattleMons[gBattlerAttacker].types[2] = targetType3;
+ gBattleMons[gBattlerAttacker].types[2] = targetTypes[2];
gBattlescriptCurrInstr = cmd->nextInstr;
}
- else if (targetType1 == TYPE_MYSTERY && targetType2 != TYPE_MYSTERY)
+ else if (targetTypes[0] == TYPE_MYSTERY && targetTypes[1] != TYPE_MYSTERY)
{
- gBattleMons[gBattlerAttacker].types[0] = targetType2;
- gBattleMons[gBattlerAttacker].types[1] = targetType2;
- gBattleMons[gBattlerAttacker].types[2] = targetType3;
+ gBattleMons[gBattlerAttacker].types[0] = targetTypes[1];
+ gBattleMons[gBattlerAttacker].types[1] = targetTypes[1];
+ gBattleMons[gBattlerAttacker].types[2] = targetTypes[2];
gBattlescriptCurrInstr = cmd->nextInstr;
}
- else if (targetType1 != TYPE_MYSTERY && targetType2 == TYPE_MYSTERY)
+ else if (targetTypes[0] != TYPE_MYSTERY && targetTypes[1] == TYPE_MYSTERY)
{
- gBattleMons[gBattlerAttacker].types[0] = targetType1;
- gBattleMons[gBattlerAttacker].types[1] = targetType1;
- gBattleMons[gBattlerAttacker].types[2] = targetType3;
+ gBattleMons[gBattlerAttacker].types[0] = targetTypes[0];
+ gBattleMons[gBattlerAttacker].types[1] = targetTypes[0];
+ gBattleMons[gBattlerAttacker].types[2] = targetTypes[2];
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
- gBattleMons[gBattlerAttacker].types[0] = targetType1;
- gBattleMons[gBattlerAttacker].types[1] = targetType2;
- gBattleMons[gBattlerAttacker].types[2] = targetType3;
+ gBattleMons[gBattlerAttacker].types[0] = targetTypes[0];
+ gBattleMons[gBattlerAttacker].types[1] = targetTypes[1];
+ gBattleMons[gBattlerAttacker].types[2] = targetTypes[2];
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@@ -16750,7 +17173,7 @@ void BS_SetPledge(void)
&& GetBattlerTurnOrderNum(gBattlerAttacker) < GetBattlerTurnOrderNum(partner)
&& !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
&& gCurrentMove != partnerMove
- && gMovesInfo[partnerMove].effect == EFFECT_PLEDGE)
+ && GetMoveEffect(partnerMove) == EFFECT_PLEDGE)
{
u32 currPledgeUser = 0;
u32 newTurnOrder[] = {0xFF, 0xFF};
@@ -16870,21 +17293,21 @@ void BS_TryHealPulse(void)
{
NATIVE_ARGS(const u8 *failInstr);
- if (BATTLER_MAX_HP(gBattlerTarget))
+ if (IsBattlerAtMaxHp(gBattlerTarget))
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
- if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && gMovesInfo[gCurrentMove].pulseMove)
- gBattleMoveDamage = -(GetNonDynamaxMaxHP(gBattlerTarget) * 75 / 100);
- else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_FLORAL_HEALING)
- gBattleMoveDamage = -(GetNonDynamaxMaxHP(gBattlerTarget) * 2 / 3);
+ if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && IsPulseMove(gCurrentMove))
+ gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 75 / 100);
+ else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN && GetMoveEffectArg_MoveProperty(gCurrentMove) == MOVE_EFFECT_FLORAL_HEALING)
+ gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) * 2 / 3);
else
- gBattleMoveDamage = -(GetNonDynamaxMaxHP(gBattlerTarget) / 2);
+ gBattleStruct->moveDamage[gBattlerTarget] = -(GetNonDynamaxMaxHP(gBattlerTarget) / 2);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = -1;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = -1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@@ -16893,13 +17316,13 @@ void BS_TryCopycat(void)
{
NATIVE_ARGS(const u8 *failInstr);
- if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || gMovesInfo[gLastUsedMove].copycatBanned || IsZMove(gLastUsedMove))
+ if (gLastUsedMove == MOVE_NONE || gLastUsedMove == MOVE_UNAVAILABLE || IsMoveCopycatBanned(gLastUsedMove) || IsZMove(gLastUsedMove))
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gLastUsedMove))
+ if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(gLastUsedMove))
{
gBattleStruct->zmove.baseMoves[gBattlerAttacker] = gLastUsedMove;
gCalledMove = GetTypeBasedZMove(gLastUsedMove);
@@ -16914,7 +17337,7 @@ void BS_TryCopycat(void)
}
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
- gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
+ gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
@@ -16945,7 +17368,7 @@ void BS_TryUpperHand(void)
if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)
|| gChosenMoveByBattler[gBattlerTarget] == MOVE_NONE
- || IS_MOVE_STATUS(gChosenMoveByBattler[gBattlerTarget])
+ || IsBattleMoveStatus(gChosenMoveByBattler[gBattlerTarget])
|| GetChosenMovePriority(gBattlerTarget) < 1 || GetChosenMovePriority(gBattlerTarget) > 3) // Fails if priority is less than 1 or greater than 3, if target already moved, or if using a status
gBattlescriptCurrInstr = cmd->failInstr;
else
@@ -16999,9 +17422,10 @@ void BS_AllySwitchFailChance(void)
void BS_SetPhotonGeyserCategory(void)
{
NATIVE_ARGS();
- if (!((gMovesInfo[gCurrentMove].effect == EFFECT_TERA_BLAST && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA)
- || (gMovesInfo[gCurrentMove].effect == EFFECT_TERA_STARSTORM && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA && gBattleMons[gBattlerAttacker].species == SPECIES_TERAPAGOS_STELLAR)))
- gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != gMovesInfo[gCurrentMove].category);
+ u32 effect = GetMoveEffect(gCurrentMove);
+ if (!((effect == EFFECT_TERA_BLAST && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA)
+ || (effect == EFFECT_TERA_STARSTORM && GetActiveGimmick(gBattlerAttacker) != GIMMICK_TERA && gBattleMons[gBattlerAttacker].species == SPECIES_TERAPAGOS_STELLAR)))
+ gBattleStruct->swapDamageCategory = (GetCategoryBasedOnStats(gBattlerAttacker) != GetMoveCategory(gCurrentMove));
gBattlescriptCurrInstr = cmd->nextInstr;
}
@@ -17071,10 +17495,10 @@ void BS_TryUpdateRecoilTracker(void)
switch(gender)
{
case MON_MALE:
- TryUpdateEvolutionTracker(EVO_RECOIL_DAMAGE_MALE, gBattleMoveDamage, MOVE_NONE);
+ TryUpdateEvolutionTracker(EVO_RECOIL_DAMAGE_MALE, gBattleStruct->moveDamage[gBattlerAttacker], MOVE_NONE);
break;
case MON_FEMALE:
- TryUpdateEvolutionTracker(EVO_RECOIL_DAMAGE_FEMALE, gBattleMoveDamage, MOVE_NONE);
+ TryUpdateEvolutionTracker(EVO_RECOIL_DAMAGE_FEMALE, gBattleStruct->moveDamage[gBattlerAttacker], MOVE_NONE);
break;
}
@@ -17125,17 +17549,17 @@ void BS_TryActivateGulpMissile(void)
{
NATIVE_ARGS();
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT
&& GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE)
{
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
}
switch(gBattleMons[gBattlerTarget].species)
@@ -17237,13 +17661,32 @@ void BS_ApplyTerastallization(void)
void BS_DamageToQuarterTargetHP(void)
{
NATIVE_ARGS();
- gBattleMoveDamage = (3 * GetNonDynamaxHP(gBattlerTarget)) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerTarget] = (3 * GetNonDynamaxHP(gBattlerTarget)) / 4;
+ if (gBattleStruct->moveDamage[gBattlerTarget] == 0)
+ gBattleStruct->moveDamage[gBattlerTarget] = 1;
gBattlescriptCurrInstr = cmd->nextInstr;
}
+void BS_JumpIfSleepClause(void)
+{
+ NATIVE_ARGS(const u8 *jumpInstr);
+
+ // Can freely sleep own partner
+ if (IsDoubleBattle() && IsSleepClauseEnabled() && GetBattlerSide(gBattlerAttacker) == GetBattlerSide(gBattlerTarget))
+ {
+ gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerTarget);
+ gBattlescriptCurrInstr = cmd->nextInstr;
+ return;
+ }
+ gBattleStruct->sleepClauseEffectExempt &= ~(1u << gBattlerTarget);
+ // Can't sleep if clause is active otherwise
+ if (IsSleepClauseActiveForSide(GetBattlerSide(gBattlerTarget)))
+ gBattlescriptCurrInstr = cmd->jumpInstr;
+ else
+ gBattlescriptCurrInstr = cmd->nextInstr;
+}
+
void BS_FickleBeamDamageCalculation(void)
{
NATIVE_ARGS();
@@ -17289,7 +17732,7 @@ void BS_JumpIfBlockedBySoundproof(void)
{
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
u32 battler = GetBattlerForBattleScript(cmd->battler);
- if (gMovesInfo[gCurrentMove].soundMove && GetBattlerAbility(battler) == ABILITY_SOUNDPROOF)
+ if (IsSoundMove(gCurrentMove) && GetBattlerAbility(battler) == ABILITY_SOUNDPROOF)
{
gLastUsedAbility = ABILITY_SOUNDPROOF;
gBattlescriptCurrInstr = cmd->jumpInstr;
@@ -17308,8 +17751,8 @@ void BS_TryHitSwitchTarget(void)
if (IsBattlerAlive(gBattlerAttacker)
&& IsBattlerAlive(gBattlerTarget)
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ && MoveResultHasEffect(gBattlerTarget)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT
&& GetBattlerAbility(gBattlerTarget) != ABILITY_GUARD_DOG)
{
@@ -17550,3 +17993,37 @@ void BS_RemoveTerrain(void)
RemoveAllTerrains();
gBattlescriptCurrInstr = cmd->nextInstr;
}
+
+void BS_SetMoveResultFlags(void)
+{
+ NATIVE_ARGS(u16 value);
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= cmd->value;
+ gBattlescriptCurrInstr = cmd->nextInstr;
+}
+
+void BS_ClearMoveResultFlags(void)
+{
+ NATIVE_ARGS(u16 value);
+ gBattleStruct->moveResultFlags[gBattlerTarget] &= ~(cmd->value);
+ gBattlescriptCurrInstr = cmd->nextInstr;
+}
+
+void BS_JumpIfMoveResultFlags(void)
+{
+ NATIVE_ARGS(u16 value, const u8 *jumpInstr);
+
+ if (gBattleStruct->moveResultFlags[gBattlerTarget] & cmd->value)
+ gBattlescriptCurrInstr = cmd->jumpInstr;
+ else
+ gBattlescriptCurrInstr = cmd->nextInstr;
+}
+
+void BS_JumpIfCriticalHit(void)
+{
+ NATIVE_ARGS(const u8 *jumpInstr);
+
+ if (gSpecialStatuses[gBattlerTarget].criticalHit)
+ gBattlescriptCurrInstr = cmd->jumpInstr;
+ else
+ gBattlescriptCurrInstr = cmd->nextInstr;
+}
diff --git a/src/battle_tower.c b/src/battle_tower.c
index 6f80823b98..9eda82f1b5 100644
--- a/src/battle_tower.c
+++ b/src/battle_tower.c
@@ -1590,7 +1590,7 @@ void CreateFacilityMon(const struct TrainerMon *fmon, u16 level, u8 fixedIV, u32
move = MOVE_FRUSTRATION;
SetMonMoveSlot(dst, move, j);
- if (gMovesInfo[move].effect == EFFECT_FRUSTRATION)
+ if (GetMoveEffect(move) == EFFECT_FRUSTRATION)
friendship = 0; // Frustration is more powerful the lower the pokemon's friendship is.
}
@@ -1758,39 +1758,6 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount)
}
}
-// Probably an early draft before the 'CreateApprenticeMon' was written.
-static void UNUSED Unused_CreateApprenticeMons(u16 trainerId, u8 firstMonId)
-{
- s32 i, j;
- u8 friendship = MAX_FRIENDSHIP;
- u8 level = 0;
- u8 fixedIV = 0;
- struct Apprentice *apprentice = &gSaveBlock2Ptr->apprentices[0];
-
- if (apprentice->numQuestions < 5)
- fixedIV = 6;
- else
- fixedIV = 9;
-
- if (gSaveBlock2Ptr->frontier.lvlMode != FRONTIER_LVL_50)
- level = FRONTIER_MAX_LEVEL_OPEN;
- else
- level = FRONTIER_MAX_LEVEL_50;
-
- for (i = 0; i != FRONTIER_PARTY_SIZE; i++)
- {
- CreateMonWithEVSpread(&gEnemyParty[firstMonId + i], apprentice->party[i].species, level, fixedIV, 8);
- friendship = MAX_FRIENDSHIP;
- for (j = 0; j < MAX_MON_MOVES; j++)
- {
- if (gMovesInfo[apprentice->party[i].moves[j]].effect == EFFECT_FRUSTRATION)
- friendship = 0;
- }
- SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_FRIENDSHIP, &friendship);
- SetMonData(&gEnemyParty[firstMonId + i], MON_DATA_HELD_ITEM, &apprentice->party[i].item);
- }
-}
-
u16 GetRandomFrontierMonFromSet(u16 trainerId)
{
u8 level = SetFacilityPtrsGetLevel();
diff --git a/src/battle_tv.c b/src/battle_tv.c
index ccea3551cd..e5be946d81 100644
--- a/src/battle_tv.c
+++ b/src/battle_tv.c
@@ -774,7 +774,7 @@ void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruc
tvPtr->side[atkSide].wishMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
tvPtr->side[atkSide].wishMoveSlot = moveSlot;
}
- if (gMovesInfo[move].effect == EFFECT_EXPLOSION)
+ if (GetMoveEffect(move) == EFFECT_EXPLOSION)
{
tvPtr->side[atkSide ^ BIT_SIDE].explosionMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
tvPtr->side[atkSide ^ BIT_SIDE].explosionMoveSlot = moveSlot;
@@ -782,10 +782,11 @@ void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruc
tvPtr->side[atkSide ^ BIT_SIDE].explosion = TRUE;
}
- AddMovePoints(PTS_REFLECT, move, gMovesInfo[move].power, 0);
- AddMovePoints(PTS_LIGHT_SCREEN, move, gMovesInfo[move].power, 0);
- AddMovePoints(PTS_WATER_SPORT, move, 0, 0);
- AddMovePoints(PTS_MUD_SPORT, move, 0, 0);
+ u32 movePower = GetMovePower(move);
+ AddMovePoints(PTS_REFLECT, move, movePower, 0);
+ AddMovePoints(PTS_LIGHT_SCREEN, move, movePower, 0);
+ AddMovePoints(PTS_WATER_SPORT, move, 0, 0);
+ AddMovePoints(PTS_MUD_SPORT, move, 0, 0);
}
void BattleTv_SetDataBasedOnAnimation(u8 animationId)
@@ -928,10 +929,10 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
{
case PTS_MOVE_EFFECT: // arg1 -> move slot, arg2 -> move
{
- u8 baseFromEffect = gBattleMoveEffects[gMovesInfo[arg2].effect].battleTvScore;
+ u8 baseFromEffect = gBattleMoveEffects[GetMoveEffect(arg2)].battleTvScore;
// Various cases to add/remove points
- if (gMovesInfo[arg2].recoil > 0)
+ if (GetMoveRecoil(arg2) > 0)
baseFromEffect++; // Recoil moves
if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_RAPID_SPIN))
baseFromEffect++;
@@ -1006,7 +1007,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
#define power arg2
case PTS_WATER_SPORT:
// If used fire move during Water Sport
- if (tvPtr->pos[defSide][0].waterSportMonId != -(tvPtr->pos[defSide][1].waterSportMonId) && gMovesInfo[move].type == TYPE_FIRE)
+ if (tvPtr->pos[defSide][0].waterSportMonId != -(tvPtr->pos[defSide][1].waterSportMonId) && GetMoveType(move) == TYPE_FIRE)
{
if (tvPtr->pos[defSide][0].waterSportMonId != 0)
{
@@ -1022,7 +1023,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
break;
case PTS_MUD_SPORT:
// If used Electric move during Mud Sport
- if (tvPtr->pos[defSide][0].mudSportMonId != -(tvPtr->pos[defSide][1].mudSportMonId) && gMovesInfo[move].type == TYPE_ELECTRIC)
+ if (tvPtr->pos[defSide][0].mudSportMonId != -(tvPtr->pos[defSide][1].mudSportMonId) && GetMoveType(move) == TYPE_ELECTRIC)
{
if (tvPtr->pos[defSide][0].mudSportMonId != 0)
{
@@ -1038,7 +1039,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
break;
case PTS_REFLECT:
// If hit Reflect with damaging physical move
- if (IS_MOVE_PHYSICAL(move) && power != 0 && tvPtr->side[defSide].reflectMonId != 0)
+ if (IsBattleMovePhysical(move) && power != 0 && tvPtr->side[defSide].reflectMonId != 0)
{
u32 id = (tvPtr->side[defSide].reflectMonId - 1) * 4;
movePoints->points[defSide][id + tvPtr->side[defSide].reflectMoveSlot] += sPointsArray[caseId][0];
@@ -1046,7 +1047,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
break;
case PTS_LIGHT_SCREEN:
// If hit Light Screen with damaging special move
- if (IS_MOVE_SPECIAL(move) && power != 0 && tvPtr->side[defSide].lightScreenMonId != 0)
+ if (IsBattleMoveSpecial(move) && power != 0 && tvPtr->side[defSide].lightScreenMonId != 0)
{
u32 id = (tvPtr->side[defSide].lightScreenMonId - 1) * 4;
movePoints->points[defSide][id + tvPtr->side[defSide].lightScreenMoveSlot] += sPointsArray[caseId][0];
@@ -1227,7 +1228,7 @@ static void TrySetBattleSeminarShow(void)
return;
else if (gBattleTypeFlags & (BATTLE_TYPE_PALACE | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID))
return;
- else if (IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]))
+ else if (IsBattleMoveStatus(gBattleMons[gBattlerAttacker].moves[gMoveSelectionCursor[gBattlerAttacker]]))
return;
i = 0;
@@ -1242,7 +1243,7 @@ static void TrySetBattleSeminarShow(void)
if (sVariableDmgMoves[i] != TABLE_END)
return;
- dmgByMove[gMoveSelectionCursor[gBattlerAttacker]] = gBattleMoveDamage;
+ dmgByMove[gMoveSelectionCursor[gBattlerAttacker]] = gBattleStruct->moveDamage[gBattlerTarget]; // TODO: Not sure
currMoveSaved = gCurrentMove;
for (i = 0; i < MAX_MON_MOVES; i++)
{
@@ -1254,13 +1255,13 @@ static void TrySetBattleSeminarShow(void)
damageCalcData.battlerAtk = gBattlerAttacker;
damageCalcData.battlerDef = gBattlerTarget;
damageCalcData.move = gCurrentMove;
- damageCalcData.moveType = gMovesInfo[gCurrentMove].type;
+ damageCalcData.moveType = GetMoveType(gCurrentMove);
damageCalcData.isCrit = FALSE;
damageCalcData.randomFactor = FALSE;
damageCalcData.updateFlags = FALSE;
- gBattleMoveDamage = CalculateMoveDamage(&damageCalcData, powerOverride);
- dmgByMove[i] = gBattleMoveDamage;
- if (dmgByMove[i] == 0 && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ gBattleStruct->moveDamage[gBattlerTarget] = CalculateMoveDamage(&damageCalcData, powerOverride);
+ dmgByMove[i] = gBattleStruct->moveDamage[gBattlerTarget];
+ if (dmgByMove[i] == 0 && MoveResultHasEffect(gBattlerTarget))
dmgByMove[i] = 1;
}
}
@@ -1290,13 +1291,13 @@ static void TrySetBattleSeminarShow(void)
}
}
- gBattleMoveDamage = dmgByMove[gMoveSelectionCursor[gBattlerAttacker]];
+ gBattleStruct->moveDamage[gBattlerTarget] = dmgByMove[gMoveSelectionCursor[gBattlerAttacker]];
gCurrentMove = currMoveSaved;
}
static bool8 ShouldCalculateDamage(u16 moveId, s32 *dmg, u16 *powerOverride)
{
- if (IS_MOVE_STATUS(moveId))
+ if (IsBattleMoveStatus(moveId))
{
*dmg = 0;
return FALSE;
diff --git a/src/battle_util.c b/src/battle_util.c
index 1e5f809c52..fd264e4606 100644
--- a/src/battle_util.c
+++ b/src/battle_util.c
@@ -56,12 +56,15 @@ match the ROM; this is also why sSoundMovesTable's declaration is in the middle
functions instead of at the top of the file with the other declarations.
*/
+typedef void (*MoveSuccessOrderCancellers)(u32 *effect);
static bool32 TryRemoveScreens(u32 battler);
static bool32 IsUnnerveAbilityOnOpposingSide(u32 battler);
static u32 GetFlingPowerFromItemId(u32 itemId);
static void SetRandomMultiHitCounter();
static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item);
static bool32 CanBeInfinitelyConfused(u32 battler);
+ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent);
+ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent);
extern const u8 *const gBattlescriptsForRunningByItem[];
extern const u8 *const gBattlescriptsForUsingItem[];
@@ -109,14 +112,17 @@ static u8 CalcBeatUpPower(void)
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
{
u32 ability = GetBattlerAbility(battlerAtk);
+ u32 effect = GetMoveEffect(move);
if (gSideTimers[defSide].followmeTimer == 0
|| !IsBattlerAlive(gSideTimers[defSide].followmeTarget)
- || gMovesInfo[move].effect == EFFECT_SNIPE_SHOT
- || gMovesInfo[move].effect == EFFECT_SKY_DROP
+ || effect == EFFECT_SNIPE_SHOT || effect == EFFECT_SKY_DROP
|| ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART)
return FALSE;
+ if (effect == EFFECT_PURSUIT && gBattleStruct->pursuitTarget)
+ return FALSE;
+
if (gSideTimers[defSide].followmePowder && !IsAffectedByPowder(battlerAtk, ability, GetBattlerHoldEffect(battlerAtk, TRUE)))
return FALSE;
@@ -138,24 +144,21 @@ void HandleAction_UseMove(void)
return;
}
- gIsCriticalHit = FALSE;
gBattleStruct->atkCancellerTracker = 0;
- gMoveResultFlags = 0;
+ ClearDamageCalcResults();
gMultiHitCounter = 0;
gBattleScripting.savedDmg = 0;
gBattleCommunication[MISS_TYPE] = 0;
gBattleScripting.savedMoveEffect = 0;
gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker);
- gBattleStruct->obedienceResult = GetAttackerObedienceForAction();
-
// choose move
if (gProtectStructs[gBattlerAttacker].noValidMoves)
{
gProtectStructs[gBattlerAttacker].noValidMoves = FALSE;
gCurrentMove = gChosenMove = MOVE_STRUGGLE;
gHitMarker |= HITMARKER_NO_PPDEDUCT;
- *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE);
+ *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(MOVE_STRUGGLE, NO_TARGET_OVERRIDE);
}
else if (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS || gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE)
{
@@ -167,7 +170,7 @@ void HandleAction_UseMove(void)
{
gCurrentMove = gChosenMove = gDisableStructs[gBattlerAttacker].encoredMove;
gCurrMovePos = gChosenMovePos = gDisableStructs[gBattlerAttacker].encoredMovePos;
- *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
}
// check if the encored move wasn't overwritten
else if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].encoredMove != MOVE_NONE
@@ -178,12 +181,12 @@ void HandleAction_UseMove(void)
gDisableStructs[gBattlerAttacker].encoredMove = MOVE_NONE;
gDisableStructs[gBattlerAttacker].encoredMovePos = 0;
gDisableStructs[gBattlerAttacker].encoreTimer = 0;
- *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
}
else if (gBattleMons[gBattlerAttacker].moves[gCurrMovePos] != gChosenMoveByBattler[gBattlerAttacker])
{
gCurrentMove = gChosenMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
- *(gBattleStruct->moveTarget + gBattlerAttacker) = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
+ *(gBattleStruct->moveTarget + gBattlerAttacker) = GetBattleMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE);
}
else
{
@@ -200,22 +203,23 @@ void HandleAction_UseMove(void)
// Set dynamic move type.
SetTypeBeforeUsingMove(gChosenMove, gBattlerAttacker);
- moveType = GetMoveType(gCurrentMove);
+ moveType = GetBattleMoveType(gCurrentMove);
// check Z-Move used
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gCurrentMove) && !IsZMove(gCurrentMove))
+ if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(gCurrentMove) && !IsZMove(gCurrentMove))
{
- gBattleStruct->categoryOverride = gMovesInfo[gCurrentMove].category;
+ gBattleStruct->categoryOverride = GetMoveCategory(gCurrentMove);
gCurrentMove = gChosenMove = GetUsableZMove(gBattlerAttacker, gCurrentMove);
}
// check Max Move used
else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX)
{
- gBattleStruct->categoryOverride = gMovesInfo[gCurrentMove].category;
+ gBattleStruct->categoryOverride = GetMoveCategory(gCurrentMove);
gCurrentMove = gChosenMove = GetMaxMove(gBattlerAttacker, gCurrentMove);
}
moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+ u32 moveEffect = GetMoveEffect(gCurrentMove);
// choose target
side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker));
@@ -227,7 +231,8 @@ void HandleAction_UseMove(void)
}
else if (IsDoubleBattle()
&& gSideTimers[side].followmeTimer == 0
- && (gMovesInfo[gCurrentMove].power != 0 || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS))
+ && !(gBattleStruct->pursuitTarget & (1u << *(gBattleStruct->moveTarget + gBattlerAttacker)))
+ && (!IsBattleMoveStatus(gCurrentMove) || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS))
&& ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER)))
{
@@ -239,8 +244,8 @@ void HandleAction_UseMove(void)
&& ((GetBattlerAbility(battler) == ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC)
|| (GetBattlerAbility(battler) == ABILITY_STORM_DRAIN && moveType == TYPE_WATER))
&& GetBattlerTurnOrderNum(battler) < var
- && gMovesInfo[gCurrentMove].effect != EFFECT_SNIPE_SHOT
- && gMovesInfo[gCurrentMove].effect != EFFECT_PLEDGE
+ && moveEffect != EFFECT_SNIPE_SHOT
+ && moveEffect != EFFECT_PLEDGE
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_PROPELLER_TAIL
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_STALWART)
{
@@ -352,7 +357,7 @@ void HandleAction_UseMove(void)
}
else
{
- gBattlescriptCurrInstr = GET_MOVE_BATTLESCRIPT(gCurrentMove);
+ gBattlescriptCurrInstr = GetMoveBattleScript(gCurrentMove);
}
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
@@ -571,7 +576,8 @@ void HandleAction_ThrowBall(void)
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
gLastUsedItem = gBallToDisplay;
- RemoveBagItem(gLastUsedItem, 1);
+ if (!ItemId_GetImportance(gLastUsedItem))
+ RemoveBagItem(gLastUsedItem, 1);
gBattlescriptCurrInstr = BattleScript_BallThrow;
gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT;
}
@@ -686,19 +692,17 @@ void HandleAction_ActionFinished(void)
| HITMARKER_CHARGING | HITMARKER_NEVER_SET | HITMARKER_IGNORE_DISGUISE);
// check if Stellar type boost should be used up
- moveType = GetMoveType(gCurrentMove);
+ moveType = GetBattleMoveType(gCurrentMove);
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA
&& GetBattlerTeraType(gBattlerAttacker) == TYPE_STELLAR
- && gMovesInfo[gCurrentMove].category != DAMAGE_CATEGORY_STATUS
+ && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS
&& IsTypeStellarBoosted(gBattlerAttacker, moveType))
{
ExpendTypeStellarBoost(gBattlerAttacker, moveType);
}
-
+ ClearDamageCalcResults();
gCurrentMove = 0;
- gBattleMoveDamage = 0;
- gMoveResultFlags = 0;
gBattleScripting.animTurn = 0;
gBattleScripting.animTargetsHit = 0;
gBattleStruct->dynamicMoveType = 0;
@@ -708,7 +712,7 @@ void HandleAction_ActionFinished(void)
gBattleScripting.multihitMoveEffect = 0;
gBattleResources->battleScriptsStack->size = 0;
- if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove)
+ if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !gBattleStruct->pursuitTarget)
{
// i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already
// taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action
@@ -762,113 +766,18 @@ static const u8 sHoldEffectToType[][2] =
{HOLD_EFFECT_FAIRY_POWER, TYPE_FAIRY},
};
-// percent in UQ_4_12 format
-static const uq4_12_t sPercentToModifier[] =
-{
- UQ_4_12(0.00), // 0
- UQ_4_12(0.01), // 1
- UQ_4_12(0.02), // 2
- UQ_4_12(0.03), // 3
- UQ_4_12(0.04), // 4
- UQ_4_12(0.05), // 5
- UQ_4_12(0.06), // 6
- UQ_4_12(0.07), // 7
- UQ_4_12(0.08), // 8
- UQ_4_12(0.09), // 9
- UQ_4_12(0.10), // 10
- UQ_4_12(0.11), // 11
- UQ_4_12(0.12), // 12
- UQ_4_12(0.13), // 13
- UQ_4_12(0.14), // 14
- UQ_4_12(0.15), // 15
- UQ_4_12(0.16), // 16
- UQ_4_12(0.17), // 17
- UQ_4_12(0.18), // 18
- UQ_4_12(0.19), // 19
- UQ_4_12(0.20), // 20
- UQ_4_12(0.21), // 21
- UQ_4_12(0.22), // 22
- UQ_4_12(0.23), // 23
- UQ_4_12(0.24), // 24
- UQ_4_12(0.25), // 25
- UQ_4_12(0.26), // 26
- UQ_4_12(0.27), // 27
- UQ_4_12(0.28), // 28
- UQ_4_12(0.29), // 29
- UQ_4_12(0.30), // 30
- UQ_4_12(0.31), // 31
- UQ_4_12(0.32), // 32
- UQ_4_12(0.33), // 33
- UQ_4_12(0.34), // 34
- UQ_4_12(0.35), // 35
- UQ_4_12(0.36), // 36
- UQ_4_12(0.37), // 37
- UQ_4_12(0.38), // 38
- UQ_4_12(0.39), // 39
- UQ_4_12(0.40), // 40
- UQ_4_12(0.41), // 41
- UQ_4_12(0.42), // 42
- UQ_4_12(0.43), // 43
- UQ_4_12(0.44), // 44
- UQ_4_12(0.45), // 45
- UQ_4_12(0.46), // 46
- UQ_4_12(0.47), // 47
- UQ_4_12(0.48), // 48
- UQ_4_12(0.49), // 49
- UQ_4_12(0.50), // 50
- UQ_4_12(0.51), // 51
- UQ_4_12(0.52), // 52
- UQ_4_12(0.53), // 53
- UQ_4_12(0.54), // 54
- UQ_4_12(0.55), // 55
- UQ_4_12(0.56), // 56
- UQ_4_12(0.57), // 57
- UQ_4_12(0.58), // 58
- UQ_4_12(0.59), // 59
- UQ_4_12(0.60), // 60
- UQ_4_12(0.61), // 61
- UQ_4_12(0.62), // 62
- UQ_4_12(0.63), // 63
- UQ_4_12(0.64), // 64
- UQ_4_12(0.65), // 65
- UQ_4_12(0.66), // 66
- UQ_4_12(0.67), // 67
- UQ_4_12(0.68), // 68
- UQ_4_12(0.69), // 69
- UQ_4_12(0.70), // 70
- UQ_4_12(0.71), // 71
- UQ_4_12(0.72), // 72
- UQ_4_12(0.73), // 73
- UQ_4_12(0.74), // 74
- UQ_4_12(0.75), // 75
- UQ_4_12(0.76), // 76
- UQ_4_12(0.77), // 77
- UQ_4_12(0.78), // 78
- UQ_4_12(0.79), // 79
- UQ_4_12(0.80), // 80
- UQ_4_12(0.81), // 81
- UQ_4_12(0.82), // 82
- UQ_4_12(0.83), // 83
- UQ_4_12(0.84), // 84
- UQ_4_12(0.85), // 85
- UQ_4_12(0.86), // 86
- UQ_4_12(0.87), // 87
- UQ_4_12(0.88), // 88
- UQ_4_12(0.89), // 89
- UQ_4_12(0.90), // 90
- UQ_4_12(0.91), // 91
- UQ_4_12(0.92), // 92
- UQ_4_12(0.93), // 93
- UQ_4_12(0.94), // 94
- UQ_4_12(0.95), // 95
- UQ_4_12(0.96), // 96
- UQ_4_12(0.97), // 97
- UQ_4_12(0.98), // 98
- UQ_4_12(0.99), // 99
- UQ_4_12(1.00), // 100
-};
-
// code
+
+ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent)
+{
+ return (4096 * percent + 50) / 100;
+}
+
+ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent)
+{
+ return (4096 * percent) / 100;
+}
+
u8 GetBattlerForBattleScript(u8 caseId)
{
u8 ret = 0;
@@ -1196,7 +1105,7 @@ static bool32 IsGravityPreventingMove(u32 move)
if (!(gFieldStatuses & STATUS_FIELD_GRAVITY))
return FALSE;
- return gMovesInfo[move].gravityBanned;
+ return IsMoveGravityBanned(move);
}
bool32 IsHealBlockPreventingMove(u32 battler, u32 move)
@@ -1204,12 +1113,12 @@ bool32 IsHealBlockPreventingMove(u32 battler, u32 move)
if (!(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
return FALSE;
- return gMovesInfo[move].healingMove;
+ return IsHealingMove(move);
}
bool32 IsBelchPreventingMove(u32 battler, u32 move)
{
- if (gMovesInfo[move].effect != EFFECT_BELCH)
+ if (GetMoveEffect(move) != EFFECT_BELCH)
return FALSE;
return !(gBattleStruct->ateBerry[battler & BIT_SIDE] & (1u << gBattlerPartyIndexes[battler]));
@@ -1225,6 +1134,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
u32 move = gBattleMons[battler].moves[moveId];
u32 holdEffect = GetBattlerHoldEffect(battler, TRUE);
u16 *choicedMove = &gBattleStruct->choicedMove[battler];
+ u32 moveEffect = GetMoveEffect(move);
if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].disabledMove == move && move != MOVE_NONE)
{
@@ -1257,7 +1167,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
}
}
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].tauntTimer != 0 && IS_MOVE_STATUS(move))
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].tauntTimer != 0 && IsBattleMoveStatus(move))
{
if ((GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX))
gCurrentMove = MOVE_MAX_GUARD;
@@ -1275,7 +1185,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
}
}
- if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].throatChopTimer != 0 && gMovesInfo[move].soundMove)
+ if (DYNAMAX_BYPASS_CHECK && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[battler].throatChopTimer != 0 && IsSoundMove(move))
{
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
@@ -1350,7 +1260,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
}
}
- if (DYNAMAX_BYPASS_CHECK && gMovesInfo[move].effect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
+ if (DYNAMAX_BYPASS_CHECK && moveEffect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
{
gCurrentMove = move;
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
@@ -1365,7 +1275,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
}
}
- if (gMovesInfo[move].cantUseTwice && move == gLastResultingMoves[battler])
+ if (MoveCantBeUsedTwice(move) && move == gLastResultingMoves[battler])
{
gCurrentMove = move;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gCurrentMove);
@@ -1397,7 +1307,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
limitations++;
}
}
- else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_ME_FIRST)
+ else if (holdEffect == HOLD_EFFECT_ASSAULT_VEST && IsBattleMoveStatus(move) && moveEffect != EFFECT_ME_FIRST)
{
if ((GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX))
gCurrentMove = MOVE_MAX_GUARD;
@@ -1445,7 +1355,7 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler)
}
}
- if (gMovesInfo[move].effect == EFFECT_PLACEHOLDER)
+ if (moveEffect == EFFECT_PLACEHOLDER)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
@@ -1474,7 +1384,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
for (i = 0; i < MAX_MON_MOVES; i++)
{
move = gBattleMons[battler].moves[i];
- moveEffect = gMovesInfo[move].effect;
+ moveEffect = GetMoveEffect(move);
// No move
if (check & MOVE_LIMITATION_ZEROMOVE && move == MOVE_NONE)
unusableMoves |= 1u << i;
@@ -1491,7 +1401,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].status2 & STATUS2_TORMENT)
unusableMoves |= 1u << i;
// Taunt
- else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IS_MOVE_STATUS(move))
+ else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IsBattleMoveStatus(move))
unusableMoves |= 1u << i;
// Imprison
else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battler, move))
@@ -1503,7 +1413,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
unusableMoves |= 1u << i;
// Assault Vest
- else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_ME_FIRST)
+ else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IsBattleMoveStatus(move) && moveEffect != EFFECT_ME_FIRST)
unusableMoves |= 1u << i;
// Gravity
else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(move))
@@ -1515,7 +1425,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battler, move))
unusableMoves |= 1u << i;
// Throat Chop
- else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && gMovesInfo[move].soundMove)
+ else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && IsSoundMove(move))
unusableMoves |= 1u << i;
// Stuff Cheeks
else if (check & MOVE_LIMITATION_STUFF_CHEEKS && moveEffect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES)
@@ -1524,7 +1434,7 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check)
else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battler) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move)
unusableMoves |= 1u << i;
// Can't Use Twice flag
- else if (check & MOVE_LIMITATION_CANT_USE_TWICE && gMovesInfo[move].cantUseTwice && move == gLastResultingMoves[battler])
+ else if (check & MOVE_LIMITATION_CANT_USE_TWICE && MoveCantBeUsedTwice(move) && move == gLastResultingMoves[battler])
unusableMoves |= 1u << i;
}
return unusableMoves;
@@ -1591,7 +1501,7 @@ u32 GetBattlerAffectionHearts(u32 battler)
return GetMonAffectionHearts(&party[gBattlerPartyIndexes[battler]]);
}
-static void TryToRevertMimicryAndFlags(void)
+void TryToRevertMimicryAndFlags(void)
{
u32 i;
@@ -1646,7 +1556,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId)
{
if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN)
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
- if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0)
+ if (gFieldTimers.terrainTimer > 0 && --gFieldTimers.terrainTimer == 0)
{
gFieldStatuses &= ~terrainFlag;
TryToRevertMimicryAndFlags();
@@ -1680,17 +1590,12 @@ u8 DoFieldEndTurnEffects(void)
switch (gBattleStruct->turnCountersTracker)
{
case ENDTURN_ORDER:
- for (i = 0; i < gBattlersCount; i++)
- {
- gBattlerByTurnOrder[i] = i;
- }
for (i = 0; i < gBattlersCount - 1; i++)
{
s32 j;
for (j = i + 1; j < gBattlersCount; j++)
{
- if (!gProtectStructs[i].quash
- && !gProtectStructs[j].quash
+ if (!(gProtectStructs[i].quash && gProtectStructs[j].quash)
&& GetWhichBattlerFaster(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE) == -1)
SwapTurnOrder(i, j);
}
@@ -1906,9 +1811,13 @@ u8 DoFieldEndTurnEffects(void)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_RAIN_STOPPED;
}
else if (gBattleWeather & B_WEATHER_RAIN_DOWNPOUR)
+ {
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DOWNPOUR_CONTINUES;
+ }
else
+ {
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_RAIN_CONTINUES;
+ }
}
else if (gBattleWeather & B_WEATHER_RAIN_DOWNPOUR)
{
@@ -2335,27 +2244,25 @@ u8 DoBattlerEndTurnEffects(void)
&& ability != ABILITY_SAND_FORCE
&& ability != ABILITY_SAND_RUSH
&& ability != ABILITY_OVERCOAT
- && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_ROCK)
- && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GROUND)
- && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_STEEL)
+ && !IS_BATTLER_ANY_TYPE(gBattlerAttacker, TYPE_ROCK, TYPE_GROUND, TYPE_STEEL)
&& !(gStatuses3[gBattlerAttacker] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
{
gBattleScripting.battler = battler;
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_DamagingWeather);
effect++;
}
else if (gBattleWeather & (B_WEATHER_HAIL | B_WEATHER_SNOW)
&& ability == ABILITY_ICE_BODY
&& !(gStatuses3[battler] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER))
- && !BATTLER_MAX_HP(battler)
+ && !IsBattlerAtMaxHp(battler)
&& !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
{
gBattleScripting.battler = battler;
- gBattleMoveDamage = -1 * max(1, GetNonDynamaxMaxHP(battler) / 16);
+ gBattleStruct->moveDamage[battler] = -1 * max(1, GetNonDynamaxMaxHP(battler) / 16);
BattleScriptExecute(BattleScript_IceBodyHeal);
effect++;
}
@@ -2368,9 +2275,9 @@ u8 DoBattlerEndTurnEffects(void)
&& GetBattlerHoldEffect(battler, TRUE) != HOLD_EFFECT_SAFETY_GOGGLES)
{
gBattleScripting.battler = battler;
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_DamagingWeather);
effect++;
}
@@ -2378,11 +2285,11 @@ u8 DoBattlerEndTurnEffects(void)
break;
case ENDTURN_INGRAIN: // ingrain
if ((gStatuses3[battler] & STATUS3_ROOTED)
- && !BATTLER_MAX_HP(battler)
+ && !IsBattlerAtMaxHp(battler)
&& !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)
&& IsBattlerAlive(battler))
{
- gBattleMoveDamage = GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16);
+ gBattleStruct->moveDamage[battler] = GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16);
BattleScriptExecute(BattleScript_IngrainTurnHeal);
effect++;
}
@@ -2390,11 +2297,11 @@ u8 DoBattlerEndTurnEffects(void)
break;
case ENDTURN_AQUA_RING: // aqua ring
if ((gStatuses3[battler] & STATUS3_AQUA_RING)
- && !BATTLER_MAX_HP(battler)
+ && !IsBattlerAtMaxHp(battler)
&& !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)
&& IsBattlerAlive(battler))
{
- gBattleMoveDamage = GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16);
+ gBattleStruct->moveDamage[battler] = GetDrainedBigRootHp(battler, GetNonDynamaxMaxHP(battler) / 16);
BattleScriptExecute(BattleScript_AquaRingHeal);
effect++;
}
@@ -2436,12 +2343,27 @@ u8 DoBattlerEndTurnEffects(void)
&& !IsBattlerProtectedByMagicGuard(battler, ability))
{
gBattlerTarget = gStatuses3[battler] & STATUS3_LEECHSEED_BATTLER; // Notice gBattlerTarget is actually the HP receiver.
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattlerAttacker = battler;
gBattleScripting.animArg1 = gBattlerTarget;
gBattleScripting.animArg2 = gBattlerAttacker;
- BattleScriptExecute(BattleScript_LeechSeedTurnDrain);
+ gBattleStruct->moveDamage[gBattlerAttacker] = max(1, GetNonDynamaxMaxHP(battler) / 8);
+ gBattleStruct->moveDamage[gBattlerTarget] = GetDrainedBigRootHp(gBattlerAttacker, gBattleStruct->moveDamage[gBattlerAttacker]);
+ gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE;
+ if (GetBattlerAbility(battler) == ABILITY_LIQUID_OOZE)
+ {
+ gBattleStruct->moveDamage[gBattlerTarget] = gBattleStruct->moveDamage[gBattlerTarget] * -1;
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_OOZE;
+ BattleScriptExecute(BattleScript_LeechSeedTurnDrainLiquidOoze);
+ }
+ else if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK)
+ {
+ BattleScriptExecute(BattleScript_LeechSeedTurnDrainHealBlock);
+ }
+ else
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_DRAIN;
+ BattleScriptExecute(BattleScript_LeechSeedTurnDrainRecovery);
+ }
effect++;
}
gBattleStruct->turnEffectsTracker++;
@@ -2453,21 +2375,21 @@ u8 DoBattlerEndTurnEffects(void)
{
if (ability == ABILITY_POISON_HEAL)
{
- if (!BATTLER_MAX_HP(battler) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
+ if (!IsBattlerAtMaxHp(battler) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
BattleScriptExecute(BattleScript_PoisonHealActivates);
effect++;
}
}
else
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_PoisonTurnDmg);
effect++;
}
@@ -2481,24 +2403,24 @@ u8 DoBattlerEndTurnEffects(void)
{
if (ability == ABILITY_POISON_HEAL)
{
- if (!BATTLER_MAX_HP(battler) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
+ if (!IsBattlerAtMaxHp(battler) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
BattleScriptExecute(BattleScript_PoisonHealActivates);
effect++;
}
}
else
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
if ((gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns
gBattleMons[battler].status1 += STATUS1_TOXIC_TURN(1);
- gBattleMoveDamage *= (gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) >> 8;
+ gBattleStruct->moveDamage[battler] *= (gBattleMons[battler].status1 & STATUS1_TOXIC_COUNTER) >> 8;
BattleScriptExecute(BattleScript_PoisonTurnDmg);
effect++;
}
@@ -2510,15 +2432,15 @@ u8 DoBattlerEndTurnEffects(void)
&& IsBattlerAlive(battler)
&& !IsBattlerProtectedByMagicGuard(battler, ability))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8);
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8);
if (ability == ABILITY_HEATPROOF)
{
- if (gBattleMoveDamage > (gBattleMoveDamage / 2) + 1) // Record ability if the burn takes less damage than it normally would.
+ if (gBattleStruct->moveDamage[battler] > (gBattleStruct->moveDamage[battler] / 2) + 1) // Record ability if the burn takes less damage than it normally would.
RecordAbilityBattle(battler, ABILITY_HEATPROOF);
- gBattleMoveDamage /= 2;
+ gBattleStruct->moveDamage[battler] /= 2;
}
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_BurnTurnDmg);
effect++;
}
@@ -2529,9 +2451,9 @@ u8 DoBattlerEndTurnEffects(void)
&& IsBattlerAlive(battler)
&& !IsBattlerProtectedByMagicGuard(battler, ability))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8);
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_FrostbiteTurnDmg);
effect++;
}
@@ -2546,9 +2468,9 @@ u8 DoBattlerEndTurnEffects(void)
// persist even after the affected Pokémon has been awakened by Shed Skin.
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_NightmareTurnDmg);
effect++;
}
@@ -2564,9 +2486,9 @@ u8 DoBattlerEndTurnEffects(void)
&& IsBattlerAlive(battler)
&& !IsBattlerProtectedByMagicGuard(battler, ability))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_CurseTurnDmg);
effect++;
}
@@ -2588,12 +2510,12 @@ u8 DoBattlerEndTurnEffects(void)
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleStruct->wrappedMove[battler]);
gBattlescriptCurrInstr = BattleScript_WrapTurnDmg;
if (GetBattlerHoldEffect(gBattleStruct->wrappedBy[battler], TRUE) == HOLD_EFFECT_BINDING_BAND)
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 6 : 8);
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 6 : 8);
else
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 8 : 16);
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (B_BINDING_DAMAGE >= GEN_6 ? 8 : 16);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
}
else // broke free
{
@@ -2607,15 +2529,14 @@ u8 DoBattlerEndTurnEffects(void)
gBattleStruct->turnEffectsTracker++;
break;
case ENDTURN_OCTOLOCK:
- {
if (gDisableStructs[battler].octolock)
{
+ gBattlerAttacker = gDisableStructs[battler].battlerPreventingEscape;
gBattlerTarget = battler;
BattleScriptExecute(BattleScript_OctolockEndTurn);
effect++;
}
gBattleStruct->turnEffectsTracker++;
- }
break;
case ENDTURN_UPROAR: // uproar
if (gBattleMons[battler].status2 & STATUS2_UPROAR)
@@ -2763,7 +2684,7 @@ u8 DoBattlerEndTurnEffects(void)
&& !IsLeafGuardProtected(battler))
{
CancelMultiTurnMoves(battler);
- gEffectBattler = battler;
+ gEffectBattler = gBattlerTarget = battler;
if (IsBattlerTerrainAffected(battler, STATUS_FIELD_ELECTRIC_TERRAIN))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINPREVENTS_ELECTRIC;
@@ -2774,6 +2695,10 @@ u8 DoBattlerEndTurnEffects(void)
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAINPREVENTS_MISTY;
BattleScriptExecute(BattleScript_TerrainPreventsEnd2);
}
+ else if (IsSleepClauseActiveForSide(GetBattlerSide(battler)))
+ {
+ BattleScriptExecute(BattleScript_SleepClausePreventsEnd);
+ }
else
{
if (B_SLEEP_TURNS >= GEN_5)
@@ -2781,6 +2706,7 @@ u8 DoBattlerEndTurnEffects(void)
else
gBattleMons[battler].status1 |= ((Random() % 4) + 3);
+ TryActivateSleepClause(battler, gBattlerPartyIndexes[battler]);
BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[battler].status1);
MarkBattlerForControllerExec(battler);
BattleScriptExecute(BattleScript_YawnMakesAsleep);
@@ -2890,12 +2816,12 @@ u8 DoBattlerEndTurnEffects(void)
&& !IsBattlerProtectedByMagicGuard(battler, ability))
{
gBattlerTarget = battler;
- if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_STEEL) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER))
- gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 4;
+ if (IS_BATTLER_ANY_TYPE(battler, TYPE_STEEL, TYPE_WATER))
+ gBattleStruct->moveDamage[battler] = gBattleMons[battler].maxHP / 4;
else
- gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = gBattleMons[battler].maxHP / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
PREPARE_MOVE_BUFFER(gBattleTextBuff1, MOVE_SALT_CURE);
BattleScriptExecute(BattleScript_SaltCureExtraDamage);
effect++;
@@ -2945,7 +2871,7 @@ u8 DoBattlerEndTurnEffects(void)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
gBattleScripting.battler = battler;
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 6;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 6;
ChooseDamageNonTypesString(gSideTimers[side].damageNonTypesType);
BattleScriptExecute(BattleScript_DamageNonTypesContinues);
effect++;
@@ -2956,7 +2882,7 @@ u8 DoBattlerEndTurnEffects(void)
case ENDTURN_SEA_OF_FIRE_DAMAGE:
if (IsBattlerAlive(battler) && gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SEA_OF_FIRE)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
BtlController_EmitStatusAnimation(battler, BUFFER_A, FALSE, STATUS1_BURN);
MarkBattlerForControllerExec(battler);
BattleScriptExecute(BattleScript_HurtByTheSeaOfFire);
@@ -3047,7 +2973,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void)
if (gDisableStructs[battler].perishSongTimer == 0)
{
gStatuses3[battler] &= ~STATUS3_PERISH_SONG;
- gBattleMoveDamage = gBattleMons[battler].hp;
+ gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp;
gBattlescriptCurrInstr = BattleScript_PerishSongTakesLife;
}
else
@@ -3193,535 +3119,750 @@ void TryClearRageAndFuryCutter(void)
}
}
+static inline bool32 TryFormChangeBeforeMove(void)
+{
+ bool32 result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE);
+ if (!result)
+ result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY);
+ if (!result)
+ return FALSE;
+
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_AttackerFormChange;
+ return TRUE;
+}
+
void SetAtkCancellerForCalledMove(void)
{
gBattleStruct->atkCancellerTracker = CANCELLER_HEAL_BLOCKED;
gBattleStruct->isAtkCancelerForCalledMove = TRUE;
}
-u8 AtkCanceller_UnableToUseMove(u32 moveType)
+static void CancellerFlags(u32 *effect)
{
- u8 effect = 0;
- do
+ gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND;
+ gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE;
+ gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH;
+}
+
+static void CancellerStanceChangeOne(u32 *effect)
+{
+ if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove())
+ *effect = 1;
+}
+
+static void CancellerSkyDrop(u32 *effect)
+{
+ // If Pokemon is being held in Sky Drop
+ if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED)
{
- switch (gBattleStruct->atkCancellerTracker)
+ gBattlescriptCurrInstr = BattleScript_MoveEnd;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerRecharge(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE)
+ {
+ gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RECHARGE;
+ gDisableStructs[gBattlerAttacker].rechargeTimer = 0;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerAsleep(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
+ {
+ if (UproarWakeUpCheck(gBattlerAttacker))
{
- case CANCELLER_FLAGS: // flags clear
- gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND;
- gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE;
- gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH;
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_SKY_DROP:
- // If Pokemon is being held in Sky Drop
- if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED)
- {
- gBattlescriptCurrInstr = BattleScript_MoveEnd;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_ASLEEP: // check being asleep
+ TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]);
+ gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
+ gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
+ BattleScriptPushCursor();
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR;
+ gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
+ *effect = 2;
+ }
+ else
+ {
+ u8 toSub;
+ if (GetBattlerAbility(gBattlerAttacker) == ABILITY_EARLY_BIRD)
+ toSub = 2;
+ else
+ toSub = 1;
+ if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) < toSub)
+ gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
+ else
+ gBattleMons[gBattlerAttacker].status1 -= toSub;
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
{
- if (UproarWakeUpCheck(gBattlerAttacker))
+ if (gChosenMove != MOVE_SNORE && gChosenMove != MOVE_SLEEP_TALK)
{
- gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
- gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
- BattleScriptPushCursor();
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR;
- gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
- effect = 2;
- }
- else
- {
- u8 toSub;
- if (GetBattlerAbility(gBattlerAttacker) == ABILITY_EARLY_BIRD)
- toSub = 2;
- else
- toSub = 1;
- if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) < toSub)
- gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
- else
- gBattleMons[gBattlerAttacker].status1 -= toSub;
- if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
- {
- if (gChosenMove != MOVE_SNORE && gChosenMove != MOVE_SLEEP_TALK)
- {
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 2;
- }
- }
- else
- {
- gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
- BattleScriptPushCursor();
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP;
- gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
- effect = 2;
- }
- }
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_FROZEN: // check being frozen
- if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE && !(gMovesInfo[gCurrentMove].thawsUser))
- {
- if (!RandomPercentage(RNG_FROZEN, 20))
- {
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
- gHitMarker |= (HITMARKER_NO_ATTACKSTRING | HITMARKER_UNABLE_TO_USE_MOVE);
- }
- else // unfreeze
- {
- gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED;
- }
- effect = 2;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_TRUANT: // truant
- if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
- {
- CancelMultiTurnMoves(gBattlerAttacker);
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LOAFING;
- gBattlerAbility = gBattlerAttacker;
- gBattlescriptCurrInstr = BattleScript_TruantLoafingAround;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_RECHARGE: // recharge
- if (gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE)
- {
- gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RECHARGE;
- gDisableStructs[gBattlerAttacker].rechargeTimer = 0;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_FLINCH: // flinch
- if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED)
- {
- gProtectStructs[gBattlerAttacker].flinchImmobility = TRUE;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_DISABLED: // disabled move
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].disabledMove == gCurrentMove && gDisableStructs[gBattlerAttacker].disabledMove != MOVE_NONE)
- {
- gProtectStructs[gBattlerAttacker].usedDisabledMove = TRUE;
- gBattleScripting.battler = gBattlerAttacker;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_HEAL_BLOCKED:
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove))
- {
- gProtectStructs[gBattlerAttacker].usedHealBlockedMove = TRUE;
- gBattleScripting.battler = gBattlerAttacker;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedHealBlockPrevents;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_GRAVITY:
- if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove))
- {
- gProtectStructs[gBattlerAttacker].usedGravityPreventedMove = TRUE;
- gBattleScripting.battler = gBattlerAttacker;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedGravityPrevents;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_TAUNTED: // taunt
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IS_MOVE_STATUS(gCurrentMove))
- {
- gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_IMPRISONED: // imprisoned
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(gBattlerAttacker, gCurrentMove))
- {
- gProtectStructs[gBattlerAttacker].usedImprisonedMove = TRUE;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_CONFUSED: // confusion
- if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
- {
- if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION))
- gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1);
- if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
- {
- // confusion dmg
- if (RandomPercentage(RNG_CONFUSION, (B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50)))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = TRUE;
- gBattlerTarget = gBattlerAttacker;
- struct DamageCalculationData damageCalcData;
- damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker;
- damageCalcData.move = MOVE_NONE;
- damageCalcData.moveType = TYPE_MYSTERY;
- damageCalcData.isCrit = FALSE;
- damageCalcData.randomFactor = FALSE;
- damageCalcData.updateFlags = TRUE;
- gBattleMoveDamage = CalculateMoveDamage(&damageCalcData, 40);
- gProtectStructs[gBattlerAttacker].confusionSelfDmg = TRUE;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- }
- else
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = FALSE;
- BattleScriptPushCursor();
- }
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused;
- }
- else // snapped out of confusion
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore;
- }
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_PARALYSED: // paralysis
- if (!gBattleStruct->isAtkCancelerForCalledMove && (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) && !RandomPercentage(RNG_PARALYSIS, 75))
- {
- gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE;
- // This is removed in FRLG and Emerald for some reason
- //CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_IN_LOVE: // infatuation
- if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
- {
- gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10);
- if (!RandomPercentage(RNG_INFATUATION, 50))
- {
- BattleScriptPushCursor();
- }
- else
- {
- BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- gProtectStructs[gBattlerAttacker].loveImmobility = TRUE;
- CancelMultiTurnMoves(gBattlerAttacker);
+ *effect = 2;
}
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_BIDE: // bide
- if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
- {
- gBattleMons[gBattlerAttacker].status2 -= STATUS2_BIDE_TURN(1);
- if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
- {
- gBattlescriptCurrInstr = BattleScript_BideStoringEnergy;
- }
- else
- {
- // This is removed in FRLG and Emerald for some reason
- //gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS;
- if (gBideDmg[gBattlerAttacker])
- {
- gCurrentMove = MOVE_BIDE;
- gBattleScripting.bideDmg = gBideDmg[gBattlerAttacker] * 2;
- gBattlerTarget = gBideTarget[gBattlerAttacker];
- if (gAbsentBattlerFlags & (1u << gBattlerTarget))
- gBattlerTarget = GetMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1);
- gBattlescriptCurrInstr = BattleScript_BideAttack;
- }
- else
- {
- gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack;
- }
- }
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_THAW: // move thawing
- if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE)
- {
- if (!(MoveHasAdditionalEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
- {
- gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE;
- }
- effect = 2;
- }
- if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && gMovesInfo[gCurrentMove].thawsUser)
- {
- if (!(MoveHasAdditionalEffectSelfArg(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
- {
- gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FROSTBITE;
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_MoveUsedUnfrostbite;
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE;
- }
- effect = 2;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_POWDER_MOVE:
- if ((gMovesInfo[gCurrentMove].powderMove) && (gBattlerAttacker != gBattlerTarget))
- {
- if (B_POWDER_GRASS >= GEN_6
- && (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT))
- {
- gBattlerAbility = gBattlerTarget;
- effect = 1;
- }
- else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES)
- {
- RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES);
- gLastUsedItem = gBattleMons[gBattlerTarget].item;
- effect = 1;
- }
-
- if (effect != 0)
- gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_POWDER_STATUS:
- if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER)
- {
- u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]];
- if ((moveType == TYPE_FIRE && !gBattleStruct->pledgeMove)
- || (gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE)
- || (gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE && gBattleStruct->pledgeMove))
- {
- gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE;
- if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
- && (B_POWDER_RAIN < GEN_7 || !IsBattlerWeatherAffected(gBattlerAttacker, B_WEATHER_RAIN_PRIMAL)))
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
-
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE
- || gBattleStruct->obedienceResult != OBEYS
- || HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE))
- gBattlescriptCurrInstr = BattleScript_MoveUsedPowder;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_THROAT_CHOP:
- if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && gMovesInfo[gCurrentMove].soundMove)
- {
- gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE;
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_Z_MOVES:
- if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE
- && gBattleStruct->obedienceResult == OBEYS)
- {
- // For Z-Mirror Move, so it doesn't play the animation twice.
- bool32 alreadyUsed = HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE);
-
- // attacker has a queued z move
- RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_Z_CRYSTAL);
- SetGimmickAsActivated(gBattlerAttacker, GIMMICK_Z_MOVE);
-
- gBattleScripting.battler = gBattlerAttacker;
- if (gProtectStructs[gBattlerAttacker].powderSelfDmg)
- {
- if (!alreadyUsed)
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ZMoveActivatePowder;
- }
- }
- else if (gMovesInfo[gCurrentMove].category == DAMAGE_CATEGORY_STATUS)
- {
- if (!alreadyUsed)
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus;
- }
- }
- else
- {
- if (!alreadyUsed)
- {
- BattleScriptPushCursor();
- gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging;
- }
- }
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_EXPLODING_DAMP:
- {
- u32 dampBattler = IsAbilityOnField(ABILITY_DAMP);
- if (dampBattler && (gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION
- || gMovesInfo[gCurrentMove].effect == EFFECT_MIND_BLOWN))
- {
- gBattleScripting.battler = dampBattler - 1;
- gBattlescriptCurrInstr = BattleScript_DampStopsExplosion;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- }
- case CANCELLER_MULTIHIT_MOVES:
- if (gMovesInfo[gCurrentMove].effect == EFFECT_MULTI_HIT)
- {
- u32 ability = GetBattlerAbility(gBattlerAttacker);
-
- if (ability == ABILITY_SKILL_LINK)
- {
- gMultiHitCounter = 5;
- }
- else if (ability == ABILITY_BATTLE_BOND
- && gCurrentMove == MOVE_WATER_SHURIKEN
- && gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_ASH)
- {
- gMultiHitCounter = 3;
- }
- else
- {
- SetRandomMultiHitCounter();
- }
-
- PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
- }
- else if (gMovesInfo[gCurrentMove].strikeCount > 1)
- {
- if (gMovesInfo[gCurrentMove].effect == EFFECT_POPULATION_BOMB && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE)
- {
- gMultiHitCounter = RandomUniform(RNG_LOADED_DICE, 4, 10);
- }
- else
- {
- gMultiHitCounter = gMovesInfo[gCurrentMove].strikeCount;
-
- if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS
- && CanTargetPartner(gBattlerAttacker, gBattlerTarget)
- && TargetFullyImmuneToCurrMove(gBattlerAttacker, gBattlerTarget))
- gBattlerTarget = BATTLE_PARTNER(gBattlerTarget);
- }
-
- PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0)
- }
- else if (B_BEAT_UP >= GEN_5 && gMovesInfo[gCurrentMove].effect == EFFECT_BEAT_UP)
- {
- struct Pokemon* party = GetBattlerParty(gBattlerAttacker);
- int i;
-
- for (i = 0; i < PARTY_SIZE; i++)
- {
- if (GetMonData(&party[i], MON_DATA_HP)
- && GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
- && !GetMonData(&party[i], MON_DATA_IS_EGG)
- && !GetMonData(&party[i], MON_DATA_STATUS))
- gMultiHitCounter++;
- }
-
- gBattleStruct->beatUpSlot = 0;
- PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
}
else
{
- gMultiHitCounter = 0;
+ TryDeactivateSleepClause(GetBattlerSide(gBattlerAttacker), gBattlerPartyIndexes[gBattlerAttacker]);
+ gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
+ BattleScriptPushCursor();
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP;
+ gBattlescriptCurrInstr = BattleScript_MoveUsedWokeUp;
+ *effect = 2;
}
- gBattleStruct->atkCancellerTracker++;
+ }
+ }
+}
+
+static void CancellerFrozen(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE && !MoveThawsUser(gCurrentMove))
+ {
+ if (!RandomPercentage(RNG_FROZEN, 20))
+ {
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen;
+ gHitMarker |= (HITMARKER_NO_ATTACKSTRING | HITMARKER_UNABLE_TO_USE_MOVE);
+ }
+ else // unfreeze
+ {
+ gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED;
+ }
+ *effect = 2;
+ }
+}
+
+static void CancellerObedience(u32 *effect)
+{
+ u32 obedienceResult = GetAttackerObedienceForAction();
+ if (obedienceResult != OBEYS
+ && !(gHitMarker & HITMARKER_NO_PPDEDUCT) // Don't check obedience after first hit of multi target move or multi hit moves
+ && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
+ {
+ switch (obedienceResult)
+ {
+ case DISOBEYS_LOAFS:
+ // Randomly select, then print a disobedient string
+ // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
+ gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
break;
- case CANCELLER_END:
+ case DISOBEYS_HITS_SELF:
+ gBattlerTarget = gBattlerAttacker;
+ struct DamageCalculationData damageCalcData;
+ damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker;
+ damageCalcData.move = MOVE_NONE;
+ damageCalcData.moveType = TYPE_MYSTERY;
+ damageCalcData.isCrit = FALSE;
+ damageCalcData.randomFactor = FALSE;
+ damageCalcData.updateFlags = TRUE;
+ gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&damageCalcData, 40);
+ gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ gHitMarker |= HITMARKER_OBEYS;
+ break;
+ case DISOBEYS_FALL_ASLEEP:
+ if (IsSleepClauseEnabled())
+ gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
+ break;
+ case DISOBEYS_WHILE_ASLEEP:
+ gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
+ break;
+ case DISOBEYS_RANDOM_MOVE:
+ gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
+ SetAtkCancellerForCalledMove();
+ gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
+ gBattlerTarget = GetBattleMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
+ gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
+ gHitMarker |= HITMARKER_OBEYS;
break;
}
+ *effect = 1;
+ }
+ else
+ {
+ gHitMarker |= HITMARKER_OBEYS;
+ }
+}
- } while (gBattleStruct->atkCancellerTracker != CANCELLER_END && gBattleStruct->atkCancellerTracker != CANCELLER_END2 && effect == 0);
+static void CancellerTruant(u32 *effect)
+{
+ if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter)
+ {
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LOAFING;
+ gBattlerAbility = gBattlerAttacker;
+ gBattlescriptCurrInstr = BattleScript_TruantLoafingAround;
+ gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED;
+ *effect = 1;
+ }
+}
+
+static void CancellerFlinch(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED)
+ {
+ gProtectStructs[gBattlerAttacker].flinchImmobility = TRUE;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerInLove(u32 *effect)
+{
+ if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
+ {
+ gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10);
+ if (!RandomPercentage(RNG_INFATUATION, 50))
+ {
+ BattleScriptPushCursor();
+ }
+ else
+ {
+ BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack);
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ gProtectStructs[gBattlerAttacker].loveImmobility = TRUE;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ }
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove;
+ *effect = 1;
+ }
+}
+
+static void CancellerDisabled(u32 *effect)
+{
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].disabledMove == gCurrentMove && gDisableStructs[gBattlerAttacker].disabledMove != MOVE_NONE)
+ {
+ gProtectStructs[gBattlerAttacker].usedDisabledMove = TRUE;
+ gBattleScripting.battler = gBattlerAttacker;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerHealBlocked(u32 *effect)
+{
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove))
+ {
+ gProtectStructs[gBattlerAttacker].usedHealBlockedMove = TRUE;
+ gBattleScripting.battler = gBattlerAttacker;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedHealBlockPrevents;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerGravity(u32 *effect)
+{
+ if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove))
+ {
+ gProtectStructs[gBattlerAttacker].usedGravityPreventedMove = TRUE;
+ gBattleScripting.battler = gBattlerAttacker;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedGravityPrevents;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerThroatChop(u32 *effect)
+{
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && IsSoundMove(gCurrentMove))
+ {
+ gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerTaunted(u32 *effect)
+{
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IsBattleMoveStatus(gCurrentMove))
+ {
+ gProtectStructs[gBattlerAttacker].usedTauntedMove = TRUE;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerImprisoned(u32 *effect)
+{
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(gBattlerAttacker, gCurrentMove))
+ {
+ gProtectStructs[gBattlerAttacker].usedImprisonedMove = TRUE;
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerConfused(u32 *effect)
+{
+ if (gBattleStruct->isAtkCancelerForCalledMove)
+ return;
+
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
+ {
+ if (!(gStatuses4[gBattlerAttacker] & STATUS4_INFINITE_CONFUSION))
+ gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1);
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
+ {
+ // confusion dmg
+ if (RandomPercentage(RNG_CONFUSION, (B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50)))
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = TRUE;
+ gBattlerTarget = gBattlerAttacker;
+ struct DamageCalculationData damageCalcData;
+ damageCalcData.battlerAtk = damageCalcData.battlerDef = gBattlerAttacker;
+ damageCalcData.move = MOVE_NONE;
+ damageCalcData.moveType = TYPE_MYSTERY;
+ damageCalcData.isCrit = FALSE;
+ damageCalcData.randomFactor = FALSE;
+ damageCalcData.updateFlags = TRUE;
+ gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&damageCalcData, 40);
+ gProtectStructs[gBattlerAttacker].confusionSelfDmg = TRUE;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ }
+ else
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = FALSE;
+ BattleScriptPushCursor();
+ }
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfused;
+ }
+ else // snapped out of confusion
+ {
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsConfusedNoMore;
+ }
+ *effect = 1;
+ }
+}
+
+static void CancellerParalysed(u32 *effect)
+{
+ if (!gBattleStruct->isAtkCancelerForCalledMove
+ && (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS)
+ && (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD && B_MAGIC_GUARD >= GEN_4)
+ && !RandomPercentage(RNG_PARALYSIS, 75))
+ {
+ gProtectStructs[gBattlerAttacker].prlzImmobility = TRUE;
+ // This is removed in FRLG and Emerald for some reason
+ //CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerBide(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
+ {
+ gBattleMons[gBattlerAttacker].status2 -= STATUS2_BIDE_TURN(1);
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
+ {
+ gBattlescriptCurrInstr = BattleScript_BideStoringEnergy;
+ }
+ else
+ {
+ // This is removed in FRLG and Emerald for some reason
+ //gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS;
+ if (gBideDmg[gBattlerAttacker])
+ {
+ gCurrentMove = MOVE_BIDE;
+ gBattlerTarget = gBideTarget[gBattlerAttacker];
+ if (gAbsentBattlerFlags & (1u << gBattlerTarget))
+ gBattlerTarget = GetBattleMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1);
+ gBattlescriptCurrInstr = BattleScript_BideAttack;
+ }
+ else
+ {
+ gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack;
+ }
+ }
+ *effect = 1;
+ }
+}
+
+static void CancellerThaw(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE)
+ {
+ if (!(IsMoveEffectRemoveSpeciesType(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
+ {
+ gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FREEZE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MoveUsedUnfroze;
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE;
+ }
+ *effect = 2;
+ }
+ if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && MoveThawsUser(gCurrentMove))
+ {
+ if (!(IsMoveEffectRemoveSpeciesType(gCurrentMove, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_FIRE)))
+ {
+ gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_FROSTBITE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MoveUsedUnfrostbite;
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE;
+ }
+ *effect = 2;
+ }
+}
+
+static void CancellerStanceChangeTwo(u32 *effect)
+{
+ if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryFormChangeBeforeMove())
+ *effect = 1;
+}
+
+static void CancellerWeatherPrimal(u32 *effect)
+{
+ if (WEATHER_HAS_EFFECT && GetMovePower(gCurrentMove) > 0)
+ {
+ u32 moveType = GetBattleMoveType(gCurrentMove);
+ if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL))
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN;
+ *effect = 1;
+ }
+ else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL))
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN;
+ *effect = 1;
+ }
+ if (*effect == 1)
+ {
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove;
+ }
+ }
+}
+
+static void CancellerDynamaxBlocked(u32 *effect)
+{
+ if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove))
+ {
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax;
+ *effect = 1;
+ }
+}
+
+static void CancellerPowderMove(u32 *effect)
+{
+ if (IsPowderMove(gCurrentMove) && (gBattlerAttacker != gBattlerTarget))
+ {
+ if (B_POWDER_GRASS >= GEN_6
+ && (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_GRASS) || GetBattlerAbility(gBattlerTarget) == ABILITY_OVERCOAT))
+ {
+ gBattlerAbility = gBattlerTarget;
+ *effect = 1;
+ }
+ else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_SAFETY_GOGGLES)
+ {
+ RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_SAFETY_GOGGLES);
+ gLastUsedItem = gBattleMons[gBattlerTarget].item;
+ *effect = 1;
+ }
+
+ if (*effect != 0)
+ gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect;
+ }
+}
+
+static void CancellerPowderStatus(u32 *effect)
+{
+ if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER)
+ {
+ u32 partnerMove = gBattleMons[BATTLE_PARTNER(gBattlerAttacker)].moves[gBattleStruct->chosenMovePositions[BATTLE_PARTNER(gBattlerAttacker)]];
+ if ((GetBattleMoveType(gCurrentMove) == TYPE_FIRE && !gBattleStruct->pledgeMove)
+ || (gCurrentMove == MOVE_FIRE_PLEDGE && partnerMove == MOVE_GRASS_PLEDGE)
+ || (gCurrentMove == MOVE_GRASS_PLEDGE && partnerMove == MOVE_FIRE_PLEDGE && gBattleStruct->pledgeMove))
+ {
+ gProtectStructs[gBattlerAttacker].powderSelfDmg = TRUE;
+ if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
+ && (B_POWDER_RAIN < GEN_7 || !IsBattlerWeatherAffected(gBattlerAttacker, B_WEATHER_RAIN_PRIMAL)))
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
+
+ if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE
+ || HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE))
+ gBattlescriptCurrInstr = BattleScript_MoveUsedPowder;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+ }
+}
+
+static void CancellerProtean(u32 *effect)
+{
+ u32 moveType = GetBattleMoveType(gCurrentMove);
+ if (ProteanTryChangeType(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), gCurrentMove, moveType))
+ {
+ if (B_PROTEAN_LIBERO == GEN_9)
+ gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE;
+ PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType);
+ gBattlerAbility = gBattlerAttacker;
+ BattleScriptPushCursor();
+ PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker);
+ gBattleCommunication[MSG_DISPLAY] = 1;
+ gBattlescriptCurrInstr = BattleScript_ProteanActivates;
+ *effect = 1;
+ }
+}
+
+static void CancellerPsychicTerrain(u32 *effect)
+{
+ if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
+ && IsBattlerGrounded(gBattlerTarget)
+ && GetChosenMovePriority(gBattlerAttacker) > 0
+ && GetMoveTarget(gCurrentMove) != MOVE_TARGET_ALL_BATTLERS
+ && GetMoveTarget(gCurrentMove) != MOVE_TARGET_OPPONENTS_FIELD
+ && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
+ {
+ CancelMultiTurnMoves(gBattlerAttacker);
+ gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerExplodingDamp(u32 *effect)
+{
+ u32 dampBattler = IsAbilityOnField(ABILITY_DAMP);
+ if (dampBattler && (GetMoveEffect(gCurrentMove) == EFFECT_EXPLOSION
+ || GetMoveEffect(gCurrentMove) == EFFECT_MIND_BLOWN))
+ {
+ gBattleScripting.battler = dampBattler - 1;
+ gBattlescriptCurrInstr = BattleScript_DampStopsExplosion;
+ gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
+ *effect = 1;
+ }
+}
+
+static void CancellerMultihitMoves(u32 *effect)
+{
+ if (GetMoveEffect(gCurrentMove) == EFFECT_MULTI_HIT)
+ {
+ u32 ability = GetBattlerAbility(gBattlerAttacker);
+
+ if (ability == ABILITY_SKILL_LINK)
+ {
+ gMultiHitCounter = 5;
+ }
+ else if (ability == ABILITY_BATTLE_BOND
+ && gCurrentMove == MOVE_WATER_SHURIKEN
+ && gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_ASH)
+ {
+ gMultiHitCounter = 3;
+ }
+ else
+ {
+ SetRandomMultiHitCounter();
+ }
+
+ PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
+ }
+ else if (GetMoveStrikeCount(gCurrentMove) > 1)
+ {
+ if (GetMoveEffect(gCurrentMove) == EFFECT_POPULATION_BOMB && GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_LOADED_DICE)
+ {
+ gMultiHitCounter = RandomUniform(RNG_LOADED_DICE, 4, 10);
+ }
+ else
+ {
+ gMultiHitCounter = GetMoveStrikeCount(gCurrentMove);
+
+ if (GetMoveEffect(gCurrentMove) == EFFECT_DRAGON_DARTS
+ && CanTargetPartner(gBattlerAttacker, gBattlerTarget)
+ && TargetFullyImmuneToCurrMove(gBattlerAttacker, gBattlerTarget))
+ gBattlerTarget = BATTLE_PARTNER(gBattlerTarget);
+ }
+
+ PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0)
+ }
+ else if (B_BEAT_UP >= GEN_5 && GetMoveEffect(gCurrentMove) == EFFECT_BEAT_UP)
+ {
+ struct Pokemon* party = GetBattlerParty(gBattlerAttacker);
+ int i;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (GetMonData(&party[i], MON_DATA_HP)
+ && GetMonData(&party[i], MON_DATA_SPECIES) != SPECIES_NONE
+ && !GetMonData(&party[i], MON_DATA_IS_EGG)
+ && !GetMonData(&party[i], MON_DATA_STATUS))
+ gMultiHitCounter++;
+ }
+
+ gBattleStruct->beatUpSlot = 0;
+ PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0)
+ }
+ else
+ {
+ gMultiHitCounter = 0;
+ }
+}
+
+static void CancellerZMoves(u32 *effect)
+{
+ if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE)
+ {
+ // For Z-Mirror Move, so it doesn't play the animation twice.
+ bool32 alreadyUsed = HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE);
+
+ // attacker has a queued z move
+ RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_Z_CRYSTAL);
+ SetGimmickAsActivated(gBattlerAttacker, GIMMICK_Z_MOVE);
+
+ gBattleScripting.battler = gBattlerAttacker;
+ if (gProtectStructs[gBattlerAttacker].powderSelfDmg)
+ {
+ if (!alreadyUsed)
+ {
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_ZMoveActivatePowder;
+ }
+ }
+ else if (GetMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_STATUS)
+ {
+ if (!alreadyUsed)
+ {
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_ZMoveActivateStatus;
+ }
+ }
+ else
+ {
+ if (!alreadyUsed)
+ {
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_ZMoveActivateDamaging;
+ }
+ }
+ *effect = 1;
+ }
+}
+
+static void CancellerMultiTargetMoves(u32 *effect)
+{
+ u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
+ if (IsSpreadMove(moveTarget))
+ {
+ for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
+ {
+ if (gBattleStruct->bouncedMoveIsUsed && B_SIDE_OPPONENT == GetBattlerSide(battlerDef))
+ continue;
+
+ if (gBattlerAttacker == battlerDef
+ || !IsBattlerAlive(battlerDef)
+ || (moveTarget == MOVE_TARGET_BOTH && gBattlerAttacker == BATTLE_PARTNER(battlerDef))
+ || IsBattlerProtected(gBattlerAttacker, battlerDef, gCurrentMove)) // Missing Invulnerable check
+ {
+ gBattleStruct->moveResultFlags[battlerDef] = MOVE_RESULT_NO_EFFECT;
+ gBattleStruct->noResultString[battlerDef] = TRUE;
+ }
+ else if (AbilityBattleEffects(ABILITYEFFECT_WOULD_BLOCK, battlerDef, 0, 0, 0)
+ || (IsBattlerTerrainAffected(gBattlerAttacker, STATUS_FIELD_PSYCHIC_TERRAIN) && GetBattleMovePriority(gBattlerAttacker, gCurrentMove) > 0))
+ {
+ gBattleStruct->moveResultFlags[battlerDef] = 0;
+ gBattleStruct->noResultString[battlerDef] = TRUE;
+ }
+ else if (AbilityBattleEffects(ABILITYEFFECT_WOULD_ABSORB, battlerDef, 0, 0, gCurrentMove))
+ {
+ gBattleStruct->moveResultFlags[battlerDef] = 0;
+ gBattleStruct->noResultString[battlerDef] = DO_ACCURACY_CHECK;
+ }
+ else
+ {
+ CalcTypeEffectivenessMultiplier(gCurrentMove, GetMoveType(gCurrentMove), gBattlerAttacker, battlerDef, GetBattlerAbility(battlerDef), TRUE);
+ }
+ }
+ if (moveTarget == MOVE_TARGET_BOTH)
+ gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER_SIDE, gBattlerAttacker);
+ else
+ gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, gBattlerAttacker);
+ }
+}
+
+static const MoveSuccessOrderCancellers sMoveSuccessOrderCancellers[] =
+{
+ [CANCELLER_FLAGS] = CancellerFlags,
+ [CANCELLER_STANCE_CHANGE_1] = CancellerStanceChangeOne,
+ [CANCELLER_SKY_DROP] = CancellerSkyDrop,
+ [CANCELLER_RECHARGE] = CancellerRecharge,
+ [CANCELLER_ASLEEP] = CancellerAsleep,
+ [CANCELLER_FROZEN] = CancellerFrozen,
+ [CANCELLER_OBEDIENCE] = CancellerObedience,
+ [CANCELLER_TRUANT] = CancellerTruant,
+ [CANCELLER_FLINCH] = CancellerFlinch,
+ [CANCELLER_IN_LOVE] = CancellerInLove,
+ [CANCELLER_DISABLED] = CancellerDisabled,
+ [CANCELLER_HEAL_BLOCKED] = CancellerHealBlocked,
+ [CANCELLER_GRAVITY] = CancellerGravity,
+ [CANCELLER_THROAT_CHOP] = CancellerThroatChop,
+ [CANCELLER_TAUNTED] = CancellerTaunted,
+ [CANCELLER_IMPRISONED] = CancellerImprisoned,
+ [CANCELLER_CONFUSED] = CancellerConfused,
+ [CANCELLER_PARALYSED] = CancellerParalysed,
+ [CANCELLER_BIDE] = CancellerBide,
+ [CANCELLER_THAW] = CancellerThaw,
+ [CANCELLER_STANCE_CHANGE_2] = CancellerStanceChangeTwo,
+ [CANCELLER_WEATHER_PRIMAL] = CancellerWeatherPrimal,
+ [CANCELLER_DYNAMAX_BLOCKED] = CancellerDynamaxBlocked,
+ [CANCELLER_POWDER_MOVE] = CancellerPowderMove,
+ [CANCELLER_POWDER_STATUS] = CancellerPowderStatus,
+ [CANCELLER_PROTEAN] = CancellerProtean,
+ [CANCELLER_PSYCHIC_TERRAIN] = CancellerPsychicTerrain,
+ [CANCELLER_EXPLODING_DAMP] = CancellerExplodingDamp,
+ [CANCELLER_MULTIHIT_MOVES] = CancellerMultihitMoves,
+ [CANCELLER_Z_MOVES] = CancellerZMoves,
+ [CANCELLER_MULTI_TARGET_MOVES] = CancellerMultiTargetMoves,
+};
+
+u32 AtkCanceller_MoveSuccessOrder(void)
+{
+ u32 effect = 0;
+
+ while (gBattleStruct->atkCancellerTracker < CANCELLER_END && effect == 0)
+ {
+ sMoveSuccessOrderCancellers[gBattleStruct->atkCancellerTracker](&effect);
+ gBattleStruct->atkCancellerTracker++;
+ }
if (effect == 2)
{
BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerAttacker].status1);
MarkBattlerForControllerExec(gBattlerAttacker);
}
- return effect;
-}
-
-// After Protean Activation.
-u8 AtkCanceller_UnableToUseMove2(void)
-{
- u8 effect = 0;
-
- do
- {
- switch (gBattleStruct->atkCancellerTracker)
- {
- case CANCELLER_END:
- gBattleStruct->atkCancellerTracker++;
- case CANCELLER_PSYCHIC_TERRAIN:
- if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN
- && IsBattlerGrounded(gBattlerTarget)
- && GetChosenMovePriority(gBattlerAttacker) > 0
- && gMovesInfo[gCurrentMove].target != MOVE_TARGET_ALL_BATTLERS
- && gMovesInfo[gCurrentMove].target != MOVE_TARGET_OPPONENTS_FIELD
- && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
- {
- CancelMultiTurnMoves(gBattlerAttacker);
- gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents;
- gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
- effect = 1;
- }
- gBattleStruct->atkCancellerTracker++;
- break;
- case CANCELLER_END2:
- break;
- }
-
- } while (gBattleStruct->atkCancellerTracker != CANCELLER_END2 && effect == 0);
return effect;
}
@@ -3913,7 +4054,7 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer)
{
if ((!(gFieldStatuses & statusFlag) && (!gBattleStruct->isSkyBattle)))
{
- gFieldStatuses &= ~(STATUS_FIELD_TERRAIN_ANY | STATUS_FIELD_TERRAIN_PERMANENT);
+ gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY;
gFieldStatuses |= statusFlag;
gDisableStructs[battler].terrainAbilityDone = FALSE;
@@ -3950,7 +4091,7 @@ static void ForewarnChooseMove(u32 battler)
continue;
data[count].moveId = gBattleMons[i].moves[j];
data[count].battler = i;
- switch (gMovesInfo[data[count].moveId].effect)
+ switch (GetMoveEffect(data[count].moveId))
{
case EFFECT_OHKO:
data[count].power = 150;
@@ -3961,12 +4102,15 @@ static void ForewarnChooseMove(u32 battler)
data[count].power = 120;
break;
default:
- if (gMovesInfo[data[count].moveId].power == 1)
+ {
+ u32 movePower = GetMovePower(data[count].moveId);
+ if (movePower == 1)
data[count].power = 80;
else
- data[count].power = gMovesInfo[data[count].moveId].power;
+ data[count].power = movePower;
break;
}
+ }
count++;
}
}
@@ -4020,7 +4164,7 @@ static inline u8 GetBattlerSideFaintCounter(u32 battler)
// Supreme Overlord adds a x0.1 damage boost for each fainted ally.
static inline uq4_12_t GetSupremeOverlordModifier(u32 battler)
{
- return UQ_4_12(1.0) + (UQ_4_12(0.1) * gBattleStruct->supremeOverlordCounter[battler]);
+ return UQ_4_12(1.0) + (PercentToUQ4_12(gBattleStruct->supremeOverlordCounter[battler] * 10));
}
static inline bool32 HadMoreThanHalfHpNowDoesnt(u32 battler)
@@ -4086,11 +4230,11 @@ u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef
switch (abilityDef)
{
case ABILITY_SOUNDPROOF:
- if (gMovesInfo[move].soundMove && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER))
+ if (IsSoundMove(move) && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER))
effect = MOVE_BLOCKED_BY_SOUNDPROOF_OR_BULLETPROOF;
break;
case ABILITY_BULLETPROOF:
- if (gMovesInfo[move].ballisticMove)
+ if (IsBallisticMove(move))
effect = MOVE_BLOCKED_BY_SOUNDPROOF_OR_BULLETPROOF;
break;
case ABILITY_DAZZLING:
@@ -4098,13 +4242,13 @@ u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef
case ABILITY_ARMOR_TAIL:
if (GetBattlerSide(battlerAtk) != GetBattlerSide(battlerDef))
{
- u32 priority = AI_DATA->aiCalcInProgress ? GetMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk);
+ u32 priority = AI_DATA->aiCalcInProgress ? GetBattleMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk);
if (priority > 0)
effect = MOVE_BLOCKED_BY_DAZZLING;
}
break;
case ABILITY_GOOD_AS_GOLD:
- if (IS_MOVE_STATUS(move))
+ if (IsBattleMoveStatus(move))
{
u32 moveTarget = GetBattlerMoveTargetType(battlerAtk, move);
if (!(moveTarget & MOVE_TARGET_OPPONENTS_FIELD) && !(moveTarget & MOVE_TARGET_ALL_BATTLERS))
@@ -4128,7 +4272,7 @@ u32 CanPartnerAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abi
case ABILITY_ARMOR_TAIL:
if (GetBattlerSide(battlerAtk) != GetBattlerSide(battlerDef))
{
- s32 priority = AI_DATA->aiCalcInProgress ? GetMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk);
+ s32 priority = AI_DATA->aiCalcInProgress ? GetBattleMovePriority(battlerAtk, move) : GetChosenMovePriority(battlerAtk);
if (priority > 0)
return MOVE_BLOCKED_BY_PARTNER_DAZZLING;
}
@@ -4147,7 +4291,7 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov
effect = MOVE_ABSORBED_BY_NO_ABILITY;
break;
case ABILITY_VOLT_ABSORB:
- if (moveType == TYPE_ELECTRIC && gMovesInfo[move].target != MOVE_TARGET_ALL_BATTLERS)
+ if (moveType == TYPE_ELECTRIC && GetMoveTarget(move) != MOVE_TARGET_ALL_BATTLERS)
effect = MOVE_ABSORBED_BY_DRAIN_HP_ABILITY;
break;
case ABILITY_WATER_ABSORB:
@@ -4160,11 +4304,11 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov
effect = MOVE_ABSORBED_BY_DRAIN_HP_ABILITY;
break;
case ABILITY_MOTOR_DRIVE:
- if (moveType == TYPE_ELECTRIC && gMovesInfo[move].target != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction)
+ if (moveType == TYPE_ELECTRIC && GetMoveTarget(move) != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction)
effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY;
break;
case ABILITY_LIGHTNING_ROD:
- if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && moveType == TYPE_ELECTRIC && gMovesInfo[move].target != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction)
+ if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && moveType == TYPE_ELECTRIC && GetMoveTarget(move) != MOVE_TARGET_ALL_BATTLERS) // Potential bug in singles (might be solved with simu hp reudction)
effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY;
break;
case ABILITY_STORM_DRAIN:
@@ -4180,7 +4324,7 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov
effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY;
break;
case ABILITY_WIND_RIDER:
- if (gMovesInfo[move].windMove && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER))
+ if (IsWindMove(move) && !(GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_USER))
effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY;
break;
case ABILITY_FLASH_FIRE:
@@ -4192,6 +4336,43 @@ u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 mov
return effect;
}
+static inline u32 SetStartingFieldStatus(u32 flag, u32 message, u32 anim, u8 *timer)
+{
+ if (!(gFieldStatuses & flag))
+ {
+ gBattleCommunication[MULTISTRING_CHOOSER] = message;
+ gFieldStatuses |= flag;
+ gBattleScripting.animArg1 = anim;
+ if (gBattleStruct->startingStatusTimer)
+ *timer = gBattleStruct->startingStatusTimer;
+ else
+ *timer = 0; // Infinite
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline u32 SetStartingSideStatus(u32 flag, u32 side, u32 message, u32 anim, u8 *timer)
+{
+ if (!(gSideStatuses[side] & flag))
+ {
+ gBattlerAttacker = gBattlerTarget = side;
+ gBattleCommunication[MULTISTRING_CHOOSER] = message;
+ gSideStatuses[side] |= flag;
+ gBattleScripting.animArg1 = anim;
+ if (gBattleStruct->startingStatusTimer)
+ *timer = gBattleStruct->startingStatusTimer;
+ else
+ *timer = 0; // Infinite
+
+ return 1;
+ }
+
+ return 0;
+}
+
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg)
{
u32 effect = 0;
@@ -4217,131 +4398,116 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
else
move = gCurrentMove;
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
switch (caseID)
{
case ABILITYEFFECT_SWITCH_IN_STATUSES: // starting field/side/etc statuses with a variable
{
- u8 timerVal = gBattleStruct->startingStatusTimer;
-
gBattleScripting.battler = battler;
switch (gBattleStruct->startingStatus)
{
case STARTING_STATUS_ELECTRIC_TERRAIN:
- if (!(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC;
- gFieldStatuses |= STATUS_FIELD_ELECTRIC_TERRAIN;
- if (timerVal == 0)
- gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT;
- else
- gFieldTimers.terrainTimer = timerVal;
- effect = 2;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_ELECTRIC_TERRAIN,
+ B_MSG_TERRAIN_SET_ELECTRIC,
+ 0,
+ &gFieldTimers.terrainTimer);
+ effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_MISTY_TERRAIN:
- if (!(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY;
- gFieldStatuses |= STATUS_FIELD_MISTY_TERRAIN;
- if (timerVal == 0)
- gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT;
- else
- gFieldTimers.terrainTimer = timerVal;
- effect = 2;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_MISTY_TERRAIN,
+ B_MSG_TERRAIN_SET_MISTY,
+ 0,
+ &gFieldTimers.terrainTimer);
+ effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_GRASSY_TERRAIN:
- if (!(gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_GRASSY;
- gFieldStatuses |= STATUS_FIELD_GRASSY_TERRAIN;
- if (timerVal == 0)
- gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT;
- else
- gFieldTimers.terrainTimer = timerVal;
- effect = 2;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_GRASSY_TERRAIN,
+ B_MSG_TERRAIN_SET_GRASSY,
+ 0,
+ &gFieldTimers.terrainTimer);
+ effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_PSYCHIC_TERRAIN:
- if (!(gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_PSYCHIC;
- gFieldStatuses |= STATUS_FIELD_PSYCHIC_TERRAIN;
- if (timerVal == 0)
- gFieldStatuses |= STATUS_FIELD_TERRAIN_PERMANENT;
- else
- gFieldTimers.terrainTimer = timerVal;
- effect = 2;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_PSYCHIC_TERRAIN,
+ B_MSG_TERRAIN_SET_PSYCHIC,
+ 0,
+ &gFieldTimers.terrainTimer);
+ effect = (effect == 1) ? 2 : 0;
break;
case STARTING_STATUS_TRICK_ROOM:
- if (!(gFieldStatuses & STATUS_FIELD_TRICK_ROOM))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TRICK_ROOM;
- gFieldStatuses |= STATUS_FIELD_TRICK_ROOM;
- gBattleScripting.animArg1 = B_ANIM_TRICK_ROOM;
- if (timerVal == 0)
- gFieldTimers.trickRoomTimer = 0; // infinite
- else
- gFieldTimers.trickRoomTimer = 5;
- effect = 1;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_TRICK_ROOM,
+ B_MSG_SET_TRICK_ROOM,
+ B_ANIM_TRICK_ROOM,
+ &gFieldTimers.trickRoomTimer);
break;
case STARTING_STATUS_MAGIC_ROOM:
- if (!(gFieldStatuses & STATUS_FIELD_MAGIC_ROOM))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MAGIC_ROOM;
- gFieldStatuses |= STATUS_FIELD_MAGIC_ROOM;
- gBattleScripting.animArg1 = B_ANIM_MAGIC_ROOM;
- if (timerVal == 0)
- gFieldTimers.magicRoomTimer = 0; // infinite
- else
- gFieldTimers.magicRoomTimer = 5;
- effect = 1;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_MAGIC_ROOM,
+ B_MSG_SET_MAGIC_ROOM,
+ B_ANIM_MAGIC_ROOM,
+ &gFieldTimers.magicRoomTimer);
break;
case STARTING_STATUS_WONDER_ROOM:
- if (!(gFieldStatuses & STATUS_FIELD_WONDER_ROOM))
- {
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_WONDER_ROOM;
- gFieldStatuses |= STATUS_FIELD_WONDER_ROOM;
- gBattleScripting.animArg1 = B_ANIM_WONDER_ROOM;
- if (timerVal == 0)
- gFieldTimers.wonderRoomTimer = 0; // infinite
- else
- gFieldTimers.wonderRoomTimer = 5;
- effect = 1;
- }
+ effect = SetStartingFieldStatus(STATUS_FIELD_WONDER_ROOM,
+ B_MSG_SET_WONDER_ROOM,
+ B_ANIM_WONDER_ROOM,
+ &gFieldTimers.wonderRoomTimer);
break;
case STARTING_STATUS_TAILWIND_PLAYER:
- if (!(gSideStatuses[B_SIDE_PLAYER] & SIDE_STATUS_TAILWIND))
- {
- gBattlerAttacker = B_POSITION_PLAYER_LEFT;
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TAILWIND_PLAYER;
- gSideStatuses[B_SIDE_PLAYER] |= SIDE_STATUS_TAILWIND;
- gBattleScripting.animArg1 = B_ANIM_TAILWIND;
- if (timerVal == 0)
- gSideTimers[B_SIDE_PLAYER].tailwindTimer = 0; // infinite
- else
- gSideTimers[B_SIDE_PLAYER].tailwindTimer = 5;
- effect = 1;
- }
+ effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND,
+ B_SIDE_PLAYER,
+ B_MSG_SET_TAILWIND,
+ B_ANIM_TAILWIND,
+ &gSideTimers[B_SIDE_PLAYER].tailwindTimer);
break;
case STARTING_STATUS_TAILWIND_OPPONENT:
- if (!(gSideStatuses[B_SIDE_OPPONENT] & SIDE_STATUS_TAILWIND))
- {
- gBattlerAttacker = B_POSITION_OPPONENT_LEFT;
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_TAILWIND_OPPONENT;
- gSideStatuses[B_SIDE_OPPONENT] |= SIDE_STATUS_TAILWIND;
- gBattleScripting.animArg1 = B_ANIM_TAILWIND;
- if (timerVal == 0)
- gSideTimers[B_SIDE_OPPONENT].tailwindTimer = 0; // infinite
- else
- gSideTimers[B_SIDE_OPPONENT].tailwindTimer = 5;
- effect = 1;
- }
+ effect = SetStartingSideStatus(SIDE_STATUS_TAILWIND,
+ B_SIDE_OPPONENT,
+ B_MSG_SET_TAILWIND,
+ B_ANIM_TAILWIND,
+ &gSideTimers[B_SIDE_OPPONENT].tailwindTimer);
+ break;
+ case STARTING_STATUS_RAINBOW_PLAYER:
+ effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW,
+ B_SIDE_PLAYER,
+ B_MSG_SET_RAINBOW,
+ B_ANIM_RAINBOW,
+ &gSideTimers[B_SIDE_PLAYER].rainbowTimer);
+ break;
+ case STARTING_STATUS_RAINBOW_OPPONENT:
+ effect = SetStartingSideStatus(SIDE_STATUS_RAINBOW,
+ B_SIDE_OPPONENT,
+ B_MSG_SET_RAINBOW,
+ B_ANIM_RAINBOW,
+ &gSideTimers[B_SIDE_OPPONENT].rainbowTimer);
+ break;
+ case STARTING_STATUS_SEA_OF_FIRE_PLAYER:
+ effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE,
+ B_SIDE_PLAYER,
+ B_MSG_SET_SEA_OF_FIRE,
+ B_ANIM_SEA_OF_FIRE,
+ &gSideTimers[B_SIDE_PLAYER].seaOfFireTimer);
+ break;
+ case STARTING_STATUS_SEA_OF_FIRE_OPPONENT:
+ effect = SetStartingSideStatus(SIDE_STATUS_SEA_OF_FIRE,
+ B_SIDE_OPPONENT,
+ B_MSG_SET_SEA_OF_FIRE,
+ B_ANIM_SEA_OF_FIRE,
+ &gSideTimers[B_SIDE_OPPONENT].seaOfFireTimer);
+ break;
+ case STARTING_STATUS_SWAMP_PLAYER:
+ effect = SetStartingSideStatus(SIDE_STATUS_SWAMP,
+ B_SIDE_PLAYER,
+ B_MSG_SET_SWAMP,
+ B_ANIM_SWAMP,
+ &gSideTimers[B_SIDE_PLAYER].swampTimer);
+ break;
+ case STARTING_STATUS_SWAMP_OPPONENT:
+ effect = SetStartingSideStatus(SIDE_STATUS_SWAMP,
+ B_SIDE_OPPONENT,
+ B_MSG_SET_SWAMP,
+ B_ANIM_SWAMP,
+ &gSideTimers[B_SIDE_OPPONENT].swampTimer);
break;
}
@@ -4357,7 +4523,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& GetCurrentWeather() == WEATHER_RAIN_THUNDERSTORM)
{
// overworld weather started rain, so just do electric terrain anim
- gFieldStatuses = (STATUS_FIELD_ELECTRIC_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
+ gFieldStatuses = STATUS_FIELD_ELECTRIC_TERRAIN;
+ gFieldTimers.terrainTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_ELECTRIC;
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
effect++;
@@ -4366,7 +4533,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& (GetCurrentWeather() == WEATHER_FOG_HORIZONTAL || GetCurrentWeather() == WEATHER_FOG_DIAGONAL)
&& !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
{
- gFieldStatuses = (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_TERRAIN_PERMANENT);
+ gFieldStatuses = STATUS_FIELD_MISTY_TERRAIN;
+ gFieldTimers.terrainTimer = 0;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_TERRAIN_SET_MISTY;
BattleScriptPushCursorAndCallback(BattleScript_OverworldTerrain);
effect++;
@@ -4586,7 +4754,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
for (j = 0; j < MAX_MON_MOVES; j++)
{
move = gBattleMons[i].moves[j];
- moveType = GetMoveType(move);
+ moveType = GetBattleMoveType(move);
if (CalcTypeEffectivenessMultiplier(move, moveType, i, battler, ABILITY_ANTICIPATION, FALSE) >= UQ_4_12(2.0))
{
effect++;
@@ -5008,7 +5176,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
gBattlerTarget = partner;
gBattlerAttacker = battler;
gSpecialStatuses[battler].switchInAbilityDone = TRUE;
- gBattleMoveDamage = (GetNonDynamaxMaxHP(partner) / 4) * -1;
+ gBattleStruct->moveDamage[partner] = (GetNonDynamaxMaxHP(partner) / 4) * -1;
BattleScriptPushCursorAndCallback(BattleScript_HospitalityActivates);
effect++;
}
@@ -5122,14 +5290,14 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
// Dry Skin works similarly to Rain Dish in Rain
case ABILITY_RAIN_DISH:
if (IsBattlerWeatherAffected(battler, B_WEATHER_RAIN)
- && !BATTLER_MAX_HP(battler)
+ && !IsBattlerAtMaxHp(battler)
&& !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
{
BattleScriptPushCursorAndCallback(BattleScript_RainDishActivates);
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / (gLastUsedAbility == ABILITY_RAIN_DISH ? 16 : 8);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / (gLastUsedAbility == ABILITY_RAIN_DISH ? 16 : 8);
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
effect++;
}
break;
@@ -5148,7 +5316,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (gBattleMons[battler].status1 & (STATUS1_POISON | STATUS1_TOXIC_POISON))
StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
+ {
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
+ }
+
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS)
StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
if (gBattleMons[battler].status1 & STATUS1_BURN)
@@ -5225,9 +5397,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
{
SOLAR_POWER_HP_DROP:
BattleScriptPushCursorAndCallback(BattleScript_SolarPowerActivates);
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
effect++;
}
break;
@@ -5323,7 +5495,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
default:
if (GetChosenMovePriority(gBattlerAttacker) > 0
&& BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE)
- && !(IS_MOVE_STATUS(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove)))
+ && !(IsBattleMoveStatus(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove)))
{
if (!IsDoubleBattle()
|| !(GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)))
@@ -5373,7 +5545,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
{
case MOVE_ABSORBED_BY_DRAIN_HP_ABILITY:
gBattleStruct->pledgeMove = FALSE;
- if (BATTLER_MAX_HP(battler) || (B_HEAL_BLOCKING >= GEN_5 && gStatuses3[battler] & STATUS3_HEAL_BLOCK))
+ if (IsBattlerAtMaxHp(battler) || (B_HEAL_BLOCKING >= GEN_5 && gStatuses3[battler] & STATUS3_HEAL_BLOCK))
{
if ((gProtectStructs[gBattlerAttacker].notFirstStrike))
gBattlescriptCurrInstr = BattleScript_MonMadeMoveUseless;
@@ -5387,10 +5559,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
else
gBattlescriptCurrInstr = BattleScript_MoveHPDrain_PPLoss;
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 4;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
}
break;
case MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY:
@@ -5444,8 +5616,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
switch (gLastUsedAbility)
{
case ABILITY_JUSTIFIED:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& moveType == TYPE_DARK
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
@@ -5458,8 +5630,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_RATTLED:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& (moveType == TYPE_DARK || moveType == TYPE_BUG || moveType == TYPE_GHOST)
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
@@ -5472,8 +5644,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_WATER_COMPACTION:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& moveType == TYPE_WATER
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
@@ -5486,9 +5658,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_STAMINA:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(battler)
&& gBattlerAttacker != gBattlerTarget
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
{
@@ -5500,8 +5672,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_BERSERK:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& HadMoreThanHalfHpNowDoesnt(battler)
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
@@ -5517,8 +5689,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_EMERGENCY_EXIT:
case ABILITY_WIMP_OUT:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
// Had more than half of hp before, now has less
&& HadMoreThanHalfHpNowDoesnt(battler)
@@ -5535,14 +5707,14 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_WEAK_ARMOR:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
- && IS_MOVE_PHYSICAL(gCurrentMove)
+ && IsBattleMovePhysical(gCurrentMove)
&& (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN) // Don't activate if both Speed and Defense cannot be raised.
|| CompareStat(battler, STAT_DEF, MIN_STAT_STAGE, CMP_GREATER_THAN)))
{
- if (gMovesInfo[gCurrentMove].effect == EFFECT_HIT_ESCAPE && CanBattlerSwitch(gBattlerAttacker))
+ if (GetMoveEffect(gCurrentMove) == EFFECT_HIT_ESCAPE && CanBattlerSwitch(gBattlerAttacker))
gProtectStructs[battler].disableEjectPack = TRUE; // Set flag for target
BattleScriptPushCursor();
@@ -5551,8 +5723,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_CURSED_BODY:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& gDisableStructs[gBattlerAttacker].disabledMove == MOVE_NONE
&& IsBattlerAlive(gBattlerAttacker)
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
@@ -5570,9 +5742,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_LINGERING_AROMA:
case ABILITY_MUMMY:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(battler)
&& IsBattlerAlive(gBattlerAttacker)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker)
&& gBattleStruct->overwrittenAbilities[gBattlerAttacker] != GetBattlerAbility(gBattlerTarget)
@@ -5595,9 +5767,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_WANDERING_SPIRIT:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(battler)
&& IsBattlerAlive(gBattlerAttacker)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker)
&& !(GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)
@@ -5619,9 +5791,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_ANGER_POINT:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && gIsCriticalHit
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(battler)
+ && gSpecialStatuses[battler].criticalHit
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
@@ -5632,10 +5804,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_COLOR_CHANGE:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(battler)
&& move != MOVE_STRUGGLE
- && gMovesInfo[move].power != 0
- && TARGET_TURN_DAMAGED
+ && !IsBattleMoveStatus(move)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& !IS_BATTLER_OF_TYPE(battler, moveType)
&& moveType != TYPE_STELLAR
&& moveType != TYPE_MYSTERY
@@ -5650,11 +5822,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_GOOEY:
case ABILITY_TANGLING_HAIR:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& (CompareStat(gBattlerAttacker, STAT_SPEED, MIN_STAT_STAGE, CMP_GREATER_THAN) || GetBattlerAbility(gBattlerAttacker) == ABILITY_MIRROR_ARMOR)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
@@ -5668,16 +5840,16 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_ROUGH_SKIN:
case ABILITY_IRON_BARBS:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / (B_ROUGH_SKIN_DMG >= GEN_4 ? 8 : 16);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / (B_ROUGH_SKIN_DMG >= GEN_4 ? 8 : 16);
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RoughSkinActivates;
@@ -5685,13 +5857,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_AFTERMATH:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !IsBattlerAlive(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
- u32 battler;
if ((battler = IsAbilityOnField(ABILITY_DAMP)))
{
gBattleScripting.battler = battler - 1;
@@ -5700,9 +5871,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
else
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AftermathDmg;
}
@@ -5710,11 +5881,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_INNARDS_OUT:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !IsBattlerAlive(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker))
{
- gBattleMoveDamage = gSpecialStatuses[gBattlerTarget].shellBellDmg;
+ gBattleStruct->moveDamage[gBattlerAttacker] = gSpecialStatuses[gBattlerTarget].shellBellDmg;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AftermathDmg;
effect++;
@@ -5748,14 +5919,16 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
goto STATIC;
// Sleep
if (i < sleep
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ && MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
- && CanBeSlept(gBattlerAttacker, ability)
+ && IsBattlerTurnDamaged(gBattlerTarget)
+ && CanBeSlept(gBattlerAttacker, ability, NOT_BLOCKED_BY_SLEEP_CLAUSE)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
+ if (IsSleepClauseEnabled())
+ gBattleStruct->sleepClauseEffectExempt |= (1u << gBattlerAttacker);
gBattleScripting.moveEffect = MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_SLEEP;
PREPARE_ABILITY_BUFFER(gBattleTextBuff1, gLastUsedAbility);
BattleScriptPushCursor();
@@ -5770,10 +5943,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_POISON_POINT, 30) : RandomChance(RNG_POISON_POINT, 1, 3))
{
POISON_POINT:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& CanBePoisoned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
@@ -5791,10 +5964,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_STATIC, 30) : RandomChance(RNG_STATIC, 1, 3))
{
STATIC:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& CanBeParalyzed(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
@@ -5809,12 +5982,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_FLAME_BODY:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& (IsMoveMakingContact(move, gBattlerAttacker))
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& CanBeBurned(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker))
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_FLAME_BODY, 30) : RandomChance(RNG_FLAME_BODY, 1, 3)))
{
@@ -5827,10 +6000,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_CUTE_CHARM:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& (B_ABILITY_TRIGGER_CHANCE >= GEN_4 ? RandomPercentage(RNG_CUTE_CHARM, 30) : RandomChance(RNG_CUTE_CHARM, 1, 3))
&& !(gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION)
@@ -5847,7 +6020,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_ILLUSION:
- if (gBattleStruct->illusion[gBattlerTarget].on && !gBattleStruct->illusion[gBattlerTarget].broken && TARGET_TURN_DAMAGED)
+ if (gBattleStruct->illusion[gBattlerTarget].on && !gBattleStruct->illusion[gBattlerTarget].broken && IsBattlerTurnDamaged(gBattlerTarget))
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_IllusionOff;
@@ -5855,10 +6028,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_COTTON_DOWN:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED)
+ && IsBattlerTurnDamaged(gBattlerTarget))
{
gEffectBattler = gBattlerTarget;
BattleScriptPushCursor();
@@ -5867,8 +6040,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_STEAM_ENGINE:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(gBattlerTarget)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN)
&& (moveType == TYPE_FIRE || moveType == TYPE_WATER))
@@ -5881,9 +6054,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_SAND_SPIT:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& !(gBattleWeather & B_WEATHER_SANDSTORM && WEATHER_HAS_EFFECT))
{
if (gBattleWeather & B_WEATHER_PRIMAL_ANY && WEATHER_HAS_EFFECT)
@@ -5902,9 +6075,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_PERISH_BODY:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& (IsMoveMakingContact(move, gBattlerAttacker))
@@ -5923,17 +6096,17 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_GULP_MISSILE:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT)
{
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 4;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
}
switch(gBattleMons[gBattlerTarget].species)
@@ -5954,9 +6127,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_SEED_SOWER:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
{
@@ -5966,8 +6139,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_THERMAL_EXCHANGE:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
+ if (MoveResultHasEffect(gBattlerTarget)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)
&& moveType == TYPE_FIRE)
@@ -5980,9 +6153,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_ANGER_SHELL:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1) // Activates after all hits from a multi-hit move.
&& IsBattlerAlive(gBattlerTarget)
&& HadMoreThanHalfHpNowDoesnt(gBattlerTarget)
@@ -5994,13 +6167,13 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_WIND_POWER:
- if (!(gMovesInfo[gCurrentMove].windMove))
+ if (!IsWindMove(gCurrentMove))
break;
// fall through
case ABILITY_ELECTROMORPHOSIS:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget))
{
BattleScriptPushCursor();
@@ -6009,11 +6182,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_TOXIC_DEBRIS:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& (!gBattleStruct->isSkyBattle)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
- && IS_MOVE_PHYSICAL(gCurrentMove)
- && TARGET_TURN_DAMAGED
+ && IsBattleMovePhysical(gCurrentMove)
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& (gSideTimers[GetBattlerSide(gBattlerAttacker)].toxicSpikesAmount != 2))
{
SWAP(gBattlerAttacker, gBattlerTarget, i);
@@ -6028,13 +6201,13 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
switch (gLastUsedAbility)
{
case ABILITY_POISON_TOUCH:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget))
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker)
- && TARGET_TURN_DAMAGED // Need to actually hit the target
+ && IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
&& RandomPercentage(RNG_POISON_TOUCH, 30))
{
gBattleScripting.moveEffect = MOVE_EFFECT_POISON;
@@ -6046,11 +6219,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_TOXIC_CHAIN:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& CanBePoisoned(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerTarget))
- && TARGET_TURN_DAMAGED // Need to actually hit the target
+ && IsBattlerTurnDamaged(gBattlerTarget) // Need to actually hit the target
&& RandomWeighted(RNG_TOXIC_CHAIN, 7, 3))
{
gBattleScripting.moveEffect = MOVE_EFFECT_TOXIC;
@@ -6062,11 +6235,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
}
break;
case ABILITY_STENCH:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
+ if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& RandomChance(RNG_STENCH, 1, 10)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& !MoveHasAdditionalEffect(gCurrentMove, MOVE_EFFECT_FLINCH))
{
gBattleScripting.moveEffect = MOVE_EFFECT_FLINCH;
@@ -6078,7 +6251,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_GULP_MISSILE:
if ((gBattleMons[gBattlerAttacker].species == SPECIES_CRAMORANT)
- && ((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER)
+ && ((gCurrentMove == MOVE_SURF && IsBattlerTurnDamaged(gBattlerTarget)) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER)
&& TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_HP_PERCENT))
{
BattleScriptPushCursor();
@@ -6106,7 +6279,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
{
case ABILITY_DANCER:
if (IsBattlerAlive(battler)
- && (gMovesInfo[gCurrentMove].danceMove)
+ && IsDanceMove(gCurrentMove)
&& !gSpecialStatuses[battler].dancerUsedMove
&& gBattlerAttacker != battler)
{
@@ -6188,6 +6361,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_VITAL_SPIRIT:
if (gBattleMons[battler].status1 & STATUS1_SLEEP)
{
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
effect = 1;
@@ -6425,17 +6599,8 @@ bool32 TryPrimalReversion(u32 battler)
if (GetBattlerHoldEffect(battler, FALSE) == HOLD_EFFECT_PRIMAL_ORB
&& GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != SPECIES_NONE)
{
- if (gBattlerAttacker == battler)
- {
- BattleScriptPushCursorAndCallback(BattleScript_PrimalReversion);
- }
- else
- {
- // edge case for scenarios like a switch-in after activated eject button
- gBattleScripting.savedBattler = gBattlerAttacker;
- gBattlerAttacker = battler;
- BattleScriptPushCursorAndCallback(BattleScript_PrimalReversionRestoreAttacker);
- }
+ gBattleScripting.battler = battler;
+ BattleScriptPushCursorAndCallback(BattleScript_PrimalReversion);
return TRUE;
}
return FALSE;
@@ -6460,12 +6625,12 @@ bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability)
return FALSE;
return (ability == ABILITY_MOLD_BREAKER || ability == ABILITY_TERAVOLT || ability == ABILITY_TURBOBLAZE
- || (ability == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove)));
+ || (ability == ABILITY_MYCELIUM_MIGHT && IsBattleMoveStatus(gCurrentMove)));
}
static inline bool32 CanBreakThroughAbility(u32 battlerAtk, u32 battlerDef, u32 ability)
{
- return ((IsMoldBreakerTypeAbility(battlerAtk, ability) || gMovesInfo[gCurrentMove].ignoresTargetAbility)
+ return ((IsMoldBreakerTypeAbility(battlerAtk, ability) || MoveIgnoresTargetAbility(gCurrentMove))
&& battlerDef != battlerAtk
&& gAbilitiesInfo[gBattleMons[battlerDef].ability].breakable
&& gBattlerByTurnOrder[gCurrentTurnActionNumber] == battlerAtk
@@ -6619,8 +6784,11 @@ bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag)
return IsBattlerGrounded(battler);
}
-bool32 CanBeSlept(u32 battler, u32 ability)
+bool32 CanBeSlept(u32 battler, u32 ability, enum SleepClauseBlock isBlockedBySleepClause)
{
+ if(IsSleepClauseActiveForSide(GetBattlerSide(battler)) && isBlockedBySleepClause)
+ return FALSE;
+
if (ability == ABILITY_INSOMNIA
|| ability == ABILITY_VITAL_SPIRIT
|| ability == ABILITY_COMATOSE
@@ -6744,25 +6912,25 @@ bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId)
return FALSE;
}
-static u8 HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, bool32 end2)
+static u32 HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, enum ItemEffect caseID)
{
if (HasEnoughHpToEatBerry(battler, (B_CONFUSE_BERRIES_HEAL >= GEN_7 ? 4 : 2), itemId)
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)))
{
PREPARE_FLAVOR_BUFFER(gBattleTextBuff1, flavorId);
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / GetBattlerItemHoldEffectParam(battler, itemId);
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / GetBattlerItemHoldEffectParam(battler, itemId);
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
if (GetBattlerAbility(battler) == ABILITY_RIPEN)
{
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[battler] *= 2;
gBattlerAbility = battler;
}
gBattleScripting.battler = battler;
- if (end2)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
if (GetFlavorRelationByPersonality(gBattleMons[battler].personality, flavorId) < 0)
BattleScriptExecute(BattleScript_BerryConfuseHealEnd2);
@@ -6783,7 +6951,7 @@ static u8 HealConfuseBerry(u32 battler, u32 itemId, u32 flavorId, bool32 end2)
return 0;
}
-static u8 StatRaiseBerry(u32 battler, u32 itemId, u32 statId, bool32 end2)
+static u32 StatRaiseBerry(u32 battler, u32 itemId, u32 statId, enum ItemEffect caseID)
{
if (CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN) && HasEnoughHpToEatBerry(battler, GetBattlerItemHoldEffectParam(battler, itemId), itemId))
{
@@ -6797,7 +6965,7 @@ static u8 StatRaiseBerry(u32 battler, u32 itemId, u32 statId, bool32 end2)
gBattleScripting.animArg1 = STAT_ANIM_PLUS1 + statId;
gBattleScripting.animArg2 = 0;
- if (end2)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
@@ -6808,10 +6976,10 @@ static u8 StatRaiseBerry(u32 battler, u32 itemId, u32 statId, bool32 end2)
}
return ITEM_STATS_CHANGE;
}
- return 0;
+ return ITEM_NO_EFFECT;
}
-static u8 RandomStatRaiseBerry(u32 battler, u32 itemId, bool32 end2)
+static u32 RandomStatRaiseBerry(u32 battler, u32 itemId, enum ItemEffect caseID)
{
s32 i;
u16 stringId;
@@ -6847,7 +7015,7 @@ static u8 RandomStatRaiseBerry(u32 battler, u32 itemId, bool32 end2)
gBattleScripting.animArg1 = STAT_ANIM_PLUS2 + i + 1;
gBattleScripting.animArg2 = 0;
- if (end2)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
@@ -6862,12 +7030,12 @@ static u8 RandomStatRaiseBerry(u32 battler, u32 itemId, bool32 end2)
return 0;
}
-static u8 TrySetMicleBerry(u32 battler, u32 itemId, bool32 end2)
+static u32 TrySetMicleBerry(u32 battler, u32 itemId, enum ItemEffect caseID)
{
if (HasEnoughHpToEatBerry(battler, 4, itemId))
{
gBattleStruct->usedMicleBerry |= 1u << battler;
- if (end2)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_MicleBerryActivateEnd2);
}
@@ -6885,14 +7053,14 @@ static u8 TrySetEnigmaBerry(u32 battler)
{
if (IsBattlerAlive(battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
- && ((TARGET_TURN_DAMAGED && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements)
+ && ((IsBattlerTurnDamaged(battler) && gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_SUPER_EFFECTIVE) || gBattleScripting.overrideBerryRequirements)
&& !(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP)
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)))
{
gBattleScripting.battler = battler;
- gBattleMoveDamage = (gBattleMons[battler].maxHP * 25 / 100) * -1;
+ gBattleStruct->moveDamage[battler] = (gBattleMons[battler].maxHP * 25 / 100) * -1;
if (GetBattlerAbility(battler) == ABILITY_RIPEN)
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[battler] *= 2;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ItemHealHP_RemoveItemRet;
@@ -6909,7 +7077,7 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
|| (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& GetBattleMoveCategory(gCurrentMove) == category
&& battler != gBattlerAttacker
- && TARGET_TURN_DAMAGED))
+ && IsBattlerTurnDamaged(battler)))
)
{
BufferStatChange(battler, statId, STRINGID_STATROSE);
@@ -6930,7 +7098,7 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
return 0;
}
-u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute)
+u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemEffect caseID)
{
if (gFieldStatuses & terrainFlag && CompareStat(battler, statId, MAX_STAT_STAGE, CMP_LESS_THAN))
{
@@ -6940,7 +7108,7 @@ u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 exe
SET_STATCHANGER(statId, 1, FALSE);
gBattleScripting.animArg1 = STAT_ANIM_PLUS1 + statId;
gBattleScripting.animArg2 = 0;
- if (execute)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_BerryStatRaiseEnd2);
}
@@ -6954,7 +7122,7 @@ u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 exe
return 0;
}
-static u32 ItemRestorePp(u32 battler, u32 itemId, bool32 execute)
+static u32 ItemRestorePp(u32 battler, u32 itemId, enum ItemEffect caseID)
{
struct Pokemon *party = GetBattlerParty(battler);
struct Pokemon *mon = &party[gBattlerPartyIndexes[battler]];
@@ -6982,7 +7150,7 @@ static u32 ItemRestorePp(u32 battler, u32 itemId, bool32 execute)
PREPARE_MOVE_BUFFER(gBattleTextBuff1, move);
- if (execute)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_BerryPPHealEnd2);
}
@@ -7001,23 +7169,23 @@ static u32 ItemRestorePp(u32 battler, u32 itemId, bool32 execute)
return 0;
}
-static u8 ItemHealHp(u32 battler, u32 itemId, bool32 end2, bool32 percentHeal)
+static u32 ItemHealHp(u32 battler, u32 itemId, enum ItemEffect caseID, bool32 percentHeal)
{
if (!(gBattleScripting.overrideBerryRequirements && gBattleMons[battler].hp == gBattleMons[battler].maxHP)
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK))
&& HasEnoughHpToEatBerry(battler, 2, itemId))
{
if (percentHeal)
- gBattleMoveDamage = (GetNonDynamaxMaxHP(battler) * GetBattlerItemHoldEffectParam(battler, itemId) / 100) * -1;
+ gBattleStruct->moveDamage[battler] = (GetNonDynamaxMaxHP(battler) * GetBattlerItemHoldEffectParam(battler, itemId) / 100) * -1;
else
- gBattleMoveDamage = GetBattlerItemHoldEffectParam(battler, itemId) * -1;
+ gBattleStruct->moveDamage[battler] = GetBattlerItemHoldEffectParam(battler, itemId) * -1;
// check ripen
if (ItemId_GetPocket(itemId) == POCKET_BERRIES && GetBattlerAbility(battler) == ABILITY_RIPEN)
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[battler] *= 2;
gBattlerAbility = battler; // in SWSH, berry juice shows ability pop up but has no effect. This is mimicked here
- if (end2)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_ItemHealHP_RemoveItemEnd2);
}
@@ -7098,9 +7266,9 @@ static bool32 GetMentalHerbEffect(u32 battler)
return ret;
}
-static u8 TryConsumeMirrorHerb(u32 battler, bool32 execute)
+static u32 TryConsumeMirrorHerb(u32 battler, enum ItemEffect caseID)
{
- u8 effect = 0;
+ u32 effect = 0;
if (gProtectStructs[battler].eatMirrorHerb)
{
@@ -7109,7 +7277,7 @@ static u8 TryConsumeMirrorHerb(u32 battler, bool32 execute)
gBattleScripting.battler = battler;
gProtectStructs[battler].eatMirrorHerb = 0;
ChooseStatBoostAnimation(battler);
- if (execute)
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
{
BattleScriptExecute(BattleScript_MirrorHerbCopyStatChangeEnd2);
}
@@ -7123,6 +7291,32 @@ static u8 TryConsumeMirrorHerb(u32 battler, bool32 execute)
return effect;
}
+static inline u32 TryBoosterEnergy(u32 battler, enum ItemEffect caseID)
+{
+ if (gBattleStruct->boosterEnergyActivates & (1u << battler) || gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
+ return ITEM_NO_EFFECT;
+
+ if (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !((gBattleWeather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT))
+ || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)))
+ {
+ PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
+ gBattlerAbility = gBattleScripting.battler = battler;
+ gBattleStruct->boosterEnergyActivates |= 1u << battler;
+ if (caseID == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseID == ITEMEFFECT_NORMAL)
+ {
+ BattleScriptExecute(BattleScript_BoosterEnergyEnd2);
+ }
+ else
+ {
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_BoosterEnergyRet;
+ }
+ return ITEM_EFFECT_OTHER;
+ }
+
+ return ITEM_NO_EFFECT;
+}
+
static u32 RestoreWhiteHerbStats(u32 battler)
{
u32 i, effect = 0;
@@ -7151,59 +7345,59 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
{
case HOLD_EFFECT_MICLE_BERRY:
if (B_HP_BERRIES >= GEN_4)
- effect = TrySetMicleBerry(battler, gLastUsedItem, FALSE);
+ effect = TrySetMicleBerry(battler, gLastUsedItem, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_RESTORE_HP:
if (B_HP_BERRIES >= GEN_4)
- effect = ItemHealHp(battler, gLastUsedItem, FALSE, FALSE);
+ effect = ItemHealHp(battler, gLastUsedItem, ITEMEFFECT_NONE, FALSE);
break;
case HOLD_EFFECT_RESTORE_PCT_HP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = ItemHealHp(battler, gLastUsedItem, FALSE, TRUE);
+ effect = ItemHealHp(battler, gLastUsedItem, ITEMEFFECT_NONE, TRUE);
break;
case HOLD_EFFECT_RESTORE_PP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = ItemRestorePp(battler, gLastUsedItem, FALSE);
+ effect = ItemRestorePp(battler, gLastUsedItem, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_CONFUSE_SPICY:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SPICY, FALSE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SPICY, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_CONFUSE_DRY:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_DRY, FALSE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_DRY, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_CONFUSE_SWEET:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SWEET, FALSE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SWEET, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_CONFUSE_BITTER:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_BITTER, FALSE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_BITTER, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_CONFUSE_SOUR:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SOUR, FALSE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SOUR, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_ATK, FALSE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_ATK, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_DEF, FALSE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_DEF, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_SPEED_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPEED, FALSE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPEED, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_SP_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPATK, FALSE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPATK, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_SP_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, FALSE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_ENIGMA_BERRY: // consume and heal if hit by super effective move
if (B_BERRIES_INSTANT >= GEN_4)
@@ -7219,7 +7413,7 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
break;
case HOLD_EFFECT_RANDOM_STAT_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = RandomStatRaiseBerry(battler, gLastUsedItem, FALSE);
+ effect = RandomStatRaiseBerry(battler, gLastUsedItem, ITEMEFFECT_NONE);
break;
case HOLD_EFFECT_CURE_PAR:
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS && !UnnerveOn(battler, gLastUsedItem))
@@ -7272,6 +7466,7 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_BerryCureSlpRet;
effect = ITEM_STATUS_CHANGE;
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
}
break;
case HOLD_EFFECT_CURE_CONFUSION:
@@ -7303,6 +7498,7 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
{
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
}
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS)
@@ -7354,20 +7550,80 @@ static u8 ItemEffectMoveEnd(u32 battler, u16 holdEffect)
effect = ITEM_STATS_CHANGE;
break;
case HOLD_EFFECT_MIRROR_HERB:
- effect = TryConsumeMirrorHerb(battler, FALSE);
+ effect = TryConsumeMirrorHerb(battler, ITEMEFFECT_NONE);
break;
}
return effect;
}
-u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
+static inline bool32 TryCureStatus(u32 battler, enum ItemEffect caseId)
{
- int i = 0, moveType;
- u8 effect = ITEM_NO_EFFECT;
- u32 battlerHoldEffect = 0, atkHoldEffect;
- u8 atkHoldEffectParam;
- u16 atkItem;
+ u32 effect = ITEM_NO_EFFECT;
+ u32 string = 0;
+
+ if ((gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].status2 & STATUS2_CONFUSION) && !UnnerveOn(battler, gLastUsedItem))
+ {
+ if (gBattleMons[battler].status1 & STATUS1_PSN_ANY)
+ {
+ StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
+ string++;
+ }
+ if (gBattleMons[battler].status1 & STATUS1_SLEEP)
+ {
+ gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
+ StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
+ string++;
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
+ }
+ if (gBattleMons[battler].status1 & STATUS1_PARALYSIS)
+ {
+ StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
+ string++;
+ }
+ if (gBattleMons[battler].status1 & STATUS1_BURN)
+ {
+ StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
+ string++;
+ }
+ if (gBattleMons[battler].status1 & STATUS1_FREEZE || gBattleMons[battler].status1 & STATUS1_FROSTBITE)
+ {
+ StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
+ string++;
+ }
+ if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
+ {
+ StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
+ string++;
+ }
+ if (string <= 1)
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_CURED_PROBLEM;
+ else
+ gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_NORMALIZED_STATUS;
+ gBattleMons[battler].status1 = 0;
+ RemoveConfusionStatus(battler);
+ if (caseId == ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN || caseId == ITEMEFFECT_NORMAL)
+ {
+ BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2);
+ }
+ else
+ {
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_BerryCureChosenStatusRet;
+ }
+ effect = ITEM_STATUS_CHANGE;
+ }
+
+ return effect;
+}
+
+u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
+{
+ u32 moveType = 0;
+ u32 effect = ITEM_NO_EFFECT;
+ u32 battlerHoldEffect = 0, atkHoldEffect = 0;
+ u32 atkHoldEffectParam = 0;
+ u32 atkItem = 0;
if (caseID != ITEMEFFECT_USE_LAST_ITEM)
{
@@ -7381,7 +7637,10 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
switch (caseID)
{
+ case ITEMEFFECT_NONE:
+ break;
case ITEMEFFECT_ON_SWITCH_IN:
+ case ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN:
if (!gSpecialStatuses[battler].switchInItemDone)
{
switch (battlerHoldEffect)
@@ -7403,43 +7662,43 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_CONFUSE_SPICY:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SPICY, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SPICY, caseID);
break;
case HOLD_EFFECT_CONFUSE_DRY:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_DRY, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_DRY, caseID);
break;
case HOLD_EFFECT_CONFUSE_SWEET:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SWEET, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SWEET, caseID);
break;
case HOLD_EFFECT_CONFUSE_BITTER:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_BITTER, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_BITTER, caseID);
break;
case HOLD_EFFECT_CONFUSE_SOUR:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SOUR, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SOUR, caseID);
break;
case HOLD_EFFECT_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_ATK, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_ATK, caseID);
break;
case HOLD_EFFECT_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_DEF, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_DEF, caseID);
break;
case HOLD_EFFECT_SPEED_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPEED, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPEED, caseID);
break;
case HOLD_EFFECT_SP_ATTACK_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPATK, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPATK, caseID);
break;
case HOLD_EFFECT_SP_DEFENSE_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, caseID);
break;
case HOLD_EFFECT_CRITICAL_UP:
if (B_BERRIES_INSTANT >= GEN_4
@@ -7454,7 +7713,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_RANDOM_STAT_UP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = RandomStatRaiseBerry(battler, gLastUsedItem, TRUE);
+ effect = RandomStatRaiseBerry(battler, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_CURE_PAR:
if (B_BERRIES_INSTANT >= GEN_4
@@ -7513,62 +7772,20 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
effect = ITEM_STATUS_CHANGE;
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
}
break;
case HOLD_EFFECT_CURE_STATUS:
- if (B_BERRIES_INSTANT >= GEN_4
- && (gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].status2 & STATUS2_CONFUSION)
- && !UnnerveOn(battler, gLastUsedItem))
- {
- i = 0;
- if (gBattleMons[battler].status1 & STATUS1_PSN_ANY)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_SLEEP)
- {
- gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
- StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_PARALYSIS)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_BURN)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_FREEZE || gBattleMons[battler].status1 & STATUS1_FROSTBITE)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
- i++;
- }
- if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
- i++;
- }
- if (i <= 1)
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_CURED_PROBLEM;
- else
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_NORMALIZED_STATUS;
- gBattleMons[battler].status1 = 0;
- RemoveConfusionStatus(battler);
- BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
+ if (B_BERRIES_INSTANT >= GEN_4)
+ effect = TryCureStatus(battler, caseID);
break;
case HOLD_EFFECT_RESTORE_HP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = ItemHealHp(battler, gLastUsedItem, TRUE, FALSE);
+ effect = ItemHealHp(battler, gLastUsedItem, caseID, FALSE);
break;
case HOLD_EFFECT_RESTORE_PCT_HP:
if (B_BERRIES_INSTANT >= GEN_4)
- effect = ItemHealHp(battler, gLastUsedItem, TRUE, TRUE);
+ effect = ItemHealHp(battler, gLastUsedItem, caseID, TRUE);
break;
case HOLD_EFFECT_AIR_BALLOON:
effect = ITEM_EFFECT_OTHER;
@@ -7587,16 +7804,16 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
switch (GetBattlerHoldEffectParam(battler))
{
case HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, gLastUsedItem, TRUE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_ELECTRIC_TERRAIN, STAT_DEF, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_PARAM_GRASSY_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, gLastUsedItem, TRUE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_GRASSY_TERRAIN, STAT_DEF, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_PARAM_MISTY_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, gLastUsedItem, TRUE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_MISTY_TERRAIN, STAT_SPDEF, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN:
- effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, gLastUsedItem, TRUE);
+ effect = TryHandleSeed(battler, STATUS_FIELD_PSYCHIC_TERRAIN, STAT_SPDEF, gLastUsedItem, caseID);
break;
}
break;
@@ -7636,20 +7853,10 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
effect = ITEM_STATS_CHANGE;
break;
case HOLD_EFFECT_MIRROR_HERB:
- effect = TryConsumeMirrorHerb(battler, TRUE);
+ effect = TryConsumeMirrorHerb(battler, caseID);
break;
case HOLD_EFFECT_BOOSTER_ENERGY:
- if (!(gBattleStruct->boosterEnergyActivates & (1u << battler))
- && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
- && (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !((gBattleWeather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT))
- || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN))))
- {
- PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
- gBattleScripting.battler = battler;
- gBattleStruct->boosterEnergyActivates |= 1u << battler;
- BattleScriptExecute(BattleScript_BoosterEnergyEnd2);
- effect = ITEM_EFFECT_OTHER;
- }
+ effect = TryBoosterEnergy(battler, caseID);
break;
}
if (effect != 0)
@@ -7673,15 +7880,15 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
{
case HOLD_EFFECT_RESTORE_HP:
if (!moveTurn)
- effect = ItemHealHp(battler, gLastUsedItem, TRUE, FALSE);
+ effect = ItemHealHp(battler, gLastUsedItem, caseID, FALSE);
break;
case HOLD_EFFECT_RESTORE_PCT_HP:
if (!moveTurn)
- effect = ItemHealHp(battler, gLastUsedItem, TRUE, TRUE);
+ effect = ItemHealHp(battler, gLastUsedItem, caseID, TRUE);
break;
case HOLD_EFFECT_RESTORE_PP:
if (!moveTurn)
- effect = ItemRestorePp(battler, gLastUsedItem, TRUE);
+ effect = ItemRestorePp(battler, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_RESTORE_STATS:
effect = RestoreWhiteHerbStats(battler);
@@ -7698,9 +7905,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
else if (GetBattlerAbility(battler) != ABILITY_MAGIC_GUARD && !moveTurn)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_ItemHurtEnd2);
effect = ITEM_HP_CHANGE;
RecordItemEffectBattle(battler, battlerHoldEffect);
@@ -7712,10 +7919,10 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
if (gBattleMons[battler].hp < gBattleMons[battler].maxHP && !moveTurn
&& (B_HEAL_BLOCKING < GEN_5 || !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)))
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
- gBattleMoveDamage *= -1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 16;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
+ gBattleStruct->moveDamage[battler] *= -1;
BattleScriptExecute(BattleScript_ItemHealHP_End2);
effect = ITEM_HP_CHANGE;
RecordItemEffectBattle(battler, battlerHoldEffect);
@@ -7723,43 +7930,43 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_CONFUSE_SPICY:
if (!moveTurn)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SPICY, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SPICY, caseID);
break;
case HOLD_EFFECT_CONFUSE_DRY:
if (!moveTurn)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_DRY, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_DRY, caseID);
break;
case HOLD_EFFECT_CONFUSE_SWEET:
if (!moveTurn)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SWEET, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SWEET, caseID);
break;
case HOLD_EFFECT_CONFUSE_BITTER:
if (!moveTurn)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_BITTER, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_BITTER, caseID);
break;
case HOLD_EFFECT_CONFUSE_SOUR:
if (!moveTurn)
- effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SOUR, TRUE);
+ effect = HealConfuseBerry(battler, gLastUsedItem, FLAVOR_SOUR, caseID);
break;
case HOLD_EFFECT_ATTACK_UP:
if (!moveTurn)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_ATK, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_ATK, caseID);
break;
case HOLD_EFFECT_DEFENSE_UP:
if (!moveTurn)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_DEF, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_DEF, caseID);
break;
case HOLD_EFFECT_SPEED_UP:
if (!moveTurn)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPEED, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPEED, caseID);
break;
case HOLD_EFFECT_SP_ATTACK_UP:
if (!moveTurn)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPATK, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPATK, caseID);
break;
case HOLD_EFFECT_SP_DEFENSE_UP:
if (!moveTurn)
- effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, TRUE);
+ effect = StatRaiseBerry(battler, gLastUsedItem, STAT_SPDEF, caseID);
break;
case HOLD_EFFECT_CRITICAL_UP:
if (!moveTurn && !(gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY)
@@ -7773,7 +7980,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_RANDOM_STAT_UP:
if (!moveTurn)
- effect = RandomStatRaiseBerry(battler, gLastUsedItem, TRUE);
+ effect = RandomStatRaiseBerry(battler, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_CURE_PAR:
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS && !UnnerveOn(battler, gLastUsedItem))
@@ -7820,6 +8027,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
BattleScriptExecute(BattleScript_BerryCureSlpEnd2);
effect = ITEM_STATUS_CHANGE;
+ TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
}
break;
case HOLD_EFFECT_CURE_CONFUSION:
@@ -7831,49 +8039,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
break;
case HOLD_EFFECT_CURE_STATUS:
- if ((gBattleMons[battler].status1 & STATUS1_ANY || gBattleMons[battler].status2 & STATUS2_CONFUSION) && !UnnerveOn(battler, gLastUsedItem))
- {
- i = 0;
- if (gBattleMons[battler].status1 & STATUS1_PSN_ANY)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_PoisonJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_SLEEP)
- {
- gBattleMons[battler].status2 &= ~STATUS2_NIGHTMARE;
- StringCopy(gBattleTextBuff1, gStatusConditionString_SleepJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_PARALYSIS)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ParalysisJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_BURN)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_BurnJpn);
- i++;
- }
- if (gBattleMons[battler].status1 & STATUS1_FREEZE || gBattleMons[battler].status1 & STATUS1_FROSTBITE)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_IceJpn);
- i++;
- }
- if (gBattleMons[battler].status2 & STATUS2_CONFUSION)
- {
- StringCopy(gBattleTextBuff1, gStatusConditionString_ConfusionJpn);
- i++;
- }
- if (i <= 1)
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_CURED_PROBLEM;
- else
- gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_NORMALIZED_STATUS;
- gBattleMons[battler].status1 = 0;
- RemoveConfusionStatus(battler);
- BattleScriptExecute(BattleScript_BerryCureChosenStatusEnd2);
- effect = ITEM_STATUS_CHANGE;
- }
+ effect = TryCureStatus(battler, caseID);
break;
case HOLD_EFFECT_MENTAL_HERB:
if (GetMentalHerbEffect(battler))
@@ -7886,7 +8052,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_MICLE_BERRY:
if (!moveTurn)
- effect = TrySetMicleBerry(battler, gLastUsedItem, TRUE);
+ effect = TrySetMicleBerry(battler, gLastUsedItem, caseID);
break;
case HOLD_EFFECT_BERSERK_GENE:
BufferStatChange(battler, STAT_ATK, STRINGID_STATROSE);
@@ -7904,20 +8070,10 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
effect = ITEM_STATS_CHANGE;
break;
case HOLD_EFFECT_MIRROR_HERB:
- effect = TryConsumeMirrorHerb(battler, TRUE);
+ effect = TryConsumeMirrorHerb(battler, caseID);
break;
case HOLD_EFFECT_BOOSTER_ENERGY:
- if (!(gBattleStruct->boosterEnergyActivates & (1u << battler))
- && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
- && (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !((gBattleWeather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT))
- || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN))))
- {
- PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler));
- gBattlerAbility = gBattleScripting.battler = battler;
- gBattleStruct->boosterEnergyActivates |= 1u << battler;
- BattleScriptExecute(BattleScript_BoosterEnergyEnd2);
- effect = ITEM_EFFECT_OTHER;
- }
+ effect = TryBoosterEnergy(battler, caseID);
break;
}
@@ -7976,10 +8132,10 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
atkHoldEffectParam *= 2;
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_RAINBOW && gCurrentMove != MOVE_SECRET_POWER)
atkHoldEffectParam *= 2;
- if (gBattleMoveDamage != 0 // Need to have done damage
- && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
- && TARGET_TURN_DAMAGED
- && !gMovesInfo[gCurrentMove].ignoresKingsRock
+ if (gBattleStruct->moveDamage[battler] != 0 // Need to have done damage
+ && MoveResultHasEffect(gBattlerTarget)
+ && IsBattlerTurnDamaged(gBattlerTarget)
+ && !MoveIgnoresKingsRock(gCurrentMove)
&& gBattleMons[gBattlerTarget].hp
&& RandomPercentage(RNG_HOLD_EFFECT_FLINCH, atkHoldEffectParam)
&& ability != ABILITY_STENCH)
@@ -8020,9 +8176,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
gLastUsedItem = atkItem;
gPotentialItemEffectBattler = gBattlerAttacker;
gBattleScripting.battler = gBattlerAttacker;
- gBattleMoveDamage = (gSpecialStatuses[gBattlerTarget].shellBellDmg / atkHoldEffectParam) * -1;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = -1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = (gSpecialStatuses[gBattlerTarget].shellBellDmg / atkHoldEffectParam) * -1;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = -1;
gSpecialStatuses[gBattlerTarget].shellBellDmg = 0;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ItemHealHP_Ret;
@@ -8037,9 +8193,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
&& !gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage
&& gSpecialStatuses[gBattlerAttacker].damagedMons)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 10;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 10;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
effect = ITEM_HP_CHANGE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ItemHurtRet;
@@ -8049,7 +8205,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
case HOLD_EFFECT_THROAT_SPRAY: // Does NOT need to be a damaging move
if (gProtectStructs[gBattlerAttacker].targetAffected
&& IsBattlerAlive(gBattlerAttacker)
- && gMovesInfo[gCurrentMove].soundMove
+ && IsSoundMove(gCurrentMove)
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)
&& !NoAliveMonsForEitherParty()) // Don't activate if battle will end
{
@@ -8064,13 +8220,13 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
break;
case ITEMEFFECT_TARGET:
- if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
+ if (MoveResultHasEffect(gBattlerTarget))
{
- moveType = GetMoveType(gCurrentMove);
+ moveType = GetBattleMoveType(gCurrentMove);
switch (battlerHoldEffect)
{
case HOLD_EFFECT_AIR_BALLOON:
- if (TARGET_TURN_DAMAGED)
+ if (IsBattlerTurnDamaged(gBattlerTarget))
{
effect = ITEM_EFFECT_OTHER;
BattleScriptPushCursor();
@@ -8078,15 +8234,15 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
break;
case HOLD_EFFECT_ROCKY_HELMET:
- if (TARGET_TURN_DAMAGED
+ if (IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(gCurrentMove, gBattlerAttacker)
&& IsBattlerAlive(gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 6;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 6;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
effect = ITEM_HP_CHANGE;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RockyHelmetActivates;
@@ -8096,8 +8252,8 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_WEAKNESS_POLICY:
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
- && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE)
+ && IsBattlerTurnDamaged(gBattlerTarget)
+ && gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_SUPER_EFFECTIVE)
{
effect = ITEM_STATS_CHANGE;
BattleScriptPushCursor();
@@ -8106,7 +8262,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_SNOWBALL:
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& moveType == TYPE_ICE)
{
effect = ITEM_STATS_CHANGE;
@@ -8117,7 +8273,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_LUMINOUS_MOSS:
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& moveType == TYPE_WATER)
{
effect = ITEM_STATS_CHANGE;
@@ -8128,7 +8284,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_CELL_BATTERY:
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& moveType == TYPE_ELECTRIC)
{
effect = ITEM_STATS_CHANGE;
@@ -8139,7 +8295,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_ABSORB_BULB:
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& moveType == TYPE_WATER)
{
effect = ITEM_STATS_CHANGE;
@@ -8153,16 +8309,16 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_JABOCA_BERRY: // consume and damage attacker if used physical move
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
- && IS_MOVE_PHYSICAL(gCurrentMove)
+ && IsBattleMovePhysical(gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
if (GetBattlerAbility(battler) == ABILITY_RIPEN)
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] *= 2;
effect = ITEM_HP_CHANGE;
BattleScriptPushCursor();
@@ -8173,16 +8329,16 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_ROWAP_BERRY: // consume and damage attacker if used special move
if (IsBattlerAlive(battler)
- && TARGET_TURN_DAMAGED
+ && IsBattlerTurnDamaged(gBattlerTarget)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
- && IS_MOVE_SPECIAL(gCurrentMove)
+ && IsBattleMoveSpecial(gCurrentMove)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 8;
+ if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
+ gBattleStruct->moveDamage[gBattlerAttacker] = 1;
if (GetBattlerAbility(battler) == ABILITY_RIPEN)
- gBattleMoveDamage *= 2;
+ gBattleStruct->moveDamage[gBattlerAttacker] *= 2;
effect = ITEM_HP_CHANGE;
BattleScriptPushCursor();
@@ -8199,7 +8355,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_CURE_STATUS: // only Toxic Chain's interaction with Knock Off
case HOLD_EFFECT_CURE_PSN:
- if (gBattleMons[battler].status1 & STATUS1_PSN_ANY && !UnnerveOn(battler, gLastUsedItem) && GetBattlerAbility(gBattlerAttacker) == ABILITY_TOXIC_CHAIN && gMovesInfo[gCurrentMove].effect == EFFECT_KNOCK_OFF)
+ if (gBattleMons[battler].status1 & STATUS1_PSN_ANY && !UnnerveOn(battler, gLastUsedItem) && GetBattlerAbility(gBattlerAttacker) == ABILITY_TOXIC_CHAIN && GetMoveEffect(gCurrentMove) == EFFECT_KNOCK_OFF)
{
gBattleScripting.battler = battler;
gBattleMons[battler].status1 &= ~(STATUS1_PSN_ANY | STATUS1_TOXIC_COUNTER);
@@ -8210,14 +8366,14 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
}
break;
case HOLD_EFFECT_STICKY_BARB:
- if (TARGET_TURN_DAMAGED
- && (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT))
- && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
- && IsMoveMakingContact(gCurrentMove, gBattlerAttacker)
- && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
- && IsBattlerAlive(gBattlerAttacker)
- && CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
- && gBattleMons[gBattlerAttacker].item == ITEM_NONE)
+ if (IsBattlerTurnDamaged(gBattlerTarget)
+ && MoveResultHasEffect(gBattlerTarget)
+ && GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
+ && IsMoveMakingContact(gCurrentMove, gBattlerAttacker)
+ && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
+ && IsBattlerAlive(gBattlerAttacker)
+ && CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item)
+ && gBattleMons[gBattlerAttacker].item == ITEM_NONE)
{
// No sticky hold checks.
gEffectBattler = battler; // gEffectBattler = target
@@ -8256,9 +8412,9 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
case HOLD_EFFECT_STICKY_BARB: // Not an orb per se, but similar effect, and needs to NOT activate with pickpocket
if (battlerAbility != ABILITY_MAGIC_GUARD)
{
- gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 8;
- if (gBattleMoveDamage == 0)
- gBattleMoveDamage = 1;
+ gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
+ if (gBattleStruct->moveDamage[battler] == 0)
+ gBattleStruct->moveDamage[battler] = 1;
BattleScriptExecute(BattleScript_ItemHurtEnd2);
effect = ITEM_HP_CHANGE;
RecordItemEffectBattle(battler, battlerHoldEffect);
@@ -8285,6 +8441,18 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
gBattlescriptCurrInstr = BattleScript_WhiteHerbRet;
}
break;
+ case HOLD_EFFECT_EJECT_PACK:
+ if (gProtectStructs[battler].statFell
+ && gProtectStructs[battler].disableEjectPack == 0
+ && CountUsablePartyMons(battler) > 0)
+ {
+ gBattleScripting.battler = battler;
+ gPotentialItemEffectBattler = battler;
+ effect = ITEM_STATS_CHANGE;
+ BattleScriptPushCursor();
+ gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
+ }
+ break;
}
break;
}
@@ -8333,11 +8501,11 @@ u32 SetRandomTarget(u32 battlerAtk)
return target;
}
-u32 GetMoveTarget(u16 move, u8 setTarget)
+u32 GetBattleMoveTarget(u16 move, u8 setTarget)
{
u8 targetBattler = 0;
u32 moveTarget, side;
- u32 moveType = GetMoveType(move);
+ u32 moveType = GetBattleMoveType(move);
if (setTarget != NO_TARGET_OVERRIDE)
moveTarget = setTarget - 1;
@@ -8474,7 +8642,8 @@ u8 GetAttackerObedienceForAction()
// is not obedient
if (gCurrentMove == MOVE_RAGE)
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE;
- if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gMovesInfo[gCurrentMove].effect == EFFECT_SNORE || gMovesInfo[gCurrentMove].effect == EFFECT_SLEEP_TALK))
+ u32 moveEffect = GetMoveEffect(gCurrentMove);
+ if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (moveEffect == EFFECT_SNORE || moveEffect == EFFECT_SLEEP_TALK))
return DISOBEYS_WHILE_ASLEEP;
calc = (levelReferenced + obedienceLevel) * ((rnd >> 8) & 255) >> 8;
@@ -8494,7 +8663,7 @@ u8 GetAttackerObedienceForAction()
obedienceLevel = levelReferenced - obedienceLevel;
calc = ((rnd >> 16) & 255);
- if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)))
+ if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), NOT_BLOCKED_BY_SLEEP_CLAUSE))
{
// try putting asleep
int i;
@@ -8562,14 +8731,14 @@ bool32 IsMoveMakingContact(u32 move, u32 battlerAtk)
{
u32 atkHoldEffect = GetBattlerHoldEffect(battlerAtk, TRUE);
- if (!gMovesInfo[move].makesContact)
+ if (!MoveMakesContact(move))
{
- if (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL)
+ if (GetMoveEffect(move) == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][gBattlerTarget] == DAMAGE_CATEGORY_PHYSICAL)
return TRUE;
else
return FALSE;
}
- else if ((atkHoldEffect == HOLD_EFFECT_PUNCHING_GLOVE && gMovesInfo[move].punchingMove)
+ else if ((atkHoldEffect == HOLD_EFFECT_PUNCHING_GLOVE && IsPunchingMove(move))
|| GetBattlerAbility(battlerAtk) == ABILITY_LONG_REACH)
{
return FALSE;
@@ -8582,59 +8751,51 @@ bool32 IsMoveMakingContact(u32 move, u32 battlerAtk)
bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move)
{
- // Decorate bypasses protect and detect, but not crafty shield
- if (move == MOVE_DECORATE)
- {
- if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD)
- return TRUE;
- else if (gProtectStructs[battlerDef].protected)
- return FALSE;
- }
+ bool32 isProtected = FALSE;
- // Z-Moves and Max Moves bypass protection (except Max Guard).
if ((IsZMove(move) || IsMaxMove(move))
- && (!gProtectStructs[battlerDef].maxGuarded
- || gMovesInfo[move].argument == MAX_EFFECT_BYPASS_PROTECT))
- return FALSE;
-
- // Max Guard is silly about the moves it blocks, including Teatime.
- if (gProtectStructs[battlerDef].maxGuarded && IsMoveBlockedByMaxGuard(move))
- return TRUE;
-
- if (!gProtectStructs[battlerDef].maxGuarded // Max Guard cannot be bypassed by Unseen Fist
- && IsMoveMakingContact(move, gBattlerAttacker)
- && GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST)
- return FALSE;
- else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD
- && IS_MOVE_STATUS(move))
- return TRUE;
- else if (gMovesInfo[move].ignoresProtect)
- return FALSE;
+ && (!gProtectStructs[battlerDef].maxGuarded || GetMoveMaxEffect(move) == MAX_EFFECT_BYPASS_PROTECT))
+ isProtected = FALSE; // Z-Moves and Max Moves bypass protection (except Max Guard).
+ else if (gProtectStructs[battlerDef].maxGuarded && IsMoveBlockedByMaxGuard(move))
+ isProtected = TRUE;
+ else if (!gProtectStructs[battlerDef].maxGuarded // Max Guard cannot be bypassed by Unseen Fist
+ && IsMoveMakingContact(move, gBattlerAttacker)
+ && GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST)
+ isProtected = FALSE;
+ else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD && IsBattleMoveStatus(move) && GetMoveEffect(move) != EFFECT_COACHING)
+ isProtected = TRUE;
+ else if (MoveIgnoresProtect(move))
+ isProtected = FALSE;
else if (gProtectStructs[battlerDef].protected)
- return TRUE;
+ isProtected = TRUE;
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_WIDE_GUARD
&& GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))
- return TRUE;
+ isProtected = TRUE;
else if (gProtectStructs[battlerDef].banefulBunkered)
- return TRUE;
+ isProtected = TRUE;
else if (gProtectStructs[battlerDef].burningBulwarked)
- return TRUE;
- else if ((gProtectStructs[battlerDef].obstructed || gProtectStructs[battlerDef].silkTrapped) && !IS_MOVE_STATUS(move))
- return TRUE;
+ isProtected = TRUE;
+ else if ((gProtectStructs[battlerDef].obstructed || gProtectStructs[battlerDef].silkTrapped) && !IsBattleMoveStatus(move))
+ isProtected = TRUE;
else if (gProtectStructs[battlerDef].spikyShielded)
- return TRUE;
- else if (gProtectStructs[battlerDef].kingsShielded && gMovesInfo[move].power != 0)
- return TRUE;
+ isProtected = TRUE;
+ else if (gProtectStructs[battlerDef].kingsShielded && !IsBattleMoveStatus(move))
+ isProtected = TRUE;
else if (gProtectStructs[battlerDef].maxGuarded)
- return TRUE;
+ isProtected = TRUE;
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_QUICK_GUARD
&& GetChosenMovePriority(gBattlerAttacker) > 0)
- return TRUE;
+ isProtected = TRUE;
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_MAT_BLOCK
- && !IS_MOVE_STATUS(move))
- return TRUE;
+ && !IsBattleMoveStatus(move))
+ isProtected = TRUE;
else
- return FALSE;
+ isProtected = FALSE;
+
+ if (isProtected)
+ gBattleStruct->missStringId[battlerDef] = gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED;
+
+ return isProtected;
}
// Only called directly when calculating damage type effectiveness
@@ -8892,7 +9053,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
u32 move = damageCalcData->move;
u32 i;
- u32 basePower = gMovesInfo[move].power;
+ u32 basePower = GetMovePower(move);
u32 weight, hpFraction, speed;
if (GetActiveGimmick(battlerAtk) == GIMMICK_Z_MOVE)
@@ -8901,7 +9062,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX)
return GetMaxMovePower(move);
- switch (gMovesInfo[move].effect)
+ switch (GetMoveEffect(move))
{
case EFFECT_PLEDGE:
if (gBattleStruct->pledgeMove)
@@ -8941,7 +9102,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
basePower = gBattleStruct->presentBasePower;
break;
case EFFECT_TRIPLE_KICK:
- basePower *= 1 + gMovesInfo[move].strikeCount - gMultiHitCounter;
+ basePower *= 1 + GetMoveStrikeCount(move) - gMultiHitCounter;
break;
case EFFECT_SPIT_UP:
basePower = 100 * gDisableStructs[battlerAtk].stockpileCounter;
@@ -8958,7 +9119,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
basePower *= 2;
break;
case EFFECT_PURSUIT:
- if (gActionsByTurnOrder[GetBattlerTurnOrderNum(battlerDef)] == B_ACTION_SWITCH)
+ if (gBattleStruct->pursuitTarget & (1u << battlerDef))
basePower *= 2;
break;
case EFFECT_NATURAL_GIFT:
@@ -8966,8 +9127,8 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
break;
case EFFECT_DOUBLE_POWER_ON_ARG_STATUS:
// Comatose targets treated as if asleep
- if ((gBattleMons[battlerDef].status1 | (STATUS1_SLEEP * (abilityDef == ABILITY_COMATOSE))) & gMovesInfo[move].argument
- && !((gMovesInfo[move].additionalEffects->moveEffect == MOVE_EFFECT_REMOVE_STATUS) && DoesSubstituteBlockMove(battlerAtk, battlerDef, move)))
+ if ((gBattleMons[battlerDef].status1 | (STATUS1_SLEEP * (abilityDef == ABILITY_COMATOSE))) & GetMoveEffectArg_Status(move)
+ && !((GetMoveAdditionalEffectById(move, 0)->moveEffect == MOVE_EFFECT_REMOVE_STATUS) && DoesSubstituteBlockMove(battlerAtk, battlerDef, move)))
{
basePower *= 2;
}
@@ -9055,7 +9216,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
case EFFECT_ROUND:
for (i = 0; i < gBattlersCount; i++)
{
- if (i != battlerAtk && IsBattlerAlive(i) && gLastMoves[i] == MOVE_ROUND)
+ if (i != battlerAtk && IsBattlerAlive(i) && GetMoveEffect(gLastUsedMove) == EFFECT_ROUND)
{
basePower *= 2;
break;
@@ -9063,7 +9224,7 @@ static inline u32 CalcMoveBasePower(struct DamageCalculationData *damageCalcData
}
break;
case EFFECT_FUSION_COMBO:
- if (gMovesInfo[gLastUsedMove].effect == EFFECT_FUSION_COMBO && move != gLastUsedMove)
+ if (GetMoveEffect(gLastUsedMove) == EFFECT_FUSION_COMBO && move != gLastUsedMove)
basePower *= 2;
break;
case EFFECT_LASH_OUT:
@@ -9161,13 +9322,14 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
u32 battlerDef = damageCalcData->battlerDef;
u32 move = damageCalcData->move;
u32 moveType = damageCalcData->moveType;
+ u32 moveEffect = GetMoveEffect(move);
uq4_12_t holdEffectModifier;
uq4_12_t modifier = UQ_4_12(1.0);
u32 atkSide = GetBattlerSide(battlerAtk);
// move effect
- switch (gMovesInfo[move].effect)
+ switch (moveEffect)
{
case EFFECT_FACADE:
if (gBattleMons[battlerAtk].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_PARALYSIS | STATUS1_FROSTBITE))
@@ -9206,7 +9368,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
if (gProtectStructs[battlerAtk].helpingHand)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
if (gSpecialStatuses[battlerAtk].gemBoost)
- modifier = uq4_12_multiply(modifier, UQ_4_12(1.0) + sPercentToModifier[gSpecialStatuses[battlerAtk].gemParam]);
+ modifier = uq4_12_multiply(modifier, uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12(gSpecialStatuses[battlerAtk].gemParam)));
if (gStatuses3[battlerAtk] & STATUS3_CHARGED_UP && moveType == TYPE_ELECTRIC)
modifier = uq4_12_multiply(modifier, UQ_4_12(2.0));
if (gStatuses3[battlerAtk] & STATUS3_ME_FIRST)
@@ -9235,19 +9397,19 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_FLARE_BOOST:
- if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && IS_MOVE_SPECIAL(move))
+ if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && IsBattleMoveSpecial(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_TOXIC_BOOST:
- if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY && IS_MOVE_PHYSICAL(move))
+ if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY && IsBattleMovePhysical(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_RECKLESS:
- if (IS_MOVE_RECOIL(move))
+ if (IsBattleMoveRecoil(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.2));
break;
case ABILITY_IRON_FIST:
- if (gMovesInfo[move].punchingMove)
+ if (IsPunchingMove(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.2));
break;
case ABILITY_SHEER_FORCE:
@@ -9274,11 +9436,11 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
break;
case ABILITY_STRONG_JAW:
- if (gMovesInfo[move].bitingMove)
+ if (IsBitingMove(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_MEGA_LAUNCHER:
- if (gMovesInfo[move].pulseMove)
+ if (IsPulseMove(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_WATER_BUBBLE:
@@ -9310,7 +9472,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
modifier = uq4_12_multiply(modifier, UQ_4_12(1.2));
break;
case ABILITY_PUNK_ROCK:
- if (gMovesInfo[move].soundMove)
+ if (IsSoundMove(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
break;
case ABILITY_STEELY_SPIRIT:
@@ -9318,7 +9480,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_SHARPNESS:
- if (gMovesInfo[move].slicingMove)
+ if (IsSlicingMove(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_SUPREME_OVERLORD:
@@ -9342,7 +9504,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
switch (GetBattlerAbility(BATTLE_PARTNER(battlerAtk)))
{
case ABILITY_BATTERY:
- if (IS_MOVE_SPECIAL(move))
+ if (IsBattleMoveSpecial(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
break;
case ABILITY_POWER_SPOT:
@@ -9375,7 +9537,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
{
u8 defHighestStat = GetHighestStatId(battlerDef);
if (((weather & B_WEATHER_SUN && WEATHER_HAS_EFFECT) || gBattleStruct->boosterEnergyActivates & (1u << battlerDef))
- && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF))
+ && ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF))
&& !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED))
modifier = uq4_12_multiply(modifier, UQ_4_12(0.7));
}
@@ -9384,7 +9546,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
{
u8 defHighestStat = GetHighestStatId(battlerDef);
if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerDef))
- && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF))
+ && ((IsBattleMovePhysical(move) && defHighestStat == STAT_DEF) || (IsBattleMoveSpecial(move) && defHighestStat == STAT_SPDEF))
&& !(gBattleMons[battlerDef].status2 & STATUS2_TRANSFORMED))
modifier = uq4_12_multiply(modifier, UQ_4_12(0.7));
}
@@ -9395,18 +9557,18 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
if (holdEffectParamAtk > 100)
holdEffectParamAtk = 100;
- holdEffectModifier = UQ_4_12(1.0) + sPercentToModifier[holdEffectParamAtk];
+ holdEffectModifier = uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12(holdEffectParamAtk));
// attacker's hold effect
switch (holdEffectAtk)
{
case HOLD_EFFECT_MUSCLE_BAND:
- if (IS_MOVE_PHYSICAL(move))
- modifier = uq4_12_multiply(modifier, holdEffectModifier);
+ if (IsBattleMovePhysical(move))
+ modifier = uq4_12_multiply(modifier, uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12_Floored(holdEffectParamAtk)));
break;
case HOLD_EFFECT_WISE_GLASSES:
- if (IS_MOVE_SPECIAL(move))
- modifier = uq4_12_multiply(modifier, holdEffectModifier);
+ if (IsBattleMoveSpecial(move))
+ modifier = uq4_12_multiply(modifier, uq4_12_add(UQ_4_12(1.0), PercentToUQ4_12_Floored(holdEffectParamAtk)));
break;
case HOLD_EFFECT_LUSTROUS_ORB:
if (GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species) == SPECIES_PALKIA && (moveType == TYPE_WATER || moveType == TYPE_DRAGON))
@@ -9423,7 +9585,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
case HOLD_EFFECT_SOUL_DEW:
if ((gBattleMons[battlerAtk].species == SPECIES_LATIAS || gBattleMons[battlerAtk].species == SPECIES_LATIOS)
&& ((B_SOUL_DEW_BOOST >= GEN_7 && (moveType == TYPE_PSYCHIC || moveType == TYPE_DRAGON))
- || (B_SOUL_DEW_BOOST < GEN_7 && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && IS_MOVE_SPECIAL(move))))
+ || (B_SOUL_DEW_BOOST < GEN_7 && !(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && IsBattleMoveSpecial(move))))
modifier = uq4_12_multiply(modifier, holdEffectModifier);
break;
case HOLD_EFFECT_BUG_POWER:
@@ -9459,7 +9621,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
modifier = uq4_12_multiply(modifier, holdEffectModifier);
break;
case HOLD_EFFECT_PUNCHING_GLOVE:
- if (gMovesInfo[move].punchingMove)
+ if (IsPunchingMove(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.1));
break;
case HOLD_EFFECT_OGERPON_MASK:
@@ -9473,9 +9635,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageCalculationData *
&& (moveType == GetBattlerTeraType(battlerAtk)
|| (GetBattlerTeraType(battlerAtk) == TYPE_STELLAR && IsTypeStellarBoosted(battlerAtk, moveType)))
&& uq4_12_multiply_by_int_half_down(modifier, basePower) < 60
- && gMovesInfo[move].strikeCount < 2
- && gMovesInfo[move].effect != EFFECT_MULTI_HIT
- && gMovesInfo[move].priority == 0)
+ && GetMoveStrikeCount(move) < 2
+ && moveEffect != EFFECT_MULTI_HIT
+ && GetMovePriority(move) == 0)
{
return 60;
}
@@ -9493,12 +9655,13 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
u32 battlerDef = damageCalcData->battlerDef;
u32 move = damageCalcData->move;
u32 moveType = damageCalcData->moveType;
+ u32 moveEffect = GetMoveEffect(move);
atkBaseSpeciesId = GET_BASE_SPECIES_ID(gBattleMons[battlerAtk].species);
- if (gMovesInfo[move].effect == EFFECT_FOUL_PLAY)
+ if (moveEffect == EFFECT_FOUL_PLAY)
{
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
{
atkStat = gBattleMons[battlerDef].attack;
atkStage = gBattleMons[battlerDef].statStages[STAT_ATK];
@@ -9509,9 +9672,9 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
atkStage = gBattleMons[battlerDef].statStages[STAT_SPATK];
}
}
- else if (gMovesInfo[move].effect == EFFECT_BODY_PRESS)
+ else if (moveEffect == EFFECT_BODY_PRESS)
{
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
{
atkStat = gBattleMons[battlerAtk].defense;
// Edge case: Body Press used during Wonder Room. For some reason, it still uses Defense over Sp.Def, but uses Sp.Def stat changes
@@ -9528,7 +9691,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
}
else
{
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
{
atkStat = gBattleMons[battlerAtk].attack;
atkStage = gBattleMons[battlerAtk].statStages[STAT_ATK];
@@ -9558,7 +9721,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
{
case ABILITY_HUGE_POWER:
case ABILITY_PURE_POWER:
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case ABILITY_SLOW_START:
@@ -9566,7 +9729,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.5));
break;
case ABILITY_SOLAR_POWER:
- if (IS_MOVE_SPECIAL(move) && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN))
+ if (IsBattleMoveSpecial(move) && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_DEFEATIST:
@@ -9594,7 +9757,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_PLUS:
- if (IS_MOVE_SPECIAL(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))
+ if (IsBattleMoveSpecial(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))
{
u32 partnerAbility = GetBattlerAbility(BATTLE_PARTNER(battlerAtk));
if (partnerAbility == ABILITY_MINUS
@@ -9603,7 +9766,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
}
break;
case ABILITY_MINUS:
- if (IS_MOVE_SPECIAL(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))
+ if (IsBattleMoveSpecial(move) && IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))
{
u32 partnerAbility = GetBattlerAbility(BATTLE_PARTNER(battlerAtk));
if (partnerAbility == ABILITY_PLUS
@@ -9612,11 +9775,11 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
}
break;
case ABILITY_FLOWER_GIFT:
- if (gBattleMons[battlerAtk].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move))
+ if (gBattleMons[battlerAtk].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN) && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_HUSTLE:
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_STAKEOUT:
@@ -9624,7 +9787,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case ABILITY_GUTS:
- if (gBattleMons[battlerAtk].status1 & STATUS1_ANY && IS_MOVE_PHYSICAL(move))
+ if (gBattleMons[battlerAtk].status1 & STATUS1_ANY && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_TRANSISTOR:
@@ -9641,7 +9804,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_GORILLA_TACTICS:
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_ROCKY_PAYLOAD:
@@ -9654,7 +9817,7 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
u32 atkHighestStat = GetHighestStatId(battlerAtk);
if (((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT) || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk))
{
- if ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))
+ if ((IsBattleMovePhysical(move) && atkHighestStat == STAT_ATK) || (IsBattleMoveSpecial(move) && atkHighestStat == STAT_SPATK))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
}
}
@@ -9665,18 +9828,18 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
u32 atkHighestStat = GetHighestStatId(battlerAtk);
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk))
{
- if ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))
+ if ((IsBattleMovePhysical(move) && atkHighestStat == STAT_ATK) || (IsBattleMoveSpecial(move) && atkHighestStat == STAT_SPATK))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
}
}
break;
case ABILITY_ORICHALCUM_PULSE:
- if ((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT && IS_MOVE_PHYSICAL(move))
- modifier = uq4_12_multiply(modifier, UQ_4_12(1.33));
+ if ((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT && IsBattleMovePhysical(move))
+ modifier = uq4_12_multiply(modifier, UQ_4_12(1.3333));
break;
case ABILITY_HADRON_ENGINE:
- if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && IS_MOVE_SPECIAL(move))
- modifier = uq4_12_multiply(modifier, UQ_4_12(1.33));
+ if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && IsBattleMoveSpecial(move))
+ modifier = uq4_12_multiply(modifier, UQ_4_12(1.3333));
break;
}
@@ -9699,49 +9862,49 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
switch (GetBattlerAbility(BATTLE_PARTNER(battlerAtk)))
{
case ABILITY_FLOWER_GIFT:
- if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerAtk), B_WEATHER_SUN) && IS_MOVE_PHYSICAL(move))
+ if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM_SUNSHINE && IsBattlerWeatherAffected(BATTLE_PARTNER(battlerAtk), B_WEATHER_SUN) && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
}
}
// field abilities
- if (IsAbilityOnField(ABILITY_VESSEL_OF_RUIN) && atkAbility != ABILITY_VESSEL_OF_RUIN && IS_MOVE_SPECIAL(move))
+ if (IsAbilityOnField(ABILITY_VESSEL_OF_RUIN) && atkAbility != ABILITY_VESSEL_OF_RUIN && IsBattleMoveSpecial(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.75));
- if (IsAbilityOnField(ABILITY_TABLETS_OF_RUIN) && atkAbility != ABILITY_TABLETS_OF_RUIN && IS_MOVE_PHYSICAL(move))
+ if (IsAbilityOnField(ABILITY_TABLETS_OF_RUIN) && atkAbility != ABILITY_TABLETS_OF_RUIN && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(0.75));
// attacker's hold effect
switch (holdEffectAtk)
{
case HOLD_EFFECT_THICK_CLUB:
- if ((atkBaseSpeciesId == SPECIES_CUBONE || atkBaseSpeciesId == SPECIES_MAROWAK) && IS_MOVE_PHYSICAL(move))
+ if ((atkBaseSpeciesId == SPECIES_CUBONE || atkBaseSpeciesId == SPECIES_MAROWAK) && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case HOLD_EFFECT_DEEP_SEA_TOOTH:
- if (gBattleMons[battlerAtk].species == SPECIES_CLAMPERL && IS_MOVE_SPECIAL(move))
+ if (gBattleMons[battlerAtk].species == SPECIES_CLAMPERL && IsBattleMoveSpecial(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case HOLD_EFFECT_LIGHT_BALL:
- if (atkBaseSpeciesId == SPECIES_PIKACHU && (B_LIGHT_BALL_ATTACK_BOOST >= GEN_4 || IS_MOVE_SPECIAL(move)))
+ if (atkBaseSpeciesId == SPECIES_PIKACHU && (B_LIGHT_BALL_ATTACK_BOOST >= GEN_4 || IsBattleMoveSpecial(move)))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0));
break;
case HOLD_EFFECT_CHOICE_BAND:
- if (IS_MOVE_PHYSICAL(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX)
+ if (IsBattleMovePhysical(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case HOLD_EFFECT_CHOICE_SPECS:
- if (IS_MOVE_SPECIAL(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX)
+ if (IsBattleMoveSpecial(move) && GetActiveGimmick(battlerAtk) != GIMMICK_DYNAMAX)
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
}
// The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the 1st badge and 7th badges.
// Having the 1st badge boosts physical attack while having the 7th badge boosts special attack.
- if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, battlerAtk) && IS_MOVE_PHYSICAL(move))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE01_GET, battlerAtk) && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
- if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerAtk) && IS_MOVE_SPECIAL(move))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerAtk) && IsBattleMoveSpecial(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
return uq4_12_multiply_by_int_half_down(modifier, atkStat);
@@ -9773,6 +9936,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData,
u32 battlerDef = damageCalcData->battlerDef;
u32 move = damageCalcData->move;
u32 moveType = damageCalcData->moveType;
+ u32 moveEffect = GetMoveEffect(move);
if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM) // the defense stats are swapped
{
@@ -9785,7 +9949,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData,
spDef = gBattleMons[battlerDef].spDefense;
}
- if (gMovesInfo[move].effect == EFFECT_PSYSHOCK || IS_MOVE_PHYSICAL(move)) // uses defense stat instead of sp.def
+ if (moveEffect == EFFECT_PSYSHOCK || IsBattleMovePhysical(move)) // uses defense stat instead of sp.def
{
defStat = def;
defStage = gBattleMons[battlerDef].statStages[STAT_DEF];
@@ -9799,7 +9963,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData,
}
// Self-destruct / Explosion cut defense in half
- if (B_EXPLOSION_DEFENSE < GEN_5 && gMovesInfo[gCurrentMove].effect == EFFECT_EXPLOSION)
+ if (B_EXPLOSION_DEFENSE < GEN_5 && moveEffect == EFFECT_EXPLOSION)
defStat /= 2;
// critical hits ignore positive stat changes
@@ -9809,7 +9973,7 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData,
if (atkAbility == ABILITY_UNAWARE)
defStage = DEFAULT_STAT_STAGE;
// certain moves also ignore stat changes
- if (gMovesInfo[move].ignoresTargetDefenseEvasionStages)
+ if (MoveIgnoresDefenseEvasionStages(move))
defStage = DEFAULT_STAT_STAGE;
defStat *= gStatStageRatios[defStage][0];
@@ -9911,9 +10075,9 @@ static inline u32 CalcDefenseStat(struct DamageCalculationData *damageCalcData,
// The defensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the 5th badge and 7th badges.
// Having the 5th badge boosts physical defense while having the 7th badge boosts special defense.
- if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, battlerDef) && IS_MOVE_PHYSICAL(move))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE05_GET, battlerDef) && IsBattleMovePhysical(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
- if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerDef) && IS_MOVE_SPECIAL(move))
+ if (ShouldGetStatBadgeBoost(FLAG_BADGE07_GET, battlerDef) && IsBattleMoveSpecial(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.1));
return uq4_12_multiply_by_int_half_down(modifier, defStat);
@@ -9962,7 +10126,7 @@ static uq4_12_t GetWeatherDamageModifier(struct DamageCalculationData *damageCal
if (weather == B_WEATHER_NONE)
return UQ_4_12(1.0);
- if (gMovesInfo[move].effect == EFFECT_HYDRO_STEAM && (weather & B_WEATHER_SUN) && holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA)
+ if (GetMoveEffect(move) == EFFECT_HYDRO_STEAM && (weather & B_WEATHER_SUN) && holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA)
return UQ_4_12(1.5);
if (holdEffectDef == HOLD_EFFECT_UTILITY_UMBRELLA)
return UQ_4_12(1.0);
@@ -9986,15 +10150,16 @@ static inline uq4_12_t GetBurnOrFrostBiteModifier(struct DamageCalculationData *
{
u32 battlerAtk = damageCalcData->battlerAtk;
u32 move = damageCalcData->move;
+ u32 moveEffect = GetMoveEffect(move);
if (gBattleMons[battlerAtk].status1 & STATUS1_BURN
- && IS_MOVE_PHYSICAL(move)
- && (B_BURN_FACADE_DMG < GEN_6 || gMovesInfo[move].effect != EFFECT_FACADE)
+ && IsBattleMovePhysical(move)
+ && (B_BURN_FACADE_DMG < GEN_6 || moveEffect != EFFECT_FACADE)
&& abilityAtk != ABILITY_GUTS)
return UQ_4_12(0.5);
if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE
- && IS_MOVE_SPECIAL(move)
- && (B_BURN_FACADE_DMG < GEN_6 || gMovesInfo[move].effect != EFFECT_FACADE))
+ && IsBattleMoveSpecial(move)
+ && (B_BURN_FACADE_DMG < GEN_6 || moveEffect != EFFECT_FACADE))
return UQ_4_12(0.5);
return UQ_4_12(1.0);
}
@@ -10022,28 +10187,28 @@ static inline uq4_12_t GetZMaxMoveAgainstProtectionModifier(struct DamageCalcula
static inline uq4_12_t GetMinimizeModifier(u32 move, u32 battlerDef)
{
- if (gMovesInfo[move].minimizeDoubleDamage && gStatuses3[battlerDef] & STATUS3_MINIMIZED)
+ if (MoveIncreasesPowerToMinimizedTargets(move) && gStatuses3[battlerDef] & STATUS3_MINIMIZED)
return UQ_4_12(2.0);
return UQ_4_12(1.0);
}
static inline uq4_12_t GetUndergroundModifier(u32 move, u32 battlerDef)
{
- if (gMovesInfo[move].damagesUnderground && gStatuses3[battlerDef] & STATUS3_UNDERGROUND)
+ if (MoveDamagesUnderground(move) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND)
return UQ_4_12(2.0);
return UQ_4_12(1.0);
}
static inline uq4_12_t GetDiveModifier(u32 move, u32 battlerDef)
{
- if (gMovesInfo[move].damagesUnderwater && gStatuses3[battlerDef] & STATUS3_UNDERWATER)
+ if (MoveDamagesUnderWater(move) && gStatuses3[battlerDef] & STATUS3_UNDERWATER)
return UQ_4_12(2.0);
return UQ_4_12(1.0);
}
static inline uq4_12_t GetAirborneModifier(u32 move, u32 battlerDef)
{
- if (gMovesInfo[move].damagesAirborneDoubleDamage && gStatuses3[battlerDef] & STATUS3_ON_AIR)
+ if (MoveDamagesAirborneDoubleDamage(move) && gStatuses3[battlerDef] & STATUS3_ON_AIR)
return UQ_4_12(2.0);
return UQ_4_12(1.0);
}
@@ -10051,8 +10216,8 @@ static inline uq4_12_t GetAirborneModifier(u32 move, u32 battlerDef)
static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerDef, bool32 isCrit, u32 abilityAtk)
{
u32 sideStatus = gSideStatuses[GetBattlerSide(battlerDef)];
- bool32 lightScreen = (sideStatus & SIDE_STATUS_LIGHTSCREEN) && IS_MOVE_SPECIAL(move);
- bool32 reflect = (sideStatus & SIDE_STATUS_REFLECT) && IS_MOVE_PHYSICAL(move);
+ bool32 lightScreen = (sideStatus & SIDE_STATUS_LIGHTSCREEN) && IsBattleMoveSpecial(move);
+ bool32 reflect = (sideStatus & SIDE_STATUS_REFLECT) && IsBattleMovePhysical(move);
bool32 auroraVeil = sideStatus & SIDE_STATUS_AURORA_VEIL;
if (isCrit || abilityAtk == ABILITY_INFILTRATOR || gProtectStructs[battlerAtk].confusionSelfDmg)
@@ -10064,7 +10229,7 @@ static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerD
static inline uq4_12_t GetCollisionCourseElectroDriftModifier(u32 move, uq4_12_t typeEffectivenessModifier)
{
- if (gMovesInfo[move].effect == EFFECT_COLLISION_COURSE && typeEffectivenessModifier >= UQ_4_12(2.0))
+ if (GetMoveEffect(move) == EFFECT_COLLISION_COURSE && typeEffectivenessModifier >= UQ_4_12(2.0))
return UQ_4_12(1.3333);
return UQ_4_12(1.0);
}
@@ -10095,7 +10260,7 @@ static inline uq4_12_t GetDefenderAbilitiesModifier(u32 move, u32 moveType, u32
{
case ABILITY_MULTISCALE:
case ABILITY_SHADOW_SHIELD:
- if (BATTLER_MAX_HP(battlerDef))
+ if (IsBattlerAtMaxHp(battlerDef))
return UQ_4_12(0.5);
break;
case ABILITY_FILTER:
@@ -10111,11 +10276,11 @@ static inline uq4_12_t GetDefenderAbilitiesModifier(u32 move, u32 moveType, u32
return UQ_4_12(0.5);
break;
case ABILITY_PUNK_ROCK:
- if (gMovesInfo[move].soundMove)
+ if (IsSoundMove(move))
return UQ_4_12(0.5);
break;
case ABILITY_ICE_SCALES:
- if (IS_MOVE_SPECIAL(move))
+ if (IsBattleMoveSpecial(move))
return UQ_4_12(0.5);
break;
}
@@ -10138,19 +10303,23 @@ static inline uq4_12_t GetDefenderPartnerAbilitiesModifier(u32 battlerPartnerDef
static inline uq4_12_t GetAttackerItemsModifier(u32 battlerAtk, uq4_12_t typeEffectivenessModifier, u32 holdEffectAtk)
{
- u32 percentBoost;
+ u32 metronomeTurns;
+ uq4_12_t metronomeBoostBase;
switch (holdEffectAtk)
{
case HOLD_EFFECT_METRONOME:
- percentBoost = min((gBattleStruct->sameMoveTurns[battlerAtk] * GetBattlerHoldEffectParam(battlerAtk)), 100);
- return uq4_12_add(sPercentToModifier[percentBoost], UQ_4_12(1.0));
+ metronomeBoostBase = PercentToUQ4_12(GetBattlerHoldEffectParam(battlerAtk));
+ metronomeTurns = min(gBattleStruct->sameMoveTurns[battlerAtk], 5);
+ // according to bulbapedia this is the "correct" way to calculate the metronome boost
+ // due to the limited domain of damage numbers it will never really matter whether this is off by one
+ return uq4_12_add(UQ_4_12(1.0), metronomeBoostBase * metronomeTurns);
break;
case HOLD_EFFECT_EXPERT_BELT:
if (typeEffectivenessModifier >= UQ_4_12(2.0))
return UQ_4_12(1.2);
break;
case HOLD_EFFECT_LIFE_ORB:
- return UQ_4_12(1.3);
+ return UQ_4_12_FLOORED(1.3);
break;
}
return UQ_4_12(1.0);
@@ -10310,9 +10479,9 @@ static inline s32 DoFutureSightAttackDamageCalcVars(struct DamageCalculationData
struct Pokemon *partyMon = &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]];
u32 partyMonLevel = GetMonData(partyMon, MON_DATA_LEVEL, NULL);
u32 partyMonSpecies = GetMonData(partyMon, MON_DATA_SPECIES, NULL);
- gBattleMovePower = gMovesInfo[move].power;
+ gBattleMovePower = GetMovePower(move);
- if (IS_MOVE_PHYSICAL(move))
+ if (IsBattleMovePhysical(move))
userFinalAttack = GetMonData(partyMon, MON_DATA_ATK, NULL);
else
userFinalAttack = GetMonData(partyMon, MON_DATA_SPATK, NULL);
@@ -10368,7 +10537,7 @@ static u32 GetWeather(void)
static inline bool32 IsFutureSightAttackerInParty(struct DamageCalculationData *damageCalcData)
{
- if (gMovesInfo[damageCalcData->move].effect != EFFECT_FUTURE_SIGHT)
+ if (GetMoveEffect(damageCalcData->move) != EFFECT_FUTURE_SIGHT)
return FALSE;
struct Pokemon *party = GetSideParty(GetBattlerSide(gBattlerAttacker));
@@ -10425,7 +10594,7 @@ static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 move
if (moveType == TYPE_PSYCHIC && defType == TYPE_DARK && gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED && mod == UQ_4_12(0.0))
mod = UQ_4_12(1.0);
- if (gMovesInfo[move].effect == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == gMovesInfo[move].argument)
+ if (GetMoveEffect(move) == EFFECT_SUPER_EFFECTIVE_ON_ARG && defType == GetMoveArgType(move))
mod = UQ_4_12(2.0);
if (moveType == TYPE_GROUND && defType == TYPE_FLYING && IsBattlerGrounded(battlerDef) && mod == UQ_4_12(0.0))
mod = UQ_4_12(1.0);
@@ -10439,7 +10608,7 @@ static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 move
mod = UQ_4_12(1.0);
}
- if (gBattleStruct->distortedTypeMatchups & (1u << battlerDef) || (AI_DATA->aiCalcInProgress && ShouldTeraShellDistortTypeMatchups(move, battlerDef)))
+ if (gSpecialStatuses[battlerDef].distortedTypeMatchups || (AI_DATA->aiCalcInProgress && ShouldTeraShellDistortTypeMatchups(move, battlerDef)))
{
mod = UQ_4_12(0.5);
if (recordAbilities)
@@ -10461,60 +10630,62 @@ static inline void TryNoticeIllusionInTypeEffectiveness(u32 move, u32 moveType,
RecordAbilityBattle(battlerDef, ABILITY_ILLUSION);
}
-static void UpdateMoveResultFlags(uq4_12_t modifier)
+static void UpdateMoveResultFlags(uq4_12_t modifier, u32 battler)
{
if (modifier == UQ_4_12(0.0))
{
- gMoveResultFlags |= MOVE_RESULT_DOESNT_AFFECT_FOE;
- gMoveResultFlags &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE);
+ gBattleStruct->moveResultFlags[battler] |= MOVE_RESULT_DOESNT_AFFECT_FOE;
+ gBattleStruct->moveResultFlags[battler] &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE);
+ gBattleStruct->blunderPolicy = FALSE; // Don't activate if missed
}
else if (modifier == UQ_4_12(1.0))
{
- gMoveResultFlags &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_DOESNT_AFFECT_FOE);
+ gBattleStruct->moveResultFlags[battler] &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_DOESNT_AFFECT_FOE);
}
else if (modifier > UQ_4_12(1.0))
{
- gMoveResultFlags |= MOVE_RESULT_SUPER_EFFECTIVE;
- gMoveResultFlags &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_DOESNT_AFFECT_FOE);
+ gBattleStruct->moveResultFlags[battler] |= MOVE_RESULT_SUPER_EFFECTIVE;
+ gBattleStruct->moveResultFlags[battler] &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_DOESNT_AFFECT_FOE);
}
else //if (modifier < UQ_4_12(1.0))
{
- gMoveResultFlags |= MOVE_RESULT_NOT_VERY_EFFECTIVE;
- gMoveResultFlags &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_DOESNT_AFFECT_FOE);
+ gBattleStruct->moveResultFlags[battler] |= MOVE_RESULT_NOT_VERY_EFFECTIVE;
+ gBattleStruct->moveResultFlags[battler] &= ~(MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_DOESNT_AFFECT_FOE);
}
}
static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, bool32 recordAbilities, uq4_12_t modifier, u32 defAbility)
{
u32 illusionSpecies;
+ u32 types[3];
+ GetBattlerTypes(battlerDef, FALSE, types);
- MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, GetBattlerType(battlerDef, 0, FALSE), battlerAtk, recordAbilities);
- if (GetBattlerType(battlerDef, 1, FALSE) != GetBattlerType(battlerDef, 0, FALSE))
- MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, GetBattlerType(battlerDef, 1, FALSE), battlerAtk, recordAbilities);
- if (GetBattlerType(battlerDef, 2, FALSE) != TYPE_MYSTERY && GetBattlerType(battlerDef, 2, FALSE) != GetBattlerType(battlerDef, 1, FALSE)
- && GetBattlerType(battlerDef, 2, FALSE) != GetBattlerType(battlerDef, 0, FALSE))
- MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, GetBattlerType(battlerDef, 2, FALSE), battlerAtk, recordAbilities);
+ MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, types[0], battlerAtk, recordAbilities);
+ if (types[1] != types[0])
+ MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, types[1], battlerAtk, recordAbilities);
+ if (types[2] != TYPE_MYSTERY && types[2] != types[1] && types[2] != types[0])
+ MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, types[2], battlerAtk, recordAbilities);
if (moveType == TYPE_FIRE && gDisableStructs[battlerDef].tarShot)
modifier = uq4_12_multiply(modifier, UQ_4_12(2.0));
if (recordAbilities && (illusionSpecies = GetIllusionMonSpecies(battlerDef)))
TryNoticeIllusionInTypeEffectiveness(move, moveType, battlerAtk, battlerDef, modifier, illusionSpecies);
- if (gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS && move != MOVE_THUNDER_WAVE)
+ if (GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS && move != MOVE_THUNDER_WAVE)
{
modifier = UQ_4_12(1.0);
if (B_GLARE_GHOST < GEN_4 && move == MOVE_GLARE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST))
modifier = UQ_4_12(0.0);
}
- else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, TRUE) && !(gMovesInfo[move].ignoreTypeIfFlyingAndUngrounded))
+ else if (moveType == TYPE_GROUND && !IsBattlerGroundedInverseCheck(battlerDef, TRUE) && !(MoveIgnoresTypeIfFlyingAndUngrounded(move)))
{
modifier = UQ_4_12(0.0);
if (recordAbilities && defAbility == ABILITY_LEVITATE)
{
+ gBattleStruct->moveResultFlags[battlerDef] |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE);
gLastUsedAbility = ABILITY_LEVITATE;
- gMoveResultFlags |= (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE);
gLastLandedMoves[battlerDef] = 0;
- gBattleCommunication[MISS_TYPE] = B_MSG_GROUND_MISS;
+ gBattleStruct->missStringId[battlerDef] = B_MSG_GROUND_MISS;
RecordAbilityBattle(battlerDef, ABILITY_LEVITATE);
}
}
@@ -10524,23 +10695,24 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(u32 move, u32 mov
}
// Thousand Arrows ignores type modifiers for flying mons
- if (!IsBattlerGrounded(battlerDef) && (gMovesInfo[move].ignoreTypeIfFlyingAndUngrounded)
- && (GetBattlerType(battlerDef, 0, FALSE) == TYPE_FLYING || GetBattlerType(battlerDef, 1, FALSE) == TYPE_FLYING || GetBattlerType(battlerDef, 2, FALSE) == TYPE_FLYING))
+ if (!IsBattlerGrounded(battlerDef)
+ && MoveIgnoresTypeIfFlyingAndUngrounded(move)
+ && IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING))
{
modifier = UQ_4_12(1.0);
}
if (((defAbility == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0))
|| (defAbility == ABILITY_TELEPATHY && battlerDef == BATTLE_PARTNER(battlerAtk)))
- && gMovesInfo[move].power)
+ && GetMovePower(move) != 0)
{
modifier = UQ_4_12(0.0);
if (recordAbilities)
{
gLastUsedAbility = gBattleMons[battlerDef].ability;
- gMoveResultFlags |= MOVE_RESULT_MISSED;
+ gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_MISSED;
gLastLandedMoves[battlerDef] = 0;
- gBattleCommunication[MISS_TYPE] = B_MSG_AVOIDED_DMG;
+ gBattleStruct->missStringId[battlerDef] = B_MSG_AVOIDED_DMG;
RecordAbilityBattle(battlerDef, gBattleMons[battlerDef].ability);
}
}
@@ -10559,19 +10731,19 @@ uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk,
if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY)
{
modifier = CalcTypeEffectivenessMultiplierInternal(move, moveType, battlerAtk, battlerDef, recordAbilities, modifier, defAbility);
- if (gMovesInfo[move].effect == EFFECT_TWO_TYPED_MOVE)
- modifier = CalcTypeEffectivenessMultiplierInternal(move, gMovesInfo[move].argument, battlerAtk, battlerDef, recordAbilities, modifier, defAbility);
+ if (GetMoveEffect(move) == EFFECT_TWO_TYPED_MOVE)
+ modifier = CalcTypeEffectivenessMultiplierInternal(move, GetMoveArgType(move), battlerAtk, battlerDef, recordAbilities, modifier, defAbility);
}
if (recordAbilities)
- UpdateMoveResultFlags(modifier);
+ UpdateMoveResultFlags(modifier, battlerDef);
return modifier;
}
uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef)
{
uq4_12_t modifier = UQ_4_12(1.0);
- u32 moveType = GetMoveType(move);
+ u32 moveType = GetBattleMoveType(move);
if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY)
{
@@ -10581,11 +10753,11 @@ uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 a
if (moveType == TYPE_GROUND && abilityDef == ABILITY_LEVITATE && !(gFieldStatuses & STATUS_FIELD_GRAVITY))
modifier = UQ_4_12(0.0);
- if (abilityDef == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0) && gMovesInfo[move].power)
+ if (abilityDef == ABILITY_WONDER_GUARD && modifier <= UQ_4_12(1.0) && GetMovePower(move) != 0)
modifier = UQ_4_12(0.0);
}
- UpdateMoveResultFlags(modifier);
+ UpdateMoveResultFlags(modifier, speciesDef);
return modifier;
}
@@ -10604,7 +10776,7 @@ static uq4_12_t GetInverseTypeMultiplier(uq4_12_t multiplier)
}
}
-uq4_12_t GetTypeEffectiveness(struct Pokemon *mon, u8 moveType)
+uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, u8 moveType)
{
uq4_12_t modifier = UQ_4_12(1.0);
u16 abilityDef = GetMonAbility(mon);
@@ -10723,6 +10895,7 @@ bool32 DoesSpeciesUseHoldItemToChangeForm(u16 species, u16 heldItemId)
case FORM_CHANGE_BATTLE_PRIMAL_REVERSION:
case FORM_CHANGE_BATTLE_ULTRA_BURST:
case FORM_CHANGE_ITEM_HOLD:
+ case FORM_CHANGE_BEGIN_BATTLE:
if (formChanges[i].param1 == heldItemId)
return TRUE;
break;
@@ -10943,6 +11116,16 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
if (GetBattlerTeraType(battler) == formChanges[i].param1)
targetSpecies = formChanges[i].targetSpecies;
break;
+ case FORM_CHANGE_BATTLE_BEFORE_MOVE:
+ if (formChanges[i].param1 == gCurrentMove
+ && (formChanges[i].param2 == ABILITY_NONE || formChanges[i].param2 == GetBattlerAbility(battler)))
+ targetSpecies = formChanges[i].targetSpecies;
+ break;
+ case FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY:
+ if (formChanges[i].param1 == GetBattleMoveCategory(gCurrentMove)
+ && (formChanges[i].param2 == ABILITY_NONE || formChanges[i].param2 == GetBattlerAbility(battler)))
+ targetSpecies = formChanges[i].targetSpecies;
+ break;
}
}
}
@@ -11029,8 +11212,9 @@ bool32 TryBattleFormChange(u32 battler, u32 method)
bool32 DoBattlersShareType(u32 battler1, u32 battler2)
{
s32 i;
- u8 types1[3] = {GetBattlerType(battler1, 0, FALSE), GetBattlerType(battler1, 1, FALSE), GetBattlerType(battler1, 2, FALSE)};
- u8 types2[3] = {GetBattlerType(battler2, 0, FALSE), GetBattlerType(battler2, 1, FALSE), GetBattlerType(battler2, 2, FALSE)};
+ u32 types1[3], types2[3];
+ GetBattlerTypes(battler1, FALSE, types1);
+ GetBattlerTypes(battler2, FALSE, types2);
if (types1[2] == TYPE_MYSTERY)
types1[2] = types1[0];
@@ -11157,7 +11341,7 @@ bool32 ShouldGetStatBadgeBoost(u16 badgeFlag, u32 battler)
static u32 SwapMoveDamageCategory(u32 move)
{
- if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL)
+ if (GetMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL)
return DAMAGE_CATEGORY_SPECIAL;
return DAMAGE_CATEGORY_PHYSICAL;
}
@@ -11169,11 +11353,11 @@ u8 GetBattleMoveCategory(u32 moveId)
if (gBattleStruct != NULL && (IsZMove(moveId) || IsMaxMove(moveId))) // TODO: Might be buggy depending on when this is called.
return gBattleStruct->categoryOverride;
if (B_PHYSICAL_SPECIAL_SPLIT >= GEN_4)
- return gMovesInfo[moveId].category;
+ return GetMoveCategory(moveId);
- if (IS_MOVE_STATUS(moveId))
+ if (IsBattleMoveStatus(moveId))
return DAMAGE_CATEGORY_STATUS;
- return gTypesInfo[GetMoveType(gCurrentMove)].damageCategory;
+ return gTypesInfo[GetBattleMoveType(moveId)].damageCategory;
}
static bool32 TryRemoveScreens(u32 battler)
@@ -11236,7 +11420,7 @@ static u32 GetFlingPowerFromItemId(u32 itemId)
{
if (itemId >= ITEM_TM01 && itemId <= ITEM_HM08)
{
- u32 power = gMovesInfo[ItemIdToBattleMoveId(itemId)].power;
+ u32 power = GetMovePower(ItemIdToBattleMoveId(itemId));
if (power > 1)
return power;
return 10; // Status moves and moves with variable power always return 10 power.
@@ -11518,7 +11702,7 @@ u16 GetUsedHeldItem(u32 battler)
bool32 CantPickupItem(u32 battler)
{
// Used by RandomUniformExcept() for RNG_PICKUP
- if (battler == gBattlerAttacker && gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK))
+ if (battler == gBattlerAttacker && (B_PICKUP_WILD < GEN_9 || gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK)))
return TRUE;
return !(IsBattlerAlive(battler) && GetUsedHeldItem(battler) && gBattleStruct->canPickupItem & (1u << battler));
}
@@ -11553,17 +11737,18 @@ u32 GetBattlerMoveTargetType(u32 battler, u32 move)
{
if (move == MOVE_CURSE && !IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
return MOVE_TARGET_USER;
- if (gMovesInfo[move].effect == EFFECT_EXPANDING_FORCE && IsBattlerTerrainAffected(battler, STATUS_FIELD_PSYCHIC_TERRAIN))
+ u32 effect = GetMoveEffect(move);
+ if (effect == EFFECT_EXPANDING_FORCE && IsBattlerTerrainAffected(battler, STATUS_FIELD_PSYCHIC_TERRAIN))
return MOVE_TARGET_BOTH;
- if (gMovesInfo[move].effect == EFFECT_TERA_STARSTORM && gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR)
+ if (effect == EFFECT_TERA_STARSTORM && gBattleMons[battler].species == SPECIES_TERAPAGOS_STELLAR)
return MOVE_TARGET_BOTH;
- return gMovesInfo[move].target;
+ return GetMoveTarget(move);
}
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move)
{
- if (gMovesInfo[move].effect == EFFECT_HIT_ENEMY_HEAL_ALLY
+ if (GetMoveEffect(move) == EFFECT_HIT_ENEMY_HEAL_ALLY
&& GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef)
&& gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK)
return FALSE; // Pokémon affected by Heal Block cannot target allies with Pollen Puff
@@ -11690,10 +11875,11 @@ bool32 IsGen6ExpShareEnabled(void)
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect)
{
u32 i;
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < numAdditionalEffects; i++)
{
- if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect
- && gMovesInfo[move].additionalEffects[i].self == FALSE)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ if (additionalEffect->moveEffect == moveEffect && additionalEffect->self == FALSE)
return TRUE;
}
return FALSE;
@@ -11702,10 +11888,11 @@ bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect)
bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance)
{
u32 i;
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < numAdditionalEffects; i++)
{
- if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect
- && gMovesInfo[move].additionalEffects[i].chance == chance)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ if (additionalEffect->moveEffect == moveEffect && additionalEffect->chance == chance)
return TRUE;
}
return FALSE;
@@ -11714,26 +11901,28 @@ bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance)
bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect)
{
u32 i;
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < numAdditionalEffects; i++)
{
- if (gMovesInfo[move].additionalEffects[i].moveEffect == moveEffect
- && gMovesInfo[move].additionalEffects[i].self == TRUE)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ if (additionalEffect->moveEffect == moveEffect && additionalEffect->self == TRUE)
return TRUE;
}
return FALSE;
}
-bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument)
+bool32 IsMoveEffectRemoveSpeciesType(u32 move, u32 moveEffect, u32 argument)
{
- return (gMovesInfo[move].argument == argument) && MoveHasAdditionalEffectSelf(move, moveEffect);
+ return (GetMoveArgType(move) == argument) && MoveHasAdditionalEffectSelf(move, moveEffect);
}
bool32 MoveHasChargeTurnAdditionalEffect(u32 move)
{
u32 i;
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < numAdditionalEffects; i++)
{
- if (gMovesInfo[move].additionalEffects[i].onChargeTurnOnly)
+ if (GetMoveAdditionalEffectById(move, i)->onChargeTurnOnly)
return TRUE;
}
return FALSE;
@@ -11742,9 +11931,16 @@ bool32 MoveHasChargeTurnAdditionalEffect(u32 move)
bool32 MoveIsAffectedBySheerForce(u32 move)
{
u32 i;
- for (i = 0; i < gMovesInfo[move].numAdditionalEffects; i++)
+ u32 numAdditionalEffects = GetMoveAdditionalEffectCount(move);
+ for (i = 0; i < numAdditionalEffects; i++)
{
- if (gMovesInfo[move].additionalEffects[i].chance > 0)
+ const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i);
+ if (additionalEffect->sheerForceBoost == SHEER_FORCE_NO_BOOST)
+ continue;
+
+ if (additionalEffect->chance > 0)
+ return TRUE;
+ if (additionalEffect->sheerForceBoost == SHEER_FORCE_BOOST)
return TRUE;
}
return FALSE;
@@ -11801,31 +11997,40 @@ bool8 IsMonBannedFromSkyBattles(u16 species)
}
}
-u8 GetBattlerType(u32 battler, u8 typeIndex, bool32 ignoreTera)
+void GetBattlerTypes(u32 battler, bool32 ignoreTera, u32 types[static 3])
{
- u32 teraType = GetBattlerTeraType(battler);
- u16 types[3] = {0};
+ // Terastallization.
+ bool32 isTera = GetActiveGimmick(battler) == GIMMICK_TERA;
+ if (!ignoreTera && isTera)
+ {
+ u32 teraType = GetBattlerTeraType(battler);
+ if (teraType != TYPE_STELLAR)
+ {
+ types[0] = types[1] = types[2] = teraType;
+ return;
+ }
+ }
+
types[0] = gBattleMons[battler].types[0];
types[1] = gBattleMons[battler].types[1];
types[2] = gBattleMons[battler].types[2];
- // Handle Terastallization
- if (GetActiveGimmick(battler) == GIMMICK_TERA && teraType != TYPE_STELLAR && !ignoreTera)
- return GetBattlerTeraType(battler);
-
- // Handle Roost's Flying-type suppression
- if (typeIndex == 0 || typeIndex == 1)
+ // Roost.
+ if (!isTera && (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST))
{
- if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_ROOST
- && GetActiveGimmick(battler) != GIMMICK_TERA)
- {
- if (types[0] == TYPE_FLYING && types[1] == TYPE_FLYING)
- return B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY;
- else
- return types[typeIndex] == TYPE_FLYING ? TYPE_MYSTERY : types[typeIndex];
- }
+ if (types[0] == TYPE_FLYING && types[1] == TYPE_FLYING)
+ types[0] = types[1] = B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY;
+ else if (types[0] == TYPE_FLYING)
+ types[0] = TYPE_MYSTERY;
+ else if (types[1] == TYPE_FLYING)
+ types[1] = TYPE_MYSTERY;
}
+}
+u32 GetBattlerType(u32 battler, u32 typeIndex, bool32 ignoreTera)
+{
+ u32 types[3];
+ GetBattlerTypes(battler, ignoreTera, types);
return types[typeIndex];
}
@@ -11851,6 +12056,7 @@ void SetShellSideArmCategory(void)
u8 statStage;
u32 physical;
u32 special;
+ u32 power = GetMovePower(MOVE_SHELL_SIDE_ARM);
for (battlerAtk = 0; battlerAtk < gBattlersCount; battlerAtk++)
{
@@ -11874,14 +12080,14 @@ void SetShellSideArmCategory(void)
targetDefStat *= gStatStageRatios[statStage][0];
targetDefStat /= gStatStageRatios[statStage][1];
- physical = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * gMovesInfo[MOVE_SHELL_SIDE_ARM].power * attackerAtkStat) / targetDefStat) / 50);
+ physical = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerAtkStat) / targetDefStat) / 50);
targetSpDefStat = gBattleMons[battlerDef].spDefense;
statStage = gBattleMons[battlerDef].statStages[STAT_SPDEF];
targetSpDefStat *= gStatStageRatios[statStage][0];
targetSpDefStat /= gStatStageRatios[statStage][1];
- special = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * gMovesInfo[MOVE_SHELL_SIDE_ARM].power * attackerSpAtkStat) / targetSpDefStat) / 50);
+ special = ((((2 * gBattleMons[battlerAtk].level / 5 + 2) * power * attackerSpAtkStat) / targetSpDefStat) / 50);
if ((physical > special) || (physical == special && RandomPercentage(RNG_SHELL_SIDE_ARM, 50)))
gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] = DAMAGE_CATEGORY_PHYSICAL;
@@ -11906,13 +12112,13 @@ static inline bool32 DoesBattlerHaveAbilityImmunity(u32 battlerDef)
bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef)
{
- return ((CalcTypeEffectivenessMultiplier(gCurrentMove, GetMoveType(gCurrentMove), battlerAtk, battlerDef, GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0))
+ return ((CalcTypeEffectivenessMultiplier(gCurrentMove, GetBattleMoveType(gCurrentMove), battlerAtk, battlerDef, GetBattlerAbility(battlerDef), FALSE) == UQ_4_12(0.0))
|| IsBattlerProtected(battlerAtk, battlerDef, gCurrentMove)
|| IsSemiInvulnerable(battlerDef, gCurrentMove)
|| DoesBattlerHaveAbilityImmunity(battlerDef));
}
-u32 GetMoveType(u32 move)
+u32 GetBattleMoveType(u32 move)
{
if (gMain.inBattle && gBattleStruct->dynamicMoveType)
return gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK;
@@ -11921,5 +12127,87 @@ u32 GetMoveType(u32 move)
|| move == MOVE_FUTURE_SIGHT
|| move == MOVE_DOOM_DESIRE))
return TYPE_MYSTERY;
- return gMovesInfo[move].type;
+ return GetMoveType(move);
+}
+
+void TryActivateSleepClause(u32 battler, u32 indexInParty)
+{
+ if (gBattleStruct->sleepClauseEffectExempt & (1u << battler))
+ {
+ gBattleStruct->sleepClauseEffectExempt &= ~(1u << battler);
+ return;
+ }
+
+ if (IsSleepClauseEnabled())
+ gBattleStruct->monCausingSleepClause[GetBattlerSide(battler)] = indexInParty;
+}
+
+void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty)
+{
+ // If the pokemon on the given side at the given index in the party is the one causing Sleep Clause to be active,
+ // set monCausingSleepClause[battlerSide] = PARTY_SIZE, which means Sleep Clause is not active for the given side
+ if (IsSleepClauseEnabled() && gBattleStruct->monCausingSleepClause[battlerSide] == indexInParty)
+ gBattleStruct->monCausingSleepClause[battlerSide] = PARTY_SIZE;
+}
+
+bool32 IsSleepClauseActiveForSide(u32 battlerSide)
+{
+ // If monCausingSleepClause[battlerSide] == PARTY_SIZE, Sleep Clause is not active for the given side.
+ // If monCausingSleepClause[battlerSide] < PARTY_SIZE, it means it is storing the index of the mon that is causing Sleep Clause to be active,
+ // from which it follows that Sleep Clause is active.
+ return (IsSleepClauseEnabled() && (gBattleStruct->monCausingSleepClause[battlerSide] < PARTY_SIZE));
+}
+
+bool32 IsSleepClauseEnabled()
+{
+ if (B_SLEEP_CLAUSE)
+ return TRUE;
+ if (FlagGet(B_FLAG_SLEEP_CLAUSE))
+ return TRUE;
+ return FALSE;
+}
+
+void ClearDamageCalcResults(void)
+{
+ for (u32 battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
+ {
+ gBattleStruct->moveDamage[battler] = 0;
+ gBattleStruct->critChance[battler] = 0;
+ gBattleStruct->moveResultFlags[battler] = 0;
+ gBattleStruct->noResultString[battler] = 0;
+ gBattleStruct->missStringId[battler] = 0;
+ gSpecialStatuses[battler].criticalHit = FALSE;
+ }
+
+ gBattleStruct->doneDoublesSpreadHit = FALSE;
+ gBattleStruct->calculatedDamageDone = FALSE;
+ gBattleStruct->calculatedSpreadMoveAccuracy = FALSE;
+ gBattleStruct->printedStrongWindsWeakenedAttack = FALSE;
+ gBattleStruct->numSpreadTargets = 0;
+}
+
+bool32 DoesDestinyBondFail(u32 battler)
+{
+ if (B_DESTINY_BOND_FAIL >= GEN_7
+ && GetMoveEffect(gLastResultingMoves[battler]) == EFFECT_DESTINY_BOND
+ && !(gBattleStruct->lastMoveFailed & (1u << battler)))
+ return TRUE;
+ return FALSE;
+}
+
+// This check has always to be the last in a condtion statement because of the recording of AI data.
+bool32 IsMoveEffectBlockedByTarget(u32 ability)
+{
+ if (ability == ABILITY_SHIELD_DUST)
+ {
+ RecordAbilityBattle(gBattlerTarget, ability);
+ return TRUE;
+ }
+ else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_COVERT_CLOAK)
+ {
+ RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_COVERT_CLOAK);
+ return TRUE;
+ }
+
+ return FALSE;
}
diff --git a/src/battle_z_move.c b/src/battle_z_move.c
index 5e6cfe8e0e..c878a2c12b 100644
--- a/src/battle_z_move.c
+++ b/src/battle_z_move.c
@@ -151,7 +151,7 @@ u32 GetUsableZMove(u32 battler, u32 move)
if (zMove != MOVE_NONE)
return zMove; // Signature z move exists
- if (move != MOVE_NONE && zMove != MOVE_Z_STATUS && gMovesInfo[move].type == ItemId_GetSecondaryId(item))
+ if (move != MOVE_NONE && zMove != MOVE_Z_STATUS && GetMoveType(move) == ItemId_GetSecondaryId(item))
return GetTypeBasedZMove(move);
}
@@ -195,7 +195,7 @@ bool32 IsViableZMove(u32 battler, u32 move)
if (zMove != MOVE_NONE)
return TRUE;
- if (move != MOVE_NONE && gMovesInfo[move].type == ItemId_GetSecondaryId(item))
+ if (move != MOVE_NONE && GetMoveType(move) == ItemId_GetSecondaryId(item))
return TRUE;
}
@@ -243,13 +243,13 @@ u32 GetSignatureZMove(u32 move, u32 species, u32 item)
u32 GetTypeBasedZMove(u32 move)
{
- u32 moveType = gMovesInfo[move].type;
+ u32 moveType = GetMoveType(move);
if (moveType >= NUMBER_OF_MON_TYPES)
moveType = TYPE_MYSTERY;
// Z-Weather Ball changes types, however Revelation Dance, -ate ability affected moves, and Hidden Power do not
- if (gBattleStruct->dynamicMoveType && gMovesInfo[move].effect == EFFECT_WEATHER_BALL)
+ if (gBattleStruct->dynamicMoveType && GetMoveEffect(move) == EFFECT_WEATHER_BALL)
moveType = gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK;
// Get Z-Move from type
@@ -276,9 +276,9 @@ bool32 MoveSelectionDisplayZMove(u16 zmove, u32 battler)
BattlePutTextOnWindow(gDisplayedStringBattle, i + 3);
}
- if (IS_MOVE_STATUS(move))
+ if (IsBattleMoveStatus(move))
{
- u8 zEffect = gMovesInfo[move].zMove.effect;
+ u8 zEffect = GetMoveZEffect(move);
gDisplayedStringBattle[0] = EOS;
@@ -388,9 +388,9 @@ static void ZMoveSelectionDisplayPower(u16 move, u16 zMove)
u16 power = GetZMovePower(move);
if (zMove >= MOVE_CATASTROPIKA)
- power = gMovesInfo[zMove].power;
+ power = GetMovePower(zMove);
- if (gMovesInfo[move].category != DAMAGE_CATEGORY_STATUS)
+ if (GetMoveCategory(move) != DAMAGE_CATEGORY_STATUS)
{
txtPtr = StringCopy(gDisplayedStringBattle, sText_PowerColon);
ConvertIntToDecimalStringN(txtPtr, power, STR_CONV_MODE_LEFT_ALIGN, 3);
@@ -415,7 +415,7 @@ static void ZMoveSelectionDisplayPpNumber(u32 battler)
static void ZMoveSelectionDisplayMoveType(u16 zMove, u32 battler)
{
u8 *txtPtr, *end;
- u32 zMoveType = GetMoveType(zMove);
+ u32 zMoveType = GetBattleMoveType(zMove);
txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfaceType);
*(txtPtr)++ = EXT_CTRL_CODE_BEGIN;
@@ -433,7 +433,7 @@ static void ZMoveSelectionDisplayMoveType(u16 zMove, u32 battler)
void SetZEffect(void)
{
u32 i;
- u32 effect = gMovesInfo[gBattleStruct->zmove.baseMoves[gBattlerAttacker]].zMove.effect;
+ u32 effect = GetMoveZEffect(gBattleStruct->zmove.baseMoves[gBattlerAttacker]);
if (effect == Z_EFFECT_CURSE)
{
@@ -503,7 +503,7 @@ void SetZEffect(void)
case Z_EFFECT_RECOVER_HP:
if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP)
{
- gBattleMoveDamage = (-1) * gBattleMons[gBattlerAttacker].maxHP;
+ gBattleStruct->moveDamage[gBattlerAttacker] = (-1) * gBattleMons[gBattlerAttacker].maxHP;
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_Z_RECOVER_HP;
BattleScriptPush(gBattlescriptCurrInstr + Z_EFFECT_BS_LENGTH);
gBattlescriptCurrInstr = BattleScript_RecoverHPZMove;
@@ -542,35 +542,25 @@ void SetZEffect(void)
u32 GetZMovePower(u32 move)
{
- if (gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
+ if (GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS)
return 0;
- if (gMovesInfo[move].effect == EFFECT_OHKO)
+ if (GetMoveEffect(move) == EFFECT_OHKO)
return 180;
- if (gMovesInfo[move].zMove.powerOverride > 0)
- return gMovesInfo[move].zMove.powerOverride;
- else
- {
- if (gMovesInfo[move].power >= 140)
- return 200;
- else if (gMovesInfo[move].power >= 130)
- return 195;
- else if (gMovesInfo[move].power >= 120)
- return 190;
- else if (gMovesInfo[move].power >= 110)
- return 185;
- else if (gMovesInfo[move].power >= 100)
- return 180;
- else if (gMovesInfo[move].power >= 90)
- return 175;
- else if (gMovesInfo[move].power >= 80)
- return 160;
- else if (gMovesInfo[move].power >= 70)
- return 140;
- else if (gMovesInfo[move].power >= 60)
- return 120;
- else
- return 100;
- }
+ u32 power = GetMoveZPowerOverride(move);
+ if (power > 0)
+ return power;
+
+ power = GetMovePower(move);
+ if (power >= 140) return 200;
+ else if (power >= 130) return 195;
+ else if (power >= 120) return 190;
+ else if (power >= 110) return 185;
+ else if (power >= 100) return 180;
+ else if (power >= 90) return 175;
+ else if (power >= 80) return 160;
+ else if (power >= 70) return 140;
+ else if (power >= 60) return 120;
+ else return 100;
}
diff --git a/src/berry.c b/src/berry.c
index 88278db47b..a287073df1 100644
--- a/src/berry.c
+++ b/src/berry.c
@@ -1711,11 +1711,13 @@ bool32 IsEnigmaBerryValid(void)
const struct Berry *GetBerryInfo(u8 berry)
{
if (berry == ITEM_TO_BERRY(ITEM_ENIGMA_BERRY_E_READER) && IsEnigmaBerryValid())
+ {
#if FREE_ENIGMA_BERRY == FALSE
return (struct Berry *)(&gSaveBlock1Ptr->enigmaBerry.berry);
#else
return &gBerries[0]; //never reached, but will appease the compiler gods
#endif //FREE_ENIGMA_BERRY
+ }
else
{
if (berry == BERRY_NONE || berry > ITEM_TO_BERRY(LAST_BERRY_INDEX))
@@ -2037,7 +2039,9 @@ static u8 CalcBerryYieldInternal(u16 max, u16 min, u8 water)
u32 extraYield;
if (water == 0 || OW_BERRY_MOISTURE)
+ {
return min;
+ }
else
{
randMin = (max - min) * (water - 1);
diff --git a/src/berry_crush.c b/src/berry_crush.c
index 2bb03e60a3..1f997708a7 100755
--- a/src/berry_crush.c
+++ b/src/berry_crush.c
@@ -3398,7 +3398,9 @@ static u32 Cmd_StopGame(struct BerryCrushGame *game, u8 *args)
break;
case 2:
if (game->gfx.counter != 0)
+ {
game->gfx.counter--;
+ }
else
{
RunOrScheduleCommand(CMD_CLOSE_LINK, SCHEDULE_CMD, NULL);
diff --git a/src/bike.c b/src/bike.c
index b369883093..5bbf647ce9 100644
--- a/src/bike.c
+++ b/src/bike.c
@@ -389,7 +389,9 @@ static u8 AcroBikeHandleInputWheelieStanding(u8 *newDirection, u16 newKeys, u16
gPlayerAvatar.runningState = NOT_MOVING;
if (heldKeys & B_BUTTON)
+ {
gPlayerAvatar.bikeFrameCounter++;
+ }
else
{
// B button was released.
diff --git a/src/caps.c b/src/caps.c
index 9c30e55527..941509c2a4 100644
--- a/src/caps.c
+++ b/src/caps.c
@@ -54,7 +54,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
if (B_LEVEL_CAP_EXP_UP)
{
levelDifference = currentLevelCap - level;
- if (levelDifference > ARRAY_COUNT(sExpScalingUp))
+ if (levelDifference > ARRAY_COUNT(sExpScalingUp) - 1)
return expValue + (expValue / sExpScalingUp[ARRAY_COUNT(sExpScalingUp) - 1]);
else
return expValue + (expValue / sExpScalingUp[levelDifference]);
@@ -71,7 +71,7 @@ u32 GetSoftLevelCapExpValue(u32 level, u32 expValue)
else if (B_EXP_CAP_TYPE == EXP_CAP_SOFT)
{
levelDifference = level - currentLevelCap;
- if (levelDifference > ARRAY_COUNT(sExpScalingDown))
+ if (levelDifference > ARRAY_COUNT(sExpScalingDown) - 1)
return expValue / sExpScalingDown[ARRAY_COUNT(sExpScalingDown) - 1];
else
return expValue / sExpScalingDown[levelDifference];
diff --git a/src/contest.c b/src/contest.c
index 16e5fde9af..a1cd62777f 100644
--- a/src/contest.c
+++ b/src/contest.c
@@ -949,23 +949,22 @@ static const struct CompressedSpriteSheet sSpriteSheets_ContestantsTurnBlinkEffe
}
};
-// Yup this is super dangerous but that's how it is here
static const struct SpritePalette sSpritePalettes_ContestantsTurnBlinkEffect[CONTESTANT_COUNT] =
{
{
- .data = (u16 *)(gHeap + 0x1A0A4),
+ .data = eContestTempSave.cachedWindowPalettes[5],
.tag = TAG_BLINK_EFFECT_CONTESTANT0
},
{
- .data = (u16 *)(gHeap + 0x1A0C4),
+ .data = eContestTempSave.cachedWindowPalettes[6],
.tag = TAG_BLINK_EFFECT_CONTESTANT1
},
{
- .data = (u16 *)(gHeap + 0x1A0E4),
+ .data = eContestTempSave.cachedWindowPalettes[7],
.tag = TAG_BLINK_EFFECT_CONTESTANT2
},
{
- .data = (u16 *)(gHeap + 0x1A104),
+ .data = eContestTempSave.cachedWindowPalettes[8],
.tag = TAG_BLINK_EFFECT_CONTESTANT3
}
};
@@ -1640,7 +1639,7 @@ static void Task_ShowMoveSelectScreen(u8 taskId)
}
else if (move != MOVE_NONE
&& eContestantStatus[gContestPlayerMonIndex].prevMove == move
- && gMovesInfo[move].contestEffect != CONTEST_EFFECT_REPETITION_NOT_BORING)
+ && GetMoveContestEffect(move) != CONTEST_EFFECT_REPETITION_NOT_BORING)
{
// Gray the text because it's a repeated move
moveNameBuffer = StringCopy(moveName, gText_ColorBlue);
@@ -2311,7 +2310,7 @@ static void Task_DoAppeals(u8 taskId)
}
else
{
- StringCopy(gStringVar3, sContestConditions[gMovesInfo[eContestantStatus[contestant].currMove].contestCategory]);
+ StringCopy(gStringVar3, sContestConditions[GetMoveContestCategory(eContestantStatus[contestant].currMove)]);
}
if (r3 > 0 && eContestantStatus[contestant].repeatedMove)
@@ -2768,7 +2767,9 @@ static void Task_EndAppeals(u8 taskId)
CalculateFinalScores();
ContestClearGeneralTextWindow();
if (!(gLinkContestFlags & LINK_CONTEST_FLAG_IS_LINK))
+ {
BravoTrainerPokemonProfile_BeforeInterview1(eContestantStatus[gContestPlayerMonIndex].prevMove);
+ }
else
{
CalculateContestLiveUpdateData();
@@ -3266,7 +3267,7 @@ static u16 GetMoveEffectSymbolTileOffset(u16 move, u8 contestant)
{
u16 offset;
- switch (gContestEffects[gMovesInfo[move].contestEffect].effectType)
+ switch (gContestEffects[GetMoveContestEffect(move)].effectType)
{
case 0:
case 1:
@@ -3292,7 +3293,7 @@ static void PrintContestMoveDescription(u16 move)
u8 numHearts;
// The contest category icon is implemented as a 5x2 group of tiles.
- category = gMovesInfo[move].contestCategory;
+ category = GetMoveContestCategory(move);
if (category == CONTEST_CATEGORY_COOL)
categoryTile = 0x4040;
else if (category == CONTEST_CATEGORY_BEAUTY)
@@ -3308,27 +3309,27 @@ static void PrintContestMoveDescription(u16 move)
ContestBG_FillBoxWithIncrementingTile(0, categoryTile + 0x10, 0x0b, 0x20, 0x05, 0x01, 0x11, 0x01);
// Appeal hearts
- if (gContestEffects[gMovesInfo[move].contestEffect].appeal == 0xFF)
+ if (gContestEffects[GetMoveContestEffect(move)].appeal == 0xFF)
numHearts = 0;
else
- numHearts = gContestEffects[gMovesInfo[move].contestEffect].appeal / 10;
+ numHearts = gContestEffects[GetMoveContestEffect(move)].appeal / 10;
if (numHearts > MAX_CONTEST_MOVE_HEARTS)
numHearts = MAX_CONTEST_MOVE_HEARTS;
ContestBG_FillBoxWithTile(0, TILE_EMPTY_APPEAL_HEART, 0x15, 0x1f, MAX_CONTEST_MOVE_HEARTS, 0x01, 0x11);
ContestBG_FillBoxWithTile(0, TILE_FILLED_APPEAL_HEART, 0x15, 0x1f, numHearts, 0x01, 0x11);
// Jam hearts
- if (gContestEffects[gMovesInfo[move].contestEffect].jam == 0xFF)
+ if (gContestEffects[GetMoveContestEffect(move)].jam == 0xFF)
numHearts = 0;
else
- numHearts = gContestEffects[gMovesInfo[move].contestEffect].jam / 10;
+ numHearts = gContestEffects[GetMoveContestEffect(move)].jam / 10;
if (numHearts > MAX_CONTEST_MOVE_HEARTS)
numHearts = MAX_CONTEST_MOVE_HEARTS;
ContestBG_FillBoxWithTile(0, TILE_EMPTY_JAM_HEART, 0x15, 0x20, MAX_CONTEST_MOVE_HEARTS, 0x01, 0x11);
ContestBG_FillBoxWithTile(0, TILE_FILLED_JAM_HEART, 0x15, 0x20, numHearts, 0x01, 0x11);
FillWindowPixelBuffer(WIN_MOVE_DESCRIPTION, PIXEL_FILL(0));
- Contest_PrintTextToBg0WindowStd(WIN_MOVE_DESCRIPTION, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect]);
+ Contest_PrintTextToBg0WindowStd(WIN_MOVE_DESCRIPTION, gContestEffectDescriptionPointers[GetMoveContestEffect(move)]);
Contest_PrintTextToBg0WindowStd(WIN_SLASH, gText_Slash);
}
@@ -4529,9 +4530,9 @@ static void CalculateAppealMoveImpact(u8 contestant)
return;
move = eContestantStatus[contestant].currMove;
- effect = gMovesInfo[move].contestEffect;
+ effect = GetMoveContestEffect(move);
- eContestantStatus[contestant].moveCategory = gMovesInfo[eContestantStatus[contestant].currMove].contestCategory;
+ eContestantStatus[contestant].moveCategory = GetMoveContestCategory(eContestantStatus[contestant].currMove);
if (eContestantStatus[contestant].currMove == eContestantStatus[contestant].prevMove && eContestantStatus[contestant].currMove != MOVE_NONE)
{
eContestantStatus[contestant].repeatedMove = TRUE;
@@ -4582,7 +4583,7 @@ static void CalculateAppealMoveImpact(u8 contestant)
}
else
{
- if (gMovesInfo[eContestantStatus[contestant].currMove].contestComboStarterId != 0)
+ if (GetMoveContestComboStarter(eContestantStatus[contestant].currMove) != 0)
{
eContestantStatus[contestant].hasJudgesAttention = TRUE;
eContestantStatus[contestant].usedComboMove = TRUE;
@@ -4662,13 +4663,13 @@ static void PrintAppealMoveResultText(u8 contestant, u8 stringId)
{
StringCopy(gStringVar1, gContestMons[contestant].nickname);
StringCopy(gStringVar2, GetMoveName(eContestantStatus[contestant].currMove));
- if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_COOL)
+ if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_COOL)
StringCopy(gStringVar3, gText_Contest_Shyness);
- else if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_BEAUTY)
+ else if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_BEAUTY)
StringCopy(gStringVar3, gText_Contest_Anxiety);
- else if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_CUTE)
+ else if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_CUTE)
StringCopy(gStringVar3, gText_Contest_Laziness);
- else if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory == CONTEST_CATEGORY_SMART)
+ else if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) == CONTEST_CATEGORY_SMART)
StringCopy(gStringVar3, gText_Contest_Hesitancy);
else
StringCopy(gStringVar3, gText_Contest_Fear);
@@ -4841,7 +4842,7 @@ static void UpdateApplauseMeter(void)
s8 Contest_GetMoveExcitement(u16 move)
{
- return sContestExcitementTable[gSpecialVar_ContestCategory][gMovesInfo[move].contestCategory];
+ return sContestExcitementTable[gSpecialVar_ContestCategory][GetMoveContestCategory(move)];
}
static u8 StartApplauseOverflowAnimation(void)
diff --git a/src/contest_ai.c b/src/contest_ai.c
index f131c709ac..4386aeee64 100644
--- a/src/contest_ai.c
+++ b/src/contest_ai.c
@@ -758,7 +758,7 @@ static void ContestAICmd_get_move_effect(void)
{
u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex];
- eContestAI.scriptResult = gMovesInfo[move].contestEffect;
+ eContestAI.scriptResult = GetMoveContestEffect(move);
gAIScriptPtr += 1;
}
@@ -786,7 +786,7 @@ static void ContestAICmd_get_move_effect_type(void)
{
u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex];
- eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].effectType;
+ eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].effectType;
gAIScriptPtr += 1;
}
@@ -814,12 +814,12 @@ static void ContestAICmd_check_most_appealing_move(void)
{
int i;
u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex];
- u8 appeal = gContestEffects[gMovesInfo[move].contestEffect].appeal;
+ u8 appeal = gContestEffects[GetMoveContestEffect(move)].appeal;
for (i = 0; i < MAX_MON_MOVES; i++)
{
u16 newMove = gContestMons[eContestAI.contestantId].moves[i];
- if (newMove != 0 && appeal < gContestEffects[gMovesInfo[newMove].contestEffect].appeal)
+ if (newMove != 0 && appeal < gContestEffects[GetMoveContestEffect(newMove)].appeal)
break;
}
@@ -845,12 +845,12 @@ static void ContestAICmd_check_most_jamming_move(void)
{
int i;
u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex];
- u8 jam = gContestEffects[gMovesInfo[move].contestEffect].jam;
+ u8 jam = gContestEffects[GetMoveContestEffect(move)].jam;
for (i = 0; i < MAX_MON_MOVES; i++)
{
u16 newMove = gContestMons[eContestAI.contestantId].moves[i];
- if (newMove != MOVE_NONE && jam < gContestEffects[gMovesInfo[newMove].contestEffect].jam)
+ if (newMove != MOVE_NONE && jam < gContestEffects[GetMoveContestEffect(newMove)].jam)
break;
}
@@ -876,7 +876,7 @@ static void ContestAICmd_get_num_move_hearts(void)
{
u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex];
- eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].appeal / 10;
+ eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].appeal / 10;
gAIScriptPtr += 1;
}
@@ -924,7 +924,7 @@ static void ContestAICmd_get_num_move_jam_hearts(void)
{
u16 move = gContestMons[eContestAI.contestantId].moves[eContestAI.nextMoveIndex];
- eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].jam / 10;
+ eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].jam / 10;
gAIScriptPtr += 1;
}
@@ -1203,7 +1203,7 @@ static void ContestAICmd_get_used_combo_starter(void)
u8 contestant = GetContestantIdByTurn(gAIScriptPtr[1]);
if (IsContestantAllowedToCombo(contestant))
- result = gMovesInfo[eContestantStatus[contestant].prevMove].contestComboStarterId ? TRUE : FALSE;
+ result = GetMoveContestComboStarter(eContestantStatus[contestant].prevMove) ? TRUE : FALSE;
eContestAI.scriptResult = result;
gAIScriptPtr += 2;
@@ -1409,7 +1409,7 @@ static void ContestAICmd_get_used_moves_effect(void)
u8 round = gAIScriptPtr[2];
u16 move = eContest.moveHistory[round][contestant];
- eContestAI.scriptResult = gMovesInfo[move].contestEffect;
+ eContestAI.scriptResult = GetMoveContestEffect(move);
gAIScriptPtr += 3;
}
@@ -1509,7 +1509,7 @@ static void ContestAICmd_get_used_moves_effect_type(void)
u8 round = gAIScriptPtr[2];
u16 move = eContest.moveHistory[round][contestant];
- eContestAI.scriptResult = gContestEffects[gMovesInfo[move].contestEffect].effectType;
+ eContestAI.scriptResult = gContestEffects[GetMoveContestEffect(move)].effectType;
gAIScriptPtr += 3;
}
@@ -1748,7 +1748,7 @@ static void ContestAICmd_check_user_has_move(void)
for (i = 0; i < MAX_MON_MOVES; i++)
{
#ifdef BUGFIX
- u16 move = gMovesInfo[gContestMons[eContestAI.contestantId].moves[i]].contestEffect;
+ u16 move = GetMoveContestEffect(gContestMons[eContestAI.contestantId].moves[i]);
#else
u16 move = gContestMons[eContestAI.contestantId].moves[i];
#endif
diff --git a/src/contest_effect.c b/src/contest_effect.c
index aa22f1d13d..51416ba14a 100644
--- a/src/contest_effect.c
+++ b/src/contest_effect.c
@@ -1,4 +1,5 @@
#include "global.h"
+#include "move.h"
#include "random.h"
#include "constants/moves.h"
#include "contest.h"
@@ -60,7 +61,7 @@ static s16 RoundUp(s16);
bool8 AreMovesContestCombo(u16 lastMove, u16 nextMove)
{
int i;
- u8 lastMoveComboStarterId = gMovesInfo[lastMove].contestComboStarterId;
+ u8 lastMoveComboStarterId = GetMoveContestComboStarter(lastMove);
if (lastMoveComboStarterId == 0)
{
@@ -70,7 +71,7 @@ bool8 AreMovesContestCombo(u16 lastMove, u16 nextMove)
{
for (i = 0; i < MAX_COMBO_MOVES; i++)
{
- if (lastMoveComboStarterId == gMovesInfo[nextMove].contestComboMoves[i])
+ if (lastMoveComboStarterId == GetMoveContestComboMoves(nextMove, i))
return TRUE;
}
return FALSE;
@@ -132,7 +133,7 @@ static void ContestEffect_UserLessEasilyStartled(void)
SetContestantEffectStringID(eContestAppealResults.contestant,CONTEST_STRING_STOPPED_CARING);
}
-// Slightly startles the POKMON in front.
+// Slightly startles the POK�MON in front.
static void ContestEffect_StartleFrontMon(void)
{
u8 idx = 0;
@@ -180,7 +181,7 @@ static void ContestEffect_StartlePrevMons(void)
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Startles the POKMON that appealed before the user.
+// Startles the POK�MON that appealed before the user.
static void ContestEffect_StartlePrevMon2(void)
{
u8 rval = Random() % 10;
@@ -197,7 +198,7 @@ static void ContestEffect_StartlePrevMon2(void)
ContestEffect_StartleFrontMon();
}
-// Startles all POKMON that appealed before the user.
+// Startles all POK�MON that appealed before the user.
static void ContestEffect_StartlePrevMons2(void)
{
u8 numStartled = 0;
@@ -273,7 +274,7 @@ static void ContestEffect_ShiftJudgeAttention(void)
}
}
-// Startles the POKMON that has the JUDGE's attention.
+// Startles the POK�MON that has the JUDGE's attention.
static void ContestEffect_StartleMonWithJudgesAttention(void)
{
u8 numStartled = 0;
@@ -311,50 +312,50 @@ static void ContestEffect_JamsOthersButMissOneTurn(void)
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Startles POKMON that made a same-type appeal.
+// Startles POK�MON that made a same-type appeal.
static void ContestEffect_StartleMonsSameTypeAppeal(void)
{
u16 move = eContestantStatus[eContestAppealResults.contestant].currMove;
- JamByMoveCategory(gMovesInfo[move].contestCategory);
+ JamByMoveCategory(GetMoveContestCategory(move));
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Badly startles POKMON that made COOL appeals.
+// Badly startles POK�MON that made COOL appeals.
static void ContestEffect_StartleMonsCoolAppeal(void)
{
JamByMoveCategory(CONTEST_CATEGORY_COOL);
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Badly startles POKMON that made BEAUTY appeals.
+// Badly startles POK�MON that made BEAUTY appeals.
static void ContestEffect_StartleMonsBeautyAppeal(void)
{
JamByMoveCategory(CONTEST_CATEGORY_BEAUTY);
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Badly startles POKMON that made CUTE appeals.
+// Badly startles POK�MON that made CUTE appeals.
static void ContestEffect_StartleMonsCuteAppeal(void)
{
JamByMoveCategory(CONTEST_CATEGORY_CUTE);
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Badly startles POKMON that made SMART appeals.
+// Badly startles POK�MON that made SMART appeals.
static void ContestEffect_StartleMonsSmartAppeal(void)
{
JamByMoveCategory(CONTEST_CATEGORY_SMART);
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Badly startles POKMON that made TOUGH appeals.
+// Badly startles POK�MON that made TOUGH appeals.
static void ContestEffect_StartleMonsToughAppeal(void)
{
JamByMoveCategory(CONTEST_CATEGORY_TOUGH);
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_ATTEMPT_STARTLE);
}
-// Makes one POKMON after the user nervous.
+// Makes one POK�MON after the user nervous.
static void ContestEffect_MakeFollowingMonNervous(void)
{
bool32 hitAny = FALSE;
@@ -386,7 +387,7 @@ static void ContestEffect_MakeFollowingMonNervous(void)
SetContestantEffectStringID2(eContestAppealResults.contestant, CONTEST_STRING_MESSED_UP2);
}
-// Makes all POKMON after the user nervous.
+// Makes all POK�MON after the user nervous.
static void ContestEffect_MakeFollowingMonsNervous(void)
{
u8 numUnnerved = 0;
@@ -428,7 +429,7 @@ static void ContestEffect_MakeFollowingMonsNervous(void)
for (i = 0; i < CONTESTANT_COUNT; i++)
{
if (eContestantStatus[i].hasJudgesAttention && IsContestantAllowedToCombo(i))
- oddsMod[i] = gMovesInfo[eContestantStatus[i].prevMove].contestComboStarterId == 0 ? 0 : 10;
+ oddsMod[i] = GetMoveContestComboStarter(eContestantStatus[i].prevMove) == 0 ? 0 : 10;
else
oddsMod[i] = 0;
oddsMod[i] -= (eContestantStatus[i].condition / 10) * 10;
@@ -493,7 +494,7 @@ static void ContestEffect_WorsenConditionOfPrevMons(void)
SetContestantEffectStringID2(eContestAppealResults.contestant, CONTEST_STRING_IGNORED);
}
-// Badly startles POKMON in good condition.
+// Badly startles POK�MON in good condition.
static void ContestEffect_BadlyStartlesMonsInGoodCondition(void)
{
u8 numHit = 0;
@@ -524,7 +525,7 @@ static void ContestEffect_BetterIfFirst(void)
if (gContestantTurnOrder[eContestAppealResults.contestant] == 0)
{
u16 move = eContestantStatus[eContestAppealResults.contestant].currMove;
- eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[gMovesInfo[move].contestEffect].appeal;
+ eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[GetMoveContestEffect(move)].appeal;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_HUSTLE_STANDOUT);
}
}
@@ -535,7 +536,7 @@ static void ContestEffect_BetterIfLast(void)
if (gContestantTurnOrder[eContestAppealResults.contestant] == 3)
{
u16 move = eContestantStatus[eContestAppealResults.contestant].currMove;
- eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[gMovesInfo[move].contestEffect].appeal;
+ eContestantStatus[eContestAppealResults.contestant].appeal += 2 * gContestEffects[GetMoveContestEffect(move)].appeal;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_WORK_HARD_UNNOTICED);
}
}
@@ -619,15 +620,18 @@ static void ContestEffect_QualityDependsOnTiming(void)
{
appeal = 10;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_NOT_VERY_WELL);
- } else if (rval < 6)
+ }
+ else if (rval < 6)
{
appeal = 20;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_SLIGHTLY_WELL2);
- } else if (rval < 8)
+ }
+ else if (rval < 8)
{
appeal = 40;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_PRETTY_WELL2);
- } else if (rval < 9)
+ }
+ else if (rval < 9)
{
appeal = 60;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_APPEAL_VERY_WELL);
@@ -668,9 +672,9 @@ static void ContestEffect_BetterIfSameType(void)
}
move = eContestantStatus[eContestAppealResults.contestant].currMove;
- if (gMovesInfo[move].contestCategory == gMovesInfo[eContestantStatus[j].currMove].contestCategory)
+ if (GetMoveContestCategory(move) == GetMoveContestCategory(eContestantStatus[j].currMove))
{
- eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[gMovesInfo[move].contestEffect].appeal * 2;
+ eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[GetMoveContestEffect(move)].appeal * 2;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_SAME_TYPE_GOOD);
}
}
@@ -686,9 +690,9 @@ static void ContestEffect_BetterIfDiffType(void)
for (i = 0; i < CONTESTANT_COUNT; i++)
{
if (eContestAppealResults.turnOrder[eContestAppealResults.contestant] - 1 == eContestAppealResults.turnOrder[i] &&
- gMovesInfo[move].contestCategory != gMovesInfo[eContestantStatus[i].currMove].contestCategory)
+ GetMoveContestCategory(move) != GetMoveContestCategory(eContestantStatus[i].currMove))
{
- eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[gMovesInfo[move].contestEffect].appeal * 2;
+ eContestantStatus[eContestAppealResults.contestant].appeal += gContestEffects[GetMoveContestEffect(move)].appeal * 2;
SetContestantEffectStringID(eContestAppealResults.contestant, CONTEST_STRING_DIFF_TYPE_GOOD);
break;
}
@@ -868,7 +872,9 @@ static void ContestEffect_ScrambleNextTurnOrder(void)
break;
}
else
+ {
rval--;
+ }
}
}
}
@@ -886,13 +892,13 @@ static void ContestEffect_ScrambleNextTurnOrder(void)
// An appeal that excites the audience in any CONTEST.
static void ContestEffect_ExciteAudienceInAnyContest(void)
{
- if (gMovesInfo[eContestantStatus[eContestAppealResults.contestant].currMove].contestCategory != gSpecialVar_ContestCategory)
+ if (GetMoveContestCategory(eContestantStatus[eContestAppealResults.contestant].currMove) != gSpecialVar_ContestCategory)
{
eContestantStatus[eContestAppealResults.contestant].overrideCategoryExcitementMod = TRUE;
}
}
-// Badly startles all POKMON that made good appeals.
+// Badly startles all POK�MON that made good appeals.
static void ContestEffect_BadlyStartleMonsWithGoodAppeals(void)
{
int i;
@@ -908,7 +914,9 @@ static void ContestEffect_BadlyStartleMonsWithGoodAppeals(void)
eContestAppealResults.jam = RoundUp(eContestAppealResults.jam);
}
else
+ {
eContestAppealResults.jam = 10;
+ }
eContestAppealResults.jamQueue[0] = i;
eContestAppealResults.jamQueue[1] = CONTESTANT_NONE;
if (WasAtLeastOneOpponentJammed())
@@ -973,7 +981,7 @@ static void JamByMoveCategory(u8 category)
{
if (eContestAppealResults.turnOrder[eContestAppealResults.contestant] > eContestAppealResults.turnOrder[i])
{
- if (category == gMovesInfo[eContestantStatus[i].currMove].contestCategory)
+ if (category == GetMoveContestCategory(eContestantStatus[i].currMove))
eContestAppealResults.jam = 40;
else
eContestAppealResults.jam = 10;
@@ -1071,7 +1079,9 @@ static s16 RoundTowardsZero(s16 score)
score -= 10 - absScore;
}
else
+ {
score -= absScore;
+ }
return score;
}
diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h
index 956a2d0f23..b9fcdd59f6 100644
--- a/src/data/battle_move_effects.h
+++ b/src/data/battle_move_effects.h
@@ -24,7 +24,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
[EFFECT_ABSORB] =
{
- .battleScript = BattleScript_EffectAbsorb,
+ .battleScript = BattleScript_EffectHit,
.battleTvScore = 4,
},
@@ -425,6 +425,27 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.encourageEncore = TRUE,
},
+ [EFFECT_HOLD_HANDS] =
+ {
+ .battleScript = BattleScript_EffectHoldHands,
+ .battleTvScore = 1,
+ .encourageEncore = TRUE,
+ },
+
+ [EFFECT_CELEBRATE] =
+ {
+ .battleScript = BattleScript_EffectCelebrate,
+ .battleTvScore = 1,
+ .encourageEncore = TRUE,
+ },
+
+ [EFFECT_HAPPY_HOUR] =
+ {
+ .battleScript = BattleScript_EffectHappyHour,
+ .battleTvScore = 1,
+ .encourageEncore = TRUE,
+ },
+
[EFFECT_DISABLE] =
{
.battleScript = BattleScript_EffectDisable,
@@ -1811,12 +1832,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.battleTvScore = 0, // TODO: Assign points
},
- [EFFECT_EERIE_SPELL] =
- {
- .battleScript = BattleScript_EffectEerieSpell,
- .battleTvScore = 0, // TODO: Assign points
- },
-
[EFFECT_JUNGLE_HEALING] =
{
.battleScript = BattleScript_EffectJungleHealing,
@@ -1880,42 +1895,12 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.battleTvScore = 0, // TODO: Assign points
},
- [EFFECT_GLITZY_GLOW] =
- {
- .battleScript = BattleScript_EffectGlitzyGlow,
- .battleTvScore = 0, // TODO: Assign points
- },
-
- [EFFECT_BADDY_BAD] =
- {
- .battleScript = BattleScript_EffectBaddyBad,
- .battleTvScore = 0, // TODO: Assign points
- },
-
- [EFFECT_SAPPY_SEED] =
- {
- .battleScript = BattleScript_EffectSappySeed,
- .battleTvScore = 0, // TODO: Assign points
- },
-
- [EFFECT_FREEZY_FROST] =
- {
- .battleScript = BattleScript_EffectFreezyFrost,
- .battleTvScore = 0, // TODO: Assign points
- },
-
[EFFECT_SPARKLY_SWIRL] =
{
.battleScript = BattleScript_EffectSparklySwirl,
.battleTvScore = 0, // TODO: Assign points
},
- [EFFECT_PLASMA_FISTS] =
- {
- .battleScript = BattleScript_EffectPlasmaFists,
- .battleTvScore = 0, // TODO: Assign points
- },
-
[EFFECT_HYPERSPACE_FURY] =
{
.battleScript = BattleScript_EffectHyperspaceFury,
@@ -2113,12 +2098,6 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.battleTvScore = 0, // TODO: Assign points
},
- [EFFECT_SALT_CURE] =
- {
- .battleScript = BattleScript_EffectSaltCure,
- .battleTvScore = 0, // TODO: Assign points
- },
-
[EFFECT_CHILLY_RECEPTION] =
{
.battleScript = BattleScript_EffectChillyReception,
diff --git a/src/data/graphics/pokemon.h b/src/data/graphics/pokemon.h
index 39b11560d4..726a0414f4 100644
--- a/src/data/graphics/pokemon.h
+++ b/src/data/graphics/pokemon.h
@@ -14459,11 +14459,11 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
#endif //P_FAMILY_SHIELDON
#if P_FAMILY_BURMY
- const u32 gMonFrontPic_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/anim_front.4bpp.lz");
- const u32 gMonPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/normal.gbapal.lz");
- const u32 gMonBackPic_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/back.4bpp.lz");
- const u32 gMonShinyPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/shiny.gbapal.lz");
- const u8 gMonIcon_BurmyPlantCloak[] = INCBIN_U8("graphics/pokemon/burmy/icon.4bpp");
+ const u32 gMonFrontPic_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/anim_front.4bpp.lz");
+ const u32 gMonPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/normal.gbapal.lz");
+ const u32 gMonBackPic_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/back.4bpp.lz");
+ const u32 gMonShinyPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/shiny.gbapal.lz");
+ const u8 gMonIcon_BurmyPlant[] = INCBIN_U8("graphics/pokemon/burmy/icon.4bpp");
#if P_FOOTPRINTS
const u8 gMonFootprint_Burmy[] = INCBIN_U8("graphics/pokemon/burmy/footprint.1bpp");
#endif //P_FOOTPRINTS
@@ -14481,24 +14481,24 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
const u8 gMonIcon_BurmyTrash[] = INCBIN_U8("graphics/pokemon/burmy/trash/icon.4bpp");
#if OW_POKEMON_OBJECT_EVENTS
- const u32 gObjectEventPic_BurmyPlantCloak[] = INCBIN_COMP("graphics/pokemon/burmy/overworld.4bpp");
+ const u32 gObjectEventPic_BurmyPlant[] = INCBIN_COMP("graphics/pokemon/burmy/overworld.4bpp");
const u32 gObjectEventPic_BurmySandy[] = INCBIN_COMP("graphics/pokemon/burmy/sandy/overworld.4bpp");
const u32 gObjectEventPic_BurmyTrash[] = INCBIN_COMP("graphics/pokemon/burmy/trash/overworld.4bpp");
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
- const u32 gOverworldPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/overworld_normal.gbapal.lz");
+ const u32 gOverworldPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/overworld_normal.gbapal.lz");
const u32 gOverworldPalette_BurmySandy[] = INCBIN_U32("graphics/pokemon/burmy/sandy/overworld_normal.gbapal.lz");
const u32 gOverworldPalette_BurmyTrash[] = INCBIN_U32("graphics/pokemon/burmy/trash/overworld_normal.gbapal.lz");
- const u32 gShinyOverworldPalette_BurmyPlantCloak[] = INCBIN_U32("graphics/pokemon/burmy/overworld_shiny.gbapal.lz");
+ const u32 gShinyOverworldPalette_BurmyPlant[] = INCBIN_U32("graphics/pokemon/burmy/overworld_shiny.gbapal.lz");
const u32 gShinyOverworldPalette_BurmySandy[] = INCBIN_U32("graphics/pokemon/burmy/sandy/overworld_shiny.gbapal.lz");
const u32 gShinyOverworldPalette_BurmyTrash[] = INCBIN_U32("graphics/pokemon/burmy/trash/overworld_shiny.gbapal.lz");
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
#endif //OW_POKEMON_OBJECT_EVENTS
- const u32 gMonFrontPic_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/anim_front.4bpp.lz");
- const u32 gMonPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/normal.gbapal.lz");
- const u32 gMonBackPic_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/back.4bpp.lz");
- const u32 gMonShinyPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/shiny.gbapal.lz");
- const u8 gMonIcon_WormadamPlantCloak[] = INCBIN_U8("graphics/pokemon/wormadam/icon.4bpp");
+ const u32 gMonFrontPic_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/anim_front.4bpp.lz");
+ const u32 gMonPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/normal.gbapal.lz");
+ const u32 gMonBackPic_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/back.4bpp.lz");
+ const u32 gMonShinyPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/shiny.gbapal.lz");
+ const u8 gMonIcon_WormadamPlant[] = INCBIN_U8("graphics/pokemon/wormadam/icon.4bpp");
#if P_FOOTPRINTS
const u8 gMonFootprint_Wormadam[] = INCBIN_U8("graphics/pokemon/wormadam/footprint.1bpp");
#endif //P_FOOTPRINTS
@@ -14516,14 +14516,14 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
const u8 gMonIcon_WormadamTrash[] = INCBIN_U8("graphics/pokemon/wormadam/trash/icon.4bpp");
#if OW_POKEMON_OBJECT_EVENTS
- const u32 gObjectEventPic_WormadamPlantCloak[] = INCBIN_COMP("graphics/pokemon/wormadam/overworld.4bpp");
+ const u32 gObjectEventPic_WormadamPlant[] = INCBIN_COMP("graphics/pokemon/wormadam/overworld.4bpp");
const u32 gObjectEventPic_WormadamSandy[] = INCBIN_COMP("graphics/pokemon/wormadam/sandy/overworld.4bpp");
const u32 gObjectEventPic_WormadamTrash[] = INCBIN_COMP("graphics/pokemon/wormadam/trash/overworld.4bpp");
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
- const u32 gOverworldPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_normal.gbapal.lz");
+ const u32 gOverworldPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_normal.gbapal.lz");
const u32 gOverworldPalette_WormadamSandy[] = INCBIN_U32("graphics/pokemon/wormadam/sandy/overworld_normal.gbapal.lz");
const u32 gOverworldPalette_WormadamTrash[] = INCBIN_U32("graphics/pokemon/wormadam/trash/overworld_normal.gbapal.lz");
- const u32 gShinyOverworldPalette_WormadamPlantCloak[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_shiny.gbapal.lz");
+ const u32 gShinyOverworldPalette_WormadamPlant[] = INCBIN_U32("graphics/pokemon/wormadam/overworld_shiny.gbapal.lz");
const u32 gShinyOverworldPalette_WormadamSandy[] = INCBIN_U32("graphics/pokemon/wormadam/sandy/overworld_shiny.gbapal.lz");
const u32 gShinyOverworldPalette_WormadamTrash[] = INCBIN_U32("graphics/pokemon/wormadam/trash/overworld_shiny.gbapal.lz");
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
@@ -18880,7 +18880,7 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
#endif //P_FAMILY_LANDORUS
#if P_FAMILY_ENAMORUS
- const u32 gMonFrontPic_EnamorusIncarnate[] = INCBIN_U32("graphics/pokemon/enamorus/front.4bpp.lz");
+ const u32 gMonFrontPic_EnamorusIncarnate[] = INCBIN_U32("graphics/pokemon/enamorus/anim_front.4bpp.lz");
const u32 gMonPalette_EnamorusIncarnate[] = INCBIN_U32("graphics/pokemon/enamorus/normal.gbapal.lz");
const u32 gMonBackPic_EnamorusIncarnate[] = INCBIN_U32("graphics/pokemon/enamorus/back.4bpp.lz");
const u32 gMonShinyPalette_EnamorusIncarnate[] = INCBIN_U32("graphics/pokemon/enamorus/shiny.gbapal.lz");
diff --git a/src/data/moves_info.h b/src/data/moves_info.h
index db5f2eaf75..2c28621286 100644
--- a/src/data/moves_info.h
+++ b/src/data/moves_info.h
@@ -17,11 +17,6 @@
#define BINDING_TURNS "2 to 5"
#endif
-/* First arg is the charge turn string id, second arg depends on effect
-EFFECT_SEMI_INVULNERABLE/EFFECT_SKY_DROP: semi-invulnerable STATUS3 to apply to battler
-EFFECT_TWO_TURNS_ATTACK/EFFECT_SOLAR_BEAM: weather in which to skip charge turn */
-#define TWO_TURN_ARG(stringid, ...) (stringid) __VA_OPT__(| ((__VA_ARGS__) << 16))
-
// Shared Move Description entries
const u8 gNotDoneYetDescription[] = _(
@@ -438,7 +433,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.windMove = B_EXTRAPOLATED_MOVE_FLAGS,
- .argument = TWO_TURN_ARG(STRINGID_PKMNWHIPPEDWHIRLWIND),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNWHIPPEDWHIRLWIND },
.contestEffect = CONTEST_EFFECT_AFFECTED_BY_PREV_APPEAL,
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = 0,
@@ -586,7 +581,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.assistBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNFLEWHIGH, COMPRESS_BITS(STATUS3_ON_AIR)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNFLEWHIGH, .status = COMPRESS_BITS(STATUS3_ON_AIR) },
.contestEffect = CONTEST_EFFECT_AVOID_STARTLE,
.contestCategory = CONTEST_CATEGORY_SMART,
.contestComboStarterId = 0,
@@ -1332,7 +1327,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = 20,
+ .argument = { .fixedDamage = 20 },
.contestEffect = CONTEST_EFFECT_BETTER_IF_SAME_TYPE,
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = 0,
@@ -1874,6 +1869,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
+ .argument = { .absorbPercentage = 50 },
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_PREV_MON,
@@ -1895,6 +1891,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
+ .argument = { .absorbPercentage = 50 },
.zMove = { .powerOverride = 120 },
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6,
@@ -1997,7 +1994,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.category = DAMAGE_CATEGORY_SPECIAL,
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNTOOKSUNLIGHT, B_WEATHER_SUN),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKSUNLIGHT, .status = B_WEATHER_SUN },
.contestEffect = CONTEST_EFFECT_HIGHLY_APPEALING,
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = 0,
@@ -2149,7 +2146,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_4) || (B_UPDATED_MOVE_FLAGS < GEN_3),
- .argument = 40,
+ .argument = { .fixedDamage = 40 },
.contestEffect = CONTEST_EFFECT_BETTER_WHEN_LATER,
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = COMBO_STARTER_DRAGON_RAGE,
@@ -2368,7 +2365,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.instructBanned = TRUE,
.assistBanned = TRUE,
.skyBattleBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNDUGHOLE, COMPRESS_BITS(STATUS3_UNDERGROUND)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNDUGHOLE, .status = COMPRESS_BITS(STATUS3_UNDERGROUND) },
.contestEffect = CONTEST_EFFECT_AVOID_STARTLE,
.contestCategory = CONTEST_CATEGORY_SMART,
.contestComboStarterId = 0,
@@ -2984,7 +2981,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.zMove = { .effect = Z_EFFECT_ACC_UP_1 },
- .argument = STATUS2_FOCUS_ENERGY,
+ .argument = { .status = STATUS2_FOCUS_ENERGY },
.ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE,
.snatchAffected = TRUE,
@@ -3341,7 +3338,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.makesContact = TRUE,
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNLOWEREDHEAD),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNLOWEREDHEAD },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_DEF_PLUS_1,
.self = TRUE,
@@ -3620,6 +3617,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
+ .argument = { .absorbPercentage = 50 },
.makesContact = TRUE,
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6,
@@ -3670,7 +3668,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.criticalHitStage = B_UPDATED_MOVE_DATA >= GEN_3,
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(B_UPDATED_MOVE_DATA >= GEN_4 ? STRINGID_CLOAKEDINAHARSHLIGHT : STRINGID_PKMNISGLOWING),
+ .argument.twoTurnAttack = { .stringId = B_UPDATED_MOVE_DATA >= GEN_4 ? STRINGID_CLOAKEDINAHARSHLIGHT : STRINGID_PKMNISGLOWING },
#if B_UPDATED_MOVE_DATA >= GEN_3
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_FLINCH,
@@ -5152,6 +5150,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
+ .argument = { .absorbPercentage = 50 },
.ignoresKingsRock = (B_UPDATED_MOVE_FLAGS == GEN_3 || B_UPDATED_MOVE_FLAGS == GEN_4),
.healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
@@ -6731,7 +6730,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = STATUS1_PARALYSIS,
+ .argument = { .status = STATUS1_PARALYSIS },
.makesContact = TRUE,
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_REMOVE_STATUS,
@@ -7387,7 +7386,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.instructBanned = TRUE,
.assistBanned = TRUE,
.skyBattleBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNHIDUNDERWATER, COMPRESS_BITS(STATUS3_UNDERWATER)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNHIDUNDERWATER, .status = COMPRESS_BITS(STATUS3_UNDERWATER) },
.contestEffect = CONTEST_EFFECT_AVOID_STARTLE_ONCE,
.contestCategory = CONTEST_CATEGORY_BEAUTY,
.contestComboStarterId = COMBO_STARTER_DIVE,
@@ -8488,7 +8487,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.type = TYPE_NORMAL,
.accuracy = 0,
.pp = 40,
- .target = MOVE_TARGET_USER,
+ .target = MOVE_TARGET_USER, // Targeting is handled through the script
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.zMove = { .effect = Z_EFFECT_ATK_UP_1 },
@@ -8595,7 +8594,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.assistBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNSPRANGUP, COMPRESS_BITS(STATUS3_ON_AIR)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNSPRANGUP, .status = COMPRESS_BITS(STATUS3_ON_AIR) },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_PARALYSIS,
.chance = 30,
@@ -9044,7 +9043,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = STATUS1_SLEEP,
+ .argument = { .status = STATUS1_SLEEP },
.makesContact = TRUE,
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_REMOVE_STATUS,
@@ -10264,6 +10263,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
+ .argument = { .absorbPercentage = 50 },
.makesContact = TRUE,
.punchingMove = TRUE,
.healingMove = B_HEAL_BLOCKING >= GEN_6,
@@ -11267,7 +11267,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = HOLD_EFFECT_PLATE,
+ .argument = { .holdEffect = HOLD_EFFECT_PLATE },
.contestEffect = CONTEST_EFFECT_SCRAMBLE_NEXT_TURN_ORDER,
.contestCategory = CONTEST_CATEGORY_SMART,
.contestComboStarterId = 0,
@@ -11697,7 +11697,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.assistBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_VANISHEDINSTANTLY, COMPRESS_BITS(STATUS3_PHANTOM_FORCE)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = COMPRESS_BITS(STATUS3_PHANTOM_FORCE) },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_FEINT,
}),
@@ -11747,7 +11747,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_USER,
.priority = 3,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TRUE, // Protects the whole side.
+ .argument = { .protect.side = TRUE, },
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
.snatchAffected = TRUE,
.ignoresProtect = TRUE,
@@ -11862,7 +11862,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = STATUS1_PSN_ANY,
+ .argument = { .status = STATUS1_PSN_ANY },
.contestEffect = CONTEST_EFFECT_BETTER_IF_SAME_TYPE,
.contestCategory = CONTEST_CATEGORY_TOUGH,
.contestComboStarterId = 0,
@@ -12212,7 +12212,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
{
.name = COMPOUND_STRING("Coil"),
.description = COMPOUND_STRING(
- "Coils up to raise Attack\n"
+ "Coils up to raise Attack,\n"
"Defense and Accuracy."),
.effect = EFFECT_COIL,
.power = 0,
@@ -12508,7 +12508,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_USER,
.priority = 3,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TRUE, // Protects the whole side.
+ .argument = { .protect.side = TRUE, },
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
.snatchAffected = TRUE,
.ignoresProtect = TRUE,
@@ -12637,7 +12637,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
.zMove = { .powerOverride = 160 },
- .argument = STATUS1_ANY,
+ .argument = { .status = STATUS1_ANY },
.contestEffect = CONTEST_EFFECT_BETTER_IF_SAME_TYPE,
.contestCategory = CONTEST_CATEGORY_SMART,
.contestComboStarterId = 0,
@@ -12664,7 +12664,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.assistBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNTOOKTARGETHIGH, COMPRESS_BITS(STATUS3_ON_AIR)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKTARGETHIGH, .status = COMPRESS_BITS(STATUS3_ON_AIR) },
.contestEffect = CONTEST_EFFECT_AVOID_STARTLE,
.contestCategory = CONTEST_CATEGORY_SMART,
.contestComboStarterId = 0,
@@ -13244,6 +13244,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
+ .argument = { .absorbPercentage = 50 },
.makesContact = TRUE,
.healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
@@ -13579,7 +13580,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = HOLD_EFFECT_DRIVE,
+ .argument = { .holdEffect = HOLD_EFFECT_DRIVE },
.metronomeBanned = TRUE,
.contestEffect = CONTEST_EFFECT_EXCITE_AUDIENCE_IN_ANY_CONTEST,
.contestCategory = CONTEST_CATEGORY_COOL,
@@ -13602,7 +13603,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_BOTH,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = STATUS1_SLEEP,
+ .argument = { .status = STATUS1_SLEEP },
.ignoresSubstitute = B_UPDATED_MOVE_FLAGS >= GEN_6,
.soundMove = TRUE,
.metronomeBanned = TRUE,
@@ -13760,7 +13761,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.metronomeBanned = TRUE,
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_CLOAKEDINAFREEZINGLIGHT),
+ .argument.twoTurnAttack = { .stringId = STRINGID_CLOAKEDINAFREEZINGLIGHT },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_PARALYSIS,
.chance = 30,
@@ -13789,7 +13790,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.metronomeBanned = TRUE,
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_CLOAKEDINAFREEZINGLIGHT),
+ .argument.twoTurnAttack = { .stringId = STRINGID_CLOAKEDINAFREEZINGLIGHT },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_BURN,
.chance = 30,
@@ -13940,7 +13941,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.zMove = { .powerOverride = 170 },
- .argument = TYPE_FLYING,
+ .argument = { .type = TYPE_FLYING },
.makesContact = TRUE,
.minimizeDoubleDamage = TRUE,
.gravityBanned = TRUE,
@@ -13966,7 +13967,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_USER,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TRUE, // Protects the whole side.
+ .argument = { .protect.side = TRUE },
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
.snatchAffected = TRUE,
.ignoresProtect = TRUE,
@@ -14102,7 +14103,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.assistBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_VANISHEDINSTANTLY, COMPRESS_BITS(STATUS3_PHANTOM_FORCE)),
+ .argument.twoTurnAttack = { .stringId = STRINGID_VANISHEDINSTANTLY, .status = COMPRESS_BITS(STATUS3_PHANTOM_FORCE) },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_FEINT,
}),
@@ -14127,7 +14128,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TYPE_GHOST,
+ .argument = { .type = TYPE_GHOST },
.zMove = { .effect = Z_EFFECT_ALL_STATS_UP_1 },
.magicCoatAffected = TRUE,
.contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS,
@@ -14200,6 +14201,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_FOES_AND_ALLY,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
+ .argument = { .absorbPercentage = 50 },
.healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
.contestCategory = CONTEST_CATEGORY_BEAUTY,
@@ -14222,7 +14224,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TYPE_GRASS,
+ .argument = { .type = TYPE_GRASS },
.zMove = { .effect = Z_EFFECT_ALL_STATS_UP_1 },
.magicCoatAffected = TRUE,
.contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS,
@@ -14272,7 +14274,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = TYPE_WATER,
+ .argument = { .type = TYPE_WATER },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_FREEZE_OR_FROSTBITE,
.chance = 10,
@@ -14367,7 +14369,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = 75, // restores 75% HP instead of 50% HP
+ .argument = { .absorbPercentage = 75 },
.makesContact = TRUE,
.healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
@@ -14391,7 +14393,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_USER,
.priority = 3,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TRUE, // Protects the whole side.
+ .argument = { .protect.side = TRUE, },
.zMove = { .effect = Z_EFFECT_SPDEF_UP_1 },
.ignoresProtect = TRUE,
.mirrorMoveBanned = TRUE,
@@ -14414,7 +14416,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.type = TYPE_FAIRY,
.accuracy = 0,
.pp = 10,
- .target = MOVE_TARGET_ALL_BATTLERS,
+ .target = MOVE_TARGET_USER, // The targeting of Flower Shield is handled through a script
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.zMove = { .effect = Z_EFFECT_DEF_UP_1 },
@@ -14963,7 +14965,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
.skyBattleBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKNMABSORBINGPOWER),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKNMABSORBINGPOWER },
.contestEffect = CONTEST_EFFECT_IMPROVE_CONDITION_PREVENT_NERVOUSNESS,
.contestCategory = CONTEST_CATEGORY_CUTE,
.contestComboStarterId = 0,
@@ -15003,7 +15005,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Doubles the amount of\n"
"Prize Money received."),
- .effect = EFFECT_DO_NOTHING,
+ .effect = EFFECT_HAPPY_HOUR,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 0,
@@ -15073,7 +15075,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Congratulates you on your\n"
"special day."),
- .effect = EFFECT_DO_NOTHING,
+ .effect = EFFECT_CELEBRATE,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 0,
@@ -15103,7 +15105,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"The user and ally hold hands\n"
"making them happy."),
- .effect = EFFECT_DO_NOTHING,
+ .effect = EFFECT_HOLD_HANDS,
.power = 0,
.type = TYPE_NORMAL,
.accuracy = 0,
@@ -15261,7 +15263,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = 75, // restores 75% HP instead of 50% HP
+ .argument = { .absorbPercentage = 75 },
.healingMove = B_HEAL_BLOCKING >= GEN_6,
.contestEffect = CONTEST_EFFECT_STARTLE_MON_WITH_JUDGES_ATTENTION,
.contestCategory = CONTEST_CATEGORY_COOL,
@@ -15503,7 +15505,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 2,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MOVE_FIRST_IMPRESSION,
+ .argument = { .moveProperty = MOVE_FIRST_IMPRESSION },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_BETTER_IF_FIRST,
.contestCategory = CONTEST_CATEGORY_COOL,
@@ -15601,7 +15603,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_FOES_AND_ALLY,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = STATUS1_BURN,
+ .argument = { .status = STATUS1_BURN },
.ignoresSubstitute = B_UPDATED_MOVE_FLAGS >= GEN_6,
.soundMove = TRUE,
.additionalEffects = ADDITIONAL_EFFECTS({
@@ -15657,7 +15659,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
.zMove = { .effect = Z_EFFECT_RESET_STATS },
- .argument = MOVE_EFFECT_FLORAL_HEALING,
+ .argument = { .moveProperty = MOVE_EFFECT_FLORAL_HEALING },
.mirrorMoveBanned = TRUE,
.healingMove = TRUE,
.magicCoatAffected = TRUE,
@@ -15732,7 +15734,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.slicingMove = TRUE,
.sleepTalkBanned = TRUE,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_PKMNTOOKSUNLIGHT, B_WEATHER_SUN),
+ .argument.twoTurnAttack = { .stringId = STRINGID_PKMNTOOKSUNLIGHT, .status = B_WEATHER_SUN },
.contestEffect = CONTEST_EFFECT_HIGHLY_APPEALING,
.contestCategory = CONTEST_CATEGORY_TOUGH,
.contestComboStarterId = 0,
@@ -16049,7 +16051,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
.thawsUser = TRUE,
- .argument = TYPE_FIRE,
+ .argument = { .type = TYPE_FIRE },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_REMOVE_ARG_TYPE,
.self = TRUE,
@@ -16713,7 +16715,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = HOLD_EFFECT_MEMORY,
+ .argument = { .holdEffect = HOLD_EFFECT_MEMORY },
.makesContact = TRUE,
.contestEffect = CONTEST_EFFECT_SCRAMBLE_NEXT_TURN_ORDER,
.contestCategory = CONTEST_CATEGORY_BEAUTY,
@@ -16750,7 +16752,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Hits with electrical fists.\n"
"Normal moves turn Electric."),
- .effect = EFFECT_PLASMA_FISTS,
+ .effect = EFFECT_HIT,
.power = 100,
.type = TYPE_ELECTRIC,
.accuracy = 100,
@@ -16765,6 +16767,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = 0,
.contestComboMoves = {0},
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_ION_DELUGE,
+ .chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
+ }),
.battleAnimScript = gBattleAnimMove_PlasmaFists,
},
@@ -16813,6 +16820,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_EVS_PLUS_1,
.chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
}),
#endif
.battleAnimScript = gBattleAnimMove_ZippyZap,
@@ -16862,6 +16870,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_FLINCH,
.chance = 30,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
}),
.battleAnimScript = gBattleAnimMove_FloatyFall,
},
@@ -16903,7 +16912,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 50, // restores 100% HP instead of 50% HP
+ .argument = { .absorbPercentage = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 50 },
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
.metronomeBanned = TRUE,
.healingMove = B_HEAL_BLOCKING >= GEN_6,
@@ -16929,6 +16938,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_PARALYSIS,
.chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
}),
.battleAnimScript = gBattleAnimMove_BuzzyBuzz,
},
@@ -16954,6 +16964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_BURN,
.chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
}),
.battleAnimScript = gBattleAnimMove_SizzlySlide,
},
@@ -16964,7 +16975,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Telekinetic force that sets\n"
"wall, lowering Sp. Atk damage."),
- .effect = EFFECT_GLITZY_GLOW,
+ .effect = EFFECT_HIT,
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 80 : 90,
.type = TYPE_PSYCHIC,
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 95 : 100,
@@ -16974,6 +16985,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.category = DAMAGE_CATEGORY_SPECIAL,
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
.metronomeBanned = TRUE,
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_LIGHT_SCREEN,
+ .chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
+ }),
.battleAnimScript = gBattleAnimMove_GlitzyGlow,
},
@@ -16983,7 +16999,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Acting badly, attacks. Sets\n"
"wall, lowering Attack damage."),
- .effect = EFFECT_BADDY_BAD,
+ .effect = EFFECT_HIT,
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 80 : 90,
.type = TYPE_DARK,
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 95 : 100,
@@ -16993,6 +17009,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.category = DAMAGE_CATEGORY_SPECIAL,
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
.metronomeBanned = TRUE,
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_REFLECT,
+ .chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
+ }),
.battleAnimScript = gBattleAnimMove_BaddyBad,
},
@@ -17002,7 +17023,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Giant stalk scatters seeds\n"
"that drain HP every turn."),
- .effect = EFFECT_SAPPY_SEED,
+ .effect = EFFECT_HIT,
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 90,
.type = TYPE_GRASS,
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 90 : 100,
@@ -17013,6 +17034,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
.magicCoatAffected = TRUE,
.metronomeBanned = TRUE,
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_LEECH_SEED,
+ .chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
+ }),
.battleAnimScript = gBattleAnimMove_SappySeed,
},
@@ -17022,7 +17048,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Crystal from cold haze hits.\n"
"Eliminates all stat changes."),
- .effect = EFFECT_FREEZY_FROST,
+ .effect = EFFECT_HIT,
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 100 : 90,
.type = TYPE_ICE,
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 90 : 100,
@@ -17032,6 +17058,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.category = DAMAGE_CATEGORY_SPECIAL,
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
.metronomeBanned = TRUE,
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_HAZE,
+ .chance = 100,
+ .sheerForceBoost = SHEER_FORCE_NO_BOOST,
+ }),
.battleAnimScript = gBattleAnimMove_FreezyFrost,
},
@@ -17041,7 +17072,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Wrap foe with whirlwind of\n"
"scent. Heals party's status."),
- .effect = EFFECT_SPARKLY_SWIRL,
+ .effect = EFFECT_SPARKLY_SWIRL, // Temprorary
.power = B_UPDATED_MOVE_DATA >= GEN_8 ? 120 : 90,
.type = TYPE_FAIRY,
.accuracy = B_UPDATED_MOVE_DATA >= GEN_8 ? 85 : 100,
@@ -17051,6 +17082,11 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.category = DAMAGE_CATEGORY_SPECIAL,
.mirrorMoveBanned = B_UPDATED_MOVE_FLAGS < GEN_8,
.metronomeBanned = TRUE,
+ // .additionalEffects = ADDITIONAL_EFFECTS({
+ // .moveEffect = 0, // MOVE_EFFECT_AROMATHERAPY, Added 0 for Sheer Force boost
+ // .chance = 100,
+ // .sheerForceBoost = SHEER_FORCE_NO_BOOST,
+ // }),
.battleAnimScript = gBattleAnimMove_SparklySwirl,
},
@@ -17266,7 +17302,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_STATUS,
- .argument = TYPE_PSYCHIC,
+ .argument = { .type = TYPE_PSYCHIC },
.magicCoatAffected = TRUE,
.powderMove = TRUE,
.contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS,
@@ -17328,7 +17364,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.name = COMPOUND_STRING("Octolock"),
.description = COMPOUND_STRING(
"Traps the foe to lower Def\n"
- "and Sp. Def fall each turn."),
+ "and Sp. Def each turn."),
.effect = EFFECT_OCTOLOCK,
.power = 0,
.type = TYPE_FIGHTING,
@@ -18012,7 +18048,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.makesContact = TRUE,
- .argument = ARG_TRY_REMOVE_TERRAIN_FAIL, // Remove a field terrain if there is one and hit, otherwise fail.
+ .argument = { .moveProperty = ARG_TRY_REMOVE_TERRAIN_FAIL }, // Remove a field terrain if there is one and hit, otherwise fail.
.skyBattleBanned = TRUE,
.contestEffect = CONTEST_EFFECT_WORSEN_CONDITION_OF_PREV_MONS,
.contestCategory = CONTEST_CATEGORY_TOUGH,
@@ -18035,7 +18071,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MOVE_EFFECT_SCALE_SHOT,
+ .argument = { .moveProperty = MOVE_EFFECT_SCALE_SHOT },
.contestEffect = CONTEST_EFFECT_NEXT_APPEAL_EARLIER,
.contestCategory = CONTEST_CATEGORY_COOL,
.contestComboStarterId = 0,
@@ -18058,7 +18094,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
.instructBanned = TRUE,
- .argument = TWO_TURN_ARG(STRINGID_METEORBEAMCHARGING),
+ .argument.twoTurnAttack = { .stringId = STRINGID_METEORBEAMCHARGING },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_SP_ATK_PLUS_1,
.self = TRUE,
@@ -18675,7 +18711,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Attacks with psychic power.\n"
"Foe's last move has 3 PP cut."),
- .effect = EFFECT_EERIE_SPELL,
+ .effect = EFFECT_HIT,
.power = 80,
.type = TYPE_PSYCHIC,
.accuracy = 100,
@@ -18689,6 +18725,10 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.contestCategory = CONTEST_CATEGORY_SMART,
.contestComboStarterId = 0,
.contestComboMoves = {0},
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_EERIE_SPELL,
+ .chance = 100,
+ }),
.battleAnimScript = gBattleAnimMove_EerieSpell,
},
@@ -18964,7 +19004,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = STATUS1_PSN_ANY,
+ .argument = { .status = STATUS1_PSN_ANY },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_POISON,
.chance = 50,
@@ -19076,7 +19116,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = STATUS1_ANY,
+ .argument = { .status = STATUS1_ANY },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_BURN,
.chance = 30,
@@ -19439,7 +19479,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.makesContact = TRUE,
- .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one.
+ .argument = { .moveProperty = ARG_TRY_REMOVE_TERRAIN_HIT }, // Remove the active field terrain if there is one.
.skyBattleBanned = B_EXTRAPOLATED_MOVE_FLAGS,
.battleAnimScript = gBattleAnimMove_IceSpinner,
},
@@ -19490,7 +19530,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.description = COMPOUND_STRING(
"Hurts foe every turn. Double\n"
"damage to Steel and Water."),
- .effect = EFFECT_SALT_CURE,
+ .effect = EFFECT_HIT,
.power = 40,
.type = TYPE_ROCK,
.accuracy = 100,
@@ -19499,6 +19539,10 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.metronomeBanned = TRUE,
+ .additionalEffects = ADDITIONAL_EFFECTS({
+ .moveEffect = MOVE_EFFECT_SALT_CURE,
+ .chance = 100,
+ }),
.battleAnimScript = gBattleAnimMove_SaltCure,
},
@@ -20021,6 +20065,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
+ .argument = { .absorbPercentage = 50 },
.makesContact = TRUE,
.slicingMove = TRUE,
.healingMove = TRUE,
@@ -20043,7 +20088,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.category = DAMAGE_CATEGORY_PHYSICAL,
.makesContact = TRUE,
.metronomeBanned = TRUE,
- .argument = TYPE_ELECTRIC,
+ .argument = { .type = TYPE_ELECTRIC },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_REMOVE_ARG_TYPE,
.self = TRUE,
@@ -20322,6 +20367,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_BOTH,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
+ .argument = { .absorbPercentage = 50 },
.thawsUser = TRUE,
.metronomeBanned = TRUE,
.healingMove = B_EXTRAPOLATED_MOVE_FLAGS,
@@ -20388,12 +20434,13 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = TWO_TURN_ARG(STRINGID_ELECTROSHOTCHARGING, B_WEATHER_RAIN),
+ .argument.twoTurnAttack = { .stringId = STRINGID_ELECTROSHOTCHARGING, .status = B_WEATHER_RAIN },
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_SP_ATK_PLUS_1,
.self = TRUE,
.onChargeTurnOnly = TRUE,
- }, SHEER_FORCE_HACK),
+ .sheerForceBoost = SHEER_FORCE_BOOST,
+ }),
.battleAnimScript = gBattleAnimMove_ElectroShot,
},
@@ -20601,6 +20648,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
.makesContact = TRUE,
+ .minimizeDoubleDamage = TRUE,
.battleAnimScript = gBattleAnimMove_SupercellSlam,
},
@@ -20666,6 +20714,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.additionalEffects = ADDITIONAL_EFFECTS({
.moveEffect = MOVE_EFFECT_TOXIC,
.chance = 50,
+ .sheerForceBoost = SHEER_FORCE_BOOST,
}),
.battleAnimScript = gBattleAnimMove_MalignantChain,
},
@@ -21011,7 +21060,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_SPECIAL,
- .argument = ARG_SET_PSYCHIC_TERRAIN, // Set Psychic Terrain. If there's a different field terrain active, overwrite it.
+ .argument = { .moveProperty = ARG_SET_PSYCHIC_TERRAIN }, // Set Psychic Terrain. If there's a different field terrain active, overwrite it.
.battleAnimScript = gBattleAnimMove_GenesisSupernova,
},
[MOVE_SINISTER_ARROW_RAID] =
@@ -21068,7 +21117,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = ARG_TRY_REMOVE_TERRAIN_HIT, // Remove the active field terrain if there is one.
+ .argument = { .moveProperty = ARG_TRY_REMOVE_TERRAIN_HIT }, // Remove the active field terrain if there is one.
.battleAnimScript = gBattleAnimMove_SplinteredStormshards,
},
[MOVE_LETS_SNUGGLE_FOREVER] =
@@ -21207,7 +21256,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_SUN,
+ .argument = { .maxEffect = MAX_EFFECT_SUN },
.battleAnimScript = gBattleAnimMove_MaxFlare,
},
@@ -21223,7 +21272,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_SP_ATK,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_SP_ATK },
.battleAnimScript = gBattleAnimMove_MaxFlutterby,
},
@@ -21239,7 +21288,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_ELECTRIC_TERRAIN,
+ .argument = { .maxEffect = MAX_EFFECT_ELECTRIC_TERRAIN },
.battleAnimScript = gBattleAnimMove_MaxLightning,
},
@@ -21255,7 +21304,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_SPEED,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_SPEED },
.battleAnimScript = gBattleAnimMove_MaxStrike,
},
@@ -21271,7 +21320,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RAISE_TEAM_ATTACK,
+ .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_ATTACK },
.battleAnimScript = gBattleAnimMove_MaxKnuckle,
},
@@ -21287,7 +21336,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_DEFENSE,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_DEFENSE },
.battleAnimScript = gBattleAnimMove_MaxPhantasm,
},
@@ -21303,7 +21352,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_HAIL,
+ .argument = { .maxEffect = MAX_EFFECT_HAIL },
.battleAnimScript = gBattleAnimMove_MaxHailstorm,
},
@@ -21319,7 +21368,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RAISE_TEAM_SP_ATK,
+ .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_SP_ATK },
.battleAnimScript = gBattleAnimMove_MaxOoze,
},
@@ -21335,7 +21384,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RAIN,
+ .argument = { .maxEffect = MAX_EFFECT_RAIN },
.battleAnimScript = gBattleAnimMove_MaxGeyser,
},
@@ -21351,7 +21400,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RAISE_TEAM_SPEED,
+ .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_SPEED },
.battleAnimScript = gBattleAnimMove_MaxAirstream,
},
@@ -21367,7 +21416,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_MISTY_TERRAIN,
+ .argument = { .maxEffect = MAX_EFFECT_MISTY_TERRAIN },
.battleAnimScript = gBattleAnimMove_MaxStarfall,
},
@@ -21383,7 +21432,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_ATTACK,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_ATTACK },
.battleAnimScript = gBattleAnimMove_MaxWyrmwind,
},
@@ -21399,7 +21448,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_PSYCHIC_TERRAIN,
+ .argument = { .maxEffect = MAX_EFFECT_PSYCHIC_TERRAIN },
.battleAnimScript = gBattleAnimMove_MaxMindstorm,
},
@@ -21415,7 +21464,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_SANDSTORM,
+ .argument = { .maxEffect = MAX_EFFECT_SANDSTORM },
.battleAnimScript = gBattleAnimMove_MaxRockfall,
},
@@ -21431,7 +21480,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RAISE_TEAM_SP_DEF,
+ .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_SP_DEF },
.skyBattleBanned = B_EXTRAPOLATED_MOVE_FLAGS,
.battleAnimScript = gBattleAnimMove_MaxQuake,
},
@@ -21448,7 +21497,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_SP_DEF,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_SP_DEF },
.battleAnimScript = gBattleAnimMove_MaxDarkness,
},
@@ -21464,7 +21513,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_GRASSY_TERRAIN,
+ .argument = { .maxEffect = MAX_EFFECT_GRASSY_TERRAIN },
.battleAnimScript = gBattleAnimMove_MaxOvergrowth,
},
@@ -21480,7 +21529,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RAISE_TEAM_DEFENSE,
+ .argument = { .maxEffect = MAX_EFFECT_RAISE_TEAM_DEFENSE },
.battleAnimScript = gBattleAnimMove_MaxSteelspike,
},
@@ -21496,7 +21545,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_VINE_LASH,
+ .argument = { .maxEffect = MAX_EFFECT_VINE_LASH },
.battleAnimScript = gBattleAnimMove_GMaxVineLash,
},
@@ -21512,7 +21561,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_WILDFIRE,
+ .argument = { .maxEffect = MAX_EFFECT_WILDFIRE },
.battleAnimScript = gBattleAnimMove_GMaxWildfire,
},
@@ -21528,7 +21577,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_CANNONADE,
+ .argument = { .maxEffect = MAX_EFFECT_CANNONADE },
.battleAnimScript = gBattleAnimMove_GMaxCannonade,
},
@@ -21544,7 +21593,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_EFFECT_SPORE_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_EFFECT_SPORE_FOES },
.battleAnimScript = gBattleAnimMove_GMaxBefuddle,
},
@@ -21560,7 +21609,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_PARALYZE_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_PARALYZE_FOES },
.battleAnimScript = gBattleAnimMove_GMaxVoltCrash,
},
@@ -21576,7 +21625,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_CONFUSE_FOES_PAY_DAY,
+ .argument = { .maxEffect = MAX_EFFECT_CONFUSE_FOES_PAY_DAY },
.battleAnimScript = gBattleAnimMove_GMaxGoldRush,
},
@@ -21592,7 +21641,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_CRIT_PLUS,
+ .argument = { .maxEffect = MAX_EFFECT_CRIT_PLUS },
.battleAnimScript = gBattleAnimMove_GMaxChiStrike,
},
@@ -21608,7 +21657,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_MEAN_LOOK,
+ .argument = { .maxEffect = MAX_EFFECT_MEAN_LOOK },
.battleAnimScript = gBattleAnimMove_GMaxTerror,
},
@@ -21624,7 +21673,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_SPEED_2_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_SPEED_2_FOES },
.battleAnimScript = gBattleAnimMove_GMaxFoamBurst,
},
@@ -21640,7 +21689,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_AURORA_VEIL,
+ .argument = { .maxEffect = MAX_EFFECT_AURORA_VEIL },
.battleAnimScript = gBattleAnimMove_GMaxResonance,
},
@@ -21656,7 +21705,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_INFATUATE_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_INFATUATE_FOES },
.battleAnimScript = gBattleAnimMove_GMaxCuddle,
},
@@ -21672,7 +21721,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_RECYCLE_BERRIES,
+ .argument = { .maxEffect = MAX_EFFECT_RECYCLE_BERRIES },
.battleAnimScript = gBattleAnimMove_GMaxReplenish,
},
@@ -21688,7 +21737,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_POISON_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_POISON_FOES },
.battleAnimScript = gBattleAnimMove_GMaxMalodor,
},
@@ -21704,7 +21753,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_TORMENT_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_TORMENT_FOES },
.battleAnimScript = gBattleAnimMove_GMaxMeltdown,
},
@@ -21720,7 +21769,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_FIXED_POWER,
+ .argument = { .maxEffect = MAX_EFFECT_FIXED_POWER },
.ignoresTargetAbility = TRUE,
.battleAnimScript = gBattleAnimMove_GMaxDrumSolo,
},
@@ -21737,7 +21786,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_FIXED_POWER,
+ .argument = { .maxEffect = MAX_EFFECT_FIXED_POWER },
.ignoresTargetAbility = TRUE,
.battleAnimScript = gBattleAnimMove_GMaxFireball,
},
@@ -21754,7 +21803,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_FIXED_POWER,
+ .argument = { .maxEffect = MAX_EFFECT_FIXED_POWER },
.ignoresTargetAbility = TRUE,
.battleAnimScript = gBattleAnimMove_GMaxHydrosnipe,
},
@@ -21771,7 +21820,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_DEFOG,
+ .argument = { .maxEffect = MAX_EFFECT_DEFOG },
.battleAnimScript = gBattleAnimMove_GMaxWindRage,
},
@@ -21787,7 +21836,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_GRAVITY,
+ .argument = { .maxEffect = MAX_EFFECT_GRAVITY },
.battleAnimScript = gBattleAnimMove_GMaxGravitas,
},
@@ -21803,7 +21852,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_STEALTH_ROCK,
+ .argument = { .maxEffect = MAX_EFFECT_STEALTH_ROCK },
.battleAnimScript = gBattleAnimMove_GMaxStonesurge,
},
@@ -21819,7 +21868,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_VOLCALITH,
+ .argument = { .maxEffect = MAX_EFFECT_VOLCALITH },
.battleAnimScript = gBattleAnimMove_GMaxVolcalith,
},
@@ -21835,7 +21884,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_LOWER_EVASIVENESS_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_LOWER_EVASIVENESS_FOES },
.battleAnimScript = gBattleAnimMove_GMaxTartness,
},
@@ -21851,7 +21900,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_AROMATHERAPY,
+ .argument = { .maxEffect = MAX_EFFECT_AROMATHERAPY },
.battleAnimScript = gBattleAnimMove_GMaxSweetness,
},
@@ -21867,7 +21916,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_SANDBLAST_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_SANDBLAST_FOES },
.battleAnimScript = gBattleAnimMove_GMaxSandblast,
},
@@ -21883,7 +21932,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_POISON_PARALYZE_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_POISON_PARALYZE_FOES },
.battleAnimScript = gBattleAnimMove_GMaxStunShock,
},
@@ -21899,7 +21948,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_FIRE_SPIN_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_FIRE_SPIN_FOES },
.battleAnimScript = gBattleAnimMove_GMaxCentiferno,
},
@@ -21915,7 +21964,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_CONFUSE_FOES,
+ .argument = { .maxEffect = MAX_EFFECT_CONFUSE_FOES },
.battleAnimScript = gBattleAnimMove_GMaxSmite,
},
@@ -21932,7 +21981,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_YAWN_FOE,
+ .argument = { .maxEffect = MAX_EFFECT_YAWN_FOE },
.battleAnimScript = gBattleAnimMove_GMaxSnooze,
},
@@ -21948,7 +21997,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_HEAL_TEAM,
+ .argument = { .maxEffect = MAX_EFFECT_HEAL_TEAM },
.battleAnimScript = gBattleAnimMove_GMaxFinale,
},
@@ -21964,7 +22013,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_STEELSURGE,
+ .argument = { .maxEffect = MAX_EFFECT_STEELSURGE },
.battleAnimScript = gBattleAnimMove_GMaxSteelsurge,
},
@@ -21980,7 +22029,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_SPITE,
+ .argument = { .maxEffect = MAX_EFFECT_SPITE },
.battleAnimScript = gBattleAnimMove_GMaxDepletion,
},
@@ -21996,7 +22045,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_BYPASS_PROTECT,
+ .argument = { .maxEffect = MAX_EFFECT_BYPASS_PROTECT },
.battleAnimScript = gBattleAnimMove_GMaxOneBlow,
},
@@ -22012,7 +22061,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.category = DAMAGE_CATEGORY_PHYSICAL,
- .argument = MAX_EFFECT_BYPASS_PROTECT,
+ .argument = { .maxEffect = MAX_EFFECT_BYPASS_PROTECT },
.battleAnimScript = gBattleAnimMove_GMaxRapidFlow,
},
diff --git a/src/data/object_events/object_event_pic_tables_followers.h b/src/data/object_events/object_event_pic_tables_followers.h
index 276e8fcf65..07193cedc7 100644
--- a/src/data/object_events/object_event_pic_tables_followers.h
+++ b/src/data/object_events/object_event_pic_tables_followers.h
@@ -3136,8 +3136,8 @@ static const struct SpriteFrameImage sPicTable_Bastiodon[] = {
#endif //P_FAMILY_SHIELDON
#if P_FAMILY_BURMY
-static const struct SpriteFrameImage sPicTable_BurmyPlantCloak[] = {
- overworld_ascending_frames(gObjectEventPic_BurmyPlantCloak, 4, 4),
+static const struct SpriteFrameImage sPicTable_BurmyPlant[] = {
+ overworld_ascending_frames(gObjectEventPic_BurmyPlant, 4, 4),
};
static const struct SpriteFrameImage sPicTable_BurmySandy[] = {
overworld_ascending_frames(gObjectEventPic_BurmySandy, 4, 4),
@@ -3145,8 +3145,8 @@ static const struct SpriteFrameImage sPicTable_BurmySandy[] = {
static const struct SpriteFrameImage sPicTable_BurmyTrash[] = {
overworld_ascending_frames(gObjectEventPic_BurmyTrash, 4, 4),
};
-static const struct SpriteFrameImage sPicTable_WormadamPlantCloak[] = {
- overworld_ascending_frames(gObjectEventPic_WormadamPlantCloak, 4, 4),
+static const struct SpriteFrameImage sPicTable_WormadamPlant[] = {
+ overworld_ascending_frames(gObjectEventPic_WormadamPlant, 4, 4),
};
static const struct SpriteFrameImage sPicTable_WormadamSandy[] = {
overworld_ascending_frames(gObjectEventPic_WormadamSandy, 4, 4),
diff --git a/src/data/party_menu.h b/src/data/party_menu.h
index 934f76930c..e6cb13ee6d 100644
--- a/src/data/party_menu.h
+++ b/src/data/party_menu.h
@@ -686,39 +686,41 @@ static const u16 sUnusedData[] =
0x0121, 0x013b, 0x000f, 0x0013, 0x0039, 0x0046, 0x0094, 0x00f9, 0x007f, 0x0123,
};
+static const u8 sText_Trade4[] = _("TRADE");
+
struct
{
const u8 *text;
TaskFunc func;
} static const sCursorOptions[MENU_FIELD_MOVES] =
{
- [MENU_SUMMARY] = {gText_Summary5, CursorCb_Summary},
- [MENU_SWITCH] = {gText_Switch2, CursorCb_Switch},
+ [MENU_SUMMARY] = {COMPOUND_STRING("SUMMARY"), CursorCb_Summary},
+ [MENU_SWITCH] = {COMPOUND_STRING("SWITCH"), CursorCb_Switch},
[MENU_CANCEL1] = {gText_Cancel2, CursorCb_Cancel1},
- [MENU_ITEM] = {gText_Item, CursorCb_Item},
+ [MENU_ITEM] = {COMPOUND_STRING("ITEM"), CursorCb_Item},
[MENU_GIVE] = {gMenuText_Give, CursorCb_Give},
- [MENU_TAKE_ITEM] = {gText_Take, CursorCb_TakeItem},
- [MENU_MAIL] = {gText_Mail, CursorCb_Mail},
- [MENU_TAKE_MAIL] = {gText_Take2, CursorCb_TakeMail},
- [MENU_READ] = {gText_Read2, CursorCb_Read},
+ [MENU_TAKE_ITEM] = {COMPOUND_STRING("TAKE"), CursorCb_TakeItem},
+ [MENU_MAIL] = {COMPOUND_STRING("MAIL"), CursorCb_Mail},
+ [MENU_TAKE_MAIL] = {COMPOUND_STRING("TAKE"), CursorCb_TakeMail},
+ [MENU_READ] = {COMPOUND_STRING("READ"), CursorCb_Read},
[MENU_CANCEL2] = {gText_Cancel2, CursorCb_Cancel2},
- [MENU_SHIFT] = {gText_Shift, CursorCb_SendMon},
- [MENU_SEND_OUT] = {gText_SendOut, CursorCb_SendMon},
- [MENU_ENTER] = {gText_Enter, CursorCb_Enter},
- [MENU_NO_ENTRY] = {gText_NoEntry, CursorCb_NoEntry},
- [MENU_STORE] = {gText_Store, CursorCb_Store},
+ [MENU_SHIFT] = {COMPOUND_STRING("SHIFT"), CursorCb_SendMon},
+ [MENU_SEND_OUT] = {COMPOUND_STRING("SEND OUT"), CursorCb_SendMon},
+ [MENU_ENTER] = {COMPOUND_STRING("ENTER"), CursorCb_Enter},
+ [MENU_NO_ENTRY] = {COMPOUND_STRING("NO ENTRY"), CursorCb_NoEntry},
+ [MENU_STORE] = {COMPOUND_STRING("STORE"), CursorCb_Store},
[MENU_REGISTER] = {gText_Register, CursorCb_Register},
- [MENU_TRADE1] = {gText_Trade4, CursorCb_Trade1},
- [MENU_TRADE2] = {gText_Trade4, CursorCb_Trade2},
+ [MENU_TRADE1] = {sText_Trade4, CursorCb_Trade1},
+ [MENU_TRADE2] = {sText_Trade4, CursorCb_Trade2},
[MENU_TOSS] = {gMenuText_Toss, CursorCb_Toss},
- [MENU_CATALOG_BULB] = {gText_LightBulb, CursorCb_CatalogBulb},
- [MENU_CATALOG_OVEN] = {gText_MicrowaveOven, CursorCb_CatalogOven},
- [MENU_CATALOG_WASHING] = {gText_WashingMachine, CursorCb_CatalogWashing},
- [MENU_CATALOG_FRIDGE] = {gText_Refrigerator, CursorCb_CatalogFridge},
- [MENU_CATALOG_FAN] = {gText_ElectricFan, CursorCb_CatalogFan},
- [MENU_CATALOG_MOWER] = {gText_LawnMower, CursorCb_CatalogMower},
- [MENU_CHANGE_FORM] = {gText_ChangeForm, CursorCb_ChangeForm},
- [MENU_CHANGE_ABILITY] = {gText_ChangeAbility, CursorCb_ChangeAbility},
+ [MENU_CATALOG_BULB] = {COMPOUND_STRING("Light bulb"), CursorCb_CatalogBulb},
+ [MENU_CATALOG_OVEN] = {COMPOUND_STRING("Microwave oven"), CursorCb_CatalogOven},
+ [MENU_CATALOG_WASHING] = {COMPOUND_STRING("Washing machine"), CursorCb_CatalogWashing},
+ [MENU_CATALOG_FRIDGE] = {COMPOUND_STRING("Refrigerator"), CursorCb_CatalogFridge},
+ [MENU_CATALOG_FAN] = {COMPOUND_STRING("Electric fan"), CursorCb_CatalogFan},
+ [MENU_CATALOG_MOWER] = {COMPOUND_STRING("Lawn mower"), CursorCb_CatalogMower},
+ [MENU_CHANGE_FORM] = {COMPOUND_STRING("Change form"), CursorCb_ChangeForm},
+ [MENU_CHANGE_ABILITY] = {COMPOUND_STRING("Change Ability"), CursorCb_ChangeAbility},
};
static const u8 sPartyMenuAction_SummarySwitchCancel[] = {MENU_SUMMARY, MENU_SWITCH, MENU_CANCEL1};
diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h
index 46dec53544..340bdb1fa6 100644
--- a/src/data/pokemon/form_change_tables.h
+++ b/src/data/pokemon/form_change_tables.h
@@ -789,9 +789,12 @@ static const struct FormChange sFurfrouFormChangeTable[] = {
#if P_FAMILY_HONEDGE
static const struct FormChange sAegislashFormChangeTable[] = {
- {FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH_SHIELD},
- {FORM_CHANGE_FAINT, SPECIES_AEGISLASH_SHIELD},
- {FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH_SHIELD},
+ {FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY, SPECIES_AEGISLASH_BLADE, DAMAGE_CATEGORY_PHYSICAL, ABILITY_STANCE_CHANGE},
+ {FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY, SPECIES_AEGISLASH_BLADE, DAMAGE_CATEGORY_SPECIAL, ABILITY_STANCE_CHANGE},
+ {FORM_CHANGE_BATTLE_BEFORE_MOVE, SPECIES_AEGISLASH_SHIELD, MOVE_KINGS_SHIELD, ABILITY_STANCE_CHANGE},
+ {FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH_SHIELD},
+ {FORM_CHANGE_FAINT, SPECIES_AEGISLASH_SHIELD},
+ {FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH_SHIELD},
{FORM_CHANGE_TERMINATOR},
};
#endif //P_FAMILY_HONEDGE
diff --git a/src/data/pokemon/level_up_learnsets/gen_1.h b/src/data/pokemon/level_up_learnsets/gen_1.h
index 8470b1b14e..f1e7cd32ff 100644
--- a/src/data/pokemon/level_up_learnsets/gen_1.h
+++ b/src/data/pokemon/level_up_learnsets/gen_1.h
@@ -7717,7 +7717,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
LEVEL_UP_MOVE(10, MOVE_PROTECT),
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
diff --git a/src/data/pokemon/level_up_learnsets/gen_2.h b/src/data/pokemon/level_up_learnsets/gen_2.h
index 0f39631c4f..3d74d70b23 100644
--- a/src/data/pokemon/level_up_learnsets/gen_2.h
+++ b/src/data/pokemon/level_up_learnsets/gen_2.h
@@ -7961,7 +7961,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
LEVEL_UP_MOVE(10, MOVE_PROTECT),
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
diff --git a/src/data/pokemon/level_up_learnsets/gen_3.h b/src/data/pokemon/level_up_learnsets/gen_3.h
index 81e6d06b46..cedd09b308 100644
--- a/src/data/pokemon/level_up_learnsets/gen_3.h
+++ b/src/data/pokemon/level_up_learnsets/gen_3.h
@@ -8187,7 +8187,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
LEVEL_UP_MOVE(10, MOVE_PROTECT),
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
diff --git a/src/data/pokemon/level_up_learnsets/gen_4.h b/src/data/pokemon/level_up_learnsets/gen_4.h
index 5c9f6872b5..4b302539b2 100644
--- a/src/data/pokemon/level_up_learnsets/gen_4.h
+++ b/src/data/pokemon/level_up_learnsets/gen_4.h
@@ -9461,7 +9461,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
LEVEL_UP_MOVE(10, MOVE_PROTECT),
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
diff --git a/src/data/pokemon/level_up_learnsets/gen_5.h b/src/data/pokemon/level_up_learnsets/gen_5.h
index cb99b6375d..2403f17b96 100644
--- a/src/data/pokemon/level_up_learnsets/gen_5.h
+++ b/src/data/pokemon/level_up_learnsets/gen_5.h
@@ -9920,7 +9920,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
LEVEL_UP_MOVE(10, MOVE_PROTECT),
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
diff --git a/src/data/pokemon/level_up_learnsets/gen_6.h b/src/data/pokemon/level_up_learnsets/gen_6.h
index 32e5849cda..c5a3a39acf 100644
--- a/src/data/pokemon/level_up_learnsets/gen_6.h
+++ b/src/data/pokemon/level_up_learnsets/gen_6.h
@@ -10382,7 +10382,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_TACKLE),
LEVEL_UP_MOVE(10, MOVE_PROTECT),
LEVEL_UP_MOVE(15, MOVE_BUG_BITE),
diff --git a/src/data/pokemon/level_up_learnsets/gen_7.h b/src/data/pokemon/level_up_learnsets/gen_7.h
index f88e4bcba7..77d2fc2deb 100644
--- a/src/data/pokemon/level_up_learnsets/gen_7.h
+++ b/src/data/pokemon/level_up_learnsets/gen_7.h
@@ -10610,7 +10610,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 0, MOVE_QUIVER_DANCE),
LEVEL_UP_MOVE( 1, MOVE_QUIVER_DANCE),
LEVEL_UP_MOVE( 1, MOVE_SUCKER_PUNCH),
diff --git a/src/data/pokemon/level_up_learnsets/gen_8.h b/src/data/pokemon/level_up_learnsets/gen_8.h
index 67d263c859..65b557a486 100644
--- a/src/data/pokemon/level_up_learnsets/gen_8.h
+++ b/src/data/pokemon/level_up_learnsets/gen_8.h
@@ -10633,7 +10633,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 0, MOVE_QUIVER_DANCE),
LEVEL_UP_MOVE( 1, MOVE_QUIVER_DANCE),
LEVEL_UP_MOVE( 1, MOVE_SUCKER_PUNCH),
diff --git a/src/data/pokemon/level_up_learnsets/gen_9.h b/src/data/pokemon/level_up_learnsets/gen_9.h
index 9f6985bc9a..0bdfbe1eb3 100644
--- a/src/data/pokemon/level_up_learnsets/gen_9.h
+++ b/src/data/pokemon/level_up_learnsets/gen_9.h
@@ -10291,7 +10291,7 @@ static const struct LevelUpMove sBurmyLevelUpLearnset[] = {
LEVEL_UP_END
};
-static const struct LevelUpMove sWormadamPlantCloakLevelUpLearnset[] = {
+static const struct LevelUpMove sWormadamPlantLevelUpLearnset[] = {
LEVEL_UP_MOVE( 0, MOVE_QUIVER_DANCE),
LEVEL_UP_MOVE( 1, MOVE_QUIVER_DANCE),
LEVEL_UP_MOVE( 1, MOVE_SUCKER_PUNCH),
diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h
index fa8c8d9fde..314b5bd73f 100644
--- a/src/data/pokemon/species_info/gen_1_families.h
+++ b/src/data/pokemon/species_info/gen_1_families.h
@@ -2533,7 +2533,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
.frontPicSize = MON_COORDS_SIZE(32, 40),
.frontPicYOffset = 13,
.frontAnimFrames = sAnims_PichuSpikyEared,
- //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
+ .frontAnimId = ANIM_V_JUMPS_H_JUMPS,
.backPic = gMonBackPic_PichuSpikyEared,
.backPicSize = MON_COORDS_SIZE(48, 56),
.backPicYOffset = 8,
@@ -2544,11 +2544,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
.iconPalIndex = 1,
SHADOW(2, 0, SHADOW_SIZE_S)
FOOTPRINT(Pichu)
- OVERWORLD(
+ OVERWORLD_SET_ANIM(
sPicTable_PichuSpikyEared,
SIZE_32x32,
SHADOW_SIZE_M,
TRACKS_FOOT,
+ sAnimTable_Following_Asym,
gOverworldPalette_PichuSpikyEared,
gShinyOverworldPalette_PichuSpikyEared
)
@@ -4762,7 +4763,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
.palette = gMonPalette_VulpixAlola,
.shinyPalette = gMonShinyPalette_VulpixAlola,
.iconSprite = gMonIcon_VulpixAlola,
- .iconPalIndex = 2,
+ .iconPalIndex = 0,
SHADOW(-2, 3, SHADOW_SIZE_M)
FOOTPRINT(Vulpix)
OVERWORLD(
@@ -4829,7 +4830,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
.palette = gMonPalette_NinetalesAlola,
.shinyPalette = gMonShinyPalette_NinetalesAlola,
.iconSprite = gMonIcon_NinetalesAlola,
- .iconPalIndex = 2,
+ .iconPalIndex = 0,
SHADOW(0, 12, SHADOW_SIZE_XL_BATTLE_ONLY)
FOOTPRINT(Ninetales)
OVERWORLD(
@@ -8709,7 +8710,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] =
.palette = gMonPalette_GravelerAlola,
.shinyPalette = gMonShinyPalette_GravelerAlola,
.iconSprite = gMonIcon_GravelerAlola,
- .iconPalIndex = 2,
+ .iconPalIndex = 0,
SHADOW(1, 5, SHADOW_SIZE_XL_BATTLE_ONLY)
FOOTPRINT(Graveler)
OVERWORLD(
diff --git a/src/data/pokemon/species_info/gen_4_families.h b/src/data/pokemon/species_info/gen_4_families.h
index b84284de29..be0cfba99e 100644
--- a/src/data/pokemon/species_info/gen_4_families.h
+++ b/src/data/pokemon/species_info/gen_4_families.h
@@ -1656,29 +1656,29 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
.pokemonOffset = 24,
.trainerScale = 256,
.trainerOffset = 0,
- .frontPic = gMonFrontPic_BurmyPlantCloak,
+ .frontPic = gMonFrontPic_BurmyPlant,
.frontPicSize = MON_COORDS_SIZE(32, 56),
.frontPicYOffset = 13,
.frontAnimFrames = sAnims_Burmy,
.frontAnimId = ANIM_V_STRETCH,
.enemyMonElevation = 10,
- .backPic = gMonBackPic_BurmyPlantCloak,
+ .backPic = gMonBackPic_BurmyPlant,
.backPicSize = MON_COORDS_SIZE(40, 56),
.backPicYOffset = 6,
.backAnimId = BACK_ANIM_H_SHAKE,
- .palette = gMonPalette_BurmyPlantCloak,
- .shinyPalette = gMonShinyPalette_BurmyPlantCloak,
- .iconSprite = gMonIcon_BurmyPlantCloak,
+ .palette = gMonPalette_BurmyPlant,
+ .shinyPalette = gMonShinyPalette_BurmyPlant,
+ .iconSprite = gMonIcon_BurmyPlant,
.iconPalIndex = 1,
SHADOW(-1, 8, SHADOW_SIZE_S)
FOOTPRINT(Burmy)
OVERWORLD(
- sPicTable_BurmyPlantCloak,
+ sPicTable_BurmyPlant,
SIZE_32x32,
SHADOW_SIZE_M,
TRACKS_FOOT,
- gOverworldPalette_BurmyPlantCloak,
- gShinyOverworldPalette_BurmyPlantCloak
+ gOverworldPalette_BurmyPlant,
+ gShinyOverworldPalette_BurmyPlant
)
.tmIlliterate = TRUE,
.levelUpLearnset = sBurmyLevelUpLearnset,
@@ -1858,32 +1858,32 @@ const struct SpeciesInfo gSpeciesInfoGen4[] =
.pokemonOffset = 13,
.trainerScale = 256,
.trainerOffset = 0,
- .frontPic = gMonFrontPic_WormadamPlantCloak,
+ .frontPic = gMonFrontPic_WormadamPlant,
.frontPicSize = MON_COORDS_SIZE(48, 56),
.frontPicYOffset = 10,
.frontAnimFrames = sAnims_Wormadam,
.frontAnimId = ANIM_SWING_CONVEX_FAST_SHORT,
.enemyMonElevation = 8,
- .backPic = gMonBackPic_WormadamPlantCloak,
+ .backPic = gMonBackPic_WormadamPlant,
.backPicSize = MON_COORDS_SIZE(56, 64),
.backPicYOffset = 2,
.backAnimId = BACK_ANIM_V_SHAKE,
- .palette = gMonPalette_WormadamPlantCloak,
- .shinyPalette = gMonShinyPalette_WormadamPlantCloak,
- .iconSprite = gMonIcon_WormadamPlantCloak,
+ .palette = gMonPalette_WormadamPlant,
+ .shinyPalette = gMonShinyPalette_WormadamPlant,
+ .iconSprite = gMonIcon_WormadamPlant,
.iconPalIndex = 1,
SHADOW(0, 9, SHADOW_SIZE_S)
FOOTPRINT(Wormadam)
OVERWORLD(
- sPicTable_WormadamPlantCloak,
+ sPicTable_WormadamPlant,
SIZE_32x32,
SHADOW_SIZE_M,
TRACKS_FOOT,
- gOverworldPalette_WormadamPlantCloak,
- gShinyOverworldPalette_WormadamPlantCloak
+ gOverworldPalette_WormadamPlant,
+ gShinyOverworldPalette_WormadamPlant
)
- .levelUpLearnset = sWormadamPlantCloakLevelUpLearnset,
- .teachableLearnset = sWormadamPlantCloakTeachableLearnset,
+ .levelUpLearnset = sWormadamPlantLevelUpLearnset,
+ .teachableLearnset = sWormadamPlantTeachableLearnset,
.formSpeciesIdTable = sWormadamFormSpeciesIdTable,
},
diff --git a/src/data/pokemon/species_info/gen_7_families.h b/src/data/pokemon/species_info/gen_7_families.h
index d42167b883..cb126fd171 100644
--- a/src/data/pokemon/species_info/gen_7_families.h
+++ b/src/data/pokemon/species_info/gen_7_families.h
@@ -5493,7 +5493,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
.palette = gMonPalette_TapuFini,
.shinyPalette = gMonShinyPalette_TapuFini,
.iconSprite = gMonIcon_TapuFini,
- .iconPalIndex = 0,
+ .iconPalIndex = 2,
SHADOW(1, 15, SHADOW_SIZE_M)
FOOTPRINT(TapuFini)
OVERWORLD(
@@ -5694,7 +5694,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
.palette = gMonPalette_Solgaleo,
.shinyPalette = gMonShinyPalette_Solgaleo,
.iconSprite = gMonIcon_Solgaleo,
- .iconPalIndex = 0,
+ .iconPalIndex = 2,
SHADOW(-1, 11, SHADOW_SIZE_XL_BATTLE_ONLY)
FOOTPRINT(Solgaleo)
OVERWORLD(
@@ -5826,7 +5826,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
.palette = gMonPalette_Nihilego,
.shinyPalette = gMonShinyPalette_Nihilego,
.iconSprite = gMonIcon_Nihilego,
- .iconPalIndex = 0,
+ .iconPalIndex = 2,
SHADOW(-2, 14, SHADOW_SIZE_S)
FOOTPRINT(Nihilego)
OVERWORLD(
@@ -6220,7 +6220,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
.palette = gMonPalette_Guzzlord,
.shinyPalette = gMonShinyPalette_Guzzlord,
.iconSprite = gMonIcon_Guzzlord,
- .iconPalIndex = 0,
+ .iconPalIndex = 2,
SHADOW(4, 10, SHADOW_SIZE_XL_BATTLE_ONLY)
FOOTPRINT(Guzzlord)
OVERWORLD(
@@ -6288,7 +6288,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] =
.palette = gMonPalette_Necrozma,
.shinyPalette = gMonShinyPalette_Necrozma,
.iconSprite = gMonIcon_Necrozma,
- .iconPalIndex = 0,
+ .iconPalIndex = 1,
SHADOW(-1, 15, SHADOW_SIZE_M)
FOOTPRINT(Necrozma)
OVERWORLD(
diff --git a/src/data/pokemon/species_info/gen_8_families.h b/src/data/pokemon/species_info/gen_8_families.h
index 37eefda7f9..ee08542523 100644
--- a/src/data/pokemon/species_info/gen_8_families.h
+++ b/src/data/pokemon/species_info/gen_8_families.h
@@ -2655,7 +2655,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.backPic = gMonBackPic_Dipplin,
.backPicSize = MON_COORDS_SIZE(64, 64),
- .backPicYOffset = 0,
+ .backPicYOffset = 1,
//.backAnimId = BACK_ANIM_NONE,
.palette = gMonPalette_Dipplin,
.shinyPalette = gMonShinyPalette_Dipplin,
@@ -7660,7 +7660,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
.trainerOffset = 1,
.frontPic = gMonFrontPic_EnamorusIncarnate,
.frontPicSize = MON_COORDS_SIZE(64, 64),
- .frontPicYOffset = 1,
+ .frontPicYOffset = 0,
.frontAnimFrames = sAnims_EnamorusIncarnate,
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.enemyMonElevation = 7,
@@ -7672,7 +7672,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
.shinyPalette = gMonShinyPalette_EnamorusIncarnate,
.iconSprite = gMonIcon_EnamorusIncarnate,
.iconPalIndex = 1,
- SHADOW(0, 17, SHADOW_SIZE_M)
+ SHADOW(-3, 19, SHADOW_SIZE_M)
FOOTPRINT(Enamorus)
OVERWORLD(
sPicTable_EnamorusIncarnate,
@@ -7730,7 +7730,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.backPic = gMonBackPic_EnamorusTherian,
.backPicSize = MON_COORDS_SIZE(64, 64),
- .backPicYOffset = 2,
+ .backPicYOffset = 0,
//.backAnimId = BACK_ANIM_NONE,
.palette = gMonPalette_EnamorusTherian,
.shinyPalette = gMonShinyPalette_EnamorusTherian,
diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h
index 7b5fcdd3d1..7402619b9a 100644
--- a/src/data/pokemon/species_info/gen_9_families.h
+++ b/src/data/pokemon/species_info/gen_9_families.h
@@ -2619,7 +2619,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
.trainerOffset = 0,
.frontPic = gMonFrontPic_Maschiff,
.frontPicSize = MON_COORDS_SIZE(64, 64),
- .frontPicYOffset = 8,
+ .frontPicYOffset = 11,
.frontAnimFrames = sAnims_Maschiff,
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.backPic = gMonBackPic_Maschiff,
@@ -7086,13 +7086,13 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
.trainerOffset = 0,
.frontPic = gMonFrontPic_Sinistcha,
.frontPicSize = MON_COORDS_SIZE(64, 64),
- .frontPicYOffset = 10,
+ .frontPicYOffset = 3,
.frontAnimFrames = sAnims_Sinistcha,
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.enemyMonElevation = 10,
.backPic = gMonBackPic_Sinistcha,
.backPicSize = MON_COORDS_SIZE(64, 64),
- .backPicYOffset = 13,
+ .backPicYOffset = 4,
//.backAnimId = BACK_ANIM_NONE,
.palette = gMonPalette_Sinistcha,
.shinyPalette = gMonShinyPalette_Sinistcha,
@@ -7147,13 +7147,13 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
.trainerOffset = 0,
.frontPic = gMonFrontPic_Sinistcha,
.frontPicSize = MON_COORDS_SIZE(64, 64),
- .frontPicYOffset = 10,
+ .frontPicYOffset = 3,
.frontAnimFrames = sAnims_Sinistcha,
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.enemyMonElevation = 10,
.backPic = gMonBackPic_Sinistcha,
.backPicSize = MON_COORDS_SIZE(64, 64),
- .backPicYOffset = 13,
+ .backPicYOffset = 4,
//.backAnimId = BACK_ANIM_NONE,
.palette = gMonPalette_Sinistcha,
.shinyPalette = gMonShinyPalette_Sinistcha,
@@ -7341,12 +7341,12 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
.trainerOffset = 0,
.frontPic = gMonFrontPic_Fezandipiti,
.frontPicSize = MON_COORDS_SIZE(64, 64),
- .frontPicYOffset = 2,
+ .frontPicYOffset = 1,
.frontAnimFrames = sAnims_Fezandipiti,
//.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,
.backPic = gMonBackPic_Fezandipiti,
.backPicSize = MON_COORDS_SIZE(64, 64),
- .backPicYOffset = 4,
+ .backPicYOffset = 0,
//.backAnimId = BACK_ANIM_NONE,
.palette = gMonPalette_Fezandipiti,
.shinyPalette = gMonShinyPalette_Fezandipiti,
@@ -7370,78 +7370,78 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
#endif //P_FAMILY_FEZANDIPITI
#if P_FAMILY_OGERPON
-#define OGERPON_SPECIES_INFO(Form1, Form2, type, ability, color, iconpalette, isTeraform) \
- { \
- .baseHP = 80, \
- .baseAttack = 120, \
- .baseDefense = 84, \
- .baseSpeed = 110, \
- .baseSpAttack = 60, \
- .baseSpDefense = 96, \
- .types = MON_TYPES(TYPE_GRASS, type), \
- .forceTeraType = type, \
- .catchRate = 5, \
- .expYield = 275, \
- .evYield_Attack = 3, \
- .genderRatio = MON_FEMALE, \
- .eggCycles = 10, \
- .friendship = STANDARD_FRIENDSHIP, \
- .growthRate = GROWTH_SLOW, \
- .eggGroups = MON_EGG_GROUPS(EGG_GROUP_NO_EGGS_DISCOVERED), \
- .abilities = { ability, ABILITY_NONE }, \
- .bodyColor = color, \
- .speciesName = _("Ogerpon"), \
- .cryId = CRY_OGERPON, \
- .natDexNum = NATIONAL_DEX_OGERPON, \
- .categoryName = _("Mask"), \
- .height = 12, \
- .weight = 398, \
- .description = gOgerpon##Form1##MaskPokedexText, \
- .pokemonScale = 356, \
- .pokemonOffset = 17, \
- .trainerScale = 256, \
- .trainerOffset = 0, \
- .frontPic = gMonFrontPic_Ogerpon##Form2, \
- .frontPicSize = MON_COORDS_SIZE(64, 64), \
- .frontPicYOffset = 0, \
- .frontAnimFrames = sAnims_Ogerpon, \
- /*.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,*/ \
- .backPic = gMonBackPic_Ogerpon##Form2, \
- .backPicSize = MON_COORDS_SIZE(64, 64), \
- .backPicYOffset = 0, \
- /*.backAnimId = BACK_ANIM_NONE,*/ \
- .palette = gMonPalette_Ogerpon##Form2, \
- .shinyPalette = gMonShinyPalette_Ogerpon##Form2, \
- .iconSprite = gMonIcon_Ogerpon##Form1, \
- .iconPalIndex = iconpalette, \
- SHADOW(7, 13, SHADOW_SIZE_L) \
- FOOTPRINT(Ogerpon) \
- OVERWORLD( \
- sPicTable_Ogerpon##Form2, \
- SIZE_32x32, \
- SHADOW_SIZE_M, \
- TRACKS_FOOT, \
- gOverworldPalette_Ogerpon##Form2, \
- gShinyOverworldPalette_Ogerpon##Form2 \
- ) \
- .levelUpLearnset = sOgerponLevelUpLearnset, \
- .teachableLearnset = sOgerponTeachableLearnset, \
- .formSpeciesIdTable = sOgerponFormSpeciesIdTable, \
- .formChangeTable = sOgerponFormChangeTable, \
- .isLegendary = TRUE, \
- .isTeraForm = isTeraform, \
- .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, \
+#define OGERPON_SPECIES_INFO(Form1, Form2, type, ability, color, frontYOffset, backYOffset, iconpalette, isTeraform) \
+ { \
+ .baseHP = 80, \
+ .baseAttack = 120, \
+ .baseDefense = 84, \
+ .baseSpeed = 110, \
+ .baseSpAttack = 60, \
+ .baseSpDefense = 96, \
+ .types = MON_TYPES(TYPE_GRASS, type), \
+ .forceTeraType = type, \
+ .catchRate = 5, \
+ .expYield = 275, \
+ .evYield_Attack = 3, \
+ .genderRatio = MON_FEMALE, \
+ .eggCycles = 10, \
+ .friendship = STANDARD_FRIENDSHIP, \
+ .growthRate = GROWTH_SLOW, \
+ .eggGroups = MON_EGG_GROUPS(EGG_GROUP_NO_EGGS_DISCOVERED), \
+ .abilities = { ability, ABILITY_NONE }, \
+ .bodyColor = color, \
+ .speciesName = _("Ogerpon"), \
+ .cryId = CRY_OGERPON, \
+ .natDexNum = NATIONAL_DEX_OGERPON, \
+ .categoryName = _("Mask"), \
+ .height = 12, \
+ .weight = 398, \
+ .description = gOgerpon##Form1##MaskPokedexText, \
+ .pokemonScale = 356, \
+ .pokemonOffset = 17, \
+ .trainerScale = 256, \
+ .trainerOffset = 0, \
+ .frontPic = gMonFrontPic_Ogerpon##Form2, \
+ .frontPicSize = MON_COORDS_SIZE(64, 64), \
+ .frontPicYOffset = frontYOffset, \
+ .frontAnimFrames = sAnims_Ogerpon, \
+ /*.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE,*/ \
+ .backPic = gMonBackPic_Ogerpon##Form2, \
+ .backPicSize = MON_COORDS_SIZE(64, 64), \
+ .backPicYOffset = backYOffset, \
+ /*.backAnimId = BACK_ANIM_NONE,*/ \
+ .palette = gMonPalette_Ogerpon##Form2, \
+ .shinyPalette = gMonShinyPalette_Ogerpon##Form2, \
+ .iconSprite = gMonIcon_Ogerpon##Form1, \
+ .iconPalIndex = iconpalette, \
+ SHADOW(7, 13, SHADOW_SIZE_L) \
+ FOOTPRINT(Ogerpon) \
+ OVERWORLD( \
+ sPicTable_Ogerpon##Form2, \
+ SIZE_32x32, \
+ SHADOW_SIZE_M, \
+ TRACKS_FOOT, \
+ gOverworldPalette_Ogerpon##Form2, \
+ gShinyOverworldPalette_Ogerpon##Form2 \
+ ) \
+ .levelUpLearnset = sOgerponLevelUpLearnset, \
+ .teachableLearnset = sOgerponTeachableLearnset, \
+ .formSpeciesIdTable = sOgerponFormSpeciesIdTable, \
+ .formChangeTable = sOgerponFormChangeTable, \
+ .isLegendary = TRUE, \
+ .isTeraForm = isTeraform, \
+ .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, \
}
- [SPECIES_OGERPON_TEAL] = OGERPON_SPECIES_INFO(Teal, Teal, TYPE_GRASS, ABILITY_DEFIANT, BODY_COLOR_GREEN, 1, FALSE),
- [SPECIES_OGERPON_WELLSPRING] = OGERPON_SPECIES_INFO(Wellspring, Wellspring, TYPE_WATER, ABILITY_WATER_ABSORB, BODY_COLOR_BLUE, 0, FALSE),
- [SPECIES_OGERPON_HEARTHFLAME] = OGERPON_SPECIES_INFO(Hearthflame, Hearthflame, TYPE_FIRE, ABILITY_MOLD_BREAKER, BODY_COLOR_RED, 0, FALSE),
- [SPECIES_OGERPON_CORNERSTONE] = OGERPON_SPECIES_INFO(Cornerstone, Cornerstone, TYPE_ROCK, ABILITY_STURDY, BODY_COLOR_GRAY, 0, FALSE),
+ [SPECIES_OGERPON_TEAL] = OGERPON_SPECIES_INFO(Teal, Teal, TYPE_GRASS, ABILITY_DEFIANT, BODY_COLOR_GREEN, 1, 7, 1, FALSE),
+ [SPECIES_OGERPON_WELLSPRING] = OGERPON_SPECIES_INFO(Wellspring, Wellspring, TYPE_WATER, ABILITY_WATER_ABSORB, BODY_COLOR_BLUE, 1, 7, 0, FALSE),
+ [SPECIES_OGERPON_HEARTHFLAME] = OGERPON_SPECIES_INFO(Hearthflame, Hearthflame, TYPE_FIRE, ABILITY_MOLD_BREAKER, BODY_COLOR_RED, 1, 7, 0, FALSE),
+ [SPECIES_OGERPON_CORNERSTONE] = OGERPON_SPECIES_INFO(Cornerstone, Cornerstone, TYPE_ROCK, ABILITY_STURDY, BODY_COLOR_GRAY, 1, 7, 0, FALSE),
#if P_TERA_FORMS
- [SPECIES_OGERPON_TEAL_TERA] = OGERPON_SPECIES_INFO(Teal, TealTera, TYPE_GRASS, ABILITY_EMBODY_ASPECT_TEAL_MASK, BODY_COLOR_GREEN, 1, TRUE),
- [SPECIES_OGERPON_WELLSPRING_TERA] = OGERPON_SPECIES_INFO(Wellspring, WellspringTera, TYPE_WATER, ABILITY_EMBODY_ASPECT_WELLSPRING_MASK, BODY_COLOR_BLUE, 0, TRUE),
- [SPECIES_OGERPON_HEARTHFLAME_TERA] = OGERPON_SPECIES_INFO(Hearthflame, HearthflameTera, TYPE_FIRE, ABILITY_EMBODY_ASPECT_HEARTHFLAME_MASK, BODY_COLOR_RED, 0, TRUE),
- [SPECIES_OGERPON_CORNERSTONE_TERA] = OGERPON_SPECIES_INFO(Cornerstone, CornerstoneTera, TYPE_ROCK, ABILITY_EMBODY_ASPECT_CORNERSTONE_MASK, BODY_COLOR_GRAY, 0, TRUE),
+ [SPECIES_OGERPON_TEAL_TERA] = OGERPON_SPECIES_INFO(Teal, TealTera, TYPE_GRASS, ABILITY_EMBODY_ASPECT_TEAL_MASK, BODY_COLOR_GREEN, 0, 0, 1, TRUE),
+ [SPECIES_OGERPON_WELLSPRING_TERA] = OGERPON_SPECIES_INFO(Wellspring, WellspringTera, TYPE_WATER, ABILITY_EMBODY_ASPECT_WELLSPRING_MASK, BODY_COLOR_BLUE, 0, 0, 0, TRUE),
+ [SPECIES_OGERPON_HEARTHFLAME_TERA] = OGERPON_SPECIES_INFO(Hearthflame, HearthflameTera, TYPE_FIRE, ABILITY_EMBODY_ASPECT_HEARTHFLAME_MASK, BODY_COLOR_RED, 0, 0, 0, TRUE),
+ [SPECIES_OGERPON_CORNERSTONE_TERA] = OGERPON_SPECIES_INFO(Cornerstone, CornerstoneTera, TYPE_ROCK, ABILITY_EMBODY_ASPECT_CORNERSTONE_MASK, BODY_COLOR_GRAY, 0, 0, 0, TRUE),
#endif //P_TERA_FORMS
#endif //P_FAMILY_OGERPON
diff --git a/src/data/pokemon/teachable_learnsets.h b/src/data/pokemon/teachable_learnsets.h
index 46354db5a0..b0755d6039 100644
--- a/src/data/pokemon/teachable_learnsets.h
+++ b/src/data/pokemon/teachable_learnsets.h
@@ -18903,7 +18903,7 @@ static const u16 sBurmyTeachableLearnset[] = {
MOVE_UNAVAILABLE,
};
-static const u16 sWormadamPlantCloakTeachableLearnset[] = {
+static const u16 sWormadamPlantTeachableLearnset[] = {
MOVE_ATTRACT,
MOVE_BULLET_SEED,
MOVE_DIG,
diff --git a/src/data/pokemon_graphics/front_pic_anims.h b/src/data/pokemon_graphics/front_pic_anims.h
index 8452e24732..adf64468aa 100644
--- a/src/data/pokemon_graphics/front_pic_anims.h
+++ b/src/data/pokemon_graphics/front_pic_anims.h
@@ -340,7 +340,17 @@ static const union AnimCmd sAnim_Pichu_1[] =
ANIMCMD_END,
};
-PLACEHOLDER_ANIM_SINGLE_FRAME(PichuSpikyEared);
+static const union AnimCmd sAnim_PichuSpikyEared_1[] =
+{
+ ANIMCMD_FRAME(0, 10),
+ ANIMCMD_FRAME(1, 10),
+ ANIMCMD_FRAME(0, 10),
+ ANIMCMD_FRAME(1, 10),
+ ANIMCMD_FRAME(0, 10),
+ ANIMCMD_FRAME(1, 10),
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
#endif //P_GEN_2_CROSS_EVOS
static const union AnimCmd sAnim_Pikachu_1[] =
@@ -5205,8 +5215,7 @@ static const union AnimCmd sAnim_DeoxysNormal_1[] =
{
ANIMCMD_FRAME(0, 16),
ANIMCMD_FRAME(1, 16),
- ANIMCMD_FRAME(0, 26),
- ANIMCMD_FRAME(1, 16),
+ ANIMCMD_FRAME(1, 26),
ANIMCMD_FRAME(0, 16),
ANIMCMD_END,
};
@@ -9795,7 +9804,7 @@ PLACEHOLDER_ANIM_SINGLE_FRAME(Calyrex);
#endif //P_FAMILY_CALYREX
#if P_FAMILY_ENAMORUS
-PLACEHOLDER_ANIM_SINGLE_FRAME(EnamorusIncarnate);
+PLACEHOLDER_ANIM_TWO_FRAMES(EnamorusIncarnate);
PLACEHOLDER_ANIM_SINGLE_FRAME(EnamorusTherian);
#endif //P_FAMILY_ENAMORUS
diff --git a/src/data/script_menu.h b/src/data/script_menu.h
index 3b29171327..fc0b574a2f 100644
--- a/src/data/script_menu.h
+++ b/src/data/script_menu.h
@@ -1,23 +1,23 @@
// multichoice lists
static const struct MenuAction MultichoiceList_BrineyOnDewford[] =
{
- {gText_Petalburg},
- {gText_Slateport},
+ {COMPOUND_STRING("PETALBURG")},
+ {COMPOUND_STRING("SLATEPORT")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_EnterInfo[] =
{
- {gText_Enter2},
+ {COMPOUND_STRING("ENTER")},
{gText_Info2},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_ContestInfo[] =
{
- {gText_WhatsAContest},
- {gText_TypesOfContests},
- {gText_Ranks},
+ {COMPOUND_STRING("What's a CONTEST?")},
+ {COMPOUND_STRING("Types of CONTESTS")},
+ {COMPOUND_STRING("Ranks")},
{gText_Cancel2},
};
@@ -56,30 +56,30 @@ static const struct MenuAction MultichoiceList_RegisterMenu[] =
static const struct MenuAction MultichoiceList_Bike[] =
{
- {gText_Mach},
- {gText_Acro},
+ {COMPOUND_STRING("MACH")},
+ {COMPOUND_STRING("ACRO")},
};
static const struct MenuAction MultichoiceList_StatusInfo[] =
{
- {gText_Psn},
- {gText_Par},
- {gText_Slp},
- {gText_Brn},
- {gText_Frz},
+ {COMPOUND_STRING("PSN")},
+ {COMPOUND_STRING("PAR")},
+ {COMPOUND_STRING("SLP")},
+ {COMPOUND_STRING("BRN")},
+ {COMPOUND_STRING("FRZ")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_BrineyOffDewford[] =
{
- {gText_Dewford},
+ {COMPOUND_STRING("DEWFORD")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_ViewedPaintings[] =
{
- {gText_SawIt},
- {gText_NotYet},
+ {COMPOUND_STRING("Saw it")},
+ {COMPOUND_STRING("Not yet")},
};
static const struct MenuAction MultichoiceList_YesNoInfo2[] =
@@ -91,8 +91,8 @@ static const struct MenuAction MultichoiceList_YesNoInfo2[] =
static const struct MenuAction MultichoiceList_ChallengeInfo[] =
{
- {gText_Challenge},
- {gText_Info3},
+ {COMPOUND_STRING("CHALLENGE")},
+ {COMPOUND_STRING("INFO")},
{gText_Exit},
};
@@ -210,82 +210,82 @@ static const struct MenuAction MultichoiceList_Mechadoll5_Q3[] =
static const struct MenuAction MultichoiceList_VendingMachine[] =
{
- {gText_FreshWaterAndPrice},
- {gText_SodaPopAndPrice},
- {gText_LemonadeAndPrice},
+ {COMPOUND_STRING("FRESH WATER{CLEAR_TO 0x48}¥200")},
+ {COMPOUND_STRING("SODA POP{CLEAR_TO 0x48}¥300")},
+ {COMPOUND_STRING("LEMONADE{CLEAR_TO 0x48}¥350")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_MachBikeInfo[] =
{
- {gText_HowToRide},
- {gText_HowToTurn},
- {gText_SandySlopes},
+ {COMPOUND_STRING("HOW TO RIDE")},
+ {COMPOUND_STRING("HOW TO TURN")},
+ {COMPOUND_STRING("SANDY SLOPES")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_AcroBikeInfo[] =
{
- {gText_Wheelies},
- {gText_BunnyHops},
- {gText_Jump},
+ {COMPOUND_STRING("WHEELIES")},
+ {COMPOUND_STRING("BUNNY-HOPS")},
+ {COMPOUND_STRING("JUMP")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_Satisfaction[] =
{
- {gText_Satisfied},
- {gText_Dissatisfied},
+ {COMPOUND_STRING("Satisfied")},
+ {COMPOUND_STRING("Dissatisfied")},
};
static const struct MenuAction MultichoiceList_SternDeepSea[] =
{
- {gText_DeepSeaTooth},
- {gText_DeepSeaScale},
+ {COMPOUND_STRING("DEEPSEATOOTH")},
+ {COMPOUND_STRING("DEEPSEASCALE")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_UnusedAshVendor[] =
{
- {gText_BlueFlute2},
- {gText_YellowFlute2},
- {gText_RedFlute2},
- {gText_WhiteFlute2},
- {gText_BlackFlute2},
- {gText_GlassChair},
- {gText_GlassDesk},
+ {COMPOUND_STRING("BLUE FLUTE")},
+ {COMPOUND_STRING("YELLOW FLUTE")},
+ {COMPOUND_STRING("RED FLUTE")},
+ {COMPOUND_STRING("WHITE FLUTE")},
+ {COMPOUND_STRING("BLACK FLUTE")},
+ {COMPOUND_STRING("GLASS CHAIR")},
+ {COMPOUND_STRING("GLASS DESK")},
{gText_Cancel2},
};
static const struct MenuAction MultichoiceList_GameCornerDolls[] =
{
- {gText_TreeckoDollAndPrice},
- {gText_TorchicDollAndPrice},
- {gText_MudkipDollAndPrice},
+ {COMPOUND_STRING("TREECKO DOLL 1,000 COINS")},
+ {COMPOUND_STRING("TORCHIC DOLL 1,000 COINS")},
+ {COMPOUND_STRING("MUDKIP DOLL 1,000 COINS")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_GameCornerTMs[] =
{
- {gText_TM32AndPrice},
- {gText_TM29AndPrice},
- {gText_TM35AndPrice},
- {gText_TM24AndPrice},
- {gText_TM13AndPrice},
+ {COMPOUND_STRING("TM32{CLEAR_TO 0x48}1,500 COINS")},
+ {COMPOUND_STRING("TM29{CLEAR_TO 0x48}3,500 COINS")},
+ {COMPOUND_STRING("TM35{CLEAR_TO 0x48}4,000 COINS")},
+ {COMPOUND_STRING("TM24{CLEAR_TO 0x48}4,000 COINS")},
+ {COMPOUND_STRING("TM13{CLEAR_TO 0x48}4,000 COINS")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_GameCornerCoins[] =
{
- {gText_50CoinsAndPrice},
- {gText_500CoinsAndPrice},
+ {COMPOUND_STRING(" 50 COINS ¥1,000")},
+ {COMPOUND_STRING("500 COINS ¥10,000")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_HowsFishing[] =
{
- {gText_Excellent2},
- {gText_NotSoGood},
+ {COMPOUND_STRING("Excellent")},
+ {COMPOUND_STRING("Not so good")},
};
static const struct MenuAction MultichoiceList_SSTidalSlateportWithBF[] =
@@ -304,8 +304,8 @@ static const struct MenuAction MultichoiceList_SSTidalBattleFrontier[] =
static const struct MenuAction MultichoiceList_RightLeft[] =
{
- {gText_Right},
- {gText_Left},
+ {COMPOUND_STRING("Right")},
+ {COMPOUND_STRING("Left")},
};
static const struct MenuAction MultichoiceList_SSTidalSlateportNoBF[] =
@@ -452,8 +452,8 @@ static const struct MenuAction MultichoiceList_TourneyNoRecord[] =
static const struct MenuAction MultichoiceList_Tent[] =
{
- {gText_RedTent},
- {gText_BlueTent},
+ {COMPOUND_STRING("RED TENT")},
+ {COMPOUND_STRING("BLUE TENT")},
};
static const struct MenuAction MultichoiceList_LinkServicesNoBerry[] =
@@ -473,9 +473,9 @@ static const struct MenuAction MultichoiceList_YesNoInfo[] =
static const struct MenuAction MultichoiceList_BattleMode[] =
{
- {gText_SingleBattle},
- {gText_DoubleBattle},
- {gText_MultiBattle},
+ {COMPOUND_STRING("SINGLE BATTLE")},
+ {COMPOUND_STRING("DOUBLE BATTLE")},
+ {COMPOUND_STRING("MULTI BATTLE")},
{gText_Info2},
{gText_Exit},
};
@@ -506,46 +506,46 @@ static const struct MenuAction MultichoiceList_LinkServicesNoRecordBerry[] =
static const struct MenuAction MultichoiceList_WirelessMinigame[] =
{
- {gText_PokemonJump},
- {gText_DodrioBerryPicking},
+ {COMPOUND_STRING("POKéMON JUMP")},
+ {COMPOUND_STRING("DODRIO BERRY-PICKING")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_LinkLeader[] =
{
- {gText_JoinGroup},
- {gText_BecomeLeader},
+ {COMPOUND_STRING("JOIN GROUP")},
+ {COMPOUND_STRING("BECOME LEADER")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_ContestRank[] =
{
- {gText_NormalRank},
- {gText_SuperRank},
- {gText_HyperRank},
- {gText_MasterRank},
+ {COMPOUND_STRING("NORMAL RANK")},
+ {COMPOUND_STRING("SUPER RANK")},
+ {COMPOUND_STRING("HYPER RANK")},
+ {COMPOUND_STRING("MASTER RANK")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_FrontierItemChoose[] =
{
- {gText_BattleBag},
- {gText_HeldItem},
+ {COMPOUND_STRING("BATTLE BAG")},
+ {COMPOUND_STRING("HELD ITEM")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_LinkContestInfo[] =
{
- {gText_LinkContest},
- {gText_AboutE_Mode},
- {gText_AboutG_Mode},
+ {COMPOUND_STRING("LINK CONTEST")},
+ {COMPOUND_STRING("ABOUT E-MODE")},
+ {COMPOUND_STRING("ABOUT G-MODE")},
{gText_Cancel2},
};
static const struct MenuAction MultichoiceList_LinkContestMode[] =
{
- {gText_E_Mode},
- {gText_G_Mode},
+ {COMPOUND_STRING("E-MODE")},
+ {COMPOUND_STRING("G-MODE")},
{gText_Exit},
};
@@ -563,9 +563,9 @@ static const struct MenuAction MultichoiceList_ForcedStartMenu[] =
static const struct MenuAction MultichoiceList_FrontierGamblerBet[] =
{
- {gText_5BP},
- {gText_10BP},
- {gText_15BP},
+ {COMPOUND_STRING(" 5BP")},
+ {COMPOUND_STRING("10BP")},
+ {COMPOUND_STRING("15BP")},
{gText_Exit},
};
@@ -600,32 +600,32 @@ static const struct MenuAction MultichoiceList_UnusedSSTidal4[] =
static const struct MenuAction MultichoiceList_Fossil[] =
{
- {gText_ClawFossil},
- {gText_RootFossil},
+ {COMPOUND_STRING("CLAW FOSSIL")},
+ {COMPOUND_STRING("ROOT FOSSIL")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_YesNo[] =
{
{gText_Yes},
- {gText_No4},
+ {COMPOUND_STRING("NO")},
};
static const struct MenuAction MultichoiceList_FrontierRules[] =
{
- {gText_TwoStyles},
- {gText_Lv50_3},
- {gText_OpenLevel2},
- {gText_MonTypeAndNo},
- {gText_HoldItems},
+ {COMPOUND_STRING("TWO STYLES")},
+ {COMPOUND_STRING("LV. 50")},
+ {COMPOUND_STRING("OPEN LEVEL")},
+ {COMPOUND_STRING("{PKMN} TYPE & NO.")},
+ {COMPOUND_STRING("HOLD ITEMS")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_FrontierPassInfo[] =
{
- {gText_Symbols2},
- {gText_Record3},
- {gText_BattlePts},
+ {COMPOUND_STRING("SYMBOLS")},
+ {COMPOUND_STRING("RECORD")},
+ {COMPOUND_STRING("BATTLE PTS")},
{gText_Exit},
};
@@ -640,18 +640,18 @@ static const struct MenuAction MultichoiceList_BattleArenaRules[] =
static const struct MenuAction MultichoiceList_BattleTowerRules[] =
{
- {gText_TowerInfo},
- {gText_BattleMon},
- {gText_BattleSalon},
- {gText_MultiLink2},
+ {COMPOUND_STRING("TOWER INFO")},
+ {COMPOUND_STRING("BATTLE {PKMN}")},
+ {COMPOUND_STRING("BATTLE SALON")},
+ {COMPOUND_STRING("MULTI-LINK")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_BattleDomeRules[] =
{
- {gText_Matchup},
- {gText_TourneyTree},
- {gText_DoubleKO},
+ {COMPOUND_STRING("MATCHUP")},
+ {COMPOUND_STRING("TOURNEY TREE")},
+ {COMPOUND_STRING("DOUBLE KO")},
{gText_Exit},
};
@@ -661,7 +661,7 @@ static const struct MenuAction MultichoiceList_BattleFactoryRules[] =
{gText_SwapPartners},
{gText_SwapNumber},
{gText_SwapNotes},
- {gText_OpenLevel3},
+ {COMPOUND_STRING("OPEN LEVEL")},
{gText_Exit},
};
@@ -677,18 +677,18 @@ static const struct MenuAction MultichoiceList_BattlePalaceRules[] =
static const struct MenuAction MultichoiceList_BattlePyramidRules[] =
{
- {gText_PyramidPokemon},
- {gText_PyramidTrainers},
- {gText_PyramidMaze},
- {gText_BattleBag2},
+ {COMPOUND_STRING("PYRAMID: POKéMON")},
+ {COMPOUND_STRING("PYRAMID: TRAINERS")},
+ {COMPOUND_STRING("PYRAMID: MAZE")},
+ {COMPOUND_STRING("BATTLE BAG")},
{gText_Exit},
};
static const struct MenuAction MultichoiceList_BattlePikeRules[] =
{
- {gText_PokenavAndBag},
- {gText_HeldItems},
- {gText_PokemonOrder},
+ {COMPOUND_STRING("POKéNAV AND BAG")},
+ {COMPOUND_STRING("HELD ITEMS")},
+ {COMPOUND_STRING("POKéMON ORDER")},
{gText_Exit},
};
@@ -722,24 +722,24 @@ static const struct MenuAction MultichoiceList_GoOnRetire[] =
static const struct MenuAction MultichoiceList_TVLati[] =
{
- {gText_Red},
- {gText_Blue},
+ {COMPOUND_STRING("RED")},
+ {COMPOUND_STRING("BLUE")},
};
static const struct MenuAction MultichoiceList_BattleTowerFeelings[] =
{
- {gText_IllBattleNow},
- {gText_IWon},
- {gText_ILost},
- {gText_IWontTell},
+ {COMPOUND_STRING("I'll battle now!")},
+ {COMPOUND_STRING("I won!")},
+ {COMPOUND_STRING("I lost!")},
+ {COMPOUND_STRING("I won't tell.")},
};
static const struct MenuAction MultichoiceList_WheresRayquaza[] =
{
- {gText_CaveOfOrigin},
- {gText_MtPyre},
- {gText_SkyPillar},
- {gText_DontRemember},
+ {COMPOUND_STRING("CAVE OF ORIGIN")},
+ {COMPOUND_STRING("MT. PYRE")},
+ {COMPOUND_STRING("SKY PILLAR")},
+ {COMPOUND_STRING("Don't remember")},
};
static const struct MenuAction MultichoiceList_SlateportTentRules[] =
@@ -773,8 +773,8 @@ static const struct MenuAction MultichoiceList_TagMatchType[] =
static const struct MenuAction MultichoiceList_BerryPlot[] =
{
- {gText_Fertilize},
- {gText_PlantBerry},
+ {COMPOUND_STRING("FERTILIZE")},
+ {COMPOUND_STRING("PLANT BERRY")},
{gText_Exit},
};
diff --git a/src/data/trainers.h b/src/data/trainers.h
index ebc85e9cab..f8e0952716 100644
--- a/src/data/trainers.h
+++ b/src/data/trainers.h
@@ -15,7 +15,7 @@
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
#line 79
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 81
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 82
@@ -34,7 +34,7 @@
.trainerClass = TRAINER_CLASS_HIKER,
#line 87
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 89
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 90
@@ -66,7 +66,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 100
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 102
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 103
@@ -98,7 +98,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 113
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 115
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 116
@@ -141,7 +141,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 130
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 132
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 133
@@ -173,7 +173,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 143
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 145
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 146
@@ -205,7 +205,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 156
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 158
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 159
@@ -237,7 +237,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 169
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 171
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 172
@@ -269,7 +269,7 @@
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 182
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 184
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 185
@@ -301,9 +301,9 @@
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 195
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 196
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 197
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 198
@@ -390,7 +390,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 228
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 230
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 231
@@ -422,7 +422,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 241
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 243
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 244
@@ -467,7 +467,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 259
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 261
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 262
@@ -510,7 +510,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 276
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 278
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 279
@@ -553,9 +553,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 293
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 294
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 295
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 296
@@ -587,7 +587,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 306
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 308
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 309
@@ -619,7 +619,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 319
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 321
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 322
@@ -651,7 +651,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 332
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 334
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 335
@@ -694,7 +694,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 349
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 351
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 352
@@ -737,7 +737,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 366
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 368
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 369
@@ -791,7 +791,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 387
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 389
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 390
@@ -823,7 +823,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 400
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 402
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 403
@@ -866,7 +866,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 417
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 419
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 420
@@ -898,7 +898,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 430
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 432
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 433
@@ -930,7 +930,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 443
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 445
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 446
@@ -962,7 +962,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 456
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 458
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 459
@@ -1005,9 +1005,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 473
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 474
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 475
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 476
@@ -1039,9 +1039,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 486
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 487
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 488
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 489
@@ -1073,9 +1073,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 499
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 500
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 501
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 502
@@ -1107,7 +1107,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 512
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 514
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 515
@@ -1150,7 +1150,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AQUA_ADMIN,
#line 529
.trainerPic = TRAINER_PIC_AQUA_ADMIN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 531
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 532
@@ -1195,7 +1195,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 547
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 549
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 550
@@ -1227,9 +1227,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AQUA_ADMIN,
#line 560
.trainerPic = TRAINER_PIC_AQUA_ADMIN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 561
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 562
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 563
@@ -1272,9 +1272,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AQUA_ADMIN,
#line 577
.trainerPic = TRAINER_PIC_AQUA_ADMIN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 578
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 579
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 580
@@ -1317,7 +1317,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AQUA_LEADER,
#line 594
.trainerPic = TRAINER_PIC_AQUA_LEADER_ARCHIE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 596
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 597
@@ -1373,9 +1373,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 616
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 617
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 618
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 619
@@ -1407,9 +1407,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 629
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 630
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 631
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 632
@@ -1452,9 +1452,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 646
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 647
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 648
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 649
@@ -1508,7 +1508,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 667
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 669
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 670
@@ -1562,9 +1562,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 688
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 689
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 690
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 691
@@ -1607,9 +1607,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 705
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 706
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 707
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 708
@@ -1652,9 +1652,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 722
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 723
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 724
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 725
@@ -1708,9 +1708,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 743
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 744
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 745
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 746
@@ -1764,9 +1764,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 764
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 765
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 766
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 767
@@ -1820,7 +1820,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 785
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 787
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 788
@@ -1859,7 +1859,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 802
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 804
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 805
@@ -1934,7 +1934,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 835
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 837
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 838
@@ -1991,7 +1991,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 860
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 862
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 863
@@ -2030,7 +2030,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 877
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 879
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 880
@@ -2069,7 +2069,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 894
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 896
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 897
@@ -2108,7 +2108,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 911
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 913
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 914
@@ -2147,7 +2147,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_INTERVIEWER,
#line 928
.trainerPic = TRAINER_PIC_INTERVIEWER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 930
TRAINER_ENCOUNTER_MUSIC_INTERVIEWER,
#line 931
@@ -2190,7 +2190,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_INTERVIEWER,
#line 945
.trainerPic = TRAINER_PIC_INTERVIEWER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 947
TRAINER_ENCOUNTER_MUSIC_INTERVIEWER,
#line 948
@@ -2233,7 +2233,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_INTERVIEWER,
#line 962
.trainerPic = TRAINER_PIC_INTERVIEWER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 964
TRAINER_ENCOUNTER_MUSIC_INTERVIEWER,
#line 965
@@ -2276,7 +2276,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_INTERVIEWER,
#line 979
.trainerPic = TRAINER_PIC_INTERVIEWER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 981
TRAINER_ENCOUNTER_MUSIC_INTERVIEWER,
#line 982
@@ -2319,7 +2319,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_INTERVIEWER,
#line 996
.trainerPic = TRAINER_PIC_INTERVIEWER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 998
TRAINER_ENCOUNTER_MUSIC_INTERVIEWER,
#line 999
@@ -2362,7 +2362,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_INTERVIEWER,
#line 1013
.trainerPic = TRAINER_PIC_INTERVIEWER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1015
TRAINER_ENCOUNTER_MUSIC_INTERVIEWER,
#line 1016
@@ -2419,9 +2419,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1038
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1039
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1040
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1041
@@ -2464,9 +2464,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1055
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1056
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1057
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1058
@@ -2498,9 +2498,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1068
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1069
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1070
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1071
@@ -2532,9 +2532,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1081
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1082
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1083
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1084
@@ -2577,9 +2577,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1098
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1099
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1100
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1101
@@ -2622,9 +2622,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1115
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1116
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1117
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1118
@@ -2667,9 +2667,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 1132
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1133
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1134
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1135
@@ -2712,7 +2712,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1149
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1151
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1152
@@ -2751,7 +2751,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1166
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1168
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1169
@@ -2794,7 +2794,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1183
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1185
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1186
@@ -2826,7 +2826,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1196
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1198
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1199
@@ -2865,7 +2865,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1213
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1215
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1216
@@ -2904,7 +2904,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1230
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1232
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1233
@@ -2943,7 +2943,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 1247
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1249
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 1250
@@ -2982,7 +2982,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1264
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1266
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1267
@@ -3022,7 +3022,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1281
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1283
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1284
@@ -3062,7 +3062,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1298
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1300
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1301
@@ -3104,7 +3104,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1315
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1317
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1318
@@ -3143,7 +3143,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1331
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1333
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1334
@@ -3256,7 +3256,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1381
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1383
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1384
@@ -3312,7 +3312,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1403
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1405
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1406
@@ -3357,7 +3357,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1421
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1423
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1424
@@ -3413,7 +3413,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1443
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1445
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1446
@@ -3458,7 +3458,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1461
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1463
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1464
@@ -3503,7 +3503,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1479
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1481
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1482
@@ -3559,7 +3559,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1501
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1503
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1504
@@ -3626,7 +3626,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1527
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1529
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1530
@@ -3682,7 +3682,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1549
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1551
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1552
@@ -3738,7 +3738,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1571
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1573
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1574
@@ -3794,7 +3794,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1593
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1595
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1596
@@ -3850,7 +3850,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1615
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1617
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1618
@@ -3906,7 +3906,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1637
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1639
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1640
@@ -3951,9 +3951,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1655
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1656
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1657
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1658
@@ -3992,9 +3992,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1671
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1672
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1673
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1674
@@ -4034,9 +4034,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1688
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1689
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1690
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1691
@@ -4075,9 +4075,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1704
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1705
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1706
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1707
@@ -4154,9 +4154,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1738
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1739
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1740
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1741
@@ -4201,9 +4201,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1756
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1757
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1758
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1759
@@ -4259,9 +4259,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1778
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1779
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1780
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1781
@@ -4295,9 +4295,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1792
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1793
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1794
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1795
@@ -4331,9 +4331,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1806
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1807
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1808
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1809
@@ -4367,9 +4367,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1820
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1821
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1822
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1823
@@ -4425,9 +4425,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1842
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1843
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1844
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1845
@@ -4472,9 +4472,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1860
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1861
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1862
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1863
@@ -4530,9 +4530,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1882
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1883
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1884
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1885
@@ -4588,9 +4588,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1904
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1905
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1906
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1907
@@ -4646,9 +4646,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1926
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1927
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1928
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1929
@@ -4704,9 +4704,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 1948
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1949
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1950
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 1951
@@ -4762,9 +4762,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 1970
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1971
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1972
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 1973
@@ -4807,9 +4807,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 1987
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 1988
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 1989
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 1990
@@ -4852,9 +4852,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2004
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2005
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2006
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2007
@@ -4897,9 +4897,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2021
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2022
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2023
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2024
@@ -4931,9 +4931,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2034
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2035
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2036
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2037
@@ -4965,9 +4965,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2047
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2048
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2049
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2050
@@ -5010,9 +5010,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2064
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2065
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2066
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2067
@@ -5055,9 +5055,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2081
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2082
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2083
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2084
@@ -5100,9 +5100,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 2098
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2099
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2100
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2101
@@ -5156,9 +5156,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2119
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2120
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2121
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2122
@@ -5194,9 +5194,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2133
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2134
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2135
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2136
@@ -5259,7 +5259,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 2159
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2161
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 2162
@@ -5313,9 +5313,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2180
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2181
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2182
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2183
@@ -5356,9 +5356,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2196
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2197
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2198
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2199
@@ -5394,9 +5394,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2210
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2211
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2212
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2213
@@ -5432,9 +5432,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2224
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2225
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2226
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2227
@@ -5470,9 +5470,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2238
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2239
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2240
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2241
@@ -5508,9 +5508,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2252
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2253
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2254
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2255
@@ -5546,9 +5546,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 2266
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2267
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2268
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2269
@@ -5591,9 +5591,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2284
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2285
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2286
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2287
@@ -5625,9 +5625,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2297
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2298
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2299
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2300
@@ -5659,9 +5659,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2310
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2311
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2312
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2313
@@ -5693,9 +5693,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2323
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2324
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2325
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2326
@@ -5752,9 +5752,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2348
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2349
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2350
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2351
@@ -5786,9 +5786,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2361
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2362
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2363
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2364
@@ -5820,9 +5820,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2374
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2375
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2376
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2377
@@ -5896,9 +5896,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2406
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2407
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2408
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2409
@@ -5941,9 +5941,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2423
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2424
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2425
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2426
@@ -6000,9 +6000,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2448
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2449
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2450
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2451
@@ -6059,9 +6059,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2473
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2474
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2475
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2476
@@ -6118,9 +6118,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2498
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2499
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2500
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2501
@@ -6177,7 +6177,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 2523
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2525
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 2526
@@ -6213,9 +6213,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 2537
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2538
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2539
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 2540
@@ -6258,7 +6258,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 2554
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2556
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 2557
@@ -6294,7 +6294,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 2568
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2570
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 2571
@@ -6330,7 +6330,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 2582
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2584
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 2585
@@ -6366,7 +6366,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 2596
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2598
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 2599
@@ -6402,7 +6402,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 2610
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2612
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 2613
@@ -6445,7 +6445,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 2628
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2630
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2631
@@ -6477,9 +6477,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 2641
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2642
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2643
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 2644
@@ -6522,7 +6522,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 2658
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2660
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2661
@@ -6554,9 +6554,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 2671
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2672
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 2673
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 2674
@@ -6588,7 +6588,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 2684
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2686
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2687
@@ -6620,7 +6620,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 2697
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2699
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2700
@@ -6663,7 +6663,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 2714
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2716
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2717
@@ -6706,7 +6706,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 2731
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2733
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 2734
@@ -6749,7 +6749,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2748
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2750
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2751
@@ -6781,7 +6781,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2761
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2763
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2764
@@ -6813,7 +6813,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2774
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2776
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2777
@@ -6856,7 +6856,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2791
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2793
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2794
@@ -6910,7 +6910,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2812
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2814
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2815
@@ -6942,7 +6942,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2825
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2827
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2828
@@ -6974,7 +6974,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2838
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2840
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2841
@@ -7006,7 +7006,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2851
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2853
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2854
@@ -7049,7 +7049,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2868
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2870
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2871
@@ -7092,7 +7092,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2885
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2887
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2888
@@ -7124,7 +7124,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2898
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2900
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2901
@@ -7156,7 +7156,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2911
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2913
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2914
@@ -7188,7 +7188,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2924
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2926
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2927
@@ -7220,7 +7220,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2937
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2939
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2940
@@ -7274,7 +7274,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2958
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2960
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2961
@@ -7306,7 +7306,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2971
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2973
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2974
@@ -7338,7 +7338,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 2984
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 2986
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 2987
@@ -7381,7 +7381,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3001
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3003
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3004
@@ -7424,7 +7424,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3018
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3020
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3021
@@ -7456,7 +7456,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3031
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3033
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3034
@@ -7488,7 +7488,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3044
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3046
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3047
@@ -7520,7 +7520,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3057
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3059
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3060
@@ -7552,7 +7552,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3070
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3072
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3073
@@ -7606,7 +7606,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3091
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3093
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3094
@@ -7649,7 +7649,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3108
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3110
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3111
@@ -7681,7 +7681,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3121
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3123
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3124
@@ -7713,7 +7713,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3134
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3136
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3137
@@ -7756,7 +7756,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 3151
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3153
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 3154
@@ -7799,7 +7799,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3168
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3170
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3171
@@ -7831,7 +7831,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3181
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3183
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3184
@@ -7874,7 +7874,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3198
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3200
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3201
@@ -7906,7 +7906,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3211
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3213
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3214
@@ -7949,7 +7949,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3228
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3230
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3231
@@ -7981,7 +7981,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3241
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3243
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3244
@@ -8013,7 +8013,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3254
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3256
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3257
@@ -8056,7 +8056,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3271
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3273
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3274
@@ -8110,7 +8110,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3292
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3294
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3295
@@ -8177,7 +8177,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3317
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3319
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3320
@@ -8220,7 +8220,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3334
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3336
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3337
@@ -8252,7 +8252,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 3347
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3349
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3350
@@ -8284,7 +8284,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3360
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3362
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3363
@@ -8340,9 +8340,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 3384
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3385
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 3386
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 3387
@@ -8385,7 +8385,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 3401
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3403
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 3404
@@ -8417,7 +8417,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3414
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3416
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3417
@@ -8460,7 +8460,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3431
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3433
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3434
@@ -8503,7 +8503,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3448
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3450
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3451
@@ -8546,7 +8546,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3465
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3467
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3468
@@ -8600,7 +8600,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3486
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3488
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3489
@@ -8654,7 +8654,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3507
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3509
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3510
@@ -8708,7 +8708,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 3528
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3530
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 3531
@@ -8762,7 +8762,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3549
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3551
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3552
@@ -8794,7 +8794,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3562
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3564
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3565
@@ -8837,7 +8837,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3579
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3581
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3582
@@ -8869,7 +8869,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3592
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3594
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3595
@@ -8901,7 +8901,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3605
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3607
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3608
@@ -8933,7 +8933,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3618
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3620
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3621
@@ -8976,7 +8976,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3635
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3637
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3638
@@ -9019,7 +9019,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3652
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3654
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3655
@@ -9062,7 +9062,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3669
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3671
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3672
@@ -9105,7 +9105,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 3686
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3688
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 3689
@@ -9148,7 +9148,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3703
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3705
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3706
@@ -9187,7 +9187,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3720
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3722
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3723
@@ -9262,7 +9262,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3753
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3755
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3756
@@ -9294,7 +9294,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3766
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3768
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3769
@@ -9337,7 +9337,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3783
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3785
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3786
@@ -9369,7 +9369,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3796
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3798
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3799
@@ -9412,9 +9412,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 3813
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3814
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 3815
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 3816
@@ -9446,7 +9446,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3826
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3828
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3829
@@ -9478,7 +9478,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3839
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3841
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3842
@@ -9521,7 +9521,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3856
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3858
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3859
@@ -9564,7 +9564,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3873
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3875
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3876
@@ -9618,7 +9618,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 3894
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3896
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 3897
@@ -9672,7 +9672,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 3915
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3917
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 3918
@@ -9704,7 +9704,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 3928
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3930
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 3931
@@ -9758,7 +9758,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 3949
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3951
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 3952
@@ -9812,7 +9812,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 3970
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3972
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 3973
@@ -9866,7 +9866,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 3991
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 3993
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 3994
@@ -9909,7 +9909,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 4008
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4010
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 4011
@@ -9963,7 +9963,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 4029
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4031
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 4032
@@ -10017,7 +10017,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 4050
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4052
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 4053
@@ -10082,7 +10082,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 4075
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4077
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 4078
@@ -10160,7 +10160,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4104
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4106
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4107
@@ -10196,7 +10196,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4118
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4120
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4121
@@ -10228,7 +10228,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4131
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4133
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4134
@@ -10260,7 +10260,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4144
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4146
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4147
@@ -10292,7 +10292,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4157
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4159
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4160
@@ -10346,7 +10346,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4178
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4180
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4181
@@ -10389,7 +10389,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4195
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4197
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4198
@@ -10421,7 +10421,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4208
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4210
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4211
@@ -10464,7 +10464,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4225
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4227
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4228
@@ -10507,7 +10507,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4242
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4244
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4245
@@ -10550,7 +10550,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4259
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4261
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4262
@@ -10593,9 +10593,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4276
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4277
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4278
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4279
@@ -10631,9 +10631,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4290
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4291
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4292
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4293
@@ -10665,9 +10665,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4303
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4304
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4305
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4306
@@ -10699,9 +10699,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4316
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4317
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4318
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4319
@@ -10733,9 +10733,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4329
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4330
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4331
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4332
@@ -10789,9 +10789,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4350
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4351
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4352
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4353
@@ -10834,9 +10834,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4367
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4368
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4369
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4370
@@ -10879,9 +10879,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4384
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4385
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4386
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4387
@@ -10924,9 +10924,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4401
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4402
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4403
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4404
@@ -10969,9 +10969,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4418
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4419
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4420
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4421
@@ -11014,9 +11014,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 4435
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4436
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4437
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 4438
@@ -11059,7 +11059,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4452
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4454
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4455
@@ -11091,7 +11091,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4465
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4467
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4468
@@ -11134,7 +11134,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4482
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4484
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4485
@@ -11166,7 +11166,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4495
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4497
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4498
@@ -11198,7 +11198,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4508
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4510
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4511
@@ -11255,7 +11255,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4533
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4535
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4536
@@ -11311,7 +11311,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 4557
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4559
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 4560
@@ -11386,7 +11386,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_ELITE_FOUR,
#line 4590
.trainerPic = TRAINER_PIC_ELITE_FOUR_SIDNEY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4592
TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR,
#line 4593
@@ -11396,7 +11396,6 @@ F_TRAINER_FEMALE |
#line 4595
.aiFlags = AI_FLAG_BASIC_TRAINER | AI_FLAG_FORCE_SETUP_FIRST_TURN,
#line 4596
- .mugshotEnabled = TRUE,
.mugshotColor = MUGSHOT_COLOR_PURPLE,
.partySize = 5,
.party = (const struct TrainerMon[])
@@ -11504,9 +11503,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_ELITE_FOUR,
#line 4641
.trainerPic = TRAINER_PIC_ELITE_FOUR_PHOEBE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4642
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4643
TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR,
#line 4644
@@ -11516,7 +11515,6 @@ F_TRAINER_FEMALE |
#line 4646
.aiFlags = AI_FLAG_BASIC_TRAINER,
#line 4647
- .mugshotEnabled = TRUE,
.mugshotColor = MUGSHOT_COLOR_GREEN,
.partySize = 5,
.party = (const struct TrainerMon[])
@@ -11624,9 +11622,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_ELITE_FOUR,
#line 4692
.trainerPic = TRAINER_PIC_ELITE_FOUR_GLACIA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4693
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4694
TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR,
#line 4695
@@ -11636,7 +11634,6 @@ F_TRAINER_FEMALE |
#line 4697
.aiFlags = AI_FLAG_BASIC_TRAINER,
#line 4698
- .mugshotEnabled = TRUE,
.mugshotColor = MUGSHOT_COLOR_PINK,
.partySize = 5,
.party = (const struct TrainerMon[])
@@ -11744,7 +11741,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_ELITE_FOUR,
#line 4743
.trainerPic = TRAINER_PIC_ELITE_FOUR_DRAKE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4745
TRAINER_ENCOUNTER_MUSIC_ELITE_FOUR,
#line 4746
@@ -11754,7 +11751,6 @@ F_TRAINER_FEMALE |
#line 4748
.aiFlags = AI_FLAG_BASIC_TRAINER,
#line 4749
- .mugshotEnabled = TRUE,
.mugshotColor = MUGSHOT_COLOR_BLUE,
.partySize = 5,
.party = (const struct TrainerMon[])
@@ -11862,9 +11858,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 4794
.trainerPic = TRAINER_PIC_LEADER_ROXANNE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4795
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4796
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 4797
@@ -11943,7 +11939,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 4828
.trainerPic = TRAINER_PIC_LEADER_BRAWLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4830
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 4831
@@ -12022,7 +12018,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 4862
.trainerPic = TRAINER_PIC_LEADER_WATTSON,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4864
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 4865
@@ -12119,9 +12115,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 4904
.trainerPic = TRAINER_PIC_LEADER_FLANNERY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4905
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4906
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 4907
@@ -12218,7 +12214,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 4946
.trainerPic = TRAINER_PIC_LEADER_NORMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4948
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 4949
@@ -12315,9 +12311,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 4988
.trainerPic = TRAINER_PIC_LEADER_WINONA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 4989
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 4990
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 4991
@@ -12432,7 +12428,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 5038
.trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5040
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 5041
@@ -12531,7 +12527,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 5080
.trainerPic = TRAINER_PIC_LEADER_JUAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5082
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5083
@@ -12646,7 +12642,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5130
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5132
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5133
@@ -12678,7 +12674,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5143
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5145
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5146
@@ -12710,7 +12706,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5156
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5158
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5159
@@ -12764,7 +12760,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5177
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5179
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5180
@@ -12807,7 +12803,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5194
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5196
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5197
@@ -12850,7 +12846,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5211
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5213
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5214
@@ -12893,7 +12889,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5228
.trainerPic = TRAINER_PIC_SCHOOL_KID_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5230
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5231
@@ -12947,9 +12943,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5249
.trainerPic = TRAINER_PIC_SCHOOL_KID_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5250
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5251
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 5252
@@ -12981,9 +12977,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5262
.trainerPic = TRAINER_PIC_SCHOOL_KID_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5263
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5264
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 5265
@@ -13026,9 +13022,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5279
.trainerPic = TRAINER_PIC_SCHOOL_KID_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5280
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5281
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 5282
@@ -13071,9 +13067,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5296
.trainerPic = TRAINER_PIC_SCHOOL_KID_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5297
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5298
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 5299
@@ -13116,9 +13112,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5313
.trainerPic = TRAINER_PIC_SCHOOL_KID_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5314
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5315
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 5316
@@ -13161,9 +13157,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SCHOOL_KID,
#line 5330
.trainerPic = TRAINER_PIC_SCHOOL_KID_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5331
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5332
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 5333
@@ -13206,7 +13202,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 5347
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5349
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5350
@@ -13263,7 +13259,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 5372
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5374
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5375
@@ -13319,7 +13315,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 5396
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5398
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5399
@@ -13375,7 +13371,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 5420
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5422
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5423
@@ -13431,7 +13427,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 5444
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5446
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5447
@@ -13487,7 +13483,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 5468
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5470
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5471
@@ -13543,7 +13539,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_WINSTRATE,
#line 5492
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5494
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5495
@@ -13590,7 +13586,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5509
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5511
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5512
@@ -13624,7 +13620,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5522
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5524
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5525
@@ -13765,7 +13761,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5579
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5581
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5582
@@ -13799,7 +13795,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5592
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5594
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5595
@@ -13833,7 +13829,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5605
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5607
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5608
@@ -13867,7 +13863,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5618
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5620
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5621
@@ -13901,9 +13897,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_WINSTRATE,
#line 5631
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5632
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5633
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5634
@@ -13937,9 +13933,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5644
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5645
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5646
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5647
@@ -13973,9 +13969,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5657
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5658
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5659
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5660
@@ -14035,9 +14031,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5678
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5679
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5680
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5681
@@ -14084,9 +14080,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5695
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5696
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5697
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5698
@@ -14133,9 +14129,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5712
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5713
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5714
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5715
@@ -14182,9 +14178,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5729
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5730
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5731
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5732
@@ -14231,9 +14227,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 5746
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5747
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5748
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 5749
@@ -14280,7 +14276,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5763
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5765
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5766
@@ -14312,7 +14308,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5776
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5778
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5779
@@ -14351,7 +14347,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5793
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5795
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5796
@@ -14390,7 +14386,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5810
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5812
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5813
@@ -14429,7 +14425,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5827
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5829
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5830
@@ -14468,9 +14464,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_WINSTRATE,
#line 5844
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5845
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5846
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5847
@@ -14509,9 +14505,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5861
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5862
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5863
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5864
@@ -14554,9 +14550,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5878
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5879
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5880
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5881
@@ -14599,9 +14595,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5895
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5896
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5897
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5898
@@ -14644,9 +14640,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5912
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5913
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5914
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5915
@@ -14689,9 +14685,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 5929
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5930
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 5931
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 5932
@@ -14734,7 +14730,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 5946
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5948
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5949
@@ -14766,7 +14762,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 5959
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5961
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5962
@@ -14809,7 +14805,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 5976
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5978
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5979
@@ -14845,7 +14841,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 5990
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 5992
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 5993
@@ -14888,7 +14884,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6007
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6009
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6010
@@ -14920,7 +14916,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6020
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6022
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6023
@@ -14977,7 +14973,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 6045
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6047
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 6048
@@ -15036,9 +15032,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 6071
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6072
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6073
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 6074
@@ -15097,7 +15093,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6097
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6099
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6100
@@ -15129,7 +15125,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6110
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6112
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6113
@@ -15161,7 +15157,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6123
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6125
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6126
@@ -15193,7 +15189,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6136
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6138
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6139
@@ -15236,7 +15232,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6153
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6155
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6156
@@ -15290,7 +15286,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6174
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6176
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6177
@@ -15344,7 +15340,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6195
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6197
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6198
@@ -15387,7 +15383,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6212
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6214
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6215
@@ -15430,7 +15426,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6229
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6231
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6232
@@ -15473,7 +15469,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CHAMPION,
#line 6246
.trainerPic = TRAINER_PIC_CHAMPION_WALLACE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6248
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6249
@@ -15483,7 +15479,6 @@ F_TRAINER_FEMALE |
#line 6251
.aiFlags = AI_FLAG_BASIC_TRAINER,
#line 6252
- .mugshotEnabled = TRUE,
.mugshotColor = MUGSHOT_COLOR_YELLOW,
.partySize = 6,
.party = (const struct TrainerMon[])
@@ -15609,7 +15604,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6305
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6307
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6308
@@ -15663,7 +15658,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6326
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6328
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6329
@@ -15717,7 +15712,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6347
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6349
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6350
@@ -15771,7 +15766,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6368
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6370
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6371
@@ -15825,7 +15820,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6389
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6391
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6392
@@ -15857,7 +15852,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6402
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6404
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6405
@@ -15922,7 +15917,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6427
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6429
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6430
@@ -15954,7 +15949,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6440
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6442
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6443
@@ -15997,7 +15992,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6457
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6459
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6460
@@ -16029,7 +16024,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6470
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6472
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6473
@@ -16072,7 +16067,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6487
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6489
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6490
@@ -16126,7 +16121,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6508
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6510
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6511
@@ -16191,7 +16186,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6533
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6535
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6536
@@ -16256,7 +16251,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6558
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6560
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6561
@@ -16321,7 +16316,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 6583
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6585
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 6586
@@ -16408,7 +16403,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6616
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6618
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6619
@@ -16462,7 +16457,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6637
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6639
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6640
@@ -16505,7 +16500,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6654
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6656
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6657
@@ -16537,7 +16532,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6667
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6669
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6670
@@ -16569,7 +16564,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6680
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6682
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6683
@@ -16601,7 +16596,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6693
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6695
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6696
@@ -16633,7 +16628,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6706
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6708
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6709
@@ -16665,9 +16660,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6719
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6720
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6721
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6722
@@ -16699,9 +16694,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6732
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6733
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6734
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6735
@@ -16755,9 +16750,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6753
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6754
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6755
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6756
@@ -16789,9 +16784,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6766
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6767
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6768
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6769
@@ -16823,9 +16818,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6779
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6780
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6781
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6782
@@ -16857,9 +16852,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6792
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6793
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6794
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6795
@@ -16891,7 +16886,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6805
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6807
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6808
@@ -16923,7 +16918,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6818
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6820
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6821
@@ -16955,7 +16950,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6831
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6833
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6834
@@ -16987,7 +16982,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6844
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6846
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6847
@@ -17019,7 +17014,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6857
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6859
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6860
@@ -17051,9 +17046,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6870
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6871
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6872
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6873
@@ -17085,9 +17080,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6883
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6884
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6885
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6886
@@ -17119,9 +17114,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6896
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6897
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6898
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6899
@@ -17153,9 +17148,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6909
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6910
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6911
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6912
@@ -17187,9 +17182,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6922
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6923
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 6924
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 6925
@@ -17221,7 +17216,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6935
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6937
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 6938
@@ -17264,7 +17259,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 6952
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6954
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 6955
@@ -17307,7 +17302,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6969
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6971
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 6972
@@ -17339,7 +17334,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6982
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 6984
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 6985
@@ -17382,7 +17377,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 6999
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7001
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7002
@@ -17425,7 +17420,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7016
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7018
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7019
@@ -17457,7 +17452,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7029
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7031
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7032
@@ -17489,7 +17484,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7042
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7044
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7045
@@ -17521,7 +17516,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7055
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7057
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7058
@@ -17553,9 +17548,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7068
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7069
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7070
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7071
@@ -17587,9 +17582,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7081
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7082
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7083
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7084
@@ -17632,9 +17627,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7098
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7099
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7100
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7101
@@ -17666,9 +17661,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7111
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7112
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7113
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7114
@@ -17700,9 +17695,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7124
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7125
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7126
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7127
@@ -17745,9 +17740,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7141
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7142
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7143
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7144
@@ -17779,9 +17774,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7154
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7155
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7156
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7157
@@ -17813,9 +17808,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7167
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7168
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7169
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7170
@@ -17847,9 +17842,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 7180
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7181
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7182
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 7183
@@ -17881,7 +17876,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DRAGON_TAMER,
#line 7193
.trainerPic = TRAINER_PIC_DRAGON_TAMER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7195
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7196
@@ -17924,7 +17919,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DRAGON_TAMER,
#line 7210
.trainerPic = TRAINER_PIC_DRAGON_TAMER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7212
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7213
@@ -17967,7 +17962,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DRAGON_TAMER,
#line 7227
.trainerPic = TRAINER_PIC_DRAGON_TAMER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7229
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7230
@@ -18010,7 +18005,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DRAGON_TAMER,
#line 7244
.trainerPic = TRAINER_PIC_DRAGON_TAMER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7246
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7247
@@ -18064,7 +18059,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DRAGON_TAMER,
#line 7265
.trainerPic = TRAINER_PIC_DRAGON_TAMER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7267
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7268
@@ -18120,7 +18115,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DRAGON_TAMER,
#line 7286
.trainerPic = TRAINER_PIC_DRAGON_TAMER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7288
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7289
@@ -18159,7 +18154,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7303
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7305
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7306
@@ -18191,7 +18186,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7316
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7318
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7319
@@ -18234,7 +18229,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7333
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7335
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7336
@@ -18266,7 +18261,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7346
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7348
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7349
@@ -18320,7 +18315,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7367
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7369
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7370
@@ -18352,7 +18347,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7380
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7382
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7383
@@ -18395,7 +18390,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7397
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7399
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7400
@@ -18438,7 +18433,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7414
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7416
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7417
@@ -18481,7 +18476,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7431
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7433
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7434
@@ -18513,7 +18508,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7444
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7446
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7447
@@ -18567,7 +18562,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7465
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7467
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7468
@@ -18610,7 +18605,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7482
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7484
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7485
@@ -18653,7 +18648,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7499
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7501
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7502
@@ -18696,7 +18691,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7516
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7518
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7519
@@ -18739,7 +18734,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7533
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7535
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7536
@@ -18782,7 +18777,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7550
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7552
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7553
@@ -18825,7 +18820,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 7567
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7569
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7570
@@ -18857,7 +18852,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7580
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7582
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7583
@@ -18889,7 +18884,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7593
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7595
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7596
@@ -18932,9 +18927,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 7610
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7611
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7612
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 7613
@@ -18987,9 +18982,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 7631
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7632
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7633
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 7634
@@ -19019,7 +19014,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7643
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7645
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7646
@@ -19092,7 +19087,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7675
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7677
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7678
@@ -19133,7 +19128,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7691
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7693
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7694
@@ -19221,7 +19216,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7728
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7730
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7731
@@ -19309,7 +19304,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7765
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7767
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7768
@@ -19395,7 +19390,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 7800
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7802
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 7803
@@ -19485,9 +19480,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7837
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7838
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7839
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7840
@@ -19519,9 +19514,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7850
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7851
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7852
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7853
@@ -19553,9 +19548,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7863
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7864
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7865
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7866
@@ -19598,9 +19593,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7880
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7881
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7882
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7883
@@ -19632,9 +19627,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7893
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7894
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7895
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7896
@@ -19666,9 +19661,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7906
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7907
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7908
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7909
@@ -19711,9 +19706,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7923
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7924
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7925
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7926
@@ -19756,9 +19751,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7940
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7941
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7942
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7943
@@ -19801,9 +19796,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 7957
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7958
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7959
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 7960
@@ -19846,9 +19841,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 7974
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7975
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7976
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 7977
@@ -19887,9 +19882,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 7991
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 7992
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 7993
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 7994
@@ -19932,9 +19927,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 8008
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8009
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8010
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 8011
@@ -19973,9 +19968,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 8025
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8026
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8027
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 8028
@@ -20014,9 +20009,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 8042
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8043
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8044
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 8045
@@ -20055,9 +20050,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 8059
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8060
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8061
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 8062
@@ -20114,9 +20109,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 8084
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8085
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8086
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 8087
@@ -20173,9 +20168,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8109
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8110
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8111
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8112
@@ -20218,9 +20213,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8126
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8127
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8128
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8129
@@ -20252,9 +20247,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8139
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8140
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8141
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8142
@@ -20286,9 +20281,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8152
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8153
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8154
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8155
@@ -20331,9 +20326,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8169
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8170
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8171
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8172
@@ -20365,9 +20360,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8182
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8183
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8184
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8185
@@ -20410,9 +20405,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8199
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8200
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8201
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8202
@@ -20444,9 +20439,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8212
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8213
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8214
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8215
@@ -20500,9 +20495,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8233
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8234
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8235
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8236
@@ -20534,9 +20529,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8246
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8247
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8248
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8249
@@ -20568,9 +20563,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8259
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8260
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8261
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8262
@@ -20602,9 +20597,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8272
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8273
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8274
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8275
@@ -20636,9 +20631,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8285
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8286
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8287
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8288
@@ -20681,9 +20676,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8302
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8303
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8304
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8305
@@ -20715,9 +20710,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8315
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8316
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8317
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8318
@@ -20760,9 +20755,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8332
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8333
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8334
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8335
@@ -20794,9 +20789,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8345
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8346
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8347
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8348
@@ -20828,9 +20823,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8358
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8359
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8360
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8361
@@ -20862,9 +20857,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8371
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8372
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8373
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8374
@@ -20907,9 +20902,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8388
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8389
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8390
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8391
@@ -20941,9 +20936,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8401
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8402
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8403
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8404
@@ -20986,9 +20981,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8418
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8419
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8420
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8421
@@ -21031,9 +21026,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8435
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8436
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8437
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8438
@@ -21076,9 +21071,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8452
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8453
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8454
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8455
@@ -21110,9 +21105,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8465
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8466
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8467
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8468
@@ -21144,9 +21139,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8478
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8479
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8480
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8481
@@ -21178,9 +21173,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8491
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8492
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8493
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8494
@@ -21223,9 +21218,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 8508
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8509
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8510
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 8511
@@ -21279,9 +21274,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8529
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8530
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8531
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8532
@@ -21338,9 +21333,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8554
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8555
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8556
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8557
@@ -21397,9 +21392,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8579
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8580
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8581
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8582
@@ -21442,9 +21437,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8596
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8597
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8598
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8599
@@ -21487,9 +21482,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8613
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8614
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8615
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8616
@@ -21532,9 +21527,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8630
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8631
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8632
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8633
@@ -21588,7 +21583,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 8651
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8653
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 8654
@@ -21627,9 +21622,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8668
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8669
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8670
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8671
@@ -21672,9 +21667,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8685
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8686
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8687
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8688
@@ -21728,9 +21723,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8706
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8707
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8708
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8709
@@ -21784,9 +21779,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8727
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8728
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8729
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8730
@@ -21840,9 +21835,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 8748
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8749
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 8750
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 8751
@@ -21896,7 +21891,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8769
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8771
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8772
@@ -21939,7 +21934,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8786
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8788
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8789
@@ -21982,7 +21977,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8803
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8805
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8806
@@ -22025,7 +22020,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8820
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8822
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8823
@@ -22068,7 +22063,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8837
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8839
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8840
@@ -22111,7 +22106,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8854
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8856
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8857
@@ -22164,7 +22159,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8875
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8877
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8878
@@ -22207,7 +22202,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8892
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8894
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8895
@@ -22264,7 +22259,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 8917
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8919
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 8920
@@ -22321,7 +22316,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 8942
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8944
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 8945
@@ -22364,7 +22359,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 8959
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8961
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 8962
@@ -22396,7 +22391,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 8972
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8974
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 8975
@@ -22439,7 +22434,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 8989
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 8991
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 8992
@@ -22493,7 +22488,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9010
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9012
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9013
@@ -22536,7 +22531,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9027
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9029
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9030
@@ -22590,7 +22585,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9048
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9050
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9051
@@ -22633,7 +22628,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9065
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9067
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9068
@@ -22687,7 +22682,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9086
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9088
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9089
@@ -22741,7 +22736,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9107
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9109
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9110
@@ -22795,7 +22790,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9128
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9130
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9131
@@ -22849,7 +22844,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 9149
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9151
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 9152
@@ -22881,9 +22876,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 9162
.trainerPic = TRAINER_PIC_POKEFAN_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9163
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9164
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 9165
@@ -22944,9 +22939,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER_2,
#line 9187
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9188
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9189
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 9190
@@ -22980,7 +22975,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 9201
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9203
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9204
@@ -23019,9 +23014,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 9218
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9219
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9220
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9221
@@ -23060,7 +23055,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 9235
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9237
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 9238
@@ -23103,7 +23098,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9252
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9254
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9255
@@ -23146,9 +23141,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 9269
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9270
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9271
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 9272
@@ -23189,9 +23184,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 9287
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9288
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9289
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 9290
@@ -23234,7 +23229,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 9304
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9306
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9307
@@ -23266,7 +23261,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 9317
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9319
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 9320
@@ -23309,7 +23304,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 9334
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9336
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9337
@@ -23352,7 +23347,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 9351
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9353
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9354
@@ -23395,7 +23390,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_MAGMA_ADMIN,
#line 9368
.trainerPic = TRAINER_PIC_MAGMA_ADMIN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9370
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 9371
@@ -23449,7 +23444,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 9389
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9391
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9392
@@ -23492,7 +23487,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 9406
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9408
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9409
@@ -23535,7 +23530,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 9423
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9425
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9426
@@ -23578,7 +23573,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COLLECTOR,
#line 9440
.trainerPic = TRAINER_PIC_COLLECTOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9442
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 9443
@@ -23621,7 +23616,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9457
.trainerPic = TRAINER_PIC_WALLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9459
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9460
@@ -23734,7 +23729,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9507
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9509
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9510
@@ -23766,7 +23761,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9520
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9522
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9523
@@ -23820,7 +23815,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9541
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9543
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9544
@@ -23874,7 +23869,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9562
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9564
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9565
@@ -23906,7 +23901,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9575
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9577
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9578
@@ -23960,7 +23955,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9596
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9598
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9599
@@ -24014,7 +24009,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9617
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9619
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9620
@@ -24046,7 +24041,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9630
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9632
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9633
@@ -24100,7 +24095,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9651
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9653
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9654
@@ -24154,9 +24149,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9672
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9673
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9674
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9675
@@ -24188,9 +24183,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9685
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9686
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9687
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9688
@@ -24244,9 +24239,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9706
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9707
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9708
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9709
@@ -24300,9 +24295,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9727
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9728
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9729
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9730
@@ -24334,9 +24329,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9740
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9741
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9742
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9743
@@ -24390,9 +24385,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9761
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9762
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9763
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9764
@@ -24446,9 +24441,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9782
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9783
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9784
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9785
@@ -24480,9 +24475,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9795
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9796
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9797
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9798
@@ -24536,9 +24531,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 9816
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9817
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 9818
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 9819
@@ -24592,7 +24587,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 9837
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9839
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9840
@@ -24679,7 +24674,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 9870
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9872
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9873
@@ -24711,7 +24706,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 9883
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9885
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 9886
@@ -24768,7 +24763,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 9908
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9910
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9911
@@ -24855,7 +24850,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 9941
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9943
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9944
@@ -24942,7 +24937,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 9974
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 9976
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 9977
@@ -25029,7 +25024,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 10007
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10009
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 10010
@@ -25116,9 +25111,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 10040
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10041
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10042
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 10043
@@ -25205,9 +25200,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 10073
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10074
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10075
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10076
@@ -25252,7 +25247,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 10091
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10093
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 10094
@@ -25284,9 +25279,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 10104
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10105
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10106
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 10107
@@ -25373,9 +25368,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 10137
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10138
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10139
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 10140
@@ -25462,9 +25457,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 10170
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10171
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10172
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 10173
@@ -25551,9 +25546,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 10203
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10204
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10205
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 10206
@@ -25640,7 +25635,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10236
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10238
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10239
@@ -25674,7 +25669,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10250
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10252
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10253
@@ -25730,7 +25725,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10272
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10274
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10275
@@ -25764,7 +25759,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10286
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10288
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10289
@@ -25798,7 +25793,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10300
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10302
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10303
@@ -25832,7 +25827,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10314
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10316
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10317
@@ -25866,7 +25861,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10328
.trainerPic = TRAINER_PIC_POKEMON_RANGER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10330
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10331
@@ -25911,9 +25906,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10346
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10347
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10348
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10349
@@ -25958,9 +25953,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10364
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10365
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10366
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10367
@@ -26016,9 +26011,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10386
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10387
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10388
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10389
@@ -26063,9 +26058,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10404
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10405
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10406
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10407
@@ -26110,9 +26105,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10422
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10423
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10424
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10425
@@ -26157,9 +26152,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10440
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10441
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10442
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10443
@@ -26204,9 +26199,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_RANGER,
#line 10458
.trainerPic = TRAINER_PIC_POKEMON_RANGER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10459
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10460
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10461
@@ -26251,7 +26246,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 10476
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10478
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 10479
@@ -26283,7 +26278,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 10489
.trainerPic = TRAINER_PIC_AQUA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10491
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 10492
@@ -26326,9 +26321,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10506
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10507
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10508
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 10509
@@ -26371,9 +26366,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 10523
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10524
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10525
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 10526
@@ -26416,7 +26411,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10540
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10542
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10543
@@ -26459,7 +26454,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 10557
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10559
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 10560
@@ -26502,7 +26497,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 10574
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10576
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 10577
@@ -26534,9 +26529,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 10587
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10588
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10589
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 10590
@@ -26568,7 +26563,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 10600
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10602
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 10603
@@ -26600,9 +26595,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 10613
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10614
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10615
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 10616
@@ -26634,7 +26629,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 10626
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10628
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 10629
@@ -26666,9 +26661,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 10639
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10640
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10641
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10642
@@ -26724,7 +26719,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 10662
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10664
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 10665
@@ -26756,7 +26751,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10675
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10677
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10678
@@ -26788,7 +26783,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 10688
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10690
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 10691
@@ -26820,9 +26815,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 10701
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10702
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10703
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 10704
@@ -26854,7 +26849,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 10714
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10716
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 10717
@@ -26886,9 +26881,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HEX_MANIAC,
#line 10727
.trainerPic = TRAINER_PIC_HEX_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10728
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10729
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 10730
@@ -26920,7 +26915,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 10740
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10742
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 10743
@@ -26952,7 +26947,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 10753
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10755
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 10756
@@ -26984,9 +26979,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10766
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10767
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10768
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10769
@@ -27029,7 +27024,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10783
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10785
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10786
@@ -27061,7 +27056,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10796
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10798
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10799
@@ -27093,7 +27088,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10809
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10811
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10812
@@ -27125,7 +27120,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 10822
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10824
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10825
@@ -27157,9 +27152,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 10835
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10836
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10837
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 10838
@@ -27191,7 +27186,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 10848
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10850
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 10851
@@ -27234,7 +27229,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 10865
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10867
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 10868
@@ -27277,7 +27272,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 10882
.trainerPic = TRAINER_PIC_EXPERT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10884
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 10885
@@ -27320,9 +27315,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 10899
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10900
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10901
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 10902
@@ -27354,9 +27349,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_AQUA,
#line 10912
.trainerPic = TRAINER_PIC_AQUA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10913
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10914
TRAINER_ENCOUNTER_MUSIC_AQUA,
#line 10915
@@ -27399,7 +27394,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_MAGMA_ADMIN,
#line 10929
.trainerPic = TRAINER_PIC_MAGMA_ADMIN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10931
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 10932
@@ -27464,7 +27459,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 10954
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10956
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 10957
@@ -27509,7 +27504,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 10972
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10974
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 10975
@@ -27552,9 +27547,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 10989
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 10990
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 10991
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 10992
@@ -27597,7 +27592,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_MAGMA_LEADER,
#line 11006
.trainerPic = TRAINER_PIC_MAGMA_LEADER_MAXIE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11008
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 11009
@@ -27653,7 +27648,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_MAGMA_LEADER,
#line 11028
.trainerPic = TRAINER_PIC_MAGMA_LEADER_MAXIE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11030
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 11031
@@ -27709,9 +27704,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11050
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11051
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11052
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11053
@@ -27754,9 +27749,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11067
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11068
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11069
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11070
@@ -27799,9 +27794,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11084
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11085
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11086
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11087
@@ -27833,9 +27828,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_WINSTRATE,
#line 11097
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11098
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11099
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11100
@@ -27889,9 +27884,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11118
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11119
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11120
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11121
@@ -27934,9 +27929,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11135
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11136
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11137
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11138
@@ -27979,9 +27974,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11152
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11153
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11154
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11155
@@ -28024,9 +28019,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11169
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11170
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11171
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11172
@@ -28080,9 +28075,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11190
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11191
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11192
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11193
@@ -28114,9 +28109,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11203
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11204
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11205
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11206
@@ -28170,9 +28165,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11224
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11225
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11226
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11227
@@ -28204,9 +28199,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LASS,
#line 11237
.trainerPic = TRAINER_PIC_LASS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11238
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11239
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11240
@@ -28249,7 +28244,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11254
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11256
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11257
@@ -28292,7 +28287,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11271
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11273
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11274
@@ -28357,7 +28352,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11296
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11298
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11299
@@ -28400,7 +28395,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11313
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11315
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11316
@@ -28443,7 +28438,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11330
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11332
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11333
@@ -28486,7 +28481,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11347
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11349
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11350
@@ -28518,7 +28513,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11360
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11362
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11363
@@ -28561,7 +28556,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11377
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11379
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11380
@@ -28593,7 +28588,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11390
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11392
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11393
@@ -28636,7 +28631,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11407
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11409
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11410
@@ -28690,7 +28685,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_CATCHER,
#line 11428
.trainerPic = TRAINER_PIC_BUG_CATCHER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11430
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 11431
@@ -28755,7 +28750,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11453
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11455
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11456
@@ -28798,7 +28793,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11470
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11472
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11473
@@ -28852,7 +28847,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11491
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11493
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11494
@@ -28895,7 +28890,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11508
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11510
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11511
@@ -28938,7 +28933,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11525
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11527
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11528
@@ -28992,7 +28987,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11546
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11548
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11549
@@ -29024,7 +29019,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11559
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11561
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11562
@@ -29067,7 +29062,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11576
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11578
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11579
@@ -29104,7 +29099,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11591
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11593
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11594
@@ -29157,7 +29152,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11612
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11614
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11615
@@ -29211,7 +29206,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11633
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11635
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11636
@@ -29276,7 +29271,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11658
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11660
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11661
@@ -29341,7 +29336,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11683
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11685
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11686
@@ -29406,7 +29401,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 11708
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11710
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 11711
@@ -29471,7 +29466,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11733
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11735
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11736
@@ -29514,7 +29509,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11750
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11752
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11753
@@ -29557,7 +29552,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11767
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11769
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11770
@@ -29600,7 +29595,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11784
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11786
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11787
@@ -29643,7 +29638,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11801
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11803
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11804
@@ -29686,7 +29681,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11818
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11820
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11821
@@ -29729,7 +29724,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 11835
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11837
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 11838
@@ -29772,9 +29767,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 11852
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11853
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11854
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 11855
@@ -29806,7 +29801,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 11865
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11867
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 11868
@@ -29847,9 +29842,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 11883
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11884
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11885
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 11886
@@ -29906,9 +29901,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 11908
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11909
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 11910
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 11911
@@ -29947,7 +29942,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 11925
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11927
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 11928
@@ -30004,7 +29999,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 11950
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11952
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 11953
@@ -30061,7 +30056,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 11975
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 11977
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 11978
@@ -30118,7 +30113,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 12000
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12002
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12003
@@ -30161,9 +30156,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 12017
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12018
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12019
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 12020
@@ -30217,7 +30212,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12038
.trainerPic = TRAINER_PIC_WALLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12040
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12041
@@ -30249,7 +30244,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12051
.trainerPic = TRAINER_PIC_WALLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12053
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12054
@@ -30362,7 +30357,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12101
.trainerPic = TRAINER_PIC_WALLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12103
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12104
@@ -30475,7 +30470,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12151
.trainerPic = TRAINER_PIC_WALLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12153
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12154
@@ -30588,7 +30583,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12201
.trainerPic = TRAINER_PIC_WALLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12203
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12204
@@ -30701,7 +30696,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12251
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12253
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12254
@@ -30766,7 +30761,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12276
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12278
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12279
@@ -30831,7 +30826,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12301
.trainerPic = TRAINER_PIC_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12303
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 12304
@@ -30896,9 +30891,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12326
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12327
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12328
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 12329
@@ -30963,9 +30958,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12351
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12352
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12353
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 12354
@@ -31030,9 +31025,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 12376
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12377
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12378
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 12379
@@ -31097,7 +31092,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 12401
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12403
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 12404
@@ -31151,7 +31146,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 12422
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12424
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 12425
@@ -31194,7 +31189,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 12439
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12441
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 12442
@@ -31248,9 +31243,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 12460
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12461
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12462
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 12463
@@ -31295,7 +31290,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 12478
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12480
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 12481
@@ -31340,7 +31335,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 12496
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12498
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 12499
@@ -31372,7 +31367,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 12509
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12511
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 12512
@@ -31426,7 +31421,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 12530
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12532
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 12533
@@ -31469,7 +31464,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 12547
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12549
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12550
@@ -31512,9 +31507,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 12564
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12565
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12566
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12567
@@ -31546,7 +31541,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TWINS,
#line 12577
.trainerPic = TRAINER_PIC_TWINS,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12579
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 12580
@@ -31589,7 +31584,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 12594
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12596
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 12597
@@ -31646,7 +31641,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SR_AND_JR,
#line 12619
.trainerPic = TRAINER_PIC_SR_AND_JR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12621
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 12622
@@ -31703,7 +31698,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNG_COUPLE,
#line 12644
.trainerPic = TRAINER_PIC_YOUNG_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12646
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 12647
@@ -31760,7 +31755,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_OLD_COUPLE,
#line 12669
.trainerPic = TRAINER_PIC_OLD_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12671
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 12672
@@ -31817,7 +31812,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_OLD_COUPLE,
#line 12694
.trainerPic = TRAINER_PIC_OLD_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12696
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 12697
@@ -31874,7 +31869,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_OLD_COUPLE,
#line 12719
.trainerPic = TRAINER_PIC_OLD_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12721
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 12722
@@ -31931,7 +31926,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_OLD_COUPLE,
#line 12744
.trainerPic = TRAINER_PIC_OLD_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12746
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 12747
@@ -31988,7 +31983,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_OLD_COUPLE,
#line 12769
.trainerPic = TRAINER_PIC_OLD_COUPLE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12771
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 12772
@@ -32045,7 +32040,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12794
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12796
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12797
@@ -32088,7 +32083,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12811
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12813
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12814
@@ -32131,7 +32126,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12828
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12830
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12831
@@ -32174,7 +32169,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12845
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12847
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12848
@@ -32217,7 +32212,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12862
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12864
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12865
@@ -32260,7 +32255,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12879
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12881
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12882
@@ -32303,7 +32298,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SIS_AND_BRO,
#line 12896
.trainerPic = TRAINER_PIC_SIS_AND_BRO,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12898
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 12899
@@ -32346,7 +32341,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 12913
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12915
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 12916
@@ -32411,7 +32406,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RICH_BOY,
#line 12938
.trainerPic = TRAINER_PIC_RICH_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12940
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 12941
@@ -32456,9 +32451,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LADY,
#line 12955
.trainerPic = TRAINER_PIC_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12956
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12957
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 12958
@@ -32505,7 +32500,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 12973
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12975
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 12976
@@ -32537,9 +32532,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_F,
#line 12986
.trainerPic = TRAINER_PIC_TUBER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 12987
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 12988
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 12989
@@ -32571,7 +32566,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TUBER_M,
#line 12999
.trainerPic = TRAINER_PIC_TUBER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13001
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 13002
@@ -32614,7 +32609,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEFAN,
#line 13016
.trainerPic = TRAINER_PIC_POKEFAN_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13018
TRAINER_ENCOUNTER_MUSIC_TWINS,
#line 13019
@@ -32661,7 +32656,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 13033
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13035
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13036
@@ -32704,9 +32699,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 13050
.trainerPic = TRAINER_PIC_CYCLING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13051
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13052
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 13053
@@ -32738,7 +32733,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 13063
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13065
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13066
@@ -32770,7 +32765,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 13076
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13078
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13079
@@ -32802,7 +32797,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 13089
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13091
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 13092
@@ -32834,9 +32829,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 13102
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13103
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13104
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 13105
@@ -32868,9 +32863,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 13115
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13116
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13117
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 13118
@@ -32902,7 +32897,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 13128
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13130
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13131
@@ -32934,9 +32929,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 13141
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13142
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13143
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 13144
@@ -32979,7 +32974,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 13158
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13160
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 13161
@@ -33022,7 +33017,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 13175
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13177
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 13178
@@ -33065,7 +33060,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_POKEMANIAC,
#line 13192
.trainerPic = TRAINER_PIC_POKEMANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13194
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 13195
@@ -33108,9 +33103,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 13209
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13210
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13211
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 13212
@@ -33153,7 +33148,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FISHERMAN,
#line 13226
.trainerPic = TRAINER_PIC_FISHERMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13228
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13229
@@ -33185,9 +33180,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 13239
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13240
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13241
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 13242
@@ -33219,7 +33214,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 13252
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13254
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 13255
@@ -33273,7 +33268,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13273
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13275
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13276
@@ -33305,7 +33300,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13286
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13288
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13289
@@ -33337,7 +33332,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13299
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13301
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13302
@@ -33369,7 +33364,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13312
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13314
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13315
@@ -33412,7 +33407,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13329
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13331
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13332
@@ -33455,7 +33450,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13346
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13348
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13349
@@ -33487,7 +33482,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13359
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13361
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13362
@@ -33519,7 +33514,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13372
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13374
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13375
@@ -33551,7 +33546,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13385
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13387
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13388
@@ -33583,7 +33578,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13398
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13400
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13401
@@ -33615,7 +33610,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13411
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13413
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13414
@@ -33647,7 +33642,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13424
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13426
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13427
@@ -33679,7 +33674,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13437
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13439
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13440
@@ -33711,9 +33706,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13450
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13451
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13452
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13453
@@ -33745,9 +33740,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13463
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13464
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13465
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13466
@@ -33779,9 +33774,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TEAM_MAGMA,
#line 13476
.trainerPic = TRAINER_PIC_MAGMA_GRUNT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13477
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13478
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13479
@@ -33813,7 +33808,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_MAGMA_ADMIN,
#line 13489
.trainerPic = TRAINER_PIC_MAGMA_ADMIN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13491
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13492
@@ -33878,9 +33873,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 13514
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13515
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13516
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 13517
@@ -33925,7 +33920,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_MAGMA_LEADER,
#line 13532
.trainerPic = TRAINER_PIC_MAGMA_LEADER_MAXIE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13534
TRAINER_ENCOUNTER_MUSIC_MAGMA,
#line 13535
@@ -33979,7 +33974,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_M,
#line 13553
.trainerPic = TRAINER_PIC_SWIMMER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13555
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 13556
@@ -34011,9 +34006,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SWIMMER_F,
#line 13566
.trainerPic = TRAINER_PIC_SWIMMER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13567
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13568
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 13569
@@ -34045,7 +34040,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 13579
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13581
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13582
@@ -34088,7 +34083,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 13596
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13598
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 13599
@@ -34131,7 +34126,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 13613
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13615
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 13616
@@ -34163,7 +34158,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 13626
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13628
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 13629
@@ -34217,9 +34212,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 13647
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13648
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13649
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 13650
@@ -34275,7 +34270,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 13669
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13671
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 13672
@@ -34318,9 +34313,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PICNICKER,
#line 13686
.trainerPic = TRAINER_PIC_PICNICKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13687
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13688
TRAINER_ENCOUNTER_MUSIC_GIRL,
#line 13689
@@ -34363,7 +34358,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 13703
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13705
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13706
@@ -34406,7 +34401,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_CAMPER,
#line 13720
.trainerPic = TRAINER_PIC_CAMPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13722
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 13723
@@ -34449,7 +34444,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 13737
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13739
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13740
@@ -34492,9 +34487,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_AROMA_LADY,
#line 13754
.trainerPic = TRAINER_PIC_AROMA_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13755
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13756
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 13757
@@ -34537,9 +34532,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 13771
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13772
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13773
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 13774
@@ -34582,7 +34577,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_NINJA_BOY,
#line 13788
.trainerPic = TRAINER_PIC_NINJA_BOY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13790
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 13791
@@ -34625,9 +34620,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 13805
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13806
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13807
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13808
@@ -34670,9 +34665,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 13822
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13823
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13824
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13825
@@ -34715,9 +34710,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 13839
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13840
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13841
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13842
@@ -34760,7 +34755,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 13856
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13858
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13859
@@ -34803,7 +34798,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_YOUNGSTER,
#line 13873
.trainerPic = TRAINER_PIC_YOUNGSTER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13875
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 13876
@@ -34846,9 +34841,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 13890
.trainerPic = TRAINER_PIC_RUNNING_TRIATHLETE_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13891
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13892
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 13893
@@ -34880,9 +34875,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 13903
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13904
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13905
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13906
@@ -34914,9 +34909,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 13916
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13917
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13918
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13919
@@ -34948,9 +34943,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_EXPERT,
#line 13929
.trainerPic = TRAINER_PIC_EXPERT_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13930
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13931
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13932
@@ -34995,7 +34990,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 13947
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13949
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 13950
@@ -35027,7 +35022,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_KINDLER,
#line 13960
.trainerPic = TRAINER_PIC_KINDLER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13962
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 13963
@@ -35070,9 +35065,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PARASOL_LADY,
#line 13977
.trainerPic = TRAINER_PIC_PARASOL_LADY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13978
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 13979
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 13980
@@ -35104,7 +35099,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 13990
.trainerPic = TRAINER_PIC_COOLTRAINER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 13992
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 13993
@@ -35144,9 +35139,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BATTLE_GIRL,
#line 14007
.trainerPic = TRAINER_PIC_BATTLE_GIRL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14008
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14009
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 14010
@@ -35189,7 +35184,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 14024
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14026
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 14027
@@ -35232,7 +35227,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 14041
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14043
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14044
@@ -35319,9 +35314,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 14074
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14075
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14076
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14077
@@ -35408,9 +35403,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 14107
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14108
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14109
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 14110
@@ -35455,9 +35450,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 14125
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14126
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14127
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14128
@@ -35500,9 +35495,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 14142
.trainerPic = TRAINER_PIC_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14143
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14144
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14145
@@ -35545,9 +35540,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14159
.trainerPic = TRAINER_PIC_LEADER_ROXANNE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14160
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14161
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14162
@@ -35646,9 +35641,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14201
.trainerPic = TRAINER_PIC_LEADER_ROXANNE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14202
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14203
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14204
@@ -35765,9 +35760,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14251
.trainerPic = TRAINER_PIC_LEADER_ROXANNE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14252
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14253
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14254
@@ -35884,9 +35879,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14301
.trainerPic = TRAINER_PIC_LEADER_ROXANNE,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14302
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14303
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14304
@@ -36021,7 +36016,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14359
.trainerPic = TRAINER_PIC_LEADER_BRAWLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14361
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14362
@@ -36120,7 +36115,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14401
.trainerPic = TRAINER_PIC_LEADER_BRAWLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14403
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14404
@@ -36219,7 +36214,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14443
.trainerPic = TRAINER_PIC_LEADER_BRAWLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14445
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14446
@@ -36336,7 +36331,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14493
.trainerPic = TRAINER_PIC_LEADER_BRAWLY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14495
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14496
@@ -36471,7 +36466,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14551
.trainerPic = TRAINER_PIC_LEADER_WATTSON,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14553
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14554
@@ -36570,7 +36565,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14593
.trainerPic = TRAINER_PIC_LEADER_WATTSON,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14595
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14596
@@ -36687,7 +36682,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14643
.trainerPic = TRAINER_PIC_LEADER_WATTSON,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14645
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14646
@@ -36804,7 +36799,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14693
.trainerPic = TRAINER_PIC_LEADER_WATTSON,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14695
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14696
@@ -36939,9 +36934,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14751
.trainerPic = TRAINER_PIC_LEADER_FLANNERY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14752
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14753
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14754
@@ -37042,9 +37037,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14793
.trainerPic = TRAINER_PIC_LEADER_FLANNERY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14794
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14795
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14796
@@ -37163,9 +37158,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14843
.trainerPic = TRAINER_PIC_LEADER_FLANNERY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14844
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14845
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14846
@@ -37302,9 +37297,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14901
.trainerPic = TRAINER_PIC_LEADER_FLANNERY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14902
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 14903
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 14904
@@ -37441,7 +37436,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 14959
.trainerPic = TRAINER_PIC_LEADER_NORMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 14961
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 14962
@@ -37540,7 +37535,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15001
.trainerPic = TRAINER_PIC_LEADER_NORMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15003
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15004
@@ -37657,7 +37652,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15051
.trainerPic = TRAINER_PIC_LEADER_NORMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15053
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15054
@@ -37774,7 +37769,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15101
.trainerPic = TRAINER_PIC_LEADER_NORMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15103
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15104
@@ -37909,9 +37904,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15159
.trainerPic = TRAINER_PIC_LEADER_WINONA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15160
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15161
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15162
@@ -38028,9 +38023,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15209
.trainerPic = TRAINER_PIC_LEADER_WINONA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15210
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15211
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15212
@@ -38165,9 +38160,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15267
.trainerPic = TRAINER_PIC_LEADER_WINONA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15268
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15269
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15270
@@ -38302,9 +38297,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15325
.trainerPic = TRAINER_PIC_LEADER_WINONA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15326
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15327
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15328
@@ -38439,7 +38434,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15383
.trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15385
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15386
@@ -38558,7 +38553,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15433
.trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15435
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15436
@@ -38695,7 +38690,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15491
.trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15493
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15494
@@ -38832,7 +38827,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15549
.trainerPic = TRAINER_PIC_LEADER_TATE_AND_LIZA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15551
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 15552
@@ -38969,7 +38964,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15607
.trainerPic = TRAINER_PIC_LEADER_JUAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15609
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15610
@@ -39086,7 +39081,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15657
.trainerPic = TRAINER_PIC_LEADER_JUAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15659
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15660
@@ -39203,7 +39198,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15707
.trainerPic = TRAINER_PIC_LEADER_JUAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15709
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15710
@@ -39338,7 +39333,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_LEADER,
#line 15765
.trainerPic = TRAINER_PIC_LEADER_JUAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15767
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15768
@@ -39473,7 +39468,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BUG_MANIAC,
#line 15823
.trainerPic = TRAINER_PIC_BUG_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15825
TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS,
#line 15826
@@ -39528,7 +39523,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BIRD_KEEPER,
#line 15846
.trainerPic = TRAINER_PIC_BIRD_KEEPER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15848
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 15849
@@ -39560,7 +39555,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 15859
.trainerPic = TRAINER_PIC_STEVEN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15861
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15862
@@ -39693,9 +39688,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SALON_MAIDEN,
#line 15917
.trainerPic = TRAINER_PIC_SALON_MAIDEN_ANABEL,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15918
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15919
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15920
@@ -39727,7 +39722,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_DOME_ACE,
#line 15930
.trainerPic = TRAINER_PIC_DOME_ACE_TUCKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15932
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15933
@@ -39759,7 +39754,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PALACE_MAVEN,
#line 15943
.trainerPic = TRAINER_PIC_PALACE_MAVEN_SPENSER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15945
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15946
@@ -39791,9 +39786,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_ARENA_TYCOON,
#line 15956
.trainerPic = TRAINER_PIC_ARENA_TYCOON_GRETA,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15957
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15958
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15959
@@ -39825,7 +39820,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_FACTORY_HEAD,
#line 15969
.trainerPic = TRAINER_PIC_FACTORY_HEAD_NOLAND,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15971
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15972
@@ -39857,9 +39852,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PIKE_QUEEN,
#line 15982
.trainerPic = TRAINER_PIC_PIKE_QUEEN_LUCY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15983
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 15984
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15985
@@ -39891,7 +39886,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PYRAMID_KING,
#line 15995
.trainerPic = TRAINER_PIC_PYRAMID_KING_BRANDON,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 15997
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 15998
@@ -39923,7 +39918,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 16008
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16010
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16011
@@ -39966,7 +39961,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 16025
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16027
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16028
@@ -40020,7 +40015,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 16046
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16048
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16049
@@ -40074,7 +40069,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RUIN_MANIAC,
#line 16067
.trainerPic = TRAINER_PIC_RUIN_MANIAC,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16069
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16070
@@ -40128,7 +40123,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 16088
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16090
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16091
@@ -40182,7 +40177,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 16109
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16111
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16112
@@ -40236,7 +40231,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 16130
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16132
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16133
@@ -40290,7 +40285,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_SAILOR,
#line 16151
.trainerPic = TRAINER_PIC_SAILOR,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16153
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16154
@@ -40344,7 +40339,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 16172
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16174
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 16175
@@ -40387,7 +40382,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 16189
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16191
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 16192
@@ -40441,7 +40436,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 16210
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16212
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 16213
@@ -40495,7 +40490,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_TRIATHLETE,
#line 16231
.trainerPic = TRAINER_PIC_SWIMMING_TRIATHLETE_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16233
TRAINER_ENCOUNTER_MUSIC_SWIMMER,
#line 16234
@@ -40549,7 +40544,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 16252
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16254
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16255
@@ -40592,7 +40587,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 16269
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16271
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16272
@@ -40646,7 +40641,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 16290
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16292
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16293
@@ -40700,7 +40695,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BLACK_BELT,
#line 16311
.trainerPic = TRAINER_PIC_BLACK_BELT,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16313
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16314
@@ -40754,9 +40749,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 16332
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16333
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16334
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 16335
@@ -40801,9 +40796,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 16350
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16351
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16352
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 16353
@@ -40859,9 +40854,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 16372
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16373
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16374
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 16375
@@ -40917,9 +40912,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_COOLTRAINER,
#line 16394
.trainerPic = TRAINER_PIC_COOLTRAINER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16395
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16396
TRAINER_ENCOUNTER_MUSIC_COOL,
#line 16397
@@ -40975,7 +40970,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 16416
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16418
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16419
@@ -41029,7 +41024,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 16437
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16439
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16440
@@ -41083,7 +41078,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 16458
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16460
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16461
@@ -41137,7 +41132,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GUITARIST,
#line 16479
.trainerPic = TRAINER_PIC_GUITARIST,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16481
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16482
@@ -41191,7 +41186,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 16500
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16502
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16503
@@ -41234,7 +41229,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 16517
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16519
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16520
@@ -41288,7 +41283,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 16538
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16540
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16541
@@ -41342,7 +41337,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_HIKER,
#line 16559
.trainerPic = TRAINER_PIC_HIKER,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16561
TRAINER_ENCOUNTER_MUSIC_HIKER,
#line 16562
@@ -41396,9 +41391,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 16580
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16581
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16582
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16583
@@ -41485,9 +41480,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 16613
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16614
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16615
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16616
@@ -41574,9 +41569,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 16646
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16647
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16648
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16649
@@ -41663,9 +41658,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PKMN_BREEDER,
#line 16679
.trainerPic = TRAINER_PIC_POKEMON_BREEDER_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16680
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16681
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16682
@@ -41752,9 +41747,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 16712
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16713
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16714
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16715
@@ -41797,9 +41792,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 16729
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16730
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16731
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16732
@@ -41853,9 +41848,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 16750
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16751
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16752
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16753
@@ -41909,9 +41904,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_BEAUTY,
#line 16771
.trainerPic = TRAINER_PIC_BEAUTY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16772
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16773
TRAINER_ENCOUNTER_MUSIC_FEMALE,
#line 16774
@@ -41965,9 +41960,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 16792
.trainerPic = TRAINER_PIC_PSYCHIC_F,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16793
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16794
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16795
@@ -41997,7 +41992,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_PSYCHIC,
#line 16804
.trainerPic = TRAINER_PIC_PSYCHIC_M,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16806
TRAINER_ENCOUNTER_MUSIC_INTENSE,
#line 16807
@@ -42038,7 +42033,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_GENTLEMAN,
#line 16820
.trainerPic = TRAINER_PIC_GENTLEMAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16822
TRAINER_ENCOUNTER_MUSIC_RICH,
#line 16823
@@ -42068,7 +42063,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 16832
.trainerPic = TRAINER_PIC_RED,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16834
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16835
@@ -42098,9 +42093,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RIVAL,
#line 16844
.trainerPic = TRAINER_PIC_LEAF,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16845
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16846
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16847
@@ -42130,7 +42125,7 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RS_PROTAG,
#line 16856
.trainerPic = TRAINER_PIC_RS_BRENDAN,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16858
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16859
@@ -42160,9 +42155,9 @@ F_TRAINER_FEMALE |
.trainerClass = TRAINER_CLASS_RS_PROTAG,
#line 16868
.trainerPic = TRAINER_PIC_RS_MAY,
- .encounterMusic_gender =
+ .encounterMusic_gender =
#line 16869
-F_TRAINER_FEMALE |
+F_TRAINER_FEMALE |
#line 16870
TRAINER_ENCOUNTER_MUSIC_MALE,
#line 16871
diff --git a/src/daycare.c b/src/daycare.c
index c62db6f347..83dd24af07 100644
--- a/src/daycare.c
+++ b/src/daycare.c
@@ -589,27 +589,6 @@ static void UNUSED TriggerPendingDaycareMaleEgg(void)
_TriggerPendingDaycareMaleEgg(&gSaveBlock1Ptr->daycare);
}
-// Removes the selected index from the given IV list and shifts the remaining
-// elements to the left.
-static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
-{
- s32 i, j;
- u8 temp[NUM_STATS];
-
- ivs[selectedIv] = 0xFF;
- for (i = 0; i < NUM_STATS; i++)
- {
- temp[i] = ivs[i];
- }
-
- j = 0;
- for (i = 0; i < NUM_STATS; i++)
- {
- if (temp[i] != 0xFF)
- ivs[j++] = temp[i];
- }
-}
-
static void InheritIVs(struct Pokemon *egg, struct DayCare *daycare)
{
u16 motherItem = GetBoxMonData(&daycare->mons[0].mon, MON_DATA_HELD_ITEM);
@@ -1153,11 +1132,17 @@ static bool8 TryProduceOrHatchEgg(struct DayCare *daycare)
}
// Try to hatch Egg
- if (++daycare->stepCounter == ((P_EGG_CYCLE_LENGTH >= GEN_8) ? 127 : 255))
+ daycare->stepCounter++;
+ if (((P_EGG_CYCLE_LENGTH <= GEN_3 || P_EGG_CYCLE_LENGTH == GEN_7) && daycare->stepCounter >= 256)
+ || (P_EGG_CYCLE_LENGTH == GEN_4 && daycare->stepCounter >= 255)
+ || ((P_EGG_CYCLE_LENGTH == GEN_5 || P_EGG_CYCLE_LENGTH == GEN_6) && daycare->stepCounter >= 257)
+ || (P_EGG_CYCLE_LENGTH >= GEN_8 && daycare->stepCounter >= 128))
{
u32 eggCycles;
u8 toSub = GetEggCyclesToSubtract();
+ daycare->stepCounter = 0;
+
for (i = 0; i < gPlayerPartyCount; i++)
{
if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
diff --git a/src/debug.c b/src/debug.c
index f1c403fc1e..9e24846d6a 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -89,6 +89,7 @@ enum UtilDebugMenu
DEBUG_UTIL_MENU_ITEM_SAVEBLOCK,
DEBUG_UTIL_MENU_ITEM_ROM_SPACE,
DEBUG_UTIL_MENU_ITEM_WEATHER,
+ DEBUG_UTIL_MENU_ITEM_FONT_TEST,
DEBUG_UTIL_MENU_ITEM_CHECKWALLCLOCK,
DEBUG_UTIL_MENU_ITEM_SETWALLCLOCK,
DEBUG_UTIL_MENU_ITEM_WATCHCREDITS,
@@ -157,8 +158,9 @@ enum FlagsVarsDebugMenu
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL,
+ DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS,
- DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLISSION,
+ DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_TRAINER_SEE,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BAG_USE,
@@ -365,6 +367,7 @@ static void DebugAction_Util_CheckSaveBlock(u8 taskId);
static void DebugAction_Util_CheckROMSpace(u8 taskId);
static void DebugAction_Util_Weather(u8 taskId);
static void DebugAction_Util_Weather_SelectId(u8 taskId);
+static void DebugAction_Util_FontTest(u8 taskId);
static void DebugAction_Util_CheckWallClock(u8 taskId);
static void DebugAction_Util_SetWallClock(u8 taskId);
static void DebugAction_Util_WatchCredits(u8 taskId);
@@ -410,6 +413,7 @@ static void DebugAction_FlagsVars_SwitchPokeNav(u8 taskId);
static void DebugAction_FlagsVars_SwitchMatchCall(u8 taskId);
static void DebugAction_FlagsVars_ToggleFlyFlags(u8 taskId);
static void DebugAction_FlagsVars_ToggleBadgeFlags(u8 taskId);
+static void DebugAction_FlagsVars_ToggleGameClear(u8 taskId);
static void DebugAction_FlagsVars_ToggleFrontierPass(u8 taskId);
static void DebugAction_FlagsVars_CollisionOnOff(u8 taskId);
static void DebugAction_FlagsVars_EncounterOnOff(u8 taskId);
@@ -453,6 +457,7 @@ static void DebugAction_BerryFunctions_Weeds(u8 taskId);
extern const u8 Debug_FlagsNotSetOverworldConfigMessage[];
extern const u8 Debug_FlagsNotSetBattleConfigMessage[];
extern const u8 Debug_FlagsAndVarNotSetBattleConfigMessage[];
+extern const u8 Debug_EventScript_FontTest[];
extern const u8 Debug_EventScript_CheckEVs[];
extern const u8 Debug_EventScript_CheckIVs[];
extern const u8 Debug_EventScript_InflictStatus1[];
@@ -525,6 +530,7 @@ static const u8 sDebugText_Util_SaveBlockSpace[] = _("Save Block space
static const u8 sDebugText_Util_ROMSpace[] = _("ROM space…{CLEAR_TO 110}{RIGHT_ARROW}");
static const u8 sDebugText_Util_Weather[] = _("Set weather…{CLEAR_TO 110}{RIGHT_ARROW}");
static const u8 sDebugText_Util_Weather_ID[] = _("Weather ID: {STR_VAR_3}\n{STR_VAR_1}\n{STR_VAR_2}");
+static const u8 sDebugText_Util_FontTest[] = _("Font Test…{CLEAR_TO 110}{RIGHT_ARROW}");
static const u8 sDebugText_Util_CheckWallClock[] = _("Check wall clock…{CLEAR_TO 110}{RIGHT_ARROW}");
static const u8 sDebugText_Util_SetWallClock[] = _("Set wall clock…{CLEAR_TO 110}{RIGHT_ARROW}");
static const u8 sDebugText_Util_WatchCredits[] = _("Watch credits…{CLEAR_TO 110}{RIGHT_ARROW}");
@@ -573,6 +579,7 @@ static const u8 sDebugText_FlagsVars_SwitchMatchCall[] = _("Toggle {STR_VAR_
static const u8 sDebugText_FlagsVars_RunningShoes[] = _("Toggle {STR_VAR_1}Running Shoes");
static const u8 sDebugText_FlagsVars_ToggleFlyFlags[] = _("Toggle {STR_VAR_1}Fly Flags");
static const u8 sDebugText_FlagsVars_ToggleAllBadges[] = _("Toggle {STR_VAR_1}All badges");
+static const u8 sDebugText_FlagsVars_ToggleGameClear[] = _("Toggle {STR_VAR_1}Game clear");
static const u8 sDebugText_FlagsVars_ToggleFrontierPass[] = _("Toggle {STR_VAR_1}Frontier Pass");
static const u8 sDebugText_FlagsVars_SwitchCollision[] = _("Toggle {STR_VAR_1}Collision OFF");
static const u8 sDebugText_FlagsVars_SwitchEncounter[] = _("Toggle {STR_VAR_1}Encounter OFF");
@@ -714,6 +721,7 @@ static const struct ListMenuItem sDebugMenu_Items_Utilities[] =
[DEBUG_UTIL_MENU_ITEM_SAVEBLOCK] = {sDebugText_Util_SaveBlockSpace, DEBUG_UTIL_MENU_ITEM_SAVEBLOCK},
[DEBUG_UTIL_MENU_ITEM_ROM_SPACE] = {sDebugText_Util_ROMSpace, DEBUG_UTIL_MENU_ITEM_ROM_SPACE},
[DEBUG_UTIL_MENU_ITEM_WEATHER] = {sDebugText_Util_Weather, DEBUG_UTIL_MENU_ITEM_WEATHER},
+ [DEBUG_UTIL_MENU_ITEM_FONT_TEST] = {sDebugText_Util_FontTest, DEBUG_UTIL_MENU_ITEM_FONT_TEST},
[DEBUG_UTIL_MENU_ITEM_CHECKWALLCLOCK] = {sDebugText_Util_CheckWallClock, DEBUG_UTIL_MENU_ITEM_CHECKWALLCLOCK},
[DEBUG_UTIL_MENU_ITEM_SETWALLCLOCK] = {sDebugText_Util_SetWallClock, DEBUG_UTIL_MENU_ITEM_SETWALLCLOCK},
[DEBUG_UTIL_MENU_ITEM_WATCHCREDITS] = {sDebugText_Util_WatchCredits, DEBUG_UTIL_MENU_ITEM_WATCHCREDITS},
@@ -782,8 +790,9 @@ static const struct ListMenuItem sDebugMenu_Items_FlagsVars[] =
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES] = {sDebugText_FlagsVars_RunningShoes, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES},
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS] = {sDebugText_FlagsVars_ToggleFlyFlags, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS},
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL] = {sDebugText_FlagsVars_ToggleAllBadges, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL},
+ [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR] = {sDebugText_FlagsVars_ToggleGameClear, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR},
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS] = {sDebugText_FlagsVars_ToggleFrontierPass, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS},
- [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLISSION] = {sDebugText_FlagsVars_SwitchCollision, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLISSION},
+ [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION] = {sDebugText_FlagsVars_SwitchCollision, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION},
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER] = {sDebugText_FlagsVars_SwitchEncounter, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER},
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_TRAINER_SEE] = {sDebugText_FlagsVars_SwitchTrainerSee, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_TRAINER_SEE},
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BAG_USE] = {sDebugText_FlagsVars_SwitchBagUse, DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BAG_USE},
@@ -884,6 +893,7 @@ static void (*const sDebugMenu_Actions_Utilities[])(u8) =
[DEBUG_UTIL_MENU_ITEM_SAVEBLOCK] = DebugAction_Util_CheckSaveBlock,
[DEBUG_UTIL_MENU_ITEM_ROM_SPACE] = DebugAction_Util_CheckROMSpace,
[DEBUG_UTIL_MENU_ITEM_WEATHER] = DebugAction_Util_Weather,
+ [DEBUG_UTIL_MENU_ITEM_FONT_TEST] = DebugAction_Util_FontTest,
[DEBUG_UTIL_MENU_ITEM_CHECKWALLCLOCK] = DebugAction_Util_CheckWallClock,
[DEBUG_UTIL_MENU_ITEM_SETWALLCLOCK] = DebugAction_Util_SetWallClock,
[DEBUG_UTIL_MENU_ITEM_WATCHCREDITS] = DebugAction_Util_WatchCredits,
@@ -952,8 +962,9 @@ static void (*const sDebugMenu_Actions_Flags[])(u8) =
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_RUN_SHOES] = DebugAction_FlagsVars_RunningShoes,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS] = DebugAction_FlagsVars_ToggleFlyFlags,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL] = DebugAction_FlagsVars_ToggleBadgeFlags,
+ [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR] = DebugAction_FlagsVars_ToggleGameClear,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS] = DebugAction_FlagsVars_ToggleFrontierPass,
- [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLISSION] = DebugAction_FlagsVars_CollisionOnOff,
+ [DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION] = DebugAction_FlagsVars_CollisionOnOff,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_ENCOUNTER] = DebugAction_FlagsVars_EncounterOnOff,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_TRAINER_SEE] = DebugAction_FlagsVars_TrainerSeeOnOff,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BAG_USE] = DebugAction_FlagsVars_BagUseOnOff,
@@ -1302,11 +1313,14 @@ static u8 Debug_CheckToggleFlags(u8 id)
FlagGet(FLAG_BADGE07_GET) &&
FlagGet(FLAG_BADGE08_GET);
break;
+ case DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_GAME_CLEAR:
+ result = FlagGet(FLAG_SYS_GAME_CLEAR);
+ break;
case DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_FRONTIER_PASS:
result = FlagGet(FLAG_SYS_FRONTIER_PASS);
break;
#if OW_FLAG_NO_COLLISION != 0
- case DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLISSION:
+ case DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_COLLISION:
result = FlagGet(OW_FLAG_NO_COLLISION);
break;
#endif
@@ -1921,7 +1935,7 @@ static void DebugAction_Util_Warp_Warp(u8 taskId)
StringExpandPlaceholders(gStringVar1, sDebugText_Util_WarpToMap_SelMax);
StringCopy(gStringVar3, gText_DigitIndicator[0]);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_WarpToMap_SelectMapGroup);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Util_Warp_SelectMapGroup;
gTasks[taskId].tSubWindowId = windowId;
@@ -1965,7 +1979,7 @@ static void DebugAction_Util_Warp_SelectMapGroup(u8 taskId)
StringExpandPlaceholders(gStringVar1, sDebugText_Util_WarpToMap_SelMax);
StringCopy(gStringVar3, gText_DigitIndicator[gTasks[taskId].tDigit]);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_WarpToMap_SelectMapGroup);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -1980,7 +1994,7 @@ static void DebugAction_Util_Warp_SelectMapGroup(u8 taskId)
GetMapName(gStringVar2, Overworld_GetMapHeaderByGroupAndId(gTasks[taskId].tMapGroup, gTasks[taskId].tInput)->regionMapSectionId, 0);
StringCopy(gStringVar3, gText_DigitIndicator[gTasks[taskId].tDigit]);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_WarpToMap_SelectMap);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Util_Warp_SelectMap;
}
@@ -2027,7 +2041,7 @@ static void DebugAction_Util_Warp_SelectMap(u8 taskId)
GetMapName(gStringVar2, Overworld_GetMapHeaderByGroupAndId(gTasks[taskId].tMapGroup, gTasks[taskId].tInput)->regionMapSectionId, 0);
StringCopy(gStringVar3, gText_DigitIndicator[gTasks[taskId].tDigit]);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_WarpToMap_SelectMap);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -2039,7 +2053,7 @@ static void DebugAction_Util_Warp_SelectMap(u8 taskId)
StringCopy(gStringVar3, gText_DigitIndicator[gTasks[taskId].tDigit]);
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_WarpToMap_SelectWarp);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Util_Warp_SelectWarp;
}
else if (JOY_NEW(B_BUTTON))
@@ -2070,7 +2084,7 @@ static void DebugAction_Util_Warp_SelectWarp(u8 taskId)
StringCopy(gStringVar3, gText_DigitIndicator[gTasks[taskId].tDigit]);
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_WarpToMap_SelectWarp);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -2230,7 +2244,7 @@ static void DebugAction_Util_Weather(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, 1, STR_CONV_MODE_LEADING_ZEROS, 2);
StringCopyPadded(gStringVar1, sWeatherNames[0], CHAR_SPACE, 30);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_Weather_ID);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Util_Weather_SelectId;
gTasks[taskId].tSubWindowId = windowId;
@@ -2276,7 +2290,7 @@ static void DebugAction_Util_Weather_SelectId(u8 taskId)
StringCopyPadded(gStringVar1, sDebugText_WeatherNotDefined, CHAR_SPACE, 30);
StringExpandPlaceholders(gStringVar4, sDebugText_Util_Weather_ID);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -2294,6 +2308,11 @@ static void DebugAction_Util_Weather_SelectId(u8 taskId)
}
}
+static void DebugAction_Util_FontTest(u8 taskId)
+{
+ Debug_DestroyMenu_Full_Script(taskId, Debug_EventScript_FontTest);
+}
+
static void DebugAction_Util_CheckWallClock(u8 taskId)
{
Debug_DestroyMenu_Full_Script(taskId, PlayersHouse_2F_EventScript_CheckWallClock);
@@ -2434,7 +2453,7 @@ static void DebugAction_FlagsVars_Flags(u8 taskId)
StringCopyPadded(gStringVar2, sDebugText_False, CHAR_SPACE, 15);
StringCopy(gStringVar3, gText_DigitIndicator[0]);
StringExpandPlaceholders(gStringVar4, sDebugText_FlagsVars_Flag);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_FlagsVars_FlagsSelect;
gTasks[taskId].tSubWindowId = windowId;
@@ -2495,7 +2514,7 @@ static void DebugAction_FlagsVars_FlagsSelect(u8 taskId)
StringCopyPadded(gStringVar2, sDebugText_False, CHAR_SPACE, 15);
StringCopy(gStringVar3, gText_DigitIndicator[gTasks[taskId].tDigit]);
StringExpandPlaceholders(gStringVar4, sDebugText_FlagsVars_Flag);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
}
@@ -2523,7 +2542,7 @@ static void DebugAction_FlagsVars_Vars(u8 taskId)
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar2, gText_DigitIndicator[0]);
StringExpandPlaceholders(gStringVar4, sDebugText_FlagsVars_Variable);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_FlagsVars_Select;
gTasks[taskId].tSubWindowId = windowId;
@@ -2575,7 +2594,7 @@ static void DebugAction_FlagsVars_Select(u8 taskId)
//Combine str's to full window string
StringExpandPlaceholders(gStringVar4, sDebugText_FlagsVars_Variable);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -2595,7 +2614,7 @@ static void DebugAction_FlagsVars_Select(u8 taskId)
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
StringExpandPlaceholders(gStringVar4, sDebugText_FlagsVars_VariableValueSet);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].data[6] = gTasks[taskId].data[5]; //New value selector
gTasks[taskId].func = DebugAction_FlagsVars_SetValue;
@@ -2663,7 +2682,7 @@ static void DebugAction_FlagsVars_SetValue(u8 taskId)
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
StringExpandPlaceholders(gStringVar4, sDebugText_FlagsVars_VariableValueSet);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
}
@@ -2851,6 +2870,16 @@ static void DebugAction_FlagsVars_ToggleBadgeFlags(u8 taskId)
}
}
+static void DebugAction_FlagsVars_ToggleGameClear(u8 taskId)
+{
+ // Sound effect
+ if (FlagGet(FLAG_SYS_GAME_CLEAR))
+ PlaySE(SE_PC_OFF);
+ else
+ PlaySE(SE_PC_LOGIN);
+ FlagToggle(FLAG_SYS_GAME_CLEAR);
+}
+
static void DebugAction_FlagsVars_ToggleFrontierPass(u8 taskId)
{
// Sound effect
@@ -2949,10 +2978,11 @@ static void DebugAction_Give_Item(u8 taskId)
// Display initial item
StringCopy(gStringVar2, gText_DigitIndicator[0]);
ConvertIntToDecimalStringN(gStringVar3, 1, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
- CopyItemName(1, gStringVar1);
+ u8* end = CopyItemName(1, gStringVar1);
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(windowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_ItemID);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Item_SelectId;
gTasks[taskId].tSubWindowId = windowId;
@@ -2994,11 +3024,12 @@ static void DebugAction_Give_Item_SelectId(u8 taskId)
}
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
- CopyItemName(gTasks[taskId].tInput, gStringVar1);
+ u8* end = CopyItemName(gTasks[taskId].tInput, gStringVar1);
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
StringExpandPlaceholders(gStringVar4, sDebugText_ItemID);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
FreeSpriteTilesByTag(ITEM_TAG); //Destroy item icon
FreeSpritePaletteByTag(ITEM_TAG); //Destroy item icon
@@ -3020,7 +3051,7 @@ static void DebugAction_Give_Item_SelectId(u8 taskId)
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEM_QUANTITY);
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_ItemQuantity);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Item_SelectQuantity;
}
@@ -3071,7 +3102,7 @@ static void DebugAction_Give_Item_SelectQuantity(u8 taskId)
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEM_QUANTITY);
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_ItemQuantity);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -3147,11 +3178,12 @@ static void DebugAction_Give_PokemonSimple(u8 taskId)
// Display initial Pokémon
StringCopy(gStringVar2, gText_DigitIndicator[0]);
- ConvertIntToDecimalStringN(gStringVar3, sDebugMonData->species, STR_CONV_MODE_LEADING_ZEROS, 3);
- StringCopy(gStringVar1, GetSpeciesName(sDebugMonData->species));
+ ConvertIntToDecimalStringN(gStringVar3, sDebugMonData->species, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
+ u8 *end = StringCopy(gStringVar1, GetSpeciesName(sDebugMonData->species));
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(windowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonID);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
//Set task data
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectId;
@@ -3187,11 +3219,12 @@ static void DebugAction_Give_PokemonComplex(u8 taskId)
// Display initial Pokémon
StringCopy(gStringVar2, gText_DigitIndicator[0]);
- ConvertIntToDecimalStringN(gStringVar3, sDebugMonData->species, STR_CONV_MODE_LEADING_ZEROS, 4);
- StringCopy(gStringVar1, GetSpeciesName(sDebugMonData->species));
+ ConvertIntToDecimalStringN(gStringVar3, sDebugMonData->species, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
+ u8 *end = StringCopy(gStringVar1, GetSpeciesName(sDebugMonData->species));
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(windowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonID);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectId;
gTasks[taskId].tSubWindowId = windowId;
@@ -3236,11 +3269,12 @@ static void DebugAction_Give_Pokemon_SelectId(u8 taskId)
}
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
- StringCopy(gStringVar1, GetSpeciesName(gTasks[taskId].tInput)); //CopyItemName(gTasks[taskId].tInput, gStringVar1);
+ u8 *end = StringCopy(gStringVar1, GetSpeciesName(gTasks[taskId].tInput)); //CopyItemName(gTasks[taskId].tInput, gStringVar1);
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
- ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 4);
+ ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonID);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
FreeAndDestroyMonIconSprite(&gSprites[gTasks[taskId].tSpriteId]);
FreeMonIconPalettes();
@@ -3259,7 +3293,7 @@ static void DebugAction_Give_Pokemon_SelectId(u8 taskId)
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonLevel);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectLevel;
}
@@ -3306,7 +3340,7 @@ static void DebugAction_Give_Pokemon_SelectLevel(u8 taskId)
ConvertIntToDecimalStringN(gStringVar1, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonLevel);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -3332,7 +3366,7 @@ static void DebugAction_Give_Pokemon_SelectLevel(u8 taskId)
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopyPadded(gStringVar2, sDebugText_False, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonShiny);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectShiny;
}
@@ -3360,7 +3394,7 @@ static void DebugAction_Give_Pokemon_SelectShiny(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 0);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonShiny);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -3374,7 +3408,7 @@ static void DebugAction_Give_Pokemon_SelectShiny(u8 taskId)
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar1, gNaturesInfo[0].name);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonNature);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectNature;
}
@@ -3410,7 +3444,7 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId)
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringCopy(gStringVar1, gNaturesInfo[gTasks[taskId].tInput].name);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonNature);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -3424,9 +3458,10 @@ static void DebugAction_Give_Pokemon_SelectNature(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
abilityId = GetAbilityBySpecies(sDebugMonData->species, 0);
- StringCopy(gStringVar1, gAbilitiesInfo[abilityId].name);
+ u8 *end = StringCopy(gStringVar1, gAbilitiesInfo[abilityId].name);
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonAbility);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectAbility;
}
@@ -3469,9 +3504,10 @@ static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId)
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
- StringCopy(gStringVar1, gAbilitiesInfo[abilityId].name);
+ u8 *end = StringCopy(gStringVar1, gAbilitiesInfo[abilityId].name);
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonAbility);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -3484,7 +3520,7 @@ static void DebugAction_Give_Pokemon_SelectAbility(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 2);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_IV_HP);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectIVs;
}
@@ -3549,7 +3585,7 @@ static void DebugAction_Give_Pokemon_SelectIVs(u8 taskId)
StringExpandPlaceholders(gStringVar4, sDebugText_IV_SpDefense);
break;
}
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
//If A or B button
@@ -3608,7 +3644,7 @@ static void DebugAction_Give_Pokemon_SelectIVs(u8 taskId)
StringExpandPlaceholders(gStringVar4, sDebugText_IV_SpDefense);
break;
}
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectIVs;
}
@@ -3622,7 +3658,7 @@ static void DebugAction_Give_Pokemon_SelectIVs(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_EV_HP);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectEVs;
}
}
@@ -3699,7 +3735,7 @@ static void DebugAction_Give_Pokemon_SelectEVs(u8 taskId)
StringExpandPlaceholders(gStringVar4, sDebugText_EV_SpDefense);
break;
}
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
//If A or B button
@@ -3758,7 +3794,7 @@ static void DebugAction_Give_Pokemon_SelectEVs(u8 taskId)
StringExpandPlaceholders(gStringVar4, sDebugText_EV_SpDefense);
break;
}
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectEVs;
}
@@ -3782,18 +3818,19 @@ static void DebugAction_Give_Pokemon_SelectEVs(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringCopyPadded(gStringVar3, gStringVar3, CHAR_SPACE, 15);
StringExpandPlaceholders(gStringVar4, sDebugText_EV_HP);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_SelectEVs;
}
else
{
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
- StringCopy(gStringVar1, GetMoveName(gTasks[taskId].tInput));
+ u8 *end = StringCopy(gStringVar1, GetMoveName(gTasks[taskId].tInput));
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonMove_0);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_Move;
}
@@ -3837,7 +3874,8 @@ static void DebugAction_Give_Pokemon_Move(u8 taskId)
}
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
- StringCopy(gStringVar1, GetMoveName(gTasks[taskId].tInput));
+ u8 *end = StringCopy(gStringVar1, GetMoveName(gTasks[taskId].tInput));
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
switch (gTasks[taskId].tIterator)
@@ -3855,7 +3893,7 @@ static void DebugAction_Give_Pokemon_Move(u8 taskId)
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonMove_3);
break;
}
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -3889,7 +3927,8 @@ static void DebugAction_Give_Pokemon_Move(u8 taskId)
gTasks[taskId].tDigit = 0;
StringCopy(gStringVar2, gText_DigitIndicator[gTasks[taskId].tDigit]);
- StringCopy(gStringVar1, GetMoveName(gTasks[taskId].tInput));
+ u8 *end = StringCopy(gStringVar1, GetMoveName(gTasks[taskId].tInput));
+ WrapFontIdToFit(gStringVar1, end, DEBUG_MENU_FONT, WindowWidthPx(gTasks[taskId].tSubWindowId));
StringCopyPadded(gStringVar1, gStringVar1, CHAR_SPACE, 15);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, 3);
switch (gTasks[taskId].tIterator)
@@ -3907,7 +3946,7 @@ static void DebugAction_Give_Pokemon_Move(u8 taskId)
StringExpandPlaceholders(gStringVar4, sDebugText_PokemonMove_3);
break;
}
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
gTasks[taskId].func = DebugAction_Give_Pokemon_Move;
}
@@ -4260,7 +4299,7 @@ static void DebugAction_Sound_SE(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, 1, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
StringCopyPadded(gStringVar1, sSENames[0], CHAR_SPACE, 35);
StringExpandPlaceholders(gStringVar4, sDebugText_Sound_SFX_ID);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
StopMapMusic(); //Stop map music to better hear sounds
@@ -4302,7 +4341,7 @@ static void DebugAction_Sound_SE_SelectId(u8 taskId)
StringCopyPadded(gStringVar1, sSENames[gTasks[taskId].tInput-1], CHAR_SPACE, 35);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
StringExpandPlaceholders(gStringVar4, sDebugText_Sound_SFX_ID);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
@@ -4342,7 +4381,7 @@ static void DebugAction_Sound_MUS(u8 taskId)
ConvertIntToDecimalStringN(gStringVar3, START_MUS, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
StringCopyPadded(gStringVar1, sBGMNames[0], CHAR_SPACE, 35);
StringExpandPlaceholders(gStringVar4, sDebugText_Sound_Music_ID);
- AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
StopMapMusic(); //Stop map music to better hear new music
@@ -4384,7 +4423,7 @@ static void DebugAction_Sound_MUS_SelectId(u8 taskId)
StringCopyPadded(gStringVar1, sBGMNames[gTasks[taskId].tInput-START_MUS], CHAR_SPACE, 35);
ConvertIntToDecimalStringN(gStringVar3, gTasks[taskId].tInput, STR_CONV_MODE_LEADING_ZEROS, DEBUG_NUMBER_DIGITS_ITEMS);
StringExpandPlaceholders(gStringVar4, sDebugText_Sound_Music_ID);
- AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 1, 1, 0, NULL);
+ AddTextPrinterParameterized(gTasks[taskId].tSubWindowId, DEBUG_MENU_FONT, gStringVar4, 0, 0, 0, NULL);
}
if (JOY_NEW(A_BUTTON))
diff --git a/src/easy_chat.c b/src/easy_chat.c
index ce3b4fe907..aa8405be75 100644
--- a/src/easy_chat.c
+++ b/src/easy_chat.c
@@ -17,6 +17,7 @@
#include "main.h"
#include "mystery_gift.h"
#include "menu.h"
+#include "move.h"
#include "overworld.h"
#include "palette.h"
#include "pokedex.h"
diff --git a/src/event_object_movement.c b/src/event_object_movement.c
index f0f1e3f00d..9392a81d86 100644
--- a/src/event_object_movement.c
+++ b/src/event_object_movement.c
@@ -2519,7 +2519,7 @@ void GetFollowerAction(struct ScriptContext *ctx) // Essentially a big switch fo
}
if (multi < NUMBER_OF_MON_TYPES)
{
- multi = GetTypeEffectiveness(mon, multi);
+ multi = GetOverworldTypeEffectiveness(mon, multi);
if (multi <= UQ_4_12(0.5))
condEmotes[condCount++] = (struct SpecialEmote) {.emotion = FOLLOWER_EMOTION_HAPPY, .index = 32};
else if (multi >= UQ_4_12(2.0))
diff --git a/src/evolution_graphics.c b/src/evolution_graphics.c
index 96ff1b52df..1568c18d5f 100644
--- a/src/evolution_graphics.c
+++ b/src/evolution_graphics.c
@@ -150,7 +150,9 @@ static void SpriteCB_Sparkle_SpiralUpward(struct Sprite *sprite)
sprite->oam.matrixNum = matrixNum;
}
else
+ {
DestroySprite(sprite);
+ }
}
static void CreateSparkle_SpiralUpward(u8 trigIdx)
@@ -178,7 +180,9 @@ static void SpriteCB_Sparkle_ArcDown(struct Sprite *sprite)
sprite->sTimer++;
}
else
+ {
DestroySprite(sprite);
+ }
}
static void CreateSparkle_ArcDown(u8 trigIdx)
@@ -206,7 +210,9 @@ static void SpriteCB_Sparkle_CircleInward(struct Sprite *sprite)
sprite->sTrigIdx += 4;
}
else
+ {
DestroySprite(sprite);
+ }
}
static void CreateSparkle_CircleInward(u8 trigIdx, u8 speed)
@@ -238,7 +244,9 @@ static void SpriteCB_Sparkle_Spray(struct Sprite *sprite)
sprite->sTrigIdx++;
matrixNum = 31 - (sprite->sTrigIdx * 12 / 128);
if (sprite->sTrigIdx > 64)
+ {
sprite->subpriority = 1;
+ }
else
{
sprite->invisible = FALSE;
@@ -252,7 +260,9 @@ static void SpriteCB_Sparkle_Spray(struct Sprite *sprite)
sprite->sTimer++;
}
else
+ {
DestroySprite(sprite);
+ }
}
static void CreateSparkle_Spray(u8 id)
@@ -348,7 +358,9 @@ static void Task_Sparkles_ArcDown(u8 taskId)
gTasks[taskId].tTimer++;
}
else
+ {
gTasks[taskId].func = Task_Sparkles_ArcDown_End;
+ }
}
static void Task_Sparkles_ArcDown_End(u8 taskId)
@@ -388,7 +400,9 @@ static void Task_Sparkles_CircleInward(u8 taskId)
gTasks[taskId].tTimer++;
}
else
+ {
gTasks[taskId].func = Task_Sparkles_CircleInward_End;
+ }
}
static void Task_Sparkles_CircleInward_End(u8 taskId)
@@ -437,7 +451,9 @@ static void Task_Sparkles_SprayAndFlash(u8 taskId)
gTasks[taskId].tTimer++;
}
else
+ {
gTasks[taskId].func = Task_Sparkles_SprayAndFlash_End;
+ }
}
static void Task_Sparkles_SprayAndFlash_End(u8 taskId)
@@ -486,7 +502,9 @@ static void Task_Sparkles_SprayAndFlashTrade(u8 taskId)
gTasks[taskId].tTimer++;
}
else
+ {
gTasks[taskId].func = Task_Sparkles_SprayAndFlash_End;
+ }
}
#undef tTimer
@@ -560,9 +578,13 @@ static void Task_CycleEvolutionMonSprite_Init(u8 taskId)
static void Task_CycleEvolutionMonSprite_TryEnd(u8 taskId)
{
if (gTasks[taskId].tEvoStopped)
+ {
EndOnPreEvoMon(taskId);
+ }
else if (gTasks[taskId].tScaleSpeed == 128)
+ {
EndOnPostEvoMon(taskId);
+ }
else
{
gTasks[taskId].tScaleSpeed += 2;
@@ -574,7 +596,9 @@ static void Task_CycleEvolutionMonSprite_TryEnd(u8 taskId)
static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
{
if (gTasks[taskId].tEvoStopped)
+ {
gTasks[taskId].func = EndOnPreEvoMon;
+ }
else
{
u16 oamMatrixArg;
@@ -583,7 +607,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
{
// Set pre-evo sprite growth
if (gTasks[taskId].tPreEvoScale < MON_MAX_SCALE - gTasks[taskId].tScaleSpeed)
+ {
gTasks[taskId].tPreEvoScale += gTasks[taskId].tScaleSpeed;
+ }
else
{
gTasks[taskId].tPreEvoScale = MON_MAX_SCALE;
@@ -592,7 +618,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
// Set post-evo sprite shrink
if (gTasks[taskId].tPostEvoScale > MON_MIN_SCALE + gTasks[taskId].tScaleSpeed)
+ {
gTasks[taskId].tPostEvoScale -= gTasks[taskId].tScaleSpeed;
+ }
else
{
gTasks[taskId].tPostEvoScale = MON_MIN_SCALE;
@@ -603,7 +631,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
{
// Set post-evo sprite growth
if (gTasks[taskId].tPostEvoScale < MON_MAX_SCALE - gTasks[taskId].tScaleSpeed)
+ {
gTasks[taskId].tPostEvoScale += gTasks[taskId].tScaleSpeed;
+ }
else
{
gTasks[taskId].tPostEvoScale = MON_MAX_SCALE;
@@ -612,7 +642,9 @@ static void Task_CycleEvolutionMonSprite_UpdateSize(u8 taskId)
// Set pre-evo sprite shrink
if (gTasks[taskId].tPreEvoScale > MON_MIN_SCALE + gTasks[taskId].tScaleSpeed)
+ {
gTasks[taskId].tPreEvoScale -= gTasks[taskId].tScaleSpeed;
+ }
else
{
gTasks[taskId].tPreEvoScale = MON_MIN_SCALE;
diff --git a/src/field_camera.c b/src/field_camera.c
index 290ddddaf1..e76ba3d855 100644
--- a/src/field_camera.c
+++ b/src/field_camera.c
@@ -231,7 +231,9 @@ static void DrawMetatileAt(const struct MapLayout *mapLayout, u16 offset, int x,
if (metatileId > NUM_METATILES_TOTAL)
metatileId = 0;
if (metatileId < NUM_METATILES_IN_PRIMARY)
+ {
metatiles = mapLayout->primaryTileset->metatiles;
+ }
else
{
metatiles = mapLayout->secondaryTileset->metatiles;
diff --git a/src/field_door.c b/src/field_door.c
index b922c939b7..1810811191 100644
--- a/src/field_door.c
+++ b/src/field_door.c
@@ -437,7 +437,9 @@ static const struct DoorGraphics *GetDoorGraphics(const struct DoorGraphics *gfx
static s8 StartDoorAnimationTask(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frames, u32 x, u32 y)
{
if (FuncIsActiveTask(Task_AnimateDoor) == TRUE)
+ {
return -1;
+ }
else
{
u8 taskId = CreateTask(Task_AnimateDoor, 0x50);
diff --git a/src/field_effect.c b/src/field_effect.c
index fad769fd2f..dda30138b6 100644
--- a/src/field_effect.c
+++ b/src/field_effect.c
@@ -1300,7 +1300,8 @@ static void CreateHofMonitorSprite(s16 taskId, s16 x, s16 y, bool8 isSmallMonito
{
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_HofMonitorBig, x, y, 0);
SetSubspriteTables(&gSprites[spriteId], &sSubspriteTable_HofMonitorBig);
- } else
+ }
+ else
{
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_HofMonitorSmall, x, y, 0);
}
@@ -2022,7 +2023,8 @@ static bool8 LavaridgeGymB1FWarpEffect_Rise(struct Task *task, struct ObjectEven
{
task->data[1] <<= 1;
}
- } else if (!(task->data[2] & 4) && (task->data[1] > 0))
+ }
+ else if (!(task->data[2] & 4) && (task->data[1] > 0))
{
task->data[1] >>= 1;
}
@@ -2036,7 +2038,8 @@ static bool8 LavaridgeGymB1FWarpEffect_Rise(struct Task *task, struct ObjectEven
{
task->data[3]++;
}
- } else
+ }
+ else
{
task->data[4] = 1;
}
@@ -2190,7 +2193,8 @@ static bool8 LavaridgeGym1FWarpEffect_AshPuff(struct Task *task, struct ObjectEv
gFieldEffectArguments[3] = sprite->oam.priority;
task->data[1] = FieldEffectStart(FLDEFF_ASH_PUFF);
task->data[0]++;
- } else
+ }
+ else
{
task->data[1]++;
ObjectEventSetHeldMovement(objectEvent, GetWalkInPlaceFasterMovementAction(objectEvent->facingDirection));
@@ -2521,7 +2525,8 @@ static void TeleportWarpInFieldEffect_SpinEnter(struct Task *task)
objectEvent->triggerGroundEffectsOnMove = TRUE;
sprite->subspriteMode = task->data[14];
}
- } else
+ }
+ else
{
sprite->oam.priority = 1;
if (sprite->subspriteMode != SUBSPRITES_OFF)
diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c
index 073c92f3e0..e07d067afc 100644
--- a/src/field_screen_effect.c
+++ b/src/field_screen_effect.c
@@ -1374,7 +1374,6 @@ static void Task_RushInjuredPokemonToCenter(u8 taskId)
ClearWindowTilemap(windowId);
CopyWindowToVram(windowId, COPYWIN_MAP);
RemoveWindow(windowId);
- FillPalBufferBlack();
FadeInFromBlack();
gTasks[taskId].tState = FRLG_WHITEOUT_HEAL_SCRIPT;
break;
diff --git a/src/field_specials.c b/src/field_specials.c
index f5154f8424..e04a8011fe 100644
--- a/src/field_specials.c
+++ b/src/field_specials.c
@@ -148,6 +148,15 @@ static void BufferFanClubTrainerName_(struct LinkBattleRecords *, u8, u8);
static void BufferFanClubTrainerName_(u8 whichLinkTrainer, u8 whichNPCTrainer);
#endif //FREE_LINK_BATTLE_RECORDS
+static const u8 sText_BigGuy[] = _("Big guy");
+static const u8 sText_BigGirl[] = _("Big girl");
+static const u8 sText_Son[] = _("son");
+static const u8 sText_Daughter[] = _("daughter");
+static const u8 sText_99TimesPlus[] = _("99 times +");
+static const u8 sText_1MinutePlus[] = _("1 minute +");
+static const u8 sText_SpaceSeconds[] = _(" seconds");
+static const u8 sText_SpaceTimes[] = _(" time(s)");
+
void Special_ShowDiploma(void)
{
SetMainCallback2(CB2_ShowDiploma);
@@ -191,11 +200,11 @@ static void DetermineCyclingRoadResults(u32 numFrames, u8 numBikeCollisions)
if (numBikeCollisions < 100)
{
ConvertIntToDecimalStringN(gStringVar1, numBikeCollisions, STR_CONV_MODE_LEFT_ALIGN, 2);
- StringAppend(gStringVar1, gText_SpaceTimes);
+ StringAppend(gStringVar1, sText_SpaceTimes);
}
else
{
- StringCopy(gStringVar1, gText_99TimesPlus);
+ StringCopy(gStringVar1, sText_99TimesPlus);
}
if (numFrames < 3600)
@@ -203,11 +212,11 @@ static void DetermineCyclingRoadResults(u32 numFrames, u8 numBikeCollisions)
ConvertIntToDecimalStringN(gStringVar2, numFrames / 60, STR_CONV_MODE_RIGHT_ALIGN, 2);
gStringVar2[2] = CHAR_DEC_SEPARATOR;
ConvertIntToDecimalStringN(&gStringVar2[3], ((numFrames % 60) * 100) / 60, STR_CONV_MODE_LEADING_ZEROS, 2);
- StringAppend(gStringVar2, gText_SpaceSeconds);
+ StringAppend(gStringVar2, sText_SpaceSeconds);
}
else
{
- StringCopy(gStringVar2, gText_1MinutePlus);
+ StringCopy(gStringVar2, sText_1MinutePlus);
}
result = 0;
@@ -916,17 +925,17 @@ u8 GetPlayerTrainerIdOnesDigit(void)
void GetPlayerBigGuyGirlString(void)
{
if (gSaveBlock2Ptr->playerGender == MALE)
- StringCopy(gStringVar1, gText_BigGuy);
+ StringCopy(gStringVar1, sText_BigGuy);
else
- StringCopy(gStringVar1, gText_BigGirl);
+ StringCopy(gStringVar1, sText_BigGirl);
}
void GetRivalSonDaughterString(void)
{
if (gSaveBlock2Ptr->playerGender == MALE)
- StringCopy(gStringVar1, gText_Daughter);
+ StringCopy(gStringVar1, sText_Daughter);
else
- StringCopy(gStringVar1, gText_Son);
+ StringCopy(gStringVar1, sText_Son);
}
u8 GetBattleOutcome(void)
@@ -2421,89 +2430,89 @@ static const u8 *const sScrollableMultichoiceOptions[][MAX_SCROLL_MULTI_LENGTH]
},
[SCROLL_MULTI_GLASS_WORKSHOP_VENDOR] =
{
- gText_BlueFlute,
- gText_YellowFlute,
- gText_RedFlute,
- gText_WhiteFlute,
- gText_BlackFlute,
- gText_PrettyChair,
- gText_PrettyDesk,
+ COMPOUND_STRING("BLUE FLUTE"),
+ COMPOUND_STRING("YELLOW FLUTE"),
+ COMPOUND_STRING("RED FLUTE"),
+ COMPOUND_STRING("WHITE FLUTE"),
+ COMPOUND_STRING("BLACK FLUTE"),
+ COMPOUND_STRING("PRETTY CHAIR"),
+ COMPOUND_STRING("PRETTY DESK"),
gText_Exit
},
[SCROLL_MULTI_POKEMON_FAN_CLUB_RATER] =
{
- gText_0Pts,
- gText_10Pts,
- gText_20Pts,
- gText_30Pts,
- gText_40Pts,
- gText_50Pts,
- gText_60Pts,
- gText_70Pts,
- gText_80Pts,
- gText_90Pts,
- gText_100Pts,
- gText_QuestionMark
+ COMPOUND_STRING("0 pts"),
+ COMPOUND_STRING("10 pts"),
+ COMPOUND_STRING("20 pts"),
+ COMPOUND_STRING("30 pts"),
+ COMPOUND_STRING("40 pts"),
+ COMPOUND_STRING("50 pts"),
+ COMPOUND_STRING("60 pts"),
+ COMPOUND_STRING("70 pts"),
+ COMPOUND_STRING("80 pts"),
+ COMPOUND_STRING("90 pts"),
+ COMPOUND_STRING("100 pts"),
+ COMPOUND_STRING("?")
},
[SCROLL_MULTI_BF_EXCHANGE_CORNER_DECOR_VENDOR_1] =
{
- gText_KissPoster16BP,
- gText_KissCushion32BP,
- gText_SmoochumDoll32BP,
- gText_TogepiDoll48BP,
- gText_MeowthDoll48BP,
- gText_ClefairyDoll48BP,
- gText_DittoDoll48BP,
- gText_CyndaquilDoll80BP,
- gText_ChikoritaDoll80BP,
- gText_TotodileDoll80BP,
+ COMPOUND_STRING("KISS POSTER{CLEAR_TO 0x5E}16BP"),
+ COMPOUND_STRING("KISS CUSHION{CLEAR_TO 0x5E}32BP"),
+ COMPOUND_STRING("SMOOCHUM DOLL{CLEAR_TO 0x5E}32BP"),
+ COMPOUND_STRING("TOGEPI DOLL{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("MEOWTH DOLL{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("CLEFAIRY DOLL{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("DITTO DOLL{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("CYNDAQUIL DOLL{CLEAR_TO 0x5E}80BP"),
+ COMPOUND_STRING("CHIKORITA DOLL{CLEAR_TO 0x5E}80BP"),
+ COMPOUND_STRING("TOTODILE DOLL{CLEAR_TO 0x5E}80BP"),
gText_Exit
},
[SCROLL_MULTI_BF_EXCHANGE_CORNER_DECOR_VENDOR_2] =
{
- gText_LaprasDoll128BP,
- gText_SnorlaxDoll128BP,
- gText_VenusaurDoll256BP,
- gText_CharizardDoll256BP,
- gText_BlastoiseDoll256BP,
+ COMPOUND_STRING("LAPRAS DOLL{CLEAR_TO 0x58}128BP"),
+ COMPOUND_STRING("SNORLAX DOLL{CLEAR_TO 0x58}128BP"),
+ COMPOUND_STRING("VENUSAUR DOLL{CLEAR_TO 0x58}256BP"),
+ COMPOUND_STRING("CHARIZARD DOLL{CLEAR_TO 0x58}256BP"),
+ COMPOUND_STRING("BLASTOISE DOLL{CLEAR_TO 0x58}256BP"),
gText_Exit
},
[SCROLL_MULTI_BF_EXCHANGE_CORNER_VITAMIN_VENDOR] =
{
- gText_Protein1BP,
- gText_Calcium1BP,
- gText_Iron1BP,
- gText_Zinc1BP,
- gText_Carbos1BP,
- gText_HpUp1BP,
+ COMPOUND_STRING("PROTEIN{CLEAR_TO 0x64}1BP"),
+ COMPOUND_STRING("CALCIUM{CLEAR_TO 0x64}1BP"),
+ COMPOUND_STRING("IRON{CLEAR_TO 0x64}1BP"),
+ COMPOUND_STRING("ZINC{CLEAR_TO 0x64}1BP"),
+ COMPOUND_STRING("CARBOS{CLEAR_TO 0x64}1BP"),
+ COMPOUND_STRING("HP UP{CLEAR_TO 0x64}1BP"),
gText_Exit
},
[SCROLL_MULTI_BF_EXCHANGE_CORNER_HOLD_ITEM_VENDOR] =
{
- gText_Leftovers48BP,
- gText_WhiteHerb48BP,
- gText_QuickClaw48BP,
- gText_MentalHerb48BP,
- gText_BrightPowder64BP,
- gText_ChoiceBand64BP,
- gText_KingsRock64BP,
- gText_FocusBand64BP,
- gText_ScopeLens64BP,
+ COMPOUND_STRING("LEFTOVERS{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("WHITE HERB{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("QUICK CLAW{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("MENTAL HERB{CLEAR_TO 0x5E}48BP"),
+ COMPOUND_STRING("BRIGHTPOWDER{CLEAR_TO 0x5E}64BP"),
+ COMPOUND_STRING("CHOICE BAND{CLEAR_TO 0x5E}64BP"),
+ COMPOUND_STRING("KING'S ROCK{CLEAR_TO 0x5E}64BP"),
+ COMPOUND_STRING("FOCUS BAND{CLEAR_TO 0x5E}64BP"),
+ COMPOUND_STRING("SCOPE LENS{CLEAR_TO 0x5E}64BP"),
gText_Exit
},
[SCROLL_MULTI_BERRY_POWDER_VENDOR] =
{
- gText_EnergyPowder50,
- gText_EnergyRoot80,
- gText_HealPowder50,
- gText_RevivalHerb300,
- gText_Protein1000,
- gText_Iron1000,
- gText_Carbos1000,
- gText_Calcium1000,
- gText_Zinc1000,
- gText_HPUp1000,
- gText_PPUp3000,
+ COMPOUND_STRING("ENERGYPOWDER{CLEAR_TO 114}{FONT_SMALL}50"),
+ COMPOUND_STRING("ENERGY ROOT{CLEAR_TO 114}{FONT_SMALL}80"),
+ COMPOUND_STRING("HEAL POWDER{CLEAR_TO 114}{FONT_SMALL}50"),
+ COMPOUND_STRING("REVIVAL HERB{CLEAR_TO 108}{FONT_SMALL}300"),
+ COMPOUND_STRING("PROTEIN{CLEAR_TO 99}{FONT_SMALL}1,000"),
+ COMPOUND_STRING("IRON{CLEAR_TO 99}{FONT_SMALL}1,000"),
+ COMPOUND_STRING("CARBOS{CLEAR_TO 99}{FONT_SMALL}1,000"),
+ COMPOUND_STRING("CALCIUM{CLEAR_TO 99}{FONT_SMALL}1,000"),
+ COMPOUND_STRING("ZINC{CLEAR_TO 99}{FONT_SMALL}1,000"),
+ COMPOUND_STRING("HP UP{CLEAR_TO 99}{FONT_SMALL}1,000"),
+ COMPOUND_STRING("PP UP{CLEAR_TO 99}{FONT_SMALL}3,000"),
gText_Exit
},
[SCROLL_MULTI_BF_RECEPTIONIST] =
@@ -2521,30 +2530,30 @@ static const u8 *const sScrollableMultichoiceOptions[][MAX_SCROLL_MULTI_LENGTH]
},
[SCROLL_MULTI_BF_MOVE_TUTOR_1] =
{
- gText_Softboiled16BP,
- gText_SeismicToss24BP,
- gText_DreamEater24BP,
- gText_MegaPunch24BP,
- gText_MegaKick48BP,
- gText_BodySlam48BP,
- gText_RockSlide48BP,
- gText_Counter48BP,
- gText_ThunderWave48BP,
- gText_SwordsDance48BP,
+ COMPOUND_STRING("SOFTBOILED{CLEAR_TO 0x4E}16BP"),
+ COMPOUND_STRING("SEISMIC TOSS{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("DREAM EATER{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("MEGA PUNCH{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("MEGA KICK{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("BODY SLAM{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("ROCK SLIDE{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("COUNTER{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("THUNDER WAVE{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("SWORDS DANCE{CLEAR_TO 0x4E}48BP"),
gText_Exit
},
[SCROLL_MULTI_BF_MOVE_TUTOR_2] =
{
- gText_DefenseCurl16BP,
- gText_Snore24BP,
- gText_MudSlap24BP,
- gText_Swift24BP,
- gText_IcyWind24BP,
- gText_Endure48BP,
- gText_PsychUp48BP,
- gText_IcePunch48BP,
- gText_ThunderPunch48BP,
- gText_FirePunch48BP,
+ COMPOUND_STRING("DEFENSE CURL{CLEAR_TO 0x4E}16BP"),
+ COMPOUND_STRING("SNORE{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("MUD-SLAP{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("SWIFT{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("ICY WIND{CLEAR_TO 0x4E}24BP"),
+ COMPOUND_STRING("ENDURE{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("PSYCH UP{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("ICE PUNCH{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("THUNDERPUNCH{CLEAR_TO 0x4E}48BP"),
+ COMPOUND_STRING("FIRE PUNCH{CLEAR_TO 0x4E}48BP"),
gText_Exit
},
[SCROLL_MULTI_SS_TIDAL_DESTINATION] =
@@ -2766,10 +2775,12 @@ static void ScrollableMultichoice_UpdateScrollArrows(u8 taskId)
struct ScrollArrowsTemplate template = sScrollableMultichoice_ScrollArrowsTemplate;
if (task->tMaxItemsOnScreen != task->tNumItems)
{
+ u32 y0 = (8 * (task->tTop - 1));
+
template.firstX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8;
- template.firstY = 8;
+ template.firstY = 8 + y0;
template.secondX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8;
- template.secondY = task->tHeight * 8 + 10;
+ template.secondY = task->tHeight * 8 + 10 + y0;
template.fullyUpThreshold = 0;
template.fullyDownThreshold = task->tNumItems - task->tMaxItemsOnScreen;
task->tScrollArrowId = AddScrollIndicatorArrowPair(&template, &gScrollableMultichoice_ScrollOffset);
diff --git a/src/fonts.c b/src/fonts.c
index 2dcb0a7e78..853f6fbde2 100644
--- a/src/fonts.c
+++ b/src/fonts.c
@@ -5,7 +5,7 @@ ALIGNED(4) const u8 gFontSmallNarrowLatinGlyphWidths[] = {
3, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, 4, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 3, 4, 5, 5, 5, 5, 4, 3,
4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 6, 3,
- 3, 3, 3, 3, 8, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 8, 0, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5, 5, 3, 8, 8, 8, 8, 8, 8, 8, 4, 5, 4, 4, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 4,
@@ -41,7 +41,7 @@ ALIGNED(4) const u8 gFontSmallLatinGlyphWidths[] = {
3, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, 4, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4, 3,
4, 4, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 8, 7, 8, 3,
- 3, 3, 3, 3, 8, 8, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 8, 8, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 4, 7, 5, 5, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 4,
@@ -77,7 +77,7 @@ ALIGNED(4) const u8 gFontNarrowLatinGlyphWidths[] = {
3, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, 4, 5, 5, 5,
8, 5, 5, 5, 5, 6, 5, 5, 3, 5, 5, 5, 5, 5, 4, 3,
4, 4, 5, 5, 5, 8, 5, 5, 5, 5, 5, 6, 9, 6, 6, 3,
- 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 8, 8, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5, 5, 4, 8, 8, 8, 7, 8, 8, 4, 4, 6, 4, 4, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 4,
@@ -113,7 +113,7 @@ ALIGNED(4) const u8 gFontShortLatinGlyphWidths[] = {
3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6,
8, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6, 6, 3,
6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 9, 8, 8, 3,
- 3, 3, 3, 3, 10, 8, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 10, 8, 5, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6, 6, 6, 8, 8, 8, 8, 8, 8, 4, 6, 8, 5, 5, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 6,
@@ -185,19 +185,19 @@ ALIGNED(4) const u8 gFontNarrowerLatinGlyphWidths[] = {
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4,
8, 4, 4, 4, 5, 5, 4, 4, 3, 4, 4, 4, 4, 4, 4, 3,
4, 4, 4, 4, 4, 6, 4, 4, 4, 5, 4, 5, 8, 6, 6, 3,
- 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 8, 8, 2, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 5, 5, 4, 8, 8, 8, 7, 8, 8, 4, 4, 6, 4, 4, 3, 3,
+ 5, 4, 2, 8, 8, 8, 7, 8, 8, 4, 4, 6, 4, 4, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 4,
3, 3, 3, 3, 3, 3, 3, 5, 3, 7, 7, 7, 7, 0, 0, 3,
4, 5, 6, 7, 4, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 3, 5, 3,
- 5, 5, 5, 3, 3, 5, 5, 6, 3, 6, 6, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4,
- 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4,
+ 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 2, 4, 2,
+ 4, 4, 4, 2, 2, 4, 4, 6, 2, 5, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4,
2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8,
- 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 8, 3, 3, 3, 3,
+ 2, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 8, 3, 3, 3, 3,
10, 10, 10, 10, 8, 8, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -221,19 +221,19 @@ ALIGNED(4) const u8 gFontSmallNarrowerLatinGlyphWidths[] = {
3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4,
5, 4, 4, 4, 5, 4, 4, 4, 3, 4, 4, 4, 4, 4, 3, 3,
4, 4, 4, 4, 4, 6, 4, 4, 4, 5, 4, 4, 7, 5, 6, 3,
- 3, 3, 3, 3, 8, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 8, 0, 2, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 5, 4, 3, 7, 7, 7, 8, 8, 8, 8, 4, 5, 4, 4, 3, 3,
+ 5, 4, 2, 7, 7, 7, 8, 8, 8, 8, 4, 7, 5, 5, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 4,
3, 3, 3, 3, 3, 3, 3, 5, 3, 8, 8, 8, 8, 0, 0, 3,
4, 5, 6, 7, 4, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 3, 4, 4,
- 5, 5, 5, 3, 3, 5, 5, 5, 4, 5, 5, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4,
+ 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 2, 4, 2,
+ 4, 4, 4, 2, 2, 4, 4, 8, 2, 8, 5, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 3, 4,
2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
- 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 8, 3, 3, 3, 3,
+ 2, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 8, 3, 3, 3, 3,
8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
@@ -257,7 +257,7 @@ ALIGNED(4) const u8 gFontShortNarrowLatinGlyphWidths[] = {
3, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, 4, 5, 5, 5,
8, 5, 5, 5, 5, 6, 5, 5, 3, 5, 5, 5, 5, 5, 4, 3,
4, 4, 5, 5, 5, 8, 5, 5, 5, 5, 6, 6, 9, 6, 6, 3,
- 3, 3, 3, 3, 10, 8, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 10, 8, 5, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6, 6, 6, 8, 8, 8, 8, 8, 8, 4, 6, 8, 5, 5, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 6,
@@ -288,6 +288,42 @@ ALIGNED(4) const u8 gFontShortNarrowLatinGlyphWidths[] = {
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 3,
};
+ALIGNED(4) const u16 gFontShortNarrowerLatinGlyphs[] = INCBIN_U16("graphics/fonts/short_narrower.latfont");
+ALIGNED(4) const u8 gFontShortNarrowerLatinGlyphWidths[] = {
+ 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4,
+ 8, 4, 4, 4, 5, 5, 4, 4, 3, 4, 4, 4, 4, 4, 4, 3,
+ 4, 4, 4, 4, 4, 6, 4, 4, 4, 5, 4, 5, 8, 6, 6, 3,
+ 3, 3, 3, 3, 10, 8, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3,
+ 6, 6, 6, 8, 8, 8, 8, 8, 8, 4, 6, 8, 5, 5, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 4,
+ 3, 3, 3, 3, 3, 3, 3, 5, 3, 7, 7, 7, 7, 0, 0, 3,
+ 4, 5, 6, 7, 4, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 5, 4, 5,
+ 6, 6, 6, 3, 3, 6, 6, 8, 3, 9, 6, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4,
+ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8,
+ 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 10, 10, 10, 10, 8, 8, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 3,
+};
+
ALIGNED(4) const u16 gFontSmallJapaneseGlyphs[] = INCBIN_U16("graphics/fonts/small.hwjpnfont");
ALIGNED(4) const u16 gFontNormalJapaneseGlyphs[] = INCBIN_U16("graphics/fonts/normal.hwjpnfont");
diff --git a/src/frontier_util.c b/src/frontier_util.c
index 4424676644..30c22d4442 100644
--- a/src/frontier_util.c
+++ b/src/frontier_util.c
@@ -2543,7 +2543,7 @@ void CreateFrontierBrainPokemon(void)
for (j = 0; j < MAX_MON_MOVES; j++)
{
SetMonMoveSlot(&gEnemyParty[monPartyId], sFrontierBrainsMons[facility][symbol][i].moves[j], j);
- if (gMovesInfo[sFrontierBrainsMons[facility][symbol][i].moves[j]].effect == EFFECT_FRUSTRATION)
+ if (GetMoveEffect(sFrontierBrainsMons[facility][symbol][i].moves[j]) == EFFECT_FRUSTRATION)
friendship = 0;
}
SetMonData(&gEnemyParty[monPartyId], MON_DATA_FRIENDSHIP, &friendship);
diff --git a/src/generational_changes.c b/src/generational_changes.c
new file mode 100644
index 0000000000..1ad29aa675
--- /dev/null
+++ b/src/generational_changes.c
@@ -0,0 +1,19 @@
+#include "global.h"
+#include "generational_changes.h"
+#include "malloc.h"
+#include "constants/generational_changes.h"
+
+#if TESTING
+EWRAM_DATA u8 *gGenerationalChangesTestOverride = NULL;
+
+void TestInitConfigData(void)
+{
+ gGenerationalChangesTestOverride = Alloc(sizeof(sGenerationalChanges));
+ memcpy(gGenerationalChangesTestOverride, sGenerationalChanges, sizeof(sGenerationalChanges));
+}
+
+void TestFreeConfigData(void)
+{
+ TRY_FREE_AND_SET_NULL(gGenerationalChangesTestOverride)
+}
+#endif
diff --git a/src/item_icon.c b/src/item_icon.c
index 14a812b7fa..03b56918be 100644
--- a/src/item_icon.c
+++ b/src/item_icon.c
@@ -1,12 +1,13 @@
#include "global.h"
+#include "battle_main.h"
#include "decompress.h"
#include "graphics.h"
+#include "item.h"
#include "item_icon.h"
#include "malloc.h"
+#include "move.h"
#include "sprite.h"
#include "constants/items.h"
-#include "item.h"
-#include "battle_main.h"
// EWRAM vars
EWRAM_DATA u8 *gItemIconDecompressionBuffer = NULL;
@@ -182,7 +183,7 @@ const void *GetItemIconPalette(u16 itemId)
if (itemId >= ITEMS_COUNT)
return gItemsInfo[0].iconPalette;
if (itemId >= ITEM_TM01 && itemId < ITEM_HM01 + NUM_HIDDEN_MACHINES)
- return gTypesInfo[gMovesInfo[gItemsInfo[itemId].secondaryId].type].paletteTMHM;
+ return gTypesInfo[GetMoveType(gItemsInfo[itemId].secondaryId)].paletteTMHM;
return gItemsInfo[itemId].iconPalette;
}
diff --git a/src/item_menu.c b/src/item_menu.c
index d885f0a8ec..ff5d569f96 100755
--- a/src/item_menu.c
+++ b/src/item_menu.c
@@ -212,6 +212,12 @@ static void ConfirmSell(u8);
static void CancelSell(u8);
static void Task_FadeAndCloseBagMenuIfMulch(u8 taskId);
+static const u8 sText_Var1CantBeHeldHere[] = _("The {STR_VAR_1} can't be held\nhere.");
+static const u8 sText_DepositHowManyVar1[] = _("Deposit how many\n{STR_VAR_1}?");
+static const u8 sText_DepositedVar2Var1s[] = _("Deposited {STR_VAR_2}\n{STR_VAR_1}.");
+static const u8 sText_NoRoomForItems[] = _("There's no room to\nstore items.");
+static const u8 sText_CantStoreImportantItems[] = _("Important items\ncan't be stored in\nthe PC!");
+
static const struct BgTemplate sBgTemplates_ItemMenu[] =
{
{
@@ -266,20 +272,20 @@ static const struct ListMenuTemplate sItemListMenu =
};
static const struct MenuAction sItemMenuActions[] = {
- [ACTION_USE] = {gMenuText_Use, {ItemMenu_UseOutOfBattle}},
- [ACTION_TOSS] = {gMenuText_Toss, {ItemMenu_Toss}},
- [ACTION_REGISTER] = {gMenuText_Register, {ItemMenu_Register}},
- [ACTION_GIVE] = {gMenuText_Give, {ItemMenu_Give}},
- [ACTION_CANCEL] = {gText_Cancel2, {ItemMenu_Cancel}},
- [ACTION_BATTLE_USE] = {gMenuText_Use, {ItemMenu_UseInBattle}},
- [ACTION_CHECK] = {gMenuText_Check, {ItemMenu_UseOutOfBattle}},
- [ACTION_WALK] = {gMenuText_Walk, {ItemMenu_UseOutOfBattle}},
- [ACTION_DESELECT] = {gMenuText_Deselect, {ItemMenu_Register}},
- [ACTION_CHECK_TAG] = {gMenuText_CheckTag, {ItemMenu_CheckTag}},
- [ACTION_CONFIRM] = {gMenuText_Confirm, {Task_FadeAndCloseBagMenu}},
- [ACTION_SHOW] = {gMenuText_Show, {ItemMenu_Show}},
- [ACTION_GIVE_FAVOR_LADY] = {gMenuText_Give2, {ItemMenu_GiveFavorLady}},
- [ACTION_CONFIRM_QUIZ_LADY] = {gMenuText_Confirm, {ItemMenu_ConfirmQuizLady}},
+ [ACTION_USE] = {gMenuText_Use, {ItemMenu_UseOutOfBattle}},
+ [ACTION_TOSS] = {gMenuText_Toss, {ItemMenu_Toss}},
+ [ACTION_REGISTER] = {gMenuText_Register, {ItemMenu_Register}},
+ [ACTION_GIVE] = {gMenuText_Give, {ItemMenu_Give}},
+ [ACTION_CANCEL] = {gText_Cancel2, {ItemMenu_Cancel}},
+ [ACTION_BATTLE_USE] = {gMenuText_Use, {ItemMenu_UseInBattle}},
+ [ACTION_CHECK] = {COMPOUND_STRING("CHECK"), {ItemMenu_UseOutOfBattle}},
+ [ACTION_WALK] = {COMPOUND_STRING("WALK"), {ItemMenu_UseOutOfBattle}},
+ [ACTION_DESELECT] = {COMPOUND_STRING("DESELECT"), {ItemMenu_Register}},
+ [ACTION_CHECK_TAG] = {COMPOUND_STRING("CHECK TAG"), {ItemMenu_CheckTag}},
+ [ACTION_CONFIRM] = {gMenuText_Confirm, {Task_FadeAndCloseBagMenu}},
+ [ACTION_SHOW] = {COMPOUND_STRING("SHOW"), {ItemMenu_Show}},
+ [ACTION_GIVE_FAVOR_LADY] = {gMenuText_Give2, {ItemMenu_GiveFavorLady}},
+ [ACTION_CONFIRM_QUIZ_LADY] = {gMenuText_Confirm, {ItemMenu_ConfirmQuizLady}},
[ACTION_DUMMY] = {gText_EmptyString2, {NULL}}
};
@@ -910,7 +916,7 @@ static void GetItemName(u8 *dest, u16 itemId)
{
case TMHM_POCKET:
end = StringCopy(gStringVar2, GetMoveName(ItemIdToBattleMoveId(itemId)));
- PrependFontIdToFit(gStringVar2, end, FONT_NARROW, 73);
+ PrependFontIdToFit(gStringVar2, end, FONT_NARROW, 61);
if (itemId >= ITEM_HM01)
{
// Get HM number
@@ -927,7 +933,7 @@ static void GetItemName(u8 *dest, u16 itemId)
case BERRIES_POCKET:
ConvertIntToDecimalStringN(gStringVar1, itemId - FIRST_BERRY_INDEX + 1, STR_CONV_MODE_LEADING_ZEROS, 2);
end = CopyItemName(itemId, gStringVar2);
- PrependFontIdToFit(gStringVar2, end, FONT_NARROW, 73);
+ PrependFontIdToFit(gStringVar2, end, FONT_NARROW, 61);
StringExpandPlaceholders(dest, gText_NumberItem_TMBerry);
break;
default:
@@ -2038,7 +2044,7 @@ static void Task_ItemContext_GiveToParty(u8 taskId)
else if (!IsHoldingItemAllowed(gSpecialVar_ItemId))
{
CopyItemName(gSpecialVar_ItemId, gStringVar1);
- StringExpandPlaceholders(gStringVar4, gText_Var1CantBeHeldHere);
+ StringExpandPlaceholders(gStringVar4, sText_Var1CantBeHeldHere);
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, HandleErrorMessage);
}
else if (gBagPosition.pocket != KEYITEMS_POCKET && !ItemId_GetImportance(gSpecialVar_ItemId))
@@ -2236,7 +2242,7 @@ static void Task_ItemContext_Deposit(u8 taskId)
{
u8 *end = CopyItemNameHandlePlural(gSpecialVar_ItemId, gStringVar1, 2);
WrapFontIdToFit(gStringVar1, end, FONT_NORMAL, WindowWidthPx(WIN_DESCRIPTION) - 10 - 6);
- StringExpandPlaceholders(gStringVar4, gText_DepositHowManyVar1);
+ StringExpandPlaceholders(gStringVar4, sText_DepositHowManyVar1);
FillWindowPixelBuffer(WIN_DESCRIPTION, PIXEL_FILL(0));
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
AddItemQuantityWindow(ITEMWIN_QUANTITY);
@@ -2276,7 +2282,7 @@ static void TryDepositItem(u8 taskId)
if (ItemId_GetImportance(gSpecialVar_ItemId))
{
// Can't deposit important items
- BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gText_CantStoreImportantItems, 3, 1, 0, 0, 0, COLORID_NORMAL);
+ BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, sText_CantStoreImportantItems, 3, 1, 0, 0, 0, COLORID_NORMAL);
gTasks[taskId].func = WaitDepositErrorMessage;
}
else if (AddPCItem(gSpecialVar_ItemId, tItemCount) == TRUE)
@@ -2285,14 +2291,14 @@ static void TryDepositItem(u8 taskId)
u8 *end = CopyItemNameHandlePlural(gSpecialVar_ItemId, gStringVar1, tItemCount);
WrapFontIdToFit(gStringVar1, end, FONT_NORMAL, WindowWidthPx(WIN_DESCRIPTION) - 10 - 6);
ConvertIntToDecimalStringN(gStringVar2, tItemCount, STR_CONV_MODE_LEFT_ALIGN, MAX_ITEM_DIGITS);
- StringExpandPlaceholders(gStringVar4, gText_DepositedVar2Var1s);
+ StringExpandPlaceholders(gStringVar4, sText_DepositedVar2Var1s);
BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gStringVar4, 3, 1, 0, 0, 0, COLORID_NORMAL);
gTasks[taskId].func = Task_RemoveItemFromBag;
}
else
{
// No room to deposit
- BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, gText_NoRoomForItems, 3, 1, 0, 0, 0, COLORID_NORMAL);
+ BagMenu_Print(WIN_DESCRIPTION, FONT_NORMAL, sText_NoRoomForItems, 3, 1, 0, 0, 0, COLORID_NORMAL);
gTasks[taskId].func = WaitDepositErrorMessage;
}
}
@@ -2598,34 +2604,36 @@ static void PrintTMHMMoveData(u16 itemId)
else
{
moveId = ItemIdToBattleMoveId(itemId);
- BlitMenuInfoIcon(WIN_TMHM_INFO, gMovesInfo[moveId].type + 1, 0, 0);
+ BlitMenuInfoIcon(WIN_TMHM_INFO, GetMoveType(moveId) + 1, 0, 0);
// Print TMHM power
- if (gMovesInfo[moveId].power <= 1)
+ u32 power = GetMovePower(moveId);
+ if (power <= 1)
{
text = gText_ThreeDashes;
}
else
{
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveId].power, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, power, STR_CONV_MODE_RIGHT_ALIGN, 3);
text = gStringVar1;
}
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, text, 7, 12, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
+ u32 accuracy = GetMoveAccuracy(moveId);
// Print TMHM accuracy
- if (gMovesInfo[moveId].accuracy == 0)
+ if (accuracy == 0)
{
text = gText_ThreeDashes;
}
else
{
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveId].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
text = gStringVar1;
}
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, text, 7, 24, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
// Print TMHM pp
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveId].pp, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, GetMovePP(moveId), STR_CONV_MODE_RIGHT_ALIGN, 3);
BagMenu_Print(WIN_TMHM_INFO, FONT_NORMAL, gStringVar1, 7, 36, 0, 0, TEXT_SKIP_DRAW, COLORID_TMHM_INFO);
CopyWindowToVram(WIN_TMHM_INFO, COPYWIN_GFX);
diff --git a/src/item_use.c b/src/item_use.c
index c04d9b9911..64db57a16d 100644
--- a/src/item_use.c
+++ b/src/item_use.c
@@ -80,6 +80,21 @@ static void CB2_OpenPokeblockFromBag(void);
static void ItemUseOnFieldCB_Honey(u8 taskId);
static bool32 IsValidLocationForVsSeeker(void);
+static const u8 sText_CantDismountBike[] = _("You can't dismount your BIKE here.{PAUSE_UNTIL_PRESS}");
+static const u8 sText_ItemFinderNearby[] = _("Huh?\nThe ITEMFINDER's responding!\pThere's an item buried around here!{PAUSE_UNTIL_PRESS}");
+static const u8 sText_ItemFinderOnTop[] = _("Oh!\nThe ITEMFINDER's shaking wildly!{PAUSE_UNTIL_PRESS}");
+static const u8 sText_ItemFinderNothing[] = _("… … … …Nope!\nThere's no response.{PAUSE_UNTIL_PRESS}");
+static const u8 sText_CoinCase[] = _("Your COINS:\n{STR_VAR_1}{PAUSE_UNTIL_PRESS}");
+static const u8 sText_PowderQty[] = _("POWDER QTY: {STR_VAR_1}{PAUSE_UNTIL_PRESS}");
+static const u8 sText_BootedUpTM[] = _("Booted up a TM.");
+static const u8 sText_BootedUpHM[] = _("Booted up an HM.");
+static const u8 sText_TMHMContainedVar1[] = _("It contained\n{STR_VAR_1}.\pTeach {STR_VAR_1}\nto a POKéMON?");
+static const u8 sText_UsedVar2WildLured[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be lured.{PAUSE_UNTIL_PRESS}");
+static const u8 sText_UsedVar2WildRepelled[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be repelled.{PAUSE_UNTIL_PRESS}");
+static const u8 sText_PlayedPokeFluteCatchy[] = _("Played the POKé FLUTE.\pNow, that's a catchy tune!{PAUSE_UNTIL_PRESS}");
+static const u8 sText_PlayedPokeFlute[] = _("Played the POKé FLUTE.");
+static const u8 sText_PokeFluteAwakenedMon[] = _("The POKé FLUTE awakened sleeping\nPOKéMON.{PAUSE_UNTIL_PRESS}");
+
// EWRAM variables
EWRAM_DATA static void(*sItemUseOnFieldCB)(u8 taskId) = NULL;
@@ -132,7 +147,9 @@ static void SetUpItemUseOnFieldCallback(u8 taskId)
SetUpItemUseCallback(taskId);
}
else
+ {
sItemUseOnFieldCB(taskId);
+ }
}
static void FieldCB_UseItemOnField(void)
@@ -158,7 +175,9 @@ static void DisplayCannotUseItemMessage(u8 taskId, bool8 isUsingRegisteredKeyIte
DisplayItemMessageInBattlePyramid(taskId, gText_DadsAdvice, Task_CloseBattlePyramidBagMessage);
}
else
+ {
DisplayItemMessageOnField(taskId, gStringVar4, Task_CloseCantUseKeyItemMessage);
+ }
}
void DisplayDadsAdviceCannotUseItemMessage(u8 taskId, bool8 isUsingRegisteredKeyItemOnField)
@@ -168,7 +187,7 @@ void DisplayDadsAdviceCannotUseItemMessage(u8 taskId, bool8 isUsingRegisteredKey
static void DisplayCannotDismountBikeMessage(u8 taskId, bool8 isUsingRegisteredKeyItemOnField)
{
- DisplayCannotUseItemMessage(taskId, isUsingRegisteredKeyItemOnField, gText_CantDismountBike);
+ DisplayCannotUseItemMessage(taskId, isUsingRegisteredKeyItemOnField, sText_CantDismountBike);
}
static void Task_CloseCantUseKeyItemMessage(u8 taskId)
@@ -239,7 +258,9 @@ void ItemUseOutOfBattle_Bike(u8 taskId)
PlayerGetDestCoords(&coordsX, &coordsY);
behavior = MapGridGetMetatileBehaviorAt(coordsX, coordsY);
if (FlagGet(FLAG_SYS_CYCLING_ROAD) == TRUE || MetatileBehavior_IsVerticalRail(behavior) == TRUE || MetatileBehavior_IsHorizontalRail(behavior) == TRUE || MetatileBehavior_IsIsolatedVerticalRail(behavior) == TRUE || MetatileBehavior_IsIsolatedHorizontalRail(behavior) == TRUE)
+ {
DisplayCannotDismountBikeMessage(taskId, tUsingRegisteredKeyItem);
+ }
else
{
if (Overworld_IsBikingAllowed() == TRUE && IsBikingDisallowedByPlayer() == 0)
@@ -248,7 +269,9 @@ void ItemUseOutOfBattle_Bike(u8 taskId)
SetUpItemUseOnFieldCallback(taskId);
}
else
+ {
DisplayDadsAdviceCannotUseItemMessage(taskId, tUsingRegisteredKeyItem);
+ }
}
}
@@ -301,7 +324,9 @@ void ItemUseOutOfBattle_Rod(u8 taskId)
SetUpItemUseOnFieldCallback(taskId);
}
else
+ {
DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
+ }
}
static void ItemUseOnFieldCB_Rod(u8 taskId)
@@ -322,7 +347,7 @@ static void ItemUseOnFieldCB_Itemfinder(u8 taskId)
if (ItemfinderCheckForHiddenItems(gMapHeader.events, taskId) == TRUE)
gTasks[taskId].func = Task_UseItemfinder;
else
- DisplayItemMessageOnField(taskId, gText_ItemFinderNothing, Task_CloseItemfinderMessage);
+ DisplayItemMessageOnField(taskId, sText_ItemFinderNothing, Task_CloseItemfinderMessage);
}
// Define itemfinder task data
@@ -615,7 +640,7 @@ static void PlayerFaceHiddenItem(u8 direction)
static void Task_HiddenItemNearby(u8 taskId)
{
if (ObjectEventCheckHeldMovementStatus(&gObjectEvents[GetObjectEventIdByLocalIdAndMap(OBJ_EVENT_ID_PLAYER, 0, 0)]) == TRUE)
- DisplayItemMessageOnField(taskId, gText_ItemFinderNearby, Task_CloseItemfinderMessage);
+ DisplayItemMessageOnField(taskId, sText_ItemFinderNearby, Task_CloseItemfinderMessage);
}
static void Task_StandingOnHiddenItem(u8 taskId)
@@ -632,7 +657,7 @@ static void Task_StandingOnHiddenItem(u8 taskId)
tCounter++;
if (tCounter == 4)
- DisplayItemMessageOnField(taskId, gText_ItemFinderOnTop, Task_CloseItemfinderMessage);
+ DisplayItemMessageOnField(taskId, sText_ItemFinderOnTop, Task_CloseItemfinderMessage);
}
}
@@ -693,7 +718,7 @@ static void Task_AccessPokemonBoxLink(u8 taskId)
void ItemUseOutOfBattle_CoinCase(u8 taskId)
{
ConvertIntToDecimalStringN(gStringVar1, GetCoins(), STR_CONV_MODE_LEFT_ALIGN, 4);
- StringExpandPlaceholders(gStringVar4, gText_CoinCase);
+ StringExpandPlaceholders(gStringVar4, sText_CoinCase);
if (!gTasks[taskId].tUsingRegisteredKeyItem)
{
@@ -708,7 +733,7 @@ void ItemUseOutOfBattle_CoinCase(u8 taskId)
void ItemUseOutOfBattle_PowderJar(u8 taskId)
{
ConvertIntToDecimalStringN(gStringVar1, GetBerryPowder(), STR_CONV_MODE_LEFT_ALIGN, 5);
- StringExpandPlaceholders(gStringVar4, gText_PowderQty);
+ StringExpandPlaceholders(gStringVar4, sText_PowderQty);
if (!gTasks[taskId].tUsingRegisteredKeyItem)
{
@@ -858,9 +883,9 @@ void ItemUseOutOfBattle_DynamaxCandy(u8 taskId)
void ItemUseOutOfBattle_TMHM(u8 taskId)
{
if (gSpecialVar_ItemId >= ITEM_HM01)
- DisplayItemMessage(taskId, FONT_NORMAL, gText_BootedUpHM, BootUpSoundTMHM); // HM
+ DisplayItemMessage(taskId, FONT_NORMAL, sText_BootedUpHM, BootUpSoundTMHM); // HM
else
- DisplayItemMessage(taskId, FONT_NORMAL, gText_BootedUpTM, BootUpSoundTMHM); // TM
+ DisplayItemMessage(taskId, FONT_NORMAL, sText_BootedUpTM, BootUpSoundTMHM); // TM
}
static void BootUpSoundTMHM(u8 taskId)
@@ -874,7 +899,7 @@ static void Task_ShowTMHMContainedMessage(u8 taskId)
if (JOY_NEW(A_BUTTON | B_BUTTON))
{
StringCopy(gStringVar1, GetMoveName(ItemIdToBattleMoveId(gSpecialVar_ItemId)));
- StringExpandPlaceholders(gStringVar4, gText_TMHMContainedVar1);
+ StringExpandPlaceholders(gStringVar4, sText_TMHMContainedVar1);
DisplayItemMessage(taskId, FONT_NORMAL, gStringVar4, UseTMHMYesNo);
}
}
@@ -1015,13 +1040,13 @@ void ItemUseOutOfBattle_BlackWhiteFlute(u8 taskId)
{
FlagSet(FLAG_SYS_ENC_UP_ITEM);
FlagClear(FLAG_SYS_ENC_DOWN_ITEM);
- StringExpandPlaceholders(gStringVar4, gText_UsedVar2WildLured);
+ StringExpandPlaceholders(gStringVar4, sText_UsedVar2WildLured);
}
else
{
FlagSet(FLAG_SYS_ENC_DOWN_ITEM);
FlagClear(FLAG_SYS_ENC_UP_ITEM);
- StringExpandPlaceholders(gStringVar4, gText_UsedVar2WildRepelled);
+ StringExpandPlaceholders(gStringVar4, sText_UsedVar2WildRepelled);
}
gTasks[taskId].data[8] = 0;
gTasks[taskId].func = Task_UsedBlackWhiteFlute;
@@ -1400,9 +1425,17 @@ void ItemUseOutOfBattle_ZygardeCube(u8 taskId)
void ItemUseOutOfBattle_Fusion(u8 taskId)
{
- gItemUseCB = ItemUseCB_Fusion;
- gTasks[taskId].data[0] = FALSE;
- SetUpItemUseCallback(taskId);
+ if (!gTasks[taskId].tUsingRegisteredKeyItem)
+ {
+ gItemUseCB = ItemUseCB_Fusion;
+ gTasks[taskId].data[0] = FALSE;
+ SetUpItemUseCallback(taskId);
+ }
+ else
+ {
+ // TODO: handle key items with callbacks to menus allow to be used by registering them.
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
+ }
}
void Task_UseHoneyOnField(u8 taskId)
@@ -1504,9 +1537,9 @@ static void Task_DisplayPokeFluteMessage(u8 taskId)
if (WaitFanfare(FALSE))
{
if (gTasks[taskId].data[3] == 0)
- DisplayItemMessage(taskId, FONT_NORMAL, gText_PokeFluteAwakenedMon, CloseItemMessage);
+ DisplayItemMessage(taskId, FONT_NORMAL, sText_PokeFluteAwakenedMon, CloseItemMessage);
else
- DisplayItemMessageOnField(taskId, gText_PokeFluteAwakenedMon, Task_CloseCantUseKeyItemMessage);
+ DisplayItemMessageOnField(taskId, sText_PokeFluteAwakenedMon, Task_CloseCantUseKeyItemMessage);
}
}
@@ -1530,16 +1563,16 @@ void ItemUseOutOfBattle_PokeFlute(u8 taskId)
if (wokeSomeoneUp)
{
if (gTasks[taskId].data[3] == 0)
- DisplayItemMessage(taskId, FONT_NORMAL, gText_PlayedPokeFlute, Task_PlayPokeFlute);
+ DisplayItemMessage(taskId, FONT_NORMAL, sText_PlayedPokeFlute, Task_PlayPokeFlute);
else
- DisplayItemMessageOnField(taskId, gText_PlayedPokeFlute, Task_PlayPokeFlute);
+ DisplayItemMessageOnField(taskId, sText_PlayedPokeFlute, Task_PlayPokeFlute);
}
else
{
if (gTasks[taskId].data[3] == 0)
- DisplayItemMessage(taskId, FONT_NORMAL, gText_PlayedPokeFluteCatchy, CloseItemMessage);
+ DisplayItemMessage(taskId, FONT_NORMAL, sText_PlayedPokeFluteCatchy, CloseItemMessage);
else
- DisplayItemMessageOnField(taskId, gText_PlayedPokeFluteCatchy, Task_CloseCantUseKeyItemMessage);
+ DisplayItemMessageOnField(taskId, sText_PlayedPokeFluteCatchy, Task_CloseCantUseKeyItemMessage);
}
}
@@ -1552,10 +1585,18 @@ static void ItemUseOnFieldCB_TownMap(u8 taskId)
void ItemUseOutOfBattle_TownMap(u8 taskId)
{
- sItemUseOnFieldCB = ItemUseOnFieldCB_TownMap;
- gFieldCallback = FieldCB_UseItemOnField;
- gBagMenu->newScreenCallback = CB2_ReturnToField;
- Task_FadeAndCloseBagMenu(taskId);
+ if (!gTasks[taskId].tUsingRegisteredKeyItem)
+ {
+ sItemUseOnFieldCB = ItemUseOnFieldCB_TownMap;
+ gFieldCallback = FieldCB_UseItemOnField;
+ gBagMenu->newScreenCallback = CB2_ReturnToField;
+ Task_FadeAndCloseBagMenu(taskId);
+ }
+ else
+ {
+ // TODO: handle key items with callbacks to menus allow to be used by registering them.
+ DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);
+ }
}
#undef tUsingRegisteredKeyItem
diff --git a/src/librfu_sio32id.c b/src/librfu_sio32id.c
index 2a1b0c94c4..45b1bc33de 100644
--- a/src/librfu_sio32id.c
+++ b/src/librfu_sio32id.c
@@ -145,7 +145,9 @@ static void Sio32IDIntr(void)
}
}
else
+ {
gRfuSIO32Id.lastId = regSIODATA32;
+ }
}
else
{
diff --git a/src/line_break.c b/src/line_break.c
new file mode 100644
index 0000000000..b8888f501f
--- /dev/null
+++ b/src/line_break.c
@@ -0,0 +1,281 @@
+#include "global.h"
+#include "line_break.h"
+#include "text.h"
+#include "malloc.h"
+
+void StripLineBreaks(u8 *src)
+{
+ u32 currIndex = 0;
+ while (src[currIndex] != EOS)
+ {
+ if (src[currIndex] == CHAR_PROMPT_SCROLL || src[currIndex] == CHAR_NEWLINE)
+ src[currIndex] = CHAR_SPACE;
+ currIndex++;
+ }
+}
+
+void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId)
+{
+ u32 currIndex = 0;
+ u8 *currSrc = src;
+ while (src[currIndex] != EOS)
+ {
+ if (src[currIndex] == CHAR_PROMPT_CLEAR)
+ {
+ u8 replacedChar = src[currIndex + 1];
+ src[currIndex + 1] = EOS;
+ BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId);
+ src[currIndex + 1] = replacedChar;
+ currSrc = &src[currIndex + 1];
+ }
+ currIndex++;
+ }
+ BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId);
+}
+
+void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId)
+{
+ // If the string already has line breaks, don't interfere with them
+ if (StringHasManualBreaks(src))
+ return;
+ // Sanity check
+ if (src[0] == EOS)
+ return;
+ u32 numChars = 1;
+ u32 numWords = 1;
+ u32 currWordIndex = 0;
+ u32 currWordLength = 1;
+ bool32 isPrevCharSplitting = FALSE;
+ bool32 isCurrCharSplitting;
+ // Get numbers of chars in string and count words
+ while (src[numChars] != EOS)
+ {
+ isCurrCharSplitting = IsWordSplittingChar(src, numChars);
+ if (isCurrCharSplitting && !isPrevCharSplitting)
+ numWords++;
+ isPrevCharSplitting = isCurrCharSplitting;
+ numChars++;
+ }
+ // Allocate enough space for word data
+ struct StringWord *allWords = Alloc(numWords*sizeof(struct StringWord));
+
+ allWords[currWordIndex].startIndex = 0;
+ allWords[currWordIndex].width = 0;
+ isPrevCharSplitting = FALSE;
+ // Fill in word begin index and lengths
+ for (u32 i = 1; i < numChars; i++)
+ {
+ isCurrCharSplitting = IsWordSplittingChar(src, i);
+ if (isCurrCharSplitting && !isPrevCharSplitting)
+ {
+ allWords[currWordIndex].length = currWordLength;
+ currWordIndex++;
+ currWordLength = 0;
+ }
+ else if (!isCurrCharSplitting && isPrevCharSplitting)
+ {
+ allWords[currWordIndex].startIndex = i;
+ allWords[currWordIndex].width = 0;
+ currWordLength++;
+ }
+ else
+ {
+ currWordLength++;
+ }
+ isPrevCharSplitting = isCurrCharSplitting;
+ }
+ allWords[currWordIndex].length = currWordLength;
+
+ // Fill in individual word widths
+ for (u32 i = 0; i < numWords; i++)
+ {
+ for (u32 j = 0; j < allWords[i].length; j++)
+ allWords[i].width += GetGlyphWidth(src[allWords[i].startIndex + j], FALSE, fontId);
+ }
+
+ // Step 1: Does it all fit one one line? Then no break
+ // Step 2: Try to split across minimum number of lines
+ u32 spaceWidth = GetGlyphWidth(0, FALSE, fontId);
+ u32 totalWidth = allWords[0].width;
+ // Calculate total widths without any line breaks
+ for (u32 i = 1; i < numWords; i++)
+ totalWidth += allWords[i].width + spaceWidth;
+
+ // If it doesn't fit on 1 line, do fancy line break calculation
+ // NOTE: Currently the line break calculation isn't fancy
+ if (totalWidth > maxWidth)
+ {
+ // Figure out how many lines are needed with naive method
+ u32 currLineWidth = 0;
+ u32 totalLines = 1;
+ bool32 shouldTryAgain;
+ for (currWordIndex = 0; currWordIndex < numWords; currWordIndex++)
+ {
+ if (currLineWidth + allWords[currWordIndex].length > maxWidth)
+ {
+ totalLines++;
+ currLineWidth = allWords[currWordIndex].width;
+ }
+ else
+ {
+ currLineWidth += allWords[currWordIndex].width + spaceWidth;
+ }
+ }
+ // LINE LAYOUT STARTS HERE
+ struct StringLine *stringLines;
+ do
+ {
+ shouldTryAgain = FALSE;
+ u16 targetLineWidth = totalWidth/totalLines;
+ stringLines = Alloc(totalLines*sizeof(struct StringLine));
+ for (u32 lineIndex = 0; lineIndex < totalLines; lineIndex++)
+ {
+ stringLines[lineIndex].numWords = 0;
+ stringLines[lineIndex].spaceWidth = spaceWidth;
+ stringLines[lineIndex].extraSpaceWidth = 0;
+ }
+ currWordIndex = 0;
+ u16 currLineIndex = 0;
+ stringLines[currLineIndex].words = &allWords[currWordIndex];
+ stringLines[currLineIndex].numWords = 1;
+ currLineWidth = allWords[currWordIndex].width;
+ currWordIndex++;
+ while (currWordIndex < numWords)
+ {
+ if (currLineWidth + spaceWidth + allWords[currWordIndex].width > maxWidth)
+ {
+ // go to next line
+ currLineIndex++;
+ if (currLineIndex == totalLines)
+ {
+ totalLines++;
+ Free(stringLines);
+ shouldTryAgain = TRUE;
+ break;
+ }
+ stringLines[currLineIndex].words = &allWords[currWordIndex];
+ stringLines[currLineIndex].numWords = 1;
+ currLineWidth = allWords[currWordIndex].width;
+ currWordIndex++;
+ }
+ else if (currLineWidth > targetLineWidth)
+ {
+ // go to next line
+ currLineIndex++;
+ if (currLineIndex == totalLines)
+ {
+ totalLines++;
+ Free(stringLines);
+ shouldTryAgain = TRUE;
+ break;
+ }
+ stringLines[currLineIndex].words = &allWords[currWordIndex];
+ stringLines[currLineIndex].numWords = 1;
+ currLineWidth = allWords[currWordIndex].width;
+ currWordIndex++;
+ }
+ else
+ {
+ // continue on current line
+ // add word and space width
+ currLineWidth += spaceWidth + allWords[currWordIndex].width;
+ stringLines[currLineIndex].numWords++;
+ currWordIndex++;
+ }
+ }
+ } while (shouldTryAgain);
+ //u32 currBadness = GetStringBadness(stringLines, totalLines, maxWidth);
+ BuildNewString(stringLines, totalLines, screenLines, src);
+ Free(stringLines);
+ }
+
+ Free(allWords);
+}
+
+// Only allow word splitting on allowed chars
+bool32 IsWordSplittingChar(const u8 *src, u32 index)
+{
+ switch (src[index])
+ {
+ case CHAR_SPACE:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+// Badness calculation
+// unfilled lines scale linerarly
+// jagged lines scales by the square
+// runts scale linearly
+// numbers not final
+// ISN'T ACTUALLY USED RIGHT NOW
+u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth)
+{
+ u32 badness = 0;
+ u32 *lineWidths = Alloc(numLines*4);
+ u32 widestWidth = 0;
+ for (u32 i = 0; i < numLines; i++)
+ {
+ lineWidths[i] = 0;
+ for (u32 j = 0; j < stringLines[i].numWords; j++)
+ lineWidths[i] += stringLines[i].words[j].width;
+ lineWidths[i] += (stringLines[i].numWords-1)*stringLines[i].spaceWidth;
+ if (lineWidths[i] > widestWidth)
+ widestWidth = lineWidths[i];
+ if (stringLines[i].numWords == 1)
+ badness += BADNESS_RUNT;
+ }
+ for (u32 i = 0; i < numLines; i++)
+ {
+ u32 extraSpaceWidth = 0;
+ if (lineWidths[i] != widestWidth)
+ {
+ // Not the best way to do this, ideally a line should be allowed to get longer than current widest
+ // line. But then the widest line has to be recalculated.
+ while (lineWidths[i] + (extraSpaceWidth + 1) * (stringLines[i].numWords - 1) < widestWidth && extraSpaceWidth < MAX_SPACE_WIDTH)
+ extraSpaceWidth++;
+ lineWidths[i] += extraSpaceWidth*(stringLines[i].numWords-1);
+ }
+ badness += (maxWidth - lineWidths[i]) * BADNESS_UNFILLED;
+ u32 baseBadness = (widestWidth - lineWidths[i]) * BADNESS_JAGGED;
+ badness += baseBadness*baseBadness;
+ stringLines[i].extraSpaceWidth = extraSpaceWidth;
+ }
+ Free(lineWidths);
+ return badness;
+}
+
+// Build the new string from the data stored in the StringLine structs
+void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str)
+{
+ u32 srcCharIndex = 0;
+ for (u32 lineIndex = 0; lineIndex < numLines; lineIndex++)
+ {
+ srcCharIndex += stringLines[lineIndex].words[0].length;
+ for (u32 wordIndex = 1; wordIndex < stringLines[lineIndex].numWords; wordIndex++)
+ // Add length of word and a space
+ srcCharIndex += stringLines[lineIndex].words[wordIndex].length + 1;
+ if (lineIndex + 1 < numLines)
+ {
+ // Add the appropriate line break depending on line number
+ if (lineIndex >= maxLines - 1 && numLines > maxLines)
+ str[srcCharIndex] = CHAR_PROMPT_SCROLL;
+ else
+ str[srcCharIndex] = CHAR_NEWLINE;
+ srcCharIndex++;
+ }
+ }
+}
+
+bool32 StringHasManualBreaks(u8 *src)
+{
+ u32 charIndex = 0;
+ while (src[charIndex] != EOS)
+ {
+ if (src[charIndex] == CHAR_PROMPT_SCROLL || src[charIndex] == CHAR_NEWLINE)
+ return TRUE;
+ charIndex++;
+ }
+ return FALSE;
+}
diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c
index 4c4323c1ed..6b20cf9678 100644
--- a/src/link_rfu_2.c
+++ b/src/link_rfu_2.c
@@ -1175,7 +1175,9 @@ static void RfuHandleReceiveCommand(u8 unused)
gRfu.numBlocksReceived[i] = 0;
}
else
+ {
gRfu.numBlocksReceived[i]++;
+ }
}
}
}
@@ -1302,7 +1304,9 @@ bool32 Rfu_InitBlockSend(const u8 *src, size_t size)
gRfu.sendBlock.count = (size / 12) + r4;
gRfu.sendBlock.next = 0;
if (size > BLOCK_BUFFER_SIZE)
+ {
gRfu.sendBlock.payload = src;
+ }
else
{
if (src != gBlockSendBuffer)
@@ -1629,9 +1633,8 @@ static bool8 CheckForLeavingGroupMembers(void)
}
else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED)
- rfu_clearSlot(TYPE_NI_RECV, i);
{
-
+ rfu_clearSlot(TYPE_NI_RECV, i);
}
}
}
@@ -1777,7 +1780,9 @@ static void Task_PlayerExchange(u8 taskId)
gTasks[taskId].tState = 101;
}
else
+ {
gTasks[taskId].tState = 2;
+ }
break;
case 101:
if (gSendCmd[0] == 0)
@@ -1798,7 +1803,9 @@ static void Task_PlayerExchange(u8 taskId)
}
}
else
+ {
gTasks[taskId].tState++;
+ }
break;
case 4:
if (AreAllPlayersFinishedReceiving())
diff --git a/src/lottery_corner.c b/src/lottery_corner.c
index 4e58c22858..1f2b3a4052 100644
--- a/src/lottery_corner.c
+++ b/src/lottery_corner.c
@@ -74,7 +74,9 @@ void PickLotteryCornerTicket(void)
}
}
else // Pokémon are always arranged from populated spots first to unpopulated, so the moment a NONE species is found, that's the end of the list.
+ {
break;
+ }
}
for (i = 0; i < TOTAL_BOXES_COUNT; i++)
@@ -132,7 +134,9 @@ static u8 GetMatchingDigits(u16 winNumber, u16 otId)
matchingDigits++;
}
else
+ {
break;
+ }
}
return matchingDigits;
}
diff --git a/src/main_menu.c b/src/main_menu.c
index 504fbfb186..bae80e543a 100644
--- a/src/main_menu.c
+++ b/src/main_menu.c
@@ -255,7 +255,6 @@ static const u16 sBirchSpeechBgPals[][16] = {
static const u32 sBirchSpeechShadowGfx[] = INCBIN_U32("graphics/birch_speech/shadow.4bpp.lz");
static const u32 sBirchSpeechBgMap[] = INCBIN_U32("graphics/birch_speech/map.bin.lz");
static const u16 sBirchSpeechBgGradientPal[] = INCBIN_U16("graphics/birch_speech/bg2.gbapal");
-static const u16 sBirchSpeechPlatformBlackPal[] = {RGB_BLACK, RGB_BLACK, RGB_BLACK, RGB_BLACK, RGB_BLACK, RGB_BLACK, RGB_BLACK, RGB_BLACK};
static const u8 gText_SaveFileCorrupted[] = _("The save file is corrupted. The\nprevious save file will be loaded.");
static const u8 gText_SaveFileErased[] = _("The save file has been erased\ndue to corruption or damage.");
@@ -1298,7 +1297,7 @@ static void Task_NewGameBirchSpeech_Init(u8 taskId)
LZ77UnCompVram(sBirchSpeechShadowGfx, (void *)VRAM);
LZ77UnCompVram(sBirchSpeechBgMap, (void *)(BG_SCREEN_ADDR(7)));
LoadPalette(sBirchSpeechBgPals, BG_PLTT_ID(0), 2 * PLTT_SIZE_4BPP);
- LoadPalette(sBirchSpeechPlatformBlackPal, BG_PLTT_ID(0) + 1, PLTT_SIZEOF(8));
+ LoadPalette(&sBirchSpeechBgGradientPal[8], BG_PLTT_ID(0) + 1, PLTT_SIZEOF(8));
ScanlineEffect_Stop();
ResetSpriteData();
FreeAllSpritePalettes();
diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c
index efadd4de1f..8b8bfb2db5 100644
--- a/src/mauville_old_man.c
+++ b/src/mauville_old_man.c
@@ -477,7 +477,9 @@ static void BardSing(struct Task *task, struct BardSong *song)
GetWordPhonemes(song, MACRO1(word));
song->currWord++;
if (song->sound->songLengthId != 0xFF)
+ {
song->state = 0;
+ }
else
{
song->state = 3;
@@ -527,7 +529,9 @@ static void BardSing(struct Task *task, struct BardSong *song)
{
song->currPhoneme++;
if (song->currPhoneme != 6 && song->sound[song->currPhoneme].songLengthId != 0xFF)
+ {
song->state = 0;
+ }
else
{
song->state = 3;
@@ -846,7 +850,9 @@ void SanitizeReceivedRubyOldMan(union OldMan * oldMan, u32 version, u32 language
trader->language[i] = LANGUAGE_JAPANESE;
}
else
+ {
trader->language[i] = language;
+ }
}
}
else
diff --git a/src/menu_specialized.c b/src/menu_specialized.c
index 693e9f12bc..7b6d94b5f2 100644
--- a/src/menu_specialized.c
+++ b/src/menu_specialized.c
@@ -10,6 +10,7 @@
#include "international_string_util.h"
#include "menu.h"
#include "menu_specialized.h"
+#include "move.h"
#include "move_relearner.h"
#include "palette.h"
#include "player_pc.h"
@@ -752,7 +753,6 @@ u8 LoadMoveRelearnerMovesList(const struct ListMenuItem *items, u16 numChoices)
static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove)
{
s32 x;
- const struct MoveInfo *move;
u8 buffer[32];
const u8 *str;
@@ -780,49 +780,41 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove)
CopyWindowToVram(RELEARNERWIN_DESC_BATTLE, COPYWIN_GFX);
return;
}
- move = &gMovesInfo[chosenMove];
- str = gTypesInfo[move->type].name;
+ str = gTypesInfo[GetMoveType(chosenMove)].name;
AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 4, 25, TEXT_SKIP_DRAW, NULL);
x = 4 + GetStringWidth(FONT_NORMAL, gText_MoveRelearnerPP, 0);
- ConvertIntToDecimalStringN(buffer, move->pp, STR_CONV_MODE_LEFT_ALIGN, 2);
+ ConvertIntToDecimalStringN(buffer, GetMovePP(chosenMove), STR_CONV_MODE_LEFT_ALIGN, 2);
AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, buffer, x, 41, TEXT_SKIP_DRAW, NULL);
- if (move->power < 2)
+ if (GetMovePower(chosenMove) < 2)
{
str = gText_ThreeDashes;
}
else
{
- ConvertIntToDecimalStringN(buffer, move->power, STR_CONV_MODE_LEFT_ALIGN, 3);
+ ConvertIntToDecimalStringN(buffer, GetMovePower(chosenMove), STR_CONV_MODE_LEFT_ALIGN, 3);
str = buffer;
}
AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 106, 25, TEXT_SKIP_DRAW, NULL);
- if (move->accuracy == 0)
+ if (GetMoveAccuracy(chosenMove) == 0)
{
str = gText_ThreeDashes;
}
else
{
- ConvertIntToDecimalStringN(buffer, move->accuracy, STR_CONV_MODE_LEFT_ALIGN, 3);
+ ConvertIntToDecimalStringN(buffer, GetMoveAccuracy(chosenMove), STR_CONV_MODE_LEFT_ALIGN, 3);
str = buffer;
}
AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 106, 41, TEXT_SKIP_DRAW, NULL);
-
- if (move->effect != EFFECT_PLACEHOLDER)
- str = gMovesInfo[chosenMove].description;
- else
- str = gNotDoneYetDescription;
-
- AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NARROW, str, 0, 65, 0, NULL);
+ AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NARROW, GetMoveDescription(chosenMove), 0, 65, 0, NULL);
}
static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove)
{
s32 x;
const u8 *str;
- const struct MoveInfo *move;
MoveRelearnerShowHideHearts(chosenMove);
FillWindowPixelBuffer(RELEARNERWIN_DESC_CONTEST, PIXEL_FILL(1));
@@ -844,11 +836,10 @@ static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove)
return;
}
- move = &gMovesInfo[chosenMove];
- str = gContestMoveTypeTextPointers[move->contestCategory];
+ str = gContestMoveTypeTextPointers[GetMoveContestCategory(chosenMove)];
AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NORMAL, str, 4, 25, TEXT_SKIP_DRAW, NULL);
- str = gContestEffectDescriptionPointers[move->contestEffect];
+ str = gContestEffectDescriptionPointers[GetMoveContestEffect(chosenMove)];
AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NARROW, str, 0, 65, TEXT_SKIP_DRAW, NULL);
CopyWindowToVram(RELEARNERWIN_DESC_CONTEST, COPYWIN_GFX);
diff --git a/src/mini_printf.c b/src/mini_printf.c
index c5b1e09bdc..c2e35354f1 100644
--- a/src/mini_printf.c
+++ b/src/mini_printf.c
@@ -86,6 +86,8 @@ static inline char mini_pchar_decode(char encoded)
ret = '('; // opening parentheses
else if (encoded == CHAR_RIGHT_PAREN)
ret = ')'; // closing parentheses
+ else if (encoded == CHAR_HYPHEN)
+ ret = '-'; // hyphen
return ret;
}
@@ -133,7 +135,31 @@ static s32 _putsEncoded(char *s, s32 len, void *buf)
{
break;
}
- *(b->pbuffer ++) = mini_pchar_decode(s[i]);
+ if (s[i] == CHAR_NEWLINE)
+ {
+ *(b->pbuffer ++) = '\\';
+ *(b->pbuffer ++) = 'n';
+ }
+ else if (s[i] == CHAR_PROMPT_SCROLL)
+ {
+ *(b->pbuffer ++) = '\\';
+ *(b->pbuffer ++) = 'l';
+ }
+ else if (s[i] == CHAR_PROMPT_CLEAR)
+ {
+ *(b->pbuffer ++) = '\\';
+ *(b->pbuffer ++) = 'p';
+ }
+ else if (s[i] == CHAR_ELLIPSIS)
+ {
+ *(b->pbuffer ++) = '.';
+ *(b->pbuffer ++) = '.';
+ *(b->pbuffer ++) = '.';
+ }
+ else
+ {
+ *(b->pbuffer ++) = mini_pchar_decode(s[i]);
+ }
}
*(b->pbuffer) = 0;
return b->pbuffer - p0;
@@ -248,7 +274,8 @@ s32 mini_vpprintf(void* buf, const char *fmt, va_list va)
{
len = 1;
len = _putsAscii(&ch, len, buf);
- } else
+ }
+ else
{
char pad_char = ' ';
s32 pad_to = 0;
@@ -284,7 +311,8 @@ s32 mini_vpprintf(void* buf, const char *fmt, va_list va)
if(l)
{
len = mini_itoa(va_arg(va, u32), 10, 0, (ch=='u'), bf2);
- } else
+ }
+ else
{
if(ch == 'u')
{
@@ -326,7 +354,8 @@ s32 mini_vpprintf(void* buf, const char *fmt, va_list va)
{
len = mini_pad(ptr, len, pad_char, pad_to, bf);
len = _putsAscii(bf, len, buf);
- } else
+ }
+ else
{
len = _putsAscii(ptr, len, buf);
}
@@ -338,7 +367,8 @@ s32 mini_vpprintf(void* buf, const char *fmt, va_list va)
{
len = mini_pad(ptr, len, pad_char, pad_to, bf);
len = _putsEncoded(bf, len, buf);
- } else
+ }
+ else
{
len = _putsEncoded(ptr, len, buf);
}
diff --git a/src/move.c b/src/move.c
new file mode 100644
index 0000000000..c77742c30e
--- /dev/null
+++ b/src/move.c
@@ -0,0 +1,6 @@
+#include "global.h"
+#include "battle.h"
+#include "main.h"
+#include "move.h"
+
+#include "data/moves_info.h"
diff --git a/src/move_relearner.c b/src/move_relearner.c
index a4cc778a45..f81e9ddc37 100644
--- a/src/move_relearner.c
+++ b/src/move_relearner.c
@@ -165,18 +165,18 @@ enum {
static EWRAM_DATA struct
{
u8 state;
- u8 heartSpriteIds[16]; /*0x001*/
- u16 movesToLearn[MAX_RELEARNER_MOVES]; /*0x01A*/
- u8 partyMon; /*0x044*/
- u8 moveSlot; /*0x045*/
- struct ListMenuItem menuItems[MAX_RELEARNER_MOVES]; /*0x0E8*/
- u8 numMenuChoices; /*0x110*/
- u8 numToShowAtOnce; /*0x111*/
- u8 moveListMenuTask; /*0x112*/
- u8 moveListScrollArrowTask; /*0x113*/
- u8 moveDisplayArrowTask; /*0x114*/
- u16 scrollOffset; /*0x116*/
- u8 categoryIconSpriteId; /*0x117*/
+ u8 heartSpriteIds[16]; /*0x001*/
+ u16 movesToLearn[MAX_RELEARNER_MOVES]; /*0x01A*/
+ u8 partyMon; /*0x044*/
+ u8 moveSlot; /*0x045*/
+ struct ListMenuItem menuItems[MAX_RELEARNER_MOVES + 1]; /*0x0E8*/
+ u8 numMenuChoices; /*0x110*/
+ u8 numToShowAtOnce; /*0x111*/
+ u8 moveListMenuTask; /*0x112*/
+ u8 moveListScrollArrowTask; /*0x113*/
+ u8 moveDisplayArrowTask; /*0x114*/
+ u16 scrollOffset; /*0x116*/
+ u8 categoryIconSpriteId; /*0x117*/
} *sMoveRelearnerStruct = {0};
static EWRAM_DATA struct {
@@ -969,7 +969,7 @@ void MoveRelearnerShowHideHearts(s32 moveId)
}
else
{
- numHearts = (u8)(gContestEffects[gMovesInfo[moveId].contestEffect].appeal / 10);
+ numHearts = (u8)(gContestEffects[GetMoveContestEffect(moveId)].appeal / 10);
if (numHearts == 0xFF)
numHearts = 0;
@@ -983,7 +983,7 @@ void MoveRelearnerShowHideHearts(s32 moveId)
gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = FALSE;
}
- numHearts = (u8)(gContestEffects[gMovesInfo[moveId].contestEffect].jam / 10);
+ numHearts = (u8)(gContestEffects[GetMoveContestEffect(moveId)].jam / 10);
if (numHearts == 0xFF)
numHearts = 0;
diff --git a/src/party_menu.c b/src/party_menu.c
index 40628c057c..416bbd7898 100644
--- a/src/party_menu.c
+++ b/src/party_menu.c
@@ -2735,7 +2735,7 @@ static u8 DisplaySelectionWindow(u8 windowType)
const u8 *text;
u8 fontColorsId = (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES) ? 4 : 3;
if (sPartyMenuInternal->actions[i] >= MENU_FIELD_MOVES)
- text = gMovesInfo[sFieldMoves[sPartyMenuInternal->actions[i] - MENU_FIELD_MOVES]].name;
+ text = GetMoveName(sFieldMoves[sPartyMenuInternal->actions[i] - MENU_FIELD_MOVES]);
else
text = sCursorOptions[sPartyMenuInternal->actions[i]].text;
@@ -5367,7 +5367,9 @@ static void Task_LearnNextMoveOrClosePartyMenu(u8 taskId)
if (IsFanfareTaskInactive() && ((JOY_NEW(A_BUTTON)) || (JOY_NEW(B_BUTTON))))
{
if (gPartyMenu.learnMoveState == 1)
+ {
Task_TryLearningNextMove(taskId);
+ }
else
{
if (gPartyMenu.learnMoveState == 2) // never occurs
diff --git a/src/player_pc.c b/src/player_pc.c
index 3dd5fcc36f..352a7a11f8 100644
--- a/src/player_pc.c
+++ b/src/player_pc.c
@@ -181,20 +181,30 @@ static EWRAM_DATA u8 sTopMenuNumOptions = 0;
EWRAM_DATA struct PlayerPCItemPageStruct gPlayerPCItemPageInfo = {};
static EWRAM_DATA struct ItemStorageMenu *sItemStorageMenu = NULL;
+static const u8 sText_WithdrawItem[] = _("WITHDRAW ITEM");
+static const u8 sText_DepositItem[] = _("DEPOSIT ITEM");
+static const u8 sText_TossItem[] = _("TOSS ITEM");
+static const u8 sText_Mailbox[] = _("MAILBOX");
+
+static const u8 sText_WithdrawHowManyItems[] = _("Withdraw how many\n{STR_VAR_1}?");
+static const u8 sText_WithdrawXItems[] = _("Withdrew {STR_VAR_2}\n{STR_VAR_1}.");
+static const u8 sText_NoRoomInBag[] = _("There is no more\nroom in the BAG.");
+static const u8 sText_TooImportantToToss[] = _("That's much too\nimportant to toss\nout!");
+
static const u8 *const sItemStorage_OptionDescriptions[] =
{
- [MENU_WITHDRAW] = gText_TakeOutItemsFromPC,
- [MENU_DEPOSIT] = gText_StoreItemsInPC,
- [MENU_TOSS] = gText_ThrowAwayItemsInPC,
+ [MENU_WITHDRAW] = COMPOUND_STRING("Take out items from the PC."),
+ [MENU_DEPOSIT] = COMPOUND_STRING("Store items in the PC."),
+ [MENU_TOSS] = COMPOUND_STRING("Throw away items stored in the PC."),
[MENU_EXIT] = gText_GoBackPrevMenu,
};
static const struct MenuAction sPlayerPCMenuActions[] =
{
- [MENU_ITEMSTORAGE] = { gText_ItemStorage, {PlayerPC_ItemStorage} },
- [MENU_MAILBOX] = { gText_Mailbox, {PlayerPC_Mailbox} },
- [MENU_DECORATION] = { gText_Decoration, {PlayerPC_Decoration} },
- [MENU_TURNOFF] = { gText_TurnOff, {PlayerPC_TurnOff} }
+ [MENU_ITEMSTORAGE] = { COMPOUND_STRING("ITEM STORAGE"), {PlayerPC_ItemStorage} },
+ [MENU_MAILBOX] = { sText_Mailbox, {PlayerPC_Mailbox} },
+ [MENU_DECORATION] = { COMPOUND_STRING("DECORATION"), {PlayerPC_Decoration} },
+ [MENU_TURNOFF] = { COMPOUND_STRING("TURN OFF"), {PlayerPC_TurnOff} }
};
static const u8 sBedroomPC_OptionOrder[] =
@@ -216,9 +226,9 @@ static const u8 sPlayerPC_OptionOrder[] =
static const struct MenuAction sItemStorage_MenuActions[] =
{
- [MENU_WITHDRAW] = { gText_WithdrawItem, {ItemStorage_Withdraw} },
- [MENU_DEPOSIT] = { gText_DepositItem, {ItemStorage_Deposit} },
- [MENU_TOSS] = { gText_TossItem, {ItemStorage_Toss} },
+ [MENU_WITHDRAW] = { sText_WithdrawItem, {ItemStorage_Withdraw} },
+ [MENU_DEPOSIT] = { sText_DepositItem, {ItemStorage_Deposit} },
+ [MENU_TOSS] = { sText_TossItem, {ItemStorage_Toss} },
[MENU_EXIT] = { gText_Cancel, {ItemStorage_Exit} }
};
@@ -230,10 +240,10 @@ static const u16 sNewGamePCItems[][2] =
const struct MenuAction gMailboxMailOptions[] =
{
- { gText_Read, {Mailbox_DoMailRead} },
- { gText_MoveToBag, {Mailbox_MoveToBag} },
- { gText_Give2, {Mailbox_Give} },
- { gText_Cancel2, {Mailbox_Cancel} }
+ { COMPOUND_STRING("READ"), {Mailbox_DoMailRead} },
+ { COMPOUND_STRING("MOVE TO BAG"), {Mailbox_MoveToBag} },
+ { COMPOUND_STRING("GIVE"), {Mailbox_Give} },
+ { gText_Cancel2, {Mailbox_Cancel} }
};
static const struct WindowTemplate sWindowTemplates_MainMenus[] =
@@ -697,7 +707,7 @@ static void Mailbox_DrawMailboxMenu(u8 taskId)
{
u8 windowId = MailboxMenu_AddWindow(MAILBOXWIN_TITLE);
MailboxMenu_AddWindow(MAILBOXWIN_LIST);
- AddTextPrinterParameterized(windowId, FONT_NORMAL, gText_Mailbox, GetStringCenterAlignXOffset(FONT_NORMAL, gText_Mailbox, 0x40), 1, 0, NULL);
+ AddTextPrinterParameterized(windowId, FONT_NORMAL, sText_Mailbox, GetStringCenterAlignXOffset(FONT_NORMAL, sText_Mailbox, 0x40), 1, 0, NULL);
ScheduleBgCopyTilemapToVram(0);
gTasks[taskId].tListTaskId = MailboxMenu_CreateList(&gPlayerPCItemPageInfo);
MailboxMenu_AddScrollArrows(&gPlayerPCItemPageInfo);
@@ -881,7 +891,9 @@ static void Mailbox_CancelMoveToBag(u8 taskId)
static void Mailbox_Give(u8 taskId)
{
if (CalculatePlayerPartyCount() == 0)
+ {
Mailbox_NoPokemonForMail(taskId);
+ }
else
{
FadeScreen(FADE_TO_BLACK, 0);
@@ -1145,9 +1157,9 @@ static void ItemStorage_CreateListMenu(u8 taskId)
for (i = 0; i <= ITEMPC_WIN_LIST_END; i++)
ItemStorage_AddWindow(i);
toss = tInTossMenu;
- text = gText_TossItem;
+ text = sText_TossItem;
if (!toss)
- text = gText_WithdrawItem;
+ text = sText_WithdrawItem;
x = GetStringCenterAlignXOffset(FONT_NORMAL, text, 104);
AddTextPrinterParameterized(sItemStorageMenu->windowIds[ITEMPC_WIN_TITLE], FONT_NORMAL, text, x, 1, 0, NULL);
CopyWindowToVram(sItemStorageMenu->windowIds[ITEMPC_WIN_ICON], COPYWIN_GFX);
@@ -1170,10 +1182,10 @@ static const u8 *ItemStorage_GetMessage(u16 itemId)
string = gText_GoBackPrevMenu;
break;
case MSG_HOW_MANY_TO_WITHDRAW:
- string = gText_WithdrawHowManyItems;
+ string = sText_WithdrawHowManyItems;
break;
case MSG_WITHDREW_ITEM:
- string = gText_WithdrawXItems;
+ string = sText_WithdrawXItems;
break;
case MSG_HOW_MANY_TO_TOSS:
string = gText_TossHowManyVar1s;
@@ -1182,10 +1194,10 @@ static const u8 *ItemStorage_GetMessage(u16 itemId)
string = gText_ThrewAwayVar2Var1s;
break;
case MSG_NO_MORE_ROOM:
- string = gText_NoRoomInBag;
+ string = sText_NoRoomInBag;
break;
case MSG_TOO_IMPORTANT:
- string = gText_TooImportantToToss;
+ string = sText_TooImportantToToss;
break;
case MSG_OKAY_TO_THROW_AWAY:
string = gText_ConfirmTossItems;
diff --git a/src/pokedex.c b/src/pokedex.c
index 87702d3371..e4b5076e59 100644
--- a/src/pokedex.c
+++ b/src/pokedex.c
@@ -2416,7 +2416,9 @@ static void CreateMonListEntry(u8 position, u16 b, u16 ignored)
if (vOffset >= LIST_SCROLL_STEP)
vOffset -= LIST_SCROLL_STEP;
if (entryNum < 0 || entryNum >= NATIONAL_DEX_COUNT || sPokedexView->pokedexList[entryNum].dexNum == 0xFFFF)
+ {
ClearMonListEntry(17, vOffset * 2, ignored);
+ }
else
{
ClearMonListEntry(17, vOffset * 2, ignored);
@@ -2711,7 +2713,9 @@ static bool8 TryDoInfoScreenScroll(void)
}
if (sPokedexView->selectedPokemon == selectedPokemon)
+ {
return FALSE;
+ }
else
{
sPokedexView->selectedPokemon = selectedPokemon;
@@ -2734,7 +2738,9 @@ static bool8 TryDoInfoScreenScroll(void)
}
if (sPokedexView->selectedPokemon == selectedPokemon)
+ {
return FALSE;
+ }
else
{
sPokedexView->selectedPokemon = selectedPokemon;
diff --git a/src/pokedex_plus_hgss.c b/src/pokedex_plus_hgss.c
index 74b57fa3a5..50a00c22b8 100644
--- a/src/pokedex_plus_hgss.c
+++ b/src/pokedex_plus_hgss.c
@@ -2560,11 +2560,11 @@ static void CreatePokedexList(u8 dexMode, u8 order)
}
break;
case ORDER_ALPHABETICAL:
- for (i = 0; i < NUM_SPECIES - 1; i++)
+ for (i = 0; i < NATIONAL_DEX_COUNT; i++)
{
temp_dexNum = gPokedexOrder_Alphabetical[i];
- if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN))
+ if ((!temp_isHoennDex || NationalToHoennOrder(temp_dexNum) != 0) && GetSetPokedexFlag(temp_dexNum, FLAG_GET_SEEN))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
@@ -2578,7 +2578,7 @@ static void CreatePokedexList(u8 dexMode, u8 order)
{
temp_dexNum = gPokedexOrder_Weight[i];
- if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
+ if ((!temp_isHoennDex || NationalToHoennOrder(temp_dexNum) != 0) && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
@@ -2592,7 +2592,7 @@ static void CreatePokedexList(u8 dexMode, u8 order)
{
temp_dexNum = gPokedexOrder_Weight[i];
- if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
+ if ((!temp_isHoennDex || NationalToHoennOrder(temp_dexNum) != 0) && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
@@ -2606,7 +2606,7 @@ static void CreatePokedexList(u8 dexMode, u8 order)
{
temp_dexNum = gPokedexOrder_Height[i];
- if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
+ if ((!temp_isHoennDex || NationalToHoennOrder(temp_dexNum) != 0) && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
@@ -2620,7 +2620,7 @@ static void CreatePokedexList(u8 dexMode, u8 order)
{
temp_dexNum = gPokedexOrder_Height[i];
- if (NationalToHoennOrder(temp_dexNum) <= temp_dexCount && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
+ if ((!temp_isHoennDex || NationalToHoennOrder(temp_dexNum) != 0) && GetSetPokedexFlag(temp_dexNum, FLAG_GET_CAUGHT))
{
sPokedexView->pokedexList[sPokedexView->pokemonListCount].dexNum = temp_dexNum;
sPokedexView->pokedexList[sPokedexView->pokemonListCount].seen = TRUE;
@@ -5182,12 +5182,12 @@ static void PrintStatsScreen_Moves_Top(u8 taskId)
//Draw move type icon
if (gTasks[taskId].data[5] == 0)
{
- SetTypeIconPosAndPal(gMovesInfo[move].type, moves_x + 146, moves_y + 17, 0);
+ SetTypeIconPosAndPal(GetMoveType(move), moves_x + 146, moves_y + 17, 0);
SetSpriteInvisibility(1, TRUE);
}
else
{
- SetTypeIconPosAndPal(NUMBER_OF_MON_TYPES + gMovesInfo[move].contestCategory, moves_x + 146, moves_y + 17, 1);
+ SetTypeIconPosAndPal(NUMBER_OF_MON_TYPES + GetMoveContestCategory(move), moves_x + 146, moves_y + 17, 1);
SetSpriteInvisibility(0, TRUE);
}
@@ -5243,12 +5243,12 @@ static void PrintStatsScreen_Moves_Description(u8 taskId)
//Move description
if (gTasks[taskId].data[5] == 0)
{
- StringCopy(gStringVar4, gMovesInfo[move].description);
+ StringCopy(gStringVar4, GetMoveDescription(move));
PrintStatsScreenTextSmall(WIN_STATS_MOVES_DESCRIPTION, gStringVar4, moves_x, moves_y);
}
else
{
- StringCopy(gStringVar4, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect]);
+ StringCopy(gStringVar4, gContestEffectDescriptionPointers[GetMoveContestEffect(move)]);
PrintStatsScreenTextSmall(WIN_STATS_MOVES_DESCRIPTION, gStringVar4, moves_x, moves_y);
}
}
@@ -5287,19 +5287,21 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId)
if (gTasks[taskId].data[5] == 0)
{
//Power
- if (gMovesInfo[move].power < 2)
+ u32 power = GetMovePower(move);
+ if (power < 2)
StringCopy(gStringVar1, gText_ThreeDashes);
else
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[move].power, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, power, STR_CONV_MODE_RIGHT_ALIGN, 3);
PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar1, moves_x + 45, moves_y);
//Physical/Special/Status Category
DestroyCategoryIcon();
ShowCategoryIcon(GetBattleMoveCategory(move));
//Accuracy
- if (gMovesInfo[move].accuracy == 0)
+ u32 accuracy = GetMoveAccuracy(move);
+ if (accuracy == 0)
StringCopy(gStringVar1, gText_ThreeDashes);
else
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[move].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar1, moves_x + 114, moves_y);
}
else //Appeal + Jam
@@ -5307,7 +5309,7 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId)
DestroyCategoryIcon();
gSprites[sPokedexView->categoryIconSpriteId].invisible = TRUE;
//Appeal
- contest_effectValue = gContestEffects[gMovesInfo[move].contestEffect].appeal;
+ contest_effectValue = gContestEffects[GetMoveContestEffect(move)].appeal;
if (contest_effectValue != 0xFF)
contest_appeal = contest_effectValue / 10;
ConvertIntToDecimalStringN(gStringVar1, contest_appeal, STR_CONV_MODE_RIGHT_ALIGN, 1);
@@ -5316,7 +5318,7 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId)
PrintStatsScreenTextSmall(WIN_STATS_MOVES_BOTTOM, gStringVar2, moves_x + 45, moves_y);
//Jam
- contest_effectValue = gContestEffects[gMovesInfo[move].contestEffect].jam;
+ contest_effectValue = gContestEffects[GetMoveContestEffect(move)].jam;
if (contest_effectValue != 0xFF)
contest_jam = contest_effectValue / 10;
ConvertIntToDecimalStringN(gStringVar1, contest_jam, STR_CONV_MODE_RIGHT_ALIGN, 1);
diff --git a/src/pokemon.c b/src/pokemon.c
index dcd4bb396b..eefbd7c4f0 100644
--- a/src/pokemon.c
+++ b/src/pokemon.c
@@ -40,6 +40,7 @@
#include "string_util.h"
#include "strings.h"
#include "task.h"
+#include "test_runner.h"
#include "text.h"
#include "trainer_hill.h"
#include "util.h"
@@ -48,6 +49,7 @@
#include "constants/battle_move_effects.h"
#include "constants/battle_script_commands.h"
#include "constants/battle_partner.h"
+#include "constants/battle_string_ids.h"
#include "constants/cries.h"
#include "constants/event_objects.h"
#include "constants/form_change_types.h"
@@ -76,7 +78,6 @@ static void EncryptBoxMon(struct BoxPokemon *boxMon);
static void DecryptBoxMon(struct BoxPokemon *boxMon);
static void Task_PlayMapChosenOrBattleBGM(u8 taskId);
static bool8 ShouldSkipFriendshipChange(void);
-static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
void TrySpecialOverworldEvo();
EWRAM_DATA static u8 sLearningMoveTableID = 0;
@@ -89,7 +90,6 @@ EWRAM_DATA static struct MonSpritesGfxManager *sMonSpritesGfxManagers[MON_SPR_GF
EWRAM_DATA static u8 sTriedEvolving = 0;
EWRAM_DATA u16 gFollowerSteps = 0;
-#include "data/moves_info.h"
#include "data/abilities.h"
// Used in an unreferenced function in RS.
@@ -1871,8 +1871,9 @@ u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL);
if (existingMove == MOVE_NONE)
{
+ u32 pp = GetMovePP(move);
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move);
- SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gMovesInfo[move].pp);
+ SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp);
return move;
}
if (existingMove == move)
@@ -1890,7 +1891,7 @@ u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move)
if (mon->moves[i] == MOVE_NONE)
{
mon->moves[i] = move;
- mon->pp[i] = gMovesInfo[move].pp;
+ mon->pp[i] = GetMovePP(move);
return move;
}
}
@@ -1901,7 +1902,8 @@ u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move)
void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot)
{
SetMonData(mon, MON_DATA_MOVE1 + slot, &move);
- SetMonData(mon, MON_DATA_PP1 + slot, &gMovesInfo[move].pp);
+ u32 pp = GetMovePP(move);
+ SetMonData(mon, MON_DATA_PP1 + slot, &pp);
}
static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, u16 move, u8 slot)
@@ -1918,7 +1920,7 @@ static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, u16 move, u8 slot)
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
{
mon->moves[slot] = move;
- mon->pp[slot] = gMovesInfo[move].pp;
+ mon->pp[slot] = GetMovePP(move);
}
void GiveMonInitialMoveset(struct Pokemon *mon)
@@ -1972,7 +1974,8 @@ void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon) //Credit: AsparagusEdua
for (i = 0; i < MAX_MON_MOVES; i++)
{
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]);
- SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gMovesInfo[moves[i]].pp);
+ u32 pp = GetMovePP(moves[i]);
+ SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp);
}
}
@@ -2025,7 +2028,7 @@ void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move)
ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
ppBonuses >>= 2;
moves[MAX_MON_MOVES - 1] = move;
- pp[MAX_MON_MOVES - 1] = gMovesInfo[move].pp;
+ pp[MAX_MON_MOVES - 1] = GetMovePP(move);
for (i = 0; i < MAX_MON_MOVES; i++)
{
@@ -2052,7 +2055,7 @@ void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL);
ppBonuses >>= 2;
moves[MAX_MON_MOVES - 1] = move;
- pp[MAX_MON_MOVES - 1] = gMovesInfo[move].pp;
+ pp[MAX_MON_MOVES - 1] = GetMovePP(move);
for (i = 0; i < MAX_MON_MOVES; i++)
{
@@ -2077,6 +2080,13 @@ u8 CountAliveMonsInBattle(u8 caseId, u32 battler)
retVal++;
}
break;
+ case BATTLE_ALIVE_EXCEPT_BATTLER_SIDE:
+ for (i = 0; i < MAX_BATTLERS_COUNT; i++)
+ {
+ if (i != battler && i != BATTLE_PARTNER(battler) && !(gAbsentBattlerFlags & (1u << i)))
+ retVal++;
+ }
+ break;
case BATTLE_ALIVE_SIDE:
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
@@ -3506,7 +3516,8 @@ void CreateSecretBaseEnemyParty(struct SecretBase *secretBaseRecord)
for (j = 0; j < MAX_MON_MOVES; j++)
{
SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * MAX_MON_MOVES + j]);
- SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gMovesInfo[gBattleResources->secretBase->party.moves[i * MAX_MON_MOVES + j]].pp);
+ u32 pp = GetMovePP(gBattleResources->secretBase->party.moves[i * MAX_MON_MOVES + j]);
+ SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &pp);
}
}
}
@@ -3631,7 +3642,7 @@ const struct FormChange *GetSpeciesFormChanges(u16 species)
u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex)
{
- u8 basePP = gMovesInfo[move].pp;
+ u8 basePP = GetMovePP(move);
return basePP + ((basePP * 20 * ((gPPUpGetMask[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100);
}
@@ -4202,7 +4213,24 @@ bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battlerId)
status &= ~healMask;
SetMonData(mon, MON_DATA_STATUS, &status);
if (gMain.inBattle && battlerId != MAX_BATTLERS_COUNT)
+ {
gBattleMons[battlerId].status1 &= ~healMask;
+ if((healMask & STATUS1_SLEEP))
+ {
+ u32 i = 0;
+ u32 battlerSide = GetBattlerSide(battlerId);
+ struct Pokemon *party = GetSideParty(battlerSide);
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ if (&party[i] == mon)
+ {
+ TryDeactivateSleepClause(battlerSide, i);
+ break;
+ }
+ }
+ }
+ }
return FALSE;
}
else
@@ -4597,7 +4625,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16
{
for (j = 0; j < MAX_MON_MOVES; j++)
{
- if (gMovesInfo[GetMonData(mon, MON_DATA_MOVE1 + j, NULL)].type == evolutions[i].param)
+ if (GetMoveType(GetMonData(mon, MON_DATA_MOVE1 + j, NULL)) == evolutions[i].param)
{
targetSpecies = evolutions[i].targetSpecies;
break;
@@ -4980,16 +5008,25 @@ u16 HoennToNationalOrder(u16 hoennNum)
The function then loops over the 16x16 spot image. For each bit in the spot's binary image, if
the bit is set then it's part of the spot; try to draw it. A pixel is drawn on Spinda if the
- pixel on Spinda satisfies the following formula: ((u8)(colorIndex - 1) <= 2). The -1 excludes
- transparent pixels, as these are index 0. Therefore only colors 1, 2, or 3 on Spinda will
- allow a spot to be drawn. These color indexes are Spinda's light brown body colors. To create
+ pixel is between FIRST_SPOT_COLOR and LAST_SPOT_COLOR (so only colors 1, 2, or 3 on Spinda will
+ allow a spot to be drawn). These color indexes are Spinda's light brown body colors. To create
the spot it adds 4 to the color index, so Spinda's spots will be colors 5, 6, and 7.
- The above is done two different ways in the function: one with << 4, and one without. This
- is because Spinda's sprite is a 4 bits per pixel image, but the pointer to Spinda's pixels
+ The above is done in TRY_DRAW_SPOT_PIXEL two different ways: one with << 4, and one without.
+ This is because Spinda's sprite is a 4 bits per pixel image, but the pointer to Spinda's pixels
(destPixels) is an 8 bit pointer, so it addresses two pixels. Shifting by 4 accesses the 2nd
of these pixels, so this is done every other time.
*/
+
+// Draw spot pixel if this is Spinda's body color
+#define TRY_DRAW_SPOT_PIXEL(pixels, shift) \
+ if (((*(pixels) & (0xF << (shift))) >= (FIRST_SPOT_COLOR << (shift))) \
+ && ((*(pixels) & (0xF << (shift))) <= (LAST_SPOT_COLOR << (shift)))) \
+ { \
+ *(pixels) += (SPOT_COLOR_ADJUSTMENT << (shift)); \
+ }
+
+
void DrawSpindaSpots(u32 personality, u8 *dest, bool32 isSecondFrame)
{
s32 i;
@@ -5031,16 +5068,12 @@ void DrawSpindaSpots(u32 personality, u8 *dest, bool32 isSecondFrame)
if (column & 1)
{
/* Draw spot pixel if this is Spinda's body color */
- if ((u8)((*destPixels & 0xF0) - (FIRST_SPOT_COLOR << 4))
- <= ((LAST_SPOT_COLOR - FIRST_SPOT_COLOR) << 4))
- *destPixels += (SPOT_COLOR_ADJUSTMENT << 4);
+ TRY_DRAW_SPOT_PIXEL(destPixels, 4);
}
else
{
/* Draw spot pixel if this is Spinda's body color */
- if ((u8)((*destPixels & 0xF) - FIRST_SPOT_COLOR)
- <= (LAST_SPOT_COLOR - FIRST_SPOT_COLOR))
- *destPixels += SPOT_COLOR_ADJUSTMENT;
+ TRY_DRAW_SPOT_PIXEL(destPixels, 0);
}
}
@@ -5722,7 +5755,9 @@ u16 GetBattleBGM(void)
}
}
else if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
+ {
return MUS_VS_TRAINER;
+ }
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
{
u8 trainerClass;
@@ -5769,7 +5804,9 @@ u16 GetBattleBGM(void)
}
}
else
+ {
return MUS_VS_WILD;
+ }
}
void PlayBattleBGM(void)
@@ -6272,7 +6309,7 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
bool8 HasTwoFramesAnimation(u16 species)
{
- return P_TWO_FRAME_FRONT_SPRITES && species != SPECIES_UNOWN;
+ return P_TWO_FRAME_FRONT_SPRITES && species != SPECIES_UNOWN && !gTestRunnerHeadless;
}
static bool8 ShouldSkipFriendshipChange(void)
@@ -6642,7 +6679,8 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove)
}
while(learnset[sLearningMoveTableID].move != LEVEL_UP_MOVE_END)
{
- while (learnset[sLearningMoveTableID].level == 0 || learnset[sLearningMoveTableID].level == level)
+ while ((learnset[sLearningMoveTableID].level == 0 || learnset[sLearningMoveTableID].level == level)
+ && !(P_EVOLUTION_LEVEL_1_LEARN >= GEN_8 && learnset[sLearningMoveTableID].level == 1))
{
gMoveToLearn = learnset[sLearningMoveTableID].move;
sLearningMoveTableID++;
@@ -6653,7 +6691,9 @@ u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove)
return 0;
}
-static void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
+// Removes the selected index from the given IV list and shifts the remaining
+// elements to the left.
+void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv)
{
s32 i, j;
u8 temp[NUM_STATS];
@@ -6889,7 +6929,7 @@ void HealBoxPokemon(struct BoxPokemon *boxMon)
u16 GetCryIdBySpecies(u16 species)
{
species = SanitizeSpeciesId(species);
- if (P_CRIES_ENABLED == FALSE || gSpeciesInfo[species].cryId >= CRY_COUNT)
+ if (P_CRIES_ENABLED == FALSE || gSpeciesInfo[species].cryId >= CRY_COUNT || gTestRunnerHeadless)
return CRY_NONE;
return gSpeciesInfo[species].cryId;
}
@@ -6913,21 +6953,6 @@ u16 GetSpeciesPreEvolution(u16 species)
return SPECIES_NONE;
}
-const u8 *GetMoveName(u16 moveId)
-{
- return gMovesInfo[moveId].name;
-}
-
-const u8 *GetMoveAnimationScript(u16 moveId)
-{
- if (gMovesInfo[moveId].battleAnimScript == NULL)
- {
- DebugPrintfLevel(MGBA_LOG_WARN, "No animation for moveId=%u", moveId);
- return gMovesInfo[MOVE_NONE].battleAnimScript;
- }
- return gMovesInfo[moveId].battleAnimScript;
-}
-
void UpdateDaysPassedSinceFormChange(u16 days)
{
u32 i;
@@ -6968,5 +6993,5 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler)
u32 moveType = GetDynamicMoveType(mon, move, battler, NULL);
if (moveType != TYPE_NONE)
return moveType;
- return gMovesInfo[move].type;
+ return GetMoveType(move);
}
diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c
index d7c0bb343c..6bd32ee514 100644
--- a/src/pokemon_animation.c
+++ b/src/pokemon_animation.c
@@ -5,6 +5,7 @@
#include "pokemon_animation.h"
#include "sprite.h"
#include "task.h"
+#include "test_runner.h"
#include "trig.h"
#include "util.h"
#include "data.h"
@@ -508,7 +509,10 @@ static void Task_HandleMonAnimation(u8 taskId)
for (i = 2; i < ARRAY_COUNT(sprite->data); i++)
sprite->data[i] = 0;
- sprite->callback = sMonAnimFunctions[gTasks[taskId].tAnimId];
+ if (gTestRunnerHeadless)
+ sprite->callback = WaitAnimEnd;
+ else
+ sprite->callback = sMonAnimFunctions[gTasks[taskId].tAnimId];
sIsSummaryAnim = FALSE;
gTasks[taskId].tState++;
diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c
index 4cfc17c707..f0c65dc2a7 100644
--- a/src/pokemon_summary_screen.c
+++ b/src/pokemon_summary_screen.c
@@ -2836,7 +2836,7 @@ static void DrawContestMoveHearts(u16 move)
if (move != MOVE_NONE)
{
// Draw appeal hearts
- u8 effectValue = gContestEffects[gMovesInfo[move].contestEffect].appeal;
+ u8 effectValue = gContestEffects[GetMoveContestEffect(move)].appeal;
if (effectValue != 0xFF)
effectValue /= 10;
@@ -2849,7 +2849,7 @@ static void DrawContestMoveHearts(u16 move)
}
// Draw jam hearts
- effectValue = gContestEffects[gMovesInfo[move].contestEffect].jam;
+ effectValue = gContestEffects[GetMoveContestEffect(move)].jam;
if (effectValue != 0xFF)
effectValue /= 10;
@@ -3750,29 +3750,31 @@ static void PrintMoveNameAndPP(u8 moveIndex)
static void PrintMovePowerAndAccuracy(u16 moveIndex)
{
const u8 *text;
- if (moveIndex != 0)
+ if (moveIndex != MOVE_NONE)
{
FillWindowPixelRect(PSS_LABEL_WINDOW_MOVES_POWER_ACC, PIXEL_FILL(0), 53, 0, 19, 32);
- if (gMovesInfo[moveIndex].power < 2)
+ u32 power = GetMovePower(moveIndex);
+ if (power < 2)
{
text = gText_ThreeDashes;
}
else
{
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveIndex].power, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, power, STR_CONV_MODE_RIGHT_ALIGN, 3);
text = gStringVar1;
}
PrintTextOnWindow(PSS_LABEL_WINDOW_MOVES_POWER_ACC, text, 53, 1, 0, 0);
- if (gMovesInfo[moveIndex].accuracy == 0)
+ u32 accuracy = GetMoveAccuracy(moveIndex);
+ if (accuracy == 0)
{
text = gText_ThreeDashes;
}
else
{
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[moveIndex].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
+ ConvertIntToDecimalStringN(gStringVar1, accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3);
text = gStringVar1;
}
@@ -3842,32 +3844,26 @@ static void PrintContestMoveDescription(u8 moveSlot)
if (move != MOVE_NONE)
{
u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION);
- PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect], 6, 1, 0, 0);
+ PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[GetMoveContestEffect(move)], 6, 1, 0, 0);
}
}
static void PrintMoveDetails(u16 move)
{
u8 windowId = AddWindowFromTemplateList(sPageMovesTemplate, PSS_DATA_WINDOW_MOVE_DESCRIPTION);
- u8 moveEffect;
FillWindowPixelBuffer(windowId, PIXEL_FILL(0));
if (move != MOVE_NONE)
{
if (sMonSummaryScreen->currPageIndex == PSS_PAGE_BATTLE_MOVES)
{
- moveEffect = gMovesInfo[move].effect;
if (B_SHOW_CATEGORY_ICON == TRUE)
ShowCategoryIcon(GetBattleMoveCategory(move));
PrintMovePowerAndAccuracy(move);
-
- if (moveEffect != EFFECT_PLACEHOLDER)
- PrintTextOnWindow(windowId, gMovesInfo[move].description, 6, 1, 0, 0);
- else
- PrintTextOnWindow(windowId, gNotDoneYetDescription, 6, 1, 0, 0);
+ PrintTextOnWindow(windowId, GetMoveDescription(move), 6, 1, 0, 0);
}
else
{
- PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[gMovesInfo[move].contestEffect], 6, 1, 0, 0);
+ PrintTextOnWindow(windowId, gContestEffectDescriptionPointers[GetMoveContestEffect(move)], 6, 1, 0, 0);
}
PutWindowTilemap(windowId);
}
@@ -3897,7 +3893,7 @@ static void PrintNewMoveDetailsOrCancelText(void)
else
PrintTextOnWindowToFit(windowId1, GetMoveName(move), 0, 65, 0, 5);
- ConvertIntToDecimalStringN(gStringVar1, gMovesInfo[move].pp, STR_CONV_MODE_RIGHT_ALIGN, 2);
+ ConvertIntToDecimalStringN(gStringVar1, GetMovePP(move), STR_CONV_MODE_RIGHT_ALIGN, 2);
DynamicPlaceholderTextUtil_Reset();
DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, gStringVar1);
DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, gStringVar1);
@@ -4051,7 +4047,7 @@ static void SetMoveTypeIcons(void)
{
if (summary->moves[i] != MOVE_NONE)
{
- type = gMovesInfo[summary->moves[i]].type;
+ type = GetMoveType(summary->moves[i]);
if (P_SHOW_DYNAMIC_TYPES)
type = CheckDynamicMoveType(mon, summary->moves[i], 0);
SetTypeSpritePosAndPal(type, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE);
@@ -4070,7 +4066,7 @@ static void SetContestMoveTypeIcons(void)
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (summary->moves[i] != MOVE_NONE)
- SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + gMovesInfo[summary->moves[i]].contestCategory, 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE);
+ SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + GetMoveContestCategory(summary->moves[i]), 85, 32 + (i * 16), i + SPRITE_ARR_ID_TYPE);
else
SetSpriteInvisibility(i + SPRITE_ARR_ID_TYPE, TRUE);
}
@@ -4078,7 +4074,7 @@ static void SetContestMoveTypeIcons(void)
static void SetNewMoveTypeIcon(void)
{
- u32 type = gMovesInfo[sMonSummaryScreen->newMove].type;
+ u32 type = GetMoveType(sMonSummaryScreen->newMove);
struct Pokemon *mon = &sMonSummaryScreen->currentMon;
if (P_SHOW_DYNAMIC_TYPES)
@@ -4096,7 +4092,7 @@ static void SetNewMoveTypeIcon(void)
}
else
{
- SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + gMovesInfo[sMonSummaryScreen->newMove].contestCategory, 85, 96, SPRITE_ARR_ID_TYPE + 4);
+ SetTypeSpritePosAndPal(NUMBER_OF_MON_TYPES + GetMoveContestCategory(sMonSummaryScreen->newMove), 85, 96, SPRITE_ARR_ID_TYPE + 4);
}
}
}
diff --git a/src/pokenav_conditions_search_results.c b/src/pokenav_conditions_search_results.c
index 4889dd788c..09ad43706b 100644
--- a/src/pokenav_conditions_search_results.c
+++ b/src/pokenav_conditions_search_results.c
@@ -186,13 +186,21 @@ static bool32 HandleConditionSearchInput_WaitSetup(struct Pokenav_SearchResults
static u32 HandleConditionSearchInput(struct Pokenav_SearchResults *menu)
{
if (JOY_REPEAT(DPAD_UP))
+ {
return CONDITION_SEARCH_FUNC_MOVE_UP;
+ }
else if (JOY_REPEAT(DPAD_DOWN))
+ {
return CONDITION_SEARCH_FUNC_MOVE_DOWN;
+ }
else if (JOY_NEW(DPAD_LEFT))
+ {
return CONDITION_SEARCH_FUNC_PAGE_UP;
+ }
else if (JOY_NEW(DPAD_RIGHT))
+ {
return CONDITION_SEARCH_FUNC_PAGE_DOWN;
+ }
else if (JOY_NEW(B_BUTTON))
{
// Exiting back to main search menu
@@ -209,7 +217,9 @@ static u32 HandleConditionSearchInput(struct Pokenav_SearchResults *menu)
return CONDITION_SEARCH_FUNC_SELECT_MON;
}
else
+ {
return CONDITION_SEARCH_FUNC_NONE;
+ }
}
static u32 ReturnToConditionSearchList(struct Pokenav_SearchResults *menu)
diff --git a/src/pokenav_menu_handler_gfx.c b/src/pokenav_menu_handler_gfx.c
index 09fb96f3dc..42588aeed0 100644
--- a/src/pokenav_menu_handler_gfx.c
+++ b/src/pokenav_menu_handler_gfx.c
@@ -509,7 +509,9 @@ static u32 LoopedTask_OpenMenu(s32 state)
ShowBg(2);
ShowBg(3);
if (gfx->pokenavAlreadyOpen)
+ {
PokenavFadeScreen(POKENAV_FADE_FROM_BLACK);
+ }
else
{
PlaySE(SE_POKENAV_ON);
diff --git a/src/recorded_battle.c b/src/recorded_battle.c
index c32e86b525..5e1ff63bbe 100644
--- a/src/recorded_battle.c
+++ b/src/recorded_battle.c
@@ -53,7 +53,7 @@ EWRAM_DATA static u32 sAI_Scripts = 0;
EWRAM_DATA static struct Pokemon sSavedPlayerParty[PARTY_SIZE] = {0};
EWRAM_DATA static struct Pokemon sSavedOpponentParty[PARTY_SIZE] = {0};
EWRAM_DATA static u16 sPlayerMonMoves[MAX_BATTLERS_COUNT / 2][MAX_MON_MOVES] = {0};
-EWRAM_DATA static struct PlayerInfo sPlayers[MAX_BATTLERS_COUNT] = {0};
+EWRAM_DATA static struct PlayerInfo sPlayers[MAX_LINK_PLAYERS] = {0};
EWRAM_DATA static bool8 sIsPlaybackFinished = 0;
EWRAM_DATA static u8 sRecordMixFriendName[PLAYER_NAME_LENGTH + 1] = {0};
EWRAM_DATA static u8 sRecordMixFriendClass = 0;
@@ -116,7 +116,7 @@ void RecordedBattle_SetTrainerInfo(void)
gRecordedBattleMultiplayerId = GetMultiplayerId();
linkPlayersCount = GetLinkPlayerCount();
- for (i = 0; i < MAX_BATTLERS_COUNT; i++)
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
{
sPlayers[i].trainerId = gLinkPlayers[i].trainerId;
sPlayers[i].gender = gLinkPlayers[i].gender;
@@ -304,7 +304,7 @@ bool32 MoveRecordedBattleToSaveData(void)
battleSave->opponentParty[i] = sSavedOpponentParty[i];
}
- for (i = 0; i < MAX_BATTLERS_COUNT; i++)
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
{
for (j = 0; j < PLAYER_NAME_LENGTH + 1; j++)
battleSave->playersName[i][j] = sPlayers[i].name[j];
@@ -511,7 +511,7 @@ void SetVariablesForRecordedBattle(struct RecordedBattleSave *src)
s32 i, j;
SetPartiesFromRecordedSave(src);
- for (i = 0; i < MAX_BATTLERS_COUNT; i++)
+ for (i = 0; i < MAX_LINK_PLAYERS; i++)
{
for (var = FALSE, j = 0; j < PLAYER_NAME_LENGTH + 1; j++)
{
diff --git a/src/rom_header_gf.c b/src/rom_header_gf.c
index 1074a86bf8..c55535003c 100644
--- a/src/rom_header_gf.c
+++ b/src/rom_header_gf.c
@@ -1,10 +1,11 @@
#include "global.h"
-#include "data.h"
-#include "pokemon_icon.h"
-#include "decoration.h"
#include "battle_main.h"
+#include "data.h"
+#include "decoration.h"
#include "item.h"
+#include "move.h"
#include "pokeball.h"
+#include "pokemon_icon.h"
// The purpose of this struct is for outside applications to be
// able to access parts of the ROM or its save file, like a public API.
diff --git a/src/scrcmd.c b/src/scrcmd.c
index 399562f9a0..2471f3b595 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -29,6 +29,7 @@
#include "main.h"
#include "menu.h"
#include "money.h"
+#include "move.h"
#include "mystery_event_script.h"
#include "palette.h"
#include "party_menu.h"
diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c
index 020094389a..fc248435a9 100644
--- a/src/script_pokemon_util.c
+++ b/src/script_pokemon_util.c
@@ -487,12 +487,49 @@ void ScrCmd_createmon(struct ScriptContext *ctx)
u8 speedEv = PARSE_FLAG(8, 0);
u8 spAtkEv = PARSE_FLAG(9, 0);
u8 spDefEv = PARSE_FLAG(10, 0);
- u8 hpIv = PARSE_FLAG(11, Random() % (MAX_PER_STAT_IVS + 1));
- u8 atkIv = PARSE_FLAG(12, Random() % (MAX_PER_STAT_IVS + 1));
- u8 defIv = PARSE_FLAG(13, Random() % (MAX_PER_STAT_IVS + 1));
- u8 speedIv = PARSE_FLAG(14, Random() % (MAX_PER_STAT_IVS + 1));
- u8 spAtkIv = PARSE_FLAG(15, Random() % (MAX_PER_STAT_IVS + 1));
- u8 spDefIv = PARSE_FLAG(16, Random() % (MAX_PER_STAT_IVS + 1));
+ u8 hpIv = Random() % (MAX_PER_STAT_IVS + 1);
+ u8 atkIv = Random() % (MAX_PER_STAT_IVS + 1);
+ u8 defIv = Random() % (MAX_PER_STAT_IVS + 1);
+ u8 speedIv = Random() % (MAX_PER_STAT_IVS + 1);
+ u8 spAtkIv = Random() % (MAX_PER_STAT_IVS + 1);
+ u8 spDefIv = Random() % (MAX_PER_STAT_IVS + 1);
+
+ // Perfect IV calculation
+ u32 i;
+ u8 availableIVs[NUM_STATS];
+ u8 selectedIvs[NUM_STATS];
+ if (gSpeciesInfo[species].perfectIVCount != 0)
+ {
+ // Initialize a list of IV indices.
+ for (i = 0; i < NUM_STATS; i++)
+ availableIVs[i] = i;
+
+ // Select the IVs that will be perfected.
+ for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++)
+ {
+ u8 index = Random() % (NUM_STATS - i);
+ selectedIvs[i] = availableIVs[index];
+ RemoveIVIndexFromList(availableIVs, index);
+ }
+ for (i = 0; i < NUM_STATS && i < gSpeciesInfo[species].perfectIVCount; i++)
+ {
+ switch (selectedIvs[i])
+ {
+ case STAT_HP: hpIv = MAX_PER_STAT_IVS; break;
+ case STAT_ATK: atkIv = MAX_PER_STAT_IVS; break;
+ case STAT_DEF: defIv = MAX_PER_STAT_IVS; break;
+ case STAT_SPEED: speedIv = MAX_PER_STAT_IVS; break;
+ case STAT_SPATK: spAtkIv = MAX_PER_STAT_IVS; break;
+ case STAT_SPDEF: spDefIv = MAX_PER_STAT_IVS; break;
+ }
+ }
+ }
+ hpIv = PARSE_FLAG(11, hpIv);
+ atkIv = PARSE_FLAG(12, atkIv);
+ defIv = PARSE_FLAG(13, defIv);
+ speedIv = PARSE_FLAG(14, speedIv);
+ spAtkIv = PARSE_FLAG(15, spAtkIv);
+ spDefIv = PARSE_FLAG(16, spDefIv);
u16 move1 = PARSE_FLAG(17, MOVE_NONE);
u16 move2 = PARSE_FLAG(18, MOVE_NONE);
u16 move3 = PARSE_FLAG(19, MOVE_NONE);
diff --git a/src/shop.c b/src/shop.c
index a343bab0d3..dae2ea86ff 100644
--- a/src/shop.c
+++ b/src/shop.c
@@ -21,6 +21,7 @@
#include "menu.h"
#include "menu_helpers.h"
#include "money.h"
+#include "move.h"
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
diff --git a/src/slot_machine.c b/src/slot_machine.c
index e813f60c66..7f11396514 100644
--- a/src/slot_machine.c
+++ b/src/slot_machine.c
@@ -2324,7 +2324,9 @@ static bool8 ReelTask_MoveToStop(struct Task *task)
memcpy(reelStopShocks, sReelStopShocks, sizeof(sReelStopShocks));
reelPixelPos = sSlotMachine->reelPixelOffsets[task->tReelId] % REEL_SYMBOL_HEIGHT;
if (reelPixelPos != 0)
+ {
reelPixelPos = AdvanceSlotReelToNextSymbol(task->tReelId, sSlotMachine->reelSpeed);
+ }
else if (sSlotMachine->reelExtraTurns[task->tReelId])
{
sSlotMachine->reelExtraTurns[task->tReelId]--;
diff --git a/src/sprite.c b/src/sprite.c
index 8ae96581c9..14e9409c66 100644
--- a/src/sprite.c
+++ b/src/sprite.c
@@ -1048,9 +1048,13 @@ void ContinueAffineAnim(struct Sprite *sprite)
u8 matrixNum = GetSpriteMatrixNum(sprite);
if (sAffineAnimStates[matrixNum].delayCounter)
+ {
AffineAnimDelay(matrixNum, sprite);
+ }
else if (sprite->affineAnimPaused)
+ {
return;
+ }
else
{
s16 type;
diff --git a/src/strings.c b/src/strings.c
index 41fbba99a1..37feea0da0 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -126,21 +126,11 @@ const u8 gMenuText_Use[] = _("USE");
const u8 gMenuText_Toss[] = _("TOSS");
const u8 gMenuText_Register[] = _("REGISTER");
const u8 gMenuText_Give[] = _("GIVE");
-const u8 gMenuText_CheckTag[] = _("CHECK TAG");
const u8 gMenuText_Confirm[] = _("CONFIRM");
-const u8 gMenuText_Walk[] = _("WALK");
const u8 gText_Cancel[] = _("CANCEL");
const u8 gText_Cancel2[] = _("CANCEL");
-const u8 gMenuText_Show[] = _("SHOW");
const u8 gText_EmptyString2[] = _("");
-const u8 gText_Cancel7[] = _("CANCEL"); // Unused
-const u8 gText_Item[] = _("ITEM");
-const u8 gText_Mail[] = _("MAIL");
-const u8 gText_Take[] = _("TAKE");
-const u8 gText_Store[] = _("STORE");
-const u8 gMenuText_Check[] = _("CHECK");
const u8 gText_None[] = _("NONE");
-const u8 gMenuText_Deselect[] = _("DESELECT");
const u8 gText_FiveMarks[] = _("?????");
const u8 gText_Slash[] = _("/");
const u8 gText_OneDash[] = _("-");
@@ -166,39 +156,19 @@ const u8 gText_CantWriteMail[] = _("You can't write\nMAIL here.");
const u8 gText_NoPokemon[] = _("There is no\nPOKéMON.");
const u8 gText_MoveVar1Where[] = _("Move the\n{STR_VAR_1}\nwhere?");
const u8 gText_Var1CantBeHeld[] = _("The {STR_VAR_1} can't be held.");
-const u8 gText_Var1CantBeHeldHere[] = _("The {STR_VAR_1} can't be held\nhere.");
-const u8 gText_DepositHowManyVar1[] = _("Deposit how many\n{STR_VAR_1}?");
-const u8 gText_DepositedVar2Var1s[] = _("Deposited {STR_VAR_2}\n{STR_VAR_1}.");
-const u8 gText_NoRoomForItems[] = _("There's no room to\nstore items.");
-const u8 gText_CantStoreImportantItems[] = _("Important items\ncan't be stored in\nthe PC!");
-const u8 gText_TooImportantToToss[] = _("That's much too\nimportant to toss\nout!");
const u8 gText_TossHowManyVar1s[] = _("Toss out how many\n{STR_VAR_1}?");
const u8 gText_ThrewAwayVar2Var1s[] = _("Threw away {STR_VAR_2}\n{STR_VAR_1}.");
const u8 gText_ConfirmTossItems[] = _("Is it okay to\nthrow away {STR_VAR_2}\n{STR_VAR_1}?");
const u8 gText_DadsAdvice[] = _("DAD's advice…\n{PLAYER}, there's a time and place for\leverything!{PAUSE_UNTIL_PRESS}");
-const u8 gText_CantDismountBike[] = _("You can't dismount your BIKE here.{PAUSE_UNTIL_PRESS}");
-const u8 gText_ItemFinderNearby[] = _("Huh?\nThe ITEMFINDER's responding!\pThere's an item buried around here!{PAUSE_UNTIL_PRESS}");
-const u8 gText_ItemFinderOnTop[] = _("Oh!\nThe ITEMFINDER's shaking wildly!{PAUSE_UNTIL_PRESS}");
-const u8 gText_ItemFinderNothing[] = _("… … … …Nope!\nThere's no response.{PAUSE_UNTIL_PRESS}");
-const u8 gText_CoinCase[] = _("Your COINS:\n{STR_VAR_1}{PAUSE_UNTIL_PRESS}");
-const u8 gText_BootedUpTM[] = _("Booted up a TM.");
-const u8 gText_BootedUpHM[] = _("Booted up an HM.");
-const u8 gText_TMHMContainedVar1[] = _("It contained\n{STR_VAR_1}.\pTeach {STR_VAR_1}\nto a POKéMON?");
const u8 gText_PlayerUsedVar2[] = _("{PLAYER} used the\n{STR_VAR_2}.{PAUSE_UNTIL_PRESS}");
const u8 gText_RepelEffectsLingered[] = _("But the effects of a REPEL\nlingered from earlier.{PAUSE_UNTIL_PRESS}");
const u8 gText_LureEffectsLingered[] = _("But the effects of a Lure\nlingered from earlier.{PAUSE_UNTIL_PRESS}");
-const u8 gText_UsedVar2WildLured[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be lured.{PAUSE_UNTIL_PRESS}");
-const u8 gText_UsedVar2WildRepelled[] = _("{PLAYER} used the\n{STR_VAR_2}.\pWild POKéMON will be repelled.{PAUSE_UNTIL_PRESS}");
const u8 gText_BoxFull[] = _("The BOX is full.{PAUSE_UNTIL_PRESS}");
-const u8 gText_PowderQty[] = _("POWDER QTY: {STR_VAR_1}{PAUSE_UNTIL_PRESS}");
const u8 gText_TheField[] = _("the field");
const u8 gText_TheBattle[] = _("the battle");
const u8 gText_ThePokemonList[] = _("the POKéMON LIST");
const u8 gText_TheShop[] = _("the shop");
const u8 gText_ThePC[] = _("the PC");
-const u8 gText_PlayedPokeFluteCatchy[] = _("Played the POKé FLUTE.\pNow, that's a catchy tune!{PAUSE_UNTIL_PRESS}");
-const u8 gText_PlayedPokeFlute[] = _("Played the POKé FLUTE.");
-const u8 gText_PokeFluteAwakenedMon[] = _("The POKé FLUTE awakened sleeping\nPOKéMON.{PAUSE_UNTIL_PRESS}");
const u8 *const gBagMenu_ReturnToStrings[] =
{
@@ -266,16 +236,6 @@ const u8 gText_HowManyToSell[] = _("{STR_VAR_2}?\nHow many would you like to sel
const u8 gText_ICanPayVar1[] = _("I can pay ¥{STR_VAR_1}.\nWould that be okay?");
const u8 gText_TurnedOverVar1ForVar2[] = _("Turned over the {STR_VAR_2}\nand received ¥{STR_VAR_1}.");
const u8 gText_PokedollarVar1[] = _("¥{STR_VAR_1}");
-const u8 gText_Shift[] = _("SHIFT");
-const u8 gText_SendOut[] = _("SEND OUT");
-const u8 gText_Switch2[] = _("SWITCH");
-const u8 gText_Summary5[] = _("SUMMARY");
-const u8 gText_Moves[] = _("MOVES"); // Unused
-const u8 gText_Enter[] = _("ENTER");
-const u8 gText_NoEntry[] = _("NO ENTRY");
-const u8 gText_Take2[] = _("TAKE");
-const u8 gText_Read2[] = _("READ");
-const u8 gText_Trade4[] = _("TRADE");
const u8 gText_HP3[] = _("HP");
const u8 gText_SpAtk3[] = _("SP. ATK");
const u8 gText_SpDef3[] = _("SP. DEF");
@@ -483,23 +443,7 @@ const u8 gText_Tristan[] = _("TRISTAN");
const u8 gText_Philip[] = _("PHILIP");
const u8 gText_Dennis[] = _("DENNIS");
const u8 gText_Roberto[] = _("ROBERTO");
-const u8 gText_TurnOff[] = _("TURN OFF");
-const u8 gText_Decoration[] = _("DECORATION");
-const u8 gText_ItemStorage[] = _("ITEM STORAGE");
-const u8 gText_Mailbox[] = _("MAILBOX");
-const u8 gText_DepositItem[] = _("DEPOSIT ITEM");
-const u8 gText_WithdrawItem[] = _("WITHDRAW ITEM");
-const u8 gText_TossItem[] = _("TOSS ITEM");
-const u8 gText_StoreItemsInPC[] = _("Store items in the PC.");
-const u8 gText_TakeOutItemsFromPC[] = _("Take out items from the PC.");
-const u8 gText_ThrowAwayItemsInPC[] = _("Throw away items stored in the PC.");
const u8 gText_NoItems[] = _("There are no items.{PAUSE_UNTIL_PRESS}");
-const u8 gText_NoRoomInBag[] = _("There is no more\nroom in the BAG.");
-const u8 gText_WithdrawHowManyItems[] = _("Withdraw how many\n{STR_VAR_1}?");
-const u8 gText_WithdrawXItems[] = _("Withdrew {STR_VAR_2}\n{STR_VAR_1}.");
-const u8 gText_Read[] = _("READ");
-const u8 gText_MoveToBag[] = _("MOVE TO BAG");
-const u8 gText_Give2[] = _("GIVE");
const u8 gText_NoMailHere[] = _("There's no MAIL here.{PAUSE_UNTIL_PRESS}");
const u8 gText_WhatToDoWithVar1sMail[] = _("What would you like to do with\n{STR_VAR_1}'s MAIL?");
const u8 gText_MessageWillBeLost[] = _("The message will be lost.\nIs that okay?");
@@ -513,17 +457,7 @@ const u8 gText_Brawly[] = _("BRAWLY");
const u8 gText_Winona[] = _("WINONA");
const u8 gText_Phoebe[] = _("PHOEBE");
const u8 gText_Glacia[] = _("GLACIA");
-const u8 gText_Petalburg[] = _("PETALBURG");
-const u8 gText_Slateport[] = _("SLATEPORT");
-const u8 gText_Littleroot[] = _("LITTLEROOT"); // Unused. Given the context, Briney may at one point have been able to sail the player here
-const u8 gText_Lilycove[] = _("LILYCOVE"); // Unused. Given the context, Briney may at one point have been able to sail the player here
-const u8 gText_Dewford[] = _("DEWFORD");
-const u8 gText_Enter2[] = _("ENTER");
const u8 gText_Info2[] = _("INFO");
-const u8 gText_WhatsAContest[] = _("What's a CONTEST?");
-const u8 gText_TypesOfContests[] = _("Types of CONTESTS");
-const u8 gText_Ranks[] = _("Ranks");
-const u8 gText_Judging[] = _("Judging"); //unused
const u8 gText_CoolnessContest[] = _("COOLNESS CONTEST");
const u8 gText_BeautyContest[] = _("BEAUTY CONTEST");
const u8 gText_CutenessContest[] = _("CUTENESS CONTEST");
@@ -531,71 +465,17 @@ const u8 gText_SmartnessContest[] = _("SMARTNESS CONTEST");
const u8 gText_ToughnessContest[] = _("TOUGHNESS CONTEST");
const u8 gText_Decoration2[] = _("DECORATION");
const u8 gText_PackUp[] = _("PACK UP");
-const u8 gText_Count[] = _("COUNT"); //unused
const u8 gText_Registry[] = _("REGISTRY");
const u8 gText_Information[] = _("INFORMATION");
-const u8 gText_Mach[] = _("MACH");
-const u8 gText_Acro[] = _("ACRO");
-const u8 gText_Psn[] = _("PSN");
-const u8 gText_Par[] = _("PAR");
-const u8 gText_Slp[] = _("SLP");
-const u8 gText_Brn[] = _("BRN");
-const u8 gText_Frz[] = _("FRZ");
-const u8 gText_Toxic[] = _("TOXIC"); // Unused
-const u8 gText_Ok3[] = _("OK"); // Unused
-const u8 gText_Quit[] = _("QUIT"); // Unused
-const u8 gText_SawIt[] = _("Saw it");
-const u8 gText_NotYet[] = _("Not yet");
const u8 gText_Yes[] = _("YES");
const u8 gText_No[] = _("NO");
-const u8 gText_Info4[] = _("INFO"); // Unused
-const u8 gText_SingleBattle[] = _("SINGLE BATTLE");
-const u8 gText_DoubleBattle[] = _("DOUBLE BATTLE");
-const u8 gText_MultiBattle[] = _("MULTI BATTLE");
-const u8 gText_MrBriney[] = _("MR. BRINEY"); // Unused
-const u8 gText_Challenge[] = _("CHALLENGE");
-const u8 gText_Info3[] = _("INFO");
const u8 gText_Lv50[] = _("LV. 50");
const u8 gText_OpenLevel[] = _("OPEN LEVEL");
-const u8 gText_FreshWaterAndPrice[] = _("FRESH WATER{CLEAR_TO 0x48}¥200");
-const u8 gText_SodaPopAndPrice[] = _("SODA POP{CLEAR_TO 0x48}¥300");
-const u8 gText_LemonadeAndPrice[] = _("LEMONADE{CLEAR_TO 0x48}¥350");
-const u8 gText_HowToRide[] = _("HOW TO RIDE");
-const u8 gText_HowToTurn[] = _("HOW TO TURN");
-const u8 gText_SandySlopes[] = _("SANDY SLOPES");
-const u8 gText_Wheelies[] = _("WHEELIES");
-const u8 gText_BunnyHops[] = _("BUNNY-HOPS");
-const u8 gText_Jump[] = _("JUMP");
-const u8 gText_Satisfied[] = _("Satisfied");
-const u8 gText_Dissatisfied[] = _("Dissatisfied");
-const u8 gText_DeepSeaTooth[] = _("DEEPSEATOOTH");
-const u8 gText_DeepSeaScale[] = _("DEEPSEASCALE");
-const u8 gText_BlueFlute2[] = _("BLUE FLUTE");
-const u8 gText_YellowFlute2[] = _("YELLOW FLUTE");
-const u8 gText_RedFlute2[] = _("RED FLUTE");
-const u8 gText_WhiteFlute2[] = _("WHITE FLUTE");
-const u8 gText_BlackFlute2[] = _("BLACK FLUTE");
-const u8 gText_GlassChair[] = _("GLASS CHAIR");
-const u8 gText_GlassDesk[] = _("GLASS DESK");
-const u8 gText_TreeckoDollAndPrice[] = _("TREECKO DOLL 1,000 COINS");
-const u8 gText_TorchicDollAndPrice[] = _("TORCHIC DOLL 1,000 COINS");
-const u8 gText_MudkipDollAndPrice[] = _("MUDKIP DOLL 1,000 COINS");
-const u8 gText_50CoinsAndPrice[] = _(" 50 COINS ¥1,000");
-const u8 gText_500CoinsAndPrice[] = _("500 COINS ¥10,000");
-const u8 gText_Excellent2[] = _("Excellent");
-const u8 gText_NotSoGood[] = _("Not so good");
const u8 gText_RedShard[] = _("RED SHARD");
const u8 gText_YellowShard[] = _("YELLOW SHARD");
const u8 gText_BlueShard[] = _("BLUE SHARD");
const u8 gText_GreenShard[] = _("GREEN SHARD");
const u8 gText_BattleFrontier[] = _("BATTLE FRONTIER");
-const u8 gText_Right[] = _("Right");
-const u8 gText_Left[] = _("Left");
-const u8 gText_TM32AndPrice[] = _("TM32{CLEAR_TO 0x48}1,500 COINS");
-const u8 gText_TM29AndPrice[] = _("TM29{CLEAR_TO 0x48}3,500 COINS");
-const u8 gText_TM35AndPrice[] = _("TM35{CLEAR_TO 0x48}4,000 COINS");
-const u8 gText_TM24AndPrice[] = _("TM24{CLEAR_TO 0x48}4,000 COINS");
-const u8 gText_TM13AndPrice[] = _("TM13{CLEAR_TO 0x48}4,000 COINS");
const u8 gText_Cool[] = _("COOL");
const u8 gText_Beauty[] = _("BEAUTY");
const u8 gText_Cute[] = _("CUTE");
@@ -623,21 +503,10 @@ const u8 gText_LogOff[] = _("LOG OFF");
const u8 gText_Opponent[] = _("OPPONENT");
const u8 gText_Tourney_Tree[] = _("TOURNEY TREE");
const u8 gText_ReadyToStart[] = _("READY TO START");
-const u8 gText_NormalRank[] = _("NORMAL RANK");
-const u8 gText_SuperRank[] = _("SUPER RANK");
-const u8 gText_HyperRank[] = _("HYPER RANK");
-const u8 gText_MasterRank[] = _("MASTER RANK");
const u8 gText_Single2[] = _("SINGLE");
const u8 gText_Double2[] = _("DOUBLE");
const u8 gText_Multi[] = _("MULTI");
const u8 gText_MultiLink[] = _("MULTI-LINK");
-const u8 gText_BattleBag[] = _("BATTLE BAG");
-const u8 gText_HeldItem[] = _("HELD ITEM");
-const u8 gText_LinkContest[] = _("LINK CONTEST");
-const u8 gText_AboutE_Mode[] = _("ABOUT E-MODE");
-const u8 gText_AboutG_Mode[] = _("ABOUT G-MODE");
-const u8 gText_E_Mode[] = _("E-MODE");
-const u8 gText_G_Mode[] = _("G-MODE");
const u8 gText_MenuOptionPokedex[] = _("POKéDEX");
const u8 gText_MenuOptionPokemon[] = _("POKéMON");
const u8 gText_MenuOptionBag[] = _("BAG");
@@ -646,22 +515,10 @@ const u8 gText_Blank[] = _("");
const u8 gText_MenuOptionSave[] = _("SAVE");
const u8 gText_MenuOptionOption[] = _("OPTION");
const u8 gText_MenuOptionExit[] = _("EXIT");
-const u8 gText_5BP[] = _(" 5BP");
-const u8 gText_10BP[] = _("10BP");
-const u8 gText_15BP[] = _("15BP");
-const u8 gText_RedTent[] = _("RED TENT");
-const u8 gText_BlueTent[] = _("BLUE TENT");
const u8 gText_SouthernIsland[] = _("SOUTHERN ISLAND");
const u8 gText_BirthIsland[] = _("BIRTH ISLAND");
const u8 gText_FarawayIsland[] = _("FARAWAY ISLAND");
const u8 gText_NavelRock[] = _("NAVEL ROCK");
-const u8 gText_ClawFossil[] = _("CLAW FOSSIL");
-const u8 gText_RootFossil[] = _("ROOT FOSSIL");
-const u8 gText_No4[] = _("NO");
-const u8 gText_IllBattleNow[] = _("I'll battle now!");
-const u8 gText_IWon[] = _("I won!");
-const u8 gText_ILost[] = _("I lost!");
-const u8 gText_IWontTell[] = _("I won't tell.");
const u8 gText_NormalTagMatch[] = _("NORMAL TAG MATCH");
const u8 gText_VarietyTagMatch[] = _("VARIETY TAG MATCH");
const u8 gText_UniqueTagMatch[] = _("UNIQUE TAG MATCH");
@@ -670,69 +527,25 @@ const u8 gText_TradeCenter[] = _("TRADE CENTER");
const u8 gText_Colosseum[] = _("COLOSSEUM");
const u8 gText_RecordCorner[] = _("RECORD CORNER");
const u8 gText_BerryCrush3[] = _("BERRY CRUSH");
-const u8 gText_EmptyLinkService[] = _(""); // Maybe Spin Trade?
-const u8 gText_PokemonJump[] = _("POKéMON JUMP");
-const u8 gText_DodrioBerryPicking[] = _("DODRIO BERRY-PICKING");
-const u8 gText_BecomeLeader[] = _("BECOME LEADER");
-const u8 gText_JoinGroup[] = _("JOIN GROUP");
-const u8 gText_TwoStyles[] = _("TWO STYLES");
-const u8 gText_Lv50_3[] = _("LV. 50");
-const u8 gText_OpenLevel2[] = _("OPEN LEVEL");
-const u8 gText_MonTypeAndNo[] = _("{PKMN} TYPE & NO.");
-const u8 gText_HoldItems[] = _("HOLD ITEMS");
-const u8 gText_Symbols2[] = _("SYMBOLS");
-const u8 gText_Record3[] = _("RECORD");
-const u8 gText_BattlePts[] = _("BATTLE PTS");
-const u8 gText_TowerInfo[] = _("TOWER INFO");
-const u8 gText_BattleMon[] = _("BATTLE {PKMN}");
-const u8 gText_BattleSalon[] = _("BATTLE SALON");
-const u8 gText_MultiLink2[] = _("MULTI-LINK");
const u8 gText_BattleRules[] = _("BATTLE RULES");
const u8 gText_JudgeMind[] = _("JUDGE: MIND");
const u8 gText_JudgeSkill[] = _("JUDGE: SKILL");
const u8 gText_JudgeBody[] = _("JUDGE: BODY");
-const u8 gText_Matchup[] = _("MATCHUP");
-const u8 gText_TourneyTree[] = _("TOURNEY TREE");
-const u8 gText_DoubleKO[] = _("DOUBLE KO");
const u8 gText_BasicRules[] = _("BASIC RULES");
const u8 gText_SwapPartners[] = _("SWAP: PARTNER");
const u8 gText_SwapNumber[] = _("SWAP: NUMBER");
const u8 gText_SwapNotes[] = _("SWAP: NOTES");
-const u8 gText_OpenLevel3[] = _("OPEN LEVEL");
const u8 gText_BattleBasics[] = _("BATTLE BASICS");
const u8 gText_PokemonNature[] = _("POKéMON NATURE");
const u8 gText_PokemonMoves[] = _("POKéMON MOVES");
const u8 gText_Underpowered[] = _("UNDERPOWERED");
const u8 gText_WhenInDanger[] = _("WHEN IN DANGER");
-const u8 gText_PyramidPokemon[] = _("PYRAMID: POKéMON");
-const u8 gText_PyramidTrainers[] = _("PYRAMID: TRAINERS");
-const u8 gText_PyramidMaze[] = _("PYRAMID: MAZE");
-const u8 gText_BattleBag2[] = _("BATTLE BAG");
-const u8 gText_PokenavAndBag[] = _("POKéNAV AND BAG");
-const u8 gText_HeldItems[] = _("HELD ITEMS");
-const u8 gText_PokemonOrder[] = _("POKéMON ORDER");
const u8 gText_BattlePokemon[] = _("BATTLE POKéMON");
const u8 gText_BattleTrainers[] = _("BATTLE TRAINERS");
const u8 gText_GoOn[] = _("GO ON");
const u8 gText_Record2[] = _("RECORD");
const u8 gText_Rest[] = _("REST");
const u8 gText_Retire[] = _("RETIRE");
-const u8 gText_99TimesPlus[] = _("99 times +");
-const u8 gText_1MinutePlus[] = _("1 minute +");
-const u8 gText_SpaceSeconds[] = _(" seconds");
-const u8 gText_SpaceTimes[] = _(" time(s)");
-const u8 gText_Dot[] = _("."); // Unused
-const u8 gText_BigGuy[] = _("Big guy");
-const u8 gText_BigGirl[] = _("Big girl");
-const u8 gText_Son[] = _("son");
-const u8 gText_Daughter[] = _("daughter");
-const u8 gText_BlueFlute[] = _("BLUE FLUTE");
-const u8 gText_YellowFlute[] = _("YELLOW FLUTE");
-const u8 gText_RedFlute[] = _("RED FLUTE");
-const u8 gText_WhiteFlute[] = _("WHITE FLUTE");
-const u8 gText_BlackFlute[] = _("BLACK FLUTE");
-const u8 gText_PrettyChair[] = _("PRETTY CHAIR");
-const u8 gText_PrettyDesk[] = _("PRETTY DESK");
const u8 gText_1F[] = _("1F");
const u8 gText_2F[] = _("2F");
const u8 gText_3F[] = _("3F");
@@ -751,25 +564,10 @@ const u8 gText_B4F[] = _("B4F");
const u8 gText_Rooftop[] = _("ROOFTOP");
const u8 gText_ElevatorNowOn[] = _("Now on:");
const u8 gText_BP[] = _("BP");
-const u8 gText_EnergyPowder50[] = _("ENERGYPOWDER{CLEAR_TO 114}{FONT_SMALL}50");
-const u8 gText_EnergyRoot80[] = _("ENERGY ROOT{CLEAR_TO 114}{FONT_SMALL}80");
-const u8 gText_HealPowder50[] = _("HEAL POWDER{CLEAR_TO 114}{FONT_SMALL}50");
-const u8 gText_RevivalHerb300[] = _("REVIVAL HERB{CLEAR_TO 108}{FONT_SMALL}300");
-const u8 gText_Protein1000[] = _("PROTEIN{CLEAR_TO 99}{FONT_SMALL}1,000");
-const u8 gText_Iron1000[] = _("IRON{CLEAR_TO 99}{FONT_SMALL}1,000");
-const u8 gText_Carbos1000[] = _("CARBOS{CLEAR_TO 99}{FONT_SMALL}1,000");
-const u8 gText_Calcium1000[] = _("CALCIUM{CLEAR_TO 99}{FONT_SMALL}1,000");
-const u8 gText_Zinc1000[] = _("ZINC{CLEAR_TO 99}{FONT_SMALL}1,000");
-const u8 gText_HPUp1000[] = _("HP UP{CLEAR_TO 99}{FONT_SMALL}1,000");
-const u8 gText_PPUp3000[] = _("PP UP{CLEAR_TO 99}{FONT_SMALL}3,000");
const u8 gText_RankingHall[] = _("RANKING HALL");
const u8 gText_ExchangeService[] = _("EXCHANGE SERVICE");
const u8 gText_LilycoveCity[] = _("LILYCOVE CITY");
const u8 gText_SlateportCity[] = _("SLATEPORT CITY");
-const u8 gText_CaveOfOrigin[] = _("CAVE OF ORIGIN");
-const u8 gText_MtPyre[] = _("MT. PYRE");
-const u8 gText_SkyPillar[] = _("SKY PILLAR");
-const u8 gText_DontRemember[] = _("Don't remember");
const u8 gText_Exit[] = _("EXIT");
const u8 gText_YourPartysFull[] = _("Your party's full!{PAUSE_UNTIL_PRESS}");
const u8 gText_NatureSlash[] = _("NATURE/");
@@ -909,68 +707,6 @@ const u8 gText_Jackpot[] = _("jackpot");
const u8 gText_First[] = _("first");
const u8 gText_Second[] = _("second");
const u8 gText_Third[] = _("third");
-const u8 gText_0Pts[] = _("0 pts");
-const u8 gText_10Pts[] = _("10 pts");
-const u8 gText_20Pts[] = _("20 pts");
-const u8 gText_30Pts[] = _("30 pts");
-const u8 gText_40Pts[] = _("40 pts");
-const u8 gText_50Pts[] = _("50 pts");
-const u8 gText_60Pts[] = _("60 pts");
-const u8 gText_70Pts[] = _("70 pts");
-const u8 gText_80Pts[] = _("80 pts");
-const u8 gText_90Pts[] = _("90 pts");
-const u8 gText_100Pts[] = _("100 pts");
-const u8 gText_QuestionMark[] = _("?");
-const u8 gText_KissPoster16BP[] = _("KISS POSTER{CLEAR_TO 0x5E}16BP");
-const u8 gText_KissCushion32BP[] = _("KISS CUSHION{CLEAR_TO 0x5E}32BP");
-const u8 gText_SmoochumDoll32BP[] = _("SMOOCHUM DOLL{CLEAR_TO 0x5E}32BP");
-const u8 gText_TogepiDoll48BP[] = _("TOGEPI DOLL{CLEAR_TO 0x5E}48BP");
-const u8 gText_MeowthDoll48BP[] = _("MEOWTH DOLL{CLEAR_TO 0x5E}48BP");
-const u8 gText_ClefairyDoll48BP[] = _("CLEFAIRY DOLL{CLEAR_TO 0x5E}48BP");
-const u8 gText_DittoDoll48BP[] = _("DITTO DOLL{CLEAR_TO 0x5E}48BP");
-const u8 gText_CyndaquilDoll80BP[] = _("CYNDAQUIL DOLL{CLEAR_TO 0x5E}80BP");
-const u8 gText_ChikoritaDoll80BP[] = _("CHIKORITA DOLL{CLEAR_TO 0x5E}80BP");
-const u8 gText_TotodileDoll80BP[] = _("TOTODILE DOLL{CLEAR_TO 0x5E}80BP");
-const u8 gText_LaprasDoll128BP[] = _("LAPRAS DOLL{CLEAR_TO 0x58}128BP");
-const u8 gText_SnorlaxDoll128BP[] = _("SNORLAX DOLL{CLEAR_TO 0x58}128BP");
-const u8 gText_VenusaurDoll256BP[] = _("VENUSAUR DOLL{CLEAR_TO 0x58}256BP");
-const u8 gText_CharizardDoll256BP[] = _("CHARIZARD DOLL{CLEAR_TO 0x58}256BP");
-const u8 gText_BlastoiseDoll256BP[] = _("BLASTOISE DOLL{CLEAR_TO 0x58}256BP");
-const u8 gText_Protein1BP[] = _("PROTEIN{CLEAR_TO 0x64}1BP");
-const u8 gText_Calcium1BP[] = _("CALCIUM{CLEAR_TO 0x64}1BP");
-const u8 gText_Iron1BP[] = _("IRON{CLEAR_TO 0x64}1BP");
-const u8 gText_Zinc1BP[] = _("ZINC{CLEAR_TO 0x64}1BP");
-const u8 gText_Carbos1BP[] = _("CARBOS{CLEAR_TO 0x64}1BP");
-const u8 gText_HpUp1BP[] = _("HP UP{CLEAR_TO 0x64}1BP");
-const u8 gText_Leftovers48BP[] = _("LEFTOVERS{CLEAR_TO 0x5E}48BP");
-const u8 gText_WhiteHerb48BP[] = _("WHITE HERB{CLEAR_TO 0x5E}48BP");
-const u8 gText_QuickClaw48BP[] = _("QUICK CLAW{CLEAR_TO 0x5E}48BP");
-const u8 gText_MentalHerb48BP[] = _("MENTAL HERB{CLEAR_TO 0x5E}48BP");
-const u8 gText_BrightPowder64BP[] = _("BRIGHTPOWDER{CLEAR_TO 0x5E}64BP");
-const u8 gText_ChoiceBand64BP[] = _("CHOICE BAND{CLEAR_TO 0x5E}64BP");
-const u8 gText_KingsRock64BP[] = _("KING'S ROCK{CLEAR_TO 0x5E}64BP");
-const u8 gText_FocusBand64BP[] = _("FOCUS BAND{CLEAR_TO 0x5E}64BP");
-const u8 gText_ScopeLens64BP[] = _("SCOPE LENS{CLEAR_TO 0x5E}64BP");
-const u8 gText_Softboiled16BP[] = _("SOFTBOILED{CLEAR_TO 0x4E}16BP");
-const u8 gText_SeismicToss24BP[] = _("SEISMIC TOSS{CLEAR_TO 0x4E}24BP");
-const u8 gText_DreamEater24BP[] = _("DREAM EATER{CLEAR_TO 0x4E}24BP");
-const u8 gText_MegaPunch24BP[] = _("MEGA PUNCH{CLEAR_TO 0x4E}24BP");
-const u8 gText_MegaKick48BP[] = _("MEGA KICK{CLEAR_TO 0x4E}48BP");
-const u8 gText_BodySlam48BP[] = _("BODY SLAM{CLEAR_TO 0x4E}48BP");
-const u8 gText_RockSlide48BP[] = _("ROCK SLIDE{CLEAR_TO 0x4E}48BP");
-const u8 gText_Counter48BP[] = _("COUNTER{CLEAR_TO 0x4E}48BP");
-const u8 gText_ThunderWave48BP[] = _("THUNDER WAVE{CLEAR_TO 0x4E}48BP");
-const u8 gText_SwordsDance48BP[] = _("SWORDS DANCE{CLEAR_TO 0x4E}48BP");
-const u8 gText_DefenseCurl16BP[] = _("DEFENSE CURL{CLEAR_TO 0x4E}16BP");
-const u8 gText_Snore24BP[] = _("SNORE{CLEAR_TO 0x4E}24BP");
-const u8 gText_MudSlap24BP[] = _("MUD-SLAP{CLEAR_TO 0x4E}24BP");
-const u8 gText_Swift24BP[] = _("SWIFT{CLEAR_TO 0x4E}24BP");
-const u8 gText_IcyWind24BP[] = _("ICY WIND{CLEAR_TO 0x4E}24BP");
-const u8 gText_Endure48BP[] = _("ENDURE{CLEAR_TO 0x4E}48BP");
-const u8 gText_PsychUp48BP[] = _("PSYCH UP{CLEAR_TO 0x4E}48BP");
-const u8 gText_IcePunch48BP[] = _("ICE PUNCH{CLEAR_TO 0x4E}48BP");
-const u8 gText_ThunderPunch48BP[] = _("THUNDERPUNCH{CLEAR_TO 0x4E}48BP");
-const u8 gText_FirePunch48BP[] = _("FIRE PUNCH{CLEAR_TO 0x4E}48BP");
#if OW_POISON_DAMAGE < GEN_4
const u8 gText_PkmnFainted_FldPsn[] = _("{STR_VAR_1} fainted…\p\n");
#else
@@ -1193,9 +929,6 @@ const u8 gJPText_ConnectionComplete[] = _("つうしん しゅうりょう!"
const u8 gJPText_NewTrainerHasComeToHoenn[] = _("あらたな トレーナーが\nホウエンに やってきた!");
const u8 gJPText_PleaseWaitAMoment[] = _("しばらく おまちください");
const u8 gJPText_WriteErrorUnableToSaveData[] = _("かきこみ エラー です\nデータが ほぞん できませんでした");
-const u8 gText_Red[] = _("RED");
-const u8 gText_Blue[] = _("BLUE");
-const u8 gText_3Dashes[] = _("---"); // Unused
const u8 gText_SingleBattleRoomResults[] = _("{PLAYER}'s Single Battle Room Results");
const u8 gText_DoubleBattleRoomResults[] = _("{PLAYER}'s Double Battle Room Results");
const u8 gText_MultiBattleRoomResults[] = _("{PLAYER}'s Multi Battle Room Results");
@@ -1498,14 +1231,6 @@ const u8 gText_TrainerHill1F[] = _("1F");
const u8 gText_TrainerHill2F[] = _("2F");
const u8 gText_TrainerHill3F[] = _("3F");
const u8 gText_TrainerHill4F[] = _("4F");
-const u8 gText_LightBulb[] = _("Light bulb");
-const u8 gText_MicrowaveOven[] = _("Microwave oven");
-const u8 gText_WashingMachine[] = _("Washing machine");
-const u8 gText_Refrigerator[] = _("Refrigerator");
-const u8 gText_ElectricFan[] = _("Electric fan");
-const u8 gText_LawnMower[] = _("Lawn mower");
-const u8 gText_ChangeForm[] = _("Change form");
-const u8 gText_ChangeAbility[] = _("Change Ability");
const u8 gText_TeachWhichMoveToPkmn[] = _("Teach which move to\n{STR_VAR_1}?");
const u8 gText_MoveRelearnerTeachMoveConfirm[] = _("Teach {STR_VAR_2}?");
const u8 gText_MoveRelearnerPkmnLearnedMove[] = _("{STR_VAR_1} learned\n{STR_VAR_2}!");
@@ -1564,8 +1289,6 @@ const u8 gText_Berries[] = _("BERRIES");
const u8 gText_ExpShareOn[] = _("The Exp. Share has been turned on.{PAUSE_UNTIL_PRESS}");
const u8 gText_ExpShareOff[] = _("The Exp. Share has been turned off.{PAUSE_UNTIL_PRESS}");
const u8 gText_BasePointsResetToZero[] = _("{STR_VAR_1}'s base points\nwere all reset to zero!{PAUSE_UNTIL_PRESS}");
-const u8 gText_Fertilize[] = _("FERTILIZE");
-const u8 gText_PlantBerry[] = _("PLANT BERRY");
const u8 gText_AM[] = _("AM");
const u8 gText_PM[] = _("PM");
const u8 gText_Relearn[] = _("{START_BUTTON} RELEARN"); // future note: don't decap this, because it mimics the summary screen BG graphics which will not get decapped
diff --git a/src/text.c b/src/text.c
index acb2871a86..29ffc5ea3a 100644
--- a/src/text.c
+++ b/src/text.c
@@ -26,6 +26,7 @@ static u16 FontFunc_SmallNarrow(struct TextPrinter *);
static u16 FontFunc_Narrower(struct TextPrinter *);
static u16 FontFunc_SmallNarrower(struct TextPrinter *);
static u16 FontFunc_ShortNarrow(struct TextPrinter *);
+static u16 FontFunc_ShortNarrower(struct TextPrinter *);
static void DecompressGlyph_Small(u16, bool32);
static void DecompressGlyph_Normal(u16, bool32);
static void DecompressGlyph_Short(u16, bool32);
@@ -35,6 +36,7 @@ static void DecompressGlyph_Bold(u16);
static void DecompressGlyph_Narrower(u16, bool32);
static void DecompressGlyph_SmallNarrower(u16, bool32);
static void DecompressGlyph_ShortNarrow(u16, bool32);
+static void DecompressGlyph_ShortNarrower(u16, bool32);
static u32 GetGlyphWidth_Small(u16, bool32);
static u32 GetGlyphWidth_Normal(u16, bool32);
static u32 GetGlyphWidth_Short(u16, bool32);
@@ -43,6 +45,7 @@ static u32 GetGlyphWidth_SmallNarrow(u16, bool32);
static u32 GetGlyphWidth_Narrower(u16, bool32);
static u32 GetGlyphWidth_SmallNarrower(u16, bool32);
static u32 GetGlyphWidth_ShortNarrow(u16, bool32);
+static u32 GetGlyphWidth_ShortNarrower(u16, bool32);
static EWRAM_DATA struct TextPrinter sTempTextPrinter = {0};
static EWRAM_DATA struct TextPrinter sTextPrinters[WINDOWS_MAX] = {0};
@@ -102,6 +105,7 @@ static const struct GlyphWidthFunc sGlyphWidthFuncs[] =
{ FONT_NARROWER, GetGlyphWidth_Narrower },
{ FONT_SMALL_NARROWER, GetGlyphWidth_SmallNarrower },
{ FONT_SHORT_NARROW, GetGlyphWidth_ShortNarrow },
+ { FONT_SHORT_NARROWER, GetGlyphWidth_ShortNarrower },
};
struct
@@ -260,6 +264,16 @@ static const struct FontInfo sFontInfos[] =
.bgColor = 1,
.shadowColor = 3,
},
+ [FONT_SHORT_NARROWER] = {
+ .fontFunction = FontFunc_ShortNarrower,
+ .maxLetterWidth = 5,
+ .maxLetterHeight = 14,
+ .letterSpacing = 0,
+ .lineSpacing = 0,
+ .fgColor = 2,
+ .bgColor = 1,
+ .shadowColor = 3,
+ },
};
static const u8 sMenuCursorDimensions[][2] =
@@ -277,6 +291,7 @@ static const u8 sMenuCursorDimensions[][2] =
[FONT_NARROWER] = { 8, 15 },
[FONT_SMALL_NARROWER] = { 8, 8 },
[FONT_SHORT_NARROW] = { 8, 14 },
+ [FONT_SHORT_NARROWER] = { 8, 14 },
};
static const u16 sFontBoldJapaneseGlyphs[] = INCBIN_U16("graphics/fonts/bold.hwjpnfont");
@@ -850,6 +865,18 @@ static u16 FontFunc_ShortNarrow(struct TextPrinter *textPrinter)
return RenderText(textPrinter);
}
+static u16 FontFunc_ShortNarrower(struct TextPrinter *textPrinter)
+{
+ struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
+
+ if (subStruct->hasFontIdBeenSet == FALSE)
+ {
+ subStruct->fontId = FONT_SHORT_NARROWER;
+ subStruct->hasFontIdBeenSet = TRUE;
+ }
+ return RenderText(textPrinter);
+}
+
void TextPrinterInitDownArrowCounters(struct TextPrinter *textPrinter)
{
struct TextPrinterSubStruct *subStruct = (struct TextPrinterSubStruct *)(&textPrinter->subStructFields);
@@ -1238,6 +1265,9 @@ static u16 RenderText(struct TextPrinter *textPrinter)
case FONT_SHORT_NARROW:
DecompressGlyph_ShortNarrow(currChar, textPrinter->japanese);
break;
+ case FONT_SHORT_NARROWER:
+ DecompressGlyph_ShortNarrower(currChar, textPrinter->japanese);
+ break;
case FONT_BRAILLE:
break;
}
@@ -2161,6 +2191,50 @@ static u32 GetGlyphWidth_ShortNarrow(u16 glyphId, bool32 isJapanese)
return gFontShortNarrowLatinGlyphWidths[glyphId];
}
+static void DecompressGlyph_ShortNarrower(u16 glyphId, bool32 isJapanese)
+{
+ const u16 *glyphs;
+
+ if (isJapanese == TRUE)
+ {
+ glyphs = gFontShortJapaneseGlyphs + (0x100 * (glyphId >> 0x3)) + (0x10 * (glyphId & 0x7));
+ DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
+ DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
+ DecompressGlyphTile(glyphs + 0x80, gCurGlyph.gfxBufferBottom); // gCurGlyph + 0x20
+ DecompressGlyphTile(glyphs + 0x88, gCurGlyph.gfxBufferBottom + 8); // gCurGlyph + 0x60
+ gCurGlyph.width = gFontShortJapaneseGlyphWidths[glyphId];
+ gCurGlyph.height = 14;
+ }
+ else
+ {
+ glyphs = gFontShortNarrowerLatinGlyphs + (0x20 * glyphId);
+ gCurGlyph.width = gFontShortNarrowerLatinGlyphWidths[glyphId];
+
+ if (gCurGlyph.width <= 8)
+ {
+ DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
+ DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
+ }
+ else
+ {
+ DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
+ DecompressGlyphTile(glyphs + 0x8, gCurGlyph.gfxBufferTop + 8);
+ DecompressGlyphTile(glyphs + 0x10, gCurGlyph.gfxBufferBottom);
+ DecompressGlyphTile(glyphs + 0x18, gCurGlyph.gfxBufferBottom + 8);
+ }
+
+ gCurGlyph.height = 14;
+ }
+}
+
+static u32 GetGlyphWidth_ShortNarrower(u16 glyphId, bool32 isJapanese)
+{
+ if (isJapanese == TRUE)
+ return gFontShortJapaneseGlyphWidths[glyphId];
+ else
+ return gFontShortNarrowerLatinGlyphWidths[glyphId];
+}
+
static const s8 sNarrowerFontIds[] =
{
[FONT_SMALL] = FONT_SMALL_NARROW,
@@ -2175,7 +2249,8 @@ static const s8 sNarrowerFontIds[] =
[FONT_BOLD] = -1,
[FONT_NARROWER] = -1,
[FONT_SMALL_NARROWER] = -1,
- [FONT_SHORT_NARROW] = -1,
+ [FONT_SHORT_NARROW] = FONT_SHORT_NARROWER,
+ [FONT_SHORT_NARROWER] = -1,
};
// If the narrowest font ID doesn't fit the text, we still return that
diff --git a/src/trainer_hill.c b/src/trainer_hill.c
index c89803ffb2..dd8ae78aa7 100644
--- a/src/trainer_hill.c
+++ b/src/trainer_hill.c
@@ -212,6 +212,14 @@ static const struct TrainerHillChallenge *const sChallengeData[NUM_TRAINER_HILL_
[HILL_MODE_EXPERT] = &sChallenge_Expert,
};
+static const struct TrainerHillFloor *const sFloorData[NUM_TRAINER_HILL_MODES] =
+{
+ [HILL_MODE_NORMAL] = &sFloors_Normal[0],
+ [HILL_MODE_VARIETY] = &sFloors_Variety[0],
+ [HILL_MODE_UNIQUE] = &sFloors_Unique[0],
+ [HILL_MODE_EXPERT] = &sFloors_Expert[0],
+};
+
// Unused.
static const u8 *const sFloorStrings[] =
{
@@ -357,20 +365,14 @@ void FreeTrainerHillBattleStruct(void)
static void SetUpDataStruct(void)
{
#if FREE_TRAINER_HILL == FALSE
- if (sHillData == NULL)
- {
- sHillData = AllocZeroed(sizeof(*sHillData));
- sHillData->floorId = gMapHeader.mapLayoutId - LAYOUT_TRAINER_HILL_1F;
+ if (sHillData != NULL) return;
- // This copy depends on the floor data for each challenge being directly after the
- // challenge header data, and for the field 'floors' in sHillData to come directly
- // after the field 'challenge'.
- // e.g. for HILL_MODE_NORMAL, it will copy sChallenge_Normal to sHillData->challenge and
- // it will copy sFloors_Normal to sHillData->floors
- CpuCopy32(sChallengeData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->challenge, sizeof(sHillData->challenge) + sizeof(sHillData->floors));
- TrainerHillDummy();
- }
-#endif //FREE_TRAINER_HILL
+ sHillData = AllocZeroed(sizeof(*sHillData));
+ sHillData->floorId = gMapHeader.mapLayoutId - LAYOUT_TRAINER_HILL_1F;
+
+ CpuCopy32(sChallengeData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->challenge, sizeof(sHillData->challenge));
+ CpuCopy32(sFloorData[gSaveBlock1Ptr->trainerHill.mode], &sHillData->floors, sizeof(sHillData->floors));
+#endif // FREE_TRAINER_HILL
}
static void FreeDataStruct(void)
diff --git a/src/tv.c b/src/tv.c
index 9030c21478..8313ee9bf5 100644
--- a/src/tv.c
+++ b/src/tv.c
@@ -5334,7 +5334,8 @@ static void DoTVShow3CheersForPokeblocks(void)
if (show->threeCheers.sheen > 24)
{
StringCopy(gStringVar2, gText_Excellent);
- } else if (show->threeCheers.sheen > 22)
+ }
+ else if (show->threeCheers.sheen > 22)
{
StringCopy(gStringVar2, gText_VeryGood);
}
diff --git a/test/battle/ability/aerilate.c b/test/battle/ability/aerilate.c
index 4386034a59..efd6776d9b 100644
--- a/test/battle/ability/aerilate.c
+++ b/test/battle/ability/aerilate.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
}
SINGLE_BATTLE_TEST("Aerilate turns a Normal-type move into Flying-type move")
diff --git a/test/battle/ability/anger_point.c b/test/battle/ability/anger_point.c
index b803b40f3f..7e8be8cb33 100644
--- a/test/battle/ability/anger_point.c
+++ b/test/battle/ability/anger_point.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Anger Point raises Attack stage to maximum after receiving a critical hit")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
+ ASSUME(MoveAlwaysCrits(MOVE_FROST_BREATH));
PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); }
OPPONENT(SPECIES_SNORUNT);
} WHEN {
@@ -23,8 +23,8 @@ SINGLE_BATTLE_TEST("Anger Point raises Attack stage to maximum after receiving a
SINGLE_BATTLE_TEST("Anger Point does not trigger when already at maximum Attack stage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
- ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
+ ASSUME(MoveAlwaysCrits(MOVE_FROST_BREATH));
+ ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM);
PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); Speed(2); }
OPPONENT(SPECIES_SNORUNT) { Speed(1); }
} WHEN {
@@ -50,8 +50,8 @@ TO_DO_BATTLE_TEST("Anger Point triggers when a substitute takes the hit (Gen4)")
SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit (Gen5+)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
- ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
+ ASSUME(MoveAlwaysCrits(MOVE_FROST_BREATH));
+ ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); Speed(2); }
OPPONENT(SPECIES_SNORUNT) { Speed(1); }
} WHEN {
diff --git a/test/battle/ability/anger_shell.c b/test/battle/ability/anger_shell.c
index c5b490216b..0dde568ca0 100644
--- a/test/battle/ability/anger_shell.c
+++ b/test/battle/ability/anger_shell.c
@@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Anger Shell activates only if the target had more than 50% o
PARAMETRIZE { hp = 254; activates = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_KLAWF) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -41,7 +41,7 @@ SINGLE_BATTLE_TEST("Anger Shell lowers Def/Sp.Def by 1 and raises Atk/Sp.Atk/Spd
{
u16 maxHp = 500;
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_KLAWF) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(maxHp / 2 + 1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -73,7 +73,7 @@ SINGLE_BATTLE_TEST("Anger Shell activates after all hits from a multi-hit move")
u32 j;
u16 maxHp = 500;
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SLAP) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_KLAWF) { Ability(ABILITY_ANGER_SHELL); MaxHP(maxHp); HP(maxHp / 2 + 1); }
OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); } // Always hits 5 times.
} WHEN {
diff --git a/test/battle/ability/battle_bond.c b/test/battle/ability/battle_bond.c
index f61a6d171c..f480367798 100644
--- a/test/battle/ability/battle_bond.c
+++ b/test/battle/ability/battle_bond.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WATER_GUN].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_WATER_GUN));
}
SINGLE_BATTLE_TEST("Battle Bond does not transform species other than Greninja")
diff --git a/test/battle/ability/beads_of_ruin.c b/test/battle/ability/beads_of_ruin.c
index bbc71f6c2b..63b07d7c8a 100644
--- a/test/battle/ability/beads_of_ruin.c
+++ b/test/battle/ability/beads_of_ruin.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY);
+ ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY);
}
SINGLE_BATTLE_TEST("Beads of Ruin reduces Sp. Def if opposing mon's ability doesn't match")
@@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Beads of Ruin reduces Sp. Def if opposing mon's ability does
SINGLE_BATTLE_TEST("Beads of Ruin's message displays correctly after all battlers fainted - Player")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) { HP(1);}
PLAYER(SPECIES_CHI_YU);
OPPONENT(SPECIES_WOBBUFFET);
@@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Beads of Ruin's message displays correctly after all battler
SINGLE_BATTLE_TEST("Beads of Ruin's message displays correctly after all battlers fainted - Opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { HP(1);}
diff --git a/test/battle/ability/berserk.c b/test/battle/ability/berserk.c
index 3bf269e1ee..c96bb260f8 100644
--- a/test/battle/ability/berserk.c
+++ b/test/battle/ability/berserk.c
@@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Berserk activates only if the target had more than 50% of it
PARAMETRIZE { hp = 254; activates = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_DRAMPA) { Ability(ABILITY_BERSERK); MaxHP(maxHp); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Berserk raises Sp.Atk by 1")
{
u16 maxHp = 500;
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_DRAMPA) { Ability(ABILITY_BERSERK); MaxHP(maxHp); HP(maxHp / 2 + 1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Berserk activates after all hits from a multi-hit move")
u32 j;
u16 maxHp = 500;
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SLAP) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_DRAMPA) { Ability(ABILITY_BERSERK); MaxHP(maxHp); HP(maxHp / 2 + 1); }
OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); } // Always hits 5 times.
} WHEN {
diff --git a/test/battle/ability/blaze.c b/test/battle/ability/blaze.c
index a21d133359..c68c7466a1 100644
--- a/test/battle/ability/blaze.c
+++ b/test/battle/ability/blaze.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage)
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
PLAYER(SPECIES_CHARMANDER) { Ability(ABILITY_BLAZE); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/clear_body.c b/test/battle/ability/clear_body.c
index 1e955431a1..89b89e96bf 100644
--- a/test/battle/ability/clear_body.c
+++ b/test/battle/ability/clear_body.c
@@ -58,13 +58,13 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke prevent stat st
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN);
- ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_FAKE_TEARS].effect == EFFECT_SPECIAL_DEFENSE_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SWEET_SCENT].effect == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN));
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN);
+ ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_FAKE_TEARS) == EFFECT_SPECIAL_DEFENSE_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_SWEET_SCENT) == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN));
+ ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN);
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -91,7 +91,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke prevent Sticky
PARAMETRIZE{ species = SPECIES_SOLGALEO; ability = ABILITY_FULL_METAL_BODY; }
PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
+ ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(SPECIES_WOBBUFFET)
OPPONENT(species) { Ability(ability); }
@@ -166,13 +166,13 @@ SINGLE_BATTLE_TEST("Mold Breaker, Teravolt, and Turboblaze ignore Clear Body and
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN);
- ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_FAKE_TEARS].effect == EFFECT_SPECIAL_DEFENSE_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SWEET_SCENT].effect == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN));
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN);
+ ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_FAKE_TEARS) == EFFECT_SPECIAL_DEFENSE_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_SWEET_SCENT) == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN));
+ ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN);
PLAYER(SPECIES_WOBBUFFET) { Ability(breakerAbility); }
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -284,7 +284,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent A
PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; burned = FALSE; }
PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; burned = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(species) { Ability(ability); if (burned) Status1(STATUS1_BURN); }
} WHEN {
@@ -306,8 +306,8 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent r
PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2);
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(3); }
OPPONENT(species) { Speed(6); Ability(ability); }
@@ -336,9 +336,9 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent T
PARAMETRIZE{ species = SPECIES_TORKOAL; ability = ABILITY_WHITE_SMOKE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY);
- ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2);
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY);
+ ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(3); }
OPPONENT(species) { Speed(6); Ability(ability); }
@@ -378,7 +378,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent S
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF) == TRUE);
- ASSUME(gMovesInfo[MOVE_AGILITY].effect == EFFECT_SPEED_UP_2);
+ ASSUME(GetMoveEffect(MOVE_AGILITY) == EFFECT_SPEED_UP_2);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
OPPONENT(species) { Speed(5); Ability(ability); }
} WHEN {
diff --git a/test/battle/ability/cloud_nine.c b/test/battle/ability/cloud_nine.c
index fb87b7f2ba..613ea86e0a 100644
--- a/test/battle/ability/cloud_nine.c
+++ b/test/battle/ability/cloud_nine.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but witho
PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; }
PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM);
+ ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM);
PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/commander.c b/test/battle/ability/commander.c
index 7eca97dacf..2220fb9ec2 100644
--- a/test/battle/ability/commander.c
+++ b/test/battle/ability/commander.c
@@ -175,7 +175,7 @@ DOUBLE_BATTLE_TEST("Commander prevents Red Card from working while Commander is
DOUBLE_BATTLE_TEST("Commander Tatsugiri is not damaged by a double target move if Dondozo faints")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_DONDOZO) { HP(1); };
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
PLAYER(SPECIES_WYNAUT);
@@ -187,9 +187,9 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri is not damaged by a double target move i
ABILITY_POPUP(playerRight, ABILITY_COMMANDER);
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
HP_BAR(playerLeft);
- MESSAGE("Dondozo fainted!");
- NOT HP_BAR(playerRight);
HP_BAR(opponentRight);
+ NOT HP_BAR(playerRight);
+ MESSAGE("Dondozo fainted!");
}
}
@@ -308,7 +308,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri is still affected by Haze while controll
DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Left Slot)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
PLAYER(SPECIES_DONDOZO);
@@ -323,15 +323,15 @@ DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Left Slot)")
MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, opponentLeft);
HP_BAR(playerLeft);
- MESSAGE("The opposing Wobbuffet's attack missed!");
HP_BAR(opponentRight);
+ MESSAGE("The opposing Wobbuffet's attack missed!");
}
}
DOUBLE_BATTLE_TEST("Commander Attacker is kept (Dondozo Right Slot)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_DONDOZO);
@@ -380,7 +380,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri does not attack if Dondozo faints the sa
DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when a commanded Dondozo faints")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_DONDOZO) { HP(1); }
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
@@ -402,7 +402,7 @@ DOUBLE_BATTLE_TEST("Commander Tatsugiri does not get hit by Dragon Darts when co
PARAMETRIZE { targetPlayerRight = TRUE; }
PARAMETRIZE { targetPlayerRight = FALSE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS);
PLAYER(SPECIES_TATSUGIRI) { Ability(ABILITY_COMMANDER); }
PLAYER(SPECIES_DONDOZO);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/compound_eyes.c b/test/battle/ability/compound_eyes.c
index 32fa1dda2e..338da6bf21 100644
--- a/test/battle/ability/compound_eyes.c
+++ b/test/battle/ability/compound_eyes.c
@@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Compound Eyes raises accuracy")
{
PASSES_RANDOMLY(91, 100, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDER].accuracy == 70);
+ ASSUME(GetMoveAccuracy(MOVE_THUNDER) == 70);
PLAYER(SPECIES_BUTTERFREE) { Ability(ABILITY_COMPOUND_EYES); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -20,8 +20,8 @@ SINGLE_BATTLE_TEST("Compound Eyes does not affect OHKO moves")
{
PASSES_RANDOMLY(30, 100, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_FISSURE].accuracy == 30);
- ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO);
+ ASSUME(GetMoveAccuracy(MOVE_FISSURE) == 30);
+ ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO);
PLAYER(SPECIES_BUTTERFREE) { Ability(ABILITY_COMPOUND_EYES); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/contrary.c b/test/battle/ability/contrary.c
index 56eb6abf65..3c9c3e6dff 100644
--- a/test/battle/ability/contrary.c
+++ b/test/battle/ability/contrary.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Contrary raises Attack when Intimidated in a single battle", s16 damage)
@@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Contrary raises stats after using a move which would normall
PARAMETRIZE { ability = ABILITY_TANGLED_FEET; }
GIVEN {
ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE);
- ASSUME(gMovesInfo[MOVE_OVERHEAT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_OVERHEAT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SPINDA) { Ability(ability); }
} WHEN {
@@ -126,7 +126,7 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal
PARAMETRIZE { ability = ABILITY_CONTRARY; }
PARAMETRIZE { ability = ABILITY_TANGLED_FEET; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
PLAYER(SPECIES_WOBBUFFET) { Defense(102); }
OPPONENT(SPECIES_SPINDA) { Ability(ability); Attack(100); }
} WHEN {
@@ -163,7 +163,7 @@ SINGLE_BATTLE_TEST("Contrary raises a stat after using a move which would normal
PARAMETRIZE { ability = ABILITY_CONTRARY; }
PARAMETRIZE { ability = ABILITY_TANGLED_FEET; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
OPPONENT(SPECIES_SPINDA) { Ability(ability); Speed(2); }
} WHEN {
@@ -194,7 +194,7 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal
PARAMETRIZE { ability = ABILITY_CONTRARY; }
PARAMETRIZE { ability = ABILITY_TANGLED_FEET; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
+ ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SPINDA) { Ability(ability); }
} WHEN {
diff --git a/test/battle/ability/corrosion.c b/test/battle/ability/corrosion.c
index 8addbd90fa..8541c21f27 100644
--- a/test/battle/ability/corrosion.c
+++ b/test/battle/ability/corrosion.c
@@ -30,8 +30,8 @@ SINGLE_BATTLE_TEST("Corrosion can poison or badly poison a Steel type with a sta
PARAMETRIZE { move = MOVE_TOXIC; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_BELDUM);
} WHEN {
@@ -72,7 +72,7 @@ SINGLE_BATTLE_TEST("Corrosion can poison Poison- and Steel-type targets if it us
PARAMETRIZE { heldItem = ITEM_TOXIC_ORB; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
+ ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING);
ASSUME(gItemsInfo[ITEM_POISON_BARB].holdEffect == HOLD_EFFECT_POISON_POWER);
ASSUME(gItemsInfo[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Item(heldItem); }
@@ -110,8 +110,8 @@ SINGLE_BATTLE_TEST("If a Poison- or Steel-type Pokémon with Corrosion poisons a
PARAMETRIZE { move = MOVE_TOXIC; }
PARAMETRIZE { move = MOVE_POISON_POWDER; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }
} WHEN {
@@ -137,8 +137,8 @@ SINGLE_BATTLE_TEST("Corrosion cannot bypass moves that prevent poisoning such as
PARAMETRIZE { move = MOVE_TOXIC; }
PARAMETRIZE { move = MOVE_POISON_POWDER; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -159,8 +159,8 @@ SINGLE_BATTLE_TEST("Corrosion cannot bypass abilities that prevent poisoning suc
PARAMETRIZE { move = MOVE_TOXIC; }
PARAMETRIZE { move = MOVE_POISON_POWDER; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); }
} WHEN {
@@ -181,9 +181,9 @@ SINGLE_BATTLE_TEST("Corrosion allows the Pokémon with the ability to poison a S
PARAMETRIZE { move = MOVE_TOXIC; }
PARAMETRIZE { move = MOVE_POISON_POWDER; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
- ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_BELDUM);
} WHEN {
@@ -205,9 +205,9 @@ SINGLE_BATTLE_TEST("Corrosion's effect is lost if the move used by the Pokémon
PARAMETRIZE { move = MOVE_TOXIC; }
PARAMETRIZE { move = MOVE_POISON_POWDER; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
- ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/cotton_down.c b/test/battle/ability/cotton_down.c
index 4d0dab9dcc..02a0f18f63 100644
--- a/test/battle/ability/cotton_down.c
+++ b/test/battle/ability/cotton_down.c
@@ -62,3 +62,37 @@ DOUBLE_BATTLE_TEST("Cotton Down drops speed by one of all other battlers on the
EXPECT_EQ(opponentRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE - 1);
}
}
+
+DOUBLE_BATTLE_TEST("Cotton Down correctly gets blocked by stat reduction preventing abilities")
+{
+ GIVEN {
+ PLAYER(SPECIES_METAGROSS) { Ability(ABILITY_CLEAR_BODY); }
+ PLAYER(SPECIES_WYNAUT) { Item(ITEM_CLEAR_AMULET); }
+ OPPONENT(SPECIES_ELDEGOSS) { Ability(ABILITY_COTTON_DOWN); }
+ OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
+ ABILITY_POPUP(opponentLeft, ABILITY_COTTON_DOWN);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
+ MESSAGE("Metagross's Speed fell!");
+ }
+ ABILITY_POPUP(playerLeft, ABILITY_CLEAR_BODY);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
+ MESSAGE("Wynaut's Speed fell!");
+ }
+ MESSAGE("The effects of the Clear Amulet held by Wynaut prevents its stats from being lowered!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
+ MESSAGE("The opposing Corviknight's Speed fell!");
+ }
+ ABILITY_POPUP(opponentRight, ABILITY_MIRROR_ARMOR);
+ } THEN {
+ EXPECT_EQ(playerLeft->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
+ EXPECT_EQ(playerRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
+ EXPECT_EQ(opponentRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
+ }
+}
diff --git a/test/battle/ability/cud_chew.c b/test/battle/ability/cud_chew.c
index 297635c9f3..9ac5593474 100644
--- a/test/battle/ability/cud_chew.c
+++ b/test/battle/ability/cud_chew.c
@@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Cud Chew will activate Kee Berry effect again on the next tu
{
GIVEN {
ASSUME(gItemsInfo[ITEM_KEE_BERRY].holdEffect == HOLD_EFFECT_KEE_BERRY);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TAUROS_PALDEA_COMBAT) { Ability(ABILITY_CUD_CHEW); Item(ITEM_KEE_BERRY); }
} WHEN {
@@ -28,8 +28,8 @@ SINGLE_BATTLE_TEST("Cud Chew will activate Oran Berry effect again on the next t
GIVEN {
ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP);
ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffectParam == 10);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TAUROS_PALDEA_COMBAT) { MaxHP(60); HP(60); Ability(ABILITY_CUD_CHEW); Item(ITEM_ORAN_BERRY); }
} WHEN {
diff --git a/test/battle/ability/cute_charm.c b/test/battle/ability/cute_charm.c
index e6eee0ae08..55e64b3226 100644
--- a/test/battle/ability/cute_charm.c
+++ b/test/battle/ability/cute_charm.c
@@ -7,15 +7,15 @@ SINGLE_BATTLE_TEST("Cute Charm inflicts infatuation on contact")
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_SWIFT));
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); }
OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); }
} WHEN {
TURN { MOVE(player, move); }
TURN { MOVE(player, move); }
} SCENE {
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(opponent, ABILITY_CUTE_CHARM);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_INFATUATION, player);
MESSAGE("The opposing Clefairy's Cute Charm infatuated Wobbuffet!");
@@ -51,7 +51,7 @@ SINGLE_BATTLE_TEST("Cute Charm triggers 30% of the time")
PASSES_RANDOMLY(3, 10, RNG_CUTE_CHARM);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET) { Gender(MON_MALE); }
OPPONENT(SPECIES_CLEFAIRY) { Gender(MON_FEMALE); Ability(ABILITY_CUTE_CHARM); }
} WHEN {
diff --git a/test/battle/ability/damp.c b/test/battle/ability/damp.c
index b567293aa0..1088a7a17e 100644
--- a/test/battle/ability/damp.c
+++ b/test/battle/ability/damp.c
@@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Damp prevents explosion-like moves from self")
SINGLE_BATTLE_TEST("Damp prevents damage from Aftermath")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_PARAS) { Ability(ABILITY_DAMP); }
OPPONENT(SPECIES_VOLTORB) { Ability(ABILITY_AFTERMATH); HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/dancer.c b/test/battle/ability/dancer.c
index 5519ac3222..657a126470 100644
--- a/test/battle/ability/dancer.c
+++ b/test/battle/ability/dancer.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Dancer can copy a dance move immediately after it was used and allow the user of Dancer to still use its move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUIVER_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_QUIVER_DANCE));
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); }
} WHEN {
@@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Dancer can copy a dance move immediately after it was used a
SINGLE_BATTLE_TEST("Dancer can copy Teeter Dance")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TEETER_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_TEETER_DANCE));
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Item(ITEM_LUM_BERRY); }
} WHEN {
@@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Dancer can copy Teeter Dance")
DOUBLE_BATTLE_TEST("Dancer can copy Teeter Dance and confuse both opposing targets")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TEETER_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_TEETER_DANCE));
ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS);
PLAYER(SPECIES_WOBBUFFET)
PLAYER(SPECIES_WYNAUT) { Item(ITEM_LUM_BERRY); }
@@ -57,7 +57,7 @@ DOUBLE_BATTLE_TEST("Dancer can copy Teeter Dance and confuse both opposing targe
DOUBLE_BATTLE_TEST("Dancer triggers from slowest to fastest")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_DANCER); Speed(10); }
PLAYER(SPECIES_WYNAUT) { Speed(50); }
OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Speed(20); }
@@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Dancer doesn't trigger if the original user flinches")
{
GIVEN {
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); }
} WHEN {
@@ -102,7 +102,7 @@ DOUBLE_BATTLE_TEST("Dancer still triggers if another dancer flinches")
{
GIVEN {
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_DANCER); Speed(10); }
PLAYER(SPECIES_WYNAUT) { Speed(5); }
OPPONENT(SPECIES_ORICORIO) { Ability(ABILITY_DANCER); Speed(20); }
@@ -130,8 +130,8 @@ DOUBLE_BATTLE_TEST("Dancer still triggers if another dancer flinches")
SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE);
- ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE);
+ ASSUME(IsDanceMove(MOVE_REVELATION_DANCE));
+ ASSUME(GetMoveEffect(MOVE_REVELATION_DANCE) == EFFECT_REVELATION_DANCE);
PLAYER(SPECIES_TANGROWTH);
OPPONENT(SPECIES_ORICORIO_BAILE);
} WHEN {
@@ -149,8 +149,8 @@ SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated")
DOUBLE_BATTLE_TEST("Dancer doesn't trigger on a snatched move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
- ASSUME(gMovesInfo[MOVE_SNATCH].effect == EFFECT_SNATCH);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
+ ASSUME(GetMoveEffect(MOVE_SNATCH) == EFFECT_SNATCH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ORICORIO);
@@ -173,9 +173,9 @@ DOUBLE_BATTLE_TEST("Dancer doesn't trigger on a snatched move")
DOUBLE_BATTLE_TEST("Dancer triggers on Instructed dance moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].instructBanned == FALSE);
- ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
+ ASSUME(!IsMoveInstructBanned(MOVE_DRAGON_DANCE));
+ ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ORICORIO);
@@ -200,9 +200,9 @@ DOUBLE_BATTLE_TEST("Dancer triggers on Instructed dance moves")
DOUBLE_BATTLE_TEST("Dancer-called move doesn't update move to be Instructed")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
- ASSUME(gMovesInfo[MOVE_TACKLE].instructBanned == FALSE);
- ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
+ ASSUME(!IsMoveInstructBanned(MOVE_TACKLE));
+ ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ORICORIO);
@@ -228,8 +228,8 @@ DOUBLE_BATTLE_TEST("Dancer-called move doesn't update move to be Instructed")
DOUBLE_BATTLE_TEST("Dancer doesn't call a move that didn't execute due to Powder")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FIERY_DANCE].danceMove == TRUE);
- ASSUME(gMovesInfo[MOVE_FIERY_DANCE].type == TYPE_FIRE);
+ ASSUME(IsDanceMove(MOVE_FIERY_DANCE));
+ ASSUME(GetMoveType(MOVE_FIERY_DANCE) == TYPE_FIRE);
PLAYER(SPECIES_VOLCARONA);
PLAYER(SPECIES_ORICORIO);
OPPONENT(SPECIES_WYNAUT);
diff --git a/test/battle/ability/dauntless_shield.c b/test/battle/ability/dauntless_shield.c
index ca9125e14f..ada4ace786 100644
--- a/test/battle/ability/dauntless_shield.c
+++ b/test/battle/ability/dauntless_shield.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(B_PROTEAN_LIBERO == GEN_9);
+ ASSUME(B_DAUNTLESS_SHIELD == GEN_9);
}
SINGLE_BATTLE_TEST("Dauntless Shield raises Defense by one stage")
diff --git a/test/battle/ability/dazzling.c b/test/battle/ability/dazzling.c
index 9eedb56a49..cc77e9a3bd 100644
--- a/test/battle/ability/dazzling.c
+++ b/test/battle/ability/dazzling.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority > 0);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) > 0);
}
DOUBLE_BATTLE_TEST("Dazzling, Queenly Majesty and Armor Tail protect the user from priority moves")
diff --git a/test/battle/ability/defeatist.c b/test/battle/ability/defeatist.c
index d2866d6f30..18d8186a50 100644
--- a/test/battle/ability/defeatist.c
+++ b/test/battle/ability/defeatist.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_ECHOED_VOICE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_ECHOED_VOICE) == DAMAGE_CATEGORY_SPECIAL);
}
SINGLE_BATTLE_TEST("Defeatist halves Attack when HP <= 50%", s16 damage)
diff --git a/test/battle/ability/defiant.c b/test/battle/ability/defiant.c
index 9b767b8323..b1bd102453 100644
--- a/test/battle/ability/defiant.c
+++ b/test/battle/ability/defiant.c
@@ -277,7 +277,7 @@ SINGLE_BATTLE_TEST("Defiant activates before White Herb")
SINGLE_BATTLE_TEST("Defiant activates for each stat that is lowered")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TICKLE].effect == EFFECT_TICKLE);
+ ASSUME(GetMoveEffect(MOVE_TICKLE) == EFFECT_TICKLE);
PLAYER(SPECIES_MANKEY) { Ability(ABILITY_DEFIANT); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/desolate_land.c b/test/battle/ability/desolate_land.c
index 06d604e8fc..5bf1358503 100644
--- a/test/battle/ability/desolate_land.c
+++ b/test/battle/ability/desolate_land.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WATER_GUN].power != 0);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(!IsBattleMoveStatus(MOVE_WATER_GUN));
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
}
SINGLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves")
@@ -32,9 +32,9 @@ SINGLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves")
DOUBLE_BATTLE_TEST("Desolate Land blocks damaging Water-type moves and prints the message only once with moves hitting multiple targets")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURF].power != 0);
- ASSUME(gMovesInfo[MOVE_SURF].type == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(!IsBattleMoveStatus(MOVE_SURF));
+ ASSUME(GetMoveType(MOVE_SURF) == TYPE_WATER);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_GROUDON) {Item(ITEM_RED_ORB); {Speed(5);}}
PLAYER(SPECIES_WOBBUFFET) {Speed(5);}
OPPONENT(SPECIES_WOBBUFFET) {Speed(10);}
diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c
index 3a8df70be5..b1d854f0cf 100644
--- a/test/battle/ability/disguise.c
+++ b/test/battle/ability/disguise.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_AERIAL_ACE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_AERIAL_ACE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing to its busted form")
@@ -28,7 +28,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing
SINGLE_BATTLE_TEST("Disguised Mimikyu takes no damage from a confusion hit and changes to its busted form")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -69,7 +69,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu's Air Balloon will pop upon changing to it
SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from secondary damage without breaking the disguise")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK);
+ ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -138,7 +138,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu is ignored by Mold Breaker")
SINGLE_BATTLE_TEST("Disguised Mimikyu's types revert back to Ghost/Fairy when Disguise is broken")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHADOW_CLAW].type == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_SHADOW_CLAW) == TYPE_GHOST);
PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -158,7 +158,7 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu's types revert back to Ghost/Fairy when Di
SINGLE_BATTLE_TEST("Disguised Mimikyu blocks a move after getting Gastro Acid Batton Passed")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -173,3 +173,19 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu blocks a move after getting Gastro Acid Ba
ABILITY_POPUP(player, ABILITY_DISGUISE);
}
}
+
+SINGLE_BATTLE_TEST("Disguise does not break from a teammate's Wish")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_WISH) == EFFECT_WISH);
+ PLAYER(SPECIES_JIRACHI);
+ PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); HP(219); MaxHP(220); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_WISH); }
+ TURN { SWITCH(player, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_WISH, player);
+ NOT ABILITY_POPUP(player, ABILITY_DISGUISE);
+ }
+}
diff --git a/test/battle/ability/download.c b/test/battle/ability/download.c
index 480f0bf10e..eec380e421 100644
--- a/test/battle/ability/download.c
+++ b/test/battle/ability/download.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_TRI_ATTACK].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TRI_ATTACK) == DAMAGE_CATEGORY_SPECIAL);
}
SINGLE_BATTLE_TEST("Download raises Attack if player has lower Def than Sp. Def", s16 damage)
@@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Download doesn't activate if target hasn't been sent out yet
PARAMETRIZE { ability = ABILITY_TRACE; }
PARAMETRIZE { ability = ABILITY_DOWNLOAD; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) { Speed(100); }
PLAYER(SPECIES_PORYGON) { Ability(ability); Defense(400); SpDefense(300); Speed(300); Attack(100); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
diff --git a/test/battle/ability/dragons_maw.c b/test/battle/ability/dragons_maw.c
index 401c4244c8..d7e1ebd793 100644
--- a/test/battle/ability/dragons_maw.c
+++ b/test/battle/ability/dragons_maw.c
@@ -14,11 +14,11 @@ SINGLE_BATTLE_TEST("Dragon's Maw increases Dragon-type move damage", s16 damage)
PARAMETRIZE { move = MOVE_DRAGON_BREATH; ability = ABILITY_DRAGONS_MAW; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_DRAGON);
- ASSUME(gMovesInfo[MOVE_DRAGON_CLAW].type == TYPE_DRAGON);
- ASSUME(gMovesInfo[MOVE_DRAGON_BREATH].type == TYPE_DRAGON);
- ASSUME(gMovesInfo[MOVE_DRAGON_CLAW].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_DRAGON_BREATH].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_DRAGON);
+ ASSUME(GetMoveType(MOVE_DRAGON_CLAW) == TYPE_DRAGON);
+ ASSUME(GetMoveType(MOVE_DRAGON_BREATH) == TYPE_DRAGON);
+ ASSUME(GetMoveCategory(MOVE_DRAGON_CLAW) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_DRAGON_BREATH) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_REGIDRAGO) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/dry_skin.c b/test/battle/ability/dry_skin.c
index 5709a58a94..95a0cd8fa8 100644
--- a/test/battle/ability/dry_skin.c
+++ b/test/battle/ability/dry_skin.c
@@ -39,8 +39,8 @@ SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%"
PARAMETRIZE { ability = ABILITY_EFFECT_SPORE; }
PARAMETRIZE { ability = ABILITY_DRY_SKIN; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_EMBER].power == 40);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMovePower(MOVE_EMBER) == 40);
ASSUME(gSpeciesInfo[SPECIES_PARASECT].types[0] == TYPE_BUG);
ASSUME(gSpeciesInfo[SPECIES_PARASECT].types[1] == TYPE_GRASS);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC);
@@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%"
SINGLE_BATTLE_TEST("Dry Skin heals 25% when hit by water type moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -79,7 +79,7 @@ SINGLE_BATTLE_TEST("Dry Skin heals 25% when hit by water type moves")
SINGLE_BATTLE_TEST("Dry Skin does not activate if protected")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -92,8 +92,8 @@ SINGLE_BATTLE_TEST("Dry Skin does not activate if protected")
SINGLE_BATTLE_TEST("Dry Skin is only triggered once on multi strike moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].type == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveType(MOVE_WATER_SHURIKEN) == TYPE_WATER);
+ ASSUME(GetMoveEffect(MOVE_WATER_SHURIKEN) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Dry Skin prevents Absorb Bulb and Luminous Moss from activat
PARAMETRIZE { item = ITEM_ABSORB_BULB; }
PARAMETRIZE { item = ITEM_LUMINOUS_MOSS; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(200); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/earth_eater.c b/test/battle/ability/earth_eater.c
index 2e6ae6dab5..c30b9674f5 100644
--- a/test/battle/ability/earth_eater.c
+++ b/test/battle/ability/earth_eater.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Earth Eater heals 25% when hit by ground type moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MUD_SLAP].type == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_MUD_SLAP) == TYPE_GROUND);
PLAYER(SPECIES_ORTHWORM) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Earth Eater heals 25% when hit by ground type moves")
SINGLE_BATTLE_TEST("Earth Eater does not activate if protected")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MUD_SLAP].type == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_MUD_SLAP) == TYPE_GROUND);
PLAYER(SPECIES_ORTHWORM) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -35,8 +35,8 @@ SINGLE_BATTLE_TEST("Earth Eater does not activate if protected")
SINGLE_BATTLE_TEST("Earth Eater activates on status moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].type == TYPE_GROUND);
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveType(MOVE_SAND_ATTACK) == TYPE_GROUND);
+ ASSUME(GetMoveCategory(MOVE_SAND_ATTACK) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_ORTHWORM) { Ability(ABILITY_EARTH_EATER); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/effect_spore.c b/test/battle/ability/effect_spore.c
index 49750c4797..06ac84f39a 100644
--- a/test/battle/ability/effect_spore.c
+++ b/test/battle/ability/effect_spore.c
@@ -8,15 +8,15 @@ SINGLE_BATTLE_TEST("Effect Spore only inflicts status on contact")
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_SWIFT));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
} WHEN {
TURN { MOVE(player, move, WITH_RNG(RNG_EFFECT_SPORE, 1)); }
TURN {}
} SCENE {
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
MESSAGE("Wobbuffet was poisoned by the opposing Breloom's Effect Spore!");
@@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes poison 9% of the time")
PASSES_RANDOMLY(9, 100, RNG_EFFECT_SPORE);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
} WHEN {
@@ -56,7 +56,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes paralysis 10% of the time")
PASSES_RANDOMLY(10, 100, RNG_EFFECT_SPORE);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
} WHEN {
@@ -75,7 +75,7 @@ SINGLE_BATTLE_TEST("Effect Spore causes sleep 11% of the time")
PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
} WHEN {
diff --git a/test/battle/ability/electric_surge.c b/test/battle/ability/electric_surge.c
new file mode 100644
index 0000000000..3509f1c687
--- /dev/null
+++ b/test/battle/ability/electric_surge.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Electric Surge creates Electric Terrain when entering the battle");
diff --git a/test/battle/ability/electromorphosis.c b/test/battle/ability/electromorphosis.c
index 094b2843bf..38a61f4c29 100644
--- a/test/battle/ability/electromorphosis.c
+++ b/test/battle/ability/electromorphosis.c
@@ -10,12 +10,12 @@ SINGLE_BATTLE_TEST("Electromorphosis sets up Charge when hit by any move")
PARAMETRIZE {move = MOVE_GUST; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
- ASSUME(gMovesInfo[MOVE_GUST].power != 0);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].power != 0);
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
+ ASSUME(!IsBattleMoveStatus(MOVE_GUST));
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(!IsBattleMoveStatus(MOVE_THUNDER_SHOCK));
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
PLAYER(SPECIES_BELLIBOLT) { Ability(ABILITY_ELECTROMORPHOSIS); Speed(10); }
OPPONENT(SPECIES_WOBBUFFET) {Ability(ABILITY_LIMBER); Speed(5) ;} // Limber, so it doesn't get paralyzed.
diff --git a/test/battle/ability/flame_body.c b/test/battle/ability/flame_body.c
index b8fa850b65..95afa862c1 100644
--- a/test/battle/ability/flame_body.c
+++ b/test/battle/ability/flame_body.c
@@ -7,14 +7,14 @@ SINGLE_BATTLE_TEST("Flame Body inflicts burn on contact")
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_SWIFT));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_MAGMAR) { Ability(ABILITY_FLAME_BODY); }
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(opponent, ABILITY_FLAME_BODY);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, player);
MESSAGE("The opposing Magmar's Flame Body burned Wobbuffet!");
@@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Flame Body triggers 30% of the time")
PASSES_RANDOMLY(3, 10, RNG_FLAME_BODY);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_MAGMAR) { Ability(ABILITY_FLAME_BODY); }
} WHEN {
diff --git a/test/battle/ability/flower_gift.c b/test/battle/ability/flower_gift.c
index 68712641e0..4f09e84a9a 100644
--- a/test/battle/ability/flower_gift.c
+++ b/test/battle/ability/flower_gift.c
@@ -63,7 +63,32 @@ SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when its abili
}
}
-TO_DO_BATTLE_TEST("Forecast transforms Castform back to normal under Cloud Nine/Air Lock");
+SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal under Cloud Nine/Air Lock")
+{
+ u32 species = 0, ability = 0;
+ PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; }
+ PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; }
+ GIVEN {
+ PLAYER(SPECIES_CHERRIM_OVERCAST) { Ability(ABILITY_FLOWER_GIFT); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(species) { Ability(ability); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SUNNY_DAY); }
+ TURN { SWITCH(opponent, 1); }
+ } SCENE {
+ // transforms
+ ABILITY_POPUP(player, ABILITY_FLOWER_GIFT);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ MESSAGE("Cherrim transformed!");
+ // back to normal
+ ABILITY_POPUP(opponent, ability);
+ ABILITY_POPUP(player, ABILITY_FLOWER_GIFT);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ MESSAGE("Cherrim transformed!");
+ } THEN {
+ EXPECT_EQ(player->species, SPECIES_CHERRIM_OVERCAST);
+ }
+}
DOUBLE_BATTLE_TEST("Flower Gift increases the attack of Cherrim and its allies by 1.5x", s16 damageL, s16 damageR)
{
@@ -71,7 +96,7 @@ DOUBLE_BATTLE_TEST("Flower Gift increases the attack of Cherrim and its allies b
PARAMETRIZE { sunny = FALSE; }
PARAMETRIZE { sunny = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_CHERRIM_OVERCAST) { Ability(ABILITY_FLOWER_GIFT); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -106,7 +131,7 @@ DOUBLE_BATTLE_TEST("Flower Gift increases the Sp. Def of Cherrim and its allies
PARAMETRIZE { sunny = FALSE; }
PARAMETRIZE { sunny = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_HYPER_VOICE) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_CHERRIM_OVERCAST) { Ability(ABILITY_FLOWER_GIFT); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/fluffy.c b/test/battle/ability/fluffy.c
index 30a8b83182..5c51ec2627 100644
--- a/test/battle/ability/fluffy.c
+++ b/test/battle/ability/fluffy.c
@@ -3,11 +3,11 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(gMovesInfo[MOVE_FIRE_PUNCH].makesContact);
- ASSUME(gMovesInfo[MOVE_FIRE_PUNCH].type == TYPE_FIRE);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(MoveMakesContact(MOVE_FIRE_PUNCH));
+ ASSUME(GetMoveType(MOVE_FIRE_PUNCH) == TYPE_FIRE);
}
SINGLE_BATTLE_TEST("Fluffy halves damage taken from moves that make direct contact", s16 damage)
diff --git a/test/battle/ability/frisk.c b/test/battle/ability/frisk.c
index 3c892329c3..e6d7f275fb 100644
--- a/test/battle/ability/frisk.c
+++ b/test/battle/ability/frisk.c
@@ -42,7 +42,7 @@ DOUBLE_BATTLE_TEST("Frisk triggers for player in a Double Battle after switching
PARAMETRIZE { target = playerRight; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_POUND].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_POUND));
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_FURRET) { Ability(ABILITY_FRISK); };
@@ -65,7 +65,7 @@ DOUBLE_BATTLE_TEST("Frisk triggers for opponent in a Double Battle after switchi
PARAMETRIZE { target = opponentRight; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_POUND].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_POUND));
PLAYER(SPECIES_WYNAUT) { Item(ITEM_POTION); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
diff --git a/test/battle/ability/gale_wings.c b/test/battle/ability/gale_wings.c
index eff4589649..df8f025326 100644
--- a/test/battle/ability/gale_wings.c
+++ b/test/battle/ability/gale_wings.c
@@ -1,20 +1,22 @@
#include "global.h"
#include "test/battle.h"
-SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP")
+SINGLE_BATTLE_TEST("Gale Wings only grants priority at full HP (Gen 7+)")
{
- u16 hp;
- PARAMETRIZE { hp = 100; }
- PARAMETRIZE { hp = 99; }
+ u32 hp, config;
+ PARAMETRIZE { hp = 100; config = GEN_7; }
+ PARAMETRIZE { hp = 99; config = GEN_7; }
+ PARAMETRIZE { hp = 100; config = GEN_6; }
+ PARAMETRIZE { hp = 99; config = GEN_6; }
GIVEN {
- ASSUME(B_GALE_WINGS >= GEN_7);
- ASSUME(gMovesInfo[MOVE_AERIAL_ACE].type == TYPE_FLYING);
+ WITH_CONFIG(GEN_CONFIG_GALE_WINGS, config);
+ ASSUME(GetMoveType(MOVE_AERIAL_ACE) == TYPE_FLYING);
PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(hp); MaxHP(100); Speed(1);}
OPPONENT(SPECIES_WOBBUFFET) { Speed(100);};
} WHEN {
TURN { MOVE(player, MOVE_AERIAL_ACE); }
} SCENE {
- if (hp == 100) {
+ if (hp == 100 || config <= GEN_6) {
MESSAGE("Talonflame used Aerial Ace!");
MESSAGE("The opposing Wobbuffet used Celebrate!");
}
@@ -31,9 +33,8 @@ SINGLE_BATTLE_TEST("Gale Wings only grants priority to Flying-type moves")
PARAMETRIZE { move = MOVE_AERIAL_ACE; }
PARAMETRIZE { move = MOVE_FLARE_BLITZ; }
GIVEN {
- ASSUME(B_GALE_WINGS >= GEN_7);
- ASSUME(gMovesInfo[MOVE_AERIAL_ACE].type == TYPE_FLYING);
- ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_AERIAL_ACE) == TYPE_FLYING);
+ ASSUME(GetMoveType(MOVE_FLARE_BLITZ) == TYPE_FIRE);
PLAYER(SPECIES_TALONFLAME) { Ability(ABILITY_GALE_WINGS); HP(100); MaxHP(100); Speed(1);}
OPPONENT(SPECIES_WOBBUFFET) { Speed(100);};
} WHEN {
@@ -58,12 +59,11 @@ SINGLE_BATTLE_TEST("Gale Wings doesn't increase priority of Flying-type Natural
PARAMETRIZE { move = MOVE_JUDGMENT; heldItem = ITEM_SKY_PLATE; }
PARAMETRIZE { move = MOVE_HIDDEN_POWER; heldItem = ITEM_NONE; }
GIVEN {
- ASSUME(B_GALE_WINGS >= GEN_7);
- ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
- ASSUME(gMovesInfo[MOVE_JUDGMENT].effect == EFFECT_CHANGE_TYPE_ON_ITEM);
+ ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT);
+ ASSUME(GetMoveEffect(MOVE_JUDGMENT) == EFFECT_CHANGE_TYPE_ON_ITEM);
// IV combinations sourced from https://www.smogon.com/forums/threads/hidden-power-iv-combinations.78083/
- ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].effect == EFFECT_HIDDEN_POWER);
- ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST);
+ ASSUME(GetMoveEffect(MOVE_HIDDEN_POWER) == EFFECT_HIDDEN_POWER);
+ ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST);
ASSUME(gItemsInfo[ITEM_SKY_PLATE].holdEffect == HOLD_EFFECT_PLATE);
ASSUME(gItemsInfo[ITEM_SKY_PLATE].secondaryId == TYPE_FLYING);
ASSUME(gNaturalGiftTable[ITEM_TO_BERRY(ITEM_LUM_BERRY)].type == TYPE_FLYING);
diff --git a/test/battle/ability/galvanize.c b/test/battle/ability/galvanize.c
index 1da82e861d..6de5675b6a 100644
--- a/test/battle/ability/galvanize.c
+++ b/test/battle/ability/galvanize.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
}
SINGLE_BATTLE_TEST("Galvanize turns a normal type move into Electric")
@@ -29,9 +29,9 @@ SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type move
PARAMETRIZE { move = MOVE_MULTI_ATTACK; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].effect == EFFECT_HIDDEN_POWER);
- ASSUME(gMovesInfo[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL);
- ASSUME(gMovesInfo[MOVE_MULTI_ATTACK].effect == EFFECT_CHANGE_TYPE_ON_ITEM);
+ ASSUME(GetMoveEffect(MOVE_HIDDEN_POWER) == EFFECT_HIDDEN_POWER);
+ ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL);
+ ASSUME(GetMoveEffect(MOVE_MULTI_ATTACK) == EFFECT_CHANGE_TYPE_ON_ITEM);
PLAYER(SPECIES_KRABBY);
OPPONENT(SPECIES_GEODUDE_ALOLA) { Ability(ABILITY_GALVANIZE); }
} WHEN {
diff --git a/test/battle/ability/good_as_gold.c b/test/battle/ability/good_as_gold.c
index 40561ee767..fc6c6bc8c4 100644
--- a/test/battle/ability/good_as_gold.c
+++ b/test/battle/ability/good_as_gold.c
@@ -5,7 +5,7 @@
SINGLE_BATTLE_TEST("Good as Gold protects from status moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveCategory(MOVE_TOXIC) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
} WHEN {
@@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Good as Gold protects from status moves")
SINGLE_BATTLE_TEST("Good as Gold doesn't protect the user from it's own moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_NASTY_PLOT].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveCategory(MOVE_NASTY_PLOT) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
} WHEN {
@@ -37,8 +37,8 @@ SINGLE_BATTLE_TEST("Good as Gold doesn't protect the user from it's own moves")
SINGLE_BATTLE_TEST("Good as Gold doesn't protect from moves that target the field")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].target == MOVE_TARGET_OPPONENTS_FIELD);
+ ASSUME(GetMoveCategory(MOVE_STEALTH_ROCK) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveTarget(MOVE_STEALTH_ROCK) == MOVE_TARGET_OPPONENTS_FIELD);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
} WHEN {
@@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Good as Gold doesn't protect from moves that target the fiel
DOUBLE_BATTLE_TEST("Good as Gold protects from partner's status moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_HELPING_HAND].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveCategory(MOVE_HELPING_HAND) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GHOLDENGO) { Ability(ABILITY_GOOD_AS_GOLD); }
diff --git a/test/battle/ability/grassy_surge.c b/test/battle/ability/grassy_surge.c
new file mode 100644
index 0000000000..ccdb471d9f
--- /dev/null
+++ b/test/battle/ability/grassy_surge.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Grassy Surge creates Grassy Terrain when entering the battle");
diff --git a/test/battle/ability/grim_neigh.c b/test/battle/ability/grim_neigh.c
index 476d9995f1..c58487722b 100644
--- a/test/battle/ability/grim_neigh.c
+++ b/test/battle/ability/grim_neigh.c
@@ -7,7 +7,7 @@ DOUBLE_BATTLE_TEST("Grim Neigh raises Sp. Attack by one stage after directly cau
PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_SNORUNT) { HP(1); }
OPPONENT(SPECIES_GLALIE) { HP(1); }
@@ -80,9 +80,8 @@ DOUBLE_BATTLE_TEST("Grim Neigh does not increase damage done by the same move th
PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_SHADOW; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; }
- KNOWN_FAILING; // Requires simultaneous damage implementation
GIVEN {
- ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_ABRA) { HP(1); }
OPPONENT(SPECIES_GLALIE);
@@ -94,6 +93,7 @@ DOUBLE_BATTLE_TEST("Grim Neigh does not increase damage done by the same move th
ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft);
HP_BAR(opponentLeft, captureDamage: &damage[0]);
HP_BAR(playerRight);
+ HP_BAR(opponentRight, captureDamage: &damage[1]);
MESSAGE("Abra fainted!");
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
@@ -101,7 +101,6 @@ DOUBLE_BATTLE_TEST("Grim Neigh does not increase damage done by the same move th
MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!");
else
MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!");
- HP_BAR(opponentRight, captureDamage: &damage[1]);
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1);
EXPECT_EQ(damage[0], damage[1]);
diff --git a/test/battle/ability/gulp_missile.c b/test/battle/ability/gulp_missile.c
index f5e1fd9d9d..72e826b252 100644
--- a/test/battle/ability/gulp_missile.c
+++ b/test/battle/ability/gulp_missile.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- // ASSUME(gMovesInfo[MOVE_AERIAL_ACE].category == DAMAGE_CATEGORY_PHYSICAL);
+ // ASSUME(GetMoveCategory(MOVE_AERIAL_ACE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("(Gulp Missile) If base Cramorant hits target with Surf it transforms into Gulping form if max HP is over 1/2")
@@ -92,6 +92,7 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant deal 1/4 of damage oppo
MESSAGE("The opposing Wobbuffet's Defense fell!");
} THEN {
EXPECT_EQ(gulpMissileDamage, opponent->maxHP / 4);
+ EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE - 1);
}
}
@@ -133,3 +134,59 @@ SINGLE_BATTLE_TEST("(Gulp Missile) triggers even if the user is fainted by oppos
STATUS_ICON(opponent, paralysis: TRUE);
}
}
+
+SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant Gulping lowers defense but is prevented by stat reduction preventing abilities")
+{
+ u32 species, ability;
+ PARAMETRIZE { species = SPECIES_METAGROSS; ability = ABILITY_CLEAR_BODY; }
+ PARAMETRIZE { species = SPECIES_CORVIKNIGHT; ability = ABILITY_MIRROR_ARMOR; }
+ PARAMETRIZE { species = SPECIES_CHATOT; ability = ABILITY_BIG_PECKS; }
+ GIVEN {
+ PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); }
+ OPPONENT(species) { Ability(ability); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SURF); MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player);
+ HP_BAR(opponent);
+ ABILITY_POPUP(player, ABILITY_GULP_MISSILE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ HP_BAR(player);
+ ABILITY_POPUP(player, ABILITY_GULP_MISSILE);
+ ABILITY_POPUP(opponent, ability);
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ } THEN {
+ EXPECT_EQ(opponent->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
+ }
+}
+
+SINGLE_BATTLE_TEST("(Gulp Missile) Transformed Cramorant Gulping lowers defense and still triggers other effects after")
+{
+ // Make sure attacker and target are correct after triggering the ability
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_INFILTRATOR; }
+ PARAMETRIZE { ability = ABILITY_CLEAR_BODY; }
+ GIVEN {
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ PLAYER(SPECIES_CRAMORANT) { Ability(ABILITY_GULP_MISSILE); Item(ITEM_ROCKY_HELMET); }
+ OPPONENT(SPECIES_DRAGAPULT) { Ability(ability); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SURF); MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SURF, player);
+ HP_BAR(opponent);
+ ABILITY_POPUP(player, ABILITY_GULP_MISSILE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ HP_BAR(player);
+ ABILITY_POPUP(player, ABILITY_GULP_MISSILE);
+ HP_BAR(opponent);
+ if (ability == ABILITY_INFILTRATOR) {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ MESSAGE("The opposing Dragapult's Defense fell!");
+ } else {
+ ABILITY_POPUP(opponent, ABILITY_CLEAR_BODY);
+ }
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ HP_BAR(opponent);
+ }
+}
diff --git a/test/battle/ability/harvest.c b/test/battle/ability/harvest.c
index 03e13b394e..92e7517df5 100644
--- a/test/battle/ability/harvest.c
+++ b/test/battle/ability/harvest.c
@@ -5,7 +5,7 @@ ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_SITRUS_BERRY].holdEffect == HOLD_EFFECT_RESTORE_PCT_HP);
ASSUME(I_SITRUS_BERRY_HEAL >= GEN_4);
- ASSUME(gMovesInfo[MOVE_SUNNY_DAY].effect == EFFECT_SUNNY_DAY);
+ ASSUME(GetMoveEffect(MOVE_SUNNY_DAY) == EFFECT_SUNNY_DAY);
}
SINGLE_BATTLE_TEST("Harvest has a 50% chance to restore a Berry at the end of the turn")
@@ -61,7 +61,7 @@ SINGLE_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Loc
SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
+ ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -80,7 +80,7 @@ SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and b
SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
+ ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@@ -97,7 +97,7 @@ SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling")
SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
+ ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@@ -209,7 +209,7 @@ DOUBLE_BATTLE_TEST("Harvest order is affected by speed")
SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another Pokémon")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
+ ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@@ -226,7 +226,7 @@ SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another P
SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from another Pokémon")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
+ ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK);
PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); }
} WHEN {
@@ -245,7 +245,7 @@ SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from anothe
SINGLE_BATTLE_TEST("Harvest can only restore the newest berry consumed that was transferred from another Pokémon instead of its original Berry")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
+ ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK);
ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP);
PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); Item(ITEM_APICOT_BERRY); }
diff --git a/test/battle/ability/hospitality.c b/test/battle/ability/hospitality.c
index 0582549180..c772d6e776 100644
--- a/test/battle/ability/hospitality.c
+++ b/test/battle/ability/hospitality.c
@@ -82,9 +82,9 @@ DOUBLE_BATTLE_TEST("Hospitality does not trigger if there is no ally on the fiel
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BLIZZARD, opponentLeft);
HP_BAR(playerLeft);
- MESSAGE("Wobbuffet fainted!");
HP_BAR(playerRight);
MESSAGE("Wobbuffet fainted!");
+ MESSAGE("Wobbuffet fainted!");
SEND_IN_MESSAGE("Poltchageist");
NOT ABILITY_POPUP(playerLeft, ABILITY_HOSPITALITY);
}
diff --git a/test/battle/ability/hyper_cutter.c b/test/battle/ability/hyper_cutter.c
index a688da2531..7bd5504965 100644
--- a/test/battle/ability/hyper_cutter.c
+++ b/test/battle/ability/hyper_cutter.c
@@ -29,7 +29,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter prevents intimidate")
SINGLE_BATTLE_TEST("Hyper Cutter prevents Attack stage reduction from moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
} WHEN {
@@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter prevents Attack stage reduction from moves")
SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack reduction from burn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
+ ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
} WHEN {
@@ -59,7 +59,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack reduction from burn")
SINGLE_BATTLE_TEST("Hyper Cutter is ignored by Mold Breaker")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
} WHEN {
@@ -97,8 +97,8 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Attack stage reduction from mov
SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Topsy-Turvy")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
- ASSUME(gMovesInfo[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
} WHEN {
@@ -116,7 +116,7 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Topsy-Turvy")
SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Spectral Thief from resetting positive Attack stage changes")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
@@ -135,8 +135,8 @@ SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent Spectral Thief from resetting p
SINGLE_BATTLE_TEST("Hyper Cutter doesn't prevent receiving negative Attack stage changes from Baton Pass")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KRABBY) { Ability(ABILITY_HYPER_CUTTER); }
diff --git a/test/battle/ability/ice_body.c b/test/battle/ability/ice_body.c
index 3f278a50cd..07890d52f2 100644
--- a/test/battle/ability/ice_body.c
+++ b/test/battle/ability/ice_body.c
@@ -2,8 +2,8 @@
#include "test/battle.h"
ASSUMPTIONS {
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
}
SINGLE_BATTLE_TEST("Ice Body prevents damage from hail")
diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c
index 54a307754c..a462b80265 100644
--- a/test/battle/ability/ice_face.c
+++ b/test/battle/ability/ice_face.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_EISCUE);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -18,8 +18,8 @@ SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noi
SINGLE_BATTLE_TEST("Ice Face does not block special moves, Eiscue stays in Ice Face form")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_EMBER].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_EMBER) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_EISCUE);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -35,9 +35,9 @@ SINGLE_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
PARAMETRIZE { move = MOVE_HAIL; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
PLAYER(SPECIES_EISCUE);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -60,9 +60,9 @@ SINGLE_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while h
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
PARAMETRIZE { move = MOVE_HAIL; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
PLAYER(SPECIES_EISCUE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -86,9 +86,9 @@ SINGLE_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face f
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
PARAMETRIZE { move = MOVE_HAIL; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
PLAYER(SPECIES_EISCUE) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -105,7 +105,7 @@ SINGLE_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face f
SINGLE_BATTLE_TEST("Ice Face form change persists after switching out")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_EISCUE) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -123,7 +123,7 @@ SINGLE_BATTLE_TEST("Ice Face form change persists after switching out")
SINGLE_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_EISCUE) { HP(1); }
OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_AIR_LOCK); }
} WHEN {
@@ -135,3 +135,33 @@ SINGLE_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is
MESSAGE("Eiscue fainted!");
}
}
+
+SINGLE_BATTLE_TEST("Ice Face is not restored if hail or snow and Eiscue are already out")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_SNOWSCAPE; }
+ PARAMETRIZE { move = MOVE_HAIL; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
+ PLAYER(SPECIES_EISCUE);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, move); }
+ TURN { MOVE(opponent, MOVE_TACKLE); }
+ TURN { SWITCH(opponent, 1); }
+ } SCENE {
+ ABILITY_POPUP(player, ABILITY_ICE_FACE);
+ MESSAGE("Eiscue transformed!");
+ ABILITY_POPUP(player, ABILITY_ICE_FACE);
+ MESSAGE("Eiscue transformed!");
+ ABILITY_POPUP(player, ABILITY_ICE_FACE);
+ MESSAGE("Eiscue transformed!");
+ NONE_OF {
+ ABILITY_POPUP(player, ABILITY_ICE_FACE);
+ MESSAGE("Eiscue transformed!");
+ }
+ }
+}
diff --git a/test/battle/ability/ice_scales.c b/test/battle/ability/ice_scales.c
index fd262147a5..37c5aa0944 100644
--- a/test/battle/ability/ice_scales.c
+++ b/test/battle/ability/ice_scales.c
@@ -12,10 +12,10 @@ SINGLE_BATTLE_TEST("Ice Scales halves the damage from special moves", s16 damage
PARAMETRIZE { ability = ABILITY_SHIELD_DUST; move = MOVE_TACKLE; }
PARAMETRIZE { ability = ABILITY_ICE_SCALES; move = MOVE_TACKLE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_PSYCHIC].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_PSYSHOCK].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_PSYSHOCK].effect == EFFECT_PSYSHOCK);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_PSYSHOCK) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveEffect(MOVE_PSYSHOCK) == EFFECT_PSYSHOCK);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_FROSMOTH) { Ability(ability); }
} WHEN {
diff --git a/test/battle/ability/immunity.c b/test/battle/ability/immunity.c
index 2fa90686c5..92e32d31f3 100644
--- a/test/battle/ability/immunity.c
+++ b/test/battle/ability/immunity.c
@@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Immunity prevents Poison Sting poison")
SINGLE_BATTLE_TEST("Immunity prevents Toxic bad poison")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); }
} WHEN {
@@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Immunity prevents Toxic bad poison")
SINGLE_BATTLE_TEST("Immunity prevents Toxic Spikes poison")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); }
diff --git a/test/battle/ability/innards_out.c b/test/battle/ability/innards_out.c
index bc59bcfa0b..5613ff72f6 100644
--- a/test/battle/ability/innards_out.c
+++ b/test/battle/ability/innards_out.c
@@ -14,8 +14,8 @@ SINGLE_BATTLE_TEST("Innards Out deal dmg on fainting equal to the amount of dmg
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { HP(70); SpAttack(1000); }
OPPONENT(SPECIES_WOBBUFFET);
- ASSUME(gMovesInfo[MOVE_PSYCHIC].power != 0);
- ASSUME(gMovesInfo[MOVE_PSYCHIC].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(!IsBattleMoveStatus(MOVE_PSYCHIC));
+ ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL);
} WHEN {
TURN { MOVE(opponent, MOVE_PSYCHIC); SEND_OUT(player, 1); if (hp == 100) { SEND_OUT(opponent, 1); } }
} SCENE {
@@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Innards Out does not trigger after Gastro Acid has been used
PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
- ASSUME(gMovesInfo[MOVE_PSYCHIC].power != 0);
- ASSUME(gMovesInfo[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID);
+ ASSUME(!IsBattleMoveStatus(MOVE_PSYCHIC));
+ ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID);
} WHEN {
TURN { MOVE(opponent, MOVE_GASTRO_ACID); }
TURN { MOVE(opponent, MOVE_PSYCHIC); SEND_OUT(player, 1); }
@@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Innards Out does not damage Magic Guard Pokemon")
PLAYER(SPECIES_PYUKUMUKU) { HP(1); Ability(ABILITY_INNARDS_OUT); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); }
- ASSUME(gMovesInfo[MOVE_PSYCHIC].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_PSYCHIC));
} WHEN {
TURN { MOVE(opponent, MOVE_PSYCHIC); SEND_OUT(player, 1); }
} SCENE {
diff --git a/test/battle/ability/insomnia.c b/test/battle/ability/insomnia.c
index 3098ce6d3f..65a69cbbc3 100644
--- a/test/battle/ability/insomnia.c
+++ b/test/battle/ability/insomnia.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Insomnia prevents sleep")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Insomnia prevents sleep")
SINGLE_BATTLE_TEST("Insomnia prevents yawn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("Insomnia prevents yawn")
SINGLE_BATTLE_TEST("Insomnia prevents rest")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/intimidate.c b/test/battle/ability/intimidate.c
index 1278a45866..2553c2755f 100644
--- a/test/battle/ability/intimidate.c
+++ b/test/battle/ability/intimidate.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Intimidate (opponent) lowers player's attack after switch out", s16 damage)
@@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Intimidate (opponent) lowers player's attack after KO", s16
DOUBLE_BATTLE_TEST("Intimidate doesn't activate on an empty field in a double battle")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
@@ -246,7 +246,7 @@ DOUBLE_BATTLE_TEST("Intimidate is not going to trigger if a mon switches out thr
}
}
-SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutralizing Gas")
+SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutralizing Gas - switching out")
{
GIVEN {
PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
@@ -263,3 +263,91 @@ SINGLE_BATTLE_TEST("Intimidate activates when it's no longer effected by Neutral
SEND_IN_MESSAGE("Wobbuffet");
}
}
+
+SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - switching moves")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_U_TURN; }
+ PARAMETRIZE { move = MOVE_HEALING_WISH; }
+ PARAMETRIZE { move = MOVE_BATON_PASS; }
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_HEALING_WISH) == EFFECT_HEALING_WISH);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
+ PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); }
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
+ } WHEN {
+ TURN { MOVE(player, move); SEND_OUT(player, 1); }
+ } SCENE {
+ ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
+ MESSAGE("Neutralizing gas filled the area!");
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ MESSAGE("The effects of the neutralizing gas wore off!");
+ ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
+ SEND_IN_MESSAGE("Wobbuffet");
+ } THEN {
+ if (move == MOVE_HEALING_WISH)
+ EXPECT_EQ(player->hp, player->maxHP);
+ }
+}
+
+SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - opponent caused switches")
+{
+ u32 move, item;
+ PARAMETRIZE { move = MOVE_TACKLE; item = ITEM_EJECT_BUTTON; }
+ PARAMETRIZE { move = MOVE_GROWL; item = ITEM_EJECT_PACK; }
+ PARAMETRIZE { move = MOVE_ROAR; item = ITEM_NONE; }
+ PARAMETRIZE { move = MOVE_DRAGON_TAIL; item = ITEM_NONE; }
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON);
+ ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
+ PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); Item(item); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
+ } WHEN {
+ if (item != ITEM_NONE) {
+ TURN { MOVE(opponent, move); SEND_OUT(player, 1); }
+ } else {
+ TURN { MOVE(opponent, move); }
+ }
+ } SCENE {
+ ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
+ MESSAGE("Neutralizing gas filled the area!");
+ ANIMATION(ANIM_TYPE_MOVE, move, opponent);
+ if (item != ITEM_NONE)
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ MESSAGE("The effects of the neutralizing gas wore off!");
+ ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
+ if (item != ITEM_NONE) {
+ SEND_IN_MESSAGE("Wobbuffet");
+ } else {
+ MESSAGE("Wobbuffet was dragged out!");
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Intimidate activates when it's no longer affected by Neutralizing Gas - fainted")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_FELL_STINGER) == EFFECT_FELL_STINGER);
+ PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); HP(1); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ARBOK) { Ability(ABILITY_INTIMIDATE); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_FELL_STINGER); SEND_OUT(player, 1); }
+ } SCENE {
+ ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS);
+ MESSAGE("Neutralizing gas filled the area!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FELL_STINGER, opponent);
+ MESSAGE("The effects of the neutralizing gas wore off!");
+ ABILITY_POPUP(opponent, ABILITY_INTIMIDATE);
+ MESSAGE("Weezing fainted!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ SEND_IN_MESSAGE("Wobbuffet");
+ }
+}
+
diff --git a/test/battle/ability/intrepid_sword.c b/test/battle/ability/intrepid_sword.c
index 68300fb229..58fd9883eb 100644
--- a/test/battle/ability/intrepid_sword.c
+++ b/test/battle/ability/intrepid_sword.c
@@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Intrepid Sword activates when it's no longer effected by Neu
SINGLE_BATTLE_TEST("Intrepid Sword and Dauntless Shield both can be Skill Swapped and active their effects on the Skill Swap user")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
+ ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); }
OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); }
diff --git a/test/battle/ability/keen_eye.c b/test/battle/ability/keen_eye.c
index b047ec988f..0268477ded 100644
--- a/test/battle/ability/keen_eye.c
+++ b/test/battle/ability/keen_eye.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].accuracy == 100);
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN);
+ ASSUME(GetMoveAccuracy(MOVE_TACKLE) == 100);
+ ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN);
ASSUME(B_ILLUMINATE_EFFECT >= GEN_9);
}
@@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye ignore target's evasi
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_TEAM].effect == EFFECT_EVASION_UP);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_TEAM) == EFFECT_EVASION_UP);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -78,7 +78,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye are ignored by Mold B
PARAMETRIZE { speciesOpponent = SPECIES_URSALUNA_BLOODMOON; abilityOpponent = ABILITY_MINDS_EYE; }
}
- PASSES_RANDOMLY(gMovesInfo[MOVE_TACKLE].accuracy * 3 / 4, 100, RNG_ACCURACY);
+ PASSES_RANDOMLY(GetMoveAccuracy(MOVE_TACKLE) * 3 / 4, 100, RNG_ACCURACY);
GIVEN {
PLAYER(speciesPlayer) { Ability(abilityPlayer); }
OPPONENT(speciesOpponent) { Ability(abilityOpponent); }
@@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent Topsy-T
PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP);
- ASSUME(gMovesInfo[MOVE_TOPSY_TURVY].effect == EFFECT_TOPSY_TURVY);
+ ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP);
+ ASSUME(GetMoveEffect(MOVE_TOPSY_TURVY) == EFFECT_TOPSY_TURVY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -141,7 +141,7 @@ SINGLE_BATTLE_TEST("Keen Eye, Gen9+ Illuminate & Minds Eye don't prevent receivi
PARAMETRIZE { species = SPECIES_URSALUNA_BLOODMOON; ability = ABILITY_MINDS_EYE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
@@ -173,7 +173,7 @@ SINGLE_BATTLE_TEST("Keen Eye & Gen9+ Illuminate don't prevent Spectral Thief fro
PARAMETRIZE { species = SPECIES_STARYU; ability = ABILITY_ILLUMINATE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP);
+ ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP);
ASSUME(MoveHasAdditionalEffect(MOVE_SPECTRAL_THIEF, MOVE_EFFECT_SPECTRAL_THIEF) == TRUE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
diff --git a/test/battle/ability/leaf_guard.c b/test/battle/ability/leaf_guard.c
index af113f1bb6..e04881ecb4 100644
--- a/test/battle/ability/leaf_guard.c
+++ b/test/battle/ability/leaf_guard.c
@@ -11,10 +11,10 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun")
PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; }
// PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; } // Pointless since you can't freeze in sunlight anyway
GIVEN {
- ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
- ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP);
- ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].effect == EFFECT_PARALYZE);
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
+ ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_PARALYZE);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun")
{
GIVEN {
ASSUME(B_LEAF_GUARD_PREVENTS_REST >= GEN_5);
- ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); HP(100); MaxHP(200); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/lightning_rod.c b/test/battle/ability/lightning_rod.c
index c719ee145d..4a90a8573c 100644
--- a/test/battle/ability/lightning_rod.c
+++ b/test/battle/ability/lightning_rod.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the Sp. Attack [Gen5+]")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
} WHEN {
@@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the
DOUBLE_BATTLE_TEST("Lightning Rod forces single-target Electric-type moves to target the Pokémon with this Ability.")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
diff --git a/test/battle/ability/liquid_ooze.c b/test/battle/ability/liquid_ooze.c
new file mode 100644
index 0000000000..05b78dce73
--- /dev/null
+++ b/test/battle/ability/liquid_ooze.c
@@ -0,0 +1,112 @@
+#include "global.h"
+#include "test/battle.h"
+
+SINGLE_BATTLE_TEST("Liquid Ooze causes Absorb users to lose HP instead of heal")
+{
+ s16 damage;
+ s16 healed;
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_ABSORB); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
+ HP_BAR(opponent, captureDamage: &damage);
+ HP_BAR(player, captureDamage: &healed);
+ MESSAGE("Wobbuffet sucked up the liquid ooze!");
+ } THEN {
+ EXPECT_MUL_EQ(damage, Q_4_12(0.5), healed);
+ }
+}
+
+SINGLE_BATTLE_TEST("Liquid Ooze causes Leech Seed users to lose HP instead of heal")
+{
+ s16 damage;
+ s16 healed;
+
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_LEECH_SEED); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player);
+ HP_BAR(opponent, captureDamage: &damage);
+ HP_BAR(player, captureDamage: &healed);
+ } THEN {
+ EXPECT_EQ(damage, healed);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Liquid Ooze causes Matcha Gatcha users to lose HP instead of heal")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_MATCHA_GOTCHA) == EFFECT_ABSORB);
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(playerLeft);
+ MESSAGE("Wobbuffet sucked up the liquid ooze!");
+ MESSAGE("Wobbuffet fainted!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Liquid Ooze will faint Matcha Gatcha users if it deals enough damage")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_MATCHA_GOTCHA) == EFFECT_ABSORB);
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_TENTACOOL) { Ability(ABILITY_LIQUID_OOZE); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(playerLeft);
+ MESSAGE("Wobbuffet sucked up the liquid ooze!");
+ MESSAGE("Wobbuffet fainted!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Liquid Ooze causes Strength Sap users to lose HP instead of heal")
+{
+ s16 lostHp;
+ s32 atkStat;
+
+ PARAMETRIZE { atkStat = 100; }
+ PARAMETRIZE { atkStat = 490; } // Checks that attacker can faint with no problems.
+
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Attack(atkStat); Ability(ABILITY_LIQUID_OOZE); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_STRENGTH_SAP); if (atkStat == 490) { SEND_OUT(player, 1); } }
+ } SCENE {
+ MESSAGE("Wobbuffet used Strength Sap!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ MESSAGE("The opposing Wobbuffet's Attack fell!");
+ ABILITY_POPUP(opponent, ABILITY_LIQUID_OOZE);
+ HP_BAR(player, captureDamage: &lostHp);
+ MESSAGE("Wobbuffet sucked up the liquid ooze!");
+ if (atkStat >= 490) {
+ MESSAGE("Wobbuffet fainted!");
+ SEND_IN_MESSAGE("Wobbuffet");
+ }
+ } THEN {
+ EXPECT_EQ(lostHp, atkStat);
+ }
+}
+
+TO_DO_BATTLE_TEST("Liquid Ooze does not cause Dream Eater users to lose HP instead of heal (Gen 3-4");
+TO_DO_BATTLE_TEST("Liquid Ooze causes Dream Eater users to lose HP instead of heal (Gen 5+");
diff --git a/test/battle/ability/magic_bounce.c b/test/battle/ability/magic_bounce.c
index a643b22824..2731a21fed 100644
--- a/test/battle/ability/magic_bounce.c
+++ b/test/battle/ability/magic_bounce.c
@@ -5,7 +5,7 @@
SINGLE_BATTLE_TEST("Magic Bounce bounces back status moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
} WHEN {
@@ -22,8 +22,8 @@ SINGLE_BATTLE_TEST("Magic Bounce bounces back status moves")
SINGLE_BATTLE_TEST("Magic Bounce bounces back powder moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
+ ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
} WHEN {
@@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Magic Bounce bounces back powder moves")
SINGLE_BATTLE_TEST("Magic Bounce cannot bounce back powder moves against Grass Types")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS);
PLAYER(SPECIES_ODDISH);
OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
@@ -59,8 +59,8 @@ SINGLE_BATTLE_TEST("Magic Bounce cannot bounce back powder moves against Grass T
DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting both foes at two foes")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN);
- ASSUME(gMovesInfo[MOVE_LEER].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN);
+ ASSUME(GetMoveTarget(MOVE_LEER) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_ABRA);
PLAYER(SPECIES_KADABRA);
OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
@@ -92,7 +92,7 @@ DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting foes field")
battlerTwo = SPECIES_ESPEON; abilityBattlerTwo = ABILITY_MAGIC_BOUNCE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].target == MOVE_TARGET_OPPONENTS_FIELD);
+ ASSUME(GetMoveTarget(MOVE_STEALTH_ROCK) == MOVE_TARGET_OPPONENTS_FIELD);
PLAYER(SPECIES_ABRA);
PLAYER(SPECIES_KADABRA);
OPPONENT(battlerOne) { Ability(abilityBattlerOne); }
@@ -118,7 +118,7 @@ DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting foes field")
SINGLE_BATTLE_TEST("Magic Bounce bounced back status moves can not be bounced back by Magic Bounce")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
} WHEN {
diff --git a/test/battle/ability/magic_guard.c b/test/battle/ability/magic_guard.c
index 5579652265..8941fb2130 100644
--- a/test/battle/ability/magic_guard.c
+++ b/test/battle/ability/magic_guard.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Magic Guard prevents recoil damage to the user")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_EDGE].recoil == 33);
+ ASSUME(GetMoveRecoil(MOVE_DOUBLE_EDGE) == 33);
PLAYER(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -15,3 +15,32 @@ SINGLE_BATTLE_TEST("Magic Guard prevents recoil damage to the user")
NOT HP_BAR(player);
}
}
+
+SINGLE_BATTLE_TEST("Magic Guard ignores immobilization that can be caused by paralysis")
+{
+ if (B_MAGIC_GUARD >= GEN_4)
+ PASSES_RANDOMLY(1, 1, RNG_PARALYSIS);
+ else
+ PASSES_RANDOMLY(75, 100, RNG_PARALYSIS);
+ GIVEN {
+ PLAYER(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); Status1(STATUS1_PARALYSIS);}
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_CELEBRATE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
+ }
+}
+
+SINGLE_BATTLE_TEST("Magic Guard does not ignore speed stat changes caused by paralysis")
+{
+ GIVEN {
+ PLAYER(SPECIES_CLEFABLE) { Speed(100); Ability(ABILITY_MAGIC_GUARD); Status1(STATUS1_PARALYSIS);}
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(99); }
+ } WHEN {
+ TURN { }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
+ }
+}
diff --git a/test/battle/ability/magician.c b/test/battle/ability/magician.c
index a951c2f973..f622ac07df 100644
--- a/test/battle/ability/magician.c
+++ b/test/battle/ability/magician.c
@@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Magician does not get self-damage recoil after stealing Life
{
GIVEN {
ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_DELPHOX) { Ability(ABILITY_MAGICIAN); Item(ITEM_NONE); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LIFE_ORB); }
} WHEN {
diff --git a/test/battle/ability/mimicry.c b/test/battle/ability/mimicry.c
new file mode 100644
index 0000000000..fbdb5cf98a
--- /dev/null
+++ b/test/battle/ability/mimicry.c
@@ -0,0 +1,72 @@
+#include "global.h"
+#include "test/battle.h"
+
+static const u16 terrainData[][2] =
+{
+ { MOVE_ELECTRIC_TERRAIN, TYPE_ELECTRIC, },
+ { MOVE_PSYCHIC_TERRAIN, TYPE_PSYCHIC, },
+ { MOVE_GRASSY_TERRAIN, TYPE_GRASS, },
+ { MOVE_MISTY_TERRAIN, TYPE_FAIRY, },
+};
+
+SINGLE_BATTLE_TEST("Mimicry changes the battler's type based on Terrain")
+{
+ u32 j;
+ u32 terrainMove = MOVE_NONE;
+ u32 terrainType = TYPE_NONE;
+
+ for (j = 0; j < ARRAY_COUNT(terrainData); j++)
+ PARAMETRIZE { terrainMove = terrainData[j][0]; terrainType = terrainData[j][1]; }
+
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); }
+ } WHEN {
+ TURN { MOVE(player, terrainMove); }
+ } SCENE {
+ ABILITY_POPUP(opponent);
+ switch (terrainMove)
+ {
+ case MOVE_ELECTRIC_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Electric!"); break;
+ case MOVE_PSYCHIC_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Psychic!"); break;
+ case MOVE_GRASSY_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Grass!"); break;
+ case MOVE_MISTY_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Fairy!"); break;
+ }
+ } THEN {
+ EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], terrainType);
+ EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[1], terrainType);
+ }
+}
+
+SINGLE_BATTLE_TEST("Mimicry restores the battler's types when terrain is removed by Steel Roller and Ice Spinner")
+{
+ u32 j;
+ u32 terrainMove = MOVE_NONE;
+ u32 removeTerrainMove = MOVE_NONE;
+
+ for (j = 0; j < ARRAY_COUNT(terrainData); j++)
+ {
+ PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainData[j][0]; }
+ PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainData[j][0]; }
+ }
+
+ GIVEN {
+ ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[0] == TYPE_GROUND);
+ ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[1] == TYPE_STEEL);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); }
+ } WHEN {
+ TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); }
+ } SCENE {
+ switch (terrainMove)
+ {
+ case MOVE_ELECTRIC_TERRAIN: MESSAGE("The electricity disappeared from the battlefield."); break;
+ case MOVE_PSYCHIC_TERRAIN: MESSAGE("The weirdness disappeared from the battlefield!"); break;
+ case MOVE_GRASSY_TERRAIN: MESSAGE("The grass disappeared from the battlefield."); break;
+ case MOVE_MISTY_TERRAIN: MESSAGE("The mist disappeared from the battlefield."); break;
+ }
+ } THEN {
+ EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GROUND);
+ EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[1], TYPE_STEEL);
+ }
+}
diff --git a/test/battle/ability/minds_eye.c b/test/battle/ability/minds_eye.c
index bf50fa0e2e..59c81746c7 100644
--- a/test/battle/ability/minds_eye.c
+++ b/test/battle/ability/minds_eye.c
@@ -48,7 +48,7 @@ AI_SINGLE_BATTLE_TEST("AI doesn't use accuracy-lowering moves if it knows that t
for (j = MOVE_NONE + 1; j < MOVES_COUNT; j++)
{
- if (gMovesInfo[j].effect == EFFECT_ACCURACY_DOWN || gMovesInfo[j].effect == EFFECT_ACCURACY_DOWN_2) {
+ if (GetMoveEffect(j) == EFFECT_ACCURACY_DOWN || GetMoveEffect(j) == EFFECT_ACCURACY_DOWN_2) {
PARAMETRIZE { moveAI = j; abilityAI = ABILITY_SWIFT_SWIM; }
PARAMETRIZE { moveAI = j; abilityAI = ABILITY_MOLD_BREAKER; }
}
diff --git a/test/battle/ability/mirror_armor.c b/test/battle/ability/mirror_armor.c
index 288fe72334..5aa2b55ef3 100644
--- a/test/battle/ability/mirror_armor.c
+++ b/test/battle/ability/mirror_armor.c
@@ -171,8 +171,8 @@ DOUBLE_BATTLE_TEST("Mirror Armor lowers Speed of the partner Pokemon after Court
{
KNOWN_FAILING;
GIVEN {
- ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
- ASSUME(gMovesInfo[MOVE_COURT_CHANGE].effect == EFFECT_COURT_CHANGE);
+ ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
+ ASSUME(GetMoveEffect(MOVE_COURT_CHANGE) == EFFECT_COURT_CHANGE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); }
diff --git a/test/battle/ability/misty_surge.c b/test/battle/ability/misty_surge.c
new file mode 100644
index 0000000000..229d26c3ba
--- /dev/null
+++ b/test/battle/ability/misty_surge.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Misty Surge creates Misty Terrain when entering the battle");
diff --git a/test/battle/ability/moxie.c b/test/battle/ability/moxie.c
index 56577736db..35ae64d164 100644
--- a/test/battle/ability/moxie.c
+++ b/test/battle/ability/moxie.c
@@ -8,7 +8,7 @@ DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh raises Attack by one stage after direct
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_SNORUNT) { HP(1); }
OPPONENT(SPECIES_GLALIE) { HP(1); }
@@ -84,7 +84,7 @@ SINGLE_BATTLE_TEST("Moxie/Chilling Neigh does not trigger when already at maximu
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
+ ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM);
PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_SNORUNT) { HP(1); }
OPPONENT(SPECIES_SNORUNT);
@@ -122,9 +122,8 @@ DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not increase damage done by the sa
PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; }
PARAMETRIZE { species = SPECIES_CALYREX_ICE; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; }
- KNOWN_FAILING; // Requires simultaneous damage implementation
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(species) { Ability(ability); }
PLAYER(SPECIES_ABRA) { HP(1); }
OPPONENT(SPECIES_GLALIE);
@@ -136,6 +135,7 @@ DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not increase damage done by the sa
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, playerLeft);
HP_BAR(opponentLeft, captureDamage: &damage[0]);
HP_BAR(playerRight);
+ HP_BAR(opponentRight, captureDamage: &damage[1]);
MESSAGE("Abra fainted!");
ABILITY_POPUP(playerLeft, abilityPopUp);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
@@ -145,7 +145,6 @@ DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not increase damage done by the sa
MESSAGE("Glastrier's Chilling Neigh raised its Attack!");
else
MESSAGE("Calyrex's Chilling Neigh raised its Attack!");
- HP_BAR(opponentRight, captureDamage: &damage[1]);
} THEN {
EXPECT_EQ(playerLeft->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
EXPECT_EQ(damage[0], damage[1]);
diff --git a/test/battle/ability/mummy.c b/test/battle/ability/mummy.c
index 74461ec2ee..f03e453e5c 100644
--- a/test/battle/ability/mummy.c
+++ b/test/battle/ability/mummy.c
@@ -10,14 +10,14 @@ SINGLE_BATTLE_TEST("Mummy/Lingering Aroma replace the attacker's ability on cont
PARAMETRIZE { move = MOVE_AQUA_JET; ability = ABILITY_LINGERING_AROMA; species = SPECIES_OINKOLOGNE; }
PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_LINGERING_AROMA; species = SPECIES_OINKOLOGNE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_AQUA_JET].makesContact);
- ASSUME(!gMovesInfo[MOVE_WATER_GUN].makesContact);
+ ASSUME(MoveMakesContact(MOVE_AQUA_JET));
+ ASSUME(!MoveMakesContact(MOVE_WATER_GUN));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(opponent, ability);
if (ability == ABILITY_MUMMY)
MESSAGE("Wobbuffet acquired Mummy!");
@@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Mummy and Lingering Aroma don't replace each other")
PARAMETRIZE { ability1 = ABILITY_MUMMY; species1 = SPECIES_YAMASK; ability2 = ABILITY_LINGERING_AROMA; species2 = SPECIES_OINKOLOGNE; }
PARAMETRIZE { ability1 = ability2 = ABILITY_LINGERING_AROMA; species1 = species2 = SPECIES_OINKOLOGNE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_AQUA_JET].makesContact);
+ ASSUME(MoveMakesContact(MOVE_AQUA_JET));
PLAYER(species1) { Ability(ability1); Speed(2); }
OPPONENT(species2) { Ability(ability2); Speed(1); }
} WHEN {
diff --git a/test/battle/ability/neuroforce.c b/test/battle/ability/neuroforce.c
index 88af00b722..bd40982d02 100644
--- a/test/battle/ability/neuroforce.c
+++ b/test/battle/ability/neuroforce.c
@@ -10,8 +10,8 @@ SINGLE_BATTLE_TEST("Neuroforce increases the strength of super-effective moves b
PARAMETRIZE { ability = ABILITY_NEUROFORCE; move = MOVE_TACKLE; }
PARAMETRIZE { ability = ABILITY_KLUTZ; move = MOVE_TACKLE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST);
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
PLAYER(SPECIES_NECROZMA_ULTRA) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/oblivious.c b/test/battle/ability/oblivious.c
index 70bf941923..3ac979a271 100644
--- a/test/battle/ability/oblivious.c
+++ b/test/battle/ability/oblivious.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Oblivious prevents Infatuation")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ATTRACT].effect == EFFECT_ATTRACT);
+ ASSUME(GetMoveEffect(MOVE_ATTRACT) == EFFECT_ATTRACT);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); }
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); }
} WHEN {
@@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Infatuation")
SINGLE_BATTLE_TEST("Oblivious prevents Captivate")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CAPTIVATE].effect == EFFECT_CAPTIVATE);
+ ASSUME(GetMoveEffect(MOVE_CAPTIVATE) == EFFECT_CAPTIVATE);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); }
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); }
} WHEN {
@@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Oblivious prevents Captivate")
SINGLE_BATTLE_TEST("Oblivious prevents Taunt")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT);
+ ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT);
ASSUME(B_OBLIVIOUS_TAUNT >= GEN_6);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/opportunist.c b/test/battle/ability/opportunist.c
index 662d442dbc..2abd483466 100644
--- a/test/battle/ability/opportunist.c
+++ b/test/battle/ability/opportunist.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Opportunist only copies foe's positive stat changes in a turn", s16 damage)
diff --git a/test/battle/ability/overcoat.c b/test/battle/ability/overcoat.c
index b73f098e78..96f3ffcb08 100644
--- a/test/battle/ability/overcoat.c
+++ b/test/battle/ability/overcoat.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Overcoat blocks powder and spore moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_PINECO) { Ability(ABILITY_OVERCOAT); }
} WHEN {
diff --git a/test/battle/ability/overgrow.c b/test/battle/ability/overgrow.c
index 0bc2d7cdd5..3ba7790093 100644
--- a/test/battle/ability/overgrow.c
+++ b/test/battle/ability/overgrow.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Overgrow boosts Grass-type moves in a pinch", s16 damage)
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS);
+ ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS);
PLAYER(SPECIES_BULBASAUR) { Ability(ABILITY_OVERGROW); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/own_tempo.c b/test/battle/ability/own_tempo.c
index 4b3c42053b..a6dd8c4591 100644
--- a/test/battle/ability/own_tempo.c
+++ b/test/battle/ability/own_tempo.c
@@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes
{
GIVEN {
ASSUME(B_UPDATED_INTIMIDATE >= GEN_8);
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); };
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
} WHEN {
@@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes
SINGLE_BATTLE_TEST("Own Tempo prevents confusion from moves by the opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
} WHEN {
@@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Own Tempo is ignored by Mold Breaker")
{
KNOWN_FAILING; // Ideally the func CanBeConfused should be split into AttackerCanBeConfused and TargetCanBeConfused or we do it in the same func but have a check for when battlerAtk == battlerDef
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
} WHEN {
@@ -77,7 +77,7 @@ SINGLE_BATTLE_TEST("Own Tempo cures confusion obtained from an opponent with Mol
{
KNOWN_FAILING;
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); };
OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
} WHEN {
@@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("Own Tempo cures confusion obtained from an opponent with Mol
SINGLE_BATTLE_TEST("Own Tempo cures confusion if it's obtained via Skill Swap")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].effect == EFFECT_CONFUSE);
- ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
+ ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/parental_bond.c b/test/battle/ability/parental_bond.c
index a1614a8ffc..29f137f6af 100644
--- a/test/battle/ability/parental_bond.c
+++ b/test/battle/ability/parental_bond.c
@@ -4,9 +4,9 @@
SINGLE_BATTLE_TEST("Parental Bond converts Tackle into a two-strike move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_TACKLE].strikeCount < 2);
- ASSUME(gMovesInfo[MOVE_TACKLE].effect == EFFECT_HIT);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveStrikeCount(MOVE_TACKLE) < 2);
+ ASSUME(GetMoveEffect(MOVE_TACKLE) == EFFECT_HIT);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -27,8 +27,8 @@ SINGLE_BATTLE_TEST("Parental Bond converts Tackle into a two-strike move")
SINGLE_BATTLE_TEST("Parental Bond does not convert a move with three or more strikes to a two-strike move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRIPLE_KICK].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_TRIPLE_KICK].strikeCount == 3);
+ ASSUME(GetMoveCategory(MOVE_TRIPLE_KICK) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveStrikeCount(MOVE_TRIPLE_KICK) == 3);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -54,10 +54,10 @@ SINGLE_BATTLE_TEST("Parental Bond converts multi-target moves into a two-strike
PARAMETRIZE { move = MOVE_ICY_WIND; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].strikeCount < 2);
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
- ASSUME(gMovesInfo[MOVE_ICY_WIND].strikeCount < 2);
- ASSUME(gMovesInfo[MOVE_ICY_WIND].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveStrikeCount(MOVE_EARTHQUAKE) < 2);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveStrikeCount(MOVE_ICY_WIND) < 2);
+ ASSUME(GetMoveTarget(MOVE_ICY_WIND) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -78,8 +78,8 @@ SINGLE_BATTLE_TEST("Parental Bond converts multi-target moves into a two-strike
DOUBLE_BATTLE_TEST("Parental Bond does not convert multi-target moves into a two-strike move in Double Battles, even if it only damages one")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].strikeCount < 2);
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveStrikeCount(MOVE_EARTHQUAKE) < 2);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
ASSUME(gSpeciesInfo[SPECIES_PIDGEY].types[1] == TYPE_FLYING);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
PLAYER(SPECIES_PIDGEY);
@@ -109,8 +109,8 @@ SINGLE_BATTLE_TEST("Parental Bond-converted moves only hit once on Lightning Rod
PARAMETRIZE { move = MOVE_THUNDERBOLT; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; type = TYPE_ELECTRIC; }
PARAMETRIZE { move = MOVE_SURF; ability = ABILITY_STORM_DRAIN; species = SPECIES_LILEEP; type = TYPE_WATER; }
GIVEN {
- ASSUME(gMovesInfo[move].strikeCount < 2);
- ASSUME(gMovesInfo[move].type == type);
+ ASSUME(GetMoveStrikeCount(move) < 2);
+ ASSUME(GetMoveType(move) == type);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -137,8 +137,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
GIVEN {
ASSUME(B_MULTI_HIT_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -163,8 +163,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
GIVEN {
ASSUME(B_MULTI_HIT_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -190,8 +190,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
GIVEN {
ASSUME(B_MULTI_HIT_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -218,8 +218,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
GIVEN {
ASSUME(B_MULTI_HIT_CHANCE >= GEN_5);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_COMET_PUNCH].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveCategory(MOVE_COMET_PUNCH) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_COMET_PUNCH) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -242,8 +242,8 @@ SINGLE_BATTLE_TEST("Parental Bond has no affect on multi hit moves and they stil
SINGLE_BATTLE_TEST("Parental Bond Smack Down effect triggers after 2nd hit")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SMACK_DOWN].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_SMACK_DOWN].strikeCount < 2);
+ ASSUME(GetMoveCategory(MOVE_SMACK_DOWN) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveStrikeCount(MOVE_SMACK_DOWN) < 2);
ASSUME(MoveHasAdditionalEffect(MOVE_SMACK_DOWN, MOVE_EFFECT_SMACK_DOWN));
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_SKARMORY);
@@ -267,7 +267,7 @@ SINGLE_BATTLE_TEST("Parental Bond Snore strikes twice while asleep")
{
s16 damage[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_SNORE].effect == EFFECT_SNORE);
+ ASSUME(GetMoveEffect(MOVE_SNORE) == EFFECT_SNORE);
PLAYER(SPECIES_KANGASKHAN_MEGA) { Status1(STATUS1_SLEEP); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -289,7 +289,7 @@ SINGLE_BATTLE_TEST("Parental Bond Snore strikes twice while asleep")
SINGLE_BATTLE_TEST("Parental Bond only triggers Dragon Tail's target switch out on the second hit")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
diff --git a/test/battle/ability/pastel_veil.c b/test/battle/ability/pastel_veil.c
index a6b6168547..686ca0ff85 100644
--- a/test/battle/ability/pastel_veil.c
+++ b/test/battle/ability/pastel_veil.c
@@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison")
{
KNOWN_FAILING;
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
} WHEN {
@@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Pastel Veil immediately cures Mold Breaker poison")
DOUBLE_BATTLE_TEST("Pastel Veil does not cure Mold Breaker poison on partner")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
@@ -70,7 +70,7 @@ DOUBLE_BATTLE_TEST("Pastel Veil does not cure Mold Breaker poison on partner")
SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
} WHEN {
@@ -86,7 +86,7 @@ SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison")
DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
@@ -104,7 +104,7 @@ DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic bad poison on partner")
SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
@@ -120,7 +120,7 @@ SINGLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison")
DOUBLE_BATTLE_TEST("Pastel Veil prevents Toxic Spikes poison on partner")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_PONYTA_GALAR) { Ability(ABILITY_PASTEL_VEIL); }
diff --git a/test/battle/ability/pickup.c b/test/battle/ability/pickup.c
index 927e1b3468..22db259399 100644
--- a/test/battle/ability/pickup.c
+++ b/test/battle/ability/pickup.c
@@ -23,7 +23,24 @@ SINGLE_BATTLE_TEST("Pickup grants an item used by another Pokémon")
}
}
-SINGLE_BATTLE_TEST("Pickup doesn't grant the user their item")
+WILD_BATTLE_TEST("Pickup grants an item used by itself in wild battles (Gen 9)")
+{
+ GIVEN {
+ ASSUME(B_PICKUP_WILD >= GEN_9);
+ PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ ABILITY_POPUP(player, ABILITY_PICKUP);
+ MESSAGE("Zigzagoon found one Sitrus Berry!");
+ } THEN {
+ EXPECT_EQ(player->item, ITEM_SITRUS_BERRY);
+ }
+}
+
+SINGLE_BATTLE_TEST("Pickup doesn't grant the user their item outside wild battles")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
@@ -103,7 +120,7 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item after its holder faints")
SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if holder is replaced")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
+ ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(300); HP(151); Item(ITEM_SITRUS_BERRY); }
@@ -185,7 +202,7 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item if the user eats it with Bug Bi
SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restored it")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
+ ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@@ -205,7 +222,7 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restor
SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
+ ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
@@ -222,7 +239,7 @@ SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged")
SINGLE_BATTLE_TEST("Pickup restores an item that was used by Natural Gift")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
+ ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
diff --git a/test/battle/ability/pixilate.c b/test/battle/ability/pixilate.c
index 97c9c37a0c..44289769a6 100644
--- a/test/battle/ability/pixilate.c
+++ b/test/battle/ability/pixilate.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
}
SINGLE_BATTLE_TEST("Pixilate turns a Normal-type move into a Fairy-type move")
diff --git a/test/battle/ability/poison_point.c b/test/battle/ability/poison_point.c
index 9f9cd5e900..635698379c 100644
--- a/test/battle/ability/poison_point.c
+++ b/test/battle/ability/poison_point.c
@@ -7,15 +7,15 @@ SINGLE_BATTLE_TEST("Poison Point inflicts poison on contact")
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_SWIFT));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); }
} WHEN {
TURN { MOVE(player, move); }
TURN {}
} SCENE {
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(opponent, ABILITY_POISON_POINT);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
MESSAGE("Wobbuffet was poisoned by the opposing Nidoran♂'s Poison Point!");
@@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Poison Point triggers 30% of the time")
PASSES_RANDOMLY(3, 10, RNG_POISON_POINT);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_NIDORAN_M) { Ability(ABILITY_POISON_POINT); }
} WHEN {
diff --git a/test/battle/ability/poison_puppeteer.c b/test/battle/ability/poison_puppeteer.c
index b8124b975b..d5c470ad37 100644
--- a/test/battle/ability/poison_puppeteer.c
+++ b/test/battle/ability/poison_puppeteer.c
@@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Poison Puppeteer confuses target if it was (badly) poisoned
SINGLE_BATTLE_TEST("Poison Puppeteer does not trigger if poison is Toxic Spikes induced")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_PECHARUNT) { Ability(ABILITY_POISON_PUPPETEER); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/poison_touch.c b/test/battle/ability/poison_touch.c
index 8fb4d243fb..530d361794 100644
--- a/test/battle/ability/poison_touch.c
+++ b/test/battle/ability/poison_touch.c
@@ -5,8 +5,8 @@ SINGLE_BATTLE_TEST("Poison Touch has a 30% chance to poison when attacking with
{
PASSES_RANDOMLY(3, 10, RNG_POISON_TOUCH);
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -27,15 +27,15 @@ SINGLE_BATTLE_TEST("Poison Touch only applies when using contact moves")
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_SWIFT));
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(player, ABILITY_POISON_TOUCH);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
MESSAGE("The opposing Wobbuffet was poisoned by Grimer's Poison Touch!");
@@ -54,8 +54,8 @@ SINGLE_BATTLE_TEST("Poison Touch only applies when using contact moves")
SINGLE_BATTLE_TEST("Poison Touch applies between multi-hit move hits")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ARM_THRUST].effect == EFFECT_MULTI_HIT);
- ASSUME(gMovesInfo[MOVE_ARM_THRUST].makesContact);
+ ASSUME(GetMoveEffect(MOVE_ARM_THRUST) == EFFECT_MULTI_HIT);
+ ASSUME(MoveMakesContact(MOVE_ARM_THRUST));
ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_POISON_TOUCH); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_PECHA_BERRY); };
diff --git a/test/battle/ability/prankster.c b/test/battle/ability/prankster.c
index c569506729..cf297214d9 100644
--- a/test/battle/ability/prankster.c
+++ b/test/battle/ability/prankster.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(gSpeciesInfo[SPECIES_UMBREON].types[0] == TYPE_DARK);
- ASSUME(gMovesInfo[MOVE_CONFUSE_RAY].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveCategory(MOVE_CONFUSE_RAY) == DAMAGE_CATEGORY_STATUS);
}
SINGLE_BATTLE_TEST("Prankster-affected moves don't affect Dark-type Pokémon")
@@ -135,7 +135,7 @@ SINGLE_BATTLE_TEST("Prankster is blocked by Quick Guard in Gen5+")
DOUBLE_BATTLE_TEST("Prankster-affected moves that target all Pokémon are successful regardless of the presence of Dark-type Pokémon")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CAPTIVATE].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_CAPTIVATE) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_ILLUMISE) { Ability(ABILITY_PRANKSTER); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_UMBREON);
diff --git a/test/battle/ability/primordial_sea.c b/test/battle/ability/primordial_sea.c
index 643dca161c..e895d8ba48 100644
--- a/test/battle/ability/primordial_sea.c
+++ b/test/battle/ability/primordial_sea.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_EMBER].power != 0);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(!IsBattleMoveStatus(MOVE_EMBER));
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
}
SINGLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves")
@@ -32,9 +32,9 @@ SINGLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves")
DOUBLE_BATTLE_TEST("Primordial Sea blocks damaging Fire-type moves and prints the message only once with moves hitting multiple targets")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ERUPTION].power != 0);
- ASSUME(gMovesInfo[MOVE_ERUPTION].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_ERUPTION].target == MOVE_TARGET_BOTH);
+ ASSUME(!IsBattleMoveStatus(MOVE_ERUPTION));
+ ASSUME(GetMoveType(MOVE_ERUPTION) == TYPE_FIRE);
+ ASSUME(GetMoveTarget(MOVE_ERUPTION) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_KYOGRE) {Item(ITEM_BLUE_ORB); {Speed(5);}}
PLAYER(SPECIES_WOBBUFFET) {Speed(5);}
OPPONENT(SPECIES_WOBBUFFET) {Speed(10);}
diff --git a/test/battle/ability/protosynthesis.c b/test/battle/ability/protosynthesis.c
index 2be9f81d28..5a468893e5 100644
--- a/test/battle/ability/protosynthesis.c
+++ b/test/battle/ability/protosynthesis.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL);
}
SINGLE_BATTLE_TEST("Protosynthesis boosts the highest stat")
diff --git a/test/battle/ability/psychic_surge.c b/test/battle/ability/psychic_surge.c
new file mode 100644
index 0000000000..d840e8d440
--- /dev/null
+++ b/test/battle/ability/psychic_surge.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Psychic Surge creates Psychic Terrain when entering the battle");
diff --git a/test/battle/ability/purifying_salt.c b/test/battle/ability/purifying_salt.c
index 495ce01a46..cb8fc6ca56 100644
--- a/test/battle/ability/purifying_salt.c
+++ b/test/battle/ability/purifying_salt.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Purifying Salt halves damage from Ghost-type moves", s16 dam
PARAMETRIZE { ability = ABILITY_STURDY; }
PARAMETRIZE { ability = ABILITY_PURIFYING_SALT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GARGANACL) { Ability(ability); }
} WHEN {
@@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Purifying Salt halves damage from dynamic Ghost-type moves",
PARAMETRIZE { ability = ABILITY_STURDY; }
PARAMETRIZE { ability = ABILITY_PURIFYING_SALT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST);
+ ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST);
PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_GHOST); }
OPPONENT(SPECIES_GARGANACL) { Ability(ability); }
} WHEN {
@@ -61,10 +61,10 @@ SINGLE_BATTLE_TEST("Purifying Salt grants immunity to status effects")
PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; }
PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
- ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP);
- ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].effect == EFFECT_PARALYZE);
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
+ ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_THUNDER_WAVE) == EFFECT_PARALYZE);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_PURIFYING_SALT); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/quark_drive.c b/test/battle/ability/quark_drive.c
index 928ee45eb5..edefdc1305 100644
--- a/test/battle/ability/quark_drive.c
+++ b/test/battle/ability/quark_drive.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL);
}
SINGLE_BATTLE_TEST("Quark Drive boosts the highest stat")
diff --git a/test/battle/ability/rain_dish.c b/test/battle/ability/rain_dish.c
index 93f642c633..dc7de954c3 100644
--- a/test/battle/ability/rain_dish.c
+++ b/test/battle/ability/rain_dish.c
@@ -2,7 +2,7 @@
#include "test/battle.h"
ASSUMPTIONS {
- ASSUME(gMovesInfo[MOVE_RAIN_DANCE].effect == EFFECT_RAIN_DANCE);
+ ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE);
}
SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain")
diff --git a/test/battle/ability/rattled.c b/test/battle/ability/rattled.c
index 5d3e47db33..465a688951 100644
--- a/test/battle/ability/rattled.c
+++ b/test/battle/ability/rattled.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FURY_CUTTER].type == TYPE_BUG);
- ASSUME(gMovesInfo[MOVE_FURY_CUTTER].power != 0);
- ASSUME(gMovesInfo[MOVE_FEINT_ATTACK].type == TYPE_DARK);
- ASSUME(gMovesInfo[MOVE_FEINT_ATTACK].power != 0);
- ASSUME(gMovesInfo[MOVE_SHADOW_PUNCH].type == TYPE_GHOST);
- ASSUME(gMovesInfo[MOVE_SHADOW_PUNCH].power != 0);
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(GetMoveType(MOVE_FURY_CUTTER) == TYPE_BUG);
+ ASSUME(!IsBattleMoveStatus(MOVE_FURY_CUTTER));
+ ASSUME(GetMoveType(MOVE_FEINT_ATTACK) == TYPE_DARK);
+ ASSUME(!IsBattleMoveStatus(MOVE_FEINT_ATTACK));
+ ASSUME(GetMoveType(MOVE_SHADOW_PUNCH) == TYPE_GHOST);
+ ASSUME(!IsBattleMoveStatus(MOVE_SHADOW_PUNCH));
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
}
SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when hit by Bug, Dark or Ghost type move")
@@ -73,8 +73,8 @@ SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when affected by Intimidate")
SINGLE_BATTLE_TEST("Rattled triggers correctly when hit by U-Turn") // Specific test here, because of #3124
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
- ASSUME(gMovesInfo[MOVE_U_TURN].type == TYPE_BUG);
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveType(MOVE_U_TURN) == TYPE_BUG);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_SUDOWOODO) {Ability(ABILITY_RATTLED); }
diff --git a/test/battle/ability/refrigerate.c b/test/battle/ability/refrigerate.c
index dbbaa30eb8..b3f7b59a9e 100644
--- a/test/battle/ability/refrigerate.c
+++ b/test/battle/ability/refrigerate.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
}
SINGLE_BATTLE_TEST("Refrigerate turns a Normal-type move into a Ice-type move")
diff --git a/test/battle/ability/regenerator.c b/test/battle/ability/regenerator.c
new file mode 100644
index 0000000000..0f1b432772
--- /dev/null
+++ b/test/battle/ability/regenerator.c
@@ -0,0 +1,50 @@
+#include "global.h"
+#include "test/battle.h"
+
+SINGLE_BATTLE_TEST("Regenerator heals 1/3 of max HP upon switching out")
+{
+ u32 currHP;
+ PARAMETRIZE { currHP = 1; }
+ PARAMETRIZE { currHP = 2; }
+ PARAMETRIZE { currHP = 3; }
+ GIVEN {
+ PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_REGENERATOR); HP(currHP); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { SWITCH(player, 1); }
+ TURN { SWITCH(player, 0); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Slowbro");
+ SEND_IN_MESSAGE("Wobbuffet");
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ SEND_IN_MESSAGE("Slowbro");
+ } THEN {
+ EXPECT_EQ(player->hp, player->maxHP / 3 + currHP);
+ }
+}
+
+SINGLE_BATTLE_TEST("Regenerator heals 1/3 of max HP upon switching out but doesn't surpass max HP")
+{
+ u32 currHP;
+ PARAMETRIZE { currHP = 5; }
+ PARAMETRIZE { currHP = 4; }
+ PARAMETRIZE { currHP = 3; }
+ PARAMETRIZE { currHP = 2; }
+ PARAMETRIZE { currHP = 1; }
+ GIVEN {
+ PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_REGENERATOR); HP(currHP); MaxHP(5); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { SWITCH(player, 1); }
+ TURN { SWITCH(player, 0); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Slowbro");
+ SEND_IN_MESSAGE("Wobbuffet");
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ SEND_IN_MESSAGE("Slowbro");
+ } THEN {
+ EXPECT_LE(player->hp, player->maxHP);
+ }
+}
diff --git a/test/battle/ability/rocky_payload.c b/test/battle/ability/rocky_payload.c
index 27cc45fda0..6756b98b8b 100644
--- a/test/battle/ability/rocky_payload.c
+++ b/test/battle/ability/rocky_payload.c
@@ -14,11 +14,11 @@ SINGLE_BATTLE_TEST("Rocky Payload increases Rock-type move damage", s16 damage)
PARAMETRIZE { move = MOVE_POWER_GEM; ability = ABILITY_ROCKY_PAYLOAD; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ROCK);
- ASSUME(gMovesInfo[MOVE_ROCK_THROW].type == TYPE_ROCK);
- ASSUME(gMovesInfo[MOVE_POWER_GEM].type == TYPE_ROCK);
- ASSUME(gMovesInfo[MOVE_ROCK_THROW].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_POWER_GEM].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_ROCK);
+ ASSUME(GetMoveType(MOVE_ROCK_THROW) == TYPE_ROCK);
+ ASSUME(GetMoveType(MOVE_POWER_GEM) == TYPE_ROCK);
+ ASSUME(GetMoveCategory(MOVE_ROCK_THROW) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_POWER_GEM) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_BOMBIRDIER) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/sand_veil.c b/test/battle/ability/sand_veil.c
index f42c267273..7622d18763 100644
--- a/test/battle/ability/sand_veil.c
+++ b/test/battle/ability/sand_veil.c
@@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Sand Veil increases evasion during sandstorm")
{
PASSES_RANDOMLY(4, 5, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_POUND].accuracy == 100);
+ ASSUME(GetMoveAccuracy(MOVE_POUND) == 100);
PLAYER(SPECIES_SANDSHREW) { Ability(ABILITY_SAND_VEIL); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/sap_sipper.c b/test/battle/ability/sap_sipper.c
index d691d4e91a..aeb746d2c6 100644
--- a/test/battle/ability/sap_sipper.c
+++ b/test/battle/ability/sap_sipper.c
@@ -61,7 +61,7 @@ SINGLE_BATTLE_TEST("Sap Sipper does not increase Attack if already maxed")
SINGLE_BATTLE_TEST("Sap Sipper blocks multi-hit grass type moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_MARILL) { Ability(ABILITY_SAP_SIPPER); }
OPPONENT(SPECIES_SHELLDER) { Ability(ABILITY_SKILL_LINK); }
} WHEN {
diff --git a/test/battle/ability/seed_sower.c b/test/battle/ability/seed_sower.c
index 822fa8b703..ad4beea515 100644
--- a/test/battle/ability/seed_sower.c
+++ b/test/battle/ability/seed_sower.c
@@ -19,7 +19,6 @@ SINGLE_BATTLE_TEST("Seed Sower sets up Grassy Terrain when hit by an attack")
#define ABILITY_PARAM(n)(abilities[n] = (k == n) ? ABILITY_SEED_SOWER : ABILITY_HARVEST)
#define MOVE_HIT(target, position) \
{ \
- HP_BAR(target); \
if (abilities[position] == ABILITY_SEED_SOWER) { \
ABILITY_POPUP(target); \
MESSAGE("Grass grew to cover the battlefield!");\
@@ -50,8 +49,8 @@ DOUBLE_BATTLE_TEST("Multi-target moves hit correct battlers after Seed Sower is
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_ARBOLIVA) { Ability(abilities[B_POSITION_PLAYER_LEFT]); }
PLAYER(SPECIES_ARBOLIVA) { Ability(abilities[B_POSITION_PLAYER_RIGHT]); }
OPPONENT(SPECIES_ARBOLIVA) { Ability(abilities[B_POSITION_OPPONENT_LEFT]); }
@@ -68,9 +67,13 @@ DOUBLE_BATTLE_TEST("Multi-target moves hit correct battlers after Seed Sower is
if (usedMove == MOVE_HYPER_VOICE) {
if ((attacker & BIT_SIDE) == B_SIDE_OPPONENT) {
if (attacker == B_POSITION_OPPONENT_LEFT) {
+ HP_BAR(playerLeft);
+ HP_BAR(playerRight);
MOVE_HIT(playerLeft, B_POSITION_PLAYER_LEFT);
MOVE_HIT(playerRight, B_POSITION_PLAYER_RIGHT);
} else {
+ HP_BAR(playerLeft);
+ HP_BAR(playerRight);
MOVE_HIT(playerRight, B_POSITION_PLAYER_RIGHT);
MOVE_HIT(playerLeft, B_POSITION_PLAYER_LEFT);
}
@@ -80,9 +83,13 @@ DOUBLE_BATTLE_TEST("Multi-target moves hit correct battlers after Seed Sower is
}
} else {
if (attacker == B_POSITION_PLAYER_LEFT) {
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
MOVE_HIT(opponentLeft, B_POSITION_OPPONENT_LEFT);
MOVE_HIT(opponentRight, B_POSITION_OPPONENT_RIGHT);
} else {
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
MOVE_HIT(opponentRight, B_POSITION_OPPONENT_RIGHT);
MOVE_HIT(opponentLeft, B_POSITION_OPPONENT_LEFT);
}
@@ -94,24 +101,36 @@ DOUBLE_BATTLE_TEST("Multi-target moves hit correct battlers after Seed Sower is
} else { // SURF
switch (attacker) {
case B_POSITION_PLAYER_LEFT:
+ HP_BAR(opponentLeft);
+ HP_BAR(playerRight);
+ HP_BAR(opponentRight);
MOVE_HIT(opponentLeft, B_POSITION_OPPONENT_LEFT);
MOVE_HIT(playerRight, B_POSITION_PLAYER_RIGHT);
MOVE_HIT(opponentRight, B_POSITION_OPPONENT_RIGHT);
NOT HP_BAR(playerLeft);
break;
case B_POSITION_OPPONENT_LEFT:
+ HP_BAR(playerLeft);
+ HP_BAR(playerRight);
+ HP_BAR(opponentRight);
MOVE_HIT(playerLeft, B_POSITION_PLAYER_LEFT);
MOVE_HIT(playerRight, B_POSITION_PLAYER_RIGHT);
MOVE_HIT(opponentRight, B_POSITION_OPPONENT_RIGHT);
NOT HP_BAR(opponentLeft);
break;
case B_POSITION_PLAYER_RIGHT:
+ HP_BAR(playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
MOVE_HIT(playerLeft, B_POSITION_PLAYER_LEFT);
MOVE_HIT(opponentLeft, B_POSITION_OPPONENT_LEFT);
MOVE_HIT(opponentRight, B_POSITION_OPPONENT_RIGHT);
NOT HP_BAR(playerRight);
break;
case B_POSITION_OPPONENT_RIGHT:
+ HP_BAR(playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(playerRight);
MOVE_HIT(playerLeft, B_POSITION_PLAYER_LEFT);
MOVE_HIT(opponentLeft, B_POSITION_OPPONENT_LEFT);
MOVE_HIT(playerRight, B_POSITION_PLAYER_RIGHT);
diff --git a/test/battle/ability/sharpness.c b/test/battle/ability/sharpness.c
index 8ecb07671d..38ed79f86f 100644
--- a/test/battle/ability/sharpness.c
+++ b/test/battle/ability/sharpness.c
@@ -11,8 +11,8 @@ SINGLE_BATTLE_TEST("Sharpness increases the power of slicing moves", s16 damage)
PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_STEADFAST; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_AERIAL_ACE].slicingMove);
- ASSUME(!gMovesInfo[MOVE_SCRATCH].slicingMove);
+ ASSUME(IsSlicingMove(MOVE_AERIAL_ACE));
+ ASSUME(!IsSlicingMove(MOVE_SCRATCH));
PLAYER(SPECIES_GALLADE) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/shed_skin.c b/test/battle/ability/shed_skin.c
index e4ab6b736c..2df293ecb4 100644
--- a/test/battle/ability/shed_skin.c
+++ b/test/battle/ability/shed_skin.c
@@ -8,7 +8,7 @@ SINGLE_BATTLE_TEST("Shed Skin triggers 33% of the time")
else
PASSES_RANDOMLY(33, 100, RNG_SHED_SKIN);
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_ARBOK) { Status1(STATUS1_POISON); Ability(ABILITY_SHED_SKIN); }
} WHEN {
diff --git a/test/battle/ability/sheer_force.c b/test/battle/ability/sheer_force.c
index 97dee48a31..c5add71df0 100644
--- a/test/battle/ability/sheer_force.c
+++ b/test/battle/ability/sheer_force.c
@@ -7,64 +7,921 @@ ASSUMPTIONS
ASSUME(MoveIsAffectedBySheerForce(MOVE_ELECTRO_SHOT) == TRUE);
}
-SINGLE_BATTLE_TEST("Sheer Force boosts power, but removes secondary effects of moves", s16 damage)
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Magnitude", s16 damage)
{
- s32 j;
- u32 ability = 0, move = 0;
-
- for (j = 1; j < MOVES_COUNT; j++)
- {
- if (MoveIsAffectedBySheerForce(j)
- //&& gMovesInfo[j].effect != EFFECT_ORDER_UP
- && gMovesInfo[j].effect != EFFECT_AURA_WHEEL
- && gMovesInfo[j].effect != EFFECT_PLACEHOLDER)
- {
- PARAMETRIZE { ability = ABILITY_ANGER_POINT; move = j; }
- PARAMETRIZE { ability = ABILITY_SHEER_FORCE; move = j; }
- }
- }
-
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
GIVEN {
- PLAYER(SPECIES_TAUROS) { Ability(ability); Status1(move == MOVE_SNORE ? STATUS1_SLEEP : STATUS1_NONE); }
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
- if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
- TURN { MOVE(opponent, MOVE_AGILITY); MOVE(player, move); }
- else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
- TURN { MOVE(opponent, MOVE_QUICK_ATTACK); MOVE(player, move); }
- else
- TURN { MOVE(player, move); }
- if (gMovesInfo[move].effect == EFFECT_TWO_TURNS_ATTACK || gMovesInfo[move].effect == EFFECT_SEMI_INVULNERABLE) {
- TURN { SKIP_TURN(player); }
- TURN { ; }
- }
+ TURN { MOVE(player, MOVE_MAGNITUDE); }
} SCENE {
- ANIMATION(ANIM_TYPE_MOVE, move, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
- if (ability == ABILITY_SHEER_FORCE) {
- NONE_OF {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
- STATUS_ICON(opponent, STATUS1_FREEZE);
- STATUS_ICON(opponent, STATUS1_POISON);
- STATUS_ICON(opponent, STATUS1_BURN);
- STATUS_ICON(opponent, STATUS1_TOXIC_POISON);
- STATUS_ICON(opponent, STATUS1_PARALYSIS);
- MESSAGE("Wobbuffet is confused!");
- MESSAGE("Wobbuffet flinched and couldn't move!");
- }
- // Volt Tackle/Flare Blitz edge case: recoil happens, but target isn't statused
- if (gMovesInfo[move].recoil > 0)
- {
- HP_BAR(player);
- MESSAGE("Tauros was damaged by the recoil!");
- }
- }
} FINALLY {
- s32 j;
- for (j = 0; j < gBattleTestRunnerState->parametersCount; j+=2)
- {
- EXPECT_GT(results[j+1].damage, results[j].damage);
- }
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Eruption", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PRESENT); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Water Spout", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PRESENT); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Present", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PRESENT); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Psywave", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PSYWAVE); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Round", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_ROUND); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Gyro Ball", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_GYRO_BALL); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Electro Ball", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_ELECTRO_BALL); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Dragon Energy", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DRAGON_ENERGY); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Belch", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); HP(1); Item(ITEM_SITRUS_BERRY); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_BELCH); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Shell Trap", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SHELL_TRAP); MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Burn Up", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ZEN_MODE; }
+ GIVEN {
+ PLAYER(SPECIES_DARMANITAN) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_BURN_UP); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Double Shock", s16 damage)
+{
+ u16 move = 0;
+ PARAMETRIZE { move = MOVE_SKILL_SWAP; }
+ PARAMETRIZE { move = MOVE_CELEBRATE; }
+ GIVEN {
+ PLAYER(SPECIES_PIKACHU);
+ OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); };
+ } WHEN {
+ TURN { MOVE(opponent, move); MOVE(player, MOVE_DOUBLE_SHOCK); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Steel Roller", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_GRASSY_TERRAIN); MOVE(player, MOVE_STEEL_ROLLER); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Synchronoise", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); HP(1); Item(ITEM_SITRUS_BERRY); }
+ OPPONENT(SPECIES_CHANSEY);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SYNCHRONOISE); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Aura Wheel", s16 damage)
+{
+ u16 move = 0;
+ PARAMETRIZE { move = MOVE_SKILL_SWAP; }
+ PARAMETRIZE { move = MOVE_CELEBRATE; }
+ GIVEN {
+ PLAYER(SPECIES_MORPEKO);
+ OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); };
+ } WHEN {
+ TURN { MOVE(opponent, move); MOVE(player, MOVE_AURA_WHEEL); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Hyperspace Fury", s16 damage)
+{
+ u16 move = 0;
+ PARAMETRIZE { move = MOVE_SKILL_SWAP; }
+ PARAMETRIZE { move = MOVE_CELEBRATE; }
+ GIVEN {
+ PLAYER(SPECIES_HOOPA_UNBOUND);
+ OPPONENT(SPECIES_TAUROS) { Ability(ABILITY_SHEER_FORCE); };
+ } WHEN {
+ TURN { MOVE(opponent, move); MOVE(player, MOVE_HYPERSPACE_FURY); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Bolt Beak", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_BOLT_BEAK); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Fishious Rend", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_FISHIOUS_REND); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Comeuppance", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, MOVE_COMEUPPANCE); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+SINGLE_BATTLE_TEST("Sheer Force doesn't boost Comeuppance", s16 damage)
+{
+ u16 ability = 0;
+ PARAMETRIZE { ability = ABILITY_SHEER_FORCE; }
+ PARAMETRIZE { ability = ABILITY_ANGER_POINT; }
+ GIVEN {
+ PLAYER(SPECIES_TAUROS) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PAYBACK); }
+ } SCENE {
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_EQ(results[0].damage, results[1].damage);
+ EXPECT_NE(results[0].damage, 0);
+ }
+}
+
+static inline bool32 IgnoreMoveForSheerForceBoost(u32 move)
+{
+ switch (move) {
+ case MOVE_PSYWAVE: // Just skip Psywve
+ case MOVE_PRESENT: // And Present...
+ case MOVE_MAGNITUDE: // And Magnitude...
+ case MOVE_ERUPTION: // And Eruption...
+ case MOVE_WATER_SPOUT:
+ case MOVE_GYRO_BALL:
+ case MOVE_SYNCHRONOISE:
+ case MOVE_ELECTRO_BALL:
+ case MOVE_ROUND:
+ case MOVE_BELCH:
+ case MOVE_HYPERSPACE_FURY:
+ case MOVE_BURN_UP:
+ case MOVE_SHELL_TRAP:
+ case MOVE_BOLT_BEAK:
+ case MOVE_FISHIOUS_REND:
+ case MOVE_AURA_WHEEL:
+ case MOVE_STEEL_ROLLER:
+ case MOVE_DRAGON_ENERGY:
+ case MOVE_DOUBLE_SHOCK:
+ case MOVE_COMEUPPANCE:
+ case MOVE_UPPER_HAND: // Bugged?
+ case MOVE_GLITZY_GLOW: // Light Screen Move Effect seems to be bugged
+ case MOVE_PAYBACK:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static inline bool32 IsMoveSheerForceBoosted(u32 move)
+{
+ switch (move) {
+ case MOVE_AIR_SLASH:
+ case MOVE_ANCIENT_POWER:
+ case MOVE_ASTONISH:
+ case MOVE_BITE:
+ case MOVE_BLIZZARD:
+ case MOVE_BODY_SLAM:
+ case MOVE_BOUNCE:
+ case MOVE_BREAKING_SWIPE:
+ case MOVE_BUBBLE:
+ case MOVE_BUBBLE_BEAM:
+ case MOVE_BUG_BUZZ:
+ case MOVE_BULLDOZE:
+ case MOVE_BURNING_JEALOUSY:
+ case MOVE_CHARGE_BEAM:
+ case MOVE_CHILLING_WATER:
+ case MOVE_CONFUSION:
+ case MOVE_CRUNCH:
+ case MOVE_CRUSH_CLAW:
+ case MOVE_DARK_PULSE:
+ case MOVE_DRAGON_RUSH:
+ case MOVE_DRAGON_BREATH:
+ case MOVE_DYNAMIC_PUNCH:
+ case MOVE_EARTH_POWER:
+ case MOVE_EMBER:
+ case MOVE_ESPER_WING:
+ case MOVE_EXTRASENSORY:
+ case MOVE_FAKE_OUT:
+ case MOVE_FIRE_BLAST:
+ case MOVE_FIRE_FANG:
+ case MOVE_FIRE_PUNCH:
+ case MOVE_FLAME_CHARGE:
+ case MOVE_FLAME_WHEEL:
+ case MOVE_FLAMETHROWER:
+ case MOVE_FLARE_BLITZ:
+ case MOVE_FLASH_CANNON:
+ case MOVE_FOCUS_BLAST:
+ case MOVE_FORCE_PALM:
+ case MOVE_GUNK_SHOT:
+ case MOVE_HEADBUTT:
+ case MOVE_HEAT_WAVE:
+ case MOVE_HURRICANE:
+ case MOVE_ICE_BEAM:
+ case MOVE_ICE_FANG:
+ case MOVE_ICE_PUNCH:
+ case MOVE_ICICLE_CRASH:
+ case MOVE_ICY_WIND:
+ case MOVE_IRON_HEAD:
+ case MOVE_IRON_TAIL:
+ case MOVE_LAVA_PLUME:
+ case MOVE_LIQUIDATION:
+ case MOVE_LOW_SWEEP:
+ case MOVE_METAL_CLAW:
+ case MOVE_MUD_BOMB:
+ case MOVE_MUDDY_WATER:
+ case MOVE_MUD_SHOT:
+ case MOVE_MUD_SLAP:
+ case MOVE_MYSTICAL_FIRE:
+ case MOVE_PLAY_ROUGH:
+ case MOVE_POISON_FANG:
+ case MOVE_POISON_JAB:
+ case MOVE_POISON_STING:
+ case MOVE_POISON_TAIL:
+ case MOVE_POUNCE:
+ case MOVE_POWER_UP_PUNCH:
+ case MOVE_PSYBEAM:
+ case MOVE_PSYCHIC:
+ case MOVE_RAZOR_SHELL:
+ case MOVE_ROCK_CLIMB:
+ case MOVE_ROCK_SLIDE:
+ case MOVE_ROCK_SMASH:
+ case MOVE_ROCK_TOMB:
+ case MOVE_SANDSEAR_STORM:
+ case MOVE_SCALD:
+ case MOVE_SCORCHING_SANDS:
+ case MOVE_SECRET_POWER:
+ case MOVE_SHADOW_BALL:
+ case MOVE_SIGNAL_BEAM:
+ case MOVE_SKY_ATTACK:
+ case MOVE_SLUDGE_BOMB:
+ case MOVE_SLUDGE_WAVE:
+ case MOVE_SNARL:
+ case MOVE_SNORE:
+ case MOVE_STEEL_WING:
+ case MOVE_STOMP:
+ case MOVE_STONE_AXE:
+ case MOVE_STRUGGLE_BUG:
+ case MOVE_THROAT_CHOP:
+ case MOVE_THUNDER:
+ case MOVE_THUNDER_FANG:
+ case MOVE_THUNDERBOLT:
+ case MOVE_THUNDER_PUNCH:
+ case MOVE_TRAILBLAZE:
+ case MOVE_TWISTER:
+ case MOVE_UPPER_HAND:
+ case MOVE_WATER_PULSE:
+ case MOVE_WATERFALL:
+ case MOVE_ZAP_CANNON:
+ case MOVE_ZEN_HEADBUTT:
+ case MOVE_ACID:
+ case MOVE_ACID_SPRAY:
+ case MOVE_ALLURING_VOICE:
+ case MOVE_ANCHOR_SHOT:
+ case MOVE_APPLE_ACID:
+ case MOVE_AQUA_STEP:
+ case MOVE_AURA_WHEEL:
+ case MOVE_AURORA_BEAM:
+ case MOVE_AXE_KICK:
+ case MOVE_BARB_BARRAGE:
+ case MOVE_BITTER_MALICE:
+ case MOVE_BLAZE_KICK:
+ case MOVE_BLAZING_TORQUE:
+ case MOVE_BLEAKWIND_STORM:
+ case MOVE_BLUE_FLARE:
+ case MOVE_BOLT_STRIKE:
+ case MOVE_BONE_CLUB:
+ case MOVE_CEASELESS_EDGE:
+ case MOVE_CHATTER:
+ case MOVE_CLANGOROUS_SOULBLAZE:
+ case MOVE_COMBAT_TORQUE:
+ case MOVE_CONSTRICT:
+ case MOVE_CROSS_POISON:
+ case MOVE_DIAMOND_STORM:
+ case MOVE_DIRE_CLAW:
+ case MOVE_DISCHARGE:
+ case MOVE_DIZZY_PUNCH:
+ case MOVE_DOUBLE_IRON_BASH:
+ case MOVE_DRUM_BEATING:
+ case MOVE_EERIE_SPELL:
+ case MOVE_ELECTROWEB:
+ case MOVE_ENERGY_BALL:
+ case MOVE_FIERY_DANCE:
+ case MOVE_FIERY_WRATH:
+ case MOVE_FREEZING_GLARE:
+ case MOVE_FIRE_LASH:
+ case MOVE_FREEZE_DRY:
+ case MOVE_FREEZE_SHOCK:
+ case MOVE_GENESIS_SUPERNOVA:
+ case MOVE_GLACIATE:
+ case MOVE_GRAV_APPLE:
+ case MOVE_HEART_STAMP:
+ case MOVE_HYPER_FANG:
+ case MOVE_ICE_BURN:
+ case MOVE_INFERNAL_PARADE:
+ case MOVE_INFERNO:
+ case MOVE_LEAF_TORNADO:
+ case MOVE_LICK:
+ case MOVE_LUMINA_CRASH:
+ case MOVE_LUNGE:
+ case MOVE_LUSTER_PURGE:
+ case MOVE_MAGICAL_TORQUE:
+ case MOVE_MALIGNANT_CHAIN:
+ case MOVE_MATCHA_GOTCHA:
+ case MOVE_METEOR_MASH:
+ case MOVE_MIRROR_SHOT:
+ case MOVE_MIST_BALL:
+ case MOVE_MOONBLAST:
+ case MOVE_MORTAL_SPIN:
+ case MOVE_MOUNTAIN_GALE:
+ case MOVE_MYSTICAL_POWER:
+ case MOVE_NEEDLE_ARM:
+ case MOVE_NIGHT_DAZE:
+ case MOVE_NOXIOUS_TORQUE:
+ case MOVE_NUZZLE:
+ case MOVE_OCTAZOOKA:
+ case MOVE_OMINOUS_WIND:
+ case MOVE_ORDER_UP:
+ case MOVE_POWDER_SNOW:
+ case MOVE_PSYSHIELD_BASH:
+ case MOVE_PYRO_BALL:
+ case MOVE_RAPID_SPIN:
+ case MOVE_RELIC_SONG:
+ case MOVE_ROLLING_KICK:
+ case MOVE_SACRED_FIRE:
+ case MOVE_SALT_CURE:
+ case MOVE_SEARING_SHOT:
+ case MOVE_SEED_FLARE:
+ case MOVE_SHADOW_BONE:
+ case MOVE_SHELL_SIDE_ARM:
+ case MOVE_SILVER_WIND:
+ case MOVE_SKITTER_SMACK:
+ case MOVE_SLUDGE:
+ case MOVE_SMOG:
+ case MOVE_SPARK:
+ case MOVE_SPARKLING_ARIA:
+ case MOVE_SPIRIT_BREAK:
+ case MOVE_SPIRIT_SHACKLE:
+ case MOVE_SPLISHY_SPLASH:
+ case MOVE_SPRINGTIDE_STORM:
+ case MOVE_STEAM_ERUPTION:
+ case MOVE_STEAMROLLER:
+ case MOVE_STOKED_SPARKSURFER:
+ case MOVE_STRANGE_STEAM:
+ case MOVE_SYRUP_BOMB:
+ case MOVE_THUNDER_SHOCK:
+ case MOVE_THUNDEROUS_KICK:
+ case MOVE_TORCH_SONG:
+ case MOVE_TRI_ATTACK:
+ case MOVE_TRIPLE_ARROWS:
+ case MOVE_TROP_KICK:
+ case MOVE_TWINEEDLE:
+ case MOVE_VOLT_TACKLE:
+ case MOVE_WICKED_TORQUE:
+ case MOVE_WILDBOLT_STORM:
+ case MOVE_ZING_ZAP:
+ case MOVE_ELECTRO_SHOT:
+ case MOVE_PSYCHIC_NOISE:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// Test split into four parts that handles ~1/4 of all moves each
+DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 1")
+{
+ s16 damage1, damage2;
+ u32 move = 0;
+ for (u32 j = 1; j < MOVES_COUNT; j += 4)
+ if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
+ PARAMETRIZE { move = j; }
+ GIVEN {
+ PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
+ PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ } WHEN {
+ if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
+ TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
+ MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
+ MOVE(playerLeft, move, target: opponentRight);
+ MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
+ TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_DREAM_EATER)
+ {
+ TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SNORE)
+ {
+ TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
+ {
+ TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ switch (GetMoveEffect(move))
+ {
+ case EFFECT_TWO_TURNS_ATTACK:
+ case EFFECT_SEMI_INVULNERABLE:
+ case EFFECT_SOLAR_BEAM:
+ case EFFECT_SKY_DROP:
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { ; }
+ break;
+ case EFFECT_FUTURE_SIGHT:
+ TURN { ; }
+ TURN { ; }
+ break;
+ case EFFECT_BIDE:
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ break;
+ }
+ } SCENE {
+ if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT)
+ {
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ HP_BAR(playerRight, captureDamage: &damage2);
+ }
+ else
+ {
+ HP_BAR(playerRight, captureDamage: &damage2);
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ }
+ } THEN {
+ if (IsMoveSheerForceBoosted(move))
+ EXPECT_GT(damage1, damage2);
+ else
+ EXPECT_EQ(damage2, damage1);
+ }
+}
+DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 2")
+{
+ s16 damage1, damage2;
+ u32 move = 0;
+ for (u32 j = 2; j < MOVES_COUNT; j += 4)
+ if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
+ PARAMETRIZE { move = j; }
+ GIVEN {
+ PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
+ PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ } WHEN {
+ if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
+ TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
+ MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
+ MOVE(playerLeft, move, target: opponentRight);
+ MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
+ TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_DREAM_EATER)
+ {
+ TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SNORE)
+ {
+ TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
+ {
+ TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ switch (GetMoveEffect(move))
+ {
+ case EFFECT_TWO_TURNS_ATTACK:
+ case EFFECT_SEMI_INVULNERABLE:
+ case EFFECT_SOLAR_BEAM:
+ case EFFECT_SKY_DROP:
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { ; }
+ break;
+ case EFFECT_FUTURE_SIGHT:
+ TURN { ; }
+ TURN { ; }
+ break;
+ case EFFECT_BIDE:
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ break;
+ }
+ } SCENE {
+ if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT)
+ {
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ HP_BAR(playerRight, captureDamage: &damage2);
+ }
+ else
+ {
+ HP_BAR(playerRight, captureDamage: &damage2);
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ }
+ } THEN {
+ if (IsMoveSheerForceBoosted(move))
+ EXPECT_GT(damage1, damage2);
+ else
+ EXPECT_EQ(damage2, damage1);
+ }
+}
+DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 3")
+{
+ s16 damage1, damage2;
+ u32 move = 0;
+ for (u32 j = 3; j < MOVES_COUNT; j += 4)
+ if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
+ PARAMETRIZE { move = j; }
+ GIVEN {
+ PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
+ PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ } WHEN {
+ if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
+ TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
+ MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
+ MOVE(playerLeft, move, target: opponentRight);
+ MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
+ TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_DREAM_EATER)
+ {
+ TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SNORE)
+ {
+ TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
+ {
+ TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ switch (GetMoveEffect(move))
+ {
+ case EFFECT_TWO_TURNS_ATTACK:
+ case EFFECT_SEMI_INVULNERABLE:
+ case EFFECT_SOLAR_BEAM:
+ case EFFECT_SKY_DROP:
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { ; }
+ break;
+ case EFFECT_FUTURE_SIGHT:
+ TURN { ; }
+ TURN { ; }
+ break;
+ case EFFECT_BIDE:
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ break;
+ }
+ } SCENE {
+ if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT)
+ {
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ HP_BAR(playerRight, captureDamage: &damage2);
+ }
+ else
+ {
+ HP_BAR(playerRight, captureDamage: &damage2);
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ }
+ } THEN {
+ if (IsMoveSheerForceBoosted(move))
+ EXPECT_GT(damage1, damage2);
+ else
+ EXPECT_EQ(damage2, damage1);
+ }
+}
+DOUBLE_BATTLE_TEST("Sheer Force only boosts the damage of moves it's supposed to boost 4")
+{
+ s16 damage1, damage2;
+ u32 move = 0;
+ for (u32 j = 4; j < MOVES_COUNT; j += 4)
+ {
+ if (GetMoveCategory(j) != DAMAGE_CATEGORY_STATUS && !IgnoreMoveForSheerForceBoost(j))
+ PARAMETRIZE { move = j; }
+ }
+ GIVEN {
+ PLAYER(SPECIES_STEELIX) { Ability(ABILITY_SHEER_FORCE); Item(ITEM_BLUK_BERRY); }
+ PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_STEELIX) { Ability(ABILITY_STURDY); Item(ITEM_BLUK_BERRY); }
+ OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); Level(100); Item(ITEM_BLUK_BERRY); }
+ } WHEN {
+ if (move == MOVE_ALLURING_VOICE || move == MOVE_BURNING_JEALOUSY) // Alluring Voice requires the target to boost stats to have an effect
+ TURN { MOVE(opponentRight, MOVE_AGILITY); MOVE(playerRight, MOVE_AGILITY); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_UPPER_HAND) // Upper Hand requires the target to be using a damaging priority move
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft); MOVE(playerRight, move, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_COUNTER || move == MOVE_UPPER_HAND)
+ TURN { MOVE(opponentRight, MOVE_QUICK_ATTACK, target: playerLeft);
+ MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft);
+ MOVE(playerLeft, move, target: opponentRight);
+ MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_MIRROR_COAT || move == MOVE_METAL_BURST)
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_SUCKER_PUNCH || move == MOVE_THUNDERCLAP)
+ TURN { MOVE(opponentRight, MOVE_TACKLE, target: playerLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ else if (move == MOVE_DREAM_EATER)
+ {
+ TURN { MOVE(playerLeft, MOVE_HYPNOSIS, target: opponentRight); MOVE(opponentLeft, MOVE_HYPNOSIS, target: playerRight); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SNORE)
+ {
+ TURN { MOVE(opponentRight, MOVE_HYPNOSIS, target: playerLeft); MOVE(playerRight, MOVE_HYPNOSIS, target: opponentLeft); MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else if (move == MOVE_SPIT_UP || move == MOVE_LAST_RESORT)
+ {
+ TURN { MOVE(playerLeft, MOVE_STOCKPILE); MOVE(opponentLeft, MOVE_STOCKPILE); }
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ }
+ else
+ TURN { MOVE(playerLeft, move, target: opponentRight); MOVE(opponentLeft, move, target: playerRight); }
+ switch (GetMoveEffect(move))
+ {
+ case EFFECT_TWO_TURNS_ATTACK:
+ case EFFECT_SEMI_INVULNERABLE:
+ case EFFECT_SOLAR_BEAM:
+ case EFFECT_SKY_DROP:
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { ; }
+ break;
+ case EFFECT_FUTURE_SIGHT:
+ TURN { ; }
+ TURN { ; }
+ break;
+ case EFFECT_BIDE:
+ TURN { MOVE(opponentRight, MOVE_WATER_GUN, target: playerLeft); MOVE(playerRight, MOVE_WATER_GUN, target: opponentLeft); SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ TURN { SKIP_TURN(playerLeft); SKIP_TURN(opponentLeft); }
+ break;
+ }
+ } SCENE {
+ if (GetMoveEffect(move) != EFFECT_FUTURE_SIGHT)
+ {
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ HP_BAR(playerRight, captureDamage: &damage2);
+ }
+ else
+ {
+ HP_BAR(playerRight, captureDamage: &damage2);
+ HP_BAR(opponentRight, captureDamage: &damage1);
+ }
+ } THEN {
+ if (IsMoveSheerForceBoosted(move))
+ EXPECT_GT(damage1, damage2);
+ else
+ EXPECT_EQ(damage2, damage1);
}
}
diff --git a/test/battle/ability/shield_dust.c b/test/battle/ability/shield_dust.c
index 9374a5f018..5833615027 100644
--- a/test/battle/ability/shield_dust.c
+++ b/test/battle/ability/shield_dust.c
@@ -124,7 +124,6 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o
DOUBLE_BATTLE_TEST("Shield Dust does or does not block Sparkling Aria depending on number of targets hit")
{
u32 moveToUse;
- KNOWN_FAILING;
PARAMETRIZE { moveToUse = MOVE_FINAL_GAMBIT; }
PARAMETRIZE { moveToUse = MOVE_TACKLE; }
GIVEN {
@@ -148,9 +147,23 @@ DOUBLE_BATTLE_TEST("Shield Dust does or does not block Sparkling Aria depending
}
}
+DOUBLE_BATTLE_TEST("Shield Dust blocks Sparkling Aria if all other targets avoid getting hit by")
+{
+ KNOWN_FAILING; // #4636
+ GIVEN {
+ PLAYER(SPECIES_PRIMARINA);
+ PLAYER(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); Status1(STATUS1_BURN); }
+ OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); }
+ OPPONENT(SPECIES_WYNAUT) { Status1(STATUS1_BURN); }
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_FLY, target:playerLeft); MOVE(opponentRight, MOVE_PROTECT); MOVE(playerRight, MOVE_CELEBRATE); MOVE(playerLeft, MOVE_SPARKLING_ARIA); }
+ } SCENE {
+ NOT MESSAGE("Vivillon's burn was cured!");
+ }
+}
+
SINGLE_BATTLE_TEST("Shield Dust blocks Sparkling Aria in singles")
{
- KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_VIVILLON) { Ability(ABILITY_SHIELD_DUST); Status1(STATUS1_BURN); }
diff --git a/test/battle/ability/snow_cloak.c b/test/battle/ability/snow_cloak.c
index a4d1acadb7..4e129c3ff7 100644
--- a/test/battle/ability/snow_cloak.c
+++ b/test/battle/ability/snow_cloak.c
@@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Snow Cloak increases evasion during hail")
{
PASSES_RANDOMLY(4, 5, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_POUND].accuracy == 100);
+ ASSUME(GetMoveAccuracy(MOVE_POUND) == 100);
PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/stalwart.c b/test/battle/ability/stalwart.c
index 6f8acd6d82..22debe74cd 100644
--- a/test/battle/ability/stalwart.c
+++ b/test/battle/ability/stalwart.c
@@ -24,8 +24,8 @@ DOUBLE_BATTLE_TEST("Stalwart stops Lightning Rod and Storm Drain from redirectin
PARAMETRIZE { ability = ABILITY_STORM_DRAIN; species = SPECIES_LUMINEON; }
PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STALWART); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
diff --git a/test/battle/ability/stamina.c b/test/battle/ability/stamina.c
index 527026284c..172154cc85 100644
--- a/test/battle/ability/stamina.c
+++ b/test/battle/ability/stamina.c
@@ -24,10 +24,10 @@ SINGLE_BATTLE_TEST("Stamina raises Defense by 1 when hit by a move")
PARAMETRIZE {move = MOVE_GUST; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
- ASSUME(gMovesInfo[MOVE_GUST].power != 0);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
+ ASSUME(!IsBattleMoveStatus(MOVE_GUST));
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STAMINA); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -56,7 +56,7 @@ DOUBLE_BATTLE_TEST("Stamina activates correctly for every battler with the abili
PARAMETRIZE {abilityLeft = ABILITY_STAMINA, abilityRight = ABILITY_STAMINA; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WOBBUFFET) { Ability(abilityLeft); Speed(10); }
PLAYER(SPECIES_WOBBUFFET) { Ability(abilityRight); Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) {Speed(20); }
@@ -67,18 +67,19 @@ DOUBLE_BATTLE_TEST("Stamina activates correctly for every battler with the abili
ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, opponentLeft);
HP_BAR(playerLeft);
+ HP_BAR(playerRight);
+ NOT HP_BAR(opponentLeft); // We need to check the attacker itself does NOT get damaged. There was an issue when the targets would get overwritten by the Stamina's stat raise.
+ HP_BAR(opponentRight);
+
if (abilityLeft == ABILITY_STAMINA) {
STAMINA_STAT_RAISE(playerLeft, "Wobbuffet's Defense rose!");
}
- NOT HP_BAR(opponentLeft); // We need to check the attacker itself does NOT get damaged. There was an issue when the targets would get overwritten by the Stamina's stat raise.
- HP_BAR(playerRight);
if (abilityRight == ABILITY_STAMINA) {
STAMINA_STAT_RAISE(playerRight, "Wobbuffet's Defense rose!");
}
- NOT HP_BAR(opponentLeft); // We need to check the attacker itself does NOT get damaged. There was an issue when the targets would get overwritten by the Stamina's stat raise.
- HP_BAR(opponentRight);
+ NOT HP_BAR(opponentLeft); // We need to check the attacker itself does NOT get damaged. There was an issue when the targets would get overwritten by the Stamina's stat raise.
}
THEN {
EXPECT_NE(playerLeft->hp, playerLeft->maxHP);
diff --git a/test/battle/ability/stance_change.c b/test/battle/ability/stance_change.c
new file mode 100644
index 0000000000..d6e08909f9
--- /dev/null
+++ b/test/battle/ability/stance_change.c
@@ -0,0 +1,83 @@
+#include "global.h"
+#include "test/battle.h"
+
+
+SINGLE_BATTLE_TEST("Stance Change changes Aegislash from Shield to Blade when using a damaging move")
+{
+ u16 move;
+ PARAMETRIZE { move = MOVE_TACKLE; }
+ PARAMETRIZE { move = MOVE_SWIFT; }
+ PARAMETRIZE { move = MOVE_GROWL; }
+ GIVEN {
+ PLAYER(SPECIES_AEGISLASH_SHIELD);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ if (move != MOVE_GROWL) {
+ ABILITY_POPUP(player, ABILITY_STANCE_CHANGE);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ } else {
+ NONE_OF {
+ ABILITY_POPUP(player, ABILITY_STANCE_CHANGE);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ }
+ }
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ } THEN {
+ if (move != MOVE_GROWL)
+ EXPECT_EQ(player->species, SPECIES_AEGISLASH_BLADE);
+ else
+ EXPECT_EQ(player->species, SPECIES_AEGISLASH_SHIELD);
+ }
+}
+
+SINGLE_BATTLE_TEST("Stance Change changes Aegislash from Blade to Shield when using King's Shield")
+{
+ u16 move;
+ PARAMETRIZE { move = MOVE_PROTECT; }
+ PARAMETRIZE { move = MOVE_KINGS_SHIELD; }
+ GIVEN {
+ PLAYER(SPECIES_AEGISLASH_BLADE);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ if (move == MOVE_KINGS_SHIELD) {
+ ABILITY_POPUP(player, ABILITY_STANCE_CHANGE);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ } else {
+ NONE_OF {
+ ABILITY_POPUP(player, ABILITY_STANCE_CHANGE);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ }
+ }
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ } THEN {
+ if (move == MOVE_KINGS_SHIELD)
+ EXPECT_EQ(player->species, SPECIES_AEGISLASH_SHIELD);
+ else
+ EXPECT_EQ(player->species, SPECIES_AEGISLASH_BLADE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Stance Change doesn't change Aegislash to Shield if King's Shield is called by a different move - Sleep Talk")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ PLAYER(SPECIES_AEGISLASH_BLADE) { Moves(MOVE_KINGS_SHIELD, MOVE_SLEEP_TALK); Status1(STATUS1_SLEEP_TURN(3)); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SLEEP_TALK); }
+ } SCENE {
+ NONE_OF {
+ ABILITY_POPUP(player, ABILITY_STANCE_CHANGE);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
+ }
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_KINGS_SHIELD, player);
+ } THEN {
+ EXPECT_EQ(player->species, SPECIES_AEGISLASH_BLADE);
+ }
+}
+
+TO_DO_BATTLE_TEST("Stance Change doesn't change Aegislash to Shield if King's Shield is called by a different move - Me First");
diff --git a/test/battle/ability/static.c b/test/battle/ability/static.c
index 3c5d042cd0..8d5a27c6b5 100644
--- a/test/battle/ability/static.c
+++ b/test/battle/ability/static.c
@@ -7,14 +7,14 @@ SINGLE_BATTLE_TEST("Static inflicts paralysis on contact")
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_SWIFT].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_SWIFT));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
- if (gMovesInfo[move].makesContact) {
+ if (MoveMakesContact(move)) {
ABILITY_POPUP(opponent, ABILITY_STATIC);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player);
MESSAGE("The opposing Pikachu's Static paralyzed Wobbuffet, so it may be unable to move!");
@@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Static triggers 30% of the time")
PASSES_RANDOMLY(3, 10, RNG_STATIC);
GIVEN {
ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_4);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_STATIC); }
} WHEN {
diff --git a/test/battle/ability/steelworker.c b/test/battle/ability/steelworker.c
index 7e8ecbb568..23d4be2917 100644
--- a/test/battle/ability/steelworker.c
+++ b/test/battle/ability/steelworker.c
@@ -14,11 +14,11 @@ SINGLE_BATTLE_TEST("Steelworker increases Steel-type move damage", s16 damage)
PARAMETRIZE { move = MOVE_FLASH_CANNON; ability = ABILITY_STEELWORKER; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_STEEL);
- ASSUME(gMovesInfo[MOVE_ANCHOR_SHOT].type == TYPE_STEEL);
- ASSUME(gMovesInfo[MOVE_FLASH_CANNON].type == TYPE_STEEL);
- ASSUME(gMovesInfo[MOVE_ANCHOR_SHOT].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_FLASH_CANNON].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_STEEL);
+ ASSUME(GetMoveType(MOVE_ANCHOR_SHOT) == TYPE_STEEL);
+ ASSUME(GetMoveType(MOVE_FLASH_CANNON) == TYPE_STEEL);
+ ASSUME(GetMoveCategory(MOVE_ANCHOR_SHOT) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_FLASH_CANNON) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_DHELMISE) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/stench.c b/test/battle/ability/stench.c
index 76b36f3ff3..f1484de6c9 100644
--- a/test/battle/ability/stench.c
+++ b/test/battle/ability/stench.c
@@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Stench has a 10% chance to flinch")
{
PASSES_RANDOMLY(1, 10, RNG_STENCH);
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_STENCH); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -20,7 +20,7 @@ SINGLE_BATTLE_TEST("Stench does not stack with King's Rock")
PASSES_RANDOMLY(1, 10, RNG_STENCH);
GIVEN {
ASSUME(gItemsInfo[ITEM_KINGS_ROCK].holdEffect == HOLD_EFFECT_FLINCH);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
PLAYER(SPECIES_GRIMER) { Ability(ABILITY_STENCH); Item(ITEM_KINGS_ROCK); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Stench does not stack with King's Rock")
DOUBLE_BATTLE_TEST("Stench only triggers if target takes damage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
@@ -58,7 +58,7 @@ DOUBLE_BATTLE_TEST("Stench only triggers if target takes damage")
DOUBLE_BATTLE_TEST("Stench doesn't trigger if partner uses a move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
ASSUME(MoveHasAdditionalEffectWithChance(MOVE_FAKE_OUT, MOVE_EFFECT_FLINCH, 100));
PLAYER(SPECIES_WOBBUFFET) { Speed(20); }
PLAYER(SPECIES_WYNAUT) { Speed(10); }
diff --git a/test/battle/ability/storm_drain.c b/test/battle/ability/storm_drain.c
index b4d5a2c169..962317b108 100644
--- a/test/battle/ability/storm_drain.c
+++ b/test/battle/ability/storm_drain.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. Attack [Gen5+]")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GASTRODON_EAST) { Ability(ABILITY_STORM_DRAIN); }
} WHEN {
@@ -34,7 +34,7 @@ SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. A
DOUBLE_BATTLE_TEST("Storm Drain forces single-target Water-type moves to target the Pokémon with this Ability.")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GASTRODON_EAST) { Ability(ABILITY_STORM_DRAIN); }
diff --git a/test/battle/ability/sturdy.c b/test/battle/ability/sturdy.c
index b79fd5e921..5ba7e16ea8 100644
--- a/test/battle/ability/sturdy.c
+++ b/test/battle/ability/sturdy.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Sturdy prevents OHKO moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO);
+ ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO);
PLAYER(SPECIES_GEODUDE) { Ability(ABILITY_STURDY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/supreme_overlord.c b/test/battle/ability/supreme_overlord.c
index f8868b4afb..eec81e89ed 100644
--- a/test/battle/ability/supreme_overlord.c
+++ b/test/battle/ability/supreme_overlord.c
@@ -95,7 +95,7 @@ SINGLE_BATTLE_TEST("Supreme Overlord does not boost attack if party members are
SINGLE_BATTLE_TEST("Supreme Overlord's message displays correctly after all battlers fainted - Player")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) { HP(1);}
PLAYER(SPECIES_KINGAMBIT) { Ability(ABILITY_SUPREME_OVERLORD); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -116,7 +116,7 @@ SINGLE_BATTLE_TEST("Supreme Overlord's message displays correctly after all batt
SINGLE_BATTLE_TEST("Supreme Overlord's message displays correctly after all battlers fainted - Opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { HP(1);}
diff --git a/test/battle/ability/swarm.c b/test/battle/ability/swarm.c
index c3da16f6b6..a70c1ffb55 100644
--- a/test/battle/ability/swarm.c
+++ b/test/battle/ability/swarm.c
@@ -7,9 +7,9 @@ SINGLE_BATTLE_TEST("Swarm boosts Bug-type moves in a pinch", s16 damage)
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUG_BITE].type == TYPE_BUG);
- ASSUME(gMovesInfo[MOVE_BUG_BITE].power == 60);
- ASSUME(gMovesInfo[MOVE_BUG_BITE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveType(MOVE_BUG_BITE) == TYPE_BUG);
+ ASSUME(GetMovePower(MOVE_BUG_BITE) == 60);
+ ASSUME(GetMoveCategory(MOVE_BUG_BITE) == DAMAGE_CATEGORY_PHYSICAL);
ASSUME(gSpeciesInfo[SPECIES_LEDYBA].types[0] == TYPE_BUG);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC);
diff --git a/test/battle/ability/sword_of_ruin.c b/test/battle/ability/sword_of_ruin.c
index 3498522423..9501322ab7 100644
--- a/test/battle/ability/sword_of_ruin.c
+++ b/test/battle/ability/sword_of_ruin.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY);
}
SINGLE_BATTLE_TEST("Sword of Ruin reduces Defense if opposing mon's ability doesn't match")
@@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Sword of Ruin reduces Defense if opposing mon's ability does
SINGLE_BATTLE_TEST("Sword of Ruin's message displays correctly after all battlers fainted - Player")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) { HP(1);}
PLAYER(SPECIES_CHIEN_PAO);
OPPONENT(SPECIES_WOBBUFFET);
@@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Sword of Ruin's message displays correctly after all battler
SINGLE_BATTLE_TEST("Sword of Ruin's message displays correctly after all battlers fainted - Opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { HP(1);}
diff --git a/test/battle/ability/tablets_of_ruin.c b/test/battle/ability/tablets_of_ruin.c
index c98384b805..976f929bbe 100644
--- a/test/battle/ability/tablets_of_ruin.c
+++ b/test/battle/ability/tablets_of_ruin.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT);
}
SINGLE_BATTLE_TEST("Tablets of Ruin reduces Attack if opposing mon's ability doesn't match")
@@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Tablets of Ruin reduces Attack if opposing mon's ability doe
SINGLE_BATTLE_TEST("Tablets of Ruin's message displays correctly after all battlers fainted - Player")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) { HP(1);}
PLAYER(SPECIES_WO_CHIEN);
OPPONENT(SPECIES_WOBBUFFET);
@@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Tablets of Ruin's message displays correctly after all battl
SINGLE_BATTLE_TEST("Tablets of Ruin's message displays correctly after all battlers fainted - Opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { HP(1);}
diff --git a/test/battle/ability/tangling_hair.c b/test/battle/ability/tangling_hair.c
index f663465163..45f6282fb8 100644
--- a/test/battle/ability/tangling_hair.c
+++ b/test/battle/ability/tangling_hair.c
@@ -3,9 +3,9 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].effect == EFFECT_HIT);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE);
+ ASSUME(GetMoveEffect(MOVE_TACKLE) == EFFECT_HIT);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
+ ASSUME(MoveMakesContact(MOVE_TACKLE) == TRUE);
}
@@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Tangling Hair drops opposing mon's speed if ability user got
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].makesContact == FALSE);
+ ASSUME(MoveMakesContact(MOVE_SWIFT) == FALSE);
PLAYER(SPECIES_DUGTRIO) { Ability(ABILITY_TANGLING_HAIR); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {
diff --git a/test/battle/ability/tera_shell.c b/test/battle/ability/tera_shell.c
index 08a9ad1cd8..ef2993a0e7 100644
--- a/test/battle/ability/tera_shell.c
+++ b/test/battle/ability/tera_shell.c
@@ -92,8 +92,8 @@ DOUBLE_BATTLE_TEST("Tera Shell only makes the first hit against Terapagos from a
MESSAGE("Terapagos made its shell gleam! It's distorting type matchups!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_BLIZZARD, opponentLeft);
HP_BAR(playerLeft);
- MESSAGE("It's not very effective…");
HP_BAR(playerRight);
+ MESSAGE("It's not very effective…");
NOT MESSAGE("It's not very effective…");
}
}
diff --git a/test/battle/ability/teraform_zero.c b/test/battle/ability/teraform_zero.c
index 819d0eef3d..09ce921931 100644
--- a/test/battle/ability/teraform_zero.c
+++ b/test/battle/ability/teraform_zero.c
@@ -39,8 +39,8 @@ DOUBLE_BATTLE_TEST("Teraform Zero can be supressed")
SINGLE_BATTLE_TEST("Teraform Zero can be replaced")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED);
- ASSUME(gMovesInfo[MOVE_REST].effect == EFFECT_REST);
+ ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
PLAYER(SPECIES_TERAPAGOS);
OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_PRANKSTER); }
} WHEN {
@@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Teraform Zero can be replaced")
SINGLE_BATTLE_TEST("Teraform Zero cannot be swapped")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
+ ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
PLAYER(SPECIES_TERAPAGOS);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -71,7 +71,7 @@ SINGLE_BATTLE_TEST("Teraform Zero cannot be swapped")
SINGLE_BATTLE_TEST("Teraform Zero cannot be copied")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY);
+ ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY);
PLAYER(SPECIES_TERAPAGOS);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/torrent.c b/test/battle/ability/torrent.c
index df27d8e996..f0da964b93 100644
--- a/test/battle/ability/torrent.c
+++ b/test/battle/ability/torrent.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Torrent boosts Water-type moves in a pinch", s16 damage)
PARAMETRIZE { hp = 99; }
PARAMETRIZE { hp = 33; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_SQUIRTLE) { Ability(ABILITY_TORRENT); MaxHP(99); HP(hp); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/toxic_chain.c b/test/battle/ability/toxic_chain.c
index 0037cb85b6..97c3fdf4f9 100644
--- a/test/battle/ability/toxic_chain.c
+++ b/test/battle/ability/toxic_chain.c
@@ -5,8 +5,8 @@ SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison when attacking")
{
PASSES_RANDOMLY(3, 10, RNG_TOXIC_CHAIN);
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -24,9 +24,9 @@ SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison when attacking")
SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison on any hit of a multi-hit move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].effect == EFFECT_MULTI_HIT);
- ASSUME(gMovesInfo[MOVE_DOUBLE_SLAP].power > 0);
+ ASSUME(GetMoveCategory(MOVE_DOUBLE_SLAP) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SLAP) == EFFECT_MULTI_HIT);
+ ASSUME(GetMovePower(MOVE_DOUBLE_SLAP) > 0);
ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN);
PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_PECHA_BERRY); }
@@ -51,9 +51,9 @@ SINGLE_BATTLE_TEST("Toxic Chain inflicts bad poison on any hit of a multi-hit mo
DOUBLE_BATTLE_TEST("Toxic Chain can inflict bad poison on both foes")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].target == MOVE_TARGET_BOTH);
- ASSUME(gMovesInfo[MOVE_RAZOR_LEAF].power > 0);
+ ASSUME(GetMoveCategory(MOVE_RAZOR_LEAF) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveTarget(MOVE_RAZOR_LEAF) == MOVE_TARGET_BOTH);
+ ASSUME(GetMovePower(MOVE_RAZOR_LEAF) > 0);
PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -62,11 +62,11 @@ DOUBLE_BATTLE_TEST("Toxic Chain can inflict bad poison on both foes")
TURN { MOVE(playerLeft, MOVE_RAZOR_LEAF, WITH_RNG(RNG_TOXIC_CHAIN, TRUE)); }
} SCENE {
HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
ABILITY_POPUP(playerLeft, ABILITY_TOXIC_CHAIN);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponentLeft);
MESSAGE("The opposing Wobbuffet was badly poisoned!");
STATUS_ICON(opponentLeft, badPoison: TRUE);
- HP_BAR(opponentRight);
ABILITY_POPUP(playerLeft, ABILITY_TOXIC_CHAIN);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponentRight);
MESSAGE("The opposing Wynaut was badly poisoned!");
@@ -85,9 +85,9 @@ SINGLE_BATTLE_TEST("Toxic Chain makes Lum/Pecha Berry trigger before being knock
PARAMETRIZE { item = ITEM_LUM_BERRY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_KNOCK_OFF].category != DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
- ASSUME(gMovesInfo[MOVE_KNOCK_OFF].power > 0);
+ ASSUME(GetMoveCategory(MOVE_KNOCK_OFF) != DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF);
+ ASSUME(GetMovePower(MOVE_KNOCK_OFF) > 0);
ASSUME(gItemsInfo[ITEM_PECHA_BERRY].holdEffect == HOLD_EFFECT_CURE_PSN);
ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS);
PLAYER(SPECIES_OKIDOGI) { Ability(ABILITY_TOXIC_CHAIN); }
diff --git a/test/battle/ability/toxic_debris.c b/test/battle/ability/toxic_debris.c
index c4a50a5d13..b3b9dbbb2e 100644
--- a/test/battle/ability/toxic_debris.c
+++ b/test/battle/ability/toxic_debris.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
}
SINGLE_BATTLE_TEST("Toxic Debris sets Toxic Spikes on the opposing side if hit by a physical attack")
diff --git a/test/battle/ability/transistor.c b/test/battle/ability/transistor.c
index f02743ab8c..eb3c015af7 100644
--- a/test/battle/ability/transistor.c
+++ b/test/battle/ability/transistor.c
@@ -4,7 +4,7 @@
#include "global.h"
#include "test/battle.h"
-SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage)
+SINGLE_BATTLE_TEST("Transistor increases Electric-type attack / special attack", s16 damage)
{
u32 move;
u16 ability;
@@ -17,11 +17,11 @@ SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage)
PARAMETRIZE { move = MOVE_THUNDER_SHOCK; ability = ABILITY_TRANSISTOR; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_WILD_CHARGE].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_WILD_CHARGE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_WILD_CHARGE) == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
+ ASSUME(GetMoveCategory(MOVE_WILD_CHARGE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_THUNDER_SHOCK) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_REGIELEKI) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -30,27 +30,20 @@ SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage)
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_EQ(results[0].damage, results[1].damage); // Tackle should be unaffected
- if (B_TRANSISTOR_BOOST >= GEN_9)
- {
- EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.3), results[3].damage); // Wild Charge should be affected
- EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.3), results[5].damage); // Thunder Shock should be affected
- }
- else
- {
- EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Wild Charge should be affected
- EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Thunder Shock should be affected
- }
+
+ EXPECT_LT(results[2].damage, results[3].damage); // cannot test exact factor because ATK / SPATK introduces inaccuracies
+ EXPECT_LT(results[4].damage, results[5].damage);
}
}
-SINGLE_BATTLE_TEST("Transistor boosts Electric type moves by 1.5 in Gen8 and 1.3 in Gen9+", s16 damage)
+SINGLE_BATTLE_TEST("Transistor is blocked by neutralizing gas", s16 damage)
{
u16 ability;
PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; }
PARAMETRIZE { ability = ABILITY_LEVITATE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
PLAYER(SPECIES_REGIELEKI) { Ability(ABILITY_TRANSISTOR); }
OPPONENT(SPECIES_KOFFING) { Ability(ability); }
} WHEN {
@@ -58,9 +51,6 @@ SINGLE_BATTLE_TEST("Transistor boosts Electric type moves by 1.5 in Gen8 and 1.3
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
- if (B_TRANSISTOR_BOOST >= GEN_9)
- EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.3), results[1].damage);
- else
- EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
+ EXPECT_LT(results[0].damage, results[1].damage); // cannot test exact factor because ATK / SPATK introduces inaccuracies
}
}
diff --git a/test/battle/ability/vessel_of_ruin.c b/test/battle/ability/vessel_of_ruin.c
index 6531cbbf3a..4d159c0b0e 100644
--- a/test/battle/ability/vessel_of_ruin.c
+++ b/test/battle/ability/vessel_of_ruin.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
+ ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT);
}
SINGLE_BATTLE_TEST("Vessel of Ruin reduces Sp. Atk if opposing mon's ability doesn't match")
@@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Vessel of Ruin reduces Sp. Atk if opposing mon's ability doe
SINGLE_BATTLE_TEST("Vessel of Ruin's message displays correctly after all battlers fainted - Player")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) { HP(1);}
PLAYER(SPECIES_TING_LU);
OPPONENT(SPECIES_WOBBUFFET);
@@ -55,7 +55,7 @@ SINGLE_BATTLE_TEST("Vessel of Ruin's message displays correctly after all battle
SINGLE_BATTLE_TEST("Vessel of Ruin's message displays correctly after all battlers fainted - Opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { HP(1);}
diff --git a/test/battle/ability/volt_absorb.c b/test/battle/ability/volt_absorb.c
index 93498bd1c7..5d88cb95e4 100644
--- a/test/battle/ability/volt_absorb.c
+++ b/test/battle/ability/volt_absorb.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Volt Absorb heals 25% when hit by electric type moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Volt Absorb heals 25% when hit by electric type moves")
SINGLE_BATTLE_TEST("Volt Absorb does not activate if protected")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Volt Absorb does not activate if protected")
SINGLE_BATTLE_TEST("Volt Absorb activates on status moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_THUNDER_WAVE].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveType(MOVE_THUNDER_WAVE) == TYPE_ELECTRIC);
+ ASSUME(GetMoveCategory(MOVE_THUNDER_WAVE) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -48,8 +48,8 @@ SINGLE_BATTLE_TEST("Volt Absorb activates on status moves")
SINGLE_BATTLE_TEST("Volt Absorb is only triggered once on multi strike moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FURY_SWIPES].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_FURY_SWIPES].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveType(MOVE_FURY_SWIPES) == TYPE_NORMAL);
+ ASSUME(GetMoveEffect(MOVE_FURY_SWIPES) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_GRAVELER_ALOLA) { Ability(ABILITY_GALVANIZE); }
} WHEN {
@@ -65,8 +65,8 @@ DOUBLE_BATTLE_TEST("Volt Absorb does not stop Electric Typed Explosion from dama
{
s16 damage1, damage2;
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
- ASSUME(gMovesInfo[MOVE_EXPLOSION].type == TYPE_NORMAL);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
+ ASSUME(GetMoveType(MOVE_EXPLOSION) == TYPE_NORMAL);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); }
PLAYER(SPECIES_ABRA);
OPPONENT(SPECIES_GRAVELER_ALOLA) { Ability(ABILITY_GALVANIZE); }
@@ -88,7 +88,7 @@ DOUBLE_BATTLE_TEST("Volt Absorb does not stop Electric Typed Explosion from dama
SINGLE_BATTLE_TEST("Volt Absorb prevents Cell Battery from activating")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(100); Item(ITEM_CELL_BATTERY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/water_absorb.c b/test/battle/ability/water_absorb.c
index 842a448bab..1c0406ebdc 100644
--- a/test/battle/ability/water_absorb.c
+++ b/test/battle/ability/water_absorb.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Water Absorb heals 25% when hit by water type moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -19,7 +19,7 @@ SINGLE_BATTLE_TEST("Water Absorb heals 25% when hit by water type moves")
SINGLE_BATTLE_TEST("Water Absorb does not activate if protected")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -32,8 +32,8 @@ SINGLE_BATTLE_TEST("Water Absorb does not activate if protected")
SINGLE_BATTLE_TEST("Water Absorb activates on status moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SOAK].type == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_SOAK].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveType(MOVE_SOAK) == TYPE_WATER);
+ ASSUME(GetMoveCategory(MOVE_SOAK) == DAMAGE_CATEGORY_STATUS);
PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -48,8 +48,8 @@ SINGLE_BATTLE_TEST("Water Absorb activates on status moves")
SINGLE_BATTLE_TEST("Water Absorb is only triggered once on multi strike moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].type == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_WATER_SHURIKEN].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveType(MOVE_WATER_SHURIKEN) == TYPE_WATER);
+ ASSUME(GetMoveEffect(MOVE_WATER_SHURIKEN) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Water Absorb prevents Absorb Bulb and Luminous Moss from act
PARAMETRIZE { item = ITEM_ABSORB_BULB; }
PARAMETRIZE { item = ITEM_LUMINOUS_MOSS; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUBBLE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_BUBBLE) == TYPE_WATER);
PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(100); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/ability/weak_armor.c b/test/battle/ability/weak_armor.c
index 7fd7e10ef7..12e9ef3bcc 100644
--- a/test/battle/ability/weak_armor.c
+++ b/test/battle/ability/weak_armor.c
@@ -3,10 +3,10 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
- ASSUME(gMovesInfo[MOVE_GUST].power != 0);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
+ ASSUME(!IsBattleMoveStatus(MOVE_GUST));
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
ASSUME(B_WEAK_ARMOR_SPEED >= GEN_7);
}
@@ -50,8 +50,8 @@ SINGLE_BATTLE_TEST("Weak Armor lowers Defense by 1 and boosts Speed by 2 when hi
SINGLE_BATTLE_TEST("Weak Armor does not trigger when brought in by Dragon Tail and taking Stealth Rock damage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK);
- ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
+ ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/ability/wind_power.c b/test/battle/ability/wind_power.c
index 6ccf896eaa..fd4a4b95f5 100644
--- a/test/battle/ability/wind_power.c
+++ b/test/battle/ability/wind_power.c
@@ -3,16 +3,16 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].power != 0);
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
- ASSUME(gMovesInfo[MOVE_AIR_CUTTER].power != 0);
- ASSUME(gMovesInfo[MOVE_AIR_CUTTER].target == MOVE_TARGET_BOTH);
- ASSUME(gMovesInfo[MOVE_AIR_CUTTER].windMove == TRUE);
- ASSUME(gMovesInfo[MOVE_PETAL_BLIZZARD].power != 0);
- ASSUME(gMovesInfo[MOVE_PETAL_BLIZZARD].target == MOVE_TARGET_FOES_AND_ALLY);
- ASSUME(gMovesInfo[MOVE_PETAL_BLIZZARD].windMove == TRUE);
- ASSUME(gMovesInfo[MOVE_TACKLE].windMove == FALSE);
+ ASSUME(!IsBattleMoveStatus(MOVE_THUNDERBOLT));
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
+ ASSUME(!IsBattleMoveStatus(MOVE_AIR_CUTTER));
+ ASSUME(GetMoveTarget(MOVE_AIR_CUTTER) == MOVE_TARGET_BOTH);
+ ASSUME(IsWindMove(MOVE_AIR_CUTTER));
+ ASSUME(!IsBattleMoveStatus(MOVE_PETAL_BLIZZARD));
+ ASSUME(GetMoveTarget(MOVE_PETAL_BLIZZARD) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(IsWindMove(MOVE_PETAL_BLIZZARD));
+ ASSUME(!IsWindMove(MOVE_TACKLE));
}
SINGLE_BATTLE_TEST("Wind Power sets up Charge for player when hit by a wind move")
@@ -165,17 +165,17 @@ DOUBLE_BATTLE_TEST("Wind Power activates correctly for every battler with the ab
ANIMATION(ANIM_TYPE_MOVE, MOVE_PETAL_BLIZZARD, opponentLeft);
HP_BAR(playerLeft);
+ HP_BAR(playerRight);
+ HP_BAR(opponentRight);
+ NOT HP_BAR(opponentLeft);
if (abilityLeft == ABILITY_WIND_POWER) {
ABILITY_POPUP(playerLeft, ABILITY_WIND_POWER);
MESSAGE("Being hit by Petal Blizzard charged Wattrel with power!");
}
- HP_BAR(playerRight);
if (abilityRight == ABILITY_WIND_POWER) {
ABILITY_POPUP(playerRight, ABILITY_WIND_POWER);
MESSAGE("Being hit by Petal Blizzard charged Wattrel with power!");
}
- HP_BAR(opponentRight);
- NOT HP_BAR(opponentLeft);
}
THEN {
EXPECT_NE(playerLeft->hp, playerLeft->maxHP);
@@ -193,7 +193,7 @@ DOUBLE_BATTLE_TEST("Wind Power activates correctly when Tailwind is used")
PARAMETRIZE {opponentSide = FALSE;}
GIVEN {
- ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
+ ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND);
PLAYER(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(10); }
PLAYER(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(5); }
OPPONENT(SPECIES_WATTREL) { Ability(ABILITY_WIND_POWER); Speed(20); }
diff --git a/test/battle/ability/wind_rider.c b/test/battle/ability/wind_rider.c
index 44baacc8a2..d68414d060 100644
--- a/test/battle/ability/wind_rider.c
+++ b/test/battle/ability/wind_rider.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
- ASSUME(gMovesInfo[MOVE_TAILWIND].windMove == TRUE);
+ ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND);
+ ASSUME(IsWindMove(MOVE_TAILWIND));
}
SINGLE_BATTLE_TEST("Wind Rider raises Attack by one stage if it sets up Tailwind")
@@ -108,7 +108,7 @@ SINGLE_BATTLE_TEST("Wind Rider activates when it's no longer effected by Neutral
SINGLE_BATTLE_TEST("Wind Rider absorbs Wind moves and raises Attack by one stage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_GUST].windMove == TRUE);
+ ASSUME(IsWindMove(MOVE_GUST));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); }
} WHEN {
diff --git a/test/battle/ability/zero_to_hero.c b/test/battle/ability/zero_to_hero.c
index 733104f153..195bb44289 100644
--- a/test/battle/ability/zero_to_hero.c
+++ b/test/battle/ability/zero_to_hero.c
@@ -60,7 +60,7 @@ SINGLE_BATTLE_TEST("Zero to Hero transforms both player and opponent")
SINGLE_BATTLE_TEST("Zero to Hero will activate if a switch move is used")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLIP_TURN].effect == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_FLIP_TURN) == EFFECT_HIT_ESCAPE);
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -83,9 +83,9 @@ SINGLE_BATTLE_TEST("Gastro Acid, Worry Seed, and Simple Beam fail if the target
PARAMETRIZE { move = MOVE_SIMPLE_BEAM; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID);
- ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED);
- ASSUME(gMovesInfo[MOVE_SIMPLE_BEAM].effect == EFFECT_SIMPLE_BEAM);
+ ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID);
+ ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
+ ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_SIMPLE_BEAM);
PLAYER(SPECIES_PALAFIN_ZERO) { Ability(ABILITY_ZERO_TO_HERO); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -139,7 +139,7 @@ SINGLE_BATTLE_TEST("Imposter doesn't apply the heroic transformation message whe
SINGLE_BATTLE_TEST("Zero to Hero's message displays correctly after all battlers fainted - Player")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_PALAFIN_ZERO);
PLAYER(SPECIES_WOBBUFFET) { HP(1);}
OPPONENT(SPECIES_WOBBUFFET);
@@ -162,7 +162,7 @@ SINGLE_BATTLE_TEST("Zero to Hero's message displays correctly after all battlers
SINGLE_BATTLE_TEST("Zero to Hero's message displays correctly after all battlers fainted - Opponent")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PALAFIN_ZERO);
diff --git a/test/battle/ai/ai.c b/test/battle/ai/ai.c
index 71c960fcc5..e9b5a2e51c 100644
--- a/test/battle/ai/ai.c
+++ b/test/battle/ai/ai.c
@@ -80,25 +80,25 @@ AI_SINGLE_BATTLE_TEST("AI prefers moves with better accuracy, but only if they b
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(hp); }
PLAYER(SPECIES_WOBBUFFET);
- ASSUME(gMovesInfo[MOVE_SWIFT].accuracy == 0);
- ASSUME(gMovesInfo[MOVE_SLAM].power == gMovesInfo[MOVE_STRENGTH].power);
- ASSUME(gMovesInfo[MOVE_MEGA_KICK].power > gMovesInfo[MOVE_STRENGTH].power);
- ASSUME(gMovesInfo[MOVE_SLAM].accuracy < gMovesInfo[MOVE_STRENGTH].accuracy);
- ASSUME(gMovesInfo[MOVE_MEGA_KICK].accuracy < gMovesInfo[MOVE_STRENGTH].accuracy);
- ASSUME(gMovesInfo[MOVE_TACKLE].accuracy == 100);
- ASSUME(gMovesInfo[MOVE_GUST].accuracy == 100);
- ASSUME(gMovesInfo[MOVE_SHOCK_WAVE].accuracy == 0);
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].accuracy == 100);
- ASSUME(gMovesInfo[MOVE_ICY_WIND].accuracy != 100);
- ASSUME(gMovesInfo[MOVE_SLAM].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_MEGA_KICK].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_SHOCK_WAVE].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_ICY_WIND].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveAccuracy(MOVE_SWIFT) == 0);
+ ASSUME(GetMovePower(MOVE_SLAM) == GetMovePower(MOVE_STRENGTH));
+ ASSUME(GetMovePower(MOVE_MEGA_KICK) > GetMovePower(MOVE_STRENGTH));
+ ASSUME(GetMoveAccuracy(MOVE_SLAM) < GetMoveAccuracy(MOVE_STRENGTH));
+ ASSUME(GetMoveAccuracy(MOVE_MEGA_KICK) < GetMoveAccuracy(MOVE_STRENGTH));
+ ASSUME(GetMoveAccuracy(MOVE_TACKLE) == 100);
+ ASSUME(GetMoveAccuracy(MOVE_GUST) == 100);
+ ASSUME(GetMoveAccuracy(MOVE_SHOCK_WAVE) == 0);
+ ASSUME(GetMoveAccuracy(MOVE_THUNDERBOLT) == 100);
+ ASSUME(GetMoveAccuracy(MOVE_ICY_WIND) != 100);
+ ASSUME(GetMoveCategory(MOVE_SLAM) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_MEGA_KICK) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SHOCK_WAVE) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_ICY_WIND) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_THUNDERBOLT) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
OPPONENT(SPECIES_EXPLOUD) { Moves(move1, move2, move3, move4); Ability(abilityAtk); SpAttack(50); } // Low Sp.Atk, so Swift deals less damage than Strength.
} WHEN {
switch (turns)
@@ -146,10 +146,10 @@ AI_SINGLE_BATTLE_TEST("AI prefers moves which deal more damage instead of moves
PARAMETRIZE { move1 = MOVE_POISON_JAB; move2 = MOVE_WATER_GUN; expectedMove = MOVE_POISON_JAB; abilityDef = ABILITY_IMMUNITY; turns = 3; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATERFALL].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SCALD].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_POISON_JAB].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_WATERFALL) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SCALD) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_POISON_JAB) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_TYPHLOSION) { Ability(abilityDef); }
PLAYER(SPECIES_WOBBUFFET);
@@ -176,8 +176,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers Earthquake over Drill Run if both require the
{
// Drill Run has less accuracy than E-quake, but can score a higher crit. However the chance is too small, so AI should ignore it.
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion
- ASSUME(gMovesInfo[MOVE_DRILL_RUN].category == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion
+ ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion
+ ASSUME(GetMoveCategory(MOVE_DRILL_RUN) == DAMAGE_CATEGORY_PHYSICAL); // Added because Geodude has to KO Typhlosion
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_TYPHLOSION);
PLAYER(SPECIES_WOBBUFFET);
@@ -202,8 +202,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers a weaker move over a one with a downside effec
PARAMETRIZE { move1 = MOVE_OVERHEAT; move2 = MOVE_FLAMETHROWER; hp = 250; expectedMove = MOVE_OVERHEAT; turns = 1; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLAMETHROWER].category == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet
- ASSUME(gMovesInfo[MOVE_OVERHEAT].category == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet
+ ASSUME(GetMoveCategory(MOVE_FLAMETHROWER) == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet
+ ASSUME(GetMoveCategory(MOVE_OVERHEAT) == DAMAGE_CATEGORY_SPECIAL); // Added because Typhlosion has to KO Wobbuffet
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(hp); }
PLAYER(SPECIES_WOBBUFFET);
@@ -242,8 +242,8 @@ AI_SINGLE_BATTLE_TEST("AI prefers moves with the best possible score, chosen ran
AI_SINGLE_BATTLE_TEST("AI can choose a status move that boosts the attack by two")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_HORN_ATTACK].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_HORN_ATTACK) == DAMAGE_CATEGORY_PHYSICAL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(277); };
PLAYER(SPECIES_WOBBUFFET);
@@ -330,8 +330,8 @@ AI_SINGLE_BATTLE_TEST("AI won't use Solar Beam if there is no Sun up or the user
PARAMETRIZE { }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_GRASS_PLEDGE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SOLAR_BEAM) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_GRASS_PLEDGE) == DAMAGE_CATEGORY_SPECIAL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(211); }
PLAYER(SPECIES_WOBBUFFET);
@@ -355,7 +355,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use Solar Beam if there is no Sun up or the user
AI_SINGLE_BATTLE_TEST("AI won't use ground type attacks against flying type Pokemon unless Gravity is in effect")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL); // Otherwise, it doesn't KO Crobat
+ ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL); // Otherwise, it doesn't KO Crobat
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_CROBAT);
PLAYER(SPECIES_WOBBUFFET);
@@ -430,7 +430,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not use a status move if partner already chose He
for (j = MOVE_NONE + 1; j < MOVES_COUNT; j++)
{
- if (gMovesInfo[j].category == DAMAGE_CATEGORY_STATUS) {
+ if (GetMoveCategory(j) == DAMAGE_CATEGORY_STATUS) {
PARAMETRIZE { statusMove = j; }
}
}
@@ -509,9 +509,9 @@ AI_SINGLE_BATTLE_TEST("AI will choose either Rock Tomb or Bulldoze if Stat drop
AI_SINGLE_BATTLE_TEST("First Impression is preferred on the first turn of the species if it's the best dmg move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].effect == EFFECT_FIRST_TURN_ONLY);
- ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].power == 90);
- ASSUME(gMovesInfo[MOVE_LUNGE].power == 80);
+ ASSUME(GetMoveEffect(MOVE_FIRST_IMPRESSION) == EFFECT_FIRST_TURN_ONLY);
+ ASSUME(GetMovePower(MOVE_FIRST_IMPRESSION) == 90);
+ ASSUME(GetMovePower(MOVE_LUNGE) == 80);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_KANGASKHAN);
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_FIRST_IMPRESSION, MOVE_LUNGE); }
@@ -531,9 +531,9 @@ AI_SINGLE_BATTLE_TEST("First Impression is not chosen if it's blocked by certain
PARAMETRIZE { species = SPECIES_TSAREENA; ability = ABILITY_QUEENLY_MAJESTY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].effect == EFFECT_FIRST_TURN_ONLY);
- ASSUME(gMovesInfo[MOVE_FIRST_IMPRESSION].power == 90);
- ASSUME(gMovesInfo[MOVE_LUNGE].power == 80);
+ ASSUME(GetMoveEffect(MOVE_FIRST_IMPRESSION) == EFFECT_FIRST_TURN_ONLY);
+ ASSUME(GetMovePower(MOVE_FIRST_IMPRESSION) == 90);
+ ASSUME(GetMovePower(MOVE_LUNGE) == 80);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_FIRST_IMPRESSION, MOVE_LUNGE); }
@@ -545,7 +545,7 @@ AI_SINGLE_BATTLE_TEST("First Impression is not chosen if it's blocked by certain
AI_SINGLE_BATTLE_TEST("AI will not choose Burn Up if the user lost the Fire typing")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_CYNDAQUIL) { Moves(MOVE_BURN_UP, MOVE_EXTRASENSORY, MOVE_FLAMETHROWER); }
@@ -559,7 +559,7 @@ AI_SINGLE_BATTLE_TEST("AI will only choose Surf 1/3 times if the opposing mon ha
{
PASSES_RANDOMLY(1, 3, RNG_AI_ABILITY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); };
OPPONENT(SPECIES_LANTURN) { Moves(MOVE_THUNDERBOLT, MOVE_ICE_BEAM, MOVE_SURF); }
@@ -576,7 +576,7 @@ AI_SINGLE_BATTLE_TEST("AI will choose Thunderbolt then Surf 2/3 times if the opp
{
PASSES_RANDOMLY(2, 3, RNG_AI_ABILITY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); };
OPPONENT(SPECIES_LANTURN) { Moves(MOVE_THUNDERBOLT, MOVE_ICE_BEAM, MOVE_SURF); }
@@ -596,10 +596,10 @@ AI_SINGLE_BATTLE_TEST("AI will choose Scratch over Power-up Punch with Contrary"
PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; }
PARAMETRIZE {ability = ABILITY_CONTRARY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCRATCH].power == 40);
- ASSUME(gMovesInfo[MOVE_SCRATCH].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].power == 40);
- ASSUME(gMovesInfo[MOVE_POWER_UP_PUNCH].type == TYPE_FIGHTING);
+ ASSUME(GetMovePower(MOVE_SCRATCH) == 40);
+ ASSUME(GetMoveType(MOVE_SCRATCH) == TYPE_NORMAL);
+ ASSUME(GetMovePower(MOVE_POWER_UP_PUNCH) == 40);
+ ASSUME(GetMoveType(MOVE_POWER_UP_PUNCH) == TYPE_FIGHTING);
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER);
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
@@ -622,10 +622,10 @@ AI_SINGLE_BATTLE_TEST("AI will choose Superpower over Outrage with Contrary")
PARAMETRIZE {ability = ABILITY_SUCTION_CUPS; }
PARAMETRIZE {ability = ABILITY_CONTRARY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SUPERPOWER].power == 120);
- ASSUME(gMovesInfo[MOVE_SUPERPOWER].type == TYPE_FIGHTING);
- ASSUME(gMovesInfo[MOVE_OUTRAGE].power == 120);
- ASSUME(gMovesInfo[MOVE_OUTRAGE].type == TYPE_DRAGON);
+ ASSUME(GetMovePower(MOVE_SUPERPOWER) == 120);
+ ASSUME(GetMoveType(MOVE_SUPERPOWER) == TYPE_FIGHTING);
+ ASSUME(GetMovePower(MOVE_OUTRAGE) == 120);
+ ASSUME(GetMoveType(MOVE_OUTRAGE) == TYPE_DRAGON);
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER);
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[1] == TYPE_WATER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
@@ -650,7 +650,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not choose Earthquake if it damages the partner")
PARAMETRIZE { species = SPECIES_CHIKORITA; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
@@ -667,7 +667,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not choose Earthquake if it damages the partner")
AI_DOUBLE_BATTLE_TEST("AI will choose Earthquake if partner is not alive")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
@@ -682,7 +682,7 @@ AI_DOUBLE_BATTLE_TEST("AI will choose Earthquake if partner is not alive")
AI_DOUBLE_BATTLE_TEST("AI will choose Earthquake if it kill an opposing mon and does 1/3 of damage to AI")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
@@ -700,7 +700,7 @@ AI_DOUBLE_BATTLE_TEST("AI will the see a corresponding absorbing ability on part
PARAMETRIZE { ability = ABILITY_STATIC; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
@@ -721,11 +721,11 @@ AI_SINGLE_BATTLE_TEST("AI calculates guaranteed criticals and detects critical i
PARAMETRIZE { ability = ABILITY_SHELL_ARMOR; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_STORM_THROW].alwaysCriticalHit);
- ASSUME(gMovesInfo[MOVE_STORM_THROW].power == 60);
- ASSUME(gMovesInfo[MOVE_BRICK_BREAK].power == 75);
- ASSUME(gMovesInfo[MOVE_STORM_THROW].type == gMovesInfo[MOVE_BRICK_BREAK].type);
- ASSUME(gMovesInfo[MOVE_STORM_THROW].category == gMovesInfo[MOVE_BRICK_BREAK].category);
+ ASSUME(MoveAlwaysCrits(MOVE_STORM_THROW));
+ ASSUME(GetMovePower(MOVE_STORM_THROW) == 60);
+ ASSUME(GetMovePower(MOVE_BRICK_BREAK) == 75);
+ ASSUME(GetMoveType(MOVE_STORM_THROW) == GetMoveType(MOVE_BRICK_BREAK));
+ ASSUME(GetMoveCategory(MOVE_STORM_THROW) == GetMoveCategory(MOVE_BRICK_BREAK));
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_OMASTAR) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_STORM_THROW, MOVE_BRICK_BREAK); }
@@ -761,11 +761,11 @@ AI_SINGLE_BATTLE_TEST("AI avoids contact moves against rocky helmet")
PARAMETRIZE { item = ITEM_ROCKY_HELMET; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_BRANCH_POKE].makesContact);
- ASSUME(!gMovesInfo[MOVE_LEAFAGE].makesContact);
- ASSUME(gMovesInfo[MOVE_BRANCH_POKE].power == gMovesInfo[MOVE_LEAFAGE].power);
- ASSUME(gMovesInfo[MOVE_BRANCH_POKE].type == gMovesInfo[MOVE_LEAFAGE].type);
- ASSUME(gMovesInfo[MOVE_BRANCH_POKE].category == gMovesInfo[MOVE_LEAFAGE].category);
+ ASSUME(MoveMakesContact(MOVE_BRANCH_POKE));
+ ASSUME(!MoveMakesContact(MOVE_LEAFAGE));
+ ASSUME(GetMovePower(MOVE_BRANCH_POKE) == GetMovePower(MOVE_LEAFAGE));
+ ASSUME(GetMoveType(MOVE_BRANCH_POKE) == GetMoveType(MOVE_LEAFAGE));
+ ASSUME(GetMoveCategory(MOVE_BRANCH_POKE) == GetMoveCategory(MOVE_LEAFAGE));
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BRANCH_POKE, MOVE_LEAFAGE); }
@@ -785,11 +785,11 @@ AI_SINGLE_BATTLE_TEST("AI uses a guaranteed KO move instead of the move with the
PARAMETRIZE { flags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
- ASSUME(gMovesInfo[MOVE_SLASH].power == 70);
- ASSUME(gMovesInfo[MOVE_STRENGTH].power == 80);
- ASSUME(gMovesInfo[MOVE_SLASH].type == gMovesInfo[MOVE_STRENGTH].type);
- ASSUME(gMovesInfo[MOVE_SLASH].category == gMovesInfo[MOVE_STRENGTH].category);
+ ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1);
+ ASSUME(GetMovePower(MOVE_SLASH) == 70);
+ ASSUME(GetMovePower(MOVE_STRENGTH) == 80);
+ ASSUME(GetMoveType(MOVE_SLASH) == GetMoveType(MOVE_STRENGTH));
+ ASSUME(GetMoveCategory(MOVE_SLASH) == GetMoveCategory(MOVE_STRENGTH));
AI_FLAGS(flags);
PLAYER(SPECIES_WOBBUFFET) { HP(225); }
OPPONENT(SPECIES_ABSOL) { Ability(ABILITY_SUPER_LUCK); Moves(MOVE_SLASH, MOVE_STRENGTH); }
@@ -806,3 +806,28 @@ AI_SINGLE_BATTLE_TEST("AI uses a guaranteed KO move instead of the move with the
NOT MESSAGE("Wobbuffet fainted!");
}
}
+
+AI_SINGLE_BATTLE_TEST("AI stays choice locked into moves in spite of the player's ability disabling them")
+{
+ u32 playerMon, ability, aiMove;
+ PARAMETRIZE { ability = ABILITY_DAZZLING; playerMon = SPECIES_BRUXISH; aiMove = MOVE_QUICK_ATTACK; }
+ PARAMETRIZE { ability = ABILITY_QUEENLY_MAJESTY; playerMon = SPECIES_TSAREENA; aiMove = MOVE_QUICK_ATTACK; }
+ PARAMETRIZE { ability = ABILITY_ARMOR_TAIL; playerMon = SPECIES_FARIGIRAF; aiMove = MOVE_QUICK_ATTACK; }
+ PARAMETRIZE { ability = ABILITY_SOUNDPROOF; playerMon = SPECIES_EXPLOUD; aiMove = MOVE_BOOMBURST; }
+ PARAMETRIZE { ability = ABILITY_BULLETPROOF; playerMon = SPECIES_CHESNAUGHT; aiMove = MOVE_BULLET_SEED; }
+
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_CHOICE_BAND].holdEffect == HOLD_EFFECT_CHOICE_BAND);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
+ ASSUME(IsSoundMove(MOVE_BOOMBURST));
+ ASSUME(IsBallisticMove(MOVE_BULLET_SEED));
+ ASSUME(GetMoveCategory(MOVE_TAIL_WHIP) == DAMAGE_CATEGORY_STATUS);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(playerMon) { Ability(ability); }
+ OPPONENT(SPECIES_SMEARGLE) { Item(ITEM_CHOICE_BAND); Moves(aiMove, MOVE_TACKLE); }
+ } WHEN {
+ TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, aiMove); }
+ TURN { EXPECT_MOVE(opponent, aiMove); }
+ }
+}
diff --git a/test/battle/ai/ai_calc_best_move_score.c b/test/battle/ai/ai_calc_best_move_score.c
index bece527f30..f3b339deba 100644
--- a/test/battle/ai/ai_calc_best_move_score.c
+++ b/test/battle/ai/ai_calc_best_move_score.c
@@ -10,9 +10,9 @@ AI_SINGLE_BATTLE_TEST("AI will not further increase Attack / Sp. Atk stat if it
PARAMETRIZE { move = MOVE_CALM_MIND; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKY_UPPERCUT].power == 85);
- ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY);
- ASSUME(gMovesInfo[MOVE_CALM_MIND].effect == EFFECT_CALM_MIND);
+ ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85);
+ ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY);
+ ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_COMBUSKEN) { Speed(15); Moves(MOVE_SKY_UPPERCUT, MOVE_CELEBRATE); };
OPPONENT(SPECIES_KANGASKHAN) { Speed(20); Moves(MOVE_CHIP_AWAY, MOVE_SWIFT, move); }
@@ -30,9 +30,9 @@ AI_SINGLE_BATTLE_TEST("AI will not further increase Attack / Sp. Atk stat if it
PARAMETRIZE { move = MOVE_CALM_MIND; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKY_UPPERCUT].power == 85);
- ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY);
- ASSUME(gMovesInfo[MOVE_CALM_MIND].effect == EFFECT_CALM_MIND);
+ ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85);
+ ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY);
+ ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_COMBUSKEN) { Speed(20); Moves(MOVE_DOUBLE_KICK, MOVE_CELEBRATE); };
OPPONENT(SPECIES_KANGASKHAN) { Speed(15); Moves(MOVE_CHIP_AWAY, MOVE_SWIFT, move); }
@@ -62,9 +62,9 @@ AI_SINGLE_BATTLE_TEST("AI will correctly predict what move the opposing mon goin
PARAMETRIZE { move = MOVE_CALM_MIND; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKY_UPPERCUT].power == 85);
- ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY);
- ASSUME(gMovesInfo[MOVE_CALM_MIND].effect == EFFECT_CALM_MIND);
+ ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85);
+ ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY);
+ ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_COMBUSKEN) { Speed(15); Moves(MOVE_SKY_UPPERCUT, MOVE_DOUBLE_KICK, MOVE_FLAME_WHEEL, MOVE_CELEBRATE); };
OPPONENT(SPECIES_KANGASKHAN) { Speed(20); Moves(MOVE_CHIP_AWAY, MOVE_SWIFT, move); }
@@ -77,10 +77,10 @@ AI_SINGLE_BATTLE_TEST("AI will correctly predict what move the opposing mon goin
AI_SINGLE_BATTLE_TEST("AI will not use Throat Chop if opposing mon has a better move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_PSYCHIC_FANGS].power == 85);
- ASSUME(gMovesInfo[MOVE_THROAT_CHOP].power == 80);
- ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].power == 40);
- ASSUME(gMovesInfo[MOVE_FLAME_BURST].power == 70);
+ ASSUME(GetMovePower(MOVE_PSYCHIC_FANGS) == 85);
+ ASSUME(GetMovePower(MOVE_THROAT_CHOP) == 80);
+ ASSUME(GetMovePower(MOVE_DISARMING_VOICE) == 40);
+ ASSUME(GetMovePower(MOVE_FLAME_BURST) == 70);
ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_REGIROCK) { Speed(15); Moves(MOVE_DISARMING_VOICE, MOVE_FLAME_BURST); };
@@ -96,10 +96,10 @@ AI_SINGLE_BATTLE_TEST("AI will select Throat Chop if the sound move is the best
{
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_THROAT_CHOP, MOVE_EFFECT_THROAT_CHOP) == TRUE);
- ASSUME(gMovesInfo[MOVE_PSYCHIC_FANGS].power == 85);
- ASSUME(gMovesInfo[MOVE_THROAT_CHOP].power == 80);
- ASSUME(gMovesInfo[MOVE_FLAME_BURST].power == 70);
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].power == 90);
+ ASSUME(GetMovePower(MOVE_PSYCHIC_FANGS) == 85);
+ ASSUME(GetMovePower(MOVE_THROAT_CHOP) == 80);
+ ASSUME(GetMovePower(MOVE_FLAME_BURST) == 70);
+ ASSUME(GetMovePower(MOVE_HYPER_VOICE) == 90);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_REGIROCK) { Speed(15); Moves(MOVE_HYPER_VOICE, MOVE_FLAME_BURST); };
OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Moves(MOVE_THROAT_CHOP, MOVE_PSYCHIC_FANGS); }
diff --git a/test/battle/ai/ai_check_viability.c b/test/battle/ai/ai_check_viability.c
index 37ad7edb15..2c20a08db6 100644
--- a/test/battle/ai/ai_check_viability.c
+++ b/test/battle/ai/ai_check_viability.c
@@ -15,7 +15,7 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Facade")
PARAMETRIZE { status1 = STATUS1_BURN; expectedMove = MOVE_FACADE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FACADE].effect == EFFECT_FACADE);
+ ASSUME(GetMoveEffect(MOVE_FACADE) == EFFECT_FACADE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(60); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BODY_SLAM, MOVE_FACADE); Status1(status1); }
@@ -36,8 +36,8 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Smelling Salt")
GIVEN {
ASSUME(B_UPDATED_MOVE_DATA >= GEN_6);
- ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
- ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].argument == STATUS1_PARALYSIS);
+ ASSUME(GetMoveEffect(MOVE_SMELLING_SALTS) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_SMELLING_SALTS) == STATUS1_PARALYSIS);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(60); Status1(status1); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BODY_SLAM, MOVE_SMELLING_SALTS); }
@@ -58,8 +58,8 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Wake Up Slap")
GIVEN {
ASSUME(B_UPDATED_MOVE_DATA >= GEN_6);
- ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
- ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].argument == STATUS1_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_WAKE_UP_SLAP) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_WAKE_UP_SLAP) == STATUS1_SLEEP);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_MEGANIUM) { HP(35); Status1(status1); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_BODY_SLAM, MOVE_WAKE_UP_SLAP); }
@@ -80,8 +80,8 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Grav Apple")
PARAMETRIZE { movePlayer = MOVE_GRAVITY; expectedMove = MOVE_GRAV_APPLE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GRAV_APPLE].effect == EFFECT_GRAV_APPLE);
- ASSUME(gMovesInfo[MOVE_GRAV_APPLE].power == gMovesInfo[MOVE_DRUM_BEATING].power);
+ ASSUME(GetMoveEffect(MOVE_GRAV_APPLE) == EFFECT_GRAV_APPLE);
+ ASSUME(GetMovePower(MOVE_GRAV_APPLE) == GetMovePower(MOVE_DRUM_BEATING));
ASSUME(MoveHasAdditionalEffect(MOVE_DRUM_BEATING, MOVE_EFFECT_SPD_MINUS_1) == TRUE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(81); Speed(20); }
@@ -103,7 +103,7 @@ AI_SINGLE_BATTLE_TEST("AI sees increased base power of Flail")
PARAMETRIZE { hp = 5; expectedMove = MOVE_FLAIL; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLAIL].effect == EFFECT_FLAIL);
+ ASSUME(GetMoveEffect(MOVE_FLAIL) == EFFECT_FLAIL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { Speed(10); }
OPPONENT(SPECIES_WOBBUFFET) { HP(hp); MaxHP(490); Speed(20); Moves(MOVE_BODY_SLAM, MOVE_FLAIL); }
@@ -134,8 +134,8 @@ AI_SINGLE_BATTLE_TEST("AI will only use Dream Eater if target is asleep")
AI_SINGLE_BATTLE_TEST("AI sees increased base power of Spit Up")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STOCKPILE].effect == EFFECT_STOCKPILE);
- ASSUME(gMovesInfo[MOVE_SPIT_UP].effect == EFFECT_SPIT_UP);
+ ASSUME(GetMoveEffect(MOVE_STOCKPILE) == EFFECT_STOCKPILE);
+ ASSUME(GetMoveEffect(MOVE_SPIT_UP) == EFFECT_SPIT_UP);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(43); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_STOCKPILE, MOVE_SPIT_UP, MOVE_TACKLE); }
@@ -155,10 +155,10 @@ AI_SINGLE_BATTLE_TEST("AI can choose Counter or Mirror Coat if the predicted mov
PARAMETRIZE { playerMove = MOVE_POWER_GEM; opponentMove = MOVE_MIRROR_COAT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_COUNTER].effect == EFFECT_COUNTER);
- ASSUME(gMovesInfo[MOVE_MIRROR_COAT].effect == EFFECT_MIRROR_COAT);
- ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_POWER_GEM].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveEffect(MOVE_COUNTER) == EFFECT_COUNTER);
+ ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT);
+ ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_POWER_GEM) == DAMAGE_CATEGORY_SPECIAL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { HP(102); Speed(100); Moves(opponentMove, MOVE_STRENGTH); }
@@ -202,7 +202,7 @@ AI_DOUBLE_BATTLE_TEST("AI chooses moves that cure self or partner")
PARAMETRIZE { status1_0 = STATUS1_NONE; status1_1 = STATUS1_PARALYSIS; partnerAbility = ABILITY_SOUNDPROOF; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_8);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
@@ -226,7 +226,7 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves that cure inactive party members")
PARAMETRIZE { status = STATUS1_TOXIC_POISON; ability = ABILITY_SOUNDPROOF; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_5);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET);
@@ -243,8 +243,8 @@ AI_SINGLE_BATTLE_TEST("AI chooses moves that cure inactive party members")
AI_DOUBLE_BATTLE_TEST("AI prioritizes Skill Swapping Contrary to allied mons that would benefit from it")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
- ASSUME(gMovesInfo[MOVE_OVERHEAT].additionalEffects[0].moveEffect == MOVE_EFFECT_SP_ATK_MINUS_2);
+ ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_OVERHEAT, 0)->moveEffect == MOVE_EFFECT_SP_ATK_MINUS_2);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_DOUBLE_BATTLE);
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
diff --git a/test/battle/ai/ai_choice.c b/test/battle/ai/ai_choice.c
index c9992d2cab..f1f13a373e 100644
--- a/test/battle/ai/ai_choice.c
+++ b/test/battle/ai/ai_choice.c
@@ -25,8 +25,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon switch out after using a status move onc
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_RHYDON)
OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(ability); }
@@ -60,7 +60,7 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use stat boosting moves")
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].target == MOVE_TARGET_USER);
+ ASSUME(GetMoveTarget(MOVE_SWORDS_DANCE) == MOVE_TARGET_USER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_RHYDON)
OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_SWORDS_DANCE, MOVE_TACKLE); Item(heldItem); Ability(ability); }
@@ -94,8 +94,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use status move if they are the on
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_RHYDON)
OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(ability); }
@@ -129,8 +129,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use status move if they don't have
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_RHYDON)
OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(ability); }
@@ -164,8 +164,8 @@ AI_SINGLE_BATTLE_TEST("Choiced Pokémon won't use status move if they are trappe
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveCategory(MOVE_YAWN) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(species) { Ability(playerAbility); }
OPPONENT(SPECIES_LOPUNNY) { Moves(MOVE_YAWN, MOVE_TACKLE); Item(heldItem); Ability(aiAbility); }
diff --git a/test/battle/ai/ai_double_ace.c b/test/battle/ai/ai_double_ace.c
index aec37b9307..5e49c0d6e1 100644
--- a/test/battle/ai/ai_double_ace.c
+++ b/test/battle/ai/ai_double_ace.c
@@ -2,8 +2,8 @@
#include "test/battle.h"
ASSUMPTIONS {
- ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
- ASSUME(gMovesInfo[MOVE_CRUNCH].type == TYPE_DARK);
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveType(MOVE_CRUNCH) == TYPE_DARK);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] == TYPE_PSYCHIC);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC);
}
diff --git a/test/battle/ai/ai_flag_predict_ability.c b/test/battle/ai/ai_flag_predict_ability.c
new file mode 100644
index 0000000000..9d85773e3e
--- /dev/null
+++ b/test/battle/ai/ai_flag_predict_ability.c
@@ -0,0 +1,16 @@
+#include "global.h"
+#include "test/battle.h"
+#include "battle_ai_util.h"
+
+AI_SINGLE_BATTLE_TEST("AI_FLAG_WEIGH_ABILITY_PREDICTION: AI will predict opposing ability based on its aiRating")
+{
+ PASSES_RANDOMLY(7, 14, RNG_AI_PREDICT_ABILITY);
+ GIVEN {
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_WEIGH_ABILITY_PREDICTION);
+ PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); };
+ OPPONENT(SPECIES_LANTURN) { Moves(MOVE_THUNDERBOLT, MOVE_ICE_BEAM, MOVE_SURF); }
+ } WHEN {
+ TURN { EXPECT_MOVE(opponent, MOVE_THUNDERBOLT); }
+ }
+}
diff --git a/test/battle/ai/ai_flag_risky.c b/test/battle/ai/ai_flag_risky.c
index 87be344ab8..bbc9a640a6 100644
--- a/test/battle/ai/ai_flag_risky.c
+++ b/test/battle/ai/ai_flag_risky.c
@@ -9,7 +9,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will blindly Mirror Coat against specia
PARAMETRIZE { aiRiskyFlag = AI_FLAG_RISKY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_MIRROR_COAT].effect == EFFECT_MIRROR_COAT);
+ ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT);
ASSUME(gSpeciesInfo[SPECIES_GROVYLE].baseSpAttack == 85);
ASSUME(gSpeciesInfo[SPECIES_GROVYLE].baseAttack == 65);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag);
@@ -28,7 +28,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will blindly Counter against physical a
PARAMETRIZE { aiRiskyFlag = AI_FLAG_RISKY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_COUNTER].effect == EFFECT_COUNTER);
+ ASSUME(GetMoveEffect(MOVE_COUNTER) == EFFECT_COUNTER);
ASSUME(gSpeciesInfo[SPECIES_MARSHTOMP].baseAttack == 85);
ASSUME(gSpeciesInfo[SPECIES_MARSHTOMP].baseSpAttack == 60);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag);
@@ -47,7 +47,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will prioritize Revenge if slower")
PARAMETRIZE { aiRiskyFlag = AI_FLAG_RISKY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_REVENGE].effect == EFFECT_REVENGE);
+ ASSUME(GetMoveEffect(MOVE_REVENGE) == EFFECT_REVENGE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag);
PLAYER(SPECIES_GROVYLE) { Level(20); Speed(4); Moves(MOVE_ENERGY_BALL); }
OPPONENT(SPECIES_CASTFORM) { Level(19); Speed(3); Moves(MOVE_TACKLE, MOVE_REVENGE); }
diff --git a/test/battle/ai/ai_flag_sequence_switching.c b/test/battle/ai/ai_flag_sequence_switching.c
index 8502efbba7..56d7eb881f 100644
--- a/test/battle/ai/ai_flag_sequence_switching.c
+++ b/test/battle/ai/ai_flag_sequence_switching.c
@@ -48,8 +48,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: Roar and Dragon Tail still fo
PASSES_RANDOMLY(1, 2, RNG_FORCE_RANDOM_SWITCH);
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR);
- ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
+ ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
AI_FLAGS(AI_FLAG_SEQUENCE_SWITCHING);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -82,10 +82,10 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: AI will always switch into lo
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
- ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
- ASSUME(gMovesInfo[MOVE_CHILLY_RECEPTION].effect == EFFECT_CHILLY_RECEPTION);
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_CHILLY_RECEPTION) == EFFECT_CHILLY_RECEPTION);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiSequenceSwitchingFlag);
PLAYER(SPECIES_SWELLOW) { Level (50); }
OPPONENT(SPECIES_MACHOP) { Level(1); Moves(move); }
diff --git a/test/battle/ai/ai_powerful_status.c b/test/battle/ai/ai_powerful_status.c
index 4a14c0bf80..99aff19384 100644
--- a/test/battle/ai/ai_powerful_status.c
+++ b/test/battle/ai/ai_powerful_status.c
@@ -5,8 +5,8 @@
AI_SINGLE_BATTLE_TEST("AI prefers to set up a powerful Status over fainting a target")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRICK_ROOM].effect == EFFECT_TRICK_ROOM);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveEffect(MOVE_TRICK_ROOM) == EFFECT_TRICK_ROOM);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_POWERFUL_STATUS);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
PLAYER(SPECIES_WYNAUT);
@@ -23,8 +23,8 @@ AI_SINGLE_BATTLE_TEST("AI will try to do damage on target instead of setting up
{
GIVEN {
ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE);
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_POWERFUL_STATUS | AI_FLAG_OMNISCIENT);
PLAYER(SPECIES_WOBBUFFET) { HP(1); Moves(MOVE_RAPID_SPIN, MOVE_DEFOG, MOVE_CELEBRATE); }
PLAYER(SPECIES_WYNAUT);
@@ -40,8 +40,8 @@ AI_SINGLE_BATTLE_TEST("AI will try to do damage on target instead of setting up
AI_SINGLE_BATTLE_TEST("AI will not set up Rain if it is already raining")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_RAIN_DANCE].effect == EFFECT_RAIN_DANCE);
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_POWERFUL_STATUS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c
index 5610689f49..a4cd202574 100644
--- a/test/battle/ai/ai_switching.c
+++ b/test/battle/ai/ai_switching.c
@@ -93,7 +93,7 @@ AI_DOUBLE_BATTLE_TEST("AI will not try to switch for the same pokemon for 2 spot
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: U-Turn will send out Ace Mon if it's the only one remaining")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_ACE_POKEMON);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); }
@@ -168,11 +168,11 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI will not switch in a Pokemo
PARAMETRIZE { speedAlakazm = 400; alakazamFirst = TRUE; aiSmartSwitchFlags = AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES; } // AI_FLAG_SMART_MON_CHOICES recognizes that Alakazam is faster and can KO, and will switch it in
GIVEN {
- ASSUME(gMovesInfo[MOVE_PSYCHIC].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_FOCUS_BLAST].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_BUBBLE_BEAM].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_STRENGTH].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_PSYCHIC) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_FOCUS_BLAST) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_BUBBLE_BEAM) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_STRENGTH) == DAMAGE_CATEGORY_PHYSICAL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiSmartSwitchFlags);
PLAYER(SPECIES_WEAVILE) { Speed(300); Ability(ABILITY_SHADOW_TAG); } // Weavile has Shadow Tag, so AI can't switch on the first turn, but has to do it after fainting.
OPPONENT(SPECIES_KADABRA) { Speed(200); Moves(MOVE_PSYCHIC, MOVE_DISABLE, MOVE_TAUNT, MOVE_CALM_MIND); }
@@ -250,7 +250,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize offensive options after slow U-Turn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FALSE_SWIPE].effect == EFFECT_FALSE_SWIPE);
+ ASSUME(GetMoveEffect(MOVE_FALSE_SWIPE) == EFFECT_FALSE_SWIPE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES);
PLAYER(SPECIES_SWELLOW) { Level(30); Moves(MOVE_FALSE_SWIPE, MOVE_BOOMBURST); Speed(5); SpAttack(50); }
OPPONENT(SPECIES_PONYTA) { Level(1); Moves(MOVE_U_TURN); Speed(4); } // Forces switchout
@@ -265,7 +265,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize
{
GIVEN {
ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON);
- ASSUME(gMovesInfo[MOVE_FALSE_SWIPE].effect == EFFECT_FALSE_SWIPE);
+ ASSUME(GetMoveEffect(MOVE_FALSE_SWIPE) == EFFECT_FALSE_SWIPE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES);
PLAYER(SPECIES_SWELLOW) { Level(30); Moves(MOVE_FALSE_SWIPE, MOVE_BOOMBURST); Speed(5); SpAttack(50); }
OPPONENT(SPECIES_PONYTA) { Level(1); Item(ITEM_EJECT_BUTTON); Moves(MOVE_TACKLE); Speed(4); } // Forces switchout
@@ -280,7 +280,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Mid-battle switches prioritize
{
GIVEN {
ASSUME(gItemsInfo[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK);
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES);
PLAYER(SPECIES_SWELLOW) { Level(30); Moves(MOVE_GROWL, MOVE_BOOMBURST); Speed(5); SpAttack(50); }
OPPONENT(SPECIES_PONYTA) { Level(1); Item(ITEM_EJECT_PACK); Moves(MOVE_TACKLE); Speed(4); } // Forces switchout
@@ -337,7 +337,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Post-KO switches prioritize of
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: Post-KO switches factor in Trick Room for revenge killing")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRICK_ROOM].effect == EFFECT_TRICK_ROOM);
+ ASSUME(GetMoveEffect(MOVE_TRICK_ROOM) == EFFECT_TRICK_ROOM);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_MON_CHOICES);
PLAYER(SPECIES_SWELLOW) { Level(30); Speed(10); Moves(MOVE_WING_ATTACK, MOVE_GROWL); }
OPPONENT(SPECIES_BALTOY) { Level(1); Speed(10); Moves(MOVE_TRICK_ROOM); }
@@ -371,10 +371,10 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will not switch out if Pokemo
PARAMETRIZE { move1 = MOVE_RAPID_SPIN; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_RAPID_SPIN].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_HEADBUTT].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_RAPID_SPIN) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_HEADBUTT) == DAMAGE_CATEGORY_PHYSICAL);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_HITMONTOP) { Level(30); Moves(MOVE_CHARM, MOVE_TACKLE, MOVE_STEALTH_ROCK, MOVE_EARTHQUAKE); Ability(ABILITY_INTIMIDATE); Speed(5); }
OPPONENT(SPECIES_GRIMER) { Level(30); Moves(MOVE_TACKLE); Item(ITEM_FOCUS_SASH); Speed(4); }
@@ -462,8 +462,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if mon would
ASSUME(gSpeciesInfo[SPECIES_RHYDON].types[0] == TYPE_GROUND);
ASSUME(gSpeciesInfo[SPECIES_PELIPPER].types[0] == TYPE_WATER);
ASSUME(gSpeciesInfo[SPECIES_PELIPPER].types[1] == TYPE_FLYING);
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES);
PLAYER(SPECIES_ELECTRODE) { Moves(MOVE_THUNDERBOLT, MOVE_THUNDER_WAVE, MOVE_THUNDER_SHOCK); }
@@ -482,8 +482,8 @@ AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch out if it can't deal damage to
ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[0] == ABILITY_WONDER_GUARD);
ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[1] == ABILITY_NONE);
ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[2] == ABILITY_NONE);
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_SHEDINJA) { Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -501,8 +501,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it can't d
ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[0] == ABILITY_WONDER_GUARD);
ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[1] == ABILITY_NONE);
ASSUME(gSpeciesInfo[SPECIES_SHEDINJA].abilities[2] == ABILITY_NONE);
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_SHADOW_BALL].type == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_SHADOW_BALL) == TYPE_GHOST);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_SHEDINJA) { Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -519,7 +519,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
PARAMETRIZE { species = SPECIES_HARIYAMA, odds = 50; }
PASSES_RANDOMLY(odds, 100, RNG_AI_SWITCH_BADLY_POISONED);
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_TOXIC, MOVE_AURA_SPHERE); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -535,7 +535,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
{
PASSES_RANDOMLY(50, 100, RNG_AI_SWITCH_CURSED);
GIVEN {
- ASSUME(gMovesInfo[MOVE_CURSE].effect == EFFECT_CURSE);
+ ASSUME(GetMoveEffect(MOVE_CURSE) == EFFECT_CURSE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_DUSCLOPS) { Moves(MOVE_FIRE_PUNCH, MOVE_CURSE); }
PLAYER(SPECIES_MILOTIC) { Moves(MOVE_WATER_GUN); }
@@ -551,7 +551,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
{
PASSES_RANDOMLY(33, 100, RNG_AI_SWITCH_NIGHTMARE);
GIVEN {
- ASSUME(gMovesInfo[MOVE_NIGHTMARE].effect == EFFECT_NIGHTMARE);
+ ASSUME(GetMoveEffect(MOVE_NIGHTMARE) == EFFECT_NIGHTMARE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_GENGAR) { Moves(MOVE_NIGHTMARE); }
OPPONENT(SPECIES_DUSCLOPS) { Moves(MOVE_SHADOW_BALL); Status1(STATUS1_SLEEP); }
@@ -566,7 +566,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
{
PASSES_RANDOMLY(25, 100, RNG_AI_SWITCH_SEEDED);
GIVEN {
- ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED);
+ ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_WHIMSICOTT) { Moves(MOVE_LEECH_SEED); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -580,7 +580,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been infatuated")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ATTRACT].effect == EFFECT_ATTRACT);
+ ASSUME(GetMoveEffect(MOVE_ATTRACT) == EFFECT_ATTRACT);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_LUVDISC) { Moves(MOVE_ATTRACT); Gender(MON_FEMALE); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); Gender(MON_MALE); }
@@ -597,7 +597,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
PARAMETRIZE { hp = 30; }
PARAMETRIZE { hp = 10; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_SLAKOTH) { Moves(MOVE_TACKLE, MOVE_YAWN); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); HP(hp); MaxHP(30); }
@@ -617,7 +617,7 @@ AI_DOUBLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
PARAMETRIZE { hp = 30; }
PARAMETRIZE { hp = 10; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_SLAKOTH) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_YAWN); }
PLAYER(SPECIES_SLAKOTH) { Moves(MOVE_TACKLE, MOVE_CELEBRATE, MOVE_YAWN); }
@@ -637,7 +637,7 @@ AI_DOUBLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's mon is semi-invulnerable and it has an absorber")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DIVE].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_DIVE) == TYPE_WATER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_LUVDISC) { Moves(MOVE_DIVE); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -652,7 +652,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has an
{
PASSES_RANDOMLY(33, 100, RNG_AI_SWITCH_ABSORBING);
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_LUVDISC) { Moves(MOVE_WATER_GUN); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SHOCK_WAVE); }
@@ -667,7 +667,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m
{
PASSES_RANDOMLY(100, 100, RNG_AI_SWITCH_ABSORBING);
GIVEN {
- ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].type == TYPE_GRASS);
+ ASSUME(GetMoveType(MOVE_SOLAR_BEAM) == TYPE_GRASS);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_BELLOSSOM) { Moves(MOVE_SOLAR_BEAM); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -681,7 +681,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's mon is charging and it has a good switchin immunity (type)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DIG].type == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_DIG) == TYPE_GROUND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_SANDSHREW) { Moves(MOVE_DIG); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -695,7 +695,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's mon is charging and it has a good switchin immunity (ability)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DIG].type == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_DIG) == TYPE_GROUND);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_SANDSHREW) { Moves(MOVE_DIG); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
@@ -708,15 +708,29 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if player's m
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has an absorber")
{
+ u32 aiMon; u32 move; u32 absorbingAbility;
+ PARAMETRIZE { aiMon = SPECIES_NINETALES; absorbingAbility = ABILITY_FLASH_FIRE; move = MOVE_FLAMETHROWER;}
+ PARAMETRIZE { aiMon = SPECIES_MANTINE; absorbingAbility = ABILITY_WATER_ABSORB; move = MOVE_SURF;}
+ PARAMETRIZE { aiMon = SPECIES_TOXICROAK; absorbingAbility = ABILITY_DRY_SKIN; move = MOVE_SURF;}
+ PARAMETRIZE { aiMon = SPECIES_GASTRODON; absorbingAbility = ABILITY_STORM_DRAIN; move = MOVE_SURF;}
+ PARAMETRIZE { aiMon = SPECIES_JOLTEON; absorbingAbility = ABILITY_VOLT_ABSORB; move = MOVE_THUNDERBOLT;}
+ PARAMETRIZE { aiMon = SPECIES_ELECTIVIRE; absorbingAbility = ABILITY_MOTOR_DRIVE; move = MOVE_THUNDERBOLT;}
+ PARAMETRIZE { aiMon = SPECIES_MANECTRIC; absorbingAbility = ABILITY_LIGHTNING_ROD; move = MOVE_THUNDERBOLT;}
+ PARAMETRIZE { aiMon = SPECIES_ELECTIVIRE; absorbingAbility = ABILITY_MOTOR_DRIVE; move = MOVE_THUNDERBOLT;}
+ PARAMETRIZE { aiMon = SPECIES_AZUMARILL; absorbingAbility = ABILITY_SAP_SIPPER; move = MOVE_GIGA_DRAIN;}
+ PARAMETRIZE { aiMon = SPECIES_ORTHWORM; absorbingAbility = ABILITY_EARTH_EATER; move = MOVE_EARTHQUAKE;}
+ PARAMETRIZE { aiMon = SPECIES_BRONZONG; absorbingAbility = ABILITY_LEVITATE; move = MOVE_EARTHQUAKE;}
+ PARAMETRIZE { aiMon = SPECIES_ELECTRODE; absorbingAbility = ABILITY_SOUNDPROOF; move = MOVE_HYPER_VOICE;}
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(B_REDIRECT_ABILITY_IMMUNITY >= GEN_5);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
- PLAYER(SPECIES_LUVDISC) { Moves(MOVE_WATER_GUN); }
+ PLAYER(SPECIES_ZIGZAGOON) { Moves(move); }
OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); }
- OPPONENT(SPECIES_MANTINE) { Moves(MOVE_TACKLE); Ability(ABILITY_WATER_ABSORB); }
+ OPPONENT(aiMon) { Moves(MOVE_TACKLE); Ability(absorbingAbility); }
} WHEN {
- TURN { MOVE(player, MOVE_WATER_GUN) ; EXPECT_MOVE(opponent, MOVE_TACKLE); }
- TURN { MOVE(player, MOVE_WATER_GUN) ; EXPECT_SWITCH(opponent, 1); }
+ TURN { MOVE(player, move); EXPECT_MOVE(opponent, MOVE_TACKLE); }
+ TURN { MOVE(player, move); EXPECT_SWITCH(opponent, 1); }
}
}
@@ -727,8 +741,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if opponent u
PARAMETRIZE { move = MOVE_FLY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(gMovesInfo[MOVE_SKY_ATTACK].effect == EFFECT_TWO_TURNS_ATTACK);
+ ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveEffect(MOVE_SKY_ATTACK) == EFFECT_TWO_TURNS_ATTACK);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_SWELLOW) { Moves(move); }
OPPONENT(SPECIES_MILOTIC) { Moves(MOVE_SURF); }
@@ -769,7 +783,7 @@ AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch out if it has <= 66% HP remaini
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has been Encore'd into a status move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE);
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_AZURILL) { Moves(MOVE_TACKLE, MOVE_ENCORE); }
OPPONENT(SPECIES_ODDISH) { Moves(MOVE_TOXIC, MOVE_SWEET_SCENT, MOVE_INGRAIN, MOVE_TACKLE); }
@@ -783,7 +797,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has bee
AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will stay in if Encore'd into super effective move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE);
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_AZURILL) { Moves(MOVE_TACKLE, MOVE_ENCORE); }
OPPONENT(SPECIES_ODDISH) { Moves(MOVE_ACID); }
@@ -799,7 +813,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if Encore'd i
KNOWN_FAILING; // AI still switches even if ShouldSwitch is set to immediately return FALSE, something external seems to be triggering this
PASSES_RANDOMLY(50, 100, RNG_AI_SWITCH_ENCORE);
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE);
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_AZURILL) { Moves(MOVE_TACKLE, MOVE_ENCORE); }
OPPONENT(SPECIES_ODDISH) { Moves(MOVE_TACKLE); }
@@ -845,8 +859,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if main attac
PARAMETRIZE {move = MOVE_EERIE_IMPULSE; aiSpecies = SPECIES_ESPEON; aiMove = MOVE_CONFUSION; };
GIVEN {
- ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2);
- ASSUME(gMovesInfo[MOVE_EERIE_IMPULSE].effect == EFFECT_SPECIAL_ATTACK_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_EERIE_IMPULSE) == EFFECT_SPECIAL_ATTACK_DOWN_2);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_ARON) { Moves(move, MOVE_TACKLE); }
OPPONENT(aiSpecies) { Moves(aiMove); }
@@ -866,8 +880,8 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if main attac
PARAMETRIZE {move = MOVE_CONFIDE; move2 = MOVE_EERIE_IMPULSE; aiSpecies = SPECIES_ESPEON; aiMove = MOVE_STORED_POWER; };
GIVEN {
- ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2);
- ASSUME(gMovesInfo[MOVE_EERIE_IMPULSE].effect == EFFECT_SPECIAL_ATTACK_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_EERIE_IMPULSE) == EFFECT_SPECIAL_ATTACK_DOWN_2);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING);
PLAYER(SPECIES_ARON) { Moves(move, move2, MOVE_TACKLE); }
OPPONENT(aiSpecies) { Moves(aiMove); }
@@ -881,6 +895,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if main attac
AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch into mon with good type matchup and SE move if current mon has no SE move and no stats raised")
{
+ KNOWN_FAILING; // Either remove or replace the function
u32 odds = 0, species = SPECIES_NONE, move = MOVE_NONE;
PARAMETRIZE { odds = 33; species = SPECIES_SCIZOR; move = MOVE_X_SCISSOR; }
PARAMETRIZE { odds = 50; species = SPECIES_DUSCLOPS; move = MOVE_SHADOW_BALL; }
@@ -895,3 +910,75 @@ AI_SINGLE_BATTLE_TEST("Switch AI: AI will switch into mon with good type matchup
TURN { MOVE(player, MOVE_TACKLE); EXPECT_SWITCH(opponent, 1); }
}
}
+
+AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI correctly handles abilities when scoring moves")
+{
+ GIVEN {
+ ASSUME(B_PRANKSTER_DARK_TYPES >= GEN_7);
+ ASSUME(gSpeciesInfo[SPECIES_GRENINJA].types[1] == TYPE_DARK);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES);
+ PLAYER(SPECIES_GRENINJA) { Moves(MOVE_WATER_GUN); }
+ OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_PRANKSTER); Moves(MOVE_LEECH_SEED, MOVE_STUN_SPORE, MOVE_ABSORB); }
+ OPPONENT(SPECIES_WHIMSICOTT) { Ability(ABILITY_INFILTRATOR); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_MOVE(opponent, MOVE_ABSORB); }
+ }
+}
+
+AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch out if Yawn'd with only Ace mon remaining")
+{
+ u32 aceFlag;
+ PARAMETRIZE{ aceFlag = 0; }
+ PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; }
+ GIVEN {
+ ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING);
+ PLAYER(SPECIES_SLOWKING) { Moves(MOVE_YAWN, MOVE_CONFUSION, MOVE_POWER_GEM, MOVE_WATER_PULSE); Item(ITEM_LEFTOVERS); }
+ OPPONENT(SPECIES_SCOLIPEDE) { Moves(MOVE_POISON_TAIL); }
+ OPPONENT(SPECIES_ABSOL) { Moves(MOVE_KNOCK_OFF, MOVE_CRUNCH); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_YAWN); EXPECT_MOVE(opponent, MOVE_POISON_TAIL); }
+ if (aceFlag)
+ TURN { MOVE(player, MOVE_POWER_GEM); EXPECT_MOVE(opponent, MOVE_POISON_TAIL); }
+ else
+ TURN { MOVE(player, MOVE_POWER_GEM); EXPECT_SWITCH(opponent, 1); }
+ }
+}
+
+AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch in ace mon after U-Turn if other options available")
+{
+ u32 aceFlag;
+ PARAMETRIZE{ aceFlag = 0; }
+ PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; }
+ GIVEN {
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING);
+ PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SURF); }
+ OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); }
+ OPPONENT(SPECIES_NUMEL) { Level(5); Moves(MOVE_SPLASH); }
+ OPPONENT(SPECIES_SCIZOR) { Moves(MOVE_BUG_BITE); }
+ } WHEN {
+ if (aceFlag)
+ TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 1); MOVE(player, MOVE_SURF); }
+ else
+ TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); MOVE(player, MOVE_SURF); }
+ }
+}
+
+AI_SINGLE_BATTLE_TEST("Switch AI: AI won't switch in ace mon after U-Turn if other options available")
+{
+ u32 aceFlag;
+ PARAMETRIZE{ aceFlag = 0; }
+ PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; }
+ GIVEN {
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT);
+ PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SURF); }
+ OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); }
+ OPPONENT(SPECIES_NUMEL) { Level(5); Moves(MOVE_SPLASH); }
+ OPPONENT(SPECIES_SCIZOR) { Moves(MOVE_BUG_BITE); }
+ } WHEN {
+ if (aceFlag)
+ TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 1); MOVE(player, MOVE_SURF); }
+ else
+ TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); MOVE(player, MOVE_SURF); }
+ }
+}
diff --git a/test/battle/ai/ai_trytofaint.c b/test/battle/ai/ai_trytofaint.c
index 10eca2d676..a1a23efdec 100644
--- a/test/battle/ai/ai_trytofaint.c
+++ b/test/battle/ai/ai_trytofaint.c
@@ -5,7 +5,7 @@
AI_SINGLE_BATTLE_TEST("AI prefers priority moves if it's slower and can kill target")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
PLAYER(SPECIES_WOBBUFFET) { Speed(100); }
@@ -20,7 +20,7 @@ AI_SINGLE_BATTLE_TEST("AI prefers priority moves if it's slower and can kill tar
AI_SINGLE_BATTLE_TEST("AI will choose a random move if it's faster and can kill target")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { HP(1); Speed(1); }
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
@@ -35,7 +35,7 @@ AI_SINGLE_BATTLE_TEST("AI will choose a random move if it's faster and can kill
AI_SINGLE_BATTLE_TEST("AI will choose a priority move if it is slower then the target and will be killed")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
PLAYER(SPECIES_WOBBUFFET) { Speed(100); }
OPPONENT(SPECIES_WOBBUFFET) { HP(60); Speed(1); Moves(MOVE_QUICK_ATTACK, MOVE_STRENGTH); }
diff --git a/test/battle/crit_chance.c b/test/battle/crit_chance.c
index 3ff4e80b4e..32c4c3380d 100644
--- a/test/battle/crit_chance.c
+++ b/test/battle/crit_chance.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Crit Chance: Side effected by Lucky Chant blocks critical hits")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_LUCKY_CHANT].effect == EFFECT_LUCKY_CHANT);
+ ASSUME(GetMoveEffect(MOVE_LUCKY_CHANT) == EFFECT_LUCKY_CHANT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Flag ignoresTargetAbility ignores Battle Armor
PARAMETRIZE { species = SPECIES_ARMALDO; ability = ABILITY_BATTLE_ARMOR; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SUNSTEEL_STRIKE].ignoresTargetAbility == TRUE);
+ ASSUME(MoveIgnoresTargetAbility(MOVE_SUNSTEEL_STRIKE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -100,7 +100,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Mold Breaker, Teravolt and Turboblaze ignore Ba
SINGLE_BATTLE_TEST("Crit Chance: User effected by Laser Focus causes moves to result in a critical hit")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_LASER_FOCUS].effect == EFFECT_LASER_FOCUS);
+ ASSUME(GetMoveEffect(MOVE_LASER_FOCUS) == EFFECT_LASER_FOCUS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -131,7 +131,7 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases the user's critical hit
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY);
+ ASSUME(GetMoveEffect(MOVE_FOCUS_ENERGY) == EFFECT_FOCUS_ENERGY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -149,7 +149,7 @@ SINGLE_BATTLE_TEST("Crit Chance: High crit rate increases the critical hit ratio
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
+ ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -195,9 +195,9 @@ SINGLE_BATTLE_TEST("Crit Chance: High crit rate, Super Luck and Scope Lens cause
{
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
+ ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1);
ASSUME(gItemsInfo[ITEM_SCOPE_LENS].holdEffect == HOLD_EFFECT_SCOPE_LENS);
- PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SUPER_LUCK); Item(ITEM_SCOPE_LENS); };
+ PLAYER(SPECIES_TOGEKISS) { Ability(ABILITY_SUPER_LUCK); Item(ITEM_SCOPE_LENS); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_SLASH); }
@@ -257,8 +257,8 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases critical hit ratio by tw
PASSES_RANDOMLY(8, 8, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
- ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY);
+ ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1);
+ ASSUME(GetMoveEffect(MOVE_FOCUS_ENERGY) == EFFECT_FOCUS_ENERGY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -271,76 +271,3 @@ SINGLE_BATTLE_TEST("Crit Chance: Focus Energy increases critical hit ratio by tw
MESSAGE("A critical hit!");
}
}
-
-SINGLE_BATTLE_TEST("Crit Chance: Dragon Cheer fails in a single battle")
-{
- GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(player, MOVE_DRAGON_CHEER); }
- } SCENE {
- MESSAGE("But it failed!");
- }
-}
-
-DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by one on non Dragon types")
-{
- PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
- GIVEN {
- ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0);
- ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WYNAUT);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft);
- MESSAGE("Wynaut is getting pumped!");
- ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
- MESSAGE("A critical hit!");
- }
-}
-
-DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer increases critical hit ratio by two on Dragon types")
-{
- PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
- GIVEN {
- ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0);
- ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_DRATINI);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft);
- MESSAGE("Dratini is getting pumped!");
- ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
- MESSAGE("A critical hit!");
- }
-}
-
-DOUBLE_BATTLE_TEST("Crit Chance: Dragon Cheer fails if critical hit stage was already increased by Focus Energy")
-{
- GIVEN {
- ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
- ASSUME(gMovesInfo[MOVE_FOCUS_ENERGY].effect == EFFECT_FOCUS_ENERGY);
- ASSUME(gMovesInfo[MOVE_DRAGON_CHEER].effect == EFFECT_DRAGON_CHEER);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(playerLeft, MOVE_FOCUS_ENERGY); MOVE(playerRight, MOVE_DRAGON_CHEER, target: playerLeft); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, playerLeft);
- MESSAGE("But it failed!");
- }
-}
diff --git a/test/battle/damage_formula.c b/test/battle/damage_formula.c
index 473f631b11..0679725510 100644
--- a/test/battle/damage_formula.c
+++ b/test/battle/damage_formula.c
@@ -24,7 +24,7 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+")
PARAMETRIZE { expectedDamage = 168; }
PARAMETRIZE { expectedDamage = 168; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ICE_FANG].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_ICE_FANG) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_GLACEON) { Level(75); Attack(123); }
OPPONENT(SPECIES_GARCHOMP) { Defense(163); }
} WHEN {
@@ -62,7 +62,7 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Muscle Band, crit)")
PARAMETRIZE { expectedDamage = 276; }
PARAMETRIZE { expectedDamage = 268; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ICE_FANG].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_ICE_FANG) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_GLACEON) { Level(75); Attack(123); Item(ITEM_MUSCLE_BAND); }
OPPONENT(SPECIES_GARCHOMP) { Defense(163); }
} WHEN {
@@ -100,7 +100,7 @@ SINGLE_BATTLE_TEST("Damage calculation matches Gen5+ (Marshadow vs Mawile)")
PARAMETRIZE { expectedDamage = 124; }
PARAMETRIZE { expectedDamage = 123; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPECTRAL_THIEF].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SPECTRAL_THIEF) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_MARSHADOW) { Level(100); Attack(286); }
OPPONENT(SPECIES_MAWILE) { Level(100); Defense(226); HP(241); }
} WHEN {
@@ -150,3 +150,134 @@ DOUBLE_BATTLE_TEST("A spread move will do correct damage to the second mon if th
EXPECT_EQ(damage[4], damage[5]);
}
}
+
+SINGLE_BATTLE_TEST("Punching Glove vs Muscle Band Damage calculation")
+{
+ s16 dmgPlayer, dmgOpponent;
+ s16 expectedDamagePlayer, expectedDamageOpponent;
+ PARAMETRIZE { expectedDamagePlayer = 204, expectedDamageOpponent = 201; }
+ PARAMETRIZE { expectedDamagePlayer = 201, expectedDamageOpponent = 198; }
+ PARAMETRIZE { expectedDamagePlayer = 199, expectedDamageOpponent = 196; }
+ PARAMETRIZE { expectedDamagePlayer = 196, expectedDamageOpponent = 193; }
+ PARAMETRIZE { expectedDamagePlayer = 195, expectedDamageOpponent = 192; }
+ PARAMETRIZE { expectedDamagePlayer = 193, expectedDamageOpponent = 190; }
+ PARAMETRIZE { expectedDamagePlayer = 190, expectedDamageOpponent = 187; }
+ PARAMETRIZE { expectedDamagePlayer = 189, expectedDamageOpponent = 186; }
+ PARAMETRIZE { expectedDamagePlayer = 187, expectedDamageOpponent = 184; }
+ PARAMETRIZE { expectedDamagePlayer = 184, expectedDamageOpponent = 181; }
+ PARAMETRIZE { expectedDamagePlayer = 183, expectedDamageOpponent = 180; }
+ PARAMETRIZE { expectedDamagePlayer = 181, expectedDamageOpponent = 178; }
+ PARAMETRIZE { expectedDamagePlayer = 178, expectedDamageOpponent = 175; }
+ PARAMETRIZE { expectedDamagePlayer = 177, expectedDamageOpponent = 174; }
+ PARAMETRIZE { expectedDamagePlayer = 174, expectedDamageOpponent = 172; }
+ PARAMETRIZE { expectedDamagePlayer = 172, expectedDamageOpponent = 169; }
+ GIVEN {
+ PLAYER(SPECIES_MAKUHITA) { Item(ITEM_PUNCHING_GLOVE); }
+ OPPONENT(SPECIES_MAKUHITA) { Item(ITEM_MUSCLE_BAND); }
+ } WHEN {
+ TURN {
+ MOVE(player, MOVE_DRAIN_PUNCH, WITH_RNG(RNG_DAMAGE_MODIFIER, i));
+ MOVE(opponent, MOVE_DRAIN_PUNCH, WITH_RNG(RNG_DAMAGE_MODIFIER, i));
+ }
+ }
+ SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAIN_PUNCH, player);
+ HP_BAR(opponent, captureDamage: &dmgPlayer);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAIN_PUNCH, opponent);
+ HP_BAR(player, captureDamage: &dmgOpponent);
+ }
+ THEN {
+ EXPECT_EQ(expectedDamagePlayer, dmgPlayer);
+ EXPECT_EQ(expectedDamageOpponent, dmgOpponent);
+ }
+}
+
+SINGLE_BATTLE_TEST("Gem boosted Damage calculation")
+{
+ s16 dmg;
+ s16 expectedDamage;
+ PARAMETRIZE { expectedDamage = 240; }
+ PARAMETRIZE { expectedDamage = 237; }
+ PARAMETRIZE { expectedDamage = 234; }
+ PARAMETRIZE { expectedDamage = 232; }
+ PARAMETRIZE { expectedDamage = 229; }
+ PARAMETRIZE { expectedDamage = 228; }
+ PARAMETRIZE { expectedDamage = 225; }
+ PARAMETRIZE { expectedDamage = 222; }
+ PARAMETRIZE { expectedDamage = 220; }
+ PARAMETRIZE { expectedDamage = 217; }
+ PARAMETRIZE { expectedDamage = 216; }
+ PARAMETRIZE { expectedDamage = 213; }
+ PARAMETRIZE { expectedDamage = 210; }
+ PARAMETRIZE { expectedDamage = 208; }
+ PARAMETRIZE { expectedDamage = 205; }
+ PARAMETRIZE { expectedDamage = 204; }
+ GIVEN {
+ PLAYER(SPECIES_MAKUHITA) { Item(ITEM_FIGHTING_GEM); }
+ OPPONENT(SPECIES_MAKUHITA);
+ } WHEN {
+ TURN {
+ MOVE(player, MOVE_DRAIN_PUNCH, WITH_RNG(RNG_DAMAGE_MODIFIER, i));
+ }
+ }
+ SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAIN_PUNCH, player);
+ HP_BAR(opponent, captureDamage: &dmg);
+ }
+ THEN {
+ EXPECT_EQ(expectedDamage, dmg);
+ }
+}
+
+#define NUM_DAMAGE_SPREADS (DMG_ROLL_PERCENT_HI - DMG_ROLL_PERCENT_LO) + 1
+
+static const s16 sThunderShockTransistorSpread[] = { 54, 55, 56, 57, 57, 58, 59, 60, 60, 60, 61, 62, 63, 63, 64, 65 };
+static const s16 sThunderShockRegularSpread[] = { 42, 42, 43, 43, 44, 45, 45, 45, 46, 46, 47, 48, 48, 48, 49, 50 };
+static const s16 sWildChargeTransistorSpread[] = { 123, 124, 126, 127, 129, 130, 132, 133, 135, 136, 138, 139, 141, 142, 144, 145 };
+static const s16 sWildChargeRegularSpread[] = { 94, 96, 96, 98, 99, 100, 101, 102, 103, 105, 105, 107, 108, 109, 110, 111 };
+
+DOUBLE_BATTLE_TEST("Transistor Damage calculation", s16 damage)
+{
+ s16 expectedDamageTransistorSpec = 0, expectedDamageRegularPhys = 0, expectedDamageRegularSpec = 0, expectedDamageTransistorPhys = 0;
+ s16 damagePlayerLeft, damagePlayerRight, damageOpponentLeft, damageOpponentRight;
+ for (u32 spread = 0; spread < 16; ++spread) {
+ PARAMETRIZE { expectedDamageTransistorSpec = sThunderShockTransistorSpread[spread],
+ expectedDamageRegularSpec = sThunderShockRegularSpread[spread],
+ expectedDamageTransistorPhys = sWildChargeTransistorSpread[spread],
+ expectedDamageRegularPhys = sWildChargeRegularSpread[spread];
+ }
+ }
+ GIVEN {
+ ASSUME(GetMoveType(MOVE_WILD_CHARGE) == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
+ ASSUME(GetMoveCategory(MOVE_WILD_CHARGE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_THUNDER_SHOCK) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(NUM_DAMAGE_SPREADS == 16);
+
+ PLAYER(SPECIES_REGIELEKI) { Ability(ABILITY_KLUTZ); }
+ PLAYER(SPECIES_REGIELEKI) { Ability(ABILITY_TRANSISTOR); }
+ OPPONENT(SPECIES_REGIELEKI) { Ability(ABILITY_KLUTZ); }
+ OPPONENT(SPECIES_REGIELEKI) { Ability(ABILITY_TRANSISTOR); }
+ } WHEN {
+ TURN {
+ MOVE(playerLeft, MOVE_THUNDER_SHOCK, target: opponentLeft, WITH_RNG(RNG_DAMAGE_MODIFIER, 15 - i));
+ MOVE(playerRight, MOVE_THUNDER_SHOCK, target: opponentRight, WITH_RNG(RNG_DAMAGE_MODIFIER, 15 - i));
+ MOVE(opponentLeft, MOVE_WILD_CHARGE, target: playerLeft, WITH_RNG(RNG_DAMAGE_MODIFIER, 15 - i));
+ MOVE(opponentRight, MOVE_WILD_CHARGE, target: playerRight, WITH_RNG(RNG_DAMAGE_MODIFIER, 15 - i));
+ }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER_SHOCK, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &damageOpponentLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER_SHOCK, playerRight);
+ HP_BAR(opponentRight, captureDamage: &damageOpponentRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_WILD_CHARGE, opponentLeft);
+ HP_BAR(playerLeft, captureDamage: &damagePlayerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_WILD_CHARGE, opponentRight);
+ HP_BAR(playerRight, captureDamage: &damagePlayerRight);
+ } THEN {
+ EXPECT_EQ(damageOpponentLeft, expectedDamageRegularSpec);
+ EXPECT_EQ(damageOpponentRight, expectedDamageTransistorSpec);
+ EXPECT_EQ(damagePlayerLeft, expectedDamageRegularPhys);
+ EXPECT_EQ(damagePlayerRight, expectedDamageTransistorPhys);
+ }
+}
diff --git a/test/battle/form_change/mega_evolution.c b/test/battle/form_change/mega_evolution.c
index 4c97c2c151..3d9d9cf507 100644
--- a/test/battle/form_change/mega_evolution.c
+++ b/test/battle/form_change/mega_evolution.c
@@ -108,7 +108,7 @@ SINGLE_BATTLE_TEST("Abilities replaced by Mega Evolution do not affect turn orde
DOUBLE_BATTLE_TEST("Mega Evolution happens after switching, but before Focus Punch-like Moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH);
+ ASSUME(GetMoveEffect(MOVE_FOCUS_PUNCH) == EFFECT_FOCUS_PUNCH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_VENUSAUR) { Item(ITEM_VENUSAURITE); }
OPPONENT(SPECIES_WYNAUT);
@@ -157,7 +157,7 @@ SINGLE_BATTLE_TEST("Regular Mega Evolution and Fervent Wish Mega Evolution can h
SINGLE_BATTLE_TEST("Mega Evolved Pokemon do not change abilities after fainting")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CRUNCH].makesContact == TRUE);
+ ASSUME(MoveMakesContact(MOVE_CRUNCH) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_GARCHOMP_MEGA].abilities[0] != ABILITY_ROUGH_SKIN);
ASSUME(gSpeciesInfo[SPECIES_GARCHOMP_MEGA].abilities[1] != ABILITY_ROUGH_SKIN);
ASSUME(gSpeciesInfo[SPECIES_GARCHOMP_MEGA].abilities[2] != ABILITY_ROUGH_SKIN);
diff --git a/test/battle/form_change/primal_reversion.c b/test/battle/form_change/primal_reversion.c
index 72e2a7e3c6..d7d956d64b 100644
--- a/test/battle/form_change/primal_reversion.c
+++ b/test/battle/form_change/primal_reversion.c
@@ -120,7 +120,7 @@ DOUBLE_BATTLE_TEST("Primal reversion's order is determined by Speed - player fas
SINGLE_BATTLE_TEST("Primal reversion happens after a mon is sent out after a mon is fainted")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET) {HP(1); }
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -156,7 +156,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens after a mon is switched in")
SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Eject Button")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
ASSUME(gItemsInfo[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON);
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_EJECT_BUTTON); }
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
@@ -177,7 +177,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Eject B
SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Red Card")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
ASSUME(gItemsInfo[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
@@ -197,7 +197,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Red Car
SINGLE_BATTLE_TEST("Primal reversion happens after the entry hazards damage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -239,7 +239,7 @@ SINGLE_BATTLE_TEST("Primal reversion happens immediately if it was brought in by
DOUBLE_BATTLE_TEST("Primal reversion triggers for multiple battlers if multiple fainted the previous turn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CATERPIE) { HP(1); }
PLAYER(SPECIES_RESHIRAM);
@@ -262,8 +262,8 @@ DOUBLE_BATTLE_TEST("Primal reversion triggers for multiple battlers if multiple
DOUBLE_BATTLE_TEST("Primal reversion triggers for all battlers if multiple fainted the previous turn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
- ASSUME(gMovesInfo[MOVE_EXPLOSION].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
+ ASSUME(GetMoveTarget(MOVE_EXPLOSION) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CATERPIE) { HP(1); }
PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); }
@@ -290,11 +290,11 @@ DOUBLE_BATTLE_TEST("Primal reversion triggers for all battlers if multiple faint
DOUBLE_BATTLE_TEST("Primal reversion and other switch-in effects trigger for all battlers if multiple fainted the previous turn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
- ASSUME(gMovesInfo[MOVE_EXPLOSION].target == MOVE_TARGET_FOES_AND_ALLY);
- ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
- ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES);
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
+ ASSUME(GetMoveTarget(MOVE_EXPLOSION) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
+ ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CATERPIE) { HP(1); }
PLAYER(SPECIES_SCRAFTY) { Ability(ABILITY_INTIMIDATE); }
diff --git a/test/battle/form_change/ultra_burst.c b/test/battle/form_change/ultra_burst.c
index 8eb21866f3..640db3f881 100644
--- a/test/battle/form_change/ultra_burst.c
+++ b/test/battle/form_change/ultra_burst.c
@@ -74,7 +74,7 @@ SINGLE_BATTLE_TEST("Ultra Burst affects turn order")
DOUBLE_BATTLE_TEST("Ultra Burst happens after switching, but before Focus Punch-like Moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH);
+ ASSUME(GetMoveEffect(MOVE_FOCUS_PUNCH) == EFFECT_FOCUS_PUNCH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_NECROZMA_DUSK_MANE) { Item(ITEM_ULTRANECROZIUM_Z); }
OPPONENT(SPECIES_WYNAUT);
diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c
index 374b4d55d5..0d06268864 100644
--- a/test/battle/gimmick/dynamax.c
+++ b/test/battle/gimmick/dynamax.c
@@ -58,7 +58,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns", u16 hp)
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FAKE_OUT].effect == EFFECT_FIRST_TURN_ONLY);
+ ASSUME(GetMoveEffect(MOVE_FAKE_OUT) == EFFECT_FIRST_TURN_ONLY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -73,7 +73,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be flinched")
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEAVY_SLAM].effect == EFFECT_HEAT_CRASH);
+ ASSUME(GetMoveEffect(MOVE_HEAVY_SLAM) == EFFECT_HEAT_CRASH);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -89,7 +89,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by weight-based mo
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FISSURE].effect == EFFECT_OHKO);
+ ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_MACHAMP) { Ability(ABILITY_NO_GUARD); }
} WHEN {
@@ -102,22 +102,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot be hit by OHKO moves")
}
}
-// can't be used at all in Raid, see "Documenting Dynamax"
-SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Destiny Bond")
-{
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET) { Speed(50); };
- OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
- } WHEN {
- TURN { MOVE(opponent, MOVE_DESTINY_BOND); MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); }
- } SCENE {
- MESSAGE("The opposing Wobbuffet used Destiny Bond!");
- MESSAGE("Wobbuffet used Max Strike!");
- MESSAGE("The opposing Wobbuffet fainted!");
- NONE_OF { HP_BAR(player); }
- }
-}
-
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge")
{
GIVEN {
@@ -136,8 +120,8 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are affected by Grudge")
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves, but still take damage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
- ASSUME(gMovesInfo[MOVE_WHIRLWIND].effect == EFFECT_ROAR);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
+ ASSUME(GetMoveEffect(MOVE_WHIRLWIND) == EFFECT_ROAR);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -158,7 +142,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing move
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by phazing moves but no block message is printed if they faint")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
PLAYER(SPECIES_WOBBUFFET) { HP(1); };
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -243,41 +227,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed o
}
}
-SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore")
-{
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_ENCORE); }
- TURN { MOVE(player, MOVE_EMBER); }
- } SCENE {
- MESSAGE("Wobbuffet used Max Strike!");
- MESSAGE("The opposing Wobbuffet used Encore!");
- MESSAGE("But it failed!");
- MESSAGE("Wobbuffet used Max Flare!");
- }
-}
-
-SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting")
-{
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; // yes, this speed is necessary
- OPPONENT(SPECIES_WOBBUFFET) { Speed(100); };
- } WHEN {
- TURN { MOVE(player, MOVE_ARM_THRUST, gimmick: GIMMICK_DYNAMAX); }
- TURN { MOVE(player, MOVE_ARM_THRUST); }
- TURN { MOVE(player, MOVE_ARM_THRUST); }
- TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); }
- } SCENE {
- MESSAGE("Wobbuffet used Max Knuckle!");
- MESSAGE("Wobbuffet used Max Knuckle!");
- MESSAGE("Wobbuffet used Max Knuckle!");
- MESSAGE("The opposing Wobbuffet used Encore!");
- MESSAGE("Wobbuffet used Arm Thrust!");
- }
-}
-
// Max Moves don't make contact, so Cursed Body doesn't need to be tested, but it is coded for.
SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled")
{
@@ -362,24 +311,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon lose their substitutes")
}
}
-SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon take double damage from Dynamax Cannon", s16 damage)
-{
- u32 dynamax;
- PARAMETRIZE { dynamax = GIMMICK_NONE; }
- PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
- GIVEN {
- ASSUME(gMovesInfo[MOVE_DYNAMAX_CANNON].effect == EFFECT_DYNAMAX_DOUBLE_DMG);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(player, MOVE_TACKLE, gimmick: dynamax); MOVE(opponent, MOVE_DYNAMAX_CANNON); }
- } SCENE {
- HP_BAR(player, captureDamage: &results[i].damage);
- } FINALLY {
- EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage);
- }
-}
-
SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 damage)
{
bool32 protected;
@@ -519,7 +450,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon cannot use Max Guard while holdi
}
}
-// Almost anything that calculates gBattleMoveDamage based on HP has been changed to non-Dynamax HP.
+// Almost anything that calculates damage based on HP has been changed to non-Dynamax HP.
// This includes Leftovers, Life Orb, Heal Pulse, Rocky Helmet, Sandstorm, etc. etc.
// There are some redundant cases (i.e Substitute) that can never be used by a Dynamaxed pokemon.
// Anything that is conditional based off max HP still uses gBattleMons[battler].maxHP.
@@ -531,7 +462,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Endeavor uses a Pokemon's non-Dynamax HP", s16 dam
PARAMETRIZE { dynamax = GIMMICK_NONE; }
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR);
+ ASSUME(GetMoveEffect(MOVE_ENDEAVOR) == EFFECT_ENDEAVOR);
PLAYER(SPECIES_WOBBUFFET) { Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
} WHEN {
@@ -550,7 +481,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Super Fang uses a Pokemon's non-Dynamax HP", s16 d
PARAMETRIZE { dynamax = GIMMICK_NONE; }
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG);
+ ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_SUPER_FANG);
PLAYER(SPECIES_WOBBUFFET) { Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
} WHEN {
@@ -569,7 +500,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Pain Split uses a Pokemon's non-Dynamax HP", s16 d
PARAMETRIZE { dynamax = GIMMICK_NONE; }
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_PAIN_SPLIT].effect == EFFECT_PAIN_SPLIT);
+ ASSUME(GetMoveEffect(MOVE_PAIN_SPLIT) == EFFECT_PAIN_SPLIT);
PLAYER(SPECIES_WOBBUFFET) { Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
} WHEN {
@@ -608,7 +539,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Heal Pulse heals based on a Pokemon's non-Dynamax
PARAMETRIZE { dynamax = GIMMICK_NONE; }
PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEAL_PULSE].effect == EFFECT_HEAL_PULSE);
+ ASSUME(GetMoveEffect(MOVE_HEAL_PULSE) == EFFECT_HEAL_PULSE);
PLAYER(SPECIES_WOBBUFFET) { HP(1); Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); Speed(100); }
} WHEN {
@@ -626,7 +557,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed")
{
GIVEN {
// Fails?: ASSUME(GetMaxMove(B_POSITION_PLAYER_LEFT, MOVE_TACKLE) == MOVE_MAX_STRIKE);
- ASSUME(gMovesInfo[MOVE_MAX_STRIKE].argument == MAX_EFFECT_LOWER_SPEED);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_STRIKE) == MAX_EFFECT_LOWER_SPEED);
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
PLAYER(SPECIES_WOBBUFFET) { Speed(80); }
} WHEN {
@@ -650,7 +581,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers single opponent's speed")
DOUBLE_BATTLE_TEST("(DYNAMAX) Max Strike lowers both opponents' speed")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_STRIKE].argument == MAX_EFFECT_LOWER_SPEED);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_STRIKE) == MAX_EFFECT_LOWER_SPEED);
PLAYER(SPECIES_WOBBUFFET) { Speed(80); }
PLAYER(SPECIES_WOBBUFFET) { Speed(79); }
OPPONENT(SPECIES_WOBBUFFET) {Speed(100); }
@@ -687,9 +618,9 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Knuckle raises both allies' attack")
{
s16 damage[4];
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_KNUCKLE].argument == MAX_EFFECT_RAISE_TEAM_ATTACK);
- ASSUME(gMovesInfo[MOVE_CLOSE_COMBAT].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_KNUCKLE) == MAX_EFFECT_RAISE_TEAM_ATTACK);
+ ASSUME(GetMoveCategory(MOVE_CLOSE_COMBAT) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -729,7 +660,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) Max Knuckle raises both allies' attack")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Flare sets up sunlight")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_FLARE].argument == MAX_EFFECT_SUN);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_FLARE) == MAX_EFFECT_SUN);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -745,7 +676,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Flare sets up sunlight")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Geyser sets up heavy rain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_GEYSER].argument == MAX_EFFECT_RAIN);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_GEYSER) == MAX_EFFECT_RAIN);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -761,7 +692,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Geyser sets up heavy rain")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Hailstorm sets up hail")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_HAILSTORM].argument == MAX_EFFECT_HAIL);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_HAILSTORM) == MAX_EFFECT_HAIL);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -777,7 +708,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Hailstorm sets up hail")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Rockfall sets up a sandstorm")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_ROCKFALL].argument == MAX_EFFECT_SANDSTORM);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_ROCKFALL) == MAX_EFFECT_SANDSTORM);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -794,7 +725,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Overgrowth sets up Grassy Terrain")
{
s32 maxHP = 490; // Because of recalculated stats upon Dynamaxing
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_OVERGROWTH].argument == MAX_EFFECT_GRASSY_TERRAIN);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_OVERGROWTH) == MAX_EFFECT_GRASSY_TERRAIN);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].baseHP == 190);
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(maxHP); HP(maxHP / 2); };
PLAYER(SPECIES_WOBBUFFET) { MaxHP(maxHP); HP(maxHP / 2); };
@@ -814,7 +745,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Overgrowth sets up Grassy Terrain")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Mindstorm sets up Psychic Terrain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_MINDSTORM].argument == MAX_EFFECT_PSYCHIC_TERRAIN);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_MINDSTORM) == MAX_EFFECT_PSYCHIC_TERRAIN);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -831,7 +762,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Mindstorm sets up Psychic Terrain")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Lightning sets up Electric Terrain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_LIGHTNING].argument == MAX_EFFECT_ELECTRIC_TERRAIN);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_LIGHTNING) == MAX_EFFECT_ELECTRIC_TERRAIN);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -846,7 +777,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Lightning sets up Electric Terrain")
SINGLE_BATTLE_TEST("(DYNAMAX) Max Starfall sets up Misty Terrain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAX_STARFALL].argument == MAX_EFFECT_MISTY_TERRAIN);
+ ASSUME(GetMoveMaxEffect(MOVE_MAX_STARFALL) == MAX_EFFECT_MISTY_TERRAIN);
OPPONENT(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
} WHEN {
@@ -861,7 +792,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Starfall sets up Misty Terrain")
SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_STONESURGE].argument == MAX_EFFECT_STEALTH_ROCK);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STONESURGE) == MAX_EFFECT_STEALTH_ROCK);
PLAYER(SPECIES_DREDNAW) { GigantamaxFactor(TRUE); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -881,7 +812,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Stonesurge sets up Stealth Rocks")
SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Steelsurge sets up sharp steel")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_STEELSURGE].argument == MAX_EFFECT_STEELSURGE);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STEELSURGE) == MAX_EFFECT_STEELSURGE);
PLAYER(SPECIES_COPPERAJAH) { GigantamaxFactor(TRUE); }
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_HATTERENE);
@@ -912,7 +843,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abili
PARAMETRIZE { move = MOVE_WATER_GUN; }
PARAMETRIZE { move = MOVE_HYDRO_CANNON; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_HYDROSNIPE].argument == MAX_EFFECT_FIXED_POWER);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_HYDROSNIPE) == MAX_EFFECT_FIXED_POWER);
PLAYER(SPECIES_INTELEON) { GigantamaxFactor(TRUE); }
OPPONENT(SPECIES_ARCTOVISH) { Ability(ABILITY_WATER_ABSORB); }
} WHEN {
@@ -928,7 +859,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) G-Max Hydrosnipe has fixed power and ignores abili
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Volt Crash paralyzes both opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_VOLT_CRASH].argument == MAX_EFFECT_PARALYZE_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_VOLT_CRASH) == MAX_EFFECT_PARALYZE_FOES);
PLAYER(SPECIES_PIKACHU) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_PICHU);
OPPONENT(SPECIES_WOBBUFFET);
@@ -955,7 +886,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponen
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = STATUS1_PARALYSIS; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = STATUS1_POISON; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_STUN_SHOCK].argument == MAX_EFFECT_POISON_PARALYZE_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STUN_SHOCK) == MAX_EFFECT_POISON_PARALYZE_FOES);
PLAYER(SPECIES_TOXTRICITY) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_TOXEL);
OPPONENT(SPECIES_WOBBUFFET);
@@ -992,7 +923,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock paralyzes or poisons both opponen
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Stun Shock chooses statuses before considering immunities")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_STUN_SHOCK].argument == MAX_EFFECT_POISON_PARALYZE_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_STUN_SHOCK) == MAX_EFFECT_POISON_PARALYZE_FOES);
PLAYER(SPECIES_TOXTRICITY) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_TOXEL);
OPPONENT(SPECIES_GARBODOR);
@@ -1025,7 +956,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = STATUS1_POISON; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = STATUS1_SLEEP; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_BEFUDDLE].argument == MAX_EFFECT_EFFECT_SPORE_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_BEFUDDLE) == MAX_EFFECT_EFFECT_SPORE_FOES);
PLAYER(SPECIES_BUTTERFREE) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_CATERPIE);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1069,7 +1000,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Befuddle paralyzes, poisons, or sleeps both
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and generates money")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_GOLD_RUSH].argument == MAX_EFFECT_CONFUSE_FOES_PAY_DAY);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_GOLD_RUSH) == MAX_EFFECT_CONFUSE_FOES_PAY_DAY);
PLAYER(SPECIES_MEOWTH) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_PERSIAN);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1089,7 +1020,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Gold Rush confuses both opponents and genera
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_SMITE].argument == MAX_EFFECT_CONFUSE_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SMITE) == MAX_EFFECT_CONFUSE_FOES);
PLAYER(SPECIES_HATTERENE) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_HATENNA);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1108,7 +1039,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Smite confuses both opponents")
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possible")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_CUDDLE].argument == MAX_EFFECT_INFATUATE_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_CUDDLE) == MAX_EFFECT_INFATUATE_FOES);
PLAYER(SPECIES_EEVEE) { Gender(MON_MALE); GigantamaxFactor(TRUE); }
PLAYER(SPECIES_EEVEE);
OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); }
@@ -1129,7 +1060,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Cuddle infatuates both opponents, if possibl
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Terror traps both opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_TERROR].argument == MAX_EFFECT_MEAN_LOOK);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_TERROR) == MAX_EFFECT_MEAN_LOOK);
PLAYER(SPECIES_GENGAR) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_GASTLY);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1150,7 +1081,7 @@ TO_DO_BATTLE_TEST("(DYNAMAX) Baton Pass passes G-Max Terror's escape prevention
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Meltdown torments both opponents for 3 turns")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_MELTDOWN].argument == MAX_EFFECT_TORMENT_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_MELTDOWN) == MAX_EFFECT_TORMENT_FOES);
PLAYER(SPECIES_MELMETAL) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_MELTAN);
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SPLASH, MOVE_CELEBRATE); }
@@ -1187,7 +1118,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Wildfire sets a field effect that damages no
{
s16 damage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_WILDFIRE].argument == MAX_EFFECT_WILDFIRE);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_WILDFIRE) == MAX_EFFECT_WILDFIRE);
PLAYER(SPECIES_CHARIZARD) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_CHARMANDER);
OPPONENT(SPECIES_WOBBUFFET) { HP(600); MaxHP(600); }
@@ -1233,7 +1164,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Replenish recycles allies' berries 50\% of t
{
PASSES_RANDOMLY(1, 2, RNG_G_MAX_REPLENISH);
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_REPLENISH].argument == MAX_EFFECT_RECYCLE_BERRIES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_REPLENISH) == MAX_EFFECT_RECYCLE_BERRIES);
PLAYER(SPECIES_SNORLAX) { Item(ITEM_APICOT_BERRY); GigantamaxFactor(TRUE); }
PLAYER(SPECIES_MUNCHLAX) { Item(ITEM_APICOT_BERRY); Ability(ABILITY_THICK_FAT); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_APICOT_BERRY); }
@@ -1261,8 +1192,8 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Snooze makes only the target drowsy")
{
PASSES_RANDOMLY(1, 2, RNG_G_MAX_SNOOZE);
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_SNOOZE].argument == MAX_EFFECT_YAWN_FOE);
- ASSUME(gMovesInfo[MOVE_DARK_PULSE].category == DAMAGE_CATEGORY_SPECIAL); // Otherwise, Blissey faints.
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SNOOZE) == MAX_EFFECT_YAWN_FOE);
+ ASSUME(GetMoveCategory(MOVE_DARK_PULSE) == DAMAGE_CATEGORY_SPECIAL); // Otherwise, Blissey faints.
PLAYER(SPECIES_GRIMMSNARL) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_IMPIDIMP);
OPPONENT(SPECIES_BLISSEY);
@@ -1285,7 +1216,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health")
{
s16 damage1, damage2;
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_FINALE].argument == MAX_EFFECT_HEAL_TEAM);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_FINALE) == MAX_EFFECT_HEAL_TEAM);
PLAYER(SPECIES_ALCREMIE) { HP(1); GigantamaxFactor(TRUE); }
PLAYER(SPECIES_MILCERY) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -1305,7 +1236,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Finale heals allies by 1/6 of their health")
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_SWEETNESS].argument == MAX_EFFECT_AROMATHERAPY);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SWEETNESS) == MAX_EFFECT_AROMATHERAPY);
PLAYER(SPECIES_APPLETUN) { Status1(STATUS1_POISON); GigantamaxFactor(TRUE); }
PLAYER(SPECIES_APPLIN) { Status1(STATUS1_POISON); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -1325,7 +1256,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Sweetness cures allies' status conditions")
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Centiferno traps both opponents in Fire Spin")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_CENTIFERNO].argument == MAX_EFFECT_FIRE_SPIN_FOES);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_CENTIFERNO) == MAX_EFFECT_FIRE_SPIN_FOES);
PLAYER(SPECIES_CENTISKORCH) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_SIZZLIPEDE);
PLAYER(SPECIES_SIZZLIPEDE);
@@ -1354,7 +1285,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Chi Strike boosts allies' crit chance")
u32 j;
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_6);
- ASSUME(gMovesInfo[MOVE_G_MAX_CHI_STRIKE].argument == MAX_EFFECT_CRIT_PLUS);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_CHI_STRIKE) == MAX_EFFECT_CRIT_PLUS);
PLAYER(SPECIES_MACHAMP) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_MACHOP);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1385,8 +1316,8 @@ TO_DO_BATTLE_TEST("(DYNAMAX) Baton Pass doesn't pass G-Max Chi Strike's effect")
DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Depletion takes away 2 PP from the target's last move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_CLAW].category == DAMAGE_CATEGORY_PHYSICAL); // Otherwise Sableye faints.
- ASSUME(gMovesInfo[MOVE_G_MAX_DEPLETION].argument == MAX_EFFECT_SPITE);
+ ASSUME(GetMoveCategory(MOVE_DRAGON_CLAW) == DAMAGE_CATEGORY_PHYSICAL); // Otherwise Sableye faints.
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_DEPLETION) == MAX_EFFECT_SPITE);
PLAYER(SPECIES_DURALUDON) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_WYNAUT);
// Dynamax behaves weird with test turn order because stats are recalculated.
@@ -1408,7 +1339,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage"
PARAMETRIZE { protect = TRUE; }
PARAMETRIZE { protect = FALSE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_G_MAX_ONE_BLOW].argument == MAX_EFFECT_BYPASS_PROTECT);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_ONE_BLOW) == MAX_EFFECT_BYPASS_PROTECT);
PLAYER(SPECIES_URSHIFU) { GigantamaxFactor(TRUE); }
PLAYER(SPECIES_KUBFU);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1431,6 +1362,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage"
}
// Bug Testing
+// This test will fail if it's the first test a thread runs
DOUBLE_BATTLE_TEST("(DYNAMAX) Max Flare doesn't softlock the game when fainting player partner")
{
GIVEN {
@@ -1465,7 +1397,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't execute effects on fainted battler
SINGLE_BATTLE_TEST("(DYNAMAX) Moxie clones can be triggered by Max Moves fainting opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATERFALL].power > 0);
+ ASSUME(GetMovePower(MOVE_WATERFALL) > 0);
PLAYER(SPECIES_GYARADOS) { Ability(ABILITY_MOXIE); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WYNAUT);
@@ -1507,11 +1439,11 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass absorbing abilities")
PARAMETRIZE { move = MOVE_VINE_WHIP; ability = ABILITY_SAP_SIPPER; species = SPECIES_MILTANK; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_MUD_BOMB].type == TYPE_GROUND);
- ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_MUD_BOMB) == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c
index a9e8fca871..709e658c38 100644
--- a/test/battle/gimmick/terastal.c
+++ b/test/battle/gimmick/terastal.c
@@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing boosts moves of the same type to 60 BP
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ABSORB].power == 20);
+ ASSUME(GetMovePower(MOVE_ABSORB) == 20);
PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_GRASS); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -113,7 +113,7 @@ SINGLE_BATTLE_TEST("(TERA) Terastallization's 60 BP floor occurs after Technicia
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEGA_DRAIN].power == 40);
+ ASSUME(GetMovePower(MOVE_MEGA_DRAIN) == 40);
PLAYER(SPECIES_MR_MIME) { Ability(ABILITY_TECHNICIAN); TeraType(TYPE_GRASS); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -393,7 +393,7 @@ SINGLE_BATTLE_TEST("(TERA) Double Shock does not remove the user's Electric type
{
s16 damage[4];
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
PLAYER(SPECIES_PICHU) { TeraType(TYPE_ELECTRIC); }
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(SPECIES_WOBBUFFET);
@@ -608,8 +608,8 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the Stellar type boosts all moves
{
s16 damage[4];
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEGA_DRAIN].power == 40);
- ASSUME(gMovesInfo[MOVE_BUBBLE].power == 40);
+ ASSUME(GetMovePower(MOVE_MEGA_DRAIN) == 40);
+ ASSUME(GetMovePower(MOVE_BUBBLE) == 40);
PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -688,7 +688,7 @@ SINGLE_BATTLE_TEST("(TERA) Stellar type's one-time boost factors in dynamically-
{
s16 damage[4];
GIVEN {
- ASSUME(gMovesInfo[MOVE_WEATHER_BALL].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_WEATHER_BALL) == TYPE_NORMAL);
PLAYER(SPECIES_PELIPPER) { Ability(ABILITY_DRIZZLE); TeraType(TYPE_STELLAR); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -731,8 +731,8 @@ SINGLE_BATTLE_TEST("(TERA) Terapagos retains the Stellar type boost at all times
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_MACH_PUNCH; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_MACH_PUNCH].type != TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_MACH_PUNCH) != TYPE_NORMAL);
PLAYER(SPECIES_TERAPAGOS);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/gimmick/zmove.c b/test/battle/gimmick/zmove.c
index eb44184e5a..358e38d031 100644
--- a/test/battle/gimmick/zmove.c
+++ b/test/battle/gimmick/zmove.c
@@ -6,7 +6,7 @@
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves do not retain priority")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_QUICK_ATTACK) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves do not retain priority")
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves are not affected by -ate abilities")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
ASSUME(gSpeciesInfo[SPECIES_SWELLOW].types[1] == TYPE_FLYING);
PLAYER(SPECIES_AURORUS) { Ability(ABILITY_REFRIGERATE); Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_SWELLOW);
@@ -38,8 +38,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves are not affected by -ate abilities")
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves are affected by Ion Deluge")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_ION_DELUGE].effect == EFFECT_ION_DELUGE);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_SWELLOW);
} WHEN {
@@ -57,8 +57,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves deal 1/4 damage through protect", s16 damag
PARAMETRIZE { protected = TRUE; }
PARAMETRIZE { protected = FALSE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
+ ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -77,7 +77,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves deal 1/4 damage through protect", s16 damag
SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_RESET_STATS clears a battler's negative stat stages")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_LEECH_SEED].zMove.effect == Z_EFFECT_RESET_STATS);
+ ASSUME(GetMoveZEffect(MOVE_LEECH_SEED) == Z_EFFECT_RESET_STATS);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_RESET_STATS clears a battler's negative st
SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_ALL_STATS_UP raises all of a battler's stat stages by one")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CELEBRATE].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_CELEBRATE].zMove.effect == Z_EFFECT_ALL_STATS_UP_1);
+ ASSUME(GetMoveType(MOVE_CELEBRATE) == TYPE_NORMAL);
+ ASSUME(GetMoveZEffect(MOVE_CELEBRATE) == Z_EFFECT_ALL_STATS_UP_1);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -118,8 +118,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_BOOST_CRITS raises a battler's critical hi
{
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN {
- ASSUME(gMovesInfo[MOVE_FORESIGHT].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_FORESIGHT].zMove.effect == Z_EFFECT_BOOST_CRITS);
+ ASSUME(GetMoveType(MOVE_FORESIGHT) == TYPE_NORMAL);
+ ASSUME(GetMoveZEffect(MOVE_FORESIGHT) == Z_EFFECT_BOOST_CRITS);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -136,8 +136,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_BOOST_CRITS raises a battler's critical hi
DOUBLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_FOLLOW_ME redirects attacks to the user")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DESTINY_BOND].type == TYPE_GHOST);
- ASSUME(gMovesInfo[MOVE_DESTINY_BOND].zMove.effect == Z_EFFECT_FOLLOW_ME);
+ ASSUME(GetMoveType(MOVE_DESTINY_BOND) == TYPE_GHOST);
+ ASSUME(GetMoveZEffect(MOVE_DESTINY_BOND) == Z_EFFECT_FOLLOW_ME);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GHOSTIUM_Z); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -157,8 +157,8 @@ DOUBLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_FOLLOW_ME redirects attacks to the user")
SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_RESTORE_REPLACEMENT_HP fully heals the replacement battler's HP")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_PARTING_SHOT].type == TYPE_DARK);
- ASSUME(gMovesInfo[MOVE_PARTING_SHOT].zMove.effect == Z_EFFECT_RESTORE_REPLACEMENT_HP);
+ ASSUME(GetMoveType(MOVE_PARTING_SHOT) == TYPE_DARK);
+ ASSUME(GetMoveZEffect(MOVE_PARTING_SHOT) == Z_EFFECT_RESTORE_REPLACEMENT_HP);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_DARKINIUM_Z); }
PLAYER(SPECIES_WYNAUT) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -181,11 +181,11 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_CURSE activates Z_EFFECT_RECOVER_HP or Z_E
PARAMETRIZE { species = SPECIES_WOBBUFFET; }
PARAMETRIZE { species = SPECIES_DUSCLOPS; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_CURSE].type == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_CURSE) == TYPE_GHOST);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_GHOST);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_GHOST);
ASSUME(gSpeciesInfo[SPECIES_DUSCLOPS].types[0] == TYPE_GHOST);
- ASSUME(gMovesInfo[MOVE_CURSE].zMove.effect == Z_EFFECT_CURSE);
+ ASSUME(GetMoveZEffect(MOVE_CURSE) == Z_EFFECT_CURSE);
PLAYER(species) { Item(ITEM_GHOSTIUM_Z); HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -218,8 +218,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z_EFFECT_CURSE activates Z_EFFECT_RECOVER_HP or Z_E
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stages and copies the last used non-status move as a Z-Move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].type == TYPE_FLYING);
- ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].zMove.effect == Z_EFFECT_ATK_UP_2);
+ ASSUME(GetMoveType(MOVE_MIRROR_MOVE) == TYPE_FLYING);
+ ASSUME(GetMoveZEffect(MOVE_MIRROR_MOVE) == Z_EFFECT_ATK_UP_2);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FLYINIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -240,8 +240,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stage
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stages and copies the last used status move regularly")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].type == TYPE_FLYING);
- ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].zMove.effect == Z_EFFECT_ATK_UP_2);
+ ASSUME(GetMoveType(MOVE_MIRROR_MOVE) == TYPE_FLYING);
+ ASSUME(GetMoveZEffect(MOVE_MIRROR_MOVE) == Z_EFFECT_ATK_UP_2);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FLYINIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -259,8 +259,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Mirror Move raises the user's attack by two stage
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Copycat raises the user's accuracy by one stage and copies the last used non-status move as a Z-Move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_COPYCAT].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_COPYCAT].zMove.effect == Z_EFFECT_ACC_UP_1);
+ ASSUME(GetMoveType(MOVE_COPYCAT) == TYPE_NORMAL);
+ ASSUME(GetMoveZEffect(MOVE_COPYCAT) == Z_EFFECT_ACC_UP_1);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -281,8 +281,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Me First raises the user's speed by two stages an
PARAMETRIZE { meFirst = TRUE; }
PARAMETRIZE { meFirst = FALSE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ME_FIRST].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_ME_FIRST].zMove.effect == Z_EFFECT_SPD_UP_2);
+ ASSUME(GetMoveType(MOVE_ME_FIRST) == TYPE_NORMAL);
+ ASSUME(GetMoveZEffect(MOVE_ME_FIRST) == Z_EFFECT_SPD_UP_2);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -313,7 +313,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Nature Power transforms into different Z-Moves ba
PARAMETRIZE { terrainMove = MOVE_GRASSY_TERRAIN; zMove = gTypesInfo[TYPE_GRASS].zMove; }
PARAMETRIZE { terrainMove = MOVE_MISTY_TERRAIN; zMove = gTypesInfo[TYPE_FAIRY].zMove; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_NATURE_POWER].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_NATURE_POWER) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -334,7 +334,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Hidden Power always transforms into Breakneck Bli
PARAMETRIZE { iv = 21; }
PARAMETRIZE { iv = 31; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_HIDDEN_POWER) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); AttackIV(iv); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -354,7 +354,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Weather Ball transforms into different Z-Moves ba
PARAMETRIZE { weatherMove = MOVE_SANDSTORM; zMove = gTypesInfo[TYPE_ROCK].zMove; }
PARAMETRIZE { weatherMove = MOVE_HAIL; zMove = gTypesInfo[TYPE_ICE].zMove; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_WEATHER_BALL].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_WEATHER_BALL) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -370,7 +370,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Weather Ball transforms into different Z-Moves ba
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk transforms a used non-status move into a Z-Move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SLEEP_TALK].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_SLEEP_TALK) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_ABSORB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -385,7 +385,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk transforms a used non-status move into
SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk turns Weather Ball into Breakneck Blitz even under rain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SLEEP_TALK].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_SLEEP_TALK) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_WEATHER_BALL); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -400,7 +400,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Sleep Talk turns Weather Ball into Breakneck Blit
SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves and deals 25% of maximum HP to the user")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FIRIUM_Z); }
OPPONENT(SPECIES_VIVILLON);
} WHEN {
@@ -417,8 +417,8 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves and deals 25% of ma
DOUBLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves (from Z-Mirror Move)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].type == TYPE_FLYING);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_MIRROR_MOVE) == TYPE_FLYING);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FLYINIUM_Z); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -436,8 +436,8 @@ DOUBLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves (from Z-Mirror Move
SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves but not boosts granted")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_WILL_O_WISP].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_WILL_O_WISP].zMove.effect == Z_EFFECT_ATK_UP_1);
+ ASSUME(GetMoveType(MOVE_WILL_O_WISP) == TYPE_FIRE);
+ ASSUME(GetMoveZEffect(MOVE_WILL_O_WISP) == Z_EFFECT_ATK_UP_1);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FIRIUM_Z); }
OPPONENT(SPECIES_VIVILLON);
} WHEN {
@@ -455,7 +455,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Powder blocks Fire type Z-Moves but not boosts gran
DOUBLE_BATTLE_TEST("(Z-MOVE) Instruct fails if the target last used a Z-Move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -474,7 +474,7 @@ DOUBLE_BATTLE_TEST("(Z-MOVE) Instruct fails if the target last used a Z-Move")
DOUBLE_BATTLE_TEST("(Z-MOVE) Dancer does not use a Z-Move if the battler has used a Z-Move the same turn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_DANCER); Item(ITEM_NORMALIUM_Z); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -498,7 +498,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Light That Burns the Sky uses the battler's highest
PARAMETRIZE { useSwordsDance = FALSE; }
PARAMETRIZE { useSwordsDance = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
PLAYER(SPECIES_NECROZMA_DUSK_MANE) { Item(ITEM_ULTRANECROZIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1000); MaxHP(1000); }; // hits hard lol
} WHEN {
@@ -521,7 +521,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) 10,000,000 Volt Thunderbolt has an increased critic
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_6);
- ASSUME(gMovesInfo[MOVE_10_000_000_VOLT_THUNDERBOLT].criticalHitStage == 2);
+ ASSUME(GetMoveCriticalHitStage(MOVE_10_000_000_VOLT_THUNDERBOLT) == 2);
PLAYER(SPECIES_PIKACHU_PARTNER) { Item(ITEM_PIKASHUNIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -536,7 +536,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) 10,000,000 Volt Thunderbolt has an increased critic
SINGLE_BATTLE_TEST("(Z-MOVE) Stoked Sparksurfer paralyzes the target")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STOKED_SPARKSURFER].additionalEffects[0].moveEffect == MOVE_EFFECT_PARALYSIS);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_STOKED_SPARKSURFER, 0)->moveEffect == MOVE_EFFECT_PARALYSIS);
PLAYER(SPECIES_RAICHU_ALOLA) { Item(ITEM_ALORAICHIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -551,7 +551,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Stoked Sparksurfer paralyzes the target")
SINGLE_BATTLE_TEST("(Z-MOVE) Extreme Evoboost boosts all the user's stats by two stages")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXTREME_EVOBOOST].effect == EFFECT_EXTREME_EVOBOOST);
+ ASSUME(GetMoveEffect(MOVE_EXTREME_EVOBOOST) == EFFECT_EXTREME_EVOBOOST);
PLAYER(SPECIES_EEVEE) { Item(ITEM_EEVIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -571,7 +571,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Extreme Evoboost boosts all the user's stats by two
SINGLE_BATTLE_TEST("(Z-MOVE) Genesis Supernova sets up psychic terrain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_GENESIS_SUPERNOVA].effect == EFFECT_HIT_SET_REMOVE_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_GENESIS_SUPERNOVA) == EFFECT_HIT_SET_REMOVE_TERRAIN);
PLAYER(SPECIES_MEW) { Item(ITEM_MEWNIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -588,7 +588,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Genesis Supernova sets up psychic terrain")
SINGLE_BATTLE_TEST("(Z-MOVE) Splintered Stormshards removes terrain")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPLINTERED_STORMSHARDS].effect == EFFECT_HIT_SET_REMOVE_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_SPLINTERED_STORMSHARDS) == EFFECT_HIT_SET_REMOVE_TERRAIN);
PLAYER(SPECIES_LYCANROC_DUSK) { Item(ITEM_LYCANIUM_Z); }
OPPONENT(SPECIES_TAPU_LELE) { Ability(ABILITY_PSYCHIC_SURGE); HP(1000); MaxHP(1000); }
} WHEN {
@@ -606,7 +606,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Splintered Stormshards removes terrain")
SINGLE_BATTLE_TEST("(Z-MOVE) Clangorous Soulblaze boosts all the user's stats by one stage")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CLANGOROUS_SOULBLAZE].additionalEffects[0].moveEffect == MOVE_EFFECT_ALL_STATS_UP);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_CLANGOROUS_SOULBLAZE, 0)->moveEffect == MOVE_EFFECT_ALL_STATS_UP);
PLAYER(SPECIES_KOMMO_O) { Item(ITEM_KOMMONIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -626,7 +626,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Clangorous Soulblaze boosts all the user's stats by
SINGLE_BATTLE_TEST("(Z-MOVE) Guardian of Alola deals 75\% of the target's current HP")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_GUARDIAN_OF_ALOLA].effect == EFFECT_GUARDIAN_OF_ALOLA);
+ ASSUME(GetMoveEffect(MOVE_GUARDIAN_OF_ALOLA) == EFFECT_GUARDIAN_OF_ALOLA);
PLAYER(SPECIES_TAPU_FINI) { Item(ITEM_TAPUNIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -662,7 +662,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Revelation Dance always transforms into Breakneck
PARAMETRIZE { species = SPECIES_ORICORIO_POM_POM; }
PARAMETRIZE { species = SPECIES_ORICORIO_SENSU; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_REVELATION_DANCE) == TYPE_NORMAL);
PLAYER(species) { Item(ITEM_NORMALIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/hold_effect/air_balloon.c b/test/battle/hold_effect/air_balloon.c
index 293e1d80ca..302a0e6397 100644
--- a/test/battle/hold_effect/air_balloon.c
+++ b/test/battle/hold_effect/air_balloon.c
@@ -4,9 +4,9 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_AIR_BALLOON].holdEffect == HOLD_EFFECT_AIR_BALLOON);
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND);
- ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_GROUND);
- ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
+ ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_GROUND);
+ ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE);
}
SINGLE_BATTLE_TEST("Air Balloon prevents the holder from taking damage from ground type moves")
diff --git a/test/battle/hold_effect/attack_up.c b/test/battle/hold_effect/attack_up.c
index 383e564ce6..63203e588a 100644
--- a/test/battle/hold_effect/attack_up.c
+++ b/test/battle/hold_effect/attack_up.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Liechi Berry raises the holder's Attack by one stage when HP drops to 1/4 or below")
diff --git a/test/battle/hold_effect/berserk_gene.c b/test/battle/hold_effect/berserk_gene.c
index 59f78c1a12..1ff601fc83 100644
--- a/test/battle/hold_effect/berserk_gene.c
+++ b/test/battle/hold_effect/berserk_gene.c
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Berserk Gene sharply raises attack at the start of a single
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_BERSERK_GENE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -37,7 +37,7 @@ DOUBLE_BATTLE_TEST("Berserk Gene sharply raises attack at the start of a double
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_BERSERK_GENE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Berserk Gene activates on switch in", s16 damage)
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_BERSERK_GENE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -91,7 +91,7 @@ SINGLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but s
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_BERSERK_GENE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_OWN_TEMPO); Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -122,7 +122,7 @@ DOUBLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but s
PARAMETRIZE { item = ITEM_BERSERK_GENE; positionLeft = TRUE; }
PARAMETRIZE { item = ITEM_BERSERK_GENE; positionLeft = FALSE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
if (positionLeft) {
PLAYER(SPECIES_SLOWBRO) { Ability(ABILITY_OWN_TEMPO); Item(item); }
PLAYER(SPECIES_WOBBUFFET);
@@ -156,7 +156,7 @@ DOUBLE_BATTLE_TEST("Berserk Gene does not confuse a Pokemon with Own Tempo but s
SINGLE_BATTLE_TEST("Berserk Gene does not confuse on Misty Terrain but still raises attack sharply")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_TAPU_FINI) { Ability(ABILITY_MISTY_SURGE); Item(ITEM_BERSERK_GENE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/hold_effect/blunder_policy.c b/test/battle/hold_effect/blunder_policy.c
new file mode 100644
index 0000000000..e9215b3eb2
--- /dev/null
+++ b/test/battle/hold_effect/blunder_policy.c
@@ -0,0 +1,67 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(gItemsInfo[ITEM_BLUNDER_POLICY].holdEffect == HOLD_EFFECT_BLUNDER_POLICY);
+}
+
+SINGLE_BATTLE_TEST("Blunder Policy raises the users speed by 2 stages if the user misses")
+{
+ PASSES_RANDOMLY(3, 10, RNG_ACCURACY);
+ GIVEN {
+ ASSUME(GetMoveAccuracy(MOVE_FOCUS_BLAST) == 70);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_FOCUS_BLAST); }
+ } SCENE {
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ } THEN {
+ EXPECT(player->item == ITEM_NONE);
+ EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 2);
+ }
+}
+
+
+SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to an immunity")
+{
+ PASSES_RANDOMLY(10, 10, RNG_ACCURACY);
+ GIVEN {
+ ASSUME(GetMoveAccuracy(MOVE_FOCUS_BLAST) == 70);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); }
+ OPPONENT(SPECIES_GASTLY);
+ } WHEN {
+ TURN { MOVE(player, MOVE_FOCUS_BLAST); }
+ } SCENE {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ }
+ } THEN {
+ EXPECT(player->item == ITEM_BLUNDER_POLICY);
+ EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Blunder Policy will never trigger if the move fails due to Protect")
+{
+ PASSES_RANDOMLY(10, 10, RNG_ACCURACY);
+ GIVEN {
+ ASSUME(GetMoveAccuracy(MOVE_FOCUS_BLAST) == 70);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_BLUNDER_POLICY); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_FOCUS_BLAST); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_BLAST, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ }
+ } THEN {
+ EXPECT(player->item == ITEM_BLUNDER_POLICY);
+ EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
+ }
+}
diff --git a/test/battle/hold_effect/booster_energy.c b/test/battle/hold_effect/booster_energy.c
index a63f462b72..f6f44a272c 100644
--- a/test/battle/hold_effect/booster_energy.c
+++ b/test/battle/hold_effect/booster_energy.c
@@ -143,7 +143,7 @@ SINGLE_BATTLE_TEST("Booster Energy increases special attack by 30% if it is the
PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_BOOSTER_ENERGY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(species) { Attack(100); Defense(100); Speed(100); SpAttack(110); SpDefense(100); Ability(ability); Item(item); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); };
} WHEN {
@@ -169,7 +169,7 @@ SINGLE_BATTLE_TEST("Booster Energy increases special defense by 30% if it is the
PARAMETRIZE { species = SPECIES_IRON_MOTH; ability = ABILITY_QUARK_DRIVE; item = ITEM_BOOSTER_ENERGY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROUND].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(species) { Attack(100); Defense(100); Speed(100); SpAttack(100); SpDefense(110); Ability(ability); Item(item); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); };
} WHEN {
@@ -209,3 +209,28 @@ SINGLE_BATTLE_TEST("Booster Energy can't be tricked if a Paradox species is invo
MESSAGE("But it failed!");
}
}
+
+DOUBLE_BATTLE_TEST("Booster Energy triggers correctly for all battlers if multiple fainted the previous turn")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_CATERPIE) { HP(1); }
+ PLAYER(SPECIES_GOUGING_FIRE) { Item(ITEM_BOOSTER_ENERGY); }
+ PLAYER(SPECIES_IRON_MOTH) { Item(ITEM_BOOSTER_ENERGY); }
+ OPPONENT(SPECIES_CATERPIE) { HP(1); }
+ OPPONENT(SPECIES_CATERPIE) { HP(1); }
+ OPPONENT(SPECIES_FLUTTER_MANE) { Item(ITEM_BOOSTER_ENERGY); }
+ OPPONENT(SPECIES_CATERPIE);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_EXPLOSION);
+ SEND_OUT(opponentRight, 3);
+ SEND_OUT(opponentLeft, 2);
+ SEND_OUT(playerRight, 3);
+ SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, playerLeft);
+ ABILITY_POPUP(playerLeft, ABILITY_PROTOSYNTHESIS);
+ ABILITY_POPUP(playerRight, ABILITY_QUARK_DRIVE);
+ ABILITY_POPUP(opponentLeft, ABILITY_PROTOSYNTHESIS);
+ }
+}
diff --git a/test/battle/hold_effect/clear_amulet.c b/test/battle/hold_effect/clear_amulet.c
index d0666ff3a9..cc143c51e1 100644
--- a/test/battle/hold_effect/clear_amulet.c
+++ b/test/battle/hold_effect/clear_amulet.c
@@ -42,13 +42,13 @@ SINGLE_BATTLE_TEST("Clear Amulet prevents stat reducing effects")
PARAMETRIZE { move = MOVE_SAND_ATTACK; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN);
- ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN);
- ASSUME(gMovesInfo[MOVE_FAKE_TEARS].effect == EFFECT_SPECIAL_DEFENSE_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SCARY_FACE].effect == EFFECT_SPEED_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SWEET_SCENT].effect == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN));
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN);
+ ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_FAKE_TEARS) == EFFECT_SPECIAL_DEFENSE_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_SCARY_FACE) == EFFECT_SPEED_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_SWEET_SCENT) == (B_UPDATED_MOVE_DATA >= GEN_6 ? EFFECT_EVASION_DOWN_2 : EFFECT_EVASION_DOWN));
+ ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_CLEAR_AMULET); };
} WHEN {
diff --git a/test/battle/hold_effect/covert_cloak.c b/test/battle/hold_effect/covert_cloak.c
index b55b1492da..150ddcbba3 100644
--- a/test/battle/hold_effect/covert_cloak.c
+++ b/test/battle/hold_effect/covert_cloak.c
@@ -127,7 +127,6 @@ SINGLE_BATTLE_TEST("Covert Cloak does not block self-targeting effects, primary
DOUBLE_BATTLE_TEST("Covert Cloak does or does not block Sparkling Aria depending on number of targets hit")
{
u32 moveToUse;
- KNOWN_FAILING;
PARAMETRIZE { moveToUse = MOVE_FINAL_GAMBIT; }
PARAMETRIZE { moveToUse = MOVE_TACKLE; }
GIVEN {
@@ -153,7 +152,6 @@ DOUBLE_BATTLE_TEST("Covert Cloak does or does not block Sparkling Aria depending
SINGLE_BATTLE_TEST("Covert Cloak blocks Sparkling Aria in singles")
{
- KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); Status1(STATUS1_BURN); }
diff --git a/test/battle/hold_effect/critical_hit_up.c b/test/battle/hold_effect/critical_hit_up.c
index c23f29773a..ee4cb6a7d2 100644
--- a/test/battle/hold_effect/critical_hit_up.c
+++ b/test/battle/hold_effect/critical_hit_up.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_LANSAT_BERRY].holdEffect == HOLD_EFFECT_CRITICAL_UP);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Lansat Berry raises the holder's critical-hit-ratio by two stages when HP drops to 1/4 or below")
@@ -52,7 +52,7 @@ SINGLE_BATTLE_TEST("Lansat Berry raises the holder's critical-hit-ratio by two s
{
PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].criticalHitStage == 0);
+ ASSUME(GetMoveCriticalHitStage(MOVE_TACKLE) == 0);
ASSUME(B_CRIT_CHANCE >= GEN_6);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(160); HP(80); Item(ITEM_LANSAT_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/hold_effect/cure_status.c b/test/battle/hold_effect/cure_status.c
index d954983f88..133eeafb41 100644
--- a/test/battle/hold_effect/cure_status.c
+++ b/test/battle/hold_effect/cure_status.c
@@ -265,3 +265,30 @@ SINGLE_BATTLE_TEST("Player Pokemon can be further poisoned with Toxic spikes aft
STATUS_ICON(player, poison: TRUE);
}
}
+
+DOUBLE_BATTLE_TEST("Lum Berry correctly cures all battlers if multiple fainted the previous turn")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_CATERPIE) { HP(1); }
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LUM_BERRY); Status1(STATUS1_BURN); }
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LUM_BERRY); Status1(STATUS1_POISON); }
+ OPPONENT(SPECIES_CATERPIE) { HP(1); }
+ OPPONENT(SPECIES_CATERPIE) { HP(1); }
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LUM_BERRY); Status1(STATUS1_PARALYSIS); }
+ OPPONENT(SPECIES_CATERPIE);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_EXPLOSION);
+ SEND_OUT(opponentRight, 3);
+ SEND_OUT(opponentLeft, 2);
+ SEND_OUT(playerRight, 3);
+ SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, playerLeft);
+ } THEN {
+ EXPECT_EQ(playerLeft->status1, STATUS1_NONE);
+ EXPECT_EQ(playerRight->status1, STATUS1_NONE);
+ EXPECT_EQ(opponentLeft->status1, STATUS1_NONE);
+
+ }
+}
diff --git a/test/battle/hold_effect/defense_up.c b/test/battle/hold_effect/defense_up.c
index 46130b9fe7..1812b96d33 100644
--- a/test/battle/hold_effect/defense_up.c
+++ b/test/battle/hold_effect/defense_up.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_GANLON_BERRY].holdEffect == HOLD_EFFECT_DEFENSE_UP);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Ganlon Berry raises the holder's Defense by one stage when HP drops to 1/4 or below")
diff --git a/test/battle/hold_effect/eject_pack.c b/test/battle/hold_effect/eject_pack.c
index 8d85a77062..0d2696392f 100644
--- a/test/battle/hold_effect/eject_pack.c
+++ b/test/battle/hold_effect/eject_pack.c
@@ -63,3 +63,42 @@ SINGLE_BATTLE_TEST("Eject Pack is triggered by self-inflicting stat decreases")
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
}
}
+
+SINGLE_BATTLE_TEST("Eject Pack will miss timing to switch out user if Emergency Exit was activated on target")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(133); };
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(player, MOVE_OVERHEAT); SEND_OUT(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ MESSAGE("Wobbuffet is switched out with the Eject Pack!");
+ }
+ ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
+ } THEN {
+ EXPECT(player->species == SPECIES_WOBBUFFET);
+ EXPECT(opponent->species == SPECIES_WYNAUT);
+ }
+}
+
+SINGLE_BATTLE_TEST("Eject Pack activates once intimidate mon switches in")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }
+ } WHEN {
+ TURN { SWITCH(opponent, 1); SEND_OUT(player, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ MESSAGE("Wobbuffet is switched out with the Eject Pack!");
+ }
+}
diff --git a/test/battle/hold_effect/enigma_berry.c b/test/battle/hold_effect/enigma_berry.c
index 5a058eed1b..762774f25d 100644
--- a/test/battle/hold_effect/enigma_berry.c
+++ b/test/battle/hold_effect/enigma_berry.c
@@ -58,3 +58,19 @@ SINGLE_BATTLE_TEST("Enigma Berry does nothing if Heal Block applies")
}
}
}
+
+DOUBLE_BATTLE_TEST("Enigma Berry doesn't trigger if partner was hit")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT) { Item(ITEM_ENIGMA_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
+ } SCENE {
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
+ } THEN {
+ EXPECT(opponentRight->item == ITEM_ENIGMA_BERRY);
+ }
+}
diff --git a/test/battle/hold_effect/jaboca_berry.c b/test/battle/hold_effect/jaboca_berry.c
index 373780be71..756b5adf3c 100644
--- a/test/battle/hold_effect/jaboca_berry.c
+++ b/test/battle/hold_effect/jaboca_berry.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_JABOCA_BERRY].holdEffect == HOLD_EFFECT_JABOCA_BERRY);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Jaboca Berry causes the attacker to lose 1/8 of its max HP if a physical move was used")
@@ -16,7 +16,7 @@ SINGLE_BATTLE_TEST("Jaboca Berry causes the attacker to lose 1/8 of its max HP i
PARAMETRIZE { move = MOVE_TACKLE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_JABOCA_BERRY); }
} WHEN {
@@ -44,7 +44,7 @@ SINGLE_BATTLE_TEST("Jaboca Berry tirggers before Bug Bite can steal it")
{
KNOWN_FAILING;
GIVEN {
- ASSUME(gMovesInfo[MOVE_BUG_BITE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_BUG_BITE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_JABOCA_BERRY); }
} WHEN {
diff --git a/test/battle/hold_effect/kee_berry.c b/test/battle/hold_effect/kee_berry.c
index 2375e65c2f..33de8ee004 100644
--- a/test/battle/hold_effect/kee_berry.c
+++ b/test/battle/hold_effect/kee_berry.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_KEE_BERRY].holdEffect == HOLD_EFFECT_KEE_BERRY);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Kee Berry raises the holder's Defense by one stage when hit by a physical move")
@@ -15,7 +15,7 @@ SINGLE_BATTLE_TEST("Kee Berry raises the holder's Defense by one stage when hit
PARAMETRIZE { move = MOVE_TACKLE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_KEE_BERRY); }
} WHEN {
@@ -73,3 +73,19 @@ SINGLE_BATTLE_TEST("Kee Berry doesn't trigger if the item hold user used a physi
EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE);
}
}
+
+DOUBLE_BATTLE_TEST("Kee Berry doesn't trigger if partner was hit")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT) { Item(ITEM_KEE_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
+ } SCENE {
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
+ } THEN {
+ EXPECT(opponentRight->item == ITEM_KEE_BERRY);
+ }
+}
diff --git a/test/battle/hold_effect/maranga_berry.c b/test/battle/hold_effect/maranga_berry.c
index 6d12f257a7..eeb1aacf94 100644
--- a/test/battle/hold_effect/maranga_berry.c
+++ b/test/battle/hold_effect/maranga_berry.c
@@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Maranga Berry raises the holder's Sp. Def by one stage when
PARAMETRIZE { move = MOVE_TACKLE; }
PARAMETRIZE { move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_MARANGA_BERRY); }
} WHEN {
@@ -40,7 +40,7 @@ SINGLE_BATTLE_TEST("Maranga Berry raises the holder's Sp. Def by one stage when
SINGLE_BATTLE_TEST("Maranga Berry raises the holder's Sp. Def by two stages with Ripen when hit by a special move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_APPLIN) { Item(ITEM_MARANGA_BERRY); Ability(ABILITY_RIPEN); }
} WHEN {
@@ -73,3 +73,19 @@ SINGLE_BATTLE_TEST("Maranga Berry doesn't trigger if the item hold user used a s
EXPECT_EQ(player->statStages[STAT_SPDEF], DEFAULT_STAT_STAGE);
}
}
+
+DOUBLE_BATTLE_TEST("Maranga Berry doesn't trigger if partner was hit")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT) { Item(ITEM_MARANGA_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); }
+ } SCENE {
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
+ } THEN {
+ EXPECT(opponentRight->item == ITEM_MARANGA_BERRY);
+ }
+}
diff --git a/test/battle/hold_effect/metronome.c b/test/battle/hold_effect/metronome.c
index 21ad326cf1..f1d756b3a7 100644
--- a/test/battle/hold_effect/metronome.c
+++ b/test/battle/hold_effect/metronome.c
@@ -112,7 +112,7 @@ SINGLE_BATTLE_TEST("Metronome Item counts charging turn of moves for its attacki
PARAMETRIZE {item = ITEM_NONE; }
PARAMETRIZE {item = ITEM_METRONOME; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].effect == EFFECT_SOLAR_BEAM);
+ ASSUME(GetMoveEffect(MOVE_SOLAR_BEAM) == EFFECT_SOLAR_BEAM);
PLAYER(SPECIES_WOBBUFFET) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -134,7 +134,7 @@ SINGLE_BATTLE_TEST("Metronome Item doesn't increase damage per hit of multi-hit
{
s16 damage[3];
GIVEN {
- ASSUME(gMovesInfo[MOVE_FURY_ATTACK].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_FURY_ATTACK) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_METRONOME); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/hold_effect/micle_berry.c b/test/battle/hold_effect/micle_berry.c
index 87f6742609..818eae09a6 100644
--- a/test/battle/hold_effect/micle_berry.c
+++ b/test/battle/hold_effect/micle_berry.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_MICLE_BERRY].holdEffect == HOLD_EFFECT_MICLE_BERRY);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Micle Berry raises the holder's accuracy by 1.2 when HP drops to 1/4 or below")
@@ -52,7 +52,7 @@ SINGLE_BATTLE_TEST("Micle Berry raises the holder's accuracy by 1.2")
{
PASSES_RANDOMLY(24, 25, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_SUBMISSION].accuracy == 80);
+ ASSUME(GetMoveAccuracy(MOVE_SUBMISSION) == 80);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(160); HP(80); Item(ITEM_MICLE_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("Micle Berry raises the holder's accuracy by 1.2")
SINGLE_BATTLE_TEST("Micle Berry increases the accuracy of the next used move across turns")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROCK_SLIDE].accuracy == 90);
+ ASSUME(GetMoveAccuracy(MOVE_ROCK_SLIDE) == 90);
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(26); Item(ITEM_MICLE_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -85,7 +85,7 @@ SINGLE_BATTLE_TEST("Micle Berry increases the accuracy of the next used move acr
SINGLE_BATTLE_TEST("Micle Berry increases the accuracy of the next used move the same turn the berry was triggered")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROCK_SLIDE].accuracy == 90);
+ ASSUME(GetMoveAccuracy(MOVE_ROCK_SLIDE) == 90);
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(26); Item(ITEM_MICLE_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/hold_effect/mirror_herb.c b/test/battle/hold_effect/mirror_herb.c
index 88a7467334..68294bee43 100644
--- a/test/battle/hold_effect/mirror_herb.c
+++ b/test/battle/hold_effect/mirror_herb.c
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Mirror Herb copies all of foe's positive stat changes in a t
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_MIRROR_HERB; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); Item(item); }
} WHEN {
diff --git a/test/battle/hold_effect/ogerpon_mask.c b/test/battle/hold_effect/ogerpon_mask.c
index 209b854d66..919151684a 100644
--- a/test/battle/hold_effect/ogerpon_mask.c
+++ b/test/battle/hold_effect/ogerpon_mask.c
@@ -21,7 +21,7 @@ SINGLE_BATTLE_TEST("Ogerpon Masks increase the base power of moves by 20%", s16
PARAMETRIZE { species = SPECIES_OGERPON_CORNERSTONE; item = ITEM_HEARTHFLAME_MASK; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].power > 0);
+ ASSUME(GetMovePower(MOVE_TACKLE) > 0);
PLAYER(species) { Item(item); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/hold_effect/protective_pads.c b/test/battle/hold_effect/protective_pads.c
index 95de944b81..843d2fa003 100644
--- a/test/battle/hold_effect/protective_pads.c
+++ b/test/battle/hold_effect/protective_pads.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_PROTECTIVE_PADS].holdEffect == HOLD_EFFECT_PROTECTIVE_PADS);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact == TRUE);
+ ASSUME(MoveMakesContact(MOVE_TACKLE) == TRUE);
}
SINGLE_BATTLE_TEST("Protective Pads protected moves still make direct contact", s16 damage)
diff --git a/test/battle/hold_effect/red_card.c b/test/battle/hold_effect/red_card.c
index e1d94b4db0..7b14d8748d 100644
--- a/test/battle/hold_effect/red_card.c
+++ b/test/battle/hold_effect/red_card.c
@@ -380,28 +380,10 @@ SINGLE_BATTLE_TEST("Red Card does not activate if attacker's Sheer Force applied
}
}
-SINGLE_BATTLE_TEST("Red Card activates before Emergency Exit")
-{
- GIVEN {
- PLAYER(SPECIES_GOLISOPOD) { MaxHP(100); HP(51); Item(ITEM_RED_CARD); }
- PLAYER(SPECIES_WIMPOD);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WYNAUT);
- } WHEN {
- TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
- MESSAGE("Golisopod held up its Red Card against the opposing Wobbuffet!");
- ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT);
- SEND_IN_MESSAGE("Wimpod");
- }
-}
-
SINGLE_BATTLE_TEST("Red Card is consumed after dragged out replacement has its Speed lowered by Sticky Web")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
+ ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT) { Moves(MOVE_TACKLE); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
@@ -468,4 +450,43 @@ SINGLE_BATTLE_TEST("Red Card does not activate if holder is switched in mid-turn
}
}
+SINGLE_BATTLE_TEST("Red Card prevents Emergency Exit activation when triggered")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_GOLISOPOD) { Item(ITEM_RED_CARD); Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(262); };
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SUPER_FANG); MOVE(opponent, MOVE_CELEBRATE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, player);
+ HP_BAR(opponent);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
+ NOT ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
+ }
+}
+
TO_DO_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed");
+
+SINGLE_BATTLE_TEST("Red Card activates before Eject Pack")
+{
+ GIVEN {
+ ASSUME(MoveHasAdditionalEffectSelf(MOVE_OVERHEAT, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(player, MOVE_OVERHEAT); MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ MESSAGE("Wobbuffet is switched out with the Eject Button!");
+ }
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
+ MESSAGE("The opposing Wobbuffet held up its Red Card against Wobbuffet!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ }
+}
diff --git a/test/battle/hold_effect/restore_hp.c b/test/battle/hold_effect/restore_hp.c
index 47f409ff84..ef96ead7e4 100644
--- a/test/battle/hold_effect/restore_hp.c
+++ b/test/battle/hold_effect/restore_hp.c
@@ -37,7 +37,7 @@ DOUBLE_BATTLE_TEST("Restore HP Item effects do not miss timing after a recoil mo
PARAMETRIZE { item = ITEM_SITRUS_BERRY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TAKE_DOWN].recoil == 25);
+ ASSUME(GetMoveRecoil(MOVE_TAKE_DOWN) == 25);
ASSUME(gItemsInfo[ITEM_ORAN_BERRY].holdEffect == HOLD_EFFECT_RESTORE_HP);
ASSUME(gItemsInfo[ITEM_BERRY_JUICE].holdEffect == HOLD_EFFECT_RESTORE_HP);
ASSUME(gItemsInfo[ITEM_SITRUS_BERRY].holdEffect == HOLD_EFFECT_RESTORE_PCT_HP);
diff --git a/test/battle/hold_effect/restore_stats.c b/test/battle/hold_effect/restore_stats.c
index c0f888469c..192ad2f65e 100644
--- a/test/battle/hold_effect/restore_stats.c
+++ b/test/battle/hold_effect/restore_stats.c
@@ -9,7 +9,7 @@ ASSUMPTIONS
SINGLE_BATTLE_TEST("White Herb restores stats when they're lowered")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN);
+ ASSUME(GetMoveEffect(MOVE_LEER) == EFFECT_DEFENSE_DOWN);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -103,7 +103,7 @@ SINGLE_BATTLE_TEST("White Herb restores stats after all hits of a multi hit move
PARAMETRIZE { species = SPECIES_DUGTRIO_ALOLA; ability = ABILITY_TANGLING_HAIR; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_DUAL_WINGBEAT].strikeCount == 2);
+ ASSUME(GetMoveStrikeCount(MOVE_DUAL_WINGBEAT) == 2);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); }
OPPONENT(species) { Ability(ability); }
} WHEN {
@@ -133,7 +133,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
- ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
+ ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF);
PLAYER(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/hold_effect/room_service.c b/test/battle/hold_effect/room_service.c
new file mode 100644
index 0000000000..e775ca496c
--- /dev/null
+++ b/test/battle/hold_effect/room_service.c
@@ -0,0 +1,33 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(gItemsInfo[ITEM_ROOM_SERVICE].holdEffect == HOLD_EFFECT_ROOM_SERVICE);
+}
+
+SINGLE_BATTLE_TEST("Room Serive decreases the holder's seep by one stage")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_TRICK_ROOM) == EFFECT_TRICK_ROOM);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); Item(ITEM_ROOM_SERVICE); }
+ OPPONENT(SPECIES_WYNAUT) { HP(1); }
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(player, MOVE_TRICK_ROOM); }
+ TURN { MOVE(player, MOVE_EXPLOSION); SEND_OUT(player, 1); SEND_OUT(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK_ROOM, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, player);
+ HP_BAR(opponent);
+ MESSAGE("2 sent out Wynaut!");
+ ABILITY_POPUP(player, ABILITY_INTIMIDATE);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ } THEN {
+ EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE - 1);
+ }
+}
diff --git a/test/battle/hold_effect/rowap_berry.c b/test/battle/hold_effect/rowap_berry.c
index 5dc85492c3..2ad8b9d300 100644
--- a/test/battle/hold_effect/rowap_berry.c
+++ b/test/battle/hold_effect/rowap_berry.c
@@ -15,8 +15,8 @@ SINGLE_BATTLE_TEST("Rowap Berry causes the attacker to lose 1/8 of its max HP if
PARAMETRIZE { move = MOVE_TACKLE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ROWAP_BERRY); }
} WHEN {
@@ -43,7 +43,7 @@ SINGLE_BATTLE_TEST("Rowap Berry causes the attacker to lose 1/8 of its max HP if
SINGLE_BATTLE_TEST("Rowap Berry is not triggered by a physical move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ROWAP_BERRY); }
} WHEN {
diff --git a/test/battle/hold_effect/safety_goggles.c b/test/battle/hold_effect/safety_goggles.c
index ec66ad8bcd..e2d329bcf6 100644
--- a/test/battle/hold_effect/safety_goggles.c
+++ b/test/battle/hold_effect/safety_goggles.c
@@ -9,7 +9,7 @@ ASSUMPTIONS
SINGLE_BATTLE_TEST("Safety Goggles block powder and spore moves")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ABRA) { Item(ITEM_SAFETY_GOGGLES); }
} WHEN {
diff --git a/test/battle/hold_effect/seeds.c b/test/battle/hold_effect/seeds.c
new file mode 100644
index 0000000000..10a415bd63
--- /dev/null
+++ b/test/battle/hold_effect/seeds.c
@@ -0,0 +1,62 @@
+#include "global.h"
+#include "test/battle.h"
+
+SINGLE_BATTLE_TEST("Electric Seed raises the holder's Defense on Electric Terrain")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffect == HOLD_EFFECT_SEEDS);
+ ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIC_SEED); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Grassy Seed raises the holder's Defense on Grassy Terrain")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffect == HOLD_EFFECT_SEEDS);
+ ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_GRASSY_TERRAIN);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSY_SEED); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_GRASSY_TERRAIN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Misty Seed raises the holder's Sp. Defense on Misty Terrain")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffect == HOLD_EFFECT_SEEDS);
+ ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_MISTY_TERRAIN);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MISTY_SEED); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_MISTY_TERRAIN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Psychic Seed raises the holder's Sp. Defense on Psychic Terrain")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffect == HOLD_EFFECT_SEEDS);
+ ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PSYCHIC_SEED); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!");
+ }
+}
diff --git a/test/battle/hold_effect/special_attack_up.c b/test/battle/hold_effect/special_attack_up.c
index ef348024fc..0199bab83c 100644
--- a/test/battle/hold_effect/special_attack_up.c
+++ b/test/battle/hold_effect/special_attack_up.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_PETAYA_BERRY].holdEffect == HOLD_EFFECT_SP_ATTACK_UP);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Petaya Berry raises the holder's Sp. Atk by one stage when HP drops to 1/4 or below")
diff --git a/test/battle/hold_effect/special_defense_up.c b/test/battle/hold_effect/special_defense_up.c
index 9585e5b5a7..e075d05c49 100644
--- a/test/battle/hold_effect/special_defense_up.c
+++ b/test/battle/hold_effect/special_defense_up.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Apicot Berry raises the holder's Sp. Def by one stage when HP drops to 1/4 or below")
diff --git a/test/battle/hold_effect/speed_up.c b/test/battle/hold_effect/speed_up.c
index 4a8b28b6d9..f31ee7e924 100644
--- a/test/battle/hold_effect/speed_up.c
+++ b/test/battle/hold_effect/speed_up.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_SALAC_BERRY].holdEffect == HOLD_EFFECT_SPEED_UP);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].effect == EFFECT_FIXED_DAMAGE_ARG);
- ASSUME(gMovesInfo[MOVE_DRAGON_RAGE].argument == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
}
SINGLE_BATTLE_TEST("Salac Berry raises the holder's Speed by one stage when HP drops to 1/4 or below")
diff --git a/test/battle/hold_effect/utility_umbrella.c b/test/battle/hold_effect/utility_umbrella.c
index f04a773789..67a3be4c7a 100644
--- a/test/battle/hold_effect/utility_umbrella.c
+++ b/test/battle/hold_effect/utility_umbrella.c
@@ -5,8 +5,8 @@
ASSUMPTIONS
{
ASSUME(gItemsInfo[ITEM_UTILITY_UMBRELLA].holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
}
SINGLE_BATTLE_TEST("Utility Umbrella blocks Sun damage modifiers", s16 damage)
diff --git a/test/battle/item_effect/escape.c b/test/battle/item_effect/escape.c
index bffa6e4292..dd27c425c2 100644
--- a/test/battle/item_effect/escape.c
+++ b/test/battle/item_effect/escape.c
@@ -21,7 +21,7 @@ WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle")
WILD_BATTLE_TEST("Poke Toy lets the player escape from a wild battle even if a move forbid them to")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEAN_LOOK].effect == EFFECT_MEAN_LOOK);
+ ASSUME(GetMoveEffect(MOVE_MEAN_LOOK) == EFFECT_MEAN_LOOK);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/item_effect/increase_stat.c b/test/battle/item_effect/increase_stat.c
index 9b3ced5759..2b9486e3a6 100644
--- a/test/battle/item_effect/increase_stat.c
+++ b/test/battle/item_effect/increase_stat.c
@@ -8,7 +8,7 @@ SINGLE_BATTLE_TEST("X Attack sharply raises battler's Attack stat", s16 damage)
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItemsInfo[ITEM_X_ATTACK].battleUsage == EFFECT_ITEM_INCREASE_STAT);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("X Defense sharply raises battler's Defense stat", s16 damage
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItemsInfo[ITEM_X_DEFENSE].battleUsage == EFFECT_ITEM_INCREASE_STAT);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -56,7 +56,7 @@ SINGLE_BATTLE_TEST("X Sp. Atk sharply raises battler's Sp. Attack stat", s16 dam
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItemsInfo[ITEM_X_SP_ATK].battleUsage == EFFECT_ITEM_INCREASE_STAT);
- ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_DISARMING_VOICE) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -80,7 +80,7 @@ SINGLE_BATTLE_TEST("X Sp. Def sharply raises battler's Sp. Defense stat", s16 da
PARAMETRIZE { useItem = TRUE; }
GIVEN {
ASSUME(gItemsInfo[ITEM_X_SP_DEF].battleUsage == EFFECT_ITEM_INCREASE_STAT);
- ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_DISARMING_VOICE) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -134,11 +134,11 @@ SINGLE_BATTLE_TEST("X Speed sharply raises battler's Speed stat", s16 damage)
SINGLE_BATTLE_TEST("X Accuracy sharply raises battler's Accuracy stat")
{
- ASSUME(gMovesInfo[MOVE_SING].accuracy == 55);
+ ASSUME(GetMoveAccuracy(MOVE_SING) == 55);
if (B_X_ITEMS_BUFF >= GEN_7)
- PASSES_RANDOMLY(gMovesInfo[MOVE_SING].accuracy * 5 / 3, 100, RNG_ACCURACY);
+ PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SING) * 5 / 3, 100, RNG_ACCURACY);
else
- PASSES_RANDOMLY(gMovesInfo[MOVE_SING].accuracy * 4 / 3, 100, RNG_ACCURACY);
+ PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SING) * 4 / 3, 100, RNG_ACCURACY);
GIVEN {
ASSUME(gItemsInfo[ITEM_X_ACCURACY].battleUsage == EFFECT_ITEM_INCREASE_STAT);
PLAYER(SPECIES_WOBBUFFET);
diff --git a/test/battle/move.c b/test/battle/move.c
index 9ee37391ec..ff397575b5 100644
--- a/test/battle/move.c
+++ b/test/battle/move.c
@@ -9,8 +9,8 @@ SINGLE_BATTLE_TEST("Accuracy controls the proportion of misses")
PARAMETRIZE { move = MOVE_HYDRO_PUMP; }
PARAMETRIZE { move = MOVE_RAZOR_LEAF; }
PARAMETRIZE { move = MOVE_SCRATCH; }
- ASSUME(0 < gMovesInfo[move].accuracy && gMovesInfo[move].accuracy <= 100);
- PASSES_RANDOMLY(gMovesInfo[move].accuracy, 100, RNG_ACCURACY);
+ ASSUME(0 < GetMoveAccuracy(move) && GetMoveAccuracy(move) <= 100);
+ PASSES_RANDOMLY(GetMoveAccuracy(move), 100, RNG_ACCURACY);
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -42,7 +42,7 @@ SINGLE_BATTLE_TEST("AdditionalEffect.chance controls the proportion of secondary
SINGLE_BATTLE_TEST("Turn order is determined by priority")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority > gMovesInfo[MOVE_TACKLE].priority);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) > GetMovePriority(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -86,10 +86,10 @@ DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie
PASSES_RANDOMLY(24, 24, RNG_SPEED_TIE);
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR);
- ASSUME(gMovesInfo[MOVE_LIFE_DEW].effect == EFFECT_JUNGLE_HEALING);
- ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_POWER_BASED_ON_TARGET_HP);
- ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG);
+ ASSUME(GetMoveEffect(MOVE_ENDEAVOR) == EFFECT_ENDEAVOR);
+ ASSUME(GetMoveEffect(MOVE_LIFE_DEW) == EFFECT_JUNGLE_HEALING);
+ ASSUME(GetMoveEffect(MOVE_CRUSH_GRIP) == EFFECT_POWER_BASED_ON_TARGET_HP);
+ ASSUME(GetMoveEffect(MOVE_SUPER_FANG) == EFFECT_SUPER_FANG);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(480); HP(360); Defense(100); Speed(1); }
PLAYER(SPECIES_WYNAUT) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Attack(100); Speed(1); }
@@ -153,7 +153,7 @@ SINGLE_BATTLE_TEST("Slash's critical hits occur at a 1/8 rate")
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
+ ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -188,7 +188,7 @@ SINGLE_BATTLE_TEST("Critical hits do not ignore positive stat stages", s16 damag
PARAMETRIZE { move = MOVE_HOWL; }
PARAMETRIZE { move = MOVE_TAIL_WHIP; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCRATCH].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -209,7 +209,7 @@ SINGLE_BATTLE_TEST("Critical hits ignore negative stat stages", s16 damage)
PARAMETRIZE { move = MOVE_HARDEN; }
PARAMETRIZE { move = MOVE_GROWL; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCRATCH].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -255,7 +255,7 @@ DOUBLE_BATTLE_TEST("Moves do not fail if an alive partner is the target")
DOUBLE_BATTLE_TEST("Moves fail if they target into a pokemon that was fainted by the previous move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
@@ -278,7 +278,7 @@ DOUBLE_BATTLE_TEST("Moves fail if they target into a pokemon that was fainted by
DOUBLE_BATTLE_TEST("Moves that target the field are not going to fail if one mon fainted by the previous move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/absorb.c b/test/battle/move_effect/absorb.c
index 698ea41091..456c888cd4 100644
--- a/test/battle/move_effect/absorb.c
+++ b/test/battle/move_effect/absorb.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ABSORB].effect == EFFECT_ABSORB);
+ ASSUME(GetMoveEffect(MOVE_ABSORB) == EFFECT_ABSORB);
}
SINGLE_BATTLE_TEST("Absorb recovers 50% of the damage dealt")
@@ -50,18 +50,18 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha recovers 50% of the damage dealt from both tar
s16 healedRight;
GIVEN {
- ASSUME(gMovesInfo[MOVE_MATCHA_GOTCHA].effect == EFFECT_ABSORB);
- PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ ASSUME(GetMoveEffect(MOVE_MATCHA_GOTCHA) == EFFECT_ABSORB);
+ PLAYER(SPECIES_PIKACHU) { HP(1); }
PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_STARYU);
+ OPPONENT(SPECIES_STARYU);
} WHEN {
TURN { MOVE(playerLeft, MOVE_MATCHA_GOTCHA); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft);
HP_BAR(opponentLeft, captureDamage: &damageLeft);
- HP_BAR(playerLeft, captureDamage: &healedLeft);
HP_BAR(opponentRight, captureDamage: &damageRight);
+ HP_BAR(playerLeft, captureDamage: &healedLeft);
HP_BAR(playerLeft, captureDamage: &healedRight);
} THEN {
EXPECT_MUL_EQ(damageLeft, Q_4_12(-0.5), healedLeft);
@@ -69,5 +69,38 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha recovers 50% of the damage dealt from both tar
}
}
+SINGLE_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt")
+{
+ s16 damage;
+ s16 healed;
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DRAINING_KISS); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAINING_KISS, player);
+ HP_BAR(opponent, captureDamage: &damage);
+ HP_BAR(player, captureDamage: &healed);
+ } THEN {
+ EXPECT_MUL_EQ(damage, Q_4_12(-0.75), healed);
+ }
+}
+
+SINGLE_BATTLE_TEST("Absorb does not drain any HP if user flinched")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_FAKE_OUT); MOVE(player, MOVE_ABSORB); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, opponent);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
+ MESSAGE("The opposing Wobbuffet had its energy drained!");
+ }
+ }
+}
+
TO_DO_BATTLE_TEST("Absorb recovers 50% of the damage dealt to a Substitute");
-TO_DO_BATTLE_TEST("Draining Kiss recovers 75% of the damage dealt"); // Tests .argument 's implementation
diff --git a/test/battle/move_effect/accuracy_down.c b/test/battle/move_effect/accuracy_down.c
index f174a7f946..c11001928f 100644
--- a/test/battle/move_effect/accuracy_down.c
+++ b/test/battle/move_effect/accuracy_down.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SAND_ATTACK].effect == EFFECT_ACCURACY_DOWN);
+ ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN);
}
SINGLE_BATTLE_TEST("Sand Attack lowers Accuracy by 1 stage")
{
- PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY);
+ PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SCRATCH) * 3 / 4, 100, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
+ ASSUME(GetMoveAccuracy(MOVE_SCRATCH) == 100);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/acrobatics.c b/test/battle/move_effect/acrobatics.c
index 70953d0958..809b77f948 100644
--- a/test/battle/move_effect/acrobatics.c
+++ b/test/battle/move_effect/acrobatics.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ACROBATICS].effect == EFFECT_ACROBATICS);
- ASSUME(gMovesInfo[MOVE_ACROBATICS].type == TYPE_FLYING);
+ ASSUME(GetMoveEffect(MOVE_ACROBATICS) == EFFECT_ACROBATICS);
+ ASSUME(GetMoveType(MOVE_ACROBATICS) == TYPE_FLYING);
}
SINGLE_BATTLE_TEST("Acrobatics doubles in power if the user has no held item", s16 damage)
diff --git a/test/battle/move_effect/after_you.c b/test/battle/move_effect/after_you.c
index c1202f0f9c..42eb0f3ff9 100644
--- a/test/battle/move_effect/after_you.c
+++ b/test/battle/move_effect/after_you.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_AFTER_YOU].effect == EFFECT_AFTER_YOU);
+ ASSUME(GetMoveEffect(MOVE_AFTER_YOU) == EFFECT_AFTER_YOU);
}
DOUBLE_BATTLE_TEST("After You makes the target move after user")
@@ -112,7 +112,7 @@ DOUBLE_BATTLE_TEST("After You doesn't fail if the turn order remains the same af
DOUBLE_BATTLE_TEST("After You ignores the effects of Quash")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH);
+ ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
PLAYER(SPECIES_WYNAUT) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
diff --git a/test/battle/move_effect/ally_switch.c b/test/battle/move_effect/ally_switch.c
index c7aa52d7c5..7222f34587 100644
--- a/test/battle/move_effect/ally_switch.c
+++ b/test/battle/move_effect/ally_switch.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ALLY_SWITCH].effect == EFFECT_ALLY_SWITCH);
+ ASSUME(GetMoveEffect(MOVE_ALLY_SWITCH) == EFFECT_ALLY_SWITCH);
}
SINGLE_BATTLE_TEST("Ally Switch fails in a single battle")
@@ -41,8 +41,8 @@ DOUBLE_BATTLE_TEST("Ally Switch fails if there is no partner")
DOUBLE_BATTLE_TEST("Ally Switch changes the position of battlers")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCREECH].effect == EFFECT_DEFENSE_DOWN_2);
- ASSUME(gMovesInfo[MOVE_SCREECH].target == MOVE_TARGET_SELECTED);
+ ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2);
+ ASSUME(GetMoveTarget(MOVE_SCREECH) == MOVE_TARGET_SELECTED);
PLAYER(SPECIES_WOBBUFFET) { Speed(5); } // Wobb is playerLeft, but it'll be Wynaut after Ally Switch
PLAYER(SPECIES_WYNAUT) { Speed(4); }
OPPONENT(SPECIES_KADABRA) { Speed(3); }
@@ -72,7 +72,7 @@ DOUBLE_BATTLE_TEST("Ally Switch changes the position of battlers")
DOUBLE_BATTLE_TEST("Ally Switch does not redirect the target of Snipe Shot")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SNIPE_SHOT].effect == EFFECT_SNIPE_SHOT);
+ ASSUME(GetMoveEffect(MOVE_SNIPE_SHOT) == EFFECT_SNIPE_SHOT);
PLAYER(SPECIES_WOBBUFFET); // Wobb is playerLeft, but it'll be Wynaut after Ally Switch
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_KADABRA);
@@ -203,5 +203,99 @@ DOUBLE_BATTLE_TEST("Ally Switch works if ally used two-turn move like Dig")
}
}
+DOUBLE_BATTLE_TEST("Ally switch swaps sky drop targets if being used by partner")
+{
+ u8 visibility;
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP);
+ PLAYER(SPECIES_FEAROW) { Speed(100); }
+ PLAYER(SPECIES_XATU) { Speed(150); }
+ OPPONENT(SPECIES_ARON) { Speed(25); Ability(ABILITY_STURDY); }
+ OPPONENT(SPECIES_WYNAUT) { Speed(30); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SKY_DROP, target: opponentLeft); }
+ TURN { MOVE(playerRight, MOVE_ALLY_SWITCH); SKIP_TURN(playerLeft); MOVE(opponentRight, MOVE_MUD_SPORT); MOVE(opponentLeft, MOVE_IRON_DEFENSE); }
+ } SCENE {
+ MESSAGE("Fearow used Sky Drop!");
+ MESSAGE("Fearow took the opposing Aron into the sky!");
+ // turn 2
+ MESSAGE("Xatu used Ally Switch!");
+ MESSAGE("Xatu and Fearow switched places!");
+ MESSAGE("Fearow used Sky Drop!");
+ HP_BAR(opponentLeft);
+ MESSAGE("The opposing Wynaut used Mud Sport!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MUD_SPORT, opponentRight);
+ MESSAGE("The opposing Aron used Iron Defense!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, opponentLeft);
+ } THEN {
+ // all battlers should be visible
+ visibility = gBattleSpritesDataPtr->battlerData[0].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[1].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[2].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[3].invisible;
+ EXPECT_EQ(visibility, 0);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Ally switch swaps opposing sky drop targets if partner is being held in the air")
+{
+ u8 visibility;
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP);
+ PLAYER(SPECIES_ARON) { Speed(25); Ability(ABILITY_STURDY); }
+ PLAYER(SPECIES_WYNAUT) { Speed(30); }
+ OPPONENT(SPECIES_FEAROW) { Speed(100); }
+ OPPONENT(SPECIES_XATU) { Speed(150); }
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_SKY_DROP, target: playerLeft); }
+ TURN { MOVE(opponentRight, MOVE_ALLY_SWITCH); SKIP_TURN(opponentLeft); MOVE(playerRight, MOVE_MUD_SPORT); MOVE(playerLeft, MOVE_IRON_DEFENSE); }
+ } SCENE {
+ MESSAGE("The opposing Fearow used Sky Drop!");
+ MESSAGE("The opposing Fearow took Aron into the sky!");
+ // turn 2
+ MESSAGE("The opposing Xatu used Ally Switch!");
+ MESSAGE("The opposing Xatu and the opposing Fearow switched places!");
+ MESSAGE("The opposing Fearow used Sky Drop!");
+ HP_BAR(playerLeft);
+ MESSAGE("Wynaut used Mud Sport!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MUD_SPORT, playerRight);
+ MESSAGE("Aron used Iron Defense!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, playerLeft);
+ } THEN {
+ // all battlers should be visible
+ visibility = gBattleSpritesDataPtr->battlerData[0].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[1].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[2].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[3].invisible;
+ EXPECT_EQ(visibility, 0);
+ }
+}
+
+// Test passes in isolation but fails on CI
+/*
+DOUBLE_BATTLE_TEST("Ally Switch swaps Illusion data")
+{
+ KNOWN_FAILING; // Test passes in isolation but fails on CI
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_ALLY_SWITCH) == EFFECT_ALLY_SWITCH);
+ PLAYER(SPECIES_HOOPA);
+ PLAYER(SPECIES_ZOROARK);
+ PLAYER(SPECIES_MAMOSWINE); // the third member here is required for zoroark
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_ALLY_SWITCH); }
+ } THEN {
+ EXPECT(&gPlayerParty[2] == gBattleStruct->illusion[0].mon);
+ }
+}
+*/
+
// Triple Battles required to test
//TO_DO_BATTLE_TEST("Ally Switch fails if the user is in the middle of the field in a Triple Battle");
diff --git a/test/battle/move_effect/assist.c b/test/battle/move_effect/assist.c
index 0c9a0b6128..6036de8e8c 100644
--- a/test/battle/move_effect/assist.c
+++ b/test/battle/move_effect/assist.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ASSIST].effect == EFFECT_ASSIST);
+ ASSUME(GetMoveEffect(MOVE_ASSIST) == EFFECT_ASSIST);
}
TO_DO_BATTLE_TEST("Assist randomly calls a move from any party member");
diff --git a/test/battle/move_effect/attack_accuracy_up.c b/test/battle/move_effect/attack_accuracy_up.c
index 102f4d4d21..25b09ab1c0 100644
--- a/test/battle/move_effect/attack_accuracy_up.c
+++ b/test/battle/move_effect/attack_accuracy_up.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Hone Claws increases Attack and Accuracy by one stage each")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_HONE_CLAWS].effect == EFFECT_ATTACK_ACCURACY_UP);
+ ASSUME(GetMoveEffect(MOVE_HONE_CLAWS) == EFFECT_ATTACK_ACCURACY_UP);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/attack_down.c b/test/battle/move_effect/attack_down.c
index e88ef43c26..eb562c0c6a 100644
--- a/test/battle/move_effect/attack_down.c
+++ b/test/battle/move_effect/attack_down.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
}
SINGLE_BATTLE_TEST("Growl lowers Attack by 1 stage", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Growl lowers Attack by 1 stage", s16 damage)
PARAMETRIZE { lowerAttack = FALSE; }
PARAMETRIZE { lowerAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/attack_down_2.c b/test/battle/move_effect/attack_down_2.c
index 6fefec5e45..896bbf947c 100644
--- a/test/battle/move_effect/attack_down_2.c
+++ b/test/battle/move_effect/attack_down_2.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2);
}
SINGLE_BATTLE_TEST("Charm lowers Attack by 2 stages", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Charm lowers Attack by 2 stages", s16 damage)
PARAMETRIZE { lowerAttack = FALSE; }
PARAMETRIZE { lowerAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/attack_spatk_up.c b/test/battle/move_effect/attack_spatk_up.c
index b5aa2418a2..671ed667a6 100644
--- a/test/battle/move_effect/attack_spatk_up.c
+++ b/test/battle/move_effect/attack_spatk_up.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WORK_UP].effect == EFFECT_ATTACK_SPATK_UP);
+ ASSUME(GetMoveEffect(MOVE_WORK_UP) == EFFECT_ATTACK_SPATK_UP);
}
SINGLE_BATTLE_TEST("Work Up raises Attack and Sp. Attack by 1 stage each", s16 damage)
@@ -16,8 +16,8 @@ SINGLE_BATTLE_TEST("Work Up raises Attack and Sp. Attack by 1 stage each", s16 d
PARAMETRIZE { raiseStats = FALSE; move = MOVE_SWIFT; }
PARAMETRIZE { raiseStats = TRUE; move = MOVE_SWIFT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/attack_up.c b/test/battle/move_effect/attack_up.c
index da878fb60d..1865c7f30e 100644
--- a/test/battle/move_effect/attack_up.c
+++ b/test/battle/move_effect/attack_up.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_MEDITATE].effect == EFFECT_ATTACK_UP);
+ ASSUME(GetMoveEffect(MOVE_MEDITATE) == EFFECT_ATTACK_UP);
}
SINGLE_BATTLE_TEST("Meditate raises Attack by 1 stage", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Meditate raises Attack by 1 stage", s16 damage)
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/attack_up_2.c b/test/battle/move_effect/attack_up_2.c
index 1f44efe9e3..fd247fad01 100644
--- a/test/battle/move_effect/attack_up_2.c
+++ b/test/battle/move_effect/attack_up_2.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
}
SINGLE_BATTLE_TEST("Swords Dance raises Attack by 2 stages", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Swords Dance raises Attack by 2 stages", s16 damage)
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/attack_up_user_ally.c b/test/battle/move_effect/attack_up_user_ally.c
index 1d623c2bbd..8f9c4a3388 100644
--- a/test/battle/move_effect/attack_up_user_ally.c
+++ b/test/battle/move_effect/attack_up_user_ally.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY);
+ ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY);
}
SINGLE_BATTLE_TEST("Howl raises user's Attack by 1 stage", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Howl raises user's Attack by 1 stage", s16 damage)
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -37,7 +37,7 @@ DOUBLE_BATTLE_TEST("Howl raises user's and partner's Attack by 1 stage", s16 dam
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Speed(15); }
PLAYER(SPECIES_WYNAUT) { Speed(10); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(13); }
@@ -69,7 +69,7 @@ DOUBLE_BATTLE_TEST("Howl does not work on partner if it has Soundproof")
s16 damage[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Speed(15); }
PLAYER(SPECIES_VOLTORB) { Speed(10); Ability(ABILITY_SOUNDPROOF); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
diff --git a/test/battle/move_effect/aura_wheel.c b/test/battle/move_effect/aura_wheel.c
index 3d601f3583..dfd31c878f 100644
--- a/test/battle/move_effect/aura_wheel.c
+++ b/test/battle/move_effect/aura_wheel.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffectSelf(MOVE_AURA_WHEEL, MOVE_EFFECT_SPD_PLUS_1) == TRUE);
- ASSUME(gMovesInfo[MOVE_AURA_WHEEL].effect == EFFECT_AURA_WHEEL);
+ ASSUME(GetMoveEffect(MOVE_AURA_WHEEL) == EFFECT_AURA_WHEEL);
}
SINGLE_BATTLE_TEST("Aura Wheel raises Speed; fails if the user is not Morpeko")
diff --git a/test/battle/move_effect/aurora_veil.c b/test/battle/move_effect/aurora_veil.c
index f681e965d7..b57c85df06 100644
--- a/test/battle/move_effect/aurora_veil.c
+++ b/test/battle/move_effect/aurora_veil.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL);
+ ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL);
}
SINGLE_BATTLE_TEST("Aurora Veil can only be used in Hail and Snow")
diff --git a/test/battle/move_effect/baton_pass.c b/test/battle/move_effect/baton_pass.c
index b6a27179f3..cb6530ae89 100644
--- a/test/battle/move_effect/baton_pass.c
+++ b/test/battle/move_effect/baton_pass.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
}
// This softlocked the game before.
@@ -39,9 +39,6 @@ TO_DO_BATTLE_TEST("Baton Pass doesn't pass ability changes");
//
TO_DO_BATTLE_TEST("Baton Pass passes confusion status"); // test/battle/status2/confusion.c
-TO_DO_BATTLE_TEST("Baton Pass passes Cursed status"); // test/battle/move_effect/curse.c
-TO_DO_BATTLE_TEST("Baton Pass doesn't pass Disable's effect"); // test/battle/move_effect/disable.c
-TO_DO_BATTLE_TEST("Baton Pass passes Dragon Cheer's effect"); // test/battle/move_effect/dragon_cheer.c
TO_DO_BATTLE_TEST("Baton Pass passes Fairy lock's escape prevention effect"); // test/battle/move_effect/fairy_lock.c
TO_DO_BATTLE_TEST("Baton Pass passes Focus Energy's effect"); // test/battle/move_effect/focus_energy.c
TO_DO_BATTLE_TEST("Baton Pass passes Heal Block's effect"); // test/battle/move_effect/heal_block.c
diff --git a/test/battle/move_effect/beak_blast.c b/test/battle/move_effect/beak_blast.c
index e716b7717f..92557ddee3 100644
--- a/test/battle/move_effect/beak_blast.c
+++ b/test/battle/move_effect/beak_blast.c
@@ -3,13 +3,13 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BEAK_BLAST].effect == EFFECT_BEAK_BLAST);
+ ASSUME(GetMoveEffect(MOVE_BEAK_BLAST) == EFFECT_BEAK_BLAST);
}
DOUBLE_BATTLE_TEST("Beak Blast's charging message is shown before other moves are used")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BEAK_BLAST].priority < 0);
+ ASSUME(GetMovePriority(MOVE_BEAK_BLAST) < 0);
PLAYER(SPECIES_WYNAUT) { Speed(10); }
PLAYER(SPECIES_WOBBUFFET) { Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
@@ -36,8 +36,8 @@ DOUBLE_BATTLE_TEST("Beak Blast's charging message is shown before other moves ar
DOUBLE_BATTLE_TEST("Beak Blast burns all who make contact with the pokemon")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BEAK_BLAST].priority < 0);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
+ ASSUME(GetMovePriority(MOVE_BEAK_BLAST) < 0);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
PLAYER(SPECIES_WYNAUT) { Speed(10); }
PLAYER(SPECIES_WOBBUFFET) { Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(3); }
@@ -80,9 +80,9 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used")
PARAMETRIZE { move = MOVE_LEER; burn = FALSE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(!gMovesInfo[MOVE_WATER_GUN].makesContact);
- ASSUME(!gMovesInfo[MOVE_LEER].makesContact);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(!MoveMakesContact(MOVE_WATER_GUN));
+ ASSUME(!MoveMakesContact(MOVE_LEER));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -113,4 +113,5 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used")
}
TO_DO_BATTLE_TEST("Beak Blast's charging message is shown regardless if it would've missed");
+TO_DO_BATTLE_TEST("Beak Blast fails if it's forced by Encore after choosing a different move");
TO_DO_BATTLE_TEST("Bulletproof is immune to Beak Blast but not to the burn it causes");
diff --git a/test/battle/move_effect/belch.c b/test/battle/move_effect/belch.c
index 2a732e0e45..1abcefb353 100644
--- a/test/battle/move_effect/belch.c
+++ b/test/battle/move_effect/belch.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BELCH].effect == EFFECT_BELCH);
- ASSUME(gMovesInfo[MOVE_MUD_SHOT].type == TYPE_GROUND);
+ ASSUME(GetMoveEffect(MOVE_BELCH) == EFFECT_BELCH);
+ ASSUME(GetMoveType(MOVE_MUD_SHOT) == TYPE_GROUND);
ASSUME(gItemsInfo[ITEM_SHUCA_BERRY].holdEffect == HOLD_EFFECT_RESIST_BERRY);
ASSUME(gItemsInfo[ITEM_SHUCA_BERRY].holdEffectParam == TYPE_GROUND);
ASSUME(gItemsInfo[ITEM_SHUCA_BERRY].pocket == POCKET_BERRIES);
@@ -21,7 +21,7 @@ AI_SINGLE_BATTLE_TEST("AI: Belch has nonzero score after eating a berry")
TURN { MOVE(player, MOVE_MUD_SHOT); EXPECT_MOVE(opponent, MOVE_TACKLE); }
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_BELCH);}
} SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, opponent);
}
}
@@ -53,6 +53,64 @@ SINGLE_BATTLE_TEST("Belch cannot be used if the user has not eaten a berry")
}
}
-TO_DO_BATTLE_TEST("Belch can still be used after switching out");
-TO_DO_BATTLE_TEST("Belch can still be used after fainting");
-TO_DO_BATTLE_TEST("Belch can still be used after restoring the consumed berry");
+SINGLE_BATTLE_TEST("Belch can still be used after switching out")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS);
+ PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); }
+ PLAYER(SPECIES_SKWOVET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
+ TURN { SWITCH(player, 1); }
+ TURN { SWITCH(player, 0); }
+ TURN { MOVE(player, MOVE_BELCH); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
+ SWITCH_OUT_MESSAGE("Greedent");
+ SWITCH_OUT_MESSAGE("Skwovet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player);
+ }
+}
+
+SINGLE_BATTLE_TEST("Belch can still be used after fainting")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS);
+ ASSUME(GetMoveEffect(MOVE_FISSURE) == EFFECT_OHKO);
+ ASSUME(GetMoveEffect(MOVE_REVIVAL_BLESSING) == EFFECT_REVIVAL_BLESSING);
+ PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); }
+ PLAYER(SPECIES_SKWOVET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_STUFF_CHEEKS); MOVE(opponent, MOVE_FISSURE); SEND_OUT(player, 1); }
+ TURN { MOVE(player, MOVE_REVIVAL_BLESSING, partyIndex: 0); }
+ TURN { SWITCH(player, 0); }
+ TURN { MOVE(player, MOVE_BELCH); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REVIVAL_BLESSING, player);
+ SWITCH_OUT_MESSAGE("Skwovet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player);
+ }
+}
+
+SINGLE_BATTLE_TEST("Belch can still be used after restoring the consumed berry")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS);
+ ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE);
+ PLAYER(SPECIES_GREEDENT) { Item(ITEM_ORAN_BERRY); }
+ PLAYER(SPECIES_SKWOVET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_STUFF_CHEEKS); }
+ TURN { MOVE(player, MOVE_RECYCLE); }
+ TURN { MOVE(player, MOVE_BELCH); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STUFF_CHEEKS, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_RECYCLE, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BELCH, player);
+ }
+}
diff --git a/test/battle/move_effect/belly_drum.c b/test/battle/move_effect/belly_drum.c
index bfc558a982..e36689ac34 100644
--- a/test/battle/move_effect/belly_drum.c
+++ b/test/battle/move_effect/belly_drum.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
+ ASSUME(GetMoveEffect(MOVE_BELLY_DRUM) == EFFECT_BELLY_DRUM);
}
SINGLE_BATTLE_TEST("Belly Drum cuts the user's HP in half")
@@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Belly Drum maximizes the user's Attack stat", s16 damage)
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Belly Drum fails if user's current HP is half or less than h
SINGLE_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Belly Drum minimizes the user's Attack stat with Contrary",
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_CONTRARY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/bide.c b/test/battle/move_effect/bide.c
index f99829d57c..177b139d08 100644
--- a/test/battle/move_effect/bide.c
+++ b/test/battle/move_effect/bide.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BIDE].effect == EFFECT_BIDE);
+ ASSUME(GetMoveEffect(MOVE_BIDE) == EFFECT_BIDE);
}
SINGLE_BATTLE_TEST("Bide deals twice the taken damage over two turns")
diff --git a/test/battle/move_effect/body_press.c b/test/battle/move_effect/body_press.c
index 3a61c4d55d..d3aafa2d32 100644
--- a/test/battle/move_effect/body_press.c
+++ b/test/battle/move_effect/body_press.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BODY_PRESS].effect == EFFECT_BODY_PRESS);
- ASSUME(gMovesInfo[MOVE_BODY_PRESS].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_BODY_PRESS) == EFFECT_BODY_PRESS);
+ ASSUME(GetMoveCategory(MOVE_BODY_PRESS) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Body Press uses physical defense stat of target", s16 damage)
@@ -15,8 +15,8 @@ SINGLE_BATTLE_TEST("Body Press uses physical defense stat of target", s16 damage
PARAMETRIZE { move = MOVE_BODY_PRESS; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRILL_PECK].power == gMovesInfo[MOVE_BODY_PRESS].power);
- ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2);
+ ASSUME(GetMovePower(MOVE_DRILL_PECK) == GetMovePower(MOVE_BODY_PRESS));
+ ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2);
PLAYER(SPECIES_MEW);
OPPONENT(SPECIES_SHELLDER);
} WHEN {
@@ -55,8 +55,8 @@ SINGLE_BATTLE_TEST("Body Press's damage depends on the user's Defense and not At
PARAMETRIZE { move = MOVE_SWORDS_DANCE; }
PARAMETRIZE { move = MOVE_CELEBRATE; } // Nothing, stats are default
GIVEN {
- ASSUME(gMovesInfo[MOVE_IRON_DEFENSE].effect == EFFECT_DEFENSE_UP_2);
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Attack(150); Defense(150); }
} WHEN {
@@ -79,7 +79,7 @@ SINGLE_BATTLE_TEST("Body Press uses Defense Stat even in Wonder Room", s16 damag
PARAMETRIZE { move = MOVE_WONDER_ROOM; }
PARAMETRIZE { move = MOVE_CELEBRATE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_WONDER_ROOM].effect == EFFECT_WONDER_ROOM);
+ ASSUME(GetMoveEffect(MOVE_WONDER_ROOM) == EFFECT_WONDER_ROOM);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { SpDefense(50); Defense(150); }
} WHEN {
@@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Body Press uses Special Defense stat Stages in Wonder Room",
PARAMETRIZE { move = MOVE_AMNESIA; }
PARAMETRIZE { move = MOVE_CELEBRATE; } // Nothing, stats are default
GIVEN {
- ASSUME(gMovesInfo[MOVE_IRON_DEFENSE].effect == EFFECT_DEFENSE_UP_2);
- ASSUME(gMovesInfo[MOVE_AMNESIA].effect == EFFECT_SPECIAL_DEFENSE_UP_2);
+ ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2);
+ ASSUME(GetMoveEffect(MOVE_AMNESIA) == EFFECT_SPECIAL_DEFENSE_UP_2);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { SpDefense(150); Defense(150); }
} WHEN {
diff --git a/test/battle/move_effect/brick_break.c b/test/battle/move_effect/brick_break.c
index 513369b5a1..a4aae1e683 100644
--- a/test/battle/move_effect/brick_break.c
+++ b/test/battle/move_effect/brick_break.c
@@ -3,11 +3,11 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BRICK_BREAK].effect == EFFECT_BRICK_BREAK);
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
- ASSUME(gMovesInfo[MOVE_LIGHT_SCREEN].effect == EFFECT_LIGHT_SCREEN);
- ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT);
- ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL);
+ ASSUME(GetMoveEffect(MOVE_BRICK_BREAK) == EFFECT_BRICK_BREAK);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_LIGHT_SCREEN) == EFFECT_LIGHT_SCREEN);
+ ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT);
+ ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL);
}
SINGLE_BATTLE_TEST("Brick Break removes Light Screen, Reflect and Aurora Veil from the target's side of the field")
diff --git a/test/battle/move_effect/change_type_on_item.c b/test/battle/move_effect/change_type_on_item.c
index 6365215a42..f5c8f92376 100644
--- a/test/battle/move_effect/change_type_on_item.c
+++ b/test/battle/move_effect/change_type_on_item.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TECHNO_BLAST].effect == EFFECT_CHANGE_TYPE_ON_ITEM);
- ASSUME(gMovesInfo[MOVE_TECHNO_BLAST].argument == HOLD_EFFECT_DRIVE);
+ ASSUME(GetMoveEffect(MOVE_TECHNO_BLAST) == EFFECT_CHANGE_TYPE_ON_ITEM);
+ ASSUME(GetMoveEffectArg_HoldEffect(MOVE_TECHNO_BLAST) == HOLD_EFFECT_DRIVE);
}
SINGLE_BATTLE_TEST("Techno Blast changes type depending on the drive the user holds")
diff --git a/test/battle/move_effect/charge.c b/test/battle/move_effect/charge.c
index f95a137993..bd84a9b4e2 100644
--- a/test/battle/move_effect/charge.c
+++ b/test/battle/move_effect/charge.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].power != 0);
- ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
+ ASSUME(!IsBattleMoveStatus(MOVE_THUNDERBOLT));
+ ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC);
}
SINGLE_BATTLE_TEST("Charge doubles the damage of the next Electric move of the user")
@@ -88,7 +88,7 @@ SINGLE_BATTLE_TEST("Charge's effect does not stack with Electromorphosis or Wind
PARAMETRIZE { species = SPECIES_TADBULB; ability = ABILITY_ELECTROMORPHOSIS; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_AIR_CUTTER].windMove == TRUE);
+ ASSUME(IsWindMove(MOVE_AIR_CUTTER));
PLAYER(species) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -114,8 +114,8 @@ SINGLE_BATTLE_TEST("Charge's effect is removed regardless if the next move is El
s16 chargedUpDamage = 0;
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
+ ASSUME(GetMoveType(MOVE_TACKLE) != TYPE_ELECTRIC);
+ ASSUME(!IsBattleMoveStatus(MOVE_TACKLE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/chilly_reception.c b/test/battle/move_effect/chilly_reception.c
index 7e821abe3d..9b464f0d03 100644
--- a/test/battle/move_effect/chilly_reception.c
+++ b/test/battle/move_effect/chilly_reception.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_CHILLY_RECEPTION].effect == EFFECT_CHILLY_RECEPTION);
+ ASSUME(GetMoveEffect(MOVE_CHILLY_RECEPTION) == EFFECT_CHILLY_RECEPTION);
}
SINGLE_BATTLE_TEST("Chilly Reception sets up snow and switches the user out")
diff --git a/test/battle/move_effect/coaching.c b/test/battle/move_effect/coaching.c
index 2f50aceab5..0cfc593d35 100644
--- a/test/battle/move_effect/coaching.c
+++ b/test/battle/move_effect/coaching.c
@@ -1,8 +1,120 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("Coaching raises Attack and Defense of ally by 1 stage each");
-TO_DO_BATTLE_TEST("Coaching doesn't raise stats of the user");
-TO_DO_BATTLE_TEST("Coaching bypasses protection of allies");
-TO_DO_BATTLE_TEST("Coaching fails in single battles");
-TO_DO_BATTLE_TEST("Coaching fails if there's no ally");
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_COACHING) == EFFECT_COACHING);
+}
+
+DOUBLE_BATTLE_TEST("Coaching raises Attack and Defense of ally by 1 stage each")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_COACHING, target: playerRight); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COACHING, playerLeft);
+ MESSAGE("Wynaut's Attack rose!");
+ MESSAGE("Wynaut's Defense rose!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Coaching bypasses Protect")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_PROTECT); MOVE(playerLeft, MOVE_COACHING, target: playerRight); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COACHING, playerLeft);
+ MESSAGE("Wynaut's Attack rose!");
+ MESSAGE("Wynaut's Defense rose!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Coaching bypasses Crafty Shield")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_CRAFTY_SHIELD) == EFFECT_PROTECT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_CRAFTY_SHIELD); MOVE(playerLeft, MOVE_COACHING, target: playerRight); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COACHING, playerLeft);
+ MESSAGE("Wynaut's Attack rose!");
+ MESSAGE("Wynaut's Defense rose!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Coaching fails if all allies are is semi-invulnerable")
+{
+ KNOWN_FAILING; // Coaching succeeds
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_HAWLUCHA);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_FLY, target: opponentLeft); MOVE(playerLeft, MOVE_COACHING, target: playerRight); }
+ } SCENE {
+ MESSAGE("Hawlucha used Fly!");
+ MESSAGE("Wobbuffet used Coaching!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COACHING, playerLeft);
+ MESSAGE("Hawlucha's Attack rose!");
+ MESSAGE("Hawlucha's Defense rose!");
+ }
+ MESSAGE("But it failed!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Coaching fails in single battles")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_COACHING); }
+ } SCENE {
+ MESSAGE("But it failed!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COACHING, player);
+ MESSAGE("Wynaut's Attack rose!");
+ MESSAGE("Wynaut's Defense rose!");
+ }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Coaching fails if there's no ally")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT) { HP(1); };
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target: playerRight); }
+ TURN { MOVE(playerLeft, MOVE_COACHING, target: playerRight); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft);
+ MESSAGE("Wynaut fainted!");
+ MESSAGE("Wobbuffet used Coaching!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COACHING, playerLeft);
+ MESSAGE("Wynaut's Attack rose!");
+ MESSAGE("Wynaut's Defense rose!");
+ }
+ MESSAGE("But it failed!");
+ }
+}
diff --git a/test/battle/move_effect/collision_course.c b/test/battle/move_effect/collision_course.c
index 9eeeda5b1e..9933df0dc7 100644
--- a/test/battle/move_effect/collision_course.c
+++ b/test/battle/move_effect/collision_course.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_COLLISION_COURSE].effect == EFFECT_COLLISION_COURSE);
+ ASSUME(GetMoveEffect(MOVE_COLLISION_COURSE) == EFFECT_COLLISION_COURSE);
}
SINGLE_BATTLE_TEST("Collision Course damage is increased by 33 Percent if super effective", s16 damage)
diff --git a/test/battle/move_effect/confuse.c b/test/battle/move_effect/confuse.c
index 0533821972..425adfc889 100644
--- a/test/battle/move_effect/confuse.c
+++ b/test/battle/move_effect/confuse.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TEETER_DANCE].effect == EFFECT_CONFUSE);
+ ASSUME(GetMoveEffect(MOVE_TEETER_DANCE) == EFFECT_CONFUSE);
}
SINGLE_BATTLE_TEST("Teeter Dance confuses target")
diff --git a/test/battle/move_effect/corrosive_gas.c b/test/battle/move_effect/corrosive_gas.c
index cc4110a7e3..84b7c1c70b 100644
--- a/test/battle/move_effect/corrosive_gas.c
+++ b/test/battle/move_effect/corrosive_gas.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_CORROSIVE_GAS].effect == EFFECT_CORROSIVE_GAS);
+ ASSUME(GetMoveEffect(MOVE_CORROSIVE_GAS) == EFFECT_CORROSIVE_GAS);
}
SINGLE_BATTLE_TEST("Corrosive Gas destroys the target's item or fails if the target has no item")
@@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Corrosive Gas doesn't destroy the item of a Pokemon with the
SINGLE_BATTLE_TEST("Items lost to Corrosive Gas cannot be restored by Recycle")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
+ ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE);
PLAYER(SPECIES_WOBBUFFET) {Speed(15); }
OPPONENT(SPECIES_WOBBUFFET) {Item(ITEM_ORAN_BERRY); Speed(10); }
} WHEN {
diff --git a/test/battle/move_effect/cosmic_power.c b/test/battle/move_effect/cosmic_power.c
index 8680e9f28e..5c8fe30f67 100644
--- a/test/battle/move_effect/cosmic_power.c
+++ b/test/battle/move_effect/cosmic_power.c
@@ -1,4 +1,21 @@
#include "global.h"
#include "test/battle.h"
-TO_DO_BATTLE_TEST("Cosmic Power increases the user's Defense and Sp. Defense by 1 stage each");
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_COSMIC_POWER) == EFFECT_COSMIC_POWER);
+}
+
+SINGLE_BATTLE_TEST("Cosmic Power increases the user's Defense and Sp. Defense by 1 stage each")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_COSMIC_POWER); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COSMIC_POWER, player);
+ MESSAGE("Wobbuffet's Defense rose!");
+ MESSAGE("Wobbuffet's Sp. Def rose!");
+ }
+}
diff --git a/test/battle/move_effect/court_change.c b/test/battle/move_effect/court_change.c
index f3775d0af6..0727baff5e 100644
--- a/test/battle/move_effect/court_change.c
+++ b/test/battle/move_effect/court_change.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_COURT_CHANGE].effect == EFFECT_COURT_CHANGE);
+ ASSUME(GetMoveEffect(MOVE_COURT_CHANGE) == EFFECT_COURT_CHANGE);
}
DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the opponent")
diff --git a/test/battle/move_effect/curse.c b/test/battle/move_effect/curse.c
index 5fe17d3561..868608caa8 100644
--- a/test/battle/move_effect/curse.c
+++ b/test/battle/move_effect/curse.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_CURSE].effect == EFFECT_CURSE);
+ ASSUME(GetMoveEffect(MOVE_CURSE) == EFFECT_CURSE);
}
SINGLE_BATTLE_TEST("Curse lowers Speed, raises Attack, and raises Defense when used by non-Ghost-types")
@@ -34,3 +34,38 @@ SINGLE_BATTLE_TEST("Curse cuts the user's HP in half when used by Ghost-types")
HP_BAR(player, hp: maxHP / 2);
}
}
+
+SINGLE_BATTLE_TEST("Curse applies to the user if used with Protean")
+{
+ GIVEN {
+ PLAYER(SPECIES_KECLEON) { Ability(ABILITY_PROTEAN); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_CURSE, target: player); }
+ } SCENE {
+ s32 playerMaxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
+ ABILITY_POPUP(player, ABILITY_PROTEAN);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CURSE, player);
+ HP_BAR(player, damage: playerMaxHP / 2);
+ HP_BAR(player, damage: playerMaxHP / 4);
+ }
+}
+
+SINGLE_BATTLE_TEST("Curse applies to the opponent if user is afflicted by Trick-or-Treat in the same turn")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_TRICK_OR_TREAT); MOVE(player, MOVE_CURSE, target: player); }
+ } SCENE {
+ s32 playerMaxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
+ s32 opponentMaxHP = GetMonData(&OPPONENT_PARTY[0], MON_DATA_MAX_HP);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK_OR_TREAT, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CURSE, player);
+ HP_BAR(player, damage: playerMaxHP / 2);
+ HP_BAR(opponent, damage: opponentMaxHP / 4);
+ }
+}
+
+TO_DO_BATTLE_TEST("Baton Pass passes Cursed status");
diff --git a/test/battle/move_effect/dark_void.c b/test/battle/move_effect/dark_void.c
new file mode 100644
index 0000000000..a69d7d6930
--- /dev/null
+++ b/test/battle/move_effect/dark_void.c
@@ -0,0 +1,42 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID);
+}
+
+SINGLE_BATTLE_TEST("Dark Void inflicts 1-3 turns of sleep")
+{
+ u32 turns, count;
+ ASSUME(B_SLEEP_TURNS >= GEN_5);
+ PARAMETRIZE { turns = 1; }
+ PARAMETRIZE { turns = 2; }
+ PARAMETRIZE { turns = 3; }
+ PASSES_RANDOMLY(1, 3, RNG_SLEEP_TURNS);
+ GIVEN {
+ PLAYER(SPECIES_DARKRAI);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DARK_VOID); MOVE(opponent, MOVE_CELEBRATE); }
+ for (count = 0; count < turns; ++count)
+ TURN {}
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DARK_VOID, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ for (count = 0; count < turns; ++count)
+ {
+ if (count < turns - 1)
+ MESSAGE("The opposing Wobbuffet is fast asleep.");
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ }
+ MESSAGE("The opposing Wobbuffet woke up!");
+ STATUS_ICON(opponent, none: TRUE);
+ }
+}
+
+TO_DO_BATTLE_TEST("Dark Void can only be used by Darkrai (Gen7+)");
+TO_DO_BATTLE_TEST("Dark Void can be used by Pokémon other than Darkrai (Gen4-6)");
+TO_DO_BATTLE_TEST("Dark Void can be used by a Pokémon transformed into Darkrai");
diff --git a/test/battle/move_effect/decorate.c b/test/battle/move_effect/decorate.c
new file mode 100644
index 0000000000..5eef9dc305
--- /dev/null
+++ b/test/battle/move_effect/decorate.c
@@ -0,0 +1,5 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Decorate raises the target's Attack by 2 stages");
+TO_DO_BATTLE_TEST("Decorate raises the target's Sp. Attack by 2 stages");
diff --git a/test/battle/move_effect/defense_curl.c b/test/battle/move_effect/defense_curl.c
new file mode 100644
index 0000000000..c8beffe171
--- /dev/null
+++ b/test/battle/move_effect/defense_curl.c
@@ -0,0 +1,37 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_DEFENSE_CURL) == EFFECT_DEFENSE_CURL);
+}
+
+SINGLE_BATTLE_TEST("Defense Curl raises Defense by 1 stage", s16 damage)
+{
+ bool32 raiseDefense;
+ PARAMETRIZE { raiseDefense = FALSE; }
+ PARAMETRIZE { raiseDefense = TRUE; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ if (raiseDefense) TURN { MOVE(player, MOVE_DEFENSE_CURL); }
+ TURN { MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ if (raiseDefense) {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DEFENSE_CURL, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's Defense rose!");
+ }
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ HP_BAR(player, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.5), results[0].damage);
+ }
+}
+
+TO_DO_BATTLE_TEST("Defense Curl doubles the power of Rollout and Ice Ball");
+TO_DO_BATTLE_TEST("Defense Curl's effect cannot be stacked");
+TO_DO_BATTLE_TEST("Defense Curl's effect is removed when switching out");
+TO_DO_BATTLE_TEST("Baton Pass doesn't pass Defense Curl's effect");
diff --git a/test/battle/move_effect/defense_down.c b/test/battle/move_effect/defense_down.c
index 0552a9c67e..9691b4a1c2 100644
--- a/test/battle/move_effect/defense_down.c
+++ b/test/battle/move_effect/defense_down.c
@@ -3,16 +3,16 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TAIL_WHIP].effect == EFFECT_DEFENSE_DOWN);
+ ASSUME(GetMoveEffect(MOVE_TAIL_WHIP) == EFFECT_DEFENSE_DOWN);
}
-SINGLE_BATTLE_TEST("Tail Whip lowers Defense", s16 damage)
+SINGLE_BATTLE_TEST("Tail Whip lowers Defense by 1 stage", s16 damage)
{
bool32 lowerDefense;
PARAMETRIZE { lowerDefense = FALSE; }
PARAMETRIZE { lowerDefense = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/defense_down_2.c b/test/battle/move_effect/defense_down_2.c
new file mode 100644
index 0000000000..961e2de02f
--- /dev/null
+++ b/test/battle/move_effect/defense_down_2.c
@@ -0,0 +1,32 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2);
+}
+
+SINGLE_BATTLE_TEST("Screech lowers Defense by 2 stages", s16 damage)
+{
+ bool32 lowerDefense;
+ PARAMETRIZE { lowerDefense = FALSE; }
+ PARAMETRIZE { lowerDefense = TRUE; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ if (lowerDefense) TURN { MOVE(player, MOVE_SCREECH); }
+ TURN { MOVE(player, MOVE_TACKLE); }
+ } SCENE {
+ if (lowerDefense) {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCREECH, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ MESSAGE("The opposing Wobbuffet's Defense harshly fell!");
+ }
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
+ HP_BAR(opponent, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
+ }
+}
diff --git a/test/battle/move_effect/defense_up.c b/test/battle/move_effect/defense_up.c
index 513d6e1c29..c83f2c01c5 100644
--- a/test/battle/move_effect/defense_up.c
+++ b/test/battle/move_effect/defense_up.c
@@ -3,16 +3,16 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HARDEN].effect == EFFECT_DEFENSE_UP);
+ ASSUME(GetMoveEffect(MOVE_HARDEN) == EFFECT_DEFENSE_UP);
}
-SINGLE_BATTLE_TEST("Harden raises Defense", s16 damage)
+SINGLE_BATTLE_TEST("Harden raises Defense by 1 stage", s16 damage)
{
bool32 raiseDefense;
PARAMETRIZE { raiseDefense = FALSE; }
PARAMETRIZE { raiseDefense = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/defense_up_2.c b/test/battle/move_effect/defense_up_2.c
new file mode 100644
index 0000000000..59ca5c1af9
--- /dev/null
+++ b/test/battle/move_effect/defense_up_2.c
@@ -0,0 +1,32 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2);
+}
+
+SINGLE_BATTLE_TEST("Iron Defense raises Defense by 2 stages", s16 damage)
+{
+ bool32 raiseDefense;
+ PARAMETRIZE { raiseDefense = FALSE; }
+ PARAMETRIZE { raiseDefense = TRUE; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ if (raiseDefense) TURN { MOVE(player, MOVE_IRON_DEFENSE); }
+ TURN { MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ if (raiseDefense) {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's Defense sharply rose!");
+ }
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ HP_BAR(player, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[1].damage, Q_4_12(2.0), results[0].damage);
+ }
+}
diff --git a/test/battle/move_effect/defense_up_3.c b/test/battle/move_effect/defense_up_3.c
new file mode 100644
index 0000000000..040537c1d4
--- /dev/null
+++ b/test/battle/move_effect/defense_up_3.c
@@ -0,0 +1,32 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_COTTON_GUARD) == EFFECT_DEFENSE_UP_3);
+}
+
+SINGLE_BATTLE_TEST("Cotton Guard raises Defense by 3 stages", s16 damage)
+{
+ bool32 raiseDefense;
+ PARAMETRIZE { raiseDefense = FALSE; }
+ PARAMETRIZE { raiseDefense = TRUE; }
+ GIVEN {
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ if (raiseDefense) TURN { MOVE(player, MOVE_COTTON_GUARD); }
+ TURN { MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ if (raiseDefense) {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_COTTON_GUARD, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's Defense drastically rose!");
+ }
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ HP_BAR(player, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[1].damage, Q_4_12(2.5), results[0].damage);
+ }
+}
diff --git a/test/battle/move_effect/defog.c b/test/battle/move_effect/defog.c
index d5838d7ffd..3d0a46806c 100644
--- a/test/battle/move_effect/defog.c
+++ b/test/battle/move_effect/defog.c
@@ -3,23 +3,23 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_DEFOG].effect == EFFECT_DEFOG);
- ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT);
- ASSUME(gMovesInfo[MOVE_LIGHT_SCREEN].effect == EFFECT_LIGHT_SCREEN);
- ASSUME(gMovesInfo[MOVE_MIST].effect == EFFECT_MIST);
- ASSUME(gMovesInfo[MOVE_SAFEGUARD].effect == EFFECT_SAFEGUARD);
- ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL);
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK);
- ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES);
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
- ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_SCREECH].effect == EFFECT_DEFENSE_DOWN_2);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveEffect(MOVE_DEFOG) == EFFECT_DEFOG);
+ ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT);
+ ASSUME(GetMoveEffect(MOVE_LIGHT_SCREEN) == EFFECT_LIGHT_SCREEN);
+ ASSUME(GetMoveEffect(MOVE_MIST) == EFFECT_MIST);
+ ASSUME(GetMoveEffect(MOVE_SAFEGUARD) == EFFECT_SAFEGUARD);
+ ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL);
+ ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK);
+ ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_SCREECH) == EFFECT_DEFENSE_DOWN_2);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
}
-SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1")
+SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 stage")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
@@ -51,7 +51,8 @@ SINGLE_BATTLE_TEST("Defog does not lower evasiveness if target behind Substitute
}
}
-DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Reflect and Light Screen from opponent's side", s16 damagePhysical, s16 damageSpecial)
+TO_DO_BATTLE_TEST("Defog doesn't remove Reflect or Light Screen from the user's side");
+DOUBLE_BATTLE_TEST("Defog removes Reflect and Light Screen from target's side", s16 damagePhysical, s16 damageSpecial)
{
u16 move;
@@ -71,8 +72,6 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Reflect and Light
ANIMATION(ANIM_TYPE_MOVE, MOVE_LIGHT_SCREEN, opponentRight);
ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
if (move == MOVE_DEFOG) {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
- MESSAGE("The opposing Wobbuffet's evasiveness fell!");
MESSAGE("The opposing team's Reflect wore off!");
MESSAGE("The opposing team's Light Screen wore off!");
}
@@ -86,7 +85,8 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Reflect and Light
}
}
-DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard from opponent's side")
+TO_DO_BATTLE_TEST("Defog doesn't remove Mist or Safeguard from the user's side");
+DOUBLE_BATTLE_TEST("Defog removes Mist and Safeguard from target's side")
{
u16 move;
@@ -105,7 +105,6 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIST, opponentLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SAFEGUARD, opponentRight);
if (move == MOVE_DEFOG) {
- MESSAGE("The opposing Wobbuffet is protected by the mist!");
ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
MESSAGE("The opposing team's Mist wore off!");
MESSAGE("The opposing team's Safeguard wore off!");
@@ -131,7 +130,9 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard
}
}
-DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and Sticky Web from player's side (Gen 6+)")
+TO_DO_BATTLE_TEST("Defog removes Stealth Rock and Sticky Web from target's side");
+TO_DO_BATTLE_TEST("Defog doesn't remove Stealth Rock or Sticky Web from user's side (Gen 4-5)");
+DOUBLE_BATTLE_TEST("Defog removes Stealth Rock and Sticky Web from user's side (Gen 6+)")
{
u16 move;
@@ -151,13 +152,9 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S
ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponentLeft);
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentRight);
ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
- if (move == MOVE_DEFOG) {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
- MESSAGE("The opposing Wobbuffet's evasiveness fell!");
- if (B_DEFOG_EFFECT_CLEARING >= GEN_6) {
- MESSAGE("The pointed stones disappeared from around your team!");
- MESSAGE("The sticky web has disappeared from the ground around your team!");
- }
+ if (move == MOVE_DEFOG && B_DEFOG_EFFECT_CLEARING >= GEN_6) {
+ MESSAGE("The pointed stones disappeared from around your team!");
+ MESSAGE("The sticky web has disappeared from the ground around your team!");
}
// Switch happens
SWITCH_OUT_MESSAGE("Wobbuffet");
@@ -181,7 +178,9 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S
}
}
-SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player's side")
+TO_DO_BATTLE_TEST("Defog removes Spikes from target's side");
+TO_DO_BATTLE_TEST("Defog doesn't remove Spikes from user's side (Gen 4-5)");
+SINGLE_BATTLE_TEST("Defog removes Spikes from user's side (Gen 6+)")
{
u16 move;
@@ -197,12 +196,8 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, opponent);
ANIMATION(ANIM_TYPE_MOVE, move, player);
- if (move == MOVE_DEFOG) {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
- MESSAGE("The opposing Wobbuffet's evasiveness fell!");
- if (B_DEFOG_EFFECT_CLEARING >= GEN_6)
- MESSAGE("The spikes disappeared from the ground around your team!");
- }
+ if (move == MOVE_DEFOG && B_DEFOG_EFFECT_CLEARING >= GEN_6)
+ MESSAGE("The spikes disappeared from the ground around your team!");
// Switch happens
SWITCH_OUT_MESSAGE("Wobbuffet");
SEND_IN_MESSAGE("Wobbuffet");
@@ -219,7 +214,8 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player
}
}
-SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)")
+TO_DO_BATTLE_TEST("Defog doesn't remove terrain (Gen 4-7)");
+SINGLE_BATTLE_TEST("Defog removes terrain (Gen 8+)")
{
u16 move;
@@ -235,8 +231,6 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)")
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DEFOG, opponent);
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Wobbuffet's evasiveness fell!");
if (B_DEFOG_EFFECT_CLEARING >= GEN_8) {
if (move == MOVE_PSYCHIC_TERRAIN) {
MESSAGE("The weirdness disappeared from the battlefield!");
@@ -263,7 +257,9 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)")
}
}
-SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from opponent's side")
+TO_DO_BATTLE_TEST("Defog removes Toxic Spikes from target's side");
+TO_DO_BATTLE_TEST("Defog doesn't remove Toxic Spikes from user's side (Gen 4-5)");
+SINGLE_BATTLE_TEST("Defog removes Toxic Spikes from user's side (Gen 6+)")
{
u16 move;
@@ -279,12 +275,8 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC_SPIKES, player);
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
- if (move == MOVE_DEFOG) {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Wobbuffet's evasiveness fell!");
- if (B_DEFOG_EFFECT_CLEARING >= GEN_6)
- MESSAGE("The poison spikes disappeared from the ground around the opposing team!");
- }
+ if (move == MOVE_DEFOG && B_DEFOG_EFFECT_CLEARING >= GEN_6)
+ MESSAGE("The poison spikes disappeared from the ground around the opposing team!");
// Switch happens
MESSAGE("2 sent out Wobbuffet!");
if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) {
@@ -302,14 +294,15 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from
}
}
-DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Aurora Veil from player's side", s16 damagePhysical, s16 damageSpecial)
+TO_DO_BATTLE_TEST("Defog doesn't remove Aurora Veil from the user's side");
+DOUBLE_BATTLE_TEST("Defog removes Aurora Veil from target's side", s16 damagePhysical, s16 damageSpecial)
{
u16 move;
PARAMETRIZE { move = MOVE_DEFOG; }
PARAMETRIZE { move = MOVE_CELEBRATE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE);
PLAYER(SPECIES_GLALIE) { Speed(4); }
PLAYER(SPECIES_GLALIE) { Speed(3); }
@@ -338,10 +331,10 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Aurora Veil from p
}
}
-DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes everything it can")
+DOUBLE_BATTLE_TEST("Defog removes everything it can")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE);
PLAYER(SPECIES_GLALIE) { Speed(4); }
PLAYER(SPECIES_GLALIE) { Speed(3); }
diff --git a/test/battle/move_effect/destiny_bond.c b/test/battle/move_effect/destiny_bond.c
index ba49e0ec43..ecb8b1d3ef 100644
--- a/test/battle/move_effect/destiny_bond.c
+++ b/test/battle/move_effect/destiny_bond.c
@@ -1,6 +1,11 @@
#include "global.h"
#include "test/battle.h"
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_DESTINY_BOND) == EFFECT_DESTINY_BOND);
+}
+
SINGLE_BATTLE_TEST("Destiny Bond faints the opposing mon if it fainted from the attack")
{
GIVEN {
@@ -15,3 +20,92 @@ SINGLE_BATTLE_TEST("Destiny Bond faints the opposing mon if it fainted from the
MESSAGE("The opposing Wobbuffet fainted!");
}
}
+
+SINGLE_BATTLE_TEST("Destiny Bond fails if used sequentially in Gen 7+")
+{
+ GIVEN {
+ ASSUME(B_DESTINY_BOND_FAIL >= GEN_7);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DESTINY_BOND); }
+ TURN { MOVE(player, MOVE_DESTINY_BOND); SWITCH(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player);
+ MESSAGE("2 sent out Zigzagoon!");
+ NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); }
+ MESSAGE("But it failed!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Destiny Bond does not fail if used repeatedly separated by other moves in Gen 7+")
+{
+ GIVEN {
+ ASSUME(B_DESTINY_BOND_FAIL >= GEN_7);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DESTINY_BOND); }
+ TURN { MOVE(player, MOVE_GROWL); SWITCH(opponent, 1); }
+ TURN { MOVE(player, MOVE_DESTINY_BOND); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player);
+ MESSAGE("2 sent out Zigzagoon!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player);
+ NOT { MESSAGE("But it failed!"); }
+ }
+}
+
+SINGLE_BATTLE_TEST("Destiny Bond does not fail if used after failing in Gen 7+")
+{
+ GIVEN {
+ ASSUME(B_DESTINY_BOND_FAIL >= GEN_7);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DESTINY_BOND); }
+ TURN { MOVE(player, MOVE_DESTINY_BOND); SWITCH(opponent, 1); }
+ TURN { MOVE(player, MOVE_DESTINY_BOND); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player);
+ MESSAGE("2 sent out Zigzagoon!");
+ NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); }
+ MESSAGE("But it failed!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player);
+ }
+}
+
+// can't be used at all in Raid, see "Documenting Dynamax"
+SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are not affected by Destiny Bond")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Speed(50); };
+ OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(100); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_DESTINY_BOND); MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); }
+ } SCENE {
+ MESSAGE("The opposing Wobbuffet used Destiny Bond!");
+ MESSAGE("Wobbuffet used Max Strike!");
+ MESSAGE("The opposing Wobbuffet fainted!");
+ NONE_OF { HP_BAR(player); }
+ }
+}
+
+TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Move");
+TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Sleep");
+TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Paralysis");
+TO_DO_BATTLE_TEST("Destiny Bond's effect disappears if the user takes a new turn - Flinching");
+TO_DO_BATTLE_TEST("Destiny Bond's effect doesn't trigger on indirect damage - Sandstorm");
+TO_DO_BATTLE_TEST("Destiny Bond's effect doesn't trigger on indirect damage - Leech Seed");
+TO_DO_BATTLE_TEST("Destiny Bond's effect doesn't trigger on indirect damage - Future Sight");
+TO_DO_BATTLE_TEST("Destiny Bond's effect bypasses Focus Sash");
+TO_DO_BATTLE_TEST("Destiny Bond's effect bypasses Sturdy");
+TO_DO_BATTLE_TEST("Destiny Bond's effect bypasses Magic Guard");
+TO_DO_BATTLE_TEST("Destiny Bond's effect can trigger on the next turn if the user hasn't moved yet");
+TO_DO_BATTLE_TEST("Destiny Bond can be used multiple times in a row (Gen 2-6)");
+TO_DO_BATTLE_TEST("Destiny Bond always fails if it was successfully used the previous turn (Gen 7+)");
+TO_DO_BATTLE_TEST("Destiny Bond cannot be used in Raids");
+
diff --git a/test/battle/move_effect/disable.c b/test/battle/move_effect/disable.c
new file mode 100644
index 0000000000..9864b360e2
--- /dev/null
+++ b/test/battle/move_effect/disable.c
@@ -0,0 +1,20 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Disable prevents the target from using a random move (Gen 1)");
+TO_DO_BATTLE_TEST("Disable prevents the target from using the last move used (Gen 2+)");
+TO_DO_BATTLE_TEST("Disable fails if one of the target's moves is already disabled");
+TO_DO_BATTLE_TEST("Disable fails if the target haven't used a move yet (Gen 2+)");
+TO_DO_BATTLE_TEST("Disable fails if the last move used was Struggle (Gen 2+)");
+TO_DO_BATTLE_TEST("Disable fails if the last move used was a Max Move");
+TO_DO_BATTLE_TEST("Disabled moves can still be used via Sleep Talk");
+TO_DO_BATTLE_TEST("Disabled moves can still be used via Metronome");
+TO_DO_BATTLE_TEST("Disabled moves can still be used via Mirror Move");
+TO_DO_BATTLE_TEST("Disable lasts 0-7 turns (Gen 1)");
+TO_DO_BATTLE_TEST("Disable lasts 2-8 turns (Gen 2)");
+TO_DO_BATTLE_TEST("Disable lasts 2-5 turns (Gen 3)");
+TO_DO_BATTLE_TEST("Disable lasts 4-7 turns (Gen 4)");
+TO_DO_BATTLE_TEST("Disable lasts 4 turns (Gen 5+)");
+TO_DO_BATTLE_TEST("Disable's timer only counts down when trying to use a move (Gen 1-2)");
+TO_DO_BATTLE_TEST("Disable's timer counts down regardless of the action (Gen 3+)");
+TO_DO_BATTLE_TEST("Baton Pass doesn't pass Disable's effect");
diff --git a/test/battle/move_effect/do_nothing.c b/test/battle/move_effect/do_nothing.c
new file mode 100644
index 0000000000..60ff198b52
--- /dev/null
+++ b/test/battle/move_effect/do_nothing.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Splash does nothing");
diff --git a/test/battle/move_effect/doodle.c b/test/battle/move_effect/doodle.c
index a43a149dc8..af144ecee5 100644
--- a/test/battle/move_effect/doodle.c
+++ b/test/battle/move_effect/doodle.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_DOODLE].effect == EFFECT_DOODLE);
+ ASSUME(GetMoveEffect(MOVE_DOODLE) == EFFECT_DOODLE);
}
DOUBLE_BATTLE_TEST("Doodle gives the target's ability to user and ally")
diff --git a/test/battle/move_effect_secondary/double_power_on_arg_status.c b/test/battle/move_effect/double_power_on_arg_status.c
similarity index 84%
rename from test/battle/move_effect_secondary/double_power_on_arg_status.c
rename to test/battle/move_effect/double_power_on_arg_status.c
index d147264470..d733d04c4f 100644
--- a/test/battle/move_effect_secondary/double_power_on_arg_status.c
+++ b/test/battle/move_effect/double_power_on_arg_status.c
@@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Hex deals double damage to foes with a status", s16 damage)
PARAMETRIZE { status1 = STATUS1_PARALYSIS; }
PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEX].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
- ASSUME(gMovesInfo[MOVE_HEX].argument == STATUS1_ANY);
+ ASSUME(GetMoveEffect(MOVE_HEX) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_HEX) == STATUS1_ANY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); }
} WHEN {
@@ -36,8 +36,8 @@ SINGLE_BATTLE_TEST("Venoshock's power doubles if the target is poisoned/badly po
PARAMETRIZE { status1 = STATUS1_POISON; }
PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_VENOSHOCK].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
- ASSUME(gMovesInfo[MOVE_VENOSHOCK].argument == STATUS1_PSN_ANY);
+ ASSUME(GetMoveEffect(MOVE_VENOSHOCK) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_VENOSHOCK) == STATUS1_PSN_ANY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); }
} WHEN {
diff --git a/test/battle/move_effect/dragon_cheer.c b/test/battle/move_effect/dragon_cheer.c
new file mode 100644
index 0000000000..1e28c6d4b3
--- /dev/null
+++ b/test/battle/move_effect/dragon_cheer.c
@@ -0,0 +1,77 @@
+#include "global.h"
+#include "test/battle.h"
+
+SINGLE_BATTLE_TEST("Dragon Cheer fails in a single battle")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_DRAGON_CHEER); }
+ } SCENE {
+ MESSAGE("But it failed!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by one on non-Dragon types")
+{
+ PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
+ GIVEN {
+ ASSUME(B_CRIT_CHANCE >= GEN_7);
+ ASSUME(GetMoveCriticalHitStage(MOVE_TACKLE) == 0);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft);
+ MESSAGE("Wynaut is getting pumped!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
+ MESSAGE("A critical hit!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Dragon Cheer increases critical hit ratio by two on Dragon types")
+{
+ PASSES_RANDOMLY(1, 2, RNG_CRITICAL_HIT);
+ GIVEN {
+ ASSUME(B_CRIT_CHANCE >= GEN_7);
+ ASSUME(GetMoveCriticalHitStage(MOVE_TACKLE) == 0);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_DRATINI);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_DRAGON_CHEER, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_CHEER, playerLeft);
+ MESSAGE("Dratini is getting pumped!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
+ MESSAGE("A critical hit!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Dragon Cheer fails if critical hit stage was already increased by Focus Energy")
+{
+ GIVEN {
+ ASSUME(GetMoveCriticalHitStage(MOVE_SLASH) == 1);
+ ASSUME(GetMoveEffect(MOVE_FOCUS_ENERGY) == EFFECT_FOCUS_ENERGY);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_CHEER) == EFFECT_DRAGON_CHEER);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_FOCUS_ENERGY); MOVE(playerRight, MOVE_DRAGON_CHEER, target: playerLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FOCUS_ENERGY, playerLeft);
+ MESSAGE("But it failed!");
+ }
+}
+
+TO_DO_BATTLE_TEST("Baton Pass passes Dragon Cheer's effect");
diff --git a/test/battle/move_effect/dragon_dance.c b/test/battle/move_effect/dragon_dance.c
new file mode 100644
index 0000000000..52587cc098
--- /dev/null
+++ b/test/battle/move_effect/dragon_dance.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Dragon Dance increases Attack and Speed by one stage each");
diff --git a/test/battle/move_effect/dragon_darts.c b/test/battle/move_effect/dragon_darts.c
index dfe629896f..9e178f67c8 100644
--- a/test/battle/move_effect/dragon_darts.c
+++ b/test/battle/move_effect/dragon_darts.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_DRAGON_DARTS].effect == EFFECT_DRAGON_DARTS);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_DARTS) == EFFECT_DRAGON_DARTS);
ASSUME(gSpeciesInfo[SPECIES_CLEFAIRY].types[0] == TYPE_FAIRY || gSpeciesInfo[SPECIES_CLEFAIRY].types[1] == TYPE_FAIRY);
}
@@ -23,170 +23,148 @@ SINGLE_BATTLE_TEST("Dragon Darts strikes twice")
DOUBLE_BATTLE_TEST("Dragon Darts strikes each opponent once in a double battle")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *secondaryTarget = NULL;
+ PARAMETRIZE { chosenTarget = opponentLeft; secondaryTarget = opponentRight; }
+ PARAMETRIZE { chosenTarget = opponentRight; secondaryTarget = opponentLeft; }
+
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
- TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
+ HP_BAR(chosenTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(secondaryTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
DOUBLE_BATTLE_TEST("Dragon Darts strikes the ally twice if the target protects")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *secondaryTarget = NULL;
+ PARAMETRIZE { chosenTarget = opponentLeft; secondaryTarget = opponentRight; }
+ PARAMETRIZE { chosenTarget = opponentRight; secondaryTarget = opponentLeft; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
- TURN { MOVE(opponentLeft, MOVE_PROTECT); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); }
+ TURN { MOVE(chosenTarget, MOVE_PROTECT); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); }
} SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponentLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, chosenTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(secondaryTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(secondaryTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
-DOUBLE_BATTLE_TEST("Dragon Darts strikes the right ally twice if the target is a fairy type")
+DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if the other one is Fairy-type")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *finalTarget = NULL;
+ u32 speciesLeft, speciesRight;
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; speciesLeft = SPECIES_CLEFAIRY; speciesRight = SPECIES_WOBBUFFET; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentRight; speciesLeft = SPECIES_CLEFAIRY; speciesRight = SPECIES_WOBBUFFET; }
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentLeft; speciesLeft = SPECIES_WOBBUFFET; speciesRight = SPECIES_CLEFAIRY; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; speciesLeft = SPECIES_WOBBUFFET; speciesRight = SPECIES_CLEFAIRY; }
GIVEN {
+ ASSUME(gSpeciesInfo[SPECIES_CLEFAIRY].types[0] == TYPE_FAIRY || gSpeciesInfo[SPECIES_CLEFAIRY].types[1] == TYPE_FAIRY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_CLEFAIRY);
- OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(speciesLeft);
+ OPPONENT(speciesRight);
} WHEN {
- TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
-DOUBLE_BATTLE_TEST("Dragon Darts strikes the left ally twice if the target is a fairy type")
+DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if electrified and the other one has Volt Absorb")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *finalTarget = NULL;
+ u32 abilityLeft, abilityRight;
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentLeft; abilityLeft = ABILITY_WATER_ABSORB; abilityRight = ABILITY_VOLT_ABSORB; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; abilityLeft = ABILITY_WATER_ABSORB; abilityRight = ABILITY_VOLT_ABSORB; }
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; abilityLeft = ABILITY_VOLT_ABSORB; abilityRight = ABILITY_WATER_ABSORB; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentRight; abilityLeft = ABILITY_VOLT_ABSORB; abilityRight = ABILITY_WATER_ABSORB; }
GIVEN {
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_CLEFAIRY);
- OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_LANTURN) { Ability(abilityLeft); };
+ OPPONENT(SPECIES_LANTURN) { Ability(abilityRight); };
} WHEN {
- TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); }
+ TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
-DOUBLE_BATTLE_TEST("Dragon Darts strikes left ally twice if electrified and right ally has Volt Absorb")
+DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if electrified and the other one has Motor Drive")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *finalTarget = NULL;
+ u32 abilityLeft, abilityRight;
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentLeft; abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_MOTOR_DRIVE; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; abilityLeft = ABILITY_VITAL_SPIRIT; abilityRight = ABILITY_MOTOR_DRIVE; }
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; abilityLeft = ABILITY_MOTOR_DRIVE; abilityRight = ABILITY_VITAL_SPIRIT; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentRight; abilityLeft = ABILITY_MOTOR_DRIVE; abilityRight = ABILITY_VITAL_SPIRIT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); };
+ OPPONENT(SPECIES_ELECTIVIRE) { Ability(abilityLeft); };
+ OPPONENT(SPECIES_ELECTIVIRE) { Ability(abilityRight); };
} WHEN {
- TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); }
+ TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
+ HP_BAR(finalTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
+ HP_BAR(finalTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
-DOUBLE_BATTLE_TEST("Dragon Darts strikes right ally twice if electrified and left ally has Volt Absorb")
+DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if the other one is in a semi-invulnerable turn")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *finalTarget = NULL;
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); };
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
- MESSAGE("The Pokémon was hit 2 time(s)!");
- }
-}
-
-DOUBLE_BATTLE_TEST("Dragon Darts strikes left ally twice if electrified and right ally has Motor Drive")
-{
- GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); };
- } WHEN {
- TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
- MESSAGE("The Pokémon was hit 2 time(s)!");
- }
-}
-
-DOUBLE_BATTLE_TEST("Dragon Darts strikes right ally twice if electrified and left ally has Motor Drive")
-{
- GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); };
- OPPONENT(SPECIES_WOBBUFFET);
- } WHEN {
- TURN { MOVE(opponentRight, MOVE_ELECTRIFY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
- MESSAGE("The Pokémon was hit 2 time(s)!");
- }
-}
-
-
-DOUBLE_BATTLE_TEST("Dragon Darts strikes the ally twice if the target is in a semi-invulnerable turn")
-{
- GIVEN {
- ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
- TURN { MOVE(opponentLeft, MOVE_FLY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); }
+ TURN { MOVE(chosenTarget, MOVE_FLY, target: playerLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); }
} SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_FLY, opponentLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FLY, chosenTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
@@ -210,39 +188,49 @@ DOUBLE_BATTLE_TEST("Dragon Darts is not effected by Wide Guard")
}
}
-DOUBLE_BATTLE_TEST("Dragon Darts strikes hit the ally if the target fainted")
+DOUBLE_BATTLE_TEST("Dragon Darts strikes an opponent twice if the other one is fainted")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *finalTarget = NULL;
+ u32 hpLeft, hpRight;
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; hpLeft = 1; hpRight = 101; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; hpLeft = 101; hpRight = 1; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
- OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { HP(hpLeft); }
+ OPPONENT(SPECIES_WOBBUFFET) { HP(hpRight); }
} WHEN {
- TURN { MOVE(playerRight, MOVE_SONIC_BOOM, target: opponentLeft); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentLeft); }
+ TURN { MOVE(playerRight, MOVE_SONIC_BOOM, target: chosenTarget); MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SONIC_BOOM, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentRight);
+ HP_BAR(finalTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
DOUBLE_BATTLE_TEST("Dragon Darts strikes left ally twice if one strike misses")
{
+ struct BattlePokemon *chosenTarget = NULL;
+ struct BattlePokemon *finalTarget = NULL;
+ u32 itemLeft, itemRight;
+ PARAMETRIZE { chosenTarget = opponentLeft; finalTarget = opponentRight; itemLeft = ITEM_BRIGHT_POWDER; itemRight = ITEM_NONE; }
+ PARAMETRIZE { chosenTarget = opponentRight; finalTarget = opponentLeft; itemLeft = ITEM_NONE; itemRight = ITEM_BRIGHT_POWDER; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_BRIGHT_POWDER); };
+ OPPONENT(SPECIES_WOBBUFFET) { Item(itemLeft); };
+ OPPONENT(SPECIES_WOBBUFFET) { Item(itemRight); };
} WHEN {
- TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: opponentRight, hit: FALSE); }
+ TURN { MOVE(playerLeft, MOVE_DRAGON_DARTS, target: chosenTarget, hit: FALSE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
+ HP_BAR(finalTarget);
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DARTS, playerLeft);
- HP_BAR(opponentLeft);
+ HP_BAR(finalTarget);
MESSAGE("The Pokémon was hit 2 time(s)!");
}
}
diff --git a/test/battle/move_effect/dream_eater.c b/test/battle/move_effect/dream_eater.c
index 7dfa6525d9..b840e9860c 100644
--- a/test/battle/move_effect/dream_eater.c
+++ b/test/battle/move_effect/dream_eater.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_DREAM_EATER].effect == EFFECT_DREAM_EATER);
+ ASSUME(GetMoveEffect(MOVE_DREAM_EATER) == EFFECT_DREAM_EATER);
}
SINGLE_BATTLE_TEST("Dream Eater recovers 50% of the damage dealt")
@@ -54,3 +54,7 @@ SINGLE_BATTLE_TEST("Dream Eater fails if Heal Block applies")
}
}
}
+
+TO_DO_BATTLE_TEST("Dream Eater works on targets with Comatose");
+TO_DO_BATTLE_TEST("Dream Eater fails if the target is behind a Substitute (Gen 1-4)");
+TO_DO_BATTLE_TEST("Dream Eater works if the target is behind a Substitute (Gen 5+)");
diff --git a/test/battle/move_effect/dynamax_double_dmg.c b/test/battle/move_effect/dynamax_double_dmg.c
new file mode 100644
index 0000000000..c19ba5ecbc
--- /dev/null
+++ b/test/battle/move_effect/dynamax_double_dmg.c
@@ -0,0 +1,20 @@
+#include "global.h"
+#include "test/battle.h"
+
+SINGLE_BATTLE_TEST("Dynamax Cannon causes double damage to Dynamaxed Pokemon", s16 damage)
+{
+ u32 dynamax;
+ PARAMETRIZE { dynamax = GIMMICK_NONE; }
+ PARAMETRIZE { dynamax = GIMMICK_DYNAMAX; }
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_DYNAMAX_CANNON) == EFFECT_DYNAMAX_DOUBLE_DMG);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_TACKLE, gimmick: dynamax); MOVE(opponent, MOVE_DYNAMAX_CANNON); }
+ } SCENE {
+ HP_BAR(player, captureDamage: &results[i].damage);
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, UQ_4_12(2.0), results[1].damage);
+ }
+}
diff --git a/test/battle/move_effect/earthquake.c b/test/battle/move_effect/earthquake.c
index 93955e15b4..2cbf3b32c5 100644
--- a/test/battle/move_effect/earthquake.c
+++ b/test/battle/move_effect/earthquake.c
@@ -10,8 +10,8 @@ SINGLE_BATTLE_TEST("Earthquake's and Bulldoze's damage is halved when Grassy Ter
PARAMETRIZE { terrain = FALSE; move = MOVE_BULLDOZE; } // 2
PARAMETRIZE { terrain = TRUE; move = MOVE_BULLDOZE; } // 3
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].effect == EFFECT_EARTHQUAKE);
- ASSUME(gMovesInfo[MOVE_BULLDOZE].effect == EFFECT_EARTHQUAKE);
+ ASSUME(GetMoveEffect(MOVE_EARTHQUAKE) == EFFECT_EARTHQUAKE);
+ ASSUME(GetMoveEffect(MOVE_BULLDOZE) == EFFECT_EARTHQUAKE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/echoed_voice.c b/test/battle/move_effect/echoed_voice.c
new file mode 100644
index 0000000000..3c36270454
--- /dev/null
+++ b/test/battle/move_effect/echoed_voice.c
@@ -0,0 +1,7 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Echoed Voice's power is multiplied for every consecutive turn used, capped at 5");
+TO_DO_BATTLE_TEST("Echoed Voice's power is reset when using a different move");
+TO_DO_BATTLE_TEST("Echoed Voice's power is increased even if it misses");
+TO_DO_BATTLE_TEST("Echoed Voice's power is increased even if it's blocked by Protect");
diff --git a/test/battle/terrain/electric.c b/test/battle/move_effect/electric_terrain.c
similarity index 74%
rename from test/battle/terrain/electric.c
rename to test/battle/move_effect/electric_terrain.c
index b3811d056c..bf6d2536e6 100644
--- a/test/battle/terrain/electric.c
+++ b/test/battle/move_effect/electric_terrain.c
@@ -19,25 +19,6 @@ SINGLE_BATTLE_TEST("Electric Terrain protects grounded battlers from falling asl
}
}
-SINGLE_BATTLE_TEST("Electric Terrain activates Electric Seed and Mimicry")
-{
- GIVEN {
- ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffect == HOLD_EFFECT_SEEDS);
- ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN);
- PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIC_SEED); }
- OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); }
- } WHEN {
- TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); }
- } SCENE {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!");
- ABILITY_POPUP(opponent);
- MESSAGE("The opposing Stunfisk's type changed to Electric!");
- } THEN {
- EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_ELECTRIC);
- }
-}
-
SINGLE_BATTLE_TEST("Electric Terrain increases power of Electric-type moves by 30/50 percent", s16 damage)
{
bool32 terrain;
diff --git a/test/battle/move_effect/electrify.c b/test/battle/move_effect/electrify.c
new file mode 100644
index 0000000000..71373cdd58
--- /dev/null
+++ b/test/battle/move_effect/electrify.c
@@ -0,0 +1,5 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Electrify makes the target's move Electric-type for the remainder of the turn");
+TO_DO_BATTLE_TEST("Electrify can change status moves to Electric-type"); // Test type immunity
diff --git a/test/battle/move_effect/electro_ball.c b/test/battle/move_effect/electro_ball.c
new file mode 100644
index 0000000000..a74445c00c
--- /dev/null
+++ b/test/battle/move_effect/electro_ball.c
@@ -0,0 +1,5 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Electro Ball inflicts more damage the faster the user is compared to the target");
+TO_DO_BATTLE_TEST("Electro Ball considers speed modifiers"); // Stat modifiers, paralysis, Iron Ball, Abilities
diff --git a/test/battle/move_effect/embargo.c b/test/battle/move_effect/embargo.c
index 81939a6d56..3e86b60b0b 100644
--- a/test/battle/move_effect/embargo.c
+++ b/test/battle/move_effect/embargo.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_EMBARGO].effect == EFFECT_EMBARGO);
+ ASSUME(GetMoveEffect(MOVE_EMBARGO) == EFFECT_EMBARGO);
}
SINGLE_BATTLE_TEST("Embargo blocks the effect of an affected Pokémon's held item")
diff --git a/test/battle/move_effect/encore.c b/test/battle/move_effect/encore.c
index ec68297ca0..2d1863da6b 100644
--- a/test/battle/move_effect/encore.c
+++ b/test/battle/move_effect/encore.c
@@ -3,94 +3,59 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE);
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
}
-SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player: Encore used before move")
+SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns: Encore used before move")
{
+ struct BattlePokemon *encoreUser = NULL;
+ struct BattlePokemon *encoreTarget = NULL;
+ u32 speedPlayer, speedOpponent;
+ PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 10; speedOpponent = 20; }
+ PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 20; speedOpponent = 10; }
GIVEN {
- PLAYER(SPECIES_WOBBUFFET) { Speed(10); }
- OPPONENT(SPECIES_WOBBUFFET) { Speed(20); }
+ PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); }
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); }
} WHEN {
- TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_CELEBRATE); }
- TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_CELEBRATE); }
- // TURN { FORCED_MOVE(player); }
- TURN { FORCED_MOVE(player); }
- TURN { FORCED_MOVE(player); }
- TURN { MOVE(player, MOVE_SPLASH); }
+ TURN { MOVE(encoreUser, MOVE_CELEBRATE); MOVE(encoreTarget, MOVE_CELEBRATE); }
+ TURN { MOVE(encoreUser, MOVE_ENCORE); MOVE(encoreTarget, MOVE_CELEBRATE); }
+ TURN { FORCED_MOVE(encoreTarget); }
+ TURN { FORCED_MOVE(encoreTarget); }
+ TURN { MOVE(encoreTarget, MOVE_SPLASH); }
} SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreUser);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, encoreUser);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, encoreTarget);
}
}
SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player: Encore used after move")
{
+ struct BattlePokemon *encoreUser = NULL;
+ struct BattlePokemon *encoreTarget = NULL;
+ u32 speedPlayer, speedOpponent;
+ PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 20; speedOpponent = 10; }
+ PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 10; speedOpponent = 20; }
GIVEN {
- PLAYER(SPECIES_WOBBUFFET) { Speed(20); }
- OPPONENT(SPECIES_WOBBUFFET) { Speed(10); }
+ PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); }
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); }
} WHEN {
- TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_ENCORE); }
- TURN { FORCED_MOVE(player); }
- TURN { FORCED_MOVE(player); }
- TURN { FORCED_MOVE(player); }
- TURN { MOVE(player, MOVE_SPLASH); }
+ TURN { MOVE(encoreTarget, MOVE_CELEBRATE); MOVE(encoreUser, MOVE_ENCORE); }
+ TURN { FORCED_MOVE(encoreTarget); }
+ TURN { FORCED_MOVE(encoreTarget); }
+ TURN { FORCED_MOVE(encoreTarget); }
+ TURN { MOVE(encoreTarget, MOVE_SPLASH); }
} SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player);
- }
-}
-
-SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for opponent: Encore used before move")
-{
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET) { Speed(20); }
- OPPONENT(SPECIES_WOBBUFFET) { Speed(10); }
- } WHEN {
- TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); }
- TURN { MOVE(player, MOVE_ENCORE); MOVE(opponent, MOVE_CELEBRATE); }
- // TURN { FORCED_MOVE(opponent); }
- TURN { FORCED_MOVE(opponent); }
- TURN { FORCED_MOVE(opponent); }
- TURN { MOVE(opponent, MOVE_SPLASH); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent);
- }
-}
-
-SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for opponent: Encore used after move")
-{
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET) { Speed(10); }
- OPPONENT(SPECIES_WOBBUFFET) { Speed(20); }
- } WHEN {
- TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_ENCORE); }
- TURN { FORCED_MOVE(opponent); }
- TURN { FORCED_MOVE(opponent); }
- TURN { FORCED_MOVE(opponent); }
- TURN { MOVE(opponent, MOVE_SPLASH); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, encoreUser);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, encoreTarget);
}
}
@@ -121,3 +86,44 @@ SINGLE_BATTLE_TEST("Encore overrides the chosen move if it occurs first")
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
}
}
+
+SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_ENCORE); }
+ TURN { MOVE(player, MOVE_EMBER); }
+ } SCENE {
+ MESSAGE("Wobbuffet used Max Strike!");
+ MESSAGE("The opposing Wobbuffet used Encore!");
+ MESSAGE("But it failed!");
+ MESSAGE("Wobbuffet used Max Flare!");
+ }
+}
+
+SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; // yes, this speed is necessary
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(100); };
+ } WHEN {
+ TURN { MOVE(player, MOVE_ARM_THRUST, gimmick: GIMMICK_DYNAMAX); }
+ TURN { MOVE(player, MOVE_ARM_THRUST); }
+ TURN { MOVE(player, MOVE_ARM_THRUST); }
+ TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); }
+ } SCENE {
+ MESSAGE("Wobbuffet used Max Knuckle!");
+ MESSAGE("Wobbuffet used Max Knuckle!");
+ MESSAGE("Wobbuffet used Max Knuckle!");
+ MESSAGE("The opposing Wobbuffet used Encore!");
+ MESSAGE("Wobbuffet used Arm Thrust!");
+ }
+}
+
+TO_DO_BATTLE_TEST("Encore's effect ends if the encored move runs out of PP");
+TO_DO_BATTLE_TEST("Encore lasts for 2-6 turns (Gen 2-3)");
+TO_DO_BATTLE_TEST("Encore lasts for 4-8 turns (Gen 4)");
+TO_DO_BATTLE_TEST("Encore lasts for 3 turns (Gen 5+)");
+TO_DO_BATTLE_TEST("Encore randomly chooses an opponent target");
diff --git a/test/battle/move_effect/endeavor.c b/test/battle/move_effect/endeavor.c
new file mode 100644
index 0000000000..43786c29b3
--- /dev/null
+++ b/test/battle/move_effect/endeavor.c
@@ -0,0 +1,23 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_ENDEAVOR) == EFFECT_ENDEAVOR);
+}
+
+SINGLE_BATTLE_TEST("Endeavor causes the target's HP to equal the user's current HP")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_ENDEAVOR); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDEAVOR, player);
+ } THEN {
+ EXPECT_EQ(player->hp, opponent->hp);
+ }
+}
+TO_DO_BATTLE_TEST("Endeavor does not change HP if the target has less HP than the user, but still plays the animation")
+TO_DO_BATTLE_TEST("Endeavor fails on Ghost-type Pokémon");
diff --git a/test/battle/move_effect/endure.c b/test/battle/move_effect/endure.c
new file mode 100644
index 0000000000..5401321162
--- /dev/null
+++ b/test/battle/move_effect/endure.c
@@ -0,0 +1,35 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Endure allows the user to survive any attack with 1 HP left");
+
+SINGLE_BATTLE_TEST("Endure does not prevent multiple hits and stat changes occur at the end of the turn")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_ENDURE) == EFFECT_ENDURE);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_ENDURE); MOVE(player, MOVE_SCALE_SHOT); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDURE, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
+ MESSAGE("The Pokémon was hit 5 time(s)!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's Defense fell!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's Speed rose!");
+ }
+}
+
+TO_DO_BATTLE_TEST("Endure's success rate decreases for every consecutively used turn");
+TO_DO_BATTLE_TEST("Endure uses the same counter as Protect");
+TO_DO_BATTLE_TEST("Endure doesn't trigger effects that require damage to be done to the Pokémon (Gen 2-4)"); // Eg. Rough Skin
+TO_DO_BATTLE_TEST("Endure triggers effects that require damage to be done to the Pokémon (Gen 5+)"); // Eg. Rough Skin
+TO_DO_BATTLE_TEST("Endure doesn't protect against Future Sight (Gen 2-4)");
+TO_DO_BATTLE_TEST("Endure protects against Future Sight (Gen 5+)");
diff --git a/test/battle/move_effect/entrainment.c b/test/battle/move_effect/entrainment.c
new file mode 100644
index 0000000000..b43f6dcbc1
--- /dev/null
+++ b/test/battle/move_effect/entrainment.c
@@ -0,0 +1,6 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Entrainment changes the target's Ability to match the user's");
+TO_DO_BATTLE_TEST("Entrainment fails if the user's ability has cantBeCopied flag");
+TO_DO_BATTLE_TEST("Entrainment fails if the targets's ability has cantBeOverwritten flag");
diff --git a/test/battle/move_effect/evasion_down.c b/test/battle/move_effect/evasion_down.c
new file mode 100644
index 0000000000..ecc0db135b
--- /dev/null
+++ b/test/battle/move_effect/evasion_down.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Sweet Scent lowers evasion by 1 stage (Gen 2-5)");
diff --git a/test/battle/move_effect/evasion_down_2.c b/test/battle/move_effect/evasion_down_2.c
new file mode 100644
index 0000000000..7584406e4c
--- /dev/null
+++ b/test/battle/move_effect/evasion_down_2.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Sweet Scent lowers evasion by 1 stage (Gen 6+)");
diff --git a/test/battle/move_effect/evasion_up.c b/test/battle/move_effect/evasion_up.c
index 7058694e9d..529a32c4f1 100644
--- a/test/battle/move_effect/evasion_up.c
+++ b/test/battle/move_effect/evasion_up.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_DOUBLE_TEAM].effect == EFFECT_EVASION_UP);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_TEAM) == EFFECT_EVASION_UP);
}
-SINGLE_BATTLE_TEST("Double Team raises Evasion")
+SINGLE_BATTLE_TEST("Double Team raises Evasion by 1 stage")
{
- PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY);
+ PASSES_RANDOMLY(GetMoveAccuracy(MOVE_SCRATCH) * 3 / 4, 100, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
+ ASSUME(GetMoveAccuracy(MOVE_SCRATCH) == 100);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/evasion_up_2.c b/test/battle/move_effect/evasion_up_2.c
new file mode 100644
index 0000000000..cd5cb543a9
--- /dev/null
+++ b/test/battle/move_effect/evasion_up_2.c
@@ -0,0 +1,28 @@
+#include "global.h"
+#include "test/battle.h"
+
+// There's no move with EFFECT_EVASION_UP_2 effect. Below is a theoretical test.
+
+/*
+ASSUMPTIONS
+{
+ ASSUME(gMovesInfo[MOVE_X].effect == EFFECT_EVASION_UP_2);
+}
+
+SINGLE_BATTLE_TEST("Double Team raises Evasion by 1 stage")
+{
+ PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 5, 100, RNG_ACCURACY);
+ GIVEN {
+ ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_X); MOVE(opponent, MOVE_SCRATCH); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_X, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's evasiveness sharply rose!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
+ }
+}
+*/
diff --git a/test/battle/move_effect/expanding_force.c b/test/battle/move_effect/expanding_force.c
new file mode 100644
index 0000000000..74b78fdd86
--- /dev/null
+++ b/test/battle/move_effect/expanding_force.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Expanding Force's power increases by 50% if the user is affected by Psychic Terrain");
diff --git a/test/battle/move_effect/explosion.c b/test/battle/move_effect/explosion.c
index d463e10349..52eec1a8e2 100644
--- a/test/battle/move_effect/explosion.c
+++ b/test/battle/move_effect/explosion.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
}
SINGLE_BATTLE_TEST("Explosion causes the user to faint")
@@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Explosion causes the user to faint even if it misses")
SINGLE_BATTLE_TEST("Explosion causes the user to faint even if it has no effect")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_EXPLOSION) == TYPE_NORMAL);
ASSUME(gSpeciesInfo[SPECIES_GASTLY].types[0] == TYPE_GHOST);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GASTLY);
@@ -82,10 +82,10 @@ DOUBLE_BATTLE_TEST("Explosion causes everyone to faint in a double battle")
HP_BAR(playerLeft, hp: 0);
ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, playerLeft);
HP_BAR(opponentLeft, hp: 0);
- MESSAGE("The opposing Abra fainted!");
HP_BAR(playerRight, hp: 0);
- MESSAGE("Wynaut fainted!");
HP_BAR(opponentRight, hp: 0);
+ MESSAGE("The opposing Abra fainted!");
+ MESSAGE("Wynaut fainted!");
MESSAGE("The opposing Kadabra fainted!");
MESSAGE("Wobbuffet fainted!");
}
@@ -139,8 +139,8 @@ DOUBLE_BATTLE_TEST("Explosion boosted by Galvanize is correctly blocked by Volt
ABILITY_POPUP(opponentLeft, ABILITY_VOLT_ABSORB);
NOT HP_BAR(opponentLeft, hp: 0);
HP_BAR(playerRight, hp: 0);
- MESSAGE("Wynaut fainted!");
HP_BAR(opponentRight, hp: 0);
+ MESSAGE("Wynaut fainted!");
MESSAGE("The opposing Wobbuffet fainted!");
MESSAGE("Geodude fainted!");
}
diff --git a/test/battle/move_effect/extreme_evoboost.c b/test/battle/move_effect/extreme_evoboost.c
new file mode 100644
index 0000000000..c43a6f7374
--- /dev/null
+++ b/test/battle/move_effect/extreme_evoboost.c
@@ -0,0 +1,4 @@
+#include "global.h"
+#include "test/battle.h"
+
+TO_DO_BATTLE_TEST("Extreme Evoboost increases the user's Attack, Defense, Special Attack, Special Defense, and Speed stats by 2 stages each");
diff --git a/test/battle/move_effect/fail_if_not_arg_type.c b/test/battle/move_effect/fail_if_not_arg_type.c
index 9e8d005d8b..368c3410c0 100644
--- a/test/battle/move_effect/fail_if_not_arg_type.c
+++ b/test/battle/move_effect/fail_if_not_arg_type.c
@@ -4,8 +4,8 @@
SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
+ ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE);
ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_CYNDAQUIL].types[1] == TYPE_FIRE);
PLAYER(SPECIES_CYNDAQUIL);
@@ -24,8 +24,8 @@ SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type")
SINGLE_BATTLE_TEST("Burn Up fails if the user isn't a Fire-type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
+ ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -41,8 +41,8 @@ SINGLE_BATTLE_TEST("Burn Up fails if the user isn't a Fire-type")
SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type if enemy faints")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BURN_UP].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
+ ASSUME(GetMoveEffect(MOVE_BURN_UP) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FIRE || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FIRE);
ASSUME(gSpeciesInfo[SPECIES_CYNDAQUIL].types[0] == TYPE_FIRE || gSpeciesInfo[SPECIES_CYNDAQUIL].types[1] == TYPE_FIRE);
PLAYER(SPECIES_CYNDAQUIL);
@@ -59,8 +59,8 @@ SINGLE_BATTLE_TEST("Burn Up user loses its Fire-type if enemy faints")
SINGLE_BATTLE_TEST("Double Shock user loses its Electric-type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC);
ASSUME(gSpeciesInfo[SPECIES_PIKACHU].types[0] == TYPE_ELECTRIC || gSpeciesInfo[SPECIES_PIKACHU].types[1] == TYPE_ELECTRIC);
PLAYER(SPECIES_PIKACHU);
@@ -79,8 +79,8 @@ SINGLE_BATTLE_TEST("Double Shock user loses its Electric-type")
SINGLE_BATTLE_TEST("Double Shock fails if the user isn't an Electric-type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("Double Shock fails if the user isn't an Electric-type")
SINGLE_BATTLE_TEST("Double Shock user loses its Electric-type if enemy faints")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_SHOCK].effect == EFFECT_FAIL_IF_NOT_ARG_TYPE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
+ ASSUME(GetMoveEffect(MOVE_DOUBLE_SHOCK) == EFFECT_FAIL_IF_NOT_ARG_TYPE);
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_DOUBLE_SHOCK, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_ELECTRIC) == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ELECTRIC || gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ELECTRIC);
ASSUME(gSpeciesInfo[SPECIES_PIKACHU].types[0] == TYPE_ELECTRIC || gSpeciesInfo[SPECIES_PIKACHU].types[1] == TYPE_ELECTRIC);
PLAYER(SPECIES_PIKACHU);
diff --git a/test/battle/move_effect/fickle_beam.c b/test/battle/move_effect/fickle_beam.c
index ffbbe4d18d..0313823aa9 100644
--- a/test/battle/move_effect/fickle_beam.c
+++ b/test/battle/move_effect/fickle_beam.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FICKLE_BEAM].effect == EFFECT_FICKLE_BEAM);
+ ASSUME(GetMoveEffect(MOVE_FICKLE_BEAM) == EFFECT_FICKLE_BEAM);
}
SINGLE_BATTLE_TEST("Fickle Beam deals double damage 30% of the time")
@@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Fickle Beam deals double damage 30% of the time")
PASSES_RANDOMLY(30, 100, RNG_FICKLE_BEAM);
GIVEN {
- ASSUME(gMovesInfo[MOVE_POWER_GEM].power == 80);
- ASSUME(gMovesInfo[MOVE_FICKLE_BEAM].power == 80);
+ ASSUME(GetMovePower(MOVE_POWER_GEM) == 80);
+ ASSUME(GetMovePower(MOVE_FICKLE_BEAM) == 80);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/fillet_away.c b/test/battle/move_effect/fillet_away.c
index de203dbc5a..f9b679bfe5 100644
--- a/test/battle/move_effect/fillet_away.c
+++ b/test/battle/move_effect/fillet_away.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FILLET_AWAY].effect == EFFECT_FILLET_AWAY);
+ ASSUME(GetMoveEffect(MOVE_FILLET_AWAY) == EFFECT_FILLET_AWAY);
}
SINGLE_BATTLE_TEST("Fillet Away cuts the user's HP in half")
diff --git a/test/battle/move_effect/fixed_damage_arg.c b/test/battle/move_effect/fixed_damage_arg.c
index 484601be05..8cb2987072 100644
--- a/test/battle/move_effect/fixed_damage_arg.c
+++ b/test/battle/move_effect/fixed_damage_arg.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SONIC_BOOM].effect == EFFECT_FIXED_DAMAGE_ARG);
+ ASSUME(GetMoveEffect(MOVE_SONIC_BOOM) == EFFECT_FIXED_DAMAGE_ARG);
}
SINGLE_BATTLE_TEST("Sonic Boom deals fixed damage", s16 damage)
@@ -11,9 +11,9 @@ SINGLE_BATTLE_TEST("Sonic Boom deals fixed damage", s16 damage)
u16 mon;
PARAMETRIZE { mon = SPECIES_RATTATA; }
PARAMETRIZE { mon = SPECIES_ARON; }
-
+
GIVEN {
- ASSUME(gMovesInfo[MOVE_SONIC_BOOM].argument == 20);
+ ASSUME(GetMoveFixedDamage(MOVE_SONIC_BOOM) == 20);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(mon);
} WHEN {
diff --git a/test/battle/move_effect/flame_burst.c b/test/battle/move_effect/flame_burst.c
index 3597c80014..df0199e116 100644
--- a/test/battle/move_effect/flame_burst.c
+++ b/test/battle/move_effect/flame_burst.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FLAME_BURST].additionalEffects->moveEffect == MOVE_EFFECT_FLAME_BURST);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_FLAME_BURST, 0)->moveEffect == MOVE_EFFECT_FLAME_BURST);
}
// Flame Burst AoE is supposed to hit through Substitute
DOUBLE_BATTLE_TEST("Flame Burst Substitute")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
+ ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WYNAUT);
diff --git a/test/battle/move_effect/fling.c b/test/battle/move_effect/fling.c
index 2bd1e824f1..b98020474b 100644
--- a/test/battle/move_effect/fling.c
+++ b/test/battle/move_effect/fling.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
+ ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING);
}
SINGLE_BATTLE_TEST("Fling fails if pokemon holds no item")
@@ -38,8 +38,8 @@ SINGLE_BATTLE_TEST("Fling fails if pokemon is under the effects of Embargo or Ma
PARAMETRIZE {move = MOVE_MAGIC_ROOM; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBARGO].effect == EFFECT_EMBARGO);
- ASSUME(gMovesInfo[MOVE_MAGIC_ROOM].effect == EFFECT_MAGIC_ROOM);
+ ASSUME(GetMoveEffect(MOVE_EMBARGO) == EFFECT_EMBARGO);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_ROOM) == EFFECT_MAGIC_ROOM);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RAZOR_CLAW); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Fling fails for pokemon with Klutz ability")
SINGLE_BATTLE_TEST("Fling's thrown item can be regained with Recycle")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
+ ASSUME(GetMoveEffect(MOVE_RECYCLE) == EFFECT_RECYCLE);
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -106,7 +106,7 @@ SINGLE_BATTLE_TEST("Fling's thrown item can be regained with Recycle")
SINGLE_BATTLE_TEST("Fling - Item is lost even when there is no target")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SELF_DESTRUCT].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_SELF_DESTRUCT) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); Speed(2); }
OPPONENT(SPECIES_WOBBUFFET) {Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) {Speed(5); }
@@ -131,7 +131,7 @@ SINGLE_BATTLE_TEST("Fling - Item is lost even when there is no target")
SINGLE_BATTLE_TEST("Fling - Item is lost when target protects itself")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT);
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_RAZOR_CLAW); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -362,7 +362,7 @@ SINGLE_BATTLE_TEST("Fling - thrown berry's effect activates for the target even
PARAMETRIZE { item = ITEM_SALAC_BERRY; effect = HOLD_EFFECT_SPEED_UP; statId = STAT_SPEED; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLING].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_FLING) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Item(item); Attack(1); }
OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); HP(399); MaxHP(400); MovesWithPP({MOVE_CELEBRATE, 35}); }
} WHEN {
@@ -441,7 +441,7 @@ SINGLE_BATTLE_TEST("Fling deals damage based on items fling power")
s16 damage[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_CRUNCH].power == 80);
+ ASSUME(GetMovePower(MOVE_CRUNCH) == 80);
ASSUME(gItemsInfo[ITEM_VENUSAURITE].flingPower == 80);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_VENUSAURITE); }
OPPONENT(SPECIES_REGIROCK);
diff --git a/test/battle/move_effect/flower_shield.c b/test/battle/move_effect/flower_shield.c
new file mode 100644
index 0000000000..784cce99f2
--- /dev/null
+++ b/test/battle/move_effect/flower_shield.c
@@ -0,0 +1,37 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_FLOWER_SHIELD) == EFFECT_FLOWER_SHIELD);
+}
+
+DOUBLE_BATTLE_TEST("Flower Shield raises the defense of all grass type pokemon")
+{
+ GIVEN {
+ ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS);
+ ASSUME(gSpeciesInfo[SPECIES_TANGROWTH].types[0] == TYPE_GRASS);
+ ASSUME(gSpeciesInfo[SPECIES_SUNKERN].types[0] == TYPE_GRASS);
+ ASSUME(gSpeciesInfo[SPECIES_SUNFLORA].types[0] == TYPE_GRASS);
+ PLAYER(SPECIES_TANGELA);
+ PLAYER(SPECIES_TANGROWTH);
+ OPPONENT(SPECIES_SUNKERN);
+ OPPONENT(SPECIES_SUNFLORA);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_FLOWER_SHIELD); MOVE(playerRight, MOVE_CELEBRATE); }
+ } SCENE {
+ MESSAGE("Tangela used Flower Shield!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft);
+ MESSAGE("Tangela's Defense rose!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
+ MESSAGE("The opposing Sunkern's Defense rose!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
+ MESSAGE("Tangrowth's Defense rose!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
+ MESSAGE("The opposing Sunflora's Defense rose!");
+ }
+}
diff --git a/test/battle/move_effect/focus_punch.c b/test/battle/move_effect/focus_punch.c
index e8f36d4ff1..55854ee80e 100644
--- a/test/battle/move_effect/focus_punch.c
+++ b/test/battle/move_effect/focus_punch.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FOCUS_PUNCH].effect == EFFECT_FOCUS_PUNCH);
+ ASSUME(GetMoveEffect(MOVE_FOCUS_PUNCH) == EFFECT_FOCUS_PUNCH);
}
SINGLE_BATTLE_TEST("Focus Punch activates only if not damaged")
diff --git a/test/battle/move_effect/foul_play.c b/test/battle/move_effect/foul_play.c
index cc853b48de..7df04201ef 100644
--- a/test/battle/move_effect/foul_play.c
+++ b/test/battle/move_effect/foul_play.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FOUL_PLAY].effect == EFFECT_FOUL_PLAY);
+ ASSUME(GetMoveEffect(MOVE_FOUL_PLAY) == EFFECT_FOUL_PLAY);
}
SINGLE_BATTLE_TEST("Foul Play uses physical attack stat of target", s16 damage)
@@ -14,8 +14,8 @@ SINGLE_BATTLE_TEST("Foul Play uses physical attack stat of target", s16 damage)
PARAMETRIZE { move = MOVE_FOUL_PLAY; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_HIGH_HORSEPOWER].power == gMovesInfo[MOVE_FOUL_PLAY].power);
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMovePower(MOVE_HIGH_HORSEPOWER) == GetMovePower(MOVE_FOUL_PLAY));
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
PLAYER(SPECIES_SHELLDER);
OPPONENT(SPECIES_SHELLDER);
} WHEN {
diff --git a/test/battle/move_effect/fury_cutter.c b/test/battle/move_effect/fury_cutter.c
index b193882d37..10d9d8a64e 100644
--- a/test/battle/move_effect/fury_cutter.c
+++ b/test/battle/move_effect/fury_cutter.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FURY_CUTTER].effect == EFFECT_FURY_CUTTER);
+ ASSUME(GetMoveEffect(MOVE_FURY_CUTTER) == EFFECT_FURY_CUTTER);
}
SINGLE_BATTLE_TEST("Fury Cutter power doubles with each use, up to 160 power")
diff --git a/test/battle/move_effect/future_sight.c b/test/battle/move_effect/future_sight.c
index e25fc75012..3995e8479f 100644
--- a/test/battle/move_effect/future_sight.c
+++ b/test/battle/move_effect/future_sight.c
@@ -3,10 +3,10 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SEED_FLARE].power == gMovesInfo[MOVE_FUTURE_SIGHT].power);
- ASSUME(gMovesInfo[MOVE_SEED_FLARE].category == gMovesInfo[MOVE_FUTURE_SIGHT].category);
- ASSUME(gMovesInfo[MOVE_FUTURE_SIGHT].effect == EFFECT_FUTURE_SIGHT);
- ASSUME(gMovesInfo[MOVE_FUTURE_SIGHT].power > 0);
+ ASSUME(GetMovePower(MOVE_SEED_FLARE) == GetMovePower(MOVE_FUTURE_SIGHT));
+ ASSUME(GetMoveCategory(MOVE_SEED_FLARE) == GetMoveCategory(MOVE_FUTURE_SIGHT));
+ ASSUME(GetMoveEffect(MOVE_FUTURE_SIGHT) == EFFECT_FUTURE_SIGHT);
+ ASSUME(GetMovePower(MOVE_FUTURE_SIGHT) > 0);
}
SINGLE_BATTLE_TEST("Future Sight uses Sp. Atk stat of the original user without modifiers")
@@ -159,7 +159,7 @@ SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints by residual d
SINGLE_BATTLE_TEST("Future Sight breaks Focus Sash and doesn't make the holder endure another move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_PSYCHIC].power > 0);
+ ASSUME(GetMovePower(MOVE_PSYCHIC) > 0);
ASSUME(gItemsInfo[ITEM_FOCUS_SASH].holdEffect == HOLD_EFFECT_FOCUS_SASH);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PIDGEY) { Level(1); Item(ITEM_FOCUS_SASH); }
diff --git a/test/battle/move_effect/gastro_acid.c b/test/battle/move_effect/gastro_acid.c
index b3ce378794..8cb0a7d4af 100644
--- a/test/battle/move_effect/gastro_acid.c
+++ b/test/battle/move_effect/gastro_acid.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_GASTRO_ACID].effect == EFFECT_GASTRO_ACID);
+ ASSUME(GetMoveEffect(MOVE_GASTRO_ACID) == EFFECT_GASTRO_ACID);
}
SINGLE_BATTLE_TEST("Gastro Acid fails if target has a banned ability")
diff --git a/test/battle/move_effect/glaive_rush.c b/test/battle/move_effect/glaive_rush.c
index 639756da44..bb5bb7aaf6 100644
--- a/test/battle/move_effect/glaive_rush.c
+++ b/test/battle/move_effect/glaive_rush.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_GLAIVE_RUSH].effect == EFFECT_GLAIVE_RUSH);
+ ASSUME(GetMoveEffect(MOVE_GLAIVE_RUSH) == EFFECT_GLAIVE_RUSH);
}
SINGLE_BATTLE_TEST("If Glaive Rush is successful moves targeted at the user do not check accuracy")
{
PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEGA_PUNCH].accuracy == 85);
+ ASSUME(GetMoveAccuracy(MOVE_MEGA_PUNCH) == 85);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/terrain/grassy.c b/test/battle/move_effect/grassy_terrain.c
similarity index 80%
rename from test/battle/terrain/grassy.c
rename to test/battle/move_effect/grassy_terrain.c
index b247933dd2..90e878b6dd 100644
--- a/test/battle/terrain/grassy.c
+++ b/test/battle/move_effect/grassy_terrain.c
@@ -18,25 +18,6 @@ SINGLE_BATTLE_TEST("Grassy Terrain recovers 1/16th HP at end of turn")
}
}
-SINGLE_BATTLE_TEST("Grassy Terrain activates Grassy Seed and Mimicry")
-{
- GIVEN {
- ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffect == HOLD_EFFECT_SEEDS);
- ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_GRASSY_TERRAIN);
- PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSY_SEED); }
- OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); }
- } WHEN {
- TURN { MOVE(player, MOVE_GRASSY_TERRAIN); }
- } SCENE {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!");
- ABILITY_POPUP(opponent);
- MESSAGE("The opposing Stunfisk's type changed to Grass!");
- } THEN {
- EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GRASS);
- }
-}
-
SINGLE_BATTLE_TEST("Grassy Terrain increases power of Grass-type moves by 30/50 percent", s16 damage)
{
bool32 terrain;
diff --git a/test/battle/move_effect/gravity.c b/test/battle/move_effect/gravity.c
new file mode 100644
index 0000000000..baac7a53ea
--- /dev/null
+++ b/test/battle/move_effect/gravity.c
@@ -0,0 +1,47 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_GRAVITY) == EFFECT_GRAVITY);
+}
+
+DOUBLE_BATTLE_TEST("Gravity cancels fly and sky drop if they are in the air")
+{
+ u8 visibility;
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Speed(100); }
+ PLAYER(SPECIES_WYNAUT) { Speed(90); }
+ OPPONENT(SPECIES_PIDGEY) { Speed(50); }
+ OPPONENT(SPECIES_ROOKIDEE) { Speed(45); }
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_SKY_DROP, target: playerRight); MOVE(opponentRight, MOVE_FLY, target: playerLeft); }
+ TURN { MOVE(playerLeft, MOVE_GRAVITY); SKIP_TURN(opponentRight); SKIP_TURN(opponentLeft); }
+ } SCENE {
+ // turn 1
+ MESSAGE("The opposing Pidgey used Sky Drop!");
+ MESSAGE("The opposing Pidgey took Wynaut into the sky!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SKY_DROP, opponentLeft);
+ MESSAGE("The opposing Rookidee used Fly!");
+ MESSAGE("The opposing Rookidee flew up high!");
+ // turn 2
+ MESSAGE("Wobbuffet used Gravity!");
+ MESSAGE("Gravity intensified!");
+ MESSAGE("The opposing Pidgey fell from the sky due to the gravity!");
+ MESSAGE("The opposing Rookidee fell from the sky due to the gravity!");
+ MESSAGE("The opposing Pidgey can't use Sky Drop because of gravity!");
+ MESSAGE("The opposing Rookidee can't use Fly because of gravity!");
+ } THEN {
+ // all battlers should be visible. assign to var first because expect_eq not working with bitfield address
+ visibility = gBattleSpritesDataPtr->battlerData[0].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[1].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[2].invisible;
+ EXPECT_EQ(visibility, 0);
+ visibility = gBattleSpritesDataPtr->battlerData[3].invisible;
+ EXPECT_EQ(visibility, 0);
+ // ensure moveend properly recorded
+ EXPECT_EQ(gLastMoves[0], MOVE_GRAVITY);
+ }
+}
diff --git a/test/battle/move_effect/guard_split.c b/test/battle/move_effect/guard_split.c
index 3f012ab6e2..d7572c1431 100644
--- a/test/battle/move_effect/guard_split.c
+++ b/test/battle/move_effect/guard_split.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_GUARD_SPLIT].effect == EFFECT_GUARD_SPLIT);
+ ASSUME(GetMoveEffect(MOVE_GUARD_SPLIT) == EFFECT_GUARD_SPLIT);
}
SINGLE_BATTLE_TEST("Guard Split averages users and targets Def and Sp. Def stats")
diff --git a/test/battle/move_effect/haze.c b/test/battle/move_effect/haze.c
index 0b28268ae9..3d0602bb73 100644
--- a/test/battle/move_effect/haze.c
+++ b/test/battle/move_effect/haze.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HAZE].effect == EFFECT_HAZE);
+ ASSUME(GetMoveEffect(MOVE_HAZE) == EFFECT_HAZE);
}
SINGLE_BATTLE_TEST("Haze resets stat changes", s16 damage)
@@ -12,8 +12,8 @@ SINGLE_BATTLE_TEST("Haze resets stat changes", s16 damage)
PARAMETRIZE { haze = FALSE; }
PARAMETRIZE { haze = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEDITATE].effect == EFFECT_ATTACK_UP);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveEffect(MOVE_MEDITATE) == EFFECT_ATTACK_UP);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/heal_bell.c b/test/battle/move_effect/heal_bell.c
index 9b62a36f9b..5c87171056 100644
--- a/test/battle/move_effect/heal_bell.c
+++ b/test/battle/move_effect/heal_bell.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HEAL_BELL].effect == EFFECT_HEAL_BELL);
- ASSUME(gMovesInfo[MOVE_AROMATHERAPY].effect == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL);
}
DOUBLE_BATTLE_TEST("Heal Bell cures the entire party")
diff --git a/test/battle/move_effect/heal_pulse.c b/test/battle/move_effect/heal_pulse.c
index e252039982..7c46cbf344 100644
--- a/test/battle/move_effect/heal_pulse.c
+++ b/test/battle/move_effect/heal_pulse.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HEAL_PULSE].effect == EFFECT_HEAL_PULSE);
+ ASSUME(GetMoveEffect(MOVE_HEAL_PULSE) == EFFECT_HEAL_PULSE);
}
SINGLE_BATTLE_TEST("Heal Pulse heals the target by 1/2 of it's maxHP")
@@ -68,7 +68,7 @@ SINGLE_BATTLE_TEST("Heal Pulse ignores accurace checks")
SINGLE_BATTLE_TEST("Heal Pulse is blocked by Substitute")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
+ ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(50); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -86,8 +86,8 @@ SINGLE_BATTLE_TEST("Heal Pulse is blocked by Substitute")
SINGLE_BATTLE_TEST("Floral Healing heals the target by 2/3rd of it's maxHP if Grassy Terrain is on the field")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLORAL_HEALING].argument == MOVE_EFFECT_FLORAL_HEALING);
- ASSUME(gMovesInfo[MOVE_GRASSY_TERRAIN].effect == EFFECT_GRASSY_TERRAIN);
+ ASSUME(GetMoveEffectArg_MoveProperty(MOVE_FLORAL_HEALING) == MOVE_EFFECT_FLORAL_HEALING);
+ ASSUME(GetMoveEffect(MOVE_GRASSY_TERRAIN) == EFFECT_GRASSY_TERRAIN);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/healing_wish.c b/test/battle/move_effect/healing_wish.c
index a597d552ed..a29b04367c 100644
--- a/test/battle/move_effect/healing_wish.c
+++ b/test/battle/move_effect/healing_wish.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH);
- ASSUME(gMovesInfo[MOVE_LUNAR_DANCE].effect == EFFECT_HEALING_WISH);
+ ASSUME(GetMoveEffect(MOVE_HEALING_WISH) == EFFECT_HEALING_WISH);
+ ASSUME(GetMoveEffect(MOVE_LUNAR_DANCE) == EFFECT_HEALING_WISH);
}
SINGLE_BATTLE_TEST("Healing Wish causes the user to faint and fully heals the replacement")
diff --git a/test/battle/move_effect/hit_escape.c b/test/battle/move_effect/hit_escape.c
index 0a494cc667..bdfdbcae98 100644
--- a/test/battle/move_effect/hit_escape.c
+++ b/test/battle/move_effect/hit_escape.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
}
SINGLE_BATTLE_TEST("U-turn switches the user out")
@@ -98,7 +98,7 @@ SINGLE_BATTLE_TEST("U-turn switches the user out if Wimp Out fails to activate")
SINGLE_BATTLE_TEST("U-turn switches the user out after Ice Face activates")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_U_TURN].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_U_TURN) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_BEEDRILL);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_EISCUE) { Ability(ABILITY_ICE_FACE); }
diff --git a/test/battle/move_effect/hit_set_remove_terrain.c b/test/battle/move_effect/hit_set_remove_terrain.c
index 98c6e179eb..9b9180d6e4 100644
--- a/test/battle/move_effect/hit_set_remove_terrain.c
+++ b/test/battle/move_effect/hit_set_remove_terrain.c
@@ -3,12 +3,12 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ELECTRIC_TERRAIN].effect == EFFECT_ELECTRIC_TERRAIN);
- ASSUME(gMovesInfo[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN);
- ASSUME(gMovesInfo[MOVE_GRASSY_TERRAIN].effect == EFFECT_GRASSY_TERRAIN);
- ASSUME(gMovesInfo[MOVE_MISTY_TERRAIN].effect == EFFECT_MISTY_TERRAIN);
- ASSUME(gMovesInfo[MOVE_STEEL_ROLLER].effect == EFFECT_HIT_SET_REMOVE_TERRAIN);
- ASSUME(gMovesInfo[MOVE_ICE_SPINNER].effect == EFFECT_HIT_SET_REMOVE_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_ELECTRIC_TERRAIN) == EFFECT_ELECTRIC_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_PSYCHIC_TERRAIN) == EFFECT_PSYCHIC_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_GRASSY_TERRAIN) == EFFECT_GRASSY_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_MISTY_TERRAIN) == EFFECT_MISTY_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_STEEL_ROLLER) == EFFECT_HIT_SET_REMOVE_TERRAIN);
+ ASSUME(GetMoveEffect(MOVE_ICE_SPINNER) == EFFECT_HIT_SET_REMOVE_TERRAIN);
}
SINGLE_BATTLE_TEST("Steel Roller and Ice Spinner can remove a terrain from the field")
@@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Ice Spinner doesn't fail if there is no terrain on the field
}
}
-AI_SINGLE_BATTLE_TEST("Steel Roller will not be chosen by the AI if it might fail")
+AI_SINGLE_BATTLE_TEST("AI will not choose Steel Roller if it might fail")
{
u32 move;
@@ -104,7 +104,7 @@ AI_SINGLE_BATTLE_TEST("Steel Roller will not be chosen by the AI if it might fai
}
}
-AI_SINGLE_BATTLE_TEST("Ice Spinner can be chosen by the AI regardless if there is a terrain or not")
+AI_SINGLE_BATTLE_TEST("AI will can choose Ice Spinner regardless if there is a terrain or not")
{
u32 move;
diff --git a/test/battle/move_effect/hit_switch_target.c b/test/battle/move_effect/hit_switch_target.c
index a899ae0b33..5a6e480f93 100644
--- a/test/battle/move_effect/hit_switch_target.c
+++ b/test/battle/move_effect/hit_switch_target.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_DRAGON_TAIL].effect == EFFECT_HIT_SWITCH_TARGET);
- ASSUME(gMovesInfo[MOVE_LOCK_ON].effect == EFFECT_LOCK_ON);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
+ ASSUME(GetMoveEffect(MOVE_LOCK_ON) == EFFECT_LOCK_ON);
}
SINGLE_BATTLE_TEST("Dragon Tail switches the target with a random non-fainted replacement")
diff --git a/test/battle/move_effect/hold_hands.c b/test/battle/move_effect/hold_hands.c
new file mode 100644
index 0000000000..fb1c498bd3
--- /dev/null
+++ b/test/battle/move_effect/hold_hands.c
@@ -0,0 +1,25 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_HOLD_HANDS) == EFFECT_HOLD_HANDS);
+}
+
+DOUBLE_BATTLE_TEST("Hold Hands is blocked by Crafty Shield")
+{
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN {
+ MOVE(playerLeft, MOVE_CRAFTY_SHIELD, target: opponentLeft);
+ MOVE(playerRight, MOVE_HOLD_HANDS, target: playerLeft);
+ }
+ } SCENE {
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_HOLD_HANDS, playerLeft);
+ MESSAGE("Wynaut protected itself!");
+ }
+}
diff --git a/test/battle/move_effect/hydro_steam.c b/test/battle/move_effect/hydro_steam.c
index a9c14c9acb..cb19cc6ec1 100644
--- a/test/battle/move_effect/hydro_steam.c
+++ b/test/battle/move_effect/hydro_steam.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HYDRO_STEAM].effect == EFFECT_HYDRO_STEAM);
+ ASSUME(GetMoveEffect(MOVE_HYDRO_STEAM) == EFFECT_HYDRO_STEAM);
}
SINGLE_BATTLE_TEST("Hydro Steam deals 1.5x damage under both Sunlight and Rain", s16 damage)
diff --git a/test/battle/move_effect/instruct.c b/test/battle/move_effect/instruct.c
index 59772ea944..248370cd6a 100644
--- a/test/battle/move_effect/instruct.c
+++ b/test/battle/move_effect/instruct.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT);
+ ASSUME(GetMoveEffect(MOVE_INSTRUCT) == EFFECT_INSTRUCT);
}
DOUBLE_BATTLE_TEST("Instruct fails if target hasn't made a move")
@@ -24,7 +24,7 @@ DOUBLE_BATTLE_TEST("Instruct fails if target hasn't made a move")
DOUBLE_BATTLE_TEST("Instruct fails if move is banned by Instruct")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BIDE].instructBanned == TRUE);
+ ASSUME(IsMoveInstructBanned(MOVE_BIDE));
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_BIDE); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -60,7 +60,7 @@ DOUBLE_BATTLE_TEST("Instruct-called move targets the target of the move picked o
DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -79,7 +79,7 @@ DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep")
DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
+ ASSUME(IsDanceMove(MOVE_DRAGON_DANCE));
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ORICORIO) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_CELEBRATE); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -100,7 +100,7 @@ DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used"
DOUBLE_BATTLE_TEST("Instruct-called move fails if it can only be used on the first turn but consumes PP")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FAKE_OUT].effect == EFFECT_FIRST_TURN_ONLY);
+ ASSUME(GetMoveEffect(MOVE_FAKE_OUT) == EFFECT_FIRST_TURN_ONLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -112,14 +112,14 @@ DOUBLE_BATTLE_TEST("Instruct-called move fails if it can only be used on the fir
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, playerRight);
} THEN {
- EXPECT_EQ(playerRight->pp[3], gMovesInfo[MOVE_FAKE_OUT].pp - 2);
+ EXPECT_EQ(playerRight->pp[3], GetMovePP(MOVE_FAKE_OUT) - 2);
}
}
DOUBLE_BATTLE_TEST("Instruct-called move doesn't fail if tormented")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT);
+ ASSUME(GetMoveEffect(MOVE_TORMENT) == EFFECT_TORMENT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -138,7 +138,7 @@ DOUBLE_BATTLE_TEST("Instruct-called status moves don't fail if holding Assault V
{
GIVEN {
ASSUME(gItemsInfo[ITEM_ASSAULT_VEST].holdEffect == HOLD_EFFECT_ASSAULT_VEST);
- ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
+ ASSUME(GetMoveEffect(MOVE_TRICK) == EFFECT_TRICK);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_TRICK); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ASSAULT_VEST); }
@@ -155,7 +155,7 @@ DOUBLE_BATTLE_TEST("Instruct-called status moves don't fail if holding Assault V
DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT);
+ ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -174,14 +174,14 @@ DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted")
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
}
} THEN {
- EXPECT_EQ(playerRight->pp[3], gMovesInfo[MOVE_GROWL].pp - 1);
+ EXPECT_EQ(playerRight->pp[3], GetMovePP(MOVE_GROWL) - 1);
}
}
DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DISABLE].effect == EFFECT_DISABLE);
+ ASSUME(GetMoveEffect(MOVE_DISABLE) == EFFECT_DISABLE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -194,15 +194,15 @@ DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled")
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
} THEN {
- EXPECT_EQ(playerRight->pp[0], gMovesInfo[MOVE_TACKLE].pp - 1);
+ EXPECT_EQ(playerRight->pp[0], GetMovePP(MOVE_TACKLE) - 1);
}
}
DOUBLE_BATTLE_TEST("Instruct-called moves keep their priority")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
- ASSUME(gMovesInfo[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
+ ASSUME(GetMoveEffect(MOVE_PSYCHIC_TERRAIN) == EFFECT_PSYCHIC_TERRAIN);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_QUICK_ATTACK); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/ion_deluge.c b/test/battle/move_effect/ion_deluge.c
index d0862ee8b4..8147048527 100644
--- a/test/battle/move_effect/ion_deluge.c
+++ b/test/battle/move_effect/ion_deluge.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ION_DELUGE].effect == EFFECT_ION_DELUGE);
+ ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE);
}
// For some reason SINGLE_BATTLE_TEST didn't catch these two issues.
@@ -51,7 +51,7 @@ WILD_BATTLE_TEST("Ion Deluge works the same way as always when used by a mon wit
SINGLE_BATTLE_TEST("Ion Deluge makes Normal type moves Electric type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TACKLE) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GOLBAT);
} WHEN {
diff --git a/test/battle/move_effect/ivy_cudgel.c b/test/battle/move_effect/ivy_cudgel.c
index 095f4d8eff..88d002ae35 100644
--- a/test/battle/move_effect/ivy_cudgel.c
+++ b/test/battle/move_effect/ivy_cudgel.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_IVY_CUDGEL].effect == EFFECT_IVY_CUDGEL);
+ ASSUME(GetMoveEffect(MOVE_IVY_CUDGEL) == EFFECT_IVY_CUDGEL);
}
SINGLE_BATTLE_TEST("Ivy Cudgel changes the move type depending on the form of Ogerpon")
diff --git a/test/battle/move_effect/knock_off.c b/test/battle/move_effect/knock_off.c
index aa1081ff67..4eb1269717 100644
--- a/test/battle/move_effect/knock_off.c
+++ b/test/battle/move_effect/knock_off.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
+ ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF);
}
SINGLE_BATTLE_TEST("Knock Off knocks a healing berry before it has the chance to activate")
@@ -202,6 +202,126 @@ SINGLE_BATTLE_TEST("Knock Off doesn't knock off items from Pokemon behind substi
} WHEN {
TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_KNOCK_OFF); }
} SCENE {
- NOT MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Poké Ball");
+ NOT MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Poké Ball!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off does knock off Mega Stones from Pokemon that don't actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ABSOLITE); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Absolite!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off doesn't knock off Mega Stones from Pokemon that actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ABSOL) { Item(ITEM_ABSOLITE); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ NOT MESSAGE("Wobbuffet knocked off the opposing Absol's Absolite!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off does knock off Orbs for Primal Reversion from Pokemon that don't actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_ORB); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Red Orb!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off doesn't knock off Orbs for Primal Reversion from Pokemon that actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ NOT MESSAGE("Wobbuffet knocked off the opposing Groudon's Red Orb!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off doesn't knock off Z-Crystals")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIUM_Z); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ NOT MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Electrium Z!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off doesn't knock off Ultranecrozium Z from Pokemon that actually use it")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_NECROZMA_DUSK_MANE) { Item(ITEM_ULTRANECROZIUM_Z); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ NOT MESSAGE("Wobbuffet knocked off the opposing Necrozma's Ultranecrozium Z!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off does knock off other form-change hold items from Pokemon that don't actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SKY_PLATE); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Sky Plate!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off doesn't knock off other form-change hold items from Pokemon that actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ARCEUS) { Item(ITEM_SKY_PLATE); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ NOT MESSAGE("Wobbuffet knocked off the opposing Arceus's Sky Plate!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off does knock off begin-battle form-change hold items from Pokemon that don't actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RUSTED_SHIELD); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ MESSAGE("Wobbuffet knocked off the opposing Wobbuffet's Rusted Shield!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Knock Off doesn't knock off begin-battle form-change hold items from Pokemon that actually use them")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_ZAMAZENTA_HERO) { Item(ITEM_RUSTED_SHIELD); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_KNOCK_OFF); }
+ } SCENE {
+ NOT MESSAGE("Wobbuffet knocked off the opposing Zamazenta's Rusted Shield!");
}
}
diff --git a/test/battle/move_effect/last_resort.c b/test/battle/move_effect/last_resort.c
index a9660f2c0e..50a0a31512 100644
--- a/test/battle/move_effect/last_resort.c
+++ b/test/battle/move_effect/last_resort.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_LAST_RESORT].effect == EFFECT_LAST_RESORT);
+ ASSUME(GetMoveEffect(MOVE_LAST_RESORT) == EFFECT_LAST_RESORT);
}
SINGLE_BATTLE_TEST("Last Resort always fails if it's the only known move")
@@ -95,7 +95,7 @@ SINGLE_BATTLE_TEST("Last Resort works only when all of the known moves have been
SINGLE_BATTLE_TEST("Last Resort works with Sleep Talk")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_LAST_RESORT, MOVE_SLEEP_TALK); Status1(STATUS1_SLEEP_TURN(3)); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/last_respects.c b/test/battle/move_effect/last_respects.c
index 9b1f01f5fc..6ef4c73c2d 100644
--- a/test/battle/move_effect/last_respects.c
+++ b/test/battle/move_effect/last_respects.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_LAST_RESPECTS].effect == EFFECT_LAST_RESPECTS);
+ ASSUME(GetMoveEffect(MOVE_LAST_RESPECTS) == EFFECT_LAST_RESPECTS);
}
SINGLE_BATTLE_TEST("Last Respects power is multiplied by the amount of fainted mon in the user's side - Player", s16 damage)
diff --git a/test/battle/move_effect/leech_seed.c b/test/battle/move_effect/leech_seed.c
index fce80c661c..d363e98009 100644
--- a/test/battle/move_effect/leech_seed.c
+++ b/test/battle/move_effect/leech_seed.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED);
+ ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED);
}
SINGLE_BATTLE_TEST("Leech Seed doesn't affect Grass-type Pokémon")
@@ -20,8 +20,45 @@ SINGLE_BATTLE_TEST("Leech Seed doesn't affect Grass-type Pokémon")
MESSAGE("It doesn't affect the opposing Oddish…");
}
}
+
+SINGLE_BATTLE_TEST("Leech Seeded targets lose 1/8 of its max HP every turn and give it to the user")
+{
+ s16 damage;
+ s16 healed;
+
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT) { HP(1); }
+ OPPONENT(SPECIES_SHELLDER);
+ } WHEN {
+ TURN { MOVE(player, MOVE_LEECH_SEED); }
+ TURN {}
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player);
+ HP_BAR(opponent);
+ HP_BAR(player);
+ HP_BAR(opponent, captureDamage: &damage);
+ HP_BAR(player, captureDamage: &healed);
+ } THEN {
+ EXPECT_MUL_EQ(damage, Q_4_12(-1), healed);
+ }
+}
+
+SINGLE_BATTLE_TEST("Leech Seed recovery is prevented by Heal Block")
+{
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT) { HP(1); }
+ OPPONENT(SPECIES_SHELLDER);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_HEAL_BLOCK); MOVE(player, MOVE_LEECH_SEED); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BLOCK, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, player);
+ HP_BAR(opponent);
+ NOT HP_BAR(player);
+ }
+}
+
TO_DO_BATTLE_TEST("Leech Seed doesn't affect already seeded targets")
-TO_DO_BATTLE_TEST("Leech Seeded targets lose 1/8 of its max HP every turn and give it to the user")
TO_DO_BATTLE_TEST("Leech Seed's effect is paused until a new battler replaces the original user's position") // Faint, can't be replaced, then revived.
TO_DO_BATTLE_TEST("Leech Seed's effect pause still prevents it from being seeded again")
TO_DO_BATTLE_TEST("Baton Pass passes Leech Seed's effect");
diff --git a/test/battle/move_effect/magic_coat.c b/test/battle/move_effect/magic_coat.c
index 2e78967f39..561d15a532 100644
--- a/test/battle/move_effect/magic_coat.c
+++ b/test/battle/move_effect/magic_coat.c
@@ -3,13 +3,13 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_MAGIC_COAT].effect == EFFECT_MAGIC_COAT);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT);
}
SINGLE_BATTLE_TEST("Magic Coat prints the correct message when bouncing back a move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
PLAYER(SPECIES_ZIGZAGOON);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
diff --git a/test/battle/move_effect/max_hp_50_recoil.c b/test/battle/move_effect/max_hp_50_recoil.c
index b35043014b..3e54e05532 100644
--- a/test/battle/move_effect/max_hp_50_recoil.c
+++ b/test/battle/move_effect/max_hp_50_recoil.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STEEL_BEAM].effect == EFFECT_MAX_HP_50_RECOIL);
+ ASSUME(GetMoveEffect(MOVE_STEEL_BEAM) == EFFECT_MAX_HP_50_RECOIL);
}
SINGLE_BATTLE_TEST("Steel Beam makes the user lose 1/2 of its Max HP")
diff --git a/test/battle/move_effect/metronome.c b/test/battle/move_effect/metronome.c
index 98e4bfd618..1a5d4aeb9d 100644
--- a/test/battle/move_effect/metronome.c
+++ b/test/battle/move_effect/metronome.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_METRONOME].effect == EFFECT_METRONOME);
+ ASSUME(GetMoveEffect(MOVE_METRONOME) == EFFECT_METRONOME);
}
SINGLE_BATTLE_TEST("Metronome picks a random move")
@@ -25,9 +25,9 @@ SINGLE_BATTLE_TEST("Metronome picks a random move")
SINGLE_BATTLE_TEST("Metronome's called powder move fails against Grass Types")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].powderMove);
+ ASSUME(IsPowderMove(MOVE_POISON_POWDER));
ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TANGELA);
} WHEN {
@@ -45,7 +45,7 @@ SINGLE_BATTLE_TEST("Metronome's called powder move fails against Grass Types")
SINGLE_BATTLE_TEST("Metronome's called multi-hit move hits multiple times")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ROCK_BLAST].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_ROCK_BLAST) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/mind_blown.c b/test/battle/move_effect/mind_blown.c
index dbb3a6164a..0a34198777 100644
--- a/test/battle/move_effect/mind_blown.c
+++ b/test/battle/move_effect/mind_blown.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_MIND_BLOWN].effect == EFFECT_MIND_BLOWN);
+ ASSUME(GetMoveEffect(MOVE_MIND_BLOWN) == EFFECT_MIND_BLOWN);
}
SINGLE_BATTLE_TEST("Mind Blown makes the user lose 1/2 of its Max HP")
@@ -96,10 +96,10 @@ DOUBLE_BATTLE_TEST("Mind Blown causes everyone to faint in a double battle")
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIND_BLOWN, playerLeft);
HP_BAR(opponentLeft, hp: 0);
- MESSAGE("The opposing Abra fainted!");
HP_BAR(playerRight, hp: 0);
- MESSAGE("Wynaut fainted!");
HP_BAR(opponentRight, hp: 0);
+ MESSAGE("The opposing Abra fainted!");
+ MESSAGE("Wynaut fainted!");
MESSAGE("The opposing Kadabra fainted!");
HP_BAR(playerLeft, hp: 0);
MESSAGE("Wobbuffet fainted!");
@@ -154,7 +154,7 @@ SINGLE_BATTLE_TEST("Mind Blown makes the user lose HP even if the opposing mon p
SINGLE_BATTLE_TEST("Mind Blown makes the user lose HP even if it is absorbed by Flash Fire")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MIND_BLOWN].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_MIND_BLOWN) == TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_CYNDAQUIL) { Ability(ABILITY_FLASH_FIRE); }
} WHEN {
diff --git a/test/battle/move_effect/mirror_move.c b/test/battle/move_effect/mirror_move.c
index 65c600fb18..cc148eb97c 100644
--- a/test/battle/move_effect/mirror_move.c
+++ b/test/battle/move_effect/mirror_move.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_MIRROR_MOVE].effect == EFFECT_MIRROR_MOVE);
+ ASSUME(GetMoveEffect(MOVE_MIRROR_MOVE) == EFFECT_MIRROR_MOVE);
}
SINGLE_BATTLE_TEST("Mirror Move copies the last used move by the target")
@@ -41,9 +41,9 @@ SINGLE_BATTLE_TEST("Mirror Move fails if no move was used before")
SINGLE_BATTLE_TEST("Mirror Move's called powder move fails against Grass Types")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS);
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE);
+ ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_PARALYZE);
PLAYER(SPECIES_ODDISH);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -62,7 +62,7 @@ SINGLE_BATTLE_TEST("Mirror Move's called powder move fails against Grass Types")
SINGLE_BATTLE_TEST("Mirror Move's called multi-hit move hits multiple times")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/terrain/misty.c b/test/battle/move_effect/misty_terrain.c
similarity index 78%
rename from test/battle/terrain/misty.c
rename to test/battle/move_effect/misty_terrain.c
index e43cf4a253..b96f0c650d 100644
--- a/test/battle/terrain/misty.c
+++ b/test/battle/move_effect/misty_terrain.c
@@ -19,25 +19,6 @@ SINGLE_BATTLE_TEST("Misty Terrain protects grounded battlers from non-volatile s
}
}
-SINGLE_BATTLE_TEST("Misty Terrain activates Misty Seed and Mimicry")
-{
- GIVEN {
- ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffect == HOLD_EFFECT_SEEDS);
- ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_MISTY_TERRAIN);
- PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MISTY_SEED); }
- OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); }
- } WHEN {
- TURN { MOVE(player, MOVE_MISTY_TERRAIN); }
- } SCENE {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!");
- ABILITY_POPUP(opponent);
- MESSAGE("The opposing Stunfisk's type changed to Fairy!");
- } THEN {
- EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_FAIRY);
- }
-}
-
SINGLE_BATTLE_TEST("Misty Terrain does not increase the power of Fairy-type moves", s16 damage)
{
bool32 terrain;
diff --git a/test/battle/move_effect/moonlight.c b/test/battle/move_effect/moonlight.c
index 41359ea97c..34baa31b14 100644
--- a/test/battle/move_effect/moonlight.c
+++ b/test/battle/move_effect/moonlight.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_MOONLIGHT].effect == EFFECT_MOONLIGHT);
+ ASSUME(GetMoveEffect(MOVE_MOONLIGHT) == EFFECT_MOONLIGHT);
}
SINGLE_BATTLE_TEST("Moonlight recovers 1/2 of the user's max HP")
diff --git a/test/battle/move_effect/morning_sun.c b/test/battle/move_effect/morning_sun.c
index 3b57f89500..64fb1b044b 100644
--- a/test/battle/move_effect/morning_sun.c
+++ b/test/battle/move_effect/morning_sun.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_MORNING_SUN].effect == EFFECT_MORNING_SUN);
+ ASSUME(GetMoveEffect(MOVE_MORNING_SUN) == EFFECT_MORNING_SUN);
}
SINGLE_BATTLE_TEST("Morning Sun recovers 1/2 of the user's max HP")
diff --git a/test/battle/move_effect/multi_hit.c b/test/battle/move_effect/multi_hit.c
index e2331efbf7..da96c07c90 100644
--- a/test/battle/move_effect/multi_hit.c
+++ b/test/battle/move_effect/multi_hit.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT);
}
SINGLE_BATTLE_TEST("Multi hit Moves hit the maximum amount with Skill Link")
@@ -141,7 +141,7 @@ SINGLE_BATTLE_TEST("Multi hit Moves hit five times 50 Percent of the time with L
SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after final hit")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -163,8 +163,8 @@ SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after final
SINGLE_BATTLE_TEST("Scale Shot is immune to Fairy types and will end the move correctly")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT);
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].type == TYPE_DRAGON);
+ ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveType(MOVE_SCALE_SHOT) == TYPE_DRAGON);
ASSUME(gSpeciesInfo[SPECIES_CLEFAIRY].types[0] == TYPE_FAIRY || gSpeciesInfo[SPECIES_CLEFAIRY].types[1] == TYPE_FAIRY);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_CLEFAIRY) { HP(1); }
@@ -179,7 +179,7 @@ SINGLE_BATTLE_TEST("Scale Shot is immune to Fairy types and will end the move co
DOUBLE_BATTLE_TEST("Scale Shot does not corrupt the next turn move used")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
@@ -200,35 +200,11 @@ DOUBLE_BATTLE_TEST("Scale Shot does not corrupt the next turn move used")
}
}
-SINGLE_BATTLE_TEST("Endure does not prevent multiple hits and stat changes occur at the end of the turn")
-{
- GIVEN {
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT);
- ASSUME(gMovesInfo[MOVE_ENDURE].effect == EFFECT_ENDURE);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
- } WHEN {
- TURN { MOVE(opponent, MOVE_ENDURE); MOVE(player, MOVE_SCALE_SHOT); }
- } SCENE {
- ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDURE, opponent);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
- ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player);
- MESSAGE("The Pokémon was hit 5 time(s)!");
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Wobbuffet's Defense fell!");
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Wobbuffet's Speed rose!");
- }
-}
-
SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after the 4th hit of Loaded Dice")
{
PASSES_RANDOMLY(50, 100, RNG_LOADED_DICE);
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LOADED_DICE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -253,7 +229,7 @@ SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after killi
PARAMETRIZE { item = ITEM_LOADED_DICE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_SCALE_SHOT) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_BAGON) { Item(item); }
OPPONENT(SPECIES_SLUGMA) { Ability(ABILITY_WEAK_ARMOR); }
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/octolock.c b/test/battle/move_effect/octolock.c
index 1a04de7331..e93f6f29cb 100644
--- a/test/battle/move_effect/octolock.c
+++ b/test/battle/move_effect/octolock.c
@@ -131,3 +131,24 @@ SINGLE_BATTLE_TEST("Octolock will not decrease Defense and Sp. Def further then
}
}
}
+
+SINGLE_BATTLE_TEST("Octolock triggers Defiant for both stat reductions")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BISHARP) { Ability(ABILITY_DEFIANT); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_OCTOLOCK); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_OCTOLOCK, player);
+ MESSAGE("The opposing Bisharp can no longer escape because of Octolock!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ MESSAGE("The opposing Bisharp's Defense fell!");
+ ABILITY_POPUP(opponent, ABILITY_DEFIANT);
+ MESSAGE("The opposing Bisharp's Attack sharply rose!");
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
+ MESSAGE("The opposing Bisharp's Sp. Def fell!");
+ ABILITY_POPUP(opponent, ABILITY_DEFIANT);
+ MESSAGE("The opposing Bisharp's Attack sharply rose!");
+ }
+}
diff --git a/test/battle/move_effect/ohko.c b/test/battle/move_effect/ohko.c
index 511d76a8ad..11dbb78f1f 100644
--- a/test/battle/move_effect/ohko.c
+++ b/test/battle/move_effect/ohko.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SHEER_COLD].effect == EFFECT_OHKO);
+ ASSUME(GetMoveEffect(MOVE_SHEER_COLD) == EFFECT_OHKO);
}
SINGLE_BATTLE_TEST("Sheer Cold doesn't affect Ice-type Pokémon")
@@ -20,6 +20,22 @@ SINGLE_BATTLE_TEST("Sheer Cold doesn't affect Ice-type Pokémon")
MESSAGE("It doesn't affect the opposing Glalie…");
}
}
+
+SINGLE_BATTLE_TEST("OHKO moves can hit semi-invulnerable mons when the user has No-Guard")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SHEER_COLD) == EFFECT_OHKO);
+ PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_NO_GUARD); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_FLY); }
+ TURN { MOVE(player, MOVE_SHEER_COLD); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SHEER_COLD, player);
+ HP_BAR(opponent, hp: 0);
+ }
+}
+
TO_DO_BATTLE_TEST("Fissure faints the target, skipping regular damage calculations")
TO_DO_BATTLE_TEST("Fissure always fails if the target has a higher level than the user")
TO_DO_BATTLE_TEST("Fissure's accuracy increases by 1% for every level the user has over the target")
diff --git a/test/battle/move_effect/photon_geyser.c b/test/battle/move_effect/photon_geyser.c
index 986d3865aa..3f4bb10146 100644
--- a/test/battle/move_effect/photon_geyser.c
+++ b/test/battle/move_effect/photon_geyser.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_PHOTON_GEYSER].effect == EFFECT_PHOTON_GEYSER);
+ ASSUME(GetMoveEffect(MOVE_PHOTON_GEYSER) == EFFECT_PHOTON_GEYSER);
}
SINGLE_BATTLE_TEST("Photon Geyser can be mirror coated if it is a special move")
{
GIVEN {
// EFFECT_PHOTON_GEYSER requires the move data to be Special to work
- ASSUME(gMovesInfo[MOVE_PHOTON_GEYSER].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_PHOTON_GEYSER) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET) { Attack(100); SpAttack(110); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/pledge.c b/test/battle/move_effect/pledge.c
index 726adc8152..5a659d7b96 100644
--- a/test/battle/move_effect/pledge.c
+++ b/test/battle/move_effect/pledge.c
@@ -3,9 +3,9 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WATER_PLEDGE].effect == EFFECT_PLEDGE);
- ASSUME(gMovesInfo[MOVE_FIRE_PLEDGE].effect == EFFECT_PLEDGE);
- ASSUME(gMovesInfo[MOVE_GRASS_PLEDGE].effect == EFFECT_PLEDGE);
+ ASSUME(GetMoveEffect(MOVE_WATER_PLEDGE) == EFFECT_PLEDGE);
+ ASSUME(GetMoveEffect(MOVE_FIRE_PLEDGE) == EFFECT_PLEDGE);
+ ASSUME(GetMoveEffect(MOVE_GRASS_PLEDGE) == EFFECT_PLEDGE);
}
DOUBLE_BATTLE_TEST("Water and Fire Pledge create a rainbow on the user's side of the field for four turns")
@@ -189,7 +189,7 @@ DOUBLE_BATTLE_TEST("The base power of a combined pledge move effect is 150")
s16 combinedPledgeDamage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_HYPER_BEAM].power == 150);
+ ASSUME(GetMovePower(MOVE_HYPER_BEAM) == 150);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
PLAYER(SPECIES_WYNAUT) { Speed(3); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
@@ -313,7 +313,7 @@ DOUBLE_BATTLE_TEST("Damage calculation: Combined pledge move")
PARAMETRIZE { expectedDamage = 136; }
PARAMETRIZE { expectedDamage = 135; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GRASS_PLEDGE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_GRASS_PLEDGE) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
PLAYER(SPECIES_WOBBUFFET) { HP(521); SpDefense(152); Speed(3); }
OPPONENT(SPECIES_CHARIZARD) { Speed(8); }
@@ -344,7 +344,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo interactions with Powder are correct")
PARAMETRIZE { moveLeft = MOVE_GRASS_PLEDGE; moveRight = MOVE_FIRE_PLEDGE; speedLeft = 4; speedRight = 3; }
PARAMETRIZE { moveLeft = MOVE_GRASS_PLEDGE; moveRight = MOVE_FIRE_PLEDGE; speedLeft = 3; speedRight = 4; } // FAIL 2
GIVEN {
- ASSUME(gMovesInfo[MOVE_FIRE_PLEDGE].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_FIRE_PLEDGE) == TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET) { Speed(speedLeft); }
PLAYER(SPECIES_WYNAUT) { Speed(speedRight); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
@@ -885,7 +885,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move
DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Electrify")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
PLAYER(SPECIES_MAROWAK) { Ability(ABILITY_LIGHTNING_ROD); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1002,7 +1002,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move
DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Motor Drive")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
PLAYER(SPECIES_ELECTIVIRE) { Ability(ABILITY_MOTOR_DRIVE); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -1027,7 +1027,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move
DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Volt Absorb")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ELECTRIFY].effect == EFFECT_ELECTRIFY);
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/population_bomb.c b/test/battle/move_effect/population_bomb.c
index b3e2e4768e..54da0726ae 100644
--- a/test/battle/move_effect/population_bomb.c
+++ b/test/battle/move_effect/population_bomb.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Population Bomb can hit ten times")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_POPULATION_BOMB].strikeCount == 10);
+ ASSUME(GetMoveStrikeCount(MOVE_POPULATION_BOMB) == 10);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/powder.c b/test/battle/move_effect/powder.c
index 85e486918b..aa789fb05f 100644
--- a/test/battle/move_effect/powder.c
+++ b/test/battle/move_effect/powder.c
@@ -3,9 +3,9 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_POWDER].effect == EFFECT_POWDER);
- ASSUME(gMovesInfo[MOVE_POWDER].powderMove == TRUE);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(GetMoveEffect(MOVE_POWDER) == EFFECT_POWDER);
+ ASSUME(IsPowderMove(MOVE_POWDER));
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
}
@@ -41,7 +41,7 @@ SINGLE_BATTLE_TEST("Powder blocks the target's Fire type moves and consumes PP")
HP_BAR(opponent);
}
} THEN {
- EXPECT_EQ(player->pp[0], gMovesInfo[MOVE_EMBER].pp - 1);
+ EXPECT_EQ(player->pp[0], GetMovePP(MOVE_EMBER) - 1);
}
}
@@ -164,8 +164,8 @@ SINGLE_BATTLE_TEST("Powder fails if the target has Overcoat")
DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it was given Grass type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].effect == EFFECT_THIRD_TYPE);
- ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].argument == TYPE_GRASS);
+ ASSUME(GetMoveEffect(MOVE_FORESTS_CURSE) == EFFECT_THIRD_TYPE);
+ ASSUME(GetMoveArgType(MOVE_FORESTS_CURSE) == TYPE_GRASS);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_TREVENANT);
@@ -185,7 +185,7 @@ DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it
DOUBLE_BATTLE_TEST("Powder still blocks the target's Fire type moves even if it was given Overcoat")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOODLE].effect == EFFECT_DOODLE);
+ ASSUME(GetMoveEffect(MOVE_DOODLE) == EFFECT_DOODLE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_FORRETRESS) { Ability(ABILITY_OVERCOAT); }
@@ -224,8 +224,8 @@ SINGLE_BATTLE_TEST("Powder prevents Protean from changing its user to Fire type"
SINGLE_BATTLE_TEST("Powder doesn't prevent a Fire move from thawing its user out")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLAME_WHEEL].thawsUser);
- ASSUME(gMovesInfo[MOVE_FLAME_WHEEL].type == TYPE_FIRE);
+ ASSUME(MoveThawsUser(MOVE_FLAME_WHEEL));
+ ASSUME(GetMoveType(MOVE_FLAME_WHEEL) == TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
OPPONENT(SPECIES_VIVILLON);
} WHEN {
@@ -244,7 +244,7 @@ SINGLE_BATTLE_TEST("Powder doesn't prevent a Fire move from thawing its user out
SINGLE_BATTLE_TEST("Powder doesn't consume Berry from Fire type Natural Gift but prevents using the move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
+ ASSUME(GetMoveEffect(MOVE_NATURAL_GIFT) == EFFECT_NATURAL_GIFT);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHERI_BERRY); }
OPPONENT(SPECIES_VIVILLON);
} WHEN {
@@ -267,12 +267,12 @@ DOUBLE_BATTLE_TEST("Powder damages a target using Shell Trap even if it wasn't h
PARAMETRIZE { move = MOVE_EMBER; }
PARAMETRIZE { move = MOVE_TICKLE;}
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].effect == EFFECT_SHELL_TRAP);
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_EMBER].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_TICKLE].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_TICKLE].effect == EFFECT_TICKLE);
+ ASSUME(GetMoveEffect(MOVE_SHELL_TRAP) == EFFECT_SHELL_TRAP);
+ ASSUME(GetMoveType(MOVE_SHELL_TRAP) == TYPE_FIRE);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_EMBER) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TICKLE) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_TICKLE) == EFFECT_TICKLE);
PLAYER(SPECIES_TURTONATOR);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
diff --git a/test/battle/move_effect/power_based_on_target_hp.c b/test/battle/move_effect/power_based_on_target_hp.c
index 2cecf3ff7f..030418cd87 100644
--- a/test/battle/move_effect/power_based_on_target_hp.c
+++ b/test/battle/move_effect/power_based_on_target_hp.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_POWER_BASED_ON_TARGET_HP);
+ ASSUME(GetMoveEffect(MOVE_CRUSH_GRIP) == EFFECT_POWER_BASED_ON_TARGET_HP);
}
SINGLE_BATTLE_TEST("Crush Grip's damage is affected by the target's current HP", s16 damage)
diff --git a/test/battle/move_effect/power_based_on_user_hp.c b/test/battle/move_effect/power_based_on_user_hp.c
index 1dfa70ddf9..622b195525 100644
--- a/test/battle/move_effect/power_based_on_user_hp.c
+++ b/test/battle/move_effect/power_based_on_user_hp.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ERUPTION].effect == EFFECT_POWER_BASED_ON_USER_HP);
+ ASSUME(GetMoveEffect(MOVE_ERUPTION) == EFFECT_POWER_BASED_ON_USER_HP);
}
SINGLE_BATTLE_TEST("Eruption's damage is affected by the user's current HP", s16 damage)
diff --git a/test/battle/move_effect/power_split.c b/test/battle/move_effect/power_split.c
index 70d1bfd5ea..84c64b1d89 100644
--- a/test/battle/move_effect/power_split.c
+++ b/test/battle/move_effect/power_split.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_POWER_SPLIT].effect == EFFECT_POWER_SPLIT);
+ ASSUME(GetMoveEffect(MOVE_POWER_SPLIT) == EFFECT_POWER_SPLIT);
}
SINGLE_BATTLE_TEST("Power Split averages user and targets Atk and Sp. Atk stats")
diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c
index 207544de1f..84862bbcd4 100644
--- a/test/battle/move_effect/protect.c
+++ b/test/battle/move_effect/protect.c
@@ -3,21 +3,21 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_PROTECT].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_DETECT].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_KINGS_SHIELD].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_SILK_TRAP].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_SPIKY_SHIELD].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_WIDE_GUARD].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_QUICK_GUARD].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_CRAFTY_SHIELD].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_BANEFUL_BUNKER].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_BURNING_BULWARK].effect == EFFECT_PROTECT);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_TACKLE].makesContact);
- ASSUME(gMovesInfo[MOVE_LEER].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(!(gMovesInfo[MOVE_WATER_GUN].makesContact));
+ ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_DETECT) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_KINGS_SHIELD) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_SILK_TRAP) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_SPIKY_SHIELD) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_WIDE_GUARD) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_QUICK_GUARD) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_CRAFTY_SHIELD) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_BANEFUL_BUNKER) == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_BURNING_BULWARK) == EFFECT_PROTECT);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(GetMoveCategory(MOVE_LEER) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(!(MoveMakesContact(MOVE_WATER_GUN)));
}
SINGLE_BATTLE_TEST("Protect, Detect, Spiky Shield, Baneful Bunker and Burning Bulwark protect from all moves")
@@ -103,7 +103,7 @@ SINGLE_BATTLE_TEST("King's Shield, Silk Trap and Obstruct protect from damaging
MESSAGE("Wobbuffet's Attack fell!");
#else
MESSAGE("Wobbuffet's Attack harshly fell!");
- #endif
+ #endif
} else if (statId == STAT_SPEED) {
MESSAGE("Wobbuffet's Speed fell!");
} else if (statId == STAT_DEF) {
@@ -244,10 +244,10 @@ SINGLE_BATTLE_TEST("Recoil damage is not applied if target was protected")
GIVEN {
- ASSUME(gMovesInfo[MOVE_VOLT_TACKLE].recoil > 0);
- ASSUME(gMovesInfo[MOVE_HEAD_SMASH].recoil > 0);
- ASSUME(gMovesInfo[MOVE_TAKE_DOWN].recoil > 0);
- ASSUME(gMovesInfo[MOVE_DOUBLE_EDGE].recoil > 0);
+ ASSUME(GetMoveRecoil(MOVE_VOLT_TACKLE) > 0);
+ ASSUME(GetMoveRecoil(MOVE_HEAD_SMASH) > 0);
+ ASSUME(GetMoveRecoil(MOVE_TAKE_DOWN) > 0);
+ ASSUME(GetMoveRecoil(MOVE_DOUBLE_EDGE) > 0);
PLAYER(SPECIES_RAPIDASH);
OPPONENT(SPECIES_BEAUTIFLY);
} WHEN {
@@ -282,7 +282,7 @@ SINGLE_BATTLE_TEST("Multi-hit moves don't hit a protected target and fail only o
PARAMETRIZE { move = MOVE_SPIKY_SHIELD; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ARM_THRUST].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_ARM_THRUST) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_RAPIDASH);
OPPONENT(SPECIES_BEAUTIFLY);
} WHEN {
@@ -325,9 +325,9 @@ DOUBLE_BATTLE_TEST("Wide Guard protects self and ally from multi-target moves")
PARAMETRIZE { move = MOVE_HYPER_VOICE; } // 2 foes
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].target == MOVE_TARGET_SELECTED);
- ASSUME(gMovesInfo[MOVE_SURF].target == MOVE_TARGET_FOES_AND_ALLY);
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_TACKLE) == MOVE_TARGET_SELECTED);
+ ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -364,7 +364,7 @@ DOUBLE_BATTLE_TEST("Wide Guard can not fail on consecutive turns")
PASSES_RANDOMLY(2, 2);
GIVEN {
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -397,8 +397,8 @@ DOUBLE_BATTLE_TEST("Quick Guard protects self and ally from priority moves")
PARAMETRIZE { move = MOVE_QUICK_ATTACK; targetOpponent = opponentRight; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].priority == 0);
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
+ ASSUME(GetMovePriority(MOVE_TACKLE) == 0);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -427,7 +427,7 @@ DOUBLE_BATTLE_TEST("Quick Guard can not fail on consecutive turns")
PASSES_RANDOMLY(2, 2);
GIVEN {
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -457,9 +457,9 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from status moves")
PARAMETRIZE { move = MOVE_TACKLE; targetOpponent = opponentRight; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_LEER].target == MOVE_TARGET_BOTH);
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].target == MOVE_TARGET_BOTH);
- ASSUME(gMovesInfo[MOVE_HYPER_VOICE].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveTarget(MOVE_LEER) == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveCategory(MOVE_HYPER_VOICE) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -487,36 +487,49 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from status moves")
}
}
-SINGLE_BATTLE_TEST("Protect does not block Confide")
+SINGLE_BATTLE_TEST("Protect does not block Confide or Decorate")
{
+ u32 move;
+ PARAMETRIZE { move = MOVE_CONFIDE; }
+ PARAMETRIZE { move = MOVE_DECORATE; }
+
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(MoveIgnoresProtect(MOVE_CONFIDE));
+ ASSUME(GetMoveEffect(MOVE_DECORATE) == EFFECT_DECORATE);
+ ASSUME(MoveIgnoresProtect(MOVE_DECORATE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
- TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_CONFIDE); }
+ TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, move); }
} SCENE {
- MESSAGE("Wobbuffet used Confide!");
- ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFIDE, player);
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
NOT MESSAGE("The opposing Wobbuffet protected itself!");
}
}
-DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide")
+DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide and Decorate")
{
+ u32 move;
+ PARAMETRIZE { move = MOVE_CONFIDE; }
+ PARAMETRIZE { move = MOVE_DECORATE; }
+
GIVEN {
- ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(MoveIgnoresProtect(MOVE_CONFIDE));
+ ASSUME(GetMoveEffect(MOVE_DECORATE) == EFFECT_DECORATE);
+ ASSUME(MoveIgnoresProtect(MOVE_DECORATE));
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
- TURN { MOVE(opponentLeft, MOVE_CRAFTY_SHIELD); MOVE(playerLeft, MOVE_CONFIDE, target: opponentLeft); MOVE(playerRight, MOVE_CONFIDE, target: opponentRight); }
+ TURN { MOVE(opponentLeft, MOVE_CRAFTY_SHIELD); MOVE(playerLeft, move, target: opponentLeft); MOVE(playerRight, move, target: opponentRight); }
} SCENE {
- MESSAGE("Wobbuffet used Confide!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
MESSAGE("The opposing Wobbuffet protected itself!");
- MESSAGE("Wynaut used Confide!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, move, playerRight);
MESSAGE("The opposing Wynaut protected itself!");
}
}
@@ -524,7 +537,6 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide")
DOUBLE_BATTLE_TEST("Crafty Shield does not protect against moves that target all battlers")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLOWER_SHIELD].target == MOVE_TARGET_ALL_BATTLERS);
ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS);
ASSUME(gSpeciesInfo[SPECIES_TANGROWTH].types[0] == TYPE_GRASS);
ASSUME(gSpeciesInfo[SPECIES_SUNKERN].types[0] == TYPE_GRASS);
@@ -570,3 +582,4 @@ SINGLE_BATTLE_TEST("Spiky Shield does not damage users on Counter or Mirror Coat
}
}
}
+
diff --git a/test/battle/terrain/psychic.c b/test/battle/move_effect/psychic_terrain.c
similarity index 84%
rename from test/battle/terrain/psychic.c
rename to test/battle/move_effect/psychic_terrain.c
index 9ac88f29da..b85653a0be 100644
--- a/test/battle/terrain/psychic.c
+++ b/test/battle/move_effect/psychic_terrain.c
@@ -18,25 +18,6 @@ SINGLE_BATTLE_TEST("Psychic Terrain protects grounded battlers from priority mov
}
}
-SINGLE_BATTLE_TEST("Psychic Terrain activates Psychic Seed and Mimicry")
-{
- GIVEN {
- ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffect == HOLD_EFFECT_SEEDS);
- ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN);
- PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PSYCHIC_SEED); }
- OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); }
- } WHEN {
- TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); }
- } SCENE {
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
- MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!");
- ABILITY_POPUP(opponent);
- MESSAGE("The opposing Stunfisk's type changed to Psychic!");
- } THEN {
- EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_PSYCHIC);
- }
-}
-
SINGLE_BATTLE_TEST("Psychic Terrain increases power of Psychic-type moves by 30/50 percent", s16 damage)
{
bool32 terrain;
diff --git a/test/battle/move_effect/pursuit.c b/test/battle/move_effect/pursuit.c
index 3a1db03d06..ea64813e68 100644
--- a/test/battle/move_effect/pursuit.c
+++ b/test/battle/move_effect/pursuit.c
@@ -3,13 +3,465 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_PURSUIT].effect == EFFECT_PURSUIT);
+ ASSUME(GetMoveEffect(MOVE_PURSUIT) == EFFECT_PURSUIT);
+}
+
+SINGLE_BATTLE_TEST("Pursuit attacks a switching foe")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ HP_BAR(player);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit attacks a foe using Volt Switch / U-Turn / Parting Shot to switch out")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_VOLT_SWITCH; }
+ PARAMETRIZE { move = MOVE_U_TURN; }
+ PARAMETRIZE { move = MOVE_PARTING_SHOT; }
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_VOLT_SWITCH) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
+ ASSUME(GetMoveEffect(MOVE_PARTING_SHOT) == EFFECT_PARTING_SHOT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(player, move); MOVE(opponent, MOVE_PURSUIT); SEND_OUT(player, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ MESSAGE("Wobbuffet went back to 1!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit doesn't attack a foe using Teleport / Baton Pass to switch out")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_TELEPORT; }
+ PARAMETRIZE { move = MOVE_BATON_PASS; }
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH);
+ ASSUME(GetMoveEffect(MOVE_TELEPORT) == EFFECT_TELEPORT);
+ ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_NIDOKING);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_QUASH, target: opponentLeft); MOVE(playerLeft, move); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_QUASH, playerRight);
+ ANIMATION(ANIM_TYPE_MOVE, move, playerLeft);
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ SEND_IN_MESSAGE("Zigzagoon");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit doesn't attack switching foe if user already acted that turn")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_PURSUIT); MOVE(player, MOVE_VOLT_SWITCH); SEND_OUT(player, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, player);
+ MESSAGE("Wobbuffet went back to 1!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit doubles in power if attacking while target switches out", s16 damage)
+{
+ u32 speed;
+ PARAMETRIZE { speed = 5; }
+ PARAMETRIZE { speed = 3; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Speed(4); }
+ PLAYER(SPECIES_ZIGZAGOON) { Speed(2); }
+ OPPONENT(SPECIES_WYNAUT) { Speed(speed); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_PURSUIT); MOVE(player, MOVE_VOLT_SWITCH); SEND_OUT(player, 1); }
+ } SCENE {
+ if (speed == 3)
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ HP_BAR(player, captureDamage: &results[i].damage);
+ if (speed == 5)
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, player);
+ SEND_IN_MESSAGE("Zigzagoon");
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit ignores accuracy checks when attacking a switching target")
+{
+ PASSES_RANDOMLY(100, 100, RNG_ACCURACY);
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SAND_ATTACK) == EFFECT_ACCURACY_DOWN);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
+ PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); }
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SAND_ATTACK); MOVE(opponent, MOVE_HAIL); }
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SAND_ATTACK, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HAIL, opponent);
+ SWITCH_OUT_MESSAGE("Glaceon");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit attacks switching foes even if not targetting them (Gen 4+)")
+{
+ GIVEN {
+ ASSUME(B_PURSUIT_TARGET >= GEN_4);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_GRIMER);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerRight); MOVE(opponentRight, MOVE_PURSUIT, target: playerRight); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerLeft);
+ SEND_IN_MESSAGE("Grimer");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe from fastest to slowest")
+{
+ u32 speedLeft, speedRight;
+ PARAMETRIZE { speedLeft = 5; speedRight = 3; }
+ PARAMETRIZE { speedLeft = 3; speedRight = 5; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
+ PLAYER(SPECIES_ZIGZAGOON) { Speed(4); }
+ PLAYER(SPECIES_GRIMER) { Speed(2); }
+ OPPONENT(SPECIES_WYNAUT) { Speed(speedLeft); }
+ OPPONENT(SPECIES_LINOONE) { Speed(speedRight); }
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ if (speedLeft > speedRight) {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerLeft);
+ } else {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerLeft);
+ }
+ SEND_IN_MESSAGE("Grimer");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe but not switching allies")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_GRIMER);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ OPPONENT(SPECIES_ABRA);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); SWITCH(opponentRight, 2); MOVE(playerRight, MOVE_PURSUIT, target: opponentRight); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, playerRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ SEND_IN_MESSAGE("Grimer");
+ MESSAGE("2 withdrew Linoone!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, playerRight);
+ MESSAGE("2 sent out Abra!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit only attacks the first switching foe")
+{
+ // This test does not make sense for B_PURSUIT_TARGET < GEN_4
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_GRIMER);
+ PLAYER(SPECIES_SUNKERN);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerLeft);
+ SEND_IN_MESSAGE("Grimer");
+ SWITCH_OUT_MESSAGE("Zigzagoon");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerRight);
+ }
+ SEND_IN_MESSAGE("Sunkern");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit only attacks a switching foe if foe is alive")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_GRIMER);
+ PLAYER(SPECIES_SUNKERN);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerLeft);
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ MESSAGE("Wobbuffet fainted!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ SEND_IN_MESSAGE("Grimer");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit attacks the second switching foe if the first faints from pursuit")
+{
+ // This test does not make sense for B_PURSUIT_TARGET < GEN_4
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { HP(1); }
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_GRIMER);
+ PLAYER(SPECIES_SUNKERN);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerRight); SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ HP_BAR(playerLeft);
+ MESSAGE("Wobbuffet fainted!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ SWITCH_OUT_MESSAGE("Zigzagoon");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerRight);
+ SEND_IN_MESSAGE("Sunkern");
+ SEND_IN_MESSAGE("Grimer");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit only attacks a switching foe if user is alive")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_GRIMER);
+ OPPONENT(SPECIES_WYNAUT) { HP(1); }
+ OPPONENT(SPECIES_LINOONE);
+ OPPONENT(SPECIES_SUNKERN);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); SEND_OUT(opponentLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
+ MESSAGE("The opposing Wynaut fainted!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ SEND_IN_MESSAGE("Grimer");
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit attacks a switching foe but fails if user is asleep")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT) { Status1(STATUS1_SLEEP_TURN(2)); }
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ MESSAGE("The opposing Wynaut is fast asleep.");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit attacks a switching foe and takes Life Orb damage")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT) { Item(ITEM_LIFE_ORB); }
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ HP_BAR(opponent);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit attacks a switching foe but isn't affected by Follow Me")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_FOLLOW_ME) == EFFECT_FOLLOW_ME);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_CLEFABLE);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_FOLLOW_ME); MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FOLLOW_ME, playerRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit user mega evolves before attacking a switching foe and hits twice if user has Parental Bond")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT, gimmick: GIMMICK_MEGA); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ HP_BAR(player);
+ HP_BAR(player);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit user mega evolves before attacking a switching foe and others mega evolve after switch")
+{
+ GIVEN {
+ PLAYER(SPECIES_CHARIZARD) { Item(ITEM_CHARIZARDITE_X); }
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); }
+ } WHEN {
+ TURN { SWITCH(playerRight, 2); MOVE(opponentRight, MOVE_PURSUIT, gimmick: GIMMICK_MEGA, target: playerRight); MOVE(playerLeft, MOVE_CELEBRATE, gimmick: GIMMICK_MEGA); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponentRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ HP_BAR(playerRight);
+ HP_BAR(playerRight);
+ SEND_IN_MESSAGE("Zigzagoon");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft);
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit user terastalizes before attacking a switching foe and gets the damage boost from the tera type", s16 damage)
+{
+ u32 tera;
+ PARAMETRIZE { tera = GIMMICK_NONE; }
+ PARAMETRIZE { tera = GIMMICK_TERA; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_KANGASKHAN) { TeraType(TYPE_DARK); }
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT, gimmick: tera); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ if (tera == GIMMICK_TERA)
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_TERA_ACTIVATE, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ HP_BAR(player, captureDamage: &results[i].damage);
+ SEND_IN_MESSAGE("Zigzagoon");
+ } FINALLY {
+ EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against immune target")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
+ PLAYER(SPECIES_DONPHAN);
+ PLAYER(SPECIES_HELIOLISK);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_ELECTRIFY, target: opponentLeft); MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, playerRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuit affected by Electrify fails against target with Volt Absorb")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_ELECTRIFY) == EFFECT_ELECTRIFY);
+ PLAYER(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); }
+ PLAYER(SPECIES_HELIOLISK);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_LINOONE);
+ } WHEN {
+ TURN { MOVE(playerRight, MOVE_ELECTRIFY, target: opponentLeft); MOVE(playerLeft, MOVE_VOLT_SWITCH, target: opponentLeft); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); SEND_OUT(playerLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIFY, playerRight);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_VOLT_SWITCH, playerLeft);
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ ABILITY_POPUP(playerLeft, ABILITY_VOLT_ABSORB);
+ SEND_IN_MESSAGE("Zigzagoon");
+ }
}
SINGLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Tangling Hair")
{
GIVEN {
- PLAYER(SPECIES_DUGTRIO) { Ability(ABILITY_TANGLING_HAIR); }
+ PLAYER(SPECIES_DUGTRIO_ALOLA) { Ability(ABILITY_TANGLING_HAIR); }
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -25,6 +477,80 @@ SINGLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and ac
}
}
+DOUBLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Tangling Hair - Doubles")
+{
+ GIVEN {
+ PLAYER(SPECIES_DUGTRIO_ALOLA) { Ability(ABILITY_TANGLING_HAIR); }
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Dugtrio");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ ABILITY_POPUP(playerLeft, ABILITY_TANGLING_HAIR);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
+ MESSAGE("The opposing Wynaut's Speed fell!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ ABILITY_POPUP(playerLeft, ABILITY_TANGLING_HAIR);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
+ MESSAGE("The opposing Wobbuffet's Speed fell!");
+ SEND_IN_MESSAGE("Wobbuffet");
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Tangling Hair - Mirror Armor")
+{
+ GIVEN {
+ PLAYER(SPECIES_DUGTRIO_ALOLA) { Ability(ABILITY_TANGLING_HAIR); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Dugtrio");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ ABILITY_POPUP(player, ABILITY_TANGLING_HAIR);
+ ABILITY_POPUP(opponent, ABILITY_MIRROR_ARMOR);
+ SEND_IN_MESSAGE("Wobbuffet");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Pursuited mon correctly switches out after it got hit and activated ability Cotton Down")
+{
+ GIVEN {
+ PLAYER(SPECIES_ELDEGOSS) { Ability(ABILITY_COTTON_DOWN); }
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { SWITCH(playerLeft, 2); MOVE(opponentLeft, MOVE_PURSUIT, target: playerLeft); MOVE(opponentRight, MOVE_PURSUIT, target: playerLeft); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Eldegoss");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentLeft);
+ ABILITY_POPUP(playerLeft, ABILITY_COTTON_DOWN);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
+ MESSAGE("The opposing Wynaut's Speed fell!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
+ MESSAGE("Wobbuffet's Speed fell!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
+ MESSAGE("The opposing Wobbuffet's Speed fell!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponentRight);
+ ABILITY_POPUP(playerLeft, ABILITY_COTTON_DOWN);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
+ MESSAGE("The opposing Wynaut's Speed fell!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight);
+ MESSAGE("Wobbuffet's Speed fell!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
+ MESSAGE("The opposing Wobbuffet's Speed fell!");
+ SEND_IN_MESSAGE("Wobbuffet");
+ }
+}
+
// Checked so that Pursuit has only 1 PP and it forces the player to use Struggle.
SINGLE_BATTLE_TEST("Pursuit becomes a locked move after being used on switch-out while holding a Choice Item")
{
@@ -46,4 +572,105 @@ SINGLE_BATTLE_TEST("Pursuit becomes a locked move after being used on switch-out
}
}
+SINGLE_BATTLE_TEST("Pursuit attacks a switching foe and switchin is correctly stored")
+{
+ u32 switchin;
+ PARAMETRIZE { switchin = 1; }
+ PARAMETRIZE { switchin = 2; }
+ PARAMETRIZE { switchin = 3; }
+ PARAMETRIZE { switchin = 4; }
+
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_AIPOM);
+ PLAYER(SPECIES_ABRA);
+ PLAYER(SPECIES_VENIPEDE);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { SWITCH(player, switchin); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ switch (switchin)
+ {
+ case 1:
+ SEND_IN_MESSAGE("Zigzagoon");
+ break;
+ case 2:
+ SEND_IN_MESSAGE("Aipom");
+ break;
+ case 3:
+ SEND_IN_MESSAGE("Abra");
+ break;
+ case 4:
+ SEND_IN_MESSAGE("Venipede");
+ break;
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit doesn't cause mon with Emergency Exit to switch twice")
+{
+ GIVEN {
+ PLAYER(SPECIES_GOLISOPOD) { HP(101); MaxHP(200); Ability(ABILITY_EMERGENCY_EXIT); }
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_VOLTORB);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); SEND_OUT(player, 2); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Golisopod");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ ABILITY_POPUP(player, ABILITY_EMERGENCY_EXIT);
+ SEND_IN_MESSAGE("Voltorb");
+ } THEN {
+ EXPECT_EQ(player->species, SPECIES_VOLTORB);
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit user gets forced out by Red Card and target still switches out")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
+ PLAYER(SPECIES_VOLTORB);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_VOLTORB);
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ MESSAGE("The opposing Voltorb was dragged out!");
+ SEND_IN_MESSAGE("Voltorb");
+ } THEN {
+ EXPECT_EQ(player->species, SPECIES_VOLTORB);
+ EXPECT_EQ(opponent->species, SPECIES_VOLTORB);
+ }
+}
+
+SINGLE_BATTLE_TEST("Pursuit user faints to Life Orb and target still switches out")
+{
+ GIVEN {
+ ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_VOLTORB);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LIFE_ORB); HP(1); }
+ OPPONENT(SPECIES_VOLTORB);
+ } WHEN {
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_PURSUIT); SEND_OUT(opponent, 1); }
+ } SCENE {
+ SWITCH_OUT_MESSAGE("Wobbuffet");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PURSUIT, opponent);
+ HP_BAR(opponent);
+ MESSAGE("The opposing Wobbuffet fainted!");
+ SEND_IN_MESSAGE("Voltorb");
+ } THEN {
+ EXPECT_EQ(player->species, SPECIES_VOLTORB);
+ EXPECT_EQ(opponent->species, SPECIES_VOLTORB);
+ }
+}
+
TO_DO_BATTLE_TEST("Baton Pass doesn't cause Pursuit to increase its power or priority");
diff --git a/test/battle/move_effect/quash.c b/test/battle/move_effect/quash.c
index b342eafd74..1d2f89230c 100644
--- a/test/battle/move_effect/quash.c
+++ b/test/battle/move_effect/quash.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_QUASH].effect == EFFECT_QUASH);
+ ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH);
}
DOUBLE_BATTLE_TEST("Quash-affected target will move last in the priority bracket")
@@ -27,7 +27,7 @@ DOUBLE_BATTLE_TEST("Quash is not affected by dynamic speed")
{
GIVEN {
ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8);
- ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
+ ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND);
PLAYER(SPECIES_VOLBEAT) { Speed(10); Ability(ABILITY_PRANKSTER); }
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
OPPONENT(SPECIES_TORCHIC) { Speed(50); }
@@ -113,8 +113,8 @@ DOUBLE_BATTLE_TEST("Quash-affected mon that acted early via After You is not aff
{
GIVEN {
ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8);
- ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
- ASSUME(gMovesInfo[MOVE_AFTER_YOU].effect == EFFECT_AFTER_YOU);
+ ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND);
+ ASSUME(GetMoveEffect(MOVE_AFTER_YOU) == EFFECT_AFTER_YOU);
PLAYER(SPECIES_VOLBEAT) { Speed(20); Ability(ABILITY_PRANKSTER); }
PLAYER(SPECIES_WOBBUFFET) { Speed(30); }
OPPONENT(SPECIES_TORCHIC) { Speed(10); }
diff --git a/test/battle/move_effect/rage_fist.c b/test/battle/move_effect/rage_fist.c
index 7bc349cef0..7a87f3e34d 100644
--- a/test/battle/move_effect/rage_fist.c
+++ b/test/battle/move_effect/rage_fist.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_RAGE_FIST].effect == EFFECT_RAGE_FIST);
- ASSUME(gMovesInfo[MOVE_RAGE_FIST].power == 50);
+ ASSUME(GetMoveEffect(MOVE_RAGE_FIST) == EFFECT_RAGE_FIST);
+ ASSUME(GetMovePower(MOVE_RAGE_FIST) == 50);
}
SINGLE_BATTLE_TEST("Rage Fist base power is increased by 50 if the user takes damage")
@@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Rage Fist base power is increased by each multi hit")
s16 timesGotHit[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_BULLET_SEED].effect == EFFECT_MULTI_HIT);
+ ASSUME(GetMoveEffect(MOVE_BULLET_SEED) == EFFECT_MULTI_HIT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_REGIROCK);
} WHEN {
@@ -130,7 +130,7 @@ SINGLE_BATTLE_TEST("Rage Fist base power is not increased if a substitute was hi
s16 timesGotHit[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_CRUNCH].category == DAMAGE_CATEGORY_PHYSICAL); // Substitute doesn't fade otherwise
+ ASSUME(GetMoveCategory(MOVE_CRUNCH) == DAMAGE_CATEGORY_PHYSICAL); // Substitute doesn't fade otherwise
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_REGIROCK);
} WHEN {
diff --git a/test/battle/move_effect/raging_bull.c b/test/battle/move_effect/raging_bull.c
index 7e72ca8273..c75c977495 100644
--- a/test/battle/move_effect/raging_bull.c
+++ b/test/battle/move_effect/raging_bull.c
@@ -3,11 +3,11 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_RAGING_BULL].effect == EFFECT_RAGING_BULL);
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
- ASSUME(gMovesInfo[MOVE_LIGHT_SCREEN].effect == EFFECT_LIGHT_SCREEN);
- ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT);
- ASSUME(gMovesInfo[MOVE_AURORA_VEIL].effect == EFFECT_AURORA_VEIL);
+ ASSUME(GetMoveEffect(MOVE_RAGING_BULL) == EFFECT_RAGING_BULL);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_LIGHT_SCREEN) == EFFECT_LIGHT_SCREEN);
+ ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT);
+ ASSUME(GetMoveEffect(MOVE_AURORA_VEIL) == EFFECT_AURORA_VEIL);
}
SINGLE_BATTLE_TEST("Raging Bull removes Light Screen, Reflect and Aurora Veil from the target's side of the field")
diff --git a/test/battle/move_effect/recoil_if_miss.c b/test/battle/move_effect/recoil_if_miss.c
index a5f0111095..8695156dd0 100644
--- a/test/battle/move_effect/recoil_if_miss.c
+++ b/test/battle/move_effect/recoil_if_miss.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_JUMP_KICK].effect == EFFECT_RECOIL_IF_MISS);
+ ASSUME(GetMoveEffect(MOVE_JUMP_KICK) == EFFECT_RECOIL_IF_MISS);
}
SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss")
@@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss")
SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect")
{
GIVEN {
- ASSUME(!gMovesInfo[MOVE_JUMP_KICK].ignoresProtect);
+ ASSUME(!MoveIgnoresProtect(MOVE_JUMP_KICK));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Jump Kick's recoil happens after Spiky Shield damage and Pok
PARAMETRIZE { hp = maxHp / 8; faintOnSpiky = TRUE; } // Faints after Spiky Shield's recoil
GIVEN {
- ASSUME(gMovesInfo[MOVE_SPIKY_SHIELD].effect == EFFECT_PROTECT);
+ ASSUME(GetMoveEffect(MOVE_SPIKY_SHIELD) == EFFECT_PROTECT);
PLAYER(SPECIES_WOBBUFFET) { HP(hp); MaxHP(maxHp); }
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/reflect.c b/test/battle/move_effect/reflect.c
index 429dc6f696..83ac3b8503 100644
--- a/test/battle/move_effect/reflect.c
+++ b/test/battle/move_effect/reflect.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_REFLECT].effect == EFFECT_REFLECT);
+ ASSUME(GetMoveEffect(MOVE_REFLECT) == EFFECT_REFLECT);
}
SINGLE_BATTLE_TEST("Reflect reduces physical damage", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Reflect reduces physical damage", s16 damage)
PARAMETRIZE { move = MOVE_CELEBRATE; }
PARAMETRIZE { move = MOVE_REFLECT; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -30,7 +30,7 @@ SINGLE_BATTLE_TEST("Reflect applies for 5 turns")
{
s16 damage[6];
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/refresh.c b/test/battle/move_effect/refresh.c
new file mode 100644
index 0000000000..7d0ba0273e
--- /dev/null
+++ b/test/battle/move_effect/refresh.c
@@ -0,0 +1,68 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_REFRESH) == EFFECT_REFRESH);
+}
+
+SINGLE_BATTLE_TEST("Refresh cures the user of burn, frostbite, poison, and paralysis")
+{
+ u32 status1;
+ PARAMETRIZE { status1 = STATUS1_POISON; }
+ PARAMETRIZE { status1 = STATUS1_BURN; }
+ PARAMETRIZE { status1 = STATUS1_PARALYSIS; }
+ PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
+ PARAMETRIZE { status1 = STATUS1_FROSTBITE; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Status1(status1); };
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_REFRESH); }
+ } SCENE {
+ MESSAGE("Wobbuffet's status returned to normal!");
+ STATUS_ICON(player, none: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Refresh does not cure the user of Freeze")
+{
+ PASSES_RANDOMLY(20, 100, RNG_FROZEN);
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_REFRESH); }
+ } SCENE {
+ MESSAGE("Wobbuffet used Refresh!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REFRESH, player);
+ STATUS_ICON(player, none: TRUE); }
+ MESSAGE("But it failed!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Refresh does not cure sleep when used by Sleep Talk")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_REFRESH); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); }
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_REFRESH); }
+ } SCENE {
+ MESSAGE("Wobbuffet used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ MESSAGE("The opposing Wobbuffet used Sleep Talk!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent);
+ MESSAGE("The opposing Wobbuffet used Refresh!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REFRESH, player);
+ STATUS_ICON(player, none: TRUE); }
+ MESSAGE("But it failed!");
+ }
+}
diff --git a/test/battle/move_effect/relic_song.c b/test/battle/move_effect/relic_song.c
index e7569c7e38..f1e7fae92f 100644
--- a/test/battle/move_effect/relic_song.c
+++ b/test/battle/move_effect/relic_song.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_RELIC_SONG].effect == EFFECT_RELIC_SONG);
+ ASSUME(GetMoveEffect(MOVE_RELIC_SONG) == EFFECT_RELIC_SONG);
ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP) == TRUE);
}
diff --git a/test/battle/move_effect/retaliate.c b/test/battle/move_effect/retaliate.c
index 581793e854..39c26d196c 100644
--- a/test/battle/move_effect/retaliate.c
+++ b/test/battle/move_effect/retaliate.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_RETALIATE].effect == EFFECT_RETALIATE);
+ ASSUME(GetMoveEffect(MOVE_RETALIATE) == EFFECT_RETALIATE);
}
SINGLE_BATTLE_TEST("Retaliate doubles in base power the turn after an ally faints")
@@ -63,17 +63,17 @@ DOUBLE_BATTLE_TEST("Retaliate works with passive damage")
PARAMETRIZE { move = MOVE_FLAME_BURST; moveTarget = playerRight; }
PARAMETRIZE { move = MOVE_FIRE_PLEDGE; moveTarget = playerRight; move2 = MOVE_GRASS_PLEDGE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
- ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON);
- ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_POISON_POWDER) == EFFECT_POISON);
+ ASSUME(GetMoveEffect(MOVE_WILL_O_WISP) == EFFECT_WILL_O_WISP);
#if B_USE_FROSTBITE == TRUE
- ASSUME(gMovesInfo[MOVE_ICE_BEAM].additionalEffects[0].moveEffect == MOVE_EFFECT_FREEZE_OR_FROSTBITE);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_ICE_BEAM, 0)->moveEffect == MOVE_EFFECT_FREEZE_OR_FROSTBITE);
#endif
- ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM);
- ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL);
- ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED);
- ASSUME(gMovesInfo[MOVE_MAGMA_STORM].additionalEffects[0].moveEffect == MOVE_EFFECT_WRAP);
- ASSUME(gMovesInfo[MOVE_FLAME_BURST].additionalEffects[0].moveEffect == MOVE_EFFECT_FLAME_BURST);
+ ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM);
+ ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL);
+ ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_MAGMA_STORM, 0)->moveEffect == MOVE_EFFECT_WRAP);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_FLAME_BURST, 0)->moveEffect == MOVE_EFFECT_FLAME_BURST);
PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); HP(18); }
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); }
PLAYER(SPECIES_WOBBUFFET);
@@ -97,7 +97,7 @@ SINGLE_BATTLE_TEST("Retaliate works with Perish Song")
{
s16 damage[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_PERISH_SONG].effect == EFFECT_PERISH_SONG);
+ ASSUME(GetMoveEffect(MOVE_PERISH_SONG) == EFFECT_PERISH_SONG);
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_KOMMO_O) { Ability(ABILITY_SOUNDPROOF); }
@@ -120,7 +120,7 @@ SINGLE_BATTLE_TEST("Retaliate works with self-inflicted fainting")
{
s16 damage[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH);
+ ASSUME(GetMoveEffect(MOVE_HEALING_WISH) == EFFECT_HEALING_WISH);
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/revelation_dance.c b/test/battle/move_effect/revelation_dance.c
index 9ab5d4a8e2..3730ecc0b2 100644
--- a/test/battle/move_effect/revelation_dance.c
+++ b/test/battle/move_effect/revelation_dance.c
@@ -3,12 +3,12 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE);
- ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE);
- ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE));
- ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].effect == EFFECT_THIRD_TYPE);
- ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].argument == TYPE_GRASS);
- ASSUME(gMovesInfo[MOVE_ROOST].effect == EFFECT_ROOST);
+ ASSUME(GetMoveEffect(MOVE_REVELATION_DANCE) == EFFECT_REVELATION_DANCE);
+ ASSUME(IsDanceMove(MOVE_REVELATION_DANCE));
+ ASSUME(IsMoveEffectRemoveSpeciesType(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE));
+ ASSUME(GetMoveEffect(MOVE_FORESTS_CURSE) == EFFECT_THIRD_TYPE);
+ ASSUME(GetMoveArgType(MOVE_FORESTS_CURSE) == TYPE_GRASS);
+ ASSUME(GetMoveEffect(MOVE_ROOST) == EFFECT_ROOST);
}
SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 1st Type")
diff --git a/test/battle/move_effect/revival_blessing.c b/test/battle/move_effect/revival_blessing.c
index dbeda39f91..10198ce352 100644
--- a/test/battle/move_effect/revival_blessing.c
+++ b/test/battle/move_effect/revival_blessing.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_REVIVAL_BLESSING].effect == EFFECT_REVIVAL_BLESSING);
+ ASSUME(GetMoveEffect(MOVE_REVIVAL_BLESSING) == EFFECT_REVIVAL_BLESSING);
}
SINGLE_BATTLE_TEST("Revival Blessing revives a chosen fainted party member for the player")
diff --git a/test/battle/move_effect/roar.c b/test/battle/move_effect/roar.c
index f67a24bba1..ef6439088f 100644
--- a/test/battle/move_effect/roar.c
+++ b/test/battle/move_effect/roar.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ROAR].effect == EFFECT_ROAR);
+ ASSUME(GetMoveEffect(MOVE_ROAR) == EFFECT_ROAR);
}
SINGLE_BATTLE_TEST("Roar switches the target with a random non-fainted replacement")
diff --git a/test/battle/move_effect/role_play.c b/test/battle/move_effect/role_play.c
index ab0d801ee9..d2d937f7d1 100644
--- a/test/battle/move_effect/role_play.c
+++ b/test/battle/move_effect/role_play.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ROLE_PLAY].effect == EFFECT_ROLE_PLAY);
+ ASSUME(GetMoveEffect(MOVE_ROLE_PLAY) == EFFECT_ROLE_PLAY);
}
SINGLE_BATTLE_TEST("Role Play copies target's ability")
diff --git a/test/battle/move_effect/roost.c b/test/battle/move_effect/roost.c
index 449119a89a..51d9499bd1 100644
--- a/test/battle/move_effect/roost.c
+++ b/test/battle/move_effect/roost.c
@@ -3,28 +3,28 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ROOST].effect == EFFECT_ROOST);
+ ASSUME(GetMoveEffect(MOVE_ROOST) == EFFECT_ROOST);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_FLYING);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_FLYING);
// One attack of each type to verify typelessness
- ASSUME(gMovesInfo[MOVE_POUND].type == TYPE_NORMAL);
- ASSUME(gMovesInfo[MOVE_KARATE_CHOP].type == TYPE_FIGHTING);
- ASSUME(gMovesInfo[MOVE_GUST].type == TYPE_FLYING);
- ASSUME(gMovesInfo[MOVE_POISON_STING].type == TYPE_POISON);
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].type == TYPE_GROUND);
- ASSUME(gMovesInfo[MOVE_ROCK_THROW].type == TYPE_ROCK);
- ASSUME(gMovesInfo[MOVE_LEECH_LIFE].type == TYPE_BUG);
- ASSUME(gMovesInfo[MOVE_LICK].type == TYPE_GHOST);
- ASSUME(gMovesInfo[MOVE_STEEL_WING].type == TYPE_STEEL);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS);
- ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
- ASSUME(gMovesInfo[MOVE_CONFUSION].type == TYPE_PSYCHIC);
- ASSUME(gMovesInfo[MOVE_ICE_BEAM].type == TYPE_ICE);
- ASSUME(gMovesInfo[MOVE_DRAGON_BREATH].type == TYPE_DRAGON);
- ASSUME(gMovesInfo[MOVE_BITE].type == TYPE_DARK);
- ASSUME(gMovesInfo[MOVE_DISARMING_VOICE].type == TYPE_FAIRY);
+ ASSUME(GetMoveType(MOVE_POUND) == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_KARATE_CHOP) == TYPE_FIGHTING);
+ ASSUME(GetMoveType(MOVE_GUST) == TYPE_FLYING);
+ ASSUME(GetMoveType(MOVE_POISON_STING) == TYPE_POISON);
+ ASSUME(GetMoveType(MOVE_EARTHQUAKE) == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_ROCK_THROW) == TYPE_ROCK);
+ ASSUME(GetMoveType(MOVE_LEECH_LIFE) == TYPE_BUG);
+ ASSUME(GetMoveType(MOVE_LICK) == TYPE_GHOST);
+ ASSUME(GetMoveType(MOVE_STEEL_WING) == TYPE_STEEL);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS);
+ ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC);
+ ASSUME(GetMoveType(MOVE_CONFUSION) == TYPE_PSYCHIC);
+ ASSUME(GetMoveType(MOVE_ICE_BEAM) == TYPE_ICE);
+ ASSUME(GetMoveType(MOVE_DRAGON_BREATH) == TYPE_DRAGON);
+ ASSUME(GetMoveType(MOVE_BITE) == TYPE_DARK);
+ ASSUME(GetMoveType(MOVE_DISARMING_VOICE) == TYPE_FAIRY);
}
SINGLE_BATTLE_TEST("Roost fails when user is at full HP")
diff --git a/test/battle/move_effect/round.c b/test/battle/move_effect/round.c
index 09209c79a2..0bac324b0f 100644
--- a/test/battle/move_effect/round.c
+++ b/test/battle/move_effect/round.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ROUND].effect == EFFECT_ROUND);
+ ASSUME(GetMoveEffect(MOVE_ROUND) == EFFECT_ROUND);
}
DOUBLE_BATTLE_TEST("Round allows other battlers which also selected the moves to immediately use the move, ignoring turn order")
{
GIVEN {
ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL);
- ASSUME(gMovesInfo[MOVE_IRON_HEAD].additionalEffects[0].moveEffect == MOVE_EFFECT_FLINCH);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_IRON_HEAD, 0)->moveEffect == MOVE_EFFECT_FLINCH);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/salt_cure.c b/test/battle/move_effect/salt_cure.c
index 495a7e8c80..94e3ead5cc 100644
--- a/test/battle/move_effect/salt_cure.c
+++ b/test/battle/move_effect/salt_cure.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SALT_CURE].effect == EFFECT_SALT_CURE);
+ ASSUME(MoveHasAdditionalEffect(MOVE_SALT_CURE, MOVE_EFFECT_SALT_CURE) == TRUE);
}
SINGLE_BATTLE_TEST("Salt Cure inflicts 1/8 of the target's maximum HP as damage per turn")
@@ -117,3 +117,18 @@ SINGLE_BATTLE_TEST("Salt Cure residual damage does not inflict any damage agains
}
}
}
+
+SINGLE_BATTLE_TEST("If Salt Cure faints the target, messages will be applied in the correct order")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { HP(25); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SALT_CURE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SALT_CURE, player);
+ MESSAGE("The opposing Wobbuffet is being salt cured!");
+ MESSAGE("The opposing Wobbuffet is hurt by Salt Cure!");
+ MESSAGE("The opposing Wobbuffet fainted!");
+ }
+}
diff --git a/test/battle/move_effect/semi_invulnerable.c b/test/battle/move_effect/semi_invulnerable.c
index d3869bfe54..331413121c 100644
--- a/test/battle/move_effect/semi_invulnerable.c
+++ b/test/battle/move_effect/semi_invulnerable.c
@@ -3,18 +3,18 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_FLY].argument)) == STATUS3_ON_AIR);
- ASSUME(gMovesInfo[MOVE_DIG].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_DIG].argument)) == STATUS3_UNDERGROUND);
- ASSUME(gMovesInfo[MOVE_BOUNCE].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_BOUNCE].argument)) == STATUS3_ON_AIR);
- ASSUME(gMovesInfo[MOVE_DIVE].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_DIVE].argument)) == STATUS3_UNDERWATER);
- ASSUME(gMovesInfo[MOVE_PHANTOM_FORCE].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_PHANTOM_FORCE].argument)) == STATUS3_PHANTOM_FORCE);
- ASSUME(gMovesInfo[MOVE_SHADOW_FORCE].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_SHADOW_FORCE].argument)) == STATUS3_PHANTOM_FORCE);
+ ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATUS3_ON_AIR);
+ ASSUME(GetMoveEffect(MOVE_DIG) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIG) == STATUS3_UNDERGROUND);
+ ASSUME(GetMoveEffect(MOVE_BOUNCE) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATUS3_ON_AIR);
+ ASSUME(GetMoveEffect(MOVE_DIVE) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_DIVE) == STATUS3_UNDERWATER);
+ ASSUME(GetMoveEffect(MOVE_PHANTOM_FORCE) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_PHANTOM_FORCE) == STATUS3_PHANTOM_FORCE);
+ ASSUME(GetMoveEffect(MOVE_SHADOW_FORCE) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SHADOW_FORCE) == STATUS3_PHANTOM_FORCE);
}
SINGLE_BATTLE_TEST("Semi-invulnerable moves make the user semi-invulnerable turn 1, then strike turn 2")
diff --git a/test/battle/move_effect/shed_tail.c b/test/battle/move_effect/shed_tail.c
index 51d7652460..4667eab1ad 100644
--- a/test/battle/move_effect/shed_tail.c
+++ b/test/battle/move_effect/shed_tail.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SHED_TAIL].effect == EFFECT_SHED_TAIL);
+ ASSUME(GetMoveEffect(MOVE_SHED_TAIL) == EFFECT_SHED_TAIL);
}
SINGLE_BATTLE_TEST("Shed Tail creates a Substitute at the cost of 1/2 users maximum HP and switches the user out")
@@ -86,6 +86,8 @@ SINGLE_BATTLE_TEST("Shed Tail's HP cost doesn't trigger effects that trigger on
}
}
+// Passes for some reason even though it seems there is some code missing
+/*
AI_SINGLE_BATTLE_TEST("AI will use Shed Tail to pivot to another mon while in damage stalemate with player")
{
KNOWN_FAILING; // missing AI code
@@ -99,3 +101,27 @@ AI_SINGLE_BATTLE_TEST("AI will use Shed Tail to pivot to another mon while in da
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_SHED_TAIL); }
}
}
+*/
+
+SINGLE_BATTLE_TEST("Shed Tail creates a Substitute with 1/4 of user maximum health")
+{
+ u32 hp;
+ PARAMETRIZE { hp = 160; }
+ PARAMETRIZE { hp = 164; }
+
+ GIVEN {
+ ASSUME(GetMoveFixedDamage(MOVE_DRAGON_RAGE) == 40);
+ ASSUME(GetMoveEffect(MOVE_DRAGON_RAGE) == EFFECT_FIXED_DAMAGE_ARG);
+ PLAYER(SPECIES_BULBASAUR) { MaxHP(hp); }
+ PLAYER(SPECIES_BULBASAUR);
+ OPPONENT(SPECIES_CHARMANDER);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SHED_TAIL); MOVE(opponent, MOVE_DRAGON_RAGE); SEND_OUT(player, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SHED_TAIL, player);
+ if (hp == 160)
+ MESSAGE("Bulbasaur's substitute faded!");
+ else
+ NOT MESSAGE("Bulbasaur's substitute faded!");
+ }
+}
diff --git a/test/battle/move_effect/shell_trap.c b/test/battle/move_effect/shell_trap.c
index d43893244a..f121d1444d 100644
--- a/test/battle/move_effect/shell_trap.c
+++ b/test/battle/move_effect/shell_trap.c
@@ -3,10 +3,10 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].effect == EFFECT_SHELL_TRAP);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_LEER].category == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMoveEffect(MOVE_SHELL_TRAP) == EFFECT_SHELL_TRAP);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_WATER_GUN) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_LEER) == DAMAGE_CATEGORY_STATUS);
}
SINGLE_BATTLE_TEST("Shell Trap activates only if hit by a physical move")
@@ -98,7 +98,7 @@ SINGLE_BATTLE_TEST("Shell Trap does not activate if battler faints before being
DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 1 and attacks both opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
PLAYER(SPECIES_WOBBUFFET) { Speed(2); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
@@ -122,7 +122,7 @@ DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 1 a
DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 2 and attacks both opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
PLAYER(SPECIES_WOBBUFFET) { Speed(2); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
@@ -146,7 +146,7 @@ DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 2 a
DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 3 and attacks both opponents")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
PLAYER(SPECIES_WOBBUFFET) { Speed(7); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(5); }
@@ -170,7 +170,7 @@ DOUBLE_BATTLE_TEST("Shell Trap activates immediately after being hit on turn 3 a
DOUBLE_BATTLE_TEST("Shell Trap targets correctly if one of the opponents has fainted")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SHELL_TRAP].target == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_SHELL_TRAP) == MOVE_TARGET_BOTH);
PLAYER(SPECIES_GRENINJA) { Speed(60); }
PLAYER(SPECIES_TURTONATOR) { Speed(10); }
OPPONENT(SPECIES_BLASTOISE) { Speed(120); }
diff --git a/test/battle/move_effect/simple_beam.c b/test/battle/move_effect/simple_beam.c
index e91bf0b8ce..4250c8ce45 100644
--- a/test/battle/move_effect/simple_beam.c
+++ b/test/battle/move_effect/simple_beam.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SIMPLE_BEAM].effect == EFFECT_SIMPLE_BEAM);
+ ASSUME(GetMoveEffect(MOVE_SIMPLE_BEAM) == EFFECT_SIMPLE_BEAM);
}
SINGLE_BATTLE_TEST("Simple Beam replaces target's ability with Simple")
diff --git a/test/battle/move_effect/skill_swap.c b/test/battle/move_effect/skill_swap.c
index 9c31ae59a7..c3c2ca91f4 100644
--- a/test/battle/move_effect/skill_swap.c
+++ b/test/battle/move_effect/skill_swap.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SKILL_SWAP].effect == EFFECT_SKILL_SWAP);
+ ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP);
}
SINGLE_BATTLE_TEST("Skill Swap swaps user and target's abilities")
diff --git a/test/battle/move_effect/sleep.c b/test/battle/move_effect/sleep.c
index 834f606672..702044d331 100644
--- a/test/battle/move_effect/sleep.c
+++ b/test/battle/move_effect/sleep.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HYPNOSIS].effect == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_HYPNOSIS) == EFFECT_SLEEP);
}
SINGLE_BATTLE_TEST("Hypnosis inflicts 1-3 turns of sleep")
diff --git a/test/battle/move_effect/sleep_talk.c b/test/battle/move_effect/sleep_talk.c
index 8ecd600f36..4ac89e69d8 100644
--- a/test/battle/move_effect/sleep_talk.c
+++ b/test/battle/move_effect/sleep_talk.c
@@ -3,10 +3,10 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK);
- ASSUME(gMovesInfo[MOVE_RAZOR_WIND].sleepTalkBanned == TRUE);
- ASSUME(gMovesInfo[MOVE_FLY].sleepTalkBanned == TRUE);
- ASSUME(gMovesInfo[MOVE_DIG].sleepTalkBanned == TRUE);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ ASSUME(IsMoveSleepTalkBanned(MOVE_RAZOR_WIND));
+ ASSUME(IsMoveSleepTalkBanned(MOVE_FLY));
+ ASSUME(IsMoveSleepTalkBanned(MOVE_DIG));
}
SINGLE_BATTLE_TEST("Sleep Talk fails if not asleep")
diff --git a/test/battle/move_effect/smelling_salts.c b/test/battle/move_effect/smelling_salts.c
index bb3f333a42..6b1d0b2d7e 100644
--- a/test/battle/move_effect/smelling_salts.c
+++ b/test/battle/move_effect/smelling_salts.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffect(MOVE_SMELLING_SALTS, MOVE_EFFECT_REMOVE_STATUS) == TRUE);
- ASSUME(gMovesInfo[MOVE_SMELLING_SALTS].argument == STATUS1_PARALYSIS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_SMELLING_SALTS) == STATUS1_PARALYSIS);
}
SINGLE_BATTLE_TEST("Smelling Salts does not cure paralyzed pokemons behind substitutes or get increased power")
diff --git a/test/battle/move_effect/solar_beam.c b/test/battle/move_effect/solar_beam.c
new file mode 100644
index 0000000000..309d950c50
--- /dev/null
+++ b/test/battle/move_effect/solar_beam.c
@@ -0,0 +1,34 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(GetMoveEffect(MOVE_SOLAR_BEAM) == EFFECT_SOLAR_BEAM);
+ ASSUME(GetMoveTwoTurnAttackWeather(MOVE_SOLAR_BLADE) == B_WEATHER_SUN);
+}
+
+SINGLE_BATTLE_TEST("Solar Beam does not need a charging turn if Sun is up")
+{
+ u32 ability;
+
+ PARAMETRIZE { ability = ABILITY_DROUGHT; }
+ PARAMETRIZE { ability = ABILITY_WHITE_SMOKE; }
+
+ GIVEN {
+ PLAYER(SPECIES_TORKOAL) { Ability(ability); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SOLAR_BEAM); }
+ if (ability == ABILITY_WHITE_SMOKE) {
+ TURN { SKIP_TURN(player); }
+ }
+ } SCENE {
+ if (ability == ABILITY_WHITE_SMOKE) {
+ MESSAGE("Torkoal used Solar Beam!");
+ MESSAGE("Torkoal absorbed light!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
+ }
+ MESSAGE("Torkoal used Solar Beam!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SOLAR_BEAM, player);
+ }
+}
diff --git a/test/battle/move_effect/sparkling_aria.c b/test/battle/move_effect/sparkling_aria.c
index 332cf8165c..86b906228b 100644
--- a/test/battle/move_effect/sparkling_aria.c
+++ b/test/battle/move_effect/sparkling_aria.c
@@ -4,8 +4,8 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffect(MOVE_SPARKLING_ARIA, MOVE_EFFECT_REMOVE_STATUS) == TRUE);
- ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].argument == STATUS1_BURN);
- ASSUME(gMovesInfo[MOVE_SPARKLING_ARIA].soundMove == TRUE);
+ ASSUME(GetMoveEffectArg_Status(MOVE_SPARKLING_ARIA) == STATUS1_BURN);
+ ASSUME(IsSoundMove(MOVE_SPARKLING_ARIA));
}
DOUBLE_BATTLE_TEST("Sparkling Aria cures burns from all Pokemon on the field and behind substitutes")
diff --git a/test/battle/move_effect/special_attack_down.c b/test/battle/move_effect/special_attack_down.c
index 60d015d1cd..63ca071fc1 100644
--- a/test/battle/move_effect/special_attack_down.c
+++ b/test/battle/move_effect/special_attack_down.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_CONFIDE) == EFFECT_SPECIAL_ATTACK_DOWN);
}
SINGLE_BATTLE_TEST("Confide lowers Special Attack", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Confide lowers Special Attack", s16 damage)
PARAMETRIZE { lowerSpecialAttack = FALSE; }
PARAMETRIZE { lowerSpecialAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/special_attack_up_3.c b/test/battle/move_effect/special_attack_up_3.c
index a701893f51..75f6c4b36d 100644
--- a/test/battle/move_effect/special_attack_up_3.c
+++ b/test/battle/move_effect/special_attack_up_3.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TAIL_GLOW].effect == EFFECT_SPECIAL_ATTACK_UP_3);
+ ASSUME(GetMoveEffect(MOVE_TAIL_GLOW) == EFFECT_SPECIAL_ATTACK_UP_3);
}
SINGLE_BATTLE_TEST("Tail Glow drastically raises Special Attack", s16 damage)
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Tail Glow drastically raises Special Attack", s16 damage)
PARAMETRIZE { raiseSpecialAttack = FALSE; }
PARAMETRIZE { raiseSpecialAttack = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/spicy_extract.c b/test/battle/move_effect/spicy_extract.c
index c9ddb3c30d..b5fe1da0f1 100644
--- a/test/battle/move_effect/spicy_extract.c
+++ b/test/battle/move_effect/spicy_extract.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SPICY_EXTRACT].effect == EFFECT_SPICY_EXTRACT);
+ ASSUME(GetMoveEffect(MOVE_SPICY_EXTRACT) == EFFECT_SPICY_EXTRACT);
}
SINGLE_BATTLE_TEST("Spicy Extract raises target's Attack by 2 stages and lowers target's Defense by 2 stages")
@@ -33,7 +33,7 @@ SINGLE_BATTLE_TEST("Spicy Extract is prevented by target's ability if it's Attac
PARAMETRIZE { ability = ABILITY_LIGHT_METAL; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWORDS_DANCE].effect == EFFECT_ATTACK_UP_2);
+ ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BELDUM) { Ability(ability); }
} WHEN {
diff --git a/test/battle/move_effect/spikes.c b/test/battle/move_effect/spikes.c
index 339a9f9a4b..187b9ce7ac 100644
--- a/test/battle/move_effect/spikes.c
+++ b/test/battle/move_effect/spikes.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SPIKES].effect == EFFECT_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_SPIKES) == EFFECT_SPIKES);
}
SINGLE_BATTLE_TEST("Spikes damage on switch in")
diff --git a/test/battle/move_effect/stealth_rock.c b/test/battle/move_effect/stealth_rock.c
index 9a38f17a5e..d4399a2d0f 100644
--- a/test/battle/move_effect/stealth_rock.c
+++ b/test/battle/move_effect/stealth_rock.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STEALTH_ROCK].effect == EFFECT_STEALTH_ROCK);
+ ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK);
}
SINGLE_BATTLE_TEST("Stealth Rock damage on switch in based on typing")
diff --git a/test/battle/move_effect/sticky_web.c b/test/battle/move_effect/sticky_web.c
index f1fff0fd1e..ed0f6e5d93 100644
--- a/test/battle/move_effect/sticky_web.c
+++ b/test/battle/move_effect/sticky_web.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STICKY_WEB].effect == EFFECT_STICKY_WEB);
+ ASSUME(GetMoveEffect(MOVE_STICKY_WEB) == EFFECT_STICKY_WEB);
}
SINGLE_BATTLE_TEST("Sticky Web lowers Speed by 1 on switch-in")
@@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Sticky Web can only be set up 1 time")
DOUBLE_BATTLE_TEST("Sticky Web lowers Speed by 1 in a double battle after Explosion fainting both mons")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXPLOSION].effect == EFFECT_EXPLOSION);
+ ASSUME(GetMoveEffect(MOVE_EXPLOSION) == EFFECT_EXPLOSION);
PLAYER(SPECIES_WOBBUFFET) {Speed(5);}
PLAYER(SPECIES_WOBBUFFET) {HP(1500); Speed(10);}
PLAYER(SPECIES_WOBBUFFET) {Speed(10);}
@@ -197,7 +197,7 @@ DOUBLE_BATTLE_TEST("Sticky Web has correct interactions with Mirror Armor - no o
PARAMETRIZE {hasReplacement = FALSE;}
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEMENTO].effect == EFFECT_MEMENTO);
+ ASSUME(GetMoveEffect(MOVE_MEMENTO) == EFFECT_MEMENTO);
PLAYER(SPECIES_SQUIRTLE) {Speed(5); }
PLAYER(SPECIES_CHARMANDER) {Speed(5); }
PLAYER(SPECIES_CORVIKNIGHT) {Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); Speed(5); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web.
@@ -271,3 +271,31 @@ SINGLE_BATTLE_TEST("Sticky Web is placed on the correct side after Memento")
MESSAGE("A sticky web has been laid out on the ground around your team!");
}
}
+
+DOUBLE_BATTLE_TEST("Sticky Web setter has their speed lowered with Mirror Armor even after Ally Switch")
+{
+ GIVEN {
+ PLAYER(SPECIES_SQUIRTLE);
+ PLAYER(SPECIES_CHARMANDER);
+ PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); Item(ITEM_IRON_BALL); } // Iron Ball, so that flying type Corviknight is affected by Sticky Web.
+ OPPONENT(SPECIES_CATERPIE);
+ OPPONENT(SPECIES_NATU);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_STICKY_WEB); }
+ TURN { MOVE(opponentRight, MOVE_ALLY_SWITCH); }
+ TURN { SWITCH(playerRight, 2); }
+ } SCENE {
+ // Turn 1 - set up sticky web
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponentLeft);
+ MESSAGE("A sticky web has been laid out on the ground around your team!");
+ // Turn 2 - ally switch
+ MESSAGE("The opposing Natu used Ally Switch!");
+ // turn 3 - send our corviknight
+ SEND_IN_MESSAGE("Corviknight");
+ MESSAGE("Corviknight was caught in a sticky web!");
+ ABILITY_POPUP(playerRight, ABILITY_MIRROR_ARMOR);
+ // sticky web setter - caterpie (now opponentRight) gets speed lowered
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
+ MESSAGE("The opposing Caterpie's Speed fell!");
+ }
+}
diff --git a/test/battle/move_effect/stockpile.c b/test/battle/move_effect/stockpile.c
index f6c3f02a46..f045fa6823 100644
--- a/test/battle/move_effect/stockpile.c
+++ b/test/battle/move_effect/stockpile.c
@@ -4,9 +4,9 @@
// These tests cover all 3 effects: Stockpile, Spit up and Swallow.
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STOCKPILE].effect == EFFECT_STOCKPILE);
- ASSUME(gMovesInfo[MOVE_SWALLOW].effect == EFFECT_SWALLOW);
- ASSUME(gMovesInfo[MOVE_SPIT_UP].effect == EFFECT_SPIT_UP);
+ ASSUME(GetMoveEffect(MOVE_STOCKPILE) == EFFECT_STOCKPILE);
+ ASSUME(GetMoveEffect(MOVE_SWALLOW) == EFFECT_SWALLOW);
+ ASSUME(GetMoveEffect(MOVE_SPIT_UP) == EFFECT_SPIT_UP);
}
SINGLE_BATTLE_TEST("Stockpile's count can go up only to 3")
@@ -148,8 +148,8 @@ SINGLE_BATTLE_TEST("Stockpile temporarily raises Def and Sp. Def", s16 dmgPyhsic
PARAMETRIZE { move = MOVE_CELEBRATE; }
GIVEN {
ASSUME(B_STOCKPILE_RAISES_DEFS >= GEN_4);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET) { Speed(2); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(1); }
} WHEN {
@@ -184,8 +184,8 @@ DOUBLE_BATTLE_TEST("Stockpile's Def and Sp. Def boost is lost after using Spit U
PARAMETRIZE { count = 3; move = MOVE_SPIT_UP; }
GIVEN {
ASSUME(B_STOCKPILE_RAISES_DEFS >= GEN_4);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_GUST].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_GUST) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET) { Speed(4); HP(399); MaxHP(400); }
PLAYER(SPECIES_WOBBUFFET) { Speed(3); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
diff --git a/test/battle/move_effect/stomping_tantrum.c b/test/battle/move_effect/stomping_tantrum.c
index 32747282e4..c759de38b1 100644
--- a/test/battle/move_effect/stomping_tantrum.c
+++ b/test/battle/move_effect/stomping_tantrum.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STOMPING_TANTRUM].effect == EFFECT_STOMPING_TANTRUM);
+ ASSUME(GetMoveEffect(MOVE_STOMPING_TANTRUM) == EFFECT_STOMPING_TANTRUM);
}
SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user flinched on the previous turn")
diff --git a/test/battle/move_effect/strength_sap.c b/test/battle/move_effect/strength_sap.c
index 0246d0881f..c38048ba8f 100644
--- a/test/battle/move_effect/strength_sap.c
+++ b/test/battle/move_effect/strength_sap.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STRENGTH_SAP].effect == EFFECT_STRENGTH_SAP);
+ ASSUME(GetMoveEffect(MOVE_STRENGTH_SAP) == EFFECT_STRENGTH_SAP);
}
SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on target's Attack Stat", s16 hp)
@@ -69,8 +69,8 @@ SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on tar
}
GIVEN {
- ASSUME(gMovesInfo[MOVE_WORK_UP].effect == EFFECT_ATTACK_SPATK_UP);
- ASSUME(gMovesInfo[MOVE_GROWL].effect == EFFECT_ATTACK_DOWN);
+ ASSUME(GetMoveEffect(MOVE_WORK_UP) == EFFECT_ATTACK_SPATK_UP);
+ ASSUME(GetMoveEffect(MOVE_GROWL) == EFFECT_ATTACK_DOWN);
PLAYER(SPECIES_WOBBUFFET) { HP(50); }
OPPONENT(SPECIES_WOBBUFFET) { Attack(60); }
} WHEN {
@@ -117,7 +117,7 @@ SINGLE_BATTLE_TEST("Strength Sap lowers Attack by 1 and restores HP based on tar
SINGLE_BATTLE_TEST("Strength Sap fails if target is at -6 Atk")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_CHARM].effect == EFFECT_ATTACK_DOWN_2);
+ ASSUME(GetMoveEffect(MOVE_CHARM) == EFFECT_ATTACK_DOWN_2);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -165,34 +165,3 @@ SINGLE_BATTLE_TEST("Strength Sap restores more HP if Big Root is held", s16 hp)
EXPECT_GT(abs(results[1].hp), abs(results[0].hp));
}
}
-
-SINGLE_BATTLE_TEST("Strength Sap makes attacker lose HP if target's ability is Liquid Ooze")
-{
- s16 lostHp;
- s32 atkStat;
-
- PARAMETRIZE { atkStat = 100; }
- PARAMETRIZE { atkStat = 490; } // Checks that attacker can faint with no problems.
-
- GIVEN {
- PLAYER(SPECIES_WOBBUFFET);
- PLAYER(SPECIES_WOBBUFFET);
- OPPONENT(SPECIES_WOBBUFFET) { Attack(atkStat); Ability(ABILITY_LIQUID_OOZE); }
- } WHEN {
- TURN { MOVE(player, MOVE_STRENGTH_SAP); if (atkStat == 490) { SEND_OUT(player, 1); } }
- } SCENE {
- MESSAGE("Wobbuffet used Strength Sap!");
- ANIMATION(ANIM_TYPE_MOVE, MOVE_STRENGTH_SAP, player);
- ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
- MESSAGE("The opposing Wobbuffet's Attack fell!");
- ABILITY_POPUP(opponent, ABILITY_LIQUID_OOZE);
- HP_BAR(player, captureDamage: &lostHp);
- MESSAGE("Wobbuffet sucked up the liquid ooze!");
- if (atkStat >= 490) {
- MESSAGE("Wobbuffet fainted!");
- SEND_IN_MESSAGE("Wobbuffet");
- }
- } THEN {
- EXPECT_EQ(lostHp, atkStat);
- }
-}
diff --git a/test/battle/move_effect/stuff_cheeks.c b/test/battle/move_effect/stuff_cheeks.c
index 3bb3f22925..9e6a34c306 100644
--- a/test/battle/move_effect/stuff_cheeks.c
+++ b/test/battle/move_effect/stuff_cheeks.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_STUFF_CHEEKS].effect == EFFECT_STUFF_CHEEKS);
+ ASSUME(GetMoveEffect(MOVE_STUFF_CHEEKS) == EFFECT_STUFF_CHEEKS);
ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].pocket == POCKET_BERRIES);
ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP);
}
@@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("Stuff Cheeks can be used even if Magic Room is active")
SINGLE_BATTLE_TEST("Stuff Cheeks fails if the user's berry is removed before they use the move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_KNOCK_OFF].effect == EFFECT_KNOCK_OFF);
+ ASSUME(GetMoveEffect(MOVE_KNOCK_OFF) == EFFECT_KNOCK_OFF);
PLAYER(SPECIES_SKWOVET) { Item(ITEM_LIECHI_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/substitute.c b/test/battle/move_effect/substitute.c
index 92e894fa07..e94767b660 100644
--- a/test/battle/move_effect/substitute.c
+++ b/test/battle/move_effect/substitute.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
+ ASSUME(GetMoveEffect(MOVE_SUBSTITUTE) == EFFECT_SUBSTITUTE);
}
SINGLE_BATTLE_TEST("Substitute creates a Substitute at the cost of 1/4 users maximum HP")
diff --git a/test/battle/move_effect/super_effective_on_arg.c b/test/battle/move_effect/super_effective_on_arg.c
index d10b8a2231..2569ccb109 100644
--- a/test/battle/move_effect/super_effective_on_arg.c
+++ b/test/battle/move_effect/super_effective_on_arg.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_FREEZE_DRY].effect == EFFECT_SUPER_EFFECTIVE_ON_ARG);
+ ASSUME(GetMoveEffect(MOVE_FREEZE_DRY) == EFFECT_SUPER_EFFECTIVE_ON_ARG);
}
SINGLE_BATTLE_TEST("Freeze Dry is super effective on water types")
diff --git a/test/battle/move_effect/synthesis.c b/test/battle/move_effect/synthesis.c
index e4a2b77869..6799bd2870 100644
--- a/test/battle/move_effect/synthesis.c
+++ b/test/battle/move_effect/synthesis.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SYNTHESIS].effect == EFFECT_SYNTHESIS);
+ ASSUME(GetMoveEffect(MOVE_SYNTHESIS) == EFFECT_SYNTHESIS);
}
SINGLE_BATTLE_TEST("Synthesis recovers 1/2 of the user's max HP")
diff --git a/test/battle/move_effect/tailwind.c b/test/battle/move_effect/tailwind.c
index 5fa5356451..f105c9612a 100644
--- a/test/battle/move_effect/tailwind.c
+++ b/test/battle/move_effect/tailwind.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND);
+ ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND);
}
SINGLE_BATTLE_TEST("Tailwind applies for 4 turns")
diff --git a/test/battle/move_effect/take_heart.c b/test/battle/move_effect/take_heart.c
index 081815cfb8..e029439103 100644
--- a/test/battle/move_effect/take_heart.c
+++ b/test/battle/move_effect/take_heart.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TAKE_HEART].effect == EFFECT_TAKE_HEART);
+ ASSUME(GetMoveEffect(MOVE_TAKE_HEART) == EFFECT_TAKE_HEART);
}
SINGLE_BATTLE_TEST("Take Heart increases Sp. Atk and Sp. Def by one stage")
@@ -40,8 +40,32 @@ SINGLE_BATTLE_TEST("Take Heart cures the user of all status conditions")
STATUS_ICON(player, none: TRUE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
} else {
+ STATUS_ICON(player, none: TRUE);
MESSAGE("Wobbuffet's status returned to normal!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
}
}
}
+
+SINGLE_BATTLE_TEST("Take Heart cures sleep when used by Sleep Talk")
+{
+ GIVEN {
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_TAKE_HEART); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); }
+ } SCENE {
+ MESSAGE("Wobbuffet used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ MESSAGE("The opposing Wobbuffet used Sleep Talk!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent);
+ MESSAGE("The opposing Wobbuffet used Take Heart!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TAKE_HEART, opponent);
+ STATUS_ICON(opponent, none: TRUE);
+ MESSAGE("The opposing Wobbuffet's status returned to normal!");
+ }
+}
diff --git a/test/battle/move_effect/tar_shot.c b/test/battle/move_effect/tar_shot.c
index 2b780577ec..f2aac4e552 100644
--- a/test/battle/move_effect/tar_shot.c
+++ b/test/battle/move_effect/tar_shot.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TAR_SHOT].effect == EFFECT_TAR_SHOT);
+ ASSUME(GetMoveEffect(MOVE_TAR_SHOT) == EFFECT_TAR_SHOT);
}
SINGLE_BATTLE_TEST("Tar Shot doubles the effectiveness of Fire-type moves used on the target")
@@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Tar Shot doubles the effectiveness of Fire-type moves used o
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[1] == TYPE_PSYCHIC);
ASSUME(gSpeciesInfo[SPECIES_OMASTAR].types[0] == TYPE_ROCK);
ASSUME(gSpeciesInfo[SPECIES_OMASTAR].types[1] == TYPE_WATER);
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effect/teatime.c b/test/battle/move_effect/teatime.c
index dfdc70c801..fc4ad22198 100644
--- a/test/battle/move_effect/teatime.c
+++ b/test/battle/move_effect/teatime.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TEATIME].effect == EFFECT_TEATIME);
+ ASSUME(GetMoveEffect(MOVE_TEATIME) == EFFECT_TEATIME);
ASSUME(gItemsInfo[ITEM_LIECHI_BERRY].holdEffect == HOLD_EFFECT_ATTACK_UP);
}
diff --git a/test/battle/move_effect/telekinesis.c b/test/battle/move_effect/telekinesis.c
index 746c42d053..31390d9733 100644
--- a/test/battle/move_effect/telekinesis.c
+++ b/test/battle/move_effect/telekinesis.c
@@ -3,14 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TELEKINESIS].effect == EFFECT_TELEKINESIS);
+ ASSUME(GetMoveEffect(MOVE_TELEKINESIS) == EFFECT_TELEKINESIS);
}
SINGLE_BATTLE_TEST("Telekinesis makes the target unable to avoid any attacks made against it")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MINIMIZE].effect == EFFECT_MINIMIZE); // Raises evs by 2
- ASSUME(gMovesInfo[MOVE_SCREECH].accuracy < 100);
+ ASSUME(GetMoveEffect(MOVE_MINIMIZE) == EFFECT_MINIMIZE); // Raises evs by 2
+ ASSUME(GetMoveAccuracy(MOVE_SCREECH) < 100);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
@@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Telekinesis ends after 3 turns")
SINGLE_BATTLE_TEST("Telekinesis makes the target immune to Ground-type attacks")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BULLDOZE].type == TYPE_GROUND);
+ ASSUME(GetMoveType(MOVE_BULLDOZE) == TYPE_GROUND);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
diff --git a/test/battle/move_effect/teleport.c b/test/battle/move_effect/teleport.c
index 3c79cb54ff..f77dffc658 100644
--- a/test/battle/move_effect/teleport.c
+++ b/test/battle/move_effect/teleport.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TELEPORT].effect == EFFECT_TELEPORT);
+ ASSUME(GetMoveEffect(MOVE_TELEPORT) == EFFECT_TELEPORT);
}
SINGLE_BATTLE_TEST("Teleport fails when there is no pokemon to switch in")
diff --git a/test/battle/move_effect/tera_blast.c b/test/battle/move_effect/tera_blast.c
index 80e960a1af..63e7a776b9 100644
--- a/test/battle/move_effect/tera_blast.c
+++ b/test/battle/move_effect/tera_blast.c
@@ -3,13 +3,13 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST);
+ ASSUME(GetMoveEffect(MOVE_TERA_BLAST) == EFFECT_TERA_BLAST);
}
SINGLE_BATTLE_TEST("Tera Blast changes from Normal-type to the user's Tera Type")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TERA_BLAST].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TERA_BLAST) == TYPE_NORMAL);
PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_DARK); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effect/tera_starstorm.c b/test/battle/move_effect/tera_starstorm.c
index b6b4571644..3077b38df9 100644
--- a/test/battle/move_effect/tera_starstorm.c
+++ b/test/battle/move_effect/tera_starstorm.c
@@ -3,13 +3,13 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].effect == EFFECT_TERA_STARSTORM);
+ ASSUME(GetMoveEffect(MOVE_TERA_STARSTORM) == EFFECT_TERA_STARSTORM);
}
SINGLE_BATTLE_TEST("Tera Starstorm changes from Normal-type to Stellar-type if used by Terapagos-Stellar")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TERA_STARSTORM) == TYPE_NORMAL);
PLAYER(SPECIES_TERAPAGOS_STELLAR);
OPPONENT(SPECIES_MISDREAVUS);
} WHEN {
@@ -25,7 +25,7 @@ SINGLE_BATTLE_TEST("Tera Starstorm changes from Normal-type to Stellar-type if u
DOUBLE_BATTLE_TEST("Tera Starstorm targets both opponents in a double battle if used by Terapagos-Stellar")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].target == MOVE_TARGET_SELECTED);
+ ASSUME(GetMoveTarget(MOVE_TERA_STARSTORM) == MOVE_TARGET_SELECTED);
PLAYER(SPECIES_TERAPAGOS_STELLAR);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_WOBBUFFET);
@@ -46,7 +46,7 @@ SINGLE_BATTLE_TEST("Tera Starstorm becomes a physical move if the user is Terapa
PARAMETRIZE { tera = GIMMICK_NONE; }
PARAMETRIZE { tera = GIMMICK_TERA; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_TERA_STARSTORM) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_TERAPAGOS_STELLAR) { Attack(100); SpAttack(50); }
OPPONENT(SPECIES_WOBBUFFET) { Defense(200); SpDefense(200); }
} WHEN {
@@ -63,7 +63,7 @@ SINGLE_BATTLE_TEST("Tera Starstorm becomes a physical move if the user is Terapa
SINGLE_BATTLE_TEST("Tera Starstorm remains Normal-type if used by Pokemon other than Terapagos")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_TERA_STARSTORM].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_TERA_STARSTORM) == TYPE_NORMAL);
ASSUME(gSpeciesInfo[SPECIES_MISDREAVUS].types[0] == TYPE_GHOST);
PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); }
OPPONENT(SPECIES_MISDREAVUS);
diff --git a/test/battle/move_effect/thousand_arrows.c b/test/battle/move_effect/thousand_arrows.c
index 09e726fa20..c62e71001d 100644
--- a/test/battle/move_effect/thousand_arrows.c
+++ b/test/battle/move_effect/thousand_arrows.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(MoveHasAdditionalEffect(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN) == TRUE);
- ASSUME(gMovesInfo[MOVE_THOUSAND_ARROWS].ignoreTypeIfFlyingAndUngrounded == TRUE);
+ ASSUME(MoveHasAdditionalEffect(MOVE_THOUSAND_ARROWS, MOVE_EFFECT_SMACK_DOWN));
+ ASSUME(MoveIgnoresTypeIfFlyingAndUngrounded(MOVE_THOUSAND_ARROWS) == TRUE);
}
SINGLE_BATTLE_TEST("Thousand Arrows does not ground mons behind substitutes")
diff --git a/test/battle/move_effect/thunder.c b/test/battle/move_effect/thunder.c
index 98a4979e79..81ebd416ca 100644
--- a/test/battle/move_effect/thunder.c
+++ b/test/battle/move_effect/thunder.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_THUNDER].effect == EFFECT_THUNDER);
- ASSUME(gMovesInfo[MOVE_THUNDER].accuracy == 70);
+ ASSUME(GetMoveEffect(MOVE_THUNDER) == EFFECT_THUNDER);
+ ASSUME(GetMoveAccuracy(MOVE_THUNDER) == 70);
}
SINGLE_BATTLE_TEST("Thunder's accuracy is lowered to 50% in Sunlight")
diff --git a/test/battle/move_effect/tidy_up.c b/test/battle/move_effect/tidy_up.c
index 986e9a2ba3..9c934ab213 100644
--- a/test/battle/move_effect/tidy_up.c
+++ b/test/battle/move_effect/tidy_up.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TIDY_UP].effect == EFFECT_TIDY_UP);
+ ASSUME(GetMoveEffect(MOVE_TIDY_UP) == EFFECT_TIDY_UP);
}
SINGLE_BATTLE_TEST("Tidy Up raises Attack and Speed by one")
@@ -99,3 +99,24 @@ AI_SINGLE_BATTLE_TEST("AI will try to remove hazards if slower then target even
TURN { EXPECT_MOVE(opponent, MOVE_TIDY_UP); }
}
}
+
+SINGLE_BATTLE_TEST("Tidy Up raises Attack and Speed by one after clearing hazards on opposing field")
+{
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_STEALTH_ROCK); }
+ TURN { MOVE(player, MOVE_TIDY_UP); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, player);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TIDY_UP, player);
+ MESSAGE("Tidying up complete!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
+ MESSAGE("Wobbuffet's Attack rose!");
+ MESSAGE("Wobbuffet's Speed rose!");
+ } THEN {
+ EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1);
+ EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1);
+ }
+}
diff --git a/test/battle/move_effect/torment.c b/test/battle/move_effect/torment.c
index dc911691b0..446d168de2 100644
--- a/test/battle/move_effect/torment.c
+++ b/test/battle/move_effect/torment.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT);
+ ASSUME(GetMoveEffect(MOVE_TORMENT) == EFFECT_TORMENT);
}
SINGLE_BATTLE_TEST("Torment prevents consecutive move uses")
diff --git a/test/battle/move_effect/toxic.c b/test/battle/move_effect/toxic.c
index 804ed56b8f..7b8274a441 100644
--- a/test/battle/move_effect/toxic.c
+++ b/test/battle/move_effect/toxic.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC);
+ ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_TOXIC);
}
SINGLE_BATTLE_TEST("Toxic inflicts bad poison")
diff --git a/test/battle/move_effect/toxic_spikes.c b/test/battle/move_effect/toxic_spikes.c
index fd18f57b97..70053b4a44 100644
--- a/test/battle/move_effect/toxic_spikes.c
+++ b/test/battle/move_effect/toxic_spikes.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TOXIC_SPIKES].effect == EFFECT_TOXIC_SPIKES);
+ ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
}
SINGLE_BATTLE_TEST("Toxic Spikes inflicts poison on switch in")
@@ -212,7 +212,7 @@ SINGLE_BATTLE_TEST("Toxic Spikes are removed by Poison-type Pokémon affected by
SINGLE_BATTLE_TEST("Toxic Spikes inflicts poison on switch in after Primal Reversed mon fainted") // Oddly specific, but encountered during testing
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_MEMENTO].effect == EFFECT_MEMENTO); // Faints the user.
+ ASSUME(GetMoveEffect(MOVE_MEMENTO) == EFFECT_MEMENTO); // Faints the user.
PLAYER(SPECIES_WOBBUFFET) {Speed(5); }
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); Speed(1); }
PLAYER(SPECIES_WYNAUT) {Speed(5); }
diff --git a/test/battle/move_effect/triple_kick.c b/test/battle/move_effect/triple_kick.c
index 9fe0ec6022..5aeb1ea442 100644
--- a/test/battle/move_effect/triple_kick.c
+++ b/test/battle/move_effect/triple_kick.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_TRIPLE_KICK].effect == EFFECT_TRIPLE_KICK);
+ ASSUME(GetMoveEffect(MOVE_TRIPLE_KICK) == EFFECT_TRIPLE_KICK);
}
SINGLE_BATTLE_TEST("Triple Kick damage is increased by its base damage for each hit")
diff --git a/test/battle/move_effect/two_turns_attack.c b/test/battle/move_effect/two_turns_attack.c
index efeb419ce5..200fc72d18 100644
--- a/test/battle/move_effect/two_turns_attack.c
+++ b/test/battle/move_effect/two_turns_attack.c
@@ -3,20 +3,14 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_RAZOR_WIND].effect == EFFECT_TWO_TURNS_ATTACK);
- ASSUME(gMovesInfo[MOVE_SKULL_BASH].effect == EFFECT_TWO_TURNS_ATTACK);
+ ASSUME(GetMoveEffect(MOVE_RAZOR_WIND) == EFFECT_TWO_TURNS_ATTACK);
+ ASSUME(GetMoveEffect(MOVE_SKULL_BASH) == EFFECT_TWO_TURNS_ATTACK);
ASSUME(MoveHasAdditionalEffectSelf(MOVE_SKULL_BASH, MOVE_EFFECT_DEF_PLUS_1) == TRUE);
- ASSUME(gMovesInfo[MOVE_SKY_ATTACK].effect == EFFECT_TWO_TURNS_ATTACK);
-
- // Solar Beam - check for sun
- ASSUME(gMovesInfo[MOVE_SOLAR_BEAM].effect == EFFECT_SOLAR_BEAM);
- ASSUME(HIHALF(gMovesInfo[MOVE_SOLAR_BLADE].argument) == B_WEATHER_SUN);
- ASSUME(gMovesInfo[MOVE_SOLAR_BLADE].effect == EFFECT_SOLAR_BEAM);
- ASSUME(HIHALF(gMovesInfo[MOVE_SOLAR_BLADE].argument) == B_WEATHER_SUN);
+ ASSUME(GetMoveEffect(MOVE_SKY_ATTACK) == EFFECT_TWO_TURNS_ATTACK);
// Electro shot - check for rain
- ASSUME(HIHALF(gMovesInfo[MOVE_ELECTRO_SHOT].argument) == B_WEATHER_RAIN);
- ASSUME(gMovesInfo[MOVE_ELECTRO_SHOT].effect == EFFECT_TWO_TURNS_ATTACK);
+ ASSUME(GetMoveTwoTurnAttackWeather(MOVE_ELECTRO_SHOT) == B_WEATHER_RAIN);
+ ASSUME(GetMoveEffect(MOVE_ELECTRO_SHOT) == EFFECT_TWO_TURNS_ATTACK);
ASSUME(MoveHasAdditionalEffectSelf(MOVE_ELECTRO_SHOT, MOVE_EFFECT_SP_ATK_PLUS_1) == TRUE);
}
diff --git a/test/battle/move_effect/upper_hand.c b/test/battle/move_effect/upper_hand.c
index 69b2b75ef9..72a80a0542 100644
--- a/test/battle/move_effect/upper_hand.c
+++ b/test/battle/move_effect/upper_hand.c
@@ -3,16 +3,16 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_UPPER_HAND].effect == EFFECT_UPPER_HAND);
- ASSUME(gMovesInfo[MOVE_UPPER_HAND].priority == 3);
+ ASSUME(GetMoveEffect(MOVE_UPPER_HAND) == EFFECT_UPPER_HAND);
+ ASSUME(GetMovePriority(MOVE_UPPER_HAND) == 3);
ASSUME(MoveHasAdditionalEffect(MOVE_UPPER_HAND, MOVE_EFFECT_FLINCH) == TRUE);
}
SINGLE_BATTLE_TEST("Upper Hand succeeds if the target is using a priority attacking move and causes it to flinch")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].priority == 2);
+ ASSUME(GetMoveCategory(MOVE_EXTREME_SPEED) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMovePriority(MOVE_EXTREME_SPEED) == 2);
PLAYER(SPECIES_MIENSHAO);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -28,8 +28,8 @@ SINGLE_BATTLE_TEST("Upper Hand succeeds if the target is using a priority attack
SINGLE_BATTLE_TEST("Upper Hand fails if the target is using a status move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_BABY_DOLL_EYES].category == DAMAGE_CATEGORY_STATUS);
- ASSUME(gMovesInfo[MOVE_BABY_DOLL_EYES].priority == 1);
+ ASSUME(GetMoveCategory(MOVE_BABY_DOLL_EYES) == DAMAGE_CATEGORY_STATUS);
+ ASSUME(GetMovePriority(MOVE_BABY_DOLL_EYES) == 1);
PLAYER(SPECIES_MIENSHAO);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -47,8 +47,8 @@ SINGLE_BATTLE_TEST("Upper Hand fails if the target is using a status move")
SINGLE_BATTLE_TEST("Upper Hand fails if the target is not using a priority move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAINING_KISS].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_DRAINING_KISS].priority == 0);
+ ASSUME(GetMoveCategory(MOVE_DRAINING_KISS) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMovePriority(MOVE_DRAINING_KISS) == 0);
PLAYER(SPECIES_MIENSHAO);
OPPONENT(SPECIES_COMFEY) { Ability(ABILITY_FLOWER_VEIL); }
} WHEN {
@@ -66,8 +66,8 @@ SINGLE_BATTLE_TEST("Upper Hand fails if the target is not using a priority move"
SINGLE_BATTLE_TEST("Upper Hand succeeds if the target's move is boosted in priority by an Ability")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAINING_KISS].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_DRAINING_KISS].priority == 0);
+ ASSUME(GetMoveCategory(MOVE_DRAINING_KISS) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMovePriority(MOVE_DRAINING_KISS) == 0);
PLAYER(SPECIES_MIENSHAO) { Speed(10); }
OPPONENT(SPECIES_COMFEY) { Speed(5); Ability(ABILITY_TRIAGE); }
} WHEN {
@@ -83,8 +83,8 @@ SINGLE_BATTLE_TEST("Upper Hand succeeds if the target's move is boosted in prior
SINGLE_BATTLE_TEST("Upper Hand fails if the target moves first")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DRAINING_KISS].category == DAMAGE_CATEGORY_SPECIAL);
- ASSUME(gMovesInfo[MOVE_DRAINING_KISS].priority == 0);
+ ASSUME(GetMoveCategory(MOVE_DRAINING_KISS) == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMovePriority(MOVE_DRAINING_KISS) == 0);
PLAYER(SPECIES_MIENSHAO) { Speed(5); }
OPPONENT(SPECIES_COMFEY) { Speed(10); Ability(ABILITY_TRIAGE); }
} WHEN {
@@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Upper Hand fails if the target moves first")
SINGLE_BATTLE_TEST("Upper Hand is boosted by Sheer Force")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].category == DAMAGE_CATEGORY_PHYSICAL);
- ASSUME(gMovesInfo[MOVE_EXTREME_SPEED].priority == 2);
+ ASSUME(GetMoveCategory(MOVE_EXTREME_SPEED) == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMovePriority(MOVE_EXTREME_SPEED) == 2);
ASSUME(MoveIsAffectedBySheerForce(MOVE_UPPER_HAND) == TRUE);
PLAYER(SPECIES_HARIYAMA) { Ability(ABILITY_SHEER_FORCE); }
OPPONENT(SPECIES_WOBBUFFET);
@@ -124,7 +124,7 @@ AI_SINGLE_BATTLE_TEST("AI won't use Upper Hand unless it has seen a priority mov
PARAMETRIZE { move = MOVE_QUICK_ATTACK; }
GIVEN {
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
- ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
+ ASSUME(GetMovePriority(MOVE_QUICK_ATTACK) == 1);
PLAYER(SPECIES_WOBBUFFET) {Moves(move); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_UPPER_HAND, MOVE_KARATE_CHOP); }
} WHEN {
diff --git a/test/battle/move_effect/uproar.c b/test/battle/move_effect/uproar.c
index a97422390f..cbe17ce066 100644
--- a/test/battle/move_effect/uproar.c
+++ b/test/battle/move_effect/uproar.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_UPROAR].effect == EFFECT_UPROAR);
+ ASSUME(GetMoveEffect(MOVE_UPROAR) == EFFECT_UPROAR);
}
DOUBLE_BATTLE_TEST("Uproar status causes sleeping pokemon to wake up during an attack")
diff --git a/test/battle/move_effect/wake_up_slap.c b/test/battle/move_effect/wake_up_slap.c
index 0a881be100..0e172bf053 100644
--- a/test/battle/move_effect/wake_up_slap.c
+++ b/test/battle/move_effect/wake_up_slap.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffect(MOVE_WAKE_UP_SLAP, MOVE_EFFECT_REMOVE_STATUS) == TRUE);
- ASSUME(gMovesInfo[MOVE_WAKE_UP_SLAP].argument == STATUS1_SLEEP);
+ ASSUME(GetMoveEffectArg_Status(MOVE_WAKE_UP_SLAP) == STATUS1_SLEEP);
}
SINGLE_BATTLE_TEST("Wake-Up Slap does not cure paralyzed pokemons behind substitutes or get increased power")
diff --git a/test/battle/move_effect/weather_ball.c b/test/battle/move_effect/weather_ball.c
index 432e5f79f7..0474383483 100644
--- a/test/battle/move_effect/weather_ball.c
+++ b/test/battle/move_effect/weather_ball.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL);
+ ASSUME(GetMoveEffect(MOVE_WEATHER_BALL) == EFFECT_WEATHER_BALL);
}
SINGLE_BATTLE_TEST("Weather Ball doubles its power and turns to a Fire-type move in Sunlight", s16 damage)
diff --git a/test/battle/move_effect/worry_seed.c b/test/battle/move_effect/worry_seed.c
index 3e74c883e7..c4b18b7cab 100644
--- a/test/battle/move_effect/worry_seed.c
+++ b/test/battle/move_effect/worry_seed.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_WORRY_SEED].effect == EFFECT_WORRY_SEED);
+ ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_WORRY_SEED);
}
SINGLE_BATTLE_TEST("Worry Seed replaces target's ability with Insomnia")
diff --git a/test/battle/move_effect_secondary/bug_bite.c b/test/battle/move_effect_secondary/bug_bite.c
index a55f7f9a2f..e086941a5e 100644
--- a/test/battle/move_effect_secondary/bug_bite.c
+++ b/test/battle/move_effect_secondary/bug_bite.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
- ASSUME(gMovesInfo[MOVE_BUG_BITE].pp == 20);
+ ASSUME(GetMovePP(MOVE_BUG_BITE) == 20);
}
// Pretty much copy/paste of the Berry Fling Test.
@@ -126,10 +126,9 @@ SINGLE_BATTLE_TEST("Tanga Berry activates before Bug Bite")
} SCENE {
MESSAGE("Wobbuffet used Bug Bite!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
- MESSAGE("The opposing Wobbuffet ate its Tanga Berry!");
+ MESSAGE("The Tanga Berry weakened the damage to the opposing Wobbuffet!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_BUG_BITE, player);
HP_BAR(opponent);
- MESSAGE("The Tanga Berry weakened the damage to the opposing Wobbuffet!");
} THEN {
EXPECT_EQ(player->item, ITEM_NONE);
}
diff --git a/test/battle/move_effect_secondary/burn.c b/test/battle/move_effect_secondary/burn.c
index 1b6843715c..0bc979f08e 100644
--- a/test/battle/move_effect_secondary/burn.c
+++ b/test/battle/move_effect_secondary/burn.c
@@ -43,7 +43,7 @@ DOUBLE_BATTLE_TEST("Lava Plume inflicts burn to all adjacent battlers")
{
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_LAVA_PLUME, MOVE_EFFECT_BURN) == TRUE);
- ASSUME(gMovesInfo[MOVE_LAVA_PLUME].target == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveTarget(MOVE_LAVA_PLUME) == MOVE_TARGET_FOES_AND_ALLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
@@ -53,12 +53,12 @@ DOUBLE_BATTLE_TEST("Lava Plume inflicts burn to all adjacent battlers")
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_LAVA_PLUME, playerLeft);
HP_BAR(opponentLeft);
+ HP_BAR(playerRight);
+ HP_BAR(opponentRight);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentLeft);
STATUS_ICON(opponentLeft, burn: TRUE);
- HP_BAR(playerRight);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, playerRight);
STATUS_ICON(playerRight, burn: TRUE);
- HP_BAR(opponentRight);
STATUS_ICON(opponentRight, burn: TRUE);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentRight);
}
@@ -94,9 +94,9 @@ DOUBLE_BATTLE_TEST("Matcha Gatcha can burn both targets")
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MATCHA_GOTCHA, playerLeft);
HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentLeft);
STATUS_ICON(opponentLeft, burn: TRUE);
- HP_BAR(opponentRight);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponentRight);
STATUS_ICON(opponentRight, burn: TRUE);
}
@@ -111,7 +111,7 @@ SINGLE_BATTLE_TEST("Scald shouldn't burn a Water-type Pokémon")
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_SQUIRTLE].types[0] == TYPE_WATER);
ASSUME(MoveHasAdditionalEffect(MOVE_SCALD, MOVE_EFFECT_BURN) == TRUE);
- ASSUME(gMovesInfo[MOVE_SCALD].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_SCALD) == TYPE_WATER);
PLAYER(SPECIES_SQUIRTLE);
OPPONENT(SPECIES_SQUIRTLE);
} WHEN {
diff --git a/test/battle/move_effect_secondary/freeze.c b/test/battle/move_effect_secondary/freeze.c
index 45005cf5d7..bfaadcebe1 100644
--- a/test/battle/move_effect_secondary/freeze.c
+++ b/test/battle/move_effect_secondary/freeze.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
- ASSUME(gMovesInfo[MOVE_BLIZZARD].accuracy == 70);
+ ASSUME(GetMoveAccuracy(MOVE_BLIZZARD) == 70);
}
#if B_USE_FROSTBITE == TRUE
@@ -92,7 +92,7 @@ SINGLE_BATTLE_TEST("Freezing Glare shouldn't freeze Psychic-types")
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_ARTICUNO_GALAR].types[0] == TYPE_PSYCHIC);
ASSUME(MoveHasAdditionalEffect(MOVE_FREEZING_GLARE, MOVE_EFFECT_FREEZE_OR_FROSTBITE) == TRUE);
- ASSUME(gMovesInfo[MOVE_FREEZING_GLARE].type == TYPE_PSYCHIC);
+ ASSUME(GetMoveType(MOVE_FREEZING_GLARE) == TYPE_PSYCHIC);
PLAYER(SPECIES_ARTICUNO_GALAR);
OPPONENT(SPECIES_ARTICUNO_GALAR);
} WHEN {
diff --git a/test/battle/move_effect_secondary/haze.c b/test/battle/move_effect_secondary/haze.c
new file mode 100644
index 0000000000..c3831f0768
--- /dev/null
+++ b/test/battle/move_effect_secondary/haze.c
@@ -0,0 +1,32 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(MoveHasAdditionalEffect(MOVE_FREEZY_FROST, MOVE_EFFECT_HAZE) == TRUE);
+}
+
+SINGLE_BATTLE_TEST("Freeze Frost restores stat changes when it was succesful")
+{
+ bool32 moveSuccess;
+ PARAMETRIZE { moveSuccess = FALSE; }
+ PARAMETRIZE { moveSuccess = TRUE; }
+
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_FREEZY_FROST, hit: moveSuccess); }
+ } SCENE {
+ if (moveSuccess == TRUE)
+ {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FREEZY_FROST, player);
+ MESSAGE("All stat changes were eliminated!");
+ } else {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FREEZY_FROST, player);
+ MESSAGE("All stat changes were eliminated!");
+ }
+ }
+ }
+}
diff --git a/test/battle/move_effect/plasma_fists.c b/test/battle/move_effect_secondary/ion_deluge.c
similarity index 79%
rename from test/battle/move_effect/plasma_fists.c
rename to test/battle/move_effect_secondary/ion_deluge.c
index 93c8869026..e5bf7c0810 100644
--- a/test/battle/move_effect/plasma_fists.c
+++ b/test/battle/move_effect_secondary/ion_deluge.c
@@ -3,13 +3,13 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_PLASMA_FISTS].effect == EFFECT_PLASMA_FISTS);
+ ASSUME(MoveHasAdditionalEffect(MOVE_PLASMA_FISTS, MOVE_EFFECT_ION_DELUGE) == TRUE);
}
SINGLE_BATTLE_TEST("Ion Duldge turns normal moves into electric for the remainder of the current turn")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ION_DELUGE].effect == EFFECT_ION_DELUGE);
+ ASSUME(GetMoveEffect(MOVE_ION_DELUGE) == EFFECT_ION_DELUGE);
PLAYER(SPECIES_KRABBY);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -47,6 +47,26 @@ SINGLE_BATTLE_TEST("Plasma Fists turns normal moves into electric for the remain
}
}
+SINGLE_BATTLE_TEST("Plasma Fists does not set up Ion Deluge if it does not connect")
+{
+ GIVEN {
+ ASSUME(gSpeciesInfo[SPECIES_PHANPY].types[0] == TYPE_GROUND || gSpeciesInfo[SPECIES_PHANPY].types[1] == TYPE_GROUND);
+ PLAYER(SPECIES_KRABBY);
+ OPPONENT(SPECIES_PHANPY);
+ } WHEN {
+ TURN { MOVE(player, MOVE_PLASMA_FISTS); MOVE(opponent, MOVE_TACKLE); }
+ } SCENE {
+ MESSAGE("Krabby used Plasma Fists!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PLASMA_FISTS, player);
+ MESSAGE("A deluge of ions showers the battlefield!");
+ }
+ MESSAGE("The opposing Phanpy used Tackle!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
+ NOT MESSAGE("It's super effective!");
+ }
+}
+
SINGLE_BATTLE_TEST("Plasma Fists type-changing effect does not override Pixilate")
{
GIVEN {
diff --git a/test/battle/move_effect_secondary/leech_seed.c b/test/battle/move_effect_secondary/leech_seed.c
new file mode 100644
index 0000000000..c5a8db57cc
--- /dev/null
+++ b/test/battle/move_effect_secondary/leech_seed.c
@@ -0,0 +1,37 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(MoveHasAdditionalEffect(MOVE_SAPPY_SEED, MOVE_EFFECT_LEECH_SEED) == TRUE);
+}
+
+SINGLE_BATTLE_TEST("Sappy Seed can seed the target")
+{
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SAPPY_SEED); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player);
+ MESSAGE("The opposing Wobbuffet was seeded!");
+ MESSAGE("The opposing Wobbuffet's health is sapped by Leech Seed!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sappy Seed is not going to seed the target if it fails")
+{
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SAPPY_SEED, hit: FALSE); }
+ } SCENE {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SAPPY_SEED, player);
+ MESSAGE("The opposing Wobbuffet was seeded!");
+ MESSAGE("The opposing Wobbuffet's health is sapped by Leech Seed!");
+ }
+ }
+}
diff --git a/test/battle/move_effect_secondary/light_screen.c b/test/battle/move_effect_secondary/light_screen.c
new file mode 100644
index 0000000000..244e469893
--- /dev/null
+++ b/test/battle/move_effect_secondary/light_screen.c
@@ -0,0 +1,32 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(MoveHasAdditionalEffect(MOVE_GLITZY_GLOW, MOVE_EFFECT_LIGHT_SCREEN) == TRUE);
+}
+
+SINGLE_BATTLE_TEST("Glitzy Glow sets up Light Screen when it was succesful")
+{
+ bool32 moveSuccess;
+ PARAMETRIZE { moveSuccess = FALSE; }
+ PARAMETRIZE { moveSuccess = TRUE; }
+
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_GLITZY_GLOW, hit: moveSuccess); }
+ } SCENE {
+ if (moveSuccess == TRUE)
+ {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_GLITZY_GLOW, player);
+ MESSAGE("Light Screen made your team stronger against special moves!");
+ } else {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_GLITZY_GLOW, player);
+ MESSAGE("Light Screen made your team stronger against special moves!");
+ }
+ }
+ }
+}
diff --git a/test/battle/move_effect_secondary/order_up.c b/test/battle/move_effect_secondary/order_up.c
index 8d286850a2..ec6f1c51b5 100644
--- a/test/battle/move_effect_secondary/order_up.c
+++ b/test/battle/move_effect_secondary/order_up.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_ORDER_UP].additionalEffects[0].moveEffect == MOVE_EFFECT_ORDER_UP);
+ ASSUME(GetMoveAdditionalEffectById(MOVE_ORDER_UP, 0)->moveEffect == MOVE_EFFECT_ORDER_UP);
}
DOUBLE_BATTLE_TEST("Order Up increases a stat based on Tatsugiri's form")
@@ -123,7 +123,7 @@ DOUBLE_BATTLE_TEST("Order up does not boosts any stats if Dondozo is not affecte
DOUBLE_BATTLE_TEST("Order Up is boosted by Sheer Force without removing the stat boosting effect")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
+ ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT);
PLAYER(SPECIES_DONDOZO) { Speed(10); }
PLAYER(SPECIES_TATSUGIRI_CURLY) { Speed(9); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(8); }
@@ -146,8 +146,8 @@ DOUBLE_BATTLE_TEST("Order Up is always boosted by Sheer Force", s16 damage)
PARAMETRIZE(move = MOVE_ENTRAINMENT, ability = ABILITY_COMMANDER);
GIVEN {
- ASSUME(gMovesInfo[MOVE_HAZE].effect == EFFECT_HAZE);
- ASSUME(gMovesInfo[MOVE_ENTRAINMENT].effect == EFFECT_ENTRAINMENT);
+ ASSUME(GetMoveEffect(MOVE_HAZE) == EFFECT_HAZE);
+ ASSUME(GetMoveEffect(MOVE_ENTRAINMENT) == EFFECT_ENTRAINMENT);
PLAYER(SPECIES_DONDOZO) { Speed(10); }
PLAYER(SPECIES_TATSUGIRI_CURLY) { Speed(9); Ability(ability); }
OPPONENT(SPECIES_TAUROS) { Speed(21); Ability(ABILITY_SHEER_FORCE); }
diff --git a/test/battle/move_effect_secondary/paralysis.c b/test/battle/move_effect_secondary/paralysis.c
index 0e9d9589a8..711ca11ee8 100644
--- a/test/battle/move_effect_secondary/paralysis.c
+++ b/test/battle/move_effect_secondary/paralysis.c
@@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Body Slam shouldn't paralyze Normal-types")
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_TAUROS].types[0] == TYPE_NORMAL);
ASSUME(MoveHasAdditionalEffect(MOVE_BODY_SLAM, MOVE_EFFECT_PARALYSIS) == TRUE);
- ASSUME(gMovesInfo[MOVE_BODY_SLAM].type == TYPE_NORMAL);
+ ASSUME(GetMoveType(MOVE_BODY_SLAM) == TYPE_NORMAL);
PLAYER(SPECIES_TAUROS);
OPPONENT(SPECIES_TAUROS);
} WHEN {
diff --git a/test/battle/move_effect_secondary/psychic_noise.c b/test/battle/move_effect_secondary/psychic_noise.c
index e44ae75abe..8e5eae4efb 100644
--- a/test/battle/move_effect_secondary/psychic_noise.c
+++ b/test/battle/move_effect_secondary/psychic_noise.c
@@ -4,7 +4,7 @@
ASSUMPTIONS
{
ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC_NOISE, MOVE_EFFECT_PSYCHIC_NOISE));
- ASSUME(gMovesInfo[MOVE_RECOVER].effect == EFFECT_RESTORE_HP);
+ ASSUME(GetMoveEffect(MOVE_RECOVER) == EFFECT_RESTORE_HP);
}
SINGLE_BATTLE_TEST("Psychic Noise blocks healing moves for 2 turns")
diff --git a/test/battle/move_effect_secondary/reflect.c b/test/battle/move_effect_secondary/reflect.c
new file mode 100644
index 0000000000..6a0dda06d8
--- /dev/null
+++ b/test/battle/move_effect_secondary/reflect.c
@@ -0,0 +1,32 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(MoveHasAdditionalEffect(MOVE_BADDY_BAD, MOVE_EFFECT_REFLECT) == TRUE);
+}
+
+SINGLE_BATTLE_TEST("Baddy Bad sets up Reflect when it was succesful")
+{
+ bool32 moveSuccess;
+ PARAMETRIZE { moveSuccess = FALSE; }
+ PARAMETRIZE { moveSuccess = TRUE; }
+
+ GIVEN {
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_BADDY_BAD, hit: moveSuccess); }
+ } SCENE {
+ if (moveSuccess == TRUE)
+ {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BADDY_BAD, player);
+ MESSAGE("Reflect made your team stronger against physical moves!");
+ } else {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_BADDY_BAD, player);
+ MESSAGE("Reflect made your team stronger against physical moves!");
+ }
+ }
+ }
+}
diff --git a/test/battle/move_effect_secondary/steal_item.c b/test/battle/move_effect_secondary/steal_item.c
new file mode 100644
index 0000000000..8a4ae931d2
--- /dev/null
+++ b/test/battle/move_effect_secondary/steal_item.c
@@ -0,0 +1,129 @@
+#include "global.h"
+#include "test/battle.h"
+
+ASSUMPTIONS
+{
+ ASSUME(MoveHasAdditionalEffect(MOVE_THIEF, MOVE_EFFECT_STEAL_ITEM) == TRUE);
+ ASSUME(MoveHasAdditionalEffect(MOVE_COVET, MOVE_EFFECT_STEAL_ITEM) == TRUE);
+}
+
+SINGLE_BATTLE_TEST("Thief and Covet steal target's held item")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_THIEF; }
+ PARAMETRIZE { move = MOVE_COVET; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_HYPER_POTION); }
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ HP_BAR(opponent);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_STEAL, opponent);
+ } THEN {
+ EXPECT_EQ(player->item, ITEM_HYPER_POTION);
+ EXPECT_EQ(opponent->item, ITEM_NONE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Thief and Covet steal player's held item if opponent is a trainer")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_THIEF; }
+ PARAMETRIZE { move = MOVE_COVET; }
+ GIVEN {
+ ASSUME(B_TRAINERS_KNOCK_OFF_ITEMS == TRUE);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_HYPER_POTION); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, opponent);
+ HP_BAR(player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_STEAL, player);
+ } THEN {
+ EXPECT_EQ(opponent->item, ITEM_HYPER_POTION);
+ EXPECT_EQ(player->item, ITEM_NONE);
+ }
+}
+
+WILD_BATTLE_TEST("Thief and Covet don't steal player's held item if opponent is a wild mon")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_THIEF; }
+ PARAMETRIZE { move = MOVE_COVET; }
+ GIVEN {
+ ASSUME(B_TRAINERS_KNOCK_OFF_ITEMS == TRUE);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_HYPER_POTION); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, opponent);
+ HP_BAR(player);
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_STEAL, player);
+ } THEN {
+ EXPECT_EQ(player->item, ITEM_HYPER_POTION);
+ EXPECT_EQ(opponent->item, ITEM_NONE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Thief and Covet don't steal target's held item if user is holding an item")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_THIEF; }
+ PARAMETRIZE { move = MOVE_COVET; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_POTION); }
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_HYPER_POTION); }
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ HP_BAR(opponent);
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_STEAL, opponent);
+ } THEN {
+ EXPECT_EQ(player->item, ITEM_POTION);
+ EXPECT_EQ(opponent->item, ITEM_HYPER_POTION);
+ }
+}
+
+SINGLE_BATTLE_TEST("Thief and Covet don't steal target's held item if target has no item")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_THIEF; }
+ PARAMETRIZE { move = MOVE_COVET; }
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ HP_BAR(opponent);
+ NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_STEAL, opponent);
+ }
+}
+
+// Test can't currently verify if the item is sent to Bag
+WILD_BATTLE_TEST("Thief and Covet steal target's held item and it's added to Bag in wild battles (Gen 9)")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_THIEF; }
+ PARAMETRIZE { move = MOVE_COVET; }
+ GIVEN {
+ ASSUME(B_STEAL_WILD_ITEMS >= GEN_9);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_HYPER_POTION); }
+ } WHEN {
+ TURN { MOVE(player, move); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, move, player);
+ HP_BAR(opponent);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_STEAL, opponent);
+ } THEN {
+ EXPECT_EQ(player->item, ITEM_NONE);
+ EXPECT_EQ(opponent->item, ITEM_NONE);
+ }
+}
diff --git a/test/battle/move_effects_combined/axe_kick.c b/test/battle/move_effects_combined/axe_kick.c
index 94ab9377ad..5cc5b9b90c 100644
--- a/test/battle/move_effects_combined/axe_kick.c
+++ b/test/battle/move_effects_combined/axe_kick.c
@@ -3,7 +3,7 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_AXE_KICK].effect == EFFECT_RECOIL_IF_MISS);
+ ASSUME(GetMoveEffect(MOVE_AXE_KICK) == EFFECT_RECOIL_IF_MISS);
ASSUME(MoveHasAdditionalEffect(MOVE_AXE_KICK, MOVE_EFFECT_CONFUSION) == TRUE);
}
diff --git a/test/battle/move_effects_combined/barb_barrage.c b/test/battle/move_effects_combined/barb_barrage.c
index e2e5059fee..62f78cd4cf 100644
--- a/test/battle/move_effects_combined/barb_barrage.c
+++ b/test/battle/move_effects_combined/barb_barrage.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_BARB_BARRAGE].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
- ASSUME(gMovesInfo[MOVE_BARB_BARRAGE].argument == STATUS1_PSN_ANY);
+ ASSUME(GetMoveEffect(MOVE_BARB_BARRAGE) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_BARB_BARRAGE) == STATUS1_PSN_ANY);
ASSUME(MoveHasAdditionalEffect(MOVE_BARB_BARRAGE, MOVE_EFFECT_POISON) == TRUE);
}
diff --git a/test/battle/move_effects_combined/hurricane.c b/test/battle/move_effects_combined/hurricane.c
index 61acac6649..02620f4d05 100644
--- a/test/battle/move_effects_combined/hurricane.c
+++ b/test/battle/move_effects_combined/hurricane.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_HURRICANE].effect == EFFECT_THUNDER);
- ASSUME(gMovesInfo[MOVE_HURRICANE].accuracy == 70);
+ ASSUME(GetMoveEffect(MOVE_HURRICANE) == EFFECT_THUNDER);
+ ASSUME(GetMoveAccuracy(MOVE_HURRICANE) == 70);
}
SINGLE_BATTLE_TEST("Hurricane's accuracy is lowered to 50% in Sunlight")
@@ -39,10 +39,10 @@ SINGLE_BATTLE_TEST("Hurricane can hit airborne targets (Fly, Bounce)")
PARAMETRIZE { move = MOVE_FLY; }
PARAMETRIZE { move = MOVE_BOUNCE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLY].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_FLY].argument)) == STATUS3_ON_AIR);
- ASSUME(gMovesInfo[MOVE_BOUNCE].effect == EFFECT_SEMI_INVULNERABLE);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_BOUNCE].argument)) == STATUS3_ON_AIR);
+ ASSUME(GetMoveEffect(MOVE_FLY) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_FLY) == STATUS3_ON_AIR);
+ ASSUME(GetMoveEffect(MOVE_BOUNCE) == EFFECT_SEMI_INVULNERABLE);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_BOUNCE) == STATUS3_ON_AIR);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Moves(move); }
} WHEN {
@@ -57,8 +57,8 @@ SINGLE_BATTLE_TEST("Hurricane can hit airborne targets (Fly, Bounce)")
DOUBLE_BATTLE_TEST("Hurricane can hit airborne targets (Sky Drop)")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_SKY_DROP].effect == EFFECT_SKY_DROP);
- ASSUME(UNCOMPRESS_BITS(HIHALF(gMovesInfo[MOVE_SKY_DROP].argument)) == STATUS3_ON_AIR);
+ ASSUME(GetMoveEffect(MOVE_SKY_DROP) == EFFECT_SKY_DROP);
+ ASSUME(GetMoveTwoTurnAttackStatus(MOVE_SKY_DROP) == STATUS3_ON_AIR);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_effects_combined/infernal_parade.c b/test/battle/move_effects_combined/infernal_parade.c
index 6aa46ef8cb..266718d2e9 100644
--- a/test/battle/move_effects_combined/infernal_parade.c
+++ b/test/battle/move_effects_combined/infernal_parade.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_INFERNAL_PARADE].effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
- ASSUME(gMovesInfo[MOVE_INFERNAL_PARADE].argument == STATUS1_ANY);
+ ASSUME(GetMoveEffect(MOVE_INFERNAL_PARADE) == EFFECT_DOUBLE_POWER_ON_ARG_STATUS);
+ ASSUME(GetMoveEffectArg_Status(MOVE_INFERNAL_PARADE) == STATUS1_ANY);
ASSUME(MoveHasAdditionalEffect(MOVE_INFERNAL_PARADE, MOVE_EFFECT_BURN) == TRUE);
}
diff --git a/test/battle/move_effects_combined/make_it_rain.c b/test/battle/move_effects_combined/make_it_rain.c
index 5469eac8a5..e9c8b153ce 100644
--- a/test/battle/move_effects_combined/make_it_rain.c
+++ b/test/battle/move_effects_combined/make_it_rain.c
@@ -12,7 +12,7 @@ SINGLE_BATTLE_TEST("Make It Rain lowers special attack by one stage")
s16 damage[2];
GIVEN {
- ASSUME(gMovesInfo[MOVE_MAKE_IT_RAIN].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_MAKE_IT_RAIN) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_effects_combined/triple_arrows.c b/test/battle/move_effects_combined/triple_arrows.c
index ad7878fdc9..4fd040e32a 100644
--- a/test/battle/move_effects_combined/triple_arrows.c
+++ b/test/battle/move_effects_combined/triple_arrows.c
@@ -49,7 +49,7 @@ SINGLE_BATTLE_TEST("Triple Arrows lands a critical hit")
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
- ASSUME(gMovesInfo[MOVE_TRIPLE_ARROWS].criticalHitStage == 1);
+ ASSUME(GetMoveCriticalHitStage(MOVE_TRIPLE_ARROWS) == 1);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_flags/cant_use_twice.c b/test/battle/move_flags/cant_use_twice.c
index 99bd681acb..cba5596d26 100644
--- a/test/battle/move_flags/cant_use_twice.c
+++ b/test/battle/move_flags/cant_use_twice.c
@@ -3,8 +3,8 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_GIGATON_HAMMER].cantUseTwice == TRUE);
- ASSUME(gMovesInfo[MOVE_BLOOD_MOON].cantUseTwice == TRUE);
+ ASSUME(MoveCantBeUsedTwice(MOVE_GIGATON_HAMMER) == TRUE);
+ ASSUME(MoveCantBeUsedTwice(MOVE_BLOOD_MOON) == TRUE);
}
SINGLE_BATTLE_TEST("Struggle will be used if slow Encore is used on moves with the cantUseTwice flag")
@@ -13,7 +13,7 @@ SINGLE_BATTLE_TEST("Struggle will be used if slow Encore is used on moves with t
PARAMETRIZE { move = MOVE_GIGATON_HAMMER; }
PARAMETRIZE { move = MOVE_BLOOD_MOON; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE);
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("Moves with the cantUseTwice flag strike again if fast encore
PARAMETRIZE { move = MOVE_GIGATON_HAMMER; }
PARAMETRIZE { move = MOVE_BLOOD_MOON; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE);
+ ASSUME(GetMoveEffect(MOVE_ENCORE) == EFFECT_ENCORE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/move_flags/damages_airborne_double_damage.c b/test/battle/move_flags/damages_airborne_double_damage.c
index dcdb801ff6..adeac7d3a2 100644
--- a/test/battle/move_flags/damages_airborne_double_damage.c
+++ b/test/battle/move_flags/damages_airborne_double_damage.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Being airborne causes the target to take double damage from
PARAMETRIZE { useDive = FALSE; }
PARAMETRIZE { useDive = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TWISTER].damagesAirborneDoubleDamage);
+ ASSUME(MoveDamagesAirborneDoubleDamage(MOVE_TWISTER));
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
} WHEN {
diff --git a/test/battle/move_flags/damages_underground.c b/test/battle/move_flags/damages_underground.c
index 97b792b4dd..7d4b8cd946 100644
--- a/test/battle/move_flags/damages_underground.c
+++ b/test/battle/move_flags/damages_underground.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Being underground causes the target to take double damage fr
PARAMETRIZE { useDig = FALSE; }
PARAMETRIZE { useDig = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_EARTHQUAKE].damagesUnderground);
+ ASSUME(MoveDamagesUnderground(MOVE_EARTHQUAKE));
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
} WHEN {
diff --git a/test/battle/move_flags/damages_underwater.c b/test/battle/move_flags/damages_underwater.c
index a7269a0162..b313d044c2 100644
--- a/test/battle/move_flags/damages_underwater.c
+++ b/test/battle/move_flags/damages_underwater.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Being underwater causes the target to take double damage fro
PARAMETRIZE { useDive = FALSE; }
PARAMETRIZE { useDive = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURF].damagesUnderwater);
+ ASSUME(MoveDamagesUnderWater(MOVE_SURF));
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
} WHEN {
diff --git a/test/battle/move_flags/ignores_target_ability.c b/test/battle/move_flags/ignores_target_ability.c
index 2836f4838e..f4f9ff30a7 100644
--- a/test/battle/move_flags/ignores_target_ability.c
+++ b/test/battle/move_flags/ignores_target_ability.c
@@ -3,9 +3,9 @@
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SUNSTEEL_STRIKE].ignoresTargetAbility);
- ASSUME(gMovesInfo[MOVE_MOONGEIST_BEAM].ignoresTargetAbility);
- ASSUME(gMovesInfo[MOVE_PHOTON_GEYSER].ignoresTargetAbility);
+ ASSUME(MoveIgnoresTargetAbility(MOVE_SUNSTEEL_STRIKE));
+ ASSUME(MoveIgnoresTargetAbility(MOVE_MOONGEIST_BEAM));
+ ASSUME(MoveIgnoresTargetAbility(MOVE_PHOTON_GEYSER));
}
SINGLE_BATTLE_TEST("ignoresTargetAbility moves do not ignore the attacker's own ability", s16 damage)
@@ -20,19 +20,19 @@ SINGLE_BATTLE_TEST("ignoresTargetAbility moves do not ignore the attacker's own
PARAMETRIZE { move = MOVE_PHOTON_GEYSER; ability = ABILITY_UNAWARE; }
ASSUME(gAbilitiesInfo[ABILITY_UNAWARE].breakable);
- ASSUME(gMovesInfo[MOVE_IRON_DEFENSE].effect == EFFECT_DEFENSE_UP_2);
- ASSUME(gMovesInfo[MOVE_AMNESIA].effect == EFFECT_SPECIAL_DEFENSE_UP_2);
+ ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2);
+ ASSUME(GetMoveEffect(MOVE_AMNESIA) == EFFECT_SPECIAL_DEFENSE_UP_2);
GIVEN {
PLAYER(SPECIES_CLEFABLE) { Speed(1); Ability(ability); }
OPPONENT(SPECIES_ARON) { Speed(2); }
} WHEN {
- if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL)
+ if (GetMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL)
TURN { MOVE(opponent, MOVE_IRON_DEFENSE); MOVE(player, move); }
else
TURN { MOVE(opponent, MOVE_AMNESIA); MOVE(player, move); }
} SCENE {
- if (gMovesInfo[move].category == DAMAGE_CATEGORY_PHYSICAL)
+ if (GetMoveCategory(move) == DAMAGE_CATEGORY_PHYSICAL)
ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_DEFENSE, opponent);
else
ANIMATION(ANIM_TYPE_MOVE, MOVE_AMNESIA, opponent);
diff --git a/test/battle/move_flags/minimize_double_damage.c b/test/battle/move_flags/minimize_double_damage.c
index f3cdd7657f..fd44077c4f 100644
--- a/test/battle/move_flags/minimize_double_damage.c
+++ b/test/battle/move_flags/minimize_double_damage.c
@@ -7,8 +7,8 @@ SINGLE_BATTLE_TEST("MinimizeDoubleDamage flag makes moves cause double damage to
PARAMETRIZE { useMinimize = FALSE; }
PARAMETRIZE { useMinimize = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_MINIMIZE].effect == EFFECT_MINIMIZE);
- ASSUME(gMovesInfo[MOVE_STEAMROLLER].minimizeDoubleDamage);
+ ASSUME(GetMoveEffect(MOVE_MINIMIZE) == EFFECT_MINIMIZE);
+ ASSUME(MoveIncreasesPowerToMinimizedTargets(MOVE_STEAMROLLER));
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
} WHEN {
diff --git a/test/battle/move_flags/powder.c b/test/battle/move_flags/powder.c
index 35a6e1012b..04920f79f3 100644
--- a/test/battle/move_flags/powder.c
+++ b/test/battle/move_flags/powder.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Powder moves are blocked by Grass-type Pokémon")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_STUN_SPORE].powderMove);
+ ASSUME(IsPowderMove(MOVE_STUN_SPORE));
ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS);
PLAYER(SPECIES_WYNAUT);
OPPONENT(SPECIES_ODDISH);
diff --git a/test/battle/move_flags/recoil.c b/test/battle/move_flags/recoil.c
index bdada8a114..dede6289da 100644
--- a/test/battle/move_flags/recoil.c
+++ b/test/battle/move_flags/recoil.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Take Down deals 25% of recoil damage to the user")
s16 recoilDamage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_TAKE_DOWN].recoil == 25);
+ ASSUME(GetMoveRecoil(MOVE_TAKE_DOWN) == 25);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -27,7 +27,7 @@ SINGLE_BATTLE_TEST("Double Edge deals 33% of recoil damage to the user")
s16 recoilDamage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_EDGE].recoil == 33);
+ ASSUME(GetMoveRecoil(MOVE_DOUBLE_EDGE) == 33);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -47,7 +47,7 @@ SINGLE_BATTLE_TEST("Head Smash deals 50% of recoil damage to the user")
s16 recoilDamage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_HEAD_SMASH].recoil == 50);
+ ASSUME(GetMoveRecoil(MOVE_HEAD_SMASH) == 50);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -67,7 +67,7 @@ SINGLE_BATTLE_TEST("Flare Blitz deals 33% of recoil damage to the user and can b
s16 recoilDamage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLARE_BLITZ].recoil == 33);
+ ASSUME(GetMoveRecoil(MOVE_FLARE_BLITZ) == 33);
ASSUME(MoveHasAdditionalEffect(MOVE_FLARE_BLITZ, MOVE_EFFECT_BURN));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
diff --git a/test/battle/move_flags/strike_count.c b/test/battle/move_flags/strike_count.c
index ba71e35c26..80a6f24359 100644
--- a/test/battle/move_flags/strike_count.c
+++ b/test/battle/move_flags/strike_count.c
@@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Two strike count turns a move into a 2-hit move")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_DOUBLE_KICK].strikeCount == 2);
+ ASSUME(GetMoveStrikeCount(MOVE_DOUBLE_KICK) == 2);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Three strike count turns a move into a 3-hit move")
s16 thirdHit;
GIVEN {
- ASSUME(gMovesInfo[MOVE_TRIPLE_DIVE].strikeCount == 3);
+ ASSUME(GetMoveStrikeCount(MOVE_TRIPLE_DIVE) == 3);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -49,8 +49,8 @@ SINGLE_BATTLE_TEST("Surging Strikes hits 3 times with each hit being a critical
s16 thirdHit;
GIVEN {
- ASSUME(gMovesInfo[MOVE_SURGING_STRIKES].strikeCount == 3);
- ASSUME(gMovesInfo[MOVE_SURGING_STRIKES].alwaysCriticalHit == TRUE);
+ ASSUME(GetMoveStrikeCount(MOVE_SURGING_STRIKES) == 3);
+ ASSUME(MoveAlwaysCrits(MOVE_SURGING_STRIKES));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/sleep_clause.c b/test/battle/sleep_clause.c
new file mode 100644
index 0000000000..a5f28f4f22
--- /dev/null
+++ b/test/battle/sleep_clause.c
@@ -0,0 +1,1816 @@
+#include "global.h"
+#include "test/battle.h"
+
+AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); }
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); }
+ }
+}
+
+AI_DOUBLE_BATTLE_TEST("Sleep Clause: AI will not use sleep moves while sleep clause is active (Doubles)")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); }
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_MACH_PUNCH); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_SPORE); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); }
+ TURN { SWITCH(playerLeft, 2); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_MACH_PUNCH); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); }
+ TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_MACH_PUNCH); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); }
+ }
+}
+
+AI_DOUBLE_BATTLE_TEST("Sleep Clause: AI will not use sleep move if partner is already using a sleep move")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); }
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_SPORE); EXPECT_MOVE(opponentRight, MOVE_MACH_PUNCH); }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_SPORE); SWITCH(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves fail when sleep clause is active (Doubles)")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentRight); MOVE(playerRight, MOVE_SPORE, target: opponentLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_REST); }
+ TURN { MOVE(player, MOVE_SPORE); SWITCH(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Rest does not activate sleep clause (Doubles)")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_REST); MOVE(playerLeft, MOVE_SPORE, target: opponentRight); }
+ } SCENE {
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, opponentLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_TACKLE); SWITCH(opponent, 1); }
+ TURN { MOVE(opponent, MOVE_REST); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, opponent);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Rest can still be used when sleep clause is active (Doubles)")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET) { HP(1); MaxHP(100); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentRight); MOVE(opponentLeft, MOVE_REST); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, opponentLeft);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will fail if sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT);
+ PLAYER(SPECIES_WOBBUFFET)
+ PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SLEEP_TALK, MOVE_PSYCHO_SHIFT); }
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
+ TURN { MOVE(opponent, MOVE_SPORE); MOVE(player, MOVE_SLEEP_TALK); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, player);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept the opposing Wobbuffet awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Psycho Shift'ing sleep will activate sleep clause")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT);
+ PLAYER(SPECIES_ZIGZAGOON)
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, MOVE_PSYCHO_SHIFT); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); }
+ TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
+ TURN { MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ STATUS_ICON(player, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
+
+AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will not use Yawn while sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_YAWN, MOVE_MACH_PUNCH); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_YAWN); }
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); }
+ TURN { SWITCH(player, 1); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); }
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_MACH_PUNCH); }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Yawn will fail when sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_YAWN); }
+ TURN { }
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_YAWN); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Wobbuffet fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ STATUS_ICON(player, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Wobbuffet awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with sleep clause active")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); }
+ TURN { MOVE(player, MOVE_TACKLE); }
+ TURN { }
+ } SCENE {
+ ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Effect Spore causes sleep 11% of the time with sleep clause active (Doubles)")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_SPORE, target:playerRight); MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft);}
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Wobbuffet fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ABILITY_POPUP(opponentLeft, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ }
+}
+
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate sleep clause")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_TACKLE); }
+ TURN {}
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Wobbuffet fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep from Effect Spore will not activate sleep clause (Doubles)")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft); MOVE(opponentLeft, MOVE_SPORE, target:playerRight); }
+ } SCENE {
+ ABILITY_POPUP(opponentLeft, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("The opposing Breloom's Effect Spore made Wobbuffet sleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Wobbuffet fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will activate sleep clause")
+{
+ PASSES_RANDOMLY(10, 100, RNG_SECONDARY_EFFECT);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_RELIC_SONG); }
+ TURN { MOVE(player, MOVE_SPORE); SWITCH(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player);
+ HP_BAR(opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ STATUS_ICON(opponent, sleep: TRUE);
+ MESSAGE("Wobbuffet used Spore!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Moves with sleep effect chance will still do damage when sleep clause active, but won't sleep")
+{
+ PASSES_RANDOMLY(100, 100, RNG_SECONDARY_EFFECT);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(MoveHasAdditionalEffect(MOVE_RELIC_SONG, MOVE_EFFECT_SLEEP));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_RELIC_SONG); SWITCH(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_RELIC_SONG, player);
+ HP_BAR(opponent);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Dire Claw cannot sleep a mon when sleep clause is active")
+{
+ PASSES_RANDOMLY(100, 100, RNG_SECONDARY_EFFECT);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(MoveHasAdditionalEffect(MOVE_DIRE_CLAW, MOVE_EFFECT_DIRE_CLAW));
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_DIRE_CLAW); SWITCH(opponent, 1); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DIRE_CLAW, player);
+ HP_BAR(opponent);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Dark Void can only sleep one opposing mon if sleep clause is active")
+{
+ // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move)
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID);
+ PLAYER(SPECIES_DARKRAI);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_DARK_VOID); }
+ TURN { MOVE(playerLeft, MOVE_DARK_VOID); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DARK_VOID, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: G-Max Befuddle can only sleep one opposing mon if sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_BEFUDDLE) == MAX_EFFECT_EFFECT_SPORE_FOES);
+ PLAYER(SPECIES_BUTTERFREE) { GigantamaxFactor(TRUE); }
+ PLAYER(SPECIES_CATERPIE);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_BUG_BITE, target: opponentLeft, gimmick: GIMMICK_DYNAMAX,
+ WITH_RNG(RNG_G_MAX_BEFUDDLE, STATUS1_SLEEP)); }
+ } SCENE {
+ MESSAGE("Butterfree used G-Max Befuddle!");
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon wakes up")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(B_SLEEP_TURNS >= GEN_5);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN {}
+ TURN {}
+ TURN {}
+ TURN { MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("The opposing Wobbuffet woke up!");
+ MESSAGE("Wobbuffet used Spore!");
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Wobbuffet fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up with Aromatherapy / Heal Bell / Sparkly Swirl")
+{
+ u32 move = MOVE_NONE, switchIndex = 0;
+ struct BattlePokemon *healingSlot = opponentRight;
+ struct BattlePokemon *sporedSlot = opponentLeft;
+ PARAMETRIZE { move = MOVE_AROMATHERAPY; healingSlot = opponentRight; sporedSlot = opponentLeft; switchIndex = 0; }
+ PARAMETRIZE { move = MOVE_HEAL_BELL; healingSlot = opponentRight; sporedSlot = opponentLeft; switchIndex = 0; }
+ PARAMETRIZE { move = MOVE_SPARKLY_SWIRL; healingSlot = opponentRight; sporedSlot = opponentLeft; switchIndex = 0; }
+ PARAMETRIZE { move = MOVE_AROMATHERAPY; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; }
+ PARAMETRIZE { move = MOVE_HEAL_BELL; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; }
+ PARAMETRIZE { move = MOVE_SPARKLY_SWIRL; healingSlot = opponentLeft; sporedSlot = opponentRight; switchIndex = 1; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_HEAL_BELL) == EFFECT_HEAL_BELL);
+ ASSUME(GetMoveEffect(MOVE_SPARKLY_SWIRL) == EFFECT_SPARKLY_SWIRL);
+ ASSUME(B_SLEEP_TURNS >= GEN_5);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:sporedSlot); }
+ TURN { SWITCH(sporedSlot, 2); MOVE(playerLeft, MOVE_SPORE, target:healingSlot); }
+ if (move == MOVE_SPARKLY_SWIRL)
+ TURN { SWITCH(sporedSlot, switchIndex); MOVE(healingSlot, move, target: playerRight); MOVE(playerLeft, MOVE_SPORE, target:sporedSlot); }
+ else
+ TURN { SWITCH(sporedSlot, switchIndex); MOVE(healingSlot, move); MOVE(playerLeft, MOVE_SPORE, target:sporedSlot); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, sporedSlot);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(sporedSlot, sleep: TRUE);
+ MESSAGE("Zigzagoon used Spore!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, healingSlot);
+ STATUS_ICON(healingSlot, sleep: TRUE);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+ MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!");
+ if (move == MOVE_AROMATHERAPY)
+ {
+ MESSAGE("The opposing Zigzagoon used Aromatherapy!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, healingSlot);
+ }
+ else if (move == MOVE_HEAL_BELL)
+ {
+ MESSAGE("The opposing Zigzagoon used Heal Bell!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HEAL_BELL, healingSlot);
+ }
+ else
+ {
+ MESSAGE("The opposing Zigzagoon used Sparkly Swirl!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPARKLY_SWIRL, healingSlot);
+ }
+ STATUS_ICON(sporedSlot, sleep: FALSE);
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, sporedSlot);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up forcefully by a move from an opponent")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(MoveHasAdditionalEffect(MOVE_WAKE_UP_SLAP, MOVE_EFFECT_REMOVE_STATUS));
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); }
+ TURN { SWITCH(opponentLeft, 2); MOVE(playerLeft, MOVE_SPORE, target:opponentRight); }
+ TURN { SWITCH(opponentLeft, 0); MOVE(playerLeft, MOVE_WAKE_UP_SLAP, target:opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ MESSAGE("Zigzagoon used Spore!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+ MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!");
+ MESSAGE("Zigzagoon used Wake-Up Slap!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_WAKE_UP_SLAP, playerLeft);
+ MESSAGE("The opposing Zigzagoon woke up!");
+ STATUS_ICON(opponentLeft, sleep: FALSE);
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up forcefully by Uproar")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_UPROAR) == EFFECT_UPROAR);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); MOVE(playerRight, MOVE_UPROAR); MOVE(opponentRight, MOVE_ROAR, target:playerRight); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ MESSAGE("Zigzagoon used Uproar!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_UPROAR, playerRight);
+ MESSAGE("Zigzagoon caused an uproar!");
+ MESSAGE("The uproar woke the opposing Zigzagoon!");
+ STATUS_ICON(opponentLeft, sleep: FALSE);
+ MESSAGE("The opposing Zigzagoon used Roar!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ROAR, opponentRight);
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using Sleep Talk into a status curing move")
+{
+ u32 move;
+ PARAMETRIZE { move = MOVE_PSYCHO_SHIFT; }
+ PARAMETRIZE { move = MOVE_JUNGLE_HEALING; }
+ PARAMETRIZE { move = MOVE_LUNAR_BLESSING; }
+ PARAMETRIZE { move = MOVE_TAKE_HEART; }
+ PARAMETRIZE { move = MOVE_AROMATHERAPY; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_SLEEP_TALK) == EFFECT_SLEEP_TALK);
+ ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT);
+ ASSUME(GetMoveEffect(MOVE_JUNGLE_HEALING) == EFFECT_JUNGLE_HEALING);
+ ASSUME(GetMoveEffect(MOVE_LUNAR_BLESSING) == EFFECT_JUNGLE_HEALING);
+ ASSUME(GetMoveEffect(MOVE_PURIFY) == EFFECT_PURIFY);
+ ASSUME(GetMoveEffect(MOVE_TAKE_HEART) == EFFECT_TAKE_HEART);
+ ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL);
+ ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP);
+ PLAYER(SPECIES_ZIGZAGOON) { Item(ITEM_CHESTO_BERRY); }
+ OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, move); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); }
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, move); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("The opposing Zigzagoon used Sleep Talk!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent);
+ if (move == MOVE_PSYCHO_SHIFT)
+ {
+ MESSAGE("The opposing Zigzagoon used Psycho Shift!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, opponent);
+ }
+ else if (move == MOVE_JUNGLE_HEALING)
+ {
+ MESSAGE("The opposing Zigzagoon used Jungle Healing!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_JUNGLE_HEALING, opponent);
+ }
+ else if (move == MOVE_LUNAR_BLESSING)
+ {
+ MESSAGE("The opposing Zigzagoon used Lunar Blessing!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_LUNAR_BLESSING, opponent);
+ }
+ else if (move == MOVE_TAKE_HEART)
+ {
+ MESSAGE("The opposing Zigzagoon used Take Heart!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TAKE_HEART, opponent);
+ }
+ else if (move == MOVE_AROMATHERAPY)
+ {
+ MESSAGE("The opposing Zigzagoon used Aromatherapy!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, opponent);
+ }
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Hydration in the rain")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_PELIPPER) { Ability(ABILITY_DRIZZLE); }
+ OPPONENT(SPECIES_LUVDISC) { Ability(ABILITY_HYDRATION); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Pelipper used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Luvdisc fell asleep!");
+ MESSAGE("The opposing Luvdisc's Hydration cured its sleep problem!");
+ STATUS_ICON(opponent, sleep: FALSE);
+ MESSAGE("Pelipper used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Luvdisc fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Natural Cure")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_SWABLU) { Ability(ABILITY_NATURAL_CURE); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 1); }
+ TURN { SWITCH(opponent, 0); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Swablu fell asleep!");
+ MESSAGE("2 withdrew Swablu!");
+ MESSAGE("2 sent out Swablu!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Swablu fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Shed Skin")
+{
+ if (B_ABILITY_TRIGGER_CHANCE == GEN_4)
+ PASSES_RANDOMLY(30, 100, RNG_SHED_SKIN);
+ else
+ PASSES_RANDOMLY(33, 100, RNG_SHED_SKIN);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_DRATINI) { Ability(ABILITY_SHED_SKIN); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Dratini fell asleep!");
+ MESSAGE("The opposing Dratini's Shed Skin cured its sleep problem!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Dratini fell asleep!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Healer")
+{
+ PASSES_RANDOMLY(30, 100, RNG_HEALER);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_CHANSEY) { Ability(ABILITY_HEALER); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target:opponentLeft); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("The opposing Chansey's Healer cured the opposing Zigzagoon's problem!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using a held item")
+{
+ u32 heldItem = ITEM_NONE;
+ PARAMETRIZE { heldItem = ITEM_CHESTO_BERRY; }
+ PARAMETRIZE { heldItem = ITEM_LUM_BERRY; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP);
+ ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON) { Item(heldItem); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ if (heldItem == ITEM_CHESTO_BERRY)
+ MESSAGE("The opposing Zigzagoon's Chesto Berry woke it up!");
+ else
+ MESSAGE("The opposing Zigzagoon's Lum Berry cured its sleep problem!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by Flinging a held item")
+{
+ u32 heldItem = ITEM_NONE;
+ PARAMETRIZE { heldItem = ITEM_CHESTO_BERRY; }
+ PARAMETRIZE { heldItem = ITEM_LUM_BERRY; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING);
+ ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP);
+ ASSUME(gItemsInfo[ITEM_LUM_BERRY].holdEffect == HOLD_EFFECT_CURE_STATUS);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON) { Item(heldItem); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); MOVE(playerRight, MOVE_FLING, target: opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("Zigzagoon used Fling!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, playerRight);
+ if (heldItem == ITEM_CHESTO_BERRY)
+ MESSAGE("The opposing Zigzagoon's Chesto Berry woke it up!");
+ else
+ MESSAGE("The opposing Zigzagoon's Lum Berry cured its sleep problem!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by using an item")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(gItemsInfo[ITEM_AWAKENING].battleUsage == EFFECT_ITEM_CURE_STATUS);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { USE_ITEM(opponent, ITEM_AWAKENING, partyIndex: 0); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("Zigzagoon had its status healed!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon faints")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON) { Level(5); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); }
+ TURN { MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("The opposing Zigzagoon fainted!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon faints (Doubles)")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON) { Level(5); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentRight);}
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("The opposing Zigzagoon fainted!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up by gaining the ability Insomnia / Vital Spirit")
+{
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; }
+ PARAMETRIZE { ability = ABILITY_INSOMNIA; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_DELIBIRD) { Ability(ability); }
+ OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SLEEP_TALK, MOVE_SKILL_SWAP); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SLEEP_TALK); }
+ TURN { MOVE(opponent, MOVE_SKILL_SWAP); }
+ TURN { MOVE(player, MOVE_SPORE); MOVE(opponent, MOVE_SKILL_SWAP); }
+ } SCENE {
+ MESSAGE("Delibird used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ MESSAGE("The opposing Zigzagoon used Sleep Talk!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SLEEP_TALK, opponent);
+ MESSAGE("The opposing Zigzagoon used Skill Swap!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, opponent);
+ if (ability == ABILITY_VITAL_SPIRIT)
+ MESSAGE("The opposing Zigzagoon's Vital Spirit cured its sleep problem!");
+ if (ability == ABILITY_INSOMNIA)
+ MESSAGE("The opposing Zigzagoon's Insomnia cured its sleep problem!");
+ MESSAGE("The opposing Zigzagoon used Skill Swap!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SKILL_SWAP, opponent);
+ MESSAGE("Delibird used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is sent out, has Trace, and Traces Insomnia / Vital spirit")
+{
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; }
+ PARAMETRIZE { ability = ABILITY_INSOMNIA; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON)
+ PLAYER(SPECIES_DELIBIRD) { Ability(ability); }
+ OPPONENT(SPECIES_RALTS) { Ability(ABILITY_TRACE); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
+ TURN { SWITCH(opponent, 0); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Ralts fell asleep!");
+ MESSAGE("2 sent out Zigzagoon!");
+ MESSAGE("2 sent out Ralts!");
+ if (ability == ABILITY_VITAL_SPIRIT)
+ MESSAGE("The opposing Ralts's Vital Spirit cured its sleep problem!");
+ if (ability == ABILITY_INSOMNIA)
+ MESSAGE("The opposing Ralts's Insomnia cured its sleep problem!");
+ MESSAGE("2 sent out Zigzagoon!");
+ MESSAGE("Delibird used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is sent out and transforms into a mon with Insomnia / Vital spirit")
+{
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; }
+ PARAMETRIZE { ability = ABILITY_INSOMNIA; }
+ KNOWN_FAILING; // Sleep Clause parts work, but Imposter seems broken with battle messages / targeting. Issue #5565 https://github.com/rh-hideout/pokeemerald-expansion/issues/5565
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL);
+ PLAYER(SPECIES_ZIGZAGOON)
+ PLAYER(SPECIES_DELIBIRD) { Ability(ability); }
+ OPPONENT(SPECIES_DITTO) { Ability(ABILITY_IMPOSTER); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); SWITCH(opponent, 1); }
+ TURN { SWITCH(opponent, 0); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("The opposing Ditto transformed into Zigzagoon using Imposter!");
+ MESSAGE("Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Ditto fell asleep!");
+ MESSAGE("2 sent out Zigzagoon!");
+ MESSAGE("2 sent out Ditto!");
+ if (ability == ABILITY_VITAL_SPIRIT)
+ MESSAGE("The opposing Ditto's Vital Spirit cured its sleep problem!");
+ else
+ MESSAGE("The opposing Ditto's Insomnia cured its sleep problem!");
+ MESSAGE("2 sent out Zigzagoon!");
+ MESSAGE("Delibird used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ }
+}
+
+AI_SINGLE_BATTLE_TEST("Sleep Clause: AI will use sleep moves again when sleep clause has been deactivated")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(gItemsInfo[ITEM_CHESTO_BERRY].holdEffect == HOLD_EFFECT_CURE_SLP);
+ AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_CHESTO_BERRY); }
+ OPPONENT(SPECIES_BRELOOM) { Moves(MOVE_SPORE, MOVE_MACH_PUNCH); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_SPORE); }
+ TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_SPORE); }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep clause is deactivated when a sleeping mon is woken up with G-Max Sweetness")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveMaxEffect(MOVE_G_MAX_SWEETNESS) == MAX_EFFECT_AROMATHERAPY);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_APPLETUN) { GigantamaxFactor(TRUE); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponentRight, MOVE_SPORE, target: playerRight); }
+ TURN { MOVE(playerLeft, MOVE_VINE_WHIP, target: opponentLeft, gimmick: GIMMICK_DYNAMAX); }
+ TURN { MOVE(opponentRight, MOVE_SPORE, target: playerRight); }
+ } SCENE {
+ MESSAGE("The opposing Wobbuffet used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Wobbuffet fell asleep!");
+ MESSAGE("Appletun used G-Max Sweetness!");
+ MESSAGE("Wobbuffet's status returned to normal!");
+ MESSAGE("The opposing Wobbuffet used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Wobbuffet fell asleep!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Pre-existing sleep condition doesn't activate sleep clause")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON) { Status1(STATUS1_SLEEP); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Sleep caused by Effect Spore does not prevent sleep clause from ever activating") // checks that sleepClauseEffectExempt works properly
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_TACKLE); }
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(player, 2); MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("The opposing Breloom's Effect Spore made Zigzagoon sleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Waking up after Effect Spore doesn't deactivate sleep clause")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ } WHEN {
+ TURN { MOVE(player, MOVE_TACKLE); }
+ TURN {}
+ TURN {}
+ TURN {}
+ TURN { MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ ABILITY_POPUP(opponent, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("The opposing Breloom's Effect Spore made Zigzagoon sleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Waking up after Effect Spore doesn't deactivate sleep clause (Doubles)")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(B_ABILITY_TRIGGER_CHANCE >= GEN_5);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_AROMATHERAPY) == EFFECT_HEAL_BELL);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); MOVE(opponentRight, MOVE_SPORE, target:playerRight); }
+ TURN { SWITCH(playerLeft, 2); }
+ TURN { MOVE(playerLeft, MOVE_AROMATHERAPY); MOVE(opponentRight, MOVE_SPORE, target:playerRight); MOVE(opponentLeft, MOVE_SPORE, target:playerLeft); }
+ } SCENE {
+ ABILITY_POPUP(opponentLeft, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("The opposing Breloom's Effect Spore made Zigzagoon sleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_AROMATHERAPY, playerLeft);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Waking up after Rest doesn't deactivate sleep clause")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_ZIGZAGOON) { HP(1); MaxHP(100); }
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_REST); }
+ TURN {}
+ TURN {}
+ TURN {}
+ TURN { MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("Zigzagoon went to sleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon woke up!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(player, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Waking up after Rest doesn't deactivate sleep clause (Doubles)")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_REST) == EFFECT_REST);
+ PLAYER(SPECIES_ZIGZAGOON) { HP(1); MaxHP(100); }
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_REST); MOVE(opponentRight, MOVE_SPORE, target:playerRight); }
+ TURN { SWITCH(playerRight, 2); }
+ TURN {}
+ TURN {}
+ TURN { MOVE(opponentRight, MOVE_SPORE, target:playerRight); }
+ } SCENE {
+ MESSAGE("Zigzagoon went to sleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, playerLeft);
+ MESSAGE("The opposing Zigzagoon used Spore!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ MESSAGE("Zigzagoon woke up!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Suppressing and then sleeping Vital Spirit / Insomnia and switching back in deactivates sleep clause")
+{
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; }
+ PARAMETRIZE { ability = ABILITY_INSOMNIA; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_DELIBIRD) { Ability(ability); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_GASTRO_ACID); }
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 0); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Delibird fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Mold Breaker Pokémon sleeping Vital Spirit / Insomnia activates sleep clause")
+{
+ KNOWN_FAILING; // Interaction between Mold Breaker and Vital Spirit / Insomnia is broken. Issue #5578 https://github.com/rh-hideout/pokeemerald-expansion/issues/5578
+ u32 ability;
+ PARAMETRIZE { ability = ABILITY_VITAL_SPIRIT; }
+ PARAMETRIZE { ability = ABILITY_INSOMNIA; }
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_PANCHAM) { Ability(ABILITY_MOLD_BREAKER); }
+ OPPONENT(SPECIES_DELIBIRD) { Ability(ability); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 0); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Delibird fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ MESSAGE("Sleep Clause kept the opposing Delibird awake!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon slept due to Effect Spore before Yawn triggers does not activate sleep clause")
+{
+ PASSES_RANDOMLY(11, 100, RNG_EFFECT_SPORE);
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ ASSUME(MoveMakesContact(MOVE_TACKLE));
+ PLAYER(SPECIES_BRELOOM) { Ability(ABILITY_EFFECT_SPORE); }
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_YAWN); }
+ TURN { MOVE(opponent, MOVE_TACKLE); }
+ TURN { SWITCH(opponent, 1); MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("The opposing Zigzagoon grew drowsy!");
+ ABILITY_POPUP(player, ABILITY_EFFECT_SPORE);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("Breloom's Effect Spore made the opposing Zigzagoon sleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Yawn'd Pokémon who's partner is slept before Yawn triggers will not fall asleep due to sleep clause being activated")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_YAWN, target: opponentLeft); MOVE(playerRight, MOVE_YAWN, target: opponentRight); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); }
+ } SCENE {
+ MESSAGE("The opposing Zigzagoon grew drowsy!");
+ MESSAGE("The opposing Zigzagoon grew drowsy!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ MESSAGE( "The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: If both Pokémon on one side are Yawn'd at the same time, one will fall asleep and the other will not")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ PLAYER(SPECIES_ZIGZAGOON) { Speed(5); }
+ PLAYER(SPECIES_ZIGZAGOON) { Speed(4); }
+ OPPONENT(SPECIES_ZIGZAGOON) { Speed(3); }
+ OPPONENT(SPECIES_ZIGZAGOON) { Speed(2); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_YAWN, target: opponentLeft); MOVE(playerRight, MOVE_YAWN, target: opponentRight); }
+ TURN { }
+ } SCENE {
+ MESSAGE("The opposing Zigzagoon grew drowsy!");
+ MESSAGE("The opposing Zigzagoon grew drowsy!");
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ MESSAGE( "The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) fail if sleep clause is active and they reflect a sleep move")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 1); }
+ TURN { MOVE(player, MOVE_MAGIC_COAT); MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player);
+ MESSAGE("The opposing Zigzagoon bounced the Spore back!"); // Should be MESSAGE("Zigzagoon bounced the Spore back!"); Issue #5579 https://github.com/rh-hideout/pokeemerald-expansion/issues/5579
+ MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!");
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) that reflect a sleep move activate sleep clause")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(player, MOVE_MAGIC_COAT); MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 1); }
+ TURN { MOVE(player, MOVE_SPORE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_MAGIC_COAT, player);
+ MESSAGE("Zigzagoon bounced the Spore back!");
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Reflection moves (ie. Magic Coat) that reflect Dark Void only sleep one opposing Pokémon")
+{
+ // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move)
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_MAGIC_COAT) == EFFECT_MAGIC_COAT);
+ ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_DARKRAI);
+ OPPONENT(SPECIES_DARKRAI);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_MAGIC_COAT); MOVE(opponentLeft, MOVE_DARK_VOID); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DARK_VOID, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Darkrai fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ MESSAGE("The opposing Darkrai fell asleep!");
+ }
+ }
+}
+
+SINGLE_BATTLE_TEST("Sleep Clause: Magic Bounce'ing a sleep move activates sleep clause, and fails if sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_SPORE); }
+ TURN { SWITCH(opponent, 1); }
+ TURN { MOVE(opponent, MOVE_SPORE); }
+ } SCENE {
+ MESSAGE("The opposing Zigzagoon's Spore was bounced back by Espeon's Magic Bounce!");
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ MESSAGE("The opposing Zigzagoon's Spore was bounced back by Espeon's Magic Bounce!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponent, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept the opposing Zigzagoon awake!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Magic Bounce reflecting Dark Void only sleeps one opposing Pokémon")
+{
+ // Source: https://bulbapedia.bulbagarden.net/wiki/Dark_Void_(move)
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_DARK_VOID) == EFFECT_DARK_VOID);
+ PLAYER(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE); }
+ PLAYER(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_DARKRAI);
+ OPPONENT(SPECIES_DARKRAI);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_DARK_VOID); }
+ } SCENE {
+ MESSAGE("The opposing Darkrai's Dark Void was bounced back by Espeon's Magic Bounce!");
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Darkrai fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ MESSAGE("The opposing Darkrai fell asleep!");
+ }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your partner Pokémon with sleep effects")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: playerRight); }
+ TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_SPORE, target: playerRight); }
+ TURN { SWITCH(playerRight, 3); MOVE(playerLeft, MOVE_SPORE, target: playerRight); }
+ TURN { SWITCH(playerRight, 4); MOVE(playerLeft, MOVE_SPORE, target: playerRight); }
+ TURN { SWITCH(playerRight, 5); MOVE(playerLeft, MOVE_SPORE, target: playerRight); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep Clause does not prevent sleeping your partner Pokémon with Yawn")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN {}
+ TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN {}
+ TURN { SWITCH(playerRight, 3); MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN {}
+ TURN { SWITCH(playerRight, 4); MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN {}
+ TURN { SWITCH(playerRight, 5); MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN {}
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Sleep moves used after being Encore'd are prevented when sleep clause is active")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_SPORE, target: playerLeft); MOVE(playerRight, MOVE_ENCORE, target: opponentLeft); }
+ TURN { SWITCH(playerLeft, 2); FORCED_MOVE(opponentLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ MESSAGE("Zigzagoon used Encore!");
+ MESSAGE("Go! Zigzagoon!");
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ }
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Spore'ing opponent after Yawn'ing partner does not prevent Yawn's effect from sleeping partner")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: playerRight); }
+ TURN { SWITCH(playerRight, 2); MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN { MOVE(playerLeft, MOVE_SPORE, target: opponentLeft); MOVE(playerRight, MOVE_SPORE, target: opponentRight); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ MESSAGE("Go! Zigzagoon!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentLeft);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentLeft, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, playerRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponentRight);
+ MESSAGE("The opposing Zigzagoon fell asleep!");
+ STATUS_ICON(opponentRight, sleep: TRUE);
+ }
+ MESSAGE("Zigzagoon fell asleep!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Sleep Clause: Opponent Spore'ing player's partner after partner was Yawn'd by player does not prevent Spore's effect from sleeping partner and activating clause")
+{
+ GIVEN {
+ FLAG_SET(B_FLAG_SLEEP_CLAUSE);
+ ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_SLEEP);
+ ASSUME(GetMoveEffect(MOVE_YAWN) == EFFECT_YAWN);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ PLAYER(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ OPPONENT(SPECIES_ZIGZAGOON);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_YAWN, target: playerRight); }
+ TURN { MOVE(opponentLeft, MOVE_SPORE, target: playerRight); MOVE(opponentRight, MOVE_SPORE, target:playerLeft); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, playerLeft);
+ MESSAGE("Zigzagoon grew drowsy!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerRight);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerRight, sleep: TRUE);
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentRight);
+ ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, playerLeft);
+ MESSAGE("Zigzagoon fell asleep!");
+ STATUS_ICON(playerLeft, sleep: TRUE);
+ }
+ MESSAGE("Sleep Clause kept Zigzagoon awake!");
+ }
+}
diff --git a/test/battle/spread_moves.c b/test/battle/spread_moves.c
new file mode 100644
index 0000000000..2791ca0ea5
--- /dev/null
+++ b/test/battle/spread_moves.c
@@ -0,0 +1,435 @@
+#include "global.h"
+#include "test/battle.h"
+
+DOUBLE_BATTLE_TEST("Spread Moves: Ability and Item effects activate correctly after a multi target move")
+{
+ // TODO: Might be a bug, verify on cardridge
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LUM_BERRY); }
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_COVERT_CLOAK); }
+ OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(260); HP(131); };
+ OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_BUTTON); }
+ OPPONENT(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_PIKACHU);
+ } WHEN {
+ TURN {
+ MOVE(opponentRight, MOVE_HEAT_WAVE);
+ MOVE(playerLeft, MOVE_HYPER_VOICE);
+ SEND_OUT(opponentRight, 3);
+ SEND_OUT(opponentLeft, 2);
+ }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
+ MESSAGE("The opposing Wobbuffet is switched out with the Eject Button!");
+ MESSAGE("2 sent out Pikachu!");
+ ABILITY_POPUP(opponentLeft, ABILITY_EMERGENCY_EXIT);
+ MESSAGE("2 sent out Wynaut!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: No damage will be dealt to a mon in an invulnerable position")
+{
+ u32 attackingMove = 0, invulMove = 0;
+ PARAMETRIZE { attackingMove = MOVE_HYPER_VOICE; invulMove = MOVE_FLY; }
+ PARAMETRIZE { attackingMove = MOVE_LAVA_PLUME; invulMove = MOVE_FLY; }
+ PARAMETRIZE { attackingMove = MOVE_HYPER_VOICE; invulMove = MOVE_DIVE; }
+ PARAMETRIZE { attackingMove = MOVE_LAVA_PLUME; invulMove = MOVE_DIVE; }
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveTarget(MOVE_LAVA_PLUME) == MOVE_TARGET_FOES_AND_ALLY);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_ZAPDOS);
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponentLeft, invulMove, target: playerLeft); MOVE(playerLeft, attackingMove); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, attackingMove, playerLeft);
+ NOT HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: A spread move attack will activate both resist berries")
+{
+ s16 opponentLeftDmg[2];
+ s16 opponentRightDmg[2];
+
+ GIVEN {
+ PLAYER(SPECIES_GARDEVOIR);
+ PLAYER(SPECIES_RALTS);
+ OPPONENT(SPECIES_RAICHU) { Item(ITEM_CHILAN_BERRY); }
+ OPPONENT(SPECIES_SANDSLASH) { Item(ITEM_CHILAN_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_HYPER_VOICE); }
+ TURN { MOVE(playerLeft, MOVE_HYPER_VOICE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentLeft);
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Raichu!");
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Sandslash!");
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[0]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[0]);
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[1]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[1]);
+ } THEN {
+ EXPECT_MUL_EQ(opponentLeftDmg[1], Q_4_12(0.5), opponentLeftDmg[0]);
+ EXPECT_MUL_EQ(opponentRightDmg[1], Q_4_12(0.5), opponentRightDmg[0]);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: If a spread move attack will activate a resist berries on one pokemon, only the damage for that mon will be reduced")
+{
+ s16 opponentLeftDmg[2];
+ s16 opponentRightDmg[2];
+
+ GIVEN {
+ PLAYER(SPECIES_GARDEVOIR);
+ PLAYER(SPECIES_RALTS);
+ OPPONENT(SPECIES_RAICHU)
+ OPPONENT(SPECIES_SANDSLASH) { Item(ITEM_CHILAN_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_HYPER_VOICE); }
+ TURN { MOVE(playerLeft, MOVE_HYPER_VOICE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponentRight);
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Sandslash!");
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[0]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[0]);
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[1]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[1]);
+ } THEN {
+ EXPECT_EQ(opponentLeftDmg[1], opponentLeftDmg[0]);
+ EXPECT_MUL_EQ(opponentRightDmg[1], Q_4_12(0.5), opponentRightDmg[0]);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: A spread move attack will be weakened by strong winds on both targets")
+{
+ s16 opponentLeftDmg[2];
+ s16 opponentRightDmg[2];
+
+ GIVEN {
+ PLAYER(SPECIES_GARDEVOIR);
+ PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_AIR_LOCK); }
+ PLAYER(SPECIES_RALTS);
+ OPPONENT(SPECIES_ZAPDOS)
+ OPPONENT(SPECIES_RAYQUAZA) { Moves(MOVE_DRAGON_ASCENT, MOVE_CELEBRATE); }
+ } WHEN {
+ TURN { MOVE(opponentRight, MOVE_CELEBRATE, gimmick: GIMMICK_MEGA); MOVE(playerLeft, MOVE_ROCK_SLIDE); }
+ TURN { SWITCH(playerRight, 2); MOVE(opponentRight, MOVE_CELEBRATE); MOVE(playerLeft, MOVE_ROCK_SLIDE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[0]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[0]);
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[1]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[1]);
+ } THEN {
+ EXPECT_MUL_EQ(opponentLeftDmg[0], Q_4_12(0.5), opponentLeftDmg[1]);
+ EXPECT_MUL_EQ(opponentRightDmg[0], Q_4_12(0.5), opponentRightDmg[1]);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: A spread move attack will be weakened by strong winds on one of the targets")
+{
+ s16 opponentLeftDmg[2];
+ s16 opponentRightDmg[2];
+
+ GIVEN {
+ PLAYER(SPECIES_GARDEVOIR);
+ PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_AIR_LOCK); }
+ PLAYER(SPECIES_RALTS);
+ OPPONENT(SPECIES_DONPHAN)
+ OPPONENT(SPECIES_RAYQUAZA) { Moves(MOVE_DRAGON_ASCENT, MOVE_CELEBRATE); }
+ } WHEN {
+ TURN { MOVE(opponentRight, MOVE_CELEBRATE, gimmick: GIMMICK_MEGA); MOVE(playerLeft, MOVE_ROCK_SLIDE); }
+ TURN { SWITCH(playerRight, 2); MOVE(opponentRight, MOVE_CELEBRATE); MOVE(playerLeft, MOVE_ROCK_SLIDE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[0]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[0]);
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft);
+ HP_BAR(opponentLeft, captureDamage: &opponentLeftDmg[1]);
+ HP_BAR(opponentRight, captureDamage: &opponentRightDmg[1]);
+ } THEN {
+ EXPECT_EQ(opponentLeftDmg[1], opponentLeftDmg[0]);
+ EXPECT_MUL_EQ(opponentRightDmg[0], Q_4_12(0.5), opponentRightDmg[1]);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (right) and Lightning Rod (left)")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_MIMIKYU);
+ OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
+ OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); HP(1); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_DISCHARGE); }
+ } SCENE {
+ ABILITY_POPUP(opponentLeft, ABILITY_LIGHTNING_ROD);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft);
+ ABILITY_POPUP(playerRight, ABILITY_DISGUISE);
+ ABILITY_POPUP(opponentRight, ABILITY_VOLT_ABSORB);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (left) and Lightning Rod (reft)")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_MIMIKYU);
+ OPPONENT(SPECIES_LANTURN) { Ability(ABILITY_VOLT_ABSORB); HP(1); }
+ OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_DISCHARGE); }
+ } SCENE {
+ ABILITY_POPUP(opponentRight, ABILITY_LIGHTNING_ROD);
+ ABILITY_POPUP(opponentLeft, ABILITY_VOLT_ABSORB);
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft);
+ ABILITY_POPUP(playerRight, ABILITY_DISGUISE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Eiscue and Mimikyu (Based on vanilla games)")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);
+ ASSUME(GetMoveCategory(MOVE_EARTHQUAKE) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_EISCUE);
+ OPPONENT(SPECIES_MIMIKYU);
+ OPPONENT(SPECIES_EISCUE);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_EARTHQUAKE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, playerLeft);
+ ABILITY_POPUP(opponentLeft, ABILITY_DISGUISE);
+ ABILITY_POPUP(playerRight, ABILITY_ICE_FACE);
+ ABILITY_POPUP(opponentRight, ABILITY_ICE_FACE);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Spread move, Gem Boosted, vs Resist Berries")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_WOBBUFFET) { Speed(40); Item(ITEM_NORMAL_GEM); }
+ PLAYER(SPECIES_WYNAUT) { Speed(30); }
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Item(ITEM_CHILAN_BERRY); }
+ OPPONENT(SPECIES_WYNAUT) { Speed(10); Item(ITEM_CHILAN_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_HYPER_VOICE); }
+ } SCENE {
+ MESSAGE("The Normal Gem strengthened Wobbuffet's power!");
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Wobbuffet!");
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Wynaut!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Explosion, Gem Boosted, vs Resist Berries")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_EXPLOSION) == MOVE_TARGET_FOES_AND_ALLY);
+ PLAYER(SPECIES_WOBBUFFET) { Speed(40); Item(ITEM_NORMAL_GEM); }
+ PLAYER(SPECIES_MISDREAVUS) { Speed(30); }
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(20); Item(ITEM_CHILAN_BERRY); }
+ OPPONENT(SPECIES_WYNAUT) { Speed(10); Item(ITEM_CHILAN_BERRY); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_EXPLOSION); }
+ } SCENE {
+ MESSAGE("The Normal Gem strengthened Wobbuffet's power!");
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Wobbuffet!");
+ MESSAGE("The Chilan Berry weakened the damage to the opposing Wynaut!");
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
+ MESSAGE("It doesn't affect Misdreavus…");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs Eiscue and Mimikyu with 1 Eject Button")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_RAZOR_LEAF) == MOVE_TARGET_BOTH);
+ ASSUME(GetMoveCategory(MOVE_RAZOR_LEAF) == DAMAGE_CATEGORY_PHYSICAL);
+ PLAYER(SPECIES_WOBBUFFET) { Speed(40); }
+ PLAYER(SPECIES_WYNAUT) { Speed(30); }
+ OPPONENT(SPECIES_MIMIKYU) { Speed(20); Item(ITEM_EJECT_BUTTON); }
+ OPPONENT(SPECIES_EISCUE) { Speed(10); }
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_RAZOR_LEAF); SEND_OUT(opponentLeft, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_RAZOR_LEAF, playerLeft);
+ ABILITY_POPUP(opponentLeft, ABILITY_DISGUISE);
+ ABILITY_POPUP(opponentRight, ABILITY_ICE_FACE);
+ MESSAGE("The opposing Mimikyu is switched out with the Eject Button!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs Wide Guard")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_WOBBUFFET) { Speed(40); }
+ PLAYER(SPECIES_WYNAUT) { Speed(20); }
+ OPPONENT(SPECIES_WOBBUFFET) { Speed(30); }
+ OPPONENT(SPECIES_WYNAUT) { Speed(10); }
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_WIDE_GUARD); MOVE(opponentLeft, MOVE_HYPER_VOICE); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_WIDE_GUARD, playerLeft);
+ MESSAGE("Wide Guard protected your team!");
+ MESSAGE("The opposing Wobbuffet used Hyper Voice!");
+ MESSAGE("Wobbuffet protected itself!");
+ MESSAGE("Wynaut protected itself!");
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Spread move vs one protecting mon")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_PROTECT); MOVE(playerLeft, MOVE_HYPER_VOICE); }
+ } SCENE {
+ MESSAGE("The opposing Wobbuffet used Protect!");
+ MESSAGE("Wobbuffet used Hyper Voice!");
+ MESSAGE("The opposing Wobbuffet protected itself!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Super Effective Message on both opposing mons")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_GOLEM);
+ OPPONENT(SPECIES_ONIX);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_PRECIPICE_BLADES); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PRECIPICE_BLADES, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
+ MESSAGE("It's super effective on the opposing Golem and Onix!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Super Effective Message on both player mons")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_GOLEM);
+ PLAYER(SPECIES_ONIX);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_PRECIPICE_BLADES); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PRECIPICE_BLADES, opponentLeft);
+ HP_BAR(playerLeft);
+ HP_BAR(playerRight);
+ MESSAGE("It's super effective on Golem and Onix!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Not very effective Message on both opposing mons")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_CHIKORITA);
+ OPPONENT(SPECIES_TREECKO);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_PRECIPICE_BLADES); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PRECIPICE_BLADES, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
+ MESSAGE("It's not very effective on the opposing Chikorita and Treecko!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Not very effective message on both player mons")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_CHIKORITA);
+ PLAYER(SPECIES_TREECKO);
+ OPPONENT(SPECIES_WOBBUFFET);
+ OPPONENT(SPECIES_WYNAUT);
+ } WHEN {
+ TURN { MOVE(opponentLeft, MOVE_PRECIPICE_BLADES); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_PRECIPICE_BLADES, opponentLeft);
+ HP_BAR(playerLeft);
+ HP_BAR(playerRight);
+ MESSAGE("It's not very effective on Chikorita and Treecko!");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Doesn't affect message on both opposing mons")
+{
+ GIVEN {
+ ASSUME(GetMoveTarget(MOVE_PRECIPICE_BLADES) == MOVE_TARGET_BOTH);
+ PLAYER(SPECIES_WOBBUFFET);
+ PLAYER(SPECIES_WYNAUT);
+ OPPONENT(SPECIES_PIDGEY);
+ OPPONENT(SPECIES_HOOTHOOT);
+ } WHEN {
+ TURN { MOVE(playerLeft, MOVE_PRECIPICE_BLADES); }
+ } SCENE {
+ NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_PRECIPICE_BLADES, playerLeft);
+ MESSAGE("It doesn't affect the opposing Pidgey and Hoothoot…");
+ }
+}
+
+DOUBLE_BATTLE_TEST("Spread Moves: Unless move hits every target user will not include partner in the target count")
+{
+ GIVEN {
+ PLAYER(SPECIES_SANDSLASH);
+ PLAYER(SPECIES_WYNAUT) { HP(1); }
+ PLAYER(SPECIES_RALTS);
+ OPPONENT(SPECIES_TORKOAL);
+ OPPONENT(SPECIES_TORKOAL);
+ } WHEN {
+ TURN { MOVE(opponentRight, MOVE_ICY_WIND); MOVE(playerLeft, MOVE_ROCK_SLIDE); SEND_OUT(playerRight, 2); }
+ } SCENE {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ICY_WIND, opponentRight);
+ HP_BAR(playerLeft);
+ HP_BAR(playerRight);
+
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_SLIDE, playerLeft);
+ HP_BAR(opponentLeft);
+ HP_BAR(opponentRight);
+ MESSAGE("It's super effective on the opposing Torkoal and Torkoal!");
+ }
+}
diff --git a/test/battle/terrain/starting_terrain.c b/test/battle/starting_status/terrain.c
similarity index 100%
rename from test/battle/terrain/starting_terrain.c
rename to test/battle/starting_status/terrain.c
diff --git a/test/battle/status1/burn.c b/test/battle/status1/burn.c
index 63d6506fb6..c37768cedf 100644
--- a/test/battle/status1/burn.c
+++ b/test/battle/status1/burn.c
@@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Burn reduces Attack by 50%", s16 damage)
PARAMETRIZE { burned = FALSE; }
PARAMETRIZE { burned = TRUE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { if (burned) Status1(STATUS1_BURN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/status1/freeze.c b/test/battle/status1/freeze.c
index f218430909..ed83675457 100644
--- a/test/battle/status1/freeze.c
+++ b/test/battle/status1/freeze.c
@@ -17,7 +17,7 @@ SINGLE_BATTLE_TEST("Freeze has a 20% chance of being thawed")
SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@@ -32,7 +32,7 @@ SINGLE_BATTLE_TEST("Freeze is thawed by opponent's Fire-type attacks")
SINGLE_BATTLE_TEST("Freeze is thawed by user's Flame Wheel")
{
GIVEN {
- ASSUME(gMovesInfo[MOVE_FLAME_WHEEL].thawsUser);
+ ASSUME(MoveThawsUser(MOVE_FLAME_WHEEL));
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_FREEZE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
diff --git a/test/battle/status1/frostbite.c b/test/battle/status1/frostbite.c
index a7776e5e2e..f45508f800 100644
--- a/test/battle/status1/frostbite.c
+++ b/test/battle/status1/frostbite.c
@@ -7,7 +7,7 @@ SINGLE_BATTLE_TEST("Frostbite reduces the special attack by 50 percent")
s16 normaleDamage;
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); }
} WHEN {
diff --git a/test/battle/status2/confusion.c b/test/battle/status2/confusion.c
index 96ed2e1362..c2ee92dd09 100644
--- a/test/battle/status2/confusion.c
+++ b/test/battle/status2/confusion.c
@@ -5,7 +5,7 @@ SINGLE_BATTLE_TEST("Confusion adds a 50/33% chance to hit self with 40 power")
{
s16 damage[2];
- ASSUME(gMovesInfo[MOVE_TACKLE].power == 40);
+ ASSUME(GetMovePower(MOVE_TACKLE) == 40);
PASSES_RANDOMLY(B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50, 100, RNG_CONFUSION);
GIVEN {
@@ -26,3 +26,21 @@ SINGLE_BATTLE_TEST("Confusion adds a 50/33% chance to hit self with 40 power")
EXPECT_EQ(damage[0], damage[1]);
}
}
+
+SINGLE_BATTLE_TEST("Confusion self hit does not consume Gems")
+{
+ PASSES_RANDOMLY(B_CONFUSION_SELF_DMG_CHANCE >= GEN_7 ? 33 : 50, 100, RNG_CONFUSION);
+ GIVEN {
+ PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); };
+ OPPONENT(SPECIES_WOBBUFFET);
+ } WHEN {
+ TURN { MOVE(opponent, MOVE_CONFUSE_RAY); MOVE(player, MOVE_TACKLE); }
+ } SCENE {
+ NONE_OF {
+ ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
+ ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
+ MESSAGE("Normal Gem strengthened Wobbuffet's power!");
+ }
+ MESSAGE("It hurt itself in its confusion!");
+ }
+}
diff --git a/test/battle/weather/rain.c b/test/battle/weather/rain.c
index 3359d25a81..0620aae100 100644
--- a/test/battle/weather/rain.c
+++ b/test/battle/weather/rain.c
@@ -4,8 +4,8 @@
// Please add Rain interactions with move, item and ability effects on their respective files.
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
}
SINGLE_BATTLE_TEST("Rain multiplies the power of Fire-type moves by 0.5x", s16 damage)
diff --git a/test/battle/weather/sandstorm.c b/test/battle/weather/sandstorm.c
index 38502cbbc7..dcac3f71c3 100644
--- a/test/battle/weather/sandstorm.c
+++ b/test/battle/weather/sandstorm.c
@@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Sandstorm multiplies the special defense of Rock-types by 1.
PARAMETRIZE { move = MOVE_SANDSTORM; }
PARAMETRIZE { move = MOVE_CELEBRATE; }
GIVEN {
- ASSUME(gMovesInfo[MOVE_SWIFT].category == DAMAGE_CATEGORY_SPECIAL);
+ ASSUME(GetMoveCategory(MOVE_SWIFT) == DAMAGE_CATEGORY_SPECIAL);
PLAYER(SPECIES_WOBBUFFET) ;
OPPONENT(SPECIES_NOSEPASS);
} WHEN {
diff --git a/test/battle/weather/snow.c b/test/battle/weather/snow.c
index 6c084f6b7a..7b4e4cb2ff 100644
--- a/test/battle/weather/snow.c
+++ b/test/battle/weather/snow.c
@@ -4,10 +4,10 @@
// Please add Snow interactions with move, item and ability effects on their respective files.
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE);
+ ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE);
ASSUME(gSpeciesInfo[SPECIES_WOBBUFFET].types[0] != TYPE_ICE && gSpeciesInfo[SPECIES_WOBBUFFET].types[1] != TYPE_ICE);
ASSUME(gSpeciesInfo[SPECIES_GLALIE].types[0] == TYPE_ICE || gSpeciesInfo[SPECIES_GLALIE].types[1] == TYPE_ICE);
- ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
+ ASSUME(GetMoveCategory(MOVE_TACKLE) == DAMAGE_CATEGORY_PHYSICAL);
}
SINGLE_BATTLE_TEST("Snow multiplies the defense of Ice-types by 1.5x", s16 damage)
diff --git a/test/battle/weather/sunlight.c b/test/battle/weather/sunlight.c
index 6cf6348987..796ad3c3af 100644
--- a/test/battle/weather/sunlight.c
+++ b/test/battle/weather/sunlight.c
@@ -4,8 +4,8 @@
// Please add Sunlight interactions with move, item and ability effects on their respective files.
ASSUMPTIONS
{
- ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
- ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
+ ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE);
+ ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER);
}
SINGLE_BATTLE_TEST("Sunlight multiplies the power of Fire-type moves by 1.5x", s16 damage)
diff --git a/test/pokemon.c b/test/pokemon.c
index f5431559ee..00b08ebb79 100644
--- a/test/pokemon.c
+++ b/test/pokemon.c
@@ -210,6 +210,50 @@ TEST("givemon [simple]")
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
}
+TEST("givemon respects perfectIVCount")
+{
+ ZeroPlayerPartyMons();
+ u32 perfectIVs[6] = {0};
+
+ ASSUME(gSpeciesInfo[SPECIES_MEW].perfectIVCount == 3);
+ ASSUME(gSpeciesInfo[SPECIES_CELEBI].perfectIVCount == 3);
+ ASSUME(gSpeciesInfo[SPECIES_JIRACHI].perfectIVCount == 3);
+ ASSUME(gSpeciesInfo[SPECIES_MANAPHY].perfectIVCount == 3);
+ ASSUME(gSpeciesInfo[SPECIES_VICTINI].perfectIVCount == 3);
+ ASSUME(gSpeciesInfo[SPECIES_DIANCIE].perfectIVCount == 3);
+
+ RUN_OVERWORLD_SCRIPT(
+ givemon SPECIES_MEW, 100;
+ givemon SPECIES_CELEBI, 100;
+ givemon SPECIES_JIRACHI, 100;
+ givemon SPECIES_MANAPHY, 100;
+ givemon SPECIES_VICTINI, 100;
+ givemon SPECIES_DIANCIE, 100;
+ );
+
+ EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_MEW);
+ EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_SPECIES), SPECIES_CELEBI);
+ EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_SPECIES), SPECIES_JIRACHI);
+ EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_SPECIES), SPECIES_MANAPHY);
+ EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_SPECIES), SPECIES_VICTINI);
+ EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_SPECIES), SPECIES_DIANCIE);
+ EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_LEVEL), 100);
+ EXPECT_EQ(GetMonData(&gPlayerParty[1], MON_DATA_LEVEL), 100);
+ EXPECT_EQ(GetMonData(&gPlayerParty[2], MON_DATA_LEVEL), 100);
+ EXPECT_EQ(GetMonData(&gPlayerParty[3], MON_DATA_LEVEL), 100);
+ EXPECT_EQ(GetMonData(&gPlayerParty[4], MON_DATA_LEVEL), 100);
+ EXPECT_EQ(GetMonData(&gPlayerParty[5], MON_DATA_LEVEL), 100);
+ for (u32 j = 0; j < 6; j++)
+ {
+ for (u32 k = 0; k < NUM_STATS; k++)
+ {
+ if (GetMonData(&gPlayerParty[j], MON_DATA_HP_IV + k) == MAX_PER_STAT_IVS)
+ perfectIVs[j]++;
+ }
+ EXPECT_GE(perfectIVs[j], 3);
+ }
+}
+
TEST("givemon [moves]")
{
ZeroPlayerPartyMons();
diff --git a/test/test_runner.c b/test/test_runner.c
index f7c4cf780e..7a81d1dc9f 100644
--- a/test/test_runner.c
+++ b/test/test_runner.c
@@ -10,7 +10,7 @@
#include "test_runner.h"
#include "test/test.h"
-#define TIMEOUT_SECONDS 55
+#define TIMEOUT_SECONDS 60
void CB2_TestRunner(void);
@@ -276,7 +276,7 @@ top:
{
if (gTasks[i].isActive)
{
- Test_MgbaPrintf("%p: task not freed", gTasks[i].func);
+ Test_MgbaPrintf(":L%s:%d - %p: task not freed", gTestRunnerState.test->filename, SourceLine(0), gTasks[i].func);
gTestRunnerState.result = TEST_RESULT_FAIL;
}
}
@@ -356,9 +356,14 @@ top:
if (gTestRunnerState.result == TEST_RESULT_PASS)
{
if (gTestRunnerState.result != gTestRunnerState.expectedResult)
+ {
+ Test_MgbaPrintf(":L%s:%d", gTestRunnerState.test->filename, SourceLine(0));
Test_MgbaPrintf(":U%s%s\e[0m", color, result);
+ }
else
+ {
Test_MgbaPrintf(":P%s%s\e[0m", color, result);
+ }
}
else if (gTestRunnerState.result == TEST_RESULT_ASSUMPTION_FAIL)
Test_MgbaPrintf(":A%s%s\e[0m", color, result);
@@ -490,6 +495,7 @@ static void Intr_Timer2(void)
if (gTestRunnerState.state == STATE_RUN_TEST)
gTestRunnerState.state = STATE_REPORT_RESULT;
gTestRunnerState.result = TEST_RESULT_TIMEOUT;
+ Test_MgbaPrintf(":L%s:%d - TIMEOUT", gTestRunnerState.test->filename, SourceLine(0));
ReinitCallbacks();
IRQ_LR = ((uintptr_t)JumpToAgbMainLoop & ~1) + 4;
}
diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c
index 04db97e85d..eda9c1eda5 100644
--- a/test/test_runner_battle.c
+++ b/test/test_runner_battle.c
@@ -160,6 +160,7 @@ static void BattleTest_SetUp(void *data)
{
const struct BattleTest *test = data;
memset(STATE, 0, sizeof(*STATE));
+ TestInitConfigData();
InvokeTestFunction(test);
STATE->parameters = STATE->parametersCount;
if (STATE->parametersCount == 0 && test->resultsSize > 0)
@@ -365,6 +366,7 @@ u32 RandomUniform(enum RandomTag tag, u32 lo, u32 hi)
if (tag == STATE->rngTag)
{
+ STATE->didRunRandomly = TRUE;
u32 n = hi - lo + 1;
if (STATE->trials == 1)
{
@@ -401,6 +403,7 @@ u32 RandomUniformExcept(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32
if (tag == STATE->rngTag)
{
+ STATE->didRunRandomly = TRUE;
if (STATE->trials == 1)
{
u32 n = 0, i;
@@ -449,6 +452,7 @@ u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
if (tag == STATE->rngTag)
{
+ STATE->didRunRandomly = TRUE;
if (STATE->trials == 1)
{
STATE->trials = n;
@@ -522,6 +526,7 @@ const void *RandomElementArray(enum RandomTag tag, const void *array, size_t siz
if (tag == STATE->rngTag)
{
+ STATE->didRunRandomly = TRUE;
if (STATE->trials == 1)
{
STATE->trials = count;
@@ -1156,6 +1161,7 @@ static s32 TryMessage(s32 i, s32 n, const u8 *string)
switch (string[j])
{
case CHAR_SPACE:
+ case CHAR_NBSP:
case CHAR_PROMPT_SCROLL:
case CHAR_PROMPT_CLEAR:
case CHAR_NEWLINE:
@@ -1349,6 +1355,7 @@ static void CB2_BattleTest_NextParameter(void)
else
{
STATE->trials = 0;
+ STATE->didRunRandomly = FALSE;
BattleTest_Run(gTestRunnerState.test->data);
}
}
@@ -1366,7 +1373,6 @@ static inline rng_value_t MakeRngValue(const u16 seed)
static void CB2_BattleTest_NextTrial(void)
{
- ClearFlagAfterTest();
TearDownBattle();
SetMainCallback2(CB2_BattleTest_NextParameter);
@@ -1395,6 +1401,9 @@ static void CB2_BattleTest_NextTrial(void)
}
else
{
+ if (STATE->rngTag && !STATE->didRunRandomly && STATE->expectedRatio != Q_4_12(0.0) && STATE->expectedRatio != Q_4_12(1.0))
+ Test_ExitWithResult(TEST_RESULT_INVALID, SourceLine(0), ":L%s:%d: PASSES_RANDOMLY specified but no Random* call with that tag executed", gTestRunnerState.test->filename, SourceLine(0));
+
// This is a tolerance of +/- ~2%.
if (abs(STATE->observedRatio - STATE->expectedRatio) <= Q_4_12(0.02))
gTestRunnerState.result = TEST_RESULT_PASS;
@@ -1408,6 +1417,7 @@ static void BattleTest_TearDown(void *data)
// Free resources that aren't cleaned up when the battle was
// aborted unexpectedly.
ClearFlagAfterTest();
+ TestFreeConfigData();
if (STATE->tearDownBattle)
TearDownBattle();
}
@@ -1504,6 +1514,12 @@ void SetFlagForTest(u32 sourceLine, u16 flagId)
FlagSet(flagId);
}
+void TestSetConfig(u32 sourceLine, enum GenConfigTag configTag, u32 value)
+{
+ INVALID_IF(!STATE->runGiven, "WITH_CONFIG outside of GIVEN");
+ SetGenConfig(configTag, value);
+}
+
void ClearFlagAfterTest(void)
{
if (DATA.flagId != 0)
@@ -1758,7 +1774,8 @@ void Moves_(u32 sourceLine, u16 moves[MAX_MON_MOVES])
break;
INVALID_IF(moves[i] >= MOVES_COUNT, "Illegal move: %d", moves[i]);
SetMonData(DATA.currentMon, MON_DATA_MOVE1 + i, &moves[i]);
- SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &gMovesInfo[moves[i]].pp);
+ u32 pp = GetMovePP(moves[i]);
+ SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &pp);
}
DATA.explicitMoves[DATA.currentSide] |= 1 << DATA.currentPartyIndex;
}
@@ -2076,7 +2093,8 @@ void MoveGetIdAndSlot(s32 battlerId, struct MoveContext *ctx, u32 *moveId, u32 *
{
INVALID_IF(DATA.explicitMoves[battlerId & BIT_SIDE] & (1 << DATA.currentMonIndexes[battlerId]), "Missing explicit %S", GetMoveName(ctx->move));
SetMonData(mon, MON_DATA_MOVE1 + i, &ctx->move);
- SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &gMovesInfo[ctx->move].pp);
+ u32 pp = GetMovePP(ctx->move);
+ SetMonData(DATA.currentMon, MON_DATA_PP1 + i, &pp);
*moveSlot = i;
*moveId = ctx->move;
break;
@@ -2105,7 +2123,7 @@ void MoveGetIdAndSlot(s32 battlerId, struct MoveContext *ctx, u32 *moveId, u32 *
// Check invalid item usage.
INVALID_IF(ctx->gimmick == GIMMICK_MEGA && holdEffect != HOLD_EFFECT_MEGA_STONE && species != SPECIES_RAYQUAZA, "Cannot Mega Evolve without a Mega Stone");
INVALID_IF(ctx->gimmick == GIMMICK_Z_MOVE && holdEffect != HOLD_EFFECT_Z_CRYSTAL, "Cannot use a Z-Move without a Z-Crystal");
- INVALID_IF(ctx->gimmick == GIMMICK_Z_MOVE && ItemId_GetSecondaryId(item) != gMovesInfo[*moveId].type
+ INVALID_IF(ctx->gimmick == GIMMICK_Z_MOVE && ItemId_GetSecondaryId(item) != GetMoveType(*moveId)
&& GetSignatureZMove(*moveId, species, item) == MOVE_NONE
&& *moveId != MOVE_PHOTON_GEYSER, // exception because test won't recognize Ultra Necrozma pre-Burst
"Cannot turn %S into a Z-Move with %S", GetMoveName(ctx->move), ItemId_GetName(item));
@@ -2167,7 +2185,7 @@ void Move(u32 sourceLine, struct BattlePokemon *battler, struct MoveContext ctx)
MoveGetIdAndSlot(battlerId, &ctx, &moveId, &moveSlot, sourceLine);
target = MoveGetTarget(battlerId, moveId, &ctx, sourceLine);
- if (gMovesInfo[moveId].effect == EFFECT_REVIVAL_BLESSING)
+ if (GetMoveEffect(moveId) == EFFECT_REVIVAL_BLESSING)
requirePartyIndex = MoveGetFirstFainted(battlerId) != PARTY_SIZE;
// Check party menu moves.
diff --git a/test/text.c b/test/text.c
index 17d9ab0ee9..781aaaed3e 100644
--- a/test/text.c
+++ b/test/text.c
@@ -23,10 +23,10 @@ TEST("Move names fit on Pokemon Summary Screen")
u32 move = MOVE_NONE;
for (i = 1; i < MOVES_COUNT; i++)
{
- PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; }
+ PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; }
}
- //DebugPrintf("Move %d: %S", GetStringWidth(fontId, gMovesInfo[move].name, 0), gMovesInfo[move].name);
- EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx);
+ //DebugPrintf("Move %d: %S", GetStringWidth(fontId, GetMoveName(move), 0), GetMoveName(move));
+ EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx);
}
TEST("Move names fit on Battle Screen")
@@ -36,28 +36,30 @@ TEST("Move names fit on Battle Screen")
u32 move = MOVE_NONE;
for (i = 1; i < MOVES_COUNT; i++)
{
- PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; }
+ PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; }
}
- EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx);
+ EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx);
}
TEST("Move names fit on Contest Screen")
{
u32 i;
- const u32 fontId = FONT_NARROWER, widthPx = 61;
+ const u32 fontId = FONT_NARROWER, widthPx = 59;
u32 move = MOVE_NONE;
for (i = 1; i < MOVES_COUNT; i++)
{
- PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; }
+ PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; }
}
// All moves explicitly listed here are too big to fit.
switch (move)
{
+ case MOVE_STOMPING_TANTRUM:
case MOVE_NATURES_MADNESS:
- EXPECT_GT(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx);
+ case MOVE_DOUBLE_IRON_BASH:
+ EXPECT_GT(GetStringWidth(fontId, GetMoveName(move), 0), widthPx);
break;
default:
- EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx);
+ EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx);
break;
}
}
@@ -65,16 +67,13 @@ TEST("Move names fit on Contest Screen")
TEST("Move names fit on TMs & HMs Bag Screen")
{
u32 i;
- const u32 fontId = FONT_NARROWER, widthPx = 63;
+ const u32 fontId = FONT_NARROWER, widthPx = 61;
u32 move = MOVE_NONE;
- for (i = 1; i < ITEMS_COUNT; i++)
+ for (i = 1; i < MOVES_COUNT; i++)
{
- if (gItemsInfo[i].pocket == POCKET_TM_HM)
- {
- PARAMETRIZE_LABEL("%S", gMovesInfo[gItemsInfo[i].secondaryId].name) { move = gItemsInfo[i].secondaryId; }
- }
+ PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; }
}
- EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx);
+ EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx);
}
TEST("Move names fit on Move Relearner Screen")
@@ -84,9 +83,9 @@ TEST("Move names fit on Move Relearner Screen")
u32 move = MOVE_NONE;
for (i = 1; i < MOVES_COUNT; i++)
{
- PARAMETRIZE_LABEL("%S", gMovesInfo[i].name) { move = i; }
+ PARAMETRIZE_LABEL("%S", GetMoveName(i)) { move = i; }
}
- EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].name, 0), widthPx);
+ EXPECT_LE(GetStringWidth(fontId, GetMoveName(move), 0), widthPx);
}
TEST("Move descriptions fit on Pokemon Summary Screen")
@@ -96,16 +95,16 @@ TEST("Move descriptions fit on Pokemon Summary Screen")
u32 move = MOVE_NONE;
for (i = 1; i < MOVES_COUNT; i++)
{
- PARAMETRIZE_LABEL("%S", gMovesInfo[i].description) { move = i; }
+ PARAMETRIZE_LABEL("%S", GetMoveDescription(i)) { move = i; }
}
- EXPECT_LE(GetStringWidth(fontId, gMovesInfo[move].description, 0), widthPx);
+ EXPECT_LE(GetStringWidth(fontId, GetMoveDescription(move), 0), widthPx);
}
TEST("Item names fit on Bag Screen (list)")
{
u32 i;
const u32 fontId = FONT_NARROWER;
- const u32 tmHmBerryWidthPx = 71, restWidthPx = 88;
+ const u32 tmHmBerryWidthPx = 61, restWidthPx = 88;
u32 item = ITEM_NONE;
for (i = 1; i < ITEMS_COUNT; i++)
{
@@ -122,7 +121,7 @@ TEST("Item plural names fit on Bag Screen (left box)")
{
u32 i;
// -6 for the question mark in FONT_NORMAL.
- const u32 fontId = FONT_NARROWER, widthPx = 102 - 6;
+ const u32 fontId = FONT_NARROWER, widthPx = 101 - 6;
u32 item = ITEM_NONE;
u8 pluralName[ITEM_NAME_PLURAL_LENGTH + 1];
for (i = 1; i < ITEMS_COUNT; i++)
@@ -133,6 +132,18 @@ TEST("Item plural names fit on Bag Screen (left box)")
EXPECT_LE(GetStringWidth(fontId, pluralName, 0), widthPx);
}
+TEST("Item names fit on PC Storage (list)")
+{
+ u32 i;
+ const u32 fontId = FONT_NARROWER, widthPx = 73;
+ u32 item = ITEM_NONE;
+ for (i = 1; i < ITEMS_COUNT; i++)
+ {
+ PARAMETRIZE_LABEL("%S", gItemsInfo[i].name) { item = i; }
+ }
+ EXPECT_LE(GetStringWidth(fontId, gItemsInfo[item].name, 0), widthPx);
+}
+
TEST("Item plural names fit on PC storage (left box)")
{
u32 i;
@@ -151,108 +162,22 @@ TEST("Item plural names fit on PC storage (left box)")
TEST("Item names fit on Pokemon Storage System")
{
u32 i;
- const u32 fontId = FONT_SMALL_NARROWER, widthPx = 50;
+ const u32 fontId = FONT_SMALL_NARROWER, widthPx = 66;
u32 item = ITEM_NONE;
for (i = 1; i < ITEMS_COUNT; i++)
{
if (gItemsInfo[i].importance) continue;
PARAMETRIZE_LABEL("%S", gItemsInfo[i].name) { item = i; }
}
- // All items explicitly listed here are too big to fit. The ones
- // with a hold effect are listed at the bottom in case you want to
- // focus on making them fit (they are the most likely to appear on
- // the storage system UI, along with anything that could be held
- // in the wild).
+ // All items explicitly listed here are too big to fit.
switch (item)
{
- case ITEM_ENERGY_POWDER:
- case ITEM_PEWTER_CRUNCHIES:
- case ITEM_RAGE_CANDY_BAR:
- case ITEM_LUMIOSE_GALETTE:
- case ITEM_HEALTH_FEATHER:
- case ITEM_MUSCLE_FEATHER:
- case ITEM_RESIST_FEATHER:
- case ITEM_GENIUS_FEATHER:
- case ITEM_CLEVER_FEATHER:
- case ITEM_ABILITY_CAPSULE:
- case ITEM_DYNAMAX_CANDY:
- case ITEM_MAX_MUSHROOMS:
- case ITEM_GOLD_BOTTLE_CAP:
- case ITEM_PRETTY_FEATHER:
- case ITEM_STRANGE_SOUVENIR:
- case ITEM_FOSSILIZED_BIRD:
- case ITEM_FOSSILIZED_FISH:
- case ITEM_FOSSILIZED_DRAKE:
- case ITEM_FOSSILIZED_DINO:
- case ITEM_SURPRISE_MULCH:
- case ITEM_YELLOW_APRICORN:
- case ITEM_GREEN_APRICORN:
- case ITEM_WHITE_APRICORN:
- case ITEM_BLACK_APRICORN:
- case ITEM_THUNDER_STONE:
- case ITEM_GALARICA_WREATH:
- case ITEM_STRAWBERRY_SWEET:
- case ITEM_AUSPICIOUS_ARMOR:
- case ITEM_BIG_BAMBOO_SHOOT:
- case ITEM_GIMMIGHOUL_COIN:
- case ITEM_LEADERS_CREST:
- case ITEM_MALICIOUS_ARMOR:
- case ITEM_TINY_BAMBOO_SHOOT:
- case ITEM_BUG_TERA_SHARD:
- case ITEM_DARK_TERA_SHARD:
- case ITEM_DRAGON_TERA_SHARD:
case ITEM_ELECTRIC_TERA_SHARD:
- case ITEM_FAIRY_TERA_SHARD:
case ITEM_FIGHTING_TERA_SHARD:
- case ITEM_FIRE_TERA_SHARD:
- case ITEM_FLYING_TERA_SHARD:
- case ITEM_GHOST_TERA_SHARD:
- case ITEM_GRASS_TERA_SHARD:
- case ITEM_GROUND_TERA_SHARD:
- case ITEM_ICE_TERA_SHARD:
- case ITEM_NORMAL_TERA_SHARD:
- case ITEM_POISON_TERA_SHARD:
case ITEM_PSYCHIC_TERA_SHARD:
- case ITEM_ROCK_TERA_SHARD:
- case ITEM_STEEL_TERA_SHARD:
- case ITEM_WATER_TERA_SHARD:
- case ITEM_BLACK_AUGURITE:
case ITEM_UNREMARKABLE_TEACUP:
case ITEM_MASTERPIECE_TEACUP:
- case ITEM_FRESH_START_MOCHI:
- case ITEM_STELLAR_TERA_SHARD:
- case ITEM_JUBILIFE_MUFFIN:
- case ITEM_SUPERB_REMEDY:
- case ITEM_AUX_POWERGUARD:
- case ITEM_CHOICE_DUMPLING:
case ITEM_TWICE_SPICED_RADISH:
- // Items with hold effects:
- case ITEM_ELECTRIC_MEMORY:
- case ITEM_FIGHTING_MEMORY:
- case ITEM_GROUND_MEMORY:
- case ITEM_PSYCHIC_MEMORY:
- case ITEM_DRAGON_MEMORY:
- case ITEM_CHARIZARDITE_X:
- case ITEM_CHARIZARDITE_Y:
- case ITEM_ULTRANECROZIUM_Z:
- case ITEM_DEEP_SEA_SCALE:
- case ITEM_DEEP_SEA_TOOTH:
- case ITEM_NEVER_MELT_ICE:
- case ITEM_WEAKNESS_POLICY:
- case ITEM_SAFETY_GOGGLES:
- case ITEM_ADRENALINE_ORB:
- case ITEM_TERRAIN_EXTENDER:
- case ITEM_PROTECTIVE_PADS:
- case ITEM_HEAVY_DUTY_BOOTS:
- case ITEM_UTILITY_UMBRELLA:
- case ITEM_MARANGA_BERRY:
- case ITEM_PUNCHING_GLOVE:
- case ITEM_BOOSTER_ENERGY:
- case ITEM_ADAMANT_CRYSTAL:
- case ITEM_LUSTROUS_GLOBE:
- case ITEM_CORNERSTONE_MASK:
- case ITEM_WELLSPRING_MASK:
- case ITEM_HEARTHFLAME_MASK:
EXPECT_GT(GetStringWidth(fontId, gItemsInfo[item].name, 0), widthPx);
break;
default:
@@ -398,7 +323,7 @@ TEST("Species names fit on Pokemon Storage System")
}
}
EXPECT_LE(GetStringWidth(FONT_NARROWER, gSpeciesInfo[species].speciesName, 0), 66);
- EXPECT_LE(GetStringWidth(FONT_SHORT_NARROW, gSpeciesInfo[species].speciesName, 0), 60);
+ EXPECT_LE(GetStringWidth(FONT_SHORT_NARROWER, gSpeciesInfo[species].speciesName, 0), 60);
}
TEST("Species names fit on Contest Screen")
@@ -434,7 +359,7 @@ TEST("Species names fit on Contest Screen - Rankings")
TEST("Species names fit on Battle Dome Screen")
{
u32 i;
- const u32 fontId = FONT_SHORT_NARROW, widthPx = 60;
+ const u32 fontId = FONT_SHORT_NARROWER, widthPx = 60;
u32 species = SPECIES_NONE;
for (i = 1; i < NUM_SPECIES; i++)
{
diff --git a/tools/learnset_helpers/porymoves_files/b2w2.json b/tools/learnset_helpers/porymoves_files/b2w2.json
index 976b125c6c..bd1762990e 100644
--- a/tools/learnset_helpers/porymoves_files/b2w2.json
+++ b/tools/learnset_helpers/porymoves_files/b2w2.json
@@ -50290,7 +50290,7 @@
"MOVE_SNORE"
]
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/bdsp.json b/tools/learnset_helpers/porymoves_files/bdsp.json
index 8e4ac589d3..af2e75a3ae 100644
--- a/tools/learnset_helpers/porymoves_files/bdsp.json
+++ b/tools/learnset_helpers/porymoves_files/bdsp.json
@@ -46223,7 +46223,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 0,
diff --git a/tools/learnset_helpers/porymoves_files/bw.json b/tools/learnset_helpers/porymoves_files/bw.json
index 7728235c5f..4a93b57602 100644
--- a/tools/learnset_helpers/porymoves_files/bw.json
+++ b/tools/learnset_helpers/porymoves_files/bw.json
@@ -45087,7 +45087,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/dp.json b/tools/learnset_helpers/porymoves_files/dp.json
index 666a6dda58..fdae45c2a6 100644
--- a/tools/learnset_helpers/porymoves_files/dp.json
+++ b/tools/learnset_helpers/porymoves_files/dp.json
@@ -44067,7 +44067,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/hgss.json b/tools/learnset_helpers/porymoves_files/hgss.json
index b0241c96f4..8aaf2714b3 100644
--- a/tools/learnset_helpers/porymoves_files/hgss.json
+++ b/tools/learnset_helpers/porymoves_files/hgss.json
@@ -49305,7 +49305,7 @@
"MOVE_STRING_SHOT"
]
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/la.json b/tools/learnset_helpers/porymoves_files/la.json
index 599596a902..4492a37c69 100644
--- a/tools/learnset_helpers/porymoves_files/la.json
+++ b/tools/learnset_helpers/porymoves_files/la.json
@@ -8433,7 +8433,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/oras.json b/tools/learnset_helpers/porymoves_files/oras.json
index 11a737628e..da1a3bf21f 100644
--- a/tools/learnset_helpers/porymoves_files/oras.json
+++ b/tools/learnset_helpers/porymoves_files/oras.json
@@ -53725,7 +53725,7 @@
"MOVE_SNORE"
]
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/pt.json b/tools/learnset_helpers/porymoves_files/pt.json
index e969777fa6..bf2ace3c59 100644
--- a/tools/learnset_helpers/porymoves_files/pt.json
+++ b/tools/learnset_helpers/porymoves_files/pt.json
@@ -48085,7 +48085,7 @@
"MOVE_SNORE"
]
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/learnset_helpers/porymoves_files/sm.json b/tools/learnset_helpers/porymoves_files/sm.json
index 65255a69fa..d79ab5c4e9 100644
--- a/tools/learnset_helpers/porymoves_files/sm.json
+++ b/tools/learnset_helpers/porymoves_files/sm.json
@@ -48246,7 +48246,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 0,
diff --git a/tools/learnset_helpers/porymoves_files/sv.json b/tools/learnset_helpers/porymoves_files/sv.json
index 04bc72f9e6..190b084611 100644
--- a/tools/learnset_helpers/porymoves_files/sv.json
+++ b/tools/learnset_helpers/porymoves_files/sv.json
@@ -36838,7 +36838,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [],
"PreEvoMoves": [],
"TMMoves": [],
diff --git a/tools/learnset_helpers/porymoves_files/usum.json b/tools/learnset_helpers/porymoves_files/usum.json
index ed4cfb69e0..2587a7de81 100644
--- a/tools/learnset_helpers/porymoves_files/usum.json
+++ b/tools/learnset_helpers/porymoves_files/usum.json
@@ -53477,7 +53477,7 @@
"MOVE_SNORE"
]
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 0,
diff --git a/tools/learnset_helpers/porymoves_files/xy.json b/tools/learnset_helpers/porymoves_files/xy.json
index 8be594e6d7..1cb68d527b 100644
--- a/tools/learnset_helpers/porymoves_files/xy.json
+++ b/tools/learnset_helpers/porymoves_files/xy.json
@@ -47960,7 +47960,7 @@
"EggMoves": [],
"TutorMoves": []
},
- "WORMADAM_PLANT_CLOAK": {
+ "WORMADAM_PLANT": {
"LevelMoves": [
{
"Level": 1,
diff --git a/tools/trainerproc/main.c b/tools/trainerproc/main.c
index b410e810b0..7cddb06930 100644
--- a/tools/trainerproc/main.c
+++ b/tools/trainerproc/main.c
@@ -251,51 +251,6 @@ static bool set_parse_error(struct Parser *p, struct SourceLocation location, co
return false;
}
-static bool show_parse_error(struct Parser *p)
-{
- // Print error message.
- int n = fprintf(stderr, "%s:%d: ", p->source->path, p->error_location.line);
- fprintf(stderr, "error: %s\n", p->error);
-
- // Seek to the line.
- int line, begin, end;
- for (line = 1, begin = 0; begin < p->source->buffer_n; begin++)
- {
- if (p->error_location.line == line)
- break;
- if (p->source->buffer[begin] == '\n')
- line++;
- }
- for (end = begin; end < p->source->buffer_n; end++)
- {
- if (p->source->buffer[end] == '\n')
- break;
- }
-
- // Print the source line.
- fprintf(stderr, "%s:%d: %.*s\n", p->source->path, p->error_location.line, end - begin, &p->source->buffer[begin]);
-
- // Print caret pointing at the column.
- fprintf(stderr, "%*s", n, "");
- for (int column = 1; column < p->error_location.column && begin + column < end; column++)
- {
- unsigned char c = p->source->buffer[begin + column];
- fputc(c == '\t' ? c : ' ', stderr);
- }
- fprintf(stderr, "^\n");
-
- p->error = NULL;
- p->fatal_error = true;
-
- return false;
-}
-
-static bool set_show_parse_error(struct Parser *p, struct SourceLocation location, const char *error)
-{
- set_parse_error(p, location, error);
- return show_parse_error(p);
-}
-
__attribute__((warn_unused_result))
static bool peek_char(struct Parser *p, unsigned char *c)
{
@@ -618,6 +573,59 @@ static bool match_move_identifier(struct Parser *p, struct Token *t)
return true;
}
+static bool show_parse_error(struct Parser *p)
+{
+ // Print error message.
+ int n = fprintf(stderr, "%s:%d: ", p->source->path, p->error_location.line);
+ fprintf(stderr, "error: %s\n", p->error);
+
+ struct Parser p_ = {
+ .source = p->source,
+ .location = { .line = 1, .column = 1 },
+ .offset = 0,
+ };
+
+ for (;;) {
+ if (p->error_location.line == p_.location.line)
+ break;
+ if (!match_empty_line(&p_))
+ skip_line(&p_);
+ if (match_eof(&p_))
+ assert(false);
+ }
+
+ int begin = p_.offset;
+ int end;
+ for (end = begin; end < p->source->buffer_n; end++)
+ {
+ if (p->source->buffer[end] == '\n')
+ break;
+ }
+
+ // Print the source line.
+ fprintf(stderr, "%s:%d: %.*s\n", p->source->path, p->error_location.line, end - begin, &p->source->buffer[begin]);
+
+ // Print caret pointing at the column.
+ fprintf(stderr, "%*s", n, "");
+ for (int column = 1; column < p->error_location.column && begin + column < end; column++)
+ {
+ unsigned char c = p->source->buffer[begin + column];
+ fputc(c == '\t' ? c : ' ', stderr);
+ }
+ fprintf(stderr, "^\n");
+
+ p->error = NULL;
+ p->fatal_error = true;
+
+ return false;
+}
+
+static bool set_show_parse_error(struct Parser *p, struct SourceLocation location, const char *error)
+{
+ set_parse_error(p, location, error);
+ return show_parse_error(p);
+}
+
__attribute__((warn_unused_result))
static bool parse_section(struct Parser *p, struct Token *section)
{
@@ -1545,6 +1553,7 @@ static void fprint_species(FILE *f, const char *prefix, struct String s)
static const unsigned char *male = (unsigned char *)u8"♂";
static const unsigned char *female = (unsigned char *)u8"♀";
static const unsigned char *e_diacritic = (unsigned char *)u8"é";
+ static const unsigned char *right_single_quotation_mark = (unsigned char *)u8"’";
for (int i = 0; i < s.string_n; i++)
{
unsigned char c = s.string[i];
@@ -1562,7 +1571,7 @@ static void fprint_species(FILE *f, const char *prefix, struct String s)
underscore = false;
fputc(c - 'a' + 'A', f);
}
- else if (c == '\'' || c == '%')
+ else if (c == '\'' || c == '%' || is_utf8_character(s, &i, right_single_quotation_mark))
{
// Do nothing.
}
@@ -1696,7 +1705,6 @@ static void fprint_trainers(const char *output_path, FILE *f, struct Parsed *par
if (!is_empty_string(trainer->mugshot))
{
fprintf(f, "#line %d\n", trainer->mugshot_line);
- fprintf(f, " .mugshotEnabled = TRUE,\n");
fprintf(f, " .mugshotColor = ");
fprint_constant(f, "MUGSHOT_COLOR", trainer->mugshot);
fprintf(f, ",\n");