Final Fantasy Hacktics

Modding => Help! => Topic started by: RiketzKarlom on September 11, 2013, 11:39:36 pm

Title: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 11, 2013, 11:39:36 pm
Could anyone direct me to a place that explains how damage from it is calculated, or point me to the right place in FFTPatcher to change it? I've been working on a balance patch, with a few other tweaks here and there for some friends, and it's the last big, glaring issue. I'm willing to bet Bravery is a factor in its damage, and that'd be the main component I'd want to take out. Ideally, I'd like the game to view PA as WA, then do the standard DA = PA*WE+Y formula, possibly even with a negative Y to keep it all in line.
Title: Re: Question about Martial Arts/Brawler
Post by: Pride on September 12, 2013, 12:33:56 am
By Martial Arts, I assume you mean the support which cannot be changed in the FFTPatcher, there should be a few ASMs that change it but won't be accessible if you're hacking wotl.
Title: Re: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 12, 2013, 12:45:57 am
Yes, I'm modding the PSX ISO, and I do mean the support skill. I poked around and found that the "Nothing" on the top of the items list is Bare-Handed, so that's a start. Just wish I knew -exactly- what formula Martial Arts/Brawler applies to unarmed damage, and if modifying the "Nothing" item could somehow make Monks a tad bit less one-shotty and broken.
Title: Re: Question about Martial Arts/Brawler
Post by: Dokurider on September 12, 2013, 02:33:24 am
Fists have the following formula:
[PA1 * (Br/100)] * PA2

When Martial Arts/Brawler is applied, PA2 is increased by 3/2. As you can tell, Bravery is the only thing keeping the fist formula from being absolutely exponential.

I would strongly suggest reading through the Battle Mechanics Guide. (http://www.gamefaqs.com/ps/197339-final-fantasy-tactics/faqs/3876) It goes into great depth on the various damage and success formulas, what effects them, and all kinds of useful information to someone wanting to modify FFT.
Title: Re: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 12, 2013, 03:39:12 am
So, if I'm reading this correctly, with 100 Brave, fist damage is PA to the second power. This presents a serious problem, as I'm trying to reduce Brave's sole function to be Reaction skill activation rate. This means I'd need to learn a bit about ASM hacking, and try and hard code a 50 Brave into that spot for all Fist damage to keep it on par with, say, Swords ranging around 20-25 WE?
Title: Re: Question about Martial Arts/Brawler
Post by: Myrmidon on September 12, 2013, 04:18:15 pm
or download Raven's Tools.

there's a formula editor in there that lets you change weapon formulas.

You can make it, say, PA*25 to keep it in line with a sword with WP25.

I...honstly think that such a WP will be a little high, though. a PA of 10 is 250DMG. in Vanilla, I can easily get a PA of around 15, which is 375DMG - which could kinda 1-shot most things, given HP growth at the time.
Title: Re: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 13, 2013, 05:51:40 am
Quote from: Myrmidon on September 12, 2013, 04:18:15 pm
or download Raven's Tools.

there's a formula editor in there that lets you change weapon formulas.

You can make it, say, PA*25 to keep it in line with a sword with WP25.

I...honstly think that such a WP will be a little high, though. a PA of 10 is 250DMG. in Vanilla, I can easily get a PA of around 15, which is 375DMG - which could kinda 1-shot most things, given HP growth at the time.

Oh my, thank you VERY much for that suggestion! Having full control over formulas is spectacular!
Title: Re: Question about Martial Arts/Brawler
Post by: Myrmidon on September 13, 2013, 01:50:25 pm
not ALL formulas, mind you - just weapon formulas.

believe me - I'd LOVE to have an easy way to have Nanoflare's formula with Faith calculations, but...no such luck...
Title: Re: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 14, 2013, 01:46:33 am
Oh, of course. I have a standard PA/MA growth of "60" across the board for all playable characters and classes, speed growth 100, etc. This way, the only differences in final stats come the class you are playing as, not your leveling path - much less of a headache in the long haul, and a lot more comfortable to newcomers. Accumulate's replaced with a modified Cheer Up, and granted to the "Special" units as well, however. This is why I was hoping to find an easy way to plug in a DMG=PA*(50/100*PA), and in the case of Brawler, 70/100. Of course, I've scaled back on WE in general, and changed the way a lot of them are wielded. 1.3 certainly had the right idea of turning off dual Knight Swords, and binding them to 2h Only. Just about everything else I could possibly hope for was right in FFTorgASM, with the only exceptions being the ability to scale Bare Handed and Brawler to appropriate power levels. Really, every other aspect of my current test play is going swimmingly, though I somehow managed to break TacText along the line. I strongly suspect it has something to do with adding in extra unit names and menu quotes where nothing was before, and things just not quite matching up anymore. Either way, I'm rambling now, will try and make heads or tails of some of these... microsoft office related spreadsheets and apps, though it's going to involve some serious hunting and downloading.
Title: Re: Question about Martial Arts/Brawler
Post by: Pride on September 14, 2013, 04:12:04 am
Quote from: Myrmidon on September 13, 2013, 01:50:25 pm
not ALL formulas, mind you - just weapon formulas.

believe me - I'd LOVE to have an easy way to have Nanoflare's formula with Faith calculations, but...no such luck...


Give me time to get my asm done.
Title: Re: Question about Martial Arts/Brawler
Post by: Myrmidon on September 14, 2013, 03:05:30 pm
If you're making an easy-to-use damage formula changer, like Raven's weapon formula changer, you'll be my hero.
Title: Re: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 16, 2013, 06:42:16 am
I'll second that. Also noticed an ASM hack that changes Meliadoul's Mighty Sword skills to use the Knightsword/Katana damage formula, and cuts it in half. If options for fractions are possible, that'd be beyond handy. I'm especially looking forward to anything that can modify Martial Arts/Brawler, because it has gone untouched in every tool I've seen. Best of luck, Pride!
Title: Re: Question about Martial Arts/Brawler
Post by: formerdeathcorps on September 16, 2013, 01:49:37 pm
In the meantime, Riketz, you can try to make it so monk does not have martial arts innate and apply the ASM that removes the skillset hard-coding for Martial Arts (which pokeytax wrote and I just fixed for Jot5).  Another idea would be to apply the weapon XA hack that does PA * Br% * Naked_PA so fist damage doesn't stack nearly as much.  In fact, Naked_PA * PA (assuming 100 brave and martial arts) ~ PA * WP (assuming damage setup and ATKUP) using vanilla growths and multipliers (though your patch may be different).

Myrmidon, Riketz, please list what kinds of formula changes you'd like to see.  Be as specific and as thorough as possible.  I'm working on a formula hack and I'd like to take suggestions on what other people would like to see, but I'd rather code it all at once than patch my entire code multiple times to address new feature requests (which wastes time and increases the likelihood for error).
Title: Re: Question about Martial Arts/Brawler
Post by: Myrmidon on September 16, 2013, 03:28:50 pm
Dmg_B(PA*(WP+Y)) 100% Status - Swordskill, but with Brave

Dmg_F(MA*(WP+Y)) 100% Status - Same as above, but with Faith

Dmg_F((MA+Y)/2*MA) - Would be amazing for making scaling spells

Dmg_B((PA+Y)/2*PA) - Again - scaling physical skills. - Possibly 2/Naked for this and above, for scaling purposes.  Will test.

Dmg_((MA+Y)/2*PA) - Opposite of Geomancy - could come in handy

Heal_(Y)%  100% Add Status on Caster  - would be great for recreating Sabin's Spirallier

Generic: Set_Skeleton: Hit(MA+X)%  - would be cool for a Necromancer skill, especially if Invite can be tacked on, and/or it can only target KO'd targets.  Don't know how easy/hard it would be, though.

Undead: Heal_(Y)% 100% Add Status - Again, would be cool for a Necromancer

Dmg_((PA+Y)*PA/2) #Hit(Rdm(1,(X/SP)) - A basic (?) multi-hit formula.  More hits based off unit's speed.

Dmg ((100-CasB)*(100-TarB)*(WP+X)*PA) - Remember the Chicken Knife?  Would also work fine without calculating opponent's Brave.

Equipped:Break Dmg_(MA*Y) - Magic-oriented break skills.  Usable for things, like Acid Breath on a dragon that dissolves armour.

Equipped:Break Dmg_(PA*Y) - Again, to make break skills for monsters.

Dmg_(MA*Y) DmgCas_(MA*Y/X) - Bloodcasting

Dmg_F(MA*Y) DmgCas_F(MA*Y/X) - Bloodcasting...with Faith!

Dmg_F((MA+Y)/2*MA) DmgCas_F(((MA+Y)/2*MA)/X) - because I'm horrible people.  I still like it, conceptually, though.

HealMP_(CasMaxMP*1/5) DmgCasMP_(CasMaxMP*1/5) - give MP to an ally.  not much explanation needed.

Hit_B(PA+X)% - again, I like the idea of being affected by Brave

Dmg_(CasMaxHP-CasCurHP) Hit_(MA+X)% - shock needs accuracy issues if it's gonna be accessible to everyone

Dmg_(CasCurHP) - not as much for a skill, but as a skill to be placed on a weapon as a different damage formula.

DmgCas_(PA*Y) HealMP_(PA*Y) - I considered having this as an MA skill, since it's obviously for mages...but I think a Wizard would kill itself very quickly using it that way...

Honestly, I just really like the idea of using Brave to calculate physical skills effectiveness, and Faith for magic effectiveness.  Kinda like the whole Fury concept, but not including weapons.

I'd also like to see more Speed formulas, but any examples elude me for now.  It makes me a little sad that speed is only used for Aim: Arm/Leg, Seal Evil, Stealing and Throwing.  Something like Dmg_((SP+Y)/2*MA) might be neat for a continuous caster or something, though.

aaand I think I'm going overboard with ideas, here.  Like, seriously overboard.  I should likely stop.
Title: Re: Question about Martial Arts/Brawler
Post by: formerdeathcorps on September 16, 2013, 09:52:51 pm
This is more "overboard" for you than it is for me.  Experience from making my patch tells me that this much variety in the damage formulas is actually wasteful because you end up with a huge variety of formulas that mostly have very similar outputs.  That being said, because most of your formulas are actually all very similar, I can address all requests other than necromancer and Sabin mimicry with:

(STAT1 +/- C) * [STAT2 * (D + 1) / 128] * (Br% or Fa%); Optional: Break Stuff, Optional: Recoil

Required:
0) A brave flag for damage
1) A faith flag for damage
2) An extra byte table of 736 bytes for the above D and O(ptional) values
3) A flag for recoil
4) A flag for breaking gear
5) A flag for affect MP
6) A flag for toggling healing/damage
7) A flag for toggling P/M-EV
8) A flag for toggling Physical/Magical Multipliers
9) X upper4bits: (STAT1---choose from PA, MA, SP, WP, Naked_PA, Naked_MA, Naked_SP, LVL / 9 + 4, (PA + MA) / 2, (PA + SP) / 2, (SP + MA) / 2, (MA + LVL / 9 + 4) / 2, (PA + LVL / 9 + 4) / 2, (SP + LVL / 9 + 4) / 2, 128, 1, not having a weapon defaults to Naked_PA)
A) X lower4bits: (STAT2---choose from PA, MA, SP, WP, CascurHP, CasmaxHP, CasmaxHP - CascurHP, CascurMP, CasmaxMP, CasmaxMP - CascurMP, TarcurHP, TarmaxHP, TarmaxHP - TarcurHP, TarcurMP, TarmaxMP, TarmaxMP - TarcurMP; STAT2 is affected by damage multipliers, not having a weapon defaults to PA * Br%)
B) Signed Y = C
C) D = (D + 1) / 128 multiplier
D) O upper3bits: (Choose from Break: Weapon, Shield, Helm, Armor, Accessory)
E) O middlebit: (Interchange formula)
F) O lowest4bits: (Recoil = Output * [lower4bits + 1] / 16)

