api: add method to find instanced tiles in the scene
Use in groundmarkers plugin
This commit is contained in:
@@ -25,6 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.api.coords;
|
package net.runelite.api.coords;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
import static net.runelite.api.Constants.CHUNK_SIZE;
|
||||||
@@ -150,7 +154,8 @@ public class WorldPoint
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the coordinate of the tile that contains the passed local point.
|
* Gets the coordinate of the tile that contains the passed local point,
|
||||||
|
* accounting for instances.
|
||||||
*
|
*
|
||||||
* @param client the client
|
* @param client the client
|
||||||
* @param localPoint the local coordinate
|
* @param localPoint the local coordinate
|
||||||
@@ -190,6 +195,46 @@ public class WorldPoint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get occurrences of a tile on the scene, accounting for instances. There may be
|
||||||
|
* more than one if the same template chunk occurs more than once on the scene.
|
||||||
|
* @param client
|
||||||
|
* @param worldPoint
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Collection<WorldPoint> toLocalInstance(Client client, WorldPoint worldPoint)
|
||||||
|
{
|
||||||
|
if (!client.isInInstancedRegion())
|
||||||
|
{
|
||||||
|
return Collections.singleton(worldPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find instance chunks using the template point. there might be more than one.
|
||||||
|
List<WorldPoint> worldPoints = new ArrayList<>();
|
||||||
|
final int z = client.getPlane();
|
||||||
|
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
||||||
|
for (int x = 0; x < instanceTemplateChunks[z].length; ++x)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y)
|
||||||
|
{
|
||||||
|
int chunkData = instanceTemplateChunks[z][x][y];
|
||||||
|
int rotation = chunkData >> 1 & 0x3;
|
||||||
|
int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
||||||
|
int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
||||||
|
if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE
|
||||||
|
&& worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE)
|
||||||
|
{
|
||||||
|
WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)),
|
||||||
|
client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)),
|
||||||
|
worldPoint.getPlane());
|
||||||
|
p = rotate(p, rotation);
|
||||||
|
worldPoints.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return worldPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotate the coordinates in the chunk according to chunk rotation
|
* Rotate the coordinates in the chunk according to chunk rotation
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.MenuAction;
|
import net.runelite.api.MenuAction;
|
||||||
import net.runelite.api.MenuEntry;
|
import net.runelite.api.MenuEntry;
|
||||||
@@ -155,87 +155,23 @@ public class GroundMarkerPlugin extends Plugin
|
|||||||
return Collections.EMPTY_LIST;
|
return Collections.EMPTY_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WorldPoint> worldPoints = new ArrayList<>();
|
return points.stream()
|
||||||
for (GroundMarkerPoint point : points)
|
.map(point ->
|
||||||
{
|
|
||||||
int regionId = point.getRegionId();
|
|
||||||
int regionX = point.getRegionX();
|
|
||||||
int regionY = point.getRegionY();
|
|
||||||
int z = point.getZ();
|
|
||||||
|
|
||||||
// world point of the tile marker
|
|
||||||
WorldPoint worldPoint = new WorldPoint(
|
|
||||||
((regionId >>> 8) << 6) + regionX,
|
|
||||||
((regionId & 0xff) << 6) + regionY,
|
|
||||||
z
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!client.isInInstancedRegion())
|
|
||||||
{
|
{
|
||||||
worldPoints.add(worldPoint);
|
int regionId = point.getRegionId();
|
||||||
continue;
|
int regionX = point.getRegionX();
|
||||||
}
|
int regionY = point.getRegionY();
|
||||||
|
int z = point.getZ();
|
||||||
|
|
||||||
// find instance chunks using the template point. there might be more than one.
|
// world point of the tile marker
|
||||||
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
return new WorldPoint(
|
||||||
for (int x = 0; x < instanceTemplateChunks[z].length; ++x)
|
((regionId >>> 8) << 6) + regionX,
|
||||||
{
|
((regionId & 0xff) << 6) + regionY,
|
||||||
for (int y = 0; y < instanceTemplateChunks[z][x].length; ++y)
|
z
|
||||||
{
|
);
|
||||||
int chunkData = instanceTemplateChunks[z][x][y];
|
})
|
||||||
int rotation = chunkData >> 1 & 0x3;
|
.flatMap(wp -> WorldPoint.toLocalInstance(client, wp).stream())
|
||||||
int templateChunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
.collect(Collectors.toList());
|
||||||
int templateChunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
|
||||||
if (worldPoint.getX() >= templateChunkX && worldPoint.getX() < templateChunkX + CHUNK_SIZE
|
|
||||||
&& worldPoint.getY() >= templateChunkY && worldPoint.getY() < templateChunkY + CHUNK_SIZE)
|
|
||||||
{
|
|
||||||
WorldPoint p = new WorldPoint(client.getBaseX() + x * CHUNK_SIZE + (worldPoint.getX() & (CHUNK_SIZE - 1)),
|
|
||||||
client.getBaseY() + y * CHUNK_SIZE + (worldPoint.getY() & (CHUNK_SIZE - 1)),
|
|
||||||
worldPoint.getPlane());
|
|
||||||
p = rotate(p, rotation);
|
|
||||||
worldPoints.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return worldPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotate the chunk containing the given point to rotation 0
|
|
||||||
*
|
|
||||||
* @param point point
|
|
||||||
* @param rotation rotation
|
|
||||||
* @return world point
|
|
||||||
*/
|
|
||||||
private static WorldPoint rotateInverse(WorldPoint point, int rotation)
|
|
||||||
{
|
|
||||||
return rotate(point, 4 - rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rotate the coordinates in the chunk according to chunk rotation
|
|
||||||
*
|
|
||||||
* @param point point
|
|
||||||
* @param rotation rotation
|
|
||||||
* @return world point
|
|
||||||
*/
|
|
||||||
private static WorldPoint rotate(WorldPoint point, int rotation)
|
|
||||||
{
|
|
||||||
int chunkX = point.getX() & ~(CHUNK_SIZE - 1);
|
|
||||||
int chunkY = point.getY() & ~(CHUNK_SIZE - 1);
|
|
||||||
int x = point.getX() & (CHUNK_SIZE - 1);
|
|
||||||
int y = point.getY() & (CHUNK_SIZE - 1);
|
|
||||||
switch (rotation)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
return new WorldPoint(chunkX + y, chunkY + (CHUNK_SIZE - 1 - x), point.getPlane());
|
|
||||||
case 2:
|
|
||||||
return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - x), chunkY + (CHUNK_SIZE - 1 - y), point.getPlane());
|
|
||||||
case 3:
|
|
||||||
return new WorldPoint(chunkX + (CHUNK_SIZE - 1 - y), chunkY + x, point.getPlane());
|
|
||||||
}
|
|
||||||
return point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
Reference in New Issue
Block a user