• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
March 19, 2024, 07:16:23 am

News:

Don't be hasty to start your own mod; all our FFT modding projects are greatly understaffed! Find out how you can help in the Recruitment section or our Discord!


ASM Collective BATTLE.BIN Map

Started by formerdeathcorps, January 06, 2011, 05:09:33 am

Vanya

Quote from: formerdeathcorps on January 19, 2011, 06:31:35 am
The upper flag, if flagged, is M-EV and Shell/MADEF.  Otherwise, it defaults to P-EV (works only if evadable is also checked), and will consider Protect/DEFUP/Critical Hits.
The lower flag, if flagged, allows spell procs.  Otherwise, it defaults to status procs.


Alright, just to make sure I get you:
upper flag = treat this as a magic skill. (further referenced as "magic flag")
no upper flag + evadable flag = treat this as physical skill.

If so, then what if I set the magic flag and the evadable flag? What if I set neither?

And because I'm just not sure I'm getting it:
spell procs = cast spell as indexed by 'inflict status'.
status procs = process status as indexed by 'inflict status'.


Quote from: formerdeathcorps on January 19, 2011, 06:31:35 am
Already addressed this with you in iRC, but for anyone who doesn't understand my post:
Stats lowered will be assigned by applying modular arithmetic to the skill numbers.  This means skill numbers {1, 9, 11, 19...} would lower PA, {2, A, 12, 1A...} would lower MA, and so on, through all 8 stats.
Y influences hit rate.  This can be fixed by FFTP.
X (fixable by FFTP) influences decrement/boost.  Numbers that are less than 0x80 decrement by X.  Numbers that are higher than 0x80 boost by the amount X - 0x80.  Maintenance will void status if X < 0x80.
The status checked by hit rate is fixed and will be determined by the formula.  Since there are lots of formulas that boost/lower stats, we can easily spare 9 of them to check for ({PA, MA, SP, 0} + X)*{Faith, 1} OR (100%).  This means that we should be able to free up formula numbers that are usable for totally new formulas (yes, I'll take suggestions for those now).


That's pretty neat, but wont it require that certain abilities be swapped around to new slots? I imagine that they aren't currently sitting in places that would allow them to keep the stat they're supposed to be modding. Also, what about the 2 abilities that mod PA, MA, SP & Brave; how will these be treated?

And lastly, will X now always be signed or is that just for formulas that mod a stat?
  • Modding version: Other/Unknown
¯\(°_0)/¯

RavenOfRazgriz

I haven't been able to catch you on IRC, but I've been meaning to ask - now that I know what you're doing, is there a reason to modularly divide by Ability Slots to find the breaking stat instead of just dividing the Y value itself similarly to how I suggested before?

The ranges would be more than large enough that no one would be bothered, and anything that removes tying things to ability slots seems better than anything that does, and I can't imagine it taking more space.  This is the same for the X value in the Break, Steal, and Mighty Sword skills.  Is there a reason you can't divide the X (since I assume you'll use X to decide PA/MA/SP etc as you have been) by a certain value for those formulas to determine the slot the ability will affect?  So say, X=1 is PA that affects Weapon, X=9 is PA that affects Shield, etc.  Maintaining the current hardcoding is a horrible idea if it can be avoided because it severely limits skill creation.

If you for some reason cannot by any means whatsoever avoid maintaining the hardcoding, will you at least be doing something similar to your original plan for the stat breaking skills and modularly dividing ability slots by 5 so any of the 3 formula can affect the proper gear when in the proper slot and they're not limited to one instance each?  That's still better than current, but I think using the X value itself for all its worth is infinitely, infinitely superior.  Any time you can break reliance on an ability slot is good because it eases the creative process, and these seem like two huge areas to go for the easing even more than the space if it for some reason hits that point.

If you're looking for custom formula to add for free formula spaces, my first recommendation would be selectable versions of all the weapon formulas in Swordskill form.  2D already covers XA * (WP+Y), so add (XA1+XA2)/2 * (WP+Y), XA * [Br/Fa]/100 * (WP+Y), etc.  For the second, again divide the X to find out what XA2 should be, same with XA * Br/Fa.  You're using them all so exploit all your Xs for all they're worth.

Also, if you make this hack require use of ARH, you can make use of the Requires Sword and Requires Materia Blade flags for your own devices.  Just saying.  Though speaking of requiring other ASMs, you should place your Gun Fix in the post where you mention needing it as well so everything is in one place.

formerdeathcorps

January 23, 2011, 05:21:19 am #22 Last Edit: January 23, 2011, 01:21:37 pm by formerdeathcorps
Quote
upper flag = treat this as a magic skill. (further referenced as "magic flag")
no upper flag + evadable flag = treat this as physical skill.


Upper Flag = Treat as magic.  No Upper Flag = Treat as physical.  If evadable, will reference upper flag to see what type; otherwise, it will ignore evasion altogether.

QuoteThe ranges would be more than large enough that no one would be bothered


That is only true for PA/MA/SP (assuming you're not making a gimmick patch where -All PA is allowed).  Quick (+127 CT), Last Dance (-127 CT), and a boss chicken spell (-40+ brave) would necessitate numbers larger than your suggested range (+/- 16).  Arguably, I could have two different routines for reading, depending on formula used, to differentiate between PA/MA/SP and CT/Br/Fa, but I'd then need two separate read routines, which seems inefficient.

Quotewill you at least be doing something similar to your original plan for the stat breaking skills and modularly dividing ability slots by 5 so any of the 3 formula can affect the proper gear when in the proper slot and they're not limited to one instance each?


Of course, though you'll still need a check on formula number, so you can differentiate between steal and break.  It's just that there's no good reason to use the same routine as stat breaks.  Dance/Sing/Talk Skill's hard-coding will likely be deleted altogether (since most of the effects are covered by either negative status formulas or my PA/MA/SP consolidation), though I'll probably put status guard (finger guard) in the general negative status routine (so it'll block all negative status formulas that don't use faith).

QuoteThough speaking of requiring other ASMs, you should place your Gun Fix in the post where you mention needing it as well so everything is in one place.


I will do that when I'm completely done; right now, I'm using up other people's ASM space for some of my hacks, meaning there will be compatibility problems.  When finished, I'll move my custom routines to the sections I managed to free up.

Quotewe can easily spare 9 of them to check for ({PA, MA, SP, 0} + X)*{Faith, 1} OR (100%)


No longer needed.  If X < 101, it will always be non-faith, if 100 < X < 255, it will always use faith, and if X = 255, it means 100%.  Thus, we really only need 4 such formulas.
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

RavenOfRazgriz

Quote from: formerdeathcorps on January 23, 2011, 05:21:19 amThat is only true for PA/MA/SP (assuming you're not making a gimmick patch where -All PA is allowed).  Quick (+127 CT), Last Dance (-127 CT), and a boss chicken spell (-40+ brave) would necessitate numbers larger than your suggested range (+/- 16).  Arguably, I could have two different routines for reading, depending on formula used, to differentiate between PA/MA/SP and CT/Br/Fa, but I'd then need two separate read routines, which seems inefficient.


You already had separate formulas for + and -, meaning each range would be 32 by default, not 16.  You can easily cut into the space used by PA, MA, SP for more Br, Fa, CT.  I would honestly just remove the ability to "break" max HP and MP altogether for a plethora of reasons and eat that 64 space, so that PA, MA, SP could have ranges something like 10, 10, 10, and the remaining 220/221 or 215/216 could be dedicated to Br/Fa/CT in groups of 75.  Quick and CT00 will need their own formula anyway unless you know how to make a read that causes "Quick" or "CT00" display if the value is +/- 127. Regardless, though, I would remove CT from this formation and add its own two formulas that read whether the number is greater than 126 or not to determine Faith use, adding 1 to the bonus if it's below 127 CT so it can add Quick or CT00 CT.

Tl;dr, read X, 0-9 = PA +1-10, 10-19 MA +1-10, 20-29 SP +1-10, 30-104 Br +1-75, 105-179 Fa +1-17, 180-255 CT +1-75, +/- operation determined by formula is what I'm suggesting based on your old setup.

Quote from: formerdeathcorps on January 23, 2011, 05:21:19 amOf course, though you'll still need a check on formula number, so you can differentiate between steal and break.  It's just that there's no good reason to use the same routine as stat breaks.


I see.  I will always mandate that you should destroy that hardcoding though.  Are you honestly just unable to do it at this time?

One could argue reading by Mod 13 and allowing XA*Y, FA_XA*Y, 100%, XA*WP*Y, Dmg_XA*(WP+Y), , etc all be able to go at any stat or equipment slot would be pretty good from a design standpoint, honestly - being able to make a unit lose 1 PA while doing damage, etc. is a nice added bit of versatility and actually justifies you maintaining the equipment slot hardcoding.  If you want to get messy, you could also consolidate the Mighty Sword formula with 2D, using X to both find the XA and determine whether it reads for Break or not, and extend this to the other damage formulas I suggested, allowing a designer to use any weapon formula to break any piece of gear or any stat without using any additional formula.  Or possibly use one of the Requires Sword or Requires Materia Blade flags to say "this skill breaks shit" if you use my suggestion of requiring ARH to get the flags you need to both go "this skill heals" and "this skill Knocks Back."  Even if you use two separate Mod formulas, the last bit about merging Mighty Sword and 2D for breaking and extending it to more damage formulas seems like a great idea.

Honestly, I know a lot of people use ARH anyway, so even if you don't want them in the general release, finding the best use for the third flag then making "add on" mini-hacks for the other two so people who are using ARH can have some added capability for their now-useless flags.

Quote from: formerdeathcorps on January 23, 2011, 05:21:19 amDance/Sing/Talk Skill's hard-coding will likely be deleted altogether (since most of the effects are covered by either negative status formulas or my PA/MA/SP consolidation), though I'll probably put status guard (finger guard) in the general negative status routine (so it'll block all negative status formulas that don't use faith)


This is good.  I don't like the idea of forcing people to use a "buffed" Finger Guard should they not want it if they want to use this consolidated Formula hack, though.  I'm guessing your use of flags makes my suggestion of X determining XA*Y's evasion useless, so I suggest something else - use two tables for X, where X = 1/2/3/4/etc determines PA/MA/SP/etc, then the next numbers after that determine the same values again but say "This skill can be blocked by Finger Guard."  This allows both XA*Y and Fa_XA*Y to be blocked by it if people want, and allows them to make skills of both that aren't instead of imposing one single form of design on them.  I would also add two optional bits of code in the hack itself that causes something blocked by Finger/Status Guard to have 0% on Sleeping targets and Monster targets, so the user can choose to implement either or both should they want to more faithfully represent Talk Skill in whatever project they're making.

The only concern is that one can't use Finger Guard to block Br/Fa modding on bosses anymore because that hard coding is being rightfully destroyed, which was a great bit of design freedom even if the skill was useless in game for the player.  Is there any plan to remedy this?

Quote from: formerdeathcorps on January 23, 2011, 05:21:19 amNo longer needed.  If X < 101, it will always be non-faith, if 100 < X < 255, it will always use faith, and if X = 255, it means 100%.  Thus, we really only need 4 such formulas.


That still doesn't cover Quick and CT00, juss sayin'.  You should use 0-126 and 127-254.  I like that this only takes 4 formula but dislike that this still forces the use of hardcoding.  I suppose there's not much choice here though, since a gain of all that formula space is pretty awesome.

formerdeathcorps

January 31, 2011, 07:58:52 am #24 Last Edit: January 31, 2011, 08:02:29 am by formerdeathcorps
I'm taking a break from direct formula coding since a lot of my coding inefficiency (i.e. not enough sub-routinization) is coming from Square's inflexible code routines (which then forces me to write to free-space).  Thus, I need to switch focus, at least temporarily, to making more efficient code routines (rather than just jal commands in the formula routines) for various functions, as well as their generalizations that reflect my plans.

In theory, this should also making testing easier since the objects being tested are smaller chunks.

Zodiac Compat. Routine Rewrite:
BATTLE.BIN
0x11D990
52
0x11D99C
4F
0x11DA2C
FF008330
21304000
02000234
0F006210
2110C000
03006228
05004010
01000234
10006210
2110C000
AA120608
00000000
04000234
0D006210
05000234
06006210
2110C000
AA120608
00000000
00021082
A9120608
2110C200
00021042
A9120608
2110C200
A8120608
00021082
2110C000
00021042
2310C200
0000E2A4
1980033C
CE386324
00006284
00000000
0200401C
01000234
000062A4
0008BD27
0800E003
00000000
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

formerdeathcorps

February 05, 2011, 04:31:44 am #25 Last Edit: February 05, 2011, 10:51:27 pm by formerdeathcorps
After weeks of discussion on iRC with Raven, I think I have the final structure hammered out.  Everything I've already posted on this matter will be completely rewritten.

Plans:

1) HP Damage is determined by the AI HP flag.
2) MP Damage is determined by the AI MP flag.
3) Stat +/- is determined by the AI Stats flag.
4) Steal is determined by the AI Unequip flag.
5) Protective effects are considered if the AI Target Enemies flag is checked.
 a) MADEF/Shell are considered if the AI MADEF flag is checked.
 b) DEFUP/Protect are considered if the AI DEF flag is checked.
 c) Checking both means both sets will be considered.  Checking neither means no protective status effects are considered.
