Merge branch '_RHH/upcoming' into _RHH/pr/upcoming/lighting-expansion-v2

This commit is contained in:
Eduardo Quezada 2024-12-20 15:22:14 -03:00
commit 05f300f6cc
123 changed files with 2347 additions and 1804 deletions

View File

@ -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 "<i>Note...</i>" 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.
<details>
<summary><i>Note for advanced users: <b>WSL2</b>...</i></summary>
> <b>WSL2</b> is an option and is even faster than <b>WSL1</b> 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 <a href="https://github.com/huderlem/porymap">porymap</a>
> may <a href="https://bugreports.qt.io/browse/QTBUG-86277">have problems with parsing the <code>\\wsl$</code> network drive path</a>.
</details>
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
```
<details>
<summary><i>Note...</i></summary>
> WSL may open automatically after restarting, but you can ignore it for now.
</details>
### 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).
<details>
<summary><i>Note...</i></summary>
> When typing in the password, there will be no visible response, but the terminal will still read in input.
</details>
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
```
<details>
<summary><i>Note...</i></summary>
> If the above command does not work, try the above command but replacing `apt` with `apt-get`.
</details>
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\\_\<user>_\Downloads** (the Downloads location for most users). To do so, enter this command, where *\<user> is your **Windows** username:
```bash
cd /mnt/c/Users/<user>/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\\_\<user>_\Desktop\decomps**. First, ensure that the folder already exists. Then, enter this command to **change directory** to said folder, where *\<user>* is your **Windows** username:
```bash
cd /mnt/c/Users/<user>/Desktop/decomps
```
<details>
<summary><i>Notes...</i></summary>
> 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/<user>/Desktop/decomp folder"`.
> Note 3: Windows path names are case-insensitive so adhering to capitalization isn't needed
</details>
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
```
<details>
<summary><i>Note...</i></summary>
> The commands will ask for confirmation, just enter the yes action when prompted.
</details>
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\\&#8288;_\<user>_**, where *\<user>* 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\\_\<user>_\Downloads** (the Downloads location for most users), enter this command:
```bash
cd Downloads
```
<details>
<summary><i>Notes...</i></summary>
> 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 isnt 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.
</details>
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\\_\<user>_\Desktop\decomps** (where *\<user>* 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
```
<details>
<summary><i>Note...</i></summary>
> Replace the drive letter c with the actual drive letter if it is not c.
</details>
### Choosing where to store pokeemerald Expansion (Cygwin)
Cygwin has its own file system that's within Windows, at **C:\cygwin64\home\\_\<user>_**. 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\\_\<user>_\Desktop\decomps**, enter this command, where *\<user>* is your **Windows** username:
```bash
cd c:/Users/<user>/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.
<details>
<summary><i>Notes...</i></summary>
> Note 1: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "c:/users/<user>/Desktop/decomp folder"`.
> Note 2: Windows path names are case-insensitive so adhering to capitalization isn't needed
</details>
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)
<details>
<summary><i>Note for advanced users...</i></summary>
> 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.
</details>
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)
<details>
<summary><i>Note for advanced users...</i></summary>
> 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.
</details>
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.*
<details>
<summary><i>If your terminal is using bash instead of zsh...</i></summary>
```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
```
</details>
### 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.
<details>
<summary><i>Note..</i>.</summary>
> Note: If the path has spaces, then the path must be wrapped with quotations, e.g. `cd "Desktop/decomp folder"`
</details>
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).
<details>
<summary><i>Note for legacy repos...</i></summary>
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).
</details>
## 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
<details>
<summary><i>Note for Windows users...</i></summary>
> 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.
</details>
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.
<details>
<summary><i>Note for WSL1...</i></summary>
```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 <folder where pokeemerald-expansion is to be stored>
> ```
> Where *\<folder where pokeemerald-expansion is to be stored>* 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.
</details>
```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.
<details>
<summary>Note for Windows...</summary>
> 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.
</details>
```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 <objs> <libs> | 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

View File

@ -928,8 +928,9 @@
.4byte \failInstr
.endm
.macro setdestinybond
.macro trysetdestinybond failInstr:req
.byte 0xaa
.4byte \failInstr
.endm
.macro trysetdestinybondtohappen

View File

