Merge pull request #218 from Toocanzs/master

Update instance map
This commit is contained in:
Adam
2017-11-19 20:13:55 -05:00
committed by GitHub
17 changed files with 940 additions and 28 deletions

View File

@@ -61,4 +61,6 @@ public interface Actor extends Renderable
Point getCanvasSpriteLocation(Graphics2D graphics, SpritePixels sprite, int zOffset);
Point getMinimapLocation();
Point getRegionLocation();
}

View File

@@ -34,7 +34,7 @@ public class Perspective
{
private static final double UNIT = Math.PI / 1024d; // How much of the circle each unit of SINE/COSINE is
private static final int LOCAL_COORD_BITS = 7;
public static final int LOCAL_COORD_BITS = 7;
public static final int LOCAL_TILE_SIZE = 1 << LOCAL_COORD_BITS; // 128 - size of a tile in local coordinates
public static final int[] SINE = new int[2048]; // sine angles for each of the 2048 units, * 65536 and stored as an int

View File

@@ -27,4 +27,8 @@ package net.runelite.api;
public interface Region
{
Tile[][][] getTiles();
int[][] getTileMask2d();
int[][] getTileRotation2d();
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.api;
public interface SceneTileModel
{
int getModelUnderlay();
int getModelOverlay();
int getShape();
int getRotation();
}

View File

@@ -42,4 +42,10 @@ public interface Tile
WallObject getWallObject();
SceneTilePaint getSceneTilePaint();
SceneTileModel getSceneTileModel();
Point getWorldLocation();
Point getLocalLocation();
}

View File

@@ -31,4 +31,7 @@ package net.runelite.api;
*/
public interface WallObject extends TileObject
{
int getOrientationA();
int getOrientationB();
}

View File

@@ -27,29 +27,77 @@ package net.runelite.client.plugins.instancemap;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.annotation.Nullable;
import javax.inject.Inject;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.Region;
import net.runelite.api.SceneTileModel;
import net.runelite.api.SceneTilePaint;
import net.runelite.api.Tile;
import net.runelite.api.WallObject;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.events.MapRegionChanged;
import static net.runelite.client.plugins.instancemap.PixelMaps.ALL;
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM;
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM_LEFT_CORNER;
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM_LEFT_TO_TOP_RIGHT;
import static net.runelite.client.plugins.instancemap.PixelMaps.BOTTOM_RIGHT_CORNER;
import static net.runelite.client.plugins.instancemap.PixelMaps.LEFT;
import static net.runelite.client.plugins.instancemap.PixelMaps.RIGHT;
import static net.runelite.client.plugins.instancemap.PixelMaps.TOP;
import static net.runelite.client.plugins.instancemap.PixelMaps.TOP_LEFT_CORNER;
import static net.runelite.client.plugins.instancemap.PixelMaps.TOP_RIGHT_CORNER;
import static net.runelite.client.plugins.instancemap.PixelMaps.TOP_RIGHT_TO_BOTTOM_LEFT;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPosition;
class InstanceMapOverlay extends Overlay
{
/**
* Size of the drawn tile in the instance map.
* The size of tiles on the map. The way the client renders requires
* this value to be 4. Changing this will break the method for rendering
* complex tiles
*/
private static final int tileSize = 3;
static final int TILE_SIZE = 4;
/**
* The multiplier to scale the map size by. This is just for rendering
* mapImage. mapImage is scaled by this value
*/
private static final double MAP_SCALING = 1;
/**
* The size of the player's position marker on the map
*/
private static final int PLAYER_MARKER_SIZE = 4;
private static final int MAX_PLANE = 3;
private static final int MIN_PLANE = 0;
/**
* The plane to render on the instance map. When the map is opened this
* defaults to the current plane. The ascend and descend buttons raise
* and lower this This is used to render parts of an instance below or
* above the local player's current plane.
*/
private int viewedPlane = 0;
private final Client client;
private final InstanceMapConfig config;
/**
* Saved image of the region, no reason to draw the whole thing every
* frame. This is redrawn in the drawToBufferedImage method
*/
private BufferedImage mapImage;
private boolean showMap = false;
@Inject
InstanceMapOverlay(@Nullable Client client,
InstanceMapConfig config)
InstanceMapOverlay(@Nullable Client client, InstanceMapConfig config)
{
super(OverlayPosition.DYNAMIC);
this.client = client;
@@ -61,9 +109,48 @@ class InstanceMapOverlay extends Overlay
return showMap;
}
/**
* Setter for showing the map. When the map is set to show, the map is
* re-rendered
*
* @param show Whether or not the map should be shown.
*/
public void setShowMap(boolean show)
{
showMap = show;
if (showMap)
{
viewedPlane = client.getPlane();//When we open the map show the current plane
mapImage = drawMapImage(getTiles());
}
}
/**
* Increases the viewed plane. The maximum viewedPlane is 3
*/
public void onAscend()
{
if (viewedPlane >= MAX_PLANE)
{
return;
}
viewedPlane++;//Increment plane
mapImage = drawMapImage(getTiles());
}
/**
* Decreases the viewed plane. The minimum viewedPlane is 0
*/
public void onDescend()
{
if (viewedPlane <= MIN_PLANE)
{
return;
}
viewedPlane--;
mapImage = drawMapImage(getTiles());
}
@Override
@@ -74,7 +161,86 @@ class InstanceMapOverlay extends Overlay
return null;
}
return drawInstanceMap(graphics);
if (mapImage == null)
{
mapImage = drawMapImage(getTiles());
}
//Scale mapImage by the mapScaling to display a larger map.
graphics.drawImage(mapImage, 0, 0, (int) (mapImage.getWidth() * MAP_SCALING), (int) (mapImage.getHeight() * MAP_SCALING), 0, 0, mapImage.getWidth(), mapImage.getHeight(), null);
if (client.getPlane() == viewedPlane)//If we are not viewing the plane we are on, don't show player's position
{
drawPlayerDot(graphics, client.getLocalPlayer(), Color.white, Color.black);
}
Tile[][] tiles = getTiles();
Dimension mapOverlaySize = new Dimension(tiles.length * TILE_SIZE, tiles[0].length * TILE_SIZE);
return mapOverlaySize;
}
/**
* Draws the players position as a dot on the map.
*
* @param graphics graphics to be drawn to
*/
private void drawPlayerDot(Graphics2D graphics, Player player, Color dotColor, Color outlineColor)
{
Point playerLocation = player.getRegionLocation();
Tile[][] tiles = getTiles();
Point localPlayerPoint = new Point(playerLocation.getX(), (tiles[0].length - 1) - playerLocation.getY()); // flip the y value
graphics.setColor(dotColor);
graphics.fillRect((int) (localPlayerPoint.getX() * TILE_SIZE * MAP_SCALING), (int) (localPlayerPoint.getY() * TILE_SIZE * MAP_SCALING), PLAYER_MARKER_SIZE, PLAYER_MARKER_SIZE);//draw the players point on the map
graphics.setColor(outlineColor);
graphics.drawRect((int) (localPlayerPoint.getX() * TILE_SIZE * MAP_SCALING), (int) (localPlayerPoint.getY() * TILE_SIZE * MAP_SCALING), PLAYER_MARKER_SIZE, PLAYER_MARKER_SIZE);//outline
}
/**
* Handles region changes and re-draws the map
*
* @param event The region change event
*/
public void onRegionChange(MapRegionChanged event)
{
mapImage = drawMapImage(getTiles());
}
/**
* Handles game state changes and re-draws the map
*
* @param event The game state change event
*/
public void onGameStateChange(GameStateChanged event)
{
mapImage = drawMapImage(getTiles());
}
/**
* Get the files for the current viewed plane
*
* @return
*/
private Tile[][] getTiles()
{
Tile[][][] regionTiles = client.getRegion().getTiles();
return regionTiles[viewedPlane];
}
/**
* Draws the map to the the buffered image mapImage
*
* @param tiles The tiles to draw to the map
*/
private BufferedImage drawMapImage(Tile[][] tiles)
{
BufferedImage image = new BufferedImage(tiles.length * TILE_SIZE, tiles[0].length * TILE_SIZE, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
drawInstanceMap(g);
g.dispose();
return image;
}
/**
@@ -84,31 +250,246 @@ class InstanceMapOverlay extends Overlay
* @param graphics graphics to draw to
* @return The dimensions of the map
*/
private Dimension drawInstanceMap(Graphics2D graphics)
private void drawInstanceMap(Graphics2D graphics)
{
Tile[][][] regionTiles = client.getRegion().getTiles();
Region region = client.getRegion();
Tile[][] tiles = getTiles();
int plane = client.getPlane();
Tile[][] tiles = regionTiles[plane];
Dimension mapOverlaySize = new Dimension(tiles.length * TILE_SIZE, tiles[0].length * TILE_SIZE);
Dimension mapOverlaySize = new Dimension(tiles.length * tileSize, tiles[0].length * tileSize);
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, mapOverlaySize.width, mapOverlaySize.height);
graphics.setColor(Color.black);
graphics.fillRect(0, 0, mapOverlaySize.width, mapOverlaySize.height);//draw background
graphics.setColor(Color.white);
graphics.drawRect(0, 0, mapOverlaySize.width - 1, mapOverlaySize.height - 1);//draw outline
//Draw the base colors first
for (int x = 0; x < tiles.length; x++)
{
for (int y = 0; y < tiles[x].length; y++)
for (int y = tiles[x].length - 1; y >= 0; y--)//flip y value
{
Tile curTile = tiles[x][(tiles[x].length - 1) - y]; // flip the y value
if (curTile != null && curTile.getSceneTilePaint() != null)
drawTileColor(graphics, region, tiles[x][(tiles[x].length - 1) - y], x, y);
}
}
//Draw walls on top
for (int x = 0; x < tiles.length; x++)
{
for (int y = tiles[x].length - 1; y >= 0; y--)//Flip y value
{
drawTileWalls(graphics, tiles[x][(tiles[x].length - 1) - y], x, y);
}
}
}
private void drawTileWalls(Graphics2D graphics, Tile curTile, int x, int y)
{
if (curTile != null)
{
WallObject wallObject = curTile.getWallObject();
if (wallObject != null)
{
drawWallObject(graphics, wallObject, curTile, x * TILE_SIZE, y * TILE_SIZE);
}
}
}
private void drawTileColor(Graphics2D graphics, Region region, Tile curTile, int x, int y)
{
if (curTile != null)
{
SceneTilePaint sceneTilePaint = curTile.getSceneTilePaint();
SceneTileModel sceneTileModel = curTile.getSceneTileModel();
if (sceneTilePaint != null)
{
drawMapPixel(graphics, sceneTilePaint, x * TILE_SIZE, y * TILE_SIZE);
}
else if (sceneTileModel != null)
{
drawComplexMapPixel(graphics, sceneTileModel, region, x * TILE_SIZE, y * TILE_SIZE);
}
}
}
/**
* Draws a tile as 4x4 pixels on the map. This tile will be drawn as a
* set of 4x4 pixels
*
* @param graphics graphics to be drawn to
* @param sceneTilePaint the tiles sceneTilePaint used to get the RGB
* value of that tile
* @param startX the top left point at which the 4x4 is drawn
* @param startY the top left point at which the 4x4 is drawn
*/
private void drawMapPixel(Graphics2D graphics, SceneTilePaint sceneTilePaint, int startX, int startY)
{
Color c = new Color(sceneTilePaint.getRBG());//Normal map pixels have only 1 solid color
graphics.setColor(c);
graphics.fillRect(startX, startY, TILE_SIZE, TILE_SIZE);
}
/**
* Gets the walls shape from the orientation
*
* @param orientationA the wall object's orientationA
* @param orientationB the wall object's orientationB
* @return A WallShape representing the wall as a 4x4 set of pixels with
* an offset
*/
private WallShape getWallShape(int orientationA, int orientationB)
{
int[][] pixels = ALL;
WallOffset wallOffset = WallOffset.NONE;
switch (orientationA)
{
case 16:
//Diagonal /
pixels = BOTTOM_LEFT_TO_TOP_RIGHT;
wallOffset = WallOffset.TOP_LEFT;
break;
case 32:
//Diagonal \
pixels = TOP_RIGHT_TO_BOTTOM_LEFT;
wallOffset = WallOffset.TOP_RIGHT;
break;
case 64:
//Diagonal /
pixels = BOTTOM_LEFT_TO_TOP_RIGHT;
wallOffset = WallOffset.BOTTOM_RIGHT;
break;
case 1:
//Left wall
pixels = LEFT;
break;
case 2:
//Top wall
pixels = TOP;
break;
case 4:
//Right wall
pixels = RIGHT;
break;
case 8:
//Bottom wall
pixels = BOTTOM;
break;
case 128:
//Diagonal \
pixels = TOP_RIGHT_TO_BOTTOM_LEFT;
wallOffset = WallOffset.BOTTOM_LEFT;
break;
}
switch (orientationB)
{
case 2:
//top left corner
pixels = TOP_LEFT_CORNER;
break;
case 4:
//top right corner
pixels = TOP_RIGHT_CORNER;
break;
case 8:
//bottom right corner
pixels = BOTTOM_RIGHT_CORNER;
break;
case 1:
//Bottom left corner
pixels = BOTTOM_LEFT_CORNER;
break;
}
return new WallShape(pixels, wallOffset);
}
/**
* Draws a wall on the map using a tiles WallObject. This wall will be
* drawn as a set of 4x4 pixels
*
* @param graphics graphics to be drawn to
* @param wallObject the wall object of the tile
* @param startX the top left point at which the 4x4 is drawn
* @param startY the top left point at which the 4x4 is drawn
*/
private void drawWallObject(Graphics2D graphics, WallObject wallObject, Tile tile, int startX, int startY)
{
graphics.setColor(Color.white);
int orientationA = wallObject.getOrientationA();//Orientation is a set of flags stored as an int
int orientationB = wallObject.getOrientationB();
WallShape wallShape = getWallShape(orientationA, orientationB);
int[][] pixels = wallShape.getPixels();
for (int i = 0; i < pixels.length; i++)
{
for (int j = 0; j < pixels.length; j++)
{
if (pixels[i][j] == 1)
{
graphics.setColor(new Color(curTile.getSceneTilePaint().getRBG()));
graphics.fillRect(x * tileSize, y * tileSize, tileSize, tileSize);
//Draw the 4x4 and offset accordingly
drawPoint(graphics, startX + wallShape.getOffset().xOffset + j, startY + wallShape.getOffset().yOffset + i);
}
}
}
return mapOverlaySize;
}
/**
* Draws just one pixel to the screen
*
* @param graphics Graphics to be drawn to
* @param x x position of the pixel
* @param y y position of the pixel
*/
private void drawPoint(Graphics2D graphics, int x, int y)
{
graphics.drawLine(x, y, x, y);
}
/**
* Draws tiles which have more than one color to them. For example a
* tile that falls on the edge of a river will have one part that is
* grass, and the other part will be water. To draw these tiles we need
* to use two colors. This tile will be drawn as a 4x4 set of pixels
*
* @param graphics the graphics to be drawn to
* @param sceneTileModel The SceneTileModel of the complex tile
* @param region The current region
* @param startX the top left point at which the 4x4 is drawn
* @param startY the top left point at which the 4x4 is drawn
*/
private void drawComplexMapPixel(Graphics2D graphics, SceneTileModel sceneTileModel, Region region, int startX, int startY)
{
//Most of this code is directly from the client from minimap rendering
int[][] TILE_MASK_2D = region.getTileMask2d();
int[][] TILE_ROTATION_2D = region.getTileRotation2d();
int shape = sceneTileModel.getShape();
int rotation = sceneTileModel.getRotation();
int overlay = sceneTileModel.getModelOverlay();//SceneTileModels have only two colors, and overlay and underlay.
int underlay = sceneTileModel.getModelUnderlay();
int[] shapes = TILE_MASK_2D[shape];
int[] rotations = TILE_ROTATION_2D[rotation];
int rotationIndex = 0;
for (int i = 0; i < TILE_SIZE; i++)
{
for (int j = 0; j < TILE_SIZE; j++)
{
int intColor = (shapes[rotations[rotationIndex++]] == 0) ? underlay : overlay;
Color c = new Color(intColor);
graphics.setColor(c);
graphics.fillRect(startX + j, startY + i, 1, 1);
}
}
}
}

