Remove object wrappers and use mixins to inject functionality

This causes hierarchy to be runelite-client -> runelite-api and
injected-client -> runescape-api -> runelite-api. The mixin injector
fufills the runelite-api interface with access to the runescape-api
interfaces. The mixins live in runelite-mixins and are not loaded within
the client.

Note the obfuscated client classes do not pass JVM verification on 7+,
so the mixins are currently set to target Java 6.
This commit is contained in:
Adam
2017-08-19 13:58:06 -04:00
parent 07c8442f22
commit 59552896ed
124 changed files with 2257 additions and 1814 deletions

63
runelite-mixins/pom.xml Normal file
View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.runelite</groupId>
<artifactId>runelite-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
</parent>
<groupId>net.runelite</groupId>
<artifactId>mixins</artifactId>
<name>Runelite Mixins</name>
<dependencies>
<dependency>
<groupId>net.runelite.rs</groupId>
<artifactId>api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<!-- RuneScape classes do not verify
under Java 7+ due to the obfuscation
-->
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,37 @@
/*
* 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.mixins;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Inject
{
}

View File

@@ -0,0 +1,44 @@
/*
* 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.mixins;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Repeatable(Mixins.class)
public @interface Mixin
{
/**
* Class to inject this mixin into
*
* @return
*/
Class<?> value();
}

View File