@ -46,6 +46,8 @@ LV = 34
'=' = 35
';' = 36
V_D_ARROW = 38
NBSP = 39
'~' = 39
'¿' = 51
'¡' = 52
PK = 53

View File

@ -5561,44 +5561,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

View File

@ -298,12 +298,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
@ -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
@ -1343,7 +1351,7 @@ BattleScript_EffectPartingShotTrySpAtk:
waitmessage B_WAIT_TIME_LONG
BattleScript_EffectPartingShotSwitch:
moveendall
goto BattleScript_MoveSwitch
goto BattleScript_MoveSwitchPursuit
BattleScript_EffectPowder::
attackcanceler
@ -2741,9 +2749,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
@ -2785,7 +2793,7 @@ BattleScript_EffectHitEscape::
jumpifbattleend BattleScript_HitEscapeEnd
jumpifbyte CMP_NOT_EQUAL, gBattleOutcome, 0, BattleScript_HitEscapeEnd
jumpifemergencyexited BS_TARGET, BattleScript_HitEscapeEnd
goto BattleScript_MoveSwitch
goto BattleScript_MoveSwitchPursuit
BattleScript_HitEscapeEnd:
end
@ -3415,7 +3423,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
@ -4063,7 +4071,7 @@ BattleScript_EffectDestinyBond::
attackcanceler
attackstring
ppreduce
setdestinybond
trysetdestinybond BattleScript_ButItFailed
attackanimation
waitanimation
printstring STRINGID_PKMNTRYINGTOTAKEFOE
@ -5767,19 +5775,10 @@ BattleScript_PrintFullBox::
BattleScript_ActionSwitch::
hpthresholds2 BS_ATTACKER
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
@ -5801,34 +5800,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

View File

@ -449,7 +449,7 @@ Debug_EventScript_EWRAMCounters_Text::
.string "Fishing Chain: {STR_VAR_2}.$"
Debug_EventScript_FontTest_Text_1::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -463,7 +463,7 @@ Debug_EventScript_FontTest_Text_1::
.string "Zloty Zodiac.$"
Debug_EventScript_FontTest_Text_2::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -474,7 +474,7 @@ Debug_EventScript_FontTest_Text_2::
.string "loud statehood and huddle.$"
Debug_EventScript_FontTest_Text_3::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -486,7 +486,7 @@ Debug_EventScript_FontTest_Text_3::
.string "bathhouse.$"
Debug_EventScript_FontTest_Text_4::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -498,7 +498,7 @@ Debug_EventScript_FontTest_Text_4::
.string "shallot.$"
Debug_EventScript_FontTest_Text_5::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -510,7 +510,7 @@ Debug_EventScript_FontTest_Text_5::
.string "bishop and supplies.$"
Debug_EventScript_FontTest_Text_6::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -521,7 +521,7 @@ Debug_EventScript_FontTest_Text_6::
.string "of the peasant ingot and ottoman.$"
Debug_EventScript_FontTest_Text_7::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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"
@ -533,12 +533,24 @@ Debug_EventScript_FontTest_Text_7::
.string "exxon.$"
Debug_EventScript_FontTest_Text_8::
.string "{FONT_SHORT_NARROWER}" @ Edit this to test your font
.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
@ -548,6 +560,7 @@ Debug_PrintFontTest::
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

View File

@ -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`

View File

@ -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
```

View File

@ -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
```

View File

@ -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
```

View File

@ -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`

View File

@ -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
```

View File

@ -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)
<details>
<summary><i>Note for advanced users...</i></summary>
> 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.
</details>
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)
<details>
<summary><i>Note for advanced users...</i></summary>
> 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.
</details>
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.*
<details>
<summary><i>If your terminal is using bash instead of zsh...</i></summary>
```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
```
</details>
### 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.

View File

@ -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`.

View File

@ -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`.

View File

@ -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
```
<details>
<summary><i>Note...</i></summary>
> WSL may open automatically after restarting, but you can ignore it for now.
</details>
## 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).
<details>
<summary><i>Note...</i></summary>
> When typing in the password, there will be no visible response, but the terminal will still read in input.
</details>
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\\_\<user>_\Desktop\decomps**. First, ensure that the folder already exists. Then, enter this command to **change directory** to said folder, where *\<user>* is your **Windows** username:
```bash
cd /mnt/c/Users/<user>/Desktop/decomps
```
<details>
<summary><i>Notes...</i></summary>
> 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/<user>/Desktop/decomp folder"`.
> Note 3: Windows path names are case-insensitive so adhering to capitalization isn't needed
</details>
## 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
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 302 B

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 465 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 905 B

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 922 B

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 832 B

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 B

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 867 B

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 540 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 962 B