6) Protective status effects and damaging counters are ignored if AI Target Allies flag is checked.
 a) Counters like Absorb Used MP will still trigger.
7) AI Undead Reverse now a toggle.  If flagged:
 a) The third blank spot under Abilities (going from top to bottom and then left to right), if flagged, means drain.  If not, means healing.
 b) If AI Undead Reverse is not flagged, the corresponding flag has no meaning.
8) Random Fire is now a toggle.  If flagged:
 a) If AI Random Hits is flagged, use 1-X hits.
 b) IF AI Random Hits is unflagged, use X hits.
9) Faith will be considered if the Unknown under AI Random Hits is flagged (this one means calculate Faith)
10) P-EV will be considered if the Unknown under the above is flagged (this one means calculate P-EV).
 a) The evadable flag will be changed to mean calculate M-EV.  Obviously, if both are flagged, P and M-EV are calculated against an attack.  If neither is flagged, neither will be.
11) The second blank spot under Abilities (going from top to bottom and then left to right) is spell proc if flagged and status proc if not.  This is unchanged from before.
12) Using ARH 2.1, Equip Sword is now redundant.  The slot is now a knockback flag.  The chance used is the same as that of Formula 37.
13) Using ARH 2.1, Equip Materia Blade is now redundant.  The slot is now a recoil flag.  The recoil damage is referenced by X (which is division as a percent of total damage)
14) All formulas will be standardized.  This means X determines XA and Y determines accuracy (on XA + Y) or damage (on XA * Y).
 a) If the lower 3 bits of X is 1, use PA (automatically means ATK UP is referenced)
 b) If the lower 3 bits of X is 2, use MA (automatically means MATK UP is referenced)
 c) If the lower 3 bits of X is 3, use SP (automatically means ATK UP is referenced)
 d) If the lower 3 bits of X is 4, use WP (automatically means ATK UP is referenced)
 e) If the lower 3 bits of X is 5, use W-EV (automatically means ATK UP is referenced)
 f) If the lower 3 bits of X is 6, use S-EV Physical (automatically means ATK UP is referenced)
 g) If the lower 3 bits of X is 7, use Level / 4, with a minimum cap of 5 (automatically means MATK UP is referenced)
 h) On formulas using % damage/recoil, damage/recoil percentage is determined by the upper 5 bits on X.  Essentially the formula is X = [X/8] * 3 + 7.  Y is normal.
 i) Items broken/stolen is determined by the upper 5 bits in X (0x8 = Shield, 0x10 = Head, 0x20 = Armor, 0x40 = Weapon, 0x80 = Accessory).  Y is normal.  Break is true if the upper 5 bits in X are non-zero and Unequip is not flagged.  Steal is true if the upper 5 bits in X are non-zero and Unequip is flagged.  Steal Gil is true (LVL * XA1 gil stolen) is true if the upper 5 bits in X are zero and Unequip is flagged.  Note, this does not stack with formulas using % damage.
 j) Stats +/- is determined by the upper 6 bits in X (0x4 = PA, 0x8 = MA, 0x10 = SP, 0x20 = CT, 0x40 = Br, 0x80 = Fa).  This means that only PA/MA/SP are possible for XA choices.  Y is such that the lower 3 bits on Y determine gradations (0 = +1 PA/MA/SP, +10 CT, +5 Br/Fa; 1 = +2 PA/MA/SP, +20 CT, +10 Br/Fa; 2 = +3 PA/MA/SP, +30 CT, +15 Br/Fa; 3 = +4 PA/MA/SP, +40 CT, +20 Br/Fa; 4 = +5 PA/MA/SP, +50 CT, +30 Br/Fa; 5 = +6 PA/MA/SP, +60 CT, +40 Br/Fa; 6 = +7 PA/MA/SP, +80 CT, +50 Br/Fa; 7 = +8 PA/MA/SP, +127 CT, +60 Br/Fa), the 4th bit determines sign (so 8-15 are the negative versions of the above), while Y = [Y/16] * 16 is the accuracy boost.  This is true only if Stats is flagged.
 k) The upper 5 bits in X determine the cap on the amount of extra hits (up to 31) if Random Fire is flagged.
 l) On formulae using (XA_1 + Y) / 2 * XA_2 or (XA_1 + Y) * XA_2 as damage formulas, or (XA_1 + XA_2 + Y)% as hit formulas, 0-15 on X corresponds to (PA/PA, PA/MA, PA/SP, PA/WP, MA/PA, MA/MA, MA/SP, MA/WP, SP/PA, SP/MA, SP/SP, SP/WP, WP/PA, WP/MA, WP/SP, WP/WP).  The damage/recoil percentage is determined by the upper 4 bits on X and is X = [X/16] * 6 + 4.  The multi-hit cap is also determined by the upper 4 bits (up to 15).  Equipment break will only consider the top 4 bits (notice this still corresponds perfectly to MIGHTY SWORD, which cannot destroy shields...while for BREAK, I will simply divide the upper four bits by two, so accessories can't be broken).
 m) On any formula using (XA + Y)% as hit chance, if Y = 255, it automatically means 100%.  On the stat break formula, if Y > 239, it automatically functions as 100% (meaning that there, the maximum effective Y in the accuracy formula is 224).
 n) It is inadvisable to try to have moves using more than one of recoil, % damage, stat break, item break, multi-hit because they all compete for the same 4-5 upper bits.