@@ -0,0 +1,37 @@
/*
* 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.mixins;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Mixins
{
Mixin[] value();
}

View File

@@ -0,0 +1,37 @@
/*
* 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.mixins;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Shadow
{
String value();
}

View File

@@ -0,0 +1,148 @@
/*
* 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 java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.image.BufferedImage;
import net.runelite.api.Actor;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSActor;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSCombatInfo1;
import net.runelite.rs.api.RSCombatInfo2;
import net.runelite.rs.api.RSCombatInfoList;
import net.runelite.rs.api.RSCombatInfoListHolder;
import net.runelite.rs.api.RSNode;
@Mixin(RSActor.class)
public abstract class RSActorMixin implements RSActor
{
@Shadow("clientInstance")
private static RSClient client;
@Inject
@Override
public Actor getInteracting()
{
int i = getRSInteracting();
if (i == -1)
{
return null;
}
if (i < 0x8000)
{
return client.getNpc(i);
}
i -= 0x8000;
return client.getPlayer(i);
}
@Inject
@Override
public int getHealthRatio()
{
RSCombatInfoList combatInfoList = getCombatInfoList();
if (combatInfoList != null)
{
RSNode node = combatInfoList.getNode();
RSNode next = node.getNext();
if (next instanceof RSCombatInfoListHolder)
{
RSCombatInfoListHolder combatInfoListWrapper = (RSCombatInfoListHolder) next;
RSCombatInfoList combatInfoList1 = combatInfoListWrapper.getCombatInfo1();
RSNode node2 = combatInfoList1.getNode();
RSNode next2 = node2.getNext();
if (next2 instanceof RSCombatInfo1)
{
RSCombatInfo1 combatInfo = (RSCombatInfo1) next2;
return combatInfo.getHealthRatio();
}
}
}
return -1;
}
@Inject
@Override
public int getHealth()
{
RSCombatInfoList combatInfoList = getCombatInfoList();
if (combatInfoList != null)
{
RSNode node = combatInfoList.getNode();
RSNode next = node.getNext();
if (next instanceof RSCombatInfoListHolder)
{
RSCombatInfoListHolder combatInfoListWrapper = (RSCombatInfoListHolder) next;
RSCombatInfo2 cf = combatInfoListWrapper.getCombatInfo2();
return cf.getHealthScale();
}
}
return -1;
}
@Inject
@Override
public Point getLocalLocation()
{
return new Point(getX(), getY());
}
@Inject
@Override
public Polygon getCanvasTilePoly()
{
return Perspective.getCanvasTilePoly(client, getLocalLocation());
}
@Inject
@Override
public Point getCanvasTextLocation(Graphics2D graphics, String text, int zOffset)
{
return Perspective.getCanvasTextLocation(client, graphics, getLocalLocation(), text, zOffset);
}
@Inject
@Override
public Point getCanvasImageLocation(Graphics2D graphics, BufferedImage image, int zOffset)
{
return Perspective.getCanvasImageLocation(client, graphics, getLocalLocation(), image, zOffset);
}
@Inject
@Override
public Point getMinimapLocation()
{
return Perspective.worldToMiniMap(client, getX(), getY());
}
}

View File

@@ -0,0 +1,225 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
import net.runelite.api.GameState;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.Prayer;
import net.runelite.api.Skill;
import net.runelite.api.Varbits;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSWidget;
@Mixin(RSClient.class)
public abstract class RSClientMixin implements RSClient
{
@Inject
@Override
public Player getPlayer(int idx)
{
return getCachedPlayers()[idx];
}
@Inject
@Override
public NPC getNpc(int idx)
{
return getCachedNPCs()[idx];
}
@Inject
@Override
public int getBoostedSkillLevel(Skill skill)
{
int[] boostedLevels = getBoostedSkillLevels();
return boostedLevels[skill.ordinal()];
}
@Inject
@Override
public int getRealSkillLevel(Skill skill)
{
int[] realLevels = getRealSkillLevels();
return realLevels[skill.ordinal()];
}
@Inject
@Override
public void sendGameMessage(String message)
{
sendGameMessage(99, "", message);
}
@Inject
@Override
public GameState getGameState()
{
return GameState.of(getRSGameState());
}
@Inject
@Override
public Point getMouseCanvasPosition()
{
return new Point(getMouseX(), getMouseY());
}
@Inject
@Override
public Widget[] getWidgetRoots()
{
int topGroup = getWidgetRoot();
List<Widget> widgets = new ArrayList<Widget>();
for (Widget widget : getWidgets()[topGroup])
{
if (widget != null && widget.getParentId() == -1)
{
widgets.add(widget);
}
}
return widgets.toArray(new Widget[widgets.size()]);
}
@Inject
@Override
public Widget getWidget(WidgetInfo widget)
{
int groupId = widget.getGroupId();
int childId = widget.getChildId();
return getWidget(groupId, childId);
}
@Inject
@Override
public Widget[] getGroup(int groupId)
{
RSWidget[][] widgets = getWidgets();
if (widgets == null || groupId < 0 || groupId >= widgets.length)
{
return null;
}
List<Widget> w = new ArrayList<Widget>();
for (Widget widget : widgets[groupId])
{
if (widget != null)
{
w.add(widget);
}
}
return w.toArray(new Widget[w.size()]);
}
@Inject
@Override
public Widget getWidget(int groupId, int childId)
{
RSWidget[][] widgets = getWidgets();
if (widgets == null || widgets.length <= groupId)
{
return null;
}
RSWidget[] childWidgets = widgets[groupId];
if (childWidgets == null || childWidgets.length <= childId)
{
return null;
}
return childWidgets[childId];
}
@Inject
@Override
public int getSetting(Varbits varbit)
{
int[] settings = getSettings();
int value = settings[varbit.getIndex()];
return varbit.get(value);
}
@Inject
@Override
public boolean isPrayerActive(Prayer prayer)
{
return getSetting(prayer.getVarbit()) == 1;
}
/**
* Returns the local player's current experience in the specified
* {@link Skill}.
*
* @param skill the {@link Skill} to retrieve the experience for
* @return the local player's current experience in the specified
* {@link Skill}, or -1 if the {@link Skill} isn't valid
*/
@Inject
@Override
public int getSkillExperience(Skill skill)
{
int[] experiences = getSkillExperiences();
if (skill == Skill.OVERALL)
{
int totalExperience = 0;
for (int experience : experiences)
{
totalExperience += experience;
}
return totalExperience;
}
int idx = skill.ordinal();
// I'm not certain exactly how needed this is, but if the Skill enum is updated in the future
// to hold something else that's not reported it'll save us from an ArrayIndexOutOfBoundsException.
if (idx >= experiences.length)
{
return -1;
}
return experiences[idx];
}
@Inject
@Override
public void refreshChat()
{
setChatCycle(getCycleCntr());
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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 java.awt.Polygon;
import net.runelite.api.Model;
import net.runelite.api.Renderable;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSDecorativeObject;
@Mixin(RSDecorativeObject.class)
public abstract class RSDecorativeObjectMixin implements RSDecorativeObject
{
@Inject
@Override
public Polygon getConvexHull()
{
Renderable renderable = getRenderable();
if (renderable == null)
{
return null;
}
Model model;
if (renderable instanceof Model)
{
model = (Model) renderable;
}
else
{
model = renderable.getModel();
}
if (model == null)
{
return null;
}
return getConvexHull(model, getOrientation());
}
}

View File

@@ -0,0 +1,65 @@
/*
* 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 java.awt.Polygon;
import net.runelite.api.Model;
import net.runelite.api.Renderable;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSGameObject;
@Mixin(RSGameObject.class)
public abstract class RSGameObjectMixin implements RSGameObject
{
@Inject
@Override
public Polygon getConvexHull()
{
Renderable renderable = getRenderable();
if (renderable == null)
{
return null;
}
Model model;
if (renderable instanceof Model)
{
model = (Model) renderable;
}
else
{
model = renderable.getModel();
}
if (model == null)
{
return null;
}
return getConvexHull(model, getOrientation());
}
}

View File

@@ -0,0 +1,62 @@
/*
* 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 java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.runelite.api.Node;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSHashTable;
import net.runelite.rs.api.RSNode;
@Mixin(RSHashTable.class)
public abstract class RSHashTableMixin implements RSHashTable
{
@Inject
@Override
public Collection<Node> getNodes()
{
List<Node> nodes = new ArrayList<Node>();
RSNode[] buckets = getBuckets();
for (int i = 0; i < buckets.length; ++i)
{
Node node = buckets[i];
// It looks like the first node in the bucket is always
// a sentinel
Node cur = node.getNext();
while (cur != node)
{
nodes.add(cur);
cur = cur.getNext();
}
}
return nodes;
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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 net.runelite.api.ChatMessageType;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSMessageNode;
@Mixin(RSMessageNode.class)
public abstract class RSMessageNodeMixin implements RSMessageNode
{
@Inject
@Override
public ChatMessageType getType()
{
return ChatMessageType.of(getRSType());
}
}

View File

@@ -0,0 +1,88 @@
/*
* 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 java.util.ArrayList;
import java.util.List;
import net.runelite.api.model.Triangle;
import net.runelite.api.model.Vertex;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSModel;
@Mixin(RSModel.class)
public abstract class RSModelMixin implements RSModel
{
@Override
@Inject
public List<Vertex> getVertices()
{
int[] verticesX = getVerticesX();
int[] verticesY = getVerticesY();
int[] verticesZ = getVerticesZ();
List<Vertex> vertices = new ArrayList<Vertex>();
for (int i = 0; i < verticesX.length; ++i)
{
Vertex v = new Vertex(
verticesX[i],
verticesY[i],
verticesZ[i]
);
vertices.add(v);
}
return vertices;
}
@Override
@Inject
public List<Triangle> getTriangles()
{
int[] trianglesX = getTrianglesX();
int[] trianglesY = getTrianglesY();
int[] trianglesZ = getTrianglesZ();
List<Vertex> vertices = getVertices();
List<Triangle> triangles = new ArrayList<Triangle>(trianglesX.length);
for (int i = 0; i < trianglesX.length; ++i)
{
int triangleX = trianglesX[i];
int triangleY = trianglesY[i];
int triangleZ = trianglesZ[i];
Triangle triangle = new Triangle(
vertices.get(triangleX),
vertices.get(triangleY),
vertices.get(triangleZ)
);
triangles.add(triangle);
}
return triangles;
}
}

View File

@@ -0,0 +1,54 @@
/*
* 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 net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSNPC;
@Mixin(RSNPC.class)
public abstract class RSNPCMixin implements RSNPC
{
@Inject
@Override
public int getId()
{
return getComposition().getId();
}
@Inject
@Override
public String getName()
{
return getComposition().getName().replace('\u00A0', ' ');
}
@Inject
@Override
public int getCombatLevel()
{
return getComposition().getCombatLevel();
}
}

View File

@@ -0,0 +1,58 @@
/*
* 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 net.runelite.api.kit.KitType;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSPlayerComposition;
@Mixin(RSPlayerComposition.class)
public abstract class RSPlayerCompositionMixin implements RSPlayerComposition
{
@Inject
@Override
public int getEquipmentId(KitType type)
{
int id = getEquipmentIds()[type.getIndex()];
if (id < 512)
{
return -1; // not an item
}
return id - 512;
}
@Inject
@Override
public int getKitId(KitType type)
{
int id = getEquipmentIds()[type.getIndex()];
if (id < 256 || id >= 512)
{
return -1; // not a kit
}
return id - 256;
}
}

View File

@@ -0,0 +1,133 @@
/*
* 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 java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.Model;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.model.Triangle;
import net.runelite.api.model.Vertex;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSPlayer;
@Mixin(RSPlayer.class)
public abstract class RSPlayerMixin implements RSPlayer
{
@Shadow("clientInstance")
private static RSClient client;
@Inject
@Override
public String getName()
{
return getRSName().replace('\u00A0', ' ');
}
@Inject
@Override
public Polygon[] getPolygons()
{
Model model = getModel();
if (model == null)
{
return null;
}
int localX = getX();
int localY = getY();
// models are orientated north (1024) and there are 2048 angles total
int orientation = (getOrientation() + 1024) % 2048;
List<Triangle> triangles = model.getTriangles();
if (orientation != 0)
{
triangles = rotate(triangles, orientation);
}
List<Polygon> polys = new ArrayList<Polygon>();
for (Triangle triangle : triangles)
{
Vertex vx = triangle.getA();
Vertex vy = triangle.getB();
Vertex vz = triangle.getC();
Point x = Perspective.worldToCanvas(client,
localX - vx.getX(),
localY - vx.getZ(),
-vx.getY());
Point y = Perspective.worldToCanvas(client,
localX - vy.getX(),
localY - vy.getZ(),
-vy.getY());
Point z = Perspective.worldToCanvas(client,
localX - vz.getX(),
localY - vz.getZ(),
-vz.getY());
int xx[] =
{
x.getX(), y.getX(), z.getX()
};
int yy[] =
{
x.getY(), y.getY(), z.getY()
};
polys.add(new Polygon(xx, yy, 3));
}
return polys.toArray(new Polygon[polys.size()]);
}
@Inject
private List<Triangle> rotate(List<Triangle> triangles, int orientation)
{
List<Triangle> rotatedTriangles = new ArrayList<Triangle>();
for (Triangle triangle : triangles)
{
Vertex a = triangle.getA();
Vertex b = triangle.getB();
Vertex c = triangle.getC();
Triangle rotatedTriangle = new Triangle(
a.rotate(orientation),
b.rotate(orientation),
c.rotate(orientation)
);
rotatedTriangles.add(rotatedTriangle);
}
return rotatedTriangles;
}
}

View File

@@ -0,0 +1,310 @@
/*
* 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 java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.runelite.api.Node;
import net.runelite.api.Point;
import net.runelite.api.WidgetNode;
import net.runelite.api.widgets.Widget;
import static net.runelite.api.widgets.WidgetInfo.TO_CHILD;
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
import net.runelite.api.widgets.WidgetItem;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSHashTable;
import net.runelite.rs.api.RSWidget;
@Mixin(RSWidget.class)
public abstract class RSWidgetMixin implements RSWidget
{
private static final int ITEM_SLOT_SIZE = 32;
@Shadow("clientInstance")
private static RSClient client;
@Inject
@Override
public Widget getParent()
{
int id = getParentId();
if (id == -1)
{
return null;
}
return client.getWidget(TO_GROUP(id), TO_CHILD(id));
}
@Inject
@Override
public int getParentId()
{
int parentId = getRSParentId();
if (parentId != -1)
{
return parentId;
}
int i = TO_GROUP(getId());
RSHashTable componentTable = client.getComponentTable();
for (Node node : componentTable.getNodes())
{
WidgetNode wn = (WidgetNode) node;
if (i == wn.getId())
{
return (int) wn.getHash();
}
}
return -1;
}
@Inject
@Override
public String getText()
{
return getRSText().replace('\u00A0', ' ');
}
@Inject
@Override
public String getName()
{
return getRSName().replace('\u00A0', ' ');
}
@Inject
@Override
public boolean isHidden()
{
Widget parent = getParent();
return (parent != null && parent.isHidden()) || isRSHidden();
}
@Inject
@Override
public Point getCanvasLocation()
{
int x = 0;
int y = 0;
RSWidget cur;
for (cur = this; cur.getParent() != null; cur = (RSWidget) cur.getParent())
{
x += cur.getRelativeX();
y += cur.getRelativeY();
x -= cur.getScrollX();
y -= cur.getScrollY();
}
// cur is now the root
int[] widgetBoundsWidth = client.getWidgetPositionsX();
int[] widgetBoundsHeight = client.getWidgetPositionsY();
int boundsIndex = cur.getBoundsIndex();
if (boundsIndex != -1)
{
x += widgetBoundsWidth[boundsIndex];
y += widgetBoundsHeight[boundsIndex];
if (cur.getType() > 0)
{
x += cur.getRelativeX();
y += cur.getRelativeY();
}
}
else
{
x += cur.getRelativeX();
y += cur.getRelativeY();
}
return new Point(x, y);
}
@Inject
@Override
public Rectangle getBounds()
{
Point canvasLocation = getCanvasLocation();
return new Rectangle(canvasLocation.getX(), canvasLocation.getY(), getWidth(), getHeight());
}
@Inject
@Override
public Collection<WidgetItem> getWidgetItems()
{
int[] itemIds = getItemIds();
if (itemIds == null)
{
return null;
}
List<WidgetItem> items = new ArrayList<WidgetItem>(itemIds.length);
for (int i = 0; i < itemIds.length; ++i)
{
WidgetItem item = getWidgetItem(i);
if (item != null)
{
items.add(item);
}
}
return items;
}
@Inject
@Override
public WidgetItem getWidgetItem(int index)
{
int[] itemIds = getItemIds();
int[] itemQuantities = getItemQuantities();
if (itemIds == null || itemQuantities == null)
{
return null;
}
int columns = getWidth(); // the number of item slot columns is stored here
int paddingX = getPaddingX();
int paddingY = getPaddingY();
int itemId = itemIds[index];
int itemQuantity = itemQuantities[index];
Point widgetCanvasLocation = getCanvasLocation();
if (itemId <= 0 || itemQuantity <= 0 || columns <= 0)
{
return null;
}
int row = index / columns;
int col = index % columns;
int itemX = widgetCanvasLocation.getX() + ((ITEM_SLOT_SIZE + paddingX) * col);
int itemY = widgetCanvasLocation.getY() + ((ITEM_SLOT_SIZE + paddingY) * row);
Rectangle bounds = new Rectangle(itemX - 1, itemY - 1, ITEM_SLOT_SIZE, ITEM_SLOT_SIZE);
return new WidgetItem(itemId - 1, itemQuantity, index, bounds);
}
@Inject
@Override
public Widget getChild(int index)
{
RSWidget[] widgets = getChildren();
if (widgets == null || widgets[index] == null)
{
return null;
}
return widgets[index];
}
@Inject
@Override
public Widget[] getDynamicChildren()
{
RSWidget[] children = getChildren();
if (children == null)
{
return new Widget[0];
}
List<Widget> widgets = new ArrayList<Widget>();
for (Widget widget : children)
{
if (widget != null && widget.getParentId() == getId())
{
widgets.add(widget);
}
}
return widgets.toArray(new Widget[widgets.size()]);
}
@Inject
@Override
public Widget[] getStaticChildren()
{
List<Widget> widgets = new ArrayList<Widget>();
for (Widget widget : client.getGroup(TO_GROUP(getId())))
{
if (widget != null && widget.getParentId() == getId())
{
widgets.add(widget);
}
}
return widgets.toArray(new Widget[widgets.size()]);
}
@Inject
@Override
public Widget[] getNestedChildren()
{
RSHashTable componentTable = client.getComponentTable();
int group = -1;
// XXX can actually use hashtable lookup instead of table
// iteration here...
for (Node node : componentTable.getNodes())
{
WidgetNode wn = (WidgetNode) node;
if (wn.getHash() == getId())
{
group = wn.getId();
break;
}
}
if (group == -1)
{
return new Widget[0];
}
List<Widget> widgets = new ArrayList<Widget>();
for (Widget widget : client.getGroup(group))
{
if (widget != null && widget.getParentId() == getId())
{
widgets.add(widget);
}
}
return widgets.toArray(new Widget[widgets.size()]);
}
}

View File

@@ -0,0 +1,165 @@
/*
* 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 java.awt.Graphics2D;
import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
import net.runelite.api.Model;
import net.runelite.api.Perspective;
import net.runelite.api.Point;
import net.runelite.api.TileObject;
import net.runelite.api.model.Jarvis;
import net.runelite.api.model.Vertex;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.api.mixins.Mixins;
import net.runelite.api.mixins.Shadow;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSDecorativeObject;
import net.runelite.rs.api.RSGameObject;
import net.runelite.rs.api.RSGroundObject;
import net.runelite.rs.api.RSItemLayer;
import net.runelite.rs.api.RSWallObject;
@Mixins({
@Mixin(RSDecorativeObject.class),
@Mixin(RSGameObject.class),
@Mixin(RSGroundObject.class),
@Mixin(RSItemLayer.class),
@Mixin(RSWallObject.class)
})
public abstract class TileObjectMixin implements TileObject
{
@Shadow("clientInstance")
private static RSClient client;
@Override
@Inject
public int getId()
{
int hash = getHash();
return hash >> 14 & 32767;
}
@Override
@Inject
public Point getWorldLocation()
{
Point localLocation = getLocalLocation();
return Perspective.localToWorld(client, localLocation);
}
@Override
@Inject
public Point getLocalLocation()
{
return new Point(getX(), getY());
}
@Override
@Inject
public Point getCanvasLocation()
{
Point locaLocation = getLocalLocation();
return Perspective.worldToCanvas(client, locaLocation.getX(), locaLocation.getY(), 0);
}
@Override
@Inject
public Polygon getCanvasTilePoly()
{
return Perspective.getCanvasTilePoly(client, getLocalLocation());
}
@Override
@Inject
public Point getCanvasTextLocation(Graphics2D graphics, String text, int zOffset)
{
return Perspective.getCanvasTextLocation(client, graphics, getLocalLocation(), text, zOffset);
}
@Override
@Inject
public Point getMinimapLocation()
{
return Perspective.worldToMiniMap(client, getX(), getY());
}
@Override
@Inject
public Polygon getConvexHull(Model model, int orientation)
{
int localX = getX();
int localY = getY();
// models are orientated north (1024) and there are 2048 angles total
orientation = (orientation + 1024) % 2048;
List<Vertex> verticies = model.getVertices();
if (orientation != 0)
{
// rotate verticies
for (int i = 0; i < verticies.size(); ++i)
{
Vertex v = verticies.get(i);
verticies.set(i, v.rotate(orientation));
}
}
List<Point> points = new ArrayList<Point>();
for (Vertex v : verticies)
{
// Compute canvas location of vertex
Point p = Perspective.worldToCanvas(client,
localX - v.getX(),
localY - v.getZ(),
-v.getY());
if (p != null)
{
points.add(p);
}
}
// Run Jarvis march algorithm
points = Jarvis.convexHull(points);
if (points == null)
{
return null;
}
// Convert to a polygon
Polygon p = new Polygon();
for (Point point : points)
{
p.addPoint(point.getX(), point.getY());
}
return p;
}
}