• Welcome to Final Fantasy Hacktics. Please login or sign up.
 
March 28, 2024, 04:23:37 pm

News:

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


Status CT timer to turn number

Started by yamish, February 24, 2019, 11:54:57 am

yamish

February 24, 2019, 11:54:57 am Last Edit: February 24, 2019, 06:05:12 pm by yamish
I know when setting timers for abilities that they must cancel each other out in order to share a timer. And their times are set in fftpatcher.

Doom seems to have a unique timer in that its CT in fftpatcher is 3, indicative that it is a variable for turn number rather than clockticks. I'd like to apply this same mechanic to other timers, but without cancelling or being cancelled by doom.

I assume this would be a very simple hex edit to copy a pointer from one timer over the pointer of another. Can anybody point me in the right direction how to do this?

Edit: meant turn number, not turn length
  • Modding version: PSX & WotL
  • Discord username: riggz raggz

Glain

Heh heh heh.  Apparently you haven't seen much of FFT's code yet.

It's probably hardcoded by status ID.  The routine that handles decreasing status CT for those that use clockticks is here and the routine that calls it is here.  It's looking directly at status IDs.

I'm not sure, however, where the code is that affects the countdown for death sentence.  Looks like a job for a debugger -- breakpoint when the value changes.
  • Modding version: Other/Unknown

yamish

February 24, 2019, 08:18:19 pm #2 Last Edit: February 24, 2019, 08:50:21 pm by yamish
Glanced it over, gonna look a little more closely and google some asm syntax i reckon.

I did notice that there's a comment in the decrease routine that says it applies to poison through reflect. Reflect's timer is located at 0E (in wherever they're located) and doom is right after it at 0F. But maybe i missed a comment where it states a section is for doom.

Thanks for the links! I'll see if I can figure it out.

Edit: Given that below is the start address of the routine



Would here be where it's using jal to call for it to run and plug in the remainder?


If so, then maybe I can spot a similar call? I don't know...i just started asm seconds ago.
  • Modding version: PSX & WotL
  • Discord username: riggz raggz

Glain

Oh, those comments are from my annotation of that code on the Wiki.  The code itself doesn't actually have comments in it.

Yes, the jal statement you highlighted is the one that calls the routine.  That code probably runs for every clocktick, whereas the code that handles the death sentence CT probably only runs on unit turns so I imagine it's somewhere else.  Finding that code is the question, and that's where I'd use a debugger.
  • Modding version: Other/Unknown

yamish

That makes sense, a doom check at start of turn rather than somehow stuffed into global CT. I'll look into debugging tools.

I'd assume grab values at the start of test unit's turn, then again at next, and note which counts down each turn.
  • Modding version: PSX & WotL
  • Discord username: riggz raggz

Glain

No need to play detective with where the value is in RAM because we already know.  This is a very handy reference.

In-battle unit data in RAM starts at address 0x801908cc and the size of a unit is 0x1c0 bytes.  They're stored sequentially in one big array.  If you use debugging tools to inspect the values of these RAM addresses at runtime, you should be able to find your test unit.

From the reference above, we also know the death sentence CT is offset 0x006c from the start of a specific unit's data.  That should give you a specific RAM address for your test unit.  You can set up a write breakpoint at that memory location which will break execution when the value is changed.
  • Modding version: Other/Unknown

yamish

February 26, 2019, 01:19:34 pm #6 Last Edit: February 27, 2019, 04:02:11 pm by yamish
Dude. Thanks so much. I've been glancing over the ASM tutorial, on the main site, in the little downtime I've had the last couple days. Seems pretty straightforward.

So basically, locate the location that's 6c from the unit's start address. Pinpoint which routine is changing that variable. Find the spot in that routine that differs from all the other status routines. Then alter a routine in the same way to hopefully make a couple statuses count by turn number. Do something wrong then come back here with another question.

Cake! Gimme 5 minutes (days)!

Edit: OK, so I've pinpointed the change, but am unsure fully what I'm looking at. In the disassembly window, just above the highlighted nop, I see that it is loading unsigned data from r5 to r2 (i think). The beginning of this starts after the preceding nop, with what appears to be summing r6 with r6 and placing the result in r4 (if i'm understanding these instructions correctly anyway). It threw a call stack at me also, as can be seen...is this call stack the location of the routine i'm actually looking for? Nevermind, I realize it's telling me where to look in the disassembly window. Any tips on isolating the routine itself from all this? I didn't realize i would be requesting as much hand holding with this, but I'm trying to limit my own ASM requests for things that seem like they should be fairly basic to me.

  • Modding version: PSX & WotL
  • Discord username: riggz raggz

Glain

That looks like a breakpoint on either a read or a write (signified by "RW" in the breakpoints window), and a read triggered it:

0x8019ab54: lbu r2, 0(r5)


That takes the value in RAM at the memory address in r5 (+ 0) and copies it into register r2.  We can see the value of r5 = 0x80190938, which is an address included in your breakpoint.
(Using 0x190938 - 0x190939 for the breakpoint will cause it to trigger for both locations; you should be able to use 0x190938 for both start and end)

The call stack there isn't actually showing the call stack but just the current instruction.  If you step through a few lines, it should eventually load the call stack properly again.  Sometimes you have to step all the way through the current routine to get it to happen.  Not entirely sure why...

Anyhow, what we're interested in is a write to the death sentence CT, not a read of it.  You can set up the breakpoint to only be for writing and you'll just see "W" instead of "RW" in the breakpoint window.  That should hopefully find the code we want to see!

Also, for clarity: addu r6, r6, r4 is r6 = r6 + r4, not r6 + r6 = r4.  The first register listed is the one assigned to, and it's nearly always that way for any instruction that modifies a register value.
  • Modding version: Other/Unknown

yamish

February 27, 2019, 06:48:29 pm #8 Last Edit: March 05, 2019, 01:03:06 pm by yamish
Thanks. I'll take another look at it when i can and post results/potential full resolution (things crossed).

Edit: while i found what i think was the full stack, i got interrupted by a client and will have to track it down again; I'm going to be tabling this for now until i'm done with the other aspects of my mod.  The purpose of this was solely to balance out haste and slow by giving them turn numbers rather than clockticks, removing the OPness of them in the late game. I did not want a zero speed growth mod, as i'm using speed-reduces-CT-of-abilities patch (whatever it's called) to add another layer to leveling/level planning.

Once i'm done working on linking item reqs to skills and trying to balance out synth shop, i'll revisit this and post my findings. Thanks a ton for the help with this, I've decided to finish what I can instead of letting this hold up everything else since each debug session currently is getting interrupted by life.
  • Modding version: PSX & WotL
  • Discord username: riggz raggz