Changes

Jump to navigation Jump to search

FF7/DamageFormula

8,472 bytes added, 16:16, 20 May 2021
m
0: Physical Accuracy Check: There is an enemy check on the Dex bonus that I didn't notice before. Physical Chance is unaffected.
== Damage Formula's description Accuracy Function considerations==Each of the upper nybble of the damage calculation determines what checks are done to accuracy of the action and whether or not it will connect, be critical or miss. Here are the functions in order processed based on the upper nybble:
<{| border="1" cellspacing="1" cellpadding="3" style="border: 1px solid black; border-collapse: collapse;"!-- 0X style= 8 none "background:rgb(always hit204,204,204)-->" | Upper Nybble<!style="background:rgb(204,204,204)" | Functions|-| 0| None (always hits)|- 1X = | 1| [[FF7/DamageFormula#0:_Physical_Accuracy_Check|Physical Accuracy]], [[FF7/DamageFormula#2 physical, isCritical:_Critical_Hit_Check|Critical Check]]|--><!-- 2X = | 2| [[FF7/DamageFormula#1 magical:_Magical_Accuracy_Check|Magical Accuracy]]|--><!-- 3X = | 3| Dummy [3 none ] (always hithits)|--><!-- 4X = | 4| Dummy [4 none ] (always hithits)|--><!-- 5X = | 5| Dummy [5 none ] (always hithits)|--><!-- 6X = | 6| [[FF7/DamageFormula#0:_Physical_Accuracy_Check|Physical Accuracy]], [[FF7/DamageFormula#2 physical, isCritical:_Critical_Hit_Check|Critical Check]]|--><!-- 7X = | 7| [[FF7/DamageFormula#1 magical:_Magical_Accuracy_Check|Magical Accuracy]]|--><!-- 8X = | 8| [[FF7/DamageFormula#7 LevelBasedAccuracy:_Level-based_Accuracy|Level->based Accuracy]]<!|-- 9X = | 9| [[FF7/DamageFormula#6 manipulate:_Manipulate_Accuracy_.28intended_solely_for_playable_characters.29|Manipulate]]|--><!-- AX = | A| [[FF7/DamageFormula#0:_Physical_Accuracy_Check|Physical Accuracy]], [[FF7/DamageFormula#2 physical, isCritical:_Critical_Hit_Check|Critical Check]]|--><!-- BX = | B| [[FF7/DamageFormula#0 physical:_Physical_Accuracy_Check|Physical Accuracy]]|--><!-- CX = 8 none | C| None (always hithits)|--><!-- DX = 8 none | D| None (always hithits)|--><!-- EX = 8 none | E| None (always hithits)|--><!-- FX = 8 none | F| None (always hithits)-->|}
0x11=Damage Calculations=These are the damage functions according to an unmodded FF7-ENG 1.02 (1998)==Standard Formulae=====X0:===''0x5DE5C0''<pre>Sets Target's 02h flag to 1. (Unknown effect)</pre>
Prepare Function 0x0 (calculate physical hit chance)===X1:===''0x5DE5DF''<pre>If Attack Property "Always Critical" is Set Set Critical Damage FlagEnd If
Prepare Function 0x2 x = (calculate critical chanceActor's Level * Actor's (M)Attack ) / 32y = ( Actor's Level + Actor's (M)Attack ) / 32z = Actor's (M)Attack + ( x * y )z = z * ( 512 - target's defense )* Attack's PowerDamage = z >> 13//This is a bit-shift left by 13 which is mathematically equivalent to dividing by 8192, but it's important to note that it doesn't actually divide as this is the source of the damage overflow glitch
If Critical Damage Function 0x1Flag is set Damage = Damage * 2End If
If Actor's Statuses include Berserk
Damage = Damage * 3 / 2
End If
0xA0:Long_Range = 0If Target is in Back Row Set Long_Range = 1End If
Prepare Function 0x0 (calculate physical hit chance)If Attack is Short Range OR Command is Enemy Attack If Actor is in Back Row Long_Range = 1 End IfElse Long_Range = 0End If
Prepare Function 0x2 (calculate critical chance)If Long_Range != 0 Damage = Damage / 2End If
If Target is Defending Damage Function 0x1= Damage / 2End If
damage If Target's Back is exposed Damage = damage Damage * (1 + number_of_status1 + 2 * number_of_status2Target's Back Attack Modifier / 8 ).End If
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)If Actor's Statuses includes Frog Damage = Damage Function 0x1 if current hp less then max hp / 4 then damage = damage * 2. if attacker in death sentence then 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 )</pre>
===X2:===
''0x5DE9B8''
<pre>
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 )
</pre>
0xA2===X3:===''0x5DEA6D''<pre>If Attack Properties Damage MP is clear Damage = Target's HPElse Damage = Target's MPEnd If
Prepare Function 0x0 (calculate physical hit chance)Damage = Damage * Attack's Power / 32
Prepare Function 0x2 If ActionData[AC] != 0 (calculate critical chance?) Damage = Damage / 2End If</pre>
===X4:===''0x5DEAF7''<pre>If Attack Properties Damage Function 0x1MP is clear Damage = Target's MHPElse Damage = Target's MMPEnd If
damage Damage = damage Damage * (1 + number_of_dead_player_units).Attack's Power / 32
If ActionData[AC] != 0 (?)
Damage = Damage / 2
End If
</pre>
===X5:===
''0x5DEB81''
<pre>
Damage = (Actor's (M)Attack + Actor's Level) * 6 + (Attack's Power * 22)
Damage = SplitDamage( Damage )
Damage = Barrier( Damage )
Damage = Variance( Damage )</pre>
0xA3===X6:===''0x5DEBE5''<pre>Damage = Attack's Power * 20</pre>
Prepare Function 0x0 ===X7:===''0x5DEC0A''<pre>Damage = (calculate physical hit chance( 512 - Target's Def ) * Attack's Power / 32 )Damage = Variance( Damage )</pre>
Prepare Function 0x2 (calculate critical chance)===X8:===''0x5DEC52''<pre>If ActionData[0x230] AND 40h ActionData[0x230] = 1Else ActionData[0x230] = 80hEnd If//presumably this checks if the target heals from restore element and will either recover or kill based on the result</pre>
power_modifier = total_level_of_all_enemy_target ==X9:===''0x5DEC8A''<pre>Actor's Attack = Actor's Strength * 2Use Damage X1 with adjusted stat</ number_of_enemy_target.pre>
===XA:===''0x5DECAA''<pre>Damage = (this only use enemy units from 4 to 10 that includes in target mask after all preparationAttack's Power + Number of Targets - 1 )/ Number of Targets</pre>
==Additional Checks=====Sadness( Damage Function 0x1)===''0x5DE958''<pre>If Target's Status includes Sadness Damage = Damage - (Damage * 3 / 10)End IfReturn Damage</pre>
===SplitDamage( Damage, multiNoSplit )===
''0x5DE8F4''
<pre>
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
</pre>
0xA4:===Barrier( Damage )===''0x5DE82C''<pre>If Attack Property "Physical" is 0 If Target's Statuses include MBarrier Set ActionData "MBarrier Active" flag End IfElse If Target's Statuses include Barrier Set ActionData "Barrier Active" flag End IfEnd If
Prepare Function 0x0 (calculate physical hit chance)If ActionData "MBarrier Active" or "Barrier Active" flags are set Damage = Damage / 2End If
Prepare Function 0x2 If attack is Magic and EnabledMagic[7] == 0 (calculate critical chance?) Damage = Damage + ( Damage * ( EnabledMagic[7] * (10 / 32) ) / 100 )End IfReturn Damage</pre>
power_modifier = 1 + ==Variance(Damage ):===''0x5DE988''<pre>Damage = Damage ((current_hp * 3[0..255] + 3841) >> 12 // max_hp) * power_modifier)from RNGLUT in KERNEL.BIN//Again, we have another chance for overflow.
If Damage Function 0x1== 0 Damage == 1End IfReturn Damage</pre>
==Secondary Damage Formulae==
===X0:===
''0x5DECFB''
<pre>
Damage = Attacker's HP
</pre>
===X1:===
''5DED1E''
<pre>
Damage = Attacker's MHP - Attacker's HP
</pre>
===X8:===
''0x5DED73''
<pre>
Dice_Count = Attacker's Level / 10
If Dice_Count < 2 then
Dice_Count = 2
Elseif Dice_Count > 6
Dice_Count = 6
End If
0xA5:total_dice_roll = 0For ( d_loop = 0; d_loop < Dice_Count; d_loop++ ) die = [0..5] all_dice[d_loop] = die total_dice_roll += die + 1
Prepare Function 0x0 (calculate physical hit chance) set die visualization based on rollLoop
Prepare Function 0x2 value_repeat = 0For (calculate critical chanced_value = 0; d_value < 6; d_value++ )
power_modifier repeat_count = 1 0 For ( d_loop = 0; d_loop < Dice_Count; d_loop++ (((current_mp * 3) / max_mp) * power_modifier).
Damage Function 0x1 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
0xA6:Damage = value_repeat * 100 * total_dice_roll</pre>===X9===''0x5DEEEF''<pre>Damage = Number of Successful Escapes</pre>===XA===''0x5DEF1D''<pre>Damage = Target's HP - 1</pre>===XB===''0x5DEF44''<pre>Damage = (Game Time Hours * 100) + (Game Time Minutes)</pre>===XC===''0x5DEF88''<pre>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</pre>===XD===''0x5DEFDD''<pre>If target is playable character MateriaCount = 0; For ( MateriaLoop = 0; MateriaLoop < 8; MateriaLoop++ ) If target has materia in weapon slot [MateriaLoop] then MateriaCount++ If target has materia in armor slot [MateriaLoop] then MateriaCount++ Loop Damage = MateriaCount * 1111End If</pre>
Prepare Function 0x0 (calculate physical hit chance)=Accuracy Functions=The point of these is to set the "attack will miss" flag in the current action memory structure.
Prepare Function 0x2 (calculate critical chance)===0: Physical Accuracy Check===''0x5DDBB0''<pre>;For the purposes of this code, "Dex" means the adjusted Dexterity of the actor/target if any in-battle dex bonuses have been granted.;Same holds for the Physical Evade. Physical Hit rate has no in-game bonus opportunities.
power_modifier = 1 + Check_For_Cover(((total_ap / 10000) * power_modifier) / 16).
(total_ap is no more than ap needed for max star, so underwater materia won't work)HitChance = -1;
Damage Function 0x1If "Always connect" flag set then HitChance = 255;
If target has one of the following statuses (Death, Sleep, Confu, Stop, Petrify, Manipulate, Paralysis) then
Remove Sleep status
Remove Confu status
Remove Manipulate status
HitChance = 255
End If
If action is flagged as "always hit" then HitChance = 255;
Physical Chance = (Actor's Dex >> 2) + action physical hit rate
If Actor is enemy then
Actor's evade = Actor's Physical evade
else
Actor's evade = (Actor's Dex >> 2) + Actor's Physical evade
End If
If Target is enemy then
Target's evade = Target's Physical evade
Else
Target's evade = (Target's Dex >> 2) + Target's Physical evade
End If
0xA7:If HitChance = -1 Then HitChance = Physical Chance + Actor's evade - Target's evade HitChance = FuryAdjust(HitChance)End If
Prepare Function 0x0 (calculate physical hit chance)If HitChance = 0 then HitChance = 1
Prepare Function 0x2 Luck Chance = [0..99]If (calculate critical chanceActor's Luck / 4)> Luck Chance Then HitChance = 255 ;Lucky HitElse If Actor is Player Character targetting an enemy Then If (Target's Luck / 4) > Luck Chance HitChance = 0 ;Lucky Dodge End If End IfEnd If
power_modifier Miss Chance = 10 + (((number_of_kills / 128) [0..65535] * power_modifier99) / 1665535)+ 1 ;essentially [1..100]if HitChance < Miss Chance then Set Miss flagEnd If</pre>
Damage Function 0x1====Check_For_Cover==== This is where the game checks if the target is covered under a "cover"ing ally. It only applies to Player Characters It might be more complicated than I'm seeing, but that is definitely ONE of its functions
====FuryAdjust(HitChance)====
<pre> If HitChance < 255 then
If Actor is in Fury Status
HitChance = HitChance - ((HitChance * 3) / 10)
End If
End If
return HitChance </pre>
===1: Magical Accuracy Check===
''0x5DDE5E''
<pre>
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
</pre>
0xA8===2:Critical Hit Check===''0x5DDF8E''<pre>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 ifend if</pre>
Prepare Function 0x0 (calculate physical 3, 4, and 5 don't exist. Since they don't set miss they will always hit chance).
Prepare Function 0x2 ===6: Manipulate Accuracy (calculate critical chanceintended solely for playable characters)===''0x5DE0D0''<pre>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 ifend ifIf ManipSuccess == 1 then Set actor's manipulated enemy to target Display String 5Ah {"Manipulated <Enemy>"} Clear Actor's 0xE4 value //unknownelse Set attack missedend if</pre>This doesn't actually place the target in the manipulate status. That happens elsewhere.
power_modifier = 1 + (((limit_bar_value * (limit_level + 1) / 16) * power_modifier) / 16). Damage Function 0x1  ===Damage Calculations7: Level-based Accuracy===For standard damage functions X0::Sets Target's 02h flag to 1. (Unknown effect) X1::If Attack is set as "Always critical" then make damage physical type :x = Attacker's level * attacker0x5DE08A''s damage stat (depending on physical or magic type):x = (x + Attacker's level AND 31) <pre>> 5:y = AttackerIf Action's level + attacker's damage stat (depending on physical or magic type)Accuracy > 0 then:y = If the remainder of (y + AttackerTarget's level AND 31) >> 5:z = attacker's damage stat + (x * y/ Action accuracy ):z = z * ( 512 - target's defense ) * attack's power:Damage = z / 16 :If attack is Berserk and Attack is Physical: Damage = Damage * 3 / 2:If target is in Confu status, set target to unnon-confusezero then:If target is in Fury, Damage = Damage / 2:If attack is back-attack attack: Damage = Damage * (back Set attack modifier / 8):If attacker is in Frog: Damage = Damage / 4missed:If target is in Sadness: Damage = Damage - (Damage * 3 / 10) end if:"Split Damage" -pendingend if:If target has barrier appropriate to attack: Damage = Damage </ 2pre> :Damage = Damage * (0x5DE8BF / 100)?:If attacker is Mini'd: Damage = So if the accuracy IS 0:Damage = Max( Damage * [3841, then it will always hit.This is to prevent a divide by zero error.4096] / 4096 , 1 )
6
edits

Navigation menu