View File

@@ -29,11 +29,14 @@ import com.google.inject.Binder;
import com.google.inject.Provides;
import javax.inject.Inject;
import net.runelite.api.widgets.WidgetInfo;
import static net.runelite.api.widgets.WidgetInfo.WORLD_MAP;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.GameStateChanged;
import net.runelite.client.events.MapRegionChanged;
import net.runelite.client.events.WidgetMenuOptionClicked;
import net.runelite.client.menus.WidgetMenuOption;
import net.runelite.client.menus.MenuManager;
import net.runelite.client.menus.WidgetMenuOption;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.Overlay;
@@ -44,6 +47,8 @@ import net.runelite.client.ui.overlay.Overlay;
public class IntanceMapPlugin extends Plugin
{
private final WidgetMenuOption openMapOption = new WidgetMenuOption("Show", "Instance Map", WidgetInfo.WORLD_MAP);
private final WidgetMenuOption ascendOption = new WidgetMenuOption("Ascend", "Instance Map", WidgetInfo.WORLD_MAP);
private final WidgetMenuOption descendOption = new WidgetMenuOption("Descend", "Instance Map", WidgetInfo.WORLD_MAP);
@Inject
InstanceMapConfig config;
@@ -66,41 +71,77 @@ public class IntanceMapPlugin extends Plugin
return configManager.getConfig(InstanceMapConfig.class);
}
private void addCustomOptions()
{
menuManager.addManagedCustomMenu(openMapOption);
menuManager.addManagedCustomMenu(descendOption);
menuManager.addManagedCustomMenu(ascendOption);
}
private void removeCustomOptions()
{
menuManager.removeManagedCustomMenu(openMapOption);
menuManager.removeManagedCustomMenu(descendOption);
menuManager.removeManagedCustomMenu(ascendOption);
}
@Override
protected void startUp() throws Exception
{
if (config.enabled())
{
menuManager.addManagedCustomMenu(openMapOption);
addCustomOptions();
}
}
@Override
protected void shutDown() throws Exception
{
removeCustomOptions();
}
@Subscribe
public void onConfigChanged(ConfigChanged event)
{
if (config.enabled())
{
menuManager.addManagedCustomMenu(openMapOption);
addCustomOptions();
}
else
{
menuManager.removeManagedCustomMenu(openMapOption);
removeCustomOptions();
}
}
@Subscribe
public void regionChange(MapRegionChanged event)
{
overlay.onRegionChange(event);
}
@Subscribe
public void gameStateChange(GameStateChanged event)
{
overlay.onGameStateChange(event);
}
private boolean clickedOptionEquals(WidgetMenuOptionClicked event, WidgetMenuOption widgetMenuOption)
{
return event.getMenuOption().equals(widgetMenuOption.getMenuOption()) && event.getMenuTarget().equals(widgetMenuOption.getMenuTarget());
}
@Subscribe
public void onWidgetMenuOptionClicked(WidgetMenuOptionClicked event)
{
if (!config.enabled())
if (!config.enabled() || event.getWidget() != WORLD_MAP)
{
return;
}
if (event.getMenuOption().equals(openMapOption.getMenuOption())
&& event.getMenuTarget().equals(openMapOption.getMenuTarget())
&& event.getWidget() == WidgetInfo.WORLD_MAP)
if (clickedOptionEquals(event, openMapOption))
{
overlay.setShowMap(!overlay.isMapShown());
if (overlay.isMapShown())
{
openMapOption.setMenuOption("Hide");
@@ -110,6 +151,14 @@ public class IntanceMapPlugin extends Plugin
openMapOption.setMenuOption("Show");
}
}
else if (clickedOptionEquals(event, ascendOption))
{
overlay.onAscend();
}
else if (clickedOptionEquals(event, descendOption))
{
overlay.onDescend();
}
}
@Override

View File

@@ -0,0 +1,207 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.instancemap;
class PixelMaps
{
static final int[][] ALL = new int[][]
{
{
1, 1, 1, 1
},
{
1, 1, 1, 1
},
{
1, 1, 1, 1
},
{
1, 1, 1, 1
}
};
//Diagonal /
static final int[][] BOTTOM_LEFT_TO_TOP_RIGHT = new int[][]
{
{
0, 0, 0, 1
},
{
0, 0, 1, 0
},
{
0, 1, 0, 0
},
{
1, 0, 0, 0
}
};
//Diagonal \
static final int[][] TOP_RIGHT_TO_BOTTOM_LEFT = new int[][]
{
{
1, 0, 0, 0
},
{
0, 1, 0, 0
},
{
0, 0, 1, 0
},
{
0, 0, 0, 1
}
};
//Left
static final int[][] LEFT = new int[][]
{
{
1, 0, 0, 0
},
{
1, 0, 0, 0
},
{
1, 0, 0, 0
},
{
1, 0, 0, 0
}
};
static final int[][] TOP = new int[][]
{
{
1, 1, 1, 1
},
{
0, 0, 0, 0
},
{
0, 0, 0, 0
},
{
0, 0, 0, 0
}
};
static final int[][] RIGHT = new int[][]
{
{
0, 0, 0, 1
},
{
0, 0, 0, 1
},
{
0, 0, 0, 1
},
{
0, 0, 0, 1
}
};
static final int BOTTOM[][] = new int[][]
{
{
0, 0, 0, 0
},
{
0, 0, 0, 0
},
{
0, 0, 0, 0
},
{
1, 1, 1, 1
}
};
static final int[][] TOP_LEFT_CORNER = new int[][]
{
{
1, 1, 1, 1
},
{
1, 0, 0, 0
},
{
1, 0, 0, 0
},
{
1, 0, 0, 0
}
};
static final int[][] TOP_RIGHT_CORNER = new int[][]
{
{
1, 1, 1, 1
},
{
0, 0, 0, 1
},
{
0, 0, 0, 1
},
{
0, 0, 0, 1
}
};
static final int[][] BOTTOM_RIGHT_CORNER = new int[][]
{
{
0, 0, 0, 1
},
{
0, 0, 0, 1
},
{
0, 0, 0, 1
},
{
1, 1, 1, 1
}
};
static final int[][] BOTTOM_LEFT_CORNER = new int[][]
{
{
1, 0, 0, 0
},
{
1, 0, 0, 0
},
{
1, 0, 0, 0
},
{
1, 1, 1, 1
}
};
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.instancemap;
import static net.runelite.client.plugins.instancemap.InstanceMapOverlay.TILE_SIZE;
enum WallOffset
{
TOP_LEFT(-TILE_SIZE / 2, -TILE_SIZE / 2),
TOP_RIGHT(TILE_SIZE / 2, -TILE_SIZE / 2),
BOTTOM_LEFT(-TILE_SIZE / 2, TILE_SIZE / 2),
BOTTOM_RIGHT(TILE_SIZE / 2, TILE_SIZE / 2),
RIGHT(TILE_SIZE / 2, 0),
LEFT(-TILE_SIZE / 2, 0),
NONE(0, 0);
public final int xOffset;
public final int yOffset;
WallOffset(int xOffset, int yOffset)
{
this.xOffset = xOffset;
this.yOffset = yOffset;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.instancemap;
/**
* Used to represent the wall as a 4x4 set of pixels with an offset
*/
class WallShape
{
private final int[][] pixels;
private final WallOffset offset;
public WallShape(int[][] pixels, WallOffset offset)
{
this.pixels = pixels;
this.offset = offset;
}
public int[][] getPixels()
{
return pixels;
}
public WallOffset getOffset()
{
return offset;
}
}

View File

@@ -30,6 +30,7 @@ import java.awt.image.BufferedImage;
import net.runelite.api.Actor;
import net.runelite.api.NPC;
import net.runelite.api.Perspective;
import static net.runelite.api.Perspective.LOCAL_COORD_BITS;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.SpritePixels;
@@ -124,6 +125,13 @@ public abstract class RSActorMixin implements RSActor
return Perspective.localToWorld(client, localLocation);
}
@Inject
@Override
public Point getRegionLocation()
{
return new Point(getX() >>> LOCAL_COORD_BITS, getY() >>> LOCAL_COORD_BITS);// divided by 128
}
@Inject
@Override
public Point getLocalLocation()

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.mixins;
import static net.runelite.api.Perspective.LOCAL_COORD_BITS;
import net.runelite.api.Point;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSTile;
@Mixin(RSTile.class)
public abstract class RSTileMixin implements RSTile
{
@Inject
@Override
public Point getWorldLocation()
{
return new Point(getLocalLocation().getX() << LOCAL_COORD_BITS, getLocalLocation().getX() << LOCAL_COORD_BITS);
}
@Inject
@Override
public Point getLocalLocation()
{
return new Point(getX(), getY());
}
}

View File

@@ -36,4 +36,13 @@ public interface RSRegion extends Region
@Import("tiles")
@Override
Tile[][][] getTiles();
@Import("TILE_MASK_2D")
@Override
int[][] getTileMask2d();
@Import("TILE_ROTATION_2D")
@Override
int[][] getTileRotation2d();
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.rs.api;
import net.runelite.api.SceneTileModel;
import net.runelite.mapping.Import;
public interface RSSceneTileModel extends SceneTileModel
{
@Import("underlay")
@Override
int getModelUnderlay();
@Import("overlay")
@Override
int getModelOverlay();
@Import("shape")
@Override
int getShape();
@Import("rotation")
@Override
int getRotation();
}

View File

@@ -28,6 +28,7 @@ import net.runelite.api.DecorativeObject;
import net.runelite.api.GameObject;
import net.runelite.api.GroundObject;
import net.runelite.api.ItemLayer;
import net.runelite.api.SceneTileModel;
import net.runelite.api.SceneTilePaint;
import net.runelite.api.Tile;
import net.runelite.api.WallObject;
@@ -59,6 +60,10 @@ public interface RSTile extends Tile
@Override
SceneTilePaint getSceneTilePaint();
@Import("overlay")
@Override
SceneTileModel getSceneTileModel();
@Import("x")
int getX();

View File

@@ -40,4 +40,12 @@ public interface RSWallObject extends WallObject
@Import("y")
@Override
int getY();
@Import("orientationA")
@Override
int getOrientationA();
@Import("orientationB")
@Override
int getOrientationB();
}