The interchanged formula is
Accuracy = (STAT1 + C) * (Br or Fa)%
Effect = [STAT2 * (D + 1) / 128]

Most of these ideas were in the planning phase of my formula hack anyways; it's helpful to flesh out my ideas for what others may want.
Title: Re: Question about Martial Arts/Brawler
Post by: RiketzKarlom on September 18, 2013, 07:21:42 am
(STAT1 +/- C) * [STAT2 * (D + 1) / 128] * (Br% or Fa%); Optional: Break Stuff, Optional: Recoil

Looks pretty great, though I'd still like the ability to take Brave and Faith out of the formula completely.
Only other idea for a formula I'd come up with would be :

+MA_(Y) NS NE

Having a magic equivalent to Accumulate could be a really neat trick for a hasted White Mage or Summoner with Short Charge to take advantage of, for example. I imagine it's possible, since non-permanent MA boost exists within Sing.
Title: Re: Question about Martial Arts/Brawler
Post by: formerdeathcorps on September 23, 2013, 04:53:46 pm

005C0508
00000000


1980033C
902D638C
00000000
04006294
00000000
40100200
040062A4


D4FFBD27
0800B0AF
0C00B1AF
1400B2AF
1800B3AF
1000BFAF
1980123C
D6385396
0680013C
C0981300
21083300
F0EB2124
06003194
04003094
00012232
05004010
982D538E
4421060C
00000000
02000010
00000000
6E21060C
1C00B4AF
E4004014
942D548E
F9384292
06000534
0F004430
1B008500
12300000
10180000
0300C014
FFFFC624
03000010
21386002
21388002
1100C014
2800E524
01006130
02002010
42180300
0400A524
04006010
FFFF6324
07006010
0200A494
03000010
0000A694
03000010
2120C000
00000000
23208600
16000010
CE3844A6
10006010
FFFF6324
10006010
FFFF6324
F9FF6010
0E00A490
02394692
FCFFA390
F5FFC014
2120C000
19008300
12200000
64000334
00000000
1B008300
EEFF0010
12200000
ECFF0010
0F00A490
EAFF0010
1000A490
F0004230
82100200
22008392
09000434
1B006400
1580043C
21204400
5871828C
12180000
08004000
04006324
98711580
A0711580
A8711580
B0711580
B8711580
C0711580
C8711580
D0711580
D8711580
E8711580
F0711580
F8711580
00721580
08721580
10721580
1C721580
25000010
01000434
23000010
80000434
21000010
21206000
1F000010
31008492
1D000010
32008492
1B000010
36008492
19000010
37008492
17000010
38008492
02394592
00000000
1300A014
2120A000
11000010
30008492
36008592
0B000010
37008492
09000010
38008592
07000010
36008492
05000010
21286000
03000010
37008492
21286000
38008492
00000000
21208500
42200400
D6384596
1580033C
40280500
21186500
2000B5AF
2400B6AF
006C7594
D03844A6
CE384396
0010B632
0400C012
FA384292
CE3844A6
900163A6
D03842A6
F7384392
F3384592
04394492
0400A230
02004010
25B0C502
25186400
FF17060C
F73943A2
03002432
15008010
02008430
09008010
00000000
8118060C
00000000
C718060C
00000000
1819060C
00000000
0B000010
00000000
1518060C
00000000
9518060C
00000000
B318060C
00000000
DB18060C
00000000
3E19060C
00000000
0010C232
04004010
D0384496
CE384396
08000010
21186400
FA384382
00000000
20208300
0200801C
CE384396
01000424
D03844A6
5912060C
CE3843A6
0010C232
05004014
00040532
5A19060C
00000000
05000010
CE384396
CE384496
90016396
0200A010
900164A6
541C060C
CE3843A6
F3384292
00000000
80004230
0F004010
0010C132
90016296
24006392
10270434
19004300
12100000
24008392
00000000
19004300
12100000
00000000
00000000
1B004400
12100000
900162A6
07002010
21184000
441D060C
00000000
8C016292
CE384396
09004010
00000000
E803622C
02004014
00000000
E7030324
B41B060C
900163A6
FE1B060C
00000000
2000B58F
2400B68F
0800B08F
0C00B18F
1400B28F
1000BF8F
1800B38F
1C00B48F
0800E003
2C00BD27



