Merge pull request #2892 from open-osrs/actually-up-to-date-now

We are actually up to date now
This commit is contained in:
Tyler Bochard
2021-01-04 04:13:08 -08:00
committed by GitHub
87 changed files with 1986 additions and 294 deletions

View File

@@ -31,6 +31,9 @@ tasks.register<JavaExec>("inject") {
main = "com.openosrs.injector.Injector"
classpath = sourceSets["main"].runtimeClasspath
args(vanillaDep.singleFile, openosrsVersion)
outputs.upToDateWhen {
false
}
}
tasks {

View File

@@ -118,9 +118,9 @@ public class RSApiInjector extends AbstractInjector
final Signature sig = apiMethod.getSignature();
if (sig.isVoid())
if (sig.size() == 1)
{
if (sig.size() == 1)
if (sig.isVoid() || sig.getReturnValue().equals(Type.fromAsmString(apiMethod.getClazz().getName())))
{
Type type = InjectUtil.apiToDeob(inject, sig.getTypeOfArg(0));
if (deobType.equals(type))
@@ -276,7 +276,7 @@ public class RSApiInjector extends AbstractInjector
final ClassFile targetClass = InjectUtil.vanillaFromApiMethod(inject, apiMethod);
apiMethod.setInjected(true);
if (apiMethod.getSignature().isVoid())
if (apiMethod.getSignature().getArguments().size() == 1)
{
++set;
log.debug("[DEBUG] Injecting setter {} for {} into {}", apiMethod.getMethod(), field.getPoolField(), targetClass.getPoolClass());

View File

@@ -102,7 +102,15 @@ public class InjectSetter
ins.add(new PutField(instructions, field));
}
ins.add(new VReturn(instructions));
if (!apiMethod.getSignature().getReturnValue().equals(Type.VOID))
{
ins.add(new ALoad(instructions, 0));
ins.add(InjectUtil.createReturnForType(instructions, apiMethod.getSignature().getReturnValue()));
}
else
{
ins.add(new VReturn(instructions));
}
targetClass.addMethod(method);
}

View File

@@ -526,6 +526,16 @@ public interface Client extends GameShell
@Nullable
Widget getWidget(int groupId, int childId);
/**
* Gets a widget by it's packed ID.
*
* <p>
* Note: Use {@link #getWidget(WidgetInfo)} or {@link #getWidget(int, int)} for
* a more readable version of this method.
*/
@Nullable
Widget getWidget(int packedID);
/**
* Gets an array containing the x-axis canvas positions
* of all widgets.
@@ -784,6 +794,15 @@ public interface Client extends GameShell
*/
void setVarbit(Varbits varbit, int value);
/**
* Gets the varbit composition for a given varbit id
*
* @param id
* @return
*/
@Nullable
VarbitComposition getVarbit(int id);
/**
* Gets the value of a given variable.
*
@@ -817,10 +836,11 @@ public interface Client extends GameShell
void setVarbitValue(int[] varps, int varbit, int value);
/**
* Gets the varbit composition for a given varbit id
* Mark the given varp as changed, causing var listeners to be
* triggered next tick
* @param varp
*/
@Nullable
VarbitComposition getVarbitDefinition(int id);
void queueChangedVarp(int varp);
/**
* Gets the widget flags table.
@@ -898,16 +918,6 @@ public interface Client extends GameShell
*/
IterableHashTable<MessageNode> getMessages();
/**
* Gets the viewport widget.
* <p>
* The viewport is the area of the game above the chatbox
* and to the left of the mini-map.
*
* @return the viewport widget
*/
Widget getViewportWidget();
/**
* Gets the object composition corresponding to an objects ID.
*
@@ -926,6 +936,18 @@ public interface Client extends GameShell
*/
NPCComposition getNpcDefinition(int npcId);
/**
* Gets the {@link StructComposition} for a given struct ID
*
* @see StructID
*/
StructComposition getStructComposition(int structID);
/**
* Gets the client's cache of in memory struct compositions
*/
NodeCache getStructCompositionCache();
/**
* Gets an array of all world areas
*
@@ -1017,6 +1039,18 @@ public interface Client extends GameShell
*/
List<GraphicsObject> getGraphicsObjects();
/**
* Gets the music volume
* @return volume 0-255 inclusive
*/
int getMusicVolume();
/**
* Sets the music volume
* @param volume 0-255 inclusive
*/
void setMusicVolume(int volume);
/**
* Play a sound effect at the player's current location. This is how UI,
* and player-generated (e.g. mining, woodcutting) sound effects are
@@ -1160,6 +1194,20 @@ public interface Client extends GameShell
*/
String[] getStringStack();
/**
* Gets the cs2 vm's active widget
*
* This is used for all {@code cc_*} operations with a {@code 0} operand
*/
Widget getScriptActiveWidget();
/**
* Gets the cs2 vm's "dot" widget
*
* This is used for all {@code .cc_*} operations with a {@code 1} operand
*/
Widget getScriptDotWidget();
/**
* Checks whether a player is on the friends list.
*
@@ -1329,11 +1377,21 @@ public interface Client extends GameShell
* <p>
* This method must be ran on the client thread and is not reentrant
*
* This method is shorthand for {@code client.createScriptEvent(args).run()}
*
* @param args the script id, then any additional arguments to execute the script with
* @see ScriptID
*/
void runScript(Object... args);
/**
* Creates a blank ScriptEvent for executing a ClientScript2 script
*
* @param args the script id, then any additional arguments to execute the script with
* @see ScriptID
*/
ScriptEvent createScriptEvent(Object ...args);
/**
* Checks whether or not there is any active hint arrow.
*
@@ -2063,16 +2121,4 @@ public interface Client extends GameShell
void setOutdatedScript(String outdatedScript);
List<String> getOutdatedScripts();
void queueChangedVarp(int varp);
VarbitComposition getVarbit(int id);
Widget getWidget(int param1);
Widget getScriptActiveWidget();
ScriptEvent createScriptEvent(Object[] args);
int getViewportColor();
}

View File

@@ -5,7 +5,7 @@ import javax.annotation.Nullable;
/**
* Represents the template of a specific item type.
*/
public interface ItemComposition
public interface ItemComposition extends ParamHolder
{
/**
* Gets the items name.

View File

@@ -27,4 +27,5 @@ package net.runelite.api;
public interface IterableHashTable<T extends Node> extends Iterable<T>
{
T get(long hash);
void put(T node, long hash);
}

View File

@@ -27,7 +27,7 @@ package net.runelite.api;
/**
* Information about a specific {@link NpcID}
*/
public interface NPCComposition
public interface NPCComposition extends ParamHolder
{
/**
* Gets the name of the NPC.

View File

@@ -27,7 +27,7 @@ package net.runelite.api;
/**
* Information about a specific {@link ObjectID}
*/
public interface ObjectComposition
public interface ObjectComposition extends ParamHolder
{
/**
* Gets ID for the object.

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2020 Abex
* 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;
/**
* A composition that can hold `param` keys. This lets Jagex attach arbitrary constant
* data to certain items, objects, npcs, or structs for use in cs2
*
* @see ParamID
*/
public interface ParamHolder
{
IterableHashTable<Node> getParams();
void setParams(IterableHashTable<Node> params);
/**
* Gets the value of a given {@link ParamID}, or its default if it is unset
*/
int getIntValue(int paramID);
/**
* Sets the value of a given {@link ParamID}
*/
void setValue(int paramID, int value);
/**
* Gets the value of a given {@link ParamID}, or its default if it is unset
*/
String getStringValue(int paramID);
/**
* Sets the value of a given {@link ParamID}
*/
void setValue(int paramID, String value);
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2020 Abex
* 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;
/**
* @see ParamHolder
*/
public class ParamID
{
/**
* @see SettingID
*/
public static final int SETTING_ID = 1077;
// defaults to 5
// 1 is continuous
public static final int SETTING_SLIDER_STEPS = 1101;
public static final int SETTING_CUSTOM_TRANSMIT = 1085;
// defaults to true
// track is foreground
public static final int SETTING_FOREGROUND_CLICKZONE = 1105;
public static final int SETTING_SLIDER_CUSTOM_ONOP = 1106;
public static final int SETTING_SLIDER_CUSTOM_SETPOS = 1107;
public static final int SETTING_SLIDER_IS_DRAGGABLE = 1108;
public static final int SETTING_SLIDER_DEADZONE = 1109;
public static final int SETTING_SLIDER_DEADTIME = 1110;
}

View File

@@ -43,15 +43,27 @@ public interface Preferences
*/
void setRememberedUsername(String username);
/**
* Gets the sound effect volume
* @return volume 0-127 inclusive
*/
int getSoundEffectVolume();
void setSoundEffectVolume(int i);
/**
* Sets the sound effect volume
* @param volume 0-127 inclusive
*/
void setSoundEffectVolume(int volume);
/**
* Gets the area sound effect volume
* @return volume 0-127 inclusive
*/
int getAreaSoundEffectVolume();
void setAreaSoundEffectVolume(int i);
int getMusicVolume();
void setClientMusicVolume(int i);
/**
* Sets the area sound effect volume
* @param volume 0-127 inclusive
*/
void setAreaSoundEffectVolume(int volume);
}

View File

@@ -348,6 +348,20 @@ public final class ScriptID
@ScriptArguments()
public static final int BANKMAIN_SEARCHING = 514;
/**
* Chooses the click handler for a {@link ParamID#SETTING_SLIDER_CUSTOM_ONOP} = 1 settings slider
*
* The active widget is set to the track created by {@link ParamID#SETTING_FOREGROUND_CLICKZONE}
* <ul>
* <li>int {@link ParamID#SETTING_ID}</li>
* <li>int (WidgetID) Slider handle ID</li>
* <li>int (widget index) Slider handle index</li>
* <li>int track width</li>
* <li>int y offset</li>
* <li>int x offset</li>
* <li>int (WidgetID) drag parent</li>
* </ul>
*/
@ScriptArguments(integer = 7)
public static final int SETTINGS_SLIDER_CHOOSE_ONOP = 3885;

View File

@@ -1596,4 +1596,8 @@ public final class SpriteID
public static final int FRIENDS_CHAT_RANK_TRIPLE_CHEVRON_SERGEANT = 2831;
public static final int FRIENDS_CHAT_RANK_DOUBLE_CHEVRON_CORPORAL = 2832;
public static final int FRIENDS_CHAT_RANK_SINGLE_CHEVRON_RECRUIT = 2833;
public static final int SETTINGS_SLIDER_HANDLE_BLUE = 2858;
public static final int SETTINGS_SLIDER_HANDLE_RED = 2859;
public static final int SETTINGS_SLIDER_HANDLE_GREEN = 2860;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020 Abex
* 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;
/**
* A config type dedicated to holding params.
*
* Historically items were often used for this before structs were made
* available, and there are many of these still around.
*
* @see ParamHolder
*/
public interface StructComposition extends ParamHolder
{
int getId();
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 Abex
* 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;
/**
* @see StructComposition
* @see Client#getStructComposition(int)
*/
public class StructID
{
public static final int SETTINGS_MUSIC_VOLUME = 2753;
public static final int SETTINGS_EFFECT_VOLUME = 2754;
public static final int SETTINGS_AREA_VOLUME = 2755;
}

View File

@@ -784,6 +784,13 @@ public enum Varbits
LEAGUE_RELIC_5(10053),
LEAGUE_RELIC_6(11696),
/**
* Muted volume restore values
*/
MUTED_MUSIC_VOLUME(9666),
MUTED_SOUND_EFFECT_VOLUME(9674),
MUTED_AREA_EFFECT_VOLUME(9675),
/**
* Whether the Special Attack orb is disabled due to being in a PvP area
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Adam <Adam@sigterm.info>
* Copyright (c) 2020 Abex
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,21 +24,18 @@
*/
package net.runelite.api.events;
import net.runelite.api.widgets.Widget;
import lombok.Data;
import net.runelite.api.StructComposition;
/**
* An event where the hidden state of a {@link Widget} has been modified.
* An event called after a new {@link StructComposition} is created and
* its data is initialized.
*/
@Data
public class WidgetHiddenChanged implements Event
public class PostStructComposition
{
/**
* The affected widget.
* The newly created struct.
*/
private Widget widget;
/**
* The new hidden state of the widget.
*/
private boolean hidden;
}
private StructComposition structComposition;
}

View File

@@ -72,9 +72,6 @@ public interface Callbacks
*/
void drawAboveOverheads();
void drawLayer(Widget layer, List<WidgetItem> widgetItems);
void drawInterface(int interfaceId, List<WidgetItem> widgetItems);
/**
* Client top-most draw method, rendering over top of most of game interfaces.
*
@@ -85,6 +82,20 @@ public interface Callbacks
*/
void draw(MainBufferProvider mainBufferProvider, Graphics graphics, int x, int y);
/**
* Called after an interface has been drawn
* @param interfaceId the interface id
* @param widgetItems Widget items within the interface
*/
void drawInterface(int interfaceId, List<WidgetItem> widgetItems);
/**
* Called after a widget layer has been drawn
* @param layer The layer
* @param widgetItems Widget items within the layer
*/
void drawLayer(Widget layer, List<WidgetItem> widgetItems);
/**
* Mouse pressed event. If this event will be consumed it will not be propagated further to client.
*

View File

@@ -70,6 +70,10 @@ public interface Widget
int getButtonType();
boolean isWidgetItemDragged(int index);
Point getWidgetItemDragOffsets();
/**
* Gets the type of content displayed by the widget.
*/
@@ -1017,13 +1021,34 @@ public interface Widget
*/
void setOnReleaseListener(Object ...args);
boolean isWidgetItemDragged(int index);
/**
* Sets a script to be ran when a drag operation is finished on this widget
*
* @param args A ScriptID, then the args for the script
*/
void setOnDragCompleteListener(Object ...args);
Point getWidgetItemDragOffsets();
/**
* Sets a script to be ran when this widget moves due to a drag
*
* @param args A ScriptID, then the args for the script
*/
void setOnDragListener(Object ...args);
static boolean getDragParent(Widget widget)
{
System.out.println("ERROR: IMPLEMENT"); //Would throw but that breaks widget inspector
return false;
}
/**
* Container this can be dragged in
*/
Widget getDragParent();
/**
* Container this can be dragged in
*/
void setDragParent(Widget dragParent);
/**
* Sets a script to be ran when a varplayer changes
*
* @param args A ScriptID, then the args for the script
*/
void setOnVarTransmitListener(Object ...args);
}

View File

@@ -888,6 +888,12 @@ public enum WidgetInfo
SEED_VAULT_ITEM_CONTAINER(WidgetID.SEED_VAULT_GROUP_ID, WidgetID.SeedVault.ITEM_CONTAINER),
SEED_VAULT_ITEM_TEXT(WidgetID.SEED_VAULT_GROUP_ID, WidgetID.SeedVault.ITEM_TEXT),
SEED_VAULT_INVENTORY_ITEMS_CONTAINER(WidgetID.SEED_VAULT_INVENTORY_GROUP_ID, WidgetID.SeedVault.INVENTORY_ITEM_CONTAINER),
SETTINGS_SIDE_CAMERA_ZOOM_SLIDER_TRACK(WidgetID.SETTINGS_SIDE_GROUP_ID, WidgetID.SettingsSide.CAMERA_ZOOM_SLIDER_TRACK),
SETTINGS_SIDE_MUSIC_SLIDER(WidgetID.SETTINGS_SIDE_GROUP_ID, WidgetID.SettingsSide.MUSIC_SLIDER),
SETTINGS_SIDE_SOUND_EFFECT_SLIDER(WidgetID.SETTINGS_SIDE_GROUP_ID, WidgetID.SettingsSide.SOUND_EFFECT_SLIDER),
SETTINGS_SIDE_AREA_SOUND_SLIDER(WidgetID.SETTINGS_SIDE_GROUP_ID, WidgetID.SettingsSide.AREA_SOUND_SLIDER),
JEWELLERY_BOX_DUEL_RING(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.DUEL_RING),
JEWELLERY_BOX_GAME_NECK(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.GAME_NECK),
JEWELLERY_BOX_COMB_BRAC(WidgetID.JEWELLERY_BOX_GROUP_ID, WidgetID.JewelBox.COMB_BRAC),
@@ -921,7 +927,6 @@ public enum WidgetInfo
HEALTH_OVERLAY_BAR(WidgetID.HEALTH_OVERLAY_BAR_GROUP_ID, WidgetID.EncounterHealthBar.CONTAINER),
SETTINGS_INIT(WidgetID.SETTINGS_GROUP_ID, WidgetID.Settings.INIT),
SETTINGS_SIDE_CAMERA_ZOOM_SLIDER_TRACK(WidgetID.SETTINGS_SIDE_GROUP_ID, WidgetID.SettingsSide.CAMERA_ZOOM_SLIDER_TRACK),
TRAILBLAZER_AREA_TELEPORT(WidgetID.TRAILBLAZER_AREAS_GROUP_ID, WidgetID.TrailblazerAreas.TELEPORT),
;

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) 2019, 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.client.plugins.music;
import net.runelite.client.config.Config;
import net.runelite.client.config.ConfigGroup;
import net.runelite.client.config.ConfigItem;
@ConfigGroup("music")
public interface MusicConfig extends Config
{
String GRANULAR_SLIDERS = "granularSliders";
@ConfigItem(
keyName = "muteOwnAreaSounds",
name = "Mute player area sounds",
description = "Mute area sounds caused by yourself",
position = 0
)
default boolean muteOwnAreaSounds()
{
return false;
}
@ConfigItem(
keyName = "muteOtherAreaSounds",
name = "Mute other players' area sounds",
description = "Mute area sounds caused by other players",
position = 1
)
default boolean muteOtherAreaSounds()
{
return false;
}
@ConfigItem(
keyName = "muteOtherAreaNPCSounds",
name = "Mute NPCs' area sounds",
description = "Mute area sounds caused by NPCs",
position = 2
)
default boolean muteNpcAreaSounds()
{
return false;
}
@ConfigItem(
keyName = "muteOtherAreaEnvironmentSounds",
name = "Mute environment area sounds",
description = "Mute area sounds caused by neither NPCs nor players",
position = 3
)
default boolean muteEnvironmentAreaSounds()
{
return false;
}
@ConfigItem(
keyName = "mutePrayerSounds",
name = "Mute prayer sounds",
description = "Mute prayer activation and deactivation sounds",
position = 4
)
default boolean mutePrayerSounds()
{
return false;
}
@ConfigItem(
keyName = GRANULAR_SLIDERS,
name = "Granular volume sliders",
description = "Make the volume sliders allow better control of volume",
position = 5
)
default boolean granularSliders()
{
return true;
}
@ConfigItem(
keyName = "musicVolume",
name = "",
description = "",
hidden = true
)
default int getMusicVolume()
{
return 0;
}
@ConfigItem(
keyName = "musicVolume",
name = "",
description = "",
hidden = true
)
void setMusicVolume(int vol);
@ConfigItem(
keyName = "soundEffectVolume",
name = "",
description = "",
hidden = true
)
default int getSoundEffectVolume()
{
return 0;
}
@ConfigItem(
keyName = "soundEffectVolume",
name = "",
description = "",
hidden = true
)
void setSoundEffectVolume(int val);
@ConfigItem(
keyName = "areaSoundEffectVolume",
name = "",
description = "",
hidden = true
)
default int getAreaSoundEffectVolume()
{
return 0;
}
@ConfigItem(
keyName = "areaSoundEffectVolume",
name = "",
description = "",
hidden = true
)
void setAreaSoundEffectVolume(int vol);
}

View File

@@ -0,0 +1,927 @@
/*
* Copyright (c) 2019, Anthony Chen <https://github.com/achencoms>
* Copyright (c) 2019, Adam <Adam@sigterm.info>
* Copyright (c) 2020, Sean Dewar <https://github.com/seandewar>
* 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.client.plugins.music;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import com.google.inject.Provides;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.stream.Collectors;
import javax.inject.Inject;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Actor;
import net.runelite.api.Client;
import net.runelite.api.GameState;
import net.runelite.api.NPC;
import net.runelite.api.ParamID;
import net.runelite.api.Player;
import net.runelite.api.Preferences;
import net.runelite.api.ScriptEvent;
import net.runelite.api.ScriptID;
import net.runelite.api.SettingID;
import net.runelite.api.SoundEffectID;
import net.runelite.api.SpriteID;
import net.runelite.api.StructComposition;
import net.runelite.api.StructID;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarPlayer;
import net.runelite.api.Varbits;
import net.runelite.api.events.AreaSoundEffectPlayed;
import net.runelite.api.events.BeforeRender;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.events.PostStructComposition;
import net.runelite.api.events.ScriptPreFired;
import net.runelite.api.events.SoundEffectPlayed;
import net.runelite.api.events.VarClientIntChanged;
import net.runelite.api.events.VolumeChanged;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetID;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.api.widgets.WidgetPositionMode;
import net.runelite.api.widgets.WidgetType;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.game.chatbox.ChatboxPanelManager;
import net.runelite.client.game.chatbox.ChatboxTextInput;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.ui.overlay.tooltip.Tooltip;
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
@Slf4j
@PluginDescriptor(
name = "Music",
description = "Adds search and filter for the music list, and additional volume control",
tags = {"sound", "volume"}
)
public class MusicPlugin extends Plugin
{
private static final int SLIDER_HANDLE_SIZE = 16;
private static final Set<Integer> SOURCELESS_PLAYER_SOUNDS = ImmutableSet.of(
SoundEffectID.TELEPORT_VWOOP
);
private static final Set<Integer> PRAYER_SOUNDS = ImmutableSet.of(
SoundEffectID.PRAYER_ACTIVATE_THICK_SKIN,
SoundEffectID.PRAYER_ACTIVATE_BURST_OF_STRENGTH,
SoundEffectID.PRAYER_ACTIVATE_CLARITY_OF_THOUGHT,
SoundEffectID.PRAYER_ACTIVATE_SHARP_EYE_RIGOUR,
SoundEffectID.PRAYER_ACTIVATE_MYSTIC_WILL_AUGURY,
SoundEffectID.PRAYER_ACTIVATE_ROCK_SKIN,
SoundEffectID.PRAYER_ACTIVATE_SUPERHUMAN_STRENGTH,
SoundEffectID.PRAYER_ACTIVATE_IMPROVED_REFLEXES,
SoundEffectID.PRAYER_ACTIVATE_RAPID_RESTORE_PRESERVE,
SoundEffectID.PRAYER_ACTIVATE_RAPID_HEAL,
SoundEffectID.PRAYER_ACTIVATE_PROTECT_ITEM,
SoundEffectID.PRAYER_ACTIVATE_HAWK_EYE,
SoundEffectID.PRAYER_ACTIVATE_MYSTIC_LORE,
SoundEffectID.PRAYER_ACTIVATE_STEEL_SKIN,
SoundEffectID.PRAYER_ACTIVATE_ULTIMATE_STRENGTH,
SoundEffectID.PRAYER_ACTIVATE_INCREDIBLE_REFLEXES,
SoundEffectID.PRAYER_ACTIVATE_PROTECT_FROM_MAGIC,
SoundEffectID.PRAYER_ACTIVATE_PROTECT_FROM_MISSILES,
SoundEffectID.PRAYER_ACTIVATE_PROTECT_FROM_MELEE,
SoundEffectID.PRAYER_ACTIVATE_EAGLE_EYE,
SoundEffectID.PRAYER_ACTIVATE_MYSTIC_MIGHT,
SoundEffectID.PRAYER_ACTIVATE_RETRIBUTION,
SoundEffectID.PRAYER_ACTIVATE_REDEMPTION,
SoundEffectID.PRAYER_ACTIVATE_SMITE,
SoundEffectID.PRAYER_ACTIVATE_CHIVALRY,
SoundEffectID.PRAYER_ACTIVATE_PIETY,
SoundEffectID.PRAYER_DEACTIVE_VWOOP
);
@Inject
private Client client;
@Inject
private ClientThread clientThread;
@Inject
private MusicConfig musicConfig;
@Inject
private ChatboxPanelManager chatboxPanelManager;
@Inject
private TooltipManager tooltipManager;
private Channel musicChannel;
private Channel effectChannel;
private Channel areaChannel;
private Channel[] channels;
private ChatboxTextInput searchInput;
private Widget musicSearchButton;
private Widget musicFilterButton;
private Collection<Widget> tracks;
private MusicState currentMusicFilter = MusicState.ALL;
private Tooltip sliderTooltip;
private boolean shuttingDown = false;
@Override
protected void startUp()
{
clientThread.invoke(() ->
{
this.shuttingDown = false;
Preferences preferences = client.getPreferences();
musicChannel = new Channel("Music",
VarPlayer.MUSIC_VOLUME, Varbits.MUTED_MUSIC_VOLUME,
musicConfig::getMusicVolume, musicConfig::setMusicVolume,
client::setMusicVolume, 255,
WidgetInfo.SETTINGS_SIDE_MUSIC_SLIDER);
effectChannel = new Channel("Sound Effects",
VarPlayer.SOUND_EFFECT_VOLUME, Varbits.MUTED_SOUND_EFFECT_VOLUME,
musicConfig::getSoundEffectVolume, musicConfig::setSoundEffectVolume,
preferences::setSoundEffectVolume, 127,
WidgetInfo.SETTINGS_SIDE_SOUND_EFFECT_SLIDER);
areaChannel = new Channel("Area Sounds",
VarPlayer.AREA_EFFECT_VOLUME, Varbits.MUTED_AREA_EFFECT_VOLUME,
musicConfig::getAreaSoundEffectVolume, musicConfig::setAreaSoundEffectVolume,
preferences::setAreaSoundEffectVolume, 127,
WidgetInfo.SETTINGS_SIDE_AREA_SOUND_SLIDER);
channels = new Channel[]{musicChannel, effectChannel, areaChannel};
addMusicButtons();
updateMusicOptions();
resetSettingsWindow();
});
}
@Override
protected void shutDown()
{
Widget header = client.getWidget(WidgetInfo.MUSIC_WINDOW);
if (header != null)
{
header.deleteAllChildren();
}
tracks = null;
clientThread.invoke(() ->
{
shuttingDown = true;
teardownMusicOptions();
});
}
@Provides
MusicConfig getConfig(ConfigManager configManager)
{
return configManager.getConfig(MusicConfig.class);
}
@Subscribe
public void onGameStateChanged(GameStateChanged gameStateChanged)
{
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN)
{
// Reset music filter on logout
currentMusicFilter = MusicState.ALL;
tracks = null;
}
}
@Subscribe
public void onWidgetLoaded(WidgetLoaded widgetLoaded)
{
if (widgetLoaded.getGroupId() == WidgetID.MUSIC_GROUP_ID)
{
tracks = null;
// Reset filter state as the widget has been reloaded.
// It is too early here to call updateFilter()
currentMusicFilter = MusicState.ALL;
addMusicButtons();
}
if ((widgetLoaded.getGroupId() == WidgetID.SETTINGS_GROUP_ID || widgetLoaded.getGroupId() == WidgetID.SETTINGS_SIDE_GROUP_ID)
&& musicConfig.granularSliders())
{
updateMusicOptions();
}
}
private void addMusicButtons()
{
Widget header = client.getWidget(WidgetInfo.MUSIC_WINDOW);
if (header == null)
{
return;
}
header.deleteAllChildren();
//Creation of the search and toggle status buttons
musicSearchButton = header.createChild(-1, WidgetType.GRAPHIC);
musicSearchButton.setSpriteId(SpriteID.GE_SEARCH);
musicSearchButton.setOriginalWidth(18);
musicSearchButton.setOriginalHeight(17);
musicSearchButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT);
musicSearchButton.setOriginalX(5);
musicSearchButton.setOriginalY(32);
musicSearchButton.setHasListener(true);
musicSearchButton.setAction(1, "Open");
musicSearchButton.setOnOpListener((JavaScriptCallback) e -> openSearch());
musicSearchButton.setName("Search");
musicSearchButton.revalidate();
musicFilterButton = header.createChild(-1, WidgetType.GRAPHIC);
musicFilterButton.setSpriteId(SpriteID.MINIMAP_ORB_PRAYER);
musicFilterButton.setOriginalWidth(15);
musicFilterButton.setOriginalHeight(15);
musicFilterButton.setXPositionMode(WidgetPositionMode.ABSOLUTE_RIGHT);
musicFilterButton.setOriginalX(25);
musicFilterButton.setOriginalY(34);
musicFilterButton.setHasListener(true);
musicFilterButton.setAction(1, "Toggle");
musicFilterButton.setOnOpListener((JavaScriptCallback) e -> toggleStatus());
musicFilterButton.setName("All");
musicFilterButton.revalidate();
}
@Subscribe
public void onVarClientIntChanged(VarClientIntChanged varClientIntChanged)
{
if (isChatboxOpen() && !isOnMusicTab())
{
chatboxPanelManager.close();
}
}
@Subscribe
public void onVolumeChanged(VolumeChanged volumeChanged)
{
if (musicConfig.granularSliders())
{
updateMusicOptions();
}
}
@Subscribe
public void onConfigChanged(ConfigChanged configChanged)
{
if ("music".equals(configChanged.getGroup()))
{
clientThread.invoke(() ->
{
if (MusicConfig.GRANULAR_SLIDERS.equals(configChanged.getKey()))
{
if (musicConfig.granularSliders())
{
updateMusicOptions();
resetSettingsWindow();
}
else
{
teardownMusicOptions();
}
}
else
{
updateMusicOptions();
}
});
}
}
private boolean isOnMusicTab()
{
return client.getVar(VarClientInt.INVENTORY_TAB) == 13;
}
private boolean isChatboxOpen()
{
return searchInput != null && chatboxPanelManager.getCurrentInput() == searchInput;
}
private String getChatboxInput()
{
return isChatboxOpen() ? searchInput.getValue() : "";
}
private void toggleStatus()
{
MusicState[] states = MusicState.values();
currentMusicFilter = states[(currentMusicFilter.ordinal() + 1) % states.length];
musicFilterButton.setSpriteId(currentMusicFilter.getSpriteID());
musicFilterButton.setName(currentMusicFilter.getName());
updateFilter(getChatboxInput());
client.playSoundEffect(SoundEffectID.UI_BOOP);
}
private void openSearch()
{
updateFilter("");
client.playSoundEffect(SoundEffectID.UI_BOOP);
musicSearchButton.setAction(1, "Close");
musicSearchButton.setOnOpListener((JavaScriptCallback) e -> closeSearch());
searchInput = chatboxPanelManager.openTextInput("Search music list")
.onChanged(s -> clientThread.invokeLater(() -> updateFilter(s.trim())))
.onDone(s -> false)
.onClose(() ->
{
clientThread.invokeLater(() -> updateFilter(""));
musicSearchButton.setOnOpListener((JavaScriptCallback) e -> openSearch());
musicSearchButton.setAction(1, "Open");
})
.build();
}
private void closeSearch()
{
updateFilter("");
chatboxPanelManager.close();
client.playSoundEffect(SoundEffectID.UI_BOOP);
}
private void updateFilter(String input)
{
final Widget container = client.getWidget(WidgetInfo.MUSIC_WINDOW);
final Widget musicList = client.getWidget(WidgetInfo.MUSIC_TRACK_LIST);
if (container == null || musicList == null)
{
return;
}
String filter = input.toLowerCase();
updateList(musicList, filter);
}
private void updateList(Widget musicList, String filter)
{
if (tracks == null)
{
tracks = Arrays.stream(musicList.getDynamicChildren())
.sorted(Comparator.comparing(Widget::getRelativeY))
.collect(Collectors.toList());
}
tracks.forEach(w -> w.setHidden(true));
Collection<Widget> relevantTracks = tracks.stream()
.filter(w -> w.getText().toLowerCase().contains(filter))
.filter(w -> currentMusicFilter == MusicState.ALL || w.getTextColor() == currentMusicFilter.getColor())
.collect(Collectors.toList());
// Original music track list has a little offset
int y = 3;
for (Widget track : relevantTracks)
{
track.setHidden(false);
track.setOriginalY(y);
track.revalidate();
y += track.getHeight();
}
y += 3;
int newHeight = 0;
if (musicList.getScrollHeight() > 0)
{
newHeight = (musicList.getScrollY() * y) / musicList.getScrollHeight();
}
musicList.setScrollHeight(y);
musicList.revalidateScroll();
client.runScript(
ScriptID.UPDATE_SCROLLBAR,
WidgetInfo.MUSIC_TRACK_SCROLLBAR.getId(),
WidgetInfo.MUSIC_TRACK_LIST.getId(),
newHeight
);
}
@AllArgsConstructor
@Getter
private enum MusicState
{
NOT_FOUND(0xff0000, "Locked", SpriteID.MINIMAP_ORB_HITPOINTS),
FOUND(0xdc10d, "Unlocked", SpriteID.MINIMAP_ORB_HITPOINTS_POISON),
ALL(0, "All", SpriteID.MINIMAP_ORB_PRAYER);
private final int color;
private final String name;
private final int spriteID;
}
@RequiredArgsConstructor
private class Slider
{
@Getter
protected final Channel channel;
protected Widget track;
protected Widget handle;
public void update()
{
handle.setOnDragListener((JavaScriptCallback) this::drag);
handle.setOnDragCompleteListener((JavaScriptCallback) this::drag);
handle.setHasListener(true);
track.setOnMouseRepeatListener((JavaScriptCallback) ev ->
{
int value = channel.getValue();
int percent = (int) Math.round((value * 100.0 / channel.getMax()));
sliderTooltip = new Tooltip(channel.getName() + ": " + percent + "%");
});
track.setOnClickListener((JavaScriptCallback) this::click);
track.setHasListener(true);
}
public void shutDown()
{
if (handle != null)
{
handle.setDragParent(null);
handle.setOnDragListener((Object[]) null);
handle.setOnDragCompleteListener((Object[]) null);
}
if (track != null)
{
track.setOnMouseRepeatListener((Object[]) null);
track.setOnClickListener((Object[]) null);
}
}
protected void drag(ScriptEvent ev)
{
moveHandle(ev.getMouseX());
}
protected void click(ScriptEvent ev)
{
moveHandle(ev.getMouseX() - (SLIDER_HANDLE_SIZE / 2));
}
protected void moveHandle(int x)
{
int level = (x * channel.max) / getWidth();
level = Ints.constrainToRange(level, 0, channel.max);
channel.setLevel(level);
}
protected int getWidth()
{
return track.getWidth() - SLIDER_HANDLE_SIZE;
}
}
private class SettingsSideSlider extends Slider
{
private final WidgetInfo root;
private Widget icon;
SettingsSideSlider(Channel channel, WidgetInfo root)
{
super(channel);
this.root = root;
}
@Override
public void update()
{
Widget root = client.getWidget(this.root);
if (root == null)
{
return;
}
Object[] onLoad = root.getOnLoadListener();
if (onLoad == null || onLoad.length != 5)
{
return;
}
this.icon = client.getWidget((Integer) onLoad[1]);
this.track = client.getWidget((Integer) onLoad[2]);
this.handle = client.getWidget((Integer) onLoad[3]);
if (this.track == null || this.handle == null)
{
return;
}
for (Widget w : track.getChildren())
{
if (w != null)
{
w.setAction(0, null);
}
}
handle.setOnVarTransmitListener((Object[]) null);
handle.setDragParent(track);
handle.setSpriteId(SpriteID.SETTINGS_SLIDER_HANDLE_GREEN);
super.update();
int val = channel.getValue();
handle.setOriginalX((val * getWidth()) / channel.getMax());
handle.revalidate();
// emulate [proc,settings_update_icon]
boolean unmuted = val != 0;
icon.getChild(1).setHidden(unmuted);
icon.setAction(0, unmuted ? "Mute" : "Unmute");
// Set name + no tooltip; we have our own for ops
icon.setName(channel.getName());
icon.setOnMouseRepeatListener((Object[]) null);
icon.setOnOpListener((JavaScriptCallback) ev -> channel.toggleMute());
}
@Override
public void shutDown()
{
super.shutDown();
handle.setSpriteId(SpriteID.SETTINGS_SLIDER_HANDLE_BLUE);
this.icon.setOnOpListener((Object[]) null);
Widget root = client.getWidget(this.root);
if (root != null)
{
client.createScriptEvent(root.getOnLoadListener())
.setSource(root)
.run();
}
this.handle = this.track = this.icon = null;
}
}
private class SettingsSlider extends Slider
{
private final int offsetX;
private final int offsetY;
private final int width;
private final Widget realTrack;
SettingsSlider(Channel channel, Widget handle, Widget track, int width, int offsetY, int offsetX, Widget realTrack)
{
super(channel);
this.handle = handle;
this.track = track;
this.width = width;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.realTrack = realTrack;
}
@Override
public void update()
{
super.update();
int val = channel.getValue();
handle.setOriginalX(offsetX + (val * getWidth()) / channel.getMax());
handle.setOriginalY(offsetY);
handle.revalidate();
}
@Override
protected int getWidth()
{
return width - SLIDER_HANDLE_SIZE;
}
@Override
protected void click(ScriptEvent ev)
{
super.click(ev);
realTrack.setOriginalX(offsetX);
realTrack.setOriginalY(offsetY);
realTrack.setOriginalWidth(this.width);
realTrack.setOriginalHeight(SLIDER_HANDLE_SIZE);
realTrack.revalidate();
}
@Override
@SuppressWarnings("PMD.UselessOverridingMethod")
public void shutDown()
{
// calling settings_init will do teardown for us
super.shutDown();
}
}
@Subscribe
private void onPostStructComposition(PostStructComposition ev)
{
if (shuttingDown)
{
return;
}
StructComposition sc = ev.getStructComposition();
switch (sc.getId())
{
case StructID.SETTINGS_MUSIC_VOLUME:
case StructID.SETTINGS_EFFECT_VOLUME:
case StructID.SETTINGS_AREA_VOLUME:
if (!musicConfig.granularSliders())
{
return;
}
sc.setValue(ParamID.SETTING_SLIDER_STEPS, 1);
sc.setValue(ParamID.SETTING_CUSTOM_TRANSMIT, 0);
sc.setValue(ParamID.SETTING_FOREGROUND_CLICKZONE, 0);
sc.setValue(ParamID.SETTING_SLIDER_CUSTOM_ONOP, 1);
sc.setValue(ParamID.SETTING_SLIDER_CUSTOM_SETPOS, 1);
sc.setValue(ParamID.SETTING_SLIDER_IS_DRAGGABLE, 1);
sc.setValue(ParamID.SETTING_SLIDER_DEADZONE, 0);
sc.setValue(ParamID.SETTING_SLIDER_DEADZONE, 0);
break;
}
}
@Subscribe
private void onScriptPreFired(ScriptPreFired ev)
{
if (shuttingDown)
{
return;
}
if (ev.getScriptId() == ScriptID.SETTINGS_SLIDER_CHOOSE_ONOP)
{
if (!musicConfig.granularSliders())
{
return;
}
int arg = client.getIntStackSize() - 7;
int[] is = client.getIntStack();
Channel channel;
switch (is[arg])
{
case SettingID.MUSIC_VOLUME:
channel = musicChannel;
break;
case SettingID.EFFECT_VOLUME:
channel = effectChannel;
break;
case SettingID.AREA_VOLUME:
channel = areaChannel;
break;
default:
return;
}
Widget track = client.getScriptActiveWidget();
Widget handle = client.getWidget(is[arg + 1])
.getChild(is[arg + 2]);
Widget realTrack = client.getWidget(is[arg + 6]);
SettingsSlider s = new SettingsSlider(channel, handle, track, is[arg + 3], is[arg + 4], is[arg + 5], realTrack);
s.update();
s.getChannel().setWindowSlider(s);
}
}
private class Channel
{
@Getter
private final String name;
private final VarPlayer var;
private final Varbits mutedVar;
private final IntSupplier getter;
private final Consumer<Integer> setter;
private final IntConsumer volumeChanger;
@Getter
private final int max;
private final Slider sideSlider;
@Setter
private Slider windowSlider;
Channel(String name,
VarPlayer var, Varbits mutedVar,
IntSupplier getter, Consumer<Integer> setter,
IntConsumer volumeChanger, int max,
WidgetInfo sideRoot)
{
this.name = name;
this.var = var;
this.mutedVar = mutedVar;
this.getter = getter;
this.setter = setter;
this.volumeChanger = volumeChanger;
this.max = max;
this.sideSlider = new SettingsSideSlider(this, sideRoot);
}
private int getValueRaw()
{
int value = getter.getAsInt();
if (value == 0)
{
// Use the vanilla value
// the varps are known by the engine and it requires they are stored so
// 0 = max and 4 = muted
int raw = 4 - client.getVar(var);
if (raw == 0)
{
raw = -(4 - client.getVar(mutedVar));
}
value = ((raw * max) / 4);
// readd our 1 offset for unknown's place
value += value < 0 ? -1 : 1;
}
return value;
}
private int getValue()
{
int value = getValueRaw();
// muted with saved restore point
if (value < 0)
{
return 0;
}
// 0 is used for unknown, so config values are 1 away from zero
return value - 1;
}
public void toggleMute()
{
int val = -getValueRaw();
if (val == -1)
{
// muted without a reset value
val = max / 2;
}
setter.accept(val);
}
public void setLevel(int level)
{
setter.accept(level + 1);
update();
}
public void update()
{
volumeChanger.accept(getValue());
sideSlider.update();
if (windowSlider != null)
{
windowSlider.update();
}
}
public void shutDown()
{
sideSlider.shutDown();
if (windowSlider != null)
{
windowSlider.shutDown();
}
int raw = 4 - client.getVar(var);
int value = ((raw * max) / 4);
volumeChanger.accept(value);
}
}
private void updateMusicOptions()
{
for (Channel channel : channels)
{
channel.update();
}
}
private void teardownMusicOptions()
{
// the side panel uses this too, so it has to run before they get shut down
client.getStructCompositionCache().reset();
for (Channel channel : channels)
{
channel.shutDown();
}
resetSettingsWindow();
}
private void resetSettingsWindow()
{
client.getStructCompositionCache().reset();
Widget init = client.getWidget(WidgetInfo.SETTINGS_INIT);
if (init != null)
{
// [clientscript, settings_init]
client.createScriptEvent(init.getOnLoadListener())
.setSource(init)
.run();
}
}
@Subscribe
private void onBeforeRender(BeforeRender ev)
{
if (sliderTooltip != null)
{
tooltipManager.add(sliderTooltip);
sliderTooltip = null;
}
}
@Subscribe
public void onAreaSoundEffectPlayed(AreaSoundEffectPlayed areaSoundEffectPlayed)
{
Actor source = areaSoundEffectPlayed.getSource();
int soundId = areaSoundEffectPlayed.getSoundId();
if (source == client.getLocalPlayer()
&& musicConfig.muteOwnAreaSounds())
{
areaSoundEffectPlayed.consume();
}
else if (source != client.getLocalPlayer()
&& (source instanceof Player || (source == null && SOURCELESS_PLAYER_SOUNDS.contains(soundId)))
&& musicConfig.muteOtherAreaSounds())
{
areaSoundEffectPlayed.consume();
}
else if (source instanceof NPC
&& musicConfig.muteNpcAreaSounds())
{
areaSoundEffectPlayed.consume();
}
else if (source == null
&& !SOURCELESS_PLAYER_SOUNDS.contains(soundId)
&& musicConfig.muteEnvironmentAreaSounds())
{
areaSoundEffectPlayed.consume();
}
}
@Subscribe
public void onSoundEffectPlayed(SoundEffectPlayed soundEffectPlayed)
{
if (musicConfig.mutePrayerSounds()
&& PRAYER_SOUNDS.contains(soundEffectPlayed.getSoundId()))
{
soundEffectPlayed.consume();
}
}
}

View File

@@ -0,0 +1,118 @@
package net.runelite.mixins;
import net.runelite.api.ParamHolder;
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.RSIntegerNode;
import net.runelite.rs.api.RSItemComposition;
import net.runelite.rs.api.RSNPCComposition;
import net.runelite.rs.api.RSNode;
import net.runelite.rs.api.RSObjectComposition;
import net.runelite.rs.api.RSObjectNode;
import net.runelite.rs.api.RSParamComposition;
import net.runelite.rs.api.RSStructComposition;
@Mixins({
@Mixin(RSStructComposition.class),
@Mixin(RSObjectComposition.class),
@Mixin(RSNPCComposition.class),
@Mixin(RSItemComposition.class)
})
public abstract class ParamHolderMixin implements ParamHolder
{
@Shadow("client")
private static RSClient client;
@Inject
private RSNode getParam(int id)
{
return this.getParams() == null ? null : (RSNode) this.getParams().get(id);
}
@Inject
private void setParam(int id, RSNode node)
{
RSParamComposition comp = client.getRSParamComposition(id);
if (comp.isString() != (node instanceof RSObjectNode))
{
if (comp.isString())
{
throw new IllegalArgumentException("trying to put int into string param");
}
else
{
throw new IllegalArgumentException("trying to put string into int param");
}
}
else
{
if (getParams() == null)
{
setParams(client.newIterableNodeHashTable(16));
}
getParams().put(node, id);
}
}
@Inject
@Override
public int getIntValue(int paramID)
{
RSNode param = getParam(paramID);
if (param != null)
{
RSIntegerNode node = (RSIntegerNode) param;
return node.getValue();
}
else
{
RSParamComposition comp = client.getRSParamComposition(paramID);
if (comp.isString())
{
throw new IllegalArgumentException("trying to get int from string param");
}
return comp.getDefaultInt();
}
}
@Inject
@Override
public void setValue(int id, int val)
{
setParam(id, client.newIntegerNode(val));
}
@Inject
@Override
public String getStringValue(int paramID)
{
RSNode param = getParam(paramID);
if (param != null)
{
RSObjectNode node = (RSObjectNode) param;
return (String) node.getValue();
}
else
{
RSParamComposition comp = client.getRSParamComposition(paramID);
if (!comp.isString())
{
throw new IllegalArgumentException("trying to get string from int param");
}
return comp.getDefaultStr();
}
}
@Inject
@Override
public void setValue(int id, String val)
{
setParam(id, client.newObjectNode(val));
}
}

View File

@@ -67,17 +67,19 @@ import net.runelite.api.NPC;
import net.runelite.api.NPCComposition;
import net.runelite.api.NameableContainer;
import net.runelite.api.Node;
import net.runelite.api.NodeCache;
import net.runelite.api.ObjectComposition;
import static net.runelite.api.Perspective.LOCAL_TILE_SIZE;
import net.runelite.api.Player;
import net.runelite.api.Point;
import net.runelite.api.Prayer;
import net.runelite.api.Projectile;
import net.runelite.api.ScriptEvent;
import net.runelite.api.Skill;
import net.runelite.api.SpritePixels;
import net.runelite.api.StructComposition;
import net.runelite.api.Tile;
import net.runelite.api.VarPlayer;
import net.runelite.api.VarbitComposition;
import net.runelite.api.Varbits;
import net.runelite.api.WidgetNode;
import net.runelite.api.WorldType;
@@ -101,11 +103,13 @@ import net.runelite.api.events.NpcSpawned;
import net.runelite.api.events.PlayerDespawned;
import net.runelite.api.events.PlayerMenuOptionsChanged;
import net.runelite.api.events.PlayerSpawned;
import net.runelite.api.events.PostStructComposition;
import net.runelite.api.events.ResizeableChanged;
import net.runelite.api.events.StatChanged;
import net.runelite.api.events.UsernameChanged;
import net.runelite.api.events.VarbitChanged;
import net.runelite.api.events.VolumeChanged;
import net.runelite.api.events.WidgetClosed;
import net.runelite.api.events.WidgetLoaded;
import net.runelite.api.events.WorldChanged;
import net.runelite.api.hooks.Callbacks;
@@ -129,6 +133,7 @@ import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSEnumComposition;
import net.runelite.rs.api.RSFriendSystem;
import net.runelite.rs.api.RSIndexedSprite;
import net.runelite.rs.api.RSInterfaceParent;
import net.runelite.rs.api.RSItemContainer;
import net.runelite.rs.api.RSNPC;
import net.runelite.rs.api.RSNode;
@@ -137,7 +142,9 @@ import net.runelite.rs.api.RSNodeHashTable;
import net.runelite.rs.api.RSPacketBuffer;
import net.runelite.rs.api.RSPlayer;
import net.runelite.rs.api.RSScene;
import net.runelite.rs.api.RSScriptEvent;
import net.runelite.rs.api.RSSpritePixels;
import net.runelite.rs.api.RSStructComposition;
import net.runelite.rs.api.RSTile;
import net.runelite.rs.api.RSTileItem;
import net.runelite.rs.api.RSUsername;
@@ -727,24 +734,6 @@ public abstract class RSClientMixin implements RSClient
setChatCycle(getCycleCntr());
}
@Inject
@Override
public Widget getViewportWidget()
{
if (isResized())
{
if (getVar(Varbits.SIDE_PANELS) == 1)
{
return getWidget(WidgetInfo.RESIZABLE_VIEWPORT_BOTTOM_LINE);
}
else
{
return getWidget(WidgetInfo.RESIZABLE_VIEWPORT_OLD_SCHOOL_BOX);
}
}
return getWidget(WidgetInfo.FIXED_VIEWPORT);
}
@Inject
@Override
public MenuEntry[] getMenuEntries()
@@ -1565,24 +1554,23 @@ public abstract class RSClientMixin implements RSClient
else if (widget.getContentType() == WidgetType.RECTANGLE)
{
if (renderX == client.getViewportXOffset() && renderY == client.getViewportYOffset()
&& widget.getWidth() == client.getViewportWidth() && widget.getHeight() == client.getViewportHeight()
&& widget.getWidth() == client.getViewportWidth() && widget.getHeight() == client.getViewportHeight()
&& widget.getOpacity() > 0 && widget.isFilled() && client.isGpu())
{
int tc = widget.getTextColor();
int alpha = widget.getOpacity() & 0xFF;
int inverseAlpha = 256 - alpha;
int vpc = viewportColor;
int c1 = (alpha * (tc & 0xff00ff) >> 8 & 0xFF00FF) + (alpha * (tc & 0x00FF00) >> 8 & 0x00FF00);
int c2 = (inverseAlpha * (vpc & 0xff00ff) >> 8 & 0xFF00FF) + (inverseAlpha * (vpc & 0x00FF00) >> 8 & 0x00FF00);
int outAlpha = alpha + ((vpc >>> 24) * (255 - alpha) * 0x8081 >>> 23);
viewportColor = outAlpha << 24 | c1 + c2;
widget.setHidden(true);
hiddenWidgets.add(widget);
continue;
int alpha = widget.getOpacity() & 0xFF;
int inverseAlpha = 256 - alpha;
int vpc = viewportColor;
int c1 = (alpha * (tc & 0xff00ff) >> 8 & 0xFF00FF) + (alpha * (tc & 0x00FF00) >> 8 & 0x00FF00);
int c2 = (inverseAlpha * (vpc & 0xff00ff) >> 8 & 0xFF00FF) + (inverseAlpha * (vpc & 0x00FF00) >> 8 & 0x00FF00);
int outAlpha = alpha + ((vpc >>> 24) * (255 - alpha) * 0x8081 >>> 23);
viewportColor = outAlpha << 24 | c1 + c2;
widget.setHidden(true);
hiddenWidgets.add(widget);
continue;
}
}
WidgetNode childNode = componentTable.get(widget.getId());
if (childNode != null)
{
@@ -2108,16 +2096,85 @@ public abstract class RSClientMixin implements RSClient
@Inject
@Override
public VarbitComposition getVarbit(int id)
public ScriptEvent createScriptEvent(Object... args)
{
return getVarbitDefinition(id);
return createRSScriptEvent(args);
}
@Inject
@Override
public int getViewportColor()
public RSScriptEvent createRSScriptEvent(Object... args)
{
return viewportColor;
RSScriptEvent event = createScriptEvent();
event.setArguments(args);
return event;
}
@Inject
@Override
public NodeCache getStructCompositionCache()
{
assert client.isClientThread() : "getStructCompositionCache must be called on client thread";
return getRSStructCompositionCache();
}
@Inject
@Override
public StructComposition getStructComposition(int structID)
{
assert client.isClientThread() : "getStructComposition must be called on client thread";
return getRSStructComposition(structID);
}
@Copy("StructDefinition_getStructDefinition")
@Replace("StructDefinition_getStructDefinition")
@SuppressWarnings("InfiniteRecursion")
static RSStructComposition copy$getStructComposition(int id)
{
RSStructComposition comp = copy$getStructComposition(id);
if (comp.getId() == -1)
{
comp.setId(id);
PostStructComposition event = new PostStructComposition();
event.setStructComposition(comp);
client.getCallbacks().post(event);
}
return comp;
}
@Inject
@Override
public int getMusicVolume()
{
return client.getPreferences().getMusicVolume();
}
@Inject
@Override
public void setMusicVolume(int volume)
{
if (volume > 0 && client.getPreferences().getMusicVolume() <= 0 && client.getCurrentTrackGroupId() != -1)
{
client.playMusicTrack(1000, client.getMusicTracks(), client.getCurrentTrackGroupId(), 0, volume, false);
}
client.getPreferences().setMusicVolume(volume);
client.setMusicTrackVolume(volume);
if (client.getMidiPcmStream() != null)
{
client.getMidiPcmStream().setPcmStreamVolume(volume);
}
}
@Inject
@MethodHook("closeInterface")
public static void preCloseInterface(RSInterfaceParent iface, boolean willUnload)
{
client.getCallbacks().post(new WidgetClosed(iface.getId(), iface.getModalMode(), willUnload));
}
}

View File

@@ -1,31 +0,0 @@
package net.runelite.mixins;
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.RSClientPreferences;
@Mixin(RSClientPreferences.class)
public abstract class RSClientPreferencesMixin implements RSClientPreferences
{
@Shadow("client")
private static RSClient client;
@Inject
@Override
public void setClientMusicVolume(int volume)
{
if (volume > 0 && client.getPreferences().getMusicVolume() <= 0 && client.getCurrentTrackGroupId() != -1)
{
client.playMusicTrack(1000, client.getMusicTracks(), client.getCurrentTrackGroupId(), 0, volume, false);
}
client.getPreferences().setMusicVolume(volume);
client.setMusicTrackVolume(volume);
if (client.getMidiPcmStream() != null)
{
client.getMidiPcmStream().setPcmStreamVolume(volume);
}
}
}

View File

@@ -42,6 +42,9 @@ public abstract class RSGameShellMixin implements RSGameShell
@Shadow("client")
private static RSClient client;
@Shadow("viewportColor")
private static int viewportColor;
@Inject
private Thread thread;
@@ -83,7 +86,7 @@ public abstract class RSGameShellMixin implements RSGameShell
DrawCallbacks drawCallbacks = client.getDrawCallbacks();
if (drawCallbacks != null)
{
drawCallbacks.draw(client.getViewportColor());
drawCallbacks.draw(viewportColor);
}
}

View File

@@ -0,0 +1,16 @@
package net.runelite.mixins;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSParamComposition;
@Mixin(RSParamComposition.class)
public abstract class RSParamCompositionMixin implements RSParamComposition
{
@Inject
@Override
public boolean isString()
{
return getType() == 's';
}
}

View File

@@ -0,0 +1,21 @@
package net.runelite.mixins;
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.RSScriptEvent;
@Mixin(RSScriptEvent.class)
public abstract class RSScriptEventMixin implements RSScriptEvent
{
@Shadow("client")
private static RSClient client;
@Inject
@Override
public void run()
{
client.runScriptEvent(this);
}
}

View File

@@ -0,0 +1,26 @@
package net.runelite.mixins;
import net.runelite.api.mixins.Inject;
import net.runelite.api.mixins.Mixin;
import net.runelite.rs.api.RSStructComposition;
@Mixin(RSStructComposition.class)
public abstract class RSStructCompositionMixin implements RSStructComposition
{
@Inject
private int id = -1;
@Inject
@Override
public int getId()
{
return id;
}
@Inject
@Override
public void setId(int id)
{
this.id = id;
}
}

View File

@@ -28,7 +28,6 @@ import net.runelite.api.HashTable;
import net.runelite.api.Node;
import net.runelite.api.Point;
import net.runelite.api.WidgetNode;
import net.runelite.api.events.WidgetHiddenChanged;
import net.runelite.api.events.WidgetPositioned;
import net.runelite.api.mixins.Copy;
import net.runelite.api.mixins.FieldHook;
@@ -410,78 +409,6 @@ public abstract class RSWidgetMixin implements RSWidget
return bounds != null && bounds.contains(new java.awt.Point(point.getX(), point.getY()));
}
@Inject
@Override
public void broadcastHidden(boolean hidden)
{
WidgetHiddenChanged event = new WidgetHiddenChanged();
event.setWidget(this);
event.setHidden(hidden);
client.getCallbacks().post(event);
RSWidget[] children = getChildren();
if (children != null)
{
// recursive through children
for (RSWidget child : children)
{
// if the widget is hidden it will not magically unhide from its parent changing
if (child == null || child.isSelfHidden())
{
continue;
}
child.broadcastHidden(hidden);
}
}
// make sure we iterate nested children as well
// cannot be null
Widget[] nestedChildren = getNestedChildren();
for (Widget nestedChild : nestedChildren)
{
if (nestedChild == null || nestedChild.isSelfHidden())
{
continue;
}
((RSWidget) nestedChild).broadcastHidden(hidden);
}
}
@FieldHook("isHidden")
@Inject
public void onHiddenChanged(int idx)
{
int id = getId();
if (id == -1)
{
return;
}
Widget parent = getParent();
// if the parent is hidden then changes in this widget don't have any visual effect
// so ignore them
if (parent != null)
{
if (parent.isHidden())
{
return;
}
}
else if (TO_GROUP(id) != client.getWidgetRoot())
{
return;
}
broadcastHidden(isSelfHidden());
}
@FieldHook("y")
@Inject
public void onPositionChanged(int idx)

View File

@@ -27,7 +27,7 @@ package net.runelite.mixins;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.runelite.api.Client;
import static net.runelite.api.Opcodes.*;
import net.runelite.api.events.ScriptCallbackEvent;
import net.runelite.api.events.ScriptPostFired;
import net.runelite.api.events.ScriptPreFired;
@@ -40,13 +40,12 @@ import net.runelite.api.widgets.JavaScriptCallback;
import net.runelite.rs.api.RSClient;
import net.runelite.rs.api.RSScript;
import net.runelite.rs.api.RSScriptEvent;
import static net.runelite.api.Opcodes.*;
@Mixin(RSClient.class)
public abstract class ScriptVMMixin implements RSClient
{
@Shadow("client")
private static Client client;
private static RSClient client;
@Inject
private static RSScript currentScript;
@@ -172,11 +171,44 @@ public abstract class ScriptVMMixin implements RSClient
@Override
public void runScript(Object... args)
{
assert isClientThread();
assert currentScript == null;
assert args[0] instanceof Integer || args[0] instanceof JavaScriptCallback : "The first argument should always be a ScriptID!";
RSScriptEvent se = createScriptEvent();
se.setArguments(args);
runScript(se, 5000000);
runScriptEvent(createRSScriptEvent(args));
}
@Inject
@Override
public void runScriptEvent(RSScriptEvent event)
{
assert isClientThread() : "runScriptEvent must be called on client thread";
assert currentScript == null : "scripts are not reentrant";
runScript(event, 5000000);
boolean assertionsEnabled = false;
assert assertionsEnabled = true;
Object[] args = event.getArguments();
if (assertionsEnabled && args[0] instanceof Integer)
{
int scriptId = (int) args[0];
RSScript script = (RSScript) client.getScriptCache().get(scriptId);
if (script != null)
{
int intCount = 0, stringCount = 0;
for (int i = 1; i < args.length; i++)
{
if (args[i] instanceof Integer)
{
intCount++;
}
else
{
stringCount++;
}
}
assert script.getIntArgumentCount() == intCount && script.getStringArgumentCount() == stringCount :
"Script " + scriptId + " was called with the incorrect number of arguments; takes "
+ script.getIntArgumentCount() + "+" + script.getStringArgumentCount() + ", got " + intCount + "+" + stringCount;
}
}
}
}

View File

@@ -2,6 +2,7 @@ package net.runelite.mixins;
import net.runelite.api.VarClientInt;
import net.runelite.api.VarClientStr;
import net.runelite.api.VarbitComposition;
import net.runelite.api.Varbits;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
@@ -55,7 +56,7 @@ public abstract class VarbitMixin implements RSClient
@Inject
@Override
public RSVarbitComposition getVarbitDefinition(int id)
public RSVarbitComposition getVarbitComposition(int id)
{
assert client.isClientThread() : "getVarbitDefinition must be called on client thread";
@@ -78,7 +79,7 @@ public abstract class VarbitMixin implements RSClient
{
assert client.isClientThread();
RSVarbitComposition v = getVarbitDefinition(varbitId);
RSVarbitComposition v = getVarbitComposition(varbitId);
if (v == null)
{
throw new IndexOutOfBoundsException("Varbit " + varbitId + " does not exist!"); // oob for "backwards compatibility lol"
@@ -95,7 +96,7 @@ public abstract class VarbitMixin implements RSClient
@Override
public void setVarbitValue(int[] varps, int varbitId, int value)
{
RSVarbitComposition v = getVarbitDefinition(varbitId);
RSVarbitComposition v = getVarbitComposition(varbitId);
if (v == null)
{
throw new IndexOutOfBoundsException(String.format("Varbit %d does not exist!", varbitId)); // oob for "backwards compatibility lol"
@@ -161,4 +162,11 @@ public abstract class VarbitMixin implements RSClient
{
return getVarcs().getVarcMap();
}
@Inject
@Override
public VarbitComposition getVarbit(int id)
{
return getVarbitComposition(id);
}
}

View File

@@ -1320,4 +1320,34 @@ public interface RSClient extends RSGameShell, Client
@Import("scriptActiveWidget")
RSWidget getScriptActiveWidget();
@Import("scriptDotWidget")
RSWidget getScriptDotWidget();
RSScriptEvent createRSScriptEvent(Object... args);
void runScriptEvent(RSScriptEvent event);
@Import("Script_cached")
RSEvictingDualNodeHashTable getScriptCache();
@Import("StructDefinition_cached")
RSEvictingDualNodeHashTable getRSStructCompositionCache();
@Import("StructDefinition_getStructDefinition")
RSStructComposition getRSStructComposition(int id);
@Import("getParamDefinition")
RSParamComposition getRSParamComposition(int id);
@Construct
RSIntegerNode newIntegerNode(int contents);
@Construct
RSObjectNode newObjectNode(Object contents);
@Construct
RSIterableNodeHashTable newIterableNodeHashTable(int size);
RSVarbitComposition getVarbitComposition(int id);
}

View File

@@ -30,7 +30,6 @@ public interface RSClientPreferences extends Preferences
void setAreaSoundEffectVolume(int i);
@Import("musicVolume")
@Override
int getMusicVolume();
@Import("musicVolume")

View File

@@ -8,4 +8,8 @@ public interface RSInterfaceParent extends RSNode, WidgetNode
@Import("group")
@Override
int getId();
@Import("type")
@Override
int getModalMode();
}

View File

@@ -84,4 +84,10 @@ public interface RSItemComposition extends ItemComposition
@Import("retextureTo")
short[] getTextureToReplaceWith();
@Import("params")
RSIterableNodeHashTable getParams();
@Import("params")
void setParams(RSIterableNodeHashTable params);
}

View File

@@ -1,6 +1,7 @@
package net.runelite.rs.api;
import net.runelite.api.IterableHashTable;
import net.runelite.api.Node;
import net.runelite.mapping.Import;
public interface RSIterableNodeHashTable extends IterableHashTable
@@ -8,4 +9,8 @@ public interface RSIterableNodeHashTable extends IterableHashTable
@Import("get")
@Override
RSNode get(long hash);
@Import("put")
@Override
void put(Node node, long hash);
}

View File

@@ -59,4 +59,10 @@ public interface RSNPCComposition extends NPCComposition
@Import("headIconPrayer")
int getRsOverheadIcon();
@Import("params")
RSIterableNodeHashTable getParams();
@Import("params")
void setParams(RSIterableNodeHashTable params);
}

View File

@@ -32,4 +32,10 @@ public interface RSObjectComposition extends ObjectComposition
@Import("transform")
@Override
RSObjectComposition getImpostor();
@Import("params")
RSIterableNodeHashTable getParams();
@Import("params")
void setParams(RSIterableNodeHashTable params);
}

View File

@@ -1,3 +1,9 @@
package net.runelite.rs.api;
public interface RSObjectNode {}
import net.runelite.mapping.Import;
public interface RSObjectNode extends RSNode
{
@Import("obj")
Object getValue();
}

View File

@@ -0,0 +1,17 @@
package net.runelite.rs.api;
import net.runelite.mapping.Import;
public interface RSParamComposition
{
boolean isString();
@Import("type")
char getType();
@Import("defaultInt")
int getDefaultInt();
@Import("defaultStr")
String getDefaultStr();
}

View File

@@ -1,3 +0,0 @@
package net.runelite.rs.api;
public interface RSParamDefinition {}

View File

@@ -12,4 +12,10 @@ public interface RSScript extends Script, RSDualNode
@Import("opcodes")
@Override
int[] getInstructions();
@Import("intArgumentCount")
int getIntArgumentCount();
@Import("stringArgumentCount")
int getStringArgumentCount();
}

View File

@@ -43,6 +43,9 @@ public interface RSScriptEvent extends ScriptEvent
@Import("widget")
Widget getSource();
@Import("widget")
RSScriptEvent setSource(Widget widget);
@Import("opIndex")
int getOp();

View File

@@ -0,0 +1,16 @@
package net.runelite.rs.api;
import net.runelite.api.StructComposition;
import net.runelite.mapping.Import;
public interface RSStructComposition extends StructComposition
{
int getId();
void setId(int id);
@Import("params")
RSIterableNodeHashTable getParams();
@Import("params")
void setParams(RSIterableNodeHashTable params);
}

View File

@@ -1,3 +0,0 @@
package net.runelite.rs.api;
public interface RSStructDefinition {}

View File

@@ -345,8 +345,6 @@ public interface RSWidget extends Widget
@Import("paddingY")
int getYPitch();
void broadcastHidden(boolean hidden);
@Import("onOp")
@Override
void setOnOpListener(Object... args);
@@ -570,4 +568,24 @@ public interface RSWidget extends Widget
@Import("onClick")
@Override
void setOnClickListener(Object[] o);
@Import("onDragComplete")
@Override
void setOnDragCompleteListener(Object[] o);
@Import("onDrag")
@Override
void setOnDragListener(Object[] o);
@Import("parent")
@Override
RSWidget getDragParent();
@Import("parent")
@Override
void setDragParent(Widget dragParent);
@Import("onVarTransmit")
@Override
void setOnVarTransmitListener(Object[] o);
}

View File

@@ -178,19 +178,19 @@ public abstract class AbstractWorldMapIcon {
garbageValue = "5"
)
@Export("StructDefinition_getStructDefinition")
public static StructDefinition StructDefinition_getStructDefinition(int var0) {
StructDefinition var1 = (StructDefinition)StructDefinition.StructDefinition_cached.get((long)var0); // L: 23
public static StructComposition StructDefinition_getStructDefinition(int var0) {
StructComposition var1 = (StructComposition) StructComposition.StructDefinition_cached.get((long)var0); // L: 23
if (var1 != null) { // L: 24
return var1;
} else {
byte[] var2 = StructDefinition.StructDefinition_archive.takeFile(34, var0); // L: 25
var1 = new StructDefinition(); // L: 26
byte[] var2 = StructComposition.StructDefinition_archive.takeFile(34, var0); // L: 25
var1 = new StructComposition(); // L: 26
if (var2 != null) { // L: 27
var1.decode(new Buffer(var2));
}
var1.postDecode(); // L: 28
StructDefinition.StructDefinition_cached.put(var1, (long)var0); // L: 29
StructComposition.StructDefinition_cached.put(var1, (long)var0); // L: 29
return var1; // L: 30
}
}

View File

@@ -274,7 +274,7 @@ public final class Canvas extends java.awt.Canvas {
ObjectComposition.ObjectDefinition_modelsArchive = var4; // L: 1917
ObjectComposition.ObjectDefinition_isLowDetail = var17; // L: 1918
World.method1849(DynamicObject.archive2, BuddyRankComparator.archive7); // L: 1920
ParamDefinition.method4526(DynamicObject.archive2); // L: 1921
ParamComposition.method4526(DynamicObject.archive2); // L: 1921
Actor.method1821(DynamicObject.archive2, BuddyRankComparator.archive7, Client.isMembersWorld, class297.fontPlain11); // L: 1922
PcmPlayer.method2538(DynamicObject.archive2, SceneTilePaint.archive0, WorldMapSprite.archive1); // L: 1923
ModelData0.method3331(DynamicObject.archive2, BuddyRankComparator.archive7); // L: 1924
@@ -294,7 +294,7 @@ public final class Canvas extends java.awt.Canvas {
class195.Widget_loadedInterfaces = new boolean[class58.Widget_archive.getGroupCount()]; // L: 1941
Archive var11 = DynamicObject.archive2; // L: 1943
InvDefinition.InvDefinition_archive = var11; // L: 1945
StructDefinition.method4545(DynamicObject.archive2); // L: 1947
StructComposition.method4545(DynamicObject.archive2); // L: 1947
ModelData0.method3330(DynamicObject.archive2); // L: 1948
class13.method129(DynamicObject.archive2); // L: 1949
Varcs.varcs = new Varcs(); // L: 1950

View File

@@ -109,19 +109,19 @@ public class ChatChannel {
garbageValue = "1207819240"
)
@Export("getParamDefinition")
public static ParamDefinition getParamDefinition(int var0) {
ParamDefinition var1 = (ParamDefinition)ParamDefinition.ParamDefinition_cached.get((long)var0); // L: 25
public static ParamComposition getParamDefinition(int var0) {
ParamComposition var1 = (ParamComposition) ParamComposition.ParamDefinition_cached.get((long)var0); // L: 25
if (var1 != null) { // L: 26
return var1;
} else {
byte[] var2 = ParamDefinition.ParamDefinition_archive.takeFile(11, var0); // L: 27
var1 = new ParamDefinition(); // L: 28
byte[] var2 = ParamComposition.ParamDefinition_archive.takeFile(11, var0); // L: 27
var1 = new ParamComposition(); // L: 28
if (var2 != null) { // L: 29
var1.decode(new Buffer(var2));
}
var1.postDecode(); // L: 30
ParamDefinition.ParamDefinition_cached.put(var1, (long)var0); // L: 31
ParamComposition.ParamDefinition_cached.put(var1, (long)var0); // L: 31
return var1; // L: 32
}
}

View File

@@ -5098,9 +5098,9 @@ public final class Client extends GameShell implements Usernamed {
field707 = (field707 + 1) % 100; // L: 6209
String var34 = AbstractFont.escapeBrackets(ServerPacket.method3663(AttackOption.method2135(var3))); // L: 6210
if (var60.modIcon != -1) { // L: 6211
UserComparator10.addChatMessage(9, class25.method248(var60.modIcon) + var38, var34, ParamDefinition.base37DecodeLong(var22));
UserComparator10.addChatMessage(9, class25.method248(var60.modIcon) + var38, var34, ParamComposition.base37DecodeLong(var22));
} else {
UserComparator10.addChatMessage(9, var38, var34, ParamDefinition.base37DecodeLong(var22)); // L: 6212
UserComparator10.addChatMessage(9, var38, var34, ParamComposition.base37DecodeLong(var22)); // L: 6212
}
}

View File

@@ -93,7 +93,7 @@ public class DynamicObject extends Renderable
this.x = var5; // L: 24
this.y = var6; // L: 25
if (var7 != -1) { // L: 26
this.sequenceDefinition = ParamDefinition.SequenceDefinition_get(var7); // L: 27
this.sequenceDefinition = ParamComposition.SequenceDefinition_get(var7); // L: 27
this.frame = 0; // L: 28
this.cycleStart = Client.cycle - 1; // L: 29
if (this.sequenceDefinition.field3548 == 0 && var9 != null && var9 instanceof DynamicObject) { // L: 30

View File

@@ -5,7 +5,7 @@ import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
@ObfuscatedName("jx")
@Implements("EnumDefinition")
@Implements("EnumComposition")
public class EnumComposition extends DualNode {
@ObfuscatedName("rk")
@ObfuscatedGetter(

View File

@@ -596,7 +596,7 @@ public class FontName {
CollisionMap.invalidateWidget(var10);
}
} else {
SequenceDefinition var47 = ParamDefinition.SequenceDefinition_get(var20); // L: 9272
SequenceDefinition var47 = ParamComposition.SequenceDefinition_get(var20); // L: 9272
var41 = var10.getModel(var47, var10.modelFrame, var36, PlayerComposition.localPlayer.appearance); // L: 9273
if (var41 == null && Widget.field2603) { // L: 9274
CollisionMap.invalidateWidget(var10);

View File

@@ -96,7 +96,7 @@ public class Frames extends DualNode {
if (var0 != ScriptOpcodes.CC_CALLONRESIZE && var0 != ScriptOpcodes.IF_CALLONRESIZE) { // L: 1145
int var4;
if (var0 == 1928) { // L: 1162
var6 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1163
var6 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1163
var4 = Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]; // L: 1164
if (var4 >= 1 && var4 <= 10) { // L: 1165
class3.widgetDefaultMenuAction(var4, var6.id, var6.childIndex, var6.itemId, ""); // L: 1168
@@ -124,7 +124,7 @@ public class Frames extends DualNode {
if (var0 >= 2000) { // L: 1150
var6 = CollisionMap.getWidget(Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]); // L: 1151
} else {
var6 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1153
var6 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1153
}
if (var6.onResize == null) { // L: 1154

View File

@@ -75,7 +75,7 @@ final class GrandExchangeOfferUnitPriceComparator implements Comparator {
garbageValue = "-613147121"
)
static int method200(int var0, Script var1, boolean var2) {
Widget var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1041
Widget var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1041
if (var0 == ScriptOpcodes.CC_GETSCROLLX) { // L: 1042
Interpreter.Interpreter_intStack[++VarcInt.Interpreter_intStackSize - 1] = var3.scrollX; // L: 1043
return 1; // L: 1044

View File

@@ -81,7 +81,7 @@ public final class GraphicsObject extends Renderable
int var8 = TileItem.SpotAnimationDefinition_get(this.id).sequence; // L: 27
if (var8 != -1) { // L: 28
this.isFinished = false; // L: 29
this.sequenceDefinition = ParamDefinition.SequenceDefinition_get(var8); // L: 30
this.sequenceDefinition = ParamComposition.SequenceDefinition_get(var8); // L: 30
} else {
this.isFinished = true; // L: 32
}

View File

@@ -148,7 +148,7 @@ public enum HorizontalAlignment implements Enumerated {
return 1; // L: 3442
} else {
int var4;
ParamDefinition var5;
ParamComposition var5;
if (var0 == ScriptOpcodes.NC_PARAM) { // L: 3444
VarcInt.Interpreter_intStackSize -= 2; // L: 3445
var3 = Interpreter.Interpreter_intStack[VarcInt.Interpreter_intStackSize]; // L: 3446

View File

@@ -5,7 +5,7 @@ import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
@ObfuscatedName("jq")
@Implements("ItemDefinition")
@Implements("ItemComposition")
public class ItemComposition extends DualNode {
@ObfuscatedName("p")
@Export("ItemDefinition_inMembersWorld")

View File

@@ -63,7 +63,7 @@ public class Messages {
garbageValue = "-729014462"
)
static int method2283(int var0, Script var1, boolean var2) {
Widget var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1012
Widget var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1012
if (var0 == ScriptOpcodes.CC_GETX) { // L: 1013
Interpreter.Interpreter_intStack[++VarcInt.Interpreter_intStackSize - 1] = var3.x; // L: 1014
return 1; // L: 1015

View File

@@ -131,7 +131,7 @@ public enum ModeWhere implements Enumerated {
var0 -= 1000; // L: 948
var3 = CollisionMap.getWidget(Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]); // L: 949
} else {
var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 951
var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 951
}
String var4 = Interpreter.Interpreter_stringStack[--Interpreter.Interpreter_stringStackSize]; // L: 952

View File

@@ -71,7 +71,7 @@ public final class NPC extends Actor {
--var4; // L: 35
}
if (super.sequence != -1 && ParamDefinition.SequenceDefinition_get(super.sequence).field3555 == 1) { // L: 37
if (super.sequence != -1 && ParamComposition.SequenceDefinition_get(super.sequence).field3555 == 1) { // L: 37
super.sequence = -1;
}
@@ -96,7 +96,7 @@ public final class NPC extends Actor {
garbageValue = "-169739231"
)
final void method2106(int var1, int var2, boolean var3) {
if (super.sequence != -1 && ParamDefinition.SequenceDefinition_get(super.sequence).field3555 == 1) { // L: 50
if (super.sequence != -1 && ParamComposition.SequenceDefinition_get(super.sequence).field3555 == 1) { // L: 50
super.sequence = -1;
}
@@ -140,8 +140,8 @@ public final class NPC extends Actor {
if (this.definition == null) { // L: 77
return null;
} else {
SequenceDefinition var1 = super.sequence != -1 && super.sequenceDelay == 0 ? ParamDefinition.SequenceDefinition_get(super.sequence) : null; // L: 78
SequenceDefinition var2 = super.movementSequence != -1 && (super.idleSequence != super.movementSequence || var1 == null) ? ParamDefinition.SequenceDefinition_get(super.movementSequence) : null; // L: 79
SequenceDefinition var1 = super.sequence != -1 && super.sequenceDelay == 0 ? ParamComposition.SequenceDefinition_get(super.sequence) : null; // L: 78
SequenceDefinition var2 = super.movementSequence != -1 && (super.idleSequence != super.movementSequence || var1 == null) ? ParamComposition.SequenceDefinition_get(super.movementSequence) : null; // L: 79
Model var3 = this.definition.getModel(var1, super.sequenceFrame, var2, super.movementFrame); // L: 80
if (var3 == null) {
return null;

View File

@@ -5,7 +5,7 @@ import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
@ObfuscatedName("jd")
@Implements("NPCDefinition")
@Implements("NPCComposition")
public class NPCComposition extends DualNode {
@ObfuscatedName("h")
@ObfuscatedSignature(

View File

@@ -5,7 +5,7 @@ import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
@ObfuscatedName("jm")
@Implements("ObjectDefinition")
@Implements("ObjectComposition")
public class ObjectComposition extends DualNode {
@ObfuscatedName("h")
@Export("ObjectDefinition_isLowDetail")

View File

@@ -5,8 +5,8 @@ import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
@ObfuscatedName("jl")
@Implements("ParamDefinition")
public class ParamDefinition extends DualNode {
@Implements("ParamComposition")
public class ParamComposition extends DualNode {
@ObfuscatedName("h")
@ObfuscatedSignature(
descriptor = "Lib;"
@@ -39,7 +39,7 @@ public class ParamDefinition extends DualNode {
ParamDefinition_cached = new EvictingDualNodeHashTable(64); // L: 12
}
ParamDefinition() {
ParamComposition() {
this.autoDisable = true; // L: 16
} // L: 18
@@ -120,7 +120,7 @@ public class ParamDefinition extends DualNode {
garbageValue = "1899658312"
)
public static void method4526(AbstractArchive var0) {
StructDefinition.StructDefinition_archive = var0; // L: 19
StructComposition.StructDefinition_archive = var0; // L: 19
} // L: 20
@ObfuscatedName("v")

View File

@@ -384,8 +384,8 @@ public final class Player extends Actor {
if (this.appearance == null) { // L: 149
return null;
} else {
SequenceDefinition var1 = super.sequence != -1 && super.sequenceDelay == 0 ? ParamDefinition.SequenceDefinition_get(super.sequence) : null; // L: 150
SequenceDefinition var2 = super.movementSequence == -1 || this.isUnanimated || super.idleSequence == super.movementSequence && var1 != null ? null : ParamDefinition.SequenceDefinition_get(super.movementSequence); // L: 151
SequenceDefinition var1 = super.sequence != -1 && super.sequenceDelay == 0 ? ParamComposition.SequenceDefinition_get(super.sequence) : null; // L: 150
SequenceDefinition var2 = super.movementSequence == -1 || this.isUnanimated || super.idleSequence == super.movementSequence && var1 != null ? null : ParamComposition.SequenceDefinition_get(super.movementSequence); // L: 151
Model var3 = this.appearance.getModel(var1, super.sequenceFrame, var2, super.movementFrame); // L: 152
if (var3 == null) { // L: 153
return null;
@@ -451,7 +451,7 @@ public final class Player extends Actor {
garbageValue = "1635620178"
)
final void method1313(int var1, int var2, byte var3) {
if (super.sequence != -1 && ParamDefinition.SequenceDefinition_get(super.sequence).field3555 == 1) { // L: 199
if (super.sequence != -1 && ParamComposition.SequenceDefinition_get(super.sequence).field3555 == 1) { // L: 199
super.sequence = -1;
}

View File

@@ -37,7 +37,8 @@ public class PlayerComposition
@ObfuscatedSignature(
descriptor = "Lhe;"
)
static Widget field2561;
@Export("scriptDotWidget")
static Widget scriptDotWidget;
@ObfuscatedName("kn")
@ObfuscatedSignature(
descriptor = "Lbq;"

View File

@@ -150,7 +150,7 @@ public final class Projectile extends Renderable
this.isMoving = false; // L: 47
int var12 = TileItem.SpotAnimationDefinition_get(this.id).sequence; // L: 48
if (var12 != -1) { // L: 49
this.sequenceDefinition = ParamDefinition.SequenceDefinition_get(var12);
this.sequenceDefinition = ParamComposition.SequenceDefinition_get(var12);
} else {
this.sequenceDefinition = null; // L: 50
}

View File

@@ -74,7 +74,7 @@ public final class SceneTilePaint
var0.isWalking = false; // L: 4080
SequenceDefinition var1;
if (var0.movementSequence != -1) { // L: 4081
var1 = ParamDefinition.SequenceDefinition_get(var0.movementSequence); // L: 4082
var1 = ParamComposition.SequenceDefinition_get(var0.movementSequence); // L: 4082
if (var1 != null && var1.frameIds != null) { // L: 4083
++var0.movementFrameCycle; // L: 4084
if (var0.movementFrame < var1.frameIds.length && var0.movementFrameCycle > var1.frameLengths[var0.movementFrame]) { // L: 4085
@@ -100,7 +100,7 @@ public final class SceneTilePaint
int var3 = TileItem.SpotAnimationDefinition_get(var0.spotAnimation).sequence; // L: 4100
if (var3 != -1) { // L: 4101
SequenceDefinition var2 = ParamDefinition.SequenceDefinition_get(var3); // L: 4102
SequenceDefinition var2 = ParamComposition.SequenceDefinition_get(var3); // L: 4102
if (var2 != null && var2.frameIds != null) { // L: 4103
++var0.spotAnimationFrameCycle; // L: 4104
if (var0.spotAnimationFrame < var2.frameIds.length && var0.spotAnimationFrameCycle > var2.frameLengths[var0.spotAnimationFrame]) { // L: 4105
@@ -121,7 +121,7 @@ public final class SceneTilePaint
}
if (var0.sequence != -1 && var0.sequenceDelay <= 1) { // L: 4118
var1 = ParamDefinition.SequenceDefinition_get(var0.sequence); // L: 4119
var1 = ParamComposition.SequenceDefinition_get(var0.sequence); // L: 4119
if (var1.field3560 == 1 && var0.field996 > 0 && var0.field984 <= Client.cycle && var0.field973 < Client.cycle) { // L: 4120 4121
var0.sequenceDelay = 1; // L: 4122
return; // L: 4123
@@ -129,7 +129,7 @@ public final class SceneTilePaint
}
if (var0.sequence != -1 && var0.sequenceDelay == 0) { // L: 4127
var1 = ParamDefinition.SequenceDefinition_get(var0.sequence); // L: 4128
var1 = ParamComposition.SequenceDefinition_get(var0.sequence); // L: 4128
if (var1 != null && var1.frameIds != null) { // L: 4129
++var0.sequenceFrameCycle; // L: 4130
if (var0.sequenceFrame < var1.frameIds.length && var0.sequenceFrameCycle > var1.frameLengths[var0.sequenceFrame]) { // L: 4131

View File

@@ -50,7 +50,7 @@ public class ScriptFrame {
var4 = CollisionMap.getWidget(Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]); // L: 778
var3 = false; // L: 779
} else {
var4 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 781
var4 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 781
}
int var11;

View File

@@ -63,7 +63,7 @@ public class SecureRandomCallable implements Callable {
boolean var3 = false; // L: 110
for (Node var4 = var1.params.first(); var4 != null; var4 = var1.params.next()) { // L: 111
ParamDefinition var5 = ChatChannel.getParamDefinition((int)var4.key); // L: 112
ParamComposition var5 = ChatChannel.getParamDefinition((int)var4.key); // L: 112
if (var5.autoDisable) { // L: 113
var4.remove();
} else {

View File

@@ -135,7 +135,7 @@ public class Skeleton extends Node {
}
if (var5 != -1) { // L: 10614
SequenceDefinition var6 = ParamDefinition.SequenceDefinition_get(var5); // L: 10615
SequenceDefinition var6 = ParamComposition.SequenceDefinition_get(var5); // L: 10615
for (var3.modelFrameCycle += Client.field850; var3.modelFrameCycle > var6.frameLengths[var3.modelFrame]; CollisionMap.invalidateWidget(var3)) { // L: 10616 10617 10624
var3.modelFrameCycle -= var6.frameLengths[var3.modelFrame]; // L: 10618

View File

@@ -203,7 +203,7 @@ public class SpotAnimationDefinition extends DualNode {
Model var5;
if (this.sequence != -1 && var1 != -1) { // L: 103
var5 = ParamDefinition.SequenceDefinition_get(this.sequence).transformSpotAnimationModel(var2, var1);
var5 = ParamComposition.SequenceDefinition_get(this.sequence).transformSpotAnimationModel(var2, var1);
} else {
var5 = var2.toSharedSpotAnimationModel(true); // L: 104
}

View File

@@ -4,8 +4,8 @@ import net.runelite.mapping.ObfuscatedName;
import net.runelite.mapping.ObfuscatedSignature;
@ObfuscatedName("jb")
@Implements("StructDefinition")
public class StructDefinition extends DualNode {
@Implements("StructComposition")
public class StructComposition extends DualNode {
@ObfuscatedName("h")
@ObfuscatedSignature(
descriptor = "Lib;"
@@ -29,7 +29,7 @@ public class StructDefinition extends DualNode {
StructDefinition_cached = new EvictingDualNodeHashTable(64); // L: 13
}
StructDefinition() {
StructComposition() {
} // L: 16
@ObfuscatedName("x")

View File

@@ -81,7 +81,7 @@ public enum StudioGame implements Enumerated {
garbageValue = "1020902177"
)
public static void method4185() {
ParamDefinition.ParamDefinition_cached.clear(); // L: 72
ParamComposition.ParamDefinition_cached.clear(); // L: 72
} // L: 73
@ObfuscatedName("ak")

View File

@@ -166,7 +166,7 @@ public final class Tiles {
@Export("performPlayerAnimation")
static void performPlayerAnimation(Player var0, int var1, int var2) {
if (var0.sequence == var1 && var1 != -1) { // L: 4151
int var3 = ParamDefinition.SequenceDefinition_get(var1).field3548; // L: 4152
int var3 = ParamComposition.SequenceDefinition_get(var1).field3548; // L: 4152
if (var3 == 1) { // L: 4153
var0.sequenceFrame = 0; // L: 4154
var0.sequenceFrameCycle = 0; // L: 4155
@@ -177,7 +177,7 @@ public final class Tiles {
if (var3 == 2) { // L: 4159
var0.field974 = 0; // L: 4160
}
} else if (var1 == -1 || var0.sequence == -1 || ParamDefinition.SequenceDefinition_get(var1).field3557 >= ParamDefinition.SequenceDefinition_get(var0.sequence).field3557) { // L: 4163
} else if (var1 == -1 || var0.sequence == -1 || ParamComposition.SequenceDefinition_get(var1).field3557 >= ParamComposition.SequenceDefinition_get(var0.sequence).field3557) { // L: 4163
var0.sequence = var1; // L: 4164
var0.sequenceFrame = 0; // L: 4165
var0.sequenceFrameCycle = 0; // L: 4166

View File

@@ -64,7 +64,7 @@ public class UserComparator9 extends AbstractUserComparator {
var0 -= 1000; // L: 735
var3 = CollisionMap.getWidget(Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]); // L: 736
} else {
var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 738
var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 738
}
CollisionMap.invalidateWidget(var3); // L: 739

View File

@@ -461,7 +461,7 @@ public class WorldMapData_0 extends AbstractWorldMapData {
var7 = var1.readUnsignedByte(); // L: 7166
if (var6 == var15.sequence && var6 != -1) { // L: 7167
var8 = ParamDefinition.SequenceDefinition_get(var6).field3548; // L: 7168
var8 = ParamComposition.SequenceDefinition_get(var6).field3548; // L: 7168
if (var8 == 1) { // L: 7169
var15.sequenceFrame = 0; // L: 7170
var15.sequenceFrameCycle = 0; // L: 7171
@@ -472,7 +472,7 @@ public class WorldMapData_0 extends AbstractWorldMapData {
if (var8 == 2) { // L: 7175
var15.field974 = 0; // L: 7176
}
} else if (var6 == -1 || var15.sequence == -1 || ParamDefinition.SequenceDefinition_get(var6).field3557 >= ParamDefinition.SequenceDefinition_get(var15.sequence).field3557) { // L: 7179
} else if (var6 == -1 || var15.sequence == -1 || ParamComposition.SequenceDefinition_get(var6).field3557 >= ParamComposition.SequenceDefinition_get(var15.sequence).field3557) { // L: 7179
var15.sequence = var6; // L: 7180
var15.sequenceFrame = 0; // L: 7181
var15.sequenceFrameCycle = 0; // L: 7182

View File

@@ -188,7 +188,7 @@ public class WorldMapData_1 extends AbstractWorldMapData {
var4 = Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]; // L: 553
var3 = CollisionMap.getWidget(var4); // L: 554
} else {
var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 556
var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 556
}
if (var0 == ScriptOpcodes.CC_SETSCROLLPOS) { // L: 557

View File

@@ -119,7 +119,7 @@ public class WorldMapID {
VarcInt.Interpreter_intStackSize -= 2; // L: 1387
var10 = Interpreter.Interpreter_intStack[VarcInt.Interpreter_intStackSize]; // L: 1388
var16 = Interpreter.Interpreter_intStack[VarcInt.Interpreter_intStackSize + 1]; // L: 1389
Widget var13 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1390
Widget var13 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1390
class13.clickWidget(var13, var10, var16); // L: 1391
return 1; // L: 1392
} else if (var0 == ScriptOpcodes.MOUSECAM) {
@@ -256,7 +256,7 @@ public class WorldMapID {
return 1; // L: 1534
} else if (var0 == 3140) {
Client.field810 = 3; // L: 1537
Client.field811 = var2 ? PlayerComposition.field2561.id * -437932207 * 653064625 : VarcInt.scriptActiveWidget.id * -437932207 * 653064625; // L: 1538
Client.field811 = var2 ? PlayerComposition.scriptDotWidget.id * -437932207 * 653064625 : VarcInt.scriptActiveWidget.id * -437932207 * 653064625; // L: 1538
return 1; // L: 1539
} else {
boolean var11;
@@ -528,7 +528,7 @@ public class WorldMapID {
if (var0.field984 >= Client.cycle) { // L: 3878
WorldMapManager.method672(var0);
} else if (var0.field973 >= Client.cycle) { // L: 3879
if (var0.field973 == Client.cycle || var0.sequence == -1 || var0.sequenceDelay != 0 || var0.sequenceFrameCycle + 1 > ParamDefinition.SequenceDefinition_get(var0.sequence).frameLengths[var0.sequenceFrame]) { // L: 3880
if (var0.field973 == Client.cycle || var0.sequence == -1 || var0.sequenceDelay != 0 || var0.sequenceFrameCycle + 1 > ParamComposition.SequenceDefinition_get(var0.sequence).frameLengths[var0.sequenceFrame]) { // L: 3880
var2 = var0.field973 - var0.field984; // L: 3881
var3 = Client.cycle - var0.field984; // L: 3882
var4 = var0.field941 * 64 + var0.field981 * 128; // L: 3883

View File

@@ -57,7 +57,7 @@ public final class WorldMapRectangle {
garbageValue = "470419605"
)
static int method331(int var0, Script var1, boolean var2) {
Widget var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1124
Widget var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1124
if (var0 == ScriptOpcodes.CC_GETTARGETMASK) { // L: 1125
Interpreter.Interpreter_intStack[++VarcInt.Interpreter_intStackSize - 1] = ServerPacket.Widget_unpackTargetMask(FaceNormal.getWidgetFlags(var3)); // L: 1126
return 1; // L: 1127
@@ -126,7 +126,7 @@ public final class WorldMapRectangle {
WorldMapID.method601(); // L: 2883
HealthBarDefinition.method4509(); // L: 2884
VarcInt.method4426(); // L: 2885
StructDefinition.StructDefinition_cached.clear(); // L: 2887
StructComposition.StructDefinition_cached.clear(); // L: 2887
StudioGame.method4185(); // L: 2889
WorldMapElement.WorldMapElement_cachedSprites.clear(); // L: 2891
PlayerComposition.PlayerAppearance_cachedModels.clear(); // L: 2894

View File

@@ -13,7 +13,7 @@ public final class class13 {
garbageValue = "2"
)
public static void method129(AbstractArchive var0) {
ParamDefinition.ParamDefinition_archive = var0; // L: 21
ParamComposition.ParamDefinition_archive = var0; // L: 21
} // L: 22
@ObfuscatedName("x")

View File

@@ -56,7 +56,7 @@ public class class200 {
var3 = Interpreter.Interpreter_intStack[--VarcInt.Interpreter_intStackSize]; // L: 503
var4 = CollisionMap.getWidget(var3); // L: 504
} else {
var4 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 506
var4 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 506
}
if (var0 == ScriptOpcodes.CC_SETPOSITION) { // L: 507

View File

@@ -157,7 +157,7 @@ public class class231 {
var12.isIf3 = true; // L: 452
var6.children[var11] = var12; // L: 453
if (var2) { // L: 454
PlayerComposition.field2561 = var12;
PlayerComposition.scriptDotWidget = var12;
} else {
VarcInt.scriptActiveWidget = var12; // L: 455
}
@@ -169,7 +169,7 @@ public class class231 {
} else {
Widget var3;
if (var0 == ScriptOpcodes.CC_DELETE) { // L: 459
var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 460
var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 460
Widget var10 = CollisionMap.getWidget(var3.id); // L: 461
var10.children[var3.childIndex] = null; // L: 462
CollisionMap.invalidateWidget(var10); // L: 463
@@ -185,7 +185,7 @@ public class class231 {
if (var3 != null) { // L: 487
Interpreter.Interpreter_intStack[++VarcInt.Interpreter_intStackSize - 1] = 1; // L: 488
if (var2) { // L: 489
PlayerComposition.field2561 = var3;
PlayerComposition.scriptDotWidget = var3;
} else {
VarcInt.scriptActiveWidget = var3; // L: 490
}
@@ -205,7 +205,7 @@ public class class231 {
if (var5 != null && var4 != -1) { // L: 477
Interpreter.Interpreter_intStack[++VarcInt.Interpreter_intStackSize - 1] = 1; // L: 478
if (var2) { // L: 479
PlayerComposition.field2561 = var5;
PlayerComposition.scriptDotWidget = var5;
} else {
VarcInt.scriptActiveWidget = var5; // L: 480
}

View File

@@ -41,7 +41,7 @@ public class class238 {
garbageValue = "1585982662"
)
public static String method4166(CharSequence var0) {
String var1 = ParamDefinition.base37DecodeLong(Renderable.method3340(var0)); // L: 75
String var1 = ParamComposition.base37DecodeLong(Renderable.method3340(var0)); // L: 75
if (var1 == null) { // L: 76
var1 = "";
}

View File

@@ -10,7 +10,7 @@ public class class277 {
garbageValue = "-1829984749"
)
static int method5005(int var0, Script var1, boolean var2) {
Widget var3 = var2 ? PlayerComposition.field2561 : VarcInt.scriptActiveWidget; // L: 1106
Widget var3 = var2 ? PlayerComposition.scriptDotWidget : VarcInt.scriptActiveWidget; // L: 1106
if (var0 == ScriptOpcodes.CC_GETINVOBJECT) { // L: 1107
Interpreter.Interpreter_intStack[++VarcInt.Interpreter_intStackSize - 1] = var3.itemId; // L: 1108
return 1; // L: 1109

View File

@@ -213,7 +213,7 @@ public class class51 implements WorldMapSection {
var0.field963 = 0; // L: 3987
} else {
if (var0.sequence != -1 && var0.sequenceDelay == 0) { // L: 3990
SequenceDefinition var1 = ParamDefinition.SequenceDefinition_get(var0.sequence); // L: 3991
SequenceDefinition var1 = ParamComposition.SequenceDefinition_get(var0.sequence); // L: 3991
if (var0.field996 > 0 && var1.field3560 == 0) { // L: 3992
++var0.field963; // L: 3993
return; // L: 3994