After

Width:  |  Height:  |  Size: 947 B

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 533 B

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 958 B

After

Width:  |  Height:  |  Size: 947 B

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

After

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 960 B

After

Width:  |  Height:  |  Size: 909 B

View File

@ -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

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 654 B

View File

@ -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

View File

@ -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

View File

@ -836,6 +836,9 @@ struct BattleStruct
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
@ -866,10 +869,6 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER
#define IS_MOVE_STATUS(move)(gMovesInfo[move].category == DAMAGE_CATEGORY_STATUS)
#define IS_MOVE_RECOIL(move)(gMovesInfo[move].recoil > 0 || gMovesInfo[move].effect == EFFECT_RECOIL_IF_MISS)
#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)))
/* 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. */
@ -1193,6 +1192,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];

View File

@ -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);

View File

@ -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[];

View File

@ -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[];

View File

@ -331,5 +331,6 @@ void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty);
bool32 IsSleepClauseActiveForSide(u32 battlerSide);
bool32 IsSleepClauseEnabled();
void ClearDamageCalcResults(void);
u32 DoesDestinyBondFail(u32 battler);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -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.
@ -177,6 +179,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
@ -220,6 +223,7 @@
#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.

View File

@ -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.

View File

@ -88,138 +88,138 @@
#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_EERIE_SPELL_PP_REDUCE,
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 1
@ -302,6 +302,7 @@ enum MoveEndEffects
MOVEEND_SAME_MOVE_TURNS,
MOVEEND_SET_EVOLUTION_TRACKER,
MOVEEND_CLEAR_BITS,
MOVEEND_PURSUIT_NEXT_ACTION,
MOVEEND_COUNT,
};

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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

View File

@ -1663,7 +1663,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
@ -1802,7 +1802,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
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
@ -1812,7 +1812,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
@ -1822,7 +1822,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
@ -1875,6 +1875,8 @@ 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)
@ -2388,7 +2390,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);
@ -2557,8 +2559,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);
@ -2683,7 +2685,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (IsMoveEffectWeather(move))
ADJUST_SCORE(-10);
break;
}
}
} // check partner move effect
// Adjust for always crit moves

View File

@ -290,7 +290,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;
@ -1142,7 +1142,7 @@ 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)
if (!AI_BattlerAtMaxHp(battlerTarget) || gMovesInfo[move].effect == EFFECT_MULTI_HIT)
return FALSE;
if (gMovesInfo[move].strikeCount > 1 && !(gMovesInfo[move].effect == EFFECT_DRAGON_DARTS && IsValidDoubleBattle(battlerTarget)))
return FALSE;
@ -1564,7 +1564,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)
@ -2761,7 +2761,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov
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
|| (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))))
@ -2769,7 +2769,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 (!IS_MOVE_STATUS(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)))
@ -2848,7 +2848,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 mov
// can knock out foe in 2 hits
if (IS_MOVE_STATUS(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;

View File

@ -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)
{
@ -1523,3 +1534,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;
}

View File

@ -1759,7 +1759,6 @@ static void MoveSelectionDisplayMoveDescription(u32 battler)
u16 move = moveInfo->moves[gMoveSelectionCursor[battler]];
u16 pwr = gMovesInfo[move].power;
u16 acc = gMovesInfo[move].accuracy;
u8 cat = gMovesInfo[move].category;
u8 pwr_num[3], acc_num[3];
u8 cat_desc[7] = _("CAT: ");
@ -1796,7 +1795,7 @@ static void MoveSelectionDisplayMoveDescription(u32 battler)
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);
}

View File

@ -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);

View File

