collinsmith / riiablo

Diablo II remade using Java and LibGDX
http://riiablo.com
Apache License 2.0
884 stars 101 forks source link

add support for warp highlight tiles #12

Open collinsmith opened 5 years ago

collinsmith commented 5 years ago

Some (if not all) warps have special tiles that are highlighted versions of existing tiles (e.g., normal cave entrance is highlighted when cursor is over it). The sub index of the special warp tile tells us the main index of the affected tiles (both highlighted and non-highlighted tiles have the same main index). In all cases I've seen, either 2 or 4 tiles are replaced with either sub index 0-1 -> 2-3 or 0-3 -> 4-7. The trick is determining which is the case. Also, is it always the case where replacement tiles are available?

Possibly useful columns in LvlWarp.txt are LitVersion, Tiles, Direction. Based on previous knowledge, Tiles was supposed to determine some kind of offset, this is false from what I've seen, since I've seen 2 and 4 tile variants both with Tiles=2, and the only time Tiles!=2 is for 3 expansion barricades where it is 4.

Also, sometimes there are 2 special warp tiles for the same warp. I think when this is the case, there is a 1:1 mapping of the special warp tiles with the replacement tiles (so this marks the 2 tile case), so if there is only 1, I think this marks the 4 tile case.

I'm going to investigate a bit more, because with the current implementation, the 2 special warp tile case will create 2 warp entities. I'm also not sure if the original client uses entities for warps like I am (my method will work fine though).

I also need to add some logic to MapRenderer to draw the (non)highlighted tiles correctly. Currently my PopPads implementation bypasses using entities and is implemented into MapRenderer itself. I think rendering the highlight tiles is more appropriate from within MapRenderer than the entity itself, not to mention the complications it will provide with the order of the rendering if done within the warp entity. The question is how I want to handle tying the Warp entity with the tiles it hides/unhides in MapRenderer

collinsmith commented 5 years ago

After looking through Act 1 warp presets, it looks like SPECIAL_10 marks an entrance/next and SPECIAL_11 marks an exit/previous. If the sub index is 0,1 then the replacement tiles are a 1:1 mapping (same main index and sub index as the tiles they replace), otherwise the replacement mapping is 0-3 -> 4-7 using the sub index of the warp tile is the main index of the replacement tiles.

LitVersion does seem to indicate if replacement tiles exist (so if LitVersion=0, no tiles get replaced). If the warp uses the 2 warp tile case, I'm guessing the one with sub index 0 is the actual warp origin and the other is just foo.

I'm going try implementing this using a set of selected tile indexes DT1.Tile.Index within Map that Warp entities will add/remove from depending on whether or not it is in the 'over' state. MapRenderer will then unhide any tiles within that set. The plan is to just render over those tiles (appears like this might be the easiest implementation), however replacement of those tiles might be preferable down the line.


Just wanted to add, the special case where LitVersion=0 in the DS1's I've looked at (tower2.ds1 and gravey.ds1) has used VIS_0_00 and VIS_1_11, but both of these have their own 1 sub index variant, so it might be the case that if LitVersion=0 we only look for the 0 sub index tile and not it's sibling.

collinsmith commented 5 years ago

talcor.ds1 uses VIS_1_11, talleft1-3.ds1 uses VIS_2_20, VIS_3_30, VIS_4_40, talright1-3.ds1 uses VIS_5_43, VIS_6_44, VIS_7_46

VIS_4_40 and VIS_5_43 are SPECIAL_11 tiles, so this goes against the previous assertion that SPECIAL_11 warps are exit/previous warps. Each one of those tiles does use a unique main index 1-7 with sub index 0 though.

collinsmith commented 5 years ago

I added support for swapping the tiles out for warps. Only DOE entrance tested, no support for wall warp tiles yet (they are added, but replacement tiles won't render in place of originals).

The substitution algorithm can be optimized, but it would require changing the functionality of the tile lookup system. Since Map.Tile is generated when the Map is being built, the warp subst tiles do not have Map.Tile instances generated for them. Additionally, Map.Zone consists of an array of Map.Tile instances, so replacing the given Map.Tile instances with the subst Map.Tile instances would not be trivial and would require iterating through the entire array for a Map.Zone. I'm not to concerned with the performance drawbacks of the current implementation, but if it becomes an issue I have a couple ideas.

I'm going to leave this open until I have implemented and tested wall warps.

collinsmith commented 5 years ago

e3366849fae34def4b1806c7f5d2186a4dd9dab0 added support for warping to the den of evil (1 way trip right now). My above assertions still hold true for the den's warp tiles.

collinsmith commented 5 years ago

It seems that LvlWarp.txt Tiles is the number to add to a wall-style warp to get the highlight tiles. Most cases this is 2, hence why 0,1 -> 2-3. In act 5 entrance to ice caves from plateau uses 3 wall tiles with Tiles=4, so 0,1,2 -> 4,5,6. I'm trying to make adjustments.


I'll worry about this more when I generate the world up to the tower where the first wall-type warp is used. I need to figure out reliably the wall warp types and the number of them that are used. As of now, only 1 tile of passed to create a warp from, and it's always subIndex=0 and I always generate replacements 0,1 -> 2,3. I can also just hard-coded those special cases since they are soo few, but obviously I'd rather figure out the proper way.

collinsmith commented 5 years ago

LvlWarp.txt implementation is wrong and will need to be fixed in the future. The Id column isn't a valid primary key and need to take into account Direction, which determines which warp type to use.

In this file, if we check carefully, we'll see that all warps have the column Direction set to b, except some of the Expansion, which have l and r. Coincidently, the warps that don't have b are a pair of warps with the same Id, but one with Direction l, the other with r. So, l stands for Left, r for Right, and b for Both. The Orientation of the Vis (10 or 11), will be used by the game to know which one of these 2 lines it'll use : if the Vis is an Orientation 10, this will be the line with the l Direction, else if it's a Vis of Orientation 11, the game will choose the line with the r Direction.