FF7 World/Field Map Scripts and Encounters

  • Thread starter Thread starter codemann8
  • Start date Start date
Status
Not open for further replies.
There's a scene at las4_0 after the Safer fight and before the final Sephiroth fight.
That's a point.  Though I guess I never saw it that way due to the battle that comes before it.  But yeah field would be calling that jump.
 
As for your query... it's much easier to just show you.   ;D

The field script doesn't have a stack or threads.  It's a very efficient and well designed script-based solution for the field module.
 
Last edited:
Oh, so you're working on a video that soon then? Sweet!

Interesting tho, so without a stack how does it keep track of calls? Or does it just have the callee (is that a word) track it's execution while the caller continues it's own execution?  If so, how does it know that Script 1 hasn't executed yet if the IP changes on the callee?  Or maybe I'm interchanging the terms stack pointer and frame pointer inappropriately, and it uses a frame pointer? But it sounds like not. Sorry, it's been awhile since I briefly studied low level language in college, although I am a coder by trade.
 
Last edited:
It just advances through script from byte to byte.  Each instruction is defined and it can jump back and forward a number of bytes (jump instructions). It keeps track of script execution via a table from what I can see.  The field module isn't stack based or assembly based (though obviously the hard code is).  It's script based.

The world map module is stack based.
 
