øAslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=profile;u=278;area=showposts;start=1080e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index44c0.htmlslickproductions.org/forum/index.php?PHPSESSID=5f0fck550j2m4m2fpbtkj2vkm1&action=profile;area=showposts;u=278e:/My Web Sites/Slick Productions - FFIV Message Board/slickproductions.org/forum/index44c0.html.zxÙåg^ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈ0P.>*OKtext/htmlISO-8859-1gzip@øÕ>*ÿÿÿÿÿÿÿÿTue, 10 Mar 2020 19:25:35 GMT0ó°° ®0®P®€§²ð®×åg^ÿÿÿÿÿÿÿÿm5>* Show Posts - chillyfeez

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

1081
Also, what would happen, in theory, if the character was using a bow and arrow, and both had a spell assignment?
Would the game only use the spell of the weapon in the dominant hand, or would both spells be cast?

1082
Final Fantasy IV Research & Development / Re: Fun with Summons
« on: October 11, 2013, 11:29:10 AM »
So, now that we know how Special sizes work, time to make them work for us.
Here is how I turned Imp into Jinn...

Imp has the first entry in the enemy graphic properties table at 7CC00.
By default, Imp's data reads:
01 00 03 C1

First thing we want to focus on is the last two bytes, the graphical pointer.
Imp's Graphical pointer is 03 C1, or C103. The formula to use is ([pointer] * 8) + 8200 = Beginning of graphical data.
so
C103 * 8 + 8200 = 60818 + 8200 = 68A18 This is the beginning of Imp's graphic
Jinn's graphic starts at 69E40 (found by using Tile Layer)
so
69E40 - 8200 = 61C40
61C40 / 8 = C388 This is Jinn's Graphic pointer (written as 88 C3)

So now we have 01 00 88 C3

As previously stated, The palette (second byte) means nothing when employing a Special size, so we can ignore that entirely.

The next (recommended) step is to use Tile Layer to lay out Jinn's sprites. This will serve two purposes:
1) we will know how large of a rectangular area we need to use
2) we will be better able to visualize what we need to do with sprite arrangement
So, doing this, we see that Jinn requires an 8x6 rectangle.
(Keep Tile Layer open in the background. We'll be referring back to this arrangement later.)
It's recommended to use a Special size that is already 8x6 or larger. While we can customize the size of the rectangle easily, we have a finite amount of data to work with for sprite arrangement (unless we change the pointer to change the location of the sprite arrangement data - which is possible, but more trouble than it's worth). For this hack, I decided to use D. Mist's size (80; also 81, but more on that later).

We know the details for Special size 80 are at 7D000, and are 35 91 A1 02 00.
First thing to do is to change to the right palette (third byte).
I want to be sure Jinn uses the correct palette. Summoned monsters' palette assignments are located at 7004C. Count along this list until we get to the 8th byte (Jinn is the 8th summon): D0. This is what we will set for the third byte of our special size details. so now we have:
35 91 D0 02 00

We could change the 5th byte in order to assign a different set of sprite arrangement data, but again, more trouble than it's probably worth. We'll keep that at 00.

The last thing to do here is to change the size assignment. As previously detailed, this Special size uses the 11th (hex) size in the size table, 0A 08. This is a bigger rectangle than we need. Two options here: either change 0A 08 to 08 06, or point to a different location in the size table. The latter is the wiser idea, because this will leave 0A 08 available for other monsters' needs. Because this was my first try at it and I didn't know everything yet, I chose the first option. I used the second (wiser) option for Indra and Shiva. I'll go into that a bit when this is over.

