Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - NFITC1

Pages: [1] 2 3 ... 115
FF7 Tools / Re: FFVII Enemy Database & Calculator V1.0.0
« on: 2019-02-19 18:25:18 »
In all honesty NFI, I was trying to refrain from sending you a bucket load of updates on this thing; I was trying to wait till it was complete (complete-complete) before sending it your way, but the definition of "complete" kept changing and growing along with the spreadsheet lol.

Do you even code, bruh? There is no "complete" complete. :) Apart from "final/definitive" versions, which is a developer's way of throwing up their hands and saying "I'm sick of this code and don't ever want to touch it again!", there will always be something that can be added/corrected/optimized.

FF7 Tools / Re: FFVII Enemy Database & Calculator V1.0.0
« on: 2019-02-19 12:18:34 »
This thing is absolutely amazing for what it is and I know you spent lots of time on it. It's a great tool for enemy designers to balance their creations.

I know you sent me drafts several times and I'm sorry I didn't get a chance to really try to break it. It looks fantastic! I'm not great with Excel so I'm not qualified to tell you if anything's wrong or how to fix it. Sorry. :)

FF7 Tools / Re: Gauging interest in WM Walkmesh Editor
« on: 2019-02-13 20:11:28 »
Such a thing has long been foretold by many prophets, but fate has not yet blessed us with it.

