Author Topic: Lava Indexing  (Read 1701 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Lava Indexing
« on: July 05, 2008, 03:15:00 AM »
To obtain an index for a lava tile, the game scans the 4 surrounding tiles Left, Top, Right, Bottom, and uses the 4 bits to form an index [0..15]. The bits are in the order just given, from most significant to least significant.

Code: [Select]
lavaDirectionIndex = (LTRB)

To obtain the index into the tile set, this is added to the base lava tile index. This value is read from the .map files, from the TerrainType section, and is at offset 0xB4 within that struct. Well, actually, a multiple of the lavaDirectionIndex is added to the baseLavaIndex at offset 0xB4, since each lava tile is animated, and needs 6 tiles for the animation. Thus, the lavaDirectionIndex must be multiplied by 6 before being added to the baseLavaIndex. The value of 6 is actually also read from the .map data, and is the value at offset 0xB6.

Code: [Select]
lavaTileIndex = baseLavaIndex + (lavaDirectionIndex * animationLength)

The values at offset 0xB8 and 0xBA are also lava related, although their exact meaning is unknown. These two values are only used when a tile is completely surrounded by neighboring lava tiles in all 4 directions. Instead of the usual calculation for lavaTileIndex, the following one is used:

Code: [Select]
lavaTileIndex = baseLavaIndex + (15 * lavaAnimationLength) + (Rand([+0xB8] - 1) * [+0xBA])

I find the minus 1 before the Rand call particularly interesting. If anyone knows why this is done, or has a theory, I wouldn't mind hearing it.
Note that 15 is the lavaDirectionIndex value when the tile is surrounded by 4 lava tiles. It was however hardcoded in this case, but this case was also guarded by a branch to make sure that lavaDirectionIndex was 15.

I also checked what value those lava entries have, and I found this:
Code: [Select]
[+0xB6] = 6  [animationLength]
[+0xB8] = 6
[+0xBA] = 1

This is only for the TerrainType's that contains lava. The other ones all had these values set to 0.
« Last Edit: July 05, 2008, 03:17:43 AM by Hooman »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Lava Indexing
« Reply #1 on: July 05, 2008, 08:37:54 PM »
I did some more digging, and I think I know what those values were intended to mean.

Code: [Select]
[+0xB8] centerAnimationLength
[+0xBA] numCenterTiles

There is some code that seems to check if a given tile is a lava tile, based on index. From the range of values checked, based on these fields, that's what I've inferred. It seems the game allows for a different number of animated tiles for the center tile that's surrounded by lava tiles in each of the 4 directions. It also allows for a different animation length for this tile. The default values treat it like all the rest though.


Note that this still doesn't explain the minus 1 I brought up in the last post. As best I can tell, this seems to be an off by 1 error. Not problem causing though, since it errs on the safe side, and just reduces the number of displayed graphics.


Btw, can anyone think of a reason why you'd need to know if a tile was a lava center tile? There are two functions that I checked. One seems to return true if the tile is a lava tile, and the other seems to return true if it's a lava tile, but only one of the center ones. I'm not really sure why the game would need to check this. The function doesn't appear to be called anywhere though. At least not from anywhere that OllyDbg picked up.



Edit: I may have those two reversed. There's not too much in the exe to make a good determination, but I'm thinking maybe it's supposed to be the other way around. That would make 6 center lava tiles, each with 1 tile in it's animation chain. I suppose that would account for the lower rate of animation for the center tiles though.

Code: [Select]
[+0xB8] numCenterTiles  [deafult value = 6]
[+0xBA] centerAnimationLength  [default value = 1]
« Last Edit: July 05, 2008, 11:13:26 PM by Hooman »

Offline Hidiot

  • Hero Member
  • *****
  • Posts: 1018
Lava Indexing
« Reply #2 on: July 06, 2008, 07:38:34 AM »
I'll risk by taking a wild guess, but I think the game keeps the center lava tiles to restrict the number of tiles to check whilst the lava is expanding too?
« Last Edit: July 06, 2008, 07:38:51 AM by Hidiot »
"Nothing from nowhere, I'm no one at all"

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Lava Indexing
« Reply #3 on: July 06, 2008, 03:35:31 PM »
Hmm, I don't really think so. When lava is expanding, what it does, is generate a bunch of random points, and then checks if those points are next to lava, and so can be expanded to. Same deal with the blight. That's how you can get those tendtrils forming, rather than even growth. I also think this is why the center tiles seem to change at random times, rather than animated like other tiles are. It probably just redoes those tiles.
 

Offline Hidiot

  • Hero Member
  • *****
  • Posts: 1018
Lava Indexing
« Reply #4 on: July 07, 2008, 06:45:14 AM »
Ok, I'll remember that.

Yeah, and the random points get generated in exactly the same way each and every time the map is loaded with the same Lava Possible tiles.
"Nothing from nowhere, I'm no one at all"

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Lava Indexing
« Reply #5 on: July 07, 2008, 09:13:36 PM »
Quite possibly. I remember seeing some code that controls that spread, which appeared to be an inlined copy of the random number generation code. It also seems to set the initial state with a fixed seed. That should mean that lava and blight spread exactly the same each time.

The spread speed only controls how many tiles are checked for expansion, and not the order in which they're checked. However, when the spread speed is set, the random number generation is also reset, so setting the spread speed at different times can lead to different behavior, provided a different number of tiles were already spread to when the generator is reset. As for how the spread speed works, what is does is multiply the SetSpreadSpeed parameter by the number of tiles in the map (Width * Height), and that value is how many "random" tiles will be checked for possible expansion.

The only non-deterministic part of the expansion that I know of, is when the spread encounters a wall. In that case, I think it uses the global random number generator to control the progression. So if you build walls, it will probably make it's way around those walls in a different manner each time.

The choice of graphics tile to display for the center lava tile also seems to use the global random number generator. Although, this has no effect on behavior. (Other than to change the state of the global random number generator).