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 - quantumpencil

Pages: 1 [2] 3
26
Don't try to take the easy way (because there isn't one). Realize that being a programming/CS are huge fields with a lot to learn, and prepare yourself for a multi-year journey.

I would suggest learning at least three languages, in the following order:
  • one classical systems language(C)
  • one functional language (Elixir/Erlang would be my bias cause <3 OTP and BEAM)
  • one scripting language (Python, probably).
  • If you want to learn specifically for modding, learn x86 after C

I would suggest C first, as it's the classical programming language and a lot of other popular programming languages are modeled on it. You can get close enough to the ASM to write code in C calling fist size structs in compiled executables, etc so it's by far the most useful languages for modding compiled code. C++ is also woefully complex for a beginner, I've worked in it for like 10 years and probably know 25% of the language spec cause it keeps getting more bloated.

Also take at least one systems programming course and one algorithms/data structures course, or familiarize yourself with the relevant material. Graph-traversals, dynamic programming, greedy/random algorithms, hashing and complexity analysis are tools you want in your toolbox for general purpose engineering. Systems programming will help you understand how code actually executes on your system, the various levels of virtualization involved, and is basically what you need to be able to mod a compiled executable.

I recommend this mostly to expose yourself to different paradigms and ways of thinking about code. Don't waste time on specific frameworks at first, this or that web-hotness is always changing and once you have a strong conceptual understanding of the foundations of programming picking up a new "framework" takes a few weeks of reading a codebase written in it + documentation.

To this end, remember to READ code, especially at first. Then try to use patterns you encounter in your own projects. You won't become better if you just write code, because -- well, you don't know how to write it. Gotta imitate before you innovate =p.

For getting started, I suggest you consider enrolling in Harvard's CS50 course: https://www.edx.org/course/cs50s-introduction-computer-science-harvardx-cs50x. It's free, and the first course in the series is taught in C and will do a good job familiarizing you with what I consider to be "the basics."

27
Would definitely be cool. I'm going to go ahead and try this in the coming weeks, my first test-case will by my float status effect for my upcoming tactical elements mod.

Ideally I'll be able to play the characters idle animations but transpose them up by a certain amount by adding a new animation per character of them "floating" up and "floating" down which is essentially the same thing the OP asked for but I'm not gonna do a bunch of work on the animation aspect (Animation will literally just be them moving straight up in idle).

If I get that working I will of course post and update and share my findings, any of these ideas are possible at that point.

28
Yes, I could probably do that.

You'll need more than one animation though. I would suggest the following at a minimum:

1: Take the animation where Cid changes into the back row as a base (03). Edit that animation in Kimera to look like a "jump" animation and make sure that he jumps really high off screen when it is used.
2: Take the animation where Cid changes into the front row as a base (04). Edit that animation to start up in the sky and "jump" back down to the ground.

That's all you need in theory. We can use a script like the change/row script with the opcodes that change/return model location(don't remember which ones, but they're in my disassembly) to have Cid jump off screen. Then we can flag him as not able to be targeted, and set a jump bit somewhere in his AI battle data. Whenever that bit is set, his just need to write a main-script that enqueues a battle command which uses Throw animation to have him rain down some lances on people by setting the data we want prior to the execution of the command. We can run the return to ground script after a certain number of C or V-Timer ticks (I'm doing this for burn already)

I wouldn't know how to create an entirely new command (I could replace one you don't care about and rename it "jump" on the menu) -- that might be possible too but I haven't looked into doing something like that yet.

29
Of course it's possible, this is just a program, and we can inject an arbitrary amount of Turing complete code into it so in theory it's possible =p.

I think it's practical as well. I recently hacked the game using DLL-injection to run a new animation script under specific conditions for my burn effect. (Simplest possible script, E8 EC FE =p)

There's really only two steps beyond that needed to do what you're talking about:

1: Someone needs to reverse engineer the structure of the animations themselves in the **da files so that a new "animation" can be created.
2: Someone needs to figure out how the game "looks up" a given animation that appears in an animation script (Where the **da files get loaded and where the pointers to the correct indexes get stored) which is just a matter of doing some more reversing work on the function that runs the animation scripts.

Then you just need to malloc a new struct to holding the custom animation you want (the *da clone data) and rewrite the opcode handler (The animation script doesn't actually think of low indexes as opcodes, so the "byte" of the specific model animation) to look up that index at your memory address instead of where it usually goes.

Depending on generated x86 that could either be super easy (If the opcode/handler for animations is a different function, you can just replace/redirect the function, which is the easiest way) or more difficult (might have to patch the raw ASM to make space for a call to a new function that does what you want).

30
EDITED to reflect solved problems.

Ok, I have found out how the relevant offsetting/handling of magic actually works. It is handled by the routine at 0x4281B1, corresponding to animation script opcode 0xE8. This explains why only matching command indexes AND model scripts can summon effects. There is a switch 31 in here, and based on the command ID, it fetches the final copy of the (relative animation ID)  and looks up an index in a table; This is an index to another big table of subroutines associated with various "animation" effects. (Mostly, Magic also has a few subs at random places handled by a secondary switch). These subs get passed to 0x4284A7 which actually executes the animations (and hits opengl libraries)

This is possibly the least modular way I can imagine this being implemented. It would still be possible to execute an Enemy Skill or something with a magic animation, but it requires some ugliness. Only way I can think of is to wrap this function and then prior to calling the original, change the Command ID and the Animation Indexes to whatever you want based on their copied values; i.e, if the it's command 0x0D (ES) with Effect ID (0x04), Instead go to the magic case with ID 0x1B and you got Fire. I'll work on a wrapper like this, but this is the actual code (I stepped through the animation frame by frame) so it's gonna work =). Not as elegant as I'd hoped though.

This also means getting burn to display will be a little tricky, as this function doesn't have a "case" for command index 23 at all, meaning I do not think that index can ever display additional effects Even if the particular model animation allows it (I know this, from testing, but now I know the reason). If this function is still called for out of range indexes then that's not too bad, but if it's not it might be annoying.

Moreover, I have found out how the game actually gets "which" script to run. This was hard to reverse as runAnimationScript is constantly running asynchronously for various actors, but basically the block that sets the ptr is at 41FBBB and it's said by taking the commandID (1D) for magic and offsetting from a ptr which is set per actor when a game,the ptr is at 0x8FE2AC, and is different every battle. For command indexes less than 2E, this is the final say on the script being run. This script is iterated over at 0x41FD66, opcode by opcode  and the calls underneath it touch openGL.


UPDATE:Burn effect is now fully functional for both player and enemy characters, and animated =).

31
Thanks ergonomy_joe! Definitely helpful, I think I mis-reversed the struct initially, +1 is the current opcode, not a ptr to the script -- that had me going down some wild goose-chases. This should help reversing the individual opcodes =)

Ok, some more progress tonight. This is as much of the path as I have figured out between "Command" and "Animation Run"

1:MainActionRoutine calls command specific loading functions which set the MainBattleStructures animation related fields.

2:The function which inflicts damage for most commands calls another function at 0x5DBD40, where it calls a "copy" anim data function at 0x5CAB7C.

3: The function at 0x5CAB7C just copies the animation related data and calls another function at 0x5C7DEA with with the AnimData as args.

4: The function at 0x5C7DEA copies this data into two different arrays of maximum size 0x40(EDIT: 0x40 and 0x80, actually), both of which have element sizes of 0xC: These two arrays are located 0x9AAD70 and 0x9ACB98, and the indexes (maintained separately) at which these structs are enqueued are held at 0x9AEA9C and 0x9AEAA0, and incremented after each copy.

