Users browsing this thread: 1 Guest(s)
Changing and Replacing Combat Functions via Special Effects
02-24-2016, 10:30 PM
(This post was last modified: 02-28-2016, 02:43 PM by ReturnerScum.)
Hi hackers. This thread is going to be for mapping out the combat function and explaining how to change and replace combat formulas via special effects, making abilities and items much more dynamic with the game.
So far I've made a rocking formula successfully but I do have 3 questions for anyone who might be familiar with storing values, special effects, and the combat function. I have searched about these, btw.
Q1: Storing Values.
I'm working on some new formulas and when I look at the original game formulas, it seems to store values in a low range of addresses. I'm looking to use 2-3 byte calculations for changing and replacing damage functions. Is there any range in particular I would need to store this extra data? There are at least two spots where damage is stored, for example -- $F0 and $11B0. I'm guessing the low address values are due to development planning rather than system mechanics---anyone know about that?
Q2: Special Effects
Special effects are called in a lot of different places--it looks like there's two tables and only one of them works for my spell sfx. Has anyone found any surprising problems with editing special effects in general? They're called in reflect and launcher too, IIRC.
Q3: Combat Functions
It seems like the combat --> damage --> result function never ends. Any caveats and wisdom would be much appreciated before I wreck my hack for good. I'm surprised at how little it seems the modify damage routine is referenced, but I'm worried there are so many references upstream I'm not seeing, that changing damage is too risky when added via special effects into $11B0 and $F0.
Thanks all. Whether we have any wisdom on this or not, I'll be sure to make it enlightening for us.
RS
So far I've made a rocking formula successfully but I do have 3 questions for anyone who might be familiar with storing values, special effects, and the combat function. I have searched about these, btw.
Q1: Storing Values.
I'm working on some new formulas and when I look at the original game formulas, it seems to store values in a low range of addresses. I'm looking to use 2-3 byte calculations for changing and replacing damage functions. Is there any range in particular I would need to store this extra data? There are at least two spots where damage is stored, for example -- $F0 and $11B0. I'm guessing the low address values are due to development planning rather than system mechanics---anyone know about that?
Q2: Special Effects
Special effects are called in a lot of different places--it looks like there's two tables and only one of them works for my spell sfx. Has anyone found any surprising problems with editing special effects in general? They're called in reflect and launcher too, IIRC.
Q3: Combat Functions
It seems like the combat --> damage --> result function never ends. Any caveats and wisdom would be much appreciated before I wreck my hack for good. I'm surprised at how little it seems the modify damage routine is referenced, but I'm worried there are so many references upstream I'm not seeing, that changing damage is too risky when added via special effects into $11B0 and $F0.
Thanks all. Whether we have any wisdom on this or not, I'll be sure to make it enlightening for us.
RS
02-27-2016, 12:35 PM
(This post was last modified: 02-27-2016, 01:18 PM by ReturnerScum.)
I've got two new special effects for us that work and one that doesn't work but seems very close to doing so.
FIRST REPLACEMENT - New Special Effect $14 - Mpwr^2/8 Added to damage
Notice that I use XBA and JSR $4781 to multiply the $11A0 Mpwr together. I then tried using $11A0 and $11A6....and it didn't work to create Mpwr*Vigor. I have the same situation for the next formula below---I get a bit more daring by using the Y index to Lvl^2, but I have a suspicion that other data near those values (3B18) don't work when called by special effects.
The XBA and JSR technique was stolen from the Flare Star code, which I'll discuss in detail for my third, huge, formula:
SECOND REPLACEMENT - $03 - Lvl*Lvl Added to Damage
But first let's talk about how insanely great this is. Would you rather have a sword that breaks, like ogre nix, or a sword that adds damage based on your Mpwr? The limits of interesting combat are quickly destroyed with the prismatic expansion of damage formulas. Do you really like having exploder in your Lore list?
But how much can we change? I've recently read a lot of the Programming the 65816 document and have, of course, made some formulas that are much more sophisticated than a squared hero statistic. This one isn't super sophisticated but it doesn't just do damage = your HP or dmg+HP, it does [(HP/64+1)+(MP/16+1)]^2 and replaces the damage from normal formulas:
And this time, for some reason, the formula doesn't work. This code loads HP and MP data, reduces them to a # which will not exceed 1 byte, then goes into 8-bit mode to do the XBA JSR trick again. The XBA trick swaps the high byte and low byte of the accumulator, with one of them (the high byte, I believe) referred to as "B" when in 8bit-mode, because there is no 2nd byte in 8bit-mod, but the space (and thus, the hex values there) is still there, it just isn't touched. When you swap the low byte and high byte, you can multiply or divide the value by 256, or you can use the JSR $4781 multiplication subroutine to multiply the two bytes together, with the result in 16bit A.
The formula of this type is much more powerful because it multiplies 2 byte values like HP and MP together, although it's not perfectly ideal because I believe there is a lot of rounding down that occurs.
So why do the first two formulas work and this one doesn't? The same HP value is called by Valiant Knife, so that should be fine---but when I change the hero stats to be $11A0 (Mpwr) instead, the formula works brilliantly.
Does anyone know the values that can or can't be loaded during combat?
Below is the quick list of values I've found throughout C2:
I should also mention that in this code, Y seems to be the attacker and X the target, but it seems extremely difficult to track the source of what's in the X or Y registers.
(Note: On the site the code text looks jilted but when editing it the code and comments are perfectly straight)
(To use these formulas by the way, FF3usME has the special effect box on the right when looking at a spell, and the special effect drop-down menu for weapons. The first formula here is effect $14 in the spell menu, the 2nd is the "0x3" special effect for weapons, replacing the "Kill with X" effect.)
FIRST REPLACEMENT - New Special Effect $14 - Mpwr^2/8 Added to damage
Code:
C2/3DF5: 8C 38 --> 90 67 Special ($14h) [20] now points to 6790
C2/4309: 8A 3E --> 90 67 Special ($14h) [20] now points to 6790
\\We changed both pointer tables because it looks like only the second one works for the spell during testing\\
C2/6790: E2 20 SEP #$20 (Set 8-bit Accumulator)
C2/6792: AD A0 11 LDA $11A0 (Mpwr)
C2/6795: EB XBA
C2/6796: AD A0 11 LDA $11A0 (Mpwr)
C2/6799: 20 81 47 JSR $4781 (Multiply them together Mpwr * Mpwr)
C2/679C: C2 20 REP #$20 (Set 16-bit Accumulator)
C2/679E: 4A LSR
C2/679F: 4A LSR
C2/67A0: 4A LSR (Divide by 8)
C2/67A1: 18 CLC
C2/67A2: 6D B0 11 ADC $11B0 (Add to damage)
C2/67A5: 8D B0 11 STA $11B0 (Store in maximum damage)
C2/67A6: 60 RTS
Notice that I use XBA and JSR $4781 to multiply the $11A0 Mpwr together. I then tried using $11A0 and $11A6....and it didn't work to create Mpwr*Vigor. I have the same situation for the next formula below---I get a bit more daring by using the Y index to Lvl^2, but I have a suspicion that other data near those values (3B18) don't work when called by special effects.
The XBA and JSR technique was stolen from the Flare Star code, which I'll discuss in detail for my third, huge, formula:
SECOND REPLACEMENT - $03 - Lvl*Lvl Added to Damage
Code:
C2/3DD3: 43 3D ($03) --> B0 67 (jump to $67B0 as new special effect $03, 4th in weapon sfx menu in FF3usME,
replacing kill with X)
C2/42E7: 8A 3E ----> B0 67
C2/67B0: E2 20 SEP #$20 (Set 8-bit Accumulator)
C2/67B2: B9 18 3B LDA $3B18,Y (Level of attacker)
C2/67B5: EB XBA
C2/67B6: B9 18 3B LDA $3B18,Y (Level of attacker)
C2/67B9: 20 81 47 JSR $4781 (Multiply them together level * level)
C2/67BC: C2 20 REP #$20 (Set 16-bit Accumulator)
C2/67BE: 18 CLC
C2/67BF: 6D B0 11 ADC $11B0 (Add to damage)
C2/67C2: 8D B0 11 STA $11B0 (Store in maximum damage)
C2/67C5: 60 RTS
But first let's talk about how insanely great this is. Would you rather have a sword that breaks, like ogre nix, or a sword that adds damage based on your Mpwr? The limits of interesting combat are quickly destroyed with the prismatic expansion of damage formulas. Do you really like having exploder in your Lore list?
But how much can we change? I've recently read a lot of the Programming the 65816 document and have, of course, made some formulas that are much more sophisticated than a squared hero statistic. This one isn't super sophisticated but it doesn't just do damage = your HP or dmg+HP, it does [(HP/64+1)+(MP/16+1)]^2 and replaces the damage from normal formulas:
Code:
HP+MP Damage Formula
OpCode Registers-> X B A Summary with comments
C2 20 REP #20 16-bit mode
B9 F4 3B LDA, Y $3BF4 LDA, Y HP
4A LSR Divide by 2
4A LSR 4
4A LSR 8
4A LSR 16
4A LSR 32
4A LSR 64
1A INC HP/64+1
48 PHA
B9 08 3C LDA, Y $3C08 LDA, Y MP
4A LSR Divide by 2
4A LSR 4
4A LSR 8
4A LSR 16
1A INC MP/16+1
8D 18 A7 STA $7A18 STA Store at two bytes
68 PLA A=HP/64+1
18 CLC Clear carry before adding
6D 18 A7 ADC $7A18 HP+MP ADC Add stored MP/16+1
4A LSR Divide by 2
E2 20 SEP #$20 HP+MP 8bit mode
8D 18 A7 STA$7A18 STA Store HP+MP at two bytes (A byte if 8-bit mode!)
EB XBA HP+MP XBA
18 CLC
6D 18 A7 ADC $7A18 HP+MP HP+MP ADC Add stored HP+MP
C2 20 REP #20 16bit
20 81 47 JSR $4781 JSR Multiply them together
0A ASL x2
8D 18 A7 STA $A718 STA Store big value HP+MP at two bytes
B9 F4 3B LDA, Y $3BF4 LDA, Y HP
4A LSR Divide by 2
4A LSR 4
18 CLC Clear carry before adding
6D 18 A7 ADC $A718 ADC Add stored HP+MP
90 03 BCC +4 BCC If carry wasn't set, overflow did not occur
A9 FF FF ADC #$65535 LDA Replace with 65535
8D B0 11 STA $11B0 STA Store to replace dmg at 11B0
60 RTS
And this time, for some reason, the formula doesn't work. This code loads HP and MP data, reduces them to a # which will not exceed 1 byte, then goes into 8-bit mode to do the XBA JSR trick again. The XBA trick swaps the high byte and low byte of the accumulator, with one of them (the high byte, I believe) referred to as "B" when in 8bit-mode, because there is no 2nd byte in 8bit-mod, but the space (and thus, the hex values there) is still there, it just isn't touched. When you swap the low byte and high byte, you can multiply or divide the value by 256, or you can use the JSR $4781 multiplication subroutine to multiply the two bytes together, with the result in 16bit A.
The formula of this type is much more powerful because it multiplies 2 byte values like HP and MP together, although it's not perfectly ideal because I believe there is a lot of rounding down that occurs.
So why do the first two formulas work and this one doesn't? The same HP value is called by Valiant Knife, so that should be fine---but when I change the hero stats to be $11A0 (Mpwr) instead, the formula works brilliantly.
Does anyone know the values that can or can't be loaded during combat?
Below is the quick list of values I've found throughout C2:
Quote: Speed (hero) - $11A4
Stamina (hero) - $11A2
Magic Power of hero - $11A0
Vigor of hero - $11A6 -->Actually Vigor or BP or SP I think in some cases. Careful, this gets changed
Vigor*2 or Mpwr - $11AE (this is weird)
Level of attacker - $11AF (probably hero only)
MDef - $3BB9,Y @ C/20CCC after damage mod
Def - $3BB8,Y
HP of Hero - $3BF4, Y
MP of Hero - $3C08,Y
Max HP - $3C1C,Y (for hero only?)
$3C1D,Y - High byte of Max HP (for hero only?)
$3BF4,Y - HP (for hero only?)
$3BF5,Y - High byte of HP (for hero only?)
$3B2C,X - (attacker Vigor * 2)
$11A8 - Hit rate (of spell checking for stamina blocking)
$3C08,X - (MP)
$3C30,X - (Max MP)
I should also mention that in this code, Y seems to be the attacker and X the target, but it seems extremely difficult to track the source of what's in the X or Y registers.
(Note: On the site the code text looks jilted but when editing it the code and comments are perfectly straight)
(To use these formulas by the way, FF3usME has the special effect box on the right when looking at a spell, and the special effect drop-down menu for weapons. The first formula here is effect $14 in the spell menu, the 2nd is the "0x3" special effect for weapons, replacing the "Kill with X" effect.)
02-27-2016, 01:47 PM
One thing you can do to troubleshoot your custom functions is to run them through the SNES9x debugger.
http://geigercount.net/crypt/
Just set a breakpoint at the address in question, then you can go through it line-by-line to check which values are getting loaded, and if they are what you expect.
http://geigercount.net/crypt/
Just set a breakpoint at the address in question, then you can go through it line-by-line to check which values are getting loaded, and if they are what you expect.
02-27-2016, 02:53 PM
(This post was last modified: 02-28-2016, 02:57 PM by ReturnerScum.)
Thanks I'll try and figure out how to use that. This thread isn't just about debugging my formulas by the way---it's to find ways that actually work, so if anyone else has successfully changed things up in a similar way, please feel free to join in.
Alright that debug tool worked like a charm once I figured out how to use it. You have to add a breakpoint then check the "Execute" and "read"function and type in your 6 digit hex address. When the address is called or used then it stops and you have to push the "step into" button to go step-by-step through the code that is executing and compare what should happen. Then you can use the same program to change the hex code of the ROM on the fly and reload.
What the debugging tool also means, is that you can track the entire combat function using the same technique. There's probably some button that can just write the code to a file but that wasn't explained by the self-titled "l337" pre-pubescent boy who was explaining this to me on Youtube.
Also I've found a nice explanation of the special effects combat function when foolishly trying to remove a patch by Assassin, the capture weapon fix "Recapture the Glory":
The problem with my formula was that my storage bytes were in the middle of the code and being interpreted as ASM instructions, derailing the train from there. Now the damage is off for a reason I haven't figured out yet. It should be doing around 4801 dmg with 2063 HP and 651 MP, but ends up around 1100.
Alright that debug tool worked like a charm once I figured out how to use it. You have to add a breakpoint then check the "Execute" and "read"function and type in your 6 digit hex address. When the address is called or used then it stops and you have to push the "step into" button to go step-by-step through the code that is executing and compare what should happen. Then you can use the same program to change the hex code of the ROM on the fly and reload.
What the debugging tool also means, is that you can track the entire combat function using the same technique. There's probably some button that can just write the code to a file but that wasn't explained by the self-titled "l337" pre-pubescent boy who was explaining this to me on Youtube.
Also I've found a nice explanation of the special effects combat function when foolishly trying to remove a patch by Assassin, the capture weapon fix "Recapture the Glory":
Quote:Also, the game only has a few basic damage formulae: one used by physical spells (and by
weapons, as Battle is physical), another used by magical spells, one for spells/items that
affect a fraction of the target's HP or MP, and one for items that just do a constant amount
of healing/damage.
What if you want to do a unconventional type of damage, like based on how many steps your
party has taken?
What if you want to use special criteria for how often an attack hits, like with Ragnarok's
Metamorph or Relm's Control?
What if you want to change statuses at random rather than a spell always trying to
inflict/remove/toggle the same ones?
What if you want to do greater damage to human targets?
For Square, the answer to all those above questions was the same: you make a special effect.
There are dozens of unique behaviors Square felt like throwing into the game, so it would
hardly be economical to designate a "Yes / No" bit for each one as done with more common
properties like elementals. Instead, they set aside a single "special effect" byte in the
spell data and the item data (the latter also includes weapons, equipment, relics, tools,
etc). When you perform an attack, this ROM byte is copied into the RAM data for the current
attack. The byte's value determines which special effect function(s) is/are called.
Up to two functions can be assigned to a given effect #: one routine is called just once per
strike (where a "strike" can have single or multiple targets); the other is called once for
each separate target. The former type of routine doesn't care about target properties,
while the latter does. Spells/items without a special effect just put zero in the byte,
which results in harmless empty functions being called.
.....
As mentioned in the last three paragraphs, there is just one special effect byte. That's
plenty sufficient in all but one known case: using the Capture command in conjunction
with a weapon that has a special effect of its own (see Section 0 for the many examples).
First, the weapon's special effect byte is copied into the RAM attack data. But before
its special effect function can be called, the Capture command overwrites that byte with
A4h. Thus, you'll get the thievery aspect, but lose any snazzy properties the weapon may
have. To handle this combination correctly, two bytes would have been needed.
____________________________________________________________________________________________
3. WHAT MY PATCH DOES
____________________________________________________________________________________________
As Kirstie Alley and Marv Albert will tell you, one byte isn't always enough. This patch
introduces a second byte to allow for multiple special effects if -- and only if -- the
Capture command is involved. Here's a very rough summary of the relevant happenings in a
given strike ("NC" means no change from original game):
- Zero the new special effect variable ($2F3D).
- The weapon data is loaded into the attack data, which includes copying the weapon special
effect into the normal special effect variable ($11A9). Weapons without a special effect
just set the variable to zero. NC
- If the command is Capture, A4h (Steal) is put into a new special effect byte ($2F3D.
Previously, the game had put it into $11A9).
- [...]
- The once-per-strike special effect routine is called as normal (i.e. using $11A9's value.
If it's zero, a harmless empty function is called). NC
- For each target of a strike (there should only be one target with Fight and Capture, as
multiple Offering or Genji Glove hits are considered separate strikes):
- [...]
- The once-per-target special effect routine is called as normal (i.e. using $11A9's
value. If it's zero, a harmless empty function is called). NC
- If Variable $11A9 =/= Variable $2F3D, call the once-per-target special effect function
again, this time using $2F3D's value so as to attempt a steal. (If $2F3D is zero, a
harmless empty function is called.)
We skip the call if $11A9 equals $2F3D, because that means either:
- Both special effects are A4h (Steal). We have the Capture command in conjunction
with a capture attempted by Thief Knife; there's no reason to call the Steal function
twice, and doing so would likely screw things up.
OR
- Both special effects are 0 (Nothing), in which case calling a second empty function
is harmless, but a waste of CPU cycles.
As mentioned above, no modification was needed for the once-per-strike special effect call,
because Steal only has a once-per-target function defined. Also note that the
once-per-target special effect call in the Super Ball/Launcher/Reflected spells routine
isn't changed, as there's no way to combine Capture with those without extensive hacking.
The problem with my formula was that my storage bytes were in the middle of the code and being interpreted as ASM instructions, derailing the train from there. Now the damage is off for a reason I haven't figured out yet. It should be doing around 4801 dmg with 2063 HP and 651 MP, but ends up around 1100.
03-06-2016, 04:19 PM
(This post was last modified: 03-06-2016, 06:27 PM by ReturnerScum.)
Here is my mapping of the two SFX tables when cross-checking the C2Code and FF3usME:
Edit: Since all my text ends up jilted, a document is attached with this (even though it also doesn't look straight in the google drive preview).
Edit: Since all my text ends up jilted, a document is attached with this (even though it also doesn't look straight in the google drive preview).
Code:
C2/3DCD: 8C 38 Nothing C2/42E1: 8A 3E
C2/3DCF: 8C 38 Steal C2/42E3: 8B 3E
C2/3DD1: 8C 38 ($2) C2/42E5: 44 40
C2/3DD3: 43 3D ($3) C2/42E7: 8A 3E
C2/3DD5: F2 38 ($4) C2/42E9: 8A 3E
C2/3DD7: 8C 38 ($5) C2/42EB: 73 3F
C2/3DD9: 8C 38 ($6) C2/42ED: 6E 3F
C2/3DDB: 8C 38 ($7) C2/42EF: 22 3F
C2/3DDD: FE 38 ($8) C2/42F1: 8A 3E
C2/3DDF: 8C 38 ($9) C2/42F3: 58 41
C2/3DE1: 8C 38 ($0A) C2/42F5: 89 3F
C2/3DE3: 8C 38 ($0B) C2/42F7: 9F 3F
C2/3DE5: 8C 38 ($0C) C2/42F9: 7E 3F
C2/3DE7: 8D 38 ($0D) C2/42FB: 8A 3E
C2/3DE9: 8C 38 ($0E) C2/42FD: CA 3E
C2/3DEB: 8C 38 ($0F) C2/42FF: 50 3F
C2/3DED: 5B 3C ($10) C2/4301: 8A 3E
C2/3DED: 8C 38 ($11) C2/4303: 65 3F
C2/3DF1: 3C 3A ($12) C2/4305: 8A 3E
C2/3DF3: 34 39 ($13) ($13) C2/4307: F6 41
C2/3DF5: 8C 38 Empty! C2/4309: 8A 3E
C2/3DF7: 8C 38 ($15) C2/430B: 63 42
C2/3DF9: 8C 38 ($16) C2/430D: 34 42
C2/3DFB: A2 3C ($17) C2/430F: 8A 3E
C2/3DFD: 8C 38 ($18) C2/4311: 4E 40
C2/3DFF: 4C 3C ($19) ($19) C2/4313: FC 3F
C2/3E01: 8C 38 ($1A) C2/4315: FE 40
C2/3E03: 8C 38 ($1B) C2/4317: 54 3F
C2/3E05: 90 3C ($1C) ($1C) C2/4319: B7 42
C2/3E08: 8C 38 ($1D) C2/431B: A1 40
C2/3E09: 8C 38 ($1E) C2/431D: A0 3E
C2/3E0B: 78 39 ($1F) C2/431F: 8A 3E
C2/3E0D: B8 3C ($20) C2/4321: 8A 3E
C2/3E0F: 4 3C ($21) C2/4323: 8A 3E
C2/3E11: 22 39 ($22) C2/4325: 8A 3E
C2/3E13: 8C 3C ($23) C2/4327: 8A 3E
C2/3E15: 8C 38 Crusader C2/4329: 8A 3E
C2/3E17: 6B 3B ($25) C2/432B: 8A 3E
C2/3E19: 89 39 ($26) C2/432D: 8A 3E
C2/3E1B: 6C 39 ($27) ($27) C2/432F: BB 40
C2/3E1D: B0 3B ($28) ($28) C2/4331: 3C 41
C2/3E1F: 8C 38 ($29) C2/4333: 4D 41
C2/3E21: 8C 38 ($2A) C2/4335: 0F 41
C2/3E23: 80 39 ($2B) C2/4337: 8A 3E
C2/3E25: 8C 38 ($2C) C2/4339: 37 40
C2/3E27: 37 3D ($2D) C2/433B: 8A 3E
C2/3E29: CE 3C ($2E) C2/433D: 8A 3E
C2/3E2B: A8 3D ($2F) C2/433F: 8A 3E
C2/3E2D: 6E 3C ($30) ($30) C2/4341: 8B 42
C2/3E2F: 8C 38 ($31) C2/4343: DA 40
C2/3E31: 8C 38 ($32) C2/4345: F1 40
C2/3E33: 66 39 ($33) ($33) C2/4347: 61 40
C2/3E35: 91 3C ($34) C2/4349: 8A 3E
C2/3E37: 49 3D ($35) C2/434B: 8A 3E
C2/3E39: 8C 38 ($36) C2/434D: 1B 42
C2/3E3B: 1E 3D ($37) C2/434F: 8A 3E
C2/3E3D: 6C 39 ($38) C2/4351: 8A 3E
C2/3E3F: 5E 39 ($39) C2/4353: 8A 3E
C2/3E41: 27 3D ($3A) C2/4354: 8A 3E
C2/3E43: CB 3B ($3B) C2/4357: 8A 3E
C2/3E45: 8C 38 Retort? C2/4359: 8A 3E
C2/3E47: 8C 38 ($3D) C2/435B: E6 41
C2/3E49: 7C 3D ($3E) C2/435D: 8A 3E
C2/3E4B: 85 3D ($3F) C2/435F: 8A 3E
C2/3E4D: B0 3D ($40) C2/4361: 8A 3E
C2/3E4F: 8C 38 ($41) Unused? C2/4363: 85 42
C2/3E51: 8C 38 ($42) Unused? C2/4365: 80 42
C2/3E53: 8C 38 ($43) C2/4367: CA 42
C2/3E55: FD 3C ($44) ($44) C2/4369: 4B 42
C2/3E57: 8C 38 Clear (spell?) C2/436B: 8A 3E
C2/3E59: 8C 38 Empty! C2/436D: 8A 3E
C2/3E5B: 8C 38 Empty! C2/436F: 8A 3E
C2/3E5D: 8C 38 Empty! C2/4371: 8A 3E
C2/3E5F: 8C 38 ($49) C2/4373: AD 3F
C2/3E61: B8 3D ($4A) ($4A) C2/4375: 2C 40
C2/3E63: 6C 39 ($4B) ($4B) C2/4377: C8 40
C2/3E65: 17 3D ($4C) ($4C) C2/4379: 36 41
C2/3E67: 8C 38 ($4D) C2/437B: 4E 40
C2/3E69: 8C 38 Empty! C2/437D: 8A 3E
C2/3E6B: 8C 38 Empty! C2/437F: 8A 3E
C2/3E6D: 98 3B ($50) ($50) C2/4381: 95 40
C2/3E6F: 8C 38 ($51) C2/4383: B7 3F
C2/3E71: 9E 39 ($52) C2/4385: 8A 3E
C2/3E73: C5 3A ($53) C2/4387: 8A 3E
C2/3E75: 71 3B ($54) C2/4389: 8A 3E
C2/3E77: 29 3B ($55) C2/438B: 8A 3E
C2/3E79: 8D 3A ($56) C2/438D: 8A 3E
C2/3E7B: 78 3C ($57) C2/438F: 8A 3E
07-30-2018, 04:05 AM
Quote:I'm working on some new formulas and when I look at the original game formulas, it seems to store values in a low range of addresses. I'm looking to use 2-3 byte calculations for changing and replacing damage functions. Is there any range in particular I would need to store this extra data? There are at least two spots where damage is stored, for example -- $F0 and $11B0. I'm guessing the low address values are due to development planning rather than system mechanics---anyone know about that?
$11B0 (low) and $11B1 (high) are the two-byte damage value. $F0 generally is used as a temporary buffer or variable to calculate damage. For special effects, to setup $11B0 AND $11B1 are the correct way to setup a custom formula damage.
Quote:Special effects are called in a lot of different places--it looks like there's two tables and only one of them works for my spell sfx. Has anyone found any surprising problems with editing special effects in general? They're called in reflect and launcher too, IIRC.
Some special effects have hard coded features and are manually setup in code instead of a weapon or spell data. Examples are sketch, control, steal, etc. If they are modified, whatever code that setups them must be nullified as well to avoid undesired surprises.
Quote:It seems like the combat --> damage --> result function never ends. Any caveats and wisdom would be much appreciated before I wreck my hack for good. I'm surprised at how little it seems the modify damage routine is referenced, but I'm worried there are so many references upstream I'm not seeing, that changing damage is too risky when added via special effects into $11B0 and $F0.
The special effects that changes damage only overwrites the calculated default damage setup in $11B0 and $11B1. If the special effects don't change damage, the default damage is left as it was calculated.
Quote:I should also mention that in this code, Y seems to be the attacker and X the target, but it seems extremely difficult to track the source of what's in the X or Y registers.
I believe X or Y are the fighters index. 0, 2, 4 and 6 are the party side and above it are the opposition (monsters). As example, $3BF4,0 should be the actual hp of the first party member. $3BF4,2 should be the actual hp of the second party member, etc. The data stored in similar two bytes structures are always two bytes to accommodate all fighter indexes, party and opposition alike.
About the wrong text display in the posts, probably you used tabs instead of white space characters. The tab characters will try to setup the column text in a different position in the forum instead of the position of your text editor. You can try to check if your text editor has the option to automatically convert tab spaces in white spaces.
The following 2 users say Thank You to HatZen08 for this post:
• madsiur (07-30-2018),ReturnerScum (07-30-2018)
• madsiur (07-30-2018),
« Next Oldest | Next Newest »
Users browsing this thread: 1 Guest(s)