We now stand at a crossroads.  The above plans can raise mechanical issues that Square never had to deal with.
1) Two Hands: How should it apply?  Should it apply to any formula with WP, any formula that uses weapon range / weapon strike, or should it require both?  Of course, staying true to vanilla (only when ATTACK or CHARGE) is an option as well.  (Be as precise as possible.)
2) Healing Spell: How should it apply if it is both elemental and undead reverse?  In other words, if it hits an undead target that absorbs the element, what should we do?
3) Recoil vs. Drain HP: If I drain the HP of an non-undead target but my spell deals recoil to myself, what applies first?  Or....should I simply sum the two effects and only perform one effect on myself?
Title: Re: Question about Martial Arts/Brawler
Post by: secondadvent on September 23, 2013, 06:43:49 pm
Quote from: formerdeathcorps on September 23, 2013, 04:53:46 pm
2) Healing Spell: How should it apply if it is both elemental and undead reverse?  In other words, if it hits an undead target that absorbs the element, what should we do?


Here's my take on how elemental and undead reversal should work together (this is using example values to show how things would work):

Healing spell:
Resistance = Normal healing/UR damage
Absorb = 150%/-50%
Neutral = 100%
Half = 50%
Null = 0%
Weak = -50%/150%

Healing causes damage to undead by default, but absorbing the element of the healing spell they'd be able to heal a small amount of the spell - absorbing the element cancels the damaging part, leaving the elemental absorption effect. Being weak to the element would cause additional damage due to the base damage from reversed healing and damage from the element itself.

Absorption spell:
Resistance = Normal damage/UR healing
Absorb = -50%/150%
Neutral = 100%
Half = 50%
Null = 0%
Weak = 150%/-50%

If you absorb the element used normally, you'd be able to override the absorb effect of the caster and instead absorb some of their health, while being weak to the element causes them to absorb more from you. Undead would combine the absorb effect from elemental affinity and from being undead to absorb more from the caster, while being weak would cancel out their undead "bonus" and leave them with their weakness, allowing the caster to absorb from the undead.

NOTE: Caster and target of absorption abilities both being undead could have a different effect, possibly reverting to normal absorb effect. Could also allow undead weak to the absorption attack's element to just halve the effect, still causing the undead to absorb from the caster (same goes for normal absorption of the element).


Feel free to hate on this idea, it's just how I see the element and undead reversal working together. I've also been away from this section of Battle.bin for a while, so forgive me if I'm forgetting stuff/derping hard.
Title: Re: Question about Martial Arts/Brawler
Post by: formerdeathcorps on September 24, 2013, 03:09:44 am
SecondAdvent, from your above rules, you seem to be wanting an elemental multiplier to total damage where:
0) Base Multiplier is 1
1) Healing is classified as negative damage
2) Null multipliers Base Mult. by 0.
3) Halve halves Base Mult.
4) UR multiplies Base Mult. by -1 and will always occur before absorb or weak.
5) ABsorb multiplies Base Mult. by -0.5 if DMG > 0 and by 1.5 if DMG < 0.
6) Weak multiplies Base Mult. by -0.5 if DMG < 0 and by 1.5 if DMG > 0.

This all looks reasonable until we have a healing / drain spell on an undead who is both weak to and absorbs an element.  After UR flips the sign, what's next?  Do we always apply absorb first and then weak?  Vice-Versa?  Or do we manipulate the order to always damage the target?  Or should the target always be healed instead?
Title: Re: Question about Martial Arts/Brawler
Post by: secondadvent on September 25, 2013, 03:35:16 am
Quote from: formerdeathcorps on September 24, 2013, 03:09:44 am
This all looks reasonable until we have a healing / drain spell on an undead who is both weak to and absorbs an element.  After UR flips the sign, what's next?  Do we always apply absorb first and then weak?  Vice-Versa?  Or do we manipulate the order to always damage the target?  Or should the target always be healed instead?


The problem is that Absorb and Weak are essentially complete opposites, so combining them is a bit of an oddball (which I forgot, because derpy me didn't think about the two being able to coexist). Some possible outcomes could be:

1). Cancel both and make the resistance Neutral.

Sort of a "can't stack" situation, similar to haste and slow. Would be a way for a person to cancel their weakness by adding absorption equipment (rather than stacking effects), or a way to cancel an enemy's absorb effect by inflicting elemental weakness.

2). Combine them to enhance the effect of Absorb (higher elemental effect due to weakness, but still absorbing).

Since there's already a way to cause reduced absorption (Absorb + Half), this would be a way to potentially boost the Absorb effect (Absorb * 150% or so). Could be overpowered though, but could also be useful on enemy units.

3). Skip checking Weak if the unit has Absorb, since Absorb takes priority (or vice versa).

Not the best solution really, but would allow either the Weak effect or the Absorb effect, but not both. Kind of a way to prevent potential OPness of 2 while still allowing some effect, but I'd rather see one of the other options used.

4). Have the same effect as Absorb + Half, but able to stack with Half (potential quarter absorption).

Another possibility, this time making weakness essentially causing your Absorb "skill" to be reduced due to having lower affinity with the element... or something. Since weakness normally causes additional damage, having it reduce the beneficial side of things (essentially giving or taking 50% depending on the situation) could be a decent solution.


Overall, I think I'd prefer either 1 or 4 as possible solutions, with 1 probably being the easy way out while still having potential tactical use if there's weakness-inducing abilities like Oil, or to neutralize a weakness from one piece of equipment/the character's job with another piece of equipment. There's obviously lots of stuff that could be done with elements, and all of them have their ups and downs, so which one's the "best" is kind of hard to decide. :P
Title: Re: Question about Martial Arts/Brawler
Post by: formerdeathcorps on November 28, 2013, 12:18:31 pm
I'm finally DONE!  ~2.5 KB of code later...



00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000