So now we have the right size, palette and sprites for Jinn. Last thing (sorta) to do is to create the right sprite arrangement. So, as noted in the previous post, size 80 uses the first sprite arrangement pointer 72 CF. We add CF72 to 68200 to get to the location of the sprite arrangement data: 75172.
Remember we left Tile Layer open with our arranged sprites? Bring it back up. It's a good idea to have Tile Layer and your Hex editor up side-by-side for this. The good news is, unlike D. Mist, Jinn's sprites all appear in the proper order, so when we don't have blank spaces, we can just count up. This is mostly true for Indra and Shiva, too, but not entirely. I'll explain what I mean by that in a later post.
We could, to make things easier, open up a notepad to make this whole process a bit easier to visualize. We know from our arrangement in Tile Layer that Jinn needs to look like this:
Code: [Select]
--XXXXX-
-XXXXXXX
-XXXXXXX
-XXXXXXX
XXXXXXXX
XXXXXXX-
So in order to make the arranging easy in my hex editor, I typed that out without any line breaks:
Code: [Select]
--XXXXX--XXXXXXX-XXXXXXX-XXXXXXXXXXXXXXXXXXXXXX-For me, this saved me a bit of thinking when writing the arrangement data. Anyway, whether you need to use that step or not, the end result will look like:
Code: [Select]
-- -- FE 02 00 01 02 03-04 FE 02 05 06 07 08 09
0A 0B FF 0C 0D 0E 0F 10-11 12 FF 13 14 15 16 17
18 19 1A 1B 1C 1D 1E 1F-20 21 22 23 24 25 26 27
28 FF
D. Mist's original arrangement will continue for a bit after this, but you don't have to worry about that. You've programmed in 48 sprites and spaces to fill your 8x6, so the game will stop looking after that.

So now we have a fully altered monster - Imp looks like Jinn. But why stop there? The GFX team went through the trouble of programming in two beautiful images for each of the three elemental summons, but we only get to see them for very brief periods at a time. Furthermore, Special-sized enemies can change their image mid-battle - so let's do it!

Most of this process will be the same as above, so I'll try to be brief.

