Search in sources :

Example 1 with WorldPoint

use of net.runelite.api.coords.WorldPoint in project runelite by runelite.

the class CannonSpotOverlay method render.

@Override
public Dimension render(Graphics2D graphics) {
    if (!config.showCannonSpots() || plugin.isCannonPlaced()) {
        return null;
    }
    for (WorldPoint spot : plugin.getSpotPoints()) {
        if (spot.getPlane() != client.getPlane()) {
            continue;
        }
        LocalPoint spotPoint = LocalPoint.fromWorld(client, spot);
        LocalPoint localLocation = client.getLocalPlayer().getLocalLocation();
        if (spotPoint != null && localLocation.distanceTo(spotPoint) <= MAX_DISTANCE) {
            renderCannonSpot(graphics, client, spotPoint, itemManager.getImage(CANNONBALL), Color.RED);
        }
    }
    return null;
}
Also used : LocalPoint(net.runelite.api.coords.LocalPoint) WorldPoint(net.runelite.api.coords.WorldPoint)

Example 2 with WorldPoint

use of net.runelite.api.coords.WorldPoint in project runelite by runelite.

the class Library method add.

private void add(int x, int y, int z, int i) {
    // 'i' is added as a parameter for readability
    WorldPoint p = new WorldPoint(x, y, z);
    Bookcase b = byPoint.get(p);
    if (b == null) {
        b = new Bookcase(p);
        byPoint.put(p, b);
        byLevel.computeIfAbsent(z, a -> new ArrayList<>()).add(b);
    }
    b.getIndex().add(i);
    assert i == byIndex.size();
    byIndex.add(b);
}
Also used : IntStream(java.util.stream.IntStream) WorldPoint(net.runelite.api.coords.WorldPoint) Arrays(java.util.Arrays) Getter(lombok.Getter) Book(net.runelite.client.plugins.kourendlibrary.Book) HashMap(java.util.HashMap) Singleton(javax.inject.Singleton) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Map(java.util.Map) Collections(java.util.Collections) WorldPoint(net.runelite.api.coords.WorldPoint) ArrayList(java.util.ArrayList)

Example 3 with WorldPoint

use of net.runelite.api.coords.WorldPoint in project runelite by runelite.

the class Library method mark.

public synchronized void mark(WorldPoint loc, Book book) {
    Bookcase bookcase = byPoint.get(loc);
    if (bookcase == null) {
        log.debug("Requested non-existent bookcase at {}", loc);
        return;
    }
    if (bookcase.isBookSet()) {
        // Check for a mismatch, unless it is now null and had a dark manuscript
        if (book != bookcase.getBook() && !(book == null && bookcase.getBook().isDarkManuscript())) {
            reset();
        }
    } else if (state != SolvedState.NO_DATA) {
        // We know all of the possible things in this shelf.
        if (book != null) {
            // Check to see if our guess is wrong
            if (!bookcase.getPossibleBooks().contains(book)) {
                reset();
            }
        }
    }
    // Everything is known, nothing to do
    if (state == SolvedState.COMPLETE) {
        return;
    }
    log.info("Setting bookcase {} to {}", bookcase.getIndex(), book);
    for (; ; ) {
        bookcase.setBook(book);
        // Basing the sequences on null is not supported, though possible
        if (book == null) {
            return;
        }
        // This is one of the 6 bookcases with 2 ids. Not fully supported.
        if (bookcase.getIndex().size() != 1) {
            return;
        }
        int bookcaseIndex = bookcase.getIndex().get(0);
        state = SolvedState.INCOMPLETE;
        // Map each sequence to the number of bookcases that match the sequence
        // return 0 if it is a mismatch.
        // Keep in mind that Bookcases with dark manuscripts may be set to null.
        int[] certainty = sequences.stream().mapToInt(sequence -> {
            int zero = getBookcaseZeroIndexForSequenceWithBook(sequence, bookcaseIndex, book);
            int found = 0;
            for (int i = 0; i < byIndex.size(); i++) {
                int ai = (i + zero) % byIndex.size();
                Bookcase iBookcase = byIndex.get(ai);
                if (i % step == 0) {
                    int seqI = i / step;
                    if (iBookcase.isBookSet() && seqI < sequence.size()) {
                        Book seqBook = sequence.get(seqI);
                        boolean isSeqManuscript = seqBook == null || seqBook.isDarkManuscript();
                        if (!((isSeqManuscript && iBookcase.getBook() == null) || (iBookcase.getBook() == seqBook))) {
                            log.debug("Bailing @ i={} ai={} {}; {} != {}", i, ai, iBookcase.getIndex(), iBookcase.getBook(), seqBook);
                            found = 0;
                            break;
                        }
                        found++;
                    }
                } else {
                    // Only bail if this isn't a double bookcase
                    if (iBookcase.isBookSet() && iBookcase.getBook() != null && iBookcase.getIndex().size() == 1) {
                        log.debug("Bailing @ i={} ai={} {}; {} is set", i, ai, iBookcase.getIndex(), iBookcase.getBook());
                        found = 0;
                        break;
                    }
                }
            }
            return found;
        }).toArray();
        log.info("Certainty is now {}", certainty);
        for (Bookcase b : byIndex) {
            b.getPossibleBooks().clear();
        }
        // Write the most likely sequences onto the bookcases
        int max = IntStream.of(certainty).max().getAsInt();
        // We have books set, but 0 sequences match, Something is wrong, reset.
        if (max == 0) {
            reset();
            continue;
        }
        IntStream.range(0, sequences.size()).filter(i -> certainty[i] == max).forEach(isequence -> {
            List<Book> sequence = sequences.get(isequence);
            int zero = getBookcaseZeroIndexForSequenceWithBook(sequence, bookcaseIndex, book);
            for (int i = 0; i < byIndex.size(); i++) {
                int ai = (i + zero) % byIndex.size();
                Bookcase iBookcase = byIndex.get(ai);
                if (iBookcase.getBook() == null) {
                    int iseq = i / step;
                    if (i % step == 0 && iseq < sequence.size()) {
                        Book seqBook = sequence.get(iseq);
                        iBookcase.getPossibleBooks().add(seqBook);
                    }
                }
            }
        });
        if (IntStream.range(0, certainty.length).filter(i -> certainty[i] == max).count() == 1) {
            state = SolvedState.COMPLETE;
        }
        return;
    }
}
Also used : IntStream(java.util.stream.IntStream) WorldPoint(net.runelite.api.coords.WorldPoint) Arrays(java.util.Arrays) Getter(lombok.Getter) Book(net.runelite.client.plugins.kourendlibrary.Book) HashMap(java.util.HashMap) Singleton(javax.inject.Singleton) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Map(java.util.Map) Collections(java.util.Collections) Book(net.runelite.client.plugins.kourendlibrary.Book) WorldPoint(net.runelite.api.coords.WorldPoint)