@ -3114,6 +3114,9 @@ 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;
@ -3355,6 +3358,9 @@ const u8* FaintClearSetData(u32 battler)
gBattleStruct->lastTakenMoveFrom[battler][1] = 0;
gBattleStruct->lastTakenMoveFrom[battler][2] = 0;
gBattleStruct->lastTakenMoveFrom[battler][3] = 0;
gBattleStruct->pursuitTarget = 0;
gBattleStruct->pursuitSwitchByMove = FALSE;
gBattleStruct->pursuitStoredSwitch = 0;
gBattleStruct->palaceFlags &= ~(1u << battler);
gBattleStruct->boosterEnergyActivates &= ~(1u << battler);
@ -4848,7 +4854,7 @@ s8 GetMovePriority(u32 battler, u16 move)
return gMovesInfo[MOVE_MAX_GUARD].priority;
if (ability == ABILITY_GALE_WINGS
&& (B_GALE_WINGS < GEN_7 || BATTLER_MAX_HP(battler))
&& (B_GALE_WINGS < GEN_7 || IsBattlerAtMaxHp(battler))
&& gMovesInfo[move].type == TYPE_FLYING)
{
priority++;
@ -5164,6 +5170,9 @@ 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();
}
@ -5180,11 +5189,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);
@ -5192,16 +5216,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;
}
}
@ -5251,7 +5267,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++)
{
@ -5369,11 +5385,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;

View File

@ -3119,7 +3119,10 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
{
while (*toCpy != EOS)
{
dst[dstID] = *toCpy;
if (*toCpy == CHAR_SPACE)
dst[dstID] = CHAR_NBSP;
else
dst[dstID] = *toCpy;
dstID++;
toCpy++;
}

View File

@ -329,6 +329,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);
@ -508,7 +509,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);
@ -767,7 +768,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
@ -1487,6 +1488,10 @@ static bool32 AccuracyCalcHelper(u32 move, u32 battler)
{
effect = TRUE;
}
else if (gBattleStruct->pursuitTarget & (1u << battler))
{
effect = TRUE;
}
else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !(gStatuses3[battler] & STATUS3_SEMI_INVULNERABLE))
{
effect = TRUE;
@ -1729,7 +1734,6 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
{
// Smart target to partner if miss
gBattlerTarget = BATTLE_PARTNER(battlerDef);
gBattleStruct->moveResultFlags[battlerDef] &= ~MOVE_RESULT_MISSED;
AccuracyCheck(TRUE, nextInstr, failInstr, move);
return;
}
@ -2203,12 +2207,12 @@ static void Cmd_adjustdamage(void)
RecordItemEffectBattle(battlerDef, holdEffect);
gSpecialStatuses[battlerDef].focusBanded = TRUE;
}
else if (B_STURDY >= GEN_5 && GetBattlerAbility(battlerDef) == ABILITY_STURDY && BATTLER_MAX_HP(battlerDef))
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 && BATTLER_MAX_HP(battlerDef))
else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && IsBattlerAtMaxHp(battlerDef))
{
RecordItemEffectBattle(battlerDef, holdEffect);
gSpecialStatuses[battlerDef].focusSashed = TRUE;
@ -2318,7 +2322,7 @@ static inline bool32 DoesBattlerNegateDamage(u32 battler)
return FALSE;
if (ability == ABILITY_DISGUISE && species == SPECIES_MIMIKYU)
return TRUE;
if (ability == ABILITY_ICE_FACE && species == SPECIES_EISCUE && GetBattleMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_SPECIAL)
if (ability == ABILITY_ICE_FACE && species == SPECIES_EISCUE && GetBattleMoveCategory(gCurrentMove) == DAMAGE_CATEGORY_PHYSICAL)
return TRUE;
return FALSE;
@ -5992,7 +5996,7 @@ static void Cmd_moveend(void)
&& gBattlerAttacker != gBattlerTarget
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)
&& MoveResultHasEffect(gBattlerTarget)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gMovesInfo[gCurrentMove].power != 0
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
@ -6277,7 +6281,7 @@ static void Cmd_moveend(void)
if (gBattlerAttacker != gBattlerTarget
&& gMovesInfo[gCurrentMove].category != DAMAGE_CATEGORY_STATUS
&& MoveResultHasEffect(gBattlerTarget)
&& TARGET_TURN_DAMAGED)
&& IsBattlerTurnDamaged(gBattlerTarget))
{
gBattleStruct->timesGotHit[GetBattlerSide(gBattlerTarget)][gBattlerPartyIndexes[gBattlerTarget]]++;
}
@ -6506,7 +6510,7 @@ static void Cmd_moveend(void)
else
{
if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS
&& gBattleStruct->moveTarget[gBattlerAttacker] == gBattlerTarget // Haven't already changed targets
&& !(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.
@ -6558,7 +6562,7 @@ 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]))
@ -6604,7 +6608,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))
@ -6699,7 +6703,7 @@ 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;
@ -6748,7 +6752,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
@ -6947,6 +6951,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:
@ -8483,7 +8513,7 @@ 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))
{
gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 3;
if (gBattleStruct->moveDamage[battler] == 0)
@ -9434,13 +9464,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.
@ -9554,7 +9585,7 @@ static void Cmd_various(void)
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;
@ -9656,7 +9687,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)))
{
@ -12665,7 +12696,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);
@ -13446,12 +13477,18 @@ static void Cmd_trychoosesleeptalkmove(void)
}
}
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)
@ -13961,45 +13998,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
&& gMovesInfo[gChosenMoveByBattler[battler]].effect == 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
{
@ -15664,13 +15700,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
{
@ -15725,6 +15766,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
{
@ -17192,7 +17238,7 @@ void BS_TryHealPulse(void)
{
NATIVE_ARGS(const u8 *failInstr);
if (BATTLER_MAX_HP(gBattlerTarget))
if (IsBattlerAtMaxHp(gBattlerTarget))
{
gBattlescriptCurrInstr = cmd->failInstr;
}
@ -17449,7 +17495,7 @@ void BS_TryActivateGulpMissile(void)
if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT
&& GetBattlerAbility(gBattlerTarget) == ABILITY_GULP_MISSILE)
{
@ -17650,7 +17696,7 @@ void BS_TryHitSwitchTarget(void)
if (IsBattlerAlive(gBattlerAttacker)
&& IsBattlerAlive(gBattlerTarget)
&& MoveResultHasEffect(gBattlerTarget)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT
&& GetBattlerAbility(gBattlerTarget) != ABILITY_GUARD_DOG)
{

View File

@ -62,6 +62,8 @@ 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[];
@ -117,6 +119,9 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
|| ability == ABILITY_PROPELLER_TAIL || ability == ABILITY_STALWART)
return FALSE;
if (gMovesInfo[move].effect == EFFECT_PURSUIT && gBattleStruct->pursuitTarget)
return FALSE;
if (gSideTimers[defSide].followmePowder && !IsAffectedByPowder(battlerAtk, ability, GetBattlerHoldEffect(battlerAtk, TRUE)))
return FALSE;
@ -224,6 +229,7 @@ void HandleAction_UseMove(void)
}
else if (IsDoubleBattle()
&& gSideTimers[side].followmeTimer == 0
&& !(gBattleStruct->pursuitTarget & (1u << *(gBattleStruct->moveTarget + gBattlerAttacker)))
&& (gMovesInfo[gCurrentMove].power != 0 || (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)))
@ -703,7 +709,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
@ -757,113 +763,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;
@ -2344,7 +2255,7 @@ u8 DoBattlerEndTurnEffects(void)
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;
@ -2371,7 +2282,7 @@ 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))
{
@ -2383,7 +2294,7 @@ 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))
{
@ -2461,7 +2372,7 @@ 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))
{
gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
if (gBattleStruct->moveDamage[battler] == 0)
@ -2489,7 +2400,7 @@ 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))
{
gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8;
if (gBattleStruct->moveDamage[battler] == 0)
@ -2615,15 +2526,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)
@ -3786,7 +3696,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
}
}
if (moveTarget == MOVE_TARGET_BOTH)
gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker);
gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER_SIDE, gBattlerAttacker);
else
gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, gBattlerAttacker);
@ -4136,7 +4046,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)
@ -5238,7 +5148,7 @@ 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);
@ -5493,7 +5403,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;
@ -5565,7 +5475,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
{
case ABILITY_JUSTIFIED:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& moveType == TYPE_DARK
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
@ -5579,7 +5489,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_RATTLED:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& (moveType == TYPE_DARK || moveType == TYPE_BUG || moveType == TYPE_GHOST)
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN))
@ -5593,7 +5503,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_WATER_COMPACTION:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& moveType == TYPE_WATER
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
@ -5608,7 +5518,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_STAMINA:
if (MoveResultHasEffect(battler)
&& gBattlerAttacker != gBattlerTarget
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN))
{
@ -5621,7 +5531,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_BERSERK:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& HadMoreThanHalfHpNowDoesnt(battler)
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
@ -5638,7 +5548,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_EMERGENCY_EXIT:
case ABILITY_WIMP_OUT:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
// Had more than half of hp before, now has less
&& HadMoreThanHalfHpNowDoesnt(battler)
@ -5656,7 +5566,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_WEAK_ARMOR:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& IS_MOVE_PHYSICAL(gCurrentMove)
&& (CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN) // Don't activate if both Speed and Defense cannot be raised.
@ -5672,7 +5582,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_CURSED_BODY:
if (MoveResultHasEffect(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gDisableStructs[gBattlerAttacker].disabledMove == MOVE_NONE
&& IsBattlerAlive(gBattlerAttacker)
&& !IsAbilityOnSide(gBattlerAttacker, ABILITY_AROMA_VEIL)
@ -5692,7 +5602,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_MUMMY:
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)
@ -5717,7 +5627,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_WANDERING_SPIRIT:
if (MoveResultHasEffect(battler)
&& IsBattlerAlive(gBattlerAttacker)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker)
&& !(GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX)
@ -5741,7 +5651,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_ANGER_POINT:
if (MoveResultHasEffect(battler)
&& gSpecialStatuses[battler].criticalHit
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN))
{
@ -5755,7 +5665,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (MoveResultHasEffect(battler)
&& move != MOVE_STRUGGLE
&& gMovesInfo[move].power != 0
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& !IS_BATTLER_OF_TYPE(battler, moveType)
&& moveType != TYPE_STELLAR
&& moveType != TYPE_MYSTERY
@ -5774,7 +5684,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& 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))
{
@ -5791,7 +5701,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
{
@ -5870,7 +5780,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& CanBeSlept(gBattlerAttacker, ability, NOT_BLOCKED_BY_SLEEP_CLAUSE)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(move, gBattlerAttacker))
@ -5894,7 +5804,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
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))
@ -5915,7 +5825,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
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))
@ -5935,7 +5845,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& !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)))
{
@ -5951,7 +5861,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
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)
@ -5968,7 +5878,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;
@ -5979,7 +5889,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
if (MoveResultHasEffect(gBattlerTarget)
&& IsBattlerAlive(gBattlerAttacker)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED)
&& IsBattlerTurnDamaged(gBattlerTarget))
{
gEffectBattler = gBattlerTarget;
BattleScriptPushCursor();
@ -5989,7 +5899,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_STEAM_ENGINE:
if (MoveResultHasEffect(gBattlerTarget)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& CompareStat(battler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN)
&& (moveType == TYPE_FIRE || moveType == TYPE_WATER))
@ -6004,7 +5914,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_SAND_SPIT:
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)
@ -6025,7 +5935,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_PERISH_BODY:
if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& (IsMoveMakingContact(move, gBattlerAttacker))
@ -6046,7 +5956,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_GULP_MISSILE:
if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(battler)
&& gBattleMons[gBattlerTarget].species != SPECIES_CRAMORANT)
{
@ -6077,7 +5987,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_SEED_SOWER:
if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& TryChangeBattleTerrain(gBattlerTarget, STATUS_FIELD_GRASSY_TERRAIN, &gFieldTimers.terrainTimer))
{
@ -6088,7 +5998,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
break;
case ABILITY_THERMAL_EXCHANGE:
if (MoveResultHasEffect(gBattlerTarget)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget)
&& CompareStat(gBattlerTarget, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN)
&& moveType == TYPE_FIRE)
@ -6103,7 +6013,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_ANGER_SHELL:
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)
@ -6121,7 +6031,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
case ABILITY_ELECTROMORPHOSIS:
if (MoveResultHasEffect(gBattlerTarget)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& IsBattlerAlive(gBattlerTarget))
{
BattleScriptPushCursor();
@ -6134,7 +6044,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& (!gBattleStruct->isSkyBattle)
&& !gProtectStructs[gBattlerAttacker].confusionSelfDmg
&& IS_MOVE_PHYSICAL(gCurrentMove)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& (gSideTimers[GetBattlerSide(gBattlerAttacker)].toxicSpikesAmount != 2))
{
SWAP(gBattlerAttacker, gBattlerTarget, i);
@ -6155,7 +6065,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& 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;
@ -6171,7 +6081,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& 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;
@ -6187,7 +6097,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& 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;
@ -6199,7 +6109,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();
@ -7001,7 +6911,7 @@ static u8 TrySetEnigmaBerry(u32 battler)
{
if (IsBattlerAlive(battler)
&& !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& ((BATTLER_TURN_DAMAGED(battler) && gBattleStruct->moveResultFlags[battler] & 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)))
{
@ -7025,7 +6935,7 @@ static u8 DamagedStatBoostBerryEffect(u32 battler, u8 statId, u8 category)
|| (!DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove)
&& GetBattleMoveCategory(gCurrentMove) == category
&& battler != gBattlerAttacker
&& BATTLER_TURN_DAMAGED(battler)))
&& IsBattlerTurnDamaged(battler)))
)
{
BufferStatChange(battler, statId, STRINGID_STATROSE);
@ -8082,7 +7992,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
atkHoldEffectParam *= 2;
if (gBattleStruct->moveDamage[battler] != 0 // Need to have done damage
&& MoveResultHasEffect(gBattlerTarget)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& !gMovesInfo[gCurrentMove].ignoresKingsRock
&& gBattleMons[gBattlerTarget].hp
&& RandomPercentage(RNG_HOLD_EFFECT_FLINCH, atkHoldEffectParam)
@ -8174,7 +8084,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
switch (battlerHoldEffect)
{
case HOLD_EFFECT_AIR_BALLOON:
if (TARGET_TURN_DAMAGED)
if (IsBattlerTurnDamaged(gBattlerTarget))
{
effect = ITEM_EFFECT_OTHER;
BattleScriptPushCursor();
@ -8182,7 +8092,7 @@ u32 ItemBattleEffects(enum ItemEffect 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)
@ -8200,7 +8110,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
break;
case HOLD_EFFECT_WEAKNESS_POLICY:
if (IsBattlerAlive(battler)
&& TARGET_TURN_DAMAGED
&& IsBattlerTurnDamaged(gBattlerTarget)
&& gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_SUPER_EFFECTIVE)
{
effect = ITEM_STATS_CHANGE;
@ -8210,7 +8120,7 @@ u32 ItemBattleEffects(enum ItemEffect 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;
@ -8221,7 +8131,7 @@ u32 ItemBattleEffects(enum ItemEffect 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;
@ -8232,7 +8142,7 @@ u32 ItemBattleEffects(enum ItemEffect 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;
@ -8243,7 +8153,7 @@ u32 ItemBattleEffects(enum ItemEffect 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;
@ -8257,7 +8167,7 @@ u32 ItemBattleEffects(enum ItemEffect 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)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
@ -8277,7 +8187,7 @@ u32 ItemBattleEffects(enum ItemEffect 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)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
@ -8314,7 +8224,7 @@ u32 ItemBattleEffects(enum ItemEffect caseID, u32 battler, bool32 moveTurn)
}
break;
case HOLD_EFFECT_STICKY_BARB:
if (TARGET_TURN_DAMAGED
if (IsBattlerTurnDamaged(gBattlerTarget)
&& MoveResultHasEffect(gBattlerTarget)
&& GetBattlerHoldEffect(gBattlerAttacker, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS
&& IsMoveMakingContact(gCurrentMove, gBattlerAttacker)
@ -8697,7 +8607,7 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move)
&& IsMoveMakingContact(move, gBattlerAttacker)
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST)
isProtected = FALSE;
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD && IS_MOVE_STATUS(move))
else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_COACHING)
isProtected = TRUE;
else if (gMovesInfo[move].ignoresProtect)
isProtected = FALSE;
@ -9054,7 +8964,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:
@ -9302,7 +9212,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)
@ -9491,18 +9401,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);
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);
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))
@ -9768,11 +9678,11 @@ static inline u32 CalcAttackStat(struct DamageCalculationData *damageCalcData, u
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));
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));
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3333));
break;
}
@ -10191,7 +10101,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:
@ -10234,19 +10144,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);
@ -11284,7 +11198,7 @@ u8 GetBattleMoveCategory(u32 moveId)
if (IS_MOVE_STATUS(moveId))
return DAMAGE_CATEGORY_STATUS;
return gTypesInfo[GetMoveType(gCurrentMove)].damageCategory;
return gTypesInfo[GetMoveType(moveId)].damageCategory;
}
static bool32 TryRemoveScreens(u32 battler)
@ -12099,3 +12013,12 @@ void ClearDamageCalcResults(void)
gBattleStruct->printedStrongWindsWeakenedAttack = FALSE;
gBattleStruct->numSpreadTargets = 0;
}
bool32 DoesDestinyBondFail(u32 battler)
{
if (B_DESTINY_BOND_FAIL >= GEN_7
&& gMovesInfo[gLastResultingMoves[battler]].effect == EFFECT_DESTINY_BOND
&& !(gBattleStruct->lastMoveFailed & (1u << battler)))
return TRUE;
return FALSE;
}

