Users browsing this thread: 1 Guest(s)
Changing Damage formulas

#1
 
Status
None
So I've done a bunch of digging over the past few days trying to figure out a change which I thought would be relatively simple, and I've gotten a lot closer but still feel so far. I simply want to change damage calculation algorithms. Magic and Physical. I've found the C2 disassembly (http://assassin17.home.comcast.net/~assa...code2i.txt) and located the stuff in windhex, but I'm unsure how to modify what the actual algorithm is.

So say, for example, the magic calculation divides by 32 and I want to change it to something else, let's say 64 for the sake of ease. How would I actually change this line of code to do that? I've searched everywhere and nothing seems to explain how to actually change this. I've found where it does this, but I have no idea how to modify the function the way I want to:
Code:
C2/2B90: 20 D1 0D     JSR $0DD1   (Divide 24-bit Damage by 32.  [note the
                                   division operates on 4 bytes] )
I have very limited assembly knowledge (see: http://www14.brinkster.com/assassin17/thegun.htm and all I do is click on the opcode and it tells me a bunch of stuff I don't understand).

I have found stuff around C2/2B69 where it tells what stat it's pulling and I've figured out how to tell it to pull a different stat, but unfortunately that still leaves me with these ridiculous equations where one stat skyrockets above the other in terms of effectiveness.

As for more in-depth formula changing, the meat of the formula seems to be here:
Code:
C2/2B86: 20 81 47     JSR $4781   (Multiplication Function:
                                   A = Magic Power * Spell Power)
C2/2B89: 20 B7 47     JSR $47B7   (Multiplication Function 2:
                                   24-bit $E8 = (Mag Pwr * Spell Power) * Level)
With that /32 tacked on later (mentioned above). But I just don't see how one would go about changing any of that. I guess the first one references $4781, which is where the multiplication functions are, but I don't see how that literally calculates Magic power * Spell power. And now that I look at it, I don't see where Spell power * 4 (first part of the formula) is calculated at all.

Ugh, this is hurting my brain. I apologize if this is really basic stuff. There doesn't seem to be much dumbed-down detail on this anywhere and it's been really hard to wrap my brain around what little I have managed to understand so far.
 
Quote  

#2
Posts: 290
Threads: 3
Thanks Received: 40
Thanks Given: 1
Joined: Apr 2012
Reputation: 9
Status
None
(11-10-2014, 10:03 PM)Odal Wrote: So say, for example, the magic calculation divides by 32 and I want to change it to something else, let's say 64 for the sake of ease. How would I actually change this line of code to do that? I've searched everywhere and nothing seems to explain how to actually change this. I've found where it does this, but I have no idea how to modify the function the way I want to:
Code:
C2/2B90: 20 D1 0D     JSR $0DD1   (Divide 24-bit Damage by 32.  [note the
                                   division operates on 4 bytes] )

If you look at C2/0DD1, the commentary will tell you what's going on. This multiplication is actually part of a larger function, but if entered at C2/0DD1, it's a bit more generalized arithmetic:

Code:
(if entered at C2/0DD1, does a more general division of a 32-bit value
[though most callers assume it's 24-bit] by 2^(A+1).)

What it doesn't tell you is what the base value being modified is, but you can discern that by looking at the function (it's the values stored in $E8 - $EA, typically, so a 24-bit value).

So the commentary says it's dividing that by 2^(A+1). If you look back at the caller, you can see an LDA #$04 instruction at C2/2B8C. So using that, we can figure out what the divisor is:

2^(4+1) = 2^5 = 32

To change the divisor to 64, you'd just need to change that LDA instruction to LDA #$05.

(11-10-2014, 10:03 PM)Odal Wrote: As for more in-depth formula changing, the meat of the formula seems to be here:
Code:
C2/2B86: 20 81 47     JSR $4781   (Multiplication Function:
                                   A = Magic Power * Spell Power)
C2/2B89: 20 B7 47     JSR $47B7   (Multiplication Function 2:
                                   24-bit $E8 = (Mag Pwr * Spell Power) * Level)
With that /32 tacked on later (mentioned above). But I just don't see how one would go about changing any of that. I guess the first one references $4781, which is where the multiplication functions are, but I don't see how that literally calculates Magic power * Spell power.

Same thing, take a look at the commentary for the function being called. At C2/4781:

Code:
Multiplication Function
Multiplies low bit of A * high bit of A. Stores result in 16-bit A.

Calling the operands the "low bit" and "high bit" is misleading; more accurately, it should be "low byte" and "high byte." These simply refers to each 8-bit portion of a 16-bit A.

For example, if A contains 13BD (5053 in decimal), then this function will multiply 13 * BD.

And at C2/47B7:

Code:
Multiplication Function 2
Results:
16-bit A = (8-bit $E8 * 16-bit A) / 256
24-bit $E8 = 3 byte (8-bit $E8 * 16-bit A)
16-bit $EC = 8-bit $E8 * high byte of A

This one is easier to understand, and a bit more versatile. As you can tell, it will give you three different results for three different sets of arithmetic.

One result will be stored in 16-bit A.
One result will be stored in 24-bit $E8 (that is, $E8 - $EA)
The last result will be stored in 16-bit $EC ($EC - $ED)

(11-10-2014, 10:03 PM)Odal Wrote: And now that I look at it, I don't see where Spell power * 4 (first part of the formula) is calculated at all.

This one's a bit less obvious than calling a multiplication function.

Code:
C2/2B71: AD A6 11     LDA $11A6   (Spell Power)
C2/2B74: C2 20        REP #$20    (Set 16-bit Accumulator)
C2/2B76: 90 02        BCC $2B7A   (If Level > 0, Spell Power *= 4)
C2/2B78: 0A           ASL
C2/2B79: 0A           ASL

The key is in the ASL instructions. These shift all bits in the operand left by one bit, which effectively doubles it. This instruction has more uses than just a quick (operand * 2), but that's all it's used for in this case.

It starts by loading the caster's spell power into A, then doubling that (A * 2), then doubling THAT (A * 4).

Of note, the LSR instruction has a similar usage in that it shifts all bits in the operand to the right by one bit, effectively halving it.

ASL = Arithmetic Shift Left
LSR = Logical Shift Right

(11-10-2014, 10:03 PM)Odal Wrote: Ugh, this is hurting my brain. I apologize if this is really basic stuff. There doesn't seem to be much dumbed-down detail on this anywhere and it's been really hard to wrap my brain around what little I have managed to understand so far.

This is about familiarity with ASM more than anything else. How basic it is depends on how comfortable the hacker is with the language. I implemented a fully custom physical damage formula in my hack, so I was hanging around these damn formulas for way too long. Tongue


GET A SILK BAG FROM THE GRAVEYARD DUCK TO LIVE LONGER.

Brave New World
  Find
Quote  
[-] The following 1 user says Thank You to Synchysi for this post:
  • ReturnerScum (01-18-2016)

#3
 
Status
None
Thank you very much for your help. So, I spent a lot of time pondering and decided I still doubt I know how to do anything complex. Here is what I have come up with in case you or anyone else is curious and I still have to test it.

I always find that in any hack, I have to itemize and value Magic Power to Vigor at a 1:2 ratio. That is, it takes roughly 2 vigor to be a similar raise in damage to 1 Magic power. I realized I may have been thinking too big when I wanted to change everything altogether. Then I had a thought: Why not just divide Magic Power by 2? (Side question here: does the game only truncate the final result? I assume it does. If not, my concern would be that an odd numbered magic power would be exactly the same as the even number preceding it.)

Well, as I understand it, I need to use the same amount of space. I'm not sure how true this is, but I don't know how I'd go about using less or more space than what is already being used. So what I came up with is this:
Remove one of the ASLs and put in a LSR after Magic Power instead. This will make for a formula that makes magic power scale more closely to vigor.

Now the only issue I have is level scaling. In Physical damage, the level is squared in its calculation and it's not squared in the Magic damage formula. I came up with a similar kind of solution for levels.

What I can do is remove one of the ASLs here again and, to use the same amount of space, divide the attacker level by 2 by putting in LSR there. Then, of course, I can just manually double monster attack powers later if I want to by hand. This doesn't completely solve the problem as the scaling is still kind of crazy being that I'm still squaring, but not as bad since it's a smaller number.

Is there some way I can just remove the squaring aspect altogether though? I see where it looks kind of separated from the main calculations.
Since it looks like it doesn't directly square the levels (it just takes the product of the level and attack then multiplies by the level again), it seems like it wouldn't be too difficult to manipulate it to something less extreme. I'm thinking maybe there's a way to make it pull up something else instead of level a second time? Perhaps I can have it pull up battle power again instead, effectively squaring that? Battle power is a lot easier to regulate by just limiting the player's options. Not sure how I'd do this without breaking everything. I'll have to play around with it.

Edit - It seems my original idea broke the game. I was going to make room for AD A6 11 (calling battle power instead of E5 E8, "get attacker level again") by deleting an ASL again. One thing it did was make the enemies deal a LOT more damage, but when I finally did get a chance to attack, the game crashed Hmm Tried calling battle power instead of level earlier on, but alas this just makes the "get attacker level again" pull battle power instead of level. So as far as I can tell, there's no way to separate the two easily. On the good side, deleting an ASL and inputting an LSR for the magic calculation has seemed to work out smoothly.

Edit 2 - All my attempts to cut level stat in half in the physical damage formula using LSR ended in failure. Basically numbers are all wrong coming from enemies and character attacks result in game reset. Tried one LSR (in place of a monster battle power *4 ASL) inserted several different spots around where it annotates a reference to character level stat being called, but no good. Tried some more with magic to see if that was a fluke, but the LSR in that seems to be working right. Not sure why it works in one and not the other. Hmm.
 
Quote  



Forum Jump:

Users browsing this thread: 1 Guest(s)


Theme by Madsiur2017Custom Graphics by JamesWhite