We're going to use D. Mist's "Mist" form for this one (we've already used one formation, so we might as well use its partner). That's Special size 81 (I documented these all here, by the way), which is at 7D005 and reads:
05 9E A1 02 01

The second form will always use the same palette as the first for summoned monsters (summons load only one palette), so we'll change A1 to D0.

We're going to make a change to the first byte here. Notice that for size 80, it's 35, but for size 81 it's 05. If we keep it this way, Jinn will move backwards a bit when he changes shape. So change the 05 to 35 and this won't happen.

Now, here's where my novice was showing again. The second byte, 9E, refers to a different size than that of Size 80. The wise thing to do would be to make this value the same as before, as the second form of Jinn is also 8x6. I didn't do that - I changed THIS size to 08 06 (from 11 08). Fine for this hack, which doesn't allow the player to see more than a few monsters, but for larger scale operations, change the second byte from 9E to 86 to use the already existing 8x6.
So now at 7D005 you'll have:
35 86 D0 02 01

We're done making changes here. On to arranging Jinn #2's sprites.
Size 81 uses the second sprite arrangement pointer, which is at 75102 and reads B4 CF.
Add CFB4 to 68200 to get 751B4. This is where we will start our sprite arrangement.
Same prep process as before, but remember - we're using the SAME bunch of sprites that were loaded for Jinn's first image. Since none of them are repeats from before (which is in contrast to what happens with Shiva and Indra), the first sprite in this arrangement will be the one after the last sprite from the previous arrangement.
In other words, Jinn #1 ended at 28, so Jinn #2 will begin at 29.
The end result will be:
Code: [Select]
-- -- -- -- FE 02 29 2A-2B 2C 2D FE 03 2E 2F 30
31 32 33 34 35 36 37 38-39 3A 3B 3C 3D 3E 3F 40
41 42 43 44 45 46 47 48-49 4A 4B 4C 4D 4E 4F 50
51 52 53

So now we've "drawn" Jinn #2. Only thing left is to change the AI so that Jinn #1 changes into Jinn #2.
Remember I said that only Special-sized monsters can change shape? Well that bit of info provides a key here. You'll notice that when a monster changes image (as originally programmed), the game says (translated into plain English) "Change sprite to 01," or whatever. Well, since Special sizes start at 80, add 80 to this command to know which Special size you are changing to (or contrapositively, subtract 80 from your Special size to know how to script the transition).
So, to make Jinn turn into form #2, "Change sprite to 01."
To make him change back to form #1, "Change sprite to 00."
(If you wanted to make Jinn change to Special size A7, "Change sprite to 27," or "39" in base 10)
I'm assuming, by the way, that you're using Ff4kster to rewrite AI. If you're reading this and you are serious about hacking FF2US and you've never used Ff4kster... well... Get Ff4kster.
I chose to chain together the form change and the attack spell. My original plan was to chain "Form change-attack spell-revert" all together, but it seems that if the last part of the chain is not an attack, then the attacks in the chain will not cause damage. Weird. So instead I increased the monster's speed and made the revert its next action.

So that's it for today. Next up is the marginally different process for Shiva and Indra. It will be a significantly shorter post. Then we'll get into changing Summoned monsters' images, which is enormously complicated to explain and will probably be the longest tutorial in this thread.

 :edit: Sorry it's taken me so long to follow up. Real life's been a bit busy, and in the off time I became semi-obsessed (again) with a hacking experiment that's not really going as well as I'd hoped. I'll finish the Special sizes tutorial tonight or tomorrow, then will get into summoned monster images very soon. Promise.

1083
Question: when using your code, does the spell cost MP?
If not, how does it know not to (since it's using the magic routine)? And is it possible to make it cost MP? This would take a bit of the cheap out of a theorhetical MKnight's special command...

1084
Wow, good stuff. Nice going, Grimoire!

1085
Final Fantasy IV Research & Development / Re: Fun with Summons
« on: October 09, 2013, 09:30:43 PM »
I'll focus first on how I changed Imp, Eagle and FloatEye into Jinn, Indra and Shiva. This is, by far, the easier of the two modifications in this hack, and some of what is done here will be referenced (mostly as a point of contrast) when explaining how to change summon images.

The first thing to note is that these three summons - three of the only five that never appear as enemies in the original programming - are irregular sizes. In an early hacking experiment, I used Tile Layer to copy Jinn's sprites over those of an existing monster, including the empty spaces necessary to make the image fit properly in a rectangular area. This worked fine, but there were a few problems/limitations to employing this method. First - doing so meant erasing the image data of an existing monster (I used EvilMask). This could have been avoided by using one of the large banks of empty data at 6EA20 or 68448, but these banks become very valuable when altering summon images, whose pointers present far more limitations than those of enemy monsters. The second problem with this method is that it does not allow for image changing. Enemies can only change size/shape if the target size/shape is one of the "special" sizes (Size byte is 80 or higher). So, in order to undertake a project like this, I decided to learn the previously undocumented information about the Special sizes.
Turns out it all starts in a table at 7D000. Each Special size (numbered 80-BF) has a five-byte entry in this table. I still don't know absolutely everything each of these bytes does, but I learned enough for what I wanted to do:
Byte 0: x-position (Special sizes have a fixed x/y that ignores battle arrangement), plus other unknowns
Byte 1:
 bits 0-5: points to to a location in the size table at 7015E
 bits 6-7: unknown
Byte 2: Palette (Special sizes ignore the standard monster palette byte - This is how K. Eblan and Q. Eblan change palettes mid-battle)
Byte 3: unknown
Byte 4: indicates which pointer to use for sprite arrangement data (more on this later)

So, D. Mist's initial form (size 80) reads:
35 91 A1 02 00

35 - small changes to this byte will move D. Mist forward or backward. Large changes do more drastic (and seemingly erratic) things.

91 - bits 0-5 point to the monster's rectangular size, so break 91 into its bits: 10010001, then disregard bits 6-7: 010001, and you get 11. So we're using size 11 on the table at 7015E. Each of these sizes is two bytes (x and y sizes) so start at 7015E (00) and count up two bytes at a time until you get to size 11, which is 0A 08. So D. Mist is 10 bytes wide and 8 bytes tall. If we wanted D. Mist to be 2x2 instead (size 00), we would change bits 0-5 to 0 (but keep bits 6-7 the same), so we would change this byte to 80.

A1 - D. Mist uses monster palette A1.

02 - unknown

00 - D. Mist uses the first tile arrangement pointer.

Now, let's take a look at the tile arrangement...
The tile arrangement pointer table is located at 75100. Each pointer is two bytes. reverse the order and add the value to 68200 to find the tile arrangement for the size in question. So, D. Mist uses the first pointer, 72 CF.
CF72 + 68200 = 75172. This is the address of D. Mist's tile arrangement data.
When the game starts loading a monster image, it firsts loads some crazy amount of sprites into memory. Presumably, this is necessary in order to load Zeromus, but for all other monsters seems like a waste. The sprite arrangement is a sequence of bytes that either indicate empty space, or which - of the sprites that have been loaded - to display. The arrangement does not need to tell the game when to move to the next line, because there is a predetermined rectangular space to work within. For the same reason, you don't need to tell the game where to stop. Within the sprite arrangement, 00-FD each represent a sprite (in the order they appear). FF represents a single empty space. FE XX represents multiple empty spaces, where XX is the amount of empty spaces.

D. Mist's tile arrangement reads:
Code: [Select]
-- -- FE 06 00 01 02 FE 06 03 04 05 06 FE 03 07
08 09 0A 0B 0C 0D FE 03 0E 0F 10 11 12 FF 14 FE
03 15 16 17 18 19 FE 05 13 1A 1B 1C 1D 1E 1F FE
02 20 21 21 22 23 24 25 26 FF 27 2F 2A 2B 29 2A
2B 2C 2D 2E

Keeping in mind that D. Mist is 10x8, this means that the arrangement will end up looking like:
(where an X is a sprite and a - is an empty space)
Code: [Select]
------XXX-
-----XXXX-
--XXXXXXX-
--XXXXX-X-
--XXXXX---
--XXXXXXX-
-XXXXXXXX-
XXXXXXXXXX

So, that's how it works. In the next post (maybe tomorrow), I'll demonstrate how this system was harnessed to transform an enemy monster into Jinn.

 :edit: sorry - this all is just a re-telling of info I've already posted, but it's presented in a much more clean fashion, and serves as a necessary basis for what will follow.

1086
Nice! I only count eleven bytes, btw (even better).
When you say Peep was 94 bytes... is that hex or base 10?

Also... Has there been previous significant speculation that "crash" was originally planned to be a now-abandoned "airship" command?
The big problem with this would be the AV - are you thinking of just stealing the animation from, say, Fire3 (easy enough, but not particularly interesting)? I guess it's possible to use the actual airship's sprites for something, but I'm certainly not adequately skilled to write new animation for such a project.

I've actually been cooking up an idea for a custom Mime command. 84 bytes may well be enough to do it.

1087
Final Fantasy IV Research & Development / Re: How do summons work?
« on: October 08, 2013, 10:15:34 PM »

1088
Final Fantasy IV Research & Development / Fun with Summons
« on: October 08, 2013, 10:14:14 PM »
I'm going to post the full how-to on this thread for ease of understanding (instead of making you read back through multiple posts in the Summons and Graphics topics), but It'll take a while to write the darn thing because the processes are a bit complicated to explain (though, once you get the hang of it, not so hard to do).

So what you have here is an ips patch and a save file.
 :edit: Save file link is broken, and I do not currently have a backup. I will restore this at some point. Sorry for the inconvenience. IPS file still works, though, but you'll have to hack in an appropriate save state.
Apply the ips to a clean FF2US v1.1 ROM and rename it to match the save file. Load the saved game (don't start a new game - I cannibalized some of the basic enemy fight routines and accidentally made it so Cecil's maid never moves away from the hallway she's blocking).
You'll start in the Baron region with Cecil, Kain and young Rydia. They all have better than normal starting levels and equipment, and Rydia has "Shadw" in her Summon list. This is a fully-working Shadow Dragon summon. It costs 99 MP and destroys one enemy 100% of the time. It replaces Imp.

Try it out. Walk around and get into a fight. You'll notice that Baron is populated with some new enemies: namely, Shiva, Indra and Jinn. Each of them will change their spriting, cast the "1" spell of their respective element, then change back.

Obviously, the purpose of this little hack is to demonstrate the applications of what I've discovered about changing "special" monster images and changing summoned monsters. I'll be posting the step-by-step how-to for all of this here over the coming week or so.

1089
Ideally, I guess the player would want the spell to occur in addition to the attack damage. I mean, if I just want to cast the spell, I'll just use the weapon as an item. But I sincerely doubt that the game is capable of doing that - there is no other instance of a single character attack that generates multiple damage calls.
You could (I think):
  • Store zero in 00A2-00A3 (end damage result location)
  • Check for weapon spell
  • If none, jump down to regular attack routine
  • RNG
  • Check if random number is within range
  • If not, jump to regular attack routine
  • Load weapon spell
  • Jump to spell subroutine (which will return here when finished)
  • Regular attack routine
  • Add attack result to 00A2-00A3

In theory, I think this would cast the spell (if luck deems it so), then attack, and combine the resultant damage. Setting A2-A3 to zero first would ensure that if no spell is cast, only the attack's damage would be applied (instead of, say, being added to residual values from whatever the last attack was).

1090
Quote
Now I wonder how difficult it would be to make the Fight Routine read the Weapon Spells and cast them on a random basis...

I was just thinking about that the other day. You'd definitely have to write some custom code... I guess it would look like (in english):
Check if spell is assigned
If not, return
Generate random #
Check if # is (in desired range)
If not, return
Check/store assigned spell
Jump to magic routine

... something like that?

1091
Huh... looks like I didn't even test Twin, so who knows what I was doing. I guess... sorry?
So it works with Salve, how is changing the targeting value in the subroutine itself affected by changing the targeting byte here, I wonder?

1092
 :blush: my mistake. Did you try targeting enemies with it? Maybe I tried that first and the result was unchanged so I jumped to conclusions... wonder what else I might have missed.

1093
Couple of questions about the targetting...
Did you try other values beyond what you listed? For example, what happens if you use 78? Does it target everyone except slot 5? Have you tried FF?
More compelling to me than that: have you noticed any other routines storing a value into 26D4? Is this always used as the targeting byte in RAM?

1094
Final Fantasy IV Research & Development / Re: Steal/Sneak Command
« on: October 03, 2013, 12:37:59 PM »
One thing I'd be concerned with regarding expanding the ROM would be the effect that doing so might have on its compatibility with FF4kster (at this point it's probably safe to say your research here is intended to supplement edits you'll be making with FF4kster).
I've made far less significant changes that caused it to no longer recognize my ROM. I guess you could make a patch to apply after all FF4kster edits are finished, though...

1095
Final Fantasy IV Research & Development / Re: Steal/Sneak Command
« on: October 03, 2013, 11:14:39 AM »
You'd have to use a JSL instead of a JSR because that allows you to specify a three-byte address. The commands are all kept within the 3XXXX range for that exact reason (it takes one less byte of code to execute a JSR or a JMP versus a JSL or a JML). There's no reason, though, that you can't JSL to some random empty space outside of the 3XXXX range as long as you're just inserting an extra piece of linear code - you just RTL at the end and you'll be back in the 3XXXX range where you started.