# The Complete Damage Formula for Black & White

## Introduction

In Generation IV, the damage formula was derived empirically by X-Act from running it countless times, an approach that is both tedious and prone to errors. The good understanding of the ARM code for Black & White allows us to document the damage formula based on the actual source code of the game. It doesn't guarantee that we didn't make any mistake (interpreting assembly language is in itself a tricky task) but having the documented source along with the formula backs up our claims and allows anyone who spots any error to fix it by themselves.

## Main concepts

### General flow of damage calculation

1. MEMORY:021C1E94 @ int __fastcall DamageCalc(void *trigger_table, void **attacking_bpkm, void **defending_bpkm, unsigned __int16 *move_id)
2. MEMORY:021C1E94 DamageCalc:                             @ CODE XREF: MEMORY:021C0B28p
3. MEMORY:021C1E94
4. MEMORY:021C1E94 double_damage= -0x30
5. MEMORY:021C1E94 p_attacking= -0x2C
6. MEMORY:021C1E94 current_damage= -0x28
7. MEMORY:021C1E94 static_damage= -0x24
8. MEMORY:021C1E94 move_cat= -0x20
9. MEMORY:021C1E94 base_power= -0x1C
10. MEMORY:021C1E94 attack_stat= -0x18
11. MEMORY:021C1E94 effectiveness_factor=  0
12. MEMORY:021C1E94 field_mod=  4
13. MEMORY:021C1E94 is_critical=  8
14. MEMORY:021C1E94 rig_mindamage=  0xC
15. MEMORY:021C1E94 p_store_result=  0x10
16. MEMORY:021C1E94
17. MEMORY:021C1E94 PUSH    {R4-R7,LR}
18. MEMORY:021C1E96 SUB     SP, SP, #0x1C
19. MEMORY:021C1E98 MOVS    R4, R3
20. MEMORY:021C1E9A MOVS    R5, R0
21. MEMORY:021C1E9C LDRH    R0, [R4]
22. MEMORY:021C1E9E STR     R1, [SP,#0x30+p_attacking]
23. MEMORY:021C1EA0 MOVS    R7, R2
24. MEMORY:021C1EA2 LDR     R6, [SP,#0x30+is_critical]
25. MEMORY:021C1EA4 BL      GetMoveCategory
26. MEMORY:021C1EA8 STR     R0, [SP,#0x30+move_cat]
27. MEMORY:021C1EAA MOVS    R0, #0
28. MEMORY:021C1EAC STR     R0, [SP,#0x30+static_damage]
29. MEMORY:021C1EAE LDR     R0, =0x1C21
30. MEMORY:021C1EB0 BL      AllocateVolatileVariables
31. MEMORY:021C1EB4 LDR     R1, [SP,#0x30+effectiveness_factor]
32. MEMORY:021C1EB6 MOVS    R0, #0x38 @ '8'
33. MEMORY:021C1EB8 BL      StoreVolatileVariableFlag3e4
34. MEMORY:021C1EBC LDR     R0, [SP,#0x30+p_attacking]
35. MEMORY:021C1EBE BL      Dereference25
36. MEMORY:021C1EC2 MOVS    R1, R0
37. MEMORY:021C1EC4 MOVS    R0, #3
38. MEMORY:021C1EC6 BL      StoreVolatileVariableFlag3e4
39. MEMORY:021C1ECA MOVS    R0, R7
40. MEMORY:021C1ECC BL      Dereference25
41. MEMORY:021C1ED0 MOVS    R1, R0
42. MEMORY:021C1ED2 MOVS    R0, #4
43. MEMORY:021C1ED4 BL      StoreVolatileVariableFlag3e4
44. MEMORY:021C1ED8 MOVS    R0, #0x45 @ 'E'
45. MEMORY:021C1EDA MOVS    R1, R6
46. MEMORY:021C1EDC BL      StoreVolatileVariableFlag3e4
47. MEMORY:021C1EE0 LDRB    R1, [R4,#6]
48. MEMORY:021C1EE2 MOVS    R0, #0x16
49. MEMORY:021C1EE4 BL      StoreVolatileVariableFlag3e4
50. MEMORY:021C1EE8 LDRH    R1, [R4]
51. MEMORY:021C1EEA MOVS    R0, #0x12
52. MEMORY:021C1EEC BL      StoreVolatileVariableFlag3e4
53. MEMORY:021C1EF0 LDR     R1, [SP,#0x30+move_cat]
54. MEMORY:021C1EF2 MOVS    R0, #0x1A
55. MEMORY:021C1EF4 BL      StoreVolatileVariableFlag3e4
56. MEMORY:021C1EF8 MOVS    R0, #0x37 @ '7'
57. MEMORY:021C1EFA MOVS    R1, #0
58. MEMORY:021C1EFC BL      InitVolatileVariable
59. MEMORY:021C1F00 MOVS    R0, R5
60. MEMORY:021C1F02 MOVS    R1, #0x46 @ 'F'
61. MEMORY:021C1F04 BL      ApplyTriggers
62. MEMORY:021C1F08 MOVS    R0, #0x37 @ '7'
63. MEMORY:021C1F0A BL      ReadVolatileVariable
64. MEMORY:021C1F0E STR     R0, [SP,#0x30+current_damage]
65. MEMORY:021C1F10 CMP     R0, #0
66. MEMORY:021C1F12 BEQ     Bank0
67. MEMORY:021C1F14 MOVS    R0, #1
68. MEMORY:021C1F16 STR     R0, [SP,#0x30+static_damage]
69. MEMORY:021C1F18 B       Bank9
70. MEMORY:021C1F1A @ ---------------------------------------------------------------------------
71. MEMORY:021C1F1A
72. MEMORY:021C1F1A Bank0:                                  @ CODE XREF: DamageCalc+7Ej
73. MEMORY:021C1F1A LDR     R1, [SP,#0x30+p_attacking]
74. MEMORY:021C1F1C MOVS    R0, R5
75. MEMORY:021C1F1E MOVS    R2, R7
76. MEMORY:021C1F20 MOVS    R3, R4
77. MEMORY:021C1F22 BL      BasePowerMods
78. MEMORY:021C1F26 STR     R0, [SP,#0x30+base_power]
79. MEMORY:021C1F28 LDR     R1, [SP,#0x30+p_attacking]
80. MEMORY:021C1F2A MOVS    R0, R5
81. MEMORY:021C1F2C MOVS    R2, R7
82. MEMORY:021C1F2E MOVS    R3, R4
83. MEMORY:021C1F30 STR     R6, [SP,#0x30+double_damage]
84. MEMORY:021C1F32 BL      BaseAttackMods
85. MEMORY:021C1F36 STR     R0, [SP,#0x30+attack_stat]
86. MEMORY:021C1F38 LDR     R1, [SP,#0x30+p_attacking]
87. MEMORY:021C1F3A MOVS    R0, R5
88. MEMORY:021C1F3C MOVS    R2, R7
89. MEMORY:021C1F3E MOVS    R3, R4
90. MEMORY:021C1F40 STR     R6, [SP,#0x30+double_damage]
91. MEMORY:021C1F42 BL      BaseDefenseMods
92. MEMORY:021C1F46 MOVS    R7, R0
93. MEMORY:021C1F48 LDR     R0, [SP,#0x30+p_attacking]
94. MEMORY:021C1F4A MOVS    R1, #0xF
95. MEMORY:021C1F4C BL      GetBpkmStat
96. MEMORY:021C1F50 LSLS    R0, R0, #0x18
97. MEMORY:021C1F52 LSRS    R2, R0, #0x18
98. MEMORY:021C1F54 LDR     R0, [SP,#0x30+base_power]
99. MEMORY:021C1F56 LDR     R1, [SP,#0x30+attack_stat]
100. MEMORY:021C1F58 MOVS    R3, R7
101. MEMORY:021C1F5A BL      BaseDamageFormula
102. MEMORY:021C1F5E MOVS    R2, #4
103. MEMORY:021C1F60 LDR     R1, [SP,#0x30+field_mod]
104. MEMORY:021C1F62 LSLS    R2, R2, #0xA
105. MEMORY:021C1F64 MOVS    R7, R0
106. MEMORY:021C1F66 CMP     R1, R2
107. MEMORY:021C1F68 BEQ     Bank1
108. MEMORY:021C1F6A BL      ApplyMod
109. MEMORY:021C1F6E ADDS    R7, R0, #0
110. MEMORY:021C1F70
111. MEMORY:021C1F70 Bank1:                                  @ CODE XREF: DamageCalc+D4j
112. MEMORY:021C1F70 MOVS    R0, R5
113. MEMORY:021C1F72 BL      WeatherTriggers
114. MEMORY:021C1F76 LDRB    R1, [R4,#6]
115. MEMORY:021C1F78 BL      WeatherMod
116. MEMORY:021C1F7C MOVS    R1, R0
117. MEMORY:021C1F7E MOVS    R0, 0x1000
118. MEMORY:021C1F82 CMP     R1, R0
119. MEMORY:021C1F84 BEQ     Bank2
120. MEMORY:021C1F86 MOVS    R0, R7
121. MEMORY:021C1F88 BL      ApplyMod
122. MEMORY:021C1F8C ADDS    R7, R0, #0
123. MEMORY:021C1F8E
124. MEMORY:021C1F8E Bank2:                                  @ CODE XREF: DamageCalc+F0j
125. MEMORY:021C1F8E CMP     R6, #0
126. MEMORY:021C1F90 BEQ     Bank3
127. MEMORY:021C1F92 LSLS    R7, R7, #1
128. MEMORY:021C1F94
129. MEMORY:021C1F94 Bank3:                                  @ CODE XREF: DamageCalc+FCj
130. MEMORY:021C1F94 LDR     R0, [R5,#4]
131. MEMORY:021C1F96 MOVS    R1, #7
132. MEMORY:021C1F98 BL      sub_21B913C
133. MEMORY:021C1F9C CMP     R0, #0
134. MEMORY:021C1F9E BNE     Bank6
135. MEMORY:021C1FA0 LDR     R0, [SP,#0x30+rig_mindamage]
136. MEMORY:021C1FA2 CMP     R0, #0
137. MEMORY:021C1FA4 BEQ     Bank4
138. MEMORY:021C1FA6 MOVS    R0, #0x55 @ 'U'
139. MEMORY:021C1FA8 B       Bank5
140. MEMORY:021C1FAA @ ---------------------------------------------------------------------------
141. MEMORY:021C1FAA
142. MEMORY:021C1FAA Bank4:                                  @ CODE XREF: DamageCalc+110j
143. MEMORY:021C1FAA MOVS    R0, #0x10
144. MEMORY:021C1FAC BL      BRand
145. MEMORY:021C1FB0 MOVS    R1, #0x64 @ 'd'
146. MEMORY:021C1FB2 SUBS    R0, R1, R0
147. MEMORY:021C1FB4 LSLS    R0, R0, #0x10
148. MEMORY:021C1FB6 LSRS    R0, R0, #0x10
149. MEMORY:021C1FB8
150. MEMORY:021C1FB8 Bank5:                                  @ CODE XREF: DamageCalc+114j
151. MEMORY:021C1FB8 MULS    R0, R7
152. MEMORY:021C1FBA MOVS    R1, #0x64 @ 'd'                 @ divisor
153. MEMORY:021C1FBC BLX     divmodUnsigned__
154. MEMORY:021C1FC0 ADDS    R7, R0, #0
155. MEMORY:021C1FC2
156. MEMORY:021C1FC2 Bank6:                                  @ CODE XREF: DamageCalc+10Aj
157. MEMORY:021C1FC2 LDRB    R2, [R4,#6]
158. MEMORY:021C1FC4 CMP     R2, #0x11
159. MEMORY:021C1FC6 BEQ     Bank7
160. MEMORY:021C1FC8 LDR     R1, [SP,#0x30+p_attacking]
161. MEMORY:021C1FCA ADDS    R0, R5, #0
162. MEMORY:021C1FCC
163. MEMORY:021C1FCC Bank_STAB:                              @ CODE XREF: MEMORY:021C1D6Aj
164. MEMORY:021C1FCC BL      STAB
165. MEMORY:021C1FD0 MOVS    R1, R0
166. MEMORY:021C1FD2 MOVS    R0, R7
167. MEMORY:021C1FD4 BL      ApplyMod
168. MEMORY:021C1FD8 ADDS    R7, R0, #0
169. MEMORY:021C1FDA
170. MEMORY:021C1FDA Bank7:                                  @ CODE XREF: DamageCalc+132j
171. MEMORY:021C1FDA LDR     R1, [SP,#0x30+effectiveness_factor]
172. MEMORY:021C1FDC
173. MEMORY:021C1FDC loc_21C1FDC:                            @ CODE XREF: MEMORY:021C1D7Aj
174. MEMORY:021C1FDC MOVS    R0, R7
175. MEMORY:021C1FDE BL      TypeEffectiveness
176. MEMORY:021C1FE2 MOVS    R4, R0
177. MEMORY:021C1FE4 LDR     R0, [SP,#0x30+move_cat]
178. MEMORY:021C1FE6 CMP     R0, #1
179. MEMORY:021C1FE8 BNE     Bank_notnull
180. MEMORY:021C1FEA LDR     R0, [SP,#0x30+p_attacking]
181. MEMORY:021C1FEC BL      GetBpkmStatus
182. MEMORY:021C1FF0 CMP     R0, #4
183. MEMORY:021C1FF2 BNE     Bank_notnull
184. MEMORY:021C1FF4 LDR     R0, [SP,#0x30+p_attacking]
185. MEMORY:021C1FF6 MOVS    R1, #0x11
186. MEMORY:021C1FF8 BL      GetBpkmStat
187. MEMORY:021C1FFC CMP     R0, #0x3E @ '>'
188. MEMORY:021C1FFE BEQ     Bank_notnull
189. MEMORY:021C2000 MOVS    R0, #0x32 @ '2'
190. MEMORY:021C2002 MULS    R0, R4
191. MEMORY:021C2004 MOVS    R1, #0x64 @ 'd'                 @ divisor
192. MEMORY:021C2006 BLX     divmodUnsigned__
193. MEMORY:021C200A ADDS    R4, R0, #0
194. MEMORY:021C200C
195. MEMORY:021C200C Bank_notnull:                           @ CODE XREF: DamageCalc+154j
196. MEMORY:021C200C                                         @ DamageCalc+15Ej ...
197. MEMORY:021C200C CMP     R4, #0
198. MEMORY:021C200E BNE     Bank8
199. MEMORY:021C2010 MOVS    R4, #1
200. MEMORY:021C2012
201. MEMORY:021C2012 Bank8:                                  @ CODE XREF: DamageCalc+17Aj
202. MEMORY:021C2012 MOVS    R1, 0x1000
203. MEMORY:021C2016 MOVS    R0, #0x35 @ '5'
204. MEMORY:021C2018 MOVS    R2, #0x29 @ ')'
205. MEMORY:021C201A LSLS    R3, R1, #5
206. MEMORY:021C201C BL      StoreVolatileVariableFlag3e3
207. MEMORY:021C2020 MOVS    R0, #0x32 @ '2'
208. MEMORY:021C2022 MOVS    R1, R4
209. MEMORY:021C2024 BL      InitVolatileVariable
210. MEMORY:021C2028 MOVS    R0, R5
211. MEMORY:021C202A MOVS    R1, #0x47 @ 'G'
212. MEMORY:021C202C BL      ApplyTriggers
213. MEMORY:021C2030 MOVS    R0, #0x35 @ '5'
214. MEMORY:021C2032 BL      ReadVolatileVariable
215. MEMORY:021C2036 MOVS    R4, R0
216. MEMORY:021C2038 MOVS    R0, #0x32 @ '2'
217. MEMORY:021C203A BL      ReadVolatileVariable
218. MEMORY:021C203E MOVS    R1, R4
219. MEMORY:021C2040 BL      ApplyMod
220. MEMORY:021C2044 STR     R0, [SP,#0x30+current_damage]
221. MEMORY:021C2046
222. MEMORY:021C2046 Bank9:                                  @ CODE XREF: DamageCalc+84j
223. MEMORY:021C2046 MOVS    R0, R5
224. MEMORY:021C2048 MOVS    R1, #0x48 @ 'H'
225. MEMORY:021C204A BL      ApplyTriggers
226. MEMORY:021C204E LDR     R0, =0x1C8D
227. MEMORY:021C2050 BL      FreeVolatileVariable
228. MEMORY:021C2054 LDR     R1, [SP,#0x30+p_store_result]
229. MEMORY:021C2056 LDR     R0, [SP,#0x30+current_damage]
230. MEMORY:021C2058 STRH    R0, [R1]
231. MEMORY:021C205A LDR     R0, [SP,#0x30+static_damage]
232. MEMORY:021C205C ADD     SP, SP, #0x1C
233. MEMORY:021C205E POP     {R4-R7,PC}
234. MEMORY:021C205E @ End of function DamageCalc
235.

Roughly speaking, the damage formula in Pokémon is a big multiplication, each factor representing the user's level and attack stat, the foe's defense stat, and a bunch of factors for STAB, held items, abilities and other field effects. In a perfect world where ARM CPUs could work on real numbers, it would be possible to multiply each factor in any order and get the same result, but in practice the game will round some multiplications and truncate others, meaning that in order to get accurate damage results, it is of utmost importance to perform the multiplication in the same order as the game and using the same rounding methods. Even though rounding errors might not sound like a big problem, they will be amplified at each step, and a few factors such as Reflect and Life Orb in a double battle can cause a significant difference between an unrounded and a properly rounded calculation.

There are three main parameters for damage calculation: the user's attack stat, the target's defense stat and the move's base power. To compute these stats, the game starts from a base value and apply a modifier to reflect the various effects that can alter the base value. This modifier is obtained by running through a list of short functions called triggers that are called based on the current active effects on field. Different triggers can modify the same modifier before it is applied, this operation is called chaining and is explained below.

Once the main parameters are set, the general steps of the calculation are as follows:

BaseDamage = ((((2 × Level) ÷ 5 + 2) * BasePower * [Sp]Atk) ÷ [Sp]Def) ÷ 50 + 2

1. Apply the multi-target modifier
2. Apply the weather modifier
3. In case of a critical hit, double the value
4. Alter with a random factor
5. Apply STAB modifier
6. Alter with type effectiveness
7. Alter with user's burn
8. Make sure damage is at least 1
9. Apply the final modifier

In this article, ÷ always denotes the in-game unsigned divmod function, i.e. the unrounded/truncated integer division. By contrast, "apply a modifier" is a rounded operation explained in the next subsection.

There are some exceptions to the formula above that correspond to the set of triggers at the very top of the damage function; they are detailed in a separate section.

### How to apply a modifier

1. MEMORY:021D7B30 @ int __fastcall ApplyMod(int base_value, int modifier)
2. MEMORY:021D7B30 ApplyMod:                               @ CODE XREF: sub_21BC968+68p
3. MEMORY:021D7B30 MULS    R1, R0
4. MEMORY:021D7B32 LDR     R0, =0xFFF
5. MEMORY:021D7B34 MOVS    R2, R1
6. MEMORY:021D7B36 ANDS    R2, R0
7. MEMORY:021D7B38 LSRS    R0, R1, #0xC
8. MEMORY:021D7B3A MOVS    R1, 0x800
9. MEMORY:021D7B3E CMP     R2, R1
10. MEMORY:021D7B40 BLS     locret_21D7B44
11. MEMORY:021D7B42 ADDS    R0, R0, #1

A modifier is a 16 bit fixed point factor, i.e. a fraction whose divisor is always 0x1000 (4096). For instance, 0x14cc is the modifier for Life Orb (0x14cc/0x1000 is about 1.3). Applying the modifier M to the damage value D means multiplying D by M and dividing the result by 0x1000; then if the decimal part is ≤0.5, round the result down, otherwise round it up. Simply put: D' = round(D * M / 0x1000)

### How to chain modifiers

1. MEMORY:021D7724 @ void __fastcall ChainMod(__int16 Volatile_index, int mod)
2. MEMORY:021D7724 ChainMod:                               @ CODE XREF: AccuracyCheck+FAp
3. MEMORY:021D7724                                         @ MEMORY:021D8B5Ep ...
4. MEMORY:021D7724 PUSH    {R3-R7,LR}
5. MEMORY:021D7726 MOVS    R2, R0
6. MEMORY:021D7728 MOVS    R7, R1
7. MEMORY:021D772A LDR     R0, =VolatileStore
8. MEMORY:021D772C MOVS    R1, R2
9. MEMORY:021D772E BL      sub_21D7808
10. MEMORY:021D7732 MOVS    R5, R0
11. MEMORY:021D7734 BMI     locret_21D7772
12. MEMORY:021D7736 LDR     R0, =VolatileStore
13. MEMORY:021D7738 ADDS    R1, R0, R5
14. MEMORY:021D773A LDR     R0, =0x544
15. MEMORY:021D773C LDRB    R0, [R1,R0]
16. MEMORY:021D773E CMP     R0, #3
17. MEMORY:021D7740 BNE     locret_21D7772
18. MEMORY:021D7742 LDR     R4, =VolatileStore
19. MEMORY:021D7744 LSLS    R6, R5, #2
20. MEMORY:021D7746 ADDS    R4, #0xC4 @ '-'
21. MEMORY:021D7748 LDR     R0, [R4,R6]                     @ num1
22. MEMORY:021D774A ASRS    R3, R7, #0x1F
23. MEMORY:021D774C ASRS    R1, R0, #0x1F
24. MEMORY:021D774E MOVS    R2, R7                          @ num2
25. MEMORY:021D7750 BLX     mul64Unsigned__
26. MEMORY:021D7754 MOVS    R3, R1
27. MEMORY:021D7756 MOVS    R1, R5
28. MEMORY:021D7758 MOVS    R5, #2
29. MEMORY:021D775A MOVS    R2, R0
30. MEMORY:021D775C MOVS    R7, #0
31. MEMORY:021D775E LSLS    R5, R5, #0xA
32. MEMORY:021D7760 ADDS    R2, R2, R5
33. MEMORY:021D7762 ADCS    R3, R7
34. MEMORY:021D7764 LDR     R0, =VolatileStore
35. MEMORY:021D7766 LSLS    R3, R3, #0x14
36. MEMORY:021D7768 LSRS    R2, R2, #0xC
37. MEMORY:021D776A ORRS    R2, R3
38. MEMORY:021D776C BL      sub_21D782C
39. MEMORY:021D7770 STR     R0, [R4,R6]

Recall that modifiers for a given parameters are computed by the triggers for that parameter. This means that when multiple triggers apply, you have to chain the modifier for the parameter, starting from 0x1000. If the current modifier is M and you want to chain with another modifier M', the resulting modifier would be: M'' = ((M * M') + 0x800) >> 12

### The multi-target modifier

1. MEMORY:021C0DCC @ ---------------------------------------------------------------------------
2. MEMORY:021C0DBE BL      sub_21C0EE4
3. MEMORY:021C0DC2 CMP     R0, #1
4. MEMORY:021C0DC4 BNE     loc_21C0DCC
5. MEMORY:021C0DC6 MOVS    R4, 0x1000
6. MEMORY:021C0DCA B       loc_21C0DD0
7. MEMORY:021C0DCC @ ---------------------------------------------------------------------------
8. MEMORY:021C0DCC loc_21C0DCC:
9. MEMORY:021C0DCC MOVS    R4, 0xC00

This modifier doesn't have any trigger and is set to 0xC00 if the move has more than one target and 0x1000 otherwise. Being a target is independent of all accuracy and effectiveness checks, but a fainted Pokémon on the field will not count as a target.

### The weather modifier

1. MEMORY:021D7C58 @ int __fastcall WeatherMod(__int16 active_weather)
2. MEMORY:021D7C58 WeatherMod:                             @ CODE XREF: DamageCalc+E4p
3. MEMORY:021D7C58 CMP     R0, #1
4. MEMORY:021D7C5A BEQ     loc_21D7C62
5. MEMORY:021D7C5C CMP     R0, #2
6. MEMORY:021D7C5E BEQ     loc_21D7C76
7. MEMORY:021D7C60 B       loc_21D7C8A
8. MEMORY:021D7C62 @ ---------------------------------------------------------------------------
9. MEMORY:021D7C62
10. MEMORY:021D7C62 loc_21D7C62:                            @ CODE XREF: WeatherMod+2j
11. MEMORY:021D7C62 CMP     R1, #9
12. MEMORY:021D7C64 BNE     loc_21D7C6C
13. MEMORY:021D7C66 MOVS    R0, 0x1800
14. MEMORY:021D7C6A BX      LR
15. MEMORY:021D7C6C @ ---------------------------------------------------------------------------
16. MEMORY:021D7C6C
17. MEMORY:021D7C6C loc_21D7C6C:                            @ CODE XREF: WeatherMod+Cj
18. MEMORY:021D7C6C CMP     R1, #0xA
19. MEMORY:021D7C6E BNE     loc_21D7C8A
20. MEMORY:021D7C70 MOVS    R0, 0x800
21. MEMORY:021D7C74 BX      LR
22. MEMORY:021D7C76 @ ---------------------------------------------------------------------------
23. MEMORY:021D7C76
24. MEMORY:021D7C76 loc_21D7C76:                            @ CODE XREF: WeatherMod+6j
25. MEMORY:021D7C76 CMP     R1, #9
26. MEMORY:021D7C78 BNE     loc_21D7C80
27. MEMORY:021D7C7A MOVS    R0, 0x800
28. MEMORY:021D7C7E BX      LR
29. MEMORY:021D7C80 @ ---------------------------------------------------------------------------
30. MEMORY:021D7C80
31. MEMORY:021D7C80 loc_21D7C80:                            @ CODE XREF: WeatherMod+20j
32. MEMORY:021D7C80 CMP     R1, #0xA
33. MEMORY:021D7C82 BNE     loc_21D7C8A
34. MEMORY:021D7C84 MOVS    R0, 0x1800
35. MEMORY:021D7C88 BX      LR
36. MEMORY:021D7C8A @ ---------------------------------------------------------------------------
37. MEMORY:021D7C8A
38. MEMORY:021D7C8A loc_21D7C8A:                            @ CODE XREF: WeatherMod+8j
39. MEMORY:021D7C8A                                         @ WeatherMod+16j ...
40. MEMORY:021D7C8A MOVS    R0, 0x1000
41. MEMORY:021D7C8E BX      LR

Even though the weather modifier has its own set of triggers listed below, they never affect the actual value of the modifier: a water move used during rain or a fire move used during intense sunlight will use 0x1800 as modifier, while a fire move used during rain or a water move during intense sunlight will use 0x800.

Trigger address Trigger description
21d9850 Cancel weather if any Pokémon on field has Air Lock or Cloud Nine.
21d9084 Internal.

### Critical hits

Trigger address Trigger description
21d9be8 Super Luck: increase user's critical hit level by 1.
21d9bc4 Battle Armor / Shell Armor: if the target has either of these abilities, bypass critical hit checks.
21dae18 Internal.
21de5fc Stick: if user is Farfetch'd and holds Stick, increase critical hit level by 2.
21de5b8 Lucky Punch: if user is Chansey and holds Lucky Punch, increase critical hit level by 2.
21de584 Razor Claw: increase holder's critical hit level by 1.
21e53b4 Internal.
6899210 Lucky Chant: if the user's party is protected by Lucky Chant, bypass critical hit checks.

### The random factor

Provided the battle isn't rigged to always use minimum damage, the current damage value D is altered using a random number 0 ≤ R ≤ 15:

D' = (D * (100-R)) ÷ 100

### STAB

1. MEMORY:021C760C STAB:                                   @ CODE XREF: DamageCalc:Bank_STABp
2. MEMORY:021C760C PUSH    {R3-R7,LR}
3. MEMORY:021C760E MOVS    R7, R1
4. MEMORY:021C7610 MOVS    R5, R0
5. MEMORY:021C7612 MOVS    R0, R7
6. MEMORY:021C7614 MOVS    R1, R2
7. MEMORY:021C7616 BL      IsMoveOfUserType
8. MEMORY:021C761A MOVS    R6, R0
9. MEMORY:021C761C MOVS    R4, #1
10. MEMORY:021C761E LDR     R0, =0x3178
11. MEMORY:021C7620 LSLS    R4, R4, #0xC
12. MEMORY:021C7622 BL      AllocateVolatileVariables
13. MEMORY:021C7626 MOVS    R0, R7
14. MEMORY:021C7628 BL      Dereference25
15. MEMORY:021C762C MOVS    R1, R0
16. MEMORY:021C762E MOVS    R0, #2
17. MEMORY:021C7630 BL      StoreVolatileVariableFlag3e4
18. MEMORY:021C7634 MOVS    R0, #0x51 @ 'Q'
19. MEMORY:021C7636 MOVS    R1, R6
20. MEMORY:021C7638 BL      StoreVolatileVariableFlag3e1
21. MEMORY:021C763C MOVS    R0, R5
22. MEMORY:021C763E MOVS    R1, #0x40 @ '@'
23. MEMORY:021C7640 BL      ApplyTriggers
24. MEMORY:021C7644 MOVS    R0, #0x51 @ 'Q'
25. MEMORY:021C7646 BL      ReadVolatileVariable
26. MEMORY:021C764A MOVS    R1, R0
27. MEMORY:021C764C BEQ     loc_21C7652
28. MEMORY:021C764E MOVS    R4, 0x1800
29. MEMORY:021C7652
30. MEMORY:021C7652 loc_21C7652:                            @ CODE XREF: STAB+40j
31. MEMORY:021C7652 MOVS    R0, #0x44 @ 'D'
32. MEMORY:021C7654 BL      StoreVolatileVariableFlag3e4
33. MEMORY:021C7658 MOVS    R0, #0x35 @ '5'
34. MEMORY:021C765A MOVS    R1, R4
35. MEMORY:021C765C BL      InitVolatileVariable
36. MEMORY:021C7660 MOVS    R0, R5
37. MEMORY:021C7662 MOVS    R1, #0x41 @ 'A'
38. MEMORY:021C7664 BL      ApplyTriggers
39. MEMORY:021C7668 MOVS    R0, #0x35 @ '5'
40. MEMORY:021C766A BL      ReadVolatileVariable
41. MEMORY:021C766E MOVS    R4, R0
42. MEMORY:021C7670 LDR     R0, =0x3189
43. MEMORY:021C7672 BL      FreeVolatileVariable
44. MEMORY:021C7676 MOVS    R0, R4
45. MEMORY:021C7678 POP     {R3-R7,PC}
46. MEMORY:021C7678 @ End of function STAB

If the type of the move match one of its users', the STAB modifier is set to 0x1800. The only trigger for this modifier is listed below.

Trigger address Trigger description
21D8C2D Adaptability: if the user has this ability and move matches one of the user's types, the initial value for the final modifier is set to 0x2000.

### Type effectiveness

1. MEMORY:021D7A8C TypeEffectiveness:                      @ CODE XREF: DamageCalc+14Ap
2. MEMORY:021D7A8C CMP     R1, #5
3. MEMORY:021D7A8E BHI     locret_21D7ABA
4. MEMORY:021D7A90 ADDS    R1, R1, R1
5. MEMORY:021D7A92 ADD     R1, PC
6. MEMORY:021D7A94 LDRH    R1, [R1,#6]
7. MEMORY:021D7A96 LSLS    R1, R1, #0x10
8. MEMORY:021D7A98 ASRS    R1, R1, #0x10
9. MEMORY:021D7A9A ADD     PC, R1
10. MEMORY:021D7A9A @ ---------------------------------------------------------------------------
11. MEMORY:021D7A9C .byte  0xA
12. MEMORY:021D7A9D .byte    0
13. MEMORY:021D7A9E .byte  0xE
14. MEMORY:021D7A9F .byte    0
15. MEMORY:021D7AA0 .byte 0x12
16. MEMORY:021D7AA1 .byte    0
17. MEMORY:021D7AA2 .byte 0x14
18. MEMORY:021D7AA3 .byte    0
19. MEMORY:021D7AA4 .byte 0x16
20. MEMORY:021D7AA5 .byte    0
21. MEMORY:021D7AA6 .byte 0x1A
22. MEMORY:021D7AA7 .byte    0
23. MEMORY:021D7AA8 @ ---------------------------------------------------------------------------
24. MEMORY:021D7AA8 MOVS    R0, #0
25. MEMORY:021D7AAA BX      LR
26. MEMORY:021D7AAC @ ---------------------------------------------------------------------------
27. MEMORY:021D7AAC LSRS    R0, R0, #2
28. MEMORY:021D7AAE BX      LR
29. MEMORY:021D7AB0 @ ---------------------------------------------------------------------------
30. MEMORY:021D7AB0 LSRS    R0, R0, #1
31. MEMORY:021D7AB2 BX      LR
32. MEMORY:021D7AB4 @ ---------------------------------------------------------------------------
33. MEMORY:021D7AB4 LSLS    R0, R0, #1
34. MEMORY:021D7AB6 BX      LR
35. MEMORY:021D7AB8 @ ---------------------------------------------------------------------------
36. MEMORY:021D7AB8 LSLS    R0, R0, #2
37. MEMORY:021D7ABA
38. MEMORY:021D7ABA locret_21D7ABA:                         @ CODE XREF: TypeEffectiveness+2j
39. MEMORY:021D7ABA BX      LR

Type effectiveness doesn't use a modifier but a simple left (respectively right) shift of one for a simple and two for a double weakness (respectively resistance), in other words an unrounded division or multiplication by 2 or 4.

### Effect of a burn

The effect of a burn is directly taken into account in the damage formula. First, the game checks if the attack is physical, then if the user is burned, and finally if its ability is different than Guts. If all conditions are satisfied, the current damage is divided by 2 with no rounding.

### Final modifier

The final modifier is decided by calling the appropriate triggers, which are listed below. Be sure to chain the modifiers in the order they are listed in.
Trigger address Modifier Trigger description
6898E29 Variable If the target's side is affected by Reflect, the move used was physical, the user's ability isn't Infiltrator and the critical hit flag isn't set.
The value of the modificator is 0xA8F if there is more than one Pokémon per side of the field and 0x800 otherwise.
6898E45 Variable Same as above with Light Screen and special moves.
21DC125 0x800 If the target's ability is Multiscale and the target is at full health.
21D8B3D 0x2000 If the user's ability is Tinted Lens and the move wasn't very effective.
21DC15D 0xC00 If one of the target's allies' ability is Friend Guard.
21D8BA5 0x1800 If user has ability Sniper and move was a critical hit.
21D8B71 0xC00 If the target's ability is Solid Rock or Filter and the move was super effective.
21DBA95 Internal.
21DEC91 Variable If the user is holding the item Metronome. If n is the number of time the current move was used successfully and successively, the value of the modifier is 0x1000+n*0x333 if n≤4 and 0x2000 otherwise.
21DEBD5 0x1333 If the user is holding an expert belt and the move was super effective.
21DEC65 0x14CC If the user is holding a Life Orb.
21DDB85 0x800 If the target is holding a damage lowering berry of the attack's type. There is one trigger for each type of berry, the others are at:
21DDC05, 21DDAE5, 21DDB05, 21DDB25, 21DDB45, 21DDB65, 21DDBA5, 21DDBC5, 21DDBE5, 21DDC25, 21DDC45, 21DDC65, 21DDC85, 21DDCA5, 21DDCC5 and 21DDCE5.
21E3A25 0x2000 If move is Stomp and target has used Minimize.
21E316D 0x2000 If move is Earthquake and target is in the charging turn of Dig.
21E39E1 0x2000 If move is Surf and target is in the charging turn of Dive.
21E1455 0x2000 If move is Steamroller and target has used Minimize.

## The base power

There are two separate sets of triggers for the base power of moves. The first is mainly used for moves with a variable base power, while the second contains the various modifiers for base power.

### Triggers for variable base power

Trigger address Summary of BP formula Move and remarks.
21d88cc Internal.
21e2aec ((255 - Happiness) * 10) ÷ 25 Frustration: if result is 0 add 1.
21e2968 50, 100 Payback: BP is doubled to 100 if target has moved this turn, 50 otherwise.
21e2aa0 (Happiness * 10) ÷ 25 Return: if result is 0 add 1.
21e7184 150, 120, 80, 60, 40 Electro Ball: Let S = UserModSpeed ÷ TargetModSpeed. BP = {150: S ≥ 4, 120: 3 ≤ S < 4, 80: 2 ≤ S < 3, 60: 1 ≤ S < 2, 40: otherwise};
21e283c 60, 120 Avalanche: BP is doubled to 120 if the target has inflicted non-effect damage to the user this turn.
21e27d0 min(150, 25 * TargetSpd ÷ UserSpd) Gyro Ball.
21e29a8 (150 * CurrentHP) ÷ MaxHP Eruption, Water Spout: if result is 0 set BP to 1.
21e2de0 min(120, 60 + 20 * statup_total) Punishment: statup_total is the sum of the target's stat levels that are ≥ 0, including accuracy and evasion.
21e2e48 20 * 2^(use_counter) Fury Cutter: use_counter counts successive and successful previous uses up to a maximum of 3.
21e2ef4 20, 40, 60, 80, 100, 120 Low Kick, Grass Knot: let W be the final weight after modifiers. If W ≥ 200, BP is 120, else if W ≥ 100, BP is 100, else if W ≥ 50, BP is 80, else if W ≥ 25, BP is 60, else if W ≥ 10, BP is 40, else BP is 20.
21e7204 40, 80, 120, 160, 200 Echoed Voice: BP increases in the listed order every turn this move is used successively on the user's side of the field.
21e702c 50, 100 Hex: BP is doubled to 100 if target has a status problem.
21e2a08 round(120 * TargetHP%) ÷ 100 Wring Out, Crush Grip: TargetHP% is computed by a fixed point division using 0x1000 as the scaling factor.
21e2eb0 50, 100 Assurance: BP is doubled to 100 if target has already been inflicted non-effect damage this turn.
21e7104 120, 100, 80, 60, 40 Heavy Slam, Heat Crash: let W = UserModWeight ÷ TargetModWeight. BP = {120: W ≥ 5, 100: 4 ≤ W < 5, 80: 3 ≤ W < 4, 60: 2 ≤ W < 3, 40: W < 2}.
21e70a0 20 + 20 * statups Stored Power: statups is the sum of all positive stat increases, including accuracy and evasion.
21e706c 55, 110 Acrobatics: BP is doubled to 110 if user has no held item.
21e28b8 P = (48 * CurrentHP) ÷ MaxHP Flail, Reversal: 200 if P ≤ 1, 150 if 2 ≤ P ≤ 4, 100 if 5 ≤ P ≤ 9, 80 if 10 ≤ P ≤ 16, 40 if 17 ≤ P ≤ 32, 20 otherwise.
21e2d7c 40, 50, 60, 80, 200 Trump Card: listed BP correspond to decreasing PP (if PP is ≥ 5 or this move was called by another move BP is 40).
21e7dd0 60, 120 Round: BP is doubled to 120 if used in direct succession of an ally.
21e2788 10, 20, 30 Triple Kick: BP is listed for the successive hits.
21e2b38 60, 120 Wake-Up Slap: BP is doubled to 120 if target is asleep.
21e2bd4 60, 120 SmellingSalt: BP is doubled to 120 is target is paralyzed.
21e2fd0 50, 100 Weather Ball: BP is doubled to 100 in any non-default weather.
21e302c 40, 80 Gust, Twister: BP is doubled to 80 is target is in the charging turn of Bounce, Fly or Sky Drop.
21e6074 CurrentPartyMemberAttack ÷ 10 + 5 Beat Up: this move attacks once for every non fainted member in the user's party, including the user.
21e3318 30 + (40 * sum(((IV[i]>>1)&1)<<i)) ÷ 63 Hidden Power: IV are indexed from 0 and listed as HP, At, Df, Sp, SA, SD.
21e17d0 100 * stockpile Spit Up: stockpile is the stockpile counter ranging from 0 to 3.
21e1dbc 40, 80 Pursuit: BP is doubled to 80 if target is switching out.
21e2d40 40, 80 or 120 Present: let 0 ≤ r < 80 be a random number. If r < 40, BP is 40, else if r < 70, BP is 80, otherwise BP is 120.
21e33dc Variable Natural Gift: base power and type depend on held berry. See 2021030 and 20210E4 for corresponding tables.
21e398c 10 + 20 * factor Magnitude: let R = rand(100), factor = {0: R < 5, 1: 5 ≤ R < 15, 2: 15 ≤ R < 35, 3: 35 ≤ R < 65, 4: 65 ≤ R < 85, 5: 85 ≤ R < 95, 7: R ≥ 95}.
21e2720 30 * 2 ^ (use_counter + defense_curl) Rollout: use_counter counts successive and successful previous uses up to a maximum of 5, defense_curl is 1 if user used Defense Curl previously on field, 0 otherwise.
21e5d44 Variable Fling: base power depends on the held item. See 21D807C for table of items.
21e84b8 150 Grass/Fire/Water Pledge: if a slower ally used a different Pledge move this turn, it will skip its turn and this move's base power will be set to 150.

### Modifiers for the base power

Trigger address Modifier Trigger description
21d9108 0x1800 If user has ability Technician and move's base power is ≤60.
21dc27c 0x1800 If user has ability Flare Boost, is burned and uses a special move.
21dc6c0 0x14CD If user has ability Analytic, move isn't Future Sight or Doom Desire and target has already moved this turn.
21d9174 0x1333 If user has ability Reckless and move has recoil or is either Jump Kick or Hi Jump Kick.
21d9138 0x1333 If the user has ability Iron Fist and move has the "Punching move" (0x7) flag set.
21dc238 0x1800 If user has ability Toxic Boost, is poisoned and move is physical.
21d9090 Variable If user has ability Rivalry. The value of the modifier is 0x1000 if either the user or target is genderless, 0x1400 if the user and target are of the same gender and 0xC00 otherwise.
21dc718 0x14CD If user has ability Sand Force and move is Rock, Ground or Steel type.
21da864 0x800 If target has ability Heatproof and move is Fire type.
21daa90 0x1400 If target has ability Dry Skin and move is Fire type.
21dbf48 0x14CD If the user has ability Sheer Force and move has a flag (0xA) set.
21d9dc4 Internal.
Multiple 0x1333 Type boosting items, plates, incenses. All are wrappers for the 21DF95C trigger. List of locations:
21df7a8, 21df878, 21df760, 21df748, 21df778, 21df7c0, 21df860, 21df890, 21df730, 21df908, 21df950, 21df790, 21df7d8, 21df7f0, 21df808, 21df718, 21df8c0, 21df938, 21df920, 21df8d8, 21df8a8.
21de6ec 0x1199 If user holds a Muscle Band and move is physical.
21df994 0x1333 If user is Palkia, holds the Lustrous Orb and move is Water or Dragon type.
21de72c 0x1199 If user holds Wise Glasses and move is special.
21df458 0x1333 If user is Giratina, holds the Griseous Orb and move is Dragon or Ghost type.
21df8f0 0x1333 If user holds Odd Incense and move is Psychic type.
21df9e8 0x1333 If user is Dialga, holds the Adamant Orb and move is Steel or Dragon type.
21e01e4 0x1800 If user holds a Normal Gem and move is normal type. Similar triggers for the other types are at:
21DFF14, 21DFF40, 21DFF6C, 21DFF98, 21DFFC4, 21DFFF0, 21E001C, 21E0048, 21E0074, 21E00A0, 21E00CC, 21E00F8, 21E0124, 21E0150, 21E017C, 21E01A8
21e2928 0x2000 If move is Facade and user is either paralyzed, poisoned or burned.
21e2a58 0x2000 If move is Brine and target's HP is ≤ 50%.
21e6fe8 0x2000 If move is Venoshock and target is poisoned.
21e729c 0x2000 If move is Retaliate and a Pokémon from the target's party fainted on the previous turn.
21e8330 0x2000 If move is either Fusion Bolt or Fusion Flare and the previously used move was respectively Fusion Flare or Fusion Bolt.
21e6f34 0x1800 If move was called using Me First.
21e64a0 0x800 If move is SolarBeam in non-sunny, non-default weather.
21e1f38 0x2000 If user used Charge the previous turn and move is Electric type.
21e5ff0 0x1800 If user has been the target of Helping Hand this turn.
6898158 0x548 If Water Sport was used by any Pokémon still on the field and move is Fire type.
6898110 0x548 If Mud Sport was used by any Pokémon still on the field and move is Electric type.

## User attack stat

1. MEMORY:021C7394 BaseAttackMods:                         @ CODE XREF: DamageCalc+9Ep
2. MEMORY:021C7394 PUSH    {R3-R7,LR}
3. MEMORY:021C7396 MOVS    R5, R3
4. MEMORY:021C7398 MOVS    R7, R0
5. MEMORY:021C739A LDRH    R0, [R5]
6. MEMORY:021C739C MOVS    R6, R1
7. MEMORY:021C739E STR     R2, [SP]
8. MEMORY:021C73A0 BL      GetMoveCategory
9. MEMORY:021C73A4 MOVS    R4, #0xA
10. MEMORY:021C73A6 CMP     R0, #2
11. MEMORY:021C73A8 BEQ     loc_21C73AC
12. MEMORY:021C73AA MOVS    R4, #8
13. MEMORY:021C73AC
14. MEMORY:021C73AC loc_21C73AC:                            @ CODE XREF: BaseAttackMods+14j
15. MEMORY:021C73AC LDR     R0, =0x30FE
16. MEMORY:021C73AE BL      AllocateVolatileVariables
17. MEMORY:021C73B2 MOVS    R0, R6
18. MEMORY:021C73B4 BL      GetPkmId
19. MEMORY:021C73B8 MOVS    R1, R0
20. MEMORY:021C73BA MOVS    R0, #3
21. MEMORY:021C73BC BL      StoreVolatileVariableFlag3e4
22. MEMORY:021C73C0 LDR     R0, [SP]
23. MEMORY:021C73C2 BL      GetPkmId
24. MEMORY:021C73C6 MOVS    R1, R0
25. MEMORY:021C73C8 MOVS    R0, #4
26. MEMORY:021C73CA BL      StoreVolatileVariableFlag3e4
27. MEMORY:021C73CE MOVS    R0, #0x3B @ ';'
28. MEMORY:021C73D0 MOVS    R1, #0x1F
29. MEMORY:021C73D2 BL      InitVolatileVariable
30. MEMORY:021C73D6 MOVS    R0, #0x51 @ 'Q'
31. MEMORY:021C73D8 MOVS    R1, #0
32. MEMORY:021C73DA BL      InitVolatileVariable
33. MEMORY:021C73DE MOVS    R0, R7
34. MEMORY:021C73E0 MOVS    R1, #0x39 @ '9'
35. MEMORY:021C73E2 BL      ApplyTriggers
36. MEMORY:021C73E6 MOVS    R0, #0x3B @ ';'
37. MEMORY:021C73E8 BL      ReadVolatileVariable
38. MEMORY:021C73EC LSLS    R0, R0, #0x18
39. MEMORY:021C73EE LSRS    R1, R0, #0x18
40. MEMORY:021C73F0 CMP     R1, #0x1F
41. MEMORY:021C73F2 BEQ     loc_21C73FC
42. MEMORY:021C73F4 LDR     R0, [R7,#8]
43. MEMORY:021C73F6 BL      GetPartyPkm
44. MEMORY:021C73FA ADDS    R6, R0, #0
45. MEMORY:021C73FC
46. MEMORY:021C73FC loc_21C73FC:                            @ CODE XREF: BaseAttackMods+5Ej
47. MEMORY:021C73FC MOVS    R0, #0x51 @ 'Q'
48. MEMORY:021C73FE BL      ReadVolatileVariable
49. MEMORY:021C7402 CMP     R0, #0
50. MEMORY:021C7404 BEQ     loc_21C7410
51. MEMORY:021C7406 MOVS    R0, R6
52. MEMORY:021C7408 MOVS    R1, R4
53. MEMORY:021C740A BL      RawBpkmStat
54. MEMORY:021C740E B       loc_21C7428
55. MEMORY:021C7410 @ ---------------------------------------------------------------------------
56. MEMORY:021C7410
57. MEMORY:021C7410 loc_21C7410:                            @ CODE XREF: BaseAttackMods+70j
58. MEMORY:021C7410 LDR     R0, [SP,#0x18]
59. MEMORY:021C7412 CMP     R0, #0
60. MEMORY:021C7414 BEQ     loc_21C7420
61. MEMORY:021C7416 MOVS    R0, R6
62. MEMORY:021C7418 MOVS    R1, R4
63. MEMORY:021C741A BL      CritAtkDefLevel
64. MEMORY:021C741E B       loc_21C7428
65. MEMORY:021C7420 @ ---------------------------------------------------------------------------
66. MEMORY:021C7420
67. MEMORY:021C7420 loc_21C7420:                            @ CODE XREF: BaseAttackMods+80j
68. MEMORY:021C7420 MOVS    R0, R6
69. MEMORY:021C7422 MOVS    R1, R4
70. MEMORY:021C7424 BL      GetBpkmStat
71. MEMORY:021C7428
72. MEMORY:021C7428 loc_21C7428:                            @ CODE XREF: BaseAttackMods+7Aj
73. MEMORY:021C7428                                         @ BaseAttackMods+8Aj
74. MEMORY:021C7428 LSLS    R0, R0, #0x10
75. MEMORY:021C742A LSRS    R4, R0, #0x10
76. MEMORY:021C742C LDRH    R1, [R5]
77. MEMORY:021C742E MOVS    R0, #0x12
78. MEMORY:021C7430 BL      StoreVolatileVariableFlag3e4
79. MEMORY:021C7434 LDRB    R1, [R5,#6]
80. MEMORY:021C7436 MOVS    R0, #0x16
81. MEMORY:021C7438 BL      StoreVolatileVariableFlag3e4
82. MEMORY:021C743C LDR     R1, [R5,#8]
83. MEMORY:021C743E MOVS    R0, #0x1A
84. MEMORY:021C7440 BL      StoreVolatileVariableFlag3e4
85. MEMORY:021C7444 MOVS    R0, #0x33 @ '3'
86. MEMORY:021C7446 MOVS    R1, R4
87. MEMORY:021C7448 BL      InitVolatileVariable
88. MEMORY:021C744C MOVS    R1, 0x1000
89. MEMORY:021C7450 LDR     R2, =0x19A
90. MEMORY:021C7452 MOVS    R0, #0x35 @ '5'
91. MEMORY:021C7454 LSLS    R3, R1, #5
92. MEMORY:021C7456 BL      StoreVolatileVariableFlag3e3
93. MEMORY:021C745A MOVS    R0, R7
94. MEMORY:021C745C MOVS    R1, #0x3B @ ';'
95. MEMORY:021C745E BL      ApplyTriggers
96. MEMORY:021C7462 MOVS    R0, #0x33 @ '3'
97. MEMORY:021C7464 BL      ReadVolatileVariable
98. MEMORY:021C7468 LSLS    R0, R0, #0x10
99. MEMORY:021C746A LSRS    R4, R0, #0x10
100. MEMORY:021C746C MOVS    R0, #0x35 @ '5'
101. MEMORY:021C746E BL      ReadVolatileVariable
102. MEMORY:021C7472 MOVS    R1, R0
103. MEMORY:021C7474 MOVS    R0, R4
104. MEMORY:021C7476 BL      ApplyMod
105. MEMORY:021C747A LSLS    R0, R0, #0x10
106. MEMORY:021C747C LSRS    R4, R0, #0x10
107. MEMORY:021C747E LDR     R0, =0x3123
108. MEMORY:021C7480 BL      FreeVolatileVariable
109. MEMORY:021C7484 MOVS    R0, R4
110. MEMORY:021C7486 POP     {R3-R7,PC}
111. MEMORY:021C7486 @ End of function BaseAttackMods

### Base value

The first step of computing the attack stat is to decide whether the attack or special attack stat should be used, and on which Pokémon. By default, the user's attack is used if the move is physical and the special attack otherwise but this behavior can be altered by the following triggers:

Trigger address Trigger description
21da828 Unaware: if target has ability Unaware do not apply any attack level boosts.
21d8db0 Internal.
21e7320 Foul Play: use the target's base attack stat instead of the user's.
21e39b0 Internal.

### Boost level

Once the base stat is decided, the stat boost level is applied:
1. If a trigger decided to skip stat boosts, use the base stat.
2. If the hit was critical and the boost level is negative, use the base stat.
3. Otherwise, apply the factor corresponding to the boost level according to the table below (multiply stat by the dividend first then use unrounded division on divisor).
Stat boost level Multiplier Decimal Approximate
-62/80.25
-52/70.2857
-42/60.3333
-32/50.4
-22/40.5
-12/30.6667
02/21
+13/21.5
+24/22
+35/22.5
+46/23
+57/23.5
+68/24

### Attack modifiers

The final attack stat is altered using the following modifiers:
Trigger address Modifier Trigger description
21d871c 0x800 If target has ability Thick Fat and move is Ice or Fire type.
21d8c78 0x1800 If user has ability Torrent, has MaxHP ÷ 3 or less HP and move is water type.
21d8d14 0x1800 If user has ability Guts, has a status problem and move is physical.
21d8cb0 0x1800 If user has ability Swarm, has MaxHP ÷ 3 or less HP and move is bug type.
21d8c94 0x1800 If user has ability Overgrow, has MaxHP ÷ 3 or less HP and move is grass type.
21d8d60 0x1800 If user has ability Plus or Minus and an ally has ability Plus or Minus and move is special.
21d8c5c 0x1800 If user has ability Blaze, has MaxHP ÷ 3 or less HP and move is fire type.
21dc0dc 0x800 If user has ability Defeatist and CurrentHP ≤ MaxHP ÷ 2.
21d8754 0x2000 If user has ability Pure Power or Huge Power and move is physical.
21d9954 0x1800 If user has ability Solar Power and weather is intense sunlight and move is special.
21d8894 0x1800 If user has ability Hustle and move is physical. This is a special trigger in the sense that instead of chaining it will directly apply the 0x1800 on the current attack stat instead of being chained with others.
21daf04 0x1800 If user has ability Flash Fire activated and move is Fire type.
21d892c 0x800 If user has ability Slow Start, has been on field for less than 5 turns and move is physical.
21d8fec 0x1800 If ally is Cherrim and has ability Flower Gift, weather is intense sunlight and move is physical.
21db424 Internal.
21de91c 0x2000 If user is Cubone or Marowak, holds a Thick Club and move is physical.
21de76c 0x2000 If user is Clamperl, holds a DeepSeaTooth and move is special.
21df53c 0x2000 If user is Pikachu and holds a Light Ball.
21de898 0x1800 If user is Latios or Latias, holds a Soul Dew and move is special.
21de968 0x1800 If user is holding Choice Band and move is physical.
21de9a0 0x1800 If user is holding Choice Specs and move is special.
21e310c Internal.

## Target defense stat

1. MEMORY:021C7494 BaseDefenseMods:                        @ CODE XREF: DamageCalc+AEp
2. MEMORY:021C7494 PUSH    {R4-R7,LR}
3. MEMORY:021C7496 SUB     SP, SP, #0xC
4. MEMORY:021C7498 MOVS    R6, R3
5. MEMORY:021C749A STR     R0, [SP]
6. MEMORY:021C749C LDRH    R0, [R6]
7. MEMORY:021C749E STR     R1, [SP,#4]
8. MEMORY:021C74A0 MOVS    R5, R2
9. MEMORY:021C74A2 BL      GetMoveCategory
10. MEMORY:021C74A6 MOVS    R4, #0xB
11. MEMORY:021C74A8 CMP     R0, #2
12. MEMORY:021C74AA BEQ     loc_21C74AE
13. MEMORY:021C74AC MOVS    R4, #9
14. MEMORY:021C74AE
15. MEMORY:021C74AE loc_21C74AE:                            @ CODE XREF: BaseDefenseMods+16j
16. MEMORY:021C74AE LDR     R0, [R6,#8]
17. MEMORY:021C74B0 STR     R0, [SP,#8]
18. MEMORY:021C74B2 LDR     R0, =0x3133
19. MEMORY:021C74B4 BL      AllocateVolatileVariables
20. MEMORY:021C74B8 LDR     R0, [SP,#4]
21. MEMORY:021C74BA BL      GetPkmId
22. MEMORY:021C74BE MOVS    R1, R0
23. MEMORY:021C74C0 MOVS    R0, #3
24. MEMORY:021C74C2 BL      StoreVolatileVariableFlag3e4
25. MEMORY:021C74C6 MOVS    R0, R5
26. MEMORY:021C74C8 BL      GetPkmId
27. MEMORY:021C74CC MOVS    R1, R0
28. MEMORY:021C74CE MOVS    R0, #4
29. MEMORY:021C74D0 BL      StoreVolatileVariableFlag3e4
30. MEMORY:021C74D4 MOVS    R0, #0x3C @ '<'
31. MEMORY:021C74D6 MOVS    R1, R4
32. MEMORY:021C74D8 BL      StoreVolatileVariableFlag3e4
33. MEMORY:021C74DC MOVS    R0, #0x3D @ '='
34. MEMORY:021C74DE MOVS    R1, #0
35. MEMORY:021C74E0 BL      InitVolatileVariable
36. MEMORY:021C74E4 MOVS    R0, #0x51 @ 'Q'
37. MEMORY:021C74E6 MOVS    R1, #0
38. MEMORY:021C74E8 BL      StoreVolatileVariableFlag3e1
39. MEMORY:021C74EC LDR     R0, [SP]
40. MEMORY:021C74EE MOVS    R1, #0x3A @ ':'
41. MEMORY:021C74F0 BL      ApplyTriggers
42. MEMORY:021C74F4 MOVS    R0, #0x3D @ '='
43. MEMORY:021C74F6 BL      ReadVolatileVariable
44. MEMORY:021C74FA MOVS    R1, #1
45. MEMORY:021C74FC TST     R0, R1
46. MEMORY:021C74FE BEQ     loc_21C7516
47. MEMORY:021C7500 CMP     R4, #9
48. MEMORY:021C7502 BNE     loc_21C7508
49. MEMORY:021C7504 MOVS    R4, #0xB
50. MEMORY:021C7506 B       loc_21C750A
51. MEMORY:021C7508 @ ---------------------------------------------------------------------------
52. MEMORY:021C7508
53. MEMORY:021C7508 loc_21C7508:                            @ CODE XREF: BaseDefenseMods+6Ej
54. MEMORY:021C7508 MOVS    R4, #9
55. MEMORY:021C750A
56. MEMORY:021C750A loc_21C750A:                            @ CODE XREF: BaseDefenseMods+72j
57. MEMORY:021C750A CMP     R4, #9
58. MEMORY:021C750C BNE     loc_21C7512
59. MEMORY:021C750E MOVS    R0, #1
60. MEMORY:021C7510 B       loc_21C7514
61. MEMORY:021C7512 @ ---------------------------------------------------------------------------
62. MEMORY:021C7512
63. MEMORY:021C7512 loc_21C7512:                            @ CODE XREF: BaseDefenseMods+78j
64. MEMORY:021C7512 MOVS    R0, #2
65. MEMORY:021C7514
66. MEMORY:021C7514 loc_21C7514:                            @ CODE XREF: BaseDefenseMods+7Cj
67. MEMORY:021C7514 STR     R0, [SP,#8]
68. MEMORY:021C7516
69. MEMORY:021C7516 loc_21C7516:                            @ CODE XREF: BaseDefenseMods+6Aj
70. MEMORY:021C7516 MOVS    R0, #0x51 @ 'Q'
71. MEMORY:021C7518 BL      ReadVolatileVariable
72. MEMORY:021C751C LSLS    R0, R0, #0x18
73. MEMORY:021C751E LSRS    R7, R0, #0x18
74. MEMORY:021C7520 LDR     R0, =0x3142
75. MEMORY:021C7522 BL      FreeVolatileVariable
76. MEMORY:021C7526 CMP     R7, #0
77. MEMORY:021C7528 BEQ     loc_21C7534
78. MEMORY:021C752A MOVS    R0, R5
79. MEMORY:021C752C MOVS    R1, R4
80. MEMORY:021C752E BL      RawBpkmStat
81. MEMORY:021C7532 B       loc_21C754C
82. MEMORY:021C7534 @ ---------------------------------------------------------------------------
83. MEMORY:021C7534
84. MEMORY:021C7534 loc_21C7534:                            @ CODE XREF: BaseDefenseMods+94j
85. MEMORY:021C7534 LDR     R0, [SP,#0x20]
86. MEMORY:021C7536 CMP     R0, #0
87. MEMORY:021C7538 BEQ     loc_21C7544
88. MEMORY:021C753A MOVS    R0, R5
89. MEMORY:021C753C MOVS    R1, R4
90. MEMORY:021C753E BL      CritAtkDefLevel
91. MEMORY:021C7542 B       loc_21C754C
92. MEMORY:021C7544 @ ---------------------------------------------------------------------------
93. MEMORY:021C7544
94. MEMORY:021C7544 loc_21C7544:                            @ CODE XREF: BaseDefenseMods+A4j
95. MEMORY:021C7544 MOVS    R0, R5
96. MEMORY:021C7546 MOVS    R1, R4
97. MEMORY:021C7548 BL      GetBpkmStat
98. MEMORY:021C754C
99. MEMORY:021C754C loc_21C754C:                            @ CODE XREF: BaseDefenseMods+9Ej
100. MEMORY:021C754C                                         @ BaseDefenseMods+AEj
101. MEMORY:021C754C LSLS    R0, R0, #0x10
102. MEMORY:021C754E LSRS    R7, R0, #0x10
103. MEMORY:021C7550 LDR     R0, [SP]
104. MEMORY:021C7552 BL      GetActiveWeather
105. MEMORY:021C7556 CMP     R0, #4
106. MEMORY:021C7558 BNE     loc_21C7578
107. MEMORY:021C755A MOVS    R0, R5
108. MEMORY:021C755C MOVS    R1, #5
109. MEMORY:021C755E BL      IsMoveOfUserType
110. MEMORY:021C7562 CMP     R0, #0
111. MEMORY:021C7564 BEQ     loc_21C7578
112. MEMORY:021C7566 CMP     R4, #0xB
113. MEMORY:021C7568 BNE     loc_21C7578
114. MEMORY:021C756A MOVS    R1, #6
115. MEMORY:021C756C MOVS    R0, R7
116. MEMORY:021C756E LSLS    R1, R1, #0xA
117. MEMORY:021C7570 BL      ApplyMod
118. MEMORY:021C7574 LSLS    R0, R0, #0x10
119. MEMORY:021C7576 LSRS    R7, R0, #0x10
120. MEMORY:021C7578
121. MEMORY:021C7578 loc_21C7578:                            @ CODE XREF: BaseDefenseMods+C4j
122. MEMORY:021C7578                                         @ BaseDefenseMods+D0j ...
123. MEMORY:021C7578 LDR     R4, =0x3157
124. MEMORY:021C757A MOVS    R0, R4
125. MEMORY:021C757C BL      AllocateVolatileVariables
126. MEMORY:021C7580 LDR     R0, [SP,#4]
127. MEMORY:021C7582 BL      GetPkmId
128. MEMORY:021C7586 MOVS    R1, R0
129. MEMORY:021C7588 MOVS    R0, #3
130. MEMORY:021C758A BL      StoreVolatileVariableFlag3e4
131. MEMORY:021C758E MOVS    R0, R5
132. MEMORY:021C7590 BL      GetPkmId
133. MEMORY:021C7594 MOVS    R1, R0
134. MEMORY:021C7596 MOVS    R0, #4
135. MEMORY:021C7598 MOVS    R5, #4
136. MEMORY:021C759A BL      StoreVolatileVariableFlag3e4
137. MEMORY:021C759E LDRH    R1, [R6]
138. MEMORY:021C75A0 MOVS    R0, #0x12
139. MEMORY:021C75A2 BL      StoreVolatileVariableFlag3e4
140. MEMORY:021C75A6 LDRB    R1, [R6,#6]
141. MEMORY:021C75A8 MOVS    R0, #0x16
142. MEMORY:021C75AA BL      StoreVolatileVariableFlag3e4
143. MEMORY:021C75AE LDR     R1, [SP,#8]
144. MEMORY:021C75B0 MOVS    R0, #0x1A
145. MEMORY:021C75B2 BL      StoreVolatileVariableFlag3e4
146. MEMORY:021C75B6 MOVS    R0, #0x34 @ '4'
147. MEMORY:021C75B8 MOVS    R1, R7
148. MEMORY:021C75BA BL      InitVolatileVariable
149. MEMORY:021C75BE LDR     R2, =0x19A
150. MEMORY:021C75C0 MOVS    R0, #0x35 @ '5'
151. MEMORY:021C75C2 LSLS    R1, R5, #0xA
152. MEMORY:021C75C4 LSLS    R3, R5, #0xF
153. MEMORY:021C75C6 BL      StoreVolatileVariableFlag3e3
154. MEMORY:021C75CA LDR     R0, [SP]
155. MEMORY:021C75CC MOVS    R1, #0x3C @ '<'
156. MEMORY:021C75CE BL      ApplyTriggers
157. MEMORY:021C75D2 MOVS    R0, #0x34 @ '4'
158. MEMORY:021C75D4 BL      ReadVolatileVariable
159. MEMORY:021C75D8 LSLS    R0, R0, #0x10
160. MEMORY:021C75DA LSRS    R5, R0, #0x10
161. MEMORY:021C75DC MOVS    R0, #0x35 @ '5'
162. MEMORY:021C75DE BL      ReadVolatileVariable
163. MEMORY:021C75E2 ADDS    R4, #0xB
164. MEMORY:021C75E4 MOVS    R6, R0
165. MEMORY:021C75E6 MOVS    R0, R4
166. MEMORY:021C75E8 BL      FreeVolatileVariable
167. MEMORY:021C75EC MOVS    R0, R5
168. MEMORY:021C75EE MOVS    R1, R6
169. MEMORY:021C75F0 BL      ApplyMod
170. MEMORY:021C75F4 LSLS    R0, R0, #0x10
171. MEMORY:021C75F6 LSRS    R0, R0, #0x10
172. MEMORY:021C75F8 ADD     SP, SP, #0xC
173. MEMORY:021C75FA POP     {R4-R7,PC}
174. MEMORY:021C75FA @ End of function BaseDefenseMods

### Base value

Just like for the attack stat, the first step is to decide which defense stat to use and whether to apply the active boost level. This is done by the following triggers:

Trigger address Trigger description
21da840 Unaware: if foe has ability Unaware do not apply any Defense level boosts.
21d8db0 Internal.
21e7944 This triggers is used for special moves that deal physical damage. It replaces the identifier of the base special defense stat with the one for defense.
21e797c Chip Away: ignore defense level boosts if foe has it.
68981a0 Wonder Room: has the same effect as 21e7944 but for all Pokémon on field. Will also cancel the effect of 21e7944.

### Boost level

This works like attack boosts except the base defense stat is used on critical hits if the boost level is positive.

### Sandstorm modifier

At this point, if the current weather (after triggers) is Sandstorm, the user is Rock type and the base stat was special attack, apply a 0x1800 modifier to the current defense stat. This is done regardless of critical hits and before any other modifier.

### Defense modifiers

The final defense stat is altered using the following modifiers:
Trigger address Modifier Trigger description
21d91bc 0x1800 If target has ability Marvel Scale, has a status problem and move is physical.
21d903c 0x1800 If ally is Cherrim and has ability Flower Gift, weather is intense sunlight and move is special.
21db8f0 Internal.
21de7bc 0x1800 Is target is Clamperl, holds a DeepSeaScale and move is special.
21de804 0x2000 Is target is (untransformed) Ditto, holds Metal Powder and move is physical.
21dfaa8 0x1800 If target is holding Eviolite and is not fully evolved.
21de8d4 0x1800 If target is Latios or Latias holding a Soul Dew and move is special.

## Special cases

The following moves do not depend on the user's attack or the target's defense and are handled by specific triggers:
Trigger address Trigger description
21e1608 Psywave: damage is always max(1, ((rand(101) + 50) * UserLevel) ÷ 100)
21e15d0 Night Shade: damage is always UserLevel.
21e1504 SonicBoom: damage is always 20.
21e1498 Super Fang: damage is always max(1, TargetHP ÷ 2).
21e14e0 Dragon Rage: damage is always 40.
21e1578 Endeavor: damage is always max(0, TargetHP-UserHP).
21e7c98 Final Gambit: damage is always UserHP.
21e0838 Brick Break: cancels the effect of Reflect / Light Screen.
21e1978 Counter: if last Pokémon to hit the user was a foe using a physical move, use double the set damage.
21e19bc Mirror Coat: same as Counter for special moves.
21e1a00 Metal Burst: if the user was hit by an attack earlier this turn, use 1.5 times the set damage.
21e3e50 Bide: store energy for 2 turns, then set damage to twice the total damage dealt to user during the charging turns.