15) Undead status now absorbs dark and is weak against holy.  Oil will function correctly (weak: fire) in this hack.
16) Drain is now always reversed against any element's absorption, and cure is always reversed against any element's weakness.  This replaces undead reversal with something far more generic.  Thus, this patch now forces drain to be darkness elemental and curative spells to be holy element.
17) After seeing the exploitative nature of ice ball + concentrate + flame shield + magic ring in the 1.3 AI tournaments (and knowing that similar tricks are possible between oil and flame shields), I'm proposing to make weak override absorb (meaning if you're weak against an element, you cannot be healed by that element).  I'm also likely going to make absorb completely ignore reactions that don't boost evasion (so you can't proc dragon spirit on fire/ice ball healing).
18) Signed loading of HP/MP damage bytes.  Doing this should free up 4 bytes I can use, possibly to assist the AI calculate damage better.  The only downside I can think of is that a 1.3 Utlima can no longer heal for 65535 HP when she eats a crystal, but rather, is forced to heal for half that amount.
19) All formulas that are non-elemental or NS will take elemental and status.
20) The first blank spot under Abilities (going from top to bottom and then left to right), if flagged, means 100% inflict on All or Nothing and 25% on separate.  If unflagged, the vanilla formulas will be observed (25% on everything except Random Fire, which is 6.25%).
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

Vanya

That all sounds fantastic to me. I don't see anything that needs be improved here.
Using the AI flags for referencing ability features is brilliant. Makes me wonder why I didn't think of that... really makes me wonder what the hell Square's PAID, PROFESSIONAL programmers were thinking.
  • Modding version: Other/Unknown
¯\(°_0)/¯

RavenOfRazgriz

February 05, 2011, 01:26:46 pm #27 Last Edit: February 05, 2011, 04:48:41 pm by RavenOfRazgriz
EDIT: 4) How does the game determine Break or Steal?  Look for a specially declared "Steal" formula(e), if true, Steak , else, Break?  Or have you broken my expectations and made Steal applicable to more formulae without telling me?  Actually.  We could have "Break" be the default setting if people choose to use an X of 9+, and override that code if Stats, Unequip, Random Fire, or Recoil.  If Stats is checked, hit stats based on X and Y, Unequip is checked and X is 9+, Steal proper slot(s), if Recoil is checked, Recoil with divisor based on table, if Random Fire is checked, hit randomly based on table.  This makes both Break and Steal completely flexible in addition to everything else, allowing for skills such as "Mug Helmet" that do a small amount of damage in addition to Stealing... or other, far more evil things.  I should've thought just of this during our IRC discussion but I was a bit too sick to think properly, I think.  Doing that also removes the need for an explicit "Steal" formula, saving space and letting Vanilla flavor Thief piggyback on the XA * Y formula like everyone else.

7) You need to force out separate space for each Undead Reverse, Heal, and Drain instead of forcing them to be together.  Vanilla has formula that can heal without Undead Reversal triggering, this hack should too.

14-l) We had agreed that the Mighty Sword being unable to hit Shields if the designer wanted it to was retarded and were going to make every equipment slot reachable by any formula.  Why the fuck did you go back on that?  That's dumb as hell.

15) Should be an optional feature as it deviates from Vanilla, though your hack of Undead Reverse pretty much makes it mandatory.

16) Is dumb, removes utility that existed in the original game, and forces more linear design.  This is why you need separate flags for each Undead Reverse, Heal, and Drain, so that if Undead Reverse, the skill gains that property, else functions as it does in Vanilla. This goes all the way back to my points against 7.  You're forcing certain design schema onto people when you shouldn't, and don't even need to.  You're using XA to determine Treat As Magical and Treat As Physical, two already used flags to determine P-EV and M-EV, and two more already used flags to determine Magic DefendUP and Defense UP.  if I remember correctly, another flag used to be Treat as MP Damage, but we incorporated that into the AI flags too.  Going through FFTP, I see...

Spell Proc Flag
Knockback Flag
Recoil Flag
Undead Reverse's current Heal/Drain flag.
???

So why the separation?  This still doesn't quite fix Drain based skills since they'd still need to be Dark to be Undead Reversed on this schema and some more minor bits of Healing nuance are still lost, but it's still far closer to Vanilla and you can easily check for the Drain flag instead of the Drain Element to reverse it and all should be good.

17) Both halves of that should be optional features of this hack.  It's forcing your own thoughts of game balance onto people else, and in no way has bearing on how the rest of the hack functions.  I say make both halves optional separately because I can easily see people wanting one and not the other - personally, I would want the second but not the first, and I could probably find someone with the opposite opinion in like 5 minutes.

Rest looks about right.  Yes, I'm being a rather picky dick about these things, but I'm still going to mandate until the end of time that if I cannot make the original Vanilla game with no noteworthy functional differences, this isn't good enough because the goal is to add features, not remove them.  Not being able to properly represent Chakra due to your use of the Undead Reverse Flag is a big offender here.  There are other smaller things that I also pointed out and should be easy tweaks.  Some of the most minor ones can't be avoided, but they're at least the most minor of the minor.

EDIT: If you remember my one request for this hack after the initial version is finished, you'll probably anticipate this last thought - but you should take the empty AI flag next to Line of Sight and make it connocate (CasBr + (ZZ))/100 * (TarBr + (ZZ))/100 and slightly edit the Faith input to be (CasFa + (YY))/100 * (TarFa + (YY))/100, where ZZ and YY are bolded portions that can be edited by the end user.  This allows for both modification of the Faith mechanic and builds the somewhat popular Fury directly into this hack in a far more controllable way.  The one I asked you for on IRC was a bit different from what I'm suggesting here (and I'd quite like it for my own work), but adding this to the general release would be amazing and round off the flag use nicely, by allowing the addition of Fury at the choice of the end user, giving Faith a constant at the choice of the end user, removing all NS, Non-Elemental, all hardcoding, better Undead Reverse control, and many other things.

EDIT 2: Vanya, Square didn't have FDC and I both being the stingiest motherfuckers imaginable and wanting to max out versatility in every possible way working for them for the span of about a week's worth of discussion.  We also know what a consistent coding convention is, which also helps a lot.

formerdeathcorps

1) Extra flag, as we discussed today in iRC, will be for setting 100% on all or nothing and 25% on separate (as formula 2D does).
2) Undead Reverse no longer exists except as a toggle.  AS I mentioned, it is now Undead status causing changes to elemental weakness/absorb and different behavior for drain/cure when dealing with absorb/weakness.  If you want a curative spell that heals everything, including the undead, flag it as non-elemental.  Ditto with drain.
3) As mentioned on iRC, I'll probably point out in the ASM the place to modify so the user can decide the correspondences for each of the 4 bits of BREAK and MIGHTY SWORD.  However, in the general release version, I will keep FFT's defaults.  The reason why I needed to use only 4 bits on formulas like MIGHTY SWORD (and ultimately BREAK as well) is because it uses two XA variables (PA and WP), both of which should be modifiable by 4 different stats.  That's a total of 16 different choices, which is the lower 4 bits.
4) Your idea about break and steal sounds good.  I didn't have a way to distinguish them before.
5) Your extra suggestion about incorporating the Fury hack as a toggle?  I probably will do it if no one else proposes a better idea, but it should be known that this is a suggestion, just like my 17).
6) I'll probably delete S-EV Magical for LVL / 4 (with a minimum cap of 5, referenced by MATK UP) because the latter has better scaling.  That being said, however, I'll reference the ASM so anyone can customize this if they want.
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

RavenOfRazgriz

Okay, FDC and I hammered out a lot of stuff regarding flags and finishing touches and stuff, and all I have to say is... 23.  It's a glorious number and you all will shit bricks.

formerdeathcorps

