Difference between revisions of "FF7/DamageFormula"
my_wiki>NFITC1 m (→Damage Calculations: Woah! Missed that. Makes a big difference.) |
my_wiki>NFITC1 (Did I really type that?!!?! Also a little reformatting) |
||
Line 146: | Line 146: | ||
=Damage Calculations= | =Damage Calculations= | ||
− | + | These are the damage functions according to an unmodded FF7-ENG 1.02 (1998) | |
+ | ==Standard Formulae== | ||
+ | ===X0:=== | ||
+ | <pre>Sets Target's 02h flag to 1. (Unknown effect)</pre> | ||
− | + | ===X1:=== | |
− | |||
− | |||
− | X1: | ||
<pre>If Attack Property "Always Critical" is Set | <pre>If Attack Property "Always Critical" is Set | ||
Set Critical Damage Flag | Set Critical Damage Flag | ||
Line 207: | Line 207: | ||
End If | End If | ||
Damage = Variance( Damage )</pre> | Damage = Variance( Damage )</pre> | ||
− | + | ||
− | X2: | + | ===X2:=== |
<pre> | <pre> | ||
multiNoSplit = ( ( ( Attack's Target Flags AND Ch ) - 4 ) == 0 ? 1 : 0 ) | multiNoSplit = ( ( ( Attack's Target Flags AND Ch ) - 4 ) == 0 ? 1 : 0 ) | ||
Line 218: | Line 218: | ||
Damage = Variance( Damage ) | Damage = Variance( Damage ) | ||
</pre> | </pre> | ||
− | + | ||
− | X3: | + | ===X3:=== |
<pre> | <pre> | ||
If Attack Properties Damage MP is clear | If Attack Properties Damage MP is clear | ||
Line 232: | Line 232: | ||
Damage = Damage / 2 | Damage = Damage / 2 | ||
End If</pre> | End If</pre> | ||
− | + | ||
− | X4: | + | ===X4:=== |
<pre>If Attack Properties Damage MP is clear | <pre>If Attack Properties Damage MP is clear | ||
Damage = Target's MHP | Damage = Target's MHP | ||
Line 246: | Line 246: | ||
End If | End If | ||
</pre> | </pre> | ||
− | + | ||
− | X5: | + | ===X5:=== |
<pre> | <pre> | ||
Damage = (Actor's (M)Attack + Actor's Level) * 6 + (Attack's Power * 22) | Damage = (Actor's (M)Attack + Actor's Level) * 6 + (Attack's Power * 22) | ||
Line 253: | Line 253: | ||
Damage = Barrier( Damage ) | Damage = Barrier( Damage ) | ||
Damage = Variance( Damage )</pre> | Damage = Variance( Damage )</pre> | ||
− | + | ||
− | X6: | + | ===X6:=== |
<pre>Damage = Attack's Power * 20</pre> | <pre>Damage = Attack's Power * 20</pre> | ||
− | + | ||
− | X7: | + | ===X7:=== |
<pre> | <pre> | ||
Damage = ( ( 512 - Target's Def ) * Attack's Power / 32 ) | Damage = ( ( 512 - Target's Def ) * Attack's Power / 32 ) | ||
Damage = Variance( Damage ) | Damage = Variance( Damage ) | ||
</pre> | </pre> | ||
− | + | ||
− | X8: | + | ===X8:=== |
<pre> | <pre> | ||
If ActionData[0x230] AND 40h | If ActionData[0x230] AND 40h | ||
Line 271: | Line 271: | ||
End If | End If | ||
//presumably this checks if the target heals from restore element and will either recover or kill based on the result</pre> | //presumably this checks if the target heals from restore element and will either recover or kill based on the result</pre> | ||
− | + | ||
− | X9: | + | ===X9:=== |
<pre> | <pre> | ||
Actor's Attack = Actor's Strength * 2 | Actor's Attack = Actor's Strength * 2 | ||
Use Damage X1 with adjusted stat | Use Damage X1 with adjusted stat | ||
</pre> | </pre> | ||
− | + | ||
− | XA: | + | ===XA:=== |
<pre>Damage = ( Attack's Power + Number of Targets - 1 ) / Number of Targets</pre> | <pre>Damage = ( Attack's Power + Number of Targets - 1 ) / Number of Targets</pre> | ||
==Additional Checks== | ==Additional Checks== | ||
− | Sadness( Damage ) | + | ===Sadness( Damage )=== |
<pre> | <pre> | ||
If Target's Status includes Sadness | If Target's Status includes Sadness | ||
Line 288: | Line 288: | ||
End If | End If | ||
Return Damage</pre> | Return Damage</pre> | ||
− | + | ||
− | SplitDamage( Damage, multiNoSplit ) | + | ===SplitDamage( Damage, multiNoSplit )=== |
<pre> | <pre> | ||
If multiNoSplit == 0 | If multiNoSplit == 0 | ||
Line 308: | Line 308: | ||
Return Damage | Return Damage | ||
</pre> | </pre> | ||
− | + | ||
− | Barrier( Damage ) | + | ===Barrier( Damage )=== |
<pre> | <pre> | ||
If Attack Property "Physical" is 0 | If Attack Property "Physical" is 0 | ||
Line 330: | Line 330: | ||
Return Damage | Return Damage | ||
</pre> | </pre> | ||
− | + | ||
Variance( Damage ): | Variance( Damage ): | ||
<pre> | <pre> | ||
Line 341: | Line 341: | ||
</pre> | </pre> | ||
− | =Secondary Damage Formulae= | + | ==Secondary Damage Formulae== |
− | X0: | + | ===X0:=== |
<pre> | <pre> | ||
Damage = Attacker's HP | Damage = Attacker's HP | ||
</pre> | </pre> | ||
− | X1: | + | ===X1:=== |
<pre> | <pre> | ||
− | Damage = | + | Damage = Attacker's MHP - Attacker's HP |
</pre> | </pre> | ||
− | X8: | + | ===X8:=== |
<pre> | <pre> | ||
Dice_Count = Attacker's Level / 10 | Dice_Count = Attacker's Level / 10 | ||
Line 388: | Line 388: | ||
Damage = value_repeat * 100 * total_dice_roll | Damage = value_repeat * 100 * total_dice_roll | ||
</pre> | </pre> | ||
− | X9 | + | ===X9=== |
<pre> | <pre> | ||
Damage = Number of Successful Escapes | Damage = Number of Successful Escapes | ||
</pre> | </pre> | ||
− | XA | + | ===XA=== |
<pre> | <pre> | ||
Damage = Target's HP - 1 | Damage = Target's HP - 1 | ||
</pre> | </pre> | ||
− | XB | + | ===XB=== |
<pre> | <pre> | ||
Damage = (Game Time Hours * 100) + (Game Time Minutes) | Damage = (Game Time Hours * 100) + (Game Time Minutes) | ||
</pre> | </pre> | ||
− | XC | + | ===XC=== |
<pre> | <pre> | ||
Damage = Target's Kill Count * 10 | Damage = Target's Kill Count * 10 | ||
Line 411: | Line 411: | ||
The point of these is to set the "attack will miss" flag in the current action memory structure. | The point of these is to set the "attack will miss" flag in the current action memory structure. | ||
− | 0: Physical Accuracy Check | + | ===0: Physical Accuracy Check=== |
<pre> | <pre> | ||
todo | todo | ||
Line 417: | Line 417: | ||
</pre> | </pre> | ||
− | 1: Magical Accuracy Check | + | ===1: Magical Accuracy Check=== |
<pre> | <pre> | ||
acc = Action's Accuracy | acc = Action's Accuracy | ||
Line 439: | Line 439: | ||
</pre> | </pre> | ||
− | 2: Critical Hit Check | + | ===2: Critical Hit Check=== |
<pre> | <pre> | ||
If attack does not miss then | If attack does not miss then | ||
Line 459: | Line 459: | ||
3, 4, and 5 don't exist. Since they don't set miss they will always hit. | 3, 4, and 5 don't exist. Since they don't set miss they will always hit. | ||
− | 6: Manipulate Accuracy (intended solely for playable characters) | + | ===6: Manipulate Accuracy (intended solely for playable characters)=== |
<pre> | <pre> | ||
int ally_loop; | int ally_loop; | ||
Line 505: | Line 505: | ||
This doesn't actually place the target in the manipulate status. That happens elsewhere. | This doesn't actually place the target in the manipulate status. That happens elsewhere. | ||
− | 7: Level-based Accuracy | + | ===7: Level-based Accuracy=== |
<pre> | <pre> | ||
If Action's Accuracy > 0 then | If Action's Accuracy > 0 then |
Revision as of 16:35, 5 June 2013
Contents
Damage Formula's description
0x11:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
Damage Function 0x1
0xA0:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
Damage Function 0x1
damage = damage * (1 + number_of_status1 + 2 * number_of_status2).
number_of_status1 are calculated as sum of attacker statuses darkness, slow, silence, sadness, poison, near death.
number_of_status2 are calculated as sum of attacker statuses death sentence, slow-numb.
0xA1:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
Damage Function 0x1
if current hp less then max hp / 4 then damage = damage * 2.
if attacker in death sentence then damage = damage * 4.
0xA2:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
Damage Function 0x1
damage = damage * (1 + number_of_dead_player_units).
0xA3:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
power_modifier = total_level_of_all_enemy_target / number_of_enemy_target.
(this only use enemy units from 4 to 10 that includes in target mask after all preparation)
Damage Function 0x1
0xA4:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
power_modifier = 1 + (((current_hp * 3) / max_hp) * power_modifier).
Damage Function 0x1
0xA5:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
power_modifier = 1 + (((current_mp * 3) / max_mp) * power_modifier).
Damage Function 0x1
0xA6:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
power_modifier = 1 + (((total_ap / 10000) * power_modifier) / 16).
(total_ap is no more than ap needed for max star, so underwater materia won't work)
Damage Function 0x1
0xA7:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
power_modifier = 10 + (((number_of_kills / 128) * power_modifier) / 16).
Damage Function 0x1
0xA8:
Prepare Function 0x0 (calculate physical hit chance)
Prepare Function 0x2 (calculate critical chance)
power_modifier = 1 + (((limit_bar_value * (limit_level + 1) / 16) * power_modifier) / 16).
Damage Function 0x1
Damage Calculations
These are the damage functions according to an unmodded FF7-ENG 1.02 (1998)
Standard Formulae
X0:
Sets Target's 02h flag to 1. (Unknown effect)
X1:
If Attack Property "Always Critical" is Set Set Critical Damage Flag End If x = ( Actor's Level * Actor's (M)Attack ) / 32 y = ( Actor's Level + Actor's (M)Attack ) / 32 z = Actor's (M)Attack + ( x * y ) z = z * ( 512 - target's defense ) * Attack's Power Damage = z / 4096 If Critical Damage Flag is set Damage = Damage * 2 End If If Actor's Statuses include Berserk Damage = Damage * 3 / 2 End If Long_Range = 0 If Target is in Back Row Set Long_Range = 1 End If If Attack is Short Range OR Command is Enemy Attack If Actor is in Back Row Long_Range = 1 End If Else Long_Range = 0 End If If Long_Range != 0 Damage = Damage / 2 End If If Target is Defending Damage = Damage / 2 End If If Target's Back is exposed Damage = Damage * ( Target's Back Attack Modifier / 8 ) End If If Actor's Statuses includes Frog Damage = Damage / 4 End If Damage = Sadness( Damage ) Damage = Split( Damage, 0 ) Damage = Barrier( Damage ) If Actor's Statuses include Mini Damage = 0 End If Damage = Variance( Damage )
X2:
multiNoSplit = ( ( ( Attack's Target Flags AND Ch ) - 4 ) == 0 ? 1 : 0 ) Base = (Actor's Attack + Actor's Level) * 6 Damage = (512 - Target's Defense) * Base * Attack's Power / 8192 Damage = Sadness( Damage ) Damage = SplitDamage( Damage, multiNoSplit ) Damage = Barrier( Damage ) Damage = Variance( Damage )
X3:
If Attack Properties Damage MP is clear Damage = Target's HP Else Damage = Target's MP End If Damage = Damage * Attack's Power / 32 If ActionData[AC] != 0 (?) Damage = Damage / 2 End If
X4:
If Attack Properties Damage MP is clear Damage = Target's MHP Else Damage = Target's MMP End If Damage = Damage * Attack's Power / 32 If ActionData[AC] != 0 (?) Damage = Damage / 2 End If
X5:
Damage = (Actor's (M)Attack + Actor's Level) * 6 + (Attack's Power * 22) Damage = SplitDamage( Damage ) Damage = Barrier( Damage ) Damage = Variance( Damage )
X6:
Damage = Attack's Power * 20
X7:
Damage = ( ( 512 - Target's Def ) * Attack's Power / 32 ) Damage = Variance( Damage )
X8:
If ActionData[0x230] AND 40h ActionData[0x230] = 1 Else ActionData[0x230] = 80h End If //presumably this checks if the target heals from restore element and will either recover or kill based on the result
X9:
Actor's Attack = Actor's Strength * 2 Use Damage X1 with adjusted stat
XA:
Damage = ( Attack's Power + Number of Targets - 1 ) / Number of Targets
Additional Checks
Sadness( Damage )
If Target's Status includes Sadness Damage = Damage - (Damage * 3 / 10) End If Return Damage
SplitDamage( Damage, multiNoSplit )
If multiNoSplit == 0 If No. of Attack's Targets >= 2 Set Attack's split damage Target Flag Else Set multiNoSplit == 1 End If End If If ActionData[0xAC] == 0 Damage = Damage / 2 Else If multiNoSplit == 0 Damage = Damage * 3 / 2 End If End If Return Damage
Barrier( Damage )
If Attack Property "Physical" is 0 If Target's Statuses include MBarrier Set ActionData "MBarrier Active" flag End If Else If Target's Statuses include Barrier Set ActionData "Barrier Active" flag End If End If If ActionData "MBarrier Active" or "Barrier Active" flags are set Damage = Damage / 2 End If If attack is Magic and EnabledMagic[7] == 0 (?) Damage = Damage + ( Damage * ( EnabledMagic[7] * (10 / 32) ) / 100 ) End If Return Damage
Variance( Damage ):
Damage = Damage ([0..255] + 3841) / 4096 //from RNGLUT in KERNEL.BIN If Damage == 0 Damage == 1 End If Return Damage
Secondary Damage Formulae
X0:
Damage = Attacker's HP
X1:
Damage = Attacker's MHP - Attacker's HP
X8:
Dice_Count = Attacker's Level / 10 If Dice_Count < 2 then Dice_Count = 2 Elseif Dice_Count > 6 Dice_Count = 6 End If total_dice_roll = 0 For ( d_loop = 0; d_loop < Dice_Count; d_loop++ ) die = [0..5] all_dice[d_loop] = die total_dice_roll += die + 1 set die visualization based on roll Loop value_repeat = 0 For ( d_value = 0; d_value < 6; d_value++ ) repeat_count = 0 For ( d_loop = 0; d_loop < Dice_Count; d_loop++ ) If all_dice[d_loop] = d_value then repeat_count++ End If Loop If repeat_count > value_repeat then value_repeat = repeat_count End If Loop Damage = value_repeat * 100 * total_dice_roll
X9
Damage = Number of Successful Escapes
XA
Damage = Target's HP - 1
XB
Damage = (Game Time Hours * 100) + (Game Time Minutes)
XC
Damage = Target's Kill Count * 10 //This is intended to be used only on players //This will cause a memory leak if done on enemies
Accuracy Functions
The point of these is to set the "attack will miss" flag in the current action memory structure.
0: Physical Accuracy Check
todo It's long so I'll tackle it when I have a lot of time on my hands
1: Magical Accuracy Check
acc = Action's Accuracy tar_save = level / 2; //rounded down acc_bonus = actor's level - tar_save rand_0 = [0..99] rand_1 = [0..99] if acc < 255 then if target does not have instant-death, null, or heal properties to current attack then if attack is not (reflectable and target in reflect status) then if attack does not inflict statuses or inflicting status include: Death, Sleep, Confu, Stop, Petrify, or Paralysis then acc = Fury_Adj( acc ); if target's M_Evade > rand_0 OR acc + acc_bonus < rand_1 then Set action miss flag end if end if end if end if end if
2: Critical Hit Check
If attack does not miss then if actor in lucky girl status then critical_chance = 255 else critical_chance = ((actor's luck + actor's level) - target's level ) >> 2; if actor is playable character then critical_chance += weapon's critical bonus //? end if Critical_random = ( ( [0..65535] * 99 ) / 65535 ) + 1; if critical_chance > critical_random then attack set to critical end if end if end if
3, 4, and 5 don't exist. Since they don't set miss they will always hit.
6: Manipulate Accuracy (intended solely for playable characters)
int ally_loop; ManipSuccess = 0; for ( ally_loop = 0; ally_loop < 3; ally_loop++ ) { if target is currently under manipulation by an actor then break; end if } if target is not currently being manipulated AND target is not a playable character AND target is an enemy AND actor is not currently manipulating an enemy AND target is not under manipulate status AND target's timer bar is running AND //like they're not stopped, petrified, etc target's attack resistance is "always-hit" then //? Manip_Chance = actor's level + 50 - target's level; //no less than 0 if target count > 1 then Manip_Chance = ( Manip_Chance << 2 ) / 5; end if if actor's [0xAC] == 0 then Manip_Chance >> 1; end if if target's attack resistance is "always-hit" then Manip_Chance = 255; end if if actor's accessory property == 5 //"Increase manip rate" property on Hypnocrown if Manip_Chance < 100 then Manip_Chance = 100; end if end if If Manip_Chance > [0..99] then ManipSuccess = 1; end if end if If ManipSuccess == 1 then Set actor's manipulated enemy to target Display String 5Ah {"Manipulated <Enemy>"} Clear Actor's 0xE4 value //unknown else Set attack missed end if
This doesn't actually place the target in the manipulate status. That happens elsewhere.
7: Level-based Accuracy
If Action's Accuracy > 0 then If the remainder of ( Target's level / Action accuracy ) is non-zero then Set attack missed end if end if
So if the accuracy IS 0, then it will always hit. This is to prevent a divide by zero error.