This is a very common C gotcha (attempting to dereference podhd via &(podhd->line6) is undefined behavior if podhd is NULL. The check for NULL belongs before the attempt at dereferencing podhd and really any C programmer will know that. There's nothing wrong with the "second check" except that it's misplaced, and most good compiler's (gcc, for example) will optimize it away as the attempt to dereference podhd in the previous line will let the compiler know (mistakenly) that podhd cannot be NULL.

Simple solution, check for NULL before you dereference pointers. These sorts of things are more of a hassle when you're learning than later on when you've developed good habits w.r.t NULL handling (responsible for about 90% of C's "gotchas"). Being able to propogate constraints like this and letting the compiler (or instructing it with __builtin_unreachable) optimize away unnecessary works/checks is another factor that contributes to the performance advantage well written C code enjoys over most other compiled languages.

This is not unique to C. This is poor program planning and a violation of the Fail Fast programming convention which can result in runtime errors. Most, but not all, IDEs in more modern languages will detect this and some won't even let you compile. That's with pretty strict options as it will just throw a nullpointerexception (or that language's equivalent) which might be caught outside the method.

The actual solution is always check all your arguments' states before performing any logic on them. Almost all programming errors are the result of NOT performing these checks and handling bad states correctly. The others result from creating massively long methods that try to do too much so no human can keep track of what it's actually doing and it ends up contradicting itself or another method. These errors are universal to all programming.

Just want to throw another hat in the ring. I know Pascal was supposed to be "great", but I hate it. Still hate C more, of course.

Assembly is as close to machine code as you can get. Just because it uses aliases for codes that may or may not be multibyte instead of straight binary doesn't mean the two aren't practically interchangeable. They aren't the same thing, no, but the difference is only technical.

How old are we talking? DOS-era? Some of those use some data compression voodoo in the code that can't be modified without unpacking it.

Start with something REALLY simple, like Perl. It doesn't do much, but almost every OS (Operating System. ie; Windows, Mac OS, Linux, etc) has the ability to run Perl scripts. If nothing else this will get you used to seeing syntax and how code executes when little things change. Perl is executed in real-time as a script.

From there, look to Scratch. Not the most powerful language, but it's hard to mess up. This can be compiled into a stand-alone executable.

The next logical transition would be to java (since Scratch translates 1:1 with java IIRC). You'll run into a lot of road-blocks with java when trying to access system resources. This can also be compiled and nearly every OS can run it.

So the next level would be C#. It's a less explicit form of C++ that is similar enough to java to look familiar, yet have far more functionality. This is where OSs differ. Any program can be written in C#, but it will have to be compiled with a particular OS in mind.

If you aren't scared away from that, you can dive into assembly. Start with whatever your favorite OS runs. Then you can really learn how processors work.

At least, this was my experience with a more modern linguistic twist (I learned QBASIC instead of Perl, but they can do similar things). I spent years (and still do) on each of the languages I learned and I'm still learning neat tricks they each can do.

Hi NFITC, you mention a 1.5.0 version but I don't see any links to it anywhere.  Also, are you planning on releasing the source at all?

It’s still not ready, and yes. This update is super ambitious so I want to make sure it’s right. It’ll have multilingual support too. Source will soon follow, but it’s mostly garbage TBH.

General discussion / Re: Elemental Materia
« on: 2019-01-04 13:20:51 »
No. Either just applies the "attempt to cause status to enemy" flag which has a singular use per action. Multiple hits would cause multiple attempts, but in the case of sleep you'd just as likely cause it then the next hit will snap the target out of it.

Materia do not have multiple elements. There's only one assigned to each materia. Kujata is a summon that has multiple elements attached to the action, but the materia technically has no affinity.


That's how poison works. It takes a delta of one of the actors' timers (I forget which one) and when it reaches a certain value it queues an action which inflicts poison damage to the poisoned. There are a lot of battle "events" that are mostly used by animations, but it can be used for almost anything.

That struct IS the "definitive" values for all things battle. It holds the considered HP values which get written to the save block at the end of each battle as well as which status each actor has, etc. To save on memory, redundancy is reduced as much as possible so these are the only "stable" values for each actor. When damage is calculated it will occasionally temporarily copy values to smaller parts, but the 4000+ battle addresses are what gets kept.

I see the confusion. I wasn't looking at my notes so I wasn't clear on what's going on. :P

The structure you are referring to is an array of 68h in size. The one I'm referring to is a pointer to an array that is 264h bytes in size. It does have a weird gap in its structure between index FF and 200. I'm not sure why, but it doesn't seem like those 256 byte are used.

What YOU are referring to translates to the battle variables 4000 - 42E0 for each actor (there are as many as 10, but only 9 are functionally used). Here's my notes on the structure. Some of the bytes (particularly toward the end) are unused. Some are so rarely used (possibly just once in the entirety of the game) I can't tell what they're for.

Code: [Select]
00000000 BattleVar_Actor struc ; (sizeof=0x68)   
00000000 Statuses        dd ?
00000004 ActorFlags      dd ?                    ; base 2
00000008 Index           db ?
00000009 Level           db ?                    ; base 10
0000000A Unused_0        db ?
0000000B ElementDamage   db ?                    ; base 2
0000000C CharacterID     db ?
0000000D AtkPower        db ?                    ; base 10
0000000E MagPower        db ?                    ; base 10
0000000F PhysEvade       db ?
00000010 IdleAnimID      db ?
00000011 DamagedAnimID   db ?
00000012 BackDamage      db ?                    ; base 2
00000013 SizeScale       db ?
00000014 Dexterity       db ?
00000015 Luck            db ?
00000016 IdleAnimHolder  db ?                    ; base 2
00000017 LastCovered     db ?
00000018 LastTargets     dw ?                    ; base 2
0000001A PreviousAttacker dw ?
0000001C PreviousPhysAttacker dw ?
0000001E PreviousMagAttacker dw ?
00000020 PDef            dw ?
00000022 MDef            dw ?                    ; base 10
00000024 MyIndex         dw ?
00000026 AbsorbedElements dw ?
00000028 CurrentMP       dw ?
0000002A CurrentMMP      dw ?
0000002C CurrentHP       dd ?
00000030 CurrentMHP      dd ?
00000034 anonymous_1     dd ?
00000038 anonymous_2     dd ?
0000003C anonymous_3     dd ?
00000040 anonymous_4     dd ?
00000044 InitialStatuses dd ?
00000048 anonymous_5     dd ?
0000004C anonymous_6     db ?
0000004D MagEvade        db ?
0000004E Row             db ?
0000004F Camera?         db ?
00000050 GilStolen       dw ?
00000052 ItemStolen      dw ?
00000054 Unknown         dw ?
00000056 APValue         dw ?
00000058 GilValue        dd ?
0000005C EXPValue        dd ?
00000060 anonymous_8     db ?
00000061 anonymous_9     db ?
00000062 anonymous_10    db ?
00000063 anonymous_11    db ?
00000064 anonymous_12    db ?
00000065 anonymous_13    db ?
00000066 anonymous_14    db ?
00000067 anonymous_15    db ?
00000068 BattleVar_Actor ends

the struct you speak of that's only 68h in actually 260h in size. There's a monstrous 512 alignment after that 68h that picks back up at 200h. That's where target stats exist and it can change per target. The first 68h stays consistent for the duration of the calculation.

I love the idea of an ida to json exporter. I'd happily apply it to my database. I've marked thousands of lines and don't even remember all the changes I've made. I've annotated nearly every routine used in accuracy/damage calculation and still have to hunt through them to find details.

I can answer both questions for you in excruciating detail, but I can only answer the first one right now since I don't have access to my notes right now.

That method you're seeing before and after the damage routine call is the additional effects handler. It has to run before the damage calculation and after to be able to influence pre damage and post damage calculation manipulation when applicable. The 0 and 1 are handled in the individual effects and will only apply if the action has an effect assigned. I had some detailed notes on the wiki if those still exist on one of the new ones.

Off the bat I can say have a look at how Diamond Weapon handles it. It selectively turns on and off its magic/physical immunities for limits.

You should probably start a new topic with a new subject rather than assume anyone's still looking at this one (other than me).

...How would i do it with "Proud Clod" in case i have to do it with that one?
...Proud Clod should offer to do it automatically when you create a scene.bin

Your KERNEL.BIN needs to be updated. Both Hojo and Proud Clod are capable of doing this. Proud Clod should offer to do it automatically when you create a scene.bin, but it works best if you're using the vanilla KERNEL.BIN (not a mod that may have it in a different place).

Team Avalanche / Re: Mako reactor bridge scenes
« on: 2018-10-17 14:33:20 »
More eerie and terrifying than the original! It's amazing!

Have you considered opening it as a google doc, or using Libre Office or something similar? Both are free and support Excel :)  In either case, is it a document you'd be willing to share? Mostly for my own fascination, and partly for potential use. Or would you prefer if I were to ask about individual things on a case-by-case, where I can't find them elsewhere?

I am using Libre Office to make a few adjustments here and there. I don't care if there's a google doc, but I don't want to bother setting it up. I'd be willing to give you what I have, but it might not make a lot of sense.

Do you happen to have a doc with the addresses noted in, or is it more looking up previous work to find stuff?

A bit of both, actually. Funnily enough I started out a spreadsheet on Excel, then my trial ran out and I'm too cheap to buy a copy of office so I just keep opening it in read-only mode. :P Whatever I can't find on the spreadsheet I dive into my debugger which has lots of comments on various addresses.

What is bit 4 about NFITC1?  I noticed 08 was always set.

It could be one of three things: active actor (animations/effects/scripts run), active target (can be targetted), something else I can't remember related to vulnerability. :P It's AI address 4023 and that's usually unset in boss death scripts IIRC. 4020 and 4022 are unset on death as well so those would be the other two.

Bit 4 would be 10h. 8 is bit 3. 8 I have listed as "Enabled" which means they can be targeted. For allies this is active as long as they are not imprisoned since you can target "dead" allies.

Yeah, that's what I meant. Active bit 6 = 40h.

I do for the original PC release

Top slot:  0x9AB0E0
Middle slot:  0x9AB148
Bottom slot:   0x9AB1B0

An active bit 6 indicates the actor is in the back row.
An active bit 5 indicates that actor is defending.

I would never turn down such an offer! I might not use them all, but having access certainly improves what can be done! <3

Just tell me what you want and I probably have it. I've envisioned random numbers, but they change every frame and by the time your program read/displayed one it would be stale.
Anything else though let me know. AI variables? Timebar values? Status time remaining? etc.

Pages: [1] 2 3 ... 115