February 06, 2011, 04:02:02 pm #30 Last Edit: February 09, 2011, 11:33:57 am by formerdeathcorps
All right...posting time.  This will not be in hex, as I normally post, but in commented commands, so people can understand better what I'm doing.

Convention:
Black = Commands
Blue = Offsets
Purple = Comments

Gets XA1 and XA2:
lui r1, 0x8019
lbu r3, 0x38F9 (r1) Loads X
lw r2, 0x2D94 (r1) Loads the attacker's stats
addiu r6, r1, 0x38CE r6 = XA1's address
addiu r7, r1, 0x38D0 r7 = XA2's address
andi r3, r3, 0x000F r3 = the last 4 bits of X
(LS) sltiu r4, r3, 0x0004
bne r4, r0, (*) If r3 < 4, GOTO (*)
lbu r5, 0x0036 (r2) r5 = Attacker PA
sltiu r4, r3, 0x0008
bne r4, r0, (*) If r3 < 8, GOTO (*)
lbu r5, 0x0037 (r2) r5 = Attacker MA
sltiu r4, r3, 0x000C
bne r4, r0, (*) If r3 < 12, GOTO (*)
lbu r5, 0x0038 (r2) r5 = Attacker SP
nop
lbu r5, 0x3902 (r1) r5 = Attacker WP
(*) beq r6, r7, (E) If r6 = r7, GOTO End.
sb r5, 0x0000 (r6) Stores r5 at the address of r6
andi r3, r3, 0x0003
sll r3, r3, 0x0002
addiu r3, r3, 0x0001 The purpose of these r3 manipulations is to put r3 in a form that the previous loop can understand.
j (LS) Jumps back to the Loop's Start.
addiu r6, r6, 0x0002 r6 = r6 + 2 = r7 = XA2's address
(E) jr 31 Returns to the Main Formula Routine.
nop
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

formerdeathcorps

February 07, 2011, 08:49:05 pm #31 Last Edit: February 12, 2011, 06:37:34 am by formerdeathcorps
Checks XA2 for support abilities (must come immediately after the above routine):

ori r4, r0, 0x0005
beq r4, r3, (MA) NOTE: r3 can only be 1, 5, 9, or 13, which corresponds to PA, MA, SP, WP.  If r3 is MA, GOTO (MA)
addu r7, r31, r0 Stores the return address in r7 because it'll be modified by the jal commands below.
ori r4, r0, 0x000D
bne r4, r3, (PA/SP) If r3 isn't WP, GOTO (PA/SP)
lbu r5, 0x38D9 (r1)  Loads the "Two Hands" byte.
jal (WP-UP) If WP, GOTO (WP-UP)
lbu r4, 0x38FF (r1) Loads weapon characteristic byte.
(PA/SP) jal (P-UP) If PA/SP, GOTO (P-UP)
lbu r3, 0x38D8 (r1) Loads Weapon Type byte.
j (E1) GOTO (E1)
nop
(MA) jal (M-UP) If MA, GOTO (M-UP)
lbu r3, 0x0090 (r2) Loads Support Byte 4.
(E1) jr 7 Return to Main Routine
nop

(WP-UP) lh r6, 0x38D0 (r1) Loads XA2 = WP
beq r5, r0, (E2) If not using two-hands, GOTO (E2)
andi r3, r4, 0x0001
bne r3, r0, (E2) If weapon is forced two-hands, GOTO (E2)
andi r5, r4, 0x0004
beq r5, r0, (E2) If weapon is not two-handable, GOTO (E2)
sll r6, r6, 0x01
sh r6, 0x38D0 (r1) If 2H is used and XA2 is WP, XA2 = XA2 * 2.
(E2) jr 31
nop
(P-UP) lbu r4, 0x0091 (r1) Loads Support Byte 5.
bne r3, r0, (A-UP)  If equipping a weapon, GOTO (A-UP)
lh r5, 0x38D0 (r1) Loads XA2 = PA or SP.
andi r4, r4, 0x0020
beq r4, r0, (A-UP) If Martial Arts isn't used, GOTO (A-UP)
sll r6, r5, 0x01
addu r6, r6, r5
sra r6, r6, 0x01
sh r6, 0x38D0 (r1) If 2H is used and XA2 is PA or SP, XA2 = XA2 * 3/2.
(A-UP) lbu r3, 0x0090 (r2) Loads Support Byte 4.
lui r4, 0x5555  r4 = 55550000.
andi r5, r3, 0x0010
beq r5, r0, (E3)  If Attack Up isn't used, GOTO (E3)
lh r3, 0x38D0 (r1) Loads XA2.
(Mult) addiu r4, r4, 0x5556 r4 = 55555556 as a multiplier against FFFFFFFF.  In simple terms, this is 1/3.
sll r3, r3, 0x02
mult r4, r3 Term on HI is XA2 * 4 * 1/3.
sra r3, r3, 0x1F r3 = 0.
mfhi r4
subu r4, r4, r3 r4 = r4 - 0.
sh r4, 0x38D0 (r1)  If ATTACK or MAGIC ATTACK UP is flagged, XA2 = XA2 * 4/3.
(E3) jr r31
nop

(M-UP) lui r4, 0x5555  r4 = 55550000.
andi r5, r3, 0x0004
beq r5, r0, (E3) If Magic Attack Up isn't used, GOTO (E3)
lh r3, 0x38D0 (r1)  Loads XA2.
j (Mult) GOTO (Mult)
nop
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

secondadvent

Throughout your code here, you have 1938F0 as XA2's location (which is actually Ability's Range) when XA2 is located at 1938D0; if you were to use 1938F0 as the ending pointer, your initial loop would override everything past the actual XA2 location until it stopped at 1938F0. 1938CE + 2 = 1938D0 = XA2's location.


Instead of:

andi r3, r3, 0x0003
sll r3, r3, 0x0002
addiu r3, r3, 0x0001

you could instead do:

srl r3, r3, 0x02

and just change the checks around a bit to achieve the same thing (instead of checking for < 4/8/12, you can check for < 1/2/3; in the following section you could change = 5/!= 13 -> = 1/!= 3). You would also need to flip the flags around in FFTP so that 0-3 = XA1, and 4-C = XA2 (instead of 0-3 = XA2, 4-C = XA1), otherwise it'd check XA1 for determining things in the support check code.


As for the:

sra r3, r3, 0x1F
mfhi r4
subu r4, r4, r3

section, do you really need to have the sra/subu? Maybe I'm missing something, but I never really saw the reason for this :/.


I don't really notice anything that is wrong, but you'll know for sure if anything is off by following it while the game is running :P. I can't really think of anything else to change; it looks pretty good.

formerdeathcorps

February 12, 2011, 06:31:27 am #33 Last Edit: February 16, 2011, 12:21:17 am by formerdeathcorps
SA, addressed concerns 1 and 3.  Concern 2 seems a bit too trivial to fix.

