Golden Sun Hacking Community

The Editor => Golden Sun Hacking => : Salanewt May 25, 2014, 05:47:41 PM



: Master Formula List
: Salanewt May 25, 2014, 05:47:41 PM
Howdy! So uh, yeah. Here's a topic in which we can organize the games' formulas and discuss them a bit. This first post will be separated into two sections; confirmed through code and unconfirmed through code (such formulas may have unknown variables that are as of yet undocumented). Organization will be a little lackluster until we have a decent proportion of the game's formulas in here.



Vanilla

Agility/Turn Order

The following section explains how PC turns are calculated.

Turn Order:
Randomized agility has priority;
PCs have priority over enemies;
Left-most slots have priority;

Agility x 0-FFFF (or ran) = RAN
LSR 14 RAN = #
Agility + #
÷ 2 for additional turns only.

So if Agility = x64 (100 decimal) and ran = xFFFF, then you multiply them;
RAN = 63FF9C
LSR 14 in a programmer's calculator;
# = 6
Add 6 to 100 Agility
= 106
If it's not the first turn (as in second, third, etc. turns);
106 ÷ 2 = 53

It boils down to:

(Agility + Agility*(0~6%))*(Multi-turn penalty)
Multi-turn penalty = 1 if it's a character's first action that turn, and 0.5 otherwise.

Maximum agility values to ensure desired turn order.
PC1: 999
PC2: 940 (941 if right of PC1)
PC3: 884 (885 if right of PC2)
PC4: 832 (833 if right of PC3)


Enemies, on the other hand, are much simpler.

For 4 turns, agility decrements by 1/6th each turn.
For 3 turns, by 1/4th.
For 2 turns, by 1/2.


Turns are normally capped at 4, manually adding more to an enemy's RAM will result in every turn after the first one having only half of its agility value.

0811D0A8 = Check for 4 turns, branch if not equal - Turn 2: 5/6 agility ; Turn 3: 4/6 agility ; Turn 4: 1/2 agility
0811D0D0 = Check for 3 turns, branch if not equal - Turn 2: 3/4 agility ; Turn 3: 1/2 agility
0811D0EE = Check for 2 turns, branch if not equal - Turn 2: 1/2 agility



Ailment Success

