cache/MapImageDumper: handle pushdown objects correctly

This commit is contained in:
Max Weber
2021-10-17 03:06:21 -06:00
parent 685ee8d7e2
commit 3ca476094c

View File

@@ -28,7 +28,10 @@ import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -51,6 +54,7 @@ import net.runelite.cache.fs.Store;
import net.runelite.cache.item.RSTextureProvider; import net.runelite.cache.item.RSTextureProvider;
import net.runelite.cache.models.JagexColor; import net.runelite.cache.models.JagexColor;
import net.runelite.cache.region.Location; import net.runelite.cache.region.Location;
import net.runelite.cache.region.Position;
import net.runelite.cache.region.Region; import net.runelite.cache.region.Region;
import net.runelite.cache.region.RegionLoader; import net.runelite.cache.region.RegionLoader;
import net.runelite.cache.util.KeyProvider; import net.runelite.cache.util.KeyProvider;
@@ -198,31 +202,36 @@ public class MapImageDumper
return; return;
} }
int[][] map = new int[Region.X * MAP_SCALE][Region.Y * MAP_SCALE]; int[][][] map = new int[4][][];
drawMap(map, region, z);
int[][] above = null;
if (z < 3)
{
above = new int[Region.X * MAP_SCALE][Region.Y * MAP_SCALE];
drawMap(above, region, z + 1);
}
for (int x = 0; x < Region.X; ++x) for (int x = 0; x < Region.X; ++x)
{ {
for (int y = 0; y < Region.Y; ++y) for (int y = 0; y < Region.Y; ++y)
{ {
boolean isBridge = (region.getTileSetting(1, x, Region.Y - y - 1) & 2) != 0; boolean isBridge = (region.getTileSetting(1, x, Region.Y - y - 1) & 2) != 0;
int tileZ = z + (isBridge ? 1 : 0);
int tileSetting = region.getTileSetting(z, x, Region.Y - y - 1); if (tileZ >= Region.Z)
if (!isBridge && ((tileSetting & 24) == 0))
{ {
drawTile(image, map, drawBaseX, drawBaseY, x, y); continue;
} }
if (z < 3 && isBridge) // client also has a check for &8 != 0 here int tileSetting = region.getTileSetting(z, x, Region.Y - y - 1);
if ((tileSetting & 24) == 0)
{ {
drawTile(image, above, drawBaseX, drawBaseY, x, y); if (z == 0 && isBridge)
{
drawTile(image, map, region, drawBaseX, drawBaseY, 0, x, y);
}
drawTile(image, map, region, drawBaseX, drawBaseY, tileZ, x, y);
}
if (tileZ < 3)
{
int upTileSetting = region.getTileSetting(z + 1, x, Region.Y - y - 1);
if ((upTileSetting & 8) != 0)
{
drawTile(image, map, region, drawBaseX, drawBaseY, tileZ + 1, x, y);
}
} }
} }
} }
@@ -246,8 +255,16 @@ public class MapImageDumper
} }
} }
private void drawTile(BufferedImage to, int[][] pixels, int drawBaseX, int drawBaseY, int x, int y) private void drawTile(BufferedImage to, int[][][] planes, Region region, int drawBaseX, int drawBaseY, int z, int x, int y)
{ {
int[][] pixels = planes[z];
if (pixels == null)
{
pixels = planes[z] = new int[Region.X * MAP_SCALE][Region.Y * MAP_SCALE];
drawMap(pixels, region, z);
}
for (int i = 0; i < MAP_SCALE; ++i) for (int i = 0; i < MAP_SCALE; ++i)
{ {
for (int j = 0; j < MAP_SCALE; ++j) for (int j = 0; j < MAP_SCALE; ++j)
@@ -532,48 +549,53 @@ public class MapImageDumper
return; return;
} }
for (Location location : region.getLocations()) List<Location> planeLocs = new ArrayList<>();
List<Location> pushDownLocs = new ArrayList<>();
List<List<Location>> layers = Arrays.asList(planeLocs, pushDownLocs);
for (int localX = 0; localX < Region.X; localX++)
{ {
int regionX = localX + region.getBaseX();
for (int localY = 0; localY < Region.Y; localY++)
{
int regionY = localY + region.getBaseY();
int rotation = location.getOrientation(); planeLocs.clear();
int type = location.getType(); pushDownLocs.clear();
int localX = location.getPosition().getX() - region.getBaseX();
int localY = location.getPosition().getY() - region.getBaseY();
boolean isBridge = (region.getTileSetting(1, localX, localY) & 2) != 0; boolean isBridge = (region.getTileSetting(1, localX, localY) & 2) != 0;
int tileZ = z + (isBridge ? 1 : 0);
if (location.getPosition().getZ() == z + 1) for (Location loc : region.getLocations())
{ {
if (!isBridge) Position pos = loc.getPosition();
{ if (pos.getX() != regionX || pos.getY() != regionY)
continue;
}
}
else if (location.getPosition().getZ() == z)
{
if (isBridge)
{ {
continue; continue;
} }
if ((region.getTileSetting(z, localX, localY) & 24) != 0) if (pos.getZ() == tileZ && (region.getTileSetting(z, localX, localY) & 24) == 0)
{ {
continue; planeLocs.add(loc);
} }
} else if (z < 3 && pos.getZ() == tileZ + 1 && (region.getTileSetting(z + 1, localX, localY) & 8) != 0)
else
{ {
continue; pushDownLocs.add(loc);
} }
}
for (List<Location> locs : layers)
{
for (Location location : locs)
{
int type = location.getType();
if (type >= 0 && type <= 3)
{
int rotation = location.getOrientation();
ObjectDefinition object = findObject(location.getId()); ObjectDefinition object = findObject(location.getId());
int drawX = (drawBaseX + localX) * MAP_SCALE; int drawX = (drawBaseX + localX) * MAP_SCALE;
int drawY = (drawBaseY + (Region.Y - object.getSizeY() - localY)) * MAP_SCALE; int drawY = (drawBaseY + (Region.Y - object.getSizeY() - localY)) * MAP_SCALE;
if (type >= 0 && type <= 3)
{
// this is a wall // this is a wall
int hash = (localY << 7) + localX + (location.getId() << 14) + 0x4000_0000; int hash = (localY << 7) + localX + (location.getId() << 14) + 0x4000_0000;
if (object.getWallOrDoor() == 0) if (object.getWallOrDoor() == 0)
@@ -679,8 +701,20 @@ public class MapImageDumper
} }
} }
} }
else if (type == 9) }
for (Location location : locs)
{ {
int type = location.getType();
if (type == 9)
{
int rotation = location.getOrientation();
ObjectDefinition object = findObject(location.getId());
int drawX = (drawBaseX + localX) * MAP_SCALE;
int drawY = (drawBaseY + (Region.Y - object.getSizeY() - localY)) * MAP_SCALE;
if (object.getMapSceneID() != -1) if (object.getMapSceneID() != -1)
{ {
blitMapDecoration(image, drawX, drawY, object); blitMapDecoration(image, drawX, drawY, object);
@@ -719,8 +753,18 @@ public class MapImageDumper
image.setRGB(drawX + 3, drawY + 0, rgb); image.setRGB(drawX + 3, drawY + 0, rgb);
} }
} }
else if (type == 22 || (type >= 9 && type <= 11)) }
for (Location location : locs)
{ {
int type = location.getType();
if (type == 22 || (type >= 9 && type <= 11))
{
ObjectDefinition object = findObject(location.getId());
int drawX = (drawBaseX + localX) * MAP_SCALE;
int drawY = (drawBaseY + (Region.Y - object.getSizeY() - localY)) * MAP_SCALE;
// ground object // ground object
if (object.getMapSceneID() != -1) if (object.getMapSceneID() != -1)
{ {
@@ -729,6 +773,9 @@ public class MapImageDumper
} }
} }
} }
}
}
}
private void drawObjects(BufferedImage image, int z) private void drawObjects(BufferedImage image, int z)
{ {
@@ -903,8 +950,13 @@ public class MapImageDumper
for (Location location : region.getLocations()) for (Location location : region.getLocations())
{ {
int localX = location.getPosition().getX() - region.getBaseX();
int localY = location.getPosition().getY() - region.getBaseY();
boolean isBridge = (region.getTileSetting(1, localX, localY) & 2) != 0;
int tileZ = z + (isBridge ? 1 : 0);
int localZ = location.getPosition().getZ(); int localZ = location.getPosition().getZ();
if (z != 0 && localZ != z) if (z != 0 && localZ != tileZ)
{ {
// draw all icons on z=0 // draw all icons on z=0
continue; continue;
@@ -914,9 +966,6 @@ public class MapImageDumper
assert od != null; assert od != null;
int localX = location.getPosition().getX() - region.getBaseX();
int localY = location.getPosition().getY() - region.getBaseY();
int drawX = drawBaseX + localX; int drawX = drawBaseX + localX;
int drawY = drawBaseY + (Region.Y - 1 - localY); int drawY = drawBaseY + (Region.Y - 1 - localY);