5: The data in these structs is consumed 0x42CBF9, which seems to copy data from a specific "enqueued" animation block into ANOTHER array of structs of size 0x20, which starts at 0xBFB710(CommandID ends up here) and a giant array with elements of size 0x1AEC (haven't found the start of this one yet, but the "Animation Effect ID" form kernel.bin or scene.bin ends up here) The values in these structs are directly referenced by The function ergo_joe linked which runs all the scripts

Some copyceptron right there

Surprisingly, Even though I've traced the animation index and command indexes this far (which is pretty close to the end) I still haven't come across the relative offset math used to fetch actual additional effects. Nor have a found where the game actually says "If the command index is 0x02, run the 'magic cast' animation script -- which is the paydirt.

32
C is a lovely elegant language with a small set of tools that are unrivaled for close to the metal programming, I don't understand how someone could dislike C =p.

C++ is a bloated monstrosity with such a large language specification and every new programming paradigm that comes into existence quickly thrown on top -_-. I've worked on a few C++ codebases and they shared almost nothing in terms of design patterns, they were such distinct  language subjects they almost felt they were written in different languages.

If you want an IDE for C I suggest CLion.

33
UPDATE: The stated goals here have been achieved. I have a burn effect, displaying the "fire" animation on every tick, working for both enemies and player characters =). Thanks ergo_joe for the help,  looking forward to announcing/sharing some things with all of you soon =D

Starting a new thread for this specific issue. I've successfully gotten a fire-elemental burn effect working, which ticks alongside poison (but is inflicted/removed differently) by hooking into the poison callback and poison data setter that's run in the games main action routine(0x435D81) during the big switch statement on the command that loads data and calculates damage.

I would like to have these ticks display a fire attack. the main current action struct of size 0x260h has fields 0x24 (which is set from ability data to the effect ID toplay) and 0x14 (which the wiki says is the base index for calculating absolute animation indexes from relative ones). Unfortunately setting thes to 0x01B and 0x00 by replacing the poison-preparation function(0x5C9FC0)  respectively does not cause poison (issued via command (0x023) to play the fire animation.

So there are two current goals:

1: This whole mess about relative animation indexes is inconvenient for modding, as it would be great to be able to reuse all animations in any context; So I am going to work on replacing this behavior with a simpler absolute animation index system, so that any command type can use any animation.

2: I want to get the new burn effect to display the Fire 1 animation on tick (Which is probably more difficult than 1, as I recall certain player ability "scripts" call additional affect animations -- and poisons 0x23 command likely has no animation scripts associated -- so it's possible a very simple script which does nothing but display the animation effect itself at the target location will need to be created, if there is no "idle/no actor animation and then display an effect at target location" ability-effect using script currently in the game.)

EDIT 2 - GOOD PROGRESS: Did a bunch of reversing tonight. The scripts in question are actually loaded from the model files, and accessed by a routine which switches on the opcodes in the scripts which lives at 0x41FBA4. This function seems to be holding the a pointer to the script in ebp-14h, which it's setting based on some kind of other switch statement, but I don't quite understand what this is doing currently.

Now I have a much clearer idea of what I'm looking for, if anyone wants to help reverse/knows this. Basically this function gets a pointer to an animation script and runs it. These scripts are loaded up from model files. When the an action is popped of the battle queue and its main action routine is called, there must be a way in which the information about that attack reaches this function for the execution of the animation.

We don't need to fully disassembly 0x41FBA4 right now (it would take a while) to get a ton of power here; If we can just trace how we get from "setting a bunch of fields in the BattleDataContext Ptr" to "Ptr to correct action script is parsed by 0x41FBA4, we can interject code into the process and instead pass a ptr to a custom animation script under-the right conditions (which we can just hold in RAM somwhere).

This would be sufficient for injecting and creating more or less arbitrary in battle animation effects -- we'll just need to figure out a model script which corresponds to magic, and play around with the op-codes until we get it to "only" display an added effect (replace the 1B with 00 and try to shorten the length it's played). Then when-ever the command index is 0x23, run that script =)