Sets up the formula (Gets Y):
lhu r7, 0x38CE (r1) Loads XA1
lbu r4, 0x38E5 (r1) Loads Formula
lbu r3, 0x38FA (r1) Loads Y
addiu r5, r0, 0x0008
beq r5, r4, (F8) If Formula 8 (I'll change this to some other number later), GOTO (F8).
addiu r6, r0, 0x0009
beq r6, r4, (F9) If Formula 9 (I'll change this to some other number later), GOTO (F9).
addiu r5, r0, 0x000A
beq r5, r4, (FA) If Formula A (I'll change this to some other number later), GOTO (FA).
addiu r6, r0, 0x000B
beq r6, r4, (FB) If Formula B (I'll change this to some other number later), GOTO (FB).
addu r7, r7, r3 r7 = XA1 + Y
lhu r4, 0x38D0 (r1) r4 = XA2
nop
addu r4, r7, r4
jr 31 Return to Main Routine
sb r4, 0x38D0 (r1) XA2 = XA1 + XA2 + Y
(FB) srl r7, r7, 0x01 XA1 = (XA1 + Y) / 2
j (E)
(FA) srl r6, r3, 0x03 r6 = [Y/8]
andi r3, r3, 0x0007 r3 = last 3 bits of Y
beq r3, r0, (Calc)
lbu r5, 0x0036 (r2) r5 = PA if r3 = 0
addiu r4, r0, 0x0001
beq r3, r4, (Calc)
lbu r5, 0x0037 (r2) r5 = MA if r3 = 1
addiu r4, r0, 0x0002
beq r3, r4, (Calc)
lbu r5, 0x0038 (r2) r5 = SP if r3 = 2
addiu r4, r0, 0x0003
beq r3, r4, (Calc)
lbu r5, 0x3902 (r1) r5 = WP if r3 = 3
addiu r4, r0, 0x0004
beq r3, r4, (Div4)
lbu r5, 0x0022 (r2) r5 = LVL if r3 = 4
addiu r4, r0, 0x0005
beq r3, r4, (Check)
addu r5, r2, 0x003E Readies the check where r5 = WEV1 if r3 = 5
addiu r4, r0, 0x0006
beq r3, r4, (Check)
addu r5, r2, 0x0045 Readies the check where r5 = SMEV1 if r3 = 6
addu r5, r2, 0x0041 Readies the check where r5 = SPEV1 if r3 = 7
(Check) lbu r4, 0x0000 (r5) r4 = RH equipment evasion.
bne r4, r0, (DivCheck) Checks RH equipment for evasion.
sltiu r3, r3, 0x0007 r3 = 1 if r3 < 7. r3 = 0 if r3 = 7.
lbu r4, 0x0001 (r5) r4 = LH equipment evasion.
(DivCheck) beq r3, r0 (Div3) If r3 = 0 (original r3 = 7), GOTO (Div3)
addu r5, r4, r0 r5 = r4
j (Calc)
srl r5, r5, 0x01 r5 = r5 / 2...this allows the SM-EV and W-EV used in formulas to cap at 25-30 in vanilla.
(Div3) lui r4, 0x5555
addu r4, r4, 0x5556
mult r5, r4
j (Calc)
mfhi r5 r5 = r5 / 3...this allows the SP-EV used in formulas to cap at 25 in vanilla.
(Div4) j (Calc)
srl r5, r5, 0x02 r5 = r5 / 4...this allows the LVL used in formulas to cap at 25 in vanilla.
(Calc) bne r5, r0 (Nonzero) If r5 is not zero, GOTO (Nonzero)
nop
addiu r5, r0, 0x0001
(Nonzero) addu r7, r7, r5 r7 = XA1 + r5 (which we'll now call YA3)
srl r7, r7, 0x01 r7 = (XA1 + YA3) / 2
j (E)
addu r7, r7, r6 XA1 = (XA1 + YA3) / 2 + [Y/8]
(F9) andi r5, r3, 0x0008 r5 = first bit of Y
beq r5, r0 (Sorter)
srl r6, r3, 0x04 r6 = [Y/16]
lw r2, 0x2D98 (r1) Load the target's stats.
(Sorter) andi r5, r3, 0x0003 r5 = last 2 bits of Y
andi r3, r3, 0x0004 r3 = second bit of Y
beq r5, r0 (Divider1)
addiu r4, r2, 0x0028 Readies the check where r4 = curHP if r5 = 0
addiu r5, r5, 0xFFFF r5 = r5 - 1
beq r5, r0 (Divider1)
addiu r4, r2, 0x002C Readies the check where r4 = curMP if r5 = 0 (original r5 = 1).
addiu r5, r5, 0xFFFF r5 = r5 - 1
beq r5, r0 (Divider2)
lbu r4, 0x0024 (r2) r4 = Br of target or caster if r5 = 0 (original r5 = 2)
lbu r5, 0x005C (r2) r5 = Status Byte 5 on target or caster if r5 = 1 (original r5 = 3)
lbu r4, 0x0026 (r2) r4 = Fa of target or caster if r5 = 1 (original r5 = 3)
andi r5, r5 0x00C0
beq r5, r0 (Divider2) If not Innocent or Faith, GOTO (Divider2)
nop
sltiu r5, r5, 0x0080 r5 = 1 if Innocent.  r5 = 0 if Faith.
beq r5, r0 (Divider2) If Faith, GOTO (Divider2)
addiu r4, r0, 0x0064 r4 = 100
addiu r4, r0, 0x0000 ELSE, r4 = 0
(Divider2) beq r3, r0 (Div100) If r3 = 0 (normal), GOTO (Div100)
addiu r5, r0, 0x0064 r5 = 100
subu r4, r5, r4 If r3 = 1 (reversed stats), r4 = 100 - (BR or Adjusted FA)
(Div100) mult r7, r4
mflo r4 r4 = XA1 * BR/FA/UnBr/UnFa
lui r5, 0x028F
addiu r5, r5, 0x5C29
mult r4, r5
mfhi r5 r5 = XA1 * Br/Fa/UnBr/UnFa / 100
j (E)
addu r7, r5, r6 XA1 = (XA1 * Br/Fa/UnBr/UnFa / 100) + [Y/16]
(Divider1) lhu r5, 0x0000 (r4) r5 = curHP or curMP
beq r3, r0 (OverMax) If r3 = 0 (normal), GOTO (OverMax)
lhu r4, 0x0002 (r4) r4 = maxHP or maxMP
subu r5, r4, r5 If r3 = 1 (reversed stats), r4 = max-cur HP/MP
(OverMax) mult r7, r5
mflo r5 r5 = XA1 * curHP/MP/max-curHP/max-curMP
nop
nop
div r5, r4
mflo r5 r5 = XA1 * curHP/MP/max-curHP/max-curMP / maxHP/MP
j (E)
addu r7, r5, r6 XA1 = (XA1 * curHP/max-curHP/curMP/max-curMP / maxHP/MP) + [Y/16]
(F8) lui r4, 0xA001
lw r5, -0x6FF0 (r4) Load random word.
lui r6, 0x41C6
addiu r6, r6, 0x4E6D
multu r5, r6
mflo r5
addiu r5, r5, 0x3039
sw r5, -0x6FF0 (r4) Store new Random Word.
mult r7, r5
mfhi r7 r7 = {0...XA1-1}
addiu r7, r7, 0x0001 r7 = {1...XA1}
addu r7, r7, r3 XA1 = {1...XA1}+Y
(E) jr 31 Return to Main Routine
sb r7, 0x38CE (r1) Store modified XA1.
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

Vanya

February 12, 2011, 09:47:01 pm #34 Last Edit: February 13, 2011, 06:53:07 am by Vanya
I need to study more because I barely understand half this stuff. But what I do get is beautiful for the promises it sweetly whispers. <3
  • Modding version: Other/Unknown
¯\(°_0)/¯

formerdeathcorps

February 12, 2011, 10:50:18 pm #35 Last Edit: February 12, 2011, 10:50:52 pm by formerdeathcorps
What do you currently not understand, Vanya?  There are 5 formulas being made:
8: XA1 = {1...XA1} + Y; XA2 = XA2
9: XA1 = (XA1 * YA3 + [Y/16]), where YA3 = target/self Normal/Reversed HP Ratio/MP Ratio/Br Percentage/Fa Percentage; XA2 = XA2
10: XA1 = ((XA1 + YA3) / 2 + [Y/8]), where YA3 = PA/MA/SP/WP/LVL*.25/W-EV*.5/MS-EV*.5/PS-EV*.3333333333; XA2 = XA2
11: XA1 = (XA1 + Y) / 2; XA2 = XA2
12: XA1 = XA1; XA2 = (XA1 + XA2 + Y)

Formula 9 works as thus.  0/1/2/3 means YA3 is the caster's HP Ratio/MP Ratio/Br%/Fa%.  4/5/6/7 means YA3 is the caster's HP Ratio/MP Ratio/Br%/Fa% subtracted from 1.  8/9/10/11 means YA3 is the target's HP Ratio/MP Ratio/Br%/Fa%.  12/13/14/15 means YA3 is the target's HP Ratio/MP Ratio/Br%/Fa% subtracted from 1.  The additive value of Y is Y / 16, rounded down.
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

formerdeathcorps

February 13, 2011, 12:45:50 am #36 Last Edit: February 16, 2011, 01:35:59 am by formerdeathcorps
Zodiac Compatibility Routine (SA...feel free to improve this or make it compatible with yours):

lw r2, 0x2D94 (r1) Loads the attacker's stats
lw r3, 0x2D98 (r1) Loads the defender's stats
lui r7, 0x8006
lhu r6, 0x38D6 (r1) r6 = Used Ability ID
lbu r4, 0x0009 (r2) Loads the attacker's Zodiac Sign Byte
sll r6, r6, 0x03 r6 = r6 * 8
addu r7, r7, r6
lbu r7, -0x140D (r7) r7 = AI Byte 1 for attack
addiu r6, r0, 0x000C
andi r7, r7, 0x0010 Checks if the currently unused flag under "Learn on Hit" is flagged.
bne r7, r0, (E) If flagged, GOTO (E)
lbu r5, 0x0009 (r3) Loads the defender's Zodiac Sign Byte
srl r4, r4, 0x04 Gets the attacker byte's upper 4 bits.
beq r4, r6, (E) If Attacker sign is Ophiuchus, GOTO (E)
srl r5, r5, 0x04 Gets the defender byte's upper 4 bits.
beq r5, r6, (E) If Defender sign is Ophiuchus, GOTO (E)
andi r7, r4, 0x0003 r7 = the lower 2 bits of attacker sign
andi r6, r5, 0x0003 r6 = the lower 2 bits of defender sign
beq r6, r7, (Good) If attacker and defender signs differ by 4, GOTO (Good)
lbu r1, 0x38D0 (r1) r1 = XA2
addiu r7, r0, 0x0002
addiu r6, r0, 0x0006
(MOD) div r4, r6
mfhi r4 r4 = r4 MOD r6...MOD means you take the remainder of the division.
nop
nop
div r5, r6
mfhi r5 r5 = r5 MOD r6
beq r4, r5 (Diff) If attacker and defender signs form a square or its diagonal, GOTO (Diff)
addiu r7, r7, 0xFFFF r7 = r7 - 1
bne r7, r0, (MOD) If r7 isn't zero, GOTO (MOD)
addiu r6, r0, 0x0003
(E) jr 31 Return to Main Routine
lui r1, 0x8019 Resets r1 = 0x80190000.
(Diff) beq r7, r0 (Bad) If r7 = 0 (when r6 = 3), GOTO (Bad)
lbu r6, 0x0006 (r2) r6 = attacker gender
lbu r7, 0x0006 (r3) r7 = defender gender
or r4, r6, r7
andi r4, r4, 0x0020
bne r4, r0, (Bad) If either combatant is a monster, GOTO (Bad)
andi r6, r6, 0x00C0
andi r7, r7, 0x00C0
beq r6, r7 (EndBranch) If the genders are the same, GOTO (EndBranch)
srl r4, r1, 0x01 XA2 = [XA2/2]
(+) addu r4, r1, r4 XA2 = XA2 + r4
(EndBranch) lui r7, 0x8019
j (E)
sb r4, 0x38D0 (r7) Store r1 as XA2
(Good) j (+)
(Bad) srl r4, r1, 0x02 r4 = [XA2/4]
j (EndBranch)
subu r4, r1, r4 XA2 = XA2 - [XA2/4]
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

RavenOfRazgriz

Oh... FDC.  I just realized we've made a minor faux paus in 08-0B.  The Y modifier should be added to XA2, not the end value of XA1 and YA3.  We were so busy both trying to cram as much out of these formula as we could that the Y modifier got shoved in the wrong place at some point.  I suppose it's not a ridiculously huge deal, but it breaks the Vanilla-friendly convention we've worked so hard to keep and should probably be fixed if it's not too hard to do.

formerdeathcorps

February 16, 2011, 04:25:38 am #38 Last Edit: February 16, 2011, 04:31:08 am by formerdeathcorps
Quote from: RavenOfRazgriz on February 14, 2011, 11:05:07 pm
Oh... FDC.  I just realized we've made a minor faux paus in 08-0B.  The Y modifier should be added to XA2, not the end value of XA1 and YA3.  We were so busy both trying to cram as much out of these formula as we could that the Y modifier got shoved in the wrong place at some point.  I suppose it's not a ridiculously huge deal, but it breaks the Vanilla-friendly convention we've worked so hard to keep and should probably be fixed if it's not too hard to do.


As I explained yesterday in iRC, this is not an issue. The addition of Y on "Charge" is the same addition used in "Geomancy" and "Martial Arts", so it's actually 2D that's the exception.  Furthermore, if you think that WP + Y gives better scaling, you can just switch XA1 (PA) and YA3 (??) with XA2 (WP--in both instances, if need be).  The only real differences from vanilla are when you try to apply 2 Hands to XA1 as WP (which is rather broken to begin with), when Magic Attack Up affects MA * WP (because MA is XA2 instead of WP, but MA * (WP + Y) didn't exist in vanilla anyways), or when you try to use the multiplicative function (((XA1 * YA3) + Y) * XA2) when Y is not zero (but people would only use that attack when YA3 is close to 1, meaning the difference is usually not much more than 20% of the spell's overall damage output).

Protect/Shell/DEFUP/MADEF Routine:

addu r2, r31, r0 r2 = Return Address, because r31 will be modified below by the jal commands.
lhu r5, 0x38D6 (r1) r5 = Used Ability ID
lui r4, 0x8006
sll r5, r5, 0x03 r5 = r5 * 8
addu r4, r4, r5
lbu r5, -0x1F0A (r4) r4 = AI Byte 4
lbu r6, 0x005B (r3) r6 = Status Byte 4
andi r4, r5, 0x0002
beq r4, r0 (Prot) If AI flag Magic Defense Up is not checked, GOTO (Prot)
andi r7, r6, 0x0010
beq r7, r0 (Prot) If target does not have Shell, GOTO (Prot)
nop
jal (Mult) If target has Shell and skill is blocked by Shell, GOTO (Mult)
(Prot) andi r4, r5, 0x0001
beq r4, r0 (MADEF) If AI flag Defense Up is not checked, GOTO (MADEF)
andi r7, r6, 0x0020
beq r7, r0 (MADEF) If target does not have Protect, GOTO (MADEF)
nop
jal (Mult) If target has Protect and skill is blocked by Protect, GOTO (Mult)
(MADEF) lbu r6, 0x0090 (r3) r6 = Support Byte 2
andi r4, r5, 0x0002
beq r4, r0 (DEFUP) If AI flag Magic Defense Up is not checked, GOTO (DEFUP)
andi r7, r6, 0x0002
beq r7, r0 (DEFUP) If target does not have Magic Defense Up, GOTO (DEFUP)
nop
jal (Mult) If target has Magic Defense Up and skill is blocked by Shell, GOTO (Mult)
(MADEF) andi r4, r5, 0x0001
beq r4, r0 (E) If AI flag Defense Up is not checked, GOTO (E)
andi r7, r6, 0x0008
beq r7, r0 (E) If target does not have Defense Up, GOTO (E)
nop
jal (Mult) If target has Defense Up and skill is blocked by Protect, GOTO (Mult)
nop
(E) jr r2 Return to Main Routine
nop

(Mult) lui r4, 0xAAAA
lhu r7, 0x38D0 (r1) r7 = XA2
addiu r4, r4, 0xAAAB r4 = AAAAAAAB
mult r7, r4
mfhi r7 r7 = XA2 * 2/3
jr 31 Return to Protect/Shell/MADEF/DEFUP Routine
sh r7, 0x38D0 (r1) XA2 = XA2 * 2/3
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.

formerdeathcorps

February 16, 2011, 04:35:22 am #39 Last Edit: February 21, 2011, 04:23:25 am by formerdeathcorps
OK...the order I posted in isn't entirely right.  The order should be:

lui r1, 0x8019
lbu r3, 0x38F9 (r1) Loads X
lw r2, 0x2D94 (r1) Loads the attacker's stats
addiu r6, r1, 0x38CE r6 = XA1's address
addiu r7, r1, 0x38D0 r7 = XA2's address
andi r3, r3, 0x000F r3 = the last 4 bits of X
(LS) sltiu r4, r3, 0x0004
bne r4, r0, (*) If r3 < 4, GOTO (*)
lbu r5, 0x0036 (r2) r5 = Attacker PA
sltiu r4, r3, 0x0008
bne r4, r0, (*) If r3 < 8, GOTO (*)
lbu r5, 0x0037 (r2) r5 = Attacker MA
sltiu r4, r3, 0x000C
bne r4, r0, (*) If r3 < 12, GOTO (*)
lbu r5, 0x0038 (r2) r5 = Attacker SP
nop
lbu r5, 0x3902 (r1) r5 = Attacker WP
(*) beq r6, r7, (E) If r6 = r7, GOTO End.
sb r5, 0x0000 (r6) Stores r5 at the address of r6
andi r3, r3, 0x0003
sll r3, r3, 0x0002
addiu r3, r3, 0x0001 The purpose of these r3 manipulations is to put r3 in a form that the previous loop can understand.
j (LS) Jumps back to the Loop's Start.
addiu r6, r6, 0x0002 r6 = r6 + 2 = r7 = XA2's address
(E) jr 31 Returns to the Main Formula Routine.
nop


lbu r4, 0x38F7 (r1) Loads ability element
lbu r5, 0x0071 (r2) Loads elements strengthened
lhu r6, 0x38D0 (r1) Loads XA2
and r4, r4, r5 Checks ability element against elements strengthened
beq r4, r0, (E) If ability element isn't a boosted element, GOTO (E)
srl r5, r6, 0x02 If ability element is boosted, r5 = [XA2/4]
addu r6, r6, r5 XA2 = XA2 + [XA2/4]
(E)  jr 31 Return to Main Routine
sh r6, 0x38D0 (r1) Stores XA2


lw r5, 0x2D98 (r1) Load target address.
ori r4, r0, 0x0005
beq r3, r4, (E) NOTE: r3 can only be 1, 5, 9, or 13, which corresponds to PA, MA, SP, WP.  If XA2 is MA, GOTO (E)
lbu r6, 0x005C (r5) Load Status Byte 5.
lbu r7, 0x0058 (r5) Load Status Byte 1.
lbu r5, 0x005A (r5) Load Status Byte 3.
andi r6, r6, 0x0010
bne r6, r0, (Mult) If target is asleep, GOTO (Mult)
andi r7, r7, 0x0008
bne r7, r0, (Mult) If target is charging, GOTO (Mult)
andi r5, r5, 0x0006
beq r5, r0, (E) If target isn't chickened/frogged, GOTO (E)
(Mult) lhu r4, 0x38D0 (r1) Load XA2.
nop
srl r5, r4, 0x01 r5 = [XA2/2]
addu r4, r4, r5 XA2 = XA2 + [XA2/2]
sh r4, 0x38D0 (r1) Store XA2.
(E) jr 31 Return to Main Routine
nop

ori r4, r0, 0x0005
beq r4, r3, (MA) NOTE: r3 can only be 1, 5, 9, or 13, which corresponds to PA, MA, SP, WP.  If r3 is MA, GOTO (MA)
addu r7, r31, r0 Stores the return address in r7 because it'll be modified by the jal commands below.
ori r4, r0, 0x000D
bne r4, r3, (PA/SP) If r3 isn't WP, GOTO (PA/SP)
lbu r5, 0x38D9 (r1)  Loads the "Two Hands" byte.
jal (WP-UP) If WP, GOTO (WP-UP)
lbu r4, 0x38FF (r1) Loads weapon characteristic byte.
(PA/SP) jal (P-UP) If PA/SP, GOTO (P-UP)
lbu r3, 0x38D8 (r1) Loads Weapon Type byte.
j (E1) GOTO (E1)
nop
(MA) jal (M-UP) If MA, GOTO (M-UP)
lbu r3, 0x0090 (r2) Loads Support Byte 4.
(E1) jr 7 Return to Main Routine
nop

(WP-UP) lhu r6, 0x38D0 (r1) Loads XA2 = WP
beq r5, r0, (E2) If not using two-hands, GOTO (E2)
andi r3, r4, 0x0001
bne r3, r0, (E2) If weapon is forced two-hands, GOTO (E2)
andi r5, r4, 0x0004
beq r5, r0, (E2) If weapon is not two-handable, GOTO (E2)
sll r6, r6, 0x01
sh r6, 0x38D0 (r1) If 2H is used and XA2 is WP, XA2 = XA2 * 2.
(E2) jr 31
nop
(P-UP) lbu r4, 0x0091 (r1) Loads Support Byte 5.
bne r3, r0, (A-UP)  If equipping a weapon, GOTO (A-UP)
lhu r5, 0x38D0 (r1) Loads XA2 = PA or SP.
andi r4, r4, 0x0020
beq r4, r0, (A-UP) If Martial Arts isn't used, GOTO (A-UP)
srl r6, r5, 0x01
addu r6, r5, r6
sh r6, 0x38D0 (r1) If Martial Arts is used and XA2 is PA or SP, XA2 = XA2 + [XA2/2].
(A-UP) lbu r3, 0x0090 (r2) Loads Support Byte 4.
lui r4, 0x5555  r4 = 55550000.
andi r5, r3, 0x0010
beq r5, r0, (E3)  If Attack Up isn't used, GOTO (E3)
lhu r3, 0x38D0 (r1) Loads XA2.
(Mult) addiu r4, r4, 0x5556 r4 = 55555556 as a multiplier against FFFFFFFF.  In simple terms, this is 1/3.
sll r3, r3, 0x02
mult r4, r3 Term on HI is XA2 * 4 * 1/3.
sra r3, r3, 0x1F r3 = 0.
mfhi r4
subu r4, r4, r3 r4 = r4 - 0.
sh r4, 0x38D0 (r1)  If ATTACK or MAGIC ATTACK UP is flagged, XA2 = XA2 * 4/3.
(E3) jr r31
nop

(M-UP) lui r4, 0x5555  r4 = 55550000.
andi r5, r3, 0x0004
beq r5, r0, (E3) If Magic Attack Up isn't used, GOTO (E3)
lhu r3, 0x38D0 (r1)  Loads XA2.
j (Mult) GOTO (Mult)
nop


addu r2, r31, r0 r2 = Return Address, because r31 will be modified below by the jal commands.
lw r3, 0x2D98 (r1) Load target address.
lhu r5, 0x38D6 (r1) r5 = Used Ability ID
lui r4, 0x8006
sll r5, r5, 0x03 r5 = r5 * 8
addu r4, r4, r5
lbu r5, -0x1F0A (r4) r4 = AI Byte 4
lbu r6, 0x005B (r3) r6 = Status Byte 4
andi r4, r5, 0x0002
beq r4, r0 (Prot) If AI flag Magic Defense Up is not checked, GOTO (Prot)
andi r7, r6, 0x0010
beq r7, r0 (Prot) If target does not have Shell, GOTO (Prot)
nop
jal (Mult) If target has Shell and skill is blocked by Shell, GOTO (Mult)
nop
(Prot) andi r4, r5, 0x0001
beq r4, r0 (MADEF) If AI flag Defense Up is not checked, GOTO (MADEF)
andi r7, r6, 0x0020
beq r7, r0 (MADEF) If target does not have Protect, GOTO (MADEF)
nop
jal (Mult) If target has Protect and skill is blocked by Protect, GOTO (Mult)
(MADEF) lbu r6, 0x0090 (r3) r6 = Support Byte 2
andi r4, r5, 0x0002
beq r4, r0 (DEFUP) If AI flag Magic Defense Up is not checked, GOTO (DEFUP)
andi r7, r6, 0x0002
beq r7, r0 (DEFUP) If target does not have Magic Defense Up, GOTO (DEFUP)
nop
jal (Mult) If target has Magic Defense Up and skill is blocked by Shell, GOTO (Mult)
(DEFUP) andi r5, r5, 0x0001
beq r5, r0 (E) If AI flag Defense Up is not checked, GOTO (E)
andi r6, r6, 0x0008
beq r6, r0 (E) If target does not have Defense Up, GOTO (E)
nop
jal (Mult) If target has Defense Up and skill is blocked by Protect, GOTO (Mult)
nop
(E) jr r2 Return to Main Routine
nop

(Mult) lui r4, 0xAAAA
lhu r7, 0x38D0 (r1) r7 = XA2
addiu r4, r4, 0xAAAB r4 = AAAAAAAB
mult r7, r4
mfhi r7 r7 = XA2 * 2/3
jr 31 Return to Protect/Shell/MADEF/DEFUP Routine
sh r7, 0x38D0 (r1) XA2 = XA2 * 2/3


lbu r4, 0x38F7 (r1) Loads ability element
lbu r5, 0x006F (r3) Loads elements halved
lhu r6, 0x38D0 (r1) Load XA2
and r4, r4, r5 Checks ability element against elements halved
beq r4, r0, (E) If ability element isn't a halved element, GOTO (E)
lw r2, 0x2D94 (r1) Loads attacker address
srl r6, r6, 0x01 If ability element is halved, XA2 = [XA2/2]
(E) jr 31 Return to Main Routine
sh r6, 0x38D0 (r1) Stores XA2


lhu r7, 0x38CE (r1) Loads XA1
lbu r4, 0x38E5 (r1) Loads Formula
lbu r3, 0x38FA (r1) Loads Y
addiu r5, r0, 0x0008
beq r5, r4, (F8) If Formula 8 (I'll change this to some other number later), GOTO (F8).
addiu r6, r0, 0x0009
beq r6, r4, (F9) If Formula 9 (I'll change this to some other number later), GOTO (F9).
addiu r5, r0, 0x000A
beq r5, r4, (FA) If Formula A (I'll change this to some other number later), GOTO (FA).
addiu r6, r0, 0x000B
beq r6, r4, (FB) If Formula B (I'll change this to some other number later), GOTO (FB).
addu r7, r7, r3 r7 = XA1 + Y
lhu r4, 0x38D0 (r1) r4 = XA2
nop
addu r4, r7, r4
jr 31 Return to Main Routine
sb r4, 0x38D0 (r1) XA2 = XA1 + XA2 + Y
(FB) srl r7, r7, 0x01 XA1 = (XA1 + Y) / 2
j (E)
(FA) srl r6, r3, 0x03 r6 = [Y/8]
andi r3, r3, 0x0007 r3 = last 3 bits of Y
beq r3, r0, (Calc)
lbu r5, 0x0036 (r2) r5 = PA if r3 = 0
addiu r4, r0, 0x0001
beq r3, r4, (Calc)
lbu r5, 0x0037 (r2) r5 = MA if r3 = 1
addiu r4, r0, 0x0002
beq r3, r4, (Calc)
lbu r5, 0x0038 (r2) r5 = SP if r3 = 2
addiu r4, r0, 0x0003
beq r3, r4, (Calc)
lbu r5, 0x3902 (r1) r5 = WP if r3 = 3
addiu r4, r0, 0x0004
beq r3, r4, (Div4)
lbu r5, 0x0022 (r2) r5 = LVL if r3 = 4
addiu r4, r0, 0x0005
beq r3, r4, (Check)
addu r5, r2, 0x003E Readies the check where r5 = WEV1 if r3 = 5
addiu r4, r0, 0x0006
beq r3, r4, (Check)
addu r5, r2, 0x0045 Readies the check where r5 = SMEV1 if r3 = 6
addu r5, r2, 0x0041 Readies the check where r5 = SPEV1 if r3 = 7
(Check) lbu r4, 0x0000 (r5) r4 = RH equipment evasion.
bne r4, r0, (DivCheck) Checks RH equipment for evasion.
sltiu r3, r3, 0x0007 r3 = 1 if r3 < 7. r3 = 0 if r3 = 7.
lbu r4, 0x0001 (r5) r4 = LH equipment evasion.
(DivCheck) beq r3, r0 (Div3) If r3 = 0 (original r3 = 7), GOTO (Div3)
addu r5, r4, r0 r5 = r4
j (Calc)
srl r5, r5, 0x01 r5 = r5 / 2...this allows the SM-EV and W-EV used in formulas to cap at 25-30 in vanilla.
(Div3) lui r4, 0x5555
addu r4, r4, 0x5556
mult r5, r4
j (Calc)
mfhi r5 r5 = r5 / 3...this allows the SP-EV used in formulas to cap at 25 in vanilla.
(Div4) j (Calc)
srl r5, r5, 0x02 r5 = r5 / 4...this allows the LVL used in formulas to cap at 25 in vanilla.
(Calc) bne r5, r0 (Nonzero) If r5 is not zero, GOTO (Nonzero)
nop
addiu r5, r0, 0x0001
(Nonzero) addu r7, r7, r5 r7 = XA1 + r5 (which we'll now call YA3)
srl r7, r7, 0x01 r7 = (XA1 + YA3) / 2
j (E)
addu r7, r7, r6 XA1 = (XA1 + YA3) / 2 + [Y/8]
(F9) andi r5, r3, 0x0008 r5 = first bit of Y
beq r5, r0 (Sorter)
srl r6, r3, 0x04 r6 = [Y/16]
lw r2, 0x2D98 (r1) Load the target's stats.
(Sorter) andi r5, r3, 0x0003 r5 = last 2 bits of Y
andi r3, r3, 0x0004 r3 = second bit of Y
beq r5, r0 (Divider1)
addiu r4, r2, 0x0028 Readies the check where r4 = curHP if r5 = 0
addiu r5, r5, 0xFFFF r5 = r5 - 1
beq r5, r0 (Divider1)
addiu r4, r2, 0x002C Readies the check where r4 = curMP if r5 = 0 (original r5 = 1).
addiu r5, r5, 0xFFFF r5 = r5 - 1
beq r5, r0 (Divider2)
lbu r4, 0x0024 (r2) r4 = Br of target or caster if r5 = 0 (original r5 = 2)
lbu r5, 0x005C (r2) r5 = Status Byte 5 on target or caster if r5 = 1 (original r5 = 3)
lbu r4, 0x0026 (r2) r4 = Fa of target or caster if r5 = 1 (original r5 = 3)
andi r5, r5 0x00C0
beq r5, r0 (Divider2) If not Innocent or Faith, GOTO (Divider2)
nop
sltiu r5, r5, 0x0080 r5 = 1 if Innocent.  r5 = 0 if Faith.
beq r5, r0 (Divider2) If Faith, GOTO (Divider2)
addiu r4, r0, 0x0064 r4 = 100
addiu r4, r0, 0x0000 ELSE, r4 = 0
(Divider2) beq r3, r0 (Div100) If r3 = 0 (normal), GOTO (Div100)
addiu r5, r0, 0x0064 r5 = 100
subu r4, r5, r4 If r3 = 1 (reversed stats), r4 = 100 - (BR or Adjusted FA)
(Div100) mult r7, r4
mflo r4 r4 = XA1 * BR/FA/UnBr/UnFa
lui r5, 0x028F
addiu r5, r5, 0x5C29
mult r4, r5
mfhi r5 r5 = XA1 * Br/Fa/UnBr/UnFa / 100
j (E)
addu r7, r5, r6 XA1 = (XA1 * Br/Fa/UnBr/UnFa / 100) + [Y/16]
(Divider1) lhu r5, 0x0000 (r4) r5 = curHP or curMP
beq r3, r0 (OverMax) If r3 = 0 (normal), GOTO (OverMax)
lhu r4, 0x0002 (r4) r4 = maxHP or maxMP
subu r5, r4, r5 If r3 = 1 (reversed stats), r4 = max-cur HP/MP
(OverMax) mult r7, r5
mflo r5 r5 = XA1 * curHP/MP/max-curHP/max-curMP
nop
nop
div r5, r4
mflo r5 r5 = XA1 * curHP/MP/max-curHP/max-curMP / maxHP/MP
j (E)
addu r7, r5, r6 XA1 = (XA1 * curHP/max-curHP/curMP/max-curMP / maxHP/MP) + [Y/16]
(F8) lui r4, 0xA001
lw r5, -0x6FF0 (r4) Load random word.
lui r6, 0x41C6
addiu r6, r6, 0x4E6D
multu r5, r6
mflo r5
addiu r5, r5, 0x3039
sw r5, -0x6FF0 (r4) Store new Random Word.
mult r7, r5
mfhi r7 r7 = {0...XA1-1}
addiu r7, r7, 0x0001 r7 = {1...XA1}
addu r7, r7, r3 XA1 = {1...XA1}+Y
(E) jr 31 Return to Main Routine
sb r7, 0x38CE (r1) Store modified XA1.


lw r2, 0x2D94 (r1) Loads the attacker's stats
lw r3, 0x2D98 (r1) Loads the defender's stats
lui r7, 0x8006
lhu r6, 0x38D6 (r1) r6 = Used Ability ID
lbu r4, 0x0009 (r2) Loads the attacker's Zodiac Sign Byte
sll r6, r6, 0x03 r6 = r6 * 8
addu r7, r7, r6
lbu r7, -0x140D (r7) r7 = AI Byte 1 for attack
addiu r6, r0, 0x000C
andi r7, r7, 0x0010 Checks if the currently unused flag under "Learn on Hit" is flagged.
bne r7, r0, (E) If flagged, GOTO (E)
lbu r5, 0x0009 (r3) Loads the defender's Zodiac Sign Byte
srl r4, r4, 0x04 Gets the attacker byte's upper 4 bits.
beq r4, r6, (E) If Attacker sign is Ophiuchus, GOTO (E)
srl r5, r5, 0x04 Gets the defender byte's upper 4 bits.
beq r5, r6, (E) If Defender sign is Ophiuchus, GOTO (E)
andi r7, r4, 0x0003 r7 = the lower 2 bits of attacker sign
andi r6, r5, 0x0003 r6 = the lower 2 bits of defender sign
beq r6, r7, (Good) If attacker and defender signs differ by 4, GOTO (Good)
lbu r1, 0x38D0 (r1) r1 = XA2
addiu r7, r0, 0x0002
addiu r6, r0, 0x0006
(MOD) div r4, r6
mfhi r4 r4 = r4 MOD r6...MOD means you take the remainder of the division.
nop
nop
div r5, r6
mfhi r5 r5 = r5 MOD r6
beq r4, r5 (Diff) If attacker and defender signs form a square or its diagonal, GOTO (Diff)
addiu r7, r7, 0xFFFF r7 = r7 - 1
bne r7, r0, (MOD) If r7 isn't zero, GOTO (MOD)
addiu r6, r0, 0x0003
(E) jr 31 Return to Main Routine
lui r1, 0x8019 Resets r1 = 0x80190000.
(Diff) beq r7, r0 (Bad) If r7 = 0 (when r6 = 3), GOTO (Bad)
lbu r6, 0x0006 (r2) r6 = attacker gender
lbu r7, 0x0006 (r3) r7 = defender gender
or r4, r6, r7
andi r4, r4, 0x0020
bne r4, r0, (Bad) If either combatant is a monster, GOTO (Bad)
andi r6, r6, 0x00C0
andi r7, r7, 0x00C0
beq r6, r7 (EndBranch) If the genders are the same, GOTO (EndBranch)
srl r4, r1, 0x01 XA2 = [XA2/2]
(+) addu r4, r1, r4 XA2 = XA2 + r4
(EndBranch) lui r7, 0x8019
j (E)
sb r4, 0x38D0 (r7) Store r1 as XA2
(Good) j (+)
(Bad) srl r4, r1, 0x02 r4 = [XA2/4]
j (EndBranch)
subu r4, r1, r4 XA2 = XA2 - [XA2/4]
The destruction of the will is the rape of the mind.
The dogmas of every era are nothing but the fantasies of those in power; their dreams are our waking nightmares.