D4FFBD27
0800B0AF
0C00B1AF
1400B2AF
1800B3AF
1000BFAF
1980123C
D6385396
0680013C
C0981300
21083300
F0EB2124
06003194
04003094
00012232
05004010
982D538E
4421060C
00000000
02000010
00000000
6E21060C
1C00B4AF
79014014
942D548E
F9384292
06000534
0F004430
1B008500
12300000
10180000
0300C014
FFFFC624
03000010
21386002
21388002
1100C014
2800E524
01006130
02002010
42180300
0400A524
04006010
FFFF6324
07006010
0200A494
03000010
0000A694
03000010
2120C000
00000000
23208600
16000010
CE3844A6
10006010
FFFF6324
10006010
FFFF6324
F9FF6010
0E00A490
02394692
FCFFA390
F5FFC014
2120C000
19008300
12200000
64000334
00000000
1B008300
EEFF0010
12200000
ECFF0010
0F00A490
EAFF0010
1000A490
F0004230
82100200
22008392
09000434
1B006400
1580043C
21204400
5871828C
12180000
08004000
04006324
98711580
A0711580
A8711580
B0711580
B8711580
C0711580
C8711580
D0711580
D8711580
E8711580
F0711580
F8711580
00721580
08721580
10721580
1C721580
25000010
01000434
23000010
80000434
21000010
21206000
1F000010
31008492
1D000010
32008492
1B000010
36008492
19000010
37008492
17000010
38008492
02394592
00000000
1300A014
2120A000
11000010
30008492
36008592
0B000010
37008492
09000010
38008592
07000010
36008492
05000010
21286000
03000010
37008492
21286000
38008492
00000000
21208500
42200400
D6384596
1580033C
40280500
21186500
2000B5AF
2400B6AF
006C7594
D03844A6
CE384396
0010B632
0400C012
FA384292
CE3844A6
900163A6
D03842A6
F7384392
F3384592
04394492
0400A230
02004010
25B0C502
25186400
FF17060C
F73943A2
58006192
00200232
10002130
400A0100
24082200
25B0C102
03000332
01000234
22086200
E1002004
02002130
DF002014
C0000132
DD002010
001A0300
000A0100
25B0C302
25B0C102
03002432
1B008010
02008430
0C008010
00000000
8118060C
00000000
0001C132
14002014
00000000
C718060C
00000000
1819060C
00000000
0E000010
00000000
1518060C
00000000
9518060C
00000000
0001C132
07002014
00000000
B318060C
00000000
DB18060C
00000000
3E19060C
00000000
0010C232
04004010
D0384496
CE384396
08000010
21186400
FA384382
00000000
20208300
0200801C
CE384396
01000424
D03844A6
5912060C
CE3843A6
0010C232
05004014
00040532
5A19060C
CE384496
03000010
90016396
90016496
CE384396
0200A010
CE3844A6
541C060C
900163A6
F3384192
90016296
80002130
0F002010
0010C132
90016296
24006392
10270434
19004300
12100000
24008392
00000000
19004300
12100000
00000000
00000000
1B004400
12100000
900162A6
07002010
21184000
441D060C
00000000
8C016292
CE384396
86004010
01000234
E803622C
02004014
00000000
E7030324
B41B060C
900163A6
90016296
FF00A332
01006324
19004300
12100000
C2110200
FE1B060C
900162A6
8C016292
00000000
74004010
01000234
90016196
000FA332
0B006010
01000234
8C0182A2
19002300
B1018292
12080000
80004234
B10182A2
90018296
02090100
21104100
900182A6
0001C132
06002010
B1016492
90016296
7F008430
920162A6
02000010
80008434
3F1C060C
B10164A2
0020C132
90016296
92016396
04002010
B1016492
920162A6
900163A6
C0008438
90016296
92016396
0040C132
0D002010
0080C132
C0008530
82300500
04002010
25208600
42100200
04000010
42180300
26208500
900160A6
920160A6
940162A6
960163A6
B10164A2
4000C132
26002010
01000134
90016296
8C0181A2
28006396
94016496
2B086200
02002010
2C006596
21106000
900162A6
2B08A400
02002010
92016396
2020A000
940164A6
90018196
22104300
22104100
05004004
B1018192
920182A6
7F002130
05000010
40002134
22100200
900182A6
BF002130
80002134
96016596
B1016692
960184A6
3000C630
0400C010
940185A6
3000C638
CF002130
25082600
B10181A2
04000132
08002010
00000000
C388000C
00000000
21086002
721E060C
00E0A332
8E1D060C
00000000
FB384292
00000000
8000412C
05002010
00000000
AD1F060C
00000000
07000010
00000000
3021060C
00000000
03004014
00000000
B91D060C
00000000
2000B58F
2400B68F
0800B08F
0C00B18F
1400B28F
1000BF8F
1800B38F
1C00B48F
0800E003
2C00BD27


421B0300
06000434
04008314
19004300
12180000
C21B0300
01006324
05000234
1A002424
00008590
06004314
FF000634
0400A610
04000634
04304600
11000010
A50126A0
FFFF4224
03004628
F5FFC010
01008424
0E004010
00008590
F9FF4314
FF000634
0500A614
04000634
02008590
FF000634
F3FFA610
01000634
04304600
A50126A0
8F0125A0
0800E003
21100000
FE000234
A50122A0
0800E003
8F0120A0


005C0508
00000000


1980033C
902D638C
00000000
04006294
00000000
40100200
040062A4


