Changes

Jump to navigation Jump to search

FF7/DamageFormula

5,990 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.If Actor's Statuses includes Frog Damage = Damage / 4End If
number_of_status2 are calculated as sum of attacker statuses death sentence, slow-numb.   0xA1: Prepare Function 0x0 Damage = Sadness(calculate physical hit chanceDamage Prepare Function 0x2 Damage = Split(calculate critical chanceDamage, 0 ) 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 Barrier(calculate physical hit chanceDamage ) Prepare Function 0x2 (calculate critical chance)If Actor's Statuses include Mini Damage Function 0x1= 0End Ifdamage Damage = damage * Variance(1 + number_of_dead_player_unitsDamage ).   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.pre>
===X2:===''0x5DE9B8''<pre>multiNoSplit = (this only use enemy units from ( ( Attack's Target Flags AND Ch ) - 4 to 10 that includes in target mask after all preparation)== 0 ? 1 : 0 )Base = (Actor's Attack + Actor's Level) * 6Damage = (512 - Target's Defense) * Base * Attack's Power / 8192Damage = Sadness( Damage )Damage = SplitDamage( Damage, multiNoSplit )Damage = Barrier( Damage )Damage = Variance( Damage )</pre>
===X3:===''0x5DEA6D''<pre>If Attack Properties Damage Function 0x1MP is clear Damage = Target's HPElse Damage = Target's MPEnd If
Damage = Damage * Attack's Power / 32
If ActionData[AC] != 0 (?)
Damage = Damage / 2
End If</pre>
0xA4===X4:===''0x5DEAF7''<pre>If Attack Properties Damage MP is clear Damage = Target's MHPElse Damage = Target's MMPEnd 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>
power_modifier = 1 + ==X5:===''0x5DEB81''<pre>Damage = (Actor's (M)Attack + Actor's Level) * 6 + (current_hp Attack's Power * 322)Damage = SplitDamage( Damage ) / max_hpDamage = Barrier( Damage ) * power_modifierDamage = Variance( Damage ).</pre>
===X6:===''0x5DEBE5''<pre>Damage Function 0x1= Attack's Power * 20</pre>
===X7:===
''0x5DEC0A''
<pre>
Damage = ( ( 512 - Target's Def ) * Attack's Power / 32 )
Damage = Variance( Damage )
</pre>
===X8:===
''0x5DEC52''
<pre>
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</pre>
0xA5===X9:===''0x5DEC8A''<pre>Actor's Attack = Actor's Strength * 2Use Damage X1 with adjusted stat</pre>
Prepare Function 0x0 ===XA:===''0x5DECAA''<pre>Damage = (calculate physical hit chanceAttack's Power + Number of Targets - 1 )/ Number of Targets</pre>
Prepare Function 0x2 ==Additional Checks=====Sadness(calculate critical chanceDamage )===''0x5DE958''<pre>If Target's Status includes Sadness Damage = Damage - (Damage * 3 / 10)End IfReturn Damage</pre>
power_modifier = 1 + ((==SplitDamage(current_mp * 3) / max_mp) * power_modifierDamage, 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 IfEnd If
If ActionData[0xAC] == 0 Damage Function 0x1= Damage / 2Else If multiNoSplit == 0 Damage = Damage * 3 / 2 End IfEnd IfReturn Damage</pre>
===Barrier( Damage )===
''0x5DE82C''
<pre>
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
0xA6:If attack is Magic and EnabledMagic[7] == 0 (?) Damage = Damage + ( Damage * ( EnabledMagic[7] * (10 / 32) ) / 100 )End IfReturn Damage</pre>
Prepare Function 0x0 ===Variance(calculate physical hit Damage ):===''0x5DE988''<pre>Damage = Damage ([0..255] + 3841) >> 12 //from RNGLUT in KERNEL.BIN//Again, we have another chance)for overflow.
Prepare Function 0x2 (calculate critical chance)If Damage == 0 Damage == 1End IfReturn Damage</pre>
power_modifier = 1 + (((total_ap =Secondary Damage Formulae=====X0:===''0x5DECFB''<pre>Damage = Attacker's HP</ 10000) * power_modifier) pre>===X1:===''5DED1E''<pre>Damage = Attacker's MHP - Attacker's HP</pre>===X8:===''0x5DED73''<pre>Dice_Count = Attacker's Level / 16).10
(total_ap is no more than ap needed for max star, so underwater materia won't work)If Dice_Count < 2 then Dice_Count = 2Elseif Dice_Count > 6 Dice_Count = 6End If
Damage Function 0x1total_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
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++ )
0xA7: If all_dice[d_loop] = d_value then repeat_count++ End If Loop
Prepare Function 0x0 (calculate physical hit chance) If repeat_count > value_repeat then value_repeat = repeat_count End If
Prepare Function 0x2 (calculate critical chance)Loop
power_modifier Damage = 10 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 ((number_of_kills / 128MateriaLoop = 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 * power_modifier) 1111End If</ 16).pre>
Damage Function 0x1=Accuracy Functions=The point of these is to set the "attack will miss" flag in the current action memory structure.
===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.
Check_For_Cover()
0xA8:HitChance = -1;
Prepare Function 0x0 (calculate physical hit chance)If "Always connect" flag set then HitChance = 255;
Prepare Function 0x2 If target has one of the following statuses (calculate critical chanceDeath, Sleep, Confu, Stop, Petrify, Manipulate, Paralysis)then Remove Sleep status Remove Confu status Remove Manipulate status HitChance = 255End If
power_modifier If action is flagged as "always hit" then HitChance = 1 + (((limit_bar_value * (limit_level + 1) / 16) * power_modifier) / 16).255;
Damage Function 0x1Physical Chance = (Actor's Dex >> 2) + action physical hit rateIf Actor is enemy then Actor's evade = Actor's Physical evadeelse Actor's evade = (Actor's Dex >> 2) + Actor's Physical evadeEnd IfIf Target is enemy then Target's evade = Target's Physical evadeElse Target's evade = (Target's Dex >> 2) + Target's Physical evadeEnd If
If HitChance = -1 Then
HitChance = Physical Chance + Actor's evade - Target's evade
HitChance = FuryAdjust(HitChance)
End If
If HitChance =0 then HitChance =Damage Calculations==For standard damage functions1
X0:Luck Chance = [0..99]:Sets TargetIf (Actor's 02h flag to 1. (Unknown effectLuck / 4)> Luck Chance Then---- HitChance = 255 ;Lucky HitX1:Else: If Attack Property "Always Critical" Actor is SetPlayer Character targetting an enemy Then If (Target's Luck / 4) > Luck Chance::Set Critical Damage Flag HitChance = 0 ;Lucky Dodge End If End If:End If
:x Miss Chance = ( Actor's Level ([0..65535] * Actor's (M99)Attack / 65535) / 32:y = ( Actor's Level + Actor's (M)Attack ) / 321 ;essentially [1..100]:z = Actor's (M)Attack + ( x * y )if HitChance < Miss Chance then:z = z * ( 512 - target's defense ) * Attack's Power Set Miss flag:Damage = z End If</ 4096pre>
:If Critical Damage Flag ====Check_For_Cover==== This is where the game checks if the target is setcovered under a "cover"ing ally.::Damage = Damage * 2 It only applies to Player Characters:End If 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's Statuses include Berserkis in Fury Status::Damage HitChance = Damage HitChance - ((HitChance * 3 ) / 210) End If: End If return HitChance </pre>
===1:Long_Range Magical Accuracy Check===''0x5DDE5E''<pre>acc = Action's Accuracytar_save = level / 2; //rounded downacc_bonus = actor's level - tar_saverand_0 = [0..99]rand_1 = [0..99]:If Target 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 Back Rowreflect status) then if attack does not inflict statuses or inflicting status include::Set Long_Range Death, Sleep, Confu, Stop, Petrify, or Paralysis then acc = 1:End IfFury_Adj( acc );:If Attack is Short Range if target's M_Evade > rand_0 OR Command is Enemy Attack::If Actor is in Back Row acc + acc_bonus < rand_1 then:::Long_Range = 1 Set action miss flag::End If end if:Else end if::Long_Range = 0 end if:End If end if:If Long_Range != 0end if::Damage = Damage </ 2:End Ifpre>
===2:Critical Hit Check===''0x5DDF8E''<pre>If Target 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 Defendingplayable character then::Damage critical_chance += weapon's critical bonus //? end if Critical_random = Damage ( ( [0..65535] * 99 ) / 265535 ) + 1; if critical_chance > critical_random then attack set to critical end if end ifend if:End If</pre>
:If Target3, 4, and 5 don's Back is exposed::Damage = Damage * ( Targett exist. Since they don's Back Attack Modifier / 8 ):End Ift set miss they will always hit.
===6:If ActorManipulate Accuracy (intended 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 Statuses includes Frogattack resistance is "always-hit" then //?::Damage Manip_Chance = Damage actor's level + 50 - target's level; // 4no less than 0:End If if target count > 1 then :Damage Manip_Chance = Sadness( Damage Manip_Chance << 2 )/ 5; end if:Damage if actor's [0xAC] == Split( Damage, 0 )then Manip_Chance >> 1; end if if target's attack resistance is "always-hit" then:Damage Manip_Chance = Barrier( Damage )255; end if:If Actor if actor's Statuses include Miniaccessory property == 5 //"Increase manip rate" property on Hypnocrown:: Damage if Manip_Chance < 100 then Manip_Chance = 100; end if end if If Manip_Chance > [0..99] then ManipSuccess = 1; end ifend if:End IfManipSuccess == 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.
:Damage = Variance( Damage )----X2::multiNoSplit = ( ( ( Attack's Target Flags AND Ch ) - 4 ) == 0 ? 1 : 0 )7:Base = (Actor's Attack + Actor's Level) * 6:Damage = (512 - Target's Defense) * Base * Attack's Power:Damage = Sadness( Damage ):Damage based Accuracy= 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 * Attack0x5DE08A's Power / 32:If ActionData[AC] != 0 (?)::Damage = Damage / 2:End If:Damage----X4::If Attack Properties Damage MP is clear::Damage = Target's MHP:Else<pre>::Damage = Target's MMP:End If:Damage = Damage * AttackAction's Power / 32:If ActionData[AC] != Accuracy > 0 (?)::Damage = Damage / 2:End If:Damage----X5::Damage = (Actor's (M)Attack + Actor's Level) * 6 + (Attack's Power * 22):Damage = SplitDamage( Damage ):Damage = Barrier( Damage ):Damage = Variance( Damage )then----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----X9::Actor's Attack = Actor's Strength * 2:Use Damage X1 with adjusted stat----XA:Damage = ( Attack's Power + Number of Targets - 1 ) / Number the remainder of Targets----Sadness( Damage )::If Target's Status includes Sadness::Damage = Damage - (Damage * 3 level / 10Action accuracy ):End If:Return Damage---is non-zero thenSplitDamage( Damage, multiNoSplit )::If multiNoSplit == 0::If No. of Attack's Targets >= 2::: Set Attack's split damage Target Flag::Elseattack missed:::Set multiNoSplit == 1 end if::End Ifend if:End If:If ActionData[0xAC] == 0::Damage = Damage </ 2:Elsepre>::If multiNoSplit == So if the accuracy IS 0:::Damage = Damage * 3 / 2::End If:End If:Return Damage----Barrier( Damage )::If Attack Property "Physical" , then it will always hit. This 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 KERNELto prevent a divide by zero error.BIN:If Damage == 0::Damage == 1:End If:Return Damage
6
edits

Navigation menu