Example 4 with WorldPoint

use of net.runelite.api.coords.WorldPoint 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.");
            }
        }
    }
}
Also used : Instant(java.time.Instant) Tile(net.runelite.api.Tile) LocalPoint(net.runelite.api.coords.LocalPoint) WorldPoint(net.runelite.api.coords.WorldPoint) GameObject(net.runelite.api.GameObject) HashMap(java.util.HashMap) Map(java.util.Map) Subscribe(com.google.common.eventbus.Subscribe)

Example 5 with WorldPoint

use of net.runelite.api.coords.WorldPoint 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;
}
Also used : Color(java.awt.Color) Polygon(java.awt.Polygon) LocalPoint(net.runelite.api.coords.LocalPoint) WorldPoint(net.runelite.api.coords.WorldPoint) OverlayLayer(net.runelite.client.ui.overlay.OverlayLayer) OverlayUtil(net.runelite.client.ui.overlay.OverlayUtil) Inject(com.google.inject.Inject) Rectangle2D(java.awt.geom.Rectangle2D) Set(java.util.Set) Player(net.runelite.api.Player) Point(net.runelite.api.Point) Client(net.runelite.api.Client) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Dimension(java.awt.Dimension) List(java.util.List) Perspective(net.runelite.api.Perspective) FontMetrics(java.awt.FontMetrics) Graphics2D(java.awt.Graphics2D) Overlay(net.runelite.client.ui.overlay.Overlay) OverlayPosition(net.runelite.client.ui.overlay.OverlayPosition) Perspective.getCanvasTilePoly(net.runelite.api.Perspective.getCanvasTilePoly) Player(net.runelite.api.Player) Color(java.awt.Color) Rectangle2D(java.awt.geom.Rectangle2D) LocalPoint(net.runelite.api.coords.LocalPoint) WorldPoint(net.runelite.api.coords.WorldPoint) Point(net.runelite.api.Point) LocalPoint(net.runelite.api.coords.LocalPoint) WorldPoint(net.runelite.api.coords.WorldPoint) Point(net.runelite.api.Point) LocalPoint(net.runelite.api.coords.LocalPoint) WorldPoint(net.runelite.api.coords.WorldPoint) FontMetrics(java.awt.FontMetrics) Objects(java.util.Objects) Polygon(java.awt.Polygon)

Aggregations

WorldPoint (net.runelite.api.coords.WorldPoint)8 HashMap (java.util.HashMap)3 List (java.util.List)3 Map (java.util.Map)3 LocalPoint (net.runelite.api.coords.LocalPoint)3 Color (java.awt.Color)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 Collections (java.util.Collections)2 HashSet (java.util.HashSet)2 IntStream (java.util.stream.IntStream)2 Singleton (javax.inject.Singleton)2 Getter (lombok.Getter)2 Slf4j (lombok.extern.slf4j.Slf4j)2 Tile (net.runelite.api.Tile)2 Book (net.runelite.client.plugins.kourendlibrary.Book)2 Subscribe (com.google.common.eventbus.Subscribe)1 Inject (com.google.inject.Inject)1 Dimension (java.awt.Dimension)1 FontMetrics (java.awt.FontMetrics)1