[0x00157000] addiu r29,r29,-0x002c    #Prepare the stack
[0x00157004] sw r16,0x0008(r29)
[0x00157008] sw r17,0x000c(r29)
[0x0015700c] sw r18,0x0014(r29)
[0x00157010] sw r19,0x0018(r29)
[0x00157014] sw r31,0x0010(r29)
[0x00157018] lui r18,0x8019
[0x0015701c] lhu r19,0x38d6(r18)       #Get ability ID
[0x00157020] lui r1,0x8006
[0x00157024] sll r19,r19,0x03
[0x00157028] addu r1,r1,r19
[0x0015702c] addiu r1,r1,-0x1410         #Get corresponding AI bytes
[0x00157030] lhu r17,0x0006(r1)           #AI byte 6 (Longbow Attack Column) + byte 7 (Used by AI to Evade by Motion)
[0x00157034] lhu r16,0x0004(r1)           #AI byte 4 (HP Column) + byte 5 (Random hits Column)
[0x00157038] andi r2,r17,0x0100
[0x0015703c] beq r2,r0,0x00157054        #Branch if MEV
[0x00157040] lw r19,0x2d98(r18)            #r19 = Target RAM offset
[0x00157044] jal 0x00188510                 #PEV routine
[0x00157048] nop
[0x0015704c] beq r0,r0,0x00157058
[0x00157050] nop
[0x00157054] jal 0x001885b8                #MEV routine
[0x00157058] sw r20,0x001c(r29)
[0x0015705c] bne r2,r0,0x00157644       #If Evaded, GOTO END
[0x00157060] lw r20,0x2d94(r18)            #r20 = Caster RAM offset
[0x00157064] lbu r2,0x38f9(r18)            #Get X Byte
[0x00157068] ori r5,r0,0x0006
[0x0015706c] andi r4,r2,0x000f             #r4 = X's lower 4 bits
[0x00157070] divu r4,r5
[0x00157074] mflo r6                          #r6 = r4 / 6
[0x00157078] mfhi r3                           #r3 = r4 % 6
[0x0015707c] bne r6,r0,0x0015708c     
[0x00157080] addiu r6,r6,-0x0001
[0x00157084] beq r0,r0,0x00157094        #If r4 is from 0-5, r7 = Target RAM offset and GOTO HERE
[0x00157088] addu r7,r19,r0
[0x0015708c] addu r7,r20,r0                  #ELSE, r7 = Caster RAM offset
[0x00157090] bne r6,r0,0x001570d8         #If r4 is 12+, get non-HP/MP stats
[0x00157094] addiu r5,r7,0x0028            #HERE: r5 = r7 + 0x0028 (the curHP offset of either target or caster)
[0x00157098] andi r1,r3,0x0001               
[0x0015709c] beq r1,r0,0x001570a8         #ELSE, if r4 is even, r5 remains at HP offset
[0x001570a0] srl r3,r3,0x01
[0x001570a4] addiu r5,r5,0x0004              #ELSE (if r4 is odd), r5 = r7 + 0x002c (the curMP offset)
[0x001570a8] beq r3,r0,0x001570bc          #If r4 % 6 = 0 or 1, then get curStat
[0x001570ac] addiu r3,r3,-0x0001
[0x001570b0] beq r3,r0,0x001570d0          #If r4 % 6 = 2 or 3, then get maxStat
[0x001570b4] lhu r4,0x0002(r5)
[0x001570b8] beq r0,r0,0x001570c8          #ELSE (if r4 % 6 = 4 or 5), then get max - curStat
[0x001570bc] lhu r6,0x0000(r5)
[0x001570c0] beq r0,r0,0x001570d0
[0x001570c4] addu r4,r6,r0
[0x001570c8] nop
[0x001570cc] subu r4,r4,r6
[0x001570d0] beq r0,r0,0x0015712c                #REBRANCH: Store r4 as XA2, GOTO GetXA1
[0x001570d4] sh r4,0x38ce(r18)
[0x001570d8] beq r3,r0,0x0015711c                #If r4 = 12, then r4 = MA, GOTO REBRANCH
[0x001570dc] addiu r3,r3,-0x0001
[0x001570e0] beq r3,r0,0x00157124                #If r4 = 13, then r4 = SP, GOTO REBRANCH
[0x001570e4] addiu r3,r3,-0x0001
[0x001570e8] beq r3,r0,0x001570d0                #If r4 = 14, then r4 = PA, GOTO REBRANCH
[0x001570ec] lbu r4,0x000e(r5)
[0x001570f0] lbu r6,0x3902(r18)                      #ELSE (if r4 = 15), then WP
[0x001570f4] lbu r3,-0x0004(r5)                      # r3 = Brave
[0x001570f8] bne r6,r0,0x001570d0
[0x001570fc] addu r4,r6,r0
[0x00157100] multu r4,r3                                #If WP = 0....
[0x00157104] mflo r4
[0x00157108] ori r3,r0,0x0064
[0x0015710c] nop
[0x00157110] divu r4,r3
[0x00157114] beq r0,r0,0x001570d0
[0x00157118] mflo r4                                    #r4 = PA * Br%, GOTO REBRANCH
[0x0015711c] beq r0,r0,0x001570d0
[0x00157120] lbu r4,0x000f(r5)
[0x00157124] beq r0,r0,0x001570d0
[0x00157128] lbu r4,0x0010(r5)
[0x0015712c] andi r2,r2,0x00f0                         #GetXA1: r2 = Upper 4 bits of X
[0x00157130] srl r2,r2,0x02                                #r2 is being modified into a form acceptable to the following table reader.
[0x00157134] lbu r3,0x0022(r20)
[0x00157138] ori r4,r0,0x0009
[0x0015713c] divu r3,r4
[0x00157140] lui r4,0x8015
[0x00157144] addu r4,r2,r4
[0x00157148] lw r2,0x7158(r4)                           #Read the entry as given by below offset table.
[0x0015714c] mflo r3
[0x00157150] jr r2
[0x00157154] addiu r3,r3,0x0004                        #r3 = (LVL / 9) + 4
[0x00157158] lb r21,0x7198(r0)
[0x0015715c] lb r21,0x71a0(r0)
[0x00157160] lb r21,0x71a8(r0)
[0x00157164] lb r21,0x71b0(r0)
[0x00157168] lb r21,0x71b8(r0)
[0x0015716c] lb r21,0x71c0(r0)
[0x00157170] lb r21,0x71c8(r0)
[0x00157174] lb r21,0x71d0(r0)
[0x00157178] lb r21,0x71d8(r0)
[0x0015717c] lb r21,0x71e8(r0)
[0x00157180] lb r21,0x71f0(r0)
[0x00157184] lb r21,0x71f8(r0)
[0x00157188] lb r21,0x7200(r0)
[0x0015718c] lb r21,0x7208(r0)
[0x00157190] lb r21,0x7210(r0)
[0x00157194] lb r21,0x721c(r0)
[0x00157198] beq r0,r0,0x00157230                  #Option 0, r4 = 1
[0x0015719c] ori r4,r0,0x0001
[0x001571a0] beq r0,r0,0x00157230                  #Option 1, r4 = 128
[0x001571a4] ori r4,r0,0x0080
[0x001571a8] beq r0,r0,0x00157230                  #Option 2, r4 = r3 = (LVL / 9) + 4
[0x001571ac] addu r4,r3,r0
[0x001571b0] beq r0,r0,0x00157230                  #Option 3, r4 = Naked MA
[0x001571b4] lbu r4,0x0031(r20)
[0x001571b8] beq r0,r0,0x00157230                  #Option 4, r4 = Naked SP                 
[0x001571bc] lbu r4,0x0032(r20)
[0x001571c0] beq r0,r0,0x00157230                  #Option 5, r4 = PA
[0x001571c4] lbu r4,0x0036(r20)
[0x001571c8] beq r0,r0,0x00157230                  #Option 6, r4 = MA
[0x001571cc] lbu r4,0x0037(r20)
[0x001571d0] beq r0,r0,0x00157230                  #Option 7, r4 = SP
[0x001571d4] lbu r4,0x0038(r20)
[0x001571d8] lbu r5,0x3902(r18)                       #Option 8, r4 = WP
[0x001571dc] nop
[0x001571e0] bne r5,r0,0x00157230
[0x001571e4] addu r4,r5,r0
[0x001571e8] beq r0,r0,0x00157230                  #If WP = 0 or Option 9, r4 = Naked PA
[0x001571ec] lbu r4,0x0030(r20)
[0x001571f0] lbu r5,0x0036(r20)                       
[0x001571f4] beq r0,r0,0x00157224                       #Option 10, r4 = avg(PA, MA)
[0x001571f8] lbu r4,0x0037(r20)
[0x001571fc] beq r0,r0,0x00157224                       #Option 11, r4 = avg(MA, SP)
[0x00157200] lbu r5,0x0038(r20)
[0x00157204] beq r0,r0,0x00157224                       #Option 12, r4 = avg(SP, PA)
[0x00157208] lbu r4,0x0036(r20)
[0x0015720c] beq r0,r0,0x00157224                       #Option 13, r4 = avg(PA, (LVL / 9) + 4)
[0x00157210] addu r5,r3,r0
[0x00157214] beq r0,r0,0x00157224                       #Option 14, r4 = avg((LVL / 9) + 4, MA)
[0x00157218] lbu r4,0x0037(r20)
[0x0015721c] addu r5,r3,r0                                  #Option 15, r4 = avg((LVL / 9) + 4, SP)
[0x00157220] lbu r4,0x0038(r20)
[0x00157224] nop
[0x00157228] addu r4,r4,r5
[0x0015722c] srl r4,r4,0x01                                 #Actually does the averaging
[0x00157230] lhu r5,0x38d6(r18)
[0x00157234] lui r3,0x8015
[0x00157238] sll r5,r5,0x01
[0x0015723c] addu r3,r3,r5                                 #Get offset of the corresponding D and O bytes
[0x00157240] sw r21,0x0020(r29)
[0x00157244] sw r22,0x0024(r29)
[0x00157248] lhu r21,0x6c00(r3)                         #r21 = lower byte (D) + upper byte (O)
[0x0015724c] sh r4,0x38d0(r18)                          #Store r4 as XA1
[0x00157250] lhu r3,0x38ce(r18)                         #r3 = XA2
[0x00157254] andi r22,r21,0x1000                        #r22 = storage halfword of useful stuff
[0x00157258] beq r22,r0,0x0015726c                    #If using first formula (see diagram below), GOTO NORMAL
[0x0015725c] lbu r2,0x38fa(r18)                            #If using second formula....
[0x00157260] sh r4,0x38ce(r18)                         #r4 = XA2
[0x00157264] sh r3,0x0190(r19)                          #r3 = Damage (this is temporary)
[0x00157268] sh r2,0x38d0(r18)                          #Y = XA1
[0x0015726c] lbu r3,0x38f7(r18)                          #r3 = Ability Element
[0x00157270] lbu r5,0x38f3(r18)                          #r5 = Weapon Strike ability flag column
[0x00157274] lbu r4,0x3904(r18)                         #r4 = Weapon Element
[0x00157278] andi r2,r5,0x0004
[0x0015727c] beq r2,r0,0x00157288                     #If Weapon Strike isn't flagged, GOTO Elemental Strengthen
[0x00157280] or r22,r22,r5                                  #r22 stores r5 as the lower byte.
[0x00157284] or r3,r3,r4                                     #ELSE, ability element = ability element + weapon element
[0x00157288] jal 0x00185ffc                                #Elemental Strengthen:
[0x0015728c] sb r3,0x39f7(r18)                          #Store ability element
[0x00157290] lbu r1,0x0058(r19)
[0x00157294] andi r2,r16,0x2000                         
[0x00157298] andi r1,r1,0x0010                         
[0x0015729c] sll r1,r1,0x09
[0x001572a0] and r1,r1,r2                                 #r1 is non-zero only if target is undead and undead reverse is flagged
[0x001572a4] or r22,r22,r1                                #Store this bit in r22
[0x001572a8] andi r3,r16,0x0003
[0x001572ac] ori r2,r0,0x0001
[0x001572b0] sub r1,r3,r2
[0x001572b4] bltz r1,0x0015763c                        #If neither target enemies or allies is flagged, GOTO END and return r2 = 1
[0x001572b8] andi r1,r1,0x0002                           
[0x001572bc] bne r1,r0,0x0015763c                    #If both target enemies and allies are flagged, GOTO END and return r2 = 1
[0x001572c0] andi r1,r16,0x00c0
[0x001572c4] beq r1,r0,0x0015763c                    #If neither HP or MP is flagged, GOTO END and return r2 = 1
[0x001572c8] sll r3,r3,0x08
[0x001572cc] sll r1,r1,0x08
[0x001572d0] or r22,r22,r3                                 #Store Target Enemies / Allies flag condition into r22
[0x001572d4] or r22,r22,r1                                  #Store HP / MP flag condition into r22....r22 now looks like...
Upper Byte (r22)
80 - HP
40 - MP
20 - Undead Reverse True AND Target is Undead
10 - Second Formula Toggle
8 -
4 -
2 - Target Enemies
1 - Target Allies
Lower Byte (r22)
80 - Affected by Brave
40 - Drain
20 - Ranged Weapon
10 - Vertical Fixed
8 - Vertical Tolerance
4 - Weapon Strike
2 - Auto
1 - Can't Target Self
[0x001572d8] andi r4,r17,0x0003
[0x001572dc] beq r4,r0,0x0015734c                     #If MADEF (Magical Attack) and DEFUP (Physical Attack) are both unflagged, GOTO Add Y
[0x001572e0] andi r4,r4,0x0002
[0x001572e4] beq r4,r0,0x00157318                      #ELSE, if not MADEF (DEFUP / Physical Attack), GOTO Physical
[0x001572e8] nop
[0x001572ec] jal 0x00186204                              #ELSE, if MADEF / Magical Attack, run MATKUP
[0x001572f0] nop
[0x001572f4] andi r1,r22,0x0100
[0x001572f8] bne r1,r0,0x0015734c                          #If healing, GOTO Zodiac Compats
[0x001572fc] nop
[0x00157300] jal 0x0018631c                                #MADEF
[0x00157304] nop
[0x00157308] jal 0x00186460                               #Magical Status Modifiers
[0x0015730c] nop
[0x00157310] beq r0,r0,0x0015734c                      #GOTO Zodiac Compats
[0x00157314] nop
[0x00157318] jal 0x00186054                                #Physical: ATKUP/Martial Arts/2H Routine
[0x0015731c] nop
[0x00157320] jal 0x00186254                              #Berserk / Frog check
[0x00157324] nop
[0x00157328] andi r1,r22,0x0100
[0x0015732c] bne r1,r0,0x0015734c                    #If healing, GOTO Zodiac Compats
[0x00157330] nop
[0x00157334] jal 0x001862cc                            #DEFUP
[0x00157338] nop
[0x0015733c] jal 0x0018636c                            #Physical Status Modifiers
[0x00157340] nop
[0x00157344] jal 0x001864f8                                #Critical Hit
[0x00157348] nop
[0x0015734c] andi r2,r22,0x1000                       #Add Y:
[0x00157350] beq r2,r0,0x00157364                  #Branch to Signed Y if using first formula
[0x00157354] lhu r4,0x38d0(r18)                     #r4 = XA1
[0x00157358] lhu r3,0x38ce(r18)
[0x0015735c] beq r0,r0,0x00157380                 #ELSE (if using second formula), XA2 = XA1 (originally Y) + XA2 (originally XA1), GOTO Zodiac
[0x00157360] addu r3,r3,r4
[0x00157364] lb r3,0x38fa(r18)                       #Signed Y:
[0x00157368] nop
[0x0015736c] add r4,r4,r3                               #r4 = r4 + r3 (signed addition)
[0x00157370] bgtz r4,0x0015737c
[0x00157374] lhu r3,0x38ce(r18)                     #For consistency reasons, r3 = XA2 (but this code is only reachable if first formula)
[0x00157378] addiu r4,r0,0x0001                     #If r4 is negative, set r4 to 1
[0x0015737c] sh r4,0x38d0(r18)                       #Store r4 as XA1 (not affected by Zodiac compat)
[0x00157380] jal 0x00184964                           #Zodiac:
[0x00157384] sh r3,0x38ce(r18)                        #Store r3 as XA2 (affected by Zodiac Compat)
[0x00157388] andi r2,r22,0x1000
[0x0015738c] bne r2,r0,0x001573a4                   #GOTO REORDER if second formula is used
[0x00157390] andi r5,r16,0x0400                       
[0x00157394] jal 0x00186568                             #If first formula, Damage = XA1 * XA2 (doesn't use r4 or r5)
[0x00157398] lhu r4,0x38ce(r18)                        #For consistency reasons, r4 = XA2       
[0x0015739c] beq r0,r0,0x001573ac                   #GOTO Faith Check
[0x001573a0] lhu r3,0x0190(r19)                        #For consistency reasons, r3 = DMG
[0x001573a4] lhu r4,0x0190(r19)                       #REORDER (if second formula): r4 = DMG (originally XA2)
[0x001573a8] lhu r3,0x38ce(r18)                           r3 = XA2 (the thing modded by Zodiac Compat above)
[0x001573ac] beq r5,r0,0x001573b8                   #Faith Check: if affected by Faith is unchecked, SKIP Faith Routine
[0x001573b0] sh r4,0x38ce(r18)                        #Store r4 as XA2 (unchanged by Faith Routine)
[0x001573b4] jal 0x00187150                             #Faith Routine
[0x001573b8] sh r3,0x0190(r19)                        #Store r3 as DMG (changed by Faith Routine)
[0x001573bc] lbu r1,0x38f3(r18)
[0x001573c0] lhu r2,0x0190(r19)                       #r2 = DMG
[0x001573c4] andi r1,r1,0x0080
[0x001573c8] beq r1,r0,0x00157408                   #GOTO TEST, if Affected by Brave isn't checked
[0x001573cc] andi r1,r22,0x1000                       
[0x001573d0] lhu r2,0x0190(r19)                       #ELSE (if Aff. by Brave is checked)...
[0x001573d4] lbu r3,0x0024(r19)
[0x001573d8] ori r4,r0,0x2710
[0x001573dc] multu r2,r3
[0x001573e0] mflo r2
[0x001573e4] lbu r3,0x0024(r20)
[0x001573e8] nop
[0x001573ec] multu r2,r3
[0x001573f0] mflo r2
[0x001573f4] nop
[0x001573f8] nop
[0x001573fc] divu r2,r4
[0x00157400] mflo r2
[0x00157404] sh r2,0x0190(r19)                 #DMG = DMG * CasBr% * TarBr%
[0x00157408] beq r1,r0,0x00157428            #TEST: GOTO DMGCHECK if first formula
[0x0015740c] addu r3,r2,r0                        #r3 = DMG
[0x00157410] jal 0x00187510                      #ELSE (if second formula), Hit% routine
[0x00157414] nop
[0x00157418] lbu r2,0x018c(r19)
[0x0015741c] lhu r3,0x38ce(r18)                  #r3 = XA2 (Originally XA2 as well)
[0x00157420] beq r2,r0,0x0015763c             #GOTO END if miss and return r2 = 1
[0x00157424] ori r2,r0,0x0001
[0x00157428] sltiu r2,r3,0x03e8                  #DMGCHECK:
[0x0015742c] bne r2,r0,0x00157438
[0x00157430] nop
[0x00157434] addiu r3,r0,0x03e7                #If r3 > 999, DMG is set to 999.
[0x00157438] jal 0x00186ed0                     #Weather
[0x0015743c] sh r3,0x0190(r19)                 #Store DMG
[0x00157440] lhu r2,0x0190(r19)                 #r2 = DMG
[0x00157444] andi r3,r21,0x00ff
[0x00157448] addiu r3,r3,0x0001                 #r3 = D+1
[0x0015744c] multu r2,r3
[0x00157450] mflo r2
[0x00157454] srl r2,r2,0x07
[0x00157458] jal 0x00186ff8                        #Elemental Routine (includes float, a fixed version of oil, and others)
[0x0015745c] sh r2,0x0190(r19)                  #Store r2 (old DMG) * r3 (D+1) / 128 as new DMG (this fixes the % HP DMG issue)
[0x00157460] lbu r2,0x018c(r19)
[0x00157464] nop
[0x00157468] beq r2,r0,0x0015763c             #GOTO END and return r2 = 1 if Elemental Null
[0x0015746c] ori r2,r0,0x0001
[0x00157470] lhu r1,0x0190(r19)                 #ELSE (if not nulled), r1 = DMG to target, r3 = Lower 4 bits (Box 3 in the diagram) of O Byte
[0x00157474] andi r3,r21,0x0f00
[0x00157478] beq r3,r0,0x001574a8            #If r3 = 0, SKIP Recoil
[0x0015747c] ori r2,r0,0x0001
[0x00157480] sb r2,0x018c(r20)               #Hit Caster
[0x00157484] multu r1,r3
[0x00157488] lbu r2,0x01b1(r20)
[0x0015748c] mflo r1
[0x00157490] ori r2,r2,0x0080
[0x00157494] sb r2,0x01b1(r20)                #Inflict HP DMG to Caster
[0x00157498] lhu r2,0x0190(r20)               #r2 = DMG to self (a necessary check if the target = caster)
[0x0015749c] srl r1,r1,0x04                      #r1 = DMG to target * Box 3 (see diagram) / 16
[0x001574a0] addu r2,r2,r1
[0x001574a4] sh r2,0x0190(r20)               # DMG to self = r2 + r1
[0x001574a8] andi r1,r22,0x0100
[0x001574ac] beq r1,r0,0x001574c8          #GOTO Elemental Absorb if Target Allies isn't flagged
[0x001574b0] lbu r4,0x01b1(r19)               #r4 = Target DMG display type byte
[0x001574b4] lhu r2,0x0190(r19)              #ELSE (if Target Allies is flagged), r2 = HP DMG to target
[0x001574b8] andi r4,r4,0x007f                #r4 no longer has HP damage bit
[0x001574bc] sh r2,0x0192(r19)               #Store r2 (formerly HP DMG) as HP Healing
[0x001574c0] beq r0,r0,0x001574cc          #SKIP Elemental Absorb but r4 now contains HP healing bit
[0x001574c4] ori r4,r4,0x0040
[0x001574c8] jal 0x001870fc                   #Elemental Absorb
[0x001574cc] sb r4,0x01b1(r19)               #Store r4 as Target DMG display byte                 
[0x001574d0] andi r1,r22,0x2000
[0x001574d4] lhu r2,0x0190(r19)              #r2 = Tar HP DMG
[0x001574d8] lhu r3,0x0192(r19)              #r3 = Tar HP Heal
[0x001574dc] beq r1,r0,0x001574f0          #SKIP if not undead reverse AND target undead
[0x001574e0] lbu r4,0x01b1(r19)             #r4 = Tar DMG display byte
[0x001574e4] sh r2,0x0192(r19)              #Else (if conditions are right), store r2 as Heal
[0x001574e8] sh r3,0x0190(r19)               #Store r3 as DMG (I don't know which halfword contains a non-zero value)
[0x001574ec] xori r4,r4,0x00c0                 #Invert the upper two bits of r4
[0x001574f0] lhu r2,0x0190(r19)              #r2 = Tar HP DMG (have to reload because they may have been modified by above)
[0x001574f4] lhu r3,0x0192(r19)              #r3 = Tar HP Heal (same reason)
[0x001574f8] andi r1,r22,0x4000
[0x001574fc] beq r1,r0,0x00157534         #If MP is not flagged, GOTO PUREHPDMG
[0x00157500] andi r1,r22,0x8000
[0x00157504] andi r5,r4,0x00c0              #r5 = HP DMG / HEal flags on r4
[0x00157508] srl r6,r5,0x02                    #r6 = r5 / 4 (i.e. the position of the HP DMG / Heal flags are now translated into MP DMG / Heal)
[0x0015750c] beq r1,r0,0x00157520        #If HP is not flagged, GOTO PUREMPDMG
[0x00157510] or r4,r4,r6                        #r4 = HP DMG / HEal Flags + MP DMG / Heal flags set the exact same way as the HP flags
[0x00157514] srl r2,r2,0x01                   #ELSE (if HP and MP are both flagged)...
[0x00157518] beq r0,r0,0x0015752c        #Store MP DMG / healing as half of HP
[0x0015751c] srl r3,r3,0x01
[0x00157520] xor r4,r4,r5                   #PUREMPDMG: Remove the HP DMG / Heal flags
[0x00157524] sh r0,0x0190(r19)           #Set HP DMG / Healing to 0
[0x00157528] sh r0,0x0192(r19)
[0x0015752c] sh r2,0x0194(r19)           #Store MP DMG / Healing
[0x00157530] sh r3,0x0196(r19)
[0x00157534] sb r4,0x01b1(r19)           #PUREHPDMG: Store r4 as Tar DMG Display Byte
[0x00157538] andi r1,r22,0x0040
[0x0015753c] beq r1,r0,0x001575d8         #GOTO BRKCHK if Drain isn't flagged
[0x00157540] ori r1,r0,0x0001
[0x00157544] lhu r2,0x0190(r19)
[0x00157548] sb r1,0x018c(r20)               #ELSE (if drain is flagged), hit self
[0x0015754c] lhu r3,0x0028(r19)
[0x00157550] lhu r4,0x0194(r19)
[0x00157554] sltu r1,r3,r2
[0x00157558] beq r1,r0,0x00157564
[0x0015755c] lhu r5,0x002c(r19)
[0x00157560] addu r2,r3,r0                        #r2 = min{tar curHP, tar HP DMG}
[0x00157564] sh r2,0x0190(r19)                  #Store r2 as tar HP DMG
[0x00157568] sltu r1,r5,r4
[0x0015756c] beq r1,r0,0x00157578
[0x00157570] lhu r3,0x0192(r19)                 #r3 = tar HP Heal
[0x00157574] add r4,r5,r0                         #r4 = min{tar curMP, tar MP DMG}
[0x00157578] sh r4,0x0194(r19)                 #Store r4 as tar MP DMG
[0x0015757c] lhu r1,0x0190(r20)                #r1 = cas HP DMG (possible since there exists recoil)
[0x00157580] sub r2,r2,r3                         
[0x00157584] sub r2,r2,r1                          #r2 = r2 - r1 = r2 - (r1 + r3) = Net HP healing on caster
[0x00157588] bltz r2,0x001575a0               #If Net HP Healing is negative, GOTO SETDMG
[0x0015758c] lbu r1,0x01b1(r20)                #r1 = Cas DMG display byte
[0x00157590] sh r2,0x0192(r20)                 #ELSE (Net HP Healing is non-negative), store r2 as Self HP Heal
[0x00157594] andi r1,r1,0x007f                   #r1 removes the HP DMG display bit
[0x00157598] beq r0,r0,0x001575b0            #GOTO MPDRAINCALC, r1 gains the HP HEAL display bit
[0x0015759c] ori r1,r1,0x0040
[0x001575a0] sub r2,r0,r2                        #SETDMG
[0x001575a4] sh r2,0x0190(r20)                #Store |r2| as Cas HP DMG
[0x001575a8] andi r1,r1,0x00bf                 #r1 removes the HP Heal Display bit
[0x001575ac] ori r1,r1,0x0080                   #r1 gains the HP DMG Display bit
[0x001575b0] lhu r5,0x0196(r19)               #MPDRAINCALC: r5 = tar MP HEAL
[0x001575b4] lbu r6,0x01b1(r19)                #r6 = tar DMG display byte
[0x001575b8] sh r4,0x0196(r20)                #STore r4 = min{tar MP DMG, tar curMP} as Cas MP HEAL
[0x001575bc] andi r6,r6,0x0030                 #r6 = tar MP Display bits
[0x001575c0] beq r6,r0,0x001575d4           #If no tar MP DMG / HEAL, GOTO STORECASDISPLAY, STORE r5 as cas MP DMG
[0x001575c4] sh r5,0x0194(r20)               
[0x001575c8] xori r6,r6,0x0030                  #Invert r6 tar MP Display bits
[0x001575cc] andi r1,r1,0x00cf                  #Remove r1 cas MP Display bits
[0x001575d0] or r1,r1,r6                           #Merge r6's bits with r1's
[0x001575d4] sb r1,0x01b1(r20)                 #STORECASDISPLAY: Store r1 as Cas DMG display byte
[0x001575d8] andi r1,r16,0x0004                #BRKCHK:
[0x001575dc] beq r1,r0,0x00157600            #SKIP BREAK if Unequip is not flagged
[0x001575e0] nop
[0x001575e4] jal 0x0002230c                     #Get RN as r2
[0x001575e8] nop
[0x001575ec] addu r1,r19,r0                      #r1 = Tar RAM Offset
[0x001575f0] jal 0x001879c8                      #Break Gear
[0x001575f4] andi r3,r21,0xe000                 #r3 = O Byte-Box 1 (see diagram below)
[0x001575f8] jal 0x00187638                      #Maintenance
[0x001575fc] nop
[0x00157600] lbu r2,0x38fb(r18)                 #r2 = Inflict Byte
[0x00157604] nop
[0x00157608] sltiu r1,r2,0x0080
[0x0015760c] beq r1,r0,0x00157624              #If r2 is at least 0x80, GOTO SPLPRCPREP
[0x00157610] nop
[0x00157614] jal 0x00187eb4                        #Status Proc---like Formula 2D, All or Nothing is 100%
[0x00157618] nop
[0x0015761c] beq r0,r0,0x0015763c              #GOTO END
[0x00157620] nop
[0x00157624] jal 0x001884c0                       #SPLPRCPREP: 19% chance to inflict...
[0x00157628] nop
[0x0015762c] bne r2,r0,0x0015763c              #If RN roll failed, GOTO END
[0x00157630] nop
[0x00157634] jal 0x001876e4                       #Spell Proc
[0x00157638] nop
[0x0015763c] lw r21,0x0020(r29)
[0x00157640] lw r22,0x0024(r29)
[0x00157644] lw r16,0x0008(r29)
[0x00157648] lw r17,0x000c(r29)
[0x0015764c] lw r18,0x0014(r29)
[0x00157650] lw r31,0x0010(r29)
[0x00157654] lw r19,0x0018(r29)
[0x00157658] lw r20,0x001c(r29)
[0x0015765c] jr r31
[0x00157660] addiu r29,r29,0x002c



