diff options
| author | Idain <luiscarlosholguinperez@outlook.com> | 2021-06-02 03:21:29 -0400 |
|---|---|---|
| committer | Idain <luiscarlosholguinperez@outlook.com> | 2021-06-02 03:21:29 -0400 |
| commit | cf964ea7543463a9c4175be722056de5277f12a6 (patch) | |
| tree | d5adaa62063ddaeac50a114df4f7295192d95ad6 | |
| parent | 7ce7dc361b7e6e2b0e353abed6ddf8e863afdc9b (diff) | |
Added Solar Beam's power section + formatting
| -rw-r--r-- | Add-Hail-as-a-new-weather-condition.md | 223 |
1 files changed, 152 insertions, 71 deletions
diff --git a/Add-Hail-as-a-new-weather-condition.md b/Add-Hail-as-a-new-weather-condition.md index 228d397..96552c0 100644 --- a/Add-Hail-as-a-new-weather-condition.md +++ b/Add-Hail-as-a-new-weather-condition.md @@ -8,9 +8,10 @@ Since Hail has a lot of similarities to Sandstorm, we can use it as a template i 2. [Add new text related to the weather condition](#2-add-new-text-related-to-the-weather-condition) 3. [Add damage-inflicting effect](#3-add-damage-inflicting-effect) 4. [Add Blizzard accuracy bypass effect](#4-add-blizzard-accuracy-bypass-effect) -5. [Add move that triggers the weather condition](#5-add-move-that-triggers-the-weather-condition) -6. [Teach the AI how to use this weather effectively](#6-teach-the-ai-how-to-use-this-weather-effectively) -7. [Make it look flashy!](#7-make-it-look-flashy) +5. [Halve Solar Beam's power during Hail](#5-halve-solar-beams-power-during-hail) +6. [Add move that triggers the weather condition](#6-add-move-that-triggers-the-weather-condition) +7. [Teach the AI how to use this weather effectively](#7-teach-the-ai-how-to-use-this-weather-effectively) +8. [Make it look flashy!](#8-make-it-look-flashy) ## 1. Define some new weather constants @@ -18,6 +19,9 @@ Since Hail has a lot of similarities to Sandstorm, we can use it as a template i Edit [constants/battle_constants.asm](../blob/master/constants/battle_constants.asm): ```diff +; values in wBattleWeather + const_def + const WEATHER_NONE const WEATHER_RAIN const WEATHER_SUN const WEATHER_SANDSTORM @@ -36,6 +40,8 @@ We need to create some new battle text to go along with the most relevant effect Edit [data/text/battle.asm](../blob/master/data/text/battle.asm): ```diff + BattleText_TheSandstormRages: + text "The sandstorm" line "rages." prompt @@ -44,12 +50,14 @@ Edit [data/text/battle.asm](../blob/master/data/text/battle.asm): + line "fall." + prompt + -BattleText_TheRainStopped: + BattleText_TheRainStopped: text "The rain stopped." prompt ... + BattleText_TheSandstormSubsided: + text "The sandstorm" line "subsided." prompt @@ -57,12 +65,13 @@ BattleText_TheRainStopped: + text "The hail stopped." + prompt + -BattleText_EnemyMonFainted: + BattleText_EnemyMonFainted: text "Enemy @" text_ram wEnemyMonNick ... + BattleText_NoTimeLeftToday: ; unreferenced text "There is no time" line "left today!" done @@ -79,7 +88,6 @@ BattleText_EnemyMonFainted: + ``` - ## 3. Add damage-inflicting effect Using Sandstorm as a guideline, we can create the actual effects of this new weather condition. This means inflicting some damage to all Pokémon, possibly excluding Ice-types. For Sandstorm, this is done core.asm. @@ -87,7 +95,7 @@ Using Sandstorm as a guideline, we can create the actual effects of this new wea Edit `HandleWeather` in [engine/battle/core.asm](../blob/master/engine/battle/core.asm): ```diff -HandleWeather: + HandleWeather: ... ld hl, wWeatherCount dec [hl] @@ -176,8 +184,8 @@ HandleWeather: ... -.WeatherMessages: -; entries correspond to WEATHER_* constants + .WeatherMessages: + ; entries correspond to WEATHER_* constants dw BattleText_RainContinuesToFall dw BattleText_TheSunlightIsStrong dw BattleText_TheSandstormRages @@ -189,9 +197,7 @@ HandleWeather: dw BattleText_TheSunlightFaded dw BattleText_TheSandstormSubsided + dw BattleText_TheHailStopped - - SubtractHPFromTarget: - call SubtractHP + ... ``` Some things to note. The `.ended` branch was moved up so as to avoid an unnecessary `jp` instruction after adding the Hail handling, and moves it closer to where the actual weather count check is made. If the weather effect is otherwise still continuing, then the code jumps to the `.continues` branch to execute the right weather effect. @@ -208,20 +214,26 @@ First we should associate Blizzard with a new specific move effect, which will b Edit [constants/move_effect_constants.asm](../blob/master/constants/move_effect_constants.asm): ```diff + ; MoveEffectsPointers indexes (see data/moves/effects_pointers.asm) + const_def + ... const EFFECT_BEAT_UP const EFFECT_FLY const EFFECT_DEFENSE_CURL + const EFFECT_BLIZZARD -NUM_MOVE_EFECTS EQU const_value + NUM_MOVE_EFECTS EQU const_value ``` Edit [data/moves/moves.asm](../blob/master/data/moves/moves.asm): ```diff - move ICE_BEAM, EFFECT_FREEZE_HIT, 95, ICE, SPECIAL, 100, 10, 10 -- move BLIZZARD, EFFECT_FREEZE_HIT, 120, ICE, SPECIAL, 70, 5, 10 -+ move BLIZZARD, EFFECT_BLIZZARD, 120, ICE, SPECIAL, 70, 5, 10 - move PSYBEAM, EFFECT_CONFUSE_HIT, 65, PSYCHIC_TYPE, SPECIAL, 100, 20, 10 + Moves: + ; entries correspond to constants/move_constants.asm + ... + move ICE_BEAM, EFFECT_FREEZE_HIT, 95, ICE, 100, 10, 10 +- move BLIZZARD, EFFECT_FREEZE_HIT, 120, ICE, 70, 5, 10 ++ move BLIZZARD, EFFECT_BLIZZARD, 120, ICE, 70, 5, 10 + move PSYBEAM, EFFECT_CONFUSE_HIT, 65, PSYCHIC_TYPE, 100, 20, 10 ``` For the effect pointer, we will reuse FreezeHit, since for the purposes of what commands the move will call, it is functionally identical to that effect. We don't need to copy it for a new redundant effect. @@ -229,6 +241,9 @@ For the effect pointer, we will reuse FreezeHit, since for the purposes of what Edit [data/moves/effects_pointers.asm](../blob/master/data/moves/effects_pointers.asm): ```diff + MoveEffectsPointers: + ; entries correspond to EFFECT_* constants + ... dw BeatUp dw Fly dw DefenseCurl @@ -236,12 +251,12 @@ Edit [data/moves/effects_pointers.asm](../blob/master/data/moves/effects_pointer assert_table_length NUM_MOVE_EFECTS ``` -Now we can check for this move effect when performing the accuracy checks, similar to how Thunder in rain works. +Now we can check for this move effect when performing the accuracy checks, similar to how Thunder works in rain. Edit `BattleCommand_CheckHit` in [engine/battle/effect_commands.asm](../blob/master/engine/battle/effect_commands.asm): ```diff -BattleCommand_CheckHit: + BattleCommand_CheckHit: ... call .ThunderRain ret z @@ -271,29 +286,53 @@ BattleCommand_CheckHit: .XAccuracy: ld a, BATTLE_VARS_SUBSTATUS4 call GetBattleVar + ... ``` `BattleCommand_CheckHit` is the routine which checks/decides whether any move (with some exceptions) will connect or not. There are special cases, such as Thunder in rain or having the "Locked-On" substatus. Here we add a subroutine which checks whether it's Blizzard (or more specifically, a move that has the effect EFFECT_BLIZZARD) and it's hailing, in which case it completely bypasses the accuracy check. +## 5. Halve Solar Beam's power during Hail -## 5. Add move that triggers the weather condition +During hail, Solar Beam's power is reduced by 50%, so we need to implement this. Go to [data/battle/weather_modifiers.asm](../blob/master/data/battle/weather_modifiers.asm): + +```diff + WeatherTypeModifiers: + db WEATHER_RAIN, WATER, MORE_EFFECTIVE + db WEATHER_RAIN, FIRE, NOT_VERY_EFFECTIVE + db WEATHER_SUN, FIRE, MORE_EFFECTIVE + db WEATHER_SUN, WATER, NOT_VERY_EFFECTIVE + db -1 ; end + + WeatherMoveModifiers: + db WEATHER_RAIN, EFFECT_SOLARBEAM, NOT_VERY_EFFECTIVE ++ db WEATHER_HAIL, EFFECT_SOLARBEAM, NOT_VERY_EFFECTIVE + db -1 ; end +``` + +## 6. Add move that triggers the weather condition We have successfully added a weather condition that we can never trigger. Let's fix that by introducing a new move, Hail. You can follow [this tutorial](https://github.com/pret/pokecrystal/wiki/Add-a-new-move) to learn how to add a new move, with the caveat that it should have a new move effect which we will implement, EFFECT_HAIL. Its battle properties are `HAIL, EFFECT_HAIL, 0, ICE, 100, 10, 0`. Let's define what this effect does. Modify [constants/move_effect_constants.asm](../blob/master/constants/move_effect_constants.asm) again: ```diff + ; MoveEffectsPointers indexes (see data/moves/effects_pointers.asm) + const_def + ... const EFFECT_BEAT_UP const EFFECT_FLY const EFFECT_DEFENSE_CURL const EFFECT_BLIZZARD + const EFFECT_HAIL -NUM_MOVE_EFECTS EQU const_value + NUM_MOVE_EFECTS EQU const_value ``` -Edit [data/moves/effects_pointers.asm](../blob/master/data/moves/effects_pointers.asm): +Edit [data/moves/effects_pointers.asm](../blob/master/data/moves/effects_pointers.asm) again: ```diff +MoveEffectsPointers: +; entries correspond to EFFECT_* constants + ... dw BeatUp dw Fly dw DefenseCurl @@ -305,9 +344,22 @@ Edit [data/moves/effects_pointers.asm](../blob/master/data/moves/effects_pointer Edit [data/moves/effects.asm](../blob/master/data/moves/effects.asm): ```diff - statupmessage - statupfailtext - endmove + MoveEffects: ; used only for BANK(MoveEffects) + + ... + + DefenseCurl: + checkobedience + usedmovetext + doturn + defenseup + curl + lowersub + statupanim + raisesub + statupmessage + statupfailtext + endmove +Hail: + checkobedience @@ -321,6 +373,8 @@ Edit [data/moves/effects.asm](../blob/master/data/moves/effects.asm): Edit [macros/scripts/battle_commands.asm](../blob/master/macros/scripts/battle_commands.asm): ```diff + ; BattleCommandPointers indexes (see data/battle/effect_command_pointers.asm) + ... command supereffectivelooptext ; ad command startloop ; ae command curl ; af @@ -335,6 +389,9 @@ NUM_EFFECT_COMMANDS EQU const_value - 1 Edit [data/battle/effect_command_pointers.asm](../blob/master/data/battle/effect_command_pointers.asm): ```diff + BattleCommandPointers: + ; entries correspond to macros/scripts/battle_commands.asm + ... dw BattleCommand_SuperEffectiveLoopText dw BattleCommand_StartLoop dw BattleCommand_Curl @@ -347,40 +404,52 @@ Here we introduced a new effect for starting the hail weather condition, and ass Create [engine/battle/move_effects/hail.asm](../blob/master/engine/battle/move_effects/hail.asm): ```diff -BattleCommand_StartHail: -; starthail - ld a, WEATHER_HAIL - ld [wBattleWeather], a - ld a, 5 - ld [wWeatherCount], a - ld hl, ItStartedToHailText - jp StdBattleTextbox - ++BattleCommand_StartHail: ++; starthail ++ ++ ld a, [wBattleWeather] ++ cp WEATHER_HAIL ++ jr z, .failed ++ ++ ld a, WEATHER_HAIL ++ ld [wBattleWeather], a ++ ld a, 5 ++ ld [wWeatherCount], a ++ ld hl, ItStartedToHailText ++ jp StdBattleTextbox ++ ++.failed ++ call AnimateFailedMove ++ jp PrintButItFailed ++ ``` Edit [engine/battle/effect_commands.asm](../blob/master/engine/battle/effect_commands.asm) again: ```diff -INCLUDE "engine/battle/move_effects/future_sight.asm" + INCLUDE "engine/battle/move_effects/future_sight.asm" -INCLUDE "engine/battle/move_effects/thunder.asm" + INCLUDE "engine/battle/move_effects/thunder.asm" +INCLUDE "engine/battle/move_effects/hail.asm" -CheckHiddenOpponent: + CheckHiddenOpponent: + ... ``` -This routine simply loads the weather with the hail constant we defined, and sets its remaining turns to 5. It then prints some text to this effect. For all practical purposes, our new weather is now implemented. +This routine simply loads the weather with the hail constant we defined, and sets its remaining turns to 5; in case hail is already set up, it'll fail. The function also prints text depending on what happens. For all practical purposes, our new weather is now implemented. If you run this at this stage, the new move is functional and the effects work as intended, but we can still do some extra steps in order to polish it. The rest of the sections should be considered optional. -## 6. Teach the AI how to use this weather effectively +## 7. Teach the AI how to use this weather effectively There is already some rudimentary logic on how the AI uses the other weather effects. Let's implement some basic checking to have the AI also use Hail in a (minimally) effective manner. Modify [engine/battle/ai/redundant.asm](../blob/master/engine/battle/ai/redundant.asm): ```diff + .Moves: + ... dbw EFFECT_MOONLIGHT, .Moonlight dbw EFFECT_SWAGGER, .Swagger dbw EFFECT_FUTURE_SIGHT, .FutureSight @@ -395,10 +464,11 @@ Modify [engine/battle/ai/redundant.asm](../blob/master/engine/battle/ai/redundan + jr z, .Redundant + jr .NotRedundant + -.Heal: -.MorningSun: -.Synthesis: -.Moonlight: + .Heal: + .MorningSun: + .Synthesis: + .Moonlight: + ... ``` This file lists some moves that the AI can quickly check for redundancy. Hail has a quick redundancy check in which, if it's hailing, then the move should be dismissed. @@ -406,7 +476,7 @@ This file lists some moves that the AI can quickly check for redundancy. Hail ha Edit [engine/battle/ai/scoring.asm](../blob/master/engine/battle/ai/scoring.asm): ```diff -AI_Smart_EffectHandlers: + AI_Smart_EffectHandlers: ... dbw EFFECT_SOLARBEAM, AI_Smart_Solarbeam dbw EFFECT_THUNDER, AI_Smart_Thunder @@ -453,7 +523,6 @@ AI_Smart_EffectHandlers: + +.greatly_discourage + inc [hl] -+ +.discourage + inc [hl] + ret @@ -462,7 +531,7 @@ AI_Smart_EffectHandlers: + db BLIZZARD + db -1 ; end + -AI_Smart_Endure: + AI_Smart_Endure: ld a, [wEnemyProtectCount] and a ``` @@ -470,42 +539,47 @@ AI_Smart_Endure: We base this behavior on the Sunny Day/Rain Dance and Sandstorm AI-related routines. The AI will avoid using the move if the player is immune to Hail or has low HP, and will encourage the move if it has any "Good Hail moves", which right now is only composed of the move Blizzard. This list is fully extensible with other moves. -## 7. Make it look flashy! +## 8. Make it look flashy! The move and weather have no special animations. It's completely possible to reuse some other move animation (such as Powder Snow), but we can quickly whip something up with the resources we already have at our disposal. The Sandstorm animation already works well as a "weather hazard," and there are some sprites representing ice, so let's make use of them. Edit [constants/battle_anim_constants.asm](../blob/master/constants/battle_anim_constants.asm): ```diff + ; BattleAnimObjects indexes (see data/battle_anims/objects.asm) + const_def + ... const ANIM_OBJ_PLAYERHEAD_1ROW const ANIM_OBJ_ENEMYFEET_2ROW const ANIM_OBJ_PLAYERHEAD_2ROW + const ANIM_OBJ_HAIL -NUM_ANIM_OBJS EQU const_value + NUM_ANIM_OBJS EQU const_value -; DoBattleAnimFrame arguments (see engine/battle_anims/functions.asm) + ; BattleAnimFrameData indexes (see data/battle_anims/framesets.asm) const_def - ... - const BATTLEANIMFRAMESET_B6 const BATTLEANIMFRAMESET_B7 const BATTLEANIMFRAMESET_B8 + const BATTLEANIMFRAMESET_HAIL -NUM_BATTLEANIMFRAMESETS EQU const_value + NUM_BATTLEANIMFRAMESETS EQU const_value + ; BattleAnimOAMData indexes (see data/battle_anims/oam.asm) + const_def ... - const BATTLEANIMOAMSET_D5 const BATTLEANIMOAMSET_D6 const BATTLEANIMOAMSET_D7 + const BATTLEANIMOAMSET_HAIL -NUM_BATTLEANIMOAMSETS EQU const_value + NUM_BATTLEANIMOAMSETS EQU const_value ``` Edit [data/battle_anims/framesets.asm](../blob/master/data/battle_anims/framesets.asm): ```diff + BattleAnimFrameData: + ; entries correspond to BATTLEANIMFRAMESET_* constants + ... dw .Frameset_b6 ; BATTLEANIMFRAMESET_B6 dw .Frameset_b7 ; BATTLEANIMFRAMESET_B7 dw .Frameset_b8 ; BATTLEANIMFRAMESET_B8 @@ -526,10 +600,13 @@ Edit [data/battle_anims/framesets.asm](../blob/master/data/battle_anims/frameset Edit [data/battle_anims/oam.asm](../blob/master/data/battle_anims/oam.asm): ```diff - dbbw $00, 6, .OAMData_d5 ; BATTLEANIMOAMSET_D5 - dbbw $00, 14, .OAMData_d6 ; BATTLEANIMOAMSET_D6 - dbbw $00, 12, .OAMData_d7 ; BATTLEANIMOAMSET_D7 -+ dbbw $00, 13, .OAMData_Hail ; BATTLEANIMOAMSET_HAIL + BattleAnimOAMData: + ; entries correspond to BATTLEANIMOAMSET_* constants + ... + battleanimoam $00, 6, .OAMData_d5 ; BATTLEANIMOAMSET_D5 + battleanimoam $00, 14, .OAMData_d6 ; BATTLEANIMOAMSET_D6 + battleanimoam $00, 12, .OAMData_d7 ; BATTLEANIMOAMSET_D7 ++ battleanimoam $00, 13, .OAMData_Hail ; BATTLEANIMOAMSET_HAIL assert_table_length NUM_BATTLEANIMOAMSETS ... @@ -560,9 +637,9 @@ These are simply some frame and OAM data that we'll use to get the proper tile f Modify [data/battle_anims/objects.asm](../blob/master/data/battle_anims/objects.asm): ```diff -; ANIM_OBJ_ENEMYFEET_2ROW + ; ANIM_OBJ_ENEMYFEET_2ROW battleanimobj ABSOLUTE_X, $00, BATTLEANIMFRAMESET_B7, BATTLEANIMFUNC_NULL, PAL_BATTLE_OB_ENEMY, ANIM_GFX_PLAYERHEAD -; ANIM_OBJ_PLAYERHEAD_2ROW + ; ANIM_OBJ_PLAYERHEAD_2ROW battleanimobj ABSOLUTE_X, $00, BATTLEANIMFRAMESET_B8, BATTLEANIMFUNC_NULL, PAL_BATTLE_OB_PLAYER, ANIM_GFX_ENEMYFEET +; ANIM_OBJ_HAIL + battleanimobj RELATIVE_X | X_FLIP, $00, BATTLEANIMFRAMESET_HAIL, BATTLEANIMFUNC_RAIN_SANDSTORM, PAL_BATTLE_OB_BLUE, ANIM_GFX_ICE @@ -574,11 +651,13 @@ Objects are the data structures that serve as the "particles" in the game's anim Edit [constants/move_constants.asm](../blob/master/constants/move_constants.asm): ```diff + ; battle anims + ... const ANIM_WOBBLE ; 113 const ANIM_SHAKE ; 114 const ANIM_HIT_CONFUSION ; 115 + const ANIM_IN_HAIL ; 116 -NUM_BATTLE_ANIMS EQU const_value - 1 + NUM_BATTLE_ANIMS EQU const_value - 1 ``` Modify [data/moves/animations.asm](../blob/master/data/moves/animations.asm): @@ -601,11 +680,11 @@ Modify [data/moves/animations.asm](../blob/master/data/moves/animations.asm): + dw BattleAnim_InHail assert_table_length NUM_BATTLE_ANIMS + 1 -BattleAnim_0: + BattleAnim_0: -BattleAnim_252: -BattleAnim_253: -BattleAnim_254: -BattleAnim_MirrorMove: + BattleAnim_253: + BattleAnim_254: + BattleAnim_MirrorMove: anim_ret ... @@ -632,10 +711,11 @@ BattleAnim_MirrorMove: + anim_ret + -BattleAnimSub_Drain: + BattleAnimSub_Drain: anim_obj ANIM_OBJ_DRAIN, 132, 44, $0 anim_obj ANIM_OBJ_DRAIN, 132, 44, $8 anim_obj ANIM_OBJ_DRAIN, 132, 44, $10 +... ``` The animation is now complete, so now we can call it whenever we need to show some hailing in the battle screen. @@ -643,7 +723,7 @@ The animation is now complete, so now we can call it whenever we need to show so Edit `HandleWeather.HailDamage` in [engine/battle/core.asm](../blob/master/engine/battle/core.asm): ```diff -.HailDamage: + .HailDamage: ... ld a, [hl] @@ -657,7 +737,7 @@ Edit `HandleWeather.HailDamage` in [engine/battle/core.asm](../blob/master/engin + call Call_PlayBattleAnim + call SwitchTurnCore + - call GetEighthMaxHP + call GetSixteenthMaxHP call SubtractHPFromUser ld hl, PeltedByHailText @@ -667,8 +747,9 @@ Edit `HandleWeather.HailDamage` in [engine/battle/core.asm](../blob/master/engin Modify the earlier file we created, `BattleCommand_StartHail` in [engine/battle/move_effects/hail.asm](../blob/master/engine/battle/move_effects/hail.asm): ```diff -BattleCommand_StartHail: -; starthail + BattleCommand_StartHail: + ; starthail + ... ld a, WEATHER_HAIL ld [wBattleWeather], a ld a, 5 @@ -676,7 +757,7 @@ BattleCommand_StartHail: + call AnimateCurrentMove ld hl, ItStartedToHailText jp StdBattleTextbox - + ... ``` And with that, everything is in place, and now we have a brand new weather type to use in the game! The main point of this tutorial was to show how one can simply use the resources already available to create something new. In a lot of cases, it helps to check similar systems already implemented in the codebase. |