View File

@ -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");

View File

@ -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,

View File

@ -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,
@ -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

View File

@ -9794,7 +9794,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

View File

@ -159,7 +159,7 @@ enum FlagsVarsDebugMenu
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS,
DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL,
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,
@ -788,7 +788,7 @@ static const struct ListMenuItem sDebugMenu_Items_FlagsVars[] =
[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_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},
@ -959,7 +959,7 @@ static void (*const sDebugMenu_Actions_Flags[])(u8) =
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_LOCATIONS] = DebugAction_FlagsVars_ToggleFlyFlags,
[DEBUG_FLAGVAR_MENU_ITEM_TOGGLE_BADGES_ALL] = DebugAction_FlagsVars_ToggleBadgeFlags,
[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,
@ -1312,7 +1312,7 @@ static u8 Debug_CheckToggleFlags(u8 id)
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
@ -1927,7 +1927,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;
@ -1971,7 +1971,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))
@ -1986,7 +1986,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;
}
@ -2033,7 +2033,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))
@ -2045,7 +2045,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))
@ -2076,7 +2076,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))
@ -2236,7 +2236,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;
@ -2282,7 +2282,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))
@ -2445,7 +2445,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;
@ -2506,7 +2506,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);
}
}
@ -2534,7 +2534,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;
@ -2586,7 +2586,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))
@ -2606,7 +2606,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;
@ -2674,7 +2674,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);
}
}
@ -2960,10 +2960,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;
@ -3005,11 +3006,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
@ -3031,7 +3033,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;
}
@ -3082,7 +3084,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))
@ -3158,11 +3160,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;
@ -3198,11 +3201,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;
@ -3247,11 +3251,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();
@ -3270,7 +3275,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;
}
@ -3317,7 +3322,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))
@ -3343,7 +3348,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;
}
@ -3371,7 +3376,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))
@ -3385,7 +3390,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;
}
@ -3421,7 +3426,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))
@ -3435,9 +3440,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;
}
@ -3480,9 +3486,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))
@ -3495,7 +3502,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;
}
@ -3560,7 +3567,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
@ -3619,7 +3626,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;
}
@ -3633,7 +3640,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;
}
}
@ -3710,7 +3717,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
@ -3769,7 +3776,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;
}
@ -3793,18 +3800,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;
}
@ -3848,7 +3856,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)
@ -3866,7 +3875,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))
@ -3900,7 +3909,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)
@ -3918,7 +3928,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;
}
@ -4271,7 +4281,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
@ -4313,7 +4323,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))
@ -4353,7 +4363,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
@ -4395,7 +4405,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))

View File

@ -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,
@ -293,19 +293,19 @@ 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, 8, 8, 3, 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,
5, 5, 4, 8, 8, 8, 7, 8, 8, 4, 4, 6, 4, 4, 3, 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, 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, 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,
4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
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,

View File

@ -280,8 +280,8 @@ static const struct MenuAction sItemMenuActions[] = {
[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("CHECK TAG"), {ItemMenu_Register}},
[ACTION_CHECK_TAG] = {COMPOUND_STRING("DESELECT"), {ItemMenu_CheckTag}},
[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}},
@ -916,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
@ -933,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:

View File

@ -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 {

View File

@ -2074,6 +2074,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++)
{
@ -6661,7 +6668,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++;

View File

@ -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)
{

View File

@ -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;
@ -30,20 +30,13 @@ 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; }
@ -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
}
}

View File

@ -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(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(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);
}
}

Some files were not shown because too many files have changed in this diff Show More