Limitations:
1) Drain or Recoil with AoE AND evadable or self-damage or healing creates unintuitive behavior.  In particular, I didn't check the cases where a drain HP attack is cast on self + recoil.
2) 2H and martial arts will apply as long as damage is flagged as physical.  I can make a version where 2H is never applied to physical damage OR a version where 2H only applies to weapon strike / weapon ranged attacks but NOT one where it corresponds only to WP in the formula without serious rewriting of this code's IF / JUMP statements (which is a headache as is).
3) Nothing SA proposed above was coded because I wanted to get the original Square behavior down first.  All the things he proposed are more complicated and I'll get to it when I'm more awake.
4) Currently conflicts with almost every other ASM hack in terms of Kanji space.  Sorry, will fix later.
5) Jack of All Trade's proposal for hand slot break was not coded, but it's on the TODO list.
6) Does not address the +Stat formulas (that is next) or pure % to cause status formulas.  Also, % to cause damage may display totally wrong accuracies.
7) Does not support formulas taking both physical and magical multipliers, though I probably don't want to do this.

Formula:
[(STAT1 +/- C) * STAT2 * (D + 1) / 128]
OR
Accuracy = (STAT1 + C) * (Br or Fa)%
Effect = [STAT2 * (D + 1) / 128]
Built-IN ASMs:
Oil Fix
If Weapon Strike, then Ability Element = Ability Element + Weapon Element
If DMG / Heal deals X% of tar/cas|cur/max|HP/MP, then pre-elemental DMG / Heal caps at min{999 * X%, tar/cas|cur/max|HP/MP * X%}
Optional Selections:
* CasBr% * TarBr%
* CasFa% * TarFa%
* Physical Multipliers
* Magical Multipliers
Proc Spell (ID Range 0x80 - 0xFF)
Proc Status Proc (ID Range 0x00-0x7F)
Break Target Gear (Random, Head, Armor, Accessory, WPN, Shield)
Healing
Drain
Undead Reverse
P or M-EV
Recoil

