This commit is contained in:
zeruth
2019-06-10 02:30:08 -04:00
parent 59ed075ddd
commit ab3c6eb1b5

View File

@@ -24,12 +24,12 @@
*/ */
package net.runelite.mixins; package net.runelite.mixins;
import java.util.ArrayList; import net.runelite.api.Actor;
import java.util.List;
import net.runelite.api.CollisionData; import net.runelite.api.CollisionData;
import net.runelite.api.CollisionDataFlag; import net.runelite.api.CollisionDataFlag;
import net.runelite.api.Constants; import net.runelite.api.Constants;
import net.runelite.api.DecorativeObject; import net.runelite.api.DecorativeObject;
import net.runelite.api.GameObject;
import net.runelite.api.GroundObject; import net.runelite.api.GroundObject;
import net.runelite.api.Item; import net.runelite.api.Item;
import net.runelite.api.ItemLayer; import net.runelite.api.ItemLayer;
@@ -53,34 +53,31 @@ import net.runelite.api.events.ItemSpawned;
import net.runelite.api.events.WallObjectChanged; import net.runelite.api.events.WallObjectChanged;
import net.runelite.api.events.WallObjectDespawned; import net.runelite.api.events.WallObjectDespawned;
import net.runelite.api.events.WallObjectSpawned; import net.runelite.api.events.WallObjectSpawned;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.mixins.FieldHook; import net.runelite.api.mixins.FieldHook;
import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow; import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSActor;
import net.runelite.rs.api.RSClient; import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSDeque;
import net.runelite.rs.api.RSGameObject; import net.runelite.rs.api.RSGameObject;
import net.runelite.rs.api.RSGraphicsObject; import net.runelite.rs.api.RSGroundItem;
import net.runelite.rs.api.RSItem; import net.runelite.rs.api.RSGroundItemPile;
import net.runelite.rs.api.RSItemLayer;
import net.runelite.rs.api.RSNode; import net.runelite.rs.api.RSNode;
import net.runelite.rs.api.RSProjectile; import net.runelite.rs.api.RSNodeDeque;
import net.runelite.rs.api.RSRenderable;
import net.runelite.rs.api.RSTile; import net.runelite.rs.api.RSTile;
import org.slf4j.Logger;
@Mixin(RSTile.class) @Mixin(RSTile.class)
public abstract class RSTileMixin implements RSTile public abstract class RSTileMixin implements RSTile
{ {
@Shadow("clientInstance") @Shadow("client")
private static RSClient client; private static RSClient client;
@Inject @Inject
private static RSGameObject lastGameObject; private static GameObject lastGameObject;
@Inject @Inject
private static RSDeque[][][] lastGroundItems = new RSDeque[Constants.MAX_Z][Constants.SCENE_SIZE][Constants.SCENE_SIZE]; private static RSNodeDeque[][][] lastGroundItems = new RSNodeDeque[Constants.MAX_Z][Constants.SCENE_SIZE][Constants.SCENE_SIZE];
@Inject @Inject
private WallObject previousWallObject; private WallObject previousWallObject;
@@ -92,7 +89,7 @@ public abstract class RSTileMixin implements RSTile
private GroundObject previousGroundObject; private GroundObject previousGroundObject;
@Inject @Inject
private RSGameObject[] previousGameObjects; private GameObject[] previousGameObjects;
@Inject @Inject
@Override @Override
@@ -115,7 +112,7 @@ public abstract class RSTileMixin implements RSTile
return LocalPoint.fromScene(getX(), getY()); return LocalPoint.fromScene(getX(), getY());
} }
@FieldHook("wallObject") @FieldHook("boundaryObject")
@Inject @Inject
public void wallObjectChanged(int idx) public void wallObjectChanged(int idx)
{ {
@@ -138,7 +135,7 @@ public abstract class RSTileMixin implements RSTile
wallObjectSpawned.setWallObject(current); wallObjectSpawned.setWallObject(current);
client.getCallbacks().post(wallObjectSpawned); client.getCallbacks().post(wallObjectSpawned);
} }
else if (current != null && previous != null) else if (current != null)
{ {
WallObjectChanged wallObjectChanged = new WallObjectChanged(); WallObjectChanged wallObjectChanged = new WallObjectChanged();
wallObjectChanged.setTile(this); wallObjectChanged.setTile(this);
@@ -148,7 +145,7 @@ public abstract class RSTileMixin implements RSTile
} }
} }
@FieldHook("decorativeObject") @FieldHook("wallDecoration")
@Inject @Inject
public void decorativeObjectChanged(int idx) public void decorativeObjectChanged(int idx)
{ {
@@ -171,7 +168,7 @@ public abstract class RSTileMixin implements RSTile
decorativeObjectSpawned.setDecorativeObject(current); decorativeObjectSpawned.setDecorativeObject(current);
client.getCallbacks().post(decorativeObjectSpawned); client.getCallbacks().post(decorativeObjectSpawned);
} }
else if (current != null && previous != null) else if (current != null)
{ {
DecorativeObjectChanged decorativeObjectChanged = new DecorativeObjectChanged(); DecorativeObjectChanged decorativeObjectChanged = new DecorativeObjectChanged();
decorativeObjectChanged.setTile(this); decorativeObjectChanged.setTile(this);
@@ -181,7 +178,7 @@ public abstract class RSTileMixin implements RSTile
} }
} }
@FieldHook("groundObject") @FieldHook("floorDecoration")
@Inject @Inject
public void groundObjectChanged(int idx) public void groundObjectChanged(int idx)
{ {
@@ -204,7 +201,7 @@ public abstract class RSTileMixin implements RSTile
groundObjectSpawned.setGroundObject(current); groundObjectSpawned.setGroundObject(current);
client.getCallbacks().post(groundObjectSpawned); client.getCallbacks().post(groundObjectSpawned);
} }
else if (current != null && previous != null) else if (current != null)
{ {
GroundObjectChanged groundObjectChanged = new GroundObjectChanged(); GroundObjectChanged groundObjectChanged = new GroundObjectChanged();
groundObjectChanged.setTile(this); groundObjectChanged.setTile(this);
@@ -214,7 +211,7 @@ public abstract class RSTileMixin implements RSTile
} }
} }
@FieldHook("objects") @FieldHook("gameObjects")
@Inject @Inject
public void gameObjectsChanged(int idx) public void gameObjectsChanged(int idx)
{ {
@@ -225,110 +222,69 @@ public abstract class RSTileMixin implements RSTile
if (previousGameObjects == null) if (previousGameObjects == null)
{ {
previousGameObjects = new RSGameObject[5]; previousGameObjects = new GameObject[5];
} }
// Previous game object // Previous game object
RSGameObject previous = previousGameObjects[idx]; GameObject previous = previousGameObjects[idx];
// GameObject that was changed. // GameObject that was changed.
RSGameObject current = (RSGameObject) getGameObjects()[idx]; RSGameObject current = (RSGameObject) getGameObjects()[idx];
// Update previous object to current
previousGameObjects[idx] = current;
// Last game object // Last game object
RSGameObject last = lastGameObject; GameObject last = lastGameObject;
// Update last game object // Update last game object
lastGameObject = current; lastGameObject = current;
// Update previous object to current
previousGameObjects[idx] = current;
// Duplicate event, return // Duplicate event, return
if (current == previous) if (current != null && current.equals(last))
{ {
return; return;
} }
if (current != null && current == last) // Characters seem to generate a constant stream of new GameObjects
if (current == null || !(current.getRenderable() instanceof Actor))
{ {
// When >1 tile objects are added to the scene, the same GameObject is added to if (current == null && previous != null)
// multiple tiles. We keep lastGameObject to prevent duplicate spawn events from
// firing for these objects.
return;
}
// actors, projectiles, and graphics objects are added and removed from the scene each frame as GameObjects,
// so ignore them.
boolean currentInvalid = false, prevInvalid = false;
if (current != null)
{
RSRenderable renderable = current.getRenderable();
currentInvalid = renderable instanceof RSActor || renderable instanceof RSProjectile || renderable instanceof RSGraphicsObject;
}
if (previous != null)
{
RSRenderable renderable = previous.getRenderable();
prevInvalid = renderable instanceof RSActor || renderable instanceof RSProjectile || renderable instanceof RSGraphicsObject;
}
Logger logger = client.getLogger();
if (current == null)
{
if (prevInvalid)
{ {
return; GameObjectDespawned gameObjectDespawned = new GameObjectDespawned();
gameObjectDespawned.setTile(this);
gameObjectDespawned.setGameObject(previous);
client.getCallbacks().post(gameObjectDespawned);
} }
else if (current != null && previous == null)
logger.trace("Game object despawn: {}", previous.getId());
GameObjectDespawned gameObjectDespawned = new GameObjectDespawned();
gameObjectDespawned.setTile(this);
gameObjectDespawned.setGameObject(previous);
client.getCallbacks().post(gameObjectDespawned);
}
else if (previous == null)
{
if (currentInvalid)
{ {
return; GameObjectSpawned gameObjectSpawned = new GameObjectSpawned();
gameObjectSpawned.setTile(this);
gameObjectSpawned.setGameObject(current);
client.getCallbacks().post(gameObjectSpawned);
} }
else if (current != null)
logger.trace("Game object spawn: {}", current.getId());
GameObjectSpawned gameObjectSpawned = new GameObjectSpawned();
gameObjectSpawned.setTile(this);
gameObjectSpawned.setGameObject(current);
client.getCallbacks().post(gameObjectSpawned);
}
else
{
if (currentInvalid && prevInvalid)
{ {
return; GameObjectChanged gameObjectsChanged = new GameObjectChanged();
gameObjectsChanged.setTile(this);
gameObjectsChanged.setPrevious(previous);
gameObjectsChanged.setGameObject(current);
client.getCallbacks().post(gameObjectsChanged);
} }
logger.trace("Game object change: {} -> {}", previous.getId(), current.getId());
GameObjectChanged gameObjectsChanged = new GameObjectChanged();
gameObjectsChanged.setTile(this);
gameObjectsChanged.setPrevious(previous);
gameObjectsChanged.setGameObject(current);
client.getCallbacks().post(gameObjectsChanged);
} }
} }
@FieldHook("itemLayer") @FieldHook("groundItemPile")
@Inject @Inject
public void itemLayerChanged(int idx) public void itemLayerChanged(int idx)
{ {
int x = getX(); int x = getX();
int y = getY(); int y = getY();
int z = client.getPlane(); int z = client.getPlane();
RSDeque[][][] groundItemDeque = client.getGroundItemDeque(); RSNodeDeque[][][] groundItemDeque = client.getGroundItemDeque();
RSDeque oldQueue = lastGroundItems[z][x][y]; RSNodeDeque oldQueue = lastGroundItems[z][x][y];
RSDeque newQueue = groundItemDeque[z][x][y]; RSNodeDeque newQueue = groundItemDeque[z][x][y];
if (oldQueue != newQueue) if (oldQueue != newQueue)
{ {
@@ -338,7 +294,7 @@ public abstract class RSTileMixin implements RSTile
RSNode head = oldQueue.getHead(); RSNode head = oldQueue.getHead();
for (RSNode cur = head.getNext(); cur != head; cur = cur.getNext()) for (RSNode cur = head.getNext(); cur != head; cur = cur.getNext())
{ {
RSItem item = (RSItem) cur; RSGroundItem item = (RSGroundItem) cur;
ItemDespawned itemDespawned = new ItemDespawned(this, item); ItemDespawned itemDespawned = new ItemDespawned(this, item);
client.getCallbacks().post(itemDespawned); client.getCallbacks().post(itemDespawned);
} }
@@ -346,13 +302,13 @@ public abstract class RSTileMixin implements RSTile
lastGroundItems[z][x][y] = newQueue; lastGroundItems[z][x][y] = newQueue;
} }
RSItem lastUnlink = client.getLastItemDespawn(); RSGroundItem lastUnlink = client.getLastItemDespawn();
if (lastUnlink != null) if (lastUnlink != null)
{ {
client.setLastItemDespawn(null); client.setLastItemDespawn(null);
} }
RSItemLayer itemLayer = (RSItemLayer) getItemLayer(); RSGroundItemPile itemLayer = (RSGroundItemPile) getItemLayer();
if (itemLayer == null) if (itemLayer == null)
{ {
if (lastUnlink != null) if (lastUnlink != null)
@@ -363,7 +319,7 @@ public abstract class RSTileMixin implements RSTile
return; return;
} }
RSDeque itemDeque = newQueue; RSNodeDeque itemDeque = newQueue;
if (itemDeque == null) if (itemDeque == null)
{ {
@@ -382,7 +338,7 @@ public abstract class RSTileMixin implements RSTile
boolean forward = false; boolean forward = false;
if (head != previous) if (head != previous)
{ {
RSItem prev = (RSItem) previous; RSGroundItem prev = (RSGroundItem) previous;
if (x != prev.getX() || y != prev.getY()) if (x != prev.getX() || y != prev.getY())
{ {
current = prev; current = prev;
@@ -392,7 +348,7 @@ public abstract class RSTileMixin implements RSTile
RSNode next = head.getNext(); RSNode next = head.getNext();
if (current == null && head != next) if (current == null && head != next)
{ {
RSItem n = (RSItem) next; RSGroundItem n = (RSGroundItem) next;
if (x != n.getX() || y != n.getY()) if (x != n.getX() || y != n.getY())
{ {
current = n; current = n;
@@ -413,7 +369,7 @@ public abstract class RSTileMixin implements RSTile
do do
{ {
RSItem item = (RSItem) current; RSGroundItem item = (RSGroundItem) current;
item.setX(x); item.setX(x);
item.setY(y); item.setY(y);
@@ -424,7 +380,7 @@ public abstract class RSTileMixin implements RSTile
// Send spawn events for anything on this tile which is at the wrong location, which happens // Send spawn events for anything on this tile which is at the wrong location, which happens
// when the scene base changes // when the scene base changes
} while (current != head && (((RSItem) current).getX() != x || ((RSItem) current).getY() != y)); } while (current != head && (((RSGroundItem) current).getX() != x || ((RSGroundItem) current).getY() != y));
} }
@Inject @Inject