Merge pull request #5151 from TheStonedTurtle/LootTrackerBugFixes
Add player death check, ToB region check and 1 loot per-tile per-tick check to loot tracker events
This commit is contained in:
@@ -27,6 +27,7 @@ package net.runelite.api.coords;
|
|||||||
|
|
||||||
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 net.runelite.api.Perspective;
|
import net.runelite.api.Perspective;
|
||||||
import net.runelite.api.Point;
|
import net.runelite.api.Point;
|
||||||
|
|
||||||
@@ -149,6 +150,72 @@ public class WorldPoint
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the coordinate of the tile that contains the passed local point.
|
||||||
|
*
|
||||||
|
* @param client the client
|
||||||
|
* @param localPoint the local coordinate
|
||||||
|
* @return the tile coordinate containing the local point
|
||||||
|
*/
|
||||||
|
public static WorldPoint fromLocalInstance(Client client, LocalPoint localPoint)
|
||||||
|
{
|
||||||
|
if (client.isInInstancedRegion())
|
||||||
|
{
|
||||||
|
// get position in the scene
|
||||||
|
int sceneX = localPoint.getSceneX();
|
||||||
|
int sceneY = localPoint.getSceneY();
|
||||||
|
|
||||||
|
// get chunk from scene
|
||||||
|
int chunkX = sceneX / CHUNK_SIZE;
|
||||||
|
int chunkY = sceneY / CHUNK_SIZE;
|
||||||
|
|
||||||
|
// get the template chunk for the chunk
|
||||||
|
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
||||||
|
int templateChunk = instanceTemplateChunks[client.getPlane()][chunkX][chunkY];
|
||||||
|
|
||||||
|
int rotation = templateChunk >> 1 & 0x3;
|
||||||
|
int templateChunkY = (templateChunk >> 3 & 0x7FF) * CHUNK_SIZE;
|
||||||
|
int templateChunkX = (templateChunk >> 14 & 0x3FF) * CHUNK_SIZE;
|
||||||
|
int plane = templateChunk >> 24 & 0x3;
|
||||||
|
|
||||||
|
// calculate world point of the template
|
||||||
|
int x = templateChunkX + (sceneX & (CHUNK_SIZE - 1));
|
||||||
|
int y = templateChunkY + (sceneY & (CHUNK_SIZE - 1));
|
||||||
|
|
||||||
|
// create and rotate point back to 0, to match with template
|
||||||
|
return rotate(new WorldPoint(x, y, plane), 4 - rotation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fromLocal(client, localPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the shortest distance from this point to a WorldArea.
|
* Gets the shortest distance from this point to a WorldArea.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.google.common.eventbus.EventBus;
|
|||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -66,6 +67,7 @@ public class LootManager
|
|||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final Client client;
|
private final Client client;
|
||||||
private final ListMultimap<Integer, ItemStack> itemSpawns = ArrayListMultimap.create();
|
private final ListMultimap<Integer, ItemStack> itemSpawns = ArrayListMultimap.create();
|
||||||
|
private final Map<LocalPoint, Boolean> killMap = new HashMap<>();
|
||||||
private WorldPoint playerLocationLastTick;
|
private WorldPoint playerLocationLastTick;
|
||||||
private WorldPoint krakenPlayerLocation;
|
private WorldPoint krakenPlayerLocation;
|
||||||
|
|
||||||
@@ -123,8 +125,14 @@ public class LootManager
|
|||||||
public void onPlayerDespawned(PlayerDespawned playerDespawned)
|
public void onPlayerDespawned(PlayerDespawned playerDespawned)
|
||||||
{
|
{
|
||||||
final Player player = playerDespawned.getPlayer();
|
final Player player = playerDespawned.getPlayer();
|
||||||
|
// Only care about dead Players
|
||||||
|
if (player.getHealthRatio() != 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final LocalPoint location = LocalPoint.fromWorld(client, player.getWorldLocation());
|
final LocalPoint location = LocalPoint.fromWorld(client, player.getWorldLocation());
|
||||||
if (location == null)
|
if (location == null || killMap.get(location))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -139,6 +147,7 @@ public class LootManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
killMap.put(location, true);
|
||||||
eventBus.post(new PlayerLootReceived(player, items));
|
eventBus.post(new PlayerLootReceived(player, items));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,12 +214,13 @@ public class LootManager
|
|||||||
{
|
{
|
||||||
playerLocationLastTick = client.getLocalPlayer().getWorldLocation();
|
playerLocationLastTick = client.getLocalPlayer().getWorldLocation();
|
||||||
itemSpawns.clear();
|
itemSpawns.clear();
|
||||||
|
killMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processNpcLoot(NPC npc)
|
private void processNpcLoot(NPC npc)
|
||||||
{
|
{
|
||||||
final LocalPoint location = LocalPoint.fromWorld(client, getDropLocation(npc, npc.getWorldLocation()));
|
final LocalPoint location = LocalPoint.fromWorld(client, getDropLocation(npc, npc.getWorldLocation()));
|
||||||
if (location == null)
|
if (location == null || killMap.get(location))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -236,6 +246,7 @@ public class LootManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
killMap.put(location, true);
|
||||||
eventBus.post(new NpcLootReceived(npc, allItems));
|
eventBus.post(new NpcLootReceived(npc, allItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,11 +34,9 @@ import java.util.EnumSet;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
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.Skill;
|
import net.runelite.api.Skill;
|
||||||
import net.runelite.api.WorldType;
|
import net.runelite.api.WorldType;
|
||||||
import net.runelite.api.coords.LocalPoint;
|
|
||||||
import net.runelite.api.coords.WorldPoint;
|
import net.runelite.api.coords.WorldPoint;
|
||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.ExperienceChanged;
|
import net.runelite.api.events.ExperienceChanged;
|
||||||
@@ -186,7 +184,7 @@ public class DiscordPlugin extends Plugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int playerRegionID = getCurrentRegion();
|
final int playerRegionID = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()).getRegionID();
|
||||||
|
|
||||||
if (playerRegionID == 0)
|
if (playerRegionID == 0)
|
||||||
{
|
{
|
||||||
@@ -238,26 +236,4 @@ public class DiscordPlugin extends Plugin
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCurrentRegion()
|
|
||||||
{
|
|
||||||
if (!client.isInInstancedRegion())
|
|
||||||
{
|
|
||||||
return client.getLocalPlayer().getWorldLocation().getRegionID();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get chunk data of current chunk
|
|
||||||
final LocalPoint localPoint = client.getLocalPlayer().getLocalLocation();
|
|
||||||
final int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
|
||||||
final int z = client.getPlane();
|
|
||||||
final int chunkData = instanceTemplateChunks[z][localPoint.getSceneX() / CHUNK_SIZE][localPoint.getSceneY() / CHUNK_SIZE];
|
|
||||||
|
|
||||||
// extract world point from chunk data
|
|
||||||
final int chunkY = (chunkData >> 3 & 0x7FF) * CHUNK_SIZE;
|
|
||||||
final int chunkX = (chunkData >> 14 & 0x3FF) * CHUNK_SIZE;
|
|
||||||
|
|
||||||
final WorldPoint worldPoint = new WorldPoint(chunkX, chunkY, z);
|
|
||||||
return worldPoint.getRegionID();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,39 +311,7 @@ public class GroundMarkerPlugin extends Plugin
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPoint worldPoint;
|
WorldPoint worldPoint = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation());
|
||||||
|
|
||||||
if (client.isInInstancedRegion())
|
|
||||||
{
|
|
||||||
// get position in the scene
|
|
||||||
int sceneX = localPoint.getSceneX();
|
|
||||||
int sceneY = localPoint.getSceneY();
|
|
||||||
|
|
||||||
// get chunk from scene
|
|
||||||
int chunkX = sceneX / CHUNK_SIZE;
|
|
||||||
int chunkY = sceneY / CHUNK_SIZE;
|
|
||||||
|
|
||||||
// get the template chunk for the chunk
|
|
||||||
int[][][] instanceTemplateChunks = client.getInstanceTemplateChunks();
|
|
||||||
int templateChunk = instanceTemplateChunks[client.getPlane()][chunkX][chunkY];
|
|
||||||
|
|
||||||
int rotation = templateChunk >> 1 & 0x3;
|
|
||||||
int templateChunkY = (templateChunk >> 3 & 0x7FF) * CHUNK_SIZE;
|
|
||||||
int templateChunkX = (templateChunk >> 14 & 0x3FF) * CHUNK_SIZE;
|
|
||||||
int plane = templateChunk >> 24 & 0x3;
|
|
||||||
|
|
||||||
// calculate world point of the template
|
|
||||||
int x = templateChunkX + (sceneX & (CHUNK_SIZE - 1));
|
|
||||||
int y = templateChunkY + (sceneY & (CHUNK_SIZE - 1));
|
|
||||||
|
|
||||||
worldPoint = new WorldPoint(x, y, plane);
|
|
||||||
// rotate point back to 0, to match with template
|
|
||||||
worldPoint = rotateInverse(worldPoint, rotation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worldPoint = WorldPoint.fromLocal(client, localPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
int regionId = worldPoint.getRegionID();
|
int regionId = worldPoint.getRegionID();
|
||||||
GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getX() & 0x3f, worldPoint.getY() & 0x3f, client.getPlane());
|
GroundMarkerPoint point = new GroundMarkerPoint(regionId, worldPoint.getX() & 0x3f, worldPoint.getY() & 0x3f, client.getPlane());
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import net.runelite.api.ItemContainer;
|
|||||||
import net.runelite.api.NPC;
|
import net.runelite.api.NPC;
|
||||||
import net.runelite.api.Player;
|
import net.runelite.api.Player;
|
||||||
import net.runelite.api.SpriteID;
|
import net.runelite.api.SpriteID;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
import net.runelite.api.events.WidgetLoaded;
|
import net.runelite.api.events.WidgetLoaded;
|
||||||
import net.runelite.api.widgets.WidgetID;
|
import net.runelite.api.widgets.WidgetID;
|
||||||
@@ -71,6 +72,7 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
// Activity/Event loot handling
|
// Activity/Event loot handling
|
||||||
private static final Pattern CLUE_SCROLL_PATTERN = Pattern.compile("You have completed [0-9]+ ([a-z]+) Treasure Trails.");
|
private static final Pattern CLUE_SCROLL_PATTERN = Pattern.compile("You have completed [0-9]+ ([a-z]+) Treasure Trails.");
|
||||||
|
private static final int THEATRE_OF_BLOOD_REGION = 12867;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientToolbar clientToolbar;
|
private ClientToolbar clientToolbar;
|
||||||
@@ -178,6 +180,11 @@ public class LootTrackerPlugin extends Plugin
|
|||||||
container = client.getItemContainer(InventoryID.CHAMBERS_OF_XERIC_CHEST);
|
container = client.getItemContainer(InventoryID.CHAMBERS_OF_XERIC_CHEST);
|
||||||
break;
|
break;
|
||||||
case (WidgetID.THEATRE_OF_BLOOD_GROUP_ID):
|
case (WidgetID.THEATRE_OF_BLOOD_GROUP_ID):
|
||||||
|
int region = WorldPoint.fromLocalInstance(client, client.getLocalPlayer().getLocalLocation()).getRegionID();
|
||||||
|
if (region != THEATRE_OF_BLOOD_REGION)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
eventType = "Theatre of Blood";
|
eventType = "Theatre of Blood";
|
||||||
container = client.getItemContainer(InventoryID.THEATRE_OF_BLOOD_CHEST);
|
container = client.getItemContainer(InventoryID.THEATRE_OF_BLOOD_CHEST);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user