diff options
author | Idain <luiscarlosholguinperez@outlook.com> | 2021-04-18 05:06:03 -0400 |
---|---|---|
committer | Idain <luiscarlosholguinperez@outlook.com> | 2021-04-18 05:06:03 -0400 |
commit | 5df86dc7a198905baeee0857c0c672f85a2800bf (patch) | |
tree | 30a58bc551b3e7b3fff165bb68d04696f7ca8f59 | |
parent | 48baf933ff7751d62dadce4360704f1632a4f02e (diff) |
Created Make time- and weather-sensitive moves only weather-dependent (markdown)
-rw-r--r-- | Make-time--and-weather-sensitive-moves-only-weather-dependent.md | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/Make-time--and-weather-sensitive-moves-only-weather-dependent.md b/Make-time--and-weather-sensitive-moves-only-weather-dependent.md new file mode 100644 index 0000000..52170e3 --- /dev/null +++ b/Make-time--and-weather-sensitive-moves-only-weather-dependent.md @@ -0,0 +1,109 @@ +In Generation 2 the Day/Night feature was introduced and, along with it, three moves that depend on it: Morning Sun (Morning), Synthesis (Day) and Moonlight (Night). The healing amount is affected by both the weather and the time of day, varying from ¼ Max HP (no weather and no matching time of day), ½ Max HP (either sunny or matching time of day), 100% Max HP (both sunny and matching time of day), and ⅛ Max HP (either rain/sandstorm and no matching time of day). + +In Generation 3 onwards it only depends on weather, normally healing ½ max HP with no weather, ⅔ max HP is there's harsh sunlight, and ¼ max HP in any other weather. The objective of this tutorial will be to make the moves mentioned above behave like in modern generations. + +## Contents + +1. [Calculate ⅔ Max HP](#1-calculate--max-hp) +2. [Update the healing routine](#2-update-the-healing-routine) + +## 1. Calculate ⅔ Max HP + +In [engine/battle/core.asm](../blob/master/engine/battle/core.asm) there are functions that calculate different HP amounts, like `GetHalfMaxHP` or `GetQuarterMaxHP`, but we need one that calculates ⅔ Max HP, so we're going to create it. Go to the mentioned file: + +```diff + GetQuarterMaxHP: + ... + ++GetThirdMaxHP:: ++; Assumes HP<768 ++ call GetMaxHP ++ xor a ++ inc b ++.loop ++ dec b ++ inc a ++ dec bc ++ dec bc ++ dec bc ++ inc b ++ jr nz, .loop ++ dec a ++ ld c, a ++ ret nz ++ inc c ; At least 1. ++ ret + + GetHalfMaxHP: + ... + ++GetTwoThirdsMaxHP: ; 2/3 Max HP ++ ; outputs bc from GetThirdMaxHP ++ call GetThirdMaxHP ++ sla c ; Multiply by 2 ++ rl b ++ ret +... +``` + +Here we're creating two functions, one that calculates ⅓ of max HP, and another one that takes the result and doubles it. `GetThirdMaxHP`gets the Max HP of a Pokémon (which is stored in `bc`), and performs an iterative substraction where `a` is increased once while `bc` is decreased three times, until it goes below 0 (underflow), then `a` is decreased once to discount the underflow, loads the value into `c`, check if it's 0 (in which case is increased once) and finally returns. `GetTwoThirdsMaxHP` calls this function and doubles the result, since 2 * ⅓ = ⅔. + +Now that we can calculate ⅔ of Max HP, let's go to the next step. + +## 2. Update the healing routine + +Edit [engine/battle/effect_commands.asm](../blob/master/engine/battle/effect_commands.asm): + +```diff + BattleCommand_TimeBasedHealContinue: +-; Time- and weather-sensitive heal. ++; Weather-sensitive heal. + + ld hl, wBattleMonMaxHP + ld de, wBattleMonHP + ldh a, [hBattleTurn] + and a + jr z, .start + ld hl, wEnemyMonMaxHP + ld de, wEnemyMonHP + + .start + ; Index for .Multipliers + ; Default restores half max HP. +- ld c, 2 ++ ld c, 1 + + ; Don't bother healing if HP is already full. ++ inc c ; Temporarily increase c to compare bytes correctly. + push bc + call CompareBytes + pop bc + jr z, .Full ++ dec c ; Return c to its original value. + +-; Don't factor in time of day in link battles. +- ld a, [wLinkMode] +- and a +- jr nz, .Weather +- +- ld a, [wTimeOfDay] +- cp b +- jr z, .Weather +- dec c ; double + +... + + .Multipliers: +- dw GetEighthMaxHP + dw GetQuarterMaxHP + dw GetHalfMaxHP +- dw GetMaxHP ++ dw GetTwoThirdsMaxHP +``` +So let's explain what's happening. `ld c, 1` serves as our index for `.Multipliers`, which will initially point to `GetHalfMaxHP`. `CompareBytes` compares the current HP with the Max HP to determine whether to apply healing or not, and since we're comparing two bytes at `de` and `hl`, we need to temporarily `inc c`; after the comparison, we `dec c` back to 1. + +In Link battles the time of day isn't taken into account, but since we're modifying the code to also behave like this in normal gameplay, we no longer need the code block related to it. + +The last change was made to the `.Multipliers` jumptable, where we removed the now useless `GetEightMaxHP` and `GetMaxHP` for `GetTwoThirdsMaxHP` to make it point to functions that heal between ¼ Max HP and ⅔ Max HP. + +And that's it! Now Morning Sun, Synthesis and Moonlight behave like they do in Gen 3+, only taking the active weather into account. |