(((((((Attacker's elemental level - Defender's elemental level) - Floor(Defender's luck / 2)) * 3) + effect's base chance + (vulnerabity's 25)) * multi_arg) / 100)  >= rnd())

Where "rnd()" is a random number from 0-99 (x00 to x63), and "multi_arg" (previously known as "unk_arg") is for diminishing success rates based on the amount of targets the effect can be used on:
First (Primary Target) = 100%
Second (Next to the target) = 60%
Third = 30%
Fourth = 30%
Fifth = 30%
Sixth = 30%

Notes:
x52 = "82 - May force target out of battle" is always 0% when class is not NPC. (0% for player characters?)

These generate three random numbers... This would make, for example, a chance of 50% (one) to be 87.5% (three), I think.
x43 = "67 - Inflicts Seal"
x50 = "80 - Inflicts Death Curse"
x55 = "85 - May inflict Stun"[/spoiler]

Base success rates (assigned in the function at 080B0514):

080B0660 - 70% (12/13 - Def debuffs)
080B0664 - 75% (16/17 - eRes debuffs)
080B0668 - 30% (22 - Charm)
080B066C - 45% (24 - Sleep)
080B0670 - 55% (18/19 - Poison/Venom, 25 - Seal)
080B0674 - 25% (26 - Haunt)
080B0678 - 20% (27 - Instant Death)
080B067C - 65% (20 - Delusion, HP Drain)
080B0680 - 35% (21 - Confuse, 34 - HP to 1)
080B0684 - Flat 60% (56 - Revive to 50%)
080B0688 - Flat 90% (57 - Revive to 80%)
080B068C - Flat 70% (73 - Revive to 60%)
080B0690 - 60% (8/9 - Attack debuffs, 28 - Curse, 32 - PP Drain, 80 - Curse)
080B0694 - 50% (35 - May ignore 50% of Def)
080B0698 - 40% (23 - Stun, 85 - Stun)
080B069C - Flat 100% (Def buffs, eRes buffs, Regen, Reflect, Break... seems to be the default for anything that either shouldn't fail or has its success rate calculated differently)

08079E58 - 70% (12/13 - Def debuffs)
08079E5C - 75% (16/17 - eRes debuffs)
08079E60 - 30% (22 - Charm)
08079E64 - 40% (23 - Stun, 85 - Stun)
08079E68 - 45% (24 - Sleep)
08079E6C - 55% (18/19 - Poison/Venom, 25 - Seal)
08079E70 - 25% (26 - Haunt)
08079E74 - 20% (27 - Instant Death)
08079E78 - 65% (20 - Delusion, HP Drain)
08079E7C - 35% (21 - Confuse, 34 - HP to 1)
08079E80 - 50% (35 - May ignore 50% of Def)
08079E84 - Flat 60% (56 - Revive to 50%)
08079E88- Flat 90% (57 - Revive to 80%)
08079E8C - 60% (8/9 - Attack debuffs, 28 - Curse, 32 - PP Drain, 80 - Curse)
08079E90 - Flat 100%


Ailment Recovery

Note: 5 or fewer turns must remain for this chance to occur.

(((Luck * 3) - (Turns * 5) + base_chance) * 655) >= rand()

Random number is 16-bit (Up to xFFFF)
If chance was 100% and you multiplied by 655, you'd get xFFDC.  Evidently, 656 would make x10040.

Base chances of recovering from an ailment, etc:

Attack = 30%
Defense = 20%
Resistance = 20%
Delusion = 30%
Confuse = 60%
Charm = 70%
Stun = 20%
Sleep = 50%
Psy-seal = 30%



Healing

This one is pretty simple.

If current HP > 0:
Restored HP = ((Base Value*ePower)/100) + (0~3)
If restored HP > max HP, overwrite with Max HP. Else add restored HP to current.

The 0~3 is basically calculated like so:
(0~3) = 3 AND rand()
Where rand() is a 16-bit value up to xFFFF. Change the 3 to change the amount that can be added to the final result.

I don't think it uses RNG when calculating the amount to restore outside of battle.



Regenerate/Coatlicue

Another easy one that's similar to the Healing formula, minus how the amount to heal is calculated:

If Duration > 0:
((Duration + 1)*Max HP))/10

So basically, having about 5 turns before the effect ends will net you 60% regeneration for that first turn. 3 turns will be 40%, 8 turns would be 90%, and so forth. You will be healed before the duration counter goes down at the end of the round.



Poison/Venom

This one is pretty similar to Regenerate, in that it reads the corresponding ailment value from the unit's RAM before making the calculations.

Located at 0812593C, it skips the calculation if Poison = 0; otherwise:
(Poison * Max HP)/10

A Poison value of 1 (regular poison) will deal about 10% of your Max HP in damage and a Poison value of 2 (venom) will deal about 20%. As an FYI, you can technically go higher than 2 despite there not being a graphic for anything higher than that (or even an effect for it). I should also mention that this does not actually apply in the field; that seems to be coded strictly for Poison values 1 and 2, and those are fixed at 5% for regular poison and 10% for venom as far as I can tell.

However, the field formula works a little differently. It only works if your Poison value is either 1 or 2, and each value uses a slightly different calculation. What I like about them is how they only deal roughly half damage when not in battle... Well anyway, here they are.

Poison: (Max HP + 10) / 20
Venom: (Max HP + 5) / 10




Summon ePow Boosts
((Tier x Tier) + Tier) x 5

"Tier" is a RAM value ranging from 1-4, depending on how many djinn of a single element are used in a summon. This formula doesn't account for differences when you follow a weaker summon with a stronger one, and the text that displays will only give you the difference (or, if the boost would put you above the 200 ePower cap, the difference between what it normally would be and the cap).

The boosts are normally 10-30-60-100 for each tier.

The formula reads more like this in the code:
((Tier x Tier) + Tier) = Tier2
(Tier2 x 4) + Tier2




So yeah! I'll work on scouring other topics for fomulas in a bit; please post any that you can think of, I would greatly appreciate it!


: Re: Master Formula List
: JamietheFlameUser May 25, 2014, 06:27:40 PM
Can you try this in "I don't need a degree in Assembly programming to understand this" version?

For example, that Agility formula confuses the hell out of me.


: Re: Master Formula List
: leaf May 25, 2014, 06:56:42 PM
I thought it was pretty clear since he said this afterward:
It boils down to:

Agility + (Agility x 0~6%) [÷ 2]
Although I'd have notated it as:

(Agility + Agility*(0~6%))*(Multi-turn penalty)
Multi-turn penalty = 1 if it's a character's first action that turn, and 0.5 otherwise.


: Re: Master Formula List
: Salanewt May 25, 2014, 07:55:38 PM
Jamie: No problem! The bolded parts are the formulas done in normal math, and the rest is the more technical stuff (or additional information, etc.).

Leaf: Done and done, thanks for the notation; it's clearer than the one I had before.


: Re: Master Formula List
: JamietheFlameUser May 25, 2014, 08:02:40 PM
Yeah, I somehow missed the bolded text.

Is the multi-action penalty really that simple? Personally, I'm under the impression that it stacks. That is, your third action is at *0.5 *0.5, and your fourth action is at *0.5 *0.5 *0.5. The reason I say this is that with one particular boss I made, in my many tests I frequently found that it would take one action before the entire party, and another action before Sheba (who was the party's slowest member due to her class). But it wouldn't take both of its other actions before Sheba got to act. Just one of them.

If you're wondering why Sheba was the slowest character, classes in this hack were rather heavily modded to emulate standard RPG/Final Fantasy archetypes instead of elemental Psynergy. Sheba's default class, the Magician, focused on damage-dealing spells of all elements. Attack power versus standard foes was good-to-mediocre, but was made up for by her ability to fairly consistently target a foe's weak point for heavy damage. The Magician has incredibly high HP and PP and decent Luck, but low Attack and Agility and abysmal Defense. She could tank base damage spells all day, but a standard physical attack from most foes would flatten her in 3 hits. Contrast Piers the Fencer, who would routinely take 1 damage from most foes' standard physical attacks, but would go down in 3 hits from any half-decent base-damage ability.

Also, weird things happen if you use the "extra turn next round" ability effect on a target multiple times. At 2 uses, the target treats their second action the same as their first, or something like that. For example, if I give an enemy 0 turns by default and another enemy targets it once with a Kite effect, it makes one action at 0.5x Agility. If another enemy targets it twice with a Kite effect, it makes one action at what seems to be either 1x Agility or 0.75x Agility.


: Re: Master Formula List
: Salanewt May 25, 2014, 08:39:50 PM
That's what I was hoping when I initially started looking into it, but I can confirm 100% that it doesn't stack for PCs. In the battle ram section, there's enough room for 20 turns per round from all units. PC turns are input first, and then are rearranged depending on agility values when enemy turns are calculated. Agility is recalculated by reassigning an action for the turn, but consecutive turns are always roughly half of the range of the first turn's agility. You can probably guess that those later turns would scramble around then...

However, looking again against an enemy with 3+ turns, it looks like enemy agility is not randomized with 0-6%. It also divides at a slightly different rate and does stack (I never looked into 3+ turn enemies before, sorry). For them, it looks like the first consecutive turn is multiplied by about 75% (or 0.75), docking off about 25% of the previous value. I'll take another look at the code and see if I can find exactly how it's calculated. Might even make a patch that does this for both PCs and enemies if I can do so without rewriting the entire function.

An enemy with 300 agility will have the following three turns:
300
225 (x.75)
150 (x.50)

Not sure what the values are for 4+ turns, but I'm going to take another look at the code and check for enemy turns this time.


Thanks for pointing that out Jamie!


: Re: Master Formula List
: JamietheFlameUser May 25, 2014, 09:08:45 PM
I know a player character cannot have more than 1 extra turn, either through equipment mods or the "Extra turn next round" effect. This I was already aware of. At the time, I had assumed that enemies followed the same Agility rules as the player, and so by "your" I was referring to an enemy. When I talked about "stacking" the Agility mod, I was referring to the multi-turn penalty stacking, not to stacking the "Extra turn next round" effect.

But even for player characters, stacking the "Extra turn next round" effect does strange things to your action priority. Targeting a player character twice in one round with that effect seems to cause both of their actions to be made at their full Agility stat. The first action always goes before the second action, however, even if your Agility roll for the second action is higher than for the first. Although, now that I think about it it's entirely possible that rolling higher Agility on the second action than the first pushes the priority of the first action up, to the point where you can act first in the turn even if you are slower than other characters.

Enemies are locked to a maximum of four turns. Even an "Extra turn next round" effect cannot override that limit, and an enemy can only gain 1 extra turn per round through that effect regardless of how many times they are targeted by it. But just as I said for player characters, the "Extra turn next round" effect does strange things to action priority when applied multiple times to a single target.


: Re: Master Formula List
: Salanewt May 25, 2014, 09:46:00 PM
Yeah, it's weird. My best guess is that it has something to do with ability and item effects not working 100% properly when it comes to granting extra turns (the ability effect being a buff that doesn't have stack). You can simply overwrite a PC's turn value in RAM and it'll work the way I've described, which I assume is how it is supposed to work. You can also do this in an enemy's RAM, so it isn't 100% locked to four turns; the downside is that the agility division stuff doesn't seem to work properly for 5+ turns (does the same thing as the PC agility formula without the randomization). You have to keep in mind, however, that you still only get a maximum of 20 turns total. PCs also get buggy if you give them too many turns...


So after testing with a Druj enemy, it seems that the agility ratings for consecutive turns are actually based on how many turns an enemy has; the x.75 multiplier doesn't apply with four turns. Likewise, the /2 thing also works for enemies if they only have two turns (which just reminded me that I knew the 0~6% thing didn't apply to enemies and forgot). This also happens to every turn after #2 if an enemy has more than four turns for some reason. So uh, I'll check the code to see if I can find the exact enemy turn formula.



: Re: Master Formula List
: JamietheFlameUser May 25, 2014, 10:05:00 PM
I suspect the enforced cap on turn counts is probably deliberate. Either that, or it was a bug that they never bothered to fix because it never, under any circumstances possible in-game, would actually need fixing.

It actually almost makes sense for having extra turns above the cap to behave the way it does, honestly. I would like to know what the exact mechanics are that result in the strange mess of action priority I've just described, though.

Maximum 20 turns total, huh? Okay. In that case, I'll remember not to give 4 turns each to enemies that come in groups of 5...


: Re: Master Formula List
: Salanewt May 25, 2014, 10:24:51 PM
Well, as it turns out, the function that reads and does the calculations for enemy turn order is entirely different from the one that calculates PC turns (and that is a part of the same function that deals with attack/psynergy/defend/etc. action commands in battle).

I've noticed so far that this function grabs both the agility and turn values. It kind of looks like this is one of the functions that Teawater took a brief glimpse at, but there isn't much documented here. It also looks like it calculates an enemy's turns differently depending on how many turns an enemy has, not using the amount they have. There's a branch for "if /= 4 turns," which goes to a "if /= 3" and so forth. I'll work on documenting this and figuring out exactly how it works.


Yep! I can't say if the RAM right after the battle stuff is used for anything or not either, so 20 is the effective cap right now. PCs also tend to bug out if you go much higher than 4-5 turns, but it's not like you can really do that anyway.

Edit: Looks like Teawater is taking a look. All I'll say for now is that, before calculating the new values, it does a series of checks that somewhat resemble the following:

If Total Turns /= 4, branch;
If Current Turn = 0 (first one), branch;
If Current Turn /= 1 (second), branch;
...
If Total Turns /=3, branch;

And so forth. Unless he wants me to explain what he's finding, then I will let him finish studying them and post the info himself.


: Re: Master Formula List
: Fox May 25, 2014, 11:02:02 PM
A Master Formula List? Sounds like a plan!

Do you plan on putting the addresses of code locations in the list for future reference? (Then again, the only people who are likely to use it is you and me... but still, someone else might one day join us in our studies. Unlikely, but you never know?)


and post the info himself.
For 4 turns, agility decrements by 1/6th each turn.
For 3 turns, by 1/4th.
For 2 turns, by 1/2th...

: from documentation - edits from me and Salanewt
Executes at the start of a round.
0811CFD0 = Start
 0811D0A2 = Write Enemy’s Slot ID to battle RAM
 0811D0A4 = Write Enemy Agility to battle RAM
 0811D0A6 = Write Enemy’s current turn (0-3)
 0811D0A8 = Check for 4 turns, branch if not equal - Turn 2: 5/6 agility ; Turn 3: 4/6 agility ; Turn 4: 1/2 agility
 0811D0D0 = Check for 3 turns, branch if not equal - Turn 2: 3/4 agility ; Turn 3: 1/2 agility
 0811D0EE = Check for 2 turns, branch if not equal - Turn 2: 1/2 agility
0811D126 = Call Enemy AI
0811D15E = End

Edit: @5+ turns... it seems like the first turn is 100%  agility, and remaining turns are 50% agility? (non-stackable) ; That is assuming that I looked at the code right, ofcourse? The way it was coded makes me think that 5+ turns wasn't supposed to be a feature in GS. (The same 1/2 agility code is used where necessary.)


EDIT: /= looks like division, you could try != or <>, though.


: Re: Master Formula List
: Salanewt May 25, 2014, 11:27:36 PM
Terrific, thanks for the info Teawater; I have added what is necessary to the first post. I also plan on including more technical info later, since it would be nice to have an area where those experienced with assembly hacking can just find all of the game's formulas.

On that note, can you think of any more formulas that I can add to this topic? I remember researching the HP Healing one back when I made the HP% formula, so I'll try finding the .png/.gif I stored it on. It's pretty much the same as what has been documented by countless others fortunately.


: Re: Master Formula List
: Rolina May 26, 2014, 02:29:02 AM
You found Ailment success?!  MOTHER FREAKING +1!  NICE JOB!


: Re: Master Formula List
: Salanewt May 26, 2014, 02:37:58 AM
Haha! Um, thanks for the compliment I guess. You know that Teawater is the one who found the formula a while back, right?


: Re: Master Formula List
: Rolina May 27, 2014, 11:03:00 PM
No, I didn't.  I'd been looking for that sucker for quite some time now, and the times I had visited in the past must have been before then.


: Re: Master Formula List
: Salanewt May 27, 2014, 11:55:02 PM
I think it might have actually been a little bit before your return in... was it November? You can catch up on the discussion here (http://forum.goldensunhacking.net/index.php?topic=2067.msg41674#msg41674) if you'd like, but it's more or less just us doing some practice calculations and basic balancing discussion.


But anyway. Unless Teawater wants to post it later, I'll see if I can search through that topic where they were discussing critical hit rate stuff and add it to the first post at some point. Can you think of any other formulas that should be added and/or researched? I know that the wiki(s) have a bunch, but I'd rather not search them and give myself a migraine just yet.


: Re: Master Formula List
: Fox May 28, 2014, 12:18:34 AM
Rolina did know about it at one point, she just forgot about it.

Remember this post? http://forum.goldensunhacking.net/index.php?topic=2067.msg37426#msg37426
Rolina posted before /and/ after it. On the same day, too.

Critical Hit Rate stuff was discussed in one of the DCrisis sections, http://forum.goldensunhacking.net/index.php?topic=2448.0

EDIT: What do you think about moving Joao's topics out of the DCrisis section?


: Re: Master Formula List
: leaf May 28, 2014, 04:08:06 AM
They probably shouldn't have been in dc to begin with, so yes. Move them out of there and into the general gs hacking forum.


: Re: Master Formula List
: jjppof June 01, 2014, 07:19:55 PM

Let me see if I understood this agility formula for PCs:

First check:
Calculates speed for each char

speed = {AGI + [(AGI * rand(0, 65535))>>20]}*k

k = 1, if PCs first move in turn,
k = 0.5, if PCs second or more move in turn

Second Check:

Check the max speeds and correct it id needed:
PC1: 999
PC2: 940
PC3: 884
PC4: 832

Third check:

If a certain PCs speed is the same of a enemy, PC goes first.

Fourth check:

The most left char has priority.


: Re: Master Formula List
: leaf June 01, 2014, 07:42:52 PM
Ignore the second check. That's the "practical use" of the formula. Sala was just saying what the highest speeds each char could have if you wanted a consistent turn order, without the rng ever causing a PC of lower agility to move before a PC of higher agility.


: Re: Master Formula List
: Salanewt June 01, 2014, 07:52:35 PM
Well, the second one isn't a check at all; merely an observation I made when I was researching this. If you cap your characters at those values, then you can guarantee your desired turn order 100% of the time. When you factor in gear, classes, buffs and so forth, then you can change around your turn order fairly easily. Granted, since reaching those agility values isn't very likely, you would almost be further ahead to try figuring out what agility values you would expect your characters to have by the end of the game and work with that.

In other words, exactly what leaf said! I think he once mentioned that dividing those values by two would give you your "practical use caps" for a normal save file.

Other than that, you've got it.


Edit: Healing and Regenerate formulas are up; they are pretty simple as far as calculations go. I probably won't do the HP% ability effects because those don't use a consistent formula, and I likewise won't add any custom formulas until there is a decent collection of vanilla ones in the first post.


: Re: Master Formula List
: jjppof June 02, 2014, 10:22:38 PM
The value returned by the Ailment Success formula is X.
   if X >= rand(0, 65535): the ailment was successful

Is it right?

--------------------------------------------

floor() always rounds down and to a integer?

-------------------------------------------

I didnt understand these 3 terms:

  • effect's base chance - are these values given?
  • vulnerabity's 25
  • unk_arg


: Re: Master Formula List
: Salanewt June 02, 2014, 11:44:16 PM
I think in this case, it's actually a random number from 0-99 (x00-x63) and it will always succeed if you get 100% or higher. I should probably add this to the first post...

Floor(luck) rounds down because it doesn't use decimals; for example, a luck value of 60 is pretty much the same as a value of 61 in this case. Both will be 30 when you divide them by 2.


As for the other three terms:

  • Base chance/rate: Yep! There's a spoiler tag in the first post that lists the rates along with most (if not all) of the effects that use those rates. A flat rate means that it doesn't use the formula, while the rest of them will.
  • Vulnerability 25: Each class has three values which correspond to ability effects; if there is a value above 0 in a class, then it will add +25% to the success rate of that effect. Enemies also have these three values that correspond to ability effects. If looking at them in the editor, they will be the numbers at the bottom of the class section and the ones above the elemental tables for enemies.
  • Unk_arg: We're not actually too sure on what it does. Teawater thinks it has something to do with multi-target effects, but I currently have a theory that it might have something to do with whether the "effect only" formula is being used or not. I'm sure one of us will test it in the relatively near future.

I hope this helps!


Oh yeah, I forgot to mention that the poison (battle) formula is up! Well, more like a calculation than a formula, but still. It's pretty powerful!


: Re: Master Formula List
: leaf June 03, 2014, 03:29:45 AM
floor() always rounds down and to a integer?
Correct. Floor(25.6) = 25. Floor(25.1) = 25. Floor(25.9999) = 25. etc. It's identical to a truncation for positive numbers, e.g. Floor(25.55) = 25 and Trunc(25.55) = 25, but differs in the case of negative numbers, where Floor(-25.55) = -26, and Trunc(-25.55) = -25. Since we pretty much never deal with negative numbers in games, the difference is mostly academic.


: Re: Master Formula List
: jjppof June 03, 2014, 09:56:03 PM
Which 3 values are you saying?
I see 2 values for party members in class section and 4 values for enemies in enemy section.
If one of these values is higher than 0, the Vulnerability  is 0.25? If not, 0?

just few enemies have all 4 fields 0 and they are strange enemies.
Can I let it 0.25 fixed?

And for a while, I will let the unk_arg = 1.

And I didnt undertand the spoiler table with the rates:
 35% (24 - Sleep), for example. The base value is 0.35 or 24?


: Re: Master Formula List
: Salanewt June 04, 2014, 01:46:37 AM
Oh yeah, I have a slightly different version of the editor that displays those correctly. Um...

The two values in the party editor are actually supposed to be four 8-bit values (with only three of them being used) rather than two 16-bit values. If you convert the number you see in that picture to hex format and separate the numbers, you should have effects x1F and x3C. Converting these to decimal again would give you ability effects 31 (may drain HP) and 60 (recover 50% damage to HP). As far as I can tell, most of the classes only use up to two vulnerability slots each despite three being available. As for the enemy editor, the box on the right does nothing at all; you can pretty much ignore it. Both classes and enemies can have them all at 0, or they can use all three.

I don't really understand what you mean by the ".25 fixed" part, would you mind clarifying that question a bit?

And lastly, the base values are whatever ends with a % symbol. The brackets merely list a bunch of the effects that use those percentages.


: Re: Master Formula List
: jjppof June 04, 2014, 02:19:09 AM
Nooooooow I got this "class ability"... nice nice nice....

If a certain class havent a certain ability, I let the base 0, right? Its summing...

------ wai-wait..... hahahaha editing.......

If a char has a class that has these abilities:
Sleep and Haunt (2426)

This char will put someone to sleep, so the formula is:

(((((levelRate - floorThing) * 3.0) + 0.35 + 0.25) * unk_arg) / 100.0)

noow... this same char will poison someone else, so the formula is:

(((((levelRate - floorThing) * 3.0) + 0.55 + 0) * unk_arg) / 100.0)

right?


: Re: Master Formula List
: Salanewt June 04, 2014, 02:37:27 AM
I think I understand what you're asking now! So...

The base rates in the spoiler are used in the formula regardless of whether a class/enemy is vulnerable to it or not (with the only exceptions being the flat success rates, as those don't use the formula). All a vulnerability does is add +25% to the value calculated earlier in the formula, and it won't do this if the class/enemy does not have a particular vulnerability. I guess it basically makes +0% the default, yeah.




: Re: Master Formula List
: jjppof June 04, 2014, 07:08:57 PM
(((((((Attacker's elemental level - Defender's elemental level) - Floor(Defender's luck / 2)) * 3) + effect's base chance + (vulnerabity's 25)) * unk_arg) / 100)  >= rnd())

for the elemental level, what is the element? Which of the four element I choose? Element of the skill I'm casting? Ask is good... hahahahaha


---------------------------

see how the code is:

function state_rate(caster, taker, state_id, skill){
    element = skill.element_id
    levelRate = 0
    if caster.isEnemy
       levelRate = eLevel_Enemy[caster.id][element] - eLevel_Ally[taker.id][element]
    else
       levelRate = eLevel_Ally[caster.id][element] - eLevel_Enemy[taker.id][element]

    floorThing = (caster.luck/2).floor

    baseChance = getBaseChance(state_id)

    unk_arg = 1

    abilities = getAbilities(caster)
    vulnerabity = 0
    if state_id in abilities
       vulnerabity = 0.25 
 
    value = (((((levelRate - floorThing) * 3) + baseChance + vulnerabity) * unk_arg) / 100)
    return value
  }

//in other function....
[...]
if rand(0,99) <= state_rate(caster, taker, state_id, skill)
        add_state(state_id)
[...]


: Re: Master Formula List
: leaf June 05, 2014, 04:25:24 AM
Yes, element of the skill you're casting. So if you're casting haunt, you would use venus elemental levels for the attacker and defender. If you're casting delude, you would use the jupiter elemental levels for the attacker and defender. And so on.


: Re: Master Formula List
: jjppof June 06, 2014, 01:35:11 AM
Ailment Recovery

(((Luck * 3) - (Turns * 5) + base_chance) * 655) >= rand()

Every turn I have to check this?


: Re: Master Formula List
: Fox June 06, 2014, 05:21:11 AM
unk_arg = 1
This should be 100. (Or you could leave it if you get rid of the /100 part.)

Think like this: a * 100 / 100 = a * 1

Anyway, it still looks like unk_arg is for multi-target.

First (Primary Target) = 100%
Second (Next to the target) = 60%
Third = 30%
Forth = 30%
Fifth = 30%
Sixth = 30%

But if you want to use decimals... then be my guest. ( a * # without the /100 in the equation. For example, a * 0.6)

Every turn I have to check this?
Yes.


: Re: Master Formula List
: jjppof June 06, 2014, 05:27:34 AM
Every turn I have to check this?
Yes.

But which states I have to check this? I cant have this check for downed, for example.

------------
and this unk_arg = 100 for the main target
                       = 60 to the next to
                       = 30 and so on
                                 ?


: Re: Master Formula List
: Fox June 06, 2014, 05:51:25 AM
There might have been a chance that I misread...

If you're asking where the checks should be done, I believe it is done at the end of a Round. (After everyone has taken a turn.) Hopefully I read that right. ; I believe that the check is made for each character, so that's probably how I misread.)

*Went back to quickly double check something*
81247F8 = End

Random chance of recovering from an ailment/debuff
(((Luck * 3) - (Turns * 5) + base_chance) * 655) >= 16BIT[rand()]
Attack = 30%
Defense = 20%
Resistance = 20%
Delusion = 30%
Confuse = 60%
Charm = 70%
Stun = 20%
Sleep = 50%
Psy-seal = 30%
08124810 = Start
08124850 = End

08124854 = Decrement Attack (De)Buff Turn Duration
081248B4 = Decrement Defense (De)Buff Turn Duration
08124914 = Decrement Resistance (De)Buff Turn Duration
08124974 = Decrement Delusion Turn Duration
(Sees clearly once again.)
081249B0 = Decrement Confuse Turn Duration
(Regains consciousness.)
081249EC = Decrement Charm Turn Duration
(Regains consciousness.)
08124A28 = Decrement Stun Turn Duration
08124A64 = Decrement Sleep Turn Duration
08124AA0 = Decrement Psy-seal Turn Duration
(Psynergy seal)
08124AF8 = Decrement Regenerate Turn Duration
(Recovering HP)
 08124B56 = [18][1]'s HP is fully restored!
 08124B68 = [18][1] recovers [22] HP!
08124BA8 = Decrement Reflect Turn Duration
08124BCC = Decrement Agility Buff Turn Duration
08124BFC = Unknown (Djinn-related)
08124CAC = Unknown (Djinn-related) (Linked from pub only.)
08124CC0 = Return
08124CC4 = Start
 08124D92 = [21] is set to [18][1]!
08124E1A = End

End of round (+ status effects)
08124E20 = Start of function.
08124F0C = [21] is set to [18][1]!
0812501E = Approximate location for setting Counter-Attack (Reflux) to 0.
081250A8 = [18][1]'s HP is fully restored!
081250B0 = [18][1] recovers [22] HP!
08125104 = [18][1]'s PP is fully restored!
08125120 = [18][1] recovers [22] PP!
08125150 = [18][1]'s Agility returns to normal!
0812517A = [18][1]'s Attack returns to normal!
081251A4 = [18][1]'s Defense returns to normal!
081251CE = [18][1]'s Resistances return to normal!
081251F8 = [18][1] sees clearly once again!
08125222 = [18][1] regains consciousness! (3306)
0812524C = [18][1] regains consciousness! (3310)
0812527C = [18][1] is no longer stunned!
081252AC = [18][1] wakes from slumber!
081252D6 = [18][1]'s Psynergy seal is gone!
08125300 = [18][1] stopped recovering HP!
0812530C = Call Decrement Reflect Turn Duration
0812532A = Reflect no longer affects [18][1]!
0812535A = End of function.
Apparently, my documentation didn't list it detailed enough...

"But which states I have to check this?" = states? *confused and feels lame for not understanding*

Each character has a series of bytes for each status effect counter. For example, you'll need 5+ Sleep count-downs, one for each PC and enemy, and 5+ for Stun, and everything else that counts turns.., I forget what happens when your character is Downed, but I could assume you could set all these count-downs to 0.



@unk_arg = Yes, pretty much... it stops at "Sixth" (11 characters) because going further is not supported.


: Re: Master Formula List
: Salanewt June 06, 2014, 06:05:58 AM
I think you're actually supposed to be cured of everything when you are downed though, so it shouldn't check in that instance anyway. It's actually one of the easiest ways to get rid of haunt if you're somehow broke and have Revive or something.

Cool, thanks for the info Teawater! I'll add it to the first post.


And... Researching the "effect only" formula right now. Some of it seems pretty complicated, but I have figured out this much so far:

((Output Damage * 100)/100)/(Multi-Penalty)
Multi-Penalty = 1 for primary target, 2 for secondary, 5 for tertiary, 10 for quaternary


I'm still trying to figure out exactly how "Output Damage" is calculated, but it does involve using the difference between the attacker's ePow and the defender's eRes stats. This shared function also has some code that defines the max eStat difference range to be from -199~200, so a difference that is a greater or lesser amount than one in that range will simply be overwritten with the floor or cap. Basically, this means that there is no difference between ePow/eRes stats of 0/200 or 50/250 (ignoring the cap of 200 of course).


Edit: Renamed "unk_arg" to "multi_arg" in the formula, seeing as it's not an unknown variable anymore.


: Re: Master Formula List
: leaf June 06, 2014, 08:06:27 AM
Multi-Penalty = 0 for primary target, 2 for secondary, 5 for tertiary, 10 for quaternary
So I'm guessing you meant it should be 1 for the primary target, unless it has infinite success rate >_>


: Re: Master Formula List
: Fox June 06, 2014, 09:19:07 AM
--- Part 1: Defense Mod(?) ---

@Multi-target for Effect Only: Are you sure that's multi-target?

"1" = 1/2 (0200064B is 1 when Isaac's defending. Maybe that's how Defend's defense is done?)
"2" = 2/5
"3" = 1/10

So that you can understand how the scaling looks:
"1" = 5/10
"2" = 4/10
"3" = 1/10


--- Part 2: Multi-target damage ---

Anyway, as for Multi-Target Damage, the percents are:

100%
50%
30%
10%
10%
10%


--- Part 3: My attempt to look at the formula ---

For the formula, I'm seeing..

damage * unknown * (multi_target_value_out_of_100/100) * defense_mod

Notes:
damage = includes the elemental mod.
unknown = Too lazy to look up at the very moment.
multi-target = see second part of post.
defense_mod = See first part of post.


: Re: Master Formula List
: jjppof June 06, 2014, 01:01:11 PM
I will try to express me better...

Every turn end I have a function that apply the recovery formula and update the states tuns count:

function update_state_turns(){
   foreach state in chars: //loop all states of all chars in battle
      actualChar = state.getActor
      luck = actualChar.luck
      actual_state_turn = state.turnCount
      recoveryBaseChance = getRecoveryBaseChance(state.id)
      formulaValue = (((luck * 3) - (actual_state_turn * 5) + recoveryBaseChance) * 655)
      randomNumber = rand(0, 65535)
      if formulaValue >= randomNumber
        remove_state(state.id)
      else
         state.turnCount -= 1
   }
}

function end_turn{
[...]
   update_state_turns()
[...]
}


What I'm asking is:
this method update_state_turns is checking all kinds of states, including downed (hahahahaha every end turn a char has a chance to revive). Beyond this state, which others can't be checked?
I dont know, but haunt and poison cant be recovered by this formula, I guess....


: Re: Master Formula List
: Salanewt June 06, 2014, 03:02:46 PM
leaf: Oops, that's right! Fixed it.

Teawater: I was pretty sure, but I just double checked and I think you might be right. Defending cuts almost all damage in half, and I tested the code with a 3-target Drain spell. Whenever I switched the primary target between two enemies, the secondary enemy always took half the damage it took when it was the primary target; neither of them had the defend command to begin with. That's why I was mistaken.

That being said, I don't see one for the "95% damage decrease" effect in here. I guess that might be because it was added in GS2 and Camelot figured out a better way to calculate it. Or something.

As for attempt 3, that's pretty much what I have now. That "unknown" part is what I'm looking into right now, and that's what uses the ePow/eRes calculation code to modify the base damage. It looks like almost every damage formula uses it, so figuring this out would make figuring the rest of the formulas out much easier. I think.

And... here's exactly what I have now in my .txt file, with your corrections in place:

Base Damage
(
(Output Damage(multi_mod * 100)/100))*def_mod
"multi_mod" = 100% for primary, 50% secondary, 30% tertiary, 10% everyone else
"def_mod" = 100% for normal, 50% for 50% damage off, 40% for 60% off, 10% for the 90% effect. Probably hard-coded in every damage formula, yay!

The "Output Damage" part is what is calculated with base damage and the eStat differences; I've figured a fair bit of it out, so I'll continue doing a little more research until I get back to work. It's temporary until I figure out exactly how it is calculated, in which case it will be replaced with the earlier parts of the formula. It also seems to happen in the "multiply by 1.28?" function that you weren't too sure about in the data document. It also looks like I don't have your "unknown" modifier in the formula; would you mind looking into that at some point while I research this other part?

Edit: When the time comes to add the completed formula to the first post, I'm probably not going to bold the "def_mod" part because that's seems to be a part of the damage formula out of laziness. I don't know. The 95% one isn't in here anyway, so... yeah.


jj: I think this function is supposed to apply to every unit at the end of the round, so everyone should be finished their own turns by then. It also shouldn't apply to poison/deadly poison, haunt, death curse/countdown, and death/downed. Or buffs! :happy:








: Re: Master Formula List
: jjppof June 06, 2014, 04:12:04 PM


jj: I think this function is supposed to apply to every unit at the end of the round, so everyone should be finished their own turns by then


Yeah, in the way that the code is, It is applying for everyone.



It also shouldn't apply to poison/deadly poison, haunt, death curse/countdown, and death/downed. Or buffs! :happy:



Thats the information I wanted!! Thanksss  :happy:


: Re: Master Formula List
: Salanewt June 06, 2014, 05:51:50 PM
Happy to help!


Also, I think I have almost figured out the damage calculation stuff. I will do it later because it's just a tad confusing to put into standard mathematical notation. It essentially boils down to "(eStat_Diff / 2) = additional % of damage to add/subtract" though, but it's not 100% exact when the difference is low. Or, rather...

Where eStat_Diff = attacker's ePow - defender's eRes.

eStat_Diff of 200 = 200% damage (you have 200 and they have 0)
eStat_Diff of 100 = 150% damage
eStat_Diff of 0 = 100% damage
eStat_Diff of -100 = 50% damage
eStat_Diff of -199 = 0% damage

Give or take a point or two sometimes, particularly for low eStat differences. Unlike the rest of the formulas, the "effect only" one does not use RNG; damage should be pretty consistent because of this.



: Re: Master Formula List
: Fox June 07, 2014, 02:36:23 AM
@Multiply by 1.28

Take a look at the table the function reference... see what happens when you multiple by 1.28? The numbers should match:

Examples:
0x64 * 1.28 = 0x80
0xC8 * 1.28 = 0x100

As you can see, the numbers (0x80 and 0x100) represent the 0x64 and 0xC8 numbers, pretty much... but it's as though invisible decimal places have been added. (If it helps you understand.)

In the end, I think it might be a similar trick to how random numbers are multiplied and divided/shifted, except they try to complicate it a bit.

That's how I see it, anyway.

---

@The unknown I was talking about: I think it was a value retrieved from the stack. The instruction of note is at 08121354, so I was a bit lazy to scroll for where a value was placed there.


--

Edit: Almost forgot, but can you verify if the def_mod is the same percentage for the other formulas as well? ("1" will probably still be 50%, but the others?)


: Re: Master Formula List
: Salanewt June 07, 2014, 03:26:54 AM
Yeah, I saw the table! Everything in the spoiler is what I have noticed so far by looking through that function; the "during" segments are the 1.28 thing, while the BL and "after" segments only seem to apply to the effect only formula. It seems that having a negative eStat difference will grab negative numbers from the table, while a positive eStat one will grab the others.

(((Base Damage * eStat_var) * 100)/[LSR 10] * unk_arg * (multi_mod * 100)/100)) * def_mod
"multi_mod" = 100% for primary, 50% secondary, 30% tertiary, 10% everyone else
"def_mod" = 100% for normal, 50% for 50% damage off, 40% for 60% off, 10% for 90%


BL (080AD130)
r2 = x100
r0 = ePow-eRes
r1 = 0
r5 = x100
- r2 added to r5 for BL (080B02DC)
r6 = base damage

During (1):

r0 = ePow-eRes (moved to r6) -> x05
r1 = 0
r2 = xC8 (200, sets ePow/eRes difference cap)
r3 = xFF38 (-199, set ePow/eRes difference floor)
r5 = #080C6B04

During (2):

r0 = 5
r1 = 0 -> +1 (loop)
r2 = +4 (loop)
r3 = xC8 -> LDSH r12 + r4 (loop) [x64 on the first loop, x00 on second, xFF9C on third]
r4 = 0 -> +r2 (loop, moved from r2)
r6 = ePow-eRes
r12 = #080C6B04 (moved from r5)

During (3):

r0 = 0 (if ePow-eRes difference is positive), xFF9C (if negative) -> positive sum of r6-r0 -> sum of (r0*r2)
r1 = 0 -> x64
r2 = 0 -> x80
r5 = #080C6B04 -> 0 (if positive), xFF80 (-127, if negative)
r6 = ePow-eRes

During (4/after division)

r0 = r0/r1
r1 = x60
r2 = x64
r3 = r0-r1
r5 = 0 (if positive), xFF80 (-127, if negative)
r6 = ePow-eRes
r7 = 0 (moved from r8) (if = 1, r3 = r0 LSR x1F, then (r3+r0)/2; doesn't seem to happen with effect only formula)

End (During (5)):

r0 = r0+r1
r1 = x100

After:

r0 = ePow-eDef output damage? -> x100 (moved from r5) -> r0*r3 -> Output Damage
r1 = x100
r2 = x64
r3 = base damage (moved from r6) -> r3*r0 (before r0 = x100)
r4 = ??? (x08 or x0C so far)
r5 = x100
r6 = base damage


The downside is that the linked function was hard to follow and I was doing this late last night before bed, so a couple of the registers might be incorrect here or there... But I think I understood most of it. I do know that for the initial linked function (not the 1.28 one), it basically divides the output damage by 16 (LSR x10) before returning to the main formula. The looping part also threw me for a loop (haha) for a bit, but I think I still understand it well enough.


Unknown: Groovy, I might take a look at that soon-ish then.

As for the def_mod part, I can definitely look into it later. I'm hoping that, by figuring out exactly how this 1.28 function works, I/we can use our research to discover exactly how the other damage formulas are laid out. Especially since it seems like most (if not every) damage formula uses it.


: Re: Master Formula List
: Fox June 07, 2014, 04:03:35 AM
@jj: Huh... so you call those states? I suppose that's fair enough since the game refers to them as Status.. ("Normal status." is a string in the game.) ; I'm more familiar with calling them status effects/ailments/(de)buffs. ; As for the plural form of status, I would have probably used statuses since "state" and "states" seem to go together, but I'm sure many people have many ways of looking at it?

I suppose the spoiler that I had earlier might hint which statuses are checked, but it's been like forever since I've looked into it, so...

@Salanewt:
"(Output Damage(multi_mod * 100)/100))*def_mod" = Multiplying by 100, only to divide by 100... that reverts the number back to what it was before you multiplied, so there's likely an error there.

@Unknown: Good, I guess that'll save me the time it takes to look it up, I guess.

@def_mod: Sounds good!!


: Re: Master Formula List
: jjppof June 07, 2014, 12:31:58 PM
If everyone here say status, I can say status too.  :happy:


: Re: Master Formula List
: Salanewt June 07, 2014, 04:03:05 PM
Probably, that formula is horribly incomplete. Though taking another look at it, the "Output Damage" part should multiply with the bracket stuff before getting divided... Although that's a placeholder for the rest of the formula anyway, so it probably doesn't matter quite as much if it weren't a placeholder.

But basically, this one formula that I'm trying to look at doesn't actually use the base damage of the ability in its calculation; that comes after all of the complicated eStat variation stuff. I think the end result will probably look something like this:

(((Base Damage * eStat_var) * 100)/[LSR 10] * unk_arg * (multi_mod * 100)/100)) * def_mod
"multi_mod" = 100% for primary, 50% secondary, 30% tertiary, 10% everyone else
"def_mod" = 100% for normal, 50% for 50% damage off, 40% for 60% off, 10% for 90%

The "eStat_var" is what I'm trying to figure out right now. It basically handles the variation as "ePow - eRes" for the ability's element (should it have one), and uses that number between -199 and 200 for calculating something. I'm pretty sure that also comes from the effect only formula, but I'll double check later (haven't really taken a look at the code before this one BL). It also looks like it's used by almost every other damage formula, so I'm probably going to post it as its own formula when I'm ready to add the finished version of this. The downside is that it looks like there are certain parts that are either not used by this damage formula or are used only under certain circumstances.

Edit: The difference will effectively appear to be "(Base Damage * (eStat_diff))/100" or something. For example:

(50 * (200-50))/100
= (50 * (150))/100
= 7500/100
= 75

But the formula itself is much more complicated than that. I have no idea why this is the case. Maybe the programmer who designed this had an hourly wage as opposed to a contractual one and stretched their efforts needlessly just to go home with a higher pay cheque. Maybe not.

Anyway, back to the pre-edit stuff!


And I'll take a closer look at the "multi_mod" stuff a bit later as well. I could have sworn that something was multiplied by 100 at some point, but there's also a good chance that I messed that up because it was later at night. Although that could also have been for the def_mod... You know, I think it was. I'll check later though!


Oops, I had one register incorrectly labeled as the element ID rather than the eStat difference. Fixed!



: Re: Master Formula List
: Fox June 08, 2014, 02:52:38 AM
Turns out the unknown I didn't know was the multiplier that ability effects use.

This starts right at Effect Only formula:
(http://i.imgur.com/l5HB2NR.png)
Just a moment ago, I was working on this incomplete image tutorial. Not sure if I'll finish it off or not, though.

Yes... imgur is good. photobucket resizes large images, but imgur doesn't!


: Re: Master Formula List
: Salanewt June 08, 2014, 05:21:53 AM
Nice work! I've added a bit more to the WIP formula I have thanks to your post:

If Cloak is not in use;
And if ailment success /= 0 (if there is one);
And if damage > 0;
(((Base Damage * eStat_var) * 100)/65536 * ability_mul * (multi_mod * 100)/100)) * def_mod
"ability_mul" = Ability effect multipliers (see respective multiplier effects), defaults to 1 when there is no effect
"multi_mod" = 100% for primary, 50% secondary, 30% tertiary, 10% everyone else
"def_mod" = 100% for normal, 50% for 50% damage off, 40% for 60% off, 10% for 90%

Obviously the "eStat_var" part is the incomplete part, but I haven't quite worked out a good way to write out an effective formula for it. Getting there though.

The linked function in the second red section links to another function, and that is the function that does all of the weird calculations with the base damage and eStat difference. It's then multiplied and divided a bit before being brought bad to the original function. To make a long story short, you could expect to see values well over x100000 if following the formula as it's coded in the game.


I was also mistaken on the "effective calculation" before, but I don't really care about fixing that one when this is the important one...


Edit: I removed the "Confirmed" and "Unconfirmed" headers from the first post because it kind of looks like we're on a roll with confirming them. So... the first has been replaced with "Vanilla" for now. I'll probably change it again later though, it's just a placeholder until I decide whether to add a second section for "Custom" formulas that are available as hacks or just keep it as a list of strictly unmodified formulas. About 99% sure it will be the latter.


: Re: Master Formula List
: Fox June 08, 2014, 06:29:22 AM
Nice work! I've added a bit more to the WIP formula I have thanks to your post:
Thanks, and you are welcome.

I could have sworn that something was multiplied by 100 at some point
I still don't remember seeing anything about the multi_mod being multiplied by 100... Hmm... But if you find anything, then be sure to enlighten me. :)

By the way, I've just updated my image tutorial in my previous post. It seems that's all the effect-only stuff... (I omitted the "But it has no effect" part in case it was used elsewhere as well? Not sure.)

"Confirmed" and "Unconfirmed" headers from the first post because it kind of looks like we're on a roll with confirming them.
Sounds good. I was wondering what the point of having those were if we were most likely not going to have any unconfirmed ones. (Or as many, anyway.)

---

I believe you forgot to list the Critical Hit/Unleash formula(s)... (Along with the the effects that are related.)

----

Looking at the Added Damage formula, I see something that tells me Attack + (Attack/4) as part of the formula... It might be with just one enemy, though? 304 Wild Gryphon

Added Damage:

max(0, userAttack - targetDef + (abilityPower * 2)) * elementalFunction(eStatDiff)

Note: It's possible that abilityPower being multiplied by 2 is undone... in which case, it could be that (userAttack - targetDef) is divided by 2...?

Multiplier:

max(0, userAttack - targetDef) * elementalFunction(eStatDiff) * abilityPower / 10


---
Now back to the 1.28 function: If you look at the call at 080B0350 (and the code around it.), it's almost like it's doing x*128/100. (Unless I'm mistaken?) That's mainly what's needed, however, I have a feeling the table was suppose to be used to change the scaling? (But they ended up keeping it linear?) Probably similar to Stat Growths? Hm..

if arg r1 = 0: (ePow - eRes) * 1.28 + 0x100

if arg r1 = 1: (ePow - eRes) * 1.28 / 2 + 0x100

Theories: (wip?)
If you have an eStatDiff of -200, the damaged returned might be 0. (if r1=1: 0x80)
eStatDiff of -100, you get 0x80... (if r1=1: 0xC0)
eStatDiff of 0, you get 0x100... (if r1=1: 0x100)
eStatDiff of 100, you get 0x180... (if r1=1: 0x140)
eStatDiff of 200, you get 0x200... (if r1=1: 0x180)

It pretty much looks like the function at 0x080B02DC returns base 16 percentages. So the parent-level function will need to shift 8-bits out after multiplying? (Um... will still need to look into this further, though.)

Hmm.. By the way, Is the r2 arg for the function at 080B03E0... is it a percentage done in base 16? If so... hehe.... so two base 16 percentages are multiplied together, making it so you have to shift 16 bits.


: Re: Master Formula List
: Salanewt June 08, 2014, 01:42:49 PM
Multi: Yeah, I've been thinking about it and it doesn't make sense to me anymore. Just removed it from the WIP formula in my text file.

Critical hit, right. Thanks for posting it! I'll wait until we're a bit closer to figuring out this eStat calculation stuff before adding them, since it may help.


As for that last one, yep. This is basically what I have as far as tracking the difference (excluding mostly irrelevant registers):

During (1):
r0 = ePow-eRes (moved to r6) -> x05

During (2 - Loop):
r6 = ePow-eRes

During (3):

r0 = 0 (if ePow-eRes difference is positive), xFF9C (-99, if negative) -> positive sum of r6-r0 -> sum of (r0*r2)
r1 = 0 -> x64
r2 = 0 -> x80
r5 = #080C6B04 -> 0 (if positive), xFF80 (-127, if negative)
r6 = ePow-eRes

During (4 - Post-division)

r0 = r0/r1
r1 = x60
r2 = x64
r3 = r0-r1
r5 = 0 (if positive), xFF80 (-127, if negative)
r6 = ePow-eRes

During (5 - End):

r0 = r0+r1
r1 = x100


So basically, the value is multiplied by 128 at some point and then divided by 100 shortly after. It kind of looks like 256 is added to it at some point as well, which is when it gets back to the previous function:

r0 = ePow-eDef output damage? -> x100 (moved from r5) -> r0*r3 -> Output Damage
r1 = x100
r2 = x64
r3 = base damage (moved from r6) -> r3*r0 (before r0 = x100)
r4 = ??? (x08 or x0C so far)
r5 = x100
r6 = base damage

And then it's multiplied by 100 again after the output is multiplied by the base damage, but before it is divided/shifted at the end of the function.


Looking at the image again, it's kind of weird that they added exceptions for Doom Dragon in this part of the code rather than have an external function like with Agatio/Karst.


: Re: Master Formula List
: Fox June 08, 2014, 02:07:04 PM
Seems after you understand it a bit, the functions aren't really that confusing... Except for the reason behind making it longer than it needs to be.

By the way, Even the documentation at GameFaqs seem to have it right (At least I think they do? I only checked the Element part.):  http://www.gamefaqs.com/gba/561356-golden-sun-the-lost-age/faqs/22880

Special Physical Attacks:
    Damage = [Base Damage * Mult Mod] + Add Mod
    If Elemental, Damage = [Damage * (1 + Relative Power / 400)]

Basic Psynergy Attacks:
    Psynergy has own Base Damage
    Damage = [Psynergy Base Damage * (1 + Relative Power / 200)]


They're calling eStatDiff by Relative Power. :)

! + (100 / 400) = 5/4 = 125%
1 + (100 / 200) = 3/2 = 150%


: Re: Master Formula List
: Salanewt June 08, 2014, 03:24:13 PM
Yeah, I noticed that Gamefaqs thing as well a couple days ago. It is pretty accurate as far as end result, but it would be cool to understand how exactly it's done in the code for future reference. It would also be less confusing to call it relative power now rather than change it in the formula later at any rate! :happy:

Plus, thinking about it, their calculation for relative damage makes much more sense. The reason why I have been ignoring it is because it's done differently in the code, and the first post is pretty much reserved for formulas as they are executed in the code; makes it less confusing for those who may want to look at the code themselves in the future. Plus with the whole "lacking decimal numbers" thing, you basically have to multiply a number by a certain amount and then divide it to get a fraction.

If Cloak is not in use;
And if ailment success /= 0 (if there is one);
And if base damage > 0;
((Base Damage * Relative Power) * ability_mul * multi_mod /100) * def_mod
"ability_mul" = Ability effect multipliers (see respective multiplier effects), defaults to 1 when there is no effect
"multi_mod" = 100% for primary, 50% secondary, 30% tertiary, 10% everyone else
"def_mod" = 100% for normal, 50% for 50% damage off, 40% for 60% off, 10% for 90%

So that's basically what the full formula comes to. The "Relative Power" bit (as it shall now be called to avoid confusion) is the part that we should try confirming at some point.


: Re: Master Formula List
: Fox June 08, 2014, 04:05:54 PM
Okay...

I'm just saying that the guide is very accurate at the simplifying part.

Remember these?
if arg r1 = 0: (ePow - eRes) * 1.28 + 0x100

if arg r1 = 1: (ePow - eRes) * 1.28 / 2 + 0x100

All you have to do is divide by 256 or 0x100, and you get these: (Literally.) The formula that I made above was before I checked with the Faq.
if arg r1 = 0: (ePow - eRes) /200 + 1

if arg r1 = 1: (ePow - eRes) /200 / 2 + 1

Relative Power ... and the "what it should be" sound like two slightly different things? Um? I think.


: Re: Master Formula List
: Salanewt June 08, 2014, 04:18:03 PM
That's certainly true, yeah! Like, I will add the "simplified" version(s) to the first post, but I didn't want to put them up until after we confirmed the formula as calculated in the function (one for the casual readers, and one for the coders).

I've also been pretty busy with my studies, so I haven't really been looking into this a lot lately... Sorry! Is the bottom one what I should add to the first post then?


: Re: Master Formula List
: Fox June 08, 2014, 04:24:28 PM
Yes. The code does divide by the 256 that I just posted in my previous post...  In three different functions (The parent functions to the child function you were probably looking at.).... (It's actually like hitting two birds with one stone, because it's shifting the other bits due to multiplying other numbers as well.)

Function 1 shifts 9 bits... 8 from the percent, 1 from actual dividing of attack - defense... I think
Function 2 shifts 16 bits.... 8 from the percent, and 8 from the percentArg. And same with Function 3.



If Cloak is not in use;
And if ailment success /= 0 (if there is one);
And if base damage > 0;
((Base Damage * ((Relative Power/200) + 1)) * ability_mul * multi_mod /100) * def_mod
"Relative Power" = User's Elemental Power - Target's Elemental Resist
"ability_mul" = Ability effect multipliers (see respective multiplier effects), defaults to 1 when there is no effect
"multi_mod" = 100% for primary, 50% secondary, 30% tertiary, 10% everyone else
"def_mod" = 100% for normal, 50% for 50% damage off, 40% for 60% off, 10% for 90%



Fixed! (I think?)


Formulas: (Mostly a WIP, so you can probably confrrm them, if you want.)

Added Damage: (Left out crit/multi_mod/effect_mod)
max(0, max(0, ((userAttack - targetDef) / 2) + abilityPower) * (1 + (Relative Power/400)))
max(0, max(0, ((userAttack - targetDef) / 2) + abilityPower) * (1 + ( Int(Relative Power*256/400)/256 )))
max(0, max(0, ((userAttack - targetDef) / 2) + abilityPower) * (1 + ( Int(Relative Power*0.64)/256 )))

Multiplier: (Left out crit/multi_mod/effect_mod)
max(0, max(0, (userAttack - targetDef) / 2) * (1 + (Relative Power/400))) * abilityPower / 10
max(0, max(0, (userAttack - targetDef) / 2) * (1 + ( Int(Relative Power*256/400)/256 ))) * abilityPower / 10
max(0, max(0, (userAttack - targetDef) / 2) * (1 + ( Int(Relative Power*0.64)/256 ))) * abilityPower / 10

Effect Only:
((Base Damage * (1 + (Relative Power/200))) * ability_mul * multi_mod /100) * def_mod
((Base Damage * (1 + ( Int(Relative Power*256/200)/256 ))) * ability_mul * multi_mod /100) * def_mod
((Base Damage * (1 + ( Int(Relative Power*1.28)/256 ))) * ability_mul * multi_mod /100) * def_mod

Where /200 and /400 occur, there is a rounding error, because the game rounds off to the nearest 1/256th before actually multiplying to anything.... To fix the rounding error, multiply the numerator by 256, get a decimal number, remove the decimal places, and then divide by 256 (To undo what you multiplied by earlier. Because * 256/256 is *1, which doesn't change anything.)


By the way, you left out multi_mod and effect_mod from your healing formula. (I'm going to assume the majority of the damage functions use these, so you can probably abbreviate on them.)

: Some battle related functions that go with stats - Their stat-like behavior is probably why they're in Party Mechanics
080AFF28 = get_summons_total(addr) addr is where to list the summons.
080AFF7C = get_summon_address(summon)
080AFF94 = obtain_summon(summon)
080AFFAC = get_elemental_levels(pc,pc_ram_addr,sp) pc can be 0-7 for PCs, or 8+ for enemies.; Return 0.
080B0028 = get_elemental_level(pc,element)
080B005C = get_enemy_elemental_attr(enemy)
080B0084 = update_elemental_pow_resist(pc_slot, pow_res_ram_addr) Includes base levels and djinn, not sure about item bonuses.
080B0144 = find_matching_class(pc,pc__ram_addr,item)
080B0288 = get_class_address(class)
080B0298 = Djinn set/removal calculations (grabs/updates class ID (possibly abilities too)? and links update_elemental_pow_resist)
080B02D4 = Call 080B0298.
080B02DC = toElementalHexPercent(Relative ePower, eHalfEffective) (Converts to hex percentage. (Multiply by 1.28 or 0.64 and add 256. Equivalent to (1 + Relative Power / 200) and (1 + Relative Power / 400), but those have a rounding error.) In parent function mult. with value and shift out 8 bits.) It’s like converting 100 to +50% in hex. (If eHalf, +25%) (150% and 125%)
080B0378 = Random Number Generator //Returns 16-bit (x0000-xFFFF)
080B039C = Return random number x0-x63.
080B03AC = calcAttack(attack,targetDef,power,Relative ePower) targetDef could be 100%, 50%, or 0% of value depending on effect. Used by Added Damage & Multiplier
Return max(0, max(0, ((userAttack - targetDef) / 2) + abilityPower) * (1 + (Int(Relative ePower*256/400)/256)))
080B03E0 = calcCast(abilityPower,Relative ePower,percent) (From left?) elemental pow/resist related  *Called from Summon and Effect Only formulas…
Return abilityPower * (1 + (Int(Relative ePower*256/200)/256) * hexPercent
080B0408 = calcHeal(Same as above, but it multiples arg r1 by 2 and subtracts by 200 at beginning.) (From Center?) *Called from Healing formula(s).
Return abilityPower * ((Int(ePower*256/100)/256) * hexPercent

080B0434 = get_elemental_attr(pc)
080B0460 = get_item_criticals(pc_addr)
080B04BC = unleash_check(pc) Returns ability to cast. (Unleash if chance succeeds, or attack.)
080B0514 = Base Ability Effect Success Chances?
080B06A8 = Return 1 if enemy found in table 080C6B18, else 0.
080B06C8 = Return 1 if enemy found in table 080C6B76, else 0.
080B06E8 = is_vulnerable/weakness(pc_addr, ability_effect)
080B0740 = Ability_Effect_Revives(ability_effect) //If effect revives, return 1, else 0.
080B075C = Calculate_Ailment_Success(attacker,defender,element,effect,percentMod)

I figure the three functions calcAttack, calcCast, calcHeal, are the base calculations, while the battle mechanics themselves use modifiers like multi_mod, effect_mod, and def_mod.


It appears that PP Recovery doesn't have a random value that gets added.


: Re: Master Formula List
: Fox May 07, 2017, 04:47:31 AM
I see this is a master formula list... but it is pretty small... It also looks like most formulas use a random number... and since the RNG is like a formula, I have a question? Does it fit here as well?


GS1/GS2:
seed = seed * 1103515245 + 12345
return seed << 8 >> 16 (16-bit random number.)
The initial seed should start at 0.

GS3: (Seems to do this type of thing in various places, but I'm not certain if there are any exceptions.)
seed = seed * 69069 + 1
return seed >> 16

Another function will do this after updating seed:
return ((seed >> 16) * range) >> 16 (Random number from 0 to range-1)
Not sure if the initial seed is 0 or not.

In all cases, seed is a 32-bit number.
Both RNGs are listed here: https://en.wikipedia.org/wiki/Linear_congruential_generator


GS3 might have another function, because the one listed with range is from 02171A64... and my scanner detects it only being called FIVE times!:
02171678
021716D4
02171810
021718BC
02172FF4


Other random number calculations found (Same seed * 69069 + 1 stuff , all numbers from in battle....)
02003624 (Arm function)
020059C0
02015D80
0202D454
0210F750
02110C78
021120B0,02112108
021194C4
02119634 = Function for calculating it as it should have been....
02119A54
0211AE54
0211CD4C
...there are way too many to list... of course, most of them are appearing with-in functions and are not a function themselves. (Except for two and maybe three/etc.)
Perfect to use as an access polnt to studying GS3's data, though!
(Also, compilers are weird, so not so sure about blaming the dev for having it everywhere.... Since a simple define in c language(s) is not a function, but some sort of substitution/etc..)


: Re: Master Formula List
: Salanewt May 08, 2017, 12:38:29 AM
The RNG function fits!

Also, thanks for the contributions to this topic. :P


: Re: Master Formula List
: Salanewt September 24, 2017, 03:43:06 AM
Okay, I threw a new one in here involving the ePower boosts you get from summons! I really need to update this thing more. :P


: Re: Master Formula List
: Fox September 24, 2017, 04:27:36 AM
Good job! But I recommend also listing the 10, 30, 60, 100, thing as well.. (And if GS1 can have summons that raise EPower for multiple elements at once or not?)


--
Also, I thought I found an error with one of the percents somewhere.... that I think I messaged you about a very long time ago... I can't remember if you ever fixed it or not, though.


---
I think I'd like to know which abilities have the Stun effect... so I can figure out why one stun generates three RNs... ; Would be funny if it was to mimic the animation or something. ; Otherwise, it could be related to a Type...? (Weapon Type, Ability Type, etc?)


: Re: Master Formula List
: Salanewt September 25, 2017, 05:54:17 AM
Oh yeah, that's a good point; I'll add it soon!

I think I remember you mentioning that once? I just fixed Sleep's percentage earlier so that may have been it.


As for the other Stun, I think Fire Puppet uses it (effect 85). Not sure about any others, since usually an ability will use 23.


: Re: Master Formula List
: JamietheFlameUser October 02, 2017, 12:28:09 PM
I think there are some Stun-inducing Djinn in GS2 that use effect 85. It's probably intended to increase the chance of it hitting by attempting to proc multiple times.


: Re: Master Formula List
: Fox November 06, 2017, 03:08:23 PM
x/0=x/1


: Re: Master Formula List
: leaf November 06, 2017, 06:13:10 PM
To clarify the above post, if the game would divide by zero, it instead divides by 1.


: Re: Master Formula List
: Fox November 06, 2017, 10:53:06 PM
Well yes, that's pretty much it.
Technically, if the game divides by 0 or 1, it just returns the numerator. (As in, the instruction (@03000568) to move that into the Return (r0) is only executed for these two cases.)


Sorry, the copyright must be in the template.
Please notify this forum's administrator that this site is missing the copyright message for SMF so they can rectify the situation. Display of copyright is a legal requirement. For more information on this please visit the Simple Machines website.