Instructions:
See attachment...it should all be self-explanatory except:
1) Flags with black dots means they now have actual effects on damage (and not just for the AI)
2) E means if flagged, element = ability element + weapon element.
3) If you see two of the same letter next to 2+ different flags, that means all related flags need to be flagged for the effect to work.
4) H+ means HP healing, H- means HP damage, M+ means MP Healing, M- means MP damage, HM- means HP / MP damage where MP damage is half of HP damage, HM+ means HP / MP healing where MP healing is half of HP healing.  P means PEV and M means MEV.
5) If you don't have a weapon, XA1 defaults to Naked PA and XA2 defaults to PA * Br%.
6) If you use the first formula, XA2 takes all multipliers (like ATKUP).  If you use the second formula, XA1 does, but the sum takes compat.
7) If you flag healing, reducing multipliers like Shell or DEFUP will be ignored.
Title: Re: Question about Martial Arts/Brawler
Post by: Timbo on November 28, 2013, 04:10:20 pm
So this is a kind of an all in one formula, right? What does this have to do with Martial Arts? Shouldn't this get it's own topic? Also, if it is as useful as it appears to be, shouldn't it be stickied?
Title: Re: Question about Martial Arts/Brawler
Post by: formerdeathcorps on November 28, 2013, 05:36:13 pm
Quote from: Jack of All Trades on November 28, 2013, 04:10:20 pm
So this is a kind of an all in one formula, right? What does this have to do with Martial Arts? Shouldn't this get it's own topic? Also, if it is as useful as it appears to be, shouldn't it be stickied?

In good time, once I get all the bugs out, it will be stickied and merged with my other topics, but as for now...it's just to answer a question.  As for what this has to do with Martial ARts, at the end of Riketz' post, he wanted
Quote
PA*WE+Y formula, possibly even with a negative Y to keep it all in line.

I just did that.

Centralized all this information in this topic (http://ffhacktics.com/smf/index.php?topic=8051.0).