34
Update: I've finished reversing most of the EventList and BattleActionQueue enqueue/pop logic (thanks ergonomy_joe =)), and while I still haven't totally figured out how the game is managing "time" --  which is the last piece to get dots working, I have thus far successfully:

Created a new mechanic for cloud where he has a chance to use double cut or combo an attack with death-blow (like added cut if the added cut were deathblow) after every physical attack, without materia (the first done by re-writing the attack index prior to the main command handling routine, and the second done by generating an event corresponding to "Deathblow on the current target" of priority 0 immediately after a "attack" from an actor identified as Cloud is issued.

Found the data that needs to be edited with to enable a class mod (There's a giant struct of player character data that holds enabled commands. By modifying it in BattleMain (after it is populated), you can pretty much give commands to characters by default without materia, i.e Yuffie can be given innate skills.  Similarly, you can disable access to certain commands, magic, summons or E-Skills in battle). Proved by giving Yuffie innate steal and no access to Deathblow, even if the materia is equipped. 

Replaced Sense with Provoke (Could probably do this without replacing Sense too, but it'd be harder): Enemies record the "provoker" mask in their unused AIVariables data block. If the provoke bit is set, then before any action, change the target mask to that AI stored value. If Sense is used, don't call the damage from the pointer table, but instead just set the bit associated with provoke  in the target, and store the actor mask in the targets AI block.

Once I figure out how the  game does all this clock magic, DoT affects will be next =D

35
Ok, so I got some time look into this. calling the sub (enqueue action?) called within the poison routine with the same arguments called there can be used to, unsurprisingly, re-create the poison effect in random situations.

enqueue_event(attacker_id, 3, 23, 0, 0) are pushed onto the stack prior to the call. The parameters are (as far as I'm able to tell):

attacker_id, some kind of queue priority, command index (poison has index 23h, which is capable of dealing damage, but I'm not sure where the data for these indexes are) attack index, and another 0 (I don't know what this one is for yet)

I have major need for this mechanic, as it is a much better way to implement, for instance, an overheated status (create an attack that does massive fire damage and enqueue it when the physical formula is used by an overheated actor).

So does anyone know what the last argument in the enqueue function is, and...
does anyone know how where the game is looking for the action attack metadata of poison (i.e, the fact that it uses formula 3, it's poison elemental, etc).

Thanks again guys =)


36
Alright, so it looks like referencing the unused variables at the end of those actor battlevariable blocks (the 68h array) in memory and applying extra damage modifiers based on their bit-state accomplishes the true elemental interaction modifiers I wanted. Current action elements are 0x44 in the "battle context struct" (the one with the large gap in between that has current ability data) and so that plus appropriate left/write shifts (which I stuck into the routine at 0x5DB593, which already handles elemental weakness/strength multiplication based on a different intermediate "current element interactions" variable set a previous sub (somewhere in 0x5DB593, though I haven't figured out exactly where) was successful.

Now I'm interested in the duration of  various expiring status effects and how the game handles that. I tried to do this through some truly ridiculous AI script (I used an invisible actor as a clock and kept localvars for every actor, and then checked the 'clock' actor every pre-action script, expiring the status after so many 'ticks' had passed.

Now that I've got routine replacement as an option, I'd prefer to see if these various effects could be made to expire the same way poison currently expires. I should be able to just malloc a new array of length 10 and the required size at runtime and use it as a place to hold any data needed (per actor) to handle the expiration. I'd like to see how the game currently expires its timed statuses, but I haven't had any luck finding the routines that manage/increment the clock or expire status effects (I think as long as I know where the game stores the in game clock, it should be possible to implement this logic). Anyone know where any of these (especially timed status effect expiration) live in the exe?

37
Thanks for the help guys. I'm gonna see about resizing the 68h actor array/relocating it somewhere else in memory. As many size-locked references to this struct as there are in the codebase, I think it may end up being simpler to just make a new array and get the AI engine to write new status data (I'm using battle variable 4310 as a new status mask in my mod) or locate exactly where that byte is being accessed by the AI scripts and have the engine access it from there (I suspect that might actually be the end of this actor struct array).  Either way hopefully once I get it figured out I can add an AddNewStatus() function utility to the dll injector.

@NFITC1 or anyone else who knows, you said the battle local_var correspondence correspond to battle vars 4000-42E0; It looks to me like these structs *are* what the scripting engine accesses/modifies when an AI script writes to actor data (They seem to be updated as expected by AI scripts when I've run them in debug mode and watched the structs), but I want to make sure there is no rawer form that is copied into this struct somewhere.  (As it seems 4300 - 433F, which  I've used extensively in my mod, are actually included in this struct as well, that's probably not the case).

Also wow,  that additional effects method is as almost as intimidating in C as the x86 version =p.

38
PM'd you  about IDA-Sync =)

I'm confused:

1: Are you saying the total struct has size 0x260h or that each actor has a struct of size 0x260h? Also, as I often express myself poorly, a clarification: I'm not talking about the struct pointed to by the battle pointer in my last post (I was in the first post tho), I think that is a different struct (and that one is 260h, I think) but a separate array that is sometimes used to access target/actor data that isn't retreived from the battle pointer. Example here:

From Magic Hit formula (Intel syntax):
mov     edx, BattleContextPtr
mov     eax, [edx+208h]
imul    eax, 68h
xor     ecx, ecx
mov     cl, byte_9AB0E5[eax]

This is only getting the "target id" (an integer) from the battle context_ptr and then referencing an array of contiguous structs starting somewhere around 9AB0E5 (but that's not the real start, that's the "level" of the first actor) and then getting the level of the target by offsetting 0x9AB0E5 by target_id*68h

That is in fact a contiguous array of structs of size 68h right?

39
Fantastic! So that method corresponds to the "effects" that can be assigned to an ability (Multiple Hits, Fills allied limit guages, etc)? Or do you mean additional effects more broadly.

As for the data structure referenced for calculation, I've noticed that there also appears to be a separate array of actor data structs of size 68h stored around 0x9AB070 (I think it starts here, not sure because instead of offsetting from the beginning of the struct, things are offset from the particular thing being fetched in the first actors struct), which seems to have some stats that aren't accessible from what I'm calling the "context" pointer. Target Level, Actor Status Masks, etc are often gotten by taking target ID from the context ptr and doing 68*target ID byte offset math to fetch the relevant actor data.

Now these structs are only 0x68h in size as opposed to the AI script accessible actor blocks of 0x3ff (masked addresses of 4000 - 43ff) so they clearly aren't the AI accessible actor blocks, but they also seem to be affected by changes made to the AI blocks. Do you/anyone else happen to know where information from the AI script accessible actor blocks gets gathered up into these smaller engine accessible blocks?

Depending on how that consolidation happens, I think it may be possible to implement *actual* new status effects within the engine with a nice C API. If the unused actor data (4300 - 433f) is not already being saved (via an object copy) to these blocks, they can be resized (by just relocating the data at runtime) to include new masks for new status effects, that can then be handled by damage calc, or elemental modifer routines, and possibly display visual effects =p

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ASIDE: NFTC1 btw if you want to sync IDA files (In case you have a lot of stuff labeled in it), I've got a plugin for exporting/importing the IDA db to json format for version control purposes. I'm planning to host this json file on github for modders along side this routine replacement toolkit so it's easy for any information about the .exe currently known to be accessed by anyone.

UPDATE: I've successfully replaced the physical damage routine with a routine which always deals 1 damage, and the game runs fine with it. I'd like to have some #includes (read: big structs) for all known data structures used in battle so they can be referenced in C++ in a human readable way and not as offsets. As long as the function signatures match (well, the argument counts match) so that the stack is not corrupted, we can in theory replace any function without needing to do rewrites on the exe, or worry about space constraints.

In particular, I think it will be very easy to add new formulas, once I get passed the data protection issues, we can relocate the function ptr table somewhere else in VRAM with more space and then register new formulas by function_ptr.  I'll try this next while waiting for more info on data.

40
I've been going through the exe battle routines and have a few questions/observations

1: The routine at 0x5D173F chooses the damage formula to call from a pointer table located at 0x8FF1F8. This same routine calls a sub 0x5DC880 which is quite daunting, but appears to be being passed a "0" and a "1" via the stack (as is standard with cdecl calls like this) and is called both before and after the damage formula pulled from the ability data in this routine is called via function pointer. Interestingly enough I can't see where this argument is used within the sub at 0x5dC880. Due to it's size I'm not totally sure what this sub does,  does but it seems to have some roll in preparing the battle context object pointed to in all damage formulas. Anyone made any substantial progress understanding this big guy?

2: The large data structure which is referenced throughout damage calculation and formula selection (and is pointed to by the pointer at 0x99CE0C) seems to contain a lot of information from my inspection, it contains at the very least attacker/target stats, ability data, and some attack flags like whether or not something crit. Has this data structure pointed to by 0x99CE0C been mapped by anyone in the modding community? I've got myself a little loader/dll injector for redirecting routines, but in order to make the redirected routines (and hopefully expose a C api for redirecting exe routines at runtime) I need a better understanding of this data structure -- it looks rather amorphous, I don't see evidence of a clear ability data struct or anything like that at the offsets which seem to correspond to ability flags (like context_ptr+ 48h, which is definitely ability power, or context_ptr + 6Ch which appears to some flags, one of which is "auto-critical")"

Thank you for your help =)


41
Yep, it sets its physical immune flag based on the performed actions action index (turns it off for 3, which is limit) which tells me that global variables like 2120, 2050, etc are set prior to pre-turn scripts.

My issue is that in order to half/double (or otherwise scale) damage taken based on the element of the previous action, I actually need to double or half the attackers level instead of the targets, diamond mutates his own flags.

So I need some way to get the index of the actor who used the attack during pre-turn which is being executed, if that was the case I could just do:

Pre-Turn
If self.soaked_bit_on{
    If 2120 bitAnd 8192 { ## was bolt attack  check
         If not already halved (will store this var in my global clock actor so its the same for all actors, and keep multiple actors from messing with it){
               temp = self.previous_attacker.level
               self.previous_attacker.level = temp/2           
         }     
    }
}

I can then unset the already_halved far and re-assign the attackers correct level in the counter script to achieve the desired effect.


EDIT: Actually, that will cause damage to be doubled for all targets if even one target is soaked, in the event that an attack hits more than one target =(

Is there a pointer table in the exe to the various formulas with actor/target stats in specific registers/fixed addresses for the jump, so that one could find an empty block and create a wrapper around base damage calculation which still performed the calculation according to the pointer, but did something like...

If target level = 255, bit-shift right the base_damage
if target level = 254, bit-shift left the base_damage.


EDIT: I've disassembled the exe, and with help from NFTC1, found the relevant routine. I have successful redirected the function in the exe to a (non functioning) custom function at run-time, so The damage formulas reference a context pointer for most stats/checks, so they have more or less global access to battle state making this much easier. I'm now confident I can implement this as described above with a bit more work tracing the formula calls to make sure my custom functions are referencing the arguments correctly.

 

42
I'm preparing to release a tactical element mod which adds 16 new status effects (mostly elemental) and elemental interactions via (somewhat lengthy and involved) AI scripts.

I've got a hidden actor working as a clock for timing/executing elemental effects (like proper burn/bleed statuses) and via using the 2120 global previous element mask and bitwise operations, this should work both when elemental materia is used to add an element to a weapon strike, or its a normal spell/summon.

Most everything is working, except one piece -- I need to be able to dynamically set an actors elemental weaknesses/resistances (double/half) within the AI script to accomplish my initial vision for this (or otherwise, and likely much more laboriously, boost/reduce damage based on element) Looping through all the bytes it seems proud clod/wall market do not recognize which addresses hold these masks, though they do exist for null/absorb elements. I was wondering if anyone had already figured out if any of the currently unlabeled actor data bytes are half/weak masks.


Example of what I am trying to accomplish:

Use water attack on enemy x, enemy gains the soaked status, which has the following interactions:
next lighting attack does double damage and has a 100% chance to paralyze (provided target is not floating),
next wind attack deals double damage and inflicts the chilled status,
next ice attack instantly freezes the target solid (so they can be shattered),
fire does 1/2 damage and removes the status.


All of this is currently working except for 1/2 fire damage and the multipliers on the lightning/wind effects.


EDIT:

I'm also trying to see if I can do this via stat manipulation

It looks like lowering the level of the target in the pre-target script doesn't affect damage (It's not a factor in damage formulas... too bad not every formula scales like conformer =p), though lowering/raising the level of the attacker prior to damage calculation would scale perfectly. Since I want this to work for both player characters and enemies I can't  lower the level prior to an action in the main script; Is it currently known when the actor values which track previous physical/magical attacker are set? If these can be accurately referenced in pre-action setup script then I could modify the attacker's level conditional on the element of their last attack (in 2120), and then zero out previous/current attacker masks at the end of the counter scripts.

So, tldr; can counter:preTurn scripts access the "2060.41E0" (I think that's it) to get the bit-mask of the user of the attack which is targeting the current actor, but that has not yet executed.

I'll try and check this when I'm back on my desktop which has FFVII set-up to run, hopefully that's the case =p. That would be even better, as it would stack with normal weakness/resistances


43
Chocobos, eh ?
10 bucks it will be replaced by motorcycle.

Agreed, and that is a horrifying, horrifying thought.

44
I don't think there's anything "Japanese" about that kind of action sequence. There's a lot of Japanese animation which doesn't feature those sorts of things.  I do personally find overblown sequences like that puerile. I prefer for the focus to be on the dialogue/character interaction and very rarely do you find the two together. I think the final fantasy series historically has kept the focus off of the action/spectacle (this was relegated to summons and maybe a few FMVs) and on the relationships between the characters.

I hope they don't change this, and I fear that they will.

Quote
How's that coming along?

A few weeks back I started working on it a lot again, and I got some cool things done. I made a very good sapphire weapon model, got the encounter working and scripted in. Some other highlights include a shinryu boss with custom animations and a Four Fiends sidequest (Marilith, Lich, Tiamat and Kraken) which are both about half-implemented in the field. Then, I took a long break because I started a new job and have been putting in a lot of extra hours to get familiar with their ENORMOUS legacy codebase, half of which is written in languages I don't have a lot of familiarity with. That situation is starting to ease up now as I have a better idea of what they need me to know and what is never gonna be touched again =p.

I've been meaning to make a blog about my mod, but I'm lazy/prone to procrastination and I've always hated documenting code/projects (much to the chagrin of all my colleagues). I have also had a hard time coming up with a name for it -_-.  I definitely have enough to show some videos and I'll get the cool ones up soon (At least sapphire weapon/some of the original bosses I'm proud of). There are some suprises I don't want people to know about until they're playing the mod, but I'd be happy to discuss in a PM =p.

45
I'm worried more than anything else. This could be great but the art-style has me worrying they're gonna muck it up by stuffing the game with unnecessary melodrama. Part of what I enjoy about the original game is the wackiness/charm and the characterization being full of ordinary dialogue and humor.

I want to be excited but at the same time I've half expected that when the gang rescues Aeris this time, It'll involve running up the side of the shinra building, back-flipping off the wall, bursting through with a spinny halo of buster swords, and a ten minute fight scene with a specter of Sephiroth.

I suppose only time will tell... and if I'm disappointed, there's still NT and the new mod I'll be releasing. (And the many other wonderful projects members of the forum have created)

46
Question about music in this utility... Is it possible to add an additional music track to a scene without having the .akao file? (By which I mean, if a scene only has two slots for music -- can I add a new slot and then use another piece of music in that scene?)

Thanks -- and tremendous work on this tool. Truly -- I feel as though it has made things possible I'd only dreamed of doing.


47
Could anyone explain to me what exactly causes the "Volume of a file has been externally altered" output in the command line? I'm having that issue now while trying to compile my battle.lgp file for my (soon to be released) mod. A few months ago I used this tool fine and didn't seem to have any problems. There exist plenty of mods which have larger battle.lgp files though -- so is there a work around for this?

Thanks,

QP

48
This is one of the best ideas I've heard in a while. If you happen to log on again soon pm me about this project -- I'd like to continue your work!

Best,

QP

49
I read through the wiki pages & the "gears" pdf, but it seemed pretty general and high level. I haven't had a chance to do a whole lot of tinkering with the executable yet (because I'm taking an OS class and we have to implement a kernel which is eating up exorbitant amounts of time) but I was hoping that there existed a more technical description of the function of the battle module (i.e, a memory addresses for all the subroutines (specifically those checking elemental/status weaknesses) and information about how these functions are placed on the call stack (so what talks to the kernel to tell it push a specific subroutine onto the call stack?) (I see that someone must know that because the order of checks seems to be well-understood (In the enemy mechanics FAQ)-- but where in the executable is the logic that's handling that?). I see where the damage formula's are located from the addresses in the wiki, but I don't see any info about the subroutines which control elemental checking (though how it works is described in the FAQ in high level terms). And I don't see any information about where the logic that governs that is

In particular, while AI scripting I noticed that modifying elemental weaknesses in battle by reassigning the enemies self mask and changing values doesn't work (so I suspect that whether or not specific items are being worn is being checked directly somewhere in the battle module) and I want to have a look at the subroutines that check elemental weaknesses to see if this is actually the case (so I can rewrite them and make it possible for a boss or enemy ability to overwrite elemental defenses)

EDIT: So, it seems like elemental checking is taking place at 0x5DEC52? It doesn't seem to be checking items explicitly though, so it seems like I should just be able to have an enemy directly modify another characters weaknesses by swapping the self-mask and changing the battle addresses... but that definitely doesn't work, which is very confusing to me. The battle addresses which store absorbs/weaknesses seem to work fine for enemies, too.  Does anyone know how the game sets elemental absorbs/weaknesses when entering a battle based on items/materia combinations? Does it just check and then write the value to that actors element def/absorb flags in their particular instance? (or what hex address I can find that logic at)?


50
Completely Unrelated / Re: Coupling and orthogonality
« on: 2015-03-22 20:34:42 »
Orthogonality in the context of object oriented design is used to mean "independent," which will make intuitive since if you've studied any form of mathematics that deals with a notion of "independent" or "not redundant" objects (linear algebra for example, a set of vectors independent if they contribute some direction to the space which no other vector did.) Orthogonality maximizes this independence. If two vectors are orthogonal, then there is no component of one vector which depends on the other. Similarly In orthogonal design, each component (module, class) handles its own task independently of other components. I can then modify specific components of my software without worrying about breaking other components because the functionality of each component is "contained" within itself and talks to other parts of the software through a separately defined interface. Each module doesn't need to care about the implementation details of any other module; those can be freely modified and the software will continue to work as long as the interface is consistent.

Coupling is pretty much the opposite -- there is dependency between components on implementation details of other components. Changing the way one part of your software does something can impact other components due to this dependency. Minimizing Coupling between software components improves the orthogonality of you design.

Pages: 1 [2] 3