I'm looking forward to understanding more after your video.  However, as I'm trying to quick get a working method of ignoring unused scripts, I need a little bit more to get started.  In MR, the different groups/entities have a "Type" and the scripts seem to have differ, based on the first opcode in Script 0.  The pseudocode logic is this:
Code: [Select]
Code:
switch(opcode) { case Opcode::PC:  type = Model;  _character = charID;  return; case Opcode::CHAR:  type = Model;  _character = 0xFF;  break; case Opcode::LINE:  if(_character==-1) type = Location;  return; case Opcode::BGPDH: case Opcode::BGSCR: case Opcode::BGON: case Opcode::BGOFF: case Opcode::BGROL: case Opcode::BGROL2: case Opcode::BGCLR:  if(_character==-1) type = Animation;  return; case Opcode::MPNAM:  if(_character==-1) type = Main;  return; default:  break;}
And based on what type each group/entity is, the different scripts are given labels:
Code: [Select]
Code:
if (type == Model) { Script 2 = "S1 - Talk"; Script 3 = "S2 - Contact";}if (type = Location) { Script 2 = "S1 - [OK]"; Script 3 = "S2 - Move"; Script 4 = "S3 - Move"; Script 5 = "S4 - Go"; Script 6 = "S5 - Go 1x"; Script 7 = "S6 - Go away";}
So, getting to the point: I know the all Script 0s and 1s execute (assuming they don't get shortcutted based on Jumps) on their own and those two scripts can execute other scripts in other entities.  However, I'm assuming that the Location type scripts (the ones that create lines in their first opcode) also execute scripts on their own (probably when your character crosses a threshold).  My question is, which ones execute specifically? Are there any other scripts that are also executed by other external forces?

I'm basically trying to weed out unused scripts, but first I need to know ALL the ways these scripts can be invoked.  If you know this, it would help out a lot.
 
Last edited:
That's only of the type is set.  In cases where a "line" instruction has been added, S2-S6 are predefined - as above.  I am not sure of the full process there.  But normal groups are simply 32 general purpose scripts. Model groups have the talk and contact scripts.

Edit:
As it says above - location and model have a few predefined actions.  For location, if you cross a line or move away from a line, for example. These are actioned by hard code.
 
Do you know who I can ask what the specific rules are? Knowing those are going to be essential in my tasks ahead.
 
Myst6re may have an idea but odds are no one does - because testing on that has never been thoroughly done as far as I am aware.

But with lines and models... if you see map jumps on the predefined scripts above, you will have no idea if they are ever called. As those will usually be user initiated.  So perhaps use different colour spider diagram line for those.
 
I made a bit of a discovery on my quest to better understand the world map scripts.  Let me first explain about some stuff that is already known and in the wiki as a primer to my later-mentioned discoveries.  I extracted an EV-type file out of Section 4 of the WM0.TXZ file (as described here).  One first thing to note is that it is definitely NOT a copy of the WM0.EV file as the wiki suggests, but I haven't dug into exactly how or what is different about it, this will probably be something I investigate soon.  An EV file contains a call table which is a listing of all the functions/scripts that exist on the world map.

There are 3 types of scripts:

[list type=decimal]
[*]a system call - which will be called by various game functions, like when the world map is loaded or every frame tick (likely for things like animations of the water)
[*]a model call - which will be scripts that are called by models, like when a model is loaded onto the map (like a Chocobo or the Highwind, etc)
[*]a walkmesh call - which is called when your character enters a specific square on the world map
[/list]

I mostly want to dive into the walkmesh calls, because I've been on a quest to figure out how your character transitions back and forth between the world map and field maps, and I have figured this out.

For each walkmesh call, there is also a set of coordinates attached to it, so it knows to execute only the portion of code that pertains to the area you're in.  The coordinates here are NOT the coordinates on the world map, but instead it is the mesh coordinate.  The world map is divided into exactly 1,008 equal squares (meshes), 28x36 meshes.  So the coordinates here will be 0-27 and 0-35.  Not all meshes have a script associated with it, but a few do.  We'll come back to coordinates later.

I'm looking specifically for code that deals with jumping to field maps, and it just so happens that there is one opcode that handles this, and many of them are called within these Walkmesh calls, the problem is, the opcode takes in two byte-size parameters, call them parameter A and B.  Parameter A is a number that never exceeds 0x40 and the parameter B is either a 0 or 1.  Field map IDs range from 0-768, so this exceeds the possible values that could come from these 2 parameters.  So, what are these numbers?  And how do they eventually reach a field map?

Moving back to the mesh coordinate system, I took the world map image from Black Chocobo and split it into a 28x36 grid.  I then took all the Walkmesh calls that contained a field map jump code and put a letter/symbol up on the world map at the coordinate that the call occurs and I came up with this map:

worldmapBCWalkmeshCoords.png


The first thing you can notice is that all the spots you see marked are all places we all recognize as points of entry into the various towns on the map.  (Note: You'll see that some of them seem to be slightly off, we can definitely attribute this to the world map image from Black Chocobo not being the absolute source of truth, but instead a good guide to point us in the right direction) What I then decided to do was to start with the code that has a parameter A of 1, which is notated on the map as 'M' (Midgar), then the code where parameter A is 2, which is 'J' (Kalm).  I made a list and kept going:


[list type=decimal]
[*]M - Midgar
[*]J - Kalm
[*]U - Chocobo Farm
[*]4 - Mythril Mine (Marsh side)
[*]9 - Mythril Mine (Condor side)
[*]# - Fort Condor
[*]Y - Junon
[*]& - TOTA
[*]T - Sleeping Man
[/list]

Notice a pattern?  It's the same exact list that DynamixDJ posted earlier in this thread, all 64 (or the ones that exist) match up exactly with the WM* field maps.  This is definitely interesting, but still not enough information to land us to how the game gets us to the final destination since the data contained within those WM*.DAT files (which are all identical byte-for-byte) is not enough space to fit all the scripting required to tell the game where to jump to for all 64 cases.  Instead, I took note of all the field map names and Field IDs of where these SHOULD be going, then searching the binary to see if I see those same values anywhere.  Here's the list I started:


[list type=decimal]
[*]M - 170 - 0x00AA - Midgar
[*]J - 335 - 0x014F - Kalm
[*]U - 343 - 0x0157 - Chocobo Farm
[*]4 - 350 - 0x015E - Mythril Mine (Marsh side)
[*]9 - 349 - 0x015D - Mythril Mine (Condor side)
[*]# - 353 - 0x0161 - Fort Condor
[*]Y - 428 - 0x01AC - Junon
[*]& - 600 - 0x258 - TOTA
[*]T - 78 - 0x004E - Sleeping Man
[/list]

I then found the FIELD.TBL file located within the /WORLD/ folder and it starts like this:

Code: [Select]
Code:
C7 02 8C F6 10 00 AA 00 84 84 84 84 00 00 00 00 00 00 00 00 00 00 00 0001 FE B2 FC 77 00 4F 01 74 74 74 74 00 00 00 00 00 00 00 00 00 00 00 001E 02 E5 FB 0A 00 57 01 98 98 98 98 EF 04 B9 05 4F 00 57 01 CC CC CC CC6C 02 CA 02 73 00 5E 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00AF 00 08 00 17 00 5D 01 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 000B 00 DF FD 09 00 61 01 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00A9 02 9A 02 1D 00 AC 01 CC CC CC CC 00 00 00 00 00 00 00 00 00 00 00 00FA 01 59 FA 00 00 58 02 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 0002 00 1A 00 03 00 4E 00 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00
If you notice, the first line contains 00AA, second line contains 014F, and so on thru the previous list, all of them at offset 0x6.  This file is just the map we are looking for!  When the opcode for jumping to field maps is called, it uses parameter A as what I call a Field Table Id, which is an ID value associated with records in this file.  There are 24 bytes per record.  The only thing left is to figure out what the second parameter B is.  Most of the time it is 0, but sometimes it is a 1.  In the case of the Chocobo Farm, the code looks like this:

Code: [Select]
Code:
Walkmesh(16, 29).FunctionType(4)IF ((((GetSpecial(0008) == #0000) || (GetSpecial(0008) == #0001)) || (GetSpecial(0008) == #0002))) {  IF (Bank0[007d].Bit(0)) {    EnterFieldScene(#0003, #0001)    GOTO Label 1  }  EnterFieldScene(#0003, #0000)Label 1:  GOTO Label 2}IF ((GetSpecial(0008) == #0013)) {  WRITE Bank0[007e].Bit(0) = #0000  WRITE Bank0[007e].Bit(2) = #0000  WRITE Bank0[007e].Bit(3) = #0000  WRITE Bank0[007e].Bit(4) = #0000  WRITE Bank0[007e].Bit(5) = #0000  WRITE Bank0[007e].Bit(6) = #0000  WRITE Bank0[007e].Bit(1) = #0000  WRITE Bank0[007c] = #0000  IF (Bank0[007d].Bit(0)) {    EnterFieldScene(#0003, #0001)    GOTO Label 2  }  EnterFieldScene(#0003, #0000)}Label 2:RETURN
Most of this you can ignore, but note the two possible ways to jump to the field map, notice one has a parameter B of 0, and the other 1.  Parameter B indicates whether an alternate scenario should occur.  If we look back at the 3rd record of the FIELD.TBL file, you'll notice that the second half of the bytes aren't zero like some of the other records.  That is because these records can be split into 2 12-byte pieces, each containing a potentially different Field ID to jump to, in this case it's the same.  What's interesting in the Chocobo Farm case, is that the first time we enter the farm, we enter from the bottom of the screen, while subsequent times we enter from the right side.  This FIELD.TBL file is how it handles that.  I'm not exactly sure how, but somewhere in the remaining 10 bytes of each scenario are the coordinates that the character should begin on.  An example of one area potentially leading to a completely different field map is North Corel.  This ONLY happens if you fail to stop the train during your mission there, you instead are transported to a map that has the crashed train in it.

And there you have it, the mystery of transporting from the WM to a field map is solved. And all my findings have already been added to the wiki.

For those curious: I've made a list of all possible field maps that can lead to the world map (left side of the wm field), and all the ways you can get back to a field map (right side of the wm field), sorry for the formatting:

Code: [Select]
Code:
fromMapId  name  menuText  fieldTableId  wmField  toMapId  name  menuText  NULL NULL NULL 1 wm0 170 mds5_5 Slum Outskirts 170 mds5_5 Slum Outskirts 1 wm0 170 mds5_5 Slum Outskirts 335 elm Kalm 2 wm1 335 elm Kalm 345 frcyo Chocobo Ranch 3 wm2 343 farm Chocobo farm  343 farm Chocobo farm 3 wm2 343 farm Chocobo farm 350 psdun_2 Mythril Mine 4 wm3 350 psdun_2 Mythril Mine 349 psdun_1 Mythril Mine 5 wm4 349 psdun_1 Mythril Mine 353 condor1 Base of Fort Condor 6 wm5 353 condor1 Base of Fort Condor 370 junonl1 Lower Junon 7 wm6 428 ujunon1 Under Junon 428 ujunon1 Under Junon 7 wm6 428 ujunon1 Under Junon 600 jtempl Temple of the Ancients 8 wm7 600 jtempl Temple of the Ancients 78 zz1 Old man's house 9 wm8 78 zz1 Old man's house 79 zz2 Weapon seller A wm9 79 zz2 Weapon seller 712 itown1a Mideel B wm10 712 itown1a Mideel 712 itown1a Mideel B wm10 714 itown1b Mideel 713 itown12 Mideel B wm10 712 itown1a Mideel 713 itown12 Mideel B wm10 714 itown1b Mideel 714 itown1b Mideel B wm10 712 itown1a Mideel 714 itown1b Mideel B wm10 714 itown1b Mideel 84 zz7 Materia Cave C wm11 84 zz7 Materia Cave 443 del2 Costa del Sol D wm12 443 del2 Costa del Sol 458 mtcrl_0 Mt. Corel E wm13 458 mtcrl_0 Mt. Corel 450 ncorel North Corel F wm14 450 ncorel North Corel 450 ncorel North Corel F wm14 451 ncorel2 North Corel 451 ncorel2 North Corel F wm14 450 ncorel North Corel 451 ncorel2 North Corel F wm14 451 ncorel2 North Corel 452 ncorel3 North Corel F wm14 450 ncorel North Corel 452 ncorel3 North Corel F wm14 451 ncorel2 North Corel 481 desert1  10 wm15 482 desert2 Corel Desert 482 desert2 Corel Desert 10 wm15 482 desert2 Corel Desert 512 crcin_2 Waiting Room 10 wm15 482 desert2 Corel Desert 518 gongaga Gongaga Village 11 wm16 515 gonjun2 Jungle 514 gonjun1 Jungle 11 wm16 515 gonjun2 Jungle 515 gonjun2 Jungle 11 wm16 515 gonjun2 Jungle 525 cos_btm Cosmo Canyon 12 wm17 525 cos_btm Cosmo Canyon 284 nivl_3 Nibelheim 13 wm18 284 nivl_3 Nibelheim 285 nivl_4  13 wm18 284 nivl_3 Nibelheim 551 rckt2 Rocket Town 14 wm19 551 rckt2 Rocket Town 551 rckt2 Rocket Town 14 wm19 557 rckt Rocket Town 557 rckt Rocket Town 14 wm19 551 rckt2 Rocket Town 557 rckt Rocket Town 14 wm19 557 rckt Rocket Town 81 zz4 Lucrecia's Cave 15 wm20 81 zz4 Lucrecia's Cave 83 zz6 Materia Cave 16 wm21 83 zz6 Materia Cave 574 yougan3 Plains 17 wm22 574 yougan3 Plains 574 yougan3 Plains 17 wm22 579 uutai1 Wutai 581 yufy1 Yuffie's House 17 wm22 574 yougan3 Plains 581 yufy1 Yuffie's House 17 wm22 579 uutai1 Wutai 579 uutai1 Wutai 17 wm22 574 yougan3 Plains 579 uutai1 Wutai 17 wm22 579 uutai1 Wutai 82 zz5 Materia Cave 18 wm23 82 zz5 Materia Cave 617 bonevil Bone Village 19 wm24 617 bonevil Bone Village 629 sandun_2 Corral Valley Cave 1A wm25 629 sandun_2 Corral Valley Cave 654 snow Icicle Inn 1B wm26 654 snow Icicle Inn 80 zz3 Mystery House 1C wm27 80 zz3 Mystery House 85 zz8 Materia Cave 1D wm28 85 zz8 Materia Cave NULL NULL NULL 1E wm29 425 semkin_5 Underwater Reactor 88 q_1 Hallway 1F wm30 88 q_1 Hallway 348 sichi Marshes 20 wm31 348 sichi Marshes 573 yougan2 Plains 21 wm32 573 yougan2 Plains 572 yougan Wilderness 22 wm33 572 yougan Wilderness NULL NULL NULL 23 wm34 572 yougan Wilderness 382 jundoc1a Junon Dock 24 wm35 439 shpin_2 Cargo Ship 440 shpin_3 Cargo Ship 25 wm36 441 del1 Costa del Sol Harbor 382 jundoc1a Junon Dock 26 wm37 441 del1 Costa del Sol Harbor 429 ujunon2 Dolphin Offing 26 wm37 441 del1 Costa del Sol Harbor 441 del1 Costa del Sol Harbor 27 wm38 382 jundoc1a Junon Dock 86 sea  28 wm39 NULL NULL NULL 70 fship_23 Highwind 29 wm40 NULL NULL NULL 406 subin_1b Submarine Bridge 2A wm41 NULL NULL NULL 284 nivl_3 Nibelheim 2B wm42 284 nivl_3 Nibelheim 285 nivl_4  2B wm42 284 nivl_3 Nibelheim 311 mtnvl2 Mt. Nibel 2C wm43 311 mtnvl2 Mt. Nibel 70 fship_23 Highwind 2D wm44 NULL NULL NULL 71 fship_24 Bridge 2D wm44 NULL NULL NULL 72 fship_25 Highwind 2D wm44 NULL NULL NULL 313 mtnvl4 Mt. Nibel 2E wm45 313 mtnvl4 Mt. Nibel NULL NULL NULL 2F wm46 654 snow Icicle Inn 658 hyou1  30 wm47 658 hyou1  662 icedun_2 Frostbite Cave 30 wm47 658 hyou1  NULL NULL NULL 31 wm48 NULL NULL NULL NULL NULL NULL 32 wm49 70 fship_23 Highwind NULL NULL NULL 32 wm49 72 fship_25 Highwind NULL NULL NULL 33 wm50 72 fship_25 Highwind NULL NULL NULL 34 wm51 71 fship_24 Bridge NULL NULL NULL 35 wm52 347 fr_e  405 subin_1a  36 wm53 NULL NULL NULL 622 anfrst_3 Ancient Forest 37 wm54 622 anfrst_3 Ancient Forest 624 anfrst_5 Ancient Forest 37 wm54 622 anfrst_3 Ancient Forest 405 subin_1a  38 wm55 405 subin_1a  405 subin_1a  38 wm55 406 subin_1b Submarine Bridge 406 subin_1b Submarine Bridge 38 wm55 405 subin_1a  406 subin_1b Submarine Bridge 38 wm55 406 subin_1b Submarine Bridge 626 sango2 Corral Valley 39 wm56 626 sango2 Corral Valley 630 lost1 Forgotten Capital 3A wm57 630 lost1 Forgotten Capital NULL NULL NULL 3B wm58 744 las0_1 Highwind, On deck 686 gaiafoot Base of Gaea's Cliff 3C wm59 686 gaiafoot Base of Gaea's Cliff 670 move_s  3D wm60 670 move_s  670 move_s  3E wm61 670 move_s  670 move_s  3F wm62 670 move_s  682 hyou12  40 wm63 682 hyou12
Another discovery I found was that of the Model calls (as described near the top of this post), some of the Model IDs are already known, such as Cloud being ID = 0, Tifa = 1, Cid = 2, Highwind = 11, etc.  Basically all 3D models used on the WM have an ID.  Previously ID 8 was unknown, but I found that to be the Cargo Ship as there is a Model script for ID 8 that deals with all 4 field map jumps pertaining to the Cargo Ship transports.

Thru similar reverse engineering, we can see that wm52 and fr_e are used for the Diamond Weapon battle and the dialogue that follows.  This also illuminates another unknown Model ID, which Diamond Weapon is ID 10.

Another area of interest is wm32 is where Yuffie Encounters end up after the battle. wm34 is where Yuffie betrays your team on the southern part of the western continent.

What I don't know is how the game knows which coordinates on the world map to drop the character when entering the WM from a particular town.  For the sake of my current project, finding that is out of scope for now, but possibly something I may dive into later.
 
Last edited:
So is it possible to edit the position on the wm when you get out front town? I have a mod that changes kalm location on the worldmap. To enter to kalm is fine but when you get out the character appears at the coordinates that kalm should be
 
Ah - yes....  Sorry about that.  I spotted the table file some time ago!

Nice work, btw.

What I don't know is how the game knows which coordinates on the world map to drop the character when entering the WM from a particular town
It will likely be hard coded it not in that table file. Best bet try searching for the X Y Z value from world map.  You may have to divide by 4096.
 
Last edited:
Right, and my problem is right now that I'm exclusively dealing with PSX at this point. My Steam account has issues currently and won't let me make purchases on it, so I can't get Steam FF7 atm. So if I wanted to get actual coordinates of the drop points for each town, I'd be a huge process and hassle that I'm not willing to do atm.

You're correct tho, the WM coordinates are definitely NOT in the FIELD.TBL file, only the field coordinates are.
 
More cool stuff. I created a rather large image of the world map walkmesh wireframe for your viewing pleasure:

I should warn you, it's over 5MB

Overworld

Underwater
 
Last edited:
Another world map image. I filled in all the triangles with color pertaining to what kind of walkmesh it is. Perhaps someday I'll actually apply the real texture, but for now that's the best I can do.

worldMap.png
 
Last edited:
Does anyone have any detail on the structure of the world.bin file?
 
Last edited:
I found a bit more.  Thanks to both ergonomy_joe and JBedford.  I found the enc_w.bin file within world.bin (after decompressed: offset 0x1D948 size:0x8A0 header:0xA0), which is the file that contains all the encounters on the world map (probability and enemy formations).  The enc_w.bin file contains 64 possible configurations for encounters.  These are divided into 16 different areas on the map (Midgar Area, Nibel Area, etc) indicated by the text that shows up in the MENU.  The text for these 16 areas are first 16 texts that are defined in a file called "mes", which is another file that exists within world.bin (offset:0x1E5F0 size:0x1000) This leaves 4 possible configurations per area, which are divided amongst some of the different terrain types that exist within that area, also known as walkmesh statuses, listed at the bottom of this page in the Wiki.  If you look at the world map walkmesh image I posted earlier (the Overworld link), you'll see a bunch of small triangles, each individual triangle has a walkmesh status associated with it.

This enc_w.bin is not a new file to us, it has been deciphered before, even with notes indicating which walkmesh statuses are the ones that are used for encounters.  This, however, can be found by simple trial and error and manually writing down this information while playing and checking against the available encounter configurations.

I, however, was looking to find how the game knows which walkmesh statuses are valid ones to use and look up in the configurations.  I thought maybe this was information that was in the 0xA0 header of the enc_w.bin file, but that lead to a dead end.  I sent a PM over to JBedford, who told me this had to be determined within the EXE, which for me is the last area of my expertise.  From there, I had a look thru the world map code that was reverse engineered by ergonomy_joe and did indeed find a table (inside his NEWFF7/C_00766B70.cpp) that contained some similar-looking numbers which looked a lot like the common walkmesh status IDs that encounters use.  Since joe's code is based on the PC version of the game, I wanted to find where it could be located in the PSX version.  Since the walkmesh statuses could've been stored a good number of ways (they only take up 5 bits), this would've been very difficult to find on my own, but with joe's code, I could see how the game stored these values, which was in 8-bit segments (leaving 3 unused).  I searched and found it in the PSX version, again in the world.bin file (offset: 0x272B4 size:0x40)

Here is the list, divided in groups of 4 (each area):
Code: [Select]
Code:
00 09 00 11 Midgar Area00 00 00 11 Grasslands Area00 09 01 11 Junon Area00 14 00 11 Corel Area00 09 08 11 Gold Saucer Area00 00 19 11 Gongaga Area00 09 13 11 Cosmo Area00 00 01 11 Nibel Area00 00 01 11 Rocket Launch Pad Area00 09 0E 11 Wutai Area00 09 19 11 Woodlands Area00 0A 09 11 Icicle Area00 09 19 11 Mideel Area00 00 08 0B North Corel Area00 00 08 00 Cactus Island00 00 01 00 Goblin Island
One thing to note, every area has a Grass status configuration, which is a walkmesh status ID of 00.  If you look at every area, they all begin with 00.  So the first configuration in each area in enc_w.bin shows you the enemies you'll encounter in the Grass parts.  However, you'll notice that some of the areas contain multiple references to Grass statuses.  I believe the game only uses the first one it finds, and effectively marks any subsequent ones as "unused".  It's unclear, as I haven't tested it, if the game REQUIRES each area to have a Grass status or not.  Either way, if the enc_w.bin Grass configuration for one area is all 00s, that effectively disables encounters for the area anyways.  My thought though is that you could have an area with 4 statuses that AREN'T a Grass status and it would work, but not tested.

Another important thing to note is the Icicle Area, the 3rd status referenced is ID 09, which is a Dirt/Wasteland status.  You'll notice there is no dirt area in the Icicle Area...or is there?  This is the configuration that is used for encounters in the snowfield area in Great Glacier!  Even though it looks like snow, that's just because a different texture ID is used instead of the usual Dirt texture.  They couldn't use the Snow status there because it's already used by the Snow area on the main world map.

So, here is the list of the statuses that are used in each area:
Code: [Select]
Code:
00 09 00 11 Midgar Area (Grass, Dirt, <unused>, Beach)00 00 00 11 Grasslands Area (Grass, <unused>, <unused>, Beach)00 09 01 11 Junon Area (Grass, Dirt, Forest, Beach)00 14 00 11 Corel Area (Grass, Mountain Pass, <unused>, Beach)00 09 08 11 Gold Saucer Area (Grass, Dirt, Desert, Beach)00 00 19 11 Gongaga Area (Grass, <unused>, Jungle, Beach)00 09 13 11 Cosmo Area (Grass, Dirt, Canyon, Beach)00 00 01 11 Nibel Area (Grass, <unused>, Forest, Beach)00 00 01 11 Rocket Launch Pad Area (Grass, <unused>, Forest, Beach)00 09 0E 11 Wutai Area (Grass, Dirt, Wutai Bridge, Beach)00 09 19 11 Woodlands Area (Grass, Dirt, Jungle, Beach)00 0A 09 11 Icicle Area (Grass, Snow, Snowfield (Dirt), Beach)00 09 19 11 Mideel Area (Grass, Dirt, Jungle, Beach)00 00 08 0B North Corel Area (Grass, <unused>, Desert, Riverside)00 00 08 00 Cactus Island (Grass, <unused>, Desert, <unused>)00 00 01 00 Goblin Island (Grass, <unused>, Forest, <unused>)
 
Last edited:
OK, coords set from field to world map are stupid. Really stupid and probably a remnant of porting from psx badly (I think it's just a calc to make use of 24 bit data).

The coords are not stored as a 3 or 4 byte integer... instead, they are stored in two separate two byte values and then operations are done to make the final 3 byte integer

Let's take Kalm, for example.  When exiting Kalm, Cloud will appear at X coord value decimal 201868

This is arrived at by the two byte value 0x18 and 0x13D6

0x18 is multiplied by 0x2000 to create 0x30000

And then the two byte value 0x13D6 is added to this to create 0x313D6 (decimal 201868).

See the following data at 00DF5C28 [You can find this from 0x764D24].  X is in red.  Y is in blue.
18 00 10 01 0D 00 08 03 00 01 10 01 D6 13 10 01 20 19

Z and character direction must close by (Z may be being calculated based on X and Y).  Z is signed, so watch out for that.

This data is written to from elsewhere (and my debugger won't tell me where).  Likely this data is raw in one of the world_us files.

Search for the above byte order in a file and you should find it.  IN the meantime, I am going to continue looking into this.

Edit.

wm0.ev (event file in world_us).  0x7e0.  This is where the data is stored. Of course... being that you'll need to use my tool Ochu to get the coords (by leaving each town) and then do the math on each coord and look it up in the event file, it's going to be annoying.
 
Last edited:
As to your question about encounters, I have added the bridge battles back some time ago (for example) for R06.

It does work on IDs as you have spotted, but the ID also has a "can battle occur here" flag attached to it.  See my own code here as to how I added wutai bridge battles back:

Code: [Select]
Code:
Procedure WorldMapTerrainBattleFlag7621C0; stdcall; // Only if result equals 0, allow world map battles.Begin  asm  mov ecx,[$E3A7D0]  cmp ecx,00  je @Label1 // unknown check    movsx ecx,word ptr [ecx+$4A] // Terrain ID    cmp ecx, $122E    je @Label1 // if terrain is Wutai Bridge, allow battles      sar ecx,05      and ecx,07      mov eax,ecx  // eax now contains terrain battle flag  jmp @End    @LABEL1:    xor eax,eax // This will also allow battles  @END:  end;End;
The game also determines if you are able to use menu by the same principle.
 
Last edited:
This is where the data is stored. Of course... being that you'll need to use my tool Ochu to get the coords (by leaving each town) and then do the math on each coord and look it up in the event file, it's going to be annoying.
No worries, I have my own tool that sifts thru WM scripts, but really I've already enlisted some help in finding the first three WM coordinates, from there I should be able to spot a pattern. The way I have my code set up, it's easy to extract data from these scripts and feed them into my database.
 
Status
Not open for further replies.
Back
Top