use of net.runelite.api.coords.LocalPoint in project runelite by runelite.
the class Perspective method getCanvasImageLocation.
/**
* Calculates image position and centers depending on image size.
*
* @param client
* @param graphics
* @param localLocation local location of the tile
* @param image image for size measurement
* @param zOffset offset from ground plane
* @return a {@link Point} on screen corresponding to the given
* localLocation.
*/
public static Point getCanvasImageLocation(Client client, Graphics2D graphics, LocalPoint localLocation, BufferedImage image, int zOffset) {
int plane = client.getPlane();
Point p = Perspective.worldToCanvas(client, localLocation.getX(), localLocation.getY(), plane, zOffset);
if (p == null) {
return null;
}
int xOffset = p.getX() - image.getWidth() / 2;
int yOffset = p.getY() - image.getHeight() / 2;
return new Point(xOffset, yOffset);
}
use of net.runelite.api.coords.LocalPoint in project runelite by runelite.
the class Perspective method getCanvasTextLocation.
/**
* Calculates text position and centers depending on string length.
*
* @param client
* @param graphics
* @param localLocation local location of the tile
* @param text string for width measurement
* @param zOffset offset from ground plane
* @return a {@link Point} on screen corresponding to the given
* localLocation.
*/
public static Point getCanvasTextLocation(Client client, Graphics2D graphics, LocalPoint localLocation, String text, int zOffset) {
int plane = client.getPlane();
Point p = Perspective.worldToCanvas(client, localLocation.getX(), localLocation.getY(), plane, zOffset);
if (p == null) {
return null;
}
FontMetrics fm = graphics.getFontMetrics();
Rectangle2D bounds = fm.getStringBounds(text, graphics);
int xOffset = p.getX() - (int) (bounds.getWidth() / 2);
return new Point(xOffset, p.getY());
}
use of net.runelite.api.coords.LocalPoint in project runelite by runelite.
the class HunterPlugin method onGameTick.
/**
* Iterates over all the traps that were placed by the local player and
* checks if the trap is still there. If the trap is gone, it removes
* the trap from the local players trap collection.
*/
@Subscribe
public void onGameTick(GameTick event) {
// Check if all traps are still there, and remove the ones that are not.
Iterator<Map.Entry<WorldPoint, HunterTrap>> it = traps.entrySet().iterator();
Tile[][][] tiles = client.getRegion().getTiles();
Instant expire = Instant.now().minus(HunterTrap.TRAP_TIME.multipliedBy(2));
while (it.hasNext()) {
Map.Entry<WorldPoint, HunterTrap> entry = it.next();
HunterTrap trap = entry.getValue();
WorldPoint world = entry.getKey();
LocalPoint local = LocalPoint.fromWorld(client, world);
// Not within the client's viewport
if (local == null) {
// Cull very old traps
if (trap.getPlacedOn().isBefore(expire)) {
log.debug("Trap removed from personal trap collection due to timeout, {} left", traps.size());
it.remove();
continue;
}
continue;
}
Tile tile = tiles[world.getPlane()][local.getRegionX()][local.getRegionY()];
GameObject[] objects = tile.getGameObjects();
boolean containsBoulder = false;
boolean containsAnything = false;
for (GameObject object : objects) {
if (object != null) {
containsAnything = true;
if (object.getId() == ObjectID.BOULDER_19215 || object.getId() == ObjectID.LARGE_BOULDER) {
containsBoulder = true;
break;
}
}
}
if (!containsAnything) {
it.remove();
log.debug("Trap removed from personal trap collection, {} left", traps.size());
} else if (// For traps like deadfalls. This is different because when the trap is gone, there is still a GameObject (boulder)
containsBoulder) {
it.remove();
log.debug("Special trap removed from personal trap collection, {} left", traps.size());
// Case we have notifications enabled and the action was not manual, throw notification
if (config.maniacalMonkeyNotify() && trap.getObjectId() == ObjectID.MONKEY_TRAP && !trap.getState().equals(HunterTrap.State.FULL) && !trap.getState().equals(HunterTrap.State.OPEN)) {
notifier.notify("The monkey escaped.");
}
}
}
}
use of net.runelite.api.coords.LocalPoint in project runelite by runelite.
the class TrapOverlay method drawCircleOnTrap.
/**
* Draws a timer on a given trap.
*
* @param graphics
* @param trap The trap on which the timer needs to be drawn
* @param fill The fill color of the timer
* @param border The border color of the timer
*/
private void drawCircleOnTrap(Graphics2D graphics, HunterTrap trap, Color fill, Color border) {
if (trap.getWorldLocation().getPlane() != client.getPlane()) {
return;
}
LocalPoint localLoc = LocalPoint.fromWorld(client, trap.getWorldLocation());
if (localLoc == null) {
return;
}
net.runelite.api.Point loc = Perspective.worldToCanvas(client, localLoc.getX(), localLoc.getY(), trap.getWorldLocation().getPlane());
ProgressPie pie = new ProgressPie();
pie.setFill(fill);
pie.setBorderColor(border);
pie.render(graphics, loc, 1);
}
use of net.runelite.api.coords.LocalPoint in project runelite by runelite.
the class KourendLibraryOverlay method render.
@Override
public Dimension render(Graphics2D g) {
Player player = client.getLocalPlayer();
if (player == null) {
return null;
}
WorldPoint playerLoc = player.getWorldLocation();
if (playerLoc.distanceTo2D(LIBRARY_CENTER) > ROUGH_ENABLE_DISTANCE) {
return null;
}
List<Bookcase> allBookcases = library.getBookcasesOnLevel(client.getPlane());
if (allBookcases == null) {
return null;
}
for (Bookcase bookcase : allBookcases) {
// AABB
WorldPoint caseLoc = bookcase.getLocation();
if (Math.abs(playerLoc.getX() - caseLoc.getX()) > MAXIMUM_DISTANCE || Math.abs(playerLoc.getY() - caseLoc.getY()) > MAXIMUM_DISTANCE) {
continue;
}
LocalPoint localBookcase = LocalPoint.fromWorld(client, caseLoc);
if (localBookcase == null) {
continue;
}
Point screenBookcase = Perspective.worldToCanvas(client, localBookcase.getX(), localBookcase.getY(), caseLoc.getPlane(), 25);
if (screenBookcase != null) {
boolean bookIsKnown = bookcase.isBookSet();
Book book = bookcase.getBook();
Set<Book> possible = bookcase.getPossibleBooks();
if (bookIsKnown && book == null) {
for (Book b : possible) {
if (b != null && b.isDarkManuscript()) {
book = b;
break;
}
}
}
if (!bookIsKnown && possible.size() == 1) {
book = possible.iterator().next();
bookIsKnown = true;
}
Color color = bookIsKnown ? Color.ORANGE : Color.WHITE;
// Render the poly on the floor
if (!(bookIsKnown && book == null) && (library.getState() == SolvedState.NO_DATA || book != null || possible.size() > 0)) {
Polygon poly = getCanvasTilePoly(client, localBookcase);
if (poly != null) {
OverlayUtil.renderPolygon(g, poly, color);
}
}
int height = 0;
// If the book is singled out, render the text and the book's icon
if (bookIsKnown) {
if (book != null) {
FontMetrics fm = g.getFontMetrics();
Rectangle2D bounds = fm.getStringBounds(book.getShortName(), g);
height = (int) bounds.getHeight() + book.getIcon().getHeight() + 6;
Point textLoc = new Point((int) (screenBookcase.getX() - (bounds.getWidth() / 2)), screenBookcase.getY() - (height / 2) + (int) bounds.getHeight());
OverlayUtil.renderTextLocation(g, textLoc, book.getShortName(), color);
g.drawImage(book.getIcon(), screenBookcase.getX() - (book.getIcon().getWidth() / 2), screenBookcase.getY() + (height / 2) - book.getIcon().getHeight(), null);
}
} else {
// otherwise render up to 9 icons of the possible books in the bookcase in a square
final int BOOK_ICON_SIZE = 32;
Book[] books = possible.stream().filter(Objects::nonNull).limit(9).toArray(Book[]::new);
if (books.length > 1 && books.length <= 9) {
int cols = (int) Math.ceil(Math.sqrt(books.length));
int rows = (int) Math.ceil((double) books.length / cols);
height = rows * BOOK_ICON_SIZE;
int xbase = screenBookcase.getX() - ((cols * BOOK_ICON_SIZE) / 2);
int ybase = screenBookcase.getY() - rows * BOOK_ICON_SIZE / 2;
for (int i = 0; i < books.length; i++) {
int col = i % cols;
int row = i / cols;
int x = col * BOOK_ICON_SIZE;
int y = row * BOOK_ICON_SIZE;
if (row == rows - 1) {
x += (BOOK_ICON_SIZE * (books.length % rows)) / 2;
}
g.drawImage(books[i].getIcon(), xbase + x, ybase + y, null);
}
}
}
// Draw the bookcase's ID on top
if (KourendLibraryPlugin.debug) {
FontMetrics fm = g.getFontMetrics();
String str = bookcase.getIndex().stream().map(Object::toString).collect(Collectors.joining(", "));
Rectangle2D bounds = fm.getStringBounds(str, g);
Point textLoc = new Point((int) (screenBookcase.getX() - (bounds.getWidth() / 2)), screenBookcase.getY() - (height / 2));
OverlayUtil.renderTextLocation(g, textLoc, str, Color.WHITE);
}
}
}
// Render the customer's wanted book on their head and a poly under their feet
LibraryCustomer customer = library.getCustomer();
if (customer != null) {
client.getNpcs().stream().filter(n -> n.getId() == customer.getId()).forEach(n -> {
Book b = library.getCustomerBook();
LocalPoint local = n.getLocalLocation();
Polygon poly = getCanvasTilePoly(client, local);
OverlayUtil.renderPolygon(g, poly, Color.WHITE);
Point screen = Perspective.worldToCanvas(client, local.getX(), local.getY(), client.getPlane(), n.getLogicalHeight());
if (screen != null) {
g.drawImage(b.getIcon(), screen.getX() - (b.getIcon().getWidth() / 2), screen.getY() - b.getIcon().getHeight(), null);
}
});
}
return null;
}
Aggregations