News:

The forum has been updated to SMF (2.1.3)!
Please be patient as we work to polish up the place and update features as we can.

Main Menu

Question Doom Dragon's HP

Started by VanishMantle, 06, May, 2015, 02:39:37 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

VanishMantle

So I am in the midst of working on version 2 of Risen Star. I noticed each head has a set amount of health that adds up together but I noticed if i set it to 32k it isn't set to that and instead each head takes HP from that number it seems. Is there a way to adjust this number so each head has 32k HP?

Salanewt

#1
I want to say the animation that plays on losing a head plays after a set amount of HP has been lost means that the first two versions of Doom Dragon are incapable of reaching 0 HP and dying, but I can't confirm yet. I also want to say that it may be as easy as just setting these amounts to a specific value and then fully healing the boss when it loses a head, but I can't confirm that either. Probably should though, might help me figure out how to make the first headshot animation (the one resulting in two heads) accessible in this patch I'm making.

I'll take a look when I have some free time later today. That way I can also confirm how the HP thing works and possibly apply that to other enemies sometime in the future.


Edit: Wait, I'm a dope... and should also have read your post a little more thoroughly. When one phase of Doom Dragon drops to 0 HP, it basically plays a special animation that swaps the entire enemy side out for another enemy/group (Doom Dragon phase) as a way of avoiding death. Kinda knew this part already. I'm pretty sure enemies have an HP cap of 16383 though, which should be half of the absolute maximum you can use. This might also be the way to fix the hardmode HP cap on Dullahan, but whatever.

You should be able to bump up the cap by editing some code at #080ADB60, which looks like the enemy HP/PP cap stuff (PC caps are a little earlier). The default cap is [xFC, LSL x06, + xFF], or 252 * 64 + 255. If you want what should be the maximum, then I would suggest changing it to [xFE, LSL x07, +xFF], or 254 * 128 + 255. That gives you a cap of 32767 (x7FFF), which I believe is be the absolute highest you can go because HP values are signed, meaning that everything above that is technically a negative number.

Although, looking at it again, it almost looks like enemy HP/PP caps are separate. PP might be at #080ADBB2. Now, I haven't confirmed 100% on either of these; this is just a 99% certainty based on what I can see in the code and some of the more minor things I know about it.

Hope this helps!
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

VanishMantle

Sweet! As always Lord Squirtle your abundance of knowledge has helped me with my mod. Definitely gotta throw you in the credits for my next update!

Salanewt

Aw, thanks! You totally don't have to though, I like looking through the code anyway.

Oh yeah, one thing to keep in mind is that the editor might limit you to the old cap when editing values (can't remember). Let me know if it does so I can tell you how to work around that with a hex editor.
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

VanishMantle

I have one more question though unrelated to the Doom Dragon it has more to do with HP regen and how Serpent's is different for basically no reason. Is it possible to rework the HP/PP regen on enemies to match how the Serpent's works?

Rolina

What, the 10x multiplier for it?  I remember someone mentioning it a while back.  Something to do with slot specific data?

Salanewt

#6
I figured that one would come up, lol. And what Role says, slot/ID-specific.

Basically, HP regeneration is capped at 255 per turn because this is a single byte. How the end-turn HP regeneration differs for the Serpent IDs is that it multiplies the normal value by 10 before adding it. Oh, and it does this using three enemy ID checks, two to grab the range of applicable Serpent IDs and one for Dullahan (210 in the editor, even though its HP regeneration only multiplies to 200 and this check isn't necessary at all for it to reach that value). The code for this is approximately located at #08125062, which is a part of the end-turn HP regeneration stuff. On that note, the multiplication isn't as straightforward as it could be:

Regen(a) LSL x2 = Regen(b)
Regen(b) + Regen(a) = Regen(c)
Regen(c) LSL x1 = Regen(final)

Or the following:

(Regen * 4 + Regen) * 2

So let's say that the base regeneration value is 3. Basic math really (and we can ignore the fact that the code could just as easily use standard multiplication):

(3 * 4 + 3) * 2
= (15) * 2
= 30

It will just skip this part and use the base Regen value if the enemy ID checks fail. Either way though, all that comes after this is the part where this is added to the unit's current HP and the appropriate line of dialogue is chosen.


If you want to have some sort of universal multiplier, then you could easily just remove the enemy ID checks and/or tweak the formula a bit; almost as easy as eating cake. I think the PP recovering formula works just slightly differently (probably with no enemy ID checks), but even then it looks like it would be fairly simple to change the code around for it. PP stuff comes right after this HP stuff and shortly before its dialogue (which is at #08125104): VBA's disassembler is great for viewing the code.


Edit: Might be able to come up with a revised system for this HP/PP regeneration stuff some day. Probably as a 4 or 6-byte system that has IDs, HP/PP regeneration multipliers, and maybe HP/PP regeneration addition modifiers to fill in the gaps of multiplication. Leaning toward 4. Also not a top priority, so whatever for now I guess.
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

VanishMantle

#7
Thanks for the info. I really need to get into this code so I can start working on some of this stuff myself. i am just not sure how to read any of it or what does what since i have 0 experience with the code.

EDIT: Yet another random question

There was something I wanted to do to make use of the Positioning in parties which largely doesn't have a use. I was wonder if it was possible to change how the self target range works. You can change the range on it but if it is set to user it only read as 1. I was thinking it would be cool to have skills that made positioning in the party matter more than it currently does if that makes sense.

Salanewt

Happy to help! Might be able to help a little further with the multiplier thing, depends on what you want to do with it.


As for self targeting abilities... no idea, I'll have to get back to you on that sometime.
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

VanishMantle

Alright thanks for looking into it. No rush on the targeting stuff I was just reminded of my original idea for some psynergy in the game. I have something that kinda works at the moment.

Rolina

That's a really strange way of multiplying by ten.  Maybe they were going for something different before?

Salanewt

Most likely, yeah. Either that or their original code was compiled weird. Only thing is I have no idea what else it could originally have been, and it's not like this is the only instance of something being less efficient than it could be either. Ah well.
Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Rolina

Perhaps they wanted it to be quadratic in nature?

leaf

I guess they just really liked using LSLs to multiply.
[spoiler=quotes]
[9:00:50 PM] Randel Peltier: Ok...what did I do last night?
[9:01:19 PM] Kain: Something boring, repetitive, and lasted for about sixty seconds.
---
[10:45:08 AM] Salanewt: But yeah, the elemental phalluses are being... Stroked up by Saturos and co., and the energy will go towards... Mt. Muffin, where the Golden Climax will arise.
[7:28:42 PM] Salanewt: An added bonus is that Isaac and co. were trying to stop Saturos and co. because their beliefs state that Mt. Muffin should remain a virgin.
---
[9:54:21 PM] Randel Peltier: Guess the number in my head an you get to pick what I say. Number between 1-10
[9:54:28 PM] leaf: 11
[9:54:36 PM] Randel Peltier: @#$%!
---
[8:38:13 PM] Randel Peltier: Shes like this queen up on a pedastal that I have yet to court.
[8:38:29 PM] Kain: You've tried courting her.
[8:38:43 PM] leaf: and failed spectacularly
[8:38:44 PM] Randel Peltier: Ive tried...shes the best dating game ever.
---
[12:24:35 AM] Salanewt: I need to find a picture of a naked person to put on the Christmas tree next year.
---
[2:19:06 PM] Zeadra: wait... Rief's a guy???
---
[1:09:57 PM] Zeadra: well if you want to know if its a new effect or something weird, just check GS1, if side step is there maby it is the nimble dodge thing
[1:10:35 PM] Kioll: For once, you've contributed something useful.  o.O[/spoiler]

Daddy Poi's Oily Gorillas

#14
Um... If you ask me, the first thing I'd say is probably because lsl can be executed faster than mul?

After all, lsl is just one simple shift of the bits, and mul may require further calculation under the hood.

And I'm betting the compiler compiles it like that. (Even if you do * 10 in source code.) (?) (But this is just a guess, so I could be wrong.)
However, there may be some instances where mul really is used... But it's probably more for other less straight-forward numbers.  (For example, it has been seen in both GS2 and Superstar Saga, that when you're mutliplying by 0x2C, the mul method is used. - This 0x2C would be the number of bytes for one entry in table... GS's would be the Items table, and Superstar Saga's would be the Enemy table. ; If a table were to have entries that were 4, 8, 12, 16, etc. bytes as long... chances are they'd use the lsl and add/sub method.)


Quote from:  GBATEK > move shifted register (lsl/lsr/asr)Execution Time: 1S

Quote from: GBATEK > ALU OperationsExecution Time:

  1S      for  AND,EOR,ADC,SBC,TST,NEG,CMP,CMN,ORR,BIC,MVN
  1S+1I   for  LSL,LSR,ASR,ROR
  1S+mI   for  MUL on ARMv4 (m=1..4; depending on MSBs of incoming Rd value)
  1S+mI   for  MUL on ARMv5 (m=3; @#$%&*! slow, no matter of MSBs of Rd value)
I never understood what all this meant, but I guess we can learn...

Stuff I already knew:
MSBs = Most Significant Bits. (The bits found on the left side of a number.)
Rd = Register destination.

Stuff I just looked up on GBATEK/may not fully understand:
Quoten = number of words transferred
b = number of cycles spent in coprocessor busy-wait loop
m = depends on most significant byte(s) of multiplier operand

QuoteN - Non-sequential cycle
Requests a transfer to/from an address which is NOT related to the address used in the previous cycle. (Called 1st Access in GBA language).
The execution time for 1N is 1 clock cycle (plus non-sequential access waitstates).

S - Sequential cycle
Requests a transfer to/from an address which is located directly after the address used in the previous cycle. Ie. for 16bit or 32bit accesses at incrementing addresses, the first access is Non-sequential, the following accesses are sequential. (Called 2nd Access in GBA language).
The execution time for 1S is 1 clock cycle (plus sequential access waitstates).

I - Internal Cycle
CPU is just too busy, not even requesting a memory transfer for now.
The execution time for 1I is 1 clock cycle (without any waitstates).

C - Coprocessor Cycle
The CPU uses the data bus to communicate with the coprocessor (if any), but no memory transfers are requested.

Memory Waitstates
Ideally, memory may be accessed free of waitstates (1N and 1S are then equal to 1 clock cycle each). However, a memory system may generate waitstates for several reasons: The memory may be just too slow. Memory is currently accessed by DMA, eg. sound, video, memory transfers, etc. Or when data is squeezed through a 16bit data bus (in that special case, 32bit access may have more waitstates than 8bit and 16bit accesses). Also, the memory system may separate between S and N cycles (if so, S cycles would be typically faster than N cycles).

Memory Waitstates for Different Memory Areas
Different memory areas (eg. ROM and RAM) may have different waitstates. When executing code in one area which accesses data in another area, then the S+N cycles must be split into code and data accesses: 1N is used for data access, plus (n-1)S for LDM/STM, the remaining S+N are code access. If an instruction jumps to a different memory area, then all code cycles for that opcode are having waitstate characteristics of the NEW memory area (except Thumb BL which still executes 1S in OLD area).

Which is GBA using again? ARMv4 or ARMv5? (I see a ARM7TDMI thing, so does that make it v7?)
v4 means that mul may have 1 to 4 more clock cycles than lsl.
v5 means that mul may have 3 more clock cycles than lsl.
(I guess?  Might be a bit confusing. )
But we shouldn't forget about calculating:
-mov instruction that would come before mul -- assuming there's no mul with an immediate value, and instead multiplies two vars together
-And the add instructions used with lsl as well.

So let's just say if it was v5, then: (Assume var2 has already been assigned a regen value)

mov var1, 0xA (1 clock cycle)     (var1 = 0xA , 0xA is hex for 10.)
mul var1, var2 (4 clock cylces)     (var1 *= var2)
Total: 5 clock cycles

lsl var1, var2, 0x2 (1 clock cycle)     (var1 = var2 << 2 , or var1 = var2 * 4 if you don't know bit shifts.)
add var1, var1, var2 (1 clock cycle)     (var1 = var1 + var2)
lsl var1, var1, 0x1 (1 clock cycle)     (var1 = var1 << 1 , or var1 = var1 * 2)
Total: 3 clock cycles

(Not counting seq. waitstates. -- Would also be nice if anyone could verify this.)


QuoteI guess they just really liked using LSLs to multiply.
And iif I remember correctly, I don't think this is limited to just Camelot... Check other games by other companies too.
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)

Salanewt

Honestly, that sounds like the most sensible reason for the LSL use over MUL. Although I'm pretty sure GBA is mostly ARMv4T, with some traces of v5T and maybe higher?

Looking it over, it looks more like GBATEK is saying that LSL/LSR/etc. is two clock cycles (1S + 1I, ignoring wait state access), but for MUL the second part of that depends on the MSBs (which I don't 100% understand either, but think I somewhat get the idea); if it actually is based more in ARMv4T, then it should have a range of 2-5 depending on MSBs (whereas v5 is 4 regardless of MSBs, like you said in your post). If all of this is true and I'm not making any major mistakes from being tired, then the current LSL/ADD/LSL thing should be five cycles and the MOV/MUL may actually be as high as 6 or may be lower. I get the feeling it's lower than 6 with a value as low as x0A/10, but I'm not entirely sure how that works. The two main things would be to figure out whether MUL is based in v4T or v5T, then from that point understand the MSB thing better.

Giving it more thought though, I do believe we are going just slightly off topic here. Ah well.

Oh yeah baby, £ me harder.

Fusion is just a cheap tactic to make weak Adepts stronger.

Yoshi's Lighthouse is a hacking website in progress. Why not check it out if you like Yoshi or the Mario & Luigi games?

Daddy Poi's Oily Gorillas

#16
QuoteLooking it over, it looks more like GBATEK is saying that LSL/LSR/etc. is two clock cycles (1S + 1I, ignoring wait state access)
Depends on which lsl/lsr commands you're using.

Look here:
  LSL Rd,Rs,Imm5bit   1S     NZc-  1   Rd=Rs SHL nn
  LSL Rd,Rs           1S+1I  NZc-  4   Rd=Rd SHL (Rs AND 0FFh)
  LSR Rd,Rs,Imm5bit   1S     NZc-  1   Rd=Rs SHR nn
  LSR Rd,Rs           1S+1I  NZc-  4   Rd=Rd SHR (Rs AND 0FFh)
  ASR Rd,Rs,Imm5bit   1S     NZc-  1   Rd=Rs SAR nn
  ASR Rd,Rs           1S+1I  NZc-  4   Rd=Rd SAR (Rs AND 0FFh)



And I still wonder if the compiler assumes worst case scenario, assuming you could probably play the same ROM on both Arm versions?
(Say... which version does the DS one use? - The NDS came out in 2004, so might be a bad example.)

QuoteGiving it more thought though, I do believe we are going just slightly off topic here. Ah well.
Yeah, looks like you're right about that. Um? Split topic?
Golden Sun Docs: Broken Seal - The Lost Age - Dark Dawn | Mario Sports Docs: Mario Golf & Mario Tennis | Misc. Docs
Refer to Yoshi's Lighthouse for any M&L hacking needs...

Sometimes I like to compare apples to oranges. (Figuratively) ... They are both fruits, but which one would you eat more? (If taken literally, I'd probably choose apples.)
Maybe it is over-analyzing, but it doesn't mean the information is useless.


The only GS Discord servers with significance are:
Golden Sun Hacking Community
GS Speedrunning
/r/Golden Sun
GS United Nations
Temple of Kraden

Can you believe how small the Golden Sun Community is?

2+2=5 Don't believe me? Those are rounded decimal numbers. Take that, flat earth theorists! :)