diff options
author | Matthew Cabral <mr.matthewcabral@gmail.com> | 2022-01-22 00:26:03 -0500 |
---|---|---|
committer | Matthew Cabral <mr.matthewcabral@gmail.com> | 2022-01-22 00:26:03 -0500 |
commit | 20c569fbaad934e1c02947163831e7958a202ea9 (patch) | |
tree | 1ad3e1c08b5650df785cb0d1905ce5880b6b9310 | |
parent | 1f61dd19fddc665954d917ba753e6dbf658ff845 (diff) |
Renamed move "Physicality" to "Category" to match common terminology
-rw-r--r-- | Add-Physical-Special-Split.md | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/Add-Physical-Special-Split.md b/Add-Physical-Special-Split.md index c01eb46..699a6a4 100644 --- a/Add-Physical-Special-Split.md +++ b/Add-Physical-Special-Split.md @@ -2,9 +2,9 @@ This tutorial is for adding the per-move physical/special split that was impleme ## Contents 1. [Adding a byte to the move struct](#1-adding-a-byte-to-the-move-struct) -2. [Modifying the physicality check macro](#2-modifying-the-physicality-check-macro) +2. [Modifying the category check macro](#2-modifying-the-category-check-macro) 3. [Modifying the damage calculation logic](#3-modifying-the-damage-calculation-logic) -4. [Adding the physicality byte to moves](#4-adding-the-physicality-byte-to-moves) +4. [Adding the category byte to moves](#4-adding-the-category-byte-to-moves) 5. [A Note on AI Scripts](#5-a-note-on-ai-scripts) ## 1. Adding a byte to the move struct @@ -24,11 +24,11 @@ struct BattleMove u8 flags; }; ``` -All we need to do is add another field to determine if the move is physical or special. I will be using the name "physicality" for this, but the name can be anything as long as it is consistent. We will also add some new macros for the possible values of this field. Again, the values can be anything as long as consistency is maintained, but I will be using 0 for physical, 1 for special, and 2 for other/status. After adding these, our modified struct looks like this: +All we need to do is add another field to determine if the move is physical, special, or status. I will be using the name "category" for this, but the name can be anything as long as it is consistent. We will also add some new macros for the possible values of this field. Again, the values can be anything as long as consistency is maintained, but I will be using 0 for physical, 1 for special, and 2 for status. After adding these, our modified struct looks like this: ```c -#define MOVE_PHYSICALITY_PHYSICAL 0 -#define MOVE_PHYSICALITY_SPECIAL 1 -#define MOVE_PHYSICALITY_OTHER 2 +#define MOVE_CATEGORY_PHYSICAL 0 +#define MOVE_CATEGORY_SPECIAL 1 +#define MOVE_CATEGORY_STATUS 2 struct BattleMove { @@ -41,20 +41,20 @@ struct BattleMove u8 target; s8 priority; u8 flags; - u8 physicality; + u8 category; }; ``` -## 2. Modifying the physicality check macro +## 2. Modifying the category check macro The game uses a function-style macro to check whether a move is physical or special based on its type. The macro lives in **include/battle.h** and looks like this: ```c #define IS_TYPE_PHYSICAL(moveType)(moveType < TYPE_MYSTERY) #define IS_TYPE_SPECIAL(moveType)(moveType > TYPE_MYSTERY) ``` -The macro simply looks at the move and compares the index of its type to TYPE_MYSTERY, which is 0x9. Types are split down the middle by TYPE_MYSTERY; all physical types are before it, and all special types are after it, so a simple comparison does the job. We will change this to look at the physicality byte of the move instead of the move's type. For my definition, it looks like this: +The macro simply looks at the move and compares the index of its type to TYPE_MYSTERY, which is 0x9. Types are split down the middle by TYPE_MYSTERY; all physical types are before it, and all special types are after it, so a simple comparison does the job. We will change this to look at the category byte of the move instead of the move's type. For my definition, it looks like this: ```c -#define IS_TYPE_PHYSICAL(move)(move.physicality == MOVE_PHYSICALITY_PHYSICAL) -#define IS_TYPE_SPECIAL(move)(move.physicality == MOVE_PHYSICALITY_SPECIAL) +#define IS_TYPE_PHYSICAL(move)(move.category == MOVE_CATEGORY_PHYSICAL) +#define IS_TYPE_SPECIAL(move)(move.category == MOVE_CATEGORY_SPECIAL) ``` ## 3. Modifying the damage calculation logic @@ -130,7 +130,7 @@ if ((gBattleResources->flags->flags[battlerIdAtk] & RESOURCE_FLAG_FLASH_FIRE) && ``` ### Thick Fat -Similarly to Flash Fire, Thick Fat only affects Fire and Ice moves, which are all special. For that reason, the damage calculation divides the special attack of the attacking Pokemon in half to reduce the damage taken. We will need to change this to reduce the base power of the move instead, so that it can apply to any physicality or move of the affected types: (**src/pokemon.c**) +Similarly to Flash Fire, Thick Fat only affects Fire and Ice moves, which are all special. For that reason, the damage calculation divides the special attack of the attacking Pokemon in half to reduce the damage taken. We will need to change this to reduce the base power of the move instead, so that it can apply to any category or move of the affected types: (**src/pokemon.c**) ```c if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE)) gBattleMovePower /= 2; @@ -171,7 +171,7 @@ We will change this to: ```c IS_TYPE_SPECIAL(gBattleMoves[gCurrentMove]) ``` -**Note:** We have changed `!IS_TYPE_PHYSICAL` to `IS_TYPE_SPECIAL` because "not physical" no longer automatically means "special" due to the introduction of the "other/status" option. +**Note:** We have changed `!IS_TYPE_PHYSICAL` to `IS_TYPE_SPECIAL` because "not physical" no longer automatically means "special" due to the introduction of the "status" option. And lastly, the two in **battle_tv.c** can be changed to: ```c @@ -188,8 +188,8 @@ In order for the `move` variable to stay defined, we will also have to relocate #undef power ``` -## 4. Adding the physicality byte to moves -The last step is definitely the most tedious, but it is very simple. We need to go through every move and define whether it is physical, special, or other. The file that defines all move effects is located at **src/data/battle_moves.h**. There are plenty of resources to find out which one a move is if you do not already know. After adding these, the split is implemented. For reference, here is one example of each possible value of the physicality byte for my names and values: +## 4. Adding the category byte to moves +The last step is definitely the most tedious, but it is very simple. We need to go through every move and define whether it is physical, special, or status. The file that defines all move effects is located at **src/data/battle_moves.h**. There are plenty of resources to find out which one a move is if you do not already know. After adding these, the split is implemented. For reference, here is one example of each possible value of the category byte for my names and values: ```c { // MOVE_ICE_PUNCH .effect = EFFECT_FREEZE_HIT, @@ -201,7 +201,7 @@ The last step is definitely the most tedious, but it is very simple. We need to .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, - .physicality = MOVE_PHYSICALITY_PHYSICAL, + .category = MOVE_CATEGORY_PHYSICAL, }, ``` ```c @@ -215,7 +215,7 @@ The last step is definitely the most tedious, but it is very simple. We need to .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGSROCK_AFFECTED, - .physicality = MOVE_PHYSICALITY_SPECIAL, + .category = MOVE_CATEGORY_SPECIAL, }, ``` ```c @@ -229,7 +229,7 @@ The last step is definitely the most tedious, but it is very simple. We need to .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGICCOAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, - .physicality = MOVE_PHYSICALITY_OTHER, + .category = MOVE_CATEGORY_STATUS, }, ``` ## 5. A Note on AI Scripts @@ -239,4 +239,4 @@ The last thing that should be noted is how AI Scripts relating to physical/speci 2. The likelihood of the AI using Reflect vs. Light Screen 3. The likelihood of the AI using Counter vs. Mirror Coat -An important note is that these decisions are all made based on the types of the opposing Pokemon itself rather than the moves it has, so the original check is pretty bad to begin with--in fact, it's arguable whether you would even notice the difference. Correcting the AI to check for the physicality of moves instead of the types of Pokemon is beyond the scope of this tutorial and is more suited to a general AI overhaul tutorial, but I wanted to mention it here to be totally clear about what's happening with these calculations. +An important note is that these decisions are all made based on the types of the opposing Pokemon itself rather than the moves it has, so the original check is pretty bad to begin with--in fact, it's arguable whether you would even notice the difference. Correcting the AI to check for the category of moves instead of the types of Pokemon is beyond the scope of this tutorial and is more suited to a general AI overhaul tutorial, but I wanted to mention it here to be totally clear about what's happening with these calculations. |