Merge branch 'master' into maven
This commit is contained in:
@@ -22,34 +22,41 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.cache.definitions.sound;
|
package net.runelite.cache.definitions.loaders.sound;
|
||||||
|
|
||||||
public class SoundEffect1Definition
|
import net.runelite.cache.definitions.sound.AudioEnvelopeDefinition;
|
||||||
|
import net.runelite.cache.io.InputStream;
|
||||||
|
|
||||||
|
public class AudioEnvelopeLoader
|
||||||
{
|
{
|
||||||
public SoundEffect2Definition field1173;
|
public AudioEnvelopeDefinition load(InputStream in)
|
||||||
public SoundEffect2Definition field1174;
|
|
||||||
public SoundEffect2Definition field1175;
|
|
||||||
public int field1176 = 500;
|
|
||||||
public int[] field1177 = new int[]
|
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 0
|
AudioEnvelopeDefinition audioEnvelope = new AudioEnvelopeDefinition();
|
||||||
};
|
|
||||||
public SoundEffect2Definition field1178;
|
load(audioEnvelope, in);
|
||||||
public int[] field1179 = new int[]
|
|
||||||
|
return audioEnvelope;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(AudioEnvelopeDefinition audioEnvelope, InputStream in)
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 0
|
audioEnvelope.form = in.readUnsignedByte();
|
||||||
};
|
audioEnvelope.start = in.readInt();
|
||||||
public int[] field1180 = new int[]
|
audioEnvelope.end = in.readInt();
|
||||||
|
this.loadSegments(audioEnvelope, in);
|
||||||
|
}
|
||||||
|
|
||||||
|
final void loadSegments(AudioEnvelopeDefinition audioEnvelope, InputStream in)
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 0
|
audioEnvelope.segments = in.readUnsignedByte();
|
||||||
};
|
audioEnvelope.durations = new int[audioEnvelope.segments];
|
||||||
public SoundEffect2Definition field1181;
|
audioEnvelope.phases = new int[audioEnvelope.segments];
|
||||||
public SoundEffect3Definition field1182;
|
|
||||||
public SoundEffect2Definition field1183;
|
for (int i = 0; i < audioEnvelope.segments; ++i)
|
||||||
public int field1184 = 100;
|
{
|
||||||
public SoundEffect2Definition field1186;
|
audioEnvelope.durations[i] = in.readUnsignedShort();
|
||||||
public int field1187 = 0;
|
audioEnvelope.phases[i] = in.readUnsignedShort();
|
||||||
public int field1188 = 0;
|
}
|
||||||
public SoundEffect2Definition field1192;
|
|
||||||
public SoundEffect2Definition field1193;
|
}
|
||||||
}
|
}
|
||||||
93
cache/src/main/java/net/runelite/cache/definitions/loaders/sound/InstrumentLoader.java
vendored
Normal file
93
cache/src/main/java/net/runelite/cache/definitions/loaders/sound/InstrumentLoader.java
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.cache.definitions.loaders.sound;
|
||||||
|
|
||||||
|
import net.runelite.cache.definitions.sound.InstrumentDefinition;
|
||||||
|
import net.runelite.cache.definitions.sound.AudioEnvelopeDefinition;
|
||||||
|
import net.runelite.cache.io.InputStream;
|
||||||
|
|
||||||
|
public class InstrumentLoader
|
||||||
|
{
|
||||||
|
private final AudioEnvelopeLoader aeLoader = new AudioEnvelopeLoader();
|
||||||
|
private final SoundEffectLoader seLoader = new SoundEffectLoader();
|
||||||
|
|
||||||
|
public InstrumentDefinition load(InputStream in)
|
||||||
|
{
|
||||||
|
InstrumentDefinition instrument = new InstrumentDefinition();
|
||||||
|
|
||||||
|
load(instrument, in);
|
||||||
|
|
||||||
|
return instrument;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void load(InstrumentDefinition instrument, InputStream in)
|
||||||
|
{
|
||||||
|
instrument.pitch = aeLoader.load(in);
|
||||||
|
instrument.volume = aeLoader.load(in);
|
||||||
|
int volume = in.readUnsignedByte();
|
||||||
|
if (volume != 0)
|
||||||
|
{
|
||||||
|
in.setOffset(in.getOffset() - 1);
|
||||||
|
instrument.pitchModifier = aeLoader.load(in);
|
||||||
|
instrument.pitchModifierAmplitude = aeLoader.load(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
volume = in.readUnsignedByte();
|
||||||
|
if (volume != 0)
|
||||||
|
{
|
||||||
|
in.setOffset(in.getOffset() - 1);
|
||||||
|
instrument.volumeMultiplier = aeLoader.load(in);
|
||||||
|
instrument.volumeMultiplierAmplitude = aeLoader.load(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
volume = in.readUnsignedByte();
|
||||||
|
if (volume != 0)
|
||||||
|
{
|
||||||
|
in.setOffset(in.getOffset() - 1);
|
||||||
|
instrument.release = aeLoader.load(in);
|
||||||
|
instrument.field1175 = aeLoader.load(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
int vol = in.readUnsignedShortSmart();
|
||||||
|
if (vol == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
instrument.oscillatorVolume[i] = vol;
|
||||||
|
instrument.oscillatorPitch[i] = in.readShortSmart();
|
||||||
|
instrument.oscillatorDelays[i] = in.readUnsignedShortSmart();
|
||||||
|
}
|
||||||
|
|
||||||
|
instrument.delayTime = in.readUnsignedShortSmart();
|
||||||
|
instrument.delayDecay = in.readUnsignedShortSmart();
|
||||||
|
instrument.duration = in.readUnsignedShort();
|
||||||
|
instrument.offset = in.readUnsignedShort();
|
||||||
|
instrument.filterEnvelope = new AudioEnvelopeDefinition();
|
||||||
|
instrument.filter = seLoader.load(in, instrument.filterEnvelope);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.cache.definitions.loaders.sound;
|
|
||||||
|
|
||||||
import net.runelite.cache.definitions.sound.SoundEffect1Definition;
|
|
||||||
import net.runelite.cache.definitions.sound.SoundEffect2Definition;
|
|
||||||
import net.runelite.cache.io.InputStream;
|
|
||||||
|
|
||||||
public class SoundEffect1Loader
|
|
||||||
{
|
|
||||||
private final SoundEffect2Loader se2Loader = new SoundEffect2Loader();
|
|
||||||
private final SoundEffect3Loader se3Loader = new SoundEffect3Loader();
|
|
||||||
|
|
||||||
public SoundEffect1Definition load(InputStream in)
|
|
||||||
{
|
|
||||||
SoundEffect1Definition se = new SoundEffect1Definition();
|
|
||||||
|
|
||||||
load(se, in);
|
|
||||||
|
|
||||||
return se;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load(SoundEffect1Definition se, InputStream var1)
|
|
||||||
{
|
|
||||||
se.field1181 = se2Loader.load(var1);
|
|
||||||
se.field1173 = se2Loader.load(var1);
|
|
||||||
int var2 = var1.readUnsignedByte();
|
|
||||||
if (var2 != 0)
|
|
||||||
{
|
|
||||||
var1.setOffset(var1.getOffset() - 1);
|
|
||||||
se.field1174 = se2Loader.load(var1);
|
|
||||||
se.field1193 = se2Loader.load(var1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var2 = var1.readUnsignedByte();
|
|
||||||
if (var2 != 0)
|
|
||||||
{
|
|
||||||
var1.setOffset(var1.getOffset() - 1);
|
|
||||||
se.field1183 = se2Loader.load(var1);
|
|
||||||
se.field1192 = se2Loader.load(var1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var2 = var1.readUnsignedByte();
|
|
||||||
if (var2 != 0)
|
|
||||||
{
|
|
||||||
var1.setOffset(var1.getOffset() - 1);
|
|
||||||
se.field1178 = se2Loader.load(var1);
|
|
||||||
se.field1175 = se2Loader.load(var1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int var3 = 0; var3 < 10; ++var3)
|
|
||||||
{
|
|
||||||
int var4 = var1.readUnsignedShortSmart();
|
|
||||||
if (var4 == 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
se.field1180[var3] = var4;
|
|
||||||
se.field1179[var3] = var1.readShortSmart();
|
|
||||||
se.field1177[var3] = var1.readUnsignedShortSmart();
|
|
||||||
}
|
|
||||||
|
|
||||||
se.field1187 = var1.readUnsignedShortSmart();
|
|
||||||
se.field1184 = var1.readUnsignedShortSmart();
|
|
||||||
se.field1176 = var1.readUnsignedShort();
|
|
||||||
se.field1188 = var1.readUnsignedShort();
|
|
||||||
se.field1186 = new SoundEffect2Definition();
|
|
||||||
se.field1182 = se3Loader.load(var1, se.field1186);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.cache.definitions.loaders.sound;
|
|
||||||
|
|
||||||
import net.runelite.cache.definitions.sound.SoundEffect2Definition;
|
|
||||||
import net.runelite.cache.definitions.sound.SoundEffect3Definition;
|
|
||||||
import net.runelite.cache.io.InputStream;
|
|
||||||
|
|
||||||
public class SoundEffect3Loader
|
|
||||||
{
|
|
||||||
private final SoundEffect2Loader se2Loader = new SoundEffect2Loader();
|
|
||||||
|
|
||||||
public SoundEffect3Definition load(InputStream in, SoundEffect2Definition var2)
|
|
||||||
{
|
|
||||||
SoundEffect3Definition se = new SoundEffect3Definition();
|
|
||||||
|
|
||||||
load(se, in, var2);
|
|
||||||
|
|
||||||
return se;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load(SoundEffect3Definition se, InputStream var1, SoundEffect2Definition var2)
|
|
||||||
{
|
|
||||||
int var3 = var1.readUnsignedByte();
|
|
||||||
se.field1155[0] = var3 >> 4;
|
|
||||||
se.field1155[1] = var3 & 15;
|
|
||||||
if (var3 != 0)
|
|
||||||
{
|
|
||||||
se.field1156[0] = var1.readUnsignedShort();
|
|
||||||
se.field1156[1] = var1.readUnsignedShort();
|
|
||||||
int var4 = var1.readUnsignedByte();
|
|
||||||
|
|
||||||
int var5;
|
|
||||||
int var6;
|
|
||||||
for (var5 = 0; var5 < 2; ++var5)
|
|
||||||
{
|
|
||||||
for (var6 = 0; var6 < se.field1155[var5]; ++var6)
|
|
||||||
{
|
|
||||||
se.field1154[var5][0][var6] = var1.readUnsignedShort();
|
|
||||||
se.field1159[var5][0][var6] = var1.readUnsignedShort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var5 = 0; var5 < 2; ++var5)
|
|
||||||
{
|
|
||||||
for (var6 = 0; var6 < se.field1155[var5]; ++var6)
|
|
||||||
{
|
|
||||||
if ((var4 & 1 << var5 * 4 << var6) != 0)
|
|
||||||
{
|
|
||||||
se.field1154[var5][1][var6] = var1.readUnsignedShort();
|
|
||||||
se.field1159[var5][1][var6] = var1.readUnsignedShort();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
se.field1154[var5][1][var6] = se.field1154[var5][0][var6];
|
|
||||||
se.field1159[var5][1][var6] = se.field1159[var5][0][var6];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (var4 != 0 || se.field1156[1] != se.field1156[0])
|
|
||||||
{
|
|
||||||
se2Loader.method1144(var2, var1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int[] var7 = se.field1156;
|
|
||||||
se.field1156[1] = 0;
|
|
||||||
var7[0] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,39 +24,70 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.cache.definitions.loaders.sound;
|
package net.runelite.cache.definitions.loaders.sound;
|
||||||
|
|
||||||
|
import net.runelite.cache.definitions.sound.AudioEnvelopeDefinition;
|
||||||
import net.runelite.cache.definitions.sound.SoundEffectDefinition;
|
import net.runelite.cache.definitions.sound.SoundEffectDefinition;
|
||||||
import net.runelite.cache.definitions.sound.SoundEffect1Definition;
|
|
||||||
import net.runelite.cache.io.InputStream;
|
import net.runelite.cache.io.InputStream;
|
||||||
|
|
||||||
public class SoundEffectLoader
|
public class SoundEffectLoader
|
||||||
{
|
{
|
||||||
public SoundEffectDefinition load(byte[] b)
|
private final AudioEnvelopeLoader audioEnvelopeLoader = new AudioEnvelopeLoader();
|
||||||
|
|
||||||
|
public SoundEffectDefinition load(InputStream in, AudioEnvelopeDefinition audioEnvelope)
|
||||||
{
|
{
|
||||||
SoundEffectDefinition se = new SoundEffectDefinition();
|
SoundEffectDefinition soundEffect = new SoundEffectDefinition();
|
||||||
InputStream in = new InputStream(b);
|
|
||||||
|
|
||||||
load(se, in);
|
load(soundEffect, audioEnvelope, in);
|
||||||
|
|
||||||
return se;
|
return soundEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(SoundEffectDefinition se, InputStream var1)
|
private void load(SoundEffectDefinition soundEffect, AudioEnvelopeDefinition audioEnvelope, InputStream in)
|
||||||
{
|
{
|
||||||
for (int var2 = 0; var2 < 10; ++var2)
|
int id = in.readUnsignedByte();
|
||||||
|
soundEffect.pairs[0] = id >> 4;
|
||||||
|
soundEffect.pairs[1] = id & 15;
|
||||||
|
if (id != 0)
|
||||||
{
|
{
|
||||||
int var3 = var1.readUnsignedByte();
|
soundEffect.unity[0] = in.readUnsignedShort();
|
||||||
if (var3 != 0)
|
soundEffect.unity[1] = in.readUnsignedShort();
|
||||||
|
int track = in.readUnsignedByte();
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
var1.setOffset(var1.getOffset() - 1);
|
for (int j = 0; j < soundEffect.pairs[i]; ++j)
|
||||||
|
{
|
||||||
|
soundEffect.phases[i][0][j] = in.readUnsignedShort();
|
||||||
|
soundEffect.magnitudes[i][0][j] = in.readUnsignedShort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SoundEffect1Loader se1Loader = new SoundEffect1Loader();
|
for (int i = 0; i < 2; ++i)
|
||||||
SoundEffect1Definition se1 = se1Loader.load(var1);
|
{
|
||||||
|
for (int j = 0; j < soundEffect.pairs[i]; ++j)
|
||||||
|
{
|
||||||
|
if ((track & 1 << i * 4 << j) != 0)
|
||||||
|
{
|
||||||
|
soundEffect.phases[i][1][j] = in.readUnsignedShort();
|
||||||
|
soundEffect.magnitudes[i][1][j] = in.readUnsignedShort();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
soundEffect.phases[i][1][j] = soundEffect.phases[i][0][j];
|
||||||
|
soundEffect.magnitudes[i][1][j] = soundEffect.magnitudes[i][0][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
se.field1008[var2] = se1;
|
if (track != 0 || soundEffect.unity[1] != soundEffect.unity[0])
|
||||||
|
{
|
||||||
|
audioEnvelopeLoader.loadSegments(audioEnvelope, in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
se.field1006 = var1.readUnsignedShort();
|
{
|
||||||
se.field1009 = var1.readUnsignedShort();
|
int[] clean = soundEffect.unity;
|
||||||
|
soundEffect.unity[1] = 0;
|
||||||
|
clean[0] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,39 +24,39 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.cache.definitions.loaders.sound;
|
package net.runelite.cache.definitions.loaders.sound;
|
||||||
|
|
||||||
import net.runelite.cache.definitions.sound.SoundEffect2Definition;
|
import net.runelite.cache.definitions.sound.SoundEffectTrackDefinition;
|
||||||
|
import net.runelite.cache.definitions.sound.InstrumentDefinition;
|
||||||
import net.runelite.cache.io.InputStream;
|
import net.runelite.cache.io.InputStream;
|
||||||
|
|
||||||
public class SoundEffect2Loader
|
public class SoundEffectTrackLoader
|
||||||
{
|
{
|
||||||
public SoundEffect2Definition load(InputStream in)
|
public SoundEffectTrackDefinition load(byte[] b)
|
||||||
{
|
{
|
||||||
SoundEffect2Definition se = new SoundEffect2Definition();
|
SoundEffectTrackDefinition soundEffect = new SoundEffectTrackDefinition();
|
||||||
|
InputStream in = new InputStream(b);
|
||||||
|
|
||||||
load(se, in);
|
load(soundEffect, in);
|
||||||
|
|
||||||
return se;
|
return soundEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(SoundEffect2Definition se, InputStream var1)
|
private void load(SoundEffectTrackDefinition soundEffect, InputStream in)
|
||||||
{
|
{
|
||||||
se.field1087 = var1.readUnsignedByte();
|
for (int i = 0; i < 10; ++i)
|
||||||
se.field1088 = var1.readInt();
|
|
||||||
se.field1089 = var1.readInt();
|
|
||||||
this.method1144(se, var1);
|
|
||||||
}
|
|
||||||
|
|
||||||
final void method1144(SoundEffect2Definition se, InputStream var1)
|
|
||||||
{
|
|
||||||
se.field1092 = var1.readUnsignedByte();
|
|
||||||
se.field1086 = new int[se.field1092];
|
|
||||||
se.field1090 = new int[se.field1092];
|
|
||||||
|
|
||||||
for (int var2 = 0; var2 < se.field1092; ++var2)
|
|
||||||
{
|
{
|
||||||
se.field1086[var2] = var1.readUnsignedShort();
|
int volume = in.readUnsignedByte();
|
||||||
se.field1090[var2] = var1.readUnsignedShort();
|
if (volume != 0)
|
||||||
|
{
|
||||||
|
in.setOffset(in.getOffset() - 1);
|
||||||
|
|
||||||
|
InstrumentLoader instrumentLoader = new InstrumentLoader();
|
||||||
|
InstrumentDefinition instrument = instrumentLoader.load(in);
|
||||||
|
|
||||||
|
soundEffect.instruments[i] = instrument;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
soundEffect.start = in.readUnsignedShort();
|
||||||
|
soundEffect.end = in.readUnsignedShort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
81
cache/src/main/java/net/runelite/cache/definitions/sound/AudioEnvelopeDefinition.java
vendored
Normal file
81
cache/src/main/java/net/runelite/cache/definitions/sound/AudioEnvelopeDefinition.java
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.cache.definitions.sound;
|
||||||
|
|
||||||
|
public class AudioEnvelopeDefinition
|
||||||
|
{
|
||||||
|
public int segments = 2;
|
||||||
|
public int[] durations = new int[2];
|
||||||
|
public int[] phases = new int[2];
|
||||||
|
public int start;
|
||||||
|
public int end;
|
||||||
|
public int form;
|
||||||
|
public int ticks;
|
||||||
|
public int phaseIndex;
|
||||||
|
public int step;
|
||||||
|
public int amplitude;
|
||||||
|
public int max;
|
||||||
|
|
||||||
|
public AudioEnvelopeDefinition()
|
||||||
|
{
|
||||||
|
this.durations[0] = 0;
|
||||||
|
this.durations[1] = '\uffff';
|
||||||
|
this.phases[0] = 0;
|
||||||
|
this.phases[1] = '\uffff';
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int step(int var1)
|
||||||
|
{
|
||||||
|
if (this.max >= this.ticks)
|
||||||
|
{
|
||||||
|
this.amplitude = this.phases[this.phaseIndex++] << 15;
|
||||||
|
|
||||||
|
if (this.phaseIndex >= this.segments)
|
||||||
|
{
|
||||||
|
this.phaseIndex = this.segments - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ticks = (int) ((double) this.durations[this.phaseIndex] / 65536.0 * (double) var1);
|
||||||
|
|
||||||
|
if (this.ticks > this.max)
|
||||||
|
{
|
||||||
|
this.step = ((this.phases[this.phaseIndex] << 15) - this.amplitude) / (this.ticks - this.max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.amplitude += this.step;
|
||||||
|
++this.max;
|
||||||
|
|
||||||
|
return this.amplitude - this.step >> 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void reset()
|
||||||
|
{
|
||||||
|
this.ticks = 0;
|
||||||
|
this.phaseIndex = 0;
|
||||||
|
this.step = 0;
|
||||||
|
this.amplitude = 0;
|
||||||
|
this.max = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
356
cache/src/main/java/net/runelite/cache/definitions/sound/InstrumentDefinition.java
vendored
Normal file
356
cache/src/main/java/net/runelite/cache/definitions/sound/InstrumentDefinition.java
vendored
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.cache.definitions.sound;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class InstrumentDefinition
|
||||||
|
{
|
||||||
|
public AudioEnvelopeDefinition volume;
|
||||||
|
public AudioEnvelopeDefinition pitchModifier;
|
||||||
|
public AudioEnvelopeDefinition field1175;
|
||||||
|
public AudioEnvelopeDefinition release;
|
||||||
|
public AudioEnvelopeDefinition volumeMultiplier;
|
||||||
|
public AudioEnvelopeDefinition volumeMultiplierAmplitude;
|
||||||
|
public AudioEnvelopeDefinition pitchModifierAmplitude;
|
||||||
|
public AudioEnvelopeDefinition pitch;
|
||||||
|
|
||||||
|
public int[] oscillatorDelays = new int[]
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
public int[] oscillatorPitch = new int[]
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
public int[] oscillatorVolume = new int[]
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
public SoundEffectDefinition filter;
|
||||||
|
public AudioEnvelopeDefinition filterEnvelope;
|
||||||
|
|
||||||
|
static int[] samples = new int[220500];
|
||||||
|
|
||||||
|
static int[] NOISE = new int[32768];
|
||||||
|
static int[] AUDIO_SINE = new int[32768];
|
||||||
|
|
||||||
|
static int[] phases = new int[5];
|
||||||
|
static int[] delays = new int[5];
|
||||||
|
|
||||||
|
static int[] volumeSteps = new int[5];
|
||||||
|
static int[] pitchSteps = new int[5];
|
||||||
|
static int[] pitchBaseSteps = new int[5];
|
||||||
|
|
||||||
|
public int duration = 500;
|
||||||
|
public int delayDecay = 100;
|
||||||
|
public int delayTime = 0;
|
||||||
|
public int offset = 0;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
Random random = new Random(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 32768; ++i)
|
||||||
|
{
|
||||||
|
InstrumentDefinition.NOISE[i] = (random.nextInt() & 2) - 1;
|
||||||
|
InstrumentDefinition.AUDIO_SINE[i] = (int) (Math.sin((double) i / 5215.1903) * 16384.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int[] synthesize(int var1, int var2)
|
||||||
|
{
|
||||||
|
int var16;
|
||||||
|
int var15;
|
||||||
|
int var14;
|
||||||
|
int var11;
|
||||||
|
int var12;
|
||||||
|
int var13;
|
||||||
|
|
||||||
|
InstrumentDefinition.method3854(samples, 0, var1);
|
||||||
|
|
||||||
|
if (var2 < 10)
|
||||||
|
{
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
double var3 = (double) var1 / ((double) var2 + 0.0);
|
||||||
|
|
||||||
|
this.pitch.reset();
|
||||||
|
this.volume.reset();
|
||||||
|
|
||||||
|
int var5 = 0;
|
||||||
|
int var6 = 0;
|
||||||
|
int var7 = 0;
|
||||||
|
|
||||||
|
if (this.pitchModifier != null)
|
||||||
|
{
|
||||||
|
this.pitchModifier.reset();
|
||||||
|
this.pitchModifierAmplitude.reset();
|
||||||
|
|
||||||
|
var5 = (int) ((double) (this.pitchModifier.end - this.pitchModifier.start) * 32.768 / var3);
|
||||||
|
var6 = (int) ((double) this.pitchModifier.start * 32.768 / var3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int var8 = 0;
|
||||||
|
int var9 = 0;
|
||||||
|
int var10 = 0;
|
||||||
|
|
||||||
|
if (this.volumeMultiplier != null)
|
||||||
|
{
|
||||||
|
this.volumeMultiplier.reset();
|
||||||
|
this.volumeMultiplierAmplitude.reset();
|
||||||
|
|
||||||
|
var8 = (int) ((double) (this.volumeMultiplier.end - this.volumeMultiplier.start) * 32.768 / var3);
|
||||||
|
var9 = (int) ((double) this.volumeMultiplier.start * 32.768 / var3);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var11 = 0; var11 < 5; ++var11)
|
||||||
|
{
|
||||||
|
if (this.oscillatorVolume[var11] == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstrumentDefinition.phases[var11] = 0;
|
||||||
|
InstrumentDefinition.delays[var11] = (int) ((double) this.oscillatorDelays[var11] * var3);
|
||||||
|
InstrumentDefinition.volumeSteps[var11] = (this.oscillatorVolume[var11] << 14) / 100;
|
||||||
|
InstrumentDefinition.pitchSteps[var11] = (int) ((double) (this.pitch.end - this.pitch.start) * 32.768 * Math.pow(1.0057929410678534, this.oscillatorPitch[var11]) / var3);
|
||||||
|
InstrumentDefinition.pitchBaseSteps[var11] = (int) ((double) this.pitch.start * 32.768 / var3);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var11 = 0; var11 < var1; ++var11)
|
||||||
|
{
|
||||||
|
var12 = this.pitch.step(var1);
|
||||||
|
var13 = this.volume.step(var1);
|
||||||
|
|
||||||
|
if (this.pitchModifier != null)
|
||||||
|
{
|
||||||
|
var14 = this.pitchModifier.step(var1);
|
||||||
|
var15 = this.pitchModifierAmplitude.step(var1);
|
||||||
|
var12 += this.evaluateWave(var7, var15, this.pitchModifier.form) >> 1;
|
||||||
|
var7 = var7 + var6 + (var14 * var5 >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.volumeMultiplier != null)
|
||||||
|
{
|
||||||
|
var14 = this.volumeMultiplier.step(var1);
|
||||||
|
var15 = this.volumeMultiplierAmplitude.step(var1);
|
||||||
|
var13 = var13 * ((this.evaluateWave(var10, var15, this.volumeMultiplier.form) >> 1) + 32768) >> 15;
|
||||||
|
var10 = var10 + var9 + (var14 * var8 >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var14 = 0; var14 < 5; ++var14)
|
||||||
|
{
|
||||||
|
if (this.oscillatorVolume[var14] == 0 || (var15 = delays[var14] + var11) >= var1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] arrn = samples;
|
||||||
|
int n = var15;
|
||||||
|
arrn[n] = arrn[n] + this.evaluateWave(phases[var14], var13 * volumeSteps[var14] >> 15, this.pitch.form);
|
||||||
|
int[] arrn2 = phases;
|
||||||
|
int n2 = var14;
|
||||||
|
arrn2[n2] = arrn2[n2] + ((var12 * pitchSteps[var14] >> 16) + pitchBaseSteps[var14]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.release != null)
|
||||||
|
{
|
||||||
|
this.release.reset();
|
||||||
|
this.field1175.reset();
|
||||||
|
|
||||||
|
var11 = 0;
|
||||||
|
boolean var20 = true;
|
||||||
|
|
||||||
|
for (var14 = 0; var14 < var1; ++var14)
|
||||||
|
{
|
||||||
|
var15 = this.release.step(var1);
|
||||||
|
var16 = this.field1175.step(var1);
|
||||||
|
var12 = var20 ? (var15 * (this.release.end - this.release.start) >> 8) + this.release.start : (var16 * (this.release.end - this.release.start) >> 8) + this.release.start;
|
||||||
|
if ((var11 += 256) >= var12)
|
||||||
|
{
|
||||||
|
var11 = 0;
|
||||||
|
}
|
||||||
|
if (!var20)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
InstrumentDefinition.samples[var14] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.delayTime > 0 && this.delayDecay > 0)
|
||||||
|
{
|
||||||
|
for (var12 = var11 = (int) ((double) this.delayTime * var3); var12 < var1; ++var12)
|
||||||
|
{
|
||||||
|
int[] arrn = samples;
|
||||||
|
int n = var12;
|
||||||
|
|
||||||
|
arrn[n] = arrn[n] + samples[var12 - var11] * this.delayDecay / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.filter.pairs[0] > 0 || this.filter.pairs[1] > 0)
|
||||||
|
{
|
||||||
|
this.filterEnvelope.reset();
|
||||||
|
|
||||||
|
var11 = this.filterEnvelope.step(var1 + 1);
|
||||||
|
var12 = this.filter.compute(0, (float) var11 / 65536.0f);
|
||||||
|
var13 = this.filter.compute(1, (float) var11 / 65536.0f);
|
||||||
|
|
||||||
|
if (var1 >= var12 + var13)
|
||||||
|
{
|
||||||
|
int var17;
|
||||||
|
|
||||||
|
var14 = 0;
|
||||||
|
var15 = var13;
|
||||||
|
|
||||||
|
if (var13 > var1 - var12)
|
||||||
|
{
|
||||||
|
var15 = var1 - var12;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (var14 < var15)
|
||||||
|
{
|
||||||
|
var16 = (int) ((long) samples[var14 + var12] * (long) SoundEffectDefinition.fowardMultiplier >> 16);
|
||||||
|
|
||||||
|
for (var17 = 0; var17 < var12; ++var17)
|
||||||
|
{
|
||||||
|
var16 += (int) ((long) samples[var14 + var12 - 1 - var17] * (long) SoundEffectDefinition.coefficients[0][var17] >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var17 = 0; var17 < var14; ++var17)
|
||||||
|
{
|
||||||
|
var16 -= (int) ((long) samples[var14 - 1 - var17] * (long) SoundEffectDefinition.coefficients[1][var17] >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
InstrumentDefinition.samples[var14] = var16;
|
||||||
|
var11 = this.filterEnvelope.step(var1 + 1);
|
||||||
|
++var14;
|
||||||
|
}
|
||||||
|
var15 = 128;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int var18;
|
||||||
|
|
||||||
|
if (var15 > var1 - var12)
|
||||||
|
{
|
||||||
|
var15 = var1 - var12;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (var14 < var15)
|
||||||
|
{
|
||||||
|
var17 = (int) ((long) samples[var14 + var12] * (long) SoundEffectDefinition.fowardMultiplier >> 16);
|
||||||
|
|
||||||
|
for (var18 = 0; var18 < var12; ++var18)
|
||||||
|
{
|
||||||
|
var17 += (int) ((long) samples[var14 + var12 - 1 - var18] * (long) SoundEffectDefinition.coefficients[0][var18] >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var18 = 0; var18 < var13; ++var18)
|
||||||
|
{
|
||||||
|
var17 -= (int) ((long) samples[var14 - 1 - var18] * (long) SoundEffectDefinition.coefficients[1][var18] >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
InstrumentDefinition.samples[var14] = var17;
|
||||||
|
var11 = this.filterEnvelope.step(var1 + 1);
|
||||||
|
++var14;
|
||||||
|
}
|
||||||
|
if (var14 >= var1 - var12)
|
||||||
|
{
|
||||||
|
while (var14 < var1)
|
||||||
|
{
|
||||||
|
var17 = 0;
|
||||||
|
for (var18 = var14 + var12 - var1; var18 < var12; ++var18)
|
||||||
|
{
|
||||||
|
var17 += (int) ((long) samples[var14 + var12 - 1 - var18]
|
||||||
|
* (long) SoundEffectDefinition.coefficients[0][var18] >> 16);
|
||||||
|
}
|
||||||
|
for (var18 = 0; var18 < var13; ++var18)
|
||||||
|
{
|
||||||
|
var17 -= (int) ((long) samples[var14 - 1 - var18]
|
||||||
|
* (long) SoundEffectDefinition.coefficients[1][var18] >> 16);
|
||||||
|
}
|
||||||
|
InstrumentDefinition.samples[var14] = var17;
|
||||||
|
this.filterEnvelope.step(var1 + 1);
|
||||||
|
++var14;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var12 = this.filter.compute(0, (float) var11 / 65536.0f);
|
||||||
|
var13 = this.filter.compute(1, (float) var11 / 65536.0f);
|
||||||
|
var15 += 128;
|
||||||
|
}
|
||||||
|
while (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var11 = 0; var11 < var1; ++var11)
|
||||||
|
{
|
||||||
|
if (samples[var11] < -32768)
|
||||||
|
{
|
||||||
|
InstrumentDefinition.samples[var11] = -32768;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samples[var11] <= 32767)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstrumentDefinition.samples[var11] = 32767;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void method3854(int[] var1, int var2, int var3)
|
||||||
|
{
|
||||||
|
var3 = var3 + var2 - 7;
|
||||||
|
|
||||||
|
while (var2 < var3)
|
||||||
|
{
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
var1[var2++] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (var2 < (var3 += 7))
|
||||||
|
{
|
||||||
|
var1[var2++] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int evaluateWave(int var1, int var2, int var3)
|
||||||
|
{
|
||||||
|
return var3 == 1 ? ((var1 & 32767) < 16384 ? var2 : -var2) : (var3 == 2 ? AUDIO_SINE[var1 & 32767] * var2 >> 14 : (var3 == 3 ? (var2 * (var1 & 32767) >> 14) - var2 : (var3 == 4 ? var2 * NOISE[var1 / 2607 & 32767] : 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,102 @@ package net.runelite.cache.definitions.sound;
|
|||||||
|
|
||||||
public class SoundEffectDefinition
|
public class SoundEffectDefinition
|
||||||
{
|
{
|
||||||
public int field1006;
|
public int[][][] phases = new int[2][2][4];
|
||||||
public SoundEffect1Definition[] field1008 = new SoundEffect1Definition[10];
|
public int[] pairs = new int[2];
|
||||||
public int field1009;
|
public int[] unity = new int[2];
|
||||||
}
|
public int[][][] magnitudes = new int[2][2][4];
|
||||||
|
|
||||||
|
public static float[][] minCoefficients = new float[2][8];
|
||||||
|
public static int[][] coefficients = new int[2][8];
|
||||||
|
public static float fowardMinCoefficientMultiplier;
|
||||||
|
public static int fowardMultiplier;
|
||||||
|
|
||||||
|
public int compute(int var1, float var2)
|
||||||
|
{
|
||||||
|
float var3;
|
||||||
|
int var4;
|
||||||
|
|
||||||
|
if (var1 == 0)
|
||||||
|
{
|
||||||
|
var3 = (float) this.unity[0] + (float) (this.unity[1] - this.unity[0]) * var2;
|
||||||
|
|
||||||
|
fowardMinCoefficientMultiplier = (float) Math.pow(0.1, (var3 *= 0.0030517578f) / 20.0f);
|
||||||
|
fowardMultiplier = (int) (fowardMinCoefficientMultiplier * 65536.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.pairs[var1] == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var3 = this.interpolateMagniture(var1, 0, var2);
|
||||||
|
|
||||||
|
minCoefficients[var1][0] = -2.0f * var3 * (float) Math.cos(this.interpolatePhase(var1, 0, var2));
|
||||||
|
minCoefficients[var1][1] = var3 * var3;
|
||||||
|
|
||||||
|
for (var4 = 1; var4 < this.pairs[var1]; ++var4)
|
||||||
|
{
|
||||||
|
var3 = this.interpolateMagniture(var1, var4, var2);
|
||||||
|
|
||||||
|
float var5 = -2.0f * var3 * (float) Math.cos(this.interpolatePhase(var1, var4, var2));
|
||||||
|
float var6 = var3 * var3;
|
||||||
|
|
||||||
|
minCoefficients[var1][var4 * 2 + 1] = minCoefficients[var1][var4 * 2 - 1] * var6;
|
||||||
|
minCoefficients[var1][var4 * 2] = minCoefficients[var1][var4 * 2 - 1] * var5 + minCoefficients[var1][var4 * 2 - 2] * var6;
|
||||||
|
|
||||||
|
for (int var7 = var4 * 2 - 1; var7 >= 2; --var7)
|
||||||
|
{
|
||||||
|
float[] arrf = minCoefficients[var1];
|
||||||
|
int n = var7;
|
||||||
|
|
||||||
|
arrf[n] = arrf[n] + (minCoefficients[var1][var7 - 1] * var5 + minCoefficients[var1][var7 - 2] * var6);
|
||||||
|
}
|
||||||
|
|
||||||
|
float[] arrf = minCoefficients[var1];
|
||||||
|
arrf[1] = arrf[1] + (minCoefficients[var1][0] * var5 + var6);
|
||||||
|
|
||||||
|
float[] arrf2 = minCoefficients[var1];
|
||||||
|
arrf2[0] = arrf2[0] + var5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var1 == 0)
|
||||||
|
{
|
||||||
|
var4 = 0;
|
||||||
|
while (var4 < this.pairs[0] * 2)
|
||||||
|
{
|
||||||
|
float[] arrf = minCoefficients[0];
|
||||||
|
int n = var4++;
|
||||||
|
|
||||||
|
arrf[n] = arrf[n] * fowardMinCoefficientMultiplier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var4 = 0; var4 < this.pairs[var1] * 2; ++var4)
|
||||||
|
{
|
||||||
|
coefficients[var1][var4] = (int) (minCoefficients[var1][var4] * 65536.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.pairs[var1] * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float interpolateMagniture(int var1, int var2, float var3)
|
||||||
|
{
|
||||||
|
float var4 = (float) this.magnitudes[var1][0][var2] + var3 * (float) (this.magnitudes[var1][1][var2] - this.magnitudes[var1][0][var2]);
|
||||||
|
|
||||||
|
return 1.0f - (float) Math.pow(10.0, (-(var4 *= 0.0015258789f)) / 20.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float interpolatePhase(int var1, int var2, float var3)
|
||||||
|
{
|
||||||
|
float var4 = (float) this.phases[var1][0][var2] + var3 * (float) (this.phases[var1][1][var2] - this.phases[var1][0][var2]);
|
||||||
|
|
||||||
|
return normalise(var4 *= 1.2207031E-4f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float normalise(float var1)
|
||||||
|
{
|
||||||
|
float var2 = 32.703197f * (float) Math.pow(2.0, var1);
|
||||||
|
|
||||||
|
return var2 * 3.1415927f / 11025.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
84
cache/src/main/java/net/runelite/cache/definitions/sound/SoundEffectTrackDefinition.java
vendored
Normal file
84
cache/src/main/java/net/runelite/cache/definitions/sound/SoundEffectTrackDefinition.java
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.cache.definitions.sound;
|
||||||
|
|
||||||
|
public class SoundEffectTrackDefinition
|
||||||
|
{
|
||||||
|
public int start;
|
||||||
|
public InstrumentDefinition[] instruments = new InstrumentDefinition[10];
|
||||||
|
public int end;
|
||||||
|
|
||||||
|
public final byte[] mix()
|
||||||
|
{
|
||||||
|
int var2;
|
||||||
|
int var1 = 0;
|
||||||
|
|
||||||
|
for (var2 = 0; var2 < 10; ++var2)
|
||||||
|
{
|
||||||
|
if (this.instruments[var2] == null || this.instruments[var2].duration + this.instruments[var2].offset <= var1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var1 = this.instruments[var2].duration + this.instruments[var2].offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var1 == 0)
|
||||||
|
{
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var2 = var1 * 22050 / 1000;
|
||||||
|
|
||||||
|
byte[] var3 = new byte[var2];
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
if (this.instruments[i] == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int var5 = this.instruments[i].duration * 22050 / 1000;
|
||||||
|
int var6 = this.instruments[i].offset * 22050 / 1000;
|
||||||
|
|
||||||
|
int[] var7 = this.instruments[i].synthesize(var5, this.instruments[i].duration);
|
||||||
|
|
||||||
|
for (int j = 0; j < var5; ++j)
|
||||||
|
{
|
||||||
|
int var9 = (var7[j] >> 8) + var3[j + var6];
|
||||||
|
|
||||||
|
if ((var9 + 128 & -256) != 0)
|
||||||
|
{
|
||||||
|
var9 = var9 >> 31 ^ 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
var3[j + var6] = (byte) var9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return var3;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,11 +27,16 @@ package net.runelite.cache;
|
|||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import net.runelite.cache.definitions.loaders.sound.SoundEffectLoader;
|
import net.runelite.cache.definitions.loaders.sound.SoundEffectTrackLoader;
|
||||||
import net.runelite.cache.definitions.sound.SoundEffectDefinition;
|
import net.runelite.cache.definitions.sound.SoundEffectTrackDefinition;
|
||||||
import net.runelite.cache.fs.Archive;
|
import net.runelite.cache.fs.Archive;
|
||||||
import net.runelite.cache.fs.Index;
|
import net.runelite.cache.fs.Index;
|
||||||
import net.runelite.cache.fs.Storage;
|
import net.runelite.cache.fs.Storage;
|
||||||
@@ -42,6 +47,11 @@ import org.junit.rules.TemporaryFolder;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.sound.sampled.AudioFileFormat;
|
||||||
|
import javax.sound.sampled.AudioFormat;
|
||||||
|
import javax.sound.sampled.AudioInputStream;
|
||||||
|
import javax.sound.sampled.AudioSystem;
|
||||||
|
|
||||||
public class SoundEffectsDumperTest
|
public class SoundEffectsDumperTest
|
||||||
{
|
{
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SoundEffectsDumperTest.class);
|
private static final Logger logger = LoggerFactory.getLogger(SoundEffectsDumperTest.class);
|
||||||
@@ -68,14 +78,68 @@ public class SoundEffectsDumperTest
|
|||||||
{
|
{
|
||||||
byte[] contents = archive.decompress(storage.loadArchive(archive));
|
byte[] contents = archive.decompress(storage.loadArchive(archive));
|
||||||
|
|
||||||
SoundEffectLoader soundEffectLoader = new SoundEffectLoader();
|
SoundEffectTrackLoader setLoader = new SoundEffectTrackLoader();
|
||||||
SoundEffectDefinition soundEffect = soundEffectLoader.load(contents);
|
SoundEffectTrackDefinition soundEffect = setLoader.load(contents);
|
||||||
|
|
||||||
Files.asCharSink(new File(dumpDir, archive.getArchiveId() + ".json"), Charset.defaultCharset()).write(gson.toJson(soundEffect));
|
Files.write(gson.toJson(soundEffect), new File(dumpDir, archive.getArchiveId() + ".json"), Charset.defaultCharset());
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("Dumped {} sound effects to {}", count, dumpDir);
|
logger.info("Dumped {} sound effects to {}", count, dumpDir);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Test
|
||||||
|
public void extractWavTest() throws IOException
|
||||||
|
{
|
||||||
|
File dumpDir = folder.newFolder();
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
try (Store store = new Store(StoreLocation.LOCATION))
|
||||||
|
{
|
||||||
|
store.load();
|
||||||
|
|
||||||
|
Storage storage = store.getStorage();
|
||||||
|
Index index = store.getIndex(IndexType.SOUNDEFFECTS);
|
||||||
|
|
||||||
|
for (Archive archive : index.getArchives())
|
||||||
|
{
|
||||||
|
byte[] contents = archive.decompress(storage.loadArchive(archive));
|
||||||
|
|
||||||
|
SoundEffectTrackLoader setLoader = new SoundEffectTrackLoader();
|
||||||
|
SoundEffectTrackDefinition soundEffect = setLoader.load(contents);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Object audioStream;
|
||||||
|
byte[] data = soundEffect.mix();
|
||||||
|
|
||||||
|
AudioFormat audioFormat = new AudioFormat(22050.0f, 8, 1, true, false);
|
||||||
|
audioStream = new AudioInputStream(new ByteArrayInputStream(data), audioFormat, data.length);
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
AudioSystem.write((AudioInputStream) audioStream, AudioFileFormat.Type.WAVE, bos);
|
||||||
|
data = bos.toByteArray();
|
||||||
|
|
||||||
|
FileOutputStream fos = new FileOutputStream(new File(dumpDir, archive.getArchiveId() + ".wav"));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fos.write(data);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Dumped {} sound effects to {}", count, dumpDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
pom.xml
2
pom.xml
@@ -50,7 +50,7 @@
|
|||||||
<mockito.version>1.10.19</mockito.version>
|
<mockito.version>1.10.19</mockito.version>
|
||||||
<sql2o.version>1.6.0</sql2o.version>
|
<sql2o.version>1.6.0</sql2o.version>
|
||||||
<minio.version>3.0.6</minio.version>
|
<minio.version>3.0.6</minio.version>
|
||||||
<okhttp3.version>4.0.0</okhttp3.version>
|
<okhttp3.version>3.14.0</okhttp3.version>
|
||||||
<zlika.reproducible.build.maven.plugin.version>0.7</zlika.reproducible.build.maven.plugin.version>
|
<zlika.reproducible.build.maven.plugin.version>0.7</zlika.reproducible.build.maven.plugin.version>
|
||||||
|
|
||||||
<maven.jar.plugin.version>3.1.2</maven.jar.plugin.version>
|
<maven.jar.plugin.version>3.1.2</maven.jar.plugin.version>
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ public final class AnimationID
|
|||||||
public static final int FARMING_PLANT_SEED = 2291;
|
public static final int FARMING_PLANT_SEED = 2291;
|
||||||
public static final int FARMING_HARVEST_FLOWER = 2292;
|
public static final int FARMING_HARVEST_FLOWER = 2292;
|
||||||
public static final int FARMING_MIX_ULTRACOMPOST = 7699;
|
public static final int FARMING_MIX_ULTRACOMPOST = 7699;
|
||||||
|
public static final int FARMING_HARVEST_ALLOTMENT = 830;
|
||||||
|
|
||||||
// Lunar spellbook
|
// Lunar spellbook
|
||||||
public static final int ENERGY_TRANSFER_VENGEANCE_OTHER = 4411;
|
public static final int ENERGY_TRANSFER_VENGEANCE_OTHER = 4411;
|
||||||
@@ -315,7 +316,7 @@ public final class AnimationID
|
|||||||
public static final int DAG_SUPREME = 2855;
|
public static final int DAG_SUPREME = 2855;
|
||||||
|
|
||||||
// Lizardman shaman
|
// Lizardman shaman
|
||||||
public static final int LIZARDMAN_SHAMAN_SPAWN = 2855;
|
public static final int LIZARDMAN_SHAMAN_SPAWN = 7157;
|
||||||
|
|
||||||
// Combat counter
|
// Combat counter
|
||||||
public static final int BARRAGE_ANIMATION = 1979;
|
public static final int BARRAGE_ANIMATION = 1979;
|
||||||
|
|||||||
@@ -1353,6 +1353,20 @@ public interface Client extends GameShell
|
|||||||
*/
|
*/
|
||||||
void setInterpolateObjectAnimations(boolean interpolate);
|
void setInterpolateObjectAnimations(boolean interpolate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether animation smoothing is enabled for widgets.
|
||||||
|
*
|
||||||
|
* @return true if widget animation smoothing is enabled, false otherwise
|
||||||
|
*/
|
||||||
|
boolean isInterpolateWidgetAnimations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the animation smoothing state for widgets.
|
||||||
|
*
|
||||||
|
* @param interpolate the new smoothing state
|
||||||
|
*/
|
||||||
|
void setInterpolateWidgetAnimations(boolean interpolate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the logged in player is in an instanced region.
|
* Checks whether the logged in player is in an instanced region.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -82,4 +82,16 @@ public enum InventoryID
|
|||||||
{
|
{
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static InventoryID getValue(int value)
|
||||||
|
{
|
||||||
|
for (InventoryID e: InventoryID.values())
|
||||||
|
{
|
||||||
|
if (e.id == value)
|
||||||
|
{
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ import net.runelite.api.ItemContainer;
|
|||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event called whenever the stack size of an {@link api.Item}
|
* An event called whenever the stack size of an {@link net.runelite.api.Item}
|
||||||
* in an {@link ItemContainer} is modified.
|
* in an {@link ItemContainer} is modified.
|
||||||
* <p>
|
* <p>
|
||||||
* Examples of when this event may trigger include:
|
* Examples of when this event may trigger include:
|
||||||
@@ -41,6 +41,11 @@ import lombok.Value;
|
|||||||
@Value
|
@Value
|
||||||
public class ItemContainerChanged
|
public class ItemContainerChanged
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The modified container's ID.
|
||||||
|
*/
|
||||||
|
private final int containerId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The modified item container.
|
* The modified item container.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -290,6 +290,16 @@
|
|||||||
<version>3.2.0</version>
|
<version>3.2.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpcore</artifactId>
|
||||||
|
<version>4.4.11</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpmime</artifactId>
|
||||||
|
<version>4.5.9</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -385,6 +385,18 @@ public class ItemManager
|
|||||||
* @return item price
|
* @return item price
|
||||||
*/
|
*/
|
||||||
public int getItemPrice(int itemID)
|
public int getItemPrice(int itemID)
|
||||||
|
{
|
||||||
|
return getItemPrice(itemID, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up an item's price
|
||||||
|
*
|
||||||
|
* @param itemID item id
|
||||||
|
* @param ignoreUntradeableMap should the price returned ignore the {@link UntradeableItemMapping}
|
||||||
|
* @return item price
|
||||||
|
*/
|
||||||
|
public int getItemPrice(int itemID, boolean ignoreUntradeableMap)
|
||||||
{
|
{
|
||||||
if (itemID == ItemID.COINS_995)
|
if (itemID == ItemID.COINS_995)
|
||||||
{
|
{
|
||||||
@@ -395,10 +407,13 @@ public class ItemManager
|
|||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
UntradeableItemMapping p = UntradeableItemMapping.map(ItemVariationMapping.map(itemID));
|
if (!ignoreUntradeableMap)
|
||||||
if (p != null)
|
|
||||||
{
|
{
|
||||||
return getItemPrice(p.getPriceID()) * p.getQuantity();
|
UntradeableItemMapping p = UntradeableItemMapping.map(ItemVariationMapping.map(itemID));
|
||||||
|
if (p != null)
|
||||||
|
{
|
||||||
|
return getItemPrice(p.getPriceID()) * p.getQuantity();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int price = 0;
|
int price = 0;
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import java.nio.file.WatchService;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.client.RuneLite;
|
import net.runelite.client.RuneLite;
|
||||||
import net.runelite.client.config.Config;
|
import net.runelite.client.config.Config;
|
||||||
@@ -154,7 +155,6 @@ public class PluginWatcher extends Thread
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Loading plugin from {}", file);
|
log.info("Loading plugin from {}", file);
|
||||||
load(file);
|
load(file);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,4 +65,14 @@ public interface AnimationSmoothingConfig extends Config
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "smoothWidgetAnimations",
|
||||||
|
name = "Smooth Widget Animations",
|
||||||
|
description = "Configures whether the widget animations are smooth or not",
|
||||||
|
position = 4
|
||||||
|
)
|
||||||
|
default boolean smoothWidgetAnimations()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ public class AnimationSmoothingPlugin extends Plugin
|
|||||||
client.setInterpolatePlayerAnimations(false);
|
client.setInterpolatePlayerAnimations(false);
|
||||||
client.setInterpolateNpcAnimations(false);
|
client.setInterpolateNpcAnimations(false);
|
||||||
client.setInterpolateObjectAnimations(false);
|
client.setInterpolateObjectAnimations(false);
|
||||||
|
client.setInterpolateWidgetAnimations(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -85,5 +86,6 @@ public class AnimationSmoothingPlugin extends Plugin
|
|||||||
client.setInterpolatePlayerAnimations(config.smoothPlayerAnimations());
|
client.setInterpolatePlayerAnimations(config.smoothPlayerAnimations());
|
||||||
client.setInterpolateNpcAnimations(config.smoothNpcAnimations());
|
client.setInterpolateNpcAnimations(config.smoothNpcAnimations());
|
||||||
client.setInterpolateObjectAnimations(config.smoothObjectAnimations());
|
client.setInterpolateObjectAnimations(config.smoothObjectAnimations());
|
||||||
|
client.setInterpolateWidgetAnimations(config.smoothWidgetAnimations());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ enum Boss
|
|||||||
KRAKEN(NpcID.KRAKEN, 8400, ChronoUnit.MILLIS, ItemID.PET_KRAKEN),
|
KRAKEN(NpcID.KRAKEN, 8400, ChronoUnit.MILLIS, ItemID.PET_KRAKEN),
|
||||||
KALPHITE_QUEEN(NpcID.KALPHITE_QUEEN_965, 30, ChronoUnit.SECONDS, ItemID.KALPHITE_PRINCESS),
|
KALPHITE_QUEEN(NpcID.KALPHITE_QUEEN_965, 30, ChronoUnit.SECONDS, ItemID.KALPHITE_PRINCESS),
|
||||||
DUSK(NpcID.DUSK_7889, 2, ChronoUnit.MINUTES, ItemID.NOON),
|
DUSK(NpcID.DUSK_7889, 2, ChronoUnit.MINUTES, ItemID.NOON),
|
||||||
ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA);
|
ALCHEMICAL_HYDRA(NpcID.ALCHEMICAL_HYDRA_8622, 25200, ChronoUnit.MILLIS, ItemID.IKKLE_HYDRA),
|
||||||
|
SARACHNIS(NpcID.SARACHNIS, 30, ChronoUnit.SECONDS, ItemID.SRARACHA);
|
||||||
|
|
||||||
private static final Map<Integer, Boss> bosses;
|
private static final Map<Integer, Boss> bosses;
|
||||||
|
|
||||||
|
|||||||
@@ -86,4 +86,15 @@ public interface ChatFilterConfig extends Config
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "filterLogin",
|
||||||
|
name = "Filter Logged In/Out Messages",
|
||||||
|
description = "Filter your private chat to remove logged in/out messages",
|
||||||
|
position = 6
|
||||||
|
)
|
||||||
|
default boolean filterLogin()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,13 @@ public class ChatFilterPlugin extends Plugin
|
|||||||
case FRIENDSCHAT:
|
case FRIENDSCHAT:
|
||||||
case GAMEMESSAGE:
|
case GAMEMESSAGE:
|
||||||
break;
|
break;
|
||||||
|
case LOGINLOGOUTNOTIFICATION:
|
||||||
|
if (config.filterLogin())
|
||||||
|
{
|
||||||
|
// Block the message
|
||||||
|
intStack[intStackSize - 3] = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,14 @@
|
|||||||
package net.runelite.client.plugins.config;
|
package net.runelite.client.plugins.config;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import net.runelite.api.MenuAction;
|
import net.runelite.api.MenuAction;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.config.ChatColorConfig;
|
import net.runelite.client.config.ChatColorConfig;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
@@ -41,6 +44,7 @@ import net.runelite.client.plugins.Plugin;
|
|||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.plugins.PluginManager;
|
import net.runelite.client.plugins.PluginManager;
|
||||||
import net.runelite.client.ui.ClientToolbar;
|
import net.runelite.client.ui.ClientToolbar;
|
||||||
|
import net.runelite.client.ui.ClientUI;
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||||
@@ -97,9 +101,25 @@ public class ConfigPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
public void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
clientToolbar.removeNavigation(navButton);
|
clientToolbar.removeNavigation(navButton);
|
||||||
|
RuneLite.getInjector().getInstance(ClientThread.class).invokeLater(() ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConfigPanel.pluginList.clear();
|
||||||
|
pluginManager.setPluginEnabled(this, true);
|
||||||
|
pluginManager.startPlugin(this);
|
||||||
|
Method expand = ClientUI.class.getDeclaredMethod("expand", NavigationButton.class);
|
||||||
|
expand.setAccessible(true);
|
||||||
|
expand.invoke(RuneLite.getInjector().getInstance(ClientUI.class), navButton);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -253,7 +253,12 @@ public class IdleNotifierPlugin extends Plugin
|
|||||||
case USING_GILDED_ALTAR:
|
case USING_GILDED_ALTAR:
|
||||||
/* Farming */
|
/* Farming */
|
||||||
case FARMING_MIX_ULTRACOMPOST:
|
case FARMING_MIX_ULTRACOMPOST:
|
||||||
/* Misc */
|
case FARMING_HARVEST_BUSH:
|
||||||
|
case FARMING_HARVEST_HERB:
|
||||||
|
case FARMING_HARVEST_FRUIT_TREE:
|
||||||
|
case FARMING_HARVEST_FLOWER:
|
||||||
|
case FARMING_HARVEST_ALLOTMENT:
|
||||||
|
/* Misc */
|
||||||
case PISCARILIUS_CRANE_REPAIR:
|
case PISCARILIUS_CRANE_REPAIR:
|
||||||
case HOME_MAKE_TABLET:
|
case HOME_MAKE_TABLET:
|
||||||
case SAND_COLLECTION:
|
case SAND_COLLECTION:
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class InventoryGridOverlay extends Overlay
|
|||||||
final Widget if1DraggingWidget = client.getIf1DraggedWidget();
|
final Widget if1DraggingWidget = client.getIf1DraggedWidget();
|
||||||
final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY);
|
final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY);
|
||||||
|
|
||||||
if (if1DraggingWidget == null || if1DraggingWidget.equals(inventoryWidget)
|
if (if1DraggingWidget == null || if1DraggingWidget != inventoryWidget
|
||||||
|| client.getItemPressedDuration() < plugin.getDragDelay() / Constants.CLIENT_TICK_LENGTH)
|
|| client.getItemPressedDuration() < plugin.getDragDelay() / Constants.CLIENT_TICK_LENGTH)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ enum AlwaysLostItem
|
|||||||
{
|
{
|
||||||
RUNE_POUCH(ItemID.RUNE_POUCH, true),
|
RUNE_POUCH(ItemID.RUNE_POUCH, true),
|
||||||
LOOTING_BAG(ItemID.LOOTING_BAG, false),
|
LOOTING_BAG(ItemID.LOOTING_BAG, false),
|
||||||
CLUE_BOX(ItemID.CLUE_BOX, false);
|
CLUE_BOX(ItemID.CLUE_BOX, false),
|
||||||
|
BRACELET_OF_ETHEREUM(ItemID.BRACELET_OF_ETHEREUM, false),
|
||||||
|
BRACELET_OF_ETHEREUM_UNCHARGED(ItemID.BRACELET_OF_ETHEREUM_UNCHARGED, false);
|
||||||
|
|
||||||
private final int itemID;
|
private final int itemID;
|
||||||
private final boolean keptOutsideOfWilderness;
|
private final boolean keptOutsideOfWilderness;
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.itemskeptondeath;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Degradable/Non-rechargeable Jewelry death prices are usually determined by the amount of charges the item has left.
|
||||||
|
* The price of each charge is based on the GE price of the fully charged item divided by the maximum item charges
|
||||||
|
* Charge price = GE Price / Max Charges
|
||||||
|
* Death Price = Charge price * Current Charges
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
enum DynamicPriceItem
|
||||||
|
{
|
||||||
|
GAMES_NECKLACE1(ItemID.GAMES_NECKLACE1, 1, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
GAMES_NECKLACE2(ItemID.GAMES_NECKLACE2, 2, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
GAMES_NECKLACE3(ItemID.GAMES_NECKLACE3, 3, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
GAMES_NECKLACE4(ItemID.GAMES_NECKLACE4, 4, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
GAMES_NECKLACE5(ItemID.GAMES_NECKLACE5, 5, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
GAMES_NECKLACE6(ItemID.GAMES_NECKLACE6, 6, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
GAMES_NECKLACE7(ItemID.GAMES_NECKLACE7, 7, 8, ItemID.GAMES_NECKLACE8),
|
||||||
|
|
||||||
|
RING_OF_DUELING1(ItemID.RING_OF_DUELING1, 1, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
RING_OF_DUELING2(ItemID.RING_OF_DUELING2, 2, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
RING_OF_DUELING3(ItemID.RING_OF_DUELING3, 3, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
RING_OF_DUELING4(ItemID.RING_OF_DUELING4, 4, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
RING_OF_DUELING5(ItemID.RING_OF_DUELING5, 5, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
RING_OF_DUELING6(ItemID.RING_OF_DUELING6, 6, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
RING_OF_DUELING7(ItemID.RING_OF_DUELING7, 7, 8, ItemID.RING_OF_DUELING8),
|
||||||
|
|
||||||
|
RING_OF_RETURNING1(ItemID.RING_OF_RETURNING1, 1, 5, ItemID.RING_OF_RETURNING5),
|
||||||
|
RING_OF_RETURNING2(ItemID.RING_OF_RETURNING2, 2, 5, ItemID.RING_OF_RETURNING5),
|
||||||
|
RING_OF_RETURNING3(ItemID.RING_OF_RETURNING3, 3, 5, ItemID.RING_OF_RETURNING5),
|
||||||
|
RING_OF_RETURNING4(ItemID.RING_OF_RETURNING4, 4, 5, ItemID.RING_OF_RETURNING5),
|
||||||
|
|
||||||
|
NECKLACE_OF_PASSAGE1(ItemID.NECKLACE_OF_PASSAGE1, 1, 5, ItemID.NECKLACE_OF_PASSAGE5),
|
||||||
|
NECKLACE_OF_PASSAGE2(ItemID.NECKLACE_OF_PASSAGE2, 2, 5, ItemID.NECKLACE_OF_PASSAGE5),
|
||||||
|
NECKLACE_OF_PASSAGE3(ItemID.NECKLACE_OF_PASSAGE3, 3, 5, ItemID.NECKLACE_OF_PASSAGE5),
|
||||||
|
NECKLACE_OF_PASSAGE4(ItemID.NECKLACE_OF_PASSAGE4, 4, 5, ItemID.NECKLACE_OF_PASSAGE5),
|
||||||
|
|
||||||
|
BURNING_AMULET1(ItemID.BURNING_AMULET1, 1, 5, ItemID.BURNING_AMULET5),
|
||||||
|
BURNING_AMULET2(ItemID.BURNING_AMULET2, 2, 5, ItemID.BURNING_AMULET5),
|
||||||
|
BURNING_AMULET3(ItemID.BURNING_AMULET3, 3, 5, ItemID.BURNING_AMULET5),
|
||||||
|
BURNING_AMULET4(ItemID.BURNING_AMULET4, 4, 5, ItemID.BURNING_AMULET5);
|
||||||
|
|
||||||
|
private final int itemId;
|
||||||
|
private final int currentCharges;
|
||||||
|
private final int maxCharges;
|
||||||
|
private final int chargedId;
|
||||||
|
|
||||||
|
private static final Map<Integer, DynamicPriceItem> DYNAMIC_ITEMS;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
final ImmutableMap.Builder<Integer, DynamicPriceItem> map = ImmutableMap.builder();
|
||||||
|
for (final DynamicPriceItem p : values())
|
||||||
|
{
|
||||||
|
map.put(p.itemId, p);
|
||||||
|
}
|
||||||
|
DYNAMIC_ITEMS = map.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the price off the partially charged jewelry based on the base items price
|
||||||
|
* @param basePrice price of the base item, usually the trade-able variant
|
||||||
|
* @return death price of the current DynamicPriceItem
|
||||||
|
*/
|
||||||
|
int calculateDeathPrice(final int basePrice)
|
||||||
|
{
|
||||||
|
return (basePrice / maxCharges) * currentCharges;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
static DynamicPriceItem find(int itemId)
|
||||||
|
{
|
||||||
|
return DYNAMIC_ITEMS.get(itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,8 +28,6 @@ package net.runelite.client.plugins.itemskeptondeath;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.api.ItemID;
|
import net.runelite.api.ItemID;
|
||||||
|
|
||||||
@@ -37,8 +35,7 @@ import net.runelite.api.ItemID;
|
|||||||
* Some items have a fixed price that is added to its default value when calculating death prices.
|
* Some items have a fixed price that is added to its default value when calculating death prices.
|
||||||
* These are typically imbued items, such as Berserker ring (i), to help it protect over the non-imbued variants.
|
* These are typically imbued items, such as Berserker ring (i), to help it protect over the non-imbued variants.
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@Getter
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
enum FixedPriceItem
|
enum FixedPriceItem
|
||||||
{
|
{
|
||||||
IMBUED_BLACK_MASK_I(ItemID.BLACK_MASK_I, 5000),
|
IMBUED_BLACK_MASK_I(ItemID.BLACK_MASK_I, 5000),
|
||||||
@@ -67,10 +64,161 @@ enum FixedPriceItem
|
|||||||
|
|
||||||
IMBUED_RING_OF_THE_GODS_I(ItemID.RING_OF_THE_GODS_I, 2000),
|
IMBUED_RING_OF_THE_GODS_I(ItemID.RING_OF_THE_GODS_I, 2000),
|
||||||
IMBUED_TREASONOUS_RING_I(ItemID.TREASONOUS_RING_I, 2000),
|
IMBUED_TREASONOUS_RING_I(ItemID.TREASONOUS_RING_I, 2000),
|
||||||
IMBUED_TYRANNICAL_RING_I(ItemID.TYRANNICAL_RING_I, 2000);
|
IMBUED_TYRANNICAL_RING_I(ItemID.TYRANNICAL_RING_I, 2000),
|
||||||
|
|
||||||
|
GRACEFUL_HOOD(ItemID.GRACEFUL_HOOD, 1965),
|
||||||
|
GRACEFUL_CAPE(ItemID.GRACEFUL_CAPE, 2460),
|
||||||
|
GRACEFUL_TOP(ItemID.GRACEFUL_TOP, 2345),
|
||||||
|
GRACEFUL_LEGS(ItemID.GRACEFUL_LEGS, 2290),
|
||||||
|
GRACEFUL_GLOVES(ItemID.GRACEFUL_GLOVES, 1970),
|
||||||
|
GRACEFUL_BOOTS(ItemID.GRACEFUL_BOOTS, 2060),
|
||||||
|
|
||||||
|
ANGLER_HAT(ItemID.ANGLER_HAT, 2600),
|
||||||
|
ANGLER_TOP(ItemID.ANGLER_TOP, 3550),
|
||||||
|
ANGLER_WADERS(ItemID.ANGLER_WADERS, 4400),
|
||||||
|
ANGLER_BOOTS(ItemID.ANGLER_BOOTS, 5300),
|
||||||
|
|
||||||
|
PROSPECTOR_HELMET(ItemID.PROSPECTOR_HELMET, 2640),
|
||||||
|
PROSPECTOR_JACKET(ItemID.PROSPECTOR_JACKET, 3550),
|
||||||
|
PROSPECTOR_LEGS(ItemID.PROSPECTOR_LEGS, 4460),
|
||||||
|
PROSPECTOR_BOOTS(ItemID.PROSPECTOR_BOOTS, 5370),
|
||||||
|
|
||||||
|
LUMBERJACK_HAT(ItemID.LUMBERJACK_HAT, 19950),
|
||||||
|
LUMBERJACK_TOP(ItemID.LUMBERJACK_TOP, 19950),
|
||||||
|
LUMBERJACK_LEGS(ItemID.LUMBERJACK_LEGS, 19950),
|
||||||
|
LUMBERJACK_BOOTS(ItemID.LUMBERJACK_BOOTS, 19950),
|
||||||
|
|
||||||
|
ROGUE_MASK(ItemID.ROGUE_MASK, 725),
|
||||||
|
ROGUE_TOP(ItemID.ROGUE_TOP, 575),
|
||||||
|
ROGUE_TROUSERS(ItemID.ROGUE_TROUSERS, 500),
|
||||||
|
ROGUE_GLOVES(ItemID.ROGUE_GLOVES, 650),
|
||||||
|
ROGUE_BOOTS(ItemID.ROGUE_BOOTS, 650),
|
||||||
|
|
||||||
|
RING_OF_WEALTH_1(ItemID.RING_OF_WEALTH_1, 500, ItemID.RING_OF_WEALTH),
|
||||||
|
RING_OF_WEALTH_2(ItemID.RING_OF_WEALTH_2, 1000, ItemID.RING_OF_WEALTH),
|
||||||
|
RING_OF_WEALTH_3(ItemID.RING_OF_WEALTH_3, 1500, ItemID.RING_OF_WEALTH),
|
||||||
|
RING_OF_WEALTH_4(ItemID.RING_OF_WEALTH_4, 2000, ItemID.RING_OF_WEALTH),
|
||||||
|
|
||||||
|
AMULET_OF_GLORY1(ItemID.AMULET_OF_GLORY1, 500, ItemID.AMULET_OF_GLORY),
|
||||||
|
AMULET_OF_GLORY2(ItemID.AMULET_OF_GLORY2, 1000, ItemID.AMULET_OF_GLORY),
|
||||||
|
AMULET_OF_GLORY3(ItemID.AMULET_OF_GLORY3, 1500, ItemID.AMULET_OF_GLORY),
|
||||||
|
AMULET_OF_GLORY5(ItemID.AMULET_OF_GLORY5, 2500, ItemID.AMULET_OF_GLORY),
|
||||||
|
|
||||||
|
COMBAT_BRACELET1(ItemID.COMBAT_BRACELET1, 500, ItemID.COMBAT_BRACELET),
|
||||||
|
COMBAT_BRACELET2(ItemID.COMBAT_BRACELET2, 1000, ItemID.COMBAT_BRACELET),
|
||||||
|
COMBAT_BRACELET3(ItemID.COMBAT_BRACELET3, 1500, ItemID.COMBAT_BRACELET),
|
||||||
|
COMBAT_BRACELET5(ItemID.COMBAT_BRACELET5, 2500, ItemID.COMBAT_BRACELET),
|
||||||
|
|
||||||
|
SKILLS_NECKLACE1(ItemID.SKILLS_NECKLACE1, 500, ItemID.SKILLS_NECKLACE),
|
||||||
|
SKILLS_NECKLACE2(ItemID.SKILLS_NECKLACE2, 1000, ItemID.SKILLS_NECKLACE),
|
||||||
|
SKILLS_NECKLACE3(ItemID.SKILLS_NECKLACE3, 1500, ItemID.SKILLS_NECKLACE),
|
||||||
|
SKILLS_NECKLACE4(ItemID.SKILLS_NECKLACE5, 2500, ItemID.SKILLS_NECKLACE),
|
||||||
|
|
||||||
|
AHRIMS_HOOD_25(ItemID.AHRIMS_HOOD_25, 2500, ItemID.AHRIMS_HOOD_0),
|
||||||
|
AHRIMS_HOOD_50(ItemID.AHRIMS_HOOD_50, 5000, ItemID.AHRIMS_HOOD_0),
|
||||||
|
AHRIMS_HOOD_75(ItemID.AHRIMS_HOOD_75, 7500, ItemID.AHRIMS_HOOD_0),
|
||||||
|
AHRIMS_HOOD_100(ItemID.AHRIMS_HOOD_100, 10000, ItemID.AHRIMS_HOOD_0),
|
||||||
|
AHRIMS_ROBETOP_25(ItemID.AHRIMS_ROBETOP_25, 2500, ItemID.AHRIMS_ROBETOP_0),
|
||||||
|
AHRIMS_ROBETOP_50(ItemID.AHRIMS_ROBETOP_50, 5000, ItemID.AHRIMS_ROBETOP_0),
|
||||||
|
AHRIMS_ROBETOP_75(ItemID.AHRIMS_ROBETOP_75, 7500, ItemID.AHRIMS_ROBETOP_0),
|
||||||
|
AHRIMS_ROBETOP_100(ItemID.AHRIMS_ROBETOP_100, 10000, ItemID.AHRIMS_ROBETOP_0),
|
||||||
|
AHRIMS_ROBESKIRT_25(ItemID.AHRIMS_ROBESKIRT_25, 2500, ItemID.AHRIMS_ROBESKIRT_0),
|
||||||
|
AHRIMS_ROBESKIRT_50(ItemID.AHRIMS_ROBESKIRT_50, 5000, ItemID.AHRIMS_ROBESKIRT_0),
|
||||||
|
AHRIMS_ROBESKIRT_75(ItemID.AHRIMS_ROBESKIRT_75, 7500, ItemID.AHRIMS_ROBESKIRT_0),
|
||||||
|
AHRIMS_ROBESKIRT_100(ItemID.AHRIMS_ROBESKIRT_100, 10000, ItemID.AHRIMS_ROBESKIRT_0),
|
||||||
|
AHRIMS_STAFF_25(ItemID.AHRIMS_STAFF_25, 2500, ItemID.AHRIMS_STAFF_0),
|
||||||
|
AHRIMS_STAFF_50(ItemID.AHRIMS_STAFF_50, 5000, ItemID.AHRIMS_STAFF_0),
|
||||||
|
AHRIMS_STAFF_75(ItemID.AHRIMS_STAFF_75, 7500, ItemID.AHRIMS_STAFF_0),
|
||||||
|
AHRIMS_STAFF_100(ItemID.AHRIMS_STAFF_100, 10000, ItemID.AHRIMS_STAFF_0),
|
||||||
|
|
||||||
|
KARILS_COIF_25(ItemID.KARILS_COIF_25, 2500, ItemID.KARILS_COIF_0),
|
||||||
|
KARILS_COIF_50(ItemID.KARILS_COIF_50, 5000, ItemID.KARILS_COIF_0),
|
||||||
|
KARILS_COIF_75(ItemID.KARILS_COIF_75, 7500, ItemID.KARILS_COIF_0),
|
||||||
|
KARILS_COIF_100(ItemID.KARILS_COIF_100, 10000, ItemID.KARILS_COIF_0),
|
||||||
|
KARILS_LEATHERTOP_25(ItemID.KARILS_LEATHERTOP_25, 2500, ItemID.KARILS_LEATHERTOP_0),
|
||||||
|
KARILS_LEATHERTOP_50(ItemID.KARILS_LEATHERTOP_50, 5000, ItemID.KARILS_LEATHERTOP_0),
|
||||||
|
KARILS_LEATHERTOP_75(ItemID.KARILS_LEATHERTOP_75, 7500, ItemID.KARILS_LEATHERTOP_0),
|
||||||
|
KARILS_LEATHERTOP_100(ItemID.KARILS_LEATHERTOP_100, 10000, ItemID.KARILS_LEATHERTOP_0),
|
||||||
|
KARILS_LEATHERSKIRT_25(ItemID.KARILS_LEATHERSKIRT_25, 2500, ItemID.KARILS_LEATHERSKIRT_0),
|
||||||
|
KARILS_LEATHERSKIRT_50(ItemID.KARILS_LEATHERSKIRT_50, 5000, ItemID.KARILS_LEATHERSKIRT_0),
|
||||||
|
KARILS_LEATHERSKIRT_75(ItemID.KARILS_LEATHERSKIRT_75, 7500, ItemID.KARILS_LEATHERSKIRT_0),
|
||||||
|
KARILS_LEATHERSKIRT_100(ItemID.KARILS_LEATHERSKIRT_100, 10000, ItemID.KARILS_LEATHERSKIRT_0),
|
||||||
|
KARILS_CROSSBOW_25(ItemID.KARILS_CROSSBOW_25, 2500, ItemID.KARILS_CROSSBOW_0),
|
||||||
|
KARILS_CROSSBOW_50(ItemID.KARILS_CROSSBOW_50, 5000, ItemID.KARILS_CROSSBOW_0),
|
||||||
|
KARILS_CROSSBOW_75(ItemID.KARILS_CROSSBOW_75, 7500, ItemID.KARILS_CROSSBOW_0),
|
||||||
|
KARILS_CROSSBOW_100(ItemID.KARILS_CROSSBOW_100, 10000, ItemID.KARILS_CROSSBOW_0),
|
||||||
|
|
||||||
|
DHAROKS_HELM_25(ItemID.DHAROKS_HELM_25, 2500, ItemID.DHAROKS_HELM_0),
|
||||||
|
DHAROKS_HELM_50(ItemID.DHAROKS_HELM_50, 5000, ItemID.DHAROKS_HELM_0),
|
||||||
|
DHAROKS_HELM_75(ItemID.DHAROKS_HELM_75, 7500, ItemID.DHAROKS_HELM_0),
|
||||||
|
DHAROKS_HELM_100(ItemID.DHAROKS_HELM_100, 10000, ItemID.DHAROKS_HELM_0),
|
||||||
|
DHAROKS_PLATEBODY_25(ItemID.DHAROKS_PLATEBODY_25, 2500, ItemID.DHAROKS_PLATEBODY_0),
|
||||||
|
DHAROKS_PLATEBODY_50(ItemID.DHAROKS_PLATEBODY_50, 5000, ItemID.DHAROKS_PLATEBODY_0),
|
||||||
|
DHAROKS_PLATEBODY_75(ItemID.DHAROKS_PLATEBODY_75, 7500, ItemID.DHAROKS_PLATEBODY_0),
|
||||||
|
DHAROKS_PLATEBODY_100(ItemID.DHAROKS_PLATEBODY_100, 10000, ItemID.DHAROKS_PLATEBODY_0),
|
||||||
|
DHAROKS_PLATELEGS_25(ItemID.DHAROKS_PLATELEGS_25, 2500, ItemID.DHAROKS_PLATELEGS_0),
|
||||||
|
DHAROKS_PLATELEGS_50(ItemID.DHAROKS_PLATELEGS_50, 5000, ItemID.DHAROKS_PLATELEGS_0),
|
||||||
|
DHAROKS_PLATELEGS_75(ItemID.DHAROKS_PLATELEGS_75, 7500, ItemID.DHAROKS_PLATELEGS_0),
|
||||||
|
DHAROKS_PLATELEGS_100(ItemID.DHAROKS_PLATELEGS_100, 10000, ItemID.DHAROKS_PLATELEGS_0),
|
||||||
|
DHAROKS_GREATAXE_25(ItemID.DHAROKS_GREATAXE_25, 2500, ItemID.DHAROKS_GREATAXE_0),
|
||||||
|
DHAROKS_GREATAXE_50(ItemID.DHAROKS_GREATAXE_50, 5000, ItemID.DHAROKS_GREATAXE_0),
|
||||||
|
DHAROKS_GREATAXE_75(ItemID.DHAROKS_GREATAXE_75, 7500, ItemID.DHAROKS_GREATAXE_0),
|
||||||
|
DHAROKS_GREATAXE_100(ItemID.DHAROKS_GREATAXE_100, 10000, ItemID.DHAROKS_GREATAXE_0),
|
||||||
|
|
||||||
|
GUTHANS_HELM_25(ItemID.GUTHANS_HELM_25, 2500, ItemID.GUTHANS_HELM_0),
|
||||||
|
GUTHANS_HELM_50(ItemID.GUTHANS_HELM_50, 5000, ItemID.GUTHANS_HELM_0),
|
||||||
|
GUTHANS_HELM_75(ItemID.GUTHANS_HELM_75, 7500, ItemID.GUTHANS_HELM_0),
|
||||||
|
GUTHANS_HELM_100(ItemID.GUTHANS_HELM_100, 10000, ItemID.GUTHANS_HELM_0),
|
||||||
|
GUTHANS_PLATEBODY_25(ItemID.GUTHANS_PLATEBODY_25, 2500, ItemID.GUTHANS_PLATEBODY_0),
|
||||||
|
GUTHANS_PLATEBODY_50(ItemID.GUTHANS_PLATEBODY_50, 5000, ItemID.GUTHANS_PLATEBODY_0),
|
||||||
|
GUTHANS_PLATEBODY_75(ItemID.GUTHANS_PLATEBODY_75, 7500, ItemID.GUTHANS_PLATEBODY_0),
|
||||||
|
GUTHANS_PLATEBODY_100(ItemID.GUTHANS_PLATEBODY_100, 10000, ItemID.GUTHANS_PLATEBODY_0),
|
||||||
|
GUTHANS_CHAINSKIRT_25(ItemID.GUTHANS_CHAINSKIRT_25, 2500, ItemID.GUTHANS_CHAINSKIRT_0),
|
||||||
|
GUTHANS_CHAINSKIRT_50(ItemID.GUTHANS_CHAINSKIRT_50, 5000, ItemID.GUTHANS_CHAINSKIRT_0),
|
||||||
|
GUTHANS_CHAINSKIRT_75(ItemID.GUTHANS_CHAINSKIRT_75, 7500, ItemID.GUTHANS_CHAINSKIRT_0),
|
||||||
|
GUTHANS_CHAINSKIRT_100(ItemID.GUTHANS_CHAINSKIRT_100, 10000, ItemID.GUTHANS_CHAINSKIRT_0),
|
||||||
|
GUTHANS_WARSPEAR_25(ItemID.GUTHANS_WARSPEAR_25, 2500, ItemID.GUTHANS_WARSPEAR_0),
|
||||||
|
GUTHANS_WARSPEAR_50(ItemID.GUTHANS_WARSPEAR_50, 5000, ItemID.GUTHANS_WARSPEAR_0),
|
||||||
|
GUTHANS_WARSPEAR_75(ItemID.GUTHANS_WARSPEAR_75, 7500, ItemID.GUTHANS_WARSPEAR_0),
|
||||||
|
GUTHANS_WARSPEAR_100(ItemID.GUTHANS_WARSPEAR_100, 10000, ItemID.GUTHANS_WARSPEAR_0),
|
||||||
|
|
||||||
|
TORAGS_HELM_25(ItemID.TORAGS_HELM_25, 2500, ItemID.TORAGS_HELM_0),
|
||||||
|
TORAGS_HELM_50(ItemID.TORAGS_HELM_50, 5000, ItemID.TORAGS_HELM_0),
|
||||||
|
TORAGS_HELM_75(ItemID.TORAGS_HELM_75, 7500, ItemID.TORAGS_HELM_0),
|
||||||
|
TORAGS_HELM_100(ItemID.TORAGS_HELM_100, 10000, ItemID.TORAGS_HELM_0),
|
||||||
|
TORAGS_PLATEBODY_25(ItemID.TORAGS_PLATEBODY_25, 2500, ItemID.TORAGS_PLATEBODY_0),
|
||||||
|
TORAGS_PLATEBODY_50(ItemID.TORAGS_PLATEBODY_50, 5000, ItemID.TORAGS_PLATEBODY_0),
|
||||||
|
TORAGS_PLATEBODY_75(ItemID.TORAGS_PLATEBODY_75, 7500, ItemID.TORAGS_PLATEBODY_0),
|
||||||
|
TORAGS_PLATEBODY_100(ItemID.TORAGS_PLATEBODY_100, 10000, ItemID.TORAGS_PLATEBODY_0),
|
||||||
|
TORAGS_PLATELEGS_25(ItemID.TORAGS_PLATELEGS_25, 2500, ItemID.TORAGS_PLATELEGS_0),
|
||||||
|
TORAGS_PLATELEGS_50(ItemID.TORAGS_PLATELEGS_50, 5000, ItemID.TORAGS_PLATELEGS_0),
|
||||||
|
TORAGS_PLATELEGS_75(ItemID.TORAGS_PLATELEGS_75, 7500, ItemID.TORAGS_PLATELEGS_0),
|
||||||
|
TORAGS_PLATELEGS_100(ItemID.TORAGS_PLATELEGS_100, 10000, ItemID.TORAGS_PLATELEGS_0),
|
||||||
|
TORAGS_HAMMERS_25(ItemID.TORAGS_HAMMERS_25, 2500, ItemID.TORAGS_HAMMERS_0),
|
||||||
|
TORAGS_HAMMERS_50(ItemID.TORAGS_HAMMERS_50, 5000, ItemID.TORAGS_HAMMERS_0),
|
||||||
|
TORAGS_HAMMERS_75(ItemID.TORAGS_HAMMERS_75, 7500, ItemID.TORAGS_HAMMERS_0),
|
||||||
|
TORAGS_HAMMERS_100(ItemID.TORAGS_HAMMERS_100, 10000, ItemID.TORAGS_HAMMERS_0),
|
||||||
|
|
||||||
|
VERACS_HELM_25(ItemID.VERACS_HELM_25, 2500, ItemID.VERACS_HELM_0),
|
||||||
|
VERACS_HELM_50(ItemID.VERACS_HELM_50, 5000, ItemID.VERACS_HELM_0),
|
||||||
|
VERACS_HELM_75(ItemID.VERACS_HELM_75, 7500, ItemID.VERACS_HELM_0),
|
||||||
|
VERACS_HELM_100(ItemID.VERACS_HELM_100, 10000, ItemID.VERACS_HELM_0),
|
||||||
|
VERACS_BRASSARD_25(ItemID.VERACS_BRASSARD_25, 2500, ItemID.VERACS_BRASSARD_0),
|
||||||
|
VERACS_BRASSARD_50(ItemID.VERACS_BRASSARD_50, 5000, ItemID.VERACS_BRASSARD_0),
|
||||||
|
VERACS_BRASSARD_75(ItemID.VERACS_BRASSARD_75, 7500, ItemID.VERACS_BRASSARD_0),
|
||||||
|
VERACS_BRASSARD_100(ItemID.VERACS_BRASSARD_100, 10000, ItemID.VERACS_BRASSARD_0),
|
||||||
|
VERACS_PLATESKIRT_25(ItemID.VERACS_PLATESKIRT_25, 2500, ItemID.VERACS_PLATESKIRT_0),
|
||||||
|
VERACS_PLATESKIRT_50(ItemID.VERACS_PLATESKIRT_50, 5000, ItemID.VERACS_PLATESKIRT_0),
|
||||||
|
VERACS_PLATESKIRT_75(ItemID.VERACS_PLATESKIRT_75, 7500, ItemID.VERACS_PLATESKIRT_0),
|
||||||
|
VERACS_PLATESKIRT_100(ItemID.VERACS_PLATESKIRT_100, 10000, ItemID.VERACS_PLATESKIRT_0),
|
||||||
|
VERACS_FLAIL_25(ItemID.VERACS_FLAIL_25, 2500, ItemID.VERACS_FLAIL_0),
|
||||||
|
VERACS_FLAIL_50(ItemID.VERACS_FLAIL_50, 5000, ItemID.VERACS_FLAIL_0),
|
||||||
|
VERACS_FLAIL_75(ItemID.VERACS_FLAIL_75, 7500, ItemID.VERACS_FLAIL_0),
|
||||||
|
VERACS_FLAIL_100(ItemID.VERACS_FLAIL_100, 10000, ItemID.VERACS_FLAIL_0);
|
||||||
|
|
||||||
private final int itemId;
|
private final int itemId;
|
||||||
private final int offset;
|
private final int offset;
|
||||||
|
private final int baseId;
|
||||||
|
|
||||||
private static final Map<Integer, FixedPriceItem> FIXED_ITEMS;
|
private static final Map<Integer, FixedPriceItem> FIXED_ITEMS;
|
||||||
|
|
||||||
@@ -84,6 +232,18 @@ enum FixedPriceItem
|
|||||||
FIXED_ITEMS = map.build();
|
FIXED_ITEMS = map.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FixedPriceItem(final int itemId, final int offset, final int baseId)
|
||||||
|
{
|
||||||
|
this.itemId = itemId;
|
||||||
|
this.offset = offset;
|
||||||
|
this.baseId = baseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
FixedPriceItem(final int itemId, final int offset)
|
||||||
|
{
|
||||||
|
this(itemId, offset, -1);
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static FixedPriceItem find(int itemId)
|
static FixedPriceItem find(int itemId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -22,12 +22,15 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.cache.definitions.sound;
|
package net.runelite.client.plugins.itemskeptondeath;
|
||||||
|
|
||||||
public class SoundEffect3Definition
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
class ItemStack
|
||||||
{
|
{
|
||||||
public int[][][] field1154 = new int[2][2][4];
|
private int id;
|
||||||
public int[] field1155 = new int[2];
|
private int qty;
|
||||||
public int[] field1156 = new int[2];
|
|
||||||
public int[][][] field1159 = new int[2][2][4];
|
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.itemskeptondeath;
|
package net.runelite.client.plugins.itemskeptondeath;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -32,8 +33,11 @@ import java.util.EnumSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Constants;
|
import net.runelite.api.Constants;
|
||||||
@@ -55,6 +59,7 @@ import net.runelite.api.widgets.WidgetInfo;
|
|||||||
import net.runelite.api.widgets.WidgetType;
|
import net.runelite.api.widgets.WidgetType;
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.game.ItemMapping;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.util.StackFormatter;
|
import net.runelite.client.util.StackFormatter;
|
||||||
@@ -71,6 +76,16 @@ public class ItemsKeptOnDeathPlugin extends Plugin
|
|||||||
private static final int DEEP_WILDY = 20;
|
private static final int DEEP_WILDY = 20;
|
||||||
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+).*");
|
private static final Pattern WILDERNESS_LEVEL_PATTERN = Pattern.compile("^Level: (\\d+).*");
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@VisibleForTesting
|
||||||
|
static class DeathItems
|
||||||
|
{
|
||||||
|
private final List<ItemStack> keptItems;
|
||||||
|
private final List<ItemStack> lostItems;
|
||||||
|
private final boolean hasAlwaysLost;
|
||||||
|
}
|
||||||
|
|
||||||
// Item Container helpers
|
// Item Container helpers
|
||||||
private static final int MAX_ROW_ITEMS = 8;
|
private static final int MAX_ROW_ITEMS = 8;
|
||||||
private static final int ITEM_X_OFFSET = 5;
|
private static final int ITEM_X_OFFSET = 5;
|
||||||
@@ -100,9 +115,12 @@ public class ItemsKeptOnDeathPlugin extends Plugin
|
|||||||
private WidgetButton deepWildyButton;
|
private WidgetButton deepWildyButton;
|
||||||
private WidgetButton lowWildyButton;
|
private WidgetButton lowWildyButton;
|
||||||
|
|
||||||
private boolean isSkulled;
|
@VisibleForTesting
|
||||||
private boolean protectingItem;
|
boolean isSkulled;
|
||||||
private int wildyLevel;
|
@VisibleForTesting
|
||||||
|
boolean protectingItem;
|
||||||
|
@VisibleForTesting
|
||||||
|
int wildyLevel;
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||||
@@ -225,97 +243,12 @@ public class ItemsKeptOnDeathPlugin extends Plugin
|
|||||||
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
|
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||||
final Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
|
final Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
|
||||||
|
|
||||||
final List<Item> items = new ArrayList<>();
|
final DeathItems deathItems = calculateKeptLostItems(inv, equip);
|
||||||
Collections.addAll(items, inv);
|
|
||||||
Collections.addAll(items, equip);
|
|
||||||
|
|
||||||
// Sort by item price
|
final List<Widget> keptItems = deathItems.getKeptItems().stream()
|
||||||
items.sort(Comparator.comparing(this::getDeathPrice).reversed());
|
.map(item -> createItemWidget(kept, item, true)).collect(Collectors.toList());
|
||||||
|
final List<Widget> lostItems = deathItems.getLostItems().stream()
|
||||||
boolean hasAlwaysLost = false;
|
.map(item -> createItemWidget(lost, item, false)).collect(Collectors.toList());
|
||||||
int keepCount = getDefaultItemsKept();
|
|
||||||
|
|
||||||
final List<Widget> keptItems = new ArrayList<>();
|
|
||||||
final List<Widget> lostItems = new ArrayList<>();
|
|
||||||
for (final Item i : items)
|
|
||||||
{
|
|
||||||
final int id = i.getId();
|
|
||||||
int itemQuantity = i.getQuantity();
|
|
||||||
|
|
||||||
if (id == -1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ItemDefinition c = itemManager.getItemDefinition(i.getId());
|
|
||||||
|
|
||||||
// Bonds are always kept and do not count towards the limit.
|
|
||||||
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
|
|
||||||
{
|
|
||||||
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
|
|
||||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
|
|
||||||
keptItems.add(itemWidget);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Certain items are always lost on death and have a white outline which we need to add
|
|
||||||
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(i.getId());
|
|
||||||
if (alwaysLostItem != null)
|
|
||||||
{
|
|
||||||
// Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
|
|
||||||
if (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0)
|
|
||||||
{
|
|
||||||
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
|
|
||||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
|
|
||||||
itemWidget.setBorderType(2); // white outline
|
|
||||||
lostItems.add(itemWidget);
|
|
||||||
hasAlwaysLost = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// the rune pouch is "always lost" but its kept outside of pvp, and does not count towards your keep count
|
|
||||||
}
|
|
||||||
else if (keepCount > 0)
|
|
||||||
{
|
|
||||||
// Keep most valuable items regardless of trade-ability.
|
|
||||||
if (i.getQuantity() > keepCount)
|
|
||||||
{
|
|
||||||
final Widget itemWidget = createItemWidget(kept, keepCount, c);
|
|
||||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, keepCount, c.getName());
|
|
||||||
keptItems.add(itemWidget);
|
|
||||||
itemQuantity -= keepCount;
|
|
||||||
keepCount = 0;
|
|
||||||
// Fall through to below to drop the rest of the stack
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
|
|
||||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
|
|
||||||
keptItems.add(itemWidget);
|
|
||||||
keepCount -= i.getQuantity();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Items are kept if:
|
|
||||||
// 1) is not tradeable
|
|
||||||
// 2) is under the deep wilderness line
|
|
||||||
// 3) is outside of the wilderness, or item has a broken form
|
|
||||||
if (!Pets.isPet(id)
|
|
||||||
&& !isTradeable(c) && wildyLevel <= DEEP_WILDY
|
|
||||||
&& (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId())))
|
|
||||||
{
|
|
||||||
final Widget itemWidget = createItemWidget(kept, itemQuantity, c);
|
|
||||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 1, itemQuantity, c.getName());
|
|
||||||
keptItems.add(itemWidget);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Otherwise, the item is lost
|
|
||||||
final Widget itemWidget = createItemWidget(lost, itemQuantity, c);
|
|
||||||
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, 0, itemQuantity, c.getName());
|
|
||||||
lostItems.add(itemWidget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int rows = (keptItems.size() + MAX_ROW_ITEMS - 1) / MAX_ROW_ITEMS;
|
int rows = (keptItems.size() + MAX_ROW_ITEMS - 1) / MAX_ROW_ITEMS;
|
||||||
// Show an empty row if there isn't anything
|
// Show an empty row if there isn't anything
|
||||||
@@ -330,36 +263,209 @@ public class ItemsKeptOnDeathPlugin extends Plugin
|
|||||||
positionWidgetItems(kept, keptItems);
|
positionWidgetItems(kept, keptItems);
|
||||||
positionWidgetItems(lost, lostItems);
|
positionWidgetItems(lost, lostItems);
|
||||||
|
|
||||||
updateKeptWidgetInfoText(hasAlwaysLost, keptItems, lostItems);
|
updateKeptWidgetInfoText(deathItems.isHasAlwaysLost(), keptItems, lostItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates which items will be kept/lost. first list is kept items, second is lost.
|
||||||
|
*
|
||||||
|
* @param inv players inventory
|
||||||
|
* @param equip players equipement
|
||||||
|
* @return list of items kept followed by a list of items lost
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
DeathItems calculateKeptLostItems(final Item[] inv, final Item[] equip)
|
||||||
|
{
|
||||||
|
final List<Item> items = new ArrayList<>();
|
||||||
|
Collections.addAll(items, inv);
|
||||||
|
Collections.addAll(items, equip);
|
||||||
|
|
||||||
|
// Sort by item price
|
||||||
|
items.sort(Comparator.comparing(this::getDeathPrice).reversed());
|
||||||
|
|
||||||
|
boolean hasClueBox = false;
|
||||||
|
boolean hasAlwaysLost = false;
|
||||||
|
int keepCount = getDefaultItemsKept();
|
||||||
|
|
||||||
|
final List<ItemStack> keptItems = new ArrayList<>();
|
||||||
|
final List<ItemStack> lostItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (final Item i : items)
|
||||||
|
{
|
||||||
|
final int id = i.getId();
|
||||||
|
int qty = i.getQuantity();
|
||||||
|
if (id == -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ItemDefinition c = itemManager.getItemDefinition(i.getId());
|
||||||
|
|
||||||
|
// Bonds are always kept and do not count towards the limit.
|
||||||
|
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
|
||||||
|
{
|
||||||
|
keptItems.add(new ItemStack(id, qty));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(id);
|
||||||
|
if (alwaysLostItem != null && (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0))
|
||||||
|
{
|
||||||
|
hasAlwaysLost = true;
|
||||||
|
hasClueBox = hasClueBox || id == ItemID.CLUE_BOX;
|
||||||
|
lostItems.add(new ItemStack(id, qty));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keepCount > 0)
|
||||||
|
{
|
||||||
|
// Keep most valuable items regardless of trade-ability.
|
||||||
|
if (i.getQuantity() > keepCount)
|
||||||
|
{
|
||||||
|
keptItems.add(new ItemStack(id, keepCount));
|
||||||
|
qty -= keepCount;
|
||||||
|
keepCount = 0;
|
||||||
|
// Fall through to determine if the rest of the stack should drop
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keptItems.add(new ItemStack(id, qty));
|
||||||
|
keepCount -= qty;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Items are kept if:
|
||||||
|
// 1) is not tradeable
|
||||||
|
// 2) is under the deep wilderness line
|
||||||
|
// 3) is outside of the wilderness, or item has a broken form
|
||||||
|
if (!Pets.isPet(id)
|
||||||
|
&& !LostIfNotProtected.isLostIfNotProtected(id)
|
||||||
|
&& !isTradeable(itemManager.getItemDefinition(id)) && wildyLevel <= DEEP_WILDY
|
||||||
|
&& (wildyLevel <= 0 || BrokenOnDeathItem.isBrokenOnDeath(i.getId())))
|
||||||
|
{
|
||||||
|
keptItems.add(new ItemStack(id, qty));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Otherwise, the item is lost
|
||||||
|
lostItems.add(new ItemStack(id, qty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasClueBox)
|
||||||
|
{
|
||||||
|
boolean alreadyProtectingClue = false;
|
||||||
|
for (final ItemStack item : keptItems)
|
||||||
|
{
|
||||||
|
if (isClueBoxable(item.getId()))
|
||||||
|
{
|
||||||
|
alreadyProtectingClue = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alreadyProtectingClue)
|
||||||
|
{
|
||||||
|
int clueId = -1;
|
||||||
|
// Clue box protects the last clue in your inventory so loop over the players inv
|
||||||
|
for (final Item i : inv)
|
||||||
|
{
|
||||||
|
final int id = i.getId();
|
||||||
|
if (id != -1 && isClueBoxable(id))
|
||||||
|
{
|
||||||
|
clueId = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clueId != -1)
|
||||||
|
{
|
||||||
|
// Move the boxed item to the kept items container and remove it from the lost items container
|
||||||
|
for (final ItemStack boxableItem : lostItems)
|
||||||
|
{
|
||||||
|
if (boxableItem.getId() == clueId)
|
||||||
|
{
|
||||||
|
if (boxableItem.getQty() > 1)
|
||||||
|
{
|
||||||
|
boxableItem.setQty(boxableItem.getQty() - 1);
|
||||||
|
keptItems.add(new ItemStack(clueId, 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lostItems.remove(boxableItem);
|
||||||
|
keptItems.add(boxableItem);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DeathItems(keptItems, lostItems, hasAlwaysLost);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isClueBoxable(final int itemID)
|
||||||
|
{
|
||||||
|
final String name = itemManager.getItemDefinition(itemID).getName();
|
||||||
|
return name.contains("Clue scroll (") || name.contains("Reward casket (");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the price of an item
|
* Get the price of an item
|
||||||
|
*
|
||||||
* @param item
|
* @param item
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private int getDeathPrice(Item item)
|
@VisibleForTesting
|
||||||
|
int getDeathPrice(Item item)
|
||||||
{
|
{
|
||||||
|
// 1) Check if the death price is dynamically calculated, if so return that value
|
||||||
|
// 2) If death price is based off another item default to that price, otherwise apply normal ItemMapping GE price
|
||||||
|
// 3) If still no price, default to store price
|
||||||
|
// 4) Apply fixed price offset if applicable
|
||||||
|
|
||||||
int itemId = item.getId();
|
int itemId = item.getId();
|
||||||
// Unnote/unplaceholder item
|
// Unnote/unplaceholder item
|
||||||
int canonicalizedItemId = itemManager.canonicalize(itemId);
|
int canonicalizedItemId = itemManager.canonicalize(itemId);
|
||||||
int exchangePrice = itemManager.getItemPrice(canonicalizedItemId);
|
int exchangePrice = 0;
|
||||||
|
|
||||||
|
final DynamicPriceItem dynamicPrice = DynamicPriceItem.find(canonicalizedItemId);
|
||||||
|
if (dynamicPrice != null)
|
||||||
|
{
|
||||||
|
final ItemDefinition c1 = itemManager.getItemDefinition(canonicalizedItemId);
|
||||||
|
exchangePrice = c1.getPrice();
|
||||||
|
final int basePrice = itemManager.getItemPrice(dynamicPrice.getChargedId(), true);
|
||||||
|
return dynamicPrice.calculateDeathPrice(basePrice);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some items have artificially offset death prices - such as ring imbues
|
||||||
|
// which are +2k over the non imbues. Check if the item has a fixed price offset
|
||||||
|
final FixedPriceItem fixedPrice = FixedPriceItem.find(canonicalizedItemId);
|
||||||
|
if (fixedPrice != null && fixedPrice.getBaseId() != -1)
|
||||||
|
{
|
||||||
|
// Grab base item price
|
||||||
|
exchangePrice = itemManager.getItemPrice(fixedPrice.getBaseId(), true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Account for items whose death value comes from their tradeable variant (barrows) or components (ornate kits)
|
||||||
|
for (final int mappedID : ItemMapping.map(canonicalizedItemId))
|
||||||
|
{
|
||||||
|
exchangePrice += itemManager.getItemPrice(mappedID, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (exchangePrice == 0)
|
if (exchangePrice == 0)
|
||||||
{
|
{
|
||||||
final ItemDefinition c1 = itemManager.getItemDefinition(canonicalizedItemId);
|
final ItemDefinition c1 = itemManager.getItemDefinition(canonicalizedItemId);
|
||||||
exchangePrice = c1.getPrice();
|
exchangePrice = c1.getPrice();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// Apply fixed price offset
|
||||||
// Some items have artifically applied death prices - such as ring imbues
|
exchangePrice += fixedPrice == null ? 0 : fixedPrice.getOffset();
|
||||||
// which are +2k over the non imbues. Check if the item has a fixed price.
|
|
||||||
FixedPriceItem fixedPrice = FixedPriceItem.find(canonicalizedItemId);
|
|
||||||
if (fixedPrice != null)
|
|
||||||
{
|
|
||||||
// Apply fixed price offset
|
|
||||||
exchangePrice += fixedPrice.getOffset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exchangePrice;
|
return exchangePrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,21 +697,29 @@ public class ItemsKeptOnDeathPlugin extends Plugin
|
|||||||
/**
|
/**
|
||||||
* Creates an Item Widget for use inside the Kept on Death Interface
|
* Creates an Item Widget for use inside the Kept on Death Interface
|
||||||
*
|
*
|
||||||
* @param qty Amount of item
|
* @param parent Widget to add element too as a child
|
||||||
* @param c Items Composition
|
* @param item the TempItem representing the item
|
||||||
* @return
|
* @param kept is the item being shown in the kept items container
|
||||||
|
* @return the Widget that was added to the `parent`
|
||||||
*/
|
*/
|
||||||
private static Widget createItemWidget(final Widget parent, final int qty, final ItemDefinition c)
|
private Widget createItemWidget(final Widget parent, final ItemStack item, boolean kept)
|
||||||
{
|
{
|
||||||
|
final int id = item.getId();
|
||||||
|
final int qty = item.getQty();
|
||||||
|
final ItemDefinition c = itemManager.getItemDefinition(id);
|
||||||
|
|
||||||
final Widget itemWidget = parent.createChild(-1, WidgetType.GRAPHIC);
|
final Widget itemWidget = parent.createChild(-1, WidgetType.GRAPHIC);
|
||||||
itemWidget.setItemId(c.getId());
|
|
||||||
itemWidget.setItemQuantity(qty);
|
|
||||||
itemWidget.setHasListener(true);
|
|
||||||
itemWidget.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
|
itemWidget.setOriginalWidth(Constants.ITEM_SPRITE_WIDTH);
|
||||||
itemWidget.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
|
itemWidget.setOriginalHeight(Constants.ITEM_SPRITE_HEIGHT);
|
||||||
itemWidget.setBorderType(1);
|
itemWidget.setItemId(id);
|
||||||
|
itemWidget.setItemQuantity(qty);
|
||||||
itemWidget.setAction(1, String.format("Item: <col=ff981f>%s", c.getName()));
|
itemWidget.setAction(1, String.format("Item: <col=ff981f>%s", c.getName()));
|
||||||
|
itemWidget.setOnOpListener(ScriptID.DEATH_KEEP_ITEM_EXAMINE, kept ? 1 : 0, qty, c.getName());
|
||||||
|
itemWidget.setHasListener(true);
|
||||||
|
|
||||||
|
final AlwaysLostItem alwaysLostItem = AlwaysLostItem.getByItemID(id);
|
||||||
|
final boolean whiteBorder = alwaysLostItem != null && (!alwaysLostItem.isKeptOutsideOfWilderness() || wildyLevel > 0);
|
||||||
|
itemWidget.setBorderType(whiteBorder ? 2 : 1);
|
||||||
|
|
||||||
return itemWidget;
|
return itemWidget;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.itemskeptondeath;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
|
||||||
|
final class LostIfNotProtected
|
||||||
|
{
|
||||||
|
private static final Set<Integer> ITEMS = ImmutableSet.of(
|
||||||
|
ItemID.AMULET_OF_THE_DAMNED,
|
||||||
|
ItemID.RING_OF_CHAROS, ItemID.RING_OF_CHAROSA,
|
||||||
|
ItemID.LUNAR_STAFF,
|
||||||
|
ItemID.SHADOW_SWORD,
|
||||||
|
ItemID.KERIS, ItemID.KERISP, ItemID.KERISP_10583, ItemID.KERISP_10584
|
||||||
|
);
|
||||||
|
|
||||||
|
public static boolean isLostIfNotProtected(int id)
|
||||||
|
{
|
||||||
|
return ITEMS.contains(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -103,10 +103,153 @@ public interface KeyRemappingConfig extends Config
|
|||||||
position = 6,
|
position = 6,
|
||||||
keyName = "fkeyRemap",
|
keyName = "fkeyRemap",
|
||||||
name = "Remap F Keys",
|
name = "Remap F Keys",
|
||||||
description = "Configures whether F-Keys are Remapped to 1 (F1) through 0 (F10), '-' (F11), and '=' (F12)"
|
description = "Configures whether F-Keys use remapped keys"
|
||||||
)
|
)
|
||||||
default boolean fkeyRemap()
|
default boolean fkeyRemap()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 7,
|
||||||
|
keyName = "f1",
|
||||||
|
name = "F1",
|
||||||
|
description = "The key which will replace {F1}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f1()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 8,
|
||||||
|
keyName = "f2",
|
||||||
|
name = "F2",
|
||||||
|
description = "The key which will replace {F2}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f2()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 9,
|
||||||
|
keyName = "f3",
|
||||||
|
name = "F3",
|
||||||
|
description = "The key which will replace {F3}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f3()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_3, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 10,
|
||||||
|
keyName = "f4",
|
||||||
|
name = "F4",
|
||||||
|
description = "The key which will replace {F4}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f4()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_4, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 11,
|
||||||
|
keyName = "f5",
|
||||||
|
name = "F5",
|
||||||
|
description = "The key which will replace {F5}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f5()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_5, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 12,
|
||||||
|
keyName = "f6",
|
||||||
|
name = "F6",
|
||||||
|
description = "The key which will replace {F6}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f6()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_6, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 13,
|
||||||
|
keyName = "f7",
|
||||||
|
name = "F7",
|
||||||
|
description = "The key which will replace {F7}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f7()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_7, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 14,
|
||||||
|
keyName = "f8",
|
||||||
|
name = "F8",
|
||||||
|
description = "The key which will replace {F8}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f8()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 15,
|
||||||
|
keyName = "f9",
|
||||||
|
name = "F9",
|
||||||
|
description = "The key which will replace {F9}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f9()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_9, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 16,
|
||||||
|
keyName = "f10",
|
||||||
|
name = "F10",
|
||||||
|
description = "The key which will replace {F10}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f10()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 17,
|
||||||
|
keyName = "f11",
|
||||||
|
name = "F11",
|
||||||
|
description = "The key which will replace {F11}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f11()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_MINUS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 18,
|
||||||
|
keyName = "f12",
|
||||||
|
name = "F12",
|
||||||
|
description = "The key which will replace {F12}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind f12()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_EQUALS, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 19,
|
||||||
|
keyName = "esc",
|
||||||
|
name = "ESC",
|
||||||
|
description = "The key which will replace {ESC}."
|
||||||
|
)
|
||||||
|
default ModifierlessKeybind esc()
|
||||||
|
{
|
||||||
|
return new ModifierlessKeybind(KeyEvent.VK_ESCAPE, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,30 +35,19 @@ import net.runelite.api.Client;
|
|||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.VarClientStr;
|
import net.runelite.api.VarClientStr;
|
||||||
import net.runelite.client.callback.ClientThread;
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.config.Keybind;
|
|
||||||
import net.runelite.client.config.ModifierlessKeybind;
|
|
||||||
import net.runelite.client.input.KeyListener;
|
import net.runelite.client.input.KeyListener;
|
||||||
import net.runelite.client.input.MouseAdapter;
|
import net.runelite.client.input.MouseAdapter;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class KeyRemappingListener extends MouseAdapter implements KeyListener
|
class KeyRemappingListener extends MouseAdapter implements KeyListener
|
||||||
{
|
{
|
||||||
private static final Keybind ONE = new ModifierlessKeybind(KeyEvent.VK_1, 0);
|
|
||||||
private static final Keybind TWO = new ModifierlessKeybind(KeyEvent.VK_2, 0);
|
|
||||||
private static final Keybind THREE = new ModifierlessKeybind(KeyEvent.VK_3, 0);
|
|
||||||
private static final Keybind FOUR = new ModifierlessKeybind(KeyEvent.VK_4, 0);
|
|
||||||
private static final Keybind FIVE = new ModifierlessKeybind(KeyEvent.VK_5, 0);
|
|
||||||
private static final Keybind SIX = new ModifierlessKeybind(KeyEvent.VK_6, 0);
|
|
||||||
private static final Keybind SEVEN = new ModifierlessKeybind(KeyEvent.VK_7, 0);
|
|
||||||
private static final Keybind EIGHT = new ModifierlessKeybind(KeyEvent.VK_8, 0);
|
|
||||||
private static final Keybind NINE = new ModifierlessKeybind(KeyEvent.VK_9, 0);
|
|
||||||
private static final Keybind ZERO = new ModifierlessKeybind(KeyEvent.VK_0, 0);
|
|
||||||
private static final Keybind MINUS = new ModifierlessKeybind(KeyEvent.VK_MINUS, 0);
|
|
||||||
private static final Keybind EQUALS = new ModifierlessKeybind(KeyEvent.VK_EQUALS, 0);
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private KeyRemappingPlugin plugin;
|
private KeyRemappingPlugin plugin;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private KeyRemappingConfig config;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@@ -111,66 +100,71 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
|
|||||||
// to select options
|
// to select options
|
||||||
if (plugin.isFkeyRemap() && !plugin.isDialogOpen())
|
if (plugin.isFkeyRemap() && !plugin.isDialogOpen())
|
||||||
{
|
{
|
||||||
if (ONE.matches(e))
|
if (config.f1().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F1);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F1);
|
||||||
e.setKeyCode(KeyEvent.VK_F1);
|
e.setKeyCode(KeyEvent.VK_F1);
|
||||||
}
|
}
|
||||||
else if (TWO.matches(e))
|
else if (config.f2().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F2);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F2);
|
||||||
e.setKeyCode(KeyEvent.VK_F2);
|
e.setKeyCode(KeyEvent.VK_F2);
|
||||||
}
|
}
|
||||||
else if (THREE.matches(e))
|
else if (config.f3().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F3);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F3);
|
||||||
e.setKeyCode(KeyEvent.VK_F3);
|
e.setKeyCode(KeyEvent.VK_F3);
|
||||||
}
|
}
|
||||||
else if (FOUR.matches(e))
|
else if (config.f4().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F4);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F4);
|
||||||
e.setKeyCode(KeyEvent.VK_F4);
|
e.setKeyCode(KeyEvent.VK_F4);
|
||||||
}
|
}
|
||||||
else if (FIVE.matches(e))
|
else if (config.f5().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F5);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F5);
|
||||||
e.setKeyCode(KeyEvent.VK_F5);
|
e.setKeyCode(KeyEvent.VK_F5);
|
||||||
}
|
}
|
||||||
else if (SIX.matches(e))
|
else if (config.f6().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F6);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F6);
|
||||||
e.setKeyCode(KeyEvent.VK_F6);
|
e.setKeyCode(KeyEvent.VK_F6);
|
||||||
}
|
}
|
||||||
else if (SEVEN.matches(e))
|
else if (config.f7().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F7);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F7);
|
||||||
e.setKeyCode(KeyEvent.VK_F7);
|
e.setKeyCode(KeyEvent.VK_F7);
|
||||||
}
|
}
|
||||||
else if (EIGHT.matches(e))
|
else if (config.f8().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F8);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F8);
|
||||||
e.setKeyCode(KeyEvent.VK_F8);
|
e.setKeyCode(KeyEvent.VK_F8);
|
||||||
}
|
}
|
||||||
else if (NINE.matches(e))
|
else if (config.f9().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F9);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F9);
|
||||||
e.setKeyCode(KeyEvent.VK_F9);
|
e.setKeyCode(KeyEvent.VK_F9);
|
||||||
}
|
}
|
||||||
else if (ZERO.matches(e))
|
else if (config.f10().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F10);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F10);
|
||||||
e.setKeyCode(KeyEvent.VK_F10);
|
e.setKeyCode(KeyEvent.VK_F10);
|
||||||
}
|
}
|
||||||
else if (MINUS.matches(e))
|
else if (config.f11().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F11);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F11);
|
||||||
e.setKeyCode(KeyEvent.VK_F11);
|
e.setKeyCode(KeyEvent.VK_F11);
|
||||||
}
|
}
|
||||||
else if (EQUALS.matches(e))
|
else if (config.f12().matches(e))
|
||||||
{
|
{
|
||||||
modified.put(e.getKeyCode(), KeyEvent.VK_F12);
|
modified.put(e.getKeyCode(), KeyEvent.VK_F12);
|
||||||
e.setKeyCode(KeyEvent.VK_F12);
|
e.setKeyCode(KeyEvent.VK_F12);
|
||||||
}
|
}
|
||||||
|
else if (config.esc().matches(e))
|
||||||
|
{
|
||||||
|
modified.put(e.getKeyCode(), KeyEvent.VK_ESCAPE);
|
||||||
|
e.setKeyCode(KeyEvent.VK_ESCAPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (e.getKeyCode())
|
switch (e.getKeyCode())
|
||||||
@@ -189,8 +183,12 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
|
|||||||
{
|
{
|
||||||
switch (e.getKeyCode())
|
switch (e.getKeyCode())
|
||||||
{
|
{
|
||||||
case KeyEvent.VK_ENTER:
|
|
||||||
case KeyEvent.VK_ESCAPE:
|
case KeyEvent.VK_ESCAPE:
|
||||||
|
// When existing typing mode, block the escape key
|
||||||
|
// so that it doesn't trigger the in-game hotkeys
|
||||||
|
e.consume();
|
||||||
|
// FALLTHROUGH
|
||||||
|
case KeyEvent.VK_ENTER:
|
||||||
plugin.setTyping(false);
|
plugin.setTyping(false);
|
||||||
clientThread.invoke(plugin::lockChat);
|
clientThread.invoke(plugin::lockChat);
|
||||||
break;
|
break;
|
||||||
@@ -240,54 +238,58 @@ class KeyRemappingListener extends MouseAdapter implements KeyListener
|
|||||||
|
|
||||||
if (plugin.isFkeyRemap())
|
if (plugin.isFkeyRemap())
|
||||||
{
|
{
|
||||||
if (ONE.matches(e))
|
if (config.f1().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F1);
|
e.setKeyCode(KeyEvent.VK_F1);
|
||||||
}
|
}
|
||||||
else if (TWO.matches(e))
|
else if (config.f2().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F2);
|
e.setKeyCode(KeyEvent.VK_F2);
|
||||||
}
|
}
|
||||||
else if (THREE.matches(e))
|
else if (config.f3().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F3);
|
e.setKeyCode(KeyEvent.VK_F3);
|
||||||
}
|
}
|
||||||
else if (FOUR.matches(e))
|
else if (config.f4().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F4);
|
e.setKeyCode(KeyEvent.VK_F4);
|
||||||
}
|
}
|
||||||
else if (FIVE.matches(e))
|
else if (config.f5().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F5);
|
e.setKeyCode(KeyEvent.VK_F5);
|
||||||
}
|
}
|
||||||
else if (SIX.matches(e))
|
else if (config.f6().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F6);
|
e.setKeyCode(KeyEvent.VK_F6);
|
||||||
}
|
}
|
||||||
else if (SEVEN.matches(e))
|
else if (config.f7().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F7);
|
e.setKeyCode(KeyEvent.VK_F7);
|
||||||
}
|
}
|
||||||
else if (EIGHT.matches(e))
|
else if (config.f8().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F8);
|
e.setKeyCode(KeyEvent.VK_F8);
|
||||||
}
|
}
|
||||||
else if (NINE.matches(e))
|
else if (config.f9().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F9);
|
e.setKeyCode(KeyEvent.VK_F9);
|
||||||
}
|
}
|
||||||
else if (ZERO.matches(e))
|
else if (config.f10().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F10);
|
e.setKeyCode(KeyEvent.VK_F10);
|
||||||
}
|
}
|
||||||
else if (MINUS.matches(e))
|
else if (config.f11().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F11);
|
e.setKeyCode(KeyEvent.VK_F11);
|
||||||
}
|
}
|
||||||
else if (EQUALS.matches(e))
|
else if (config.f12().matches(e))
|
||||||
{
|
{
|
||||||
e.setKeyCode(KeyEvent.VK_F12);
|
e.setKeyCode(KeyEvent.VK_F12);
|
||||||
}
|
}
|
||||||
|
else if (config.esc().matches(e))
|
||||||
|
{
|
||||||
|
e.setKeyCode(KeyEvent.VK_ESCAPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import lombok.Getter;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Actor;
|
import net.runelite.api.Actor;
|
||||||
import static net.runelite.api.AnimationID.LIZARDMAN_SHAMAN_SPAWN;
|
import static net.runelite.api.AnimationID.LIZARDMAN_SHAMAN_SPAWN;
|
||||||
import net.runelite.api.ChatMessageType;
|
|
||||||
import net.runelite.api.coords.LocalPoint;
|
import net.runelite.api.coords.LocalPoint;
|
||||||
import net.runelite.api.events.AnimationChanged;
|
import net.runelite.api.events.AnimationChanged;
|
||||||
import net.runelite.api.events.ChatMessage;
|
import net.runelite.api.events.ChatMessage;
|
||||||
@@ -104,7 +103,8 @@ public class LizardmenShamanPlugin extends Plugin
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
public void onChatMessage(ChatMessage event)
|
public void onChatMessage(ChatMessage event)
|
||||||
{
|
{
|
||||||
if (this.notifyOnSpawn && event.getType() == ChatMessageType.GAMEMESSAGE && event.getMessage().contains(MESSAGE))
|
if (this.notifyOnSpawn && /* event.getType() == ChatMessageType.GAMEMESSAGE && */event.getMessage().contains(MESSAGE))
|
||||||
|
// ChatMessageType should probably be SPAM <- should be tested first though
|
||||||
{
|
{
|
||||||
notifier.notify(MESSAGE);
|
notifier.notify(MESSAGE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 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.client.plugins.regenmeter;
|
|
||||||
|
|
||||||
import java.awt.BasicStroke;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
import java.awt.Stroke;
|
|
||||||
import java.awt.geom.Arc2D;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.VarPlayer;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class RegenMeterOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private static final Color HITPOINTS_COLOR = brighter(0x9B0703);
|
|
||||||
private static final Color SPECIAL_COLOR = brighter(0x1E95B0);
|
|
||||||
private static final Color OVERLAY_COLOR = new Color(255, 255, 255, 60);
|
|
||||||
private static final double DIAMETER = 26D;
|
|
||||||
private static final int OFFSET = 27;
|
|
||||||
private static final Stroke STROKE = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
|
||||||
|
|
||||||
private final Client client;
|
|
||||||
private final RegenMeterPlugin plugin;
|
|
||||||
|
|
||||||
private Rectangle getBounds(WidgetInfo widgetInfo)
|
|
||||||
{
|
|
||||||
Widget widget = client.getWidget(widgetInfo);
|
|
||||||
if (widget == null || widget.isHidden())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return widget.getBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Color brighter(int color)
|
|
||||||
{
|
|
||||||
float[] hsv = new float[3];
|
|
||||||
Color.RGBtoHSB(color >>> 16, (color >> 8) & 0xFF, color & 0xFF, hsv);
|
|
||||||
return Color.getHSBColor(hsv[0], 1.f, 1.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public RegenMeterOverlay(final Client client, final RegenMeterPlugin plugin)
|
|
||||||
{
|
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
|
||||||
this.client = client;
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D g)
|
|
||||||
{
|
|
||||||
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
|
||||||
|
|
||||||
if (plugin.isShowHitpoints())
|
|
||||||
{
|
|
||||||
renderRegen(g, WidgetInfo.MINIMAP_HEALTH_ORB, plugin.getHitpointsPercentage(), HITPOINTS_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.isShowSpecial())
|
|
||||||
{
|
|
||||||
if (client.getVar(VarPlayer.SPECIAL_ATTACK_ENABLED) == 1)
|
|
||||||
{
|
|
||||||
final Rectangle bounds = getBounds(WidgetInfo.MINIMAP_SPEC_ORB);
|
|
||||||
if (bounds != null)
|
|
||||||
{
|
|
||||||
g.setColor(RegenMeterOverlay.OVERLAY_COLOR);
|
|
||||||
g.fillOval(
|
|
||||||
bounds.x + OFFSET,
|
|
||||||
bounds.y + (int) (bounds.height / 2D - (DIAMETER) / 2D),
|
|
||||||
(int) DIAMETER, (int) DIAMETER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renderRegen(g, WidgetInfo.MINIMAP_SPEC_ORB, plugin.getSpecialPercentage(), SPECIAL_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderRegen(Graphics2D g, WidgetInfo widgetInfo, double percent, Color color)
|
|
||||||
{
|
|
||||||
final Rectangle bounds = getBounds(widgetInfo);
|
|
||||||
if (bounds != null)
|
|
||||||
{
|
|
||||||
Arc2D.Double arc = new Arc2D.Double(bounds.x + OFFSET, bounds.y + (bounds.height / 2 - DIAMETER / 2), DIAMETER, DIAMETER, 90.d, -360.d * percent, Arc2D.OPEN);
|
|
||||||
g.setStroke(STROKE);
|
|
||||||
g.setColor(color);
|
|
||||||
g.draw(arc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2019, Sean Dewar <https://github.com/seandewar>
|
|
||||||
* Copyright (c) 2018, Abex
|
|
||||||
* Copyright (c) 2018, Zimaya <https://github.com/Zimaya>
|
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
|
||||||
* list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package net.runelite.client.plugins.regenmeter;
|
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.Constants;
|
|
||||||
import net.runelite.api.GameState;
|
|
||||||
import net.runelite.api.Prayer;
|
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.api.VarPlayer;
|
|
||||||
import net.runelite.api.events.ConfigChanged;
|
|
||||||
import net.runelite.api.events.GameStateChanged;
|
|
||||||
import net.runelite.api.events.GameTick;
|
|
||||||
import net.runelite.api.events.VarbitChanged;
|
|
||||||
import net.runelite.client.Notifier;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
|
||||||
import net.runelite.client.plugins.Plugin;
|
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
|
||||||
|
|
||||||
@PluginDescriptor(
|
|
||||||
name = "Regeneration Meter",
|
|
||||||
description = "Track and show the hitpoints and special attack regeneration timers",
|
|
||||||
tags = {"combat", "health", "hitpoints", "special", "attack", "overlay", "notifications"}
|
|
||||||
)
|
|
||||||
@Singleton
|
|
||||||
public class RegenMeterPlugin extends Plugin
|
|
||||||
{
|
|
||||||
private static final int SPEC_REGEN_TICKS = 50;
|
|
||||||
private static final int NORMAL_HP_REGEN_TICKS = 100;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private OverlayManager overlayManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Notifier notifier;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RegenMeterOverlay overlay;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RegenMeterConfig config;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private double hitpointsPercentage;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private double specialPercentage;
|
|
||||||
|
|
||||||
private int ticksSinceSpecRegen;
|
|
||||||
private int ticksSinceHPRegen;
|
|
||||||
private boolean wasRapidHeal;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private boolean showHitpoints;
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private boolean showSpecial;
|
|
||||||
private boolean showWhenNoChange;
|
|
||||||
private int getNotifyBeforeHpRegenSeconds;
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
RegenMeterConfig provideConfig(ConfigManager configManager)
|
|
||||||
{
|
|
||||||
return configManager.getConfig(RegenMeterConfig.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void startUp() throws Exception
|
|
||||||
{
|
|
||||||
updateConfig();
|
|
||||||
overlayManager.add(overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void shutDown() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.remove(overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
private void onGameStateChanged(GameStateChanged ev)
|
|
||||||
{
|
|
||||||
if (ev.getGameState() == GameState.HOPPING || ev.getGameState() == GameState.LOGIN_SCREEN)
|
|
||||||
{
|
|
||||||
ticksSinceHPRegen = -2; // For some reason this makes this accurate
|
|
||||||
ticksSinceSpecRegen = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
private void onVarbitChanged(VarbitChanged ev)
|
|
||||||
{
|
|
||||||
boolean isRapidHeal = client.isPrayerActive(Prayer.RAPID_HEAL);
|
|
||||||
if (wasRapidHeal != isRapidHeal)
|
|
||||||
{
|
|
||||||
ticksSinceHPRegen = 0;
|
|
||||||
}
|
|
||||||
wasRapidHeal = isRapidHeal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onGameTick(GameTick event)
|
|
||||||
{
|
|
||||||
if (client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT) == 1000)
|
|
||||||
{
|
|
||||||
// The recharge doesn't tick when at 100%
|
|
||||||
ticksSinceSpecRegen = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ticksSinceSpecRegen = (ticksSinceSpecRegen + 1) % SPEC_REGEN_TICKS;
|
|
||||||
}
|
|
||||||
specialPercentage = ticksSinceSpecRegen / (double) SPEC_REGEN_TICKS;
|
|
||||||
|
|
||||||
|
|
||||||
int ticksPerHPRegen = NORMAL_HP_REGEN_TICKS;
|
|
||||||
if (client.isPrayerActive(Prayer.RAPID_HEAL))
|
|
||||||
{
|
|
||||||
ticksPerHPRegen /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
ticksSinceHPRegen = (ticksSinceHPRegen + 1) % ticksPerHPRegen;
|
|
||||||
hitpointsPercentage = ticksSinceHPRegen / (double) ticksPerHPRegen;
|
|
||||||
|
|
||||||
int currentHP = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
|
||||||
int maxHP = client.getRealSkillLevel(Skill.HITPOINTS);
|
|
||||||
if (currentHP == maxHP && !this.showWhenNoChange)
|
|
||||||
{
|
|
||||||
hitpointsPercentage = 0;
|
|
||||||
}
|
|
||||||
else if (currentHP > maxHP)
|
|
||||||
{
|
|
||||||
// Show it going down
|
|
||||||
hitpointsPercentage = 1 - hitpointsPercentage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getNotifyBeforeHpRegenSeconds > 0 && currentHP < maxHP && shouldNotifyHpRegenThisTick(ticksPerHPRegen))
|
|
||||||
{
|
|
||||||
notifier.notify("[" + client.getLocalPlayer().getName() + "] regenerates their next hitpoint soon!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldNotifyHpRegenThisTick(int ticksPerHPRegen)
|
|
||||||
{
|
|
||||||
// if the configured duration lies between two ticks, choose the earlier tick
|
|
||||||
final int ticksBeforeHPRegen = ticksPerHPRegen - ticksSinceHPRegen;
|
|
||||||
final int notifyTick = (int) Math.ceil(this.getNotifyBeforeHpRegenSeconds * 1000d / Constants.GAME_TICK_LENGTH);
|
|
||||||
return ticksBeforeHPRegen == notifyTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onConfigChanged(ConfigChanged event)
|
|
||||||
{
|
|
||||||
if (event.getGroup().equals("regenmeter"))
|
|
||||||
{
|
|
||||||
updateConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateConfig()
|
|
||||||
{
|
|
||||||
this.showHitpoints = config.showHitpoints();
|
|
||||||
this.showSpecial = config.showSpecial();
|
|
||||||
this.showWhenNoChange = config.showWhenNoChange();
|
|
||||||
this.getNotifyBeforeHpRegenSeconds = config.getNotifyBeforeHpRegenSeconds();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, 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.runenergy;
|
|
||||||
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.Point;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
|
||||||
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
|
||||||
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class RunEnergyOverlay extends Overlay
|
|
||||||
{
|
|
||||||
private final RunEnergyPlugin plugin;
|
|
||||||
private final Client client;
|
|
||||||
private final RunEnergyConfig config;
|
|
||||||
private final TooltipManager tooltipManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RunEnergyOverlay(final RunEnergyPlugin plugin, final Client client, final RunEnergyConfig config, final TooltipManager tooltipManager)
|
|
||||||
{
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.client = client;
|
|
||||||
this.config = config;
|
|
||||||
this.tooltipManager = tooltipManager;
|
|
||||||
setPosition(OverlayPosition.DYNAMIC);
|
|
||||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension render(Graphics2D graphics)
|
|
||||||
{
|
|
||||||
final Widget runOrb = client.getWidget(WidgetInfo.MINIMAP_TOGGLE_RUN_ORB);
|
|
||||||
|
|
||||||
if (runOrb == null || runOrb.isHidden())
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Rectangle bounds = runOrb.getBounds();
|
|
||||||
|
|
||||||
if (bounds.getX() <= 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Point mousePosition = client.getMouseCanvasPosition();
|
|
||||||
|
|
||||||
if (bounds.contains(mousePosition.getX(), mousePosition.getY()))
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Weight: ").append(client.getWeight()).append(" kg</br>");
|
|
||||||
|
|
||||||
if (config.replaceOrbText())
|
|
||||||
{
|
|
||||||
sb.append("Run Energy: ").append(client.getEnergy()).append("%");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.append("Run Time Remaining: ").append(plugin.getEstimatedRunTimeRemaining(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
int secondsUntil100 = plugin.getEstimatedRecoverTimeRemaining();
|
|
||||||
if (secondsUntil100 > 0)
|
|
||||||
{
|
|
||||||
final int minutes = (int) Math.floor(secondsUntil100 / 60.0);
|
|
||||||
final int seconds = (int) Math.floor(secondsUntil100 - (minutes * 60.0));
|
|
||||||
|
|
||||||
sb.append("</br>").append("100% Energy In: ").append(minutes).append(':').append(StringUtils.leftPad(Integer.toString(seconds), 2, "0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltipManager.add(new Tooltip(sb.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,340 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, 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.runenergy;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.Constants;
|
|
||||||
import net.runelite.api.EquipmentInventorySlot;
|
|
||||||
import net.runelite.api.InventoryID;
|
|
||||||
import net.runelite.api.Item;
|
|
||||||
import net.runelite.api.ItemContainer;
|
|
||||||
import static net.runelite.api.ItemID.AGILITY_CAPE;
|
|
||||||
import static net.runelite.api.ItemID.AGILITY_CAPET;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_11861;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13589;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13590;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13601;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13602;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13613;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13614;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13625;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13626;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13637;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13638;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13677;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_13678;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_21076;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_BOOTS_21078;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_11853;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13581;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13582;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13593;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13594;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13605;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13606;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13617;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13618;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13629;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13630;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13669;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_13670;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_21064;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_CAPE_21066;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_11859;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13587;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13588;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13599;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13600;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13611;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13612;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13623;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13624;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13635;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13636;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13675;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_13676;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_21073;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_GLOVES_21075;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_11851;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13579;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13580;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13591;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13592;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13603;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13604;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13615;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13616;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13627;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13628;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13667;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_13668;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_21061;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_HOOD_21063;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_11857;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13585;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13586;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13597;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13598;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13609;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13610;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13621;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13622;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13633;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13634;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13673;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_13674;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_21070;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_LEGS_21072;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_11855;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13583;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13584;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13595;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13596;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13607;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13608;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13619;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13620;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13631;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13632;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13671;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_13672;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_21067;
|
|
||||||
import static net.runelite.api.ItemID.GRACEFUL_TOP_21069;
|
|
||||||
import static net.runelite.api.ItemID.MAX_CAPE;
|
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.api.Varbits;
|
|
||||||
import net.runelite.api.coords.WorldPoint;
|
|
||||||
import net.runelite.api.events.ConfigChanged;
|
|
||||||
import net.runelite.api.events.GameTick;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
|
||||||
import net.runelite.client.config.ConfigManager;
|
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
|
||||||
import net.runelite.client.plugins.Plugin;
|
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
@PluginDescriptor(
|
|
||||||
name = "Run Energy",
|
|
||||||
description = "Show various information related to run energy",
|
|
||||||
tags = {"overlay", "stamina"}
|
|
||||||
)
|
|
||||||
@Singleton
|
|
||||||
public class RunEnergyPlugin extends Plugin
|
|
||||||
{
|
|
||||||
// TODO It would be nice if we have the IDs for just the equipped variants of the Graceful set items.
|
|
||||||
private static final ImmutableSet<Integer> ALL_GRACEFUL_HOODS = ImmutableSet.of(
|
|
||||||
GRACEFUL_HOOD_11851, GRACEFUL_HOOD_13579, GRACEFUL_HOOD_13580, GRACEFUL_HOOD_13591, GRACEFUL_HOOD_13592,
|
|
||||||
GRACEFUL_HOOD_13603, GRACEFUL_HOOD_13604, GRACEFUL_HOOD_13615, GRACEFUL_HOOD_13616, GRACEFUL_HOOD_13627,
|
|
||||||
GRACEFUL_HOOD_13628, GRACEFUL_HOOD_13667, GRACEFUL_HOOD_13668, GRACEFUL_HOOD_21061, GRACEFUL_HOOD_21063
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final ImmutableSet<Integer> ALL_GRACEFUL_TOPS = ImmutableSet.of(
|
|
||||||
GRACEFUL_TOP_11855, GRACEFUL_TOP_13583, GRACEFUL_TOP_13584, GRACEFUL_TOP_13595, GRACEFUL_TOP_13596,
|
|
||||||
GRACEFUL_TOP_13607, GRACEFUL_TOP_13608, GRACEFUL_TOP_13619, GRACEFUL_TOP_13620, GRACEFUL_TOP_13631,
|
|
||||||
GRACEFUL_TOP_13632, GRACEFUL_TOP_13671, GRACEFUL_TOP_13672, GRACEFUL_TOP_21067, GRACEFUL_TOP_21069
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final ImmutableSet<Integer> ALL_GRACEFUL_LEGS = ImmutableSet.of(
|
|
||||||
GRACEFUL_LEGS_11857, GRACEFUL_LEGS_13585, GRACEFUL_LEGS_13586, GRACEFUL_LEGS_13597, GRACEFUL_LEGS_13598,
|
|
||||||
GRACEFUL_LEGS_13609, GRACEFUL_LEGS_13610, GRACEFUL_LEGS_13621, GRACEFUL_LEGS_13622, GRACEFUL_LEGS_13633,
|
|
||||||
GRACEFUL_LEGS_13634, GRACEFUL_LEGS_13673, GRACEFUL_LEGS_13674, GRACEFUL_LEGS_21070, GRACEFUL_LEGS_21072
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final ImmutableSet<Integer> ALL_GRACEFUL_GLOVES = ImmutableSet.of(
|
|
||||||
GRACEFUL_GLOVES_11859, GRACEFUL_GLOVES_13587, GRACEFUL_GLOVES_13588, GRACEFUL_GLOVES_13599, GRACEFUL_GLOVES_13600,
|
|
||||||
GRACEFUL_GLOVES_13611, GRACEFUL_GLOVES_13612, GRACEFUL_GLOVES_13623, GRACEFUL_GLOVES_13624, GRACEFUL_GLOVES_13635,
|
|
||||||
GRACEFUL_GLOVES_13636, GRACEFUL_GLOVES_13675, GRACEFUL_GLOVES_13676, GRACEFUL_GLOVES_21073, GRACEFUL_GLOVES_21075
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final ImmutableSet<Integer> ALL_GRACEFUL_BOOTS = ImmutableSet.of(
|
|
||||||
GRACEFUL_BOOTS_11861, GRACEFUL_BOOTS_13589, GRACEFUL_BOOTS_13590, GRACEFUL_BOOTS_13601, GRACEFUL_BOOTS_13602,
|
|
||||||
GRACEFUL_BOOTS_13613, GRACEFUL_BOOTS_13614, GRACEFUL_BOOTS_13625, GRACEFUL_BOOTS_13626, GRACEFUL_BOOTS_13637,
|
|
||||||
GRACEFUL_BOOTS_13638, GRACEFUL_BOOTS_13677, GRACEFUL_BOOTS_13678, GRACEFUL_BOOTS_21076, GRACEFUL_BOOTS_21078
|
|
||||||
);
|
|
||||||
|
|
||||||
// Agility skill capes and the non-cosmetic Max capes also count for the Graceful set effect
|
|
||||||
private static final ImmutableSet<Integer> ALL_GRACEFUL_CAPES = ImmutableSet.of(
|
|
||||||
GRACEFUL_CAPE_11853, GRACEFUL_CAPE_13581, GRACEFUL_CAPE_13582, GRACEFUL_CAPE_13593, GRACEFUL_CAPE_13594,
|
|
||||||
GRACEFUL_CAPE_13605, GRACEFUL_CAPE_13606, GRACEFUL_CAPE_13617, GRACEFUL_CAPE_13618, GRACEFUL_CAPE_13629,
|
|
||||||
GRACEFUL_CAPE_13630, GRACEFUL_CAPE_13669, GRACEFUL_CAPE_13670, GRACEFUL_CAPE_21064, GRACEFUL_CAPE_21066,
|
|
||||||
AGILITY_CAPE, AGILITY_CAPET, MAX_CAPE
|
|
||||||
);
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Client client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private OverlayManager overlayManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RunEnergyOverlay energyOverlay;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RunEnergyConfig energyConfig;
|
|
||||||
|
|
||||||
private boolean localPlayerRunningToDestination;
|
|
||||||
private WorldPoint prevLocalPlayerLocation;
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
RunEnergyConfig getConfig(ConfigManager configManager)
|
|
||||||
{
|
|
||||||
return configManager.getConfig(RunEnergyConfig.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void startUp() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.add(energyOverlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void shutDown() throws Exception
|
|
||||||
{
|
|
||||||
overlayManager.remove(energyOverlay);
|
|
||||||
localPlayerRunningToDestination = false;
|
|
||||||
prevLocalPlayerLocation = null;
|
|
||||||
resetRunOrbText();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onGameTick(GameTick event)
|
|
||||||
{
|
|
||||||
localPlayerRunningToDestination =
|
|
||||||
prevLocalPlayerLocation != null &&
|
|
||||||
client.getLocalDestinationLocation() != null &&
|
|
||||||
prevLocalPlayerLocation.distanceTo(client.getLocalPlayer().getWorldLocation()) > 1;
|
|
||||||
|
|
||||||
prevLocalPlayerLocation = client.getLocalPlayer().getWorldLocation();
|
|
||||||
|
|
||||||
if (energyConfig.replaceOrbText())
|
|
||||||
{
|
|
||||||
setRunOrbText(getEstimatedRunTimeRemaining(true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onConfigChanged(ConfigChanged event)
|
|
||||||
{
|
|
||||||
if (event.getGroup().equals("runenergy") && !energyConfig.replaceOrbText())
|
|
||||||
{
|
|
||||||
resetRunOrbText();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setRunOrbText(String text)
|
|
||||||
{
|
|
||||||
Widget runOrbText = client.getWidget(WidgetInfo.MINIMAP_RUN_ORB_TEXT);
|
|
||||||
|
|
||||||
if (runOrbText != null)
|
|
||||||
{
|
|
||||||
runOrbText.setText(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetRunOrbText()
|
|
||||||
{
|
|
||||||
setRunOrbText(Integer.toString(client.getEnergy()));
|
|
||||||
}
|
|
||||||
|
|
||||||
String getEstimatedRunTimeRemaining(boolean inSeconds)
|
|
||||||
{
|
|
||||||
// Calculate the amount of energy lost every tick.
|
|
||||||
// Negative weight has the same depletion effect as 0 kg.
|
|
||||||
final int effectiveWeight = Math.max(client.getWeight(), 0);
|
|
||||||
double lossRate = (Math.min(effectiveWeight, 64) / 100.0) + 0.64;
|
|
||||||
|
|
||||||
if (client.getVar(Varbits.RUN_SLOWED_DEPLETION_ACTIVE) != 0)
|
|
||||||
{
|
|
||||||
lossRate *= 0.3; // Stamina effect reduces energy depletion to 30%
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the number of seconds left
|
|
||||||
final double secondsLeft = (client.getEnergy() * Constants.GAME_TICK_LENGTH) / (lossRate * 1000.0);
|
|
||||||
|
|
||||||
// Return the text
|
|
||||||
if (inSeconds)
|
|
||||||
{
|
|
||||||
return (int) Math.floor(secondsLeft) + "s";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
final int minutes = (int) Math.floor(secondsLeft / 60.0);
|
|
||||||
final int seconds = (int) Math.floor(secondsLeft - (minutes * 60.0));
|
|
||||||
|
|
||||||
return minutes + ":" + StringUtils.leftPad(Integer.toString(seconds), 2, "0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isLocalPlayerWearingFullGraceful()
|
|
||||||
{
|
|
||||||
final ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
|
|
||||||
|
|
||||||
if (equipment == null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Item[] items = equipment.getItems();
|
|
||||||
|
|
||||||
// Check that the local player is wearing enough items to be using full Graceful
|
|
||||||
// (the Graceful boots will have the highest slot index in the worn set).
|
|
||||||
if (items == null || items.length <= EquipmentInventorySlot.BOOTS.getSlotIdx())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ALL_GRACEFUL_HOODS.contains(items[EquipmentInventorySlot.HEAD.getSlotIdx()].getId()) &&
|
|
||||||
ALL_GRACEFUL_TOPS.contains(items[EquipmentInventorySlot.BODY.getSlotIdx()].getId()) &&
|
|
||||||
ALL_GRACEFUL_LEGS.contains(items[EquipmentInventorySlot.LEGS.getSlotIdx()].getId()) &&
|
|
||||||
ALL_GRACEFUL_GLOVES.contains(items[EquipmentInventorySlot.GLOVES.getSlotIdx()].getId()) &&
|
|
||||||
ALL_GRACEFUL_BOOTS.contains(items[EquipmentInventorySlot.BOOTS.getSlotIdx()].getId()) &&
|
|
||||||
ALL_GRACEFUL_CAPES.contains(items[EquipmentInventorySlot.CAPE.getSlotIdx()].getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int getEstimatedRecoverTimeRemaining()
|
|
||||||
{
|
|
||||||
if (localPlayerRunningToDestination)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the amount of energy recovered every second
|
|
||||||
double recoverRate = (48 + client.getBoostedSkillLevel(Skill.AGILITY)) / 360.0;
|
|
||||||
|
|
||||||
if (isLocalPlayerWearingFullGraceful())
|
|
||||||
{
|
|
||||||
recoverRate *= 1.3; // 30% recover rate increase from Graceful set effect
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the number of seconds left
|
|
||||||
return (int) ((100 - client.getEnergy()) / recoverRate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,675 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* 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.skillcalculator;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.JCheckBox;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.runelite.api.Client;
|
|
||||||
import net.runelite.api.Experience;
|
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.client.game.ItemManager;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.beans.SecondaryItem;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.ui.CriticalItemPanel;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.beans.SkillDataBonus;
|
|
||||||
import net.runelite.client.ui.ColorScheme;
|
|
||||||
import net.runelite.client.ui.DynamicGridLayout;
|
|
||||||
import net.runelite.client.ui.FontManager;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Singleton
|
|
||||||
public class BankedCalculator extends JPanel
|
|
||||||
{
|
|
||||||
private static final DecimalFormat XP_FORMAT_COMMA = new DecimalFormat("#,###.#");
|
|
||||||
|
|
||||||
private final SkillCalculatorPanel parent;
|
|
||||||
private final Client client;
|
|
||||||
private final UICalculatorInputArea uiInput;
|
|
||||||
private final SkillCalculatorConfig config;
|
|
||||||
private final ItemManager itemManager;
|
|
||||||
|
|
||||||
private final CacheSkillData skillData = new CacheSkillData();
|
|
||||||
private final List<JCheckBox> bonusCheckBoxes = new ArrayList<>();
|
|
||||||
|
|
||||||
// UI Input data
|
|
||||||
private float xpFactor = 1.0f;
|
|
||||||
private CalculatorType currentCalc;
|
|
||||||
private Skill currentSkill;
|
|
||||||
|
|
||||||
private double totalBankedXp = 0.0f;
|
|
||||||
private final JLabel totalLabel = new JLabel();
|
|
||||||
private final JPanel detailConfigContainer;
|
|
||||||
private final JPanel detailContainer;
|
|
||||||
|
|
||||||
// Banked Experience magic
|
|
||||||
private Map<Integer, Integer> bankMap = new HashMap<>();
|
|
||||||
private final Map<String, Boolean> categoryMap = new HashMap<>(); // Check if CriticalItem Category is enabled
|
|
||||||
private final Map<CriticalItem, CriticalItemPanel> panelMap = new HashMap<>();
|
|
||||||
private final Map<CriticalItem, Integer> criticalMap = new HashMap<>(); // Quantity of CriticalItem inside bankMap
|
|
||||||
private final Map<CriticalItem, Activity> activityMap = new HashMap<>(); // Selected Activity used for calculating xp
|
|
||||||
private final Map<CriticalItem, Integer> linkedMap = new HashMap<>(); // ItemID of item that links to the CriticalItem
|
|
||||||
|
|
||||||
BankedCalculator(
|
|
||||||
final SkillCalculatorPanel parent,
|
|
||||||
final Client client,
|
|
||||||
final UICalculatorInputArea uiInput,
|
|
||||||
final SkillCalculatorConfig config,
|
|
||||||
final ItemManager itemManager)
|
|
||||||
{
|
|
||||||
this.parent = parent;
|
|
||||||
this.client = client;
|
|
||||||
this.uiInput = uiInput;
|
|
||||||
this.config = config;
|
|
||||||
this.itemManager = itemManager;
|
|
||||||
|
|
||||||
setLayout(new DynamicGridLayout(0, 1, 0, 5));
|
|
||||||
|
|
||||||
detailContainer = new JPanel();
|
|
||||||
detailContainer.setLayout(new BoxLayout(detailContainer, BoxLayout.Y_AXIS));
|
|
||||||
|
|
||||||
detailConfigContainer = new JPanel();
|
|
||||||
detailConfigContainer.setLayout(new BoxLayout(detailConfigContainer, BoxLayout.Y_AXIS));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reset()
|
|
||||||
{
|
|
||||||
criticalMap.clear();
|
|
||||||
linkedMap.clear();
|
|
||||||
xpFactor = 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update target Xp and Level inputs to match current Xp + total banked XP
|
|
||||||
*/
|
|
||||||
private void syncInputFields()
|
|
||||||
{
|
|
||||||
// Update Target XP & Level to include total banked xp
|
|
||||||
int newTotal = (int) (uiInput.getCurrentXPInput() + totalBankedXp);
|
|
||||||
uiInput.setTargetXPInput(newTotal);
|
|
||||||
uiInput.setTargetLevelInput(Experience.getLevelForXp(newTotal));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Banked Experience Logic
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows the Banked Xp tab for the CalculatorType
|
|
||||||
*
|
|
||||||
* @param calculatorType Selected Calculator Type
|
|
||||||
*/
|
|
||||||
void openBanked(CalculatorType calculatorType)
|
|
||||||
{
|
|
||||||
// clean slate for creating the required panel
|
|
||||||
removeAll();
|
|
||||||
reset();
|
|
||||||
if (calculatorType.getSkill() != currentSkill)
|
|
||||||
{
|
|
||||||
// Only clear Category and Activity map on skill change.
|
|
||||||
activityMap.clear();
|
|
||||||
categoryMap.clear();
|
|
||||||
}
|
|
||||||
currentCalc = calculatorType;
|
|
||||||
currentSkill = calculatorType.getSkill();
|
|
||||||
bankMap = parent.getBankMap();
|
|
||||||
|
|
||||||
uiInput.setCurrentLevelInput(client.getRealSkillLevel(currentSkill));
|
|
||||||
uiInput.setCurrentXPInput(client.getSkillExperience(currentSkill));
|
|
||||||
|
|
||||||
// Only adds Banked Experience portion if enabled for this SkillCalc and have seen their bank
|
|
||||||
if (!calculatorType.isBankedXpFlag())
|
|
||||||
{
|
|
||||||
add(new JLabel("<html><div style='text-align: center;'>Banked Experience is not enabled for this skill.</div></html>", JLabel.CENTER));
|
|
||||||
}
|
|
||||||
else if (bankMap.size() <= 0)
|
|
||||||
{
|
|
||||||
add(new JLabel("Please visit a bank!", JLabel.CENTER));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Prevent editing of the target level/exp since we automagically adjust them
|
|
||||||
uiInput.getUiFieldTargetLevel().setEditable(false);
|
|
||||||
uiInput.getUiFieldTargetXP().setEditable(false);
|
|
||||||
|
|
||||||
// Now we can actually show the Banked Experience Panel
|
|
||||||
// Adds Config Options for this panel
|
|
||||||
renderBankedXpOptions();
|
|
||||||
|
|
||||||
renderBonusXpOptions();
|
|
||||||
|
|
||||||
// sprite 202
|
|
||||||
calculatedBankedMaps();
|
|
||||||
|
|
||||||
// Calculate total banked experience and create detail container
|
|
||||||
refreshDetailContainer();
|
|
||||||
|
|
||||||
// Add back all necessary content
|
|
||||||
add(detailConfigContainer);
|
|
||||||
add(totalLabel);
|
|
||||||
add(detailContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
|
|
||||||
// Update the input fields.
|
|
||||||
syncInputFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the config options for toggling each Item Category
|
|
||||||
*/
|
|
||||||
private void renderBankedXpOptions()
|
|
||||||
{
|
|
||||||
Set<String> categories = CriticalItem.getSkillCategories(currentSkill);
|
|
||||||
if (categories == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
add(new JLabel("Configs:"));
|
|
||||||
|
|
||||||
for (String category : categories)
|
|
||||||
{
|
|
||||||
JPanel uiOption = new JPanel(new BorderLayout());
|
|
||||||
JLabel uiLabel = new JLabel(category);
|
|
||||||
JCheckBox uiCheckbox = new JCheckBox();
|
|
||||||
|
|
||||||
uiLabel.setForeground(Color.WHITE);
|
|
||||||
uiLabel.setFont(FontManager.getRunescapeSmallFont());
|
|
||||||
|
|
||||||
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
|
|
||||||
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
|
||||||
|
|
||||||
// Everything is enabled by default
|
|
||||||
uiCheckbox.setSelected(true);
|
|
||||||
categoryMap.put(category, true);
|
|
||||||
|
|
||||||
// Adjust Total Banked XP check-state of the box.
|
|
||||||
uiCheckbox.addActionListener(e -> toggleCategory(category, uiCheckbox.isSelected()));
|
|
||||||
uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR);
|
|
||||||
|
|
||||||
uiOption.add(uiLabel, BorderLayout.WEST);
|
|
||||||
uiOption.add(uiCheckbox, BorderLayout.EAST);
|
|
||||||
|
|
||||||
add(uiOption);
|
|
||||||
add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to toggle Categories of Items inside the Banked Xp tab
|
|
||||||
*
|
|
||||||
* @param category Category Name
|
|
||||||
* @param enabled is enabled
|
|
||||||
*/
|
|
||||||
private void toggleCategory(String category, boolean enabled)
|
|
||||||
{
|
|
||||||
categoryMap.put(category, enabled);
|
|
||||||
refreshDetailContainer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the Maps used for easy access when calculating Banked Xp
|
|
||||||
*/
|
|
||||||
private void calculatedBankedMaps()
|
|
||||||
{
|
|
||||||
// Grab all CriticalItems for this skill
|
|
||||||
List<CriticalItem> items = CriticalItem.getBySkillName(currentSkill);
|
|
||||||
|
|
||||||
// Loop over all Critical Items for this skill and determine how many are in the bank
|
|
||||||
for (CriticalItem item : items)
|
|
||||||
{
|
|
||||||
Integer qty = bankMap.get(item.getItemID());
|
|
||||||
if (qty != null && qty > 0)
|
|
||||||
{
|
|
||||||
if (criticalMap.containsKey(item))
|
|
||||||
{
|
|
||||||
criticalMap.put(item, criticalMap.get(item) + qty);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
criticalMap.put(item, qty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the item this is linked to maps back to us.
|
|
||||||
if (item.getLinkedItemId() != -1)
|
|
||||||
{
|
|
||||||
CriticalItem i = CriticalItem.getByItemId(item.getLinkedItemId());
|
|
||||||
if (i != null)
|
|
||||||
{
|
|
||||||
linkedMap.put(i, item.getItemID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Populates the detailContainer with the necessary CriticalItemPanels
|
|
||||||
*/
|
|
||||||
private void refreshDetailContainer()
|
|
||||||
{
|
|
||||||
detailContainer.removeAll();
|
|
||||||
panelMap.clear();
|
|
||||||
|
|
||||||
Map<CriticalItem, Integer> map = getBankedXpBreakdown();
|
|
||||||
for (Map.Entry<CriticalItem, Integer> entry : map.entrySet())
|
|
||||||
{
|
|
||||||
CriticalItem item = entry.getKey();
|
|
||||||
createItemPanel(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
detailContainer.revalidate();
|
|
||||||
detailContainer.repaint();
|
|
||||||
|
|
||||||
calculateBankedXpTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an Individual Item Panel if it should be displayed
|
|
||||||
*
|
|
||||||
* @param item CriticalItem this information is tied too
|
|
||||||
*/
|
|
||||||
private void createItemPanel(CriticalItem item)
|
|
||||||
{
|
|
||||||
// Category Included?
|
|
||||||
if (categoryMap.get(item.getCategory()))
|
|
||||||
{
|
|
||||||
// Get possible activities limited to current level
|
|
||||||
List<Activity> activities = Activity.getByCriticalItem(item, uiInput.getCurrentLevelInput());
|
|
||||||
|
|
||||||
// Check if this should count as another item.
|
|
||||||
if (item.getLinkedItemId() != -1)
|
|
||||||
{
|
|
||||||
// Ensure the linked item panel is created even if there are none in bank.
|
|
||||||
CriticalItem linked = CriticalItem.getByItemId(item.getLinkedItemId());
|
|
||||||
if (!criticalMap.containsKey(linked))
|
|
||||||
{
|
|
||||||
createItemPanel(linked);
|
|
||||||
}
|
|
||||||
|
|
||||||
// One activity and rewards no xp ignore.
|
|
||||||
if (activities.size() == 1 && activities.get(0).getXp() <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it doesn't have any activities ignore it in the breakdown.
|
|
||||||
if (activities.size() <= 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Either this item has multiple activities or the single activity rewards xp, create the item panel.
|
|
||||||
|
|
||||||
// Determine xp rate for this item
|
|
||||||
Activity a = getSelectedActivity(item);
|
|
||||||
double activityXp = a == null ? 0 : a.getXp();
|
|
||||||
double xp = activityXp * (item.isIgnoreBonus() ? 1.0f : xpFactor);
|
|
||||||
int amount = 0;
|
|
||||||
|
|
||||||
// If it has linked items figure out the working total.
|
|
||||||
Map<CriticalItem, Integer> links = getLinkedTotalMap(item);
|
|
||||||
for (Integer num : links.values())
|
|
||||||
{
|
|
||||||
amount += num;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually create the panel displaying banked experience for this item
|
|
||||||
CriticalItemPanel panel = new CriticalItemPanel(this, itemManager, item, xp, amount, links);
|
|
||||||
|
|
||||||
// Limit to Banked Secondaries
|
|
||||||
if (config.limitedBankedSecondaries() && a != null)
|
|
||||||
{
|
|
||||||
panel.updateAmount(limitToActivitySecondaries(a, amount), true);
|
|
||||||
panel.recalculate();
|
|
||||||
}
|
|
||||||
panelMap.put(item, panel);
|
|
||||||
detailContainer.add(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the Activity the player selected for this Item. Defaults to First activity
|
|
||||||
*
|
|
||||||
* @param i CriticalItem to check for
|
|
||||||
* @return selected Activity
|
|
||||||
*/
|
|
||||||
public Activity getSelectedActivity(CriticalItem i)
|
|
||||||
{
|
|
||||||
// Pull from memory if available
|
|
||||||
Activity a = activityMap.get(i);
|
|
||||||
if (a != null)
|
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not in memory select the first Activity and add to memory
|
|
||||||
List<Activity> activities = Activity.getByCriticalItem(i);
|
|
||||||
if (activities.size() == 0)
|
|
||||||
{
|
|
||||||
// If you can't find an activity it means this item must link to one and give 0 xp
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Activity selected = activities.get(0);
|
|
||||||
activityMap.put(i, selected);
|
|
||||||
return selected;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Map of Item ID and QTY for this Skill by Category. Keeps order for better UI display
|
|
||||||
*
|
|
||||||
* @return Map of Item ID and QTY for this Skill by Category
|
|
||||||
*/
|
|
||||||
private Map<CriticalItem, Integer> getBankedXpBreakdown()
|
|
||||||
{
|
|
||||||
Map<CriticalItem, Integer> map = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
for (String category : CriticalItem.getSkillCategories(currentSkill))
|
|
||||||
{
|
|
||||||
List<CriticalItem> items = CriticalItem.getItemsForSkillCategories(currentSkill, category);
|
|
||||||
for (CriticalItem item : items)
|
|
||||||
{
|
|
||||||
Integer amount = bankMap.get(item.getItemID());
|
|
||||||
if (amount != null && amount > 0)
|
|
||||||
{
|
|
||||||
map.put(item, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to select an Activity for an item
|
|
||||||
*
|
|
||||||
* @param i CriticalItem
|
|
||||||
* @param a Activity selected
|
|
||||||
*/
|
|
||||||
public void activitySelected(CriticalItem i, Activity a)
|
|
||||||
{
|
|
||||||
// This is triggered on every click so don't update if activity didn't actually change
|
|
||||||
Activity cur = activityMap.get(i);
|
|
||||||
if (cur != null && cur.equals(a))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update selected activity in map
|
|
||||||
activityMap.put(i, a);
|
|
||||||
|
|
||||||
// If had a previous selection and this item links to another check for item prevention change.
|
|
||||||
// If there are changes adjust the Linked panel quantity as well
|
|
||||||
if (cur != null && i.getLinkedItemId() != -1 && cur.isPreventLinked() != a.isPreventLinked())
|
|
||||||
{
|
|
||||||
CriticalItem linked = CriticalItem.getByItemId(i.getLinkedItemId());
|
|
||||||
CriticalItemPanel l = panelMap.get(linked);
|
|
||||||
if (l != null)
|
|
||||||
{
|
|
||||||
l.updateLinkedMap(getLinkedTotalMap(linked));
|
|
||||||
int amount = config.limitedBankedSecondaries() ? limitToActivitySecondaries(a, l.getAmount()) : l.getAmount();
|
|
||||||
l.updateAmount(amount, false);
|
|
||||||
l.recalculate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Total banked experience
|
|
||||||
CriticalItemPanel p = panelMap.get(i);
|
|
||||||
if (p != null)
|
|
||||||
{
|
|
||||||
p.updateLinkedMap(getLinkedTotalMap(i));
|
|
||||||
int amount = config.limitedBankedSecondaries() ? limitToActivitySecondaries(a, p.getAmount()) : p.getAmount();
|
|
||||||
p.updateAmount(amount, true);
|
|
||||||
p.updateXp(a.getXp() * (i.isIgnoreBonus() ? 1.0f : xpFactor));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update total banked xp value based on updated panels
|
|
||||||
calculateBankedXpTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<CriticalItem, Integer> getLinkedTotalMap(CriticalItem i)
|
|
||||||
{
|
|
||||||
return getLinkedTotalMap(i, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a Map of CriticalItem and Qty for all items that link to the passed CriticalItem
|
|
||||||
*
|
|
||||||
* @param i CriticalItem to base Map off of
|
|
||||||
* @param first Since this is called recursively we want to ensure the original CriticalItem is always added
|
|
||||||
* @return Map of Linked CriticalItems and their Qty
|
|
||||||
*/
|
|
||||||
private Map<CriticalItem, Integer> getLinkedTotalMap(CriticalItem i, boolean first)
|
|
||||||
{
|
|
||||||
Map<CriticalItem, Integer> map = new LinkedHashMap<>();
|
|
||||||
if (!categoryMap.get(i.getCategory()))
|
|
||||||
{
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This item has an activity selected and its preventing linked functionality?
|
|
||||||
Activity selected = activityMap.get(i);
|
|
||||||
if (selected != null && selected.isPreventLinked()
|
|
||||||
// If initial request is for this item
|
|
||||||
&& !first)
|
|
||||||
{
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add self to map
|
|
||||||
int amount = criticalMap.getOrDefault(i, 0);
|
|
||||||
if (amount > 0)
|
|
||||||
{
|
|
||||||
map.put(i, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This item doesn't link to anything, all done.
|
|
||||||
if (linkedMap.get(i) == null)
|
|
||||||
{
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
CriticalItem item = CriticalItem.getByItemId(linkedMap.get(i));
|
|
||||||
if (item == null)
|
|
||||||
{
|
|
||||||
log.warn("Error finding Critical Item for Item ID: {}", linkedMap.get(i));
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
map.putAll(getLinkedTotalMap(item, false));
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SkillCalculatorPlugin sends the Bank Map when the bank contents change
|
|
||||||
*
|
|
||||||
* @param map Map of Item IDs and Quantity
|
|
||||||
*/
|
|
||||||
void updateBankMap(Map<Integer, Integer> map)
|
|
||||||
{
|
|
||||||
boolean oldMapFlag = (bankMap.size() <= 0);
|
|
||||||
bankMap = map;
|
|
||||||
// Refresh entire panel if old map was empty
|
|
||||||
if (oldMapFlag)
|
|
||||||
{
|
|
||||||
CalculatorType calc = CalculatorType.getBySkill(currentSkill);
|
|
||||||
SwingUtilities.invokeLater(() ->
|
|
||||||
{
|
|
||||||
if (calc != null)
|
|
||||||
{
|
|
||||||
openBanked(calc);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// recalculate all data related to banked experience except for activity selections
|
|
||||||
criticalMap.clear();
|
|
||||||
linkedMap.clear();
|
|
||||||
calculatedBankedMaps();
|
|
||||||
|
|
||||||
// Update the Total XP banked and the details panel
|
|
||||||
SwingUtilities.invokeLater(this::refreshDetailContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loops over all ItemPanels too sum their total xp and updates the label with the new value
|
|
||||||
*/
|
|
||||||
private void calculateBankedXpTotal()
|
|
||||||
{
|
|
||||||
double total = 0.0;
|
|
||||||
for (CriticalItemPanel p : panelMap.values())
|
|
||||||
{
|
|
||||||
total += p.getTotal();
|
|
||||||
}
|
|
||||||
|
|
||||||
totalBankedXp = total;
|
|
||||||
|
|
||||||
syncBankedXp();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to update the UI to reflect the new Banked XP amount
|
|
||||||
*/
|
|
||||||
private void syncBankedXp()
|
|
||||||
{
|
|
||||||
totalLabel.setText("Total Banked xp: " + XP_FORMAT_COMMA.format(totalBankedXp));
|
|
||||||
|
|
||||||
syncInputFields();
|
|
||||||
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check Bank for Activity Secondaries and Limits to possible Activity amounts
|
|
||||||
*
|
|
||||||
* @param a Selected Activity
|
|
||||||
* @param possible Amount of Critical Item available
|
|
||||||
* @return possible Limited to Banked Secondaries
|
|
||||||
*/
|
|
||||||
private int limitToActivitySecondaries(Activity a, int possible)
|
|
||||||
{
|
|
||||||
for (SecondaryItem i : a.getSecondaries())
|
|
||||||
{
|
|
||||||
int banked = bankMap.getOrDefault(i.getId(), 0);
|
|
||||||
int newPossible = banked / i.getQty();
|
|
||||||
possible = newPossible < possible ? newPossible : possible;
|
|
||||||
}
|
|
||||||
|
|
||||||
return possible;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the Xp Modifier options
|
|
||||||
*/
|
|
||||||
|
|
||||||
private void renderBonusXpOptions()
|
|
||||||
{
|
|
||||||
SkillDataBonus[] bonuses = skillData.getSkillData(currentCalc.getDataFile()).getBonuses();
|
|
||||||
if (bonuses != null)
|
|
||||||
{
|
|
||||||
add(new JLabel("Bonus Experience:"));
|
|
||||||
for (SkillDataBonus bonus : bonuses)
|
|
||||||
{
|
|
||||||
JPanel checkboxPanel = buildCheckboxPanel(bonus);
|
|
||||||
|
|
||||||
add(checkboxPanel);
|
|
||||||
add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel buildCheckboxPanel(SkillDataBonus bonus)
|
|
||||||
{
|
|
||||||
JPanel uiOption = new JPanel(new BorderLayout());
|
|
||||||
JLabel uiLabel = new JLabel(bonus.getName());
|
|
||||||
JCheckBox uiCheckbox = new JCheckBox();
|
|
||||||
|
|
||||||
uiLabel.setForeground(Color.WHITE);
|
|
||||||
uiLabel.setFont(FontManager.getRunescapeSmallFont());
|
|
||||||
|
|
||||||
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
|
|
||||||
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
|
||||||
|
|
||||||
// Adjust XP bonus depending on check-state of the boxes.
|
|
||||||
uiCheckbox.addActionListener(event -> adjustCheckboxes(uiCheckbox, bonus));
|
|
||||||
|
|
||||||
uiCheckbox.setBackground(ColorScheme.MEDIUM_GRAY_COLOR);
|
|
||||||
|
|
||||||
uiOption.add(uiLabel, BorderLayout.WEST);
|
|
||||||
uiOption.add(uiCheckbox, BorderLayout.EAST);
|
|
||||||
bonusCheckBoxes.add(uiCheckbox);
|
|
||||||
|
|
||||||
return uiOption;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void adjustCheckboxes(JCheckBox target, SkillDataBonus bonus)
|
|
||||||
{
|
|
||||||
adjustXPBonus(0);
|
|
||||||
bonusCheckBoxes.forEach(otherSelectedCheckbox ->
|
|
||||||
{
|
|
||||||
if (otherSelectedCheckbox != target)
|
|
||||||
{
|
|
||||||
otherSelectedCheckbox.setSelected(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (target.isSelected())
|
|
||||||
{
|
|
||||||
adjustXPBonus(bonus.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void adjustXPBonus(float value)
|
|
||||||
{
|
|
||||||
xpFactor = 1f + value;
|
|
||||||
refreshDetailContainer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -35,7 +35,7 @@ class CacheSkillData
|
|||||||
{
|
{
|
||||||
private final Map<String, SkillData> cache = new HashMap<>();
|
private final Map<String, SkillData> cache = new HashMap<>();
|
||||||
|
|
||||||
SkillData getSkillData(final String dataFile)
|
SkillData getSkillData(String dataFile)
|
||||||
{
|
{
|
||||||
if (cache.containsKey(dataFile))
|
if (cache.containsKey(dataFile))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
|
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -25,47 +24,32 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.skillcalculator;
|
package net.runelite.client.plugins.skillcalculator;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter
|
||||||
public enum CalculatorType
|
enum CalculatorType
|
||||||
{
|
{
|
||||||
AGILITY(Skill.AGILITY, "skill_agility.json", false),
|
MINING(Skill.MINING, "skill_mining.json"),
|
||||||
CONSTRUCTION(Skill.CONSTRUCTION, "skill_construction.json", true),
|
AGILITY(Skill.AGILITY, "skill_agility.json"),
|
||||||
COOKING(Skill.COOKING, "skill_cooking.json", true),
|
SMITHING(Skill.SMITHING, "skill_smithing.json"),
|
||||||
CRAFTING(Skill.CRAFTING, "skill_crafting.json", true),
|
HERBLORE(Skill.HERBLORE, "skill_herblore.json"),
|
||||||
FARMING(Skill.FARMING, "skill_farming.json", true),
|
FISHING(Skill.FISHING, "skill_fishing.json"),
|
||||||
FIREMAKING(Skill.FIREMAKING, "skill_firemaking.json", false),
|
THIEVING(Skill.THIEVING, "skill_thieving.json"),
|
||||||
FLETCHING(Skill.FLETCHING, "skill_fletching.json", false),
|
COOKING(Skill.COOKING, "skill_cooking.json"),
|
||||||
FISHING(Skill.FISHING, "skill_fishing.json", false),
|
PRAYER(Skill.PRAYER, "skill_prayer.json"),
|
||||||
HERBLORE(Skill.HERBLORE, "skill_herblore.json", true),
|
CRAFTING(Skill.CRAFTING, "skill_crafting.json"),
|
||||||
HUNTER(Skill.HUNTER, "skill_hunter.json", false),
|
FIREMAKING(Skill.FIREMAKING, "skill_firemaking.json"),
|
||||||
MAGIC(Skill.MAGIC, "skill_magic.json", false),
|
MAGIC(Skill.MAGIC, "skill_magic.json"),
|
||||||
MINING(Skill.MINING, "skill_mining.json", false),
|
FLETCHING(Skill.FLETCHING, "skill_fletching.json"),
|
||||||
PRAYER(Skill.PRAYER, "skill_prayer.json", true),
|
WOODCUTTING(Skill.WOODCUTTING, "skill_woodcutting.json"),
|
||||||
RUNECRAFT(Skill.RUNECRAFT, "skill_runecraft.json", false),
|
RUNECRAFT(Skill.RUNECRAFT, "skill_runecraft.json"),
|
||||||
SMITHING(Skill.SMITHING, "skill_smithing.json", true),
|
FARMING(Skill.FARMING, "skill_farming.json"),
|
||||||
THIEVING(Skill.THIEVING, "skill_thieving.json", false),
|
CONSTRUCTION(Skill.CONSTRUCTION, "skill_construction.json"),
|
||||||
WOODCUTTING(Skill.WOODCUTTING, "skill_woodcutting.json", false);
|
HUNTER(Skill.HUNTER, "skill_hunter.json");
|
||||||
|
|
||||||
private final Skill skill;
|
private final Skill skill;
|
||||||
private final String dataFile;
|
private final String dataFile;
|
||||||
private final boolean bankedXpFlag;
|
|
||||||
|
|
||||||
public static CalculatorType getBySkill(Skill skill)
|
|
||||||
{
|
|
||||||
for (CalculatorType c : values())
|
|
||||||
{
|
|
||||||
if (c.getSkill().equals(skill))
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -34,18 +34,13 @@ import java.text.DecimalFormat;
|
|||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.JCheckBox;
|
import javax.swing.JCheckBox;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Experience;
|
import net.runelite.api.Experience;
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.game.SpriteManager;
|
import net.runelite.client.game.SpriteManager;
|
||||||
import net.runelite.client.plugins.skillcalculator.beans.SkillData;
|
import net.runelite.client.plugins.skillcalculator.beans.SkillData;
|
||||||
@@ -59,7 +54,6 @@ import net.runelite.client.ui.components.IconTextField;
|
|||||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class SkillCalculator extends JPanel
|
class SkillCalculator extends JPanel
|
||||||
{
|
{
|
||||||
private static final int MAX_XP = 200_000_000;
|
private static final int MAX_XP = 200_000_000;
|
||||||
@@ -71,9 +65,7 @@ class SkillCalculator extends JPanel
|
|||||||
private final ItemManager itemManager;
|
private final ItemManager itemManager;
|
||||||
private final List<UIActionSlot> uiActionSlots = new ArrayList<>();
|
private final List<UIActionSlot> uiActionSlots = new ArrayList<>();
|
||||||
private final CacheSkillData cacheSkillData = new CacheSkillData();
|
private final CacheSkillData cacheSkillData = new CacheSkillData();
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private final UICombinedActionSlot combinedActionSlot;
|
private final UICombinedActionSlot combinedActionSlot;
|
||||||
@Getter(AccessLevel.PACKAGE)
|
|
||||||
private final List<UIActionSlot> combinedActionSlots = new ArrayList<>();
|
private final List<UIActionSlot> combinedActionSlots = new ArrayList<>();
|
||||||
private final List<JCheckBox> bonusCheckBoxes = new ArrayList<>();
|
private final List<JCheckBox> bonusCheckBoxes = new ArrayList<>();
|
||||||
private final IconTextField searchBar = new IconTextField();
|
private final IconTextField searchBar = new IconTextField();
|
||||||
@@ -85,9 +77,8 @@ class SkillCalculator extends JPanel
|
|||||||
private int targetXP = Experience.getXpForLevel(targetLevel);
|
private int targetXP = Experience.getXpForLevel(targetLevel);
|
||||||
private float xpFactor = 1.0f;
|
private float xpFactor = 1.0f;
|
||||||
private float lastBonus = 0.0f;
|
private float lastBonus = 0.0f;
|
||||||
private CalculatorType calculatorType;
|
|
||||||
|
|
||||||
SkillCalculator(final Client client, final UICalculatorInputArea uiInput, final SpriteManager spriteManager, final ItemManager itemManager)
|
SkillCalculator(Client client, UICalculatorInputArea uiInput, SpriteManager spriteManager, ItemManager itemManager)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.uiInput = uiInput;
|
this.uiInput = uiInput;
|
||||||
@@ -123,8 +114,6 @@ class SkillCalculator extends JPanel
|
|||||||
|
|
||||||
void openCalculator(CalculatorType calculatorType)
|
void openCalculator(CalculatorType calculatorType)
|
||||||
{
|
{
|
||||||
this.calculatorType = calculatorType;
|
|
||||||
|
|
||||||
// Load the skill data.
|
// Load the skill data.
|
||||||
skillData = cacheSkillData.getSkillData(calculatorType.getDataFile());
|
skillData = cacheSkillData.getSkillData(calculatorType.getDataFile());
|
||||||
|
|
||||||
@@ -132,11 +121,10 @@ class SkillCalculator extends JPanel
|
|||||||
xpFactor = 1.0f;
|
xpFactor = 1.0f;
|
||||||
|
|
||||||
// Update internal skill/XP values.
|
// Update internal skill/XP values.
|
||||||
updateInternalValues();
|
currentXP = client.getSkillExperience(calculatorType.getSkill());
|
||||||
|
currentLevel = Experience.getLevelForXp(currentXP);
|
||||||
// BankedCalculator prevents these from being editable so just ensure they are editable.
|
targetLevel = enforceSkillBounds(currentLevel + 1);
|
||||||
uiInput.getUiFieldTargetLevel().setEditable(true);
|
targetXP = Experience.getXpForLevel(targetLevel);
|
||||||
uiInput.getUiFieldTargetXP().setEditable(true);
|
|
||||||
|
|
||||||
// Remove all components (action slots) from this panel.
|
// Remove all components (action slots) from this panel.
|
||||||
removeAll();
|
removeAll();
|
||||||
@@ -144,9 +132,6 @@ class SkillCalculator extends JPanel
|
|||||||
// Clear the search bar
|
// Clear the search bar
|
||||||
searchBar.setText(null);
|
searchBar.setText(null);
|
||||||
|
|
||||||
// Clear the search bar
|
|
||||||
searchBar.setText(null);
|
|
||||||
|
|
||||||
// Add in checkboxes for available skill bonuses.
|
// Add in checkboxes for available skill bonuses.
|
||||||
renderBonusOptions();
|
renderBonusOptions();
|
||||||
|
|
||||||
@@ -163,24 +148,6 @@ class SkillCalculator extends JPanel
|
|||||||
updateInputFields();
|
updateInputFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInternalValues()
|
|
||||||
{
|
|
||||||
updateCurrentValues();
|
|
||||||
updateTargetValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCurrentValues()
|
|
||||||
{
|
|
||||||
currentXP = client.getSkillExperience(calculatorType.getSkill());
|
|
||||||
currentLevel = Experience.getLevelForXp(currentXP);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTargetValues()
|
|
||||||
{
|
|
||||||
targetLevel = enforceSkillBounds(currentLevel + 1);
|
|
||||||
targetXP = Experience.getXpForLevel(targetLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCombinedAction()
|
private void updateCombinedAction()
|
||||||
{
|
{
|
||||||
int size = combinedActionSlots.size();
|
int size = combinedActionSlots.size();
|
||||||
@@ -254,7 +221,7 @@ class SkillCalculator extends JPanel
|
|||||||
JCheckBox uiCheckbox = new JCheckBox();
|
JCheckBox uiCheckbox = new JCheckBox();
|
||||||
|
|
||||||
uiLabel.setForeground(Color.WHITE);
|
uiLabel.setForeground(Color.WHITE);
|
||||||
uiLabel.setFont(FontManager.getSmallFont(getFont()));
|
uiLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
|
||||||
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
|
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 7, 3, 0));
|
||||||
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
@@ -270,7 +237,7 @@ class SkillCalculator extends JPanel
|
|||||||
|
|
||||||
for (JCheckBox checkBox : uiCheckBoxList)
|
for (JCheckBox checkBox : uiCheckBoxList)
|
||||||
{
|
{
|
||||||
if (checkBox != null && !checkBox.equals(uiCheckBox))
|
if (checkBox != uiCheckBox)
|
||||||
{
|
{
|
||||||
checkBox.setSelected(false);
|
checkBox.setSelected(false);
|
||||||
}
|
}
|
||||||
@@ -466,25 +433,4 @@ class SkillCalculator extends JPanel
|
|||||||
return slot.getAction().getName().toLowerCase().contains(text.toLowerCase());
|
return slot.getAction().getName().toLowerCase().contains(text.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the current skill calculator (if present)
|
|
||||||
* <p>
|
|
||||||
* This method is invoked by the {@link SkillCalculatorPlugin} event subscriber
|
|
||||||
* when an {@link ExperienceChanged} object is posted to the event bus
|
|
||||||
*/
|
|
||||||
void updateSkillCalculator(Skill skill)
|
|
||||||
{
|
|
||||||
// If the user has selected a calculator, update its fields
|
|
||||||
Optional.ofNullable(calculatorType).ifPresent(calc ->
|
|
||||||
{
|
|
||||||
if (skill.equals(calculatorType.getSkill()))
|
|
||||||
{
|
|
||||||
// Update our model "current" values
|
|
||||||
updateCurrentValues();
|
|
||||||
|
|
||||||
// Update the UI to reflect our new model
|
|
||||||
updateInputFields();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -32,24 +32,24 @@ import net.runelite.client.config.ConfigItem;
|
|||||||
public interface SkillCalculatorConfig extends Config
|
public interface SkillCalculatorConfig extends Config
|
||||||
{
|
{
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "showBankedXp",
|
keyName = "enabledBankedXp",
|
||||||
name = "Show Banked xp Tab",
|
name = "Add Banked XP Panel",
|
||||||
description = "Shows the Banked xp tab inside the Calculator Panel",
|
description = "Adds the Banked XP Panel to the side bar",
|
||||||
position = 0
|
position = 0
|
||||||
)
|
)
|
||||||
default boolean showBankedXp()
|
default boolean showBankedXp()
|
||||||
{
|
{
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "limitedBankedSecondaries",
|
keyName = "cascadeBankedXp",
|
||||||
name = "Limit Banked xp to Secondaries",
|
name = "Include output items",
|
||||||
description = "Limits the Banked xp shown based on secondaries banked as well",
|
description = "Includes output items in the item quantity calculations",
|
||||||
position = 1
|
position = 1
|
||||||
)
|
)
|
||||||
default boolean limitedBankedSecondaries()
|
default boolean cascadeBankedXp()
|
||||||
{
|
{
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
|
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
|
||||||
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
* Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -30,20 +29,10 @@ package net.runelite.client.plugins.skillcalculator;
|
|||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
import java.awt.GridBagLayout;
|
import java.awt.GridBagLayout;
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.game.SkillIconManager;
|
import net.runelite.client.game.SkillIconManager;
|
||||||
import net.runelite.client.game.SpriteManager;
|
import net.runelite.client.game.SpriteManager;
|
||||||
@@ -52,43 +41,30 @@ import net.runelite.client.ui.PluginPanel;
|
|||||||
import net.runelite.client.ui.components.materialtabs.MaterialTab;
|
import net.runelite.client.ui.components.materialtabs.MaterialTab;
|
||||||
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;
|
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Singleton
|
|
||||||
class SkillCalculatorPanel extends PluginPanel
|
class SkillCalculatorPanel extends PluginPanel
|
||||||
{
|
{
|
||||||
private final SkillCalculator uiCalculator;
|
private final SkillCalculator uiCalculator;
|
||||||
private final SkillIconManager iconManager;
|
private final SkillIconManager iconManager;
|
||||||
private final SkillCalculatorConfig config;
|
|
||||||
private final BankedCalculator bankedCalculator;
|
|
||||||
|
|
||||||
private CalculatorType currentCalc;
|
|
||||||
private final MaterialTabGroup skillGroup;
|
|
||||||
private final MaterialTabGroup tabGroup;
|
private final MaterialTabGroup tabGroup;
|
||||||
private String currentTab;
|
|
||||||
private final List<String> tabs = new ArrayList<>();
|
|
||||||
@Getter
|
|
||||||
private Map<Integer, Integer> bankMap = new HashMap<>();
|
|
||||||
private final GridBagConstraints c;
|
|
||||||
|
|
||||||
SkillCalculatorPanel(final SkillIconManager iconManager, final Client client, final SkillCalculatorConfig config, final SpriteManager spriteManager, final ItemManager itemManager)
|
SkillCalculatorPanel(SkillIconManager iconManager, Client client, SpriteManager spriteManager, ItemManager itemManager)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
getScrollPane().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
getScrollPane().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
|
||||||
|
|
||||||
this.iconManager = iconManager;
|
this.iconManager = iconManager;
|
||||||
this.config = config;
|
|
||||||
|
|
||||||
setBorder(new EmptyBorder(10, 10, 10, 10));
|
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
setLayout(new GridBagLayout());
|
setLayout(new GridBagLayout());
|
||||||
|
|
||||||
c = new GridBagConstraints();
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
c.fill = GridBagConstraints.HORIZONTAL;
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
c.weightx = 1;
|
c.weightx = 1;
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = 0;
|
c.gridy = 0;
|
||||||
|
|
||||||
skillGroup = new MaterialTabGroup();
|
tabGroup = new MaterialTabGroup();
|
||||||
skillGroup.setLayout(new GridLayout(0, 6, 7, 7));
|
tabGroup.setLayout(new GridLayout(0, 6, 7, 7));
|
||||||
|
|
||||||
addCalculatorButtons();
|
addCalculatorButtons();
|
||||||
|
|
||||||
@@ -97,23 +73,14 @@ class SkillCalculatorPanel extends PluginPanel
|
|||||||
uiInput.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
uiInput.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
uiCalculator = new SkillCalculator(client, uiInput, spriteManager, itemManager);
|
uiCalculator = new SkillCalculator(client, uiInput, spriteManager, itemManager);
|
||||||
|
|
||||||
bankedCalculator = new BankedCalculator(this, client, uiInput, config, itemManager);
|
add(tabGroup, c);
|
||||||
|
|
||||||
tabGroup = new MaterialTabGroup();
|
|
||||||
tabGroup.setBorder(new EmptyBorder(0, 0, 10, 0));
|
|
||||||
|
|
||||||
addTabButtons();
|
|
||||||
|
|
||||||
add(skillGroup, c);
|
|
||||||
c.gridy++;
|
c.gridy++;
|
||||||
|
|
||||||
add(uiInput, c);
|
add(uiInput, c);
|
||||||
c.gridy++;
|
c.gridy++;
|
||||||
|
|
||||||
add(tabGroup, c);
|
|
||||||
c.gridy++;
|
|
||||||
|
|
||||||
add(uiCalculator, c);
|
add(uiCalculator, c);
|
||||||
|
c.gridy++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCalculatorButtons()
|
private void addCalculatorButtons()
|
||||||
@@ -121,126 +88,14 @@ class SkillCalculatorPanel extends PluginPanel
|
|||||||
for (CalculatorType calculatorType : CalculatorType.values())
|
for (CalculatorType calculatorType : CalculatorType.values())
|
||||||
{
|
{
|
||||||
ImageIcon icon = new ImageIcon(iconManager.getSkillImage(calculatorType.getSkill(), true));
|
ImageIcon icon = new ImageIcon(iconManager.getSkillImage(calculatorType.getSkill(), true));
|
||||||
MaterialTab tab = new MaterialTab(icon, skillGroup, null);
|
MaterialTab tab = new MaterialTab(icon, tabGroup, null);
|
||||||
tab.setOnSelectEvent(() ->
|
tab.setOnSelectEvent(() ->
|
||||||
{
|
{
|
||||||
if (currentCalc != null && currentCalc.equals(calculatorType))
|
uiCalculator.openCalculator(calculatorType);
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
currentCalc = calculatorType;
|
|
||||||
selectedTab(currentTab, true);
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
skillGroup.addTab(tab);
|
tabGroup.addTab(tab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTabButtons()
|
|
||||||
{
|
|
||||||
tabGroup.removeAll();
|
|
||||||
tabs.clear();
|
|
||||||
|
|
||||||
tabs.add("Calculator");
|
|
||||||
if (config.showBankedXp())
|
|
||||||
{
|
|
||||||
tabs.add("Banked Xp");
|
|
||||||
}
|
|
||||||
// Only show if both options are visible
|
|
||||||
tabGroup.setVisible(tabs.size() > 1);
|
|
||||||
|
|
||||||
tabGroup.setLayout(new GridLayout(0, tabs.size(), 7, 7));
|
|
||||||
|
|
||||||
for (String s : tabs)
|
|
||||||
{
|
|
||||||
MaterialTab matTab = new MaterialTab(s, tabGroup, null);
|
|
||||||
|
|
||||||
matTab.setHorizontalAlignment(SwingUtilities.CENTER);
|
|
||||||
|
|
||||||
// Ensure Background is applied
|
|
||||||
matTab.setOpaque(true);
|
|
||||||
matTab.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
|
||||||
|
|
||||||
// When Clicked
|
|
||||||
matTab.setOnSelectEvent(() ->
|
|
||||||
{
|
|
||||||
selectedTab(s, false);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
tabGroup.addTab(matTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialTab selected = tabGroup.getTab(0);
|
|
||||||
if (tabs.contains(currentTab))
|
|
||||||
{
|
|
||||||
selected = tabGroup.getTab(tabs.indexOf(currentTab));
|
|
||||||
}
|
|
||||||
|
|
||||||
tabGroup.select(selected);
|
|
||||||
currentTab = selected.getText();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectedTab(String s, boolean force)
|
|
||||||
{
|
|
||||||
// Do not refresh the panel if they clicked the same tab, unless they selected a new skill
|
|
||||||
if (Objects.equals(currentTab, s) && !force)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTab = s;
|
|
||||||
|
|
||||||
// Only open a panel if a skill is selected
|
|
||||||
if (currentCalc == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (s)
|
|
||||||
{
|
|
||||||
case "Calculator":
|
|
||||||
remove(bankedCalculator);
|
|
||||||
add(uiCalculator, c);
|
|
||||||
uiCalculator.openCalculator(currentCalc);
|
|
||||||
break;
|
|
||||||
case "Banked Xp":
|
|
||||||
remove(uiCalculator);
|
|
||||||
add(bankedCalculator, c);
|
|
||||||
bankedCalculator.openBanked(currentCalc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.revalidate();
|
|
||||||
this.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh entire panel
|
|
||||||
void refreshPanel()
|
|
||||||
{
|
|
||||||
// Recreate Tabs (in case of Config change) and selects the first tab
|
|
||||||
addTabButtons();
|
|
||||||
|
|
||||||
// Ensure reload
|
|
||||||
selectedTab(currentTab, true);
|
|
||||||
|
|
||||||
this.revalidate();
|
|
||||||
this.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapper function for updating SkillCalculator's bankMap
|
|
||||||
void updateBankMap(Map<Integer, Integer> bank)
|
|
||||||
{
|
|
||||||
bankMap = bank;
|
|
||||||
if (currentCalc != null & currentTab.equals("Banked Xp"))
|
|
||||||
{
|
|
||||||
bankedCalculator.updateBankMap(bankMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateSkillCalculator(Skill skill)
|
|
||||||
{
|
|
||||||
uiCalculator.updateSkillCalculator(skill);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
|
* Copyright (c) 2018, Kruithne <kruithne@gmail.com>
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -31,18 +31,13 @@ import java.awt.image.BufferedImage;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.InventoryID;
|
import net.runelite.api.InventoryID;
|
||||||
import net.runelite.api.Item;
|
import net.runelite.api.Item;
|
||||||
import net.runelite.api.ItemContainer;
|
import net.runelite.api.ItemContainer;
|
||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.api.events.ExperienceChanged;
|
import net.runelite.api.events.ScriptCallbackEvent;
|
||||||
import net.runelite.api.events.GameTick;
|
|
||||||
import net.runelite.api.widgets.Widget;
|
|
||||||
import net.runelite.api.widgets.WidgetInfo;
|
|
||||||
import net.runelite.client.callback.ClientThread;
|
import net.runelite.client.callback.ClientThread;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.eventbus.Subscribe;
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
@@ -51,7 +46,9 @@ import net.runelite.client.game.SkillIconManager;
|
|||||||
import net.runelite.client.game.SpriteManager;
|
import net.runelite.client.game.SpriteManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
|
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculatorPanel;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.CriticalItem;
|
||||||
import net.runelite.client.ui.ClientToolbar;
|
import net.runelite.client.ui.ClientToolbar;
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import net.runelite.client.util.ImageUtil;
|
import net.runelite.client.util.ImageUtil;
|
||||||
@@ -61,7 +58,6 @@ import net.runelite.client.util.ImageUtil;
|
|||||||
description = "Enable the Skill Calculator panel",
|
description = "Enable the Skill Calculator panel",
|
||||||
tags = {"panel", "skilling"}
|
tags = {"panel", "skilling"}
|
||||||
)
|
)
|
||||||
@Singleton
|
|
||||||
public class SkillCalculatorPlugin extends Plugin
|
public class SkillCalculatorPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
@@ -86,12 +82,10 @@ public class SkillCalculatorPlugin extends Plugin
|
|||||||
private SkillCalculatorConfig skillCalculatorConfig;
|
private SkillCalculatorConfig skillCalculatorConfig;
|
||||||
|
|
||||||
private NavigationButton uiNavigationButton;
|
private NavigationButton uiNavigationButton;
|
||||||
private SkillCalculatorPanel uiPanel;
|
private NavigationButton bankedUiNavigationButton;
|
||||||
|
|
||||||
@Getter
|
private BankedCalculatorPanel bankedUiPanel;
|
||||||
private Map<Integer, Integer> bankMap = new HashMap<>();
|
private int bankHash = -1;
|
||||||
|
|
||||||
private int bankHash;
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
SkillCalculatorConfig getConfig(ConfigManager configManager)
|
SkillCalculatorConfig getConfig(ConfigManager configManager)
|
||||||
@@ -103,7 +97,7 @@ public class SkillCalculatorPlugin extends Plugin
|
|||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "calc.png");
|
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "calc.png");
|
||||||
this.uiPanel = new SkillCalculatorPanel(skillIconManager, client, skillCalculatorConfig, spriteManager, itemManager);
|
final SkillCalculatorPanel uiPanel = new SkillCalculatorPanel(skillIconManager, client, spriteManager, itemManager);
|
||||||
|
|
||||||
uiNavigationButton = NavigationButton.builder()
|
uiNavigationButton = NavigationButton.builder()
|
||||||
.tooltip("Skill Calculator")
|
.tooltip("Skill Calculator")
|
||||||
@@ -114,56 +108,32 @@ public class SkillCalculatorPlugin extends Plugin
|
|||||||
|
|
||||||
clientToolbar.addNavigation(uiNavigationButton);
|
clientToolbar.addNavigation(uiNavigationButton);
|
||||||
|
|
||||||
clientThread.invokeLater(() ->
|
toggleBankedXpPanel();
|
||||||
{
|
|
||||||
switch (client.getGameState())
|
|
||||||
{
|
|
||||||
case STARTING:
|
|
||||||
case UNKNOWN:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CriticalItem.prepareItemDefinitions(itemManager);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
clientToolbar.removeNavigation(uiNavigationButton);
|
clientToolbar.removeNavigation(uiNavigationButton);
|
||||||
bankMap.clear();
|
if (bankedUiNavigationButton != null)
|
||||||
bankHash = -1;
|
{
|
||||||
|
clientToolbar.removeNavigation(bankedUiNavigationButton);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onConfigChanged(ConfigChanged event)
|
public void onConfigChanged(ConfigChanged event)
|
||||||
{
|
{
|
||||||
if (event.getGroup().equals("skillCalculator"))
|
if (event.getGroup().equals("skillCalculator") && event.getKey().equals("enabledBankedXp"))
|
||||||
{
|
{
|
||||||
if (event.getKey().equals("showBankedXp"))
|
toggleBankedXpPanel();
|
||||||
{
|
|
||||||
bankMap.clear();
|
|
||||||
bankHash = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> uiPanel.refreshPanel());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pulled from bankvalue plugin to check if bank is open
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onGameTick(GameTick event)
|
public void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||||
{
|
{
|
||||||
if (!skillCalculatorConfig.showBankedXp())
|
if (!event.getEventName().equals("setBankTitle") || !skillCalculatorConfig.showBankedXp())
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
|
|
||||||
|
|
||||||
// Don't update on a search because rs seems to constantly update the title
|
|
||||||
if (widgetBankTitleBar == null || widgetBankTitleBar.isHidden() || widgetBankTitleBar.getText().contains("Showing"))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -171,54 +141,80 @@ public class SkillCalculatorPlugin extends Plugin
|
|||||||
updateBankItems();
|
updateBankItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void toggleBankedXpPanel()
|
||||||
|
{
|
||||||
|
if (skillCalculatorConfig.showBankedXp())
|
||||||
|
{
|
||||||
|
final BufferedImage icon = ImageUtil.getResourceStreamFromClass(getClass(), "banked.png");
|
||||||
|
|
||||||
|
bankedUiPanel = new BankedCalculatorPanel(client, skillCalculatorConfig, skillIconManager, itemManager);
|
||||||
|
bankedUiNavigationButton = NavigationButton.builder()
|
||||||
|
.tooltip("Banked XP")
|
||||||
|
.icon(icon)
|
||||||
|
.priority(6)
|
||||||
|
.panel(bankedUiPanel)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
clientToolbar.addNavigation(bankedUiNavigationButton);
|
||||||
|
|
||||||
|
clientThread.invoke(() ->
|
||||||
|
{
|
||||||
|
switch (client.getGameState())
|
||||||
|
{
|
||||||
|
case LOGIN_SCREEN:
|
||||||
|
case LOGIN_SCREEN_AUTHENTICATOR:
|
||||||
|
case LOGGING_IN:
|
||||||
|
case LOADING:
|
||||||
|
case LOGGED_IN:
|
||||||
|
case CONNECTION_LOST:
|
||||||
|
case HOPPING:
|
||||||
|
CriticalItem.prepareItemDefinitions(itemManager);
|
||||||
|
Activity.prepareItemDefinitions(itemManager);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bankedUiNavigationButton == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clientToolbar.removeNavigation(bankedUiNavigationButton);
|
||||||
|
|
||||||
|
bankedUiNavigationButton = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if bank contents changed and if so send to UI
|
// Check if bank contents changed and if so send to UI
|
||||||
private void updateBankItems()
|
private void updateBankItems()
|
||||||
{
|
{
|
||||||
ItemContainer c = client.getItemContainer(InventoryID.BANK);
|
final ItemContainer c = client.getItemContainer(InventoryID.BANK);
|
||||||
Item[] widgetItems = (c == null ? new Item[0] : c.getItems());
|
if (c == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Couldn't find any items in bank, do nothing.
|
final Item[] widgetItems = c.getItems();
|
||||||
if (widgetItems == null || widgetItems.length == 0)
|
if (widgetItems == null || widgetItems.length == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Integer, Integer> newBankMap = getBankMapIfDiff(widgetItems);
|
final Map<Integer, Integer> m = new HashMap<>();
|
||||||
|
|
||||||
// Bank didn't change
|
|
||||||
if (newBankMap.size() == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bankMap = newBankMap;
|
|
||||||
// send updated bank map to ui
|
|
||||||
uiPanel.updateBankMap(bankMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recreates the bankMap and checks if the hashCode is different (the map has changed). Sends an empty map if no changes
|
|
||||||
private Map<Integer, Integer> getBankMapIfDiff(Item[] widgetItems)
|
|
||||||
{
|
|
||||||
Map<Integer, Integer> mapCheck = new HashMap<>();
|
|
||||||
for (Item widgetItem : widgetItems)
|
for (Item widgetItem : widgetItems)
|
||||||
{
|
{
|
||||||
mapCheck.put(widgetItem.getId(), widgetItem.getQuantity());
|
m.put(widgetItem.getId(), widgetItem.getQuantity());
|
||||||
}
|
}
|
||||||
|
|
||||||
int curHash = mapCheck.hashCode();
|
final int curHash = m.hashCode();
|
||||||
|
if (bankHash != curHash)
|
||||||
if (curHash != bankHash)
|
|
||||||
{
|
{
|
||||||
bankHash = curHash;
|
bankHash = curHash;
|
||||||
return mapCheck;
|
SwingUtilities.invokeLater(() -> bankedUiPanel.setBankMap(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onExperienceChanged(ExperienceChanged changeEvent)
|
|
||||||
{
|
|
||||||
uiPanel.updateSkillCalculator(changeEvent.getSkill());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,6 @@ import java.awt.GridLayout;
|
|||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@@ -48,7 +47,6 @@ import net.runelite.client.ui.ColorScheme;
|
|||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class UIActionSlot extends JPanel
|
class UIActionSlot extends JPanel
|
||||||
{
|
{
|
||||||
private static final Border GREEN_BORDER = new CompoundBorder(
|
private static final Border GREEN_BORDER = new CompoundBorder(
|
||||||
@@ -127,7 +125,7 @@ class UIActionSlot extends JPanel
|
|||||||
uiLabelName.setForeground(Color.WHITE);
|
uiLabelName.setForeground(Color.WHITE);
|
||||||
|
|
||||||
uiLabelActions = new JShadowedLabel("Unknown");
|
uiLabelActions = new JShadowedLabel("Unknown");
|
||||||
uiLabelActions.setFont(FontManager.getSmallFont(getFont()));
|
uiLabelActions.setFont(FontManager.getRunescapeSmallFont());
|
||||||
uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||||
|
|
||||||
uiInfo.add(uiLabelName);
|
uiInfo.add(uiLabelName);
|
||||||
|
|||||||
@@ -28,27 +28,24 @@ package net.runelite.client.plugins.skillcalculator;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTextField;
|
import javax.swing.JTextField;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.components.FlatTextField;
|
import net.runelite.client.ui.components.FlatTextField;
|
||||||
|
|
||||||
@Getter(AccessLevel.PACKAGE)
|
@Getter
|
||||||
@Singleton
|
public class UICalculatorInputArea extends JPanel
|
||||||
class UICalculatorInputArea extends JPanel
|
|
||||||
{
|
{
|
||||||
private final JTextField uiFieldCurrentLevel;
|
private final JTextField uiFieldCurrentLevel;
|
||||||
private final JTextField uiFieldCurrentXP;
|
private final JTextField uiFieldCurrentXP;
|
||||||
private final JTextField uiFieldTargetLevel;
|
private final JTextField uiFieldTargetLevel;
|
||||||
private final JTextField uiFieldTargetXP;
|
private final JTextField uiFieldTargetXP;
|
||||||
|
|
||||||
UICalculatorInputArea()
|
public UICalculatorInputArea()
|
||||||
{
|
{
|
||||||
setLayout(new GridLayout(2, 2, 7, 7));
|
setLayout(new GridLayout(2, 2, 7, 7));
|
||||||
uiFieldCurrentLevel = addComponent("Current Level");
|
uiFieldCurrentLevel = addComponent("Current Level");
|
||||||
@@ -62,7 +59,7 @@ class UICalculatorInputArea extends JPanel
|
|||||||
return getInput(uiFieldCurrentLevel);
|
return getInput(uiFieldCurrentLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrentLevelInput(int value)
|
public void setCurrentLevelInput(int value)
|
||||||
{
|
{
|
||||||
setInput(uiFieldCurrentLevel, value);
|
setInput(uiFieldCurrentLevel, value);
|
||||||
}
|
}
|
||||||
@@ -72,7 +69,7 @@ class UICalculatorInputArea extends JPanel
|
|||||||
return getInput(uiFieldCurrentXP);
|
return getInput(uiFieldCurrentXP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCurrentXPInput(Object value)
|
public void setCurrentXPInput(Object value)
|
||||||
{
|
{
|
||||||
setInput(uiFieldCurrentXP, value);
|
setInput(uiFieldCurrentXP, value);
|
||||||
}
|
}
|
||||||
@@ -82,7 +79,7 @@ class UICalculatorInputArea extends JPanel
|
|||||||
return getInput(uiFieldTargetLevel);
|
return getInput(uiFieldTargetLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTargetLevelInput(Object value)
|
public void setTargetLevelInput(Object value)
|
||||||
{
|
{
|
||||||
setInput(uiFieldTargetLevel, value);
|
setInput(uiFieldTargetLevel, value);
|
||||||
}
|
}
|
||||||
@@ -92,7 +89,7 @@ class UICalculatorInputArea extends JPanel
|
|||||||
return getInput(uiFieldTargetXP);
|
return getInput(uiFieldTargetXP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTargetXPInput(Object value)
|
public void setTargetXPInput(Object value)
|
||||||
{
|
{
|
||||||
setInput(uiFieldTargetXP, value);
|
setInput(uiFieldTargetXP, value);
|
||||||
}
|
}
|
||||||
@@ -126,7 +123,7 @@ class UICalculatorInputArea extends JPanel
|
|||||||
uiInput.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR);
|
uiInput.setHoverBackgroundColor(ColorScheme.DARK_GRAY_HOVER_COLOR);
|
||||||
uiInput.setBorder(new EmptyBorder(5, 7, 5, 7));
|
uiInput.setBorder(new EmptyBorder(5, 7, 5, 7));
|
||||||
|
|
||||||
uiLabel.setFont(FontManager.getSmallFont(getFont()));
|
uiLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
uiLabel.setBorder(new EmptyBorder(0, 0, 4, 0));
|
uiLabel.setBorder(new EmptyBorder(0, 0, 4, 0));
|
||||||
uiLabel.setForeground(Color.WHITE);
|
uiLabel.setForeground(Color.WHITE);
|
||||||
|
|
||||||
@@ -137,4 +134,4 @@ class UICalculatorInputArea extends JPanel
|
|||||||
|
|
||||||
return uiInput.getTextField();
|
return uiInput.getTextField();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,6 @@ import java.awt.BorderLayout;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.GridLayout;
|
import java.awt.GridLayout;
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@@ -40,14 +39,13 @@ import net.runelite.client.ui.ColorScheme;
|
|||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class UICombinedActionSlot extends JPanel
|
class UICombinedActionSlot extends JPanel
|
||||||
{
|
{
|
||||||
private static final Dimension ICON_SIZE = new Dimension(32, 32);
|
private static final Dimension ICON_SIZE = new Dimension(32, 32);
|
||||||
private final JShadowedLabel uiLabelActions;
|
private final JShadowedLabel uiLabelActions;
|
||||||
private final JShadowedLabel uiLabelTitle;
|
private final JShadowedLabel uiLabelTitle;
|
||||||
|
|
||||||
UICombinedActionSlot(final SpriteManager spriteManager)
|
UICombinedActionSlot(SpriteManager spriteManager)
|
||||||
{
|
{
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
@@ -70,7 +68,7 @@ class UICombinedActionSlot extends JPanel
|
|||||||
uiLabelTitle.setForeground(Color.WHITE);
|
uiLabelTitle.setForeground(Color.WHITE);
|
||||||
|
|
||||||
uiLabelActions = new JShadowedLabel("Shift-click to select multiple");
|
uiLabelActions = new JShadowedLabel("Shift-click to select multiple");
|
||||||
uiLabelActions.setFont(FontManager.getSmallFont(getFont()));
|
uiLabelActions.setFont(FontManager.getRunescapeSmallFont());
|
||||||
uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
uiLabelActions.setForeground(ColorScheme.LIGHT_GRAY_COLOR);
|
||||||
|
|
||||||
uiInfo.add(uiLabelTitle);
|
uiInfo.add(uiLabelTitle);
|
||||||
|
|||||||
@@ -0,0 +1,462 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked;
|
||||||
|
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Experience;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.client.game.AsyncBufferedImage;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.SkillCalculatorConfig;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.UICalculatorInputArea;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.CriticalItem;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.XpModifiers;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.components.GridItem;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.components.ModifyPanel;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.components.SelectionGrid;
|
||||||
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
import net.runelite.client.ui.DynamicGridLayout;
|
||||||
|
import net.runelite.client.ui.FontManager;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class BankedCalculator extends JPanel
|
||||||
|
{
|
||||||
|
public static final DecimalFormat XP_FORMAT_COMMA = new DecimalFormat("#,###.#");
|
||||||
|
|
||||||
|
private final Client client;
|
||||||
|
@Getter
|
||||||
|
private final SkillCalculatorConfig config;
|
||||||
|
private final UICalculatorInputArea uiInput;
|
||||||
|
private final ItemManager itemManager;
|
||||||
|
|
||||||
|
// Some activities output a CriticalItem and may need to be included in the calculable qty
|
||||||
|
// Using multimap for cases where there are multiple items linked directly to one item, use recursion for otherwise
|
||||||
|
private final Multimap<CriticalItem, BankedItem> linkedMap = ArrayListMultimap.create();
|
||||||
|
|
||||||
|
private final Map<CriticalItem, BankedItem> bankedItemMap = new LinkedHashMap<>();
|
||||||
|
private final JLabel totalXpLabel = new JLabel();
|
||||||
|
private final ModifyPanel modifyPanel;
|
||||||
|
private SelectionGrid itemGrid;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Map<Integer, Integer> bankMap = new HashMap<>();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Skill currentSkill;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private int skillLevel, skillExp, endLevel, endExp;
|
||||||
|
|
||||||
|
private final Collection<JCheckBox> xpModifierButtons = new ArrayList<>();
|
||||||
|
@Getter
|
||||||
|
private float xpFactor = 1.0f;
|
||||||
|
|
||||||
|
BankedCalculator(UICalculatorInputArea uiInput, Client client, SkillCalculatorConfig config, ItemManager itemManager)
|
||||||
|
{
|
||||||
|
this.uiInput = uiInput;
|
||||||
|
this.client = client;
|
||||||
|
this.config = config;
|
||||||
|
this.itemManager = itemManager;
|
||||||
|
|
||||||
|
setLayout(new DynamicGridLayout(0, 1, 0, 5));
|
||||||
|
|
||||||
|
// Panel used to modify banked item values
|
||||||
|
this.modifyPanel = new ModifyPanel(this, itemManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* opens the Banked Calculator for this skill
|
||||||
|
*/
|
||||||
|
void open(final Skill newSkill)
|
||||||
|
{
|
||||||
|
if (newSkill.equals(currentSkill))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentSkill = newSkill;
|
||||||
|
removeAll();
|
||||||
|
xpFactor = 1.0f;
|
||||||
|
|
||||||
|
if (bankMap.size() <= 0)
|
||||||
|
{
|
||||||
|
add(new JLabel("Please visit a bank!", JLabel.CENTER));
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
skillLevel = client.getRealSkillLevel(currentSkill);
|
||||||
|
skillExp = client.getSkillExperience(currentSkill);
|
||||||
|
endLevel = skillLevel;
|
||||||
|
endExp = skillExp;
|
||||||
|
|
||||||
|
uiInput.setCurrentLevelInput(skillLevel);
|
||||||
|
uiInput.setCurrentXPInput(skillExp);
|
||||||
|
uiInput.setTargetLevelInput(endLevel);
|
||||||
|
uiInput.setTargetXPInput(endExp);
|
||||||
|
|
||||||
|
recreateBankedItemMap();
|
||||||
|
|
||||||
|
final Collection<XpModifiers> modifiers = XpModifiers.getModifiersBySkill(this.currentSkill);
|
||||||
|
for (final XpModifiers modifier : modifiers)
|
||||||
|
{
|
||||||
|
JPanel uiOption = new JPanel(new BorderLayout());
|
||||||
|
JLabel uiLabel = new JLabel(modifier.getName());
|
||||||
|
JCheckBox btn = new JCheckBox();
|
||||||
|
|
||||||
|
uiLabel.setForeground(Color.WHITE);
|
||||||
|
uiLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
uiLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
|
uiOption.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 0));
|
||||||
|
uiOption.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
|
||||||
|
btn.addItemListener((event) ->
|
||||||
|
{
|
||||||
|
switch (event.getStateChange())
|
||||||
|
{
|
||||||
|
case ItemEvent.DESELECTED:
|
||||||
|
xpFactor = 1.0f;
|
||||||
|
break;
|
||||||
|
case ItemEvent.SELECTED:
|
||||||
|
// Deselects all but the current item
|
||||||
|
final JCheckBox box = (JCheckBox) event.getItem();
|
||||||
|
xpModifierButtons.forEach(b -> b.setSelected(b == box));
|
||||||
|
|
||||||
|
xpFactor = modifier.getModifier();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
modifierUpdated();
|
||||||
|
});
|
||||||
|
xpModifierButtons.add(btn);
|
||||||
|
|
||||||
|
uiOption.add(uiLabel, BorderLayout.WEST);
|
||||||
|
uiOption.add(btn, BorderLayout.EAST);
|
||||||
|
add(uiOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
recreateItemGrid();
|
||||||
|
|
||||||
|
// This should only be null if there are no items in their bank for this skill
|
||||||
|
if (itemGrid.getSelectedItem() == null)
|
||||||
|
{
|
||||||
|
add(new JLabel("Couldn't find any items for this skill.", JLabel.CENTER));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
add(totalXpLabel);
|
||||||
|
add(modifyPanel);
|
||||||
|
add(itemGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recreateBankedItemMap()
|
||||||
|
{
|
||||||
|
bankedItemMap.clear();
|
||||||
|
linkedMap.clear();
|
||||||
|
|
||||||
|
final Collection<CriticalItem> items = CriticalItem.getBySkill(currentSkill);
|
||||||
|
log.debug("Critical Items for the {} Skill: {}", currentSkill.getName(), items);
|
||||||
|
|
||||||
|
for (final CriticalItem item : items)
|
||||||
|
{
|
||||||
|
final BankedItem banked = new BankedItem(item, bankMap.getOrDefault(item.getItemID(), 0));
|
||||||
|
bankedItemMap.put(item, banked);
|
||||||
|
|
||||||
|
Activity a = item.getSelectedActivity();
|
||||||
|
if (a == null)
|
||||||
|
{
|
||||||
|
final List<Activity> activities = Activity.getByCriticalItem(item);
|
||||||
|
if (activities.size() == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setSelectedActivity(activities.get(0));
|
||||||
|
a = activities.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.getLinkedItem() != null)
|
||||||
|
{
|
||||||
|
linkedMap.put(a.getLinkedItem(), banked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug("Banked Item Map: {}", bankedItemMap);
|
||||||
|
log.debug("Linked Map: {}", linkedMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the detailContainer with the necessary BankedItemPanels
|
||||||
|
*/
|
||||||
|
private void recreateItemGrid()
|
||||||
|
{
|
||||||
|
// Selection grid will only display values with > 0 items
|
||||||
|
itemGrid = new SelectionGrid(this, bankedItemMap.values(), itemManager);
|
||||||
|
itemGrid.setOnSelectEvent(() ->
|
||||||
|
{
|
||||||
|
modifyPanel.setBankedItem(itemGrid.getSelectedItem());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
itemGrid.setOnIgnoreEvent(() ->
|
||||||
|
{
|
||||||
|
CriticalItem item = itemGrid.getLastIgnoredItem().getItem();
|
||||||
|
updateLinkedItems(item.getSelectedActivity());
|
||||||
|
calculateBankedXpTotal();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Select the first item in the list
|
||||||
|
modifyPanel.setBankedItem(itemGrid.getSelectedItem());
|
||||||
|
|
||||||
|
calculateBankedXpTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getItemXpRate(final BankedItem bankedItem)
|
||||||
|
{
|
||||||
|
return bankedItem.getXpRate() * (bankedItem.getItem().isIgnoreBonus() ? 1.0f : xpFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates total item quantity accounting for backwards linked items
|
||||||
|
*
|
||||||
|
* @param item starting item
|
||||||
|
* @return item qty including linked items
|
||||||
|
*/
|
||||||
|
public int getItemQty(final BankedItem item)
|
||||||
|
{
|
||||||
|
int qty = item.getQty();
|
||||||
|
|
||||||
|
if (!config.cascadeBankedXp())
|
||||||
|
{
|
||||||
|
return qty;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<CriticalItem, Integer> linked = createLinksMap(item);
|
||||||
|
final int linkedQty = linked.values().stream().mapToInt(Integer::intValue).sum();
|
||||||
|
|
||||||
|
return qty + linkedQty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateBankedXpTotal()
|
||||||
|
{
|
||||||
|
double total = 0.0;
|
||||||
|
for (final GridItem i : itemGrid.getPanelMap().values())
|
||||||
|
{
|
||||||
|
if (i.isIgnored())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BankedItem bi = i.getBankedItem();
|
||||||
|
total += getItemQty(bi) * getItemXpRate(bi);
|
||||||
|
}
|
||||||
|
|
||||||
|
endExp = (int) (skillExp + total);
|
||||||
|
endLevel = Experience.getLevelForXp(endExp);
|
||||||
|
|
||||||
|
totalXpLabel.setText("Total Banked xp: " + XP_FORMAT_COMMA.format(total));
|
||||||
|
uiInput.setTargetLevelInput(endLevel);
|
||||||
|
uiInput.setTargetXPInput(Math.min(Experience.MAX_SKILL_XP, endExp));
|
||||||
|
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to select an Activity for an item
|
||||||
|
*
|
||||||
|
* @param i BankedItem item the activity is tied to
|
||||||
|
* @param a Activity the selected activity
|
||||||
|
*/
|
||||||
|
public void activitySelected(final BankedItem i, final Activity a)
|
||||||
|
{
|
||||||
|
final CriticalItem item = i.getItem();
|
||||||
|
final Activity old = item.getSelectedActivity();
|
||||||
|
if (a.equals(old))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setSelectedActivity(a);
|
||||||
|
|
||||||
|
// Cascade activity changes if necessary.
|
||||||
|
if (config.cascadeBankedXp() && (old.getLinkedItem() != a.getLinkedItem()))
|
||||||
|
{
|
||||||
|
// Update Linked Map
|
||||||
|
linkedMap.remove(old.getLinkedItem(), i);
|
||||||
|
linkedMap.put(a.getLinkedItem(), i);
|
||||||
|
// Update all items the old activity effects
|
||||||
|
updateLinkedItems(old);
|
||||||
|
// Update all the items the new activity effects
|
||||||
|
updateLinkedItems(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyPanel.setBankedItem(i);
|
||||||
|
itemGrid.getPanelMap().get(i).updateToolTip();
|
||||||
|
|
||||||
|
// recalculate total xp
|
||||||
|
calculateBankedXpTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the item quantities of all forward linked items
|
||||||
|
*
|
||||||
|
* @param activity the starting {@link Activity} to start the cascade from
|
||||||
|
*/
|
||||||
|
private void updateLinkedItems(final Activity activity)
|
||||||
|
{
|
||||||
|
if (activity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean foundSelected = false;
|
||||||
|
boolean panelAmountChange = false;
|
||||||
|
|
||||||
|
CriticalItem i = activity.getLinkedItem();
|
||||||
|
while (i != null)
|
||||||
|
{
|
||||||
|
final BankedItem bi = bankedItemMap.get(i);
|
||||||
|
if (bi == null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int qty = getItemQty(bi);
|
||||||
|
final boolean stackable = bi.getItem().getItemInfo().isStackable() || qty > 1;
|
||||||
|
final AsyncBufferedImage img = itemManager.getImage(bi.getItem().getItemID(), qty, stackable);
|
||||||
|
|
||||||
|
final GridItem gridItem = itemGrid.getPanelMap().get(bi);
|
||||||
|
final int oldQty = gridItem.getAmount();
|
||||||
|
panelAmountChange = panelAmountChange || ((oldQty == 0 && qty > 0) || (oldQty > 0 && qty == 0));
|
||||||
|
gridItem.updateIcon(img, qty);
|
||||||
|
gridItem.updateToolTip();
|
||||||
|
|
||||||
|
foundSelected = foundSelected || itemGrid.getSelectedItem().equals(bi);
|
||||||
|
|
||||||
|
final Activity a = bi.getItem().getSelectedActivity();
|
||||||
|
if (a == null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = a.getLinkedItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panelAmountChange)
|
||||||
|
{
|
||||||
|
itemGrid.refreshGridDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundSelected)
|
||||||
|
{
|
||||||
|
// Refresh current modify panel if the cascade effects it
|
||||||
|
modifyPanel.setBankedItem(itemGrid.getSelectedItem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Map of CriticalItem to bank qty for all items that are being linked to this one
|
||||||
|
*
|
||||||
|
* @param item starting item
|
||||||
|
* @return Map of CriticalItem to bank qty
|
||||||
|
*/
|
||||||
|
public Map<CriticalItem, Integer> createLinksMap(final BankedItem item)
|
||||||
|
{
|
||||||
|
final Map<CriticalItem, Integer> qtyMap = new HashMap<>();
|
||||||
|
|
||||||
|
final Activity a = item.getItem().getSelectedActivity();
|
||||||
|
if (a == null)
|
||||||
|
{
|
||||||
|
return qtyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Collection<BankedItem> linkedBank = linkedMap.get(item.getItem());
|
||||||
|
if (linkedBank == null || linkedBank.size() == 0)
|
||||||
|
{
|
||||||
|
return qtyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final BankedItem linked : linkedBank)
|
||||||
|
{
|
||||||
|
// Check if the item is ignored in the grid
|
||||||
|
if (itemGrid != null)
|
||||||
|
{
|
||||||
|
final GridItem grid = itemGrid.getPanelMap().get(linked);
|
||||||
|
if (grid != null && grid.isIgnored())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int qty = linked.getQty();
|
||||||
|
if (qty > 0)
|
||||||
|
{
|
||||||
|
qtyMap.put(linked.getItem(), qty);
|
||||||
|
}
|
||||||
|
qtyMap.putAll(createLinksMap(linked));
|
||||||
|
}
|
||||||
|
|
||||||
|
return qtyMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifierUpdated()
|
||||||
|
{
|
||||||
|
itemGrid.getPanelMap().values().forEach(GridItem::updateToolTip);
|
||||||
|
modifyPanel.setBankedItem(modifyPanel.getBankedItem());
|
||||||
|
calculateBankedXpTotal();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.game.SkillIconManager;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.SkillCalculatorConfig;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.UICalculatorInputArea;
|
||||||
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
import net.runelite.client.ui.PluginPanel;
|
||||||
|
import net.runelite.client.ui.components.ComboBoxIconEntry;
|
||||||
|
import net.runelite.client.ui.components.ComboBoxListRenderer;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class BankedCalculatorPanel extends PluginPanel
|
||||||
|
{
|
||||||
|
private final static ImmutableSet<Skill> BANKABLE_SKILLS = ImmutableSet.of(
|
||||||
|
Skill.CONSTRUCTION, Skill.COOKING, Skill.CRAFTING, Skill.FARMING, Skill.HERBLORE, Skill.PRAYER, Skill.SMITHING
|
||||||
|
);
|
||||||
|
|
||||||
|
private final BankedCalculator calculator;
|
||||||
|
|
||||||
|
public BankedCalculatorPanel(Client client, SkillCalculatorConfig config, SkillIconManager skillIconManager, ItemManager itemManager)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
|
setLayout(new GridBagLayout());
|
||||||
|
|
||||||
|
final UICalculatorInputArea inputs = new UICalculatorInputArea();
|
||||||
|
inputs.setBorder(new EmptyBorder(15, 0, 15, 0));
|
||||||
|
inputs.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
|
||||||
|
inputs.getUiFieldTargetXP().setEditable(false);
|
||||||
|
inputs.getUiFieldTargetLevel().setEditable(false);
|
||||||
|
|
||||||
|
calculator = new BankedCalculator(inputs, client, config, itemManager);
|
||||||
|
|
||||||
|
// Create the Skill dropdown with icons
|
||||||
|
final JComboBox<ComboBoxIconEntry> dropdown = new JComboBox<>();
|
||||||
|
|
||||||
|
final ComboBoxListRenderer renderer = new ComboBoxListRenderer();
|
||||||
|
renderer.setDefaultText("Select a Skill...");
|
||||||
|
dropdown.setRenderer(renderer);
|
||||||
|
|
||||||
|
for (final Skill skill : BANKABLE_SKILLS)
|
||||||
|
{
|
||||||
|
final BufferedImage img = skillIconManager.getSkillImage(skill, true);
|
||||||
|
final ComboBoxIconEntry entry = new ComboBoxIconEntry(new ImageIcon(img), skill.getName(), skill);
|
||||||
|
dropdown.addItem(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click event handler now to prevent above code from triggering it.
|
||||||
|
dropdown.addItemListener(e ->
|
||||||
|
{
|
||||||
|
if (e.getStateChange() == ItemEvent.SELECTED)
|
||||||
|
{
|
||||||
|
final ComboBoxIconEntry source = (ComboBoxIconEntry) e.getItem();
|
||||||
|
if (source.getData() instanceof Skill)
|
||||||
|
{
|
||||||
|
final Skill skill = (Skill) source.getData();
|
||||||
|
this.calculator.open(skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdown.setSelectedIndex(-1);
|
||||||
|
|
||||||
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
c.weightx = 1;
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 0;
|
||||||
|
|
||||||
|
add(dropdown, c);
|
||||||
|
c.gridy++;
|
||||||
|
add(inputs, c);
|
||||||
|
c.gridy++;
|
||||||
|
add(calculator, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBankMap(final Map<Integer, Integer> bankMap)
|
||||||
|
{
|
||||||
|
calculator.setBankMap(bankMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,418 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* 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.skillcalculator.banked;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.ItemDefinition;
|
|
||||||
import net.runelite.api.ItemID;
|
|
||||||
import net.runelite.api.Skill;
|
|
||||||
import net.runelite.client.game.ItemManager;
|
|
||||||
|
|
||||||
public enum CriticalItem
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Construction Items
|
|
||||||
*/
|
|
||||||
// Planks
|
|
||||||
PLANK(ItemID.PLANK, "Planks", Skill.CONSTRUCTION),
|
|
||||||
OAK_PLANK(ItemID.OAK_PLANK, "Planks", Skill.CONSTRUCTION),
|
|
||||||
TEAK_PLANK(ItemID.TEAK_PLANK, "Planks", Skill.CONSTRUCTION),
|
|
||||||
MAHOGANY_PLANK(ItemID.MAHOGANY_PLANK, "Planks", Skill.CONSTRUCTION),
|
|
||||||
// Logs
|
|
||||||
LOGS(ItemID.LOGS, "Logs", Skill.CONSTRUCTION, ItemID.PLANK),
|
|
||||||
OAK_LOGS(ItemID.OAK_LOGS, "Logs", Skill.CONSTRUCTION, ItemID.OAK_PLANK),
|
|
||||||
TEAK_LOGS(ItemID.TEAK_LOGS, "Logs", Skill.CONSTRUCTION, ItemID.TEAK_PLANK),
|
|
||||||
MAHOGANY_LOGS(ItemID.MAHOGANY_LOGS, "Logs", Skill.CONSTRUCTION, ItemID.MAHOGANY_PLANK),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Herblore Items
|
|
||||||
*/
|
|
||||||
// Grimy Herbs
|
|
||||||
GRIMY_GUAM_LEAF(ItemID.GRIMY_GUAM_LEAF, "Grimy Herbs", Skill.HERBLORE, ItemID.GUAM_LEAF),
|
|
||||||
GRIMY_MARRENTILL(ItemID.GRIMY_MARRENTILL, "Grimy Herbs", Skill.HERBLORE, ItemID.MARRENTILL),
|
|
||||||
GRIMY_TARROMIN(ItemID.GRIMY_TARROMIN, "Grimy Herbs", Skill.HERBLORE, ItemID.TARROMIN),
|
|
||||||
GRIMY_HARRALANDER(ItemID.GRIMY_HARRALANDER, "Grimy Herbs", Skill.HERBLORE, ItemID.HARRALANDER),
|
|
||||||
GRIMY_RANARR_WEED(ItemID.GRIMY_RANARR_WEED, "Grimy Herbs", Skill.HERBLORE, ItemID.RANARR_WEED),
|
|
||||||
GRIMY_TOADFLAX(ItemID.GRIMY_TOADFLAX, "Grimy Herbs", Skill.HERBLORE, ItemID.TOADFLAX),
|
|
||||||
GRIMY_IRIT_LEAF(ItemID.GRIMY_IRIT_LEAF, "Grimy Herbs", Skill.HERBLORE, ItemID.IRIT_LEAF),
|
|
||||||
GRIMY_AVANTOE(ItemID.GRIMY_AVANTOE, "Grimy Herbs", Skill.HERBLORE, ItemID.AVANTOE),
|
|
||||||
GRIMY_KWUARM(ItemID.GRIMY_KWUARM, "Grimy Herbs", Skill.HERBLORE, ItemID.KWUARM),
|
|
||||||
GRIMY_SNAPDRAGON(ItemID.GRIMY_SNAPDRAGON, "Grimy Herbs", Skill.HERBLORE, ItemID.SNAPDRAGON),
|
|
||||||
GRIMY_CADANTINE(ItemID.GRIMY_CADANTINE, "Grimy Herbs", Skill.HERBLORE, ItemID.CADANTINE),
|
|
||||||
GRIMY_LANTADYME(ItemID.GRIMY_LANTADYME, "Grimy Herbs", Skill.HERBLORE, ItemID.LANTADYME),
|
|
||||||
GRIMY_DWARF_WEED(ItemID.GRIMY_DWARF_WEED, "Grimy Herbs", Skill.HERBLORE, ItemID.DWARF_WEED),
|
|
||||||
GRIMY_TORSTOL(ItemID.GRIMY_TORSTOL, "Grimy Herbs", Skill.HERBLORE, ItemID.TORSTOL),
|
|
||||||
// Clean Herbs
|
|
||||||
GUAM_LEAF(ItemID.GUAM_LEAF, "Cleaned Herbs", Skill.HERBLORE, ItemID.GUAM_POTION_UNF),
|
|
||||||
MARRENTILL(ItemID.MARRENTILL, "Cleaned Herbs", Skill.HERBLORE, ItemID.MARRENTILL_POTION_UNF),
|
|
||||||
TARROMIN(ItemID.TARROMIN, "Cleaned Herbs", Skill.HERBLORE, ItemID.TARROMIN_POTION_UNF),
|
|
||||||
HARRALANDER(ItemID.HARRALANDER, "Cleaned Herbs", Skill.HERBLORE, ItemID.HARRALANDER_POTION_UNF),
|
|
||||||
RANARR_WEED(ItemID.RANARR_WEED, "Cleaned Herbs", Skill.HERBLORE, ItemID.RANARR_POTION_UNF),
|
|
||||||
TOADFLAX(ItemID.TOADFLAX, "Cleaned Herbs", Skill.HERBLORE, ItemID.TOADFLAX_POTION_UNF),
|
|
||||||
IRIT_LEAF(ItemID.IRIT_LEAF, "Cleaned Herbs", Skill.HERBLORE, ItemID.IRIT_POTION_UNF),
|
|
||||||
AVANTOE(ItemID.AVANTOE, "Cleaned Herbs", Skill.HERBLORE, ItemID.AVANTOE_POTION_UNF),
|
|
||||||
KWUARM(ItemID.KWUARM, "Cleaned Herbs", Skill.HERBLORE, ItemID.KWUARM_POTION_UNF),
|
|
||||||
SNAPDRAGON(ItemID.SNAPDRAGON, "Cleaned Herbs", Skill.HERBLORE, ItemID.SNAPDRAGON_POTION_UNF),
|
|
||||||
CADANTINE(ItemID.CADANTINE, "Cleaned Herbs", Skill.HERBLORE, ItemID.CADANTINE_POTION_UNF),
|
|
||||||
LANTADYME(ItemID.LANTADYME, "Cleaned Herbs", Skill.HERBLORE, ItemID.LANTADYME_POTION_UNF),
|
|
||||||
DWARF_WEED(ItemID.DWARF_WEED, "Cleaned Herbs", Skill.HERBLORE, ItemID.DWARF_WEED_POTION_UNF),
|
|
||||||
TORSTOL(ItemID.TORSTOL, "Cleaned Herbs", Skill.HERBLORE, ItemID.TORSTOL_POTION_UNF),
|
|
||||||
// Unfinished Potions
|
|
||||||
GUAM_LEAF_POTION_UNF(ItemID.GUAM_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
RANARR_POTION_UNF(ItemID.RANARR_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
TOADFLAX_POTION_UNF(ItemID.TOADFLAX_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
IRIT_POTION_UNF(ItemID.IRIT_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
AVANTOE_POTION_UNF(ItemID.AVANTOE_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
KWUARM_POTION_UNF(ItemID.KWUARM_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
SNAPDRAGON_POTION_UNF(ItemID.SNAPDRAGON_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
CADANTINE_POTION_UNF(ItemID.CADANTINE_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
LANTADYME_POTION_UNF(ItemID.LANTADYME_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
DWARF_WEED_POTION_UNF(ItemID.DWARF_WEED_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, "Unfinished Potions", Skill.HERBLORE),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prayer Items
|
|
||||||
*/
|
|
||||||
// Bones
|
|
||||||
BONES(ItemID.BONES, "Bones", Skill.PRAYER),
|
|
||||||
WOLF_BONES(ItemID.WOLF_BONES, "Bones", Skill.PRAYER),
|
|
||||||
BURNT_BONES(ItemID.BURNT_BONES, "Bones", Skill.PRAYER),
|
|
||||||
MONKEY_BONES(ItemID.MONKEY_BONES, "Bones", Skill.PRAYER),
|
|
||||||
BAT_BONES(ItemID.BAT_BONES, "Bones", Skill.PRAYER),
|
|
||||||
JOGRE_BONES(ItemID.JOGRE_BONES, "Bones", Skill.PRAYER),
|
|
||||||
BIG_BONES(ItemID.BIG_BONES, "Bones", Skill.PRAYER),
|
|
||||||
ZOGRE_BONES(ItemID.ZOGRE_BONES, "Bones", Skill.PRAYER),
|
|
||||||
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, "Bones", Skill.PRAYER),
|
|
||||||
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Bones", Skill.PRAYER),
|
|
||||||
WYVERN_BONES(ItemID.WYVERN_BONES, "Bones", Skill.PRAYER),
|
|
||||||
DRAGON_BONES(ItemID.DRAGON_BONES, "Bones", Skill.PRAYER),
|
|
||||||
FAYRG_BONES(ItemID.FAYRG_BONES, "Bones", Skill.PRAYER),
|
|
||||||
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Bones", Skill.PRAYER),
|
|
||||||
RAURG_BONES(ItemID.RAURG_BONES, "Bones", Skill.PRAYER),
|
|
||||||
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Bones", Skill.PRAYER),
|
|
||||||
OURG_BONES(ItemID.OURG_BONES, "Bones", Skill.PRAYER),
|
|
||||||
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, "Bones", Skill.PRAYER),
|
|
||||||
// Shade Remains (Pyre Logs)
|
|
||||||
LOAR_REMAINS(ItemID.LOAR_REMAINS, "Shades", Skill.PRAYER, true),
|
|
||||||
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, "Shades", Skill.PRAYER, true),
|
|
||||||
RIYL_REMAINS(ItemID.RIYL_REMAINS, "Shades", Skill.PRAYER, true),
|
|
||||||
ASYN_REMAINS(ItemID.ASYN_REMAINS, "Shades", Skill.PRAYER, true),
|
|
||||||
FIYR_REMAINS(ItemID.FIYR_REMAINS, "Shades", Skill.PRAYER, true),
|
|
||||||
// Ensouled Heads
|
|
||||||
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, "Ensouled Heads", Skill.PRAYER, true),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cooking Items
|
|
||||||
*/
|
|
||||||
RAW_HERRING(ItemID.RAW_HERRING, "Fish", Skill.COOKING),
|
|
||||||
RAW_MACKEREL(ItemID.RAW_MACKEREL, "Fish", Skill.COOKING),
|
|
||||||
RAW_TROUT(ItemID.RAW_TROUT, "Fish", Skill.COOKING),
|
|
||||||
RAW_COD(ItemID.RAW_COD, "Fish", Skill.COOKING),
|
|
||||||
RAW_PIKE(ItemID.RAW_PIKE, "Fish", Skill.COOKING),
|
|
||||||
RAW_SALMON(ItemID.RAW_SALMON, "Fish", Skill.COOKING),
|
|
||||||
RAW_TUNA(ItemID.RAW_TUNA, "Fish", Skill.COOKING),
|
|
||||||
RAW_KARAMBWAN(ItemID.RAW_KARAMBWAN, "Fish", Skill.COOKING),
|
|
||||||
RAW_LOBSTER(ItemID.RAW_LOBSTER, "Fish", Skill.COOKING),
|
|
||||||
RAW_BASS(ItemID.RAW_BASS, "Fish", Skill.COOKING),
|
|
||||||
RAW_SWORDFISH(ItemID.RAW_SWORDFISH, "Fish", Skill.COOKING),
|
|
||||||
RAW_MONKFISH(ItemID.RAW_MONKFISH, "Fish", Skill.COOKING),
|
|
||||||
RAW_SHARK(ItemID.RAW_SHARK, "Fish", Skill.COOKING),
|
|
||||||
RAW_SEA_TURTLE(ItemID.RAW_SEA_TURTLE, "Fish", Skill.COOKING),
|
|
||||||
RAW_ANGLERFISH(ItemID.RAW_ANGLERFISH, "Fish", Skill.COOKING),
|
|
||||||
RAW_DARK_CRAB(ItemID.RAW_DARK_CRAB, "Fish", Skill.COOKING),
|
|
||||||
RAW_MANTA_RAY(ItemID.RAW_MANTA_RAY, "Fish", Skill.COOKING),
|
|
||||||
|
|
||||||
GRAPES(ItemID.GRAPES, "Other", Skill.COOKING),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Crafting Items
|
|
||||||
*/
|
|
||||||
WOOL(ItemID.WOOL, "Misc", Skill.CRAFTING),
|
|
||||||
FLAX(ItemID.FLAX, "Misc", Skill.CRAFTING),
|
|
||||||
MOLTEN_GLASS(ItemID.MOLTEN_GLASS, "Misc", Skill.CRAFTING),
|
|
||||||
BATTLESTAFF(ItemID.BATTLESTAFF, "Misc", Skill.CRAFTING),
|
|
||||||
|
|
||||||
// D'hide/Dragon Leather
|
|
||||||
GREEN_DRAGONHIDE(ItemID.GREEN_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.GREEN_DRAGON_LEATHER),
|
|
||||||
GREEN_DRAGON_LEATHER(ItemID.GREEN_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
|
|
||||||
BLUE_DRAGONHIDE(ItemID.BLUE_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.BLUE_DRAGON_LEATHER),
|
|
||||||
BLUE_DRAGON_LEATHER(ItemID.BLUE_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
|
|
||||||
RED_DRAGONHIDE(ItemID.RED_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.RED_DRAGON_LEATHER),
|
|
||||||
RED_DRAGON_LEATHER(ItemID.RED_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
|
|
||||||
BLACK_DRAGONHIDE(ItemID.BLACK_DRAGONHIDE, "D'hide", Skill.CRAFTING, ItemID.BLACK_DRAGON_LEATHER),
|
|
||||||
BLACK_DRAGON_LEATHER(ItemID.BLACK_DRAGON_LEATHER, "D'hide", Skill.CRAFTING),
|
|
||||||
|
|
||||||
// Uncut Gems
|
|
||||||
UNCUT_OPAL(ItemID.UNCUT_OPAL, "Gems", Skill.CRAFTING, ItemID.OPAL),
|
|
||||||
UNCUT_JADE(ItemID.UNCUT_JADE, "Gems", Skill.CRAFTING, ItemID.JADE),
|
|
||||||
UNCUT_RED_TOPAZ(ItemID.UNCUT_RED_TOPAZ, "Gems", Skill.CRAFTING, ItemID.RED_TOPAZ),
|
|
||||||
UNCUT_SAPPHIRE(ItemID.UNCUT_SAPPHIRE, "Gems", Skill.CRAFTING, ItemID.SAPPHIRE),
|
|
||||||
UNCUT_EMERALD(ItemID.UNCUT_EMERALD, "Gems", Skill.CRAFTING, ItemID.EMERALD),
|
|
||||||
UNCUT_RUBY(ItemID.UNCUT_RUBY, "Gems", Skill.CRAFTING, ItemID.RUBY),
|
|
||||||
UNCUT_DIAMOND(ItemID.UNCUT_DIAMOND, "Gems", Skill.CRAFTING, ItemID.DIAMOND),
|
|
||||||
UNCUT_DRAGONSTONE(ItemID.UNCUT_DRAGONSTONE, "Gems", Skill.CRAFTING, ItemID.DRAGONSTONE),
|
|
||||||
UNCUT_ONYX(ItemID.UNCUT_ONYX, "Gems", Skill.CRAFTING, ItemID.ONYX),
|
|
||||||
UNCUT_ZENYTE(ItemID.UNCUT_ZENYTE, "Gems", Skill.CRAFTING, ItemID.ZENYTE),
|
|
||||||
|
|
||||||
// Cut Gems
|
|
||||||
OPAL(ItemID.OPAL, "Gems", Skill.CRAFTING),
|
|
||||||
JADE(ItemID.JADE, "Gems", Skill.CRAFTING),
|
|
||||||
RED_TOPAZ(ItemID.RED_TOPAZ, "Gems", Skill.CRAFTING),
|
|
||||||
SAPPHIRE(ItemID.SAPPHIRE, "Gems", Skill.CRAFTING),
|
|
||||||
EMERALD(ItemID.EMERALD, "Gems", Skill.CRAFTING),
|
|
||||||
RUBY(ItemID.RUBY, "Gems", Skill.CRAFTING),
|
|
||||||
DIAMOND(ItemID.DIAMOND, "Gems", Skill.CRAFTING),
|
|
||||||
DRAGONSTONE(ItemID.DRAGONSTONE, "Gems", Skill.CRAFTING),
|
|
||||||
ONYX(ItemID.ONYX, "Gems", Skill.CRAFTING),
|
|
||||||
ZENYTE(ItemID.ZENYTE, "Gems", Skill.CRAFTING),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smithing Items
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Ores
|
|
||||||
IRON_ORE(ItemID.IRON_ORE, "Ore", Skill.SMITHING),
|
|
||||||
SILVER_ORE(ItemID.SILVER_ORE, "Ore", Skill.SMITHING),
|
|
||||||
GOLD_ORE(ItemID.GOLD_ORE, "Ore", Skill.SMITHING),
|
|
||||||
MITHRIL_ORE(ItemID.MITHRIL_ORE, "Ore", Skill.SMITHING),
|
|
||||||
ADAMANTITE_ORE(ItemID.ADAMANTITE_ORE, "Ore", Skill.SMITHING),
|
|
||||||
RUNITE_ORE(ItemID.RUNITE_ORE, "Ore", Skill.SMITHING),
|
|
||||||
|
|
||||||
// Bars
|
|
||||||
BRONZE_BAR(ItemID.BRONZE_BAR, "Bars", Skill.SMITHING),
|
|
||||||
IRON_BAR(ItemID.IRON_BAR, "Bars", Skill.SMITHING),
|
|
||||||
STEEL_BAR(ItemID.STEEL_BAR, "Bars", Skill.SMITHING),
|
|
||||||
MITHRIL_BAR(ItemID.MITHRIL_BAR, "Bars", Skill.SMITHING),
|
|
||||||
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, "Bars", Skill.SMITHING),
|
|
||||||
RUNITE_BAR(ItemID.RUNITE_BAR, "Bars", Skill.SMITHING),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Farming Items
|
|
||||||
*/
|
|
||||||
// Seeds
|
|
||||||
ACORN(ItemID.ACORN, "Seeds", Skill.FARMING),
|
|
||||||
WILLOW_SEED(ItemID.WILLOW_SEED, "Seeds", Skill.FARMING),
|
|
||||||
MAPLE_SEED(ItemID.MAPLE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
YEW_SEED(ItemID.YEW_SEED, "Seeds", Skill.FARMING),
|
|
||||||
MAGIC_SEED(ItemID.MAGIC_SEED, "Seeds", Skill.FARMING),
|
|
||||||
APPLE_TREE_SEED(ItemID.APPLE_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
BANANA_TREE_SEED(ItemID.BANANA_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
ORANGE_TREE_SEED(ItemID.ORANGE_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
CURRY_TREE_SEED(ItemID.CURRY_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
PINEAPPLE_SEED(ItemID.PINEAPPLE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
PAPAYA_TREE_SEED(ItemID.PAPAYA_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
PALM_TREE_SEED(ItemID.PALM_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
CALQUAT_TREE_SEED(ItemID.CALQUAT_TREE_SEED, "Seeds", Skill.FARMING),
|
|
||||||
TEAK_SEED(ItemID.TEAK_SEED, "Seeds", Skill.FARMING),
|
|
||||||
MAHOGANY_SEED(ItemID.MAHOGANY_SEED, "Seeds", Skill.FARMING),
|
|
||||||
SPIRIT_SEED(ItemID.SPIRIT_SEED, "Seeds", Skill.FARMING),
|
|
||||||
|
|
||||||
// Saplings
|
|
||||||
OAK_SAPLING(ItemID.OAK_SAPLING, "Saplings", Skill.FARMING, ItemID.ACORN),
|
|
||||||
WILLOW_SAPLING(ItemID.WILLOW_SAPLING, "Saplings", Skill.FARMING, ItemID.WILLOW_SEED),
|
|
||||||
MAPLE_SAPLING(ItemID.MAPLE_SAPLING, "Saplings", Skill.FARMING, ItemID.MAPLE_SEED),
|
|
||||||
YEW_SAPLING(ItemID.YEW_SAPLING, "Saplings", Skill.FARMING, ItemID.YEW_SEED),
|
|
||||||
MAGIC_SAPLING(ItemID.MAGIC_SAPLING, "Saplings", Skill.FARMING, ItemID.MAGIC_SEED),
|
|
||||||
APPLE_TREE_SAPLING(ItemID.APPLE_SAPLING, "Saplings", Skill.FARMING, ItemID.APPLE_TREE_SEED),
|
|
||||||
BANANA_TREE_SAPLING(ItemID.BANANA_SAPLING, "Saplings", Skill.FARMING, ItemID.BANANA_TREE_SEED),
|
|
||||||
ORANGE_TREE_SAPLING(ItemID.ORANGE_SAPLING, "Saplings", Skill.FARMING, ItemID.ORANGE_TREE_SEED),
|
|
||||||
CURRY_TREE_SAPLING(ItemID.CURRY_SAPLING, "Saplings", Skill.FARMING, ItemID.CURRY_TREE_SEED),
|
|
||||||
PINEAPPLE_SAPLING(ItemID.PINEAPPLE_SAPLING, "Saplings", Skill.FARMING, ItemID.PINEAPPLE_SEED),
|
|
||||||
PAPAYA_TREE_SAPLING(ItemID.PAPAYA_SAPLING, "Saplings", Skill.FARMING, ItemID.PAPAYA_TREE_SEED),
|
|
||||||
PALM_TREE_SAPLING(ItemID.PALM_SAPLING, "Saplings", Skill.FARMING, ItemID.PALM_TREE_SEED),
|
|
||||||
CALQUAT_TREE_SAPLING(ItemID.CALQUAT_SAPLING, "Saplings", Skill.FARMING, ItemID.CALQUAT_TREE_SEED),
|
|
||||||
TEAK_SAPLING(ItemID.TEAK_SAPLING, "Saplings", Skill.FARMING, ItemID.TEAK_SEED),
|
|
||||||
MAHOGANY_SAPLING(ItemID.MAHOGANY_SAPLING, "Saplings", Skill.FARMING, ItemID.MAHOGANY_SEED),
|
|
||||||
SPIRIT_SAPLING(ItemID.SPIRIT_SAPLING, "Saplings", Skill.FARMING, ItemID.SPIRIT_SEED),
|
|
||||||
;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final int itemID;
|
|
||||||
@Getter
|
|
||||||
private final String category;
|
|
||||||
@Getter
|
|
||||||
private final Skill skill;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should be operated on and then treated like this item or does nothing if null.
|
|
||||||
* Used mostly for things like herblore where you want Grimy, Clean, and UNF to count for creating potions.
|
|
||||||
* To do this GRIMY links to CLEAN which links to UNFINISHED which links to null
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
private final int linkedItemId;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private boolean ignoreBonus;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private ItemDefinition definition;
|
|
||||||
|
|
||||||
CriticalItem(int itemID, String category, Skill skill, int linkedItem)
|
|
||||||
{
|
|
||||||
this.itemID = itemID;
|
|
||||||
this.category = category;
|
|
||||||
this.skill = skill;
|
|
||||||
this.linkedItemId = linkedItem;
|
|
||||||
this.definition = null;
|
|
||||||
this.ignoreBonus = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CriticalItem(int itemID, String category, Skill skill)
|
|
||||||
{
|
|
||||||
this(itemID, category, skill, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
CriticalItem(int itemID, String category, Skill skill, boolean ignoreBonusXp)
|
|
||||||
{
|
|
||||||
this(itemID, category, skill, -1);
|
|
||||||
this.ignoreBonus = ignoreBonusXp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a Map to reduce looping frequency
|
|
||||||
private static Map<Skill, List<CriticalItem>> buildSkillItemMap()
|
|
||||||
{
|
|
||||||
Map<Skill, List<CriticalItem>> map = new HashMap<>();
|
|
||||||
for (CriticalItem item : values())
|
|
||||||
{
|
|
||||||
map.computeIfAbsent(item.getSkill(), e -> new ArrayList<>()).add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<Skill, List<CriticalItem>> bySkillName = buildSkillItemMap();
|
|
||||||
|
|
||||||
public static List<CriticalItem> getBySkillName(Skill skill)
|
|
||||||
{
|
|
||||||
return bySkillName.get(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a Map to reduce looping frequency
|
|
||||||
private static Map<Skill, Set<String>> buildSkillCategoryMap()
|
|
||||||
{
|
|
||||||
Map<Skill, Set<String>> map = new HashMap<>();
|
|
||||||
for (CriticalItem item : values())
|
|
||||||
{
|
|
||||||
map.computeIfAbsent(item.getSkill(), k -> new HashSet<>()).add(item.category);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<Skill, Set<String>> bySkillCategory = buildSkillCategoryMap();
|
|
||||||
|
|
||||||
public static Set<String> getSkillCategories(Skill skill)
|
|
||||||
{
|
|
||||||
return bySkillCategory.get(skill);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a Map to reduce looping frequency
|
|
||||||
private static Map<String, List<CriticalItem>> buildItemSkillCategoryMap()
|
|
||||||
{
|
|
||||||
Map<String, List<CriticalItem>> map = new HashMap<>();
|
|
||||||
for (CriticalItem item : values())
|
|
||||||
{
|
|
||||||
String key = item.getCategory() + item.skill.getName();
|
|
||||||
map.computeIfAbsent(key, e -> new ArrayList<>()).add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<String, List<CriticalItem>> itemsBySkillCategory = buildItemSkillCategoryMap();
|
|
||||||
|
|
||||||
public static List<CriticalItem> getItemsForSkillCategories(Skill skill, String category)
|
|
||||||
{
|
|
||||||
return itemsBySkillCategory.get(category + skill.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a Map to reduce looping frequency
|
|
||||||
private static Map<Integer, CriticalItem> buildItemsByIdMap()
|
|
||||||
{
|
|
||||||
Map<Integer, CriticalItem> map = new HashMap<>();
|
|
||||||
for (CriticalItem item : values())
|
|
||||||
{
|
|
||||||
map.put(item.getItemID(), item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<Integer, CriticalItem> itemsById = buildItemsByIdMap();
|
|
||||||
|
|
||||||
public static CriticalItem getByItemId(int id)
|
|
||||||
{
|
|
||||||
return itemsById.get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaches the Item Composition to each Critical Item on client initial load
|
|
||||||
*
|
|
||||||
* @param m ItemManager
|
|
||||||
*/
|
|
||||||
public static void prepareItemDefinitions(ItemManager m)
|
|
||||||
{
|
|
||||||
for (CriticalItem i : values())
|
|
||||||
{
|
|
||||||
i.definition = m.getItemDefinition(i.getItemID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString()
|
|
||||||
{
|
|
||||||
return "CriticalItem=(name=" + this.name() + ",id=" + this.itemID + ",category=" + this.category + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,17 +24,19 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.skillcalculator.banked.beans;
|
package net.runelite.client.plugins.skillcalculator.banked.beans;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
import lombok.AccessLevel;
|
import javax.annotation.Nullable;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.ItemDefinition;
|
||||||
import net.runelite.api.ItemID;
|
import net.runelite.api.ItemID;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
|
import net.runelite.client.game.ItemManager;
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
@Getter
|
||||||
public enum Activity
|
public enum Activity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -42,372 +44,679 @@ public enum Activity
|
|||||||
*/
|
*/
|
||||||
// Creating Potions
|
// Creating Potions
|
||||||
// Guam
|
// Guam
|
||||||
GUAM_POTION_UNF(ItemID.GUAM_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.GUAM_LEAF, ActivitySecondaries.UNFINISHED_POTION),
|
GUAM_POTION_UNF(ItemID.GUAM_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0,
|
||||||
GUAM_TAR(ItemID.GUAM_TAR, "Guam tar", Skill.HERBLORE, 19, 30, CriticalItem.GUAM_LEAF, ActivitySecondaries.SWAMP_TAR, true),
|
CriticalItem.GUAM_LEAF, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.GUAM_POTION_UNF, 1)),
|
||||||
|
GUAM_TAR(ItemID.GUAM_TAR, "Guam tar", Skill.HERBLORE, 19, 30,
|
||||||
|
CriticalItem.GUAM_LEAF, Secondaries.SWAMP_TAR, new ItemStack(ItemID.GUAM_TAR, 15)),
|
||||||
|
|
||||||
ATTACK_POTION(ItemID.ATTACK_POTION4, "Attack Potion", Skill.HERBLORE, 3, 25, CriticalItem.GUAM_LEAF_POTION_UNF, ActivitySecondaries.ATTACK_POTION),
|
ATTACK_POTION(ItemID.ATTACK_POTION3, "Attack potion", Skill.HERBLORE, 3, 25,
|
||||||
|
CriticalItem.GUAM_LEAF_POTION_UNF, Secondaries.ATTACK_POTION, new ItemStack(ItemID.ATTACK_POTION3, 1)),
|
||||||
// Marrentil
|
// Marrentil
|
||||||
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.MARRENTILL, ActivitySecondaries.UNFINISHED_POTION),
|
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 1, 0,
|
||||||
MARRENTILL_TAR(ItemID.MARRENTILL_TAR, "Marrentill tar", Skill.HERBLORE, 31, 42.5, CriticalItem.MARRENTILL, ActivitySecondaries.SWAMP_TAR, true),
|
CriticalItem.MARRENTILL, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.MARRENTILL_POTION_UNF, 1)),
|
||||||
|
MARRENTILL_TAR(ItemID.MARRENTILL_TAR, "Marrentill tar", Skill.HERBLORE, 31, 42.5,
|
||||||
|
CriticalItem.MARRENTILL, Secondaries.SWAMP_TAR, new ItemStack(ItemID.MARRENTILL_TAR, 15)),
|
||||||
|
|
||||||
ANTIPOISON(ItemID.ANTIPOISON4, "Antipoison", Skill.HERBLORE, 5, 37.5, CriticalItem.MARRENTILL_POTION_UNF, ActivitySecondaries.ANTIPOISON),
|
ANTIPOISON(ItemID.ANTIPOISON3, "Antipoison", Skill.HERBLORE, 5, 37.5,
|
||||||
|
CriticalItem.MARRENTILL_POTION_UNF, Secondaries.ANTIPOISON, new ItemStack(ItemID.ANTIPOISON3, 1)),
|
||||||
// Tarromin
|
// Tarromin
|
||||||
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.TARROMIN, ActivitySecondaries.UNFINISHED_POTION),
|
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 1, 0,
|
||||||
TARROMIN_TAR(ItemID.TARROMIN_TAR, "Tarromin tar", Skill.HERBLORE, 39, 55, CriticalItem.TARROMIN, ActivitySecondaries.SWAMP_TAR, true),
|
CriticalItem.TARROMIN, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.TARROMIN_POTION_UNF, 1)),
|
||||||
|
TARROMIN_TAR(ItemID.TARROMIN_TAR, "Tarromin tar", Skill.HERBLORE, 39, 55,
|
||||||
|
CriticalItem.TARROMIN, Secondaries.SWAMP_TAR, new ItemStack(ItemID.TARROMIN_TAR, 15)),
|
||||||
|
|
||||||
STRENGTH_POTION(ItemID.STRENGTH_POTION4, "Strength potion", Skill.HERBLORE, 12, 50, CriticalItem.TARROMIN_POTION_UNF, ActivitySecondaries.STRENGTH_POTION),
|
STRENGTH_POTION(ItemID.STRENGTH_POTION3, "Strength potion", Skill.HERBLORE, 12, 50,
|
||||||
SERUM_207(ItemID.SERUM_207_4, "Serum 207", Skill.HERBLORE, 15, 50, CriticalItem.TARROMIN_POTION_UNF, ActivitySecondaries.SERUM_207),
|
CriticalItem.TARROMIN_POTION_UNF, Secondaries.STRENGTH_POTION, new ItemStack(ItemID.STRENGTH_POTION3, 1)),
|
||||||
|
SERUM_207(ItemID.SERUM_207_3, "Serum 207", Skill.HERBLORE, 15, 50,
|
||||||
|
CriticalItem.TARROMIN_POTION_UNF, Secondaries.SERUM_207, new ItemStack(ItemID.SERUM_207_3, 1)),
|
||||||
// Harralander
|
// Harralander
|
||||||
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 1, 0, CriticalItem.HARRALANDER, ActivitySecondaries.UNFINISHED_POTION),
|
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 1, 0,
|
||||||
HARRALANDER_TAR(ItemID.HARRALANDER_TAR, "Harralander tar", Skill.HERBLORE, 44, 72.5, CriticalItem.HARRALANDER, ActivitySecondaries.SWAMP_TAR, true),
|
CriticalItem.HARRALANDER, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.HARRALANDER_POTION_UNF, 1)),
|
||||||
|
HARRALANDER_TAR(ItemID.HARRALANDER_TAR, "Harralander tar", Skill.HERBLORE, 44, 72.5,
|
||||||
|
CriticalItem.HARRALANDER, Secondaries.SWAMP_TAR, new ItemStack(ItemID.HARRALANDER_TAR, 15)),
|
||||||
|
|
||||||
COMPOST_POTION(ItemID.COMPOST_POTION4, "Compost potion", Skill.HERBLORE, 21, 60, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.COMPOST_POTION),
|
COMPOST_POTION(ItemID.COMPOST_POTION3, "Compost potion", Skill.HERBLORE, 21, 60,
|
||||||
RESTORE_POTION(ItemID.RESTORE_POTION4, "Restore potion", Skill.HERBLORE, 22, 62.5, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.RESTORE_POTION),
|
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.COMPOST_POTION, new ItemStack(ItemID.COMPOST_POTION3, 1)),
|
||||||
ENERGY_POTION(ItemID.ENERGY_POTION4, "Energy potion", Skill.HERBLORE, 26, 67.5, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.ENERGY_POTION),
|
RESTORE_POTION(ItemID.RESTORE_POTION3, "Restore potion", Skill.HERBLORE, 22, 62.5,
|
||||||
COMBAT_POTION(ItemID.COMBAT_POTION4, "Combat potion", Skill.HERBLORE, 36, 84, CriticalItem.HARRALANDER_POTION_UNF, ActivitySecondaries.COMBAT_POTION),
|
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.RESTORE_POTION, new ItemStack(ItemID.RESTORE_POTION3, 1)),
|
||||||
|
ENERGY_POTION(ItemID.ENERGY_POTION3, "Energy potion", Skill.HERBLORE, 26, 67.5,
|
||||||
|
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.ENERGY_POTION, new ItemStack(ItemID.ENERGY_POTION3, 1)),
|
||||||
|
COMBAT_POTION(ItemID.COMBAT_POTION3, "Combat potion", Skill.HERBLORE, 36, 84,
|
||||||
|
CriticalItem.HARRALANDER_POTION_UNF, Secondaries.COMBAT_POTION, new ItemStack(ItemID.COMBAT_POTION3, 1)),
|
||||||
// Ranarr Weed
|
// Ranarr Weed
|
||||||
DEFENCE_POTION(ItemID.DEFENCE_POTION4, "Defence potion", Skill.HERBLORE, 30, 75, CriticalItem.RANARR_POTION_UNF, ActivitySecondaries.DEFENCE_POTION),
|
RANARR_POTION_UNF(ItemID.RANARR_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 30, 0,
|
||||||
PRAYER_POTION(ItemID.PRAYER_POTION4, "Prayer potion", Skill.HERBLORE, 38, 87.5, CriticalItem.RANARR_POTION_UNF, ActivitySecondaries.PRAYER_POTION),
|
CriticalItem.RANARR_WEED, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.RANARR_POTION_UNF, 1)),
|
||||||
|
DEFENCE_POTION(ItemID.DEFENCE_POTION3, "Defence potion", Skill.HERBLORE, 30, 75,
|
||||||
|
CriticalItem.RANARR_POTION_UNF, Secondaries.DEFENCE_POTION, new ItemStack(ItemID.DEFENCE_POTION3, 1)),
|
||||||
|
PRAYER_POTION(ItemID.PRAYER_POTION3, "Prayer potion", Skill.HERBLORE, 38, 87.5,
|
||||||
|
CriticalItem.RANARR_POTION_UNF, Secondaries.PRAYER_POTION, new ItemStack(ItemID.PRAYER_POTION3, 1)),
|
||||||
// Toadflax
|
// Toadflax
|
||||||
AGILITY_POTION(ItemID.AGILITY_POTION4, "Agility potion", Skill.HERBLORE, 34, 80, CriticalItem.TOADFLAX_POTION_UNF, ActivitySecondaries.AGILITY_POTION),
|
TOADFLAX_POTION_UNF(ItemID.TOADFLAX_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 34, 0,
|
||||||
SARADOMIN_BREW(ItemID.SARADOMIN_BREW4, "Saradomin brew", Skill.HERBLORE, 81, 180, CriticalItem.TOADFLAX_POTION_UNF, ActivitySecondaries.SARADOMIN_BREW),
|
CriticalItem.TOADFLAX, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.TOADFLAX_POTION_UNF, 1)),
|
||||||
|
AGILITY_POTION(ItemID.AGILITY_POTION3, "Agility potion", Skill.HERBLORE, 34, 80,
|
||||||
|
CriticalItem.TOADFLAX_POTION_UNF, Secondaries.AGILITY_POTION, new ItemStack(ItemID.AGILITY_POTION3, 1)),
|
||||||
|
SARADOMIN_BREW(ItemID.SARADOMIN_BREW3, "Saradomin brew", Skill.HERBLORE, 81, 180,
|
||||||
|
CriticalItem.TOADFLAX_POTION_UNF, Secondaries.SARADOMIN_BREW, new ItemStack(ItemID.SARADOMIN_BREW3, 1)),
|
||||||
// Irit
|
// Irit
|
||||||
SUPER_ATTACK(ItemID.SUPER_ATTACK4, "Super attack", Skill.HERBLORE, 45, 100, CriticalItem.IRIT_POTION_UNF, ActivitySecondaries.SUPER_ATTACK),
|
IRIT_POTION_UNF(ItemID.IRIT_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 45, 0,
|
||||||
SUPERANTIPOISON(ItemID.SUPERANTIPOISON4, "Superantipoison", Skill.HERBLORE, 48, 106.3, CriticalItem.IRIT_POTION_UNF, ActivitySecondaries.SUPERANTIPOISON),
|
CriticalItem.IRIT_LEAF, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.IRIT_POTION_UNF, 1)),
|
||||||
|
SUPER_ATTACK(ItemID.SUPER_ATTACK3, "Super attack", Skill.HERBLORE, 45, 100,
|
||||||
|
CriticalItem.IRIT_POTION_UNF, Secondaries.SUPER_ATTACK, new ItemStack(ItemID.SUPER_ATTACK3, 1)),
|
||||||
|
SUPERANTIPOISON(ItemID.SUPERANTIPOISON3, "Superantipoison", Skill.HERBLORE, 48, 106.3,
|
||||||
|
CriticalItem.IRIT_POTION_UNF, Secondaries.SUPERANTIPOISON, new ItemStack(ItemID.SUPERANTIPOISON3, 1)),
|
||||||
// Avantoe
|
// Avantoe
|
||||||
FISHING_POTION(ItemID.FISHING_POTION4, "Fishing potion", Skill.HERBLORE, 50, 112.5, CriticalItem.AVANTOE_POTION_UNF, ActivitySecondaries.FISHING_POTION),
|
AVANTOE_POTION_UNF(ItemID.AVANTOE_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 50, 0,
|
||||||
SUPER_ENERGY_POTION(ItemID.SUPER_ENERGY3_20549, "Super energy potion", Skill.HERBLORE, 52, 117.5, CriticalItem.AVANTOE_POTION_UNF, ActivitySecondaries.SUPER_ENERGY_POTION),
|
CriticalItem.AVANTOE, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.AVANTOE_POTION_UNF, 1)),
|
||||||
HUNTER_POTION(ItemID.HUNTER_POTION4, "Hunter potion", Skill.HERBLORE, 53, 120, CriticalItem.AVANTOE_POTION_UNF, ActivitySecondaries.HUNTER_POTION),
|
FISHING_POTION(ItemID.FISHING_POTION3, "Fishing potion", Skill.HERBLORE, 50, 112.5,
|
||||||
|
CriticalItem.AVANTOE_POTION_UNF, Secondaries.FISHING_POTION, new ItemStack(ItemID.FISHING_POTION3, 1)),
|
||||||
|
SUPER_ENERGY_POTION(ItemID.SUPER_ENERGY3_20549, "Super energy potion", Skill.HERBLORE, 52, 117.5,
|
||||||
|
CriticalItem.AVANTOE_POTION_UNF, Secondaries.SUPER_ENERGY_POTION, new ItemStack(ItemID.SUPER_ENERGY3_20549, 1)),
|
||||||
|
HUNTER_POTION(ItemID.HUNTER_POTION3, "Hunter potion", Skill.HERBLORE, 53, 120,
|
||||||
|
CriticalItem.AVANTOE_POTION_UNF, Secondaries.HUNTER_POTION, new ItemStack(ItemID.HUNTER_POTION3, 1)),
|
||||||
// Kwuarm
|
// Kwuarm
|
||||||
SUPER_STRENGTH(ItemID.SUPER_STRENGTH4, "Super strength", Skill.HERBLORE, 55, 125, CriticalItem.KWUARM_POTION_UNF, ActivitySecondaries.SUPER_STRENGTH),
|
KWUARM_POTION_UNF(ItemID.KWUARM_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 55, 0,
|
||||||
|
CriticalItem.KWUARM, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.KWUARM_POTION_UNF, 1)),
|
||||||
|
SUPER_STRENGTH(ItemID.SUPER_STRENGTH3, "Super strength", Skill.HERBLORE, 55, 125,
|
||||||
|
CriticalItem.KWUARM_POTION_UNF, Secondaries.SUPER_STRENGTH, new ItemStack(ItemID.SUPER_STRENGTH3, 1)),
|
||||||
// Snapdragon
|
// Snapdragon
|
||||||
SUPER_RESTORE(ItemID.SUPER_RESTORE4, "Super restore", Skill.HERBLORE, 63, 142.5, CriticalItem.SNAPDRAGON_POTION_UNF, ActivitySecondaries.SUPER_RESTORE),
|
SNAPDRAGON_POTION_UNF(ItemID.SNAPDRAGON_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 63, 0,
|
||||||
SANFEW_SERUM(ItemID.SANFEW_SERUM4, "Sanfew serum", Skill.HERBLORE, 65, 160, CriticalItem.SNAPDRAGON_POTION_UNF, ActivitySecondaries.SANFEW_SERUM),
|
CriticalItem.SNAPDRAGON, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.SNAPDRAGON_POTION_UNF, 1)),
|
||||||
|
SUPER_RESTORE(ItemID.SUPER_RESTORE3, "Super restore", Skill.HERBLORE, 63, 142.5,
|
||||||
|
CriticalItem.SNAPDRAGON_POTION_UNF, Secondaries.SUPER_RESTORE, new ItemStack(ItemID.SUPER_RESTORE3, 1)),
|
||||||
|
SANFEW_SERUM(ItemID.SANFEW_SERUM3, "Sanfew serum", Skill.HERBLORE, 65, 160,
|
||||||
|
CriticalItem.SNAPDRAGON_POTION_UNF, Secondaries.SANFEW_SERUM, new ItemStack(ItemID.SANFEW_SERUM3, 1)),
|
||||||
// Cadantine
|
// Cadantine
|
||||||
SUPER_DEFENCE_POTION(ItemID.SUPER_DEFENCE4, "Super defence", Skill.HERBLORE, 66, 150, CriticalItem.CADANTINE_POTION_UNF, ActivitySecondaries.SUPER_DEFENCE_POTION),
|
CADANTINE_POTION_UNF(ItemID.CADANTINE_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 66, 0,
|
||||||
|
CriticalItem.CADANTINE, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.CADANTINE_POTION_UNF, 1)),
|
||||||
|
SUPER_DEFENCE_POTION(ItemID.SUPER_DEFENCE3, "Super defence", Skill.HERBLORE, 66, 150,
|
||||||
|
CriticalItem.CADANTINE_POTION_UNF, Secondaries.SUPER_DEFENCE_POTION, new ItemStack(ItemID.SUPER_DEFENCE3, 1)),
|
||||||
// Lantadyme
|
// Lantadyme
|
||||||
ANTIFIRE_POTION(ItemID.ANTIFIRE_POTION4, "Anti-fire potion", Skill.HERBLORE, 69, 157.5, CriticalItem.LANTADYME_POTION_UNF, ActivitySecondaries.ANTIFIRE_POTION),
|
LANTADYME_POTION_UNF(ItemID.LANTADYME_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 69, 0,
|
||||||
MAGIC_POTION(ItemID.MAGIC_POTION4, "Magic potion", Skill.HERBLORE, 76, 172.5, CriticalItem.LANTADYME_POTION_UNF, ActivitySecondaries.MAGIC_POTION),
|
CriticalItem.LANTADYME, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.LANTADYME_POTION_UNF, 1)),
|
||||||
|
ANTIFIRE_POTION(ItemID.ANTIFIRE_POTION3, "Anti-fire potion", Skill.HERBLORE, 69, 157.5,
|
||||||
|
CriticalItem.LANTADYME_POTION_UNF, Secondaries.ANTIFIRE_POTION, new ItemStack(ItemID.ANTIFIRE_POTION3, 1)),
|
||||||
|
MAGIC_POTION(ItemID.MAGIC_POTION3, "Magic potion", Skill.HERBLORE, 76, 172.5,
|
||||||
|
CriticalItem.LANTADYME_POTION_UNF, Secondaries.MAGIC_POTION, new ItemStack(ItemID.MAGIC_POTION3, 1)),
|
||||||
// Dwarf Weed
|
// Dwarf Weed
|
||||||
RANGING_POTION(ItemID.RANGING_POTION4, "Ranging potion", Skill.HERBLORE, 72, 162.5, CriticalItem.DWARF_WEED_POTION_UNF, ActivitySecondaries.RANGING_POTION),
|
DWARF_WEED_POTION_UNF(ItemID.DWARF_WEED_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 72, 0,
|
||||||
|
CriticalItem.DWARF_WEED, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.DWARF_WEED_POTION_UNF, 1)),
|
||||||
|
RANGING_POTION(ItemID.RANGING_POTION3, "Ranging potion", Skill.HERBLORE, 72, 162.5,
|
||||||
|
CriticalItem.DWARF_WEED_POTION_UNF, Secondaries.RANGING_POTION, new ItemStack(ItemID.RANGING_POTION3, 1)),
|
||||||
// Torstol
|
// Torstol
|
||||||
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, "Unfinished Potion", Skill.HERBLORE, 78, 0, CriticalItem.TORSTOL, ActivitySecondaries.UNFINISHED_POTION),
|
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, "Unfinished potion", Skill.HERBLORE, 78, 0,
|
||||||
SUPER_COMBAT_POTION(ItemID.SUPER_COMBAT_POTION4, "Super combat", Skill.HERBLORE, 90, 150, CriticalItem.TORSTOL, ActivitySecondaries.SUPER_COMBAT_POTION, true),
|
CriticalItem.TORSTOL, Secondaries.UNFINISHED_POTION, new ItemStack(ItemID.TORSTOL_POTION_UNF, 1)),
|
||||||
ANTIVENOM_PLUS(ItemID.ANTIVENOM4_12913, "Anti-venom+", Skill.HERBLORE, 94, 125, CriticalItem.TORSTOL, ActivitySecondaries.ANTIVENOM_PLUS, true),
|
SUPER_COMBAT_POTION(ItemID.SUPER_COMBAT_POTION4, "Super combat", Skill.HERBLORE, 90, 150,
|
||||||
|
CriticalItem.TORSTOL, Secondaries.SUPER_COMBAT_POTION, new ItemStack(ItemID.SUPER_COMBAT_POTION4, 1)),
|
||||||
|
ANTIVENOM_PLUS(ItemID.ANTIVENOM3_12915, "Anti-venom+", Skill.HERBLORE, 94, 125,
|
||||||
|
CriticalItem.TORSTOL, Secondaries.ANTIVENOM_PLUS, new ItemStack(ItemID.ANTIVENOM3_12915, 1)),
|
||||||
|
|
||||||
ZAMORAK_BREW(ItemID.ZAMORAK_BREW4, "Zamorak brew", Skill.HERBLORE, 78, 175, CriticalItem.TORSTOL_POTION_UNF, ActivitySecondaries.ZAMORAK_BREW),
|
ZAMORAK_BREW(ItemID.ZAMORAK_BREW3, "Zamorak brew", Skill.HERBLORE, 78, 175,
|
||||||
|
CriticalItem.TORSTOL_POTION_UNF, Secondaries.ZAMORAK_BREW, new ItemStack(ItemID.ZAMORAK_BREW3, 1)),
|
||||||
|
|
||||||
// Cleaning Grimy Herbs
|
// Cleaning Grimy Herbs
|
||||||
CLEAN_GUAM(ItemID.GUAM_LEAF, "Clean guam", Skill.HERBLORE, 3, 2.5, CriticalItem.GRIMY_GUAM_LEAF),
|
CLEAN_GUAM(ItemID.GUAM_LEAF, "Clean guam", Skill.HERBLORE, 3, 2.5,
|
||||||
CLEAN_MARRENTILL(ItemID.MARRENTILL, "Clean marrentill", Skill.HERBLORE, 5, 3.8, CriticalItem.GRIMY_MARRENTILL),
|
CriticalItem.GRIMY_GUAM_LEAF, null, new ItemStack(ItemID.GUAM_LEAF, 1)),
|
||||||
CLEAN_TARROMIN(ItemID.TARROMIN, "Clean tarromin", Skill.HERBLORE, 11, 5, CriticalItem.GRIMY_TARROMIN),
|
CLEAN_MARRENTILL(ItemID.MARRENTILL, "Clean marrentill", Skill.HERBLORE, 5, 3.8,
|
||||||
CLEAN_HARRALANDER(ItemID.HARRALANDER, "Clean harralander", Skill.HERBLORE, 20, 6.3, CriticalItem.GRIMY_HARRALANDER),
|
CriticalItem.GRIMY_MARRENTILL, null, new ItemStack(ItemID.MARRENTILL, 1)),
|
||||||
CLEAN_RANARR_WEED(ItemID.RANARR_WEED, "Clean ranarr weed", Skill.HERBLORE, 25, 7.5, CriticalItem.GRIMY_RANARR_WEED),
|
CLEAN_TARROMIN(ItemID.TARROMIN, "Clean tarromin", Skill.HERBLORE, 11, 5,
|
||||||
CLEAN_TOADFLAX(ItemID.TOADFLAX, "Clean toadflax", Skill.HERBLORE, 30, 8, CriticalItem.GRIMY_TOADFLAX),
|
CriticalItem.GRIMY_TARROMIN, null, new ItemStack(ItemID.TARROMIN, 1)),
|
||||||
CLEAN_IRIT_LEAF(ItemID.IRIT_LEAF, "Clean irit leaf", Skill.HERBLORE, 40, 8.8, CriticalItem.GRIMY_IRIT_LEAF),
|
CLEAN_HARRALANDER(ItemID.HARRALANDER, "Clean harralander", Skill.HERBLORE, 20, 6.3,
|
||||||
CLEAN_AVANTOE(ItemID.AVANTOE, "Clean avantoe", Skill.HERBLORE, 48, 10, CriticalItem.GRIMY_AVANTOE),
|
CriticalItem.GRIMY_HARRALANDER, null, new ItemStack(ItemID.HARRALANDER, 1)),
|
||||||
CLEAN_KWUARM(ItemID.KWUARM, "Clean kwuarm", Skill.HERBLORE, 54, 11.3, CriticalItem.GRIMY_KWUARM),
|
CLEAN_RANARR_WEED(ItemID.RANARR_WEED, "Clean ranarr weed", Skill.HERBLORE, 25, 7.5,
|
||||||
CLEAN_SNAPDRAGON(ItemID.SNAPDRAGON, "Clean snapdragon", Skill.HERBLORE, 59, 11.8, CriticalItem.GRIMY_SNAPDRAGON),
|
CriticalItem.GRIMY_RANARR_WEED, null, new ItemStack(ItemID.RANARR_WEED, 1)),
|
||||||
CLEAN_CADANTINE(ItemID.CADANTINE, "Clean cadantine", Skill.HERBLORE, 65, 12.5, CriticalItem.GRIMY_CADANTINE),
|
CLEAN_TOADFLAX(ItemID.TOADFLAX, "Clean toadflax", Skill.HERBLORE, 30, 8,
|
||||||
CLEAN_LANTADYME(ItemID.LANTADYME, "Clean lantadyme", Skill.HERBLORE, 67, 13.1, CriticalItem.GRIMY_LANTADYME),
|
CriticalItem.GRIMY_TOADFLAX, null, new ItemStack(ItemID.TOADFLAX, 1)),
|
||||||
CLEAN_DWARF_WEED(ItemID.DWARF_WEED, "Clean dwarf weed", Skill.HERBLORE, 70, 13.8, CriticalItem.GRIMY_DWARF_WEED),
|
CLEAN_IRIT_LEAF(ItemID.IRIT_LEAF, "Clean irit leaf", Skill.HERBLORE, 40, 8.8,
|
||||||
CLEAN_TORSTOL(ItemID.TORSTOL, "Clean torstol", Skill.HERBLORE, 75, 15, CriticalItem.GRIMY_TORSTOL),
|
CriticalItem.GRIMY_IRIT_LEAF, null, new ItemStack(ItemID.IRIT_LEAF, 1)),
|
||||||
|
CLEAN_AVANTOE(ItemID.AVANTOE, "Clean avantoe", Skill.HERBLORE, 48, 10,
|
||||||
|
CriticalItem.GRIMY_AVANTOE, null, new ItemStack(ItemID.AVANTOE, 1)),
|
||||||
|
CLEAN_KWUARM(ItemID.KWUARM, "Clean kwuarm", Skill.HERBLORE, 54, 11.3,
|
||||||
|
CriticalItem.GRIMY_KWUARM, null, new ItemStack(ItemID.KWUARM, 1)),
|
||||||
|
CLEAN_SNAPDRAGON(ItemID.SNAPDRAGON, "Clean snapdragon", Skill.HERBLORE, 59, 11.8,
|
||||||
|
CriticalItem.GRIMY_SNAPDRAGON, null, new ItemStack(ItemID.SNAPDRAGON, 1)),
|
||||||
|
CLEAN_CADANTINE(ItemID.CADANTINE, "Clean cadantine", Skill.HERBLORE, 65, 12.5,
|
||||||
|
CriticalItem.GRIMY_CADANTINE, null, new ItemStack(ItemID.CADANTINE, 1)),
|
||||||
|
CLEAN_LANTADYME(ItemID.LANTADYME, "Clean lantadyme", Skill.HERBLORE, 67, 13.1,
|
||||||
|
CriticalItem.GRIMY_LANTADYME, null, new ItemStack(ItemID.LANTADYME, 1)),
|
||||||
|
CLEAN_DWARF_WEED(ItemID.DWARF_WEED, "Clean dwarf weed", Skill.HERBLORE, 70, 13.8,
|
||||||
|
CriticalItem.GRIMY_DWARF_WEED, null, new ItemStack(ItemID.DWARF_WEED, 1)),
|
||||||
|
CLEAN_TORSTOL(ItemID.TORSTOL, "Clean torstol", Skill.HERBLORE, 75, 15,
|
||||||
|
CriticalItem.GRIMY_TORSTOL, null, new ItemStack(ItemID.TORSTOL, 1)),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construction Options
|
* Construction Options
|
||||||
*/
|
*/
|
||||||
PLANKS(ItemID.PLANK, "Normal Plank Products", Skill.CONSTRUCTION, 1, 29, CriticalItem.PLANK),
|
PLANK(ItemID.PLANK, "Regular Plank", Skill.CONSTRUCTION, 1, 0,
|
||||||
OAK_PLANKS(ItemID.OAK_PLANK, "Normal Oak Products", Skill.CONSTRUCTION, 1, 60, CriticalItem.OAK_PLANK),
|
CriticalItem.LOGS, Secondaries.COINS_100, new ItemStack(ItemID.PLANK, 1)),
|
||||||
TEAK_PLANKS(ItemID.TEAK_PLANK, "Normal Teak Products", Skill.CONSTRUCTION, 1, 90, CriticalItem.TEAK_PLANK),
|
PLANKS(ItemID.PLANK, "Regular plank products", Skill.CONSTRUCTION, 1, 29,
|
||||||
MYTHICAL_CAPE(ItemID.MYTHICAL_CAPE, "Mythical Cape Rakes", Skill.CONSTRUCTION, 1, 123.33, CriticalItem.TEAK_PLANK),
|
CriticalItem.PLANK, null, null),
|
||||||
MAHOGANY_PLANKS(ItemID.MAHOGANY_PLANK, "Normal Mahogany Products", Skill.CONSTRUCTION, 1, 140, CriticalItem.MAHOGANY_PLANK),
|
|
||||||
|
OAK_PLANK(ItemID.OAK_PLANK, "Oak Plank", Skill.CONSTRUCTION, 1, 0,
|
||||||
|
CriticalItem.OAK_LOGS, Secondaries.COINS_250, new ItemStack(ItemID.OAK_PLANK, 1)),
|
||||||
|
OAK_PLANKS(ItemID.OAK_PLANK, "Oak products", Skill.CONSTRUCTION, 1, 60,
|
||||||
|
CriticalItem.OAK_PLANK, null, null),
|
||||||
|
|
||||||
|
TEAK_PLANK(ItemID.TEAK_PLANK, "Teak Plank", Skill.CONSTRUCTION, 1, 0,
|
||||||
|
CriticalItem.TEAK_LOGS, Secondaries.COINS_500, new ItemStack(ItemID.TEAK_PLANK, 1)),
|
||||||
|
TEAK_PLANKS(ItemID.TEAK_PLANK, "Teak products", Skill.CONSTRUCTION, 1, 90,
|
||||||
|
CriticalItem.TEAK_PLANK, null, null),
|
||||||
|
MYTHICAL_CAPE(ItemID.MYTHICAL_CAPE, "Mythical cape rakes", Skill.CONSTRUCTION, 1, 123.33,
|
||||||
|
CriticalItem.TEAK_PLANK, null, null),
|
||||||
|
|
||||||
|
|
||||||
|
MAHOGANY_PLANK(ItemID.MAHOGANY_PLANK, "Mahogany Plank", Skill.CONSTRUCTION, 1, 0,
|
||||||
|
CriticalItem.MAHOGANY_LOGS, Secondaries.COINS_1500, new ItemStack(ItemID.MAHOGANY_PLANK, 1)),
|
||||||
|
MAHOGANY_PLANKS(ItemID.MAHOGANY_PLANK, "Mahogany products", Skill.CONSTRUCTION, 1, 140,
|
||||||
|
CriticalItem.MAHOGANY_PLANK, null, null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prayer Options
|
* Prayer Options
|
||||||
*/
|
*/
|
||||||
BONES(ItemID.BONES, "Bones", Skill.PRAYER, 1, 4.5, CriticalItem.BONES),
|
BONES(ItemID.BONES, "Bones", Skill.PRAYER, 1, 4.5,
|
||||||
WOLF_BONES(ItemID.WOLF_BONES, "Bones", Skill.PRAYER, 1, 4.5, CriticalItem.WOLF_BONES),
|
CriticalItem.BONES, null, null),
|
||||||
BURNT_BONES(ItemID.BURNT_BONES, "Bones", Skill.PRAYER, 1, 4.5, CriticalItem.BURNT_BONES),
|
WOLF_BONES(ItemID.WOLF_BONES, "Wolf bones", Skill.PRAYER, 1, 4.5,
|
||||||
MONKEY_BONES(ItemID.MONKEY_BONES, "Bones", Skill.PRAYER, 1, 5.0, CriticalItem.MONKEY_BONES),
|
CriticalItem.WOLF_BONES, null, null),
|
||||||
BAT_BONES(ItemID.BAT_BONES, "Bones", Skill.PRAYER, 1, 5.3, CriticalItem.BAT_BONES),
|
BURNT_BONES(ItemID.BURNT_BONES, "Burnt bones", Skill.PRAYER, 1, 4.5,
|
||||||
JOGRE_BONES(ItemID.JOGRE_BONES, "Bones", Skill.PRAYER, 1, 15.0, CriticalItem.JOGRE_BONES),
|
CriticalItem.BURNT_BONES, null, null),
|
||||||
BIG_BONES(ItemID.BIG_BONES, "Bones", Skill.PRAYER, 1, 15.0, CriticalItem.BIG_BONES),
|
MONKEY_BONES(ItemID.MONKEY_BONES, "Monkey bones", Skill.PRAYER, 1, 5.0,
|
||||||
ZOGRE_BONES(ItemID.ZOGRE_BONES, "Bones", Skill.PRAYER, 1, 22.5, CriticalItem.ZOGRE_BONES),
|
CriticalItem.MONKEY_BONES, null, null),
|
||||||
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, "Bones", Skill.PRAYER, 1, 25.0, CriticalItem.SHAIKAHAN_BONES),
|
BAT_BONES(ItemID.BAT_BONES, "Bat bones", Skill.PRAYER, 1, 5.3,
|
||||||
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Bones", Skill.PRAYER, 1, 30.0, CriticalItem.BABYDRAGON_BONES),
|
CriticalItem.BAT_BONES, null, null),
|
||||||
WYVERN_BONES(ItemID.WYVERN_BONES, "Bones", Skill.PRAYER, 1, 72.0, CriticalItem.WYVERN_BONES),
|
JOGRE_BONES(ItemID.JOGRE_BONES, "Jogre bones", Skill.PRAYER, 1, 15.0,
|
||||||
DRAGON_BONES(ItemID.DRAGON_BONES, "Bones", Skill.PRAYER, 1, 72.0, CriticalItem.DRAGON_BONES),
|
CriticalItem.JOGRE_BONES, null, null),
|
||||||
FAYRG_BONES(ItemID.FAYRG_BONES, "Bones", Skill.PRAYER, 1, 84.0, CriticalItem.FAYRG_BONES),
|
BIG_BONES(ItemID.BIG_BONES, "Big bones", Skill.PRAYER, 1, 15.0,
|
||||||
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Bones", Skill.PRAYER, 1, 85.0, CriticalItem.LAVA_DRAGON_BONES),
|
CriticalItem.BIG_BONES, null, null),
|
||||||
RAURG_BONES(ItemID.RAURG_BONES, "Bones", Skill.PRAYER, 1, 96.0, CriticalItem.RAURG_BONES),
|
ZOGRE_BONES(ItemID.ZOGRE_BONES, "Zogre bones", Skill.PRAYER, 1, 22.5,
|
||||||
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Bones", Skill.PRAYER, 1, 125.0, CriticalItem.DAGANNOTH_BONES),
|
CriticalItem.ZOGRE_BONES, null, null),
|
||||||
OURG_BONES(ItemID.OURG_BONES, "Bones", Skill.PRAYER, 1, 140.0, CriticalItem.OURG_BONES),
|
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, "Shaikahan bones", Skill.PRAYER, 1, 25.0,
|
||||||
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, "Bones", Skill.PRAYER, 1, 150.0, CriticalItem.SUPERIOR_DRAGON_BONES),
|
CriticalItem.SHAIKAHAN_BONES, null, null),
|
||||||
|
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, "Babydragon bones", Skill.PRAYER, 1, 30.0,
|
||||||
|
CriticalItem.BABYDRAGON_BONES, null, null),
|
||||||
|
WYVERN_BONES(ItemID.WYVERN_BONES, "Wyvern bones", Skill.PRAYER, 1, 72.0,
|
||||||
|
CriticalItem.WYVERN_BONES, null, null),
|
||||||
|
DRAGON_BONES(ItemID.DRAGON_BONES, "Dragon bones", Skill.PRAYER, 1, 72.0,
|
||||||
|
CriticalItem.DRAGON_BONES, null, null),
|
||||||
|
FAYRG_BONES(ItemID.FAYRG_BONES, "Fayrg bones", Skill.PRAYER, 1, 84.0,
|
||||||
|
CriticalItem.FAYRG_BONES, null, null),
|
||||||
|
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, "Lava dragon bones", Skill.PRAYER, 1, 85.0,
|
||||||
|
CriticalItem.LAVA_DRAGON_BONES, null, null),
|
||||||
|
RAURG_BONES(ItemID.RAURG_BONES, "Raurg bones", Skill.PRAYER, 1, 96.0,
|
||||||
|
CriticalItem.RAURG_BONES, null, null),
|
||||||
|
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, "Dagannoth bones", Skill.PRAYER, 1, 125.0,
|
||||||
|
CriticalItem.DAGANNOTH_BONES, null, null),
|
||||||
|
OURG_BONES(ItemID.OURG_BONES, "Ourg bones", Skill.PRAYER, 1, 140.0,
|
||||||
|
CriticalItem.OURG_BONES, null, null),
|
||||||
|
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, "Superior dragon bones", Skill.PRAYER, 1, 150.0,
|
||||||
|
CriticalItem.SUPERIOR_DRAGON_BONES, null, null),
|
||||||
// Shade Remains (Pyre Logs)
|
// Shade Remains (Pyre Logs)
|
||||||
LOAR_REMAINS(ItemID.LOAR_REMAINS, "Shades", Skill.PRAYER, 1, 33.0, CriticalItem.LOAR_REMAINS),
|
LOAR_REMAINS(ItemID.LOAR_REMAINS, "Loar remains", Skill.PRAYER, 1, 33.0,
|
||||||
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, "Shades", Skill.PRAYER, 1, 46.5, CriticalItem.PHRIN_REMAINS),
|
CriticalItem.LOAR_REMAINS, null, null),
|
||||||
RIYL_REMAINS(ItemID.RIYL_REMAINS, "Shades", Skill.PRAYER, 1, 59.5, CriticalItem.RIYL_REMAINS),
|
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, "Phrin remains", Skill.PRAYER, 1, 46.5,
|
||||||
ASYN_REMAINS(ItemID.ASYN_REMAINS, "Shades", Skill.PRAYER, 1, 82.5, CriticalItem.ASYN_REMAINS),
|
CriticalItem.PHRIN_REMAINS, null, null),
|
||||||
FIYR_REMAINS(ItemID.FIYR_REMAINS, "Shades", Skill.PRAYER, 1, 84.0, CriticalItem.FIYR_REMAINS),
|
RIYL_REMAINS(ItemID.RIYL_REMAINS, "Riyl remains", Skill.PRAYER, 1, 59.5,
|
||||||
|
CriticalItem.RIYL_REMAINS, null, null),
|
||||||
|
ASYN_REMAINS(ItemID.ASYN_REMAINS, "Asyn remains", Skill.PRAYER, 1, 82.5,
|
||||||
|
CriticalItem.ASYN_REMAINS, null, null),
|
||||||
|
FIYR_REMAINS(ItemID.FIYR_REMAINS, "Fiyre remains", Skill.PRAYER, 1, 84.0,
|
||||||
|
CriticalItem.FIYR_REMAINS, null, null),
|
||||||
// Ensouled Heads
|
// Ensouled Heads
|
||||||
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, "Ensouled Heads", Skill.PRAYER, 1, 130.0, CriticalItem.ENSOULED_GOBLIN_HEAD),
|
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, "Ensouled goblin head", Skill.PRAYER, 1, 130.0,
|
||||||
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, "Ensouled Heads", Skill.PRAYER, 1, 182.0, CriticalItem.ENSOULED_MONKEY_HEAD),
|
CriticalItem.ENSOULED_GOBLIN_HEAD, null, null),
|
||||||
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, "Ensouled Heads", Skill.PRAYER, 1, 286.0, CriticalItem.ENSOULED_IMP_HEAD),
|
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, "Ensouled monkey head", Skill.PRAYER, 1, 182.0,
|
||||||
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, "Ensouled Heads", Skill.PRAYER, 1, 364.0, CriticalItem.ENSOULED_MINOTAUR_HEAD),
|
CriticalItem.ENSOULED_MONKEY_HEAD, null, null),
|
||||||
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, "Ensouled Heads", Skill.PRAYER, 1, 454.0, CriticalItem.ENSOULED_SCORPION_HEAD),
|
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, "Ensouled imp head", Skill.PRAYER, 1, 286.0,
|
||||||
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, "Ensouled Heads", Skill.PRAYER, 1, 480.0, CriticalItem.ENSOULED_BEAR_HEAD),
|
CriticalItem.ENSOULED_IMP_HEAD, null, null),
|
||||||
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, "Ensouled Heads", Skill.PRAYER, 1, 494.0, CriticalItem.ENSOULED_UNICORN_HEAD),
|
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, "Ensouled minotaur head", Skill.PRAYER, 1, 364.0,
|
||||||
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, "Ensouled Heads", Skill.PRAYER, 1, 520.0, CriticalItem.ENSOULED_DOG_HEAD),
|
CriticalItem.ENSOULED_MINOTAUR_HEAD, null, null),
|
||||||
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, "Ensouled Heads", Skill.PRAYER, 1, 584.0, CriticalItem.ENSOULED_CHAOS_DRUID_HEAD),
|
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, "Ensouled scorpion head", Skill.PRAYER, 1, 454.0,
|
||||||
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, "Ensouled Heads", Skill.PRAYER, 1, 650.0, CriticalItem.ENSOULED_GIANT_HEAD),
|
CriticalItem.ENSOULED_SCORPION_HEAD, null, null),
|
||||||
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, "Ensouled Heads", Skill.PRAYER, 1, 716.0, CriticalItem.ENSOULED_OGRE_HEAD),
|
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, "Ensouled bear head", Skill.PRAYER, 1, 480.0,
|
||||||
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, "Ensouled Heads", Skill.PRAYER, 1, 754.0, CriticalItem.ENSOULED_ELF_HEAD),
|
CriticalItem.ENSOULED_BEAR_HEAD, null, null),
|
||||||
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, "Ensouled Heads", Skill.PRAYER, 1, 780.0, CriticalItem.ENSOULED_TROLL_HEAD),
|
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, "Ensouled unicorn head", Skill.PRAYER, 1, 494.0,
|
||||||
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, "Ensouled Heads", Skill.PRAYER, 1, 832.0, CriticalItem.ENSOULED_HORROR_HEAD),
|
CriticalItem.ENSOULED_UNICORN_HEAD, null, null),
|
||||||
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, "Ensouled Heads", Skill.PRAYER, 1, 884.0, CriticalItem.ENSOULED_KALPHITE_HEAD),
|
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, "Ensouled dog head", Skill.PRAYER, 1, 520.0,
|
||||||
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, "Ensouled Heads", Skill.PRAYER, 1, 936.0, CriticalItem.ENSOULED_DAGANNOTH_HEAD),
|
CriticalItem.ENSOULED_DOG_HEAD, null, null),
|
||||||
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, "Ensouled Heads", Skill.PRAYER, 1, 1040.0, CriticalItem.ENSOULED_BLOODVELD_HEAD),
|
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, "Ensouled druid head", Skill.PRAYER, 1, 584.0,
|
||||||
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, "Ensouled Heads", Skill.PRAYER, 1, 1104.0, CriticalItem.ENSOULED_TZHAAR_HEAD),
|
CriticalItem.ENSOULED_CHAOS_DRUID_HEAD, null, null),
|
||||||
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, "Ensouled Heads", Skill.PRAYER, 1, 1170.0, CriticalItem.ENSOULED_DEMON_HEAD),
|
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, "Ensouled giant head", Skill.PRAYER, 1, 650.0,
|
||||||
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, "Ensouled Heads", Skill.PRAYER, 1, 1234.0, CriticalItem.ENSOULED_AVIANSIE_HEAD),
|
CriticalItem.ENSOULED_GIANT_HEAD, null, null),
|
||||||
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, "Ensouled Heads", Skill.PRAYER, 1, 1300.0, CriticalItem.ENSOULED_ABYSSAL_HEAD),
|
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, "Ensouled ogre head", Skill.PRAYER, 1, 716.0,
|
||||||
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, "Ensouled Heads", Skill.PRAYER, 1, 1560.0, CriticalItem.ENSOULED_DRAGON_HEAD),
|
CriticalItem.ENSOULED_OGRE_HEAD, null, null),
|
||||||
|
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, "Ensouled elf head", Skill.PRAYER, 1, 754.0,
|
||||||
|
CriticalItem.ENSOULED_ELF_HEAD, null, null),
|
||||||
|
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, "Ensouled troll head", Skill.PRAYER, 1, 780.0,
|
||||||
|
CriticalItem.ENSOULED_TROLL_HEAD, null, null),
|
||||||
|
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, "Ensouled horror head", Skill.PRAYER, 1, 832.0,
|
||||||
|
CriticalItem.ENSOULED_HORROR_HEAD, null, null),
|
||||||
|
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, "Ensouled kalphite head", Skill.PRAYER, 1, 884.0,
|
||||||
|
CriticalItem.ENSOULED_KALPHITE_HEAD, null, null),
|
||||||
|
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, "Ensouled dagannoth head", Skill.PRAYER, 1, 936.0,
|
||||||
|
CriticalItem.ENSOULED_DAGANNOTH_HEAD, null, null),
|
||||||
|
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, "Ensouled bloodveld head", Skill.PRAYER, 1, 1040.0,
|
||||||
|
CriticalItem.ENSOULED_BLOODVELD_HEAD, null, null),
|
||||||
|
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, "Ensouled tzhaar head", Skill.PRAYER, 1, 1104.0,
|
||||||
|
CriticalItem.ENSOULED_TZHAAR_HEAD, null, null),
|
||||||
|
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, "Ensouled demon head", Skill.PRAYER, 1, 1170.0,
|
||||||
|
CriticalItem.ENSOULED_DEMON_HEAD, null, null),
|
||||||
|
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, "Ensouled aviansie head", Skill.PRAYER, 1, 1234.0,
|
||||||
|
CriticalItem.ENSOULED_AVIANSIE_HEAD, null, null),
|
||||||
|
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, "Ensouled abyssal head", Skill.PRAYER, 1, 1300.0,
|
||||||
|
CriticalItem.ENSOULED_ABYSSAL_HEAD, null, null),
|
||||||
|
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, "Ensouled dragon head", Skill.PRAYER, 1, 1560.0,
|
||||||
|
CriticalItem.ENSOULED_DRAGON_HEAD, null, null),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cooking Items
|
* Cooking Items
|
||||||
*/
|
*/
|
||||||
RAW_HERRING(ItemID.RAW_HERRING, "Fish", Skill.COOKING, 5, 50.0, CriticalItem.RAW_HERRING),
|
COOK_HERRING(ItemID.HERRING, "Herring", Skill.COOKING, 5, 50.0,
|
||||||
RAW_MACKEREL(ItemID.RAW_MACKEREL, "Fish", Skill.COOKING, 10, 60.0, CriticalItem.RAW_MACKEREL),
|
CriticalItem.RAW_HERRING, null, new ItemStack(ItemID.HERRING, 1)),
|
||||||
RAW_TROUT(ItemID.RAW_TROUT, "Fish", Skill.COOKING, 15, 70.0, CriticalItem.RAW_TROUT),
|
COOK_MACKEREL(ItemID.MACKEREL, "Mackerel", Skill.COOKING, 10, 60.0,
|
||||||
RAW_COD(ItemID.RAW_COD, "Fish", Skill.COOKING, 18, 75.0, CriticalItem.RAW_COD),
|
CriticalItem.RAW_MACKEREL, null, new ItemStack(ItemID.MACKEREL, 1)),
|
||||||
RAW_PIKE(ItemID.RAW_PIKE, "Fish", Skill.COOKING, 20, 80.0, CriticalItem.RAW_PIKE),
|
COOK_TROUT(ItemID.TROUT, "Trout", Skill.COOKING, 15, 70.0,
|
||||||
RAW_SALMON(ItemID.RAW_SALMON, "Fish", Skill.COOKING, 25, 90.0, CriticalItem.RAW_SALMON),
|
CriticalItem.RAW_TROUT, null, new ItemStack(ItemID.TROUT, 1)),
|
||||||
RAW_TUNA(ItemID.RAW_TUNA, "Fish", Skill.COOKING, 30, 100.0, CriticalItem.RAW_TUNA),
|
COOK_COD(ItemID.COD, "Cod", Skill.COOKING, 18, 75.0,
|
||||||
RAW_KARAMBWAN(ItemID.RAW_KARAMBWAN, "Fish", Skill.COOKING, 30, 190.0, CriticalItem.RAW_KARAMBWAN),
|
CriticalItem.RAW_COD, null, new ItemStack(ItemID.COD, 1)),
|
||||||
RAW_LOBSTER(ItemID.RAW_LOBSTER, "Fish", Skill.COOKING, 40, 120.0, CriticalItem.RAW_LOBSTER),
|
COOK_PIKE(ItemID.PIKE, "Pike", Skill.COOKING, 20, 80.0,
|
||||||
RAW_BASS(ItemID.RAW_BASS, "Fish", Skill.COOKING, 43, 130.0, CriticalItem.RAW_BASS),
|
CriticalItem.RAW_PIKE, null, new ItemStack(ItemID.PIKE, 1)),
|
||||||
RAW_SWORDFISH(ItemID.RAW_SWORDFISH, "Fish", Skill.COOKING, 45, 140.0, CriticalItem.RAW_SWORDFISH),
|
COOK_SALMON(ItemID.SALMON, "Salmon", Skill.COOKING, 25, 90.0,
|
||||||
RAW_MONKFISH(ItemID.RAW_MONKFISH, "Fish", Skill.COOKING, 62, 150.0, CriticalItem.RAW_MONKFISH),
|
CriticalItem.RAW_SALMON, null, new ItemStack(ItemID.SALMON, 1)),
|
||||||
RAW_SHARK(ItemID.RAW_SHARK, "Fish", Skill.COOKING, 80, 210.0, CriticalItem.RAW_SHARK),
|
COOK_TUNA(ItemID.TUNA, "Tuna", Skill.COOKING, 30, 100.0,
|
||||||
RAW_SEA_TURTLE(ItemID.RAW_SEA_TURTLE, "Fish", Skill.COOKING, 82, 211.3, CriticalItem.RAW_SEA_TURTLE),
|
CriticalItem.RAW_TUNA, null, new ItemStack(ItemID.TUNA, 1)),
|
||||||
RAW_ANGLERFISH(ItemID.RAW_ANGLERFISH, "Fish", Skill.COOKING, 84, 230.0, CriticalItem.RAW_ANGLERFISH),
|
COOK_KARAMBWAN(ItemID.COOKED_KARAMBWAN, "Cooked Karambwan", Skill.COOKING, 30, 190.0,
|
||||||
RAW_DARK_CRAB(ItemID.RAW_DARK_CRAB, "Fish", Skill.COOKING, 90, 215.0, CriticalItem.RAW_DARK_CRAB),
|
CriticalItem.RAW_KARAMBWAN, null, new ItemStack(ItemID.COOKED_KARAMBWAN, 1)),
|
||||||
RAW_MANTA_RAY(ItemID.RAW_MANTA_RAY, "Fish", Skill.COOKING, 91, 216.2, CriticalItem.RAW_MANTA_RAY),
|
COOK_LOBSTER(ItemID.LOBSTER, "Lobster", Skill.COOKING, 40, 120.0,
|
||||||
|
CriticalItem.RAW_LOBSTER, null, new ItemStack(ItemID.LOBSTER, 1)),
|
||||||
|
COOK_BASS(ItemID.BASS, "Bass", Skill.COOKING, 43, 130.0,
|
||||||
|
CriticalItem.RAW_BASS, null, new ItemStack(ItemID.BASS, 1)),
|
||||||
|
COOK_SWORDFISH(ItemID.SWORDFISH, "Swordfish", Skill.COOKING, 45, 140.0,
|
||||||
|
CriticalItem.RAW_SWORDFISH, null, new ItemStack(ItemID.SWORDFISH, 1)),
|
||||||
|
COOK_MONKFISH(ItemID.MONKFISH, "Monkfish", Skill.COOKING, 62, 150.0,
|
||||||
|
CriticalItem.RAW_MONKFISH, null, new ItemStack(ItemID.MONKFISH, 1)),
|
||||||
|
COOK_SHARK(ItemID.SHARK, "Shark", Skill.COOKING, 80, 210.0,
|
||||||
|
CriticalItem.RAW_SHARK, null, new ItemStack(ItemID.SHARK, 1)),
|
||||||
|
COOK_SEA_TURTLE(ItemID.SEA_TURTLE, "Sea turtle", Skill.COOKING, 82, 211.3,
|
||||||
|
CriticalItem.RAW_SEA_TURTLE, null, new ItemStack(ItemID.SEA_TURTLE, 1)),
|
||||||
|
COOK_ANGLERFISH(ItemID.ANGLERFISH, "Anglerfish", Skill.COOKING, 84, 230.0,
|
||||||
|
CriticalItem.RAW_ANGLERFISH, null, new ItemStack(ItemID.ANGLERFISH, 1)),
|
||||||
|
COOK_DARK_CRAB(ItemID.DARK_CRAB, "Dark crab", Skill.COOKING, 90, 215.0,
|
||||||
|
CriticalItem.RAW_DARK_CRAB, null, new ItemStack(ItemID.DARK_CRAB, 1)),
|
||||||
|
COOK_MANTA_RAY(ItemID.MANTA_RAY, "Manta ray", Skill.COOKING, 91, 216.2,
|
||||||
|
CriticalItem.RAW_MANTA_RAY, null, new ItemStack(ItemID.MANTA_RAY, 1)),
|
||||||
|
|
||||||
WINE(ItemID.JUG_OF_WINE, "Other", Skill.COOKING, 35, 200, CriticalItem.GRAPES, ActivitySecondaries.JUG_OF_WATER),
|
WINE(ItemID.JUG_OF_WINE, "Jug of wine", Skill.COOKING, 35, 200,
|
||||||
|
CriticalItem.GRAPES, Secondaries.JUG_OF_WATER, new ItemStack(ItemID.JUG_OF_WINE, 1)),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Crafting Items
|
* Crafting Items
|
||||||
*/
|
*/
|
||||||
// Spinning
|
// Spinning
|
||||||
BALL_OF_WOOL(ItemID.WOOL, "Misc", Skill.CRAFTING, 1, 2.5, CriticalItem.WOOL),
|
BALL_OF_WOOL(ItemID.BALL_OF_WOOL, "Ball of wool", Skill.CRAFTING, 1, 2.5,
|
||||||
BOW_STRING(ItemID.BOW_STRING, "Misc", Skill.CRAFTING, 1, 15, CriticalItem.FLAX),
|
CriticalItem.WOOL, null, new ItemStack(ItemID.BALL_OF_WOOL, 1)),
|
||||||
|
BOW_STRING(ItemID.BOW_STRING, "Bow string", Skill.CRAFTING, 1, 15,
|
||||||
|
CriticalItem.FLAX, null, new ItemStack(ItemID.BOW_STRING, 1)),
|
||||||
// Glass Blowing
|
// Glass Blowing
|
||||||
BEER_GLASS(ItemID.BEER_GLASS, "Beer Glass", Skill.CRAFTING, 1, 17.5, CriticalItem.MOLTEN_GLASS),
|
BEER_GLASS(ItemID.BEER_GLASS, "Beer glass", Skill.CRAFTING, 1, 17.5,
|
||||||
CANDLE_LANTERN(ItemID.CANDLE_LANTERN, "Candle Lantern", Skill.CRAFTING, 4, 19, CriticalItem.MOLTEN_GLASS),
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.BEER_GLASS, 1)),
|
||||||
OIL_LAMP(ItemID.OIL_LAMP, "Oil Lamp", Skill.CRAFTING, 12, 25, CriticalItem.MOLTEN_GLASS),
|
CANDLE_LANTERN(ItemID.CANDLE_LANTERN, "Candle lantern", Skill.CRAFTING, 4, 19,
|
||||||
VIAL(ItemID.VIAL, "Vial", Skill.CRAFTING, 33, 35, CriticalItem.MOLTEN_GLASS),
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.CANDLE_LANTERN, 1)),
|
||||||
EMPTY_FISHBOWL(ItemID.EMPTY_FISHBOWL, "Empty fishbowl", Skill.CRAFTING, 42, 42.5, CriticalItem.MOLTEN_GLASS),
|
OIL_LAMP(ItemID.OIL_LAMP, "Oil lamp", Skill.CRAFTING, 12, 25,
|
||||||
UNPOWERED_ORB(ItemID.UNPOWERED_ORB, "Unpowered orb", Skill.CRAFTING, 46, 52.5, CriticalItem.MOLTEN_GLASS),
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.OIL_LAMP, 1)),
|
||||||
LANTERN_LENS(ItemID.LANTERN_LENS, "Lantern lens", Skill.CRAFTING, 49, 55, CriticalItem.MOLTEN_GLASS),
|
VIAL(ItemID.VIAL, "Vial", Skill.CRAFTING, 33, 35,
|
||||||
LIGHT_ORB(ItemID.LIGHT_ORB, "Light orb", Skill.CRAFTING, 87, 70, CriticalItem.MOLTEN_GLASS),
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.VIAL, 1)),
|
||||||
|
EMPTY_FISHBOWL(ItemID.EMPTY_FISHBOWL, "Empty fishbowl", Skill.CRAFTING, 42, 42.5,
|
||||||
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.EMPTY_FISHBOWL, 1)),
|
||||||
|
UNPOWERED_ORB(ItemID.UNPOWERED_ORB, "Unpowered orb", Skill.CRAFTING, 46, 52.5,
|
||||||
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.UNPOWERED_ORB, 1)),
|
||||||
|
LANTERN_LENS(ItemID.LANTERN_LENS, "Lantern lens", Skill.CRAFTING, 49, 55,
|
||||||
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.LANTERN_LENS, 1)),
|
||||||
|
LIGHT_ORB(ItemID.LIGHT_ORB, "Light orb", Skill.CRAFTING, 87, 70,
|
||||||
|
CriticalItem.MOLTEN_GLASS, null, new ItemStack(ItemID.LIGHT_ORB, 1)),
|
||||||
|
|
||||||
// D'hide/Dragon Leather
|
// D'hide/Dragon Leather
|
||||||
GREEN_DRAGON_LEATHER(ItemID.GREEN_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 57, 62.0, CriticalItem.GREEN_DRAGON_LEATHER),
|
GREEN_DRAGONHIDE(ItemID.GREEN_DRAGON_LEATHER, "Tan Green D'hide", Skill.CRAFTING, 57, 0,
|
||||||
BLUE_DRAGON_LEATHER(ItemID.BLUE_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 66, 70.0, CriticalItem.BLUE_DRAGON_LEATHER),
|
CriticalItem.GREEN_DRAGONHIDE, null, new ItemStack(ItemID.GREEN_DRAGON_LEATHER, 1)),
|
||||||
RED_DRAGON_LEATHER(ItemID.RED_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 73, 78.0, CriticalItem.RED_DRAGON_LEATHER),
|
BLUE_DRAGONHIDE(ItemID.BLUE_DRAGON_LEATHER, "Tan Blue D'hide", Skill.CRAFTING, 66, 0,
|
||||||
BLACK_DRAGON_LEATHER(ItemID.BLACK_DRAGON_LEATHER, "D'hide", Skill.CRAFTING, 79, 86.0, CriticalItem.BLACK_DRAGON_LEATHER),
|
CriticalItem.BLUE_DRAGONHIDE, null, new ItemStack(ItemID.BLUE_DRAGON_LEATHER, 1)),
|
||||||
|
RED_DRAGONHIDE(ItemID.RED_DRAGON_LEATHER, "Tan Red D'hide", Skill.CRAFTING, 73, 0,
|
||||||
|
CriticalItem.RED_DRAGONHIDE, null, new ItemStack(ItemID.RED_DRAGON_LEATHER, 1)),
|
||||||
|
BLACK_DRAGONHIDE(ItemID.BLACK_DRAGON_LEATHER, "Tan Black D'hide", Skill.CRAFTING, 79, 0,
|
||||||
|
CriticalItem.BLACK_DRAGONHIDE, null, new ItemStack(ItemID.BLACK_DRAGON_LEATHER, 1)),
|
||||||
|
|
||||||
|
GREEN_DRAGON_LEATHER(ItemID.GREEN_DHIDE_VAMB, "Green D'hide product", Skill.CRAFTING, 57, 62.0,
|
||||||
|
CriticalItem.GREEN_DRAGON_LEATHER, null, null),
|
||||||
|
BLUE_DRAGON_LEATHER(ItemID.BLUE_DHIDE_VAMB, "Blue D'hide product", Skill.CRAFTING, 66, 70.0,
|
||||||
|
CriticalItem.BLUE_DRAGON_LEATHER, null, null),
|
||||||
|
RED_DRAGON_LEATHER(ItemID.RED_DHIDE_VAMB, "Red D'hide product", Skill.CRAFTING, 73, 78.0,
|
||||||
|
CriticalItem.RED_DRAGON_LEATHER, null, null),
|
||||||
|
BLACK_DRAGON_LEATHER(ItemID.BLACK_DHIDE_VAMB, "Black D'hide product", Skill.CRAFTING, 79, 86.0,
|
||||||
|
CriticalItem.BLACK_DRAGON_LEATHER, null, null),
|
||||||
|
|
||||||
// Uncut Gems
|
// Uncut Gems
|
||||||
UNCUT_OPAL(ItemID.UNCUT_OPAL, "Gems", Skill.CRAFTING, 1, 15.0, CriticalItem.UNCUT_OPAL),
|
UNCUT_OPAL(ItemID.OPAL, "Cut opal", Skill.CRAFTING, 1, 15.0,
|
||||||
UNCUT_JADE(ItemID.UNCUT_JADE, "Gems", Skill.CRAFTING, 13, 20.0, CriticalItem.UNCUT_JADE),
|
CriticalItem.UNCUT_OPAL, null, new ItemStack(ItemID.OPAL, 1)),
|
||||||
UNCUT_RED_TOPAZ(ItemID.UNCUT_RED_TOPAZ, "Gems", Skill.CRAFTING, 16, 25.0, CriticalItem.UNCUT_RED_TOPAZ),
|
UNCUT_JADE(ItemID.JADE, "Cut jade", Skill.CRAFTING, 13, 20.0,
|
||||||
UNCUT_SAPPHIRE(ItemID.UNCUT_SAPPHIRE, "Gems", Skill.CRAFTING, 20, 50.0, CriticalItem.UNCUT_SAPPHIRE),
|
CriticalItem.UNCUT_JADE, null, new ItemStack(ItemID.JADE, 1)),
|
||||||
UNCUT_EMERALD(ItemID.UNCUT_EMERALD, "Gems", Skill.CRAFTING, 27, 67.5, CriticalItem.UNCUT_EMERALD),
|
UNCUT_RED_TOPAZ(ItemID.RED_TOPAZ, "Cut red topaz", Skill.CRAFTING, 16, 25.0,
|
||||||
UNCUT_RUBY(ItemID.UNCUT_RUBY, "Gems", Skill.CRAFTING, 34, 85, CriticalItem.UNCUT_RUBY),
|
CriticalItem.UNCUT_RED_TOPAZ, null, new ItemStack(ItemID.RED_TOPAZ, 1)),
|
||||||
UNCUT_DIAMOND(ItemID.UNCUT_DIAMOND, "Gems", Skill.CRAFTING, 43, 107.5, CriticalItem.UNCUT_DIAMOND),
|
UNCUT_SAPPHIRE(ItemID.SAPPHIRE, "Cut sapphire", Skill.CRAFTING, 20, 50.0,
|
||||||
UNCUT_DRAGONSTONE(ItemID.UNCUT_DRAGONSTONE, "Gems", Skill.CRAFTING, 55, 137.5, CriticalItem.UNCUT_DRAGONSTONE),
|
CriticalItem.UNCUT_SAPPHIRE, null, new ItemStack(ItemID.SAPPHIRE, 1)),
|
||||||
UNCUT_ONYX(ItemID.UNCUT_ONYX, "Gems", Skill.CRAFTING, 67, 167.5, CriticalItem.UNCUT_ONYX),
|
UNCUT_EMERALD(ItemID.EMERALD, "Cut emerald", Skill.CRAFTING, 27, 67.5,
|
||||||
UNCUT_ZENYTE(ItemID.UNCUT_ZENYTE, "Gems", Skill.CRAFTING, 89, 200.0, CriticalItem.UNCUT_ZENYTE),
|
CriticalItem.UNCUT_EMERALD, null, new ItemStack(ItemID.EMERALD, 1)),
|
||||||
|
UNCUT_RUBY(ItemID.RUBY, "Cut ruby", Skill.CRAFTING, 34, 85,
|
||||||
|
CriticalItem.UNCUT_RUBY, null, new ItemStack(ItemID.RUBY, 1)),
|
||||||
|
UNCUT_DIAMOND(ItemID.DIAMOND, "Cut diamond", Skill.CRAFTING, 43, 107.5,
|
||||||
|
CriticalItem.UNCUT_DIAMOND, null, new ItemStack(ItemID.DIAMOND, 1)),
|
||||||
|
UNCUT_DRAGONSTONE(ItemID.DRAGONSTONE, "Cut dragonstone", Skill.CRAFTING, 55, 137.5,
|
||||||
|
CriticalItem.UNCUT_DRAGONSTONE, null, new ItemStack(ItemID.DRAGONSTONE, 1)),
|
||||||
|
UNCUT_ONYX(ItemID.ONYX, "Cut onyx", Skill.CRAFTING, 67, 167.5,
|
||||||
|
CriticalItem.UNCUT_ONYX, null, new ItemStack(ItemID.ONYX, 1)),
|
||||||
|
UNCUT_ZENYTE(ItemID.ZENYTE, "Cut zenyte", Skill.CRAFTING, 89, 200.0,
|
||||||
|
CriticalItem.UNCUT_ZENYTE, null, new ItemStack(ItemID.ZENYTE, 1)),
|
||||||
// Silver Jewelery
|
// Silver Jewelery
|
||||||
OPAL_RING(ItemID.OPAL_RING, "Opal ring", Skill.CRAFTING, 1, 10, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
|
OPAL_RING(ItemID.OPAL_RING, "Opal ring", Skill.CRAFTING, 1, 10,
|
||||||
OPAL_NECKLACE(ItemID.OPAL_NECKLACE, "Opal necklace", Skill.CRAFTING, 16, 35, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
|
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_RING, 1)),
|
||||||
OPAL_BRACELET(ItemID.OPAL_BRACELET, "Opal bracelet", Skill.CRAFTING, 22, 45, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
|
OPAL_NECKLACE(ItemID.OPAL_NECKLACE, "Opal necklace", Skill.CRAFTING, 16, 35,
|
||||||
OPAL_AMULET(ItemID.OPAL_AMULET, "Opal amulet", Skill.CRAFTING, 27, 55, CriticalItem.OPAL, ActivitySecondaries.SILVER_BAR),
|
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_NECKLACE, 1)),
|
||||||
JADE_RING(ItemID.JADE_RING, "Jade ring", Skill.CRAFTING, 13, 32, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
|
OPAL_BRACELET(ItemID.OPAL_BRACELET, "Opal bracelet", Skill.CRAFTING, 22, 45,
|
||||||
JADE_NECKLACE(ItemID.JADE_NECKLACE, "Jade necklace", Skill.CRAFTING, 25, 54, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
|
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_BRACELET, 1)),
|
||||||
JADE_BRACELET(ItemID.JADE_BRACELET, "Jade bracelet", Skill.CRAFTING, 29, 60, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
|
OPAL_AMULET(ItemID.OPAL_AMULET, "Opal amulet", Skill.CRAFTING, 27, 55,
|
||||||
JADE_AMULET(ItemID.JADE_AMULET, "Jade amulet", Skill.CRAFTING, 34, 70, CriticalItem.JADE, ActivitySecondaries.SILVER_BAR),
|
CriticalItem.OPAL, Secondaries.SILVER_BAR, new ItemStack(ItemID.OPAL_AMULET, 1)),
|
||||||
TOPAZ_RING(ItemID.TOPAZ_RING, "Topaz ring", Skill.CRAFTING, 16, 35, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
|
JADE_RING(ItemID.JADE_RING, "Jade ring", Skill.CRAFTING, 13, 32,
|
||||||
TOPAZ_NECKLACE(ItemID.TOPAZ_NECKLACE, "Topaz necklace", Skill.CRAFTING, 32, 70, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
|
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_RING, 1)),
|
||||||
TOPAZ_BRACELET(ItemID.TOPAZ_BRACELET, "Topaz bracelet", Skill.CRAFTING, 38, 75, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
|
JADE_NECKLACE(ItemID.JADE_NECKLACE, "Jade necklace", Skill.CRAFTING, 25, 54,
|
||||||
TOPAZ_AMULET(ItemID.TOPAZ_AMULET, "Topaz amulet", Skill.CRAFTING, 45, 80, CriticalItem.RED_TOPAZ, ActivitySecondaries.SILVER_BAR),
|
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_NECKLACE, 1)),
|
||||||
|
JADE_BRACELET(ItemID.JADE_BRACELET, "Jade bracelet", Skill.CRAFTING, 29, 60,
|
||||||
|
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_BRACELET, 1)),
|
||||||
|
JADE_AMULET(ItemID.JADE_AMULET, "Jade amulet", Skill.CRAFTING, 34, 70,
|
||||||
|
CriticalItem.JADE, Secondaries.SILVER_BAR, new ItemStack(ItemID.JADE_AMULET, 1)),
|
||||||
|
TOPAZ_RING(ItemID.TOPAZ_RING, "Topaz ring", Skill.CRAFTING, 16, 35,
|
||||||
|
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_RING, 1)),
|
||||||
|
TOPAZ_NECKLACE(ItemID.TOPAZ_NECKLACE, "Topaz necklace", Skill.CRAFTING, 32, 70,
|
||||||
|
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_NECKLACE, 1)),
|
||||||
|
TOPAZ_BRACELET(ItemID.TOPAZ_BRACELET, "Topaz bracelet", Skill.CRAFTING, 38, 75,
|
||||||
|
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_BRACELET, 1)),
|
||||||
|
TOPAZ_AMULET(ItemID.TOPAZ_AMULET, "Topaz amulet", Skill.CRAFTING, 45, 80,
|
||||||
|
CriticalItem.RED_TOPAZ, Secondaries.SILVER_BAR, new ItemStack(ItemID.TOPAZ_AMULET, 1)),
|
||||||
// Gold Jewelery
|
// Gold Jewelery
|
||||||
SAPPHIRE_RING(ItemID.SAPPHIRE_RING, "Sapphire ring", Skill.CRAFTING, 20, 40, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
|
SAPPHIRE_RING(ItemID.SAPPHIRE_RING, "Sapphire ring", Skill.CRAFTING, 20, 40,
|
||||||
SAPPHIRE_NECKLACE(ItemID.SAPPHIRE_NECKLACE, "Sapphire necklace", Skill.CRAFTING, 22, 55, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_RING, 1)),
|
||||||
SAPPHIRE_BRACELET(ItemID.SAPPHIRE_BRACELET, "Sapphire bracelet", Skill.CRAFTING, 23, 60, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
|
SAPPHIRE_NECKLACE(ItemID.SAPPHIRE_NECKLACE, "Sapphire necklace", Skill.CRAFTING, 22, 55,
|
||||||
SAPPHIRE_AMULET(ItemID.SAPPHIRE_AMULET, "Sapphire amulet", Skill.CRAFTING, 24, 65, CriticalItem.SAPPHIRE, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_NECKLACE, 1)),
|
||||||
EMERALD_RING(ItemID.EMERALD_RING, "Emerald ring", Skill.CRAFTING, 27, 55, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
|
SAPPHIRE_BRACELET(ItemID.SAPPHIRE_BRACELET, "Sapphire bracelet", Skill.CRAFTING, 23, 60,
|
||||||
EMERALD_NECKLACE(ItemID.EMERALD_NECKLACE, "Emerald necklace", Skill.CRAFTING, 29, 60, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_BRACELET, 1)),
|
||||||
EMERALD_BRACELET(ItemID.EMERALD_BRACELET, "Emerald bracelet", Skill.CRAFTING, 30, 65, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
|
SAPPHIRE_AMULET(ItemID.SAPPHIRE_AMULET, "Sapphire amulet", Skill.CRAFTING, 24, 65,
|
||||||
EMERALD_AMULET(ItemID.EMERALD_AMULET, "Emerald amulet", Skill.CRAFTING, 31, 70, CriticalItem.EMERALD, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.SAPPHIRE, Secondaries.GOLD_BAR, new ItemStack(ItemID.SAPPHIRE_AMULET, 1)),
|
||||||
RUBY_RING(ItemID.RUBY_RING, "Ruby ring", Skill.CRAFTING, 34, 70, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
|
EMERALD_RING(ItemID.EMERALD_RING, "Emerald ring", Skill.CRAFTING, 27, 55,
|
||||||
RUBY_NECKLACE(ItemID.RUBY_NECKLACE, "Ruby necklace", Skill.CRAFTING, 40, 75, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_RING, 1)),
|
||||||
RUBY_BRACELET(ItemID.RUBY_BRACELET, "Ruby bracelet", Skill.CRAFTING, 42, 80, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
|
EMERALD_NECKLACE(ItemID.EMERALD_NECKLACE, "Emerald necklace", Skill.CRAFTING, 29, 60,
|
||||||
RUBY_AMULET(ItemID.RUBY_AMULET, "Ruby amulet", Skill.CRAFTING, 50, 85, CriticalItem.RUBY, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_NECKLACE, 1)),
|
||||||
DIAMOND_RING(ItemID.DIAMOND_RING, "Diamond ring", Skill.CRAFTING, 43, 85, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
|
EMERALD_BRACELET(ItemID.EMERALD_BRACELET, "Emerald bracelet", Skill.CRAFTING, 30, 65,
|
||||||
DIAMOND_NECKLACE(ItemID.DIAMOND_NECKLACE, "Diamond necklace", Skill.CRAFTING, 56, 90, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_BRACELET, 1)),
|
||||||
DIAMOND_BRACELET(ItemID.DIAMOND_BRACELET, "Diamond bracelet", Skill.CRAFTING, 58, 95, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
|
EMERALD_AMULET(ItemID.EMERALD_AMULET, "Emerald amulet", Skill.CRAFTING, 31, 70,
|
||||||
DIAMOND_AMULET(ItemID.DIAMOND_AMULET, "Diamond amulet", Skill.CRAFTING, 70, 100, CriticalItem.DIAMOND, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.EMERALD, Secondaries.GOLD_BAR, new ItemStack(ItemID.EMERALD_AMULET, 1)),
|
||||||
DRAGONSTONE_RING(ItemID.DRAGONSTONE_RING, "Dragonstone ring", Skill.CRAFTING, 55, 100, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
|
RUBY_RING(ItemID.RUBY_RING, "Ruby ring", Skill.CRAFTING, 34, 70,
|
||||||
DRAGON_NECKLACE(ItemID.DRAGON_NECKLACE, "Dragon necklace", Skill.CRAFTING, 72, 105, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_RING, 1)),
|
||||||
DRAGONSTONE_BRACELET(ItemID.DRAGONSTONE_BRACELET, "Dragonstone bracelet", Skill.CRAFTING, 74, 110, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
|
RUBY_NECKLACE(ItemID.RUBY_NECKLACE, "Ruby necklace", Skill.CRAFTING, 40, 75,
|
||||||
DRAGONSTONE_AMULET(ItemID.DRAGONSTONE_AMULET, "Dragonstone amulet", Skill.CRAFTING, 80, 150, CriticalItem.DRAGONSTONE, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_NECKLACE, 1)),
|
||||||
ONYX_RING(ItemID.ONYX_RING, "Onyx ring", Skill.CRAFTING, 67, 115, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
|
RUBY_BRACELET(ItemID.RUBY_BRACELET, "Ruby bracelet", Skill.CRAFTING, 42, 80,
|
||||||
ONYX_NECKLACE(ItemID.ONYX_NECKLACE, "Onyx necklace", Skill.CRAFTING, 82, 120, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_BRACELET, 1)),
|
||||||
REGEN_BRACELET(ItemID.REGEN_BRACELET, "Regen bracelet", Skill.CRAFTING, 84, 125, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
|
RUBY_AMULET(ItemID.RUBY_AMULET, "Ruby amulet", Skill.CRAFTING, 50, 85,
|
||||||
ONYX_AMULET(ItemID.ONYX_AMULET, "Onyx amulet", Skill.CRAFTING, 90, 165, CriticalItem.ONYX, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.RUBY, Secondaries.GOLD_BAR, new ItemStack(ItemID.RUBY_AMULET, 1)),
|
||||||
ZENYTE_RING(ItemID.ZENYTE_RING, "Zenyte ring", Skill.CRAFTING, 89, 150, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
|
DIAMOND_RING(ItemID.DIAMOND_RING, "Diamond ring", Skill.CRAFTING, 43, 85,
|
||||||
ZENYTE_NECKLACE(ItemID.ZENYTE_NECKLACE, "Zenyte necklace", Skill.CRAFTING, 92, 165, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_RING, 1)),
|
||||||
ZENYTE_BRACELET(ItemID.ZENYTE_BRACELET, "Zenyte bracelet", Skill.CRAFTING, 95, 180, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
|
DIAMOND_NECKLACE(ItemID.DIAMOND_NECKLACE, "Diamond necklace", Skill.CRAFTING, 56, 90,
|
||||||
ZENYTE_AMULET(ItemID.ZENYTE_AMULET, "Zenyte amulet", Skill.CRAFTING, 98, 200, CriticalItem.ZENYTE, ActivitySecondaries.GOLD_BAR),
|
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_NECKLACE, 1)),
|
||||||
|
DIAMOND_BRACELET(ItemID.DIAMOND_BRACELET, "Diamond bracelet", Skill.CRAFTING, 58, 95,
|
||||||
|
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_BRACELET, 1)),
|
||||||
|
DIAMOND_AMULET(ItemID.DIAMOND_AMULET, "Diamond amulet", Skill.CRAFTING, 70, 100,
|
||||||
|
CriticalItem.DIAMOND, Secondaries.GOLD_BAR, new ItemStack(ItemID.DIAMOND_AMULET, 1)),
|
||||||
|
DRAGONSTONE_RING(ItemID.DRAGONSTONE_RING, "Dragonstone ring", Skill.CRAFTING, 55, 100,
|
||||||
|
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGONSTONE_RING, 1)),
|
||||||
|
DRAGON_NECKLACE(ItemID.DRAGON_NECKLACE, "Dragon necklace", Skill.CRAFTING, 72, 105,
|
||||||
|
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGON_NECKLACE, 1)),
|
||||||
|
DRAGONSTONE_BRACELET(ItemID.DRAGONSTONE_BRACELET, "Dragonstone bracelet", Skill.CRAFTING, 74, 110,
|
||||||
|
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGONSTONE_BRACELET, 1)),
|
||||||
|
DRAGONSTONE_AMULET(ItemID.DRAGONSTONE_AMULET, "Dragonstone amulet", Skill.CRAFTING, 80, 150,
|
||||||
|
CriticalItem.DRAGONSTONE, Secondaries.GOLD_BAR, new ItemStack(ItemID.DRAGONSTONE_AMULET, 1)),
|
||||||
|
ONYX_RING(ItemID.ONYX_RING, "Onyx ring", Skill.CRAFTING, 67, 115,
|
||||||
|
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.ONYX_RING, 1)),
|
||||||
|
ONYX_NECKLACE(ItemID.ONYX_NECKLACE, "Onyx necklace", Skill.CRAFTING, 82, 120,
|
||||||
|
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.ONYX_NECKLACE, 1)),
|
||||||
|
REGEN_BRACELET(ItemID.REGEN_BRACELET, "Regen bracelet", Skill.CRAFTING, 84, 125,
|
||||||
|
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.REGEN_BRACELET, 1)),
|
||||||
|
ONYX_AMULET(ItemID.ONYX_AMULET, "Onyx amulet", Skill.CRAFTING, 90, 165,
|
||||||
|
CriticalItem.ONYX, Secondaries.GOLD_BAR, new ItemStack(ItemID.ONYX_AMULET, 1)),
|
||||||
|
ZENYTE_RING(ItemID.ZENYTE_RING, "Zenyte ring", Skill.CRAFTING, 89, 150,
|
||||||
|
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_RING, 1)),
|
||||||
|
ZENYTE_NECKLACE(ItemID.ZENYTE_NECKLACE, "Zenyte necklace", Skill.CRAFTING, 92, 165,
|
||||||
|
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_NECKLACE, 1)),
|
||||||
|
ZENYTE_BRACELET(ItemID.ZENYTE_BRACELET, "Zenyte bracelet", Skill.CRAFTING, 95, 180,
|
||||||
|
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_BRACELET, 1)),
|
||||||
|
ZENYTE_AMULET(ItemID.ZENYTE_AMULET, "Zenyte amulet", Skill.CRAFTING, 98, 200,
|
||||||
|
CriticalItem.ZENYTE, Secondaries.GOLD_BAR, new ItemStack(ItemID.ZENYTE_AMULET, 1)),
|
||||||
// Battle Staves
|
// Battle Staves
|
||||||
WATER_BATTLESTAFF(ItemID.WATER_BATTLESTAFF, "Water battlestaff", Skill.CRAFTING, 54, 100, CriticalItem.BATTLESTAFF, ActivitySecondaries.WATER_ORB),
|
WATER_BATTLESTAFF(ItemID.WATER_BATTLESTAFF, "Water battlestaff", Skill.CRAFTING, 54, 100,
|
||||||
EARTH_BATTLESTAFF(ItemID.EARTH_BATTLESTAFF, "Earth battlestaff", Skill.CRAFTING, 58, 112.5, CriticalItem.BATTLESTAFF, ActivitySecondaries.EARTH_ORB),
|
CriticalItem.BATTLESTAFF, Secondaries.WATER_ORB, new ItemStack(ItemID.WATER_BATTLESTAFF, 1)),
|
||||||
FIRE_BATTLESTAFF(ItemID.FIRE_BATTLESTAFF, "Fire battlestaff", Skill.CRAFTING, 62, 125, CriticalItem.BATTLESTAFF, ActivitySecondaries.FIRE_ORB),
|
EARTH_BATTLESTAFF(ItemID.EARTH_BATTLESTAFF, "Earth battlestaff", Skill.CRAFTING, 58, 112.5,
|
||||||
AIR_BATTLESTAFF(ItemID.AIR_BATTLESTAFF, "Air battlestaff", Skill.CRAFTING, 66, 137.5, CriticalItem.BATTLESTAFF, ActivitySecondaries.AIR_ORB),
|
CriticalItem.BATTLESTAFF, Secondaries.EARTH_ORB, new ItemStack(ItemID.EARTH_BATTLESTAFF, 1)),
|
||||||
|
FIRE_BATTLESTAFF(ItemID.FIRE_BATTLESTAFF, "Fire battlestaff", Skill.CRAFTING, 62, 125,
|
||||||
|
CriticalItem.BATTLESTAFF, Secondaries.FIRE_ORB, new ItemStack(ItemID.FIRE_BATTLESTAFF, 1)),
|
||||||
|
AIR_BATTLESTAFF(ItemID.AIR_BATTLESTAFF, "Air battlestaff", Skill.CRAFTING, 66, 137.5,
|
||||||
|
CriticalItem.BATTLESTAFF, Secondaries.AIR_ORB, new ItemStack(ItemID.AIR_BATTLESTAFF, 1)),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Smithing Items
|
* Smithing Items
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Smelting ores (Furnace)
|
// Smelting ores (Furnace)
|
||||||
IRON_ORE(ItemID.IRON_BAR, "Iron Bars", Skill.SMITHING, 15, 12.5, CriticalItem.IRON_ORE, ActivitySecondaries.COAL_ORE),
|
IRON_ORE(ItemID.IRON_BAR, "Iron bar", Skill.SMITHING, 15, 12.5,
|
||||||
STEEL_ORE(ItemID.STEEL_BAR, "Steel Bars", Skill.SMITHING, 30, 17.5, CriticalItem.IRON_ORE, ActivitySecondaries.COAL_ORE_2),
|
CriticalItem.IRON_ORE, Secondaries.COAL_ORE, new ItemStack(ItemID.IRON_BAR, 1)),
|
||||||
SILVER_ORE(ItemID.SILVER_ORE, "Bar", Skill.SMITHING, 20, 13.67, CriticalItem.SILVER_ORE),
|
STEEL_ORE(ItemID.STEEL_BAR, "Steel bar", Skill.SMITHING, 30, 17.5,
|
||||||
GOLD_ORE(ItemID.GOLD_BAR, "Regular exp", Skill.SMITHING, 40, 22.5, CriticalItem.GOLD_ORE),
|
CriticalItem.IRON_ORE, Secondaries.COAL_ORE_2, new ItemStack(ItemID.STEEL_BAR, 1)),
|
||||||
GOLD_ORE_GAUNTLETS(ItemID.GOLDSMITH_GAUNTLETS, "Goldsmith Gauntlets", Skill.SMITHING, 40, 56.2, CriticalItem.GOLD_ORE),
|
SILVER_ORE(ItemID.SILVER_BAR, "Silver Bar", Skill.SMITHING, 20, 13.67,
|
||||||
MITHRIL_ORE(ItemID.MITHRIL_ORE, "Bar", Skill.SMITHING, 50, 30, CriticalItem.MITHRIL_ORE, ActivitySecondaries.COAL_ORE_4),
|
CriticalItem.SILVER_ORE, null, new ItemStack(ItemID.SILVER_BAR, 1)),
|
||||||
ADAMANTITE_ORE(ItemID.ADAMANTITE_ORE, "Bar", Skill.SMITHING, 70, 37.5, CriticalItem.ADAMANTITE_ORE, ActivitySecondaries.COAL_ORE_6),
|
GOLD_ORE(ItemID.GOLD_BAR, "Gold bar", Skill.SMITHING, 40, 22.5,
|
||||||
RUNITE_ORE(ItemID.RUNITE_ORE, "Bar", Skill.SMITHING, 85, 50, CriticalItem.RUNITE_ORE, ActivitySecondaries.COAL_ORE_8),
|
CriticalItem.GOLD_ORE, null, new ItemStack(ItemID.GOLD_BAR, 1)),
|
||||||
|
GOLD_ORE_GAUNTLETS(ItemID.GOLDSMITH_GAUNTLETS, "Goldsmith gauntlets", Skill.SMITHING, 40, 56.2,
|
||||||
|
CriticalItem.GOLD_ORE, null, new ItemStack(ItemID.GOLD_BAR, 1)),
|
||||||
|
MITHRIL_ORE(ItemID.MITHRIL_BAR, "Mithril bar", Skill.SMITHING, 50, 30,
|
||||||
|
CriticalItem.MITHRIL_ORE, Secondaries.COAL_ORE_4, new ItemStack(ItemID.MITHRIL_BAR, 1)),
|
||||||
|
ADAMANTITE_ORE(ItemID.ADAMANTITE_BAR, "Adamantite bar", Skill.SMITHING, 70, 37.5,
|
||||||
|
CriticalItem.ADAMANTITE_ORE, Secondaries.COAL_ORE_6, new ItemStack(ItemID.ADAMANTITE_BAR, 1)),
|
||||||
|
RUNITE_ORE(ItemID.RUNITE_BAR, "Runite bar", Skill.SMITHING, 85, 50,
|
||||||
|
CriticalItem.RUNITE_ORE, Secondaries.COAL_ORE_8, new ItemStack(ItemID.RUNITE_BAR, 1)),
|
||||||
|
|
||||||
// Smelting bars (Anvil)
|
// Smelting bars (Anvil)
|
||||||
BRONZE_BAR(ItemID.BRONZE_BAR, "Bars", Skill.SMITHING, 1, 12.5, CriticalItem.BRONZE_BAR),
|
BRONZE_BAR(ItemID.BRONZE_BAR, "Bronze products", Skill.SMITHING, 1, 12.5,
|
||||||
IRON_BAR(ItemID.IRON_BAR, "Bars", Skill.SMITHING, 15, 25.0, CriticalItem.IRON_BAR),
|
CriticalItem.BRONZE_BAR, null, null),
|
||||||
STEEL_BAR(ItemID.STEEL_BAR, "Steel Products", Skill.SMITHING, 30, 37.5, CriticalItem.STEEL_BAR),
|
IRON_BAR(ItemID.IRON_BAR, "Iron products", Skill.SMITHING, 15, 25.0,
|
||||||
CANNONBALLS(ItemID.CANNONBALL, "Cannonballs", Skill.SMITHING, 35, 25.5, CriticalItem.STEEL_BAR),
|
CriticalItem.IRON_BAR, null, null),
|
||||||
MITHRIL_BAR(ItemID.MITHRIL_BAR, "Bars", Skill.SMITHING, 50, 50.0, CriticalItem.MITHRIL_BAR),
|
STEEL_BAR(ItemID.STEEL_BAR, "Steel products", Skill.SMITHING, 30, 37.5,
|
||||||
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, "Bars", Skill.SMITHING, 70, 62.5, CriticalItem.ADAMANTITE_BAR),
|
CriticalItem.STEEL_BAR, null, null),
|
||||||
RUNITE_BAR(ItemID.RUNITE_BAR, "Bars", Skill.SMITHING, 85, 75.0, CriticalItem.RUNITE_BAR),
|
CANNONBALLS(ItemID.CANNONBALL, "Cannonballs", Skill.SMITHING, 35, 25.5,
|
||||||
|
CriticalItem.STEEL_BAR, null, new ItemStack(ItemID.CANNONBALL, 4)),
|
||||||
|
MITHRIL_BAR(ItemID.MITHRIL_BAR, "Mithril products", Skill.SMITHING, 50, 50.0,
|
||||||
|
CriticalItem.MITHRIL_BAR, null, null),
|
||||||
|
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, "Adamantite products", Skill.SMITHING, 70, 62.5,
|
||||||
|
CriticalItem.ADAMANTITE_BAR, null, null),
|
||||||
|
RUNITE_BAR(ItemID.RUNITE_BAR, "Runite products", Skill.SMITHING, 85, 75.0,
|
||||||
|
CriticalItem.RUNITE_BAR, null, null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Farming Items
|
* Farming Items
|
||||||
*/
|
*/
|
||||||
ACORN(ItemID.ACORN, "Seeds", Skill.FARMING, 15, 481.3, CriticalItem.ACORN),
|
ACORN(ItemID.OAK_SAPLING, "Oak sapling", Skill.FARMING, 15, 0,
|
||||||
WILLOW_SEED(ItemID.WILLOW_SEED, "Seeds", Skill.FARMING, 30, 1481.5, CriticalItem.WILLOW_SEED),
|
CriticalItem.ACORN, null, new ItemStack(ItemID.OAK_SAPLING, 1)),
|
||||||
MAPLE_SEED(ItemID.MAPLE_SEED, "Seeds", Skill.FARMING, 45, 3448.4, CriticalItem.MAPLE_SEED),
|
WILLOW_SEED(ItemID.WILLOW_SAPLING, "Willow sapling", Skill.FARMING, 30, 0,
|
||||||
YEW_SEED(ItemID.YEW_SEED, "Seeds", Skill.FARMING, 60, 7150.9, CriticalItem.YEW_SEED),
|
CriticalItem.WILLOW_SEED, null, new ItemStack(ItemID.WILLOW_SAPLING, 1)),
|
||||||
MAGIC_SEED(ItemID.MAGIC_SEED, "Seeds", Skill.FARMING, 75, 13913.8, CriticalItem.MAGIC_SEED),
|
MAPLE_SEED(ItemID.MAPLE_SAPLING, "Maple sapling", Skill.FARMING, 45, 0,
|
||||||
APPLE_TREE_SEED(ItemID.APPLE_TREE_SEED, "Seeds", Skill.FARMING, 27, 1272.5, CriticalItem.APPLE_TREE_SEED),
|
CriticalItem.MAPLE_SEED, null, new ItemStack(ItemID.MAPLE_SAPLING, 1)),
|
||||||
BANANA_TREE_SEED(ItemID.BANANA_TREE_SEED, "Seeds", Skill.FARMING, 33, 1841.5, CriticalItem.BANANA_TREE_SEED),
|
YEW_SEED(ItemID.YEW_SAPLING, "Yew sapling", Skill.FARMING, 60, 0,
|
||||||
ORANGE_TREE_SEED(ItemID.ORANGE_TREE_SEED, "Seeds", Skill.FARMING, 39, 2586.7, CriticalItem.ORANGE_TREE_SEED),
|
CriticalItem.YEW_SEED, null, new ItemStack(ItemID.YEW_SAPLING, 1)),
|
||||||
CURRY_TREE_SEED(ItemID.CURRY_TREE_SEED, "Seeds", Skill.FARMING, 42, 3036.9, CriticalItem.CURRY_TREE_SEED),
|
MAGIC_SEED(ItemID.MAGIC_SAPLING, "Magic sapling", Skill.FARMING, 75, 0,
|
||||||
PINEAPPLE_SEED(ItemID.PINEAPPLE_SEED, "Seeds", Skill.FARMING, 51, 4791.7, CriticalItem.PINEAPPLE_SEED),
|
CriticalItem.MAGIC_SEED, null, new ItemStack(ItemID.MAGIC_SAPLING, 1)),
|
||||||
PAPAYA_TREE_SEED(ItemID.PAPAYA_TREE_SEED, "Seeds", Skill.FARMING, 57, 6380.4, CriticalItem.PAPAYA_TREE_SEED),
|
APPLE_TREE_SEED(ItemID.APPLE_SAPLING, "Apple sapling", Skill.FARMING, 27, 0,
|
||||||
PALM_TREE_SEED(ItemID.PALM_TREE_SEED, "Seeds", Skill.FARMING, 68, 10509.6, CriticalItem.PALM_TREE_SEED),
|
CriticalItem.APPLE_TREE_SEED, null, new ItemStack(ItemID.APPLE_SAPLING, 1)),
|
||||||
CALQUAT_TREE_SEED(ItemID.CALQUAT_TREE_SEED, "Seeds", Skill.FARMING, 72, 12516.5, CriticalItem.CALQUAT_TREE_SEED),
|
BANANA_TREE_SEED(ItemID.BANANA_SAPLING, "Banana sapling", Skill.FARMING, 33, 0,
|
||||||
TEAK_SEED(ItemID.TEAK_SEED, "Seeds", Skill.FARMING, 35, 7325, CriticalItem.TEAK_SEED),
|
CriticalItem.BANANA_TREE_SEED, null, new ItemStack(ItemID.BANANA_SAPLING, 1)),
|
||||||
MAHOGANY_SEED(ItemID.MAHOGANY_SEED, "Seeds", Skill.FARMING, 55, 15783, CriticalItem.MAHOGANY_SEED),
|
ORANGE_TREE_SEED(ItemID.ORANGE_SAPLING, "Orange sapling", Skill.FARMING, 39, 0,
|
||||||
SPIRIT_SEED(ItemID.SPIRIT_SEED, "Seeds", Skill.FARMING, 83, 19500, CriticalItem.SPIRIT_SEED),
|
CriticalItem.ORANGE_TREE_SEED, null, new ItemStack(ItemID.ORANGE_SAPLING, 1)),
|
||||||
|
CURRY_TREE_SEED(ItemID.CURRY_SAPLING, "Curry sapling", Skill.FARMING, 42, 0,
|
||||||
|
CriticalItem.CURRY_TREE_SEED, null, new ItemStack(ItemID.CURRY_SAPLING, 1)),
|
||||||
|
PINEAPPLE_SEED(ItemID.PINEAPPLE_SAPLING, "Pineapple sapling", Skill.FARMING, 51, 0,
|
||||||
|
CriticalItem.PINEAPPLE_SEED, null, new ItemStack(ItemID.PINEAPPLE_SAPLING, 1)),
|
||||||
|
PAPAYA_TREE_SEED(ItemID.PAPAYA_SAPLING, "Papaya sapling", Skill.FARMING, 57, 0,
|
||||||
|
CriticalItem.PAPAYA_TREE_SEED, null, new ItemStack(ItemID.PAPAYA_SAPLING, 1)),
|
||||||
|
PALM_TREE_SEED(ItemID.PALM_SAPLING, "Palm sapling", Skill.FARMING, 68, 0,
|
||||||
|
CriticalItem.PALM_TREE_SEED, null, new ItemStack(ItemID.PALM_SAPLING, 1)),
|
||||||
|
CALQUAT_TREE_SEED(ItemID.CALQUAT_SAPLING, "Calquat sapling", Skill.FARMING, 72, 0,
|
||||||
|
CriticalItem.CALQUAT_TREE_SEED, null, new ItemStack(ItemID.CALQUAT_SAPLING, 1)),
|
||||||
|
TEAK_SEED(ItemID.TEAK_SAPLING, "Teak sapling", Skill.FARMING, 35, 0,
|
||||||
|
CriticalItem.TEAK_SEED, null, new ItemStack(ItemID.TEAK_SAPLING, 1)),
|
||||||
|
MAHOGANY_SEED(ItemID.MAHOGANY_SAPLING, "Mahogany sapling", Skill.FARMING, 55, 0,
|
||||||
|
CriticalItem.MAHOGANY_SEED, null, new ItemStack(ItemID.MAHOGANY_SAPLING, 1)),
|
||||||
|
SPIRIT_SEED(ItemID.SPIRIT_SAPLING, "Spirit sapling", Skill.FARMING, 83, 0,
|
||||||
|
CriticalItem.SPIRIT_SEED, null, new ItemStack(ItemID.SPIRIT_SAPLING, 1)),
|
||||||
|
|
||||||
|
OAK_SAPPLING(ItemID.OAK_SAPLING, "Oak tree", Skill.FARMING, 15, 481.3,
|
||||||
|
CriticalItem.OAK_SAPLING, null, null),
|
||||||
|
WILLOW_SAPLING(ItemID.WILLOW_SAPLING, "Willow tree", Skill.FARMING, 30, 1481.5,
|
||||||
|
CriticalItem.WILLOW_SAPLING, null, null),
|
||||||
|
MAPLE_SAPLING(ItemID.MAPLE_SAPLING, "Maple tree", Skill.FARMING, 45, 3448.4,
|
||||||
|
CriticalItem.MAPLE_SAPLING, null, null),
|
||||||
|
YEW_SAPLING(ItemID.YEW_SAPLING, "Yew tree", Skill.FARMING, 60, 7150.9,
|
||||||
|
CriticalItem.YEW_SAPLING, null, null),
|
||||||
|
MAGIC_SAPLING(ItemID.MAGIC_SAPLING, "Magic tree", Skill.FARMING, 75, 13913.8,
|
||||||
|
CriticalItem.MAGIC_SAPLING, null, null),
|
||||||
|
APPLE_TREE_SAPLING(ItemID.APPLE_SAPLING, "Apple tree", Skill.FARMING, 27, 1272.5,
|
||||||
|
CriticalItem.APPLE_TREE_SAPLING, null, null),
|
||||||
|
BANANA_TREE_SAPLING(ItemID.BANANA_SAPLING, "Banana tree", Skill.FARMING, 33, 1841.5,
|
||||||
|
CriticalItem.BANANA_TREE_SAPLING, null, null),
|
||||||
|
ORANGE_TREE_SAPLING(ItemID.ORANGE_SAPLING, "Orange tree", Skill.FARMING, 39, 2586.7,
|
||||||
|
CriticalItem.ORANGE_TREE_SAPLING, null, null),
|
||||||
|
CURRY_TREE_SAPLING(ItemID.CURRY_SAPLING, "Curry tree", Skill.FARMING, 42, 3036.9,
|
||||||
|
CriticalItem.CURRY_TREE_SAPLING, null, null),
|
||||||
|
PINEAPPLE_SAPLING(ItemID.PINEAPPLE_SAPLING, "Pineapple tree", Skill.FARMING, 51, 4791.7,
|
||||||
|
CriticalItem.PINEAPPLE_SAPLING, null, null),
|
||||||
|
PAPAYA_TREE_SAPLING(ItemID.PAPAYA_SAPLING, "Papaya tree", Skill.FARMING, 57, 6380.4,
|
||||||
|
CriticalItem.PAPAYA_TREE_SAPLING, null, null),
|
||||||
|
PALM_TREE_SAPLING(ItemID.PALM_SAPLING, "Palm tree", Skill.FARMING, 68, 10509.6,
|
||||||
|
CriticalItem.PALM_TREE_SAPLING, null, null),
|
||||||
|
CALQUAT_TREE_SAPLING(ItemID.CALQUAT_SAPLING, "Calquat tree", Skill.FARMING, 72, 12516.5,
|
||||||
|
CriticalItem.CALQUAT_TREE_SAPLING, null, null),
|
||||||
|
TEAK_SAPLING(ItemID.TEAK_SAPLING, "Teak tree", Skill.FARMING, 35, 7325,
|
||||||
|
CriticalItem.TEAK_SAPLING, null, null),
|
||||||
|
MAHOGANY_SAPLING(ItemID.MAHOGANY_SAPLING, "Mahogany tree", Skill.FARMING, 55, 15783,
|
||||||
|
CriticalItem.MAHOGANY_SAPLING, null, null),
|
||||||
|
SPIRIT_SAPLING(ItemID.SPIRIT_SAPLING, "Spirit tree", Skill.FARMING, 83, 19500,
|
||||||
|
CriticalItem.SPIRIT_SAPLING, null, null),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final int icon;
|
private final int icon;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private final CriticalItem criticalItem;
|
||||||
private final Skill skill;
|
private final Skill skill;
|
||||||
private final int level;
|
private final int level;
|
||||||
private final double xp;
|
private final double xp;
|
||||||
private final SecondaryItem[] secondaries;
|
private final ItemStack[] secondaries;
|
||||||
private final CriticalItem criticalItem;
|
@Nullable
|
||||||
private final boolean preventLinked;
|
private final ItemStack output;
|
||||||
|
private ItemInfo outputItemInfo = null;
|
||||||
|
@Nullable
|
||||||
|
private final CriticalItem linkedItem;
|
||||||
|
|
||||||
Activity(int Icon, String name, Skill skill, int level, double xp, CriticalItem criticalItem)
|
// Store activity by CriticalItem
|
||||||
{
|
private static final ImmutableMultimap<CriticalItem, Activity> CRITICAL_MAP;
|
||||||
this.icon = Icon;
|
|
||||||
this.name = name;
|
|
||||||
this.skill = skill;
|
|
||||||
this.level = level;
|
|
||||||
this.xp = xp;
|
|
||||||
this.criticalItem = criticalItem;
|
|
||||||
this.secondaries = new SecondaryItem[0];
|
|
||||||
this.preventLinked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Activity(int Icon, String name, Skill skill, int level, double xp, CriticalItem criticalItem, ActivitySecondaries secondaries)
|
static
|
||||||
{
|
{
|
||||||
this.icon = Icon;
|
final ImmutableMultimap.Builder<CriticalItem, Activity> map = ImmutableMultimap.builder();
|
||||||
this.name = name;
|
for (final Activity item : values())
|
||||||
this.skill = skill;
|
|
||||||
this.level = level;
|
|
||||||
this.xp = xp;
|
|
||||||
this.criticalItem = criticalItem;
|
|
||||||
this.secondaries = secondaries == null ? new SecondaryItem[0] : secondaries.getItems();
|
|
||||||
this.preventLinked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Activity(final int Icon, final String name, final Skill skill, final int level, final double xp, final CriticalItem criticalItem, final ActivitySecondaries secondaries, final boolean preventLinked)
|
|
||||||
{
|
|
||||||
this.icon = Icon;
|
|
||||||
this.name = name;
|
|
||||||
this.skill = skill;
|
|
||||||
this.level = level;
|
|
||||||
this.xp = xp;
|
|
||||||
this.criticalItem = criticalItem;
|
|
||||||
this.secondaries = secondaries == null ? new SecondaryItem[0] : secondaries.getItems();
|
|
||||||
this.preventLinked = preventLinked;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a Map to reduce looping frequency
|
|
||||||
private static Map<CriticalItem, ArrayList<Activity>> buildItemMap()
|
|
||||||
{
|
|
||||||
Map<CriticalItem, ArrayList<Activity>> map = new HashMap<>();
|
|
||||||
for (Activity item : values())
|
|
||||||
{
|
{
|
||||||
map.computeIfAbsent(item.getCriticalItem(), e -> new ArrayList<>()).add(item);
|
map.put(item.getCriticalItem(), item);
|
||||||
}
|
}
|
||||||
|
CRITICAL_MAP = map.build();
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<CriticalItem, ArrayList<Activity>> byCriticalItem = buildItemMap();
|
Activity(
|
||||||
|
final int icon,
|
||||||
public static List<Activity> getByCriticalItem(CriticalItem item)
|
final String name,
|
||||||
|
final Skill skill,
|
||||||
|
final int level,
|
||||||
|
final double xp,
|
||||||
|
final CriticalItem criticalItem,
|
||||||
|
@Nullable final Secondaries secondaries,
|
||||||
|
@Nullable final ItemStack output)
|
||||||
{
|
{
|
||||||
|
this.icon = icon;
|
||||||
return byCriticalItem.getOrDefault(item, new ArrayList<>());
|
this.name = name;
|
||||||
|
this.skill = skill;
|
||||||
|
this.level = level;
|
||||||
|
this.xp = xp;
|
||||||
|
this.criticalItem = criticalItem;
|
||||||
|
this.secondaries = secondaries == null ? new ItemStack[0] : secondaries.getItems();
|
||||||
|
this.output = output;
|
||||||
|
this.linkedItem = output == null ? null : CriticalItem.getByItemId(output.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all Activities for this CriticalItem
|
* Get all Activities for this CriticalItem
|
||||||
*
|
*
|
||||||
* @param item CriticalItem to check for
|
* @param item CriticalItem to check for
|
||||||
* @param limitLevel Level to check Activitiy requirements against. -1 or 0 value disables limits
|
* @return an empty Collection if no activities
|
||||||
* @return an empty list if no activities
|
|
||||||
*/
|
*/
|
||||||
public static List<Activity> getByCriticalItem(CriticalItem item, int limitLevel)
|
public static List<Activity> getByCriticalItem(CriticalItem item)
|
||||||
{
|
{
|
||||||
List<Activity> activities = getByCriticalItem(item);
|
final Collection<Activity> activities = CRITICAL_MAP.get(item);
|
||||||
List<Activity> l = new ArrayList<>();
|
if (activities == null)
|
||||||
|
{
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<>(activities);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all Activities for this CriticalItem limited to level
|
||||||
|
*
|
||||||
|
* @param item CriticalItem to check for
|
||||||
|
* @param limitLevel Level to check Activitiy requirements against. -1/0 value disables limits
|
||||||
|
* @return an empty Collection if no activities
|
||||||
|
*/
|
||||||
|
public static List<Activity> getByCriticalItem(final CriticalItem item, final int limitLevel)
|
||||||
|
{
|
||||||
|
// Return as list to allow getting by index
|
||||||
|
final List<Activity> l = getByCriticalItem(item);
|
||||||
if (limitLevel <= 0)
|
if (limitLevel <= 0)
|
||||||
{
|
{
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Activity a : activities)
|
return l.stream().filter(a -> a.getLevel() <= limitLevel).collect(Collectors.toList());
|
||||||
{
|
|
||||||
if (!(a.getLevel() > limitLevel))
|
|
||||||
{
|
|
||||||
l.add(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Attaches the Item Composition to each CriticalItem on client initial load
|
||||||
|
*
|
||||||
|
* @param m ItemManager
|
||||||
|
*/
|
||||||
|
public static void prepareItemDefinitions(ItemManager m)
|
||||||
|
{
|
||||||
|
for (Activity a : values())
|
||||||
|
{
|
||||||
|
final ItemStack output = a.getOutput();
|
||||||
|
if (output == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.getOutputItemInfo() != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ItemDefinition c = m.getItemDefinition(output.getId());
|
||||||
|
a.outputItemInfo = new ItemInfo(c.getName(), c.isStackable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* 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.skillcalculator.banked.beans;
|
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.api.ItemID;
|
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
|
||||||
public enum ActivitySecondaries
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Herblore
|
|
||||||
*/
|
|
||||||
UNFINISHED_POTION(new SecondaryItem(ItemID.VIAL_OF_WATER, 1)),
|
|
||||||
SWAMP_TAR(new SecondaryItem(ItemID.SWAMP_TAR, 15)),
|
|
||||||
|
|
||||||
// Guam
|
|
||||||
ATTACK_POTION(new SecondaryItem(ItemID.EYE_OF_NEWT)),
|
|
||||||
// Marrentil
|
|
||||||
ANTIPOISON(new SecondaryItem(ItemID.UNICORN_HORN_DUST)),
|
|
||||||
// Tarromin
|
|
||||||
STRENGTH_POTION(new SecondaryItem(ItemID.LIMPWURT_ROOT)),
|
|
||||||
SERUM_207(new SecondaryItem(ItemID.ASHES)),
|
|
||||||
// Harralander
|
|
||||||
COMPOST_POTION(new SecondaryItem(ItemID.VOLCANIC_ASH)),
|
|
||||||
RESTORE_POTION(new SecondaryItem(ItemID.RED_SPIDERS_EGGS)),
|
|
||||||
ENERGY_POTION(new SecondaryItem(ItemID.CHOCOLATE_DUST)),
|
|
||||||
COMBAT_POTION(new SecondaryItem(ItemID.GOAT_HORN_DUST)),
|
|
||||||
// Ranarr Weed
|
|
||||||
DEFENCE_POTION(new SecondaryItem(ItemID.WHITE_BERRIES)),
|
|
||||||
PRAYER_POTION(new SecondaryItem(ItemID.SNAPE_GRASS)),
|
|
||||||
// Toadflax
|
|
||||||
AGILITY_POTION(new SecondaryItem(ItemID.TOADS_LEGS)),
|
|
||||||
SARADOMIN_BREW(new SecondaryItem(ItemID.CRUSHED_NEST)),
|
|
||||||
// Irit
|
|
||||||
SUPER_ATTACK(new SecondaryItem(ItemID.EYE_OF_NEWT)),
|
|
||||||
SUPERANTIPOISON(new SecondaryItem(ItemID.UNICORN_HORN_DUST)),
|
|
||||||
// Avantoe
|
|
||||||
FISHING_POTION(new SecondaryItem(ItemID.SNAPE_GRASS)),
|
|
||||||
SUPER_ENERGY_POTION(new SecondaryItem(ItemID.MORT_MYRE_FUNGUS)),
|
|
||||||
HUNTER_POTION(new SecondaryItem(ItemID.KEBBIT_TEETH_DUST)),
|
|
||||||
// Kwuarm
|
|
||||||
SUPER_STRENGTH(new SecondaryItem(ItemID.LIMPWURT_ROOT)),
|
|
||||||
// Snapdragon
|
|
||||||
SUPER_RESTORE(new SecondaryItem(ItemID.RED_SPIDERS_EGGS)),
|
|
||||||
SANFEW_SERUM(new SecondaryItem(ItemID.SNAKE_WEED), new SecondaryItem(ItemID.UNICORN_HORN_DUST), new SecondaryItem(ItemID.SUPER_RESTORE4), new SecondaryItem(ItemID.NAIL_BEAST_NAILS)),
|
|
||||||
// Cadantine
|
|
||||||
SUPER_DEFENCE_POTION(new SecondaryItem(ItemID.WHITE_BERRIES)),
|
|
||||||
// Lantadyme
|
|
||||||
ANTIFIRE_POTION(new SecondaryItem(ItemID.DRAGON_SCALE_DUST)),
|
|
||||||
MAGIC_POTION(new SecondaryItem(ItemID.POTATO_CACTUS)),
|
|
||||||
// Dwarf Weed
|
|
||||||
RANGING_POTION(new SecondaryItem(ItemID.WINE_OF_ZAMORAK)),
|
|
||||||
// Torstol
|
|
||||||
ZAMORAK_BREW(new SecondaryItem(ItemID.JANGERBERRIES)),
|
|
||||||
SUPER_COMBAT_POTION(new SecondaryItem(ItemID.SUPER_ATTACK3), new SecondaryItem(ItemID.SUPER_STRENGTH3), new SecondaryItem(ItemID.SUPER_DEFENCE3)),
|
|
||||||
ANTIVENOM_PLUS(new SecondaryItem(ItemID.ANTIVENOM4)),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Smithing
|
|
||||||
*/
|
|
||||||
COAL_ORE(new SecondaryItem(ItemID.COAL)),
|
|
||||||
COAL_ORE_2(new SecondaryItem(ItemID.COAL, 2)),
|
|
||||||
COAL_ORE_4(new SecondaryItem(ItemID.COAL, 4)),
|
|
||||||
COAL_ORE_6(new SecondaryItem(ItemID.COAL, 6)),
|
|
||||||
COAL_ORE_8(new SecondaryItem(ItemID.COAL, 8)),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Crafting
|
|
||||||
*/
|
|
||||||
GOLD_BAR(new SecondaryItem(ItemID.GOLD_BAR)),
|
|
||||||
SILVER_BAR(new SecondaryItem(ItemID.SILVER_BAR)),
|
|
||||||
WATER_ORB(new SecondaryItem(ItemID.WATER_ORB)),
|
|
||||||
EARTH_ORB(new SecondaryItem(ItemID.EARTH_ORB)),
|
|
||||||
FIRE_ORB(new SecondaryItem(ItemID.FIRE_ORB)),
|
|
||||||
AIR_ORB(new SecondaryItem(ItemID.AIR_ORB)),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cooking
|
|
||||||
*/
|
|
||||||
JUG_OF_WATER(new SecondaryItem(ItemID.JUG_OF_WATER)),
|
|
||||||
;
|
|
||||||
private final SecondaryItem[] items;
|
|
||||||
|
|
||||||
ActivitySecondaries(final SecondaryItem... items)
|
|
||||||
{
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -22,27 +22,32 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.cache.definitions.sound;
|
package net.runelite.client.plugins.skillcalculator.banked.beans;
|
||||||
|
|
||||||
public class SoundEffect2Definition
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class BankedItem
|
||||||
{
|
{
|
||||||
public int field1085;
|
private final CriticalItem item;
|
||||||
public int[] field1086 = new int[2];
|
private final int qty;
|
||||||
public int field1087;
|
|
||||||
public int field1088;
|
|
||||||
public int field1089;
|
|
||||||
public int[] field1090 = new int[2];
|
|
||||||
public int field1091;
|
|
||||||
public int field1092 = 2;
|
|
||||||
public int field1093;
|
|
||||||
public int field1094;
|
|
||||||
public int field1095;
|
|
||||||
|
|
||||||
public SoundEffect2Definition()
|
public double getXpRate()
|
||||||
{
|
{
|
||||||
this.field1086[0] = 0;
|
final Activity selectedActivity = item.getSelectedActivity();
|
||||||
this.field1086[1] = '\uffff';
|
if (selectedActivity == null)
|
||||||
this.field1090[0] = 0;
|
{
|
||||||
this.field1090[1] = '\uffff';
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedActivity.getXp();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return item.name() + " x " + qty;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked.beans;
|
||||||
|
|
||||||
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.api.ItemDefinition;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum CriticalItem
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Construction Items
|
||||||
|
*/
|
||||||
|
// Logs
|
||||||
|
LOGS(ItemID.LOGS, Skill.CONSTRUCTION, "Logs"),
|
||||||
|
OAK_LOGS(ItemID.OAK_LOGS, Skill.CONSTRUCTION, "Logs"),
|
||||||
|
TEAK_LOGS(ItemID.TEAK_LOGS, Skill.CONSTRUCTION, "Logs"),
|
||||||
|
MAHOGANY_LOGS(ItemID.MAHOGANY_LOGS, Skill.CONSTRUCTION, "Logs"),
|
||||||
|
// Planks
|
||||||
|
PLANK(ItemID.PLANK, Skill.CONSTRUCTION, "Planks"),
|
||||||
|
OAK_PLANK(ItemID.OAK_PLANK, Skill.CONSTRUCTION, "Planks"),
|
||||||
|
TEAK_PLANK(ItemID.TEAK_PLANK, Skill.CONSTRUCTION, "Planks"),
|
||||||
|
MAHOGANY_PLANK(ItemID.MAHOGANY_PLANK, Skill.CONSTRUCTION, "Planks"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Herblore Items
|
||||||
|
*/
|
||||||
|
// Grimy Herbs
|
||||||
|
GRIMY_GUAM_LEAF(ItemID.GRIMY_GUAM_LEAF, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_MARRENTILL(ItemID.GRIMY_MARRENTILL, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_TARROMIN(ItemID.GRIMY_TARROMIN, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_HARRALANDER(ItemID.GRIMY_HARRALANDER, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_RANARR_WEED(ItemID.GRIMY_RANARR_WEED, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_TOADFLAX(ItemID.GRIMY_TOADFLAX, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_IRIT_LEAF(ItemID.GRIMY_IRIT_LEAF, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_AVANTOE(ItemID.GRIMY_AVANTOE, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_KWUARM(ItemID.GRIMY_KWUARM, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_SNAPDRAGON(ItemID.GRIMY_SNAPDRAGON, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_CADANTINE(ItemID.GRIMY_CADANTINE, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_LANTADYME(ItemID.GRIMY_LANTADYME, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_DWARF_WEED(ItemID.GRIMY_DWARF_WEED, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
GRIMY_TORSTOL(ItemID.GRIMY_TORSTOL, Skill.HERBLORE, "Grimy Herbs"),
|
||||||
|
// Clean Herbs
|
||||||
|
GUAM_LEAF(ItemID.GUAM_LEAF, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
MARRENTILL(ItemID.MARRENTILL, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
TARROMIN(ItemID.TARROMIN, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
HARRALANDER(ItemID.HARRALANDER, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
RANARR_WEED(ItemID.RANARR_WEED, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
TOADFLAX(ItemID.TOADFLAX, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
IRIT_LEAF(ItemID.IRIT_LEAF, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
AVANTOE(ItemID.AVANTOE, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
KWUARM(ItemID.KWUARM, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
SNAPDRAGON(ItemID.SNAPDRAGON, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
CADANTINE(ItemID.CADANTINE, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
LANTADYME(ItemID.LANTADYME, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
DWARF_WEED(ItemID.DWARF_WEED, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
TORSTOL(ItemID.TORSTOL, Skill.HERBLORE, "Cleaned Herbs"),
|
||||||
|
// Unfinished Potions
|
||||||
|
GUAM_LEAF_POTION_UNF(ItemID.GUAM_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
MARRENTILL_POTION_UNF(ItemID.MARRENTILL_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
TARROMIN_POTION_UNF(ItemID.TARROMIN_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
HARRALANDER_POTION_UNF(ItemID.HARRALANDER_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
RANARR_POTION_UNF(ItemID.RANARR_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
TOADFLAX_POTION_UNF(ItemID.TOADFLAX_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
IRIT_POTION_UNF(ItemID.IRIT_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
AVANTOE_POTION_UNF(ItemID.AVANTOE_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
KWUARM_POTION_UNF(ItemID.KWUARM_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
SNAPDRAGON_POTION_UNF(ItemID.SNAPDRAGON_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
CADANTINE_POTION_UNF(ItemID.CADANTINE_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
LANTADYME_POTION_UNF(ItemID.LANTADYME_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
DWARF_WEED_POTION_UNF(ItemID.DWARF_WEED_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
TORSTOL_POTION_UNF(ItemID.TORSTOL_POTION_UNF, Skill.HERBLORE, "Unfinished Potions"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prayer Items
|
||||||
|
*/
|
||||||
|
// Bones
|
||||||
|
BONES(ItemID.BONES, Skill.PRAYER, "Bones"),
|
||||||
|
WOLF_BONES(ItemID.WOLF_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
BURNT_BONES(ItemID.BURNT_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
MONKEY_BONES(ItemID.MONKEY_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
BAT_BONES(ItemID.BAT_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
JOGRE_BONES(ItemID.JOGRE_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
BIG_BONES(ItemID.BIG_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
ZOGRE_BONES(ItemID.ZOGRE_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
SHAIKAHAN_BONES(ItemID.SHAIKAHAN_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
BABYDRAGON_BONES(ItemID.BABYDRAGON_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
WYVERN_BONES(ItemID.WYVERN_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
DRAGON_BONES(ItemID.DRAGON_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
FAYRG_BONES(ItemID.FAYRG_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
LAVA_DRAGON_BONES(ItemID.LAVA_DRAGON_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
RAURG_BONES(ItemID.RAURG_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
DAGANNOTH_BONES(ItemID.DAGANNOTH_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
OURG_BONES(ItemID.OURG_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
SUPERIOR_DRAGON_BONES(ItemID.SUPERIOR_DRAGON_BONES, Skill.PRAYER, "Bones"),
|
||||||
|
// Shade Remains (Pyre Logs)
|
||||||
|
LOAR_REMAINS(ItemID.LOAR_REMAINS, Skill.PRAYER, "Shades", true),
|
||||||
|
PHRIN_REMAINS(ItemID.PHRIN_REMAINS, Skill.PRAYER, "Shades", true),
|
||||||
|
RIYL_REMAINS(ItemID.RIYL_REMAINS, Skill.PRAYER, "Shades", true),
|
||||||
|
ASYN_REMAINS(ItemID.ASYN_REMAINS, Skill.PRAYER, "Shades", true),
|
||||||
|
FIYR_REMAINS(ItemID.FIYR_REMAINS, Skill.PRAYER, "Shades", true),
|
||||||
|
// Ensouled Heads
|
||||||
|
ENSOULED_GOBLIN_HEAD(ItemID.ENSOULED_GOBLIN_HEAD_13448, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_MONKEY_HEAD(ItemID.ENSOULED_MONKEY_HEAD_13451, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_IMP_HEAD(ItemID.ENSOULED_IMP_HEAD_13454, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_MINOTAUR_HEAD(ItemID.ENSOULED_MINOTAUR_HEAD_13457, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_SCORPION_HEAD(ItemID.ENSOULED_SCORPION_HEAD_13460, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_BEAR_HEAD(ItemID.ENSOULED_BEAR_HEAD_13463, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_UNICORN_HEAD(ItemID.ENSOULED_UNICORN_HEAD_13466, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_DOG_HEAD(ItemID.ENSOULED_DOG_HEAD_13469, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_CHAOS_DRUID_HEAD(ItemID.ENSOULED_CHAOS_DRUID_HEAD_13472, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_GIANT_HEAD(ItemID.ENSOULED_GIANT_HEAD_13475, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_OGRE_HEAD(ItemID.ENSOULED_OGRE_HEAD_13478, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_ELF_HEAD(ItemID.ENSOULED_ELF_HEAD_13481, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_TROLL_HEAD(ItemID.ENSOULED_TROLL_HEAD_13484, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_HORROR_HEAD(ItemID.ENSOULED_HORROR_HEAD_13487, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_KALPHITE_HEAD(ItemID.ENSOULED_KALPHITE_HEAD_13490, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_DAGANNOTH_HEAD(ItemID.ENSOULED_DAGANNOTH_HEAD_13493, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_BLOODVELD_HEAD(ItemID.ENSOULED_BLOODVELD_HEAD_13496, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_TZHAAR_HEAD(ItemID.ENSOULED_TZHAAR_HEAD_13499, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_DEMON_HEAD(ItemID.ENSOULED_DEMON_HEAD_13502, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_AVIANSIE_HEAD(ItemID.ENSOULED_AVIANSIE_HEAD_13505, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_ABYSSAL_HEAD(ItemID.ENSOULED_ABYSSAL_HEAD_13508, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
ENSOULED_DRAGON_HEAD(ItemID.ENSOULED_DRAGON_HEAD_13511, Skill.PRAYER, "Ensouled Heads", true),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cooking Items
|
||||||
|
*/
|
||||||
|
RAW_HERRING(ItemID.RAW_HERRING, Skill.COOKING, "Fish"),
|
||||||
|
RAW_MACKEREL(ItemID.RAW_MACKEREL, Skill.COOKING, "Fish"),
|
||||||
|
RAW_TROUT(ItemID.RAW_TROUT, Skill.COOKING, "Fish"),
|
||||||
|
RAW_COD(ItemID.RAW_COD, Skill.COOKING, "Fish"),
|
||||||
|
RAW_PIKE(ItemID.RAW_PIKE, Skill.COOKING, "Fish"),
|
||||||
|
RAW_SALMON(ItemID.RAW_SALMON, Skill.COOKING, "Fish"),
|
||||||
|
RAW_TUNA(ItemID.RAW_TUNA, Skill.COOKING, "Fish"),
|
||||||
|
RAW_KARAMBWAN(ItemID.RAW_KARAMBWAN, Skill.COOKING, "Fish"),
|
||||||
|
RAW_LOBSTER(ItemID.RAW_LOBSTER, Skill.COOKING, "Fish"),
|
||||||
|
RAW_BASS(ItemID.RAW_BASS, Skill.COOKING, "Fish"),
|
||||||
|
RAW_SWORDFISH(ItemID.RAW_SWORDFISH, Skill.COOKING, "Fish"),
|
||||||
|
RAW_MONKFISH(ItemID.RAW_MONKFISH, Skill.COOKING, "Fish"),
|
||||||
|
RAW_SHARK(ItemID.RAW_SHARK, Skill.COOKING, "Fish"),
|
||||||
|
RAW_SEA_TURTLE(ItemID.RAW_SEA_TURTLE, Skill.COOKING, "Fish"),
|
||||||
|
RAW_ANGLERFISH(ItemID.RAW_ANGLERFISH, Skill.COOKING, "Fish"),
|
||||||
|
RAW_DARK_CRAB(ItemID.RAW_DARK_CRAB, Skill.COOKING, "Fish"),
|
||||||
|
RAW_MANTA_RAY(ItemID.RAW_MANTA_RAY, Skill.COOKING, "Fish"),
|
||||||
|
|
||||||
|
GRAPES(ItemID.GRAPES, Skill.COOKING, "Other"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crafting Items
|
||||||
|
*/
|
||||||
|
WOOL(ItemID.WOOL, Skill.CRAFTING, "Misc"),
|
||||||
|
FLAX(ItemID.FLAX, Skill.CRAFTING, "Misc"),
|
||||||
|
MOLTEN_GLASS(ItemID.MOLTEN_GLASS, Skill.CRAFTING, "Misc"),
|
||||||
|
BATTLESTAFF(ItemID.BATTLESTAFF, Skill.CRAFTING, "Misc"),
|
||||||
|
|
||||||
|
// D'hide/Dragon Leather
|
||||||
|
GREEN_DRAGONHIDE(ItemID.GREEN_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
|
||||||
|
GREEN_DRAGON_LEATHER(ItemID.GREEN_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
|
||||||
|
BLUE_DRAGONHIDE(ItemID.BLUE_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
|
||||||
|
BLUE_DRAGON_LEATHER(ItemID.BLUE_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
|
||||||
|
RED_DRAGONHIDE(ItemID.RED_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
|
||||||
|
RED_DRAGON_LEATHER(ItemID.RED_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
|
||||||
|
BLACK_DRAGONHIDE(ItemID.BLACK_DRAGONHIDE, Skill.CRAFTING, "D'hide"),
|
||||||
|
BLACK_DRAGON_LEATHER(ItemID.BLACK_DRAGON_LEATHER, Skill.CRAFTING, "D'hide"),
|
||||||
|
|
||||||
|
// Uncut Gems
|
||||||
|
UNCUT_OPAL(ItemID.UNCUT_OPAL, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_JADE(ItemID.UNCUT_JADE, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_RED_TOPAZ(ItemID.UNCUT_RED_TOPAZ, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_SAPPHIRE(ItemID.UNCUT_SAPPHIRE, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_EMERALD(ItemID.UNCUT_EMERALD, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_RUBY(ItemID.UNCUT_RUBY, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_DIAMOND(ItemID.UNCUT_DIAMOND, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_DRAGONSTONE(ItemID.UNCUT_DRAGONSTONE, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_ONYX(ItemID.UNCUT_ONYX, Skill.CRAFTING, "Gems"),
|
||||||
|
UNCUT_ZENYTE(ItemID.UNCUT_ZENYTE, Skill.CRAFTING, "Gems"),
|
||||||
|
|
||||||
|
// Cut Gems
|
||||||
|
OPAL(ItemID.OPAL, Skill.CRAFTING, "Gems"),
|
||||||
|
JADE(ItemID.JADE, Skill.CRAFTING, "Gems"),
|
||||||
|
RED_TOPAZ(ItemID.RED_TOPAZ, Skill.CRAFTING, "Gems"),
|
||||||
|
SAPPHIRE(ItemID.SAPPHIRE, Skill.CRAFTING, "Gems"),
|
||||||
|
EMERALD(ItemID.EMERALD, Skill.CRAFTING, "Gems"),
|
||||||
|
RUBY(ItemID.RUBY, Skill.CRAFTING, "Gems"),
|
||||||
|
DIAMOND(ItemID.DIAMOND, Skill.CRAFTING, "Gems"),
|
||||||
|
DRAGONSTONE(ItemID.DRAGONSTONE, Skill.CRAFTING, "Gems"),
|
||||||
|
ONYX(ItemID.ONYX, Skill.CRAFTING, "Gems"),
|
||||||
|
ZENYTE(ItemID.ZENYTE, Skill.CRAFTING, "Gems"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smithing Items
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Ores
|
||||||
|
IRON_ORE(ItemID.IRON_ORE, Skill.SMITHING, "Ore"),
|
||||||
|
SILVER_ORE(ItemID.SILVER_ORE, Skill.SMITHING, "Ore"),
|
||||||
|
GOLD_ORE(ItemID.GOLD_ORE, Skill.SMITHING, "Ore"),
|
||||||
|
MITHRIL_ORE(ItemID.MITHRIL_ORE, Skill.SMITHING, "Ore"),
|
||||||
|
ADAMANTITE_ORE(ItemID.ADAMANTITE_ORE, Skill.SMITHING, "Ore"),
|
||||||
|
RUNITE_ORE(ItemID.RUNITE_ORE, Skill.SMITHING, "Ore"),
|
||||||
|
|
||||||
|
// Bars
|
||||||
|
BRONZE_BAR(ItemID.BRONZE_BAR, Skill.SMITHING, "Bars"),
|
||||||
|
IRON_BAR(ItemID.IRON_BAR, Skill.SMITHING, "Bars"),
|
||||||
|
STEEL_BAR(ItemID.STEEL_BAR, Skill.SMITHING, "Bars"),
|
||||||
|
MITHRIL_BAR(ItemID.MITHRIL_BAR, Skill.SMITHING, "Bars"),
|
||||||
|
ADAMANTITE_BAR(ItemID.ADAMANTITE_BAR, Skill.SMITHING, "Bars"),
|
||||||
|
RUNITE_BAR(ItemID.RUNITE_BAR, Skill.SMITHING, "Bars"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Farming Items
|
||||||
|
*/
|
||||||
|
// Seeds
|
||||||
|
ACORN(ItemID.ACORN, Skill.FARMING, "Seeds"),
|
||||||
|
WILLOW_SEED(ItemID.WILLOW_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
MAPLE_SEED(ItemID.MAPLE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
YEW_SEED(ItemID.YEW_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
MAGIC_SEED(ItemID.MAGIC_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
APPLE_TREE_SEED(ItemID.APPLE_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
BANANA_TREE_SEED(ItemID.BANANA_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
ORANGE_TREE_SEED(ItemID.ORANGE_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
CURRY_TREE_SEED(ItemID.CURRY_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
PINEAPPLE_SEED(ItemID.PINEAPPLE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
PAPAYA_TREE_SEED(ItemID.PAPAYA_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
PALM_TREE_SEED(ItemID.PALM_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
CALQUAT_TREE_SEED(ItemID.CALQUAT_TREE_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
TEAK_SEED(ItemID.TEAK_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
MAHOGANY_SEED(ItemID.MAHOGANY_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
SPIRIT_SEED(ItemID.SPIRIT_SEED, Skill.FARMING, "Seeds"),
|
||||||
|
|
||||||
|
// Saplings
|
||||||
|
OAK_SAPLING(ItemID.OAK_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
WILLOW_SAPLING(ItemID.WILLOW_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
MAPLE_SAPLING(ItemID.MAPLE_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
YEW_SAPLING(ItemID.YEW_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
MAGIC_SAPLING(ItemID.MAGIC_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
APPLE_TREE_SAPLING(ItemID.APPLE_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
BANANA_TREE_SAPLING(ItemID.BANANA_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
ORANGE_TREE_SAPLING(ItemID.ORANGE_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
CURRY_TREE_SAPLING(ItemID.CURRY_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
PINEAPPLE_SAPLING(ItemID.PINEAPPLE_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
PAPAYA_TREE_SAPLING(ItemID.PAPAYA_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
PALM_TREE_SAPLING(ItemID.PALM_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
CALQUAT_TREE_SAPLING(ItemID.CALQUAT_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
TEAK_SAPLING(ItemID.TEAK_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
MAHOGANY_SAPLING(ItemID.MAHOGANY_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
SPIRIT_SAPLING(ItemID.SPIRIT_SAPLING, Skill.FARMING, "Saplings"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final int itemID;
|
||||||
|
private final Skill skill;
|
||||||
|
private final String category;
|
||||||
|
private boolean ignoreBonus;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
// Stores the item composition info we use since we don't operate on the game thread
|
||||||
|
private ItemInfo itemInfo = null;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Activity selectedActivity;
|
||||||
|
|
||||||
|
private static final Multimap<Skill, CriticalItem> SKILL_MAP = ArrayListMultimap.create();
|
||||||
|
private static final Map<Integer, CriticalItem> ITEM_ID_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for (CriticalItem i : values())
|
||||||
|
{
|
||||||
|
Skill s = i.getSkill();
|
||||||
|
SKILL_MAP.put(s, i);
|
||||||
|
ITEM_ID_MAP.put(i.getItemID(), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalItem(int itemID, Skill skill, String category, boolean ignoreBonus)
|
||||||
|
{
|
||||||
|
this.itemID = itemID;
|
||||||
|
this.category = category;
|
||||||
|
this.skill = skill;
|
||||||
|
this.ignoreBonus = ignoreBonus;
|
||||||
|
}
|
||||||
|
|
||||||
|
CriticalItem(int itemID, Skill skill, String category)
|
||||||
|
{
|
||||||
|
this(itemID, skill, category, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Collection<CriticalItem> getBySkill(Skill skill)
|
||||||
|
{
|
||||||
|
Collection<CriticalItem> items = SKILL_MAP.get(skill);
|
||||||
|
if (items == null)
|
||||||
|
{
|
||||||
|
items = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CriticalItem getByItemId(int id)
|
||||||
|
{
|
||||||
|
return ITEM_ID_MAP.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches the Item Composition to each CriticalItem on client initial load
|
||||||
|
*
|
||||||
|
* @param m ItemManager
|
||||||
|
*/
|
||||||
|
public static void prepareItemDefinitions(ItemManager m)
|
||||||
|
{
|
||||||
|
for (CriticalItem i : values())
|
||||||
|
{
|
||||||
|
if (i.itemInfo != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ItemDefinition c = m.getItemDefinition(i.getItemID());
|
||||||
|
i.itemInfo = new ItemInfo(c.getName(), c.isStackable());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,23 +24,13 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.skillcalculator.banked.beans;
|
package net.runelite.client.plugins.skillcalculator.banked.beans;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Data;
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
@Data
|
||||||
public class SecondaryItem
|
@AllArgsConstructor
|
||||||
|
public class ItemInfo
|
||||||
{
|
{
|
||||||
private final int id;
|
private String name;
|
||||||
private final int qty;
|
private boolean stackable;
|
||||||
|
}
|
||||||
SecondaryItem(int id, int qty)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
this.qty = qty;
|
|
||||||
}
|
|
||||||
|
|
||||||
SecondaryItem(int id)
|
|
||||||
{
|
|
||||||
this(id, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Sean Dewar <https://github.com/seandewar>
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -22,22 +22,15 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.runenergy;
|
package net.runelite.client.plugins.skillcalculator.banked.beans;
|
||||||
|
|
||||||
import net.runelite.client.config.Config;
|
import lombok.AllArgsConstructor;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
import lombok.Data;
|
||||||
import net.runelite.client.config.ConfigItem;
|
|
||||||
|
|
||||||
@ConfigGroup("runenergy")
|
@Data
|
||||||
public interface RunEnergyConfig extends Config
|
@AllArgsConstructor
|
||||||
|
class ItemStack
|
||||||
{
|
{
|
||||||
@ConfigItem(
|
private int id;
|
||||||
keyName = "replaceOrbText",
|
private int qty;
|
||||||
name = "Replace orb text with run time left",
|
}
|
||||||
description = "Show the remaining run time (in seconds) next in the energy orb."
|
|
||||||
)
|
|
||||||
default boolean replaceOrbText()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked.beans;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum Secondaries
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Herblore
|
||||||
|
*/
|
||||||
|
UNFINISHED_POTION(new ItemStack(ItemID.VIAL_OF_WATER, 1)),
|
||||||
|
SWAMP_TAR(new ItemStack(ItemID.SWAMP_TAR, 15)),
|
||||||
|
// Guam
|
||||||
|
ATTACK_POTION(new ItemStack(ItemID.EYE_OF_NEWT, 1)),
|
||||||
|
// Marrentil
|
||||||
|
ANTIPOISON(new ItemStack(ItemID.UNICORN_HORN_DUST, 1)),
|
||||||
|
// Tarromin
|
||||||
|
STRENGTH_POTION(new ItemStack(ItemID.LIMPWURT_ROOT, 1)),
|
||||||
|
SERUM_207(new ItemStack(ItemID.ASHES, 1)),
|
||||||
|
// Harralander
|
||||||
|
COMPOST_POTION(new ItemStack(ItemID.VOLCANIC_ASH, 1)),
|
||||||
|
RESTORE_POTION(new ItemStack(ItemID.RED_SPIDERS_EGGS, 1)),
|
||||||
|
ENERGY_POTION(new ItemStack(ItemID.CHOCOLATE_DUST, 1)),
|
||||||
|
COMBAT_POTION(new ItemStack(ItemID.GOAT_HORN_DUST, 1)),
|
||||||
|
// Ranarr Weed
|
||||||
|
DEFENCE_POTION(new ItemStack(ItemID.WHITE_BERRIES, 1)),
|
||||||
|
PRAYER_POTION(new ItemStack(ItemID.SNAPE_GRASS, 1)),
|
||||||
|
// Toadflax
|
||||||
|
AGILITY_POTION(new ItemStack(ItemID.TOADS_LEGS, 1)),
|
||||||
|
SARADOMIN_BREW(new ItemStack(ItemID.CRUSHED_NEST, 1)),
|
||||||
|
// Irit
|
||||||
|
SUPER_ATTACK(new ItemStack(ItemID.EYE_OF_NEWT, 1)),
|
||||||
|
SUPERANTIPOISON(new ItemStack(ItemID.UNICORN_HORN_DUST, 1)),
|
||||||
|
// Avantoe
|
||||||
|
FISHING_POTION(new ItemStack(ItemID.SNAPE_GRASS, 1)),
|
||||||
|
SUPER_ENERGY_POTION(new ItemStack(ItemID.MORT_MYRE_FUNGUS, 1)),
|
||||||
|
HUNTER_POTION(new ItemStack(ItemID.KEBBIT_TEETH_DUST, 1)),
|
||||||
|
// Kwuarm
|
||||||
|
SUPER_STRENGTH(new ItemStack(ItemID.LIMPWURT_ROOT, 1)),
|
||||||
|
// Snapdragon
|
||||||
|
SUPER_RESTORE(new ItemStack(ItemID.RED_SPIDERS_EGGS, 1)),
|
||||||
|
SANFEW_SERUM(new ItemStack(ItemID.SNAKE_WEED, 1), new ItemStack(ItemID.UNICORN_HORN_DUST, 1), new ItemStack(ItemID.SUPER_RESTORE4, 1), new ItemStack(ItemID.NAIL_BEAST_NAILS, 1)),
|
||||||
|
// Cadantine
|
||||||
|
SUPER_DEFENCE_POTION(new ItemStack(ItemID.WHITE_BERRIES, 1)),
|
||||||
|
// Lantadyme
|
||||||
|
ANTIFIRE_POTION(new ItemStack(ItemID.DRAGON_SCALE_DUST, 1)),
|
||||||
|
MAGIC_POTION(new ItemStack(ItemID.POTATO_CACTUS, 1)),
|
||||||
|
// Dwarf Weed
|
||||||
|
RANGING_POTION(new ItemStack(ItemID.WINE_OF_ZAMORAK, 1)),
|
||||||
|
// Torstol
|
||||||
|
ZAMORAK_BREW(new ItemStack(ItemID.JANGERBERRIES, 1)),
|
||||||
|
SUPER_COMBAT_POTION(new ItemStack(ItemID.SUPER_ATTACK4, 1), new ItemStack(ItemID.SUPER_STRENGTH4, 1), new ItemStack(ItemID.SUPER_DEFENCE4, 1)),
|
||||||
|
ANTIVENOM_PLUS(new ItemStack(ItemID.ANTIVENOM4, 1)),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smithing
|
||||||
|
*/
|
||||||
|
COAL_ORE(new ItemStack(ItemID.COAL, 1)),
|
||||||
|
COAL_ORE_2(new ItemStack(ItemID.COAL, 2)),
|
||||||
|
COAL_ORE_4(new ItemStack(ItemID.COAL, 4)),
|
||||||
|
COAL_ORE_6(new ItemStack(ItemID.COAL, 6)),
|
||||||
|
COAL_ORE_8(new ItemStack(ItemID.COAL, 8)),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crafting
|
||||||
|
*/
|
||||||
|
GOLD_BAR(new ItemStack(ItemID.GOLD_BAR, 1)),
|
||||||
|
SILVER_BAR(new ItemStack(ItemID.SILVER_BAR, 1)),
|
||||||
|
WATER_ORB(new ItemStack(ItemID.WATER_ORB, 1)),
|
||||||
|
EARTH_ORB(new ItemStack(ItemID.EARTH_ORB, 1)),
|
||||||
|
FIRE_ORB(new ItemStack(ItemID.FIRE_ORB, 1)),
|
||||||
|
AIR_ORB(new ItemStack(ItemID.AIR_ORB, 1)),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construction
|
||||||
|
*/
|
||||||
|
COINS_100(new ItemStack(ItemID.COINS_995, 100)),
|
||||||
|
COINS_250(new ItemStack(ItemID.COINS_995, 250)),
|
||||||
|
COINS_500(new ItemStack(ItemID.COINS_995, 500)),
|
||||||
|
COINS_1500(new ItemStack(ItemID.COINS_995, 1500)),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cooking
|
||||||
|
*/
|
||||||
|
JUG_OF_WATER(new ItemStack(ItemID.JUG_OF_WATER, 1)),
|
||||||
|
;
|
||||||
|
private final ItemStack[] items;
|
||||||
|
|
||||||
|
Secondaries(ItemStack... items)
|
||||||
|
{
|
||||||
|
this.items = items;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked.beans;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import java.util.Collection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum XpModifiers
|
||||||
|
{
|
||||||
|
LIT_GILDER_ALTAR(Skill.PRAYER, "Lit Gilded Altar (350%)", 3.5f),
|
||||||
|
ECTOFUNTUS(Skill.PRAYER, "Ectofuntus (400%)", 4),
|
||||||
|
WILDY_ALTAR(Skill.PRAYER, "Wildy Altar (700%)", 7),
|
||||||
|
|
||||||
|
FARMERS_OUTFIT(Skill.FARMING, "Farmer's Outfit (+2.5%)", 1.025f);
|
||||||
|
|
||||||
|
private final Skill skill;
|
||||||
|
private final String name;
|
||||||
|
private final float modifier;
|
||||||
|
|
||||||
|
private final static Multimap<Skill, XpModifiers> MODIFIERS_MAP;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
final ImmutableMultimap.Builder<Skill, XpModifiers> map = ImmutableMultimap.builder();
|
||||||
|
for (final XpModifiers m : values())
|
||||||
|
{
|
||||||
|
map.put(m.skill, m);
|
||||||
|
}
|
||||||
|
MODIFIERS_MAP = map.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Collection<XpModifiers> getModifiersBySkill(final Skill skill)
|
||||||
|
{
|
||||||
|
return MODIFIERS_MAP.get(skill);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked.components;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.client.game.AsyncBufferedImage;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculator;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
|
||||||
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
public class GridItem extends JLabel
|
||||||
|
{
|
||||||
|
private final static String IGNORE = "Ignore Item";
|
||||||
|
private final static String INCLUDE = "Include Item";
|
||||||
|
|
||||||
|
private static final Color UNSELECTED_BACKGROUND = ColorScheme.DARKER_GRAY_COLOR;
|
||||||
|
private static final Color UNSELECTED_HOVER_BACKGROUND = ColorScheme.DARKER_GRAY_HOVER_COLOR;
|
||||||
|
|
||||||
|
private static final Color SELECTED_BACKGROUND = new Color(0, 70, 0);
|
||||||
|
private static final Color SELECTED_HOVER_BACKGROUND = new Color(0, 100, 0);
|
||||||
|
|
||||||
|
private static final Color IGNORED_BACKGROUND = new Color(90, 0, 0);
|
||||||
|
private static final Color IGNORED_HOVER_BACKGROUND = new Color(120, 0, 0);
|
||||||
|
|
||||||
|
/* To be executed when this element is clicked */
|
||||||
|
@Setter(AccessLevel.PUBLIC)
|
||||||
|
private BooleanSupplier onSelectEvent;
|
||||||
|
|
||||||
|
/* To be executed when this element is ignored */
|
||||||
|
@Setter(AccessLevel.PUBLIC)
|
||||||
|
private BooleanSupplier onIgnoreEvent;
|
||||||
|
|
||||||
|
private final SelectionGrid parent;
|
||||||
|
private final BankedItem bankedItem;
|
||||||
|
private int amount;
|
||||||
|
|
||||||
|
private boolean selected = false;
|
||||||
|
private boolean ignored = false;
|
||||||
|
|
||||||
|
private final JMenuItem IGNORE_OPTION = new JMenuItem(IGNORE);
|
||||||
|
|
||||||
|
GridItem(final SelectionGrid parent, final BankedItem item, final AsyncBufferedImage icon, final int amount)
|
||||||
|
{
|
||||||
|
super("");
|
||||||
|
|
||||||
|
this.parent = parent;
|
||||||
|
this.bankedItem = item;
|
||||||
|
|
||||||
|
this.setOpaque(true);
|
||||||
|
this.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
this.setBorder(BorderFactory.createEmptyBorder(5, 0, 2, 0));
|
||||||
|
|
||||||
|
this.setVerticalAlignment(SwingConstants.CENTER);
|
||||||
|
this.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
|
updateIcon(icon, amount);
|
||||||
|
updateToolTip();
|
||||||
|
|
||||||
|
this.addMouseListener(new MouseAdapter()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent mouseEvent)
|
||||||
|
{
|
||||||
|
if (mouseEvent.getButton() == MouseEvent.BUTTON1)
|
||||||
|
{
|
||||||
|
select();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e)
|
||||||
|
{
|
||||||
|
final GridItem item = (GridItem) e.getSource();
|
||||||
|
item.setBackground(getHoverBackgroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e)
|
||||||
|
{
|
||||||
|
final GridItem item = (GridItem) e.getSource();
|
||||||
|
item.setBackground(getBackgroundColor());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
IGNORE_OPTION.addActionListener(e ->
|
||||||
|
{
|
||||||
|
// Update ignored flag now so event knows new state
|
||||||
|
this.ignored = !this.ignored;
|
||||||
|
|
||||||
|
if (onIgnoreEvent != null && !onIgnoreEvent.getAsBoolean())
|
||||||
|
{
|
||||||
|
// Reset state
|
||||||
|
this.ignored = !this.ignored;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGNORE_OPTION.setText(this.ignored ? INCLUDE : IGNORE);
|
||||||
|
this.setBackground(getBackgroundColor());
|
||||||
|
});
|
||||||
|
|
||||||
|
final JPopupMenu popupMenu = new JPopupMenu();
|
||||||
|
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||||
|
popupMenu.add(IGNORE_OPTION);
|
||||||
|
|
||||||
|
this.setComponentPopupMenu(popupMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color getBackgroundColor()
|
||||||
|
{
|
||||||
|
return ignored ? IGNORED_BACKGROUND : (selected ? SELECTED_BACKGROUND : UNSELECTED_BACKGROUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color getHoverBackgroundColor()
|
||||||
|
{
|
||||||
|
return ignored ? IGNORED_HOVER_BACKGROUND : (selected ? SELECTED_HOVER_BACKGROUND : UNSELECTED_HOVER_BACKGROUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void select()
|
||||||
|
{
|
||||||
|
if (onSelectEvent != null && !onSelectEvent.getAsBoolean())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selected = true;
|
||||||
|
setBackground(getBackgroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
void unselect()
|
||||||
|
{
|
||||||
|
selected = false;
|
||||||
|
setBackground(getBackgroundColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateIcon(final AsyncBufferedImage icon, final int amount)
|
||||||
|
{
|
||||||
|
icon.addTo(this);
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateToolTip()
|
||||||
|
{
|
||||||
|
this.setToolTipText(buildToolTip());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildToolTip()
|
||||||
|
{
|
||||||
|
String tip = "<html>" + bankedItem.getItem().getItemInfo().getName();
|
||||||
|
|
||||||
|
final Activity a = bankedItem.getItem().getSelectedActivity();
|
||||||
|
if (a != null)
|
||||||
|
{
|
||||||
|
final double xp = parent.getCalc().getItemXpRate(bankedItem);
|
||||||
|
tip += "<br/>Activity: " + a.getName();
|
||||||
|
tip += "<br/>Xp/Action: " + BankedCalculator.XP_FORMAT_COMMA.format(xp);
|
||||||
|
tip += "<br/>Total Xp: " + BankedCalculator.XP_FORMAT_COMMA.format(xp * amount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tip += "<br/>Outputs: " + bankedItem.getItem().getItemInfo().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tip + "</html>";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,354 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked.components;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.event.ItemEvent;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.border.Border;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.Constants;
|
||||||
|
import net.runelite.client.game.AsyncBufferedImage;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculator;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.CriticalItem;
|
||||||
|
import net.runelite.client.ui.ColorScheme;
|
||||||
|
import net.runelite.client.ui.FontManager;
|
||||||
|
import net.runelite.client.ui.components.ComboBoxIconEntry;
|
||||||
|
import net.runelite.client.ui.components.ComboBoxListRenderer;
|
||||||
|
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||||
|
|
||||||
|
public class ModifyPanel extends JPanel
|
||||||
|
{
|
||||||
|
private static final Dimension ICON_SIZE = new Dimension(Constants.ITEM_SPRITE_WIDTH, Constants.ITEM_SPRITE_HEIGHT);
|
||||||
|
private static final DecimalFormat FORMAT_COMMA = new DecimalFormat("#,###.#");
|
||||||
|
|
||||||
|
private static final Border PANEL_BORDER = new EmptyBorder(3, 0, 3, 0);
|
||||||
|
private static final Color BACKGROUND_COLOR = ColorScheme.DARKER_GRAY_COLOR;
|
||||||
|
|
||||||
|
private final BankedCalculator calc;
|
||||||
|
private final ItemManager itemManager;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private BankedItem bankedItem;
|
||||||
|
private Map<CriticalItem, Integer> linkedMap;
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private int amount = 0;
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private double total = 0;
|
||||||
|
|
||||||
|
// Banked item information display
|
||||||
|
private final JPanel labelContainer;
|
||||||
|
private final JLabel image;
|
||||||
|
private final JShadowedLabel labelName;
|
||||||
|
private final JShadowedLabel labelValue;
|
||||||
|
|
||||||
|
// Elements used to adjust banked item
|
||||||
|
private final JPanel adjustContainer;
|
||||||
|
|
||||||
|
public ModifyPanel(final BankedCalculator calc, final ItemManager itemManager)
|
||||||
|
{
|
||||||
|
this.calc = calc;
|
||||||
|
this.itemManager = itemManager;
|
||||||
|
|
||||||
|
this.setLayout(new GridBagLayout());
|
||||||
|
this.setBorder(PANEL_BORDER);
|
||||||
|
this.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
|
||||||
|
// Banked item information display
|
||||||
|
labelContainer = new JPanel();
|
||||||
|
labelContainer.setLayout(new BorderLayout());
|
||||||
|
labelContainer.setBackground(BACKGROUND_COLOR);
|
||||||
|
labelContainer.setBorder(new EmptyBorder(5, 0, 5, 0));
|
||||||
|
|
||||||
|
// Icon
|
||||||
|
image = new JLabel();
|
||||||
|
image.setMinimumSize(ICON_SIZE);
|
||||||
|
image.setMaximumSize(ICON_SIZE);
|
||||||
|
image.setPreferredSize(ICON_SIZE);
|
||||||
|
image.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
image.setBorder(new EmptyBorder(0, 8, 0, 0));
|
||||||
|
|
||||||
|
// Wrapper panel for the shadowed labels
|
||||||
|
final JPanel uiInfo = new JPanel(new GridLayout(2, 1));
|
||||||
|
uiInfo.setBorder(new EmptyBorder(0, 5, 0, 0));
|
||||||
|
uiInfo.setBackground(BACKGROUND_COLOR);
|
||||||
|
|
||||||
|
labelName = new JShadowedLabel();
|
||||||
|
labelName.setForeground(Color.WHITE);
|
||||||
|
labelName.setVerticalAlignment(SwingUtilities.BOTTOM);
|
||||||
|
|
||||||
|
labelValue = new JShadowedLabel();
|
||||||
|
labelValue.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
labelValue.setVerticalAlignment(SwingUtilities.TOP);
|
||||||
|
|
||||||
|
uiInfo.add(labelName);
|
||||||
|
uiInfo.add(labelValue);
|
||||||
|
|
||||||
|
// Append elements to item info panel
|
||||||
|
labelContainer.add(image, BorderLayout.LINE_START);
|
||||||
|
labelContainer.add(uiInfo, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// Container for tools to adjust banked calculation for this item
|
||||||
|
adjustContainer = new JPanel();
|
||||||
|
adjustContainer.setLayout(new GridBagLayout());
|
||||||
|
adjustContainer.setBackground(BACKGROUND_COLOR);
|
||||||
|
|
||||||
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
|
c.fill = GridBagConstraints.BOTH;
|
||||||
|
c.weightx = 1;
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 0;
|
||||||
|
c.ipady = 0;
|
||||||
|
|
||||||
|
this.add(labelContainer, c);
|
||||||
|
c.gridy++;
|
||||||
|
this.add(adjustContainer, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the UI for the selected item
|
||||||
|
public void setBankedItem(final BankedItem bankedItem)
|
||||||
|
{
|
||||||
|
if (bankedItem == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bankedItem = bankedItem;
|
||||||
|
if (this.calc.getConfig().cascadeBankedXp())
|
||||||
|
{
|
||||||
|
this.linkedMap = this.calc.createLinksMap(bankedItem);
|
||||||
|
|
||||||
|
this.amount = bankedItem.getQty();
|
||||||
|
for (int i : linkedMap.values())
|
||||||
|
{
|
||||||
|
this.amount += i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.linkedMap = new HashMap<>();
|
||||||
|
this.amount = this.calc.getItemQty(bankedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateImageTooltip();
|
||||||
|
updateLabelContainer();
|
||||||
|
updateAdjustContainer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateImageTooltip()
|
||||||
|
{
|
||||||
|
final StringBuilder b = new StringBuilder("<html>");
|
||||||
|
b.append(bankedItem.getQty()).append(" x ").append(bankedItem.getItem().getItemInfo().getName());
|
||||||
|
|
||||||
|
for (final Map.Entry<CriticalItem, Integer> e : this.linkedMap.entrySet())
|
||||||
|
{
|
||||||
|
b.append("<br/>").append(e.getValue()).append(" x ").append(e.getKey().getItemInfo().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
b.append("</html>");
|
||||||
|
this.image.setToolTipText(b.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLabelContainer()
|
||||||
|
{
|
||||||
|
final CriticalItem item = bankedItem.getItem();
|
||||||
|
|
||||||
|
// Update image icon
|
||||||
|
final boolean stackable = item.getItemInfo().isStackable() || amount > 1;
|
||||||
|
final AsyncBufferedImage icon = itemManager.getImage(item.getItemID(), amount, stackable);
|
||||||
|
final Runnable resize = () -> image.setIcon(new ImageIcon(icon.getScaledInstance(ICON_SIZE.width, ICON_SIZE.height, Image.SCALE_SMOOTH)));
|
||||||
|
icon.onChanged(resize);
|
||||||
|
resize.run();
|
||||||
|
|
||||||
|
final String itemName = item.getItemInfo().getName();
|
||||||
|
labelName.setText(itemName);
|
||||||
|
|
||||||
|
double xp = calc.getItemXpRate(bankedItem);
|
||||||
|
total = amount * xp;
|
||||||
|
|
||||||
|
final String value = FORMAT_COMMA.format(total) + "xp";
|
||||||
|
labelValue.setText(value);
|
||||||
|
|
||||||
|
labelContainer.setToolTipText("<html>" + itemName
|
||||||
|
+ "<br/>xp: " + xp
|
||||||
|
+ "<br/>Total: " + total + "</html");
|
||||||
|
|
||||||
|
labelContainer.revalidate();
|
||||||
|
labelContainer.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAdjustContainer()
|
||||||
|
{
|
||||||
|
adjustContainer.removeAll();
|
||||||
|
|
||||||
|
final JLabel label = new JLabel("Output:");
|
||||||
|
label.setVerticalAlignment(JLabel.CENTER);
|
||||||
|
label.setHorizontalAlignment(JLabel.CENTER);
|
||||||
|
|
||||||
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
c.weightx = 1;
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 0;
|
||||||
|
c.ipady = 0;
|
||||||
|
|
||||||
|
adjustContainer.add(label, c);
|
||||||
|
c.gridy++;
|
||||||
|
|
||||||
|
final float xpFactor = (bankedItem.getItem().isIgnoreBonus() ? 1.0f : this.calc.getXpFactor());
|
||||||
|
|
||||||
|
final List<Activity> activities = Activity.getByCriticalItem(bankedItem.getItem(), calc.getSkillLevel());
|
||||||
|
if (activities == null || activities.size() == 0)
|
||||||
|
{
|
||||||
|
adjustContainer.add(new JLabel("Unknown"));
|
||||||
|
}
|
||||||
|
else if (activities.size() == 1)
|
||||||
|
{
|
||||||
|
final Activity a = activities.get(0);
|
||||||
|
|
||||||
|
final AsyncBufferedImage img = itemManager.getImage(a.getIcon());
|
||||||
|
final ImageIcon icon = new ImageIcon(img);
|
||||||
|
final double xp = a.getXp() * xpFactor;
|
||||||
|
final JPanel container = createShadowedLabel(icon, a.getName(), FORMAT_COMMA.format(xp) + "xp");
|
||||||
|
|
||||||
|
img.onChanged(() ->
|
||||||
|
{
|
||||||
|
icon.setImage(img);
|
||||||
|
container.repaint();
|
||||||
|
});
|
||||||
|
|
||||||
|
adjustContainer.add(container, c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final JComboBox<ComboBoxIconEntry> dropdown = new JComboBox<>();
|
||||||
|
final ComboBoxListRenderer renderer = new ComboBoxListRenderer();
|
||||||
|
dropdown.setRenderer(renderer);
|
||||||
|
|
||||||
|
for (final Activity option : activities)
|
||||||
|
{
|
||||||
|
final double xp = option.getXp() * xpFactor;
|
||||||
|
String name = option.getName();
|
||||||
|
if (xp > 0)
|
||||||
|
{
|
||||||
|
name += " (" + FORMAT_COMMA.format(xp) + "xp)";
|
||||||
|
}
|
||||||
|
|
||||||
|
final AsyncBufferedImage img = itemManager.getImage(option.getIcon());
|
||||||
|
final ImageIcon icon = new ImageIcon(img);
|
||||||
|
final ComboBoxIconEntry entry = new ComboBoxIconEntry(icon, name, option);
|
||||||
|
dropdown.addItem(entry);
|
||||||
|
|
||||||
|
img.onChanged(() ->
|
||||||
|
{
|
||||||
|
icon.setImage(img);
|
||||||
|
dropdown.revalidate();
|
||||||
|
dropdown.repaint();
|
||||||
|
});
|
||||||
|
|
||||||
|
final Activity selected = bankedItem.getItem().getSelectedActivity();
|
||||||
|
if (option.equals(selected))
|
||||||
|
{
|
||||||
|
dropdown.setSelectedItem(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add click event handler now to prevent above code from triggering it.
|
||||||
|
dropdown.addItemListener(e ->
|
||||||
|
{
|
||||||
|
if (e.getStateChange() == ItemEvent.SELECTED && e.getItem() instanceof ComboBoxIconEntry)
|
||||||
|
{
|
||||||
|
final ComboBoxIconEntry source = (ComboBoxIconEntry) e.getItem();
|
||||||
|
if (source.getData() instanceof Activity)
|
||||||
|
{
|
||||||
|
final Activity selectedActivity = ((Activity) source.getData());
|
||||||
|
calc.activitySelected(bankedItem, selectedActivity);
|
||||||
|
updateLabelContainer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
adjustContainer.add(dropdown, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private JPanel createShadowedLabel(final ImageIcon icon, final String name, final String value)
|
||||||
|
{
|
||||||
|
// Wrapper panel for the shadowed labels
|
||||||
|
final JPanel wrapper = new JPanel(new GridLayout(2, 1));
|
||||||
|
wrapper.setBorder(new EmptyBorder(0, 5, 0, 0));
|
||||||
|
wrapper.setBackground(BACKGROUND_COLOR);
|
||||||
|
|
||||||
|
final JShadowedLabel nameLabel = new JShadowedLabel(name);
|
||||||
|
nameLabel.setForeground(Color.WHITE);
|
||||||
|
nameLabel.setVerticalAlignment(SwingUtilities.BOTTOM);
|
||||||
|
|
||||||
|
final JShadowedLabel valueLabel = new JShadowedLabel(value);
|
||||||
|
valueLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||||
|
valueLabel.setVerticalAlignment(SwingUtilities.TOP);
|
||||||
|
|
||||||
|
wrapper.add(nameLabel);
|
||||||
|
wrapper.add(valueLabel);
|
||||||
|
|
||||||
|
final JPanel container = new JPanel();
|
||||||
|
container.setLayout(new BorderLayout());
|
||||||
|
container.setBackground(BACKGROUND_COLOR);
|
||||||
|
container.setBorder(new EmptyBorder(5, 0, 5, 0));
|
||||||
|
|
||||||
|
final JLabel image = new JLabel();
|
||||||
|
image.setMinimumSize(ICON_SIZE);
|
||||||
|
image.setMaximumSize(ICON_SIZE);
|
||||||
|
image.setPreferredSize(ICON_SIZE);
|
||||||
|
image.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
image.setBorder(new EmptyBorder(0, 8, 0, 0));
|
||||||
|
|
||||||
|
image.setIcon(icon);
|
||||||
|
|
||||||
|
container.add(image, BorderLayout.LINE_START);
|
||||||
|
container.add(wrapper, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.skillcalculator.banked.components;
|
||||||
|
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import net.runelite.client.game.AsyncBufferedImage;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.BankedCalculator;
|
||||||
|
import net.runelite.client.plugins.skillcalculator.banked.beans.BankedItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A grid that supports mouse events
|
||||||
|
*/
|
||||||
|
public class SelectionGrid extends JPanel
|
||||||
|
{
|
||||||
|
private static final int ITEMS_PER_ROW = 5;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private final Map<BankedItem, GridItem> panelMap = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private BankedItem selectedItem;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private BankedItem lastIgnoredItem;
|
||||||
|
|
||||||
|
/* To be executed when this element is clicked */
|
||||||
|
@Setter(AccessLevel.PUBLIC)
|
||||||
|
private BooleanSupplier onSelectEvent;
|
||||||
|
|
||||||
|
/* To be executed when this element is ignored */
|
||||||
|
@Setter(AccessLevel.PUBLIC)
|
||||||
|
private BooleanSupplier onIgnoreEvent;
|
||||||
|
|
||||||
|
@Getter(AccessLevel.PUBLIC)
|
||||||
|
private final BankedCalculator calc;
|
||||||
|
|
||||||
|
public SelectionGrid(final BankedCalculator calc, final Collection<BankedItem> items, final ItemManager itemManager)
|
||||||
|
{
|
||||||
|
this.calc = calc;
|
||||||
|
// Create a panel for every item
|
||||||
|
for (final BankedItem item : items)
|
||||||
|
{
|
||||||
|
final int qty = calc.getItemQty(item);
|
||||||
|
final boolean stackable = item.getItem().getItemInfo().isStackable() || qty > 1;
|
||||||
|
final AsyncBufferedImage img = itemManager.getImage(item.getItem().getItemID(), qty, stackable);
|
||||||
|
|
||||||
|
final GridItem gridItem = new GridItem(this, item, img, qty);
|
||||||
|
|
||||||
|
gridItem.setOnSelectEvent(() -> selected(item));
|
||||||
|
gridItem.setOnIgnoreEvent(() -> ignore(item));
|
||||||
|
panelMap.put(item, gridItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshGridDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshGridDisplay()
|
||||||
|
{
|
||||||
|
this.removeAll();
|
||||||
|
|
||||||
|
final List<GridItem> items = panelMap.values().stream().filter(gi -> gi.getAmount() > 0).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Calculates how many rows need to be display to fit all items
|
||||||
|
final int rowSize = ((items.size() % ITEMS_PER_ROW == 0) ? 0 : 1) + items.size() / ITEMS_PER_ROW;
|
||||||
|
setLayout(new GridLayout(rowSize, ITEMS_PER_ROW, 1, 1));
|
||||||
|
|
||||||
|
for (final GridItem gridItem : items)
|
||||||
|
{
|
||||||
|
// Select the first option
|
||||||
|
if (selectedItem == null)
|
||||||
|
{
|
||||||
|
gridItem.select();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.add(gridItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean selected(final BankedItem item)
|
||||||
|
{
|
||||||
|
final BankedItem old = this.selectedItem;
|
||||||
|
if (item.equals(old))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set selected item now so the boolean can see what was just clicked
|
||||||
|
this.selectedItem = item;
|
||||||
|
if (onSelectEvent != null && !onSelectEvent.getAsBoolean())
|
||||||
|
{
|
||||||
|
this.selectedItem = old;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final GridItem gridItem = panelMap.get(old);
|
||||||
|
if (gridItem != null)
|
||||||
|
{
|
||||||
|
gridItem.unselect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean ignore(final BankedItem item)
|
||||||
|
{
|
||||||
|
this.lastIgnoredItem = item;
|
||||||
|
return onIgnoreEvent.getAsBoolean();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,402 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
|
||||||
* 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.skillcalculator.banked.ui;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.GridBagConstraints;
|
|
||||||
import java.awt.GridBagLayout;
|
|
||||||
import java.awt.GridLayout;
|
|
||||||
import java.awt.Image;
|
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.SwingConstants;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.border.Border;
|
|
||||||
import javax.swing.border.EmptyBorder;
|
|
||||||
import javax.swing.border.MatteBorder;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.runelite.client.game.AsyncBufferedImage;
|
|
||||||
import net.runelite.client.game.ItemManager;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.BankedCalculator;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.CriticalItem;
|
|
||||||
import net.runelite.client.plugins.skillcalculator.banked.beans.Activity;
|
|
||||||
import net.runelite.client.ui.ColorScheme;
|
|
||||||
import net.runelite.client.ui.FontManager;
|
|
||||||
import net.runelite.client.ui.components.materialtabs.MaterialTab;
|
|
||||||
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;
|
|
||||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
|
||||||
import net.runelite.client.util.StackFormatter;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class CriticalItemPanel extends JPanel
|
|
||||||
{
|
|
||||||
private static final Dimension ICON_SIZE = new Dimension(36, 36);
|
|
||||||
private static final DecimalFormat FORMAT_COMMA = new DecimalFormat("#,###.#");
|
|
||||||
|
|
||||||
private static final BufferedImage ICON_SETTINGS;
|
|
||||||
|
|
||||||
private static final Border PANEL_BORDER = new EmptyBorder(3, 0, 3, 0);
|
|
||||||
private final static Color BACKGROUND_COLOR = ColorScheme.DARKER_GRAY_COLOR;
|
|
||||||
private final static Color BUTTON_HOVER_COLOR = ColorScheme.DARKER_GRAY_HOVER_COLOR;
|
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
BufferedImage i1;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
synchronized (ImageIO.class)
|
|
||||||
{
|
|
||||||
i1 = ImageIO.read(BankedCalculator.class.getResourceAsStream("view-more-white.png"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
ICON_SETTINGS = i1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final BankedCalculator bankedCalculator;
|
|
||||||
private final CriticalItem item;
|
|
||||||
private final ItemManager itemManager;
|
|
||||||
private double xp;
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
|
||||||
private int amount;
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
|
||||||
private double total;
|
|
||||||
private Map<CriticalItem, Integer> linkedMap;
|
|
||||||
private JShadowedLabel labelValue;
|
|
||||||
|
|
||||||
private final JPanel infoContainer;
|
|
||||||
private final JLabel image;
|
|
||||||
private boolean infoVisibility = false;
|
|
||||||
|
|
||||||
public CriticalItemPanel(BankedCalculator bankedCalculator, ItemManager itemManager, CriticalItem item, double xp, int amount, Map<CriticalItem, Integer> linkedMap)
|
|
||||||
{
|
|
||||||
this.bankedCalculator = bankedCalculator;
|
|
||||||
this.item = item;
|
|
||||||
this.xp = xp;
|
|
||||||
this.amount = amount;
|
|
||||||
this.total = xp * amount;
|
|
||||||
this.itemManager = itemManager;
|
|
||||||
this.linkedMap = linkedMap;
|
|
||||||
|
|
||||||
this.setLayout(new GridBagLayout());
|
|
||||||
this.setBorder(PANEL_BORDER);
|
|
||||||
this.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
|
||||||
this.setVisible(this.amount > 0);
|
|
||||||
|
|
||||||
infoContainer = new JPanel();
|
|
||||||
infoContainer.setLayout(new GridBagLayout());
|
|
||||||
infoContainer.setVisible(false);
|
|
||||||
infoContainer.setBackground(BACKGROUND_COLOR);
|
|
||||||
infoContainer.setBorder(new MatteBorder(1, 0, 0, 0, Color.GRAY));
|
|
||||||
|
|
||||||
// Icon
|
|
||||||
AsyncBufferedImage icon = itemManager.getImage(item.getItemID(), amount, item.getDefinition().isStackable() || amount > 1);
|
|
||||||
image = new JLabel();
|
|
||||||
image.setMinimumSize(ICON_SIZE);
|
|
||||||
image.setMaximumSize(ICON_SIZE);
|
|
||||||
image.setPreferredSize(ICON_SIZE);
|
|
||||||
image.setHorizontalAlignment(SwingConstants.CENTER);
|
|
||||||
image.setBorder(new EmptyBorder(0, 8, 0, 0));
|
|
||||||
|
|
||||||
Runnable resize = () ->
|
|
||||||
image.setIcon(new ImageIcon(icon.getScaledInstance((int) ICON_SIZE.getWidth(), (int) ICON_SIZE.getHeight(), Image.SCALE_SMOOTH)));
|
|
||||||
icon.onChanged(resize);
|
|
||||||
resize.run();
|
|
||||||
|
|
||||||
// Container for Info
|
|
||||||
JPanel uiInfo = new JPanel(new GridLayout(2, 1));
|
|
||||||
uiInfo.setBorder(new EmptyBorder(0, 5, 0, 0));
|
|
||||||
uiInfo.setBackground(BACKGROUND_COLOR);
|
|
||||||
|
|
||||||
JShadowedLabel labelName = new JShadowedLabel(item.getDefinition().getName());
|
|
||||||
labelName.setForeground(Color.WHITE);
|
|
||||||
labelName.setVerticalAlignment(SwingUtilities.BOTTOM);
|
|
||||||
|
|
||||||
labelValue = new JShadowedLabel();
|
|
||||||
labelValue.setFont(FontManager.getRunescapeSmallFont());
|
|
||||||
labelValue.setVerticalAlignment(SwingUtilities.TOP);
|
|
||||||
updateXp(xp);
|
|
||||||
|
|
||||||
uiInfo.add(labelName);
|
|
||||||
uiInfo.add(labelValue);
|
|
||||||
|
|
||||||
// Settings Button
|
|
||||||
JLabel settingsButton = new JLabel();
|
|
||||||
settingsButton.setBorder(new EmptyBorder(0, 5, 0, 5));
|
|
||||||
settingsButton.setIcon(new ImageIcon(ICON_SETTINGS));
|
|
||||||
settingsButton.setOpaque(true);
|
|
||||||
settingsButton.setBackground(BACKGROUND_COLOR);
|
|
||||||
|
|
||||||
settingsButton.addMouseListener(new MouseAdapter()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void mouseEntered(MouseEvent e)
|
|
||||||
{
|
|
||||||
settingsButton.setBackground(BUTTON_HOVER_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExited(MouseEvent e)
|
|
||||||
{
|
|
||||||
settingsButton.setBackground(BACKGROUND_COLOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e)
|
|
||||||
{
|
|
||||||
toggleInfo();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create and append elements to container panel
|
|
||||||
JPanel panel = new JPanel();
|
|
||||||
panel.setLayout(new BorderLayout());
|
|
||||||
panel.setBackground(BACKGROUND_COLOR);
|
|
||||||
|
|
||||||
panel.add(image, BorderLayout.LINE_START);
|
|
||||||
panel.add(uiInfo, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
// Only add button if has activity selection options or linked items
|
|
||||||
List<Activity> activities = Activity.getByCriticalItem(item);
|
|
||||||
// If linked map has 1 item and it isn't this item still show breakdown (cleaned herbs into unfinished)
|
|
||||||
if ((linkedMap.size() > 1 || (linkedMap.size() == 1 && linkedMap.get(item) == null))
|
|
||||||
|| activities.size() > 1)
|
|
||||||
{
|
|
||||||
panel.add(settingsButton, BorderLayout.LINE_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
panel.setToolTipText("<html>" + item.getDefinition().getName()
|
|
||||||
+ "<br/>xp: " + xp
|
|
||||||
+ "<br/>Total: " + StackFormatter.quantityToStackSize((long) total) + "</html");
|
|
||||||
|
|
||||||
GridBagConstraints c = new GridBagConstraints();
|
|
||||||
c.fill = GridBagConstraints.BOTH;
|
|
||||||
c.weightx = 1;
|
|
||||||
c.gridx = 0;
|
|
||||||
c.gridy = 0;
|
|
||||||
c.ipady = 20;
|
|
||||||
|
|
||||||
this.add(panel, c);
|
|
||||||
c.gridy++;
|
|
||||||
this.add(infoContainer, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toggleInfo()
|
|
||||||
{
|
|
||||||
infoVisibility = !infoVisibility;
|
|
||||||
|
|
||||||
if (infoVisibility)
|
|
||||||
{
|
|
||||||
createInfoPanel();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
infoContainer.removeAll();
|
|
||||||
infoContainer.setVisible(false);
|
|
||||||
|
|
||||||
infoContainer.revalidate();
|
|
||||||
infoContainer.repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createInfoPanel()
|
|
||||||
{
|
|
||||||
infoContainer.removeAll();
|
|
||||||
infoContainer.setVisible(true);
|
|
||||||
|
|
||||||
GridBagConstraints c = new GridBagConstraints();
|
|
||||||
c.fill = GridBagConstraints.BOTH;
|
|
||||||
c.weightx = 1;
|
|
||||||
c.gridx = 0;
|
|
||||||
c.gridy = 0;
|
|
||||||
c.ipady = 0;
|
|
||||||
|
|
||||||
JPanel p = createActivitiesPanel();
|
|
||||||
if (p != null)
|
|
||||||
{
|
|
||||||
infoContainer.add(p, c);
|
|
||||||
c.gridy++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show linked item breakdown, including own items
|
|
||||||
if (linkedMap.size() > 1 || (linkedMap.size() == 1 && linkedMap.get(item) == null))
|
|
||||||
{
|
|
||||||
JLabel l = new JLabel("Item Breakdown");
|
|
||||||
l.setBorder(new EmptyBorder(3, 0, 3, 0));
|
|
||||||
l.setHorizontalAlignment(JLabel.CENTER);
|
|
||||||
infoContainer.add(l, c);
|
|
||||||
c.gridy++;
|
|
||||||
|
|
||||||
JPanel con = new JPanel();
|
|
||||||
con.setLayout(new GridBagLayout());
|
|
||||||
con.setBackground(BACKGROUND_COLOR);
|
|
||||||
for (Map.Entry<CriticalItem, Integer> e : linkedMap.entrySet())
|
|
||||||
{
|
|
||||||
// Icon
|
|
||||||
AsyncBufferedImage icon = itemManager.getImage(e.getKey().getItemID(), e.getValue(), e.getKey().getDefinition().isStackable() || e.getValue() > 1);
|
|
||||||
JLabel image = new JLabel();
|
|
||||||
image.setMinimumSize(ICON_SIZE);
|
|
||||||
image.setMaximumSize(ICON_SIZE);
|
|
||||||
image.setPreferredSize(ICON_SIZE);
|
|
||||||
image.setHorizontalAlignment(SwingConstants.CENTER);
|
|
||||||
image.setBorder(new EmptyBorder(0, 8, 0, 0));
|
|
||||||
|
|
||||||
Runnable resize = () ->
|
|
||||||
image.setIcon(new ImageIcon(icon.getScaledInstance((int) ICON_SIZE.getWidth(), (int) ICON_SIZE.getHeight(), Image.SCALE_SMOOTH)));
|
|
||||||
icon.onChanged(resize);
|
|
||||||
resize.run();
|
|
||||||
|
|
||||||
image.setToolTipText(e.getKey().getDefinition().getName());
|
|
||||||
|
|
||||||
con.add(image, c);
|
|
||||||
c.gridx++;
|
|
||||||
}
|
|
||||||
c.gridx = 0;
|
|
||||||
infoContainer.add(con, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private JPanel createActivitiesPanel()
|
|
||||||
{
|
|
||||||
List<Activity> activities = Activity.getByCriticalItem(item);
|
|
||||||
if (activities == null || activities.size() == 1)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
JPanel p = new JPanel();
|
|
||||||
p.setBackground(BACKGROUND_COLOR);
|
|
||||||
p.setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
JLabel label = new JLabel("Possible training methods");
|
|
||||||
|
|
||||||
MaterialTabGroup group = new MaterialTabGroup();
|
|
||||||
group.setLayout(new GridLayout(0, 6, 0, 2));
|
|
||||||
group.setBorder(new MatteBorder(1, 1, 1, 1, Color.BLACK));
|
|
||||||
|
|
||||||
Activity selected = this.bankedCalculator.getSelectedActivity(this.item);
|
|
||||||
boolean s = false;
|
|
||||||
|
|
||||||
for (Activity option : activities)
|
|
||||||
{
|
|
||||||
AsyncBufferedImage icon = itemManager.getImage(option.getIcon());
|
|
||||||
MaterialTab matTab = new MaterialTab("", group, null);
|
|
||||||
matTab.setHorizontalAlignment(SwingUtilities.RIGHT);
|
|
||||||
matTab.setToolTipText(option.getName());
|
|
||||||
|
|
||||||
Runnable resize = () ->
|
|
||||||
matTab.setIcon(new ImageIcon(icon.getScaledInstance(24, 24, Image.SCALE_SMOOTH)));
|
|
||||||
icon.onChanged(resize);
|
|
||||||
resize.run();
|
|
||||||
|
|
||||||
group.addTab(matTab);
|
|
||||||
|
|
||||||
// Select first option by default
|
|
||||||
if (!s)
|
|
||||||
{
|
|
||||||
s = true;
|
|
||||||
group.select(matTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select the option if its their selected activity
|
|
||||||
if (option.equals(selected))
|
|
||||||
{
|
|
||||||
group.select(matTab);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add click event handler now to prevent above code from triggering it.
|
|
||||||
matTab.setOnSelectEvent(() ->
|
|
||||||
{
|
|
||||||
bankedCalculator.activitySelected(item, option);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
p.add(label, BorderLayout.NORTH);
|
|
||||||
p.add(group, BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateXp(double newXpRate)
|
|
||||||
{
|
|
||||||
xp = newXpRate;
|
|
||||||
total = xp * amount;
|
|
||||||
labelValue.setText(FORMAT_COMMA.format(total) + "xp");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateAmount(int newAmount, boolean forceVisible)
|
|
||||||
{
|
|
||||||
this.setVisible(newAmount > 0 || forceVisible);
|
|
||||||
this.amount = newAmount;
|
|
||||||
AsyncBufferedImage icon = itemManager.getImage(item.getItemID(), amount, item.getDefinition().isStackable() || amount > 1);
|
|
||||||
Runnable resize = () ->
|
|
||||||
image.setIcon(new ImageIcon(icon.getScaledInstance((int) ICON_SIZE.getWidth(), (int) ICON_SIZE.getHeight(), Image.SCALE_SMOOTH)));
|
|
||||||
icon.onChanged(resize);
|
|
||||||
resize.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateLinkedMap(Map<CriticalItem, Integer> newLinkedMap)
|
|
||||||
{
|
|
||||||
this.linkedMap = newLinkedMap;
|
|
||||||
|
|
||||||
int sum = 0;
|
|
||||||
for (Integer v : newLinkedMap.values())
|
|
||||||
{
|
|
||||||
sum += v;
|
|
||||||
}
|
|
||||||
this.updateAmount(sum, false);
|
|
||||||
|
|
||||||
this.updateXp(xp);
|
|
||||||
|
|
||||||
// Refresh info panel if visible
|
|
||||||
if (infoVisibility)
|
|
||||||
{
|
|
||||||
createInfoPanel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void recalculate()
|
|
||||||
{
|
|
||||||
updateXp(xp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,10 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.skillcalculator.beans;
|
package net.runelite.client.plugins.skillcalculator.beans;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
@Getter
|
||||||
public class SkillData
|
public class SkillData
|
||||||
{
|
{
|
||||||
private SkillDataEntry[] actions;
|
private SkillDataEntry[] actions;
|
||||||
|
|||||||
@@ -24,10 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.skillcalculator.beans;
|
package net.runelite.client.plugins.skillcalculator.beans;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
@Getter
|
||||||
public class SkillDataBonus
|
public class SkillDataBonus
|
||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
@@ -24,10 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.skillcalculator.beans;
|
package net.runelite.client.plugins.skillcalculator.beans;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter(AccessLevel.PUBLIC)
|
@Getter
|
||||||
public class SkillDataEntry
|
public class SkillDataEntry
|
||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
|
|||||||
@@ -166,6 +166,17 @@ public interface SlayerConfig extends Config
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
position = 14,
|
||||||
|
keyName = "pointsCommand",
|
||||||
|
name = "Points Command",
|
||||||
|
description = "Configures whether the slayer points command is enabled<br> !points"
|
||||||
|
)
|
||||||
|
default boolean pointsCommand()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Stored data
|
// Stored data
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "taskName",
|
keyName = "taskName",
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
private static final String TASK_COMMAND_STRING = "!task";
|
private static final String TASK_COMMAND_STRING = "!task";
|
||||||
private static final Pattern TASK_STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]");
|
private static final Pattern TASK_STRING_VALIDATION = Pattern.compile("[^a-zA-Z0-9' -]");
|
||||||
private static final int TASK_STRING_MAX_LENGTH = 50;
|
private static final int TASK_STRING_MAX_LENGTH = 50;
|
||||||
|
private static final String POINTS_COMMAND_STRING = "!points";
|
||||||
|
|
||||||
// Superiors
|
// Superiors
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -280,6 +281,8 @@ public class SlayerPlugin extends Plugin
|
|||||||
private boolean taskCommand;
|
private boolean taskCommand;
|
||||||
private String taskName;
|
private String taskName;
|
||||||
private String taskLocation;
|
private String taskLocation;
|
||||||
|
@Setter(AccessLevel.PACKAGE)
|
||||||
|
private boolean pointsCommand;
|
||||||
private int amount;
|
private int amount;
|
||||||
private int initialAmount;
|
private int initialAmount;
|
||||||
private int lastCertainAmount;
|
private int lastCertainAmount;
|
||||||
@@ -316,6 +319,8 @@ public class SlayerPlugin extends Plugin
|
|||||||
clientToolbar.addNavigation(navButton);
|
clientToolbar.addNavigation(navButton);
|
||||||
|
|
||||||
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
chatCommandManager.registerCommandAsync(TASK_COMMAND_STRING, this::taskLookup, this::taskSubmit);
|
||||||
|
|
||||||
|
chatCommandManager.registerCommandAsync(POINTS_COMMAND_STRING, this::pointsLookup); //here
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -329,6 +334,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
clearTrackedNPCs();
|
clearTrackedNPCs();
|
||||||
|
|
||||||
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
chatCommandManager.unregisterCommand(TASK_COMMAND_STRING);
|
||||||
|
chatCommandManager.unregisterCommand(POINTS_COMMAND_STRING);
|
||||||
clientToolbar.removeNavigation(navButton);
|
clientToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1121,6 +1127,44 @@ public class SlayerPlugin extends Plugin
|
|||||||
client.refreshChat();
|
client.refreshChat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pointsLookup(ChatMessage chatMessage, String message)
|
||||||
|
{
|
||||||
|
if (!this.pointsCommand)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessageType type = chatMessage.getType();
|
||||||
|
|
||||||
|
final String player;
|
||||||
|
if (type.equals(ChatMessageType.PRIVATECHATOUT))
|
||||||
|
{
|
||||||
|
player = client.getLocalPlayer().getName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player = Text.removeTags(chatMessage.getName())
|
||||||
|
.replace('\u00A0', ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Integer.toString(getPoints()) == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String response = new ChatMessageBuilder()
|
||||||
|
.append(ChatColorType.NORMAL)
|
||||||
|
.append("Slayer Points: ")
|
||||||
|
.append(ChatColorType.HIGHLIGHT)
|
||||||
|
.append(Integer.toString(getPoints()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||||
|
messageNode.setRuneLiteFormatMessage(response);
|
||||||
|
chatMessageManager.update(messageNode);
|
||||||
|
client.refreshChat();
|
||||||
|
}
|
||||||
|
|
||||||
/* package access method for changing the pause state of the time tracker for the current task */
|
/* package access method for changing the pause state of the time tracker for the current task */
|
||||||
void setPaused(boolean paused)
|
void setPaused(boolean paused)
|
||||||
{
|
{
|
||||||
@@ -1208,6 +1252,7 @@ public class SlayerPlugin extends Plugin
|
|||||||
this.drawMinimapNames = config.drawMinimapNames();
|
this.drawMinimapNames = config.drawMinimapNames();
|
||||||
this.weaknessPrompt = config.weaknessPrompt();
|
this.weaknessPrompt = config.weaknessPrompt();
|
||||||
this.taskCommand = config.taskCommand();
|
this.taskCommand = config.taskCommand();
|
||||||
|
this.pointsCommand = config.pointsCommand();
|
||||||
this.taskName = config.taskName();
|
this.taskName = config.taskName();
|
||||||
this.amount = config.amount();
|
this.amount = config.amount();
|
||||||
this.initialAmount = config.initialAmount();
|
this.initialAmount = config.initialAmount();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Abex
|
* Copyright (c) 2018 Abex
|
||||||
|
* Copyright (c) 2018, Sean Dewar <https://github.com/seandewar>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -22,29 +23,47 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.regenmeter;
|
package net.runelite.client.plugins.statusorbs;
|
||||||
|
|
||||||
import net.runelite.client.config.Config;
|
import net.runelite.client.config.Config;
|
||||||
import net.runelite.client.config.ConfigGroup;
|
import net.runelite.client.config.ConfigGroup;
|
||||||
import net.runelite.client.config.ConfigItem;
|
import net.runelite.client.config.ConfigItem;
|
||||||
|
import net.runelite.client.config.Stub;
|
||||||
|
|
||||||
@ConfigGroup("regenmeter")
|
@ConfigGroup("statusorbs")
|
||||||
public interface RegenMeterConfig extends Config
|
public interface StatusOrbsConfig extends Config
|
||||||
{
|
{
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "showHitpoints",
|
keyName = "hp",
|
||||||
name = "Show hitpoints regen",
|
name = "Hitpoints",
|
||||||
description = "Show a ring around the hitpoints orb")
|
description = "",
|
||||||
default boolean showHitpoints()
|
position = 0
|
||||||
|
)
|
||||||
|
default Stub hp()
|
||||||
|
{
|
||||||
|
return new Stub();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "dynamicHpHeart",
|
||||||
|
name = "Dynamic hitpoints heart",
|
||||||
|
description = "Changes the HP heart color to match players current affliction",
|
||||||
|
parent = "hp",
|
||||||
|
position = 1
|
||||||
|
)
|
||||||
|
default boolean dynamicHpHeart()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "showSpecial",
|
keyName = "showHitpoints",
|
||||||
name = "Show Spec. Attack regen",
|
name = "Show hitpoints regen",
|
||||||
description = "Show a ring around the Special Attack orb")
|
description = "Show a ring around the hitpoints orb",
|
||||||
default boolean showSpecial()
|
parent = "hp",
|
||||||
|
position = 2
|
||||||
|
)
|
||||||
|
default boolean showHitpoints()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -52,7 +71,10 @@ public interface RegenMeterConfig extends Config
|
|||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "showWhenNoChange",
|
keyName = "showWhenNoChange",
|
||||||
name = "Show hitpoints regen at full hitpoints",
|
name = "Show hitpoints regen at full hitpoints",
|
||||||
description = "Always show the hitpoints regen orb, even if there will be no stat change")
|
description = "Always show the hitpoints regen orb, even if there will be no stat change",
|
||||||
|
parent = "hp",
|
||||||
|
position = 3
|
||||||
|
)
|
||||||
default boolean showWhenNoChange()
|
default boolean showWhenNoChange()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -61,10 +83,70 @@ public interface RegenMeterConfig extends Config
|
|||||||
@ConfigItem(
|
@ConfigItem(
|
||||||
keyName = "notifyBeforeHpRegenDuration",
|
keyName = "notifyBeforeHpRegenDuration",
|
||||||
name = "Hitpoint Regen Notification (seconds)",
|
name = "Hitpoint Regen Notification (seconds)",
|
||||||
description = "Notify approximately when your next hitpoint is about to regen. A value of 0 will disable notification."
|
description = "Notify approximately when your next hitpoint is about to regen. A value of 0 will disable notification.",
|
||||||
|
parent = "hp",
|
||||||
|
position = 4
|
||||||
)
|
)
|
||||||
default int getNotifyBeforeHpRegenSeconds()
|
default int getNotifyBeforeHpRegenSeconds()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "spec",
|
||||||
|
name = "Special attack",
|
||||||
|
description = "",
|
||||||
|
position = 5
|
||||||
|
)
|
||||||
|
default Stub spec()
|
||||||
|
{
|
||||||
|
return new Stub();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "showSpecial",
|
||||||
|
name = "Show Spec. Attack regen",
|
||||||
|
description = "Show a ring around the Special Attack orb",
|
||||||
|
parent = "spec",
|
||||||
|
position = 6
|
||||||
|
)
|
||||||
|
default boolean showSpecial()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "run",
|
||||||
|
name = "Run energy",
|
||||||
|
description = "",
|
||||||
|
position = 7
|
||||||
|
)
|
||||||
|
default Stub run()
|
||||||
|
{
|
||||||
|
return new Stub();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "showRun",
|
||||||
|
name = "Show run energy regen",
|
||||||
|
description = "Show a ring around the run regen orb",
|
||||||
|
position = 8,
|
||||||
|
parent = "run"
|
||||||
|
)
|
||||||
|
default boolean showRun()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigItem(
|
||||||
|
keyName = "replaceOrbText",
|
||||||
|
name = "Replace run orb text with run time left",
|
||||||
|
description = "Show the remaining run time (in seconds) next in the energy orb",
|
||||||
|
position = 9,
|
||||||
|
parent = "run"
|
||||||
|
)
|
||||||
|
default boolean replaceOrbText()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Abex
|
||||||
|
* Copyright (c) 2018, 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.statusorbs;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.Stroke;
|
||||||
|
import java.awt.geom.Arc2D;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Point;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.VarPlayer;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||||
|
import net.runelite.client.ui.overlay.tooltip.Tooltip;
|
||||||
|
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
|
||||||
|
import net.runelite.client.util.Graceful;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
public class StatusOrbsOverlay extends Overlay
|
||||||
|
{
|
||||||
|
private static final Color HITPOINTS_COLOR = brighter(0x9B0703);
|
||||||
|
private static final Color SPECIAL_COLOR = brighter(0x1E95B0);
|
||||||
|
private static final Color RUN_COLOR = new Color(255, 215, 0);
|
||||||
|
private static final Color OVERLAY_COLOR = new Color(255, 255, 255, 60);
|
||||||
|
private static final double DIAMETER = 26D;
|
||||||
|
private static final int OFFSET = 27;
|
||||||
|
|
||||||
|
private final Client client;
|
||||||
|
private final StatusOrbsPlugin plugin;
|
||||||
|
private final TooltipManager tooltipManager;
|
||||||
|
|
||||||
|
private long last = System.nanoTime();
|
||||||
|
private double percentHp;
|
||||||
|
private double lastHp;
|
||||||
|
private double percentSpec;
|
||||||
|
private double lastSpec;
|
||||||
|
private double percentRun;
|
||||||
|
private double lastRun;
|
||||||
|
|
||||||
|
private static Color brighter(int color)
|
||||||
|
{
|
||||||
|
float[] hsv = new float[3];
|
||||||
|
Color.RGBtoHSB(color >>> 16, (color >> 8) & 0xFF, color & 0xFF, hsv);
|
||||||
|
return Color.getHSBColor(hsv[0], 1.f, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public StatusOrbsOverlay(Client client, StatusOrbsPlugin plugin, TooltipManager tooltipManager)
|
||||||
|
{
|
||||||
|
setPosition(OverlayPosition.DYNAMIC);
|
||||||
|
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||||
|
this.client = client;
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.tooltipManager = tooltipManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension render(Graphics2D g)
|
||||||
|
{
|
||||||
|
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
|
||||||
|
|
||||||
|
long current = System.nanoTime();
|
||||||
|
double ms = (current - last) / (double) 1000000;
|
||||||
|
|
||||||
|
if (plugin.isShowHitpoints())
|
||||||
|
{
|
||||||
|
if (lastHp == plugin.getHitpointsPercentage() && plugin.getHitpointsPercentage() != 0)
|
||||||
|
{
|
||||||
|
percentHp += ms * plugin.getHpPerMs();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
percentHp = plugin.getHitpointsPercentage();
|
||||||
|
lastHp = plugin.getHitpointsPercentage();
|
||||||
|
}
|
||||||
|
renderRegen(g, WidgetInfo.MINIMAP_HEALTH_ORB, percentHp, HITPOINTS_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.isShowSpecial())
|
||||||
|
{
|
||||||
|
if (client.getVar(VarPlayer.SPECIAL_ATTACK_ENABLED) == 1)
|
||||||
|
{
|
||||||
|
final Widget widget = client.getWidget(WidgetInfo.MINIMAP_SPEC_ORB);
|
||||||
|
|
||||||
|
if (widget != null && !widget.isHidden())
|
||||||
|
{
|
||||||
|
final Rectangle bounds = widget.getBounds();
|
||||||
|
g.setColor(OVERLAY_COLOR);
|
||||||
|
g.fillOval(
|
||||||
|
bounds.x + OFFSET,
|
||||||
|
bounds.y + (int) (bounds.height / 2 - (DIAMETER) / 2),
|
||||||
|
(int) DIAMETER, (int) DIAMETER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastSpec == plugin.getSpecialPercentage() && plugin.getSpecialPercentage() != 0)
|
||||||
|
{
|
||||||
|
percentSpec += ms * plugin.getSpecPerMs();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
percentSpec = plugin.getSpecialPercentage();
|
||||||
|
lastSpec = plugin.getSpecialPercentage();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRegen(g, WidgetInfo.MINIMAP_SPEC_ORB, percentSpec, SPECIAL_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.isReplaceOrbText())
|
||||||
|
{
|
||||||
|
final Widget runOrb = client.getWidget(WidgetInfo.MINIMAP_TOGGLE_RUN_ORB);
|
||||||
|
|
||||||
|
if (runOrb == null || runOrb.isHidden())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Rectangle bounds = runOrb.getBounds();
|
||||||
|
|
||||||
|
if (bounds.getX() <= 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Point mousePosition = client.getMouseCanvasPosition();
|
||||||
|
|
||||||
|
if (bounds.contains(mousePosition.getX(), mousePosition.getY()))
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Weight: ").append(client.getWeight()).append(" kg</br>");
|
||||||
|
|
||||||
|
if (plugin.isReplaceOrbText())
|
||||||
|
{
|
||||||
|
sb.append("Run Energy: ").append(client.getEnergy()).append("%");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.append("Run Time Remaining: ").append(plugin.getEstimatedRunTimeRemaining(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
int secondsUntil100 = plugin.getEstimatedRecoverTimeRemaining();
|
||||||
|
if (secondsUntil100 > 0)
|
||||||
|
{
|
||||||
|
final int minutes = (int) Math.floor(secondsUntil100 / 60.0);
|
||||||
|
final int seconds = (int) Math.floor(secondsUntil100 - (minutes * 60.0));
|
||||||
|
|
||||||
|
sb.append("</br>").append("100% Energy In: ").append(minutes).append(':').append(StringUtils.leftPad(Integer.toString(seconds), 2, "0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltipManager.add(new Tooltip(sb.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.isShowRun())
|
||||||
|
{
|
||||||
|
if (lastRun == plugin.getRunPercentage() && plugin.getRunPercentage() != 0)
|
||||||
|
{
|
||||||
|
double recoverRate = (48 + client.getBoostedSkillLevel(Skill.AGILITY)) / 360000.0;
|
||||||
|
|
||||||
|
if (Graceful.hasFullSet(client.getItemContainer(InventoryID.EQUIPMENT)))
|
||||||
|
{
|
||||||
|
recoverRate *= 1.3; // 30% recover rate increase from Graceful set effect
|
||||||
|
}
|
||||||
|
|
||||||
|
percentRun += ms * recoverRate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
percentRun = plugin.getRunPercentage();
|
||||||
|
lastRun = plugin.getRunPercentage();
|
||||||
|
}
|
||||||
|
renderRegen(g, WidgetInfo.MINIMAP_RUN_ORB, percentRun, RUN_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
last = current;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderRegen(Graphics2D g, WidgetInfo widgetInfo, double percent, Color color)
|
||||||
|
{
|
||||||
|
Widget widget = client.getWidget(widgetInfo);
|
||||||
|
if (widget == null || widget.isHidden())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Rectangle bounds = widget.getBounds();
|
||||||
|
|
||||||
|
Arc2D.Double arc = new Arc2D.Double(bounds.x + OFFSET, bounds.y + (bounds.height / 2 - DIAMETER / 2), DIAMETER, DIAMETER, 90.d, -360.d * percent, Arc2D.OPEN);
|
||||||
|
final Stroke STROKE = new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
||||||
|
g.setStroke(STROKE);
|
||||||
|
g.setColor(color);
|
||||||
|
g.draw(arc);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,490 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Owain van Brakel <https://github.com/Owain94>
|
||||||
|
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* Copyright (c) 2018 Abex
|
||||||
|
* Copyright (c) 2018, Zimaya <https://github.com/Zimaya>
|
||||||
|
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.plugins.statusorbs;
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Constants;
|
||||||
|
import net.runelite.api.GameState;
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
|
import net.runelite.api.Prayer;
|
||||||
|
import net.runelite.api.Skill;
|
||||||
|
import net.runelite.api.SpriteID;
|
||||||
|
import net.runelite.api.VarPlayer;
|
||||||
|
import net.runelite.api.Varbits;
|
||||||
|
import net.runelite.api.coords.WorldPoint;
|
||||||
|
import net.runelite.api.events.ConfigChanged;
|
||||||
|
import net.runelite.api.events.GameStateChanged;
|
||||||
|
import net.runelite.api.events.GameTick;
|
||||||
|
import net.runelite.api.events.VarbitChanged;
|
||||||
|
import net.runelite.api.widgets.Widget;
|
||||||
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
|
import net.runelite.client.Notifier;
|
||||||
|
import net.runelite.client.callback.ClientThread;
|
||||||
|
import net.runelite.client.config.ConfigManager;
|
||||||
|
import net.runelite.client.eventbus.Subscribe;
|
||||||
|
import net.runelite.client.plugins.Plugin;
|
||||||
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
|
import net.runelite.client.util.Graceful;
|
||||||
|
import net.runelite.client.util.ImageUtil;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
@PluginDescriptor(
|
||||||
|
name = "Status Orbs",
|
||||||
|
description = "Configure settings for the Minimap orbs",
|
||||||
|
tags = {"minimap", "orb", "regen", "energy", "special"}
|
||||||
|
)
|
||||||
|
public class StatusOrbsPlugin extends Plugin
|
||||||
|
{
|
||||||
|
private static final BufferedImage HEART_DISEASE;
|
||||||
|
private static final BufferedImage HEART_POISON;
|
||||||
|
private static final BufferedImage HEART_VENOM;
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
HEART_DISEASE = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(StatusOrbsPlugin.class, "1067-DISEASE.png"), 26, 26);
|
||||||
|
HEART_POISON = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(StatusOrbsPlugin.class, "1067-POISON.png"), 26, 26);
|
||||||
|
HEART_VENOM = ImageUtil.resizeCanvas(ImageUtil.getResourceStreamFromClass(StatusOrbsPlugin.class, "1067-VENOM.png"), 26, 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int SPEC_REGEN_TICKS = 50;
|
||||||
|
private static final int NORMAL_HP_REGEN_TICKS = 100;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientThread clientThread;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ConfigManager configManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private StatusOrbsConfig config;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private StatusOrbsOverlay overlay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private OverlayManager overlayManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Notifier notifier;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private double hitpointsPercentage;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private double specialPercentage;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private double runPercentage;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private double hpPerMs;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private double specPerMs = (double) 1 / (SPEC_REGEN_TICKS * 600);
|
||||||
|
|
||||||
|
// RegenMeter
|
||||||
|
private int ticksSinceSpecRegen;
|
||||||
|
private int ticksSinceHPRegen;
|
||||||
|
private boolean wasRapidHeal;
|
||||||
|
private double ticksSinceRunRegen;
|
||||||
|
|
||||||
|
// Run Energy
|
||||||
|
private int lastEnergy = 0;
|
||||||
|
private boolean localPlayerRunningToDestination;
|
||||||
|
private WorldPoint currPoint;
|
||||||
|
private WorldPoint prevLocalPlayerLocation;
|
||||||
|
|
||||||
|
private BufferedImage heart;
|
||||||
|
|
||||||
|
private boolean dynamicHpHeart;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean showHitpoints;
|
||||||
|
private boolean showWhenNoChange;
|
||||||
|
private int getNotifyBeforeHpRegenSeconds;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean showSpecial;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean showRun;
|
||||||
|
@Getter(AccessLevel.PACKAGE)
|
||||||
|
private boolean replaceOrbText;
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
StatusOrbsConfig provideConfig(ConfigManager configManager)
|
||||||
|
{
|
||||||
|
return configManager.getConfig(StatusOrbsConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startUp() throws Exception
|
||||||
|
{
|
||||||
|
migrateConfigs();
|
||||||
|
updateConfig();
|
||||||
|
overlayManager.add(overlay);
|
||||||
|
if (this.dynamicHpHeart && client.getGameState().equals(GameState.LOGGED_IN))
|
||||||
|
{
|
||||||
|
clientThread.invoke(this::checkHealthIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
|
{
|
||||||
|
overlayManager.remove(overlay);
|
||||||
|
localPlayerRunningToDestination = false;
|
||||||
|
prevLocalPlayerLocation = null;
|
||||||
|
resetRunOrbText();
|
||||||
|
if (this.dynamicHpHeart)
|
||||||
|
{
|
||||||
|
clientThread.invoke(this::resetHealthIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onConfigChanged(ConfigChanged event)
|
||||||
|
{
|
||||||
|
if (event.getGroup().equals("statusorbs"))
|
||||||
|
{
|
||||||
|
updateConfig();
|
||||||
|
switch (event.getKey())
|
||||||
|
{
|
||||||
|
case "replaceOrbText":
|
||||||
|
if (!this.replaceOrbText)
|
||||||
|
{
|
||||||
|
resetRunOrbText();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "dynamicHpHeart":
|
||||||
|
if (this.dynamicHpHeart)
|
||||||
|
{
|
||||||
|
checkHealthIcon();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resetHealthIcon();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
private void onVarbitChanged(VarbitChanged e)
|
||||||
|
{
|
||||||
|
if (this.dynamicHpHeart)
|
||||||
|
{
|
||||||
|
checkHealthIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isRapidHeal = client.isPrayerActive(Prayer.RAPID_HEAL);
|
||||||
|
if (wasRapidHeal != isRapidHeal)
|
||||||
|
{
|
||||||
|
ticksSinceHPRegen = 0;
|
||||||
|
}
|
||||||
|
wasRapidHeal = isRapidHeal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
private void onGameStateChanged(GameStateChanged ev)
|
||||||
|
{
|
||||||
|
if (ev.getGameState() == GameState.HOPPING || ev.getGameState() == GameState.LOGIN_SCREEN)
|
||||||
|
{
|
||||||
|
ticksSinceHPRegen = -2; // For some reason this makes this accurate
|
||||||
|
ticksSinceSpecRegen = 0;
|
||||||
|
ticksSinceRunRegen = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onGameTick(GameTick event)
|
||||||
|
{
|
||||||
|
if (client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT) == 1000)
|
||||||
|
{
|
||||||
|
// The recharge doesn't tick when at 100%
|
||||||
|
ticksSinceSpecRegen = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticksSinceSpecRegen = (ticksSinceSpecRegen + 1) % SPEC_REGEN_TICKS;
|
||||||
|
}
|
||||||
|
specialPercentage = ticksSinceSpecRegen / (double) SPEC_REGEN_TICKS;
|
||||||
|
|
||||||
|
int ticksPerHPRegen = NORMAL_HP_REGEN_TICKS;
|
||||||
|
hpPerMs = ticksPerHPRegen / (double) 6000000;
|
||||||
|
if (client.isPrayerActive(Prayer.RAPID_HEAL))
|
||||||
|
{
|
||||||
|
ticksPerHPRegen /= 2;
|
||||||
|
hpPerMs *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ticksSinceHPRegen = (ticksSinceHPRegen + 1) % ticksPerHPRegen;
|
||||||
|
hitpointsPercentage = ticksSinceHPRegen / (double) ticksPerHPRegen;
|
||||||
|
|
||||||
|
int currentHP = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
||||||
|
int maxHP = client.getRealSkillLevel(Skill.HITPOINTS);
|
||||||
|
if (currentHP == maxHP && !this.showWhenNoChange)
|
||||||
|
{
|
||||||
|
hitpointsPercentage = 0;
|
||||||
|
}
|
||||||
|
else if (currentHP > maxHP)
|
||||||
|
{
|
||||||
|
// Show it going down
|
||||||
|
hitpointsPercentage = 1 - hitpointsPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run Energy
|
||||||
|
localPlayerRunningToDestination =
|
||||||
|
prevLocalPlayerLocation != null &&
|
||||||
|
client.getLocalDestinationLocation() != null &&
|
||||||
|
prevLocalPlayerLocation.distanceTo(client.getLocalPlayer().getWorldLocation()) > 1;
|
||||||
|
|
||||||
|
if (this.getNotifyBeforeHpRegenSeconds > 0 && currentHP < maxHP && shouldNotifyHpRegenThisTick(ticksPerHPRegen))
|
||||||
|
{
|
||||||
|
notifier.notify("[" + client.getLocalPlayer().getName() + "] regenerates their next hitpoint soon!");
|
||||||
|
}
|
||||||
|
|
||||||
|
localPlayerRunningToDestination =
|
||||||
|
prevLocalPlayerLocation != null &&
|
||||||
|
client.getLocalDestinationLocation() != null &&
|
||||||
|
prevLocalPlayerLocation.distanceTo(client.getLocalPlayer().getWorldLocation()) > 1;
|
||||||
|
|
||||||
|
prevLocalPlayerLocation = client.getLocalPlayer().getWorldLocation();
|
||||||
|
|
||||||
|
if (this.replaceOrbText)
|
||||||
|
{
|
||||||
|
setRunOrbText(getEstimatedRunTimeRemaining(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
int currEnergy = client.getEnergy();
|
||||||
|
currPoint = client.getLocalPlayer().getWorldLocation();
|
||||||
|
if (currEnergy == 100 || (prevLocalPlayerLocation != null && currPoint.distanceTo(prevLocalPlayerLocation) > 1) || currEnergy < lastEnergy)
|
||||||
|
{
|
||||||
|
ticksSinceRunRegen = 0;
|
||||||
|
}
|
||||||
|
else if (currEnergy > lastEnergy)
|
||||||
|
{
|
||||||
|
if (runPercentage < 1)
|
||||||
|
{
|
||||||
|
ticksSinceRunRegen = (1 - runPercentage) / runRegenPerTick();
|
||||||
|
ticksSinceRunRegen = ticksSinceRunRegen > 1 ? 1 : ticksSinceRunRegen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticksSinceRunRegen = (runPercentage - 1) / runRegenPerTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ticksSinceRunRegen += 1;
|
||||||
|
}
|
||||||
|
runPercentage = ticksSinceRunRegen * runRegenPerTick();
|
||||||
|
prevLocalPlayerLocation = currPoint;
|
||||||
|
lastEnergy = currEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldNotifyHpRegenThisTick(int ticksPerHPRegen)
|
||||||
|
{
|
||||||
|
// if the configured duration lies between two ticks, choose the earlier tick
|
||||||
|
final int ticksBeforeHPRegen = ticksPerHPRegen - ticksSinceHPRegen;
|
||||||
|
final int notifyTick = (int) Math.ceil(this.getNotifyBeforeHpRegenSeconds * 1000d / Constants.GAME_TICK_LENGTH);
|
||||||
|
return ticksBeforeHPRegen == notifyTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRunOrbText(String text)
|
||||||
|
{
|
||||||
|
Widget runOrbText = client.getWidget(WidgetInfo.MINIMAP_RUN_ORB_TEXT);
|
||||||
|
|
||||||
|
if (runOrbText != null)
|
||||||
|
{
|
||||||
|
runOrbText.setText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetRunOrbText()
|
||||||
|
{
|
||||||
|
setRunOrbText(Integer.toString(client.getEnergy()));
|
||||||
|
}
|
||||||
|
|
||||||
|
String getEstimatedRunTimeRemaining(boolean inSeconds)
|
||||||
|
{
|
||||||
|
// Calculate the amount of energy lost every 2 ticks (0.6 seconds).
|
||||||
|
// Negative weight has the same depletion effect as 0 kg.
|
||||||
|
final int effectiveWeight = Math.max(client.getWeight(), 0);
|
||||||
|
double lossRate = (Math.min(effectiveWeight, 64) / 100.0) + 0.64;
|
||||||
|
|
||||||
|
if (client.getVar(Varbits.RUN_SLOWED_DEPLETION_ACTIVE) != 0)
|
||||||
|
{
|
||||||
|
lossRate *= 0.3; // Stamina effect reduces energy depletion to 30%
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the number of seconds left
|
||||||
|
final double secondsLeft = (client.getEnergy() * 0.6) / lossRate;
|
||||||
|
|
||||||
|
// Return the text
|
||||||
|
if (inSeconds)
|
||||||
|
{
|
||||||
|
return (int) Math.floor(secondsLeft) + "s";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final int minutes = (int) Math.floor(secondsLeft / 60.0);
|
||||||
|
final int seconds = (int) Math.floor(secondsLeft - (minutes * 60.0));
|
||||||
|
|
||||||
|
return minutes + ":" + StringUtils.leftPad(Integer.toString(seconds), 2, "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getEstimatedRecoverTimeRemaining()
|
||||||
|
{
|
||||||
|
if (localPlayerRunningToDestination)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the amount of energy recovered every second
|
||||||
|
double recoverRate = (48 + client.getBoostedSkillLevel(Skill.AGILITY)) / 360.0;
|
||||||
|
|
||||||
|
if (Graceful.hasFullSet(client.getItemContainer(InventoryID.EQUIPMENT)))
|
||||||
|
{
|
||||||
|
recoverRate *= 1.3; // 30% recover rate increase from Graceful set effect
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the number of seconds left
|
||||||
|
final double secondsLeft = (100 - client.getEnergy()) / recoverRate;
|
||||||
|
return (int) secondsLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check player afflictions to determine health icon
|
||||||
|
*/
|
||||||
|
private void checkHealthIcon()
|
||||||
|
{
|
||||||
|
BufferedImage newHeart;
|
||||||
|
|
||||||
|
int poison = client.getVar(VarPlayer.IS_POISONED);
|
||||||
|
if (poison >= 1000000)
|
||||||
|
{
|
||||||
|
newHeart = HEART_VENOM;
|
||||||
|
}
|
||||||
|
else if (poison > 0)
|
||||||
|
{
|
||||||
|
newHeart = HEART_POISON;
|
||||||
|
}
|
||||||
|
else if (client.getVar(VarPlayer.DISEASE_VALUE) > 0)
|
||||||
|
{
|
||||||
|
newHeart = HEART_DISEASE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
heart = null;
|
||||||
|
resetHealthIcon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update sprites when the heart icon actually changes
|
||||||
|
if (newHeart != heart)
|
||||||
|
{
|
||||||
|
heart = newHeart;
|
||||||
|
client.getWidgetSpriteCache().reset();
|
||||||
|
client.getSpriteOverrides().put(SpriteID.MINIMAP_ORB_HITPOINTS_ICON, ImageUtil.getImageSprite(heart, client));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double runRegenPerTick()
|
||||||
|
{
|
||||||
|
double recoverRate = (client.getBoostedSkillLevel(Skill.AGILITY) / 6d + 8) / 100;
|
||||||
|
|
||||||
|
if (Graceful.hasFullSet(client.getItemContainer(InventoryID.EQUIPMENT)))
|
||||||
|
{
|
||||||
|
return recoverRate * 1.3;
|
||||||
|
}
|
||||||
|
return recoverRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure the HP Heart is the default Sprite
|
||||||
|
*/
|
||||||
|
private void resetHealthIcon()
|
||||||
|
{
|
||||||
|
client.getWidgetSpriteCache().reset();
|
||||||
|
client.getSpriteOverrides().remove(SpriteID.MINIMAP_ORB_HITPOINTS_ICON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates configs from runenergy and regenmeter to this plugin and deletes the old config values.
|
||||||
|
* This method should be removed after a reasonable amount of time.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private void migrateConfigs()
|
||||||
|
{
|
||||||
|
migrateConfig("regenmeter", "showHitpoints");
|
||||||
|
migrateConfig("regenmeter", "showSpecial");
|
||||||
|
migrateConfig("regenmeter", "showWhenNoChange");
|
||||||
|
migrateConfig("regenmeter", "notifyBeforeHpRegenDuration");
|
||||||
|
|
||||||
|
migrateConfig("runenergy", "replaceOrbText");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for migrating individual config options
|
||||||
|
* This method should be removed after a reasonable amount of time.
|
||||||
|
*
|
||||||
|
* @param group old group name
|
||||||
|
* @param key key name to migrate
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private void migrateConfig(String group, String key)
|
||||||
|
{
|
||||||
|
String value = configManager.getConfiguration(group, key);
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
configManager.setConfiguration("statusorbs", key, value);
|
||||||
|
configManager.unsetConfiguration(group, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConfig()
|
||||||
|
{
|
||||||
|
this.dynamicHpHeart = config.dynamicHpHeart();
|
||||||
|
this.showHitpoints = config.showHitpoints();
|
||||||
|
this.showWhenNoChange = config.showWhenNoChange();
|
||||||
|
this.getNotifyBeforeHpRegenSeconds = config.getNotifyBeforeHpRegenSeconds();
|
||||||
|
this.showSpecial = config.showSpecial();
|
||||||
|
this.showRun = config.showRun();
|
||||||
|
this.replaceOrbText = config.replaceOrbText();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <http://www.github.com/TheStonedTurtle>
|
||||||
|
* 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.ui.components;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used with ComboBoxListRenderer to render an icon next to the text of the list entry.
|
||||||
|
* Also supports adding a data object to be used for more complex selection logic
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class ComboBoxIconEntry
|
||||||
|
{
|
||||||
|
private Icon icon;
|
||||||
|
private String text;
|
||||||
|
@Nullable
|
||||||
|
private Object data;
|
||||||
|
}
|
||||||
@@ -30,6 +30,7 @@ import javax.swing.JLabel;
|
|||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import javax.swing.ListCellRenderer;
|
import javax.swing.ListCellRenderer;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import lombok.Setter;
|
||||||
import net.runelite.client.ui.ColorScheme;
|
import net.runelite.client.ui.ColorScheme;
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
|
|
||||||
@@ -41,6 +42,8 @@ import net.runelite.client.util.Text;
|
|||||||
*/
|
*/
|
||||||
public final class ComboBoxListRenderer extends JLabel implements ListCellRenderer
|
public final class ComboBoxListRenderer extends JLabel implements ListCellRenderer
|
||||||
{
|
{
|
||||||
|
@Setter
|
||||||
|
private String defaultText = "Select an option...";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getListCellRendererComponent(JList list, Object o, int index, boolean isSelected, boolean cellHasFocus)
|
public Component getListCellRendererComponent(JList list, Object o, int index, boolean isSelected, boolean cellHasFocus)
|
||||||
@@ -57,12 +60,24 @@ public final class ComboBoxListRenderer extends JLabel implements ListCellRender
|
|||||||
}
|
}
|
||||||
|
|
||||||
setBorder(new EmptyBorder(5, 5, 5, 0));
|
setBorder(new EmptyBorder(5, 5, 5, 0));
|
||||||
|
setIcon(null);
|
||||||
|
|
||||||
String text;
|
String text;
|
||||||
if (o instanceof Enum)
|
// If using setSelectedItem(null) or setSelectedIndex(-1) show default text until a selection is made
|
||||||
|
if (index == -1 && o == null)
|
||||||
|
{
|
||||||
|
text = defaultText;
|
||||||
|
}
|
||||||
|
else if (o instanceof Enum)
|
||||||
{
|
{
|
||||||
text = Text.titleCase((Enum) o);
|
text = Text.titleCase((Enum) o);
|
||||||
}
|
}
|
||||||
|
else if (o instanceof ComboBoxIconEntry)
|
||||||
|
{
|
||||||
|
ComboBoxIconEntry e = (ComboBoxIconEntry) o;
|
||||||
|
text = e.getText();
|
||||||
|
setIcon(e.getIcon());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text = o.toString();
|
text = o.toString();
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ public class GameEventManager
|
|||||||
|
|
||||||
if (itemContainer != null)
|
if (itemContainer != null)
|
||||||
{
|
{
|
||||||
eventBus.post(new ItemContainerChanged(itemContainer));
|
eventBus.post(new ItemContainerChanged(inventory.getId(), itemContainer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 raiyni <https://github.com/raiyni>
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import net.runelite.api.EquipmentInventorySlot;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemContainer;
|
||||||
|
import static net.runelite.api.ItemID.*;
|
||||||
|
|
||||||
|
public enum Graceful
|
||||||
|
{
|
||||||
|
// TODO: It would be nice if we have the IDs for just the equipped variants of the Graceful set items.
|
||||||
|
HOOD(
|
||||||
|
GRACEFUL_HOOD_11851, GRACEFUL_HOOD_13579, GRACEFUL_HOOD_13580, GRACEFUL_HOOD_13591, GRACEFUL_HOOD_13592,
|
||||||
|
GRACEFUL_HOOD_13603, GRACEFUL_HOOD_13604, GRACEFUL_HOOD_13615, GRACEFUL_HOOD_13616, GRACEFUL_HOOD_13627,
|
||||||
|
GRACEFUL_HOOD_13628, GRACEFUL_HOOD_13667, GRACEFUL_HOOD_13668, GRACEFUL_HOOD_21061, GRACEFUL_HOOD_21063
|
||||||
|
),
|
||||||
|
|
||||||
|
TOP(
|
||||||
|
GRACEFUL_TOP_11855, GRACEFUL_TOP_13583, GRACEFUL_TOP_13584, GRACEFUL_TOP_13595, GRACEFUL_TOP_13596,
|
||||||
|
GRACEFUL_TOP_13607, GRACEFUL_TOP_13608, GRACEFUL_TOP_13619, GRACEFUL_TOP_13620, GRACEFUL_TOP_13631,
|
||||||
|
GRACEFUL_TOP_13632, GRACEFUL_TOP_13671, GRACEFUL_TOP_13672, GRACEFUL_TOP_21067, GRACEFUL_TOP_21069
|
||||||
|
),
|
||||||
|
|
||||||
|
LEGS(
|
||||||
|
GRACEFUL_LEGS_11857, GRACEFUL_LEGS_13585, GRACEFUL_LEGS_13586, GRACEFUL_LEGS_13597, GRACEFUL_LEGS_13598,
|
||||||
|
GRACEFUL_LEGS_13609, GRACEFUL_LEGS_13610, GRACEFUL_LEGS_13621, GRACEFUL_LEGS_13622, GRACEFUL_LEGS_13633,
|
||||||
|
GRACEFUL_LEGS_13634, GRACEFUL_LEGS_13673, GRACEFUL_LEGS_13674, GRACEFUL_LEGS_21070, GRACEFUL_LEGS_21072
|
||||||
|
),
|
||||||
|
|
||||||
|
GLOVES(
|
||||||
|
GRACEFUL_GLOVES_11859, GRACEFUL_GLOVES_13587, GRACEFUL_GLOVES_13588, GRACEFUL_GLOVES_13599, GRACEFUL_GLOVES_13600,
|
||||||
|
GRACEFUL_GLOVES_13611, GRACEFUL_GLOVES_13612, GRACEFUL_GLOVES_13623, GRACEFUL_GLOVES_13624, GRACEFUL_GLOVES_13635,
|
||||||
|
GRACEFUL_GLOVES_13636, GRACEFUL_GLOVES_13675, GRACEFUL_GLOVES_13676, GRACEFUL_GLOVES_21073, GRACEFUL_GLOVES_21075
|
||||||
|
),
|
||||||
|
|
||||||
|
BOOTS(
|
||||||
|
GRACEFUL_BOOTS_11861, GRACEFUL_BOOTS_13589, GRACEFUL_BOOTS_13590, GRACEFUL_BOOTS_13601, GRACEFUL_BOOTS_13602,
|
||||||
|
GRACEFUL_BOOTS_13613, GRACEFUL_BOOTS_13614, GRACEFUL_BOOTS_13625, GRACEFUL_BOOTS_13626, GRACEFUL_BOOTS_13637,
|
||||||
|
GRACEFUL_BOOTS_13638, GRACEFUL_BOOTS_13677, GRACEFUL_BOOTS_13678, GRACEFUL_BOOTS_21076, GRACEFUL_BOOTS_21078
|
||||||
|
),
|
||||||
|
|
||||||
|
// Agility skill capes and the non-cosmetic Max capes also count for the Graceful set effect
|
||||||
|
CAPE(
|
||||||
|
GRACEFUL_CAPE_11853, GRACEFUL_CAPE_13581, GRACEFUL_CAPE_13582, GRACEFUL_CAPE_13593, GRACEFUL_CAPE_13594,
|
||||||
|
GRACEFUL_CAPE_13605, GRACEFUL_CAPE_13606, GRACEFUL_CAPE_13617, GRACEFUL_CAPE_13618, GRACEFUL_CAPE_13629,
|
||||||
|
GRACEFUL_CAPE_13630, GRACEFUL_CAPE_13669, GRACEFUL_CAPE_13670, GRACEFUL_CAPE_21064, GRACEFUL_CAPE_21066,
|
||||||
|
AGILITY_CAPE, AGILITY_CAPET, MAX_CAPE
|
||||||
|
);
|
||||||
|
|
||||||
|
private final ImmutableSet<Integer> ids;
|
||||||
|
|
||||||
|
Graceful(Integer... ids)
|
||||||
|
{
|
||||||
|
this.ids = ImmutableSet.copyOf(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasFullSet(final ItemContainer equipment)
|
||||||
|
{
|
||||||
|
if (equipment == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Item[] items = equipment.getItems();
|
||||||
|
|
||||||
|
if (equipment == null || items.length <= EquipmentInventorySlot.BOOTS.getSlotIdx())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HOOD.ids.contains(items[EquipmentInventorySlot.HEAD.getSlotIdx()].getId())
|
||||||
|
&& TOP.ids.contains(items[EquipmentInventorySlot.BODY.getSlotIdx()].getId())
|
||||||
|
&& LEGS.ids.contains(items[EquipmentInventorySlot.LEGS.getSlotIdx()].getId())
|
||||||
|
&& GLOVES.ids.contains(items[EquipmentInventorySlot.GLOVES.getSlotIdx()].getId())
|
||||||
|
&& BOOTS.ids.contains(items[EquipmentInventorySlot.BOOTS.getSlotIdx()].getId())
|
||||||
|
&& CAPE.ids.contains(items[EquipmentInventorySlot.CAPE.getSlotIdx()].getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ import com.sun.jna.platform.win32.WinDef;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
class IcmpEchoReply extends Structure
|
public class IcmpEchoReply extends Structure
|
||||||
{
|
{
|
||||||
private static final int IP_OPTION_INFO_SIZE = 1 + 1 + 1 + 1 + (Pointer.SIZE == 8 ? 12 : 4); // on 64bit vms add 4 byte padding
|
private static final int IP_OPTION_INFO_SIZE = 1 + 1 + 1 + 1 + (Pointer.SIZE == 8 ? 12 : 4); // on 64bit vms add 4 byte padding
|
||||||
public static final int SIZE = 4 + 4 + 4 + 2 + 2 + Pointer.SIZE + IP_OPTION_INFO_SIZE;
|
public static final int SIZE = 4 + 4 + 4 + 2 + 2 + Pointer.SIZE + IP_OPTION_INFO_SIZE;
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,616 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||||
|
* 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.itemskeptondeath;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.testing.fieldbinder.Bind;
|
||||||
|
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import net.runelite.api.Client;
|
||||||
|
import net.runelite.api.Item;
|
||||||
|
import net.runelite.api.ItemDefinition;
|
||||||
|
import net.runelite.api.ItemID;
|
||||||
|
import net.runelite.client.game.ItemManager;
|
||||||
|
import static net.runelite.client.plugins.itemskeptondeath.ItemsKeptOnDeathPlugin.DeathItems;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ItemsKeptOnDeathPluginTest
|
||||||
|
{
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private Client client;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
@Bind
|
||||||
|
private ItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ItemsKeptOnDeathPlugin plugin;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before()
|
||||||
|
{
|
||||||
|
Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this);
|
||||||
|
resetBuffs();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetBuffs()
|
||||||
|
{
|
||||||
|
plugin.isSkulled = false;
|
||||||
|
plugin.protectingItem = false;
|
||||||
|
plugin.wildyLevel = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mocks an item and the necessary itemManager functions for it
|
||||||
|
private Item mItem(final int id, final int qty, final String name, final boolean tradeable, final int price)
|
||||||
|
{
|
||||||
|
// Mock Item Composition and necessary ItemManager methods for this item
|
||||||
|
ItemDefinition c = mock(ItemDefinition.class);
|
||||||
|
when(c.getId())
|
||||||
|
.thenReturn(id);
|
||||||
|
when(c.getName())
|
||||||
|
.thenReturn(name);
|
||||||
|
when(c.isTradeable())
|
||||||
|
.thenReturn(tradeable);
|
||||||
|
when(c.getPrice())
|
||||||
|
.thenReturn(price);
|
||||||
|
|
||||||
|
if (!tradeable)
|
||||||
|
{
|
||||||
|
when(c.getNote()).thenReturn(-1);
|
||||||
|
when(c.getLinkedNoteId()).thenReturn(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
when(itemManager.getItemDefinition(id)).thenReturn(c);
|
||||||
|
when(itemManager.canonicalize(id)).thenReturn(id);
|
||||||
|
when(itemManager.getItemPrice(id, true)).thenReturn(price);
|
||||||
|
|
||||||
|
return mockItem(id, qty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a mocked item
|
||||||
|
private Item mockItem(final int id, final int qty)
|
||||||
|
{
|
||||||
|
Item item = mock(Item.class);
|
||||||
|
|
||||||
|
when(item.getId()).thenReturn(id);
|
||||||
|
when(item.getQuantity()).thenReturn(qty);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deathPriceTestRegularItems()
|
||||||
|
{
|
||||||
|
final Item acs = mItem(ItemID.ARMADYL_CHAINSKIRT, 1, "Armadyl chainskirt", true, 27837495);
|
||||||
|
assertEquals(27837495, plugin.getDeathPrice(acs));
|
||||||
|
|
||||||
|
final Item karambwan = mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608);
|
||||||
|
assertEquals(608, plugin.getDeathPrice(karambwan));
|
||||||
|
|
||||||
|
final Item defender = mItem(ItemID.RUNE_DEFENDER, 1, "Rune defender", false, 35000);
|
||||||
|
assertEquals(35000, plugin.getDeathPrice(defender));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deathPriceTestItemMapping()
|
||||||
|
{
|
||||||
|
mItem(ItemID.OCCULT_NECKLACE, 1, "Occult necklace", true, 1000000);
|
||||||
|
mItem(ItemID.OCCULT_ORNAMENT_KIT, 1, "Occult ornament kit", true, 3000000);
|
||||||
|
final Item occult = mItem(ItemID.OCCULT_NECKLACE_OR, 1, "Occult necklace (or)", false, 0);
|
||||||
|
assertEquals(4000000, plugin.getDeathPrice(occult));
|
||||||
|
|
||||||
|
mItem(ItemID.BLACK_MASK, 1, "Black mask", true, 1000000);
|
||||||
|
final Item blackMask8 = mItem(ItemID.BLACK_MASK_8, 1, "Black mask (8)", false, 0);
|
||||||
|
assertEquals(1000000, plugin.getDeathPrice(blackMask8));
|
||||||
|
final Item slayerHelm = mItem(ItemID.SLAYER_HELMET, 1, "Slayer helmet", false, 0);
|
||||||
|
assertEquals(1000000, plugin.getDeathPrice(slayerHelm));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deathPriceTestFixedPriceItems()
|
||||||
|
{
|
||||||
|
mItem(ItemID.KARILS_COIF_0, 1, "Karil's coif 0", true, 35000);
|
||||||
|
final Item coif = mItem(ItemID.KARILS_COIF_100, 1, "Karil's coif 100", false, 0);
|
||||||
|
final int coifOffset = FixedPriceItem.KARILS_COIF_100.getOffset();
|
||||||
|
assertEquals(35000 + coifOffset, plugin.getDeathPrice(coif));
|
||||||
|
|
||||||
|
mItem(ItemID.AHRIMS_ROBETOP_0, 1, "Ahrim's robetop 0", true, 2500000);
|
||||||
|
final Item robetop = mItem(ItemID.AHRIMS_ROBETOP_25, 1, "Ahrim's robetop 100", false, 0);
|
||||||
|
final int robetopOffset = FixedPriceItem.AHRIMS_ROBETOP_25.getOffset();
|
||||||
|
assertEquals(2500000 + robetopOffset, plugin.getDeathPrice(robetop));
|
||||||
|
|
||||||
|
mItem(ItemID.AMULET_OF_GLORY, 1, "Amulet of glory", true, 13000);
|
||||||
|
final Item glory = mItem(ItemID.AMULET_OF_GLORY3, 1, "Amulet of glory(3)", true, 0);
|
||||||
|
final int gloryOffset = FixedPriceItem.AMULET_OF_GLORY3.getOffset();
|
||||||
|
assertEquals(13000 + gloryOffset, plugin.getDeathPrice(glory));
|
||||||
|
|
||||||
|
mItem(ItemID.COMBAT_BRACELET, 1, "Combat bracelet", true, 13500);
|
||||||
|
final Item brace = mItem(ItemID.COMBAT_BRACELET1, 1, "Combat bracelet(1)", true, 0);
|
||||||
|
final int braceletOffset = FixedPriceItem.COMBAT_BRACELET1.getOffset();
|
||||||
|
assertEquals(13500 + braceletOffset, plugin.getDeathPrice(brace));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deathPriceTestDynamicPriceItems()
|
||||||
|
{
|
||||||
|
final Item rod8 = mItem(ItemID.RING_OF_DUELING8, 1, "Ring of dueling(8)", true, 725);
|
||||||
|
final Item rod3 = mItem(ItemID.RING_OF_DUELING3, 1, "Ring of dueling(3)", true, 0);
|
||||||
|
final Item rod1 = mItem(ItemID.RING_OF_DUELING1, 1, "Ring of dueling(1)", true, 0);
|
||||||
|
// Dynamic price items
|
||||||
|
final int rodPrice = 725 / 8;
|
||||||
|
assertEquals(rodPrice, plugin.getDeathPrice(rod1));
|
||||||
|
assertEquals(725, plugin.getDeathPrice(rod8));
|
||||||
|
assertEquals(rodPrice * 3, plugin.getDeathPrice(rod3));
|
||||||
|
|
||||||
|
final Item nop5 = mItem(ItemID.NECKLACE_OF_PASSAGE5, 1, "Necklace of passage(5)", true, 1250);
|
||||||
|
final Item nop4 = mItem(ItemID.NECKLACE_OF_PASSAGE4, 1, "Necklace of passage(4)", true, 0);
|
||||||
|
final Item nop2 = mItem(ItemID.NECKLACE_OF_PASSAGE2, 1, "Necklace of passage(2)", true, 0);
|
||||||
|
|
||||||
|
final int nopPrice = 1250 / 5;
|
||||||
|
assertEquals(nopPrice * 2, plugin.getDeathPrice(nop2));
|
||||||
|
assertEquals(nopPrice * 4, plugin.getDeathPrice(nop4));
|
||||||
|
assertEquals(1250, plugin.getDeathPrice(nop5));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item[] getFourExpensiveItems()
|
||||||
|
{
|
||||||
|
return new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.TWISTED_BOW, 1, "Twister bow", true, Integer.MAX_VALUE),
|
||||||
|
mItem(ItemID.SCYTHE_OF_VITUR, 1, "Scythe of vitur", true, Integer.MAX_VALUE),
|
||||||
|
mItem(ItemID.ELYSIAN_SPIRIT_SHIELD, 1, "Elysian spirit shield", true, 800000000),
|
||||||
|
mItem(ItemID.ARCANE_SPIRIT_SHIELD, 1, "Arcane spirit shield", true, 250000000)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alwaysLostTestRunePouch()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFourExpensiveItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.RUNE_POUCH, 1, "Rune pouch", false, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
assertFalse(deathItems.isHasAlwaysLost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alwaysLostTestRunePouchWildy()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFourExpensiveItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.RUNE_POUCH, 1, "Rune pouch", false, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
assertTrue(deathItems.isHasAlwaysLost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alwaysLostTestLootBag()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFourExpensiveItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.LOOTING_BAG, 1, "Looting bag", false, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
assertTrue(deathItems.isHasAlwaysLost());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void alwaysLostTestLootBagWildy()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFourExpensiveItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.LOOTING_BAG, 1, "Looting bag", false, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
assertTrue(deathItems.isHasAlwaysLost());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item[] getClueBoxTestInventory()
|
||||||
|
{
|
||||||
|
return new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.BLACK_DHIDE_BODY, 1, "Black d'hide body", true, 7552),
|
||||||
|
mItem(ItemID.ARMADYL_CHAINSKIRT, 1, "Armadyl chainskirt", true, 27837495),
|
||||||
|
mItem(ItemID.PEGASIAN_BOOTS, 1, "Pegasian boots", true, 30542187),
|
||||||
|
mItem(ItemID.DRAGON_SCIMITAR, 1, "Dragon scimitar", true, 63123),
|
||||||
|
|
||||||
|
mItem(ItemID.HELM_OF_NEITIZNOT, 1, "Helm of neitiznot", true, 45519),
|
||||||
|
mItem(ItemID.RUNE_DEFENDER, 1, "Rune defender", false, 35000),
|
||||||
|
mItem(ItemID.SPADE, 1, "Spade", true, 104),
|
||||||
|
mItem(ItemID.CLUE_SCROLL_EASY, 1, "Clue scroll (easy)", false, 50),
|
||||||
|
|
||||||
|
mItem(ItemID.CLUE_BOX, 1, "Clue box", false, 50),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.LAW_RUNE, 200, "Law rune", true, 212),
|
||||||
|
mItem(ItemID.DUST_RUNE, 200, "Dust rune", true, 3),
|
||||||
|
|
||||||
|
mItem(ItemID.CLUE_SCROLL_MASTER, 1, "Clue scroll (master)", false, 50),
|
||||||
|
mItem(ItemID.CLUELESS_SCROLL, 1, "Clueless scroll", false, 50),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isClueBoxableTest()
|
||||||
|
{
|
||||||
|
getClueBoxTestInventory();
|
||||||
|
mItem(ItemID.REWARD_CASKET_EASY, 1, "Reward casket (easy)", false, 50);
|
||||||
|
|
||||||
|
assertTrue(plugin.isClueBoxable(ItemID.CLUE_SCROLL_EASY));
|
||||||
|
assertTrue(plugin.isClueBoxable(ItemID.CLUE_SCROLL_MASTER));
|
||||||
|
assertTrue(plugin.isClueBoxable(ItemID.REWARD_CASKET_EASY));
|
||||||
|
|
||||||
|
assertFalse(plugin.isClueBoxable(ItemID.CLUELESS_SCROLL));
|
||||||
|
assertFalse(plugin.isClueBoxable(ItemID.LAW_RUNE));
|
||||||
|
assertFalse(plugin.isClueBoxable(ItemID.SPADE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestDefault()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.PEGASIAN_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.ARMADYL_CHAINSKIRT, 1),
|
||||||
|
new ItemStack(ItemID.DRAGON_SCIMITAR, 1),
|
||||||
|
new ItemStack(ItemID.RUNE_DEFENDER, 1),
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_EASY, 1),
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1),
|
||||||
|
new ItemStack(ItemID.CLUELESS_SCROLL, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
assertEquals((inv.length + equip.length) - expectedKept.size(), lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestDeepWildy()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 21;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.PEGASIAN_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.ARMADYL_CHAINSKIRT, 1),
|
||||||
|
new ItemStack(ItemID.DRAGON_SCIMITAR, 1),
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size();
|
||||||
|
assertEquals((inv.length + equip.length) - keptOffset, lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestDeepWildyProtectItem()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 21;
|
||||||
|
plugin.protectingItem = true;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.PEGASIAN_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.ARMADYL_CHAINSKIRT, 1),
|
||||||
|
new ItemStack(ItemID.DRAGON_SCIMITAR, 1),
|
||||||
|
new ItemStack(ItemID.HELM_OF_NEITIZNOT, 1),
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1) // Clue box
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size();
|
||||||
|
assertEquals((inv.length + equip.length) - keptOffset, lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestDeepWildySkulled()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 21;
|
||||||
|
plugin.isSkulled = true;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Collections.singletonList(
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size();
|
||||||
|
assertEquals(lost.size(), (inv.length + equip.length) - keptOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestLowWildy()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.PEGASIAN_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.ARMADYL_CHAINSKIRT, 1),
|
||||||
|
new ItemStack(ItemID.DRAGON_SCIMITAR, 1),
|
||||||
|
new ItemStack(ItemID.RUNE_DEFENDER, 1), // Rune defender protected because of broken variant
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size();
|
||||||
|
assertEquals(lost.size(), (inv.length + equip.length) - keptOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestLowWildyProtectItem()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
plugin.protectingItem = true;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.PEGASIAN_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.ARMADYL_CHAINSKIRT, 1),
|
||||||
|
new ItemStack(ItemID.DRAGON_SCIMITAR, 1),
|
||||||
|
new ItemStack(ItemID.HELM_OF_NEITIZNOT, 1),
|
||||||
|
new ItemStack(ItemID.RUNE_DEFENDER, 1), // Rune defender protected because of broken variant
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size();
|
||||||
|
assertEquals((inv.length + equip.length) - keptOffset, lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestLowWildySkulled()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
plugin.isSkulled = true;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.RUNE_DEFENDER, 1), // Rune defender protected because of broken variant
|
||||||
|
new ItemStack(ItemID.CLUE_SCROLL_MASTER, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size();
|
||||||
|
assertEquals((inv.length + equip.length) - keptOffset, lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item[] getClueBoxCasketTestInventory()
|
||||||
|
{
|
||||||
|
// Reward caskets can stack but the clue box should only protect one
|
||||||
|
return new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.BLACK_DHIDE_BODY, 1, "Black d'hide body", true, 7552),
|
||||||
|
mItem(ItemID.ARMADYL_CHAINSKIRT, 1, "Armadyl chainskirt", true, 27837495),
|
||||||
|
mItem(ItemID.PEGASIAN_BOOTS, 1, "Pegasian boots", true, 30542187),
|
||||||
|
mItem(ItemID.DRAGON_SCIMITAR, 1, "Dragon scimitar", true, 63123),
|
||||||
|
|
||||||
|
mItem(ItemID.SPADE, 1, "Spade", true, 104),
|
||||||
|
mItem(ItemID.CLUE_SCROLL_EASY, 1, "Clue scroll (easy)", false, 50),
|
||||||
|
mItem(ItemID.REWARD_CASKET_EASY, 20, "Reward casket (easy)", false, 50),
|
||||||
|
mItem(ItemID.CLUE_BOX, 1, "Clue box", false, 50),
|
||||||
|
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
mItem(ItemID.COOKED_KARAMBWAN, 1, "Cooked karambwan", true, 608),
|
||||||
|
|
||||||
|
mItem(ItemID.LAW_RUNE, 200, "Law rune", true, 212),
|
||||||
|
mItem(ItemID.DUST_RUNE, 200, "Dust rune", true, 3),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clueBoxTestCasketProtect()
|
||||||
|
{
|
||||||
|
final Item[] inv = getClueBoxCasketTestInventory();
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.PEGASIAN_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.ARMADYL_CHAINSKIRT, 1),
|
||||||
|
new ItemStack(ItemID.DRAGON_SCIMITAR, 1),
|
||||||
|
new ItemStack(ItemID.REWARD_CASKET_EASY, 1) // Clue box
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
final int keptOffset = expectedKept.size() - 1; // We are still losing some reward caskets.
|
||||||
|
assertEquals((inv.length + equip.length) - keptOffset, lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item[] getFullGracefulItems()
|
||||||
|
{
|
||||||
|
return new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.GRACEFUL_HOOD, 1, "Graceful hood", false, 35),
|
||||||
|
mItem(ItemID.GRACEFUL_CAPE, 1, "Graceful cape", false, 40),
|
||||||
|
mItem(ItemID.GRACEFUL_TOP, 1, "Graceful top", false, 55),
|
||||||
|
mItem(ItemID.GRACEFUL_LEGS, 1, "Graceful legs", false, 60),
|
||||||
|
mItem(ItemID.GRACEFUL_BOOTS, 1, "Graceful boots", false, 40),
|
||||||
|
mItem(ItemID.GRACEFUL_GLOVES, 1, "Graceful gloves", false, 30),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void gracefulValueTest()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFullGracefulItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.AMULET_OF_GLORY6, 1, "Amulet of glory (6)", true, 20000)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.AMULET_OF_GLORY6, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_CAPE, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_TOP, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_LEGS, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_BOOTS, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_HOOD, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_GLOVES, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
assertEquals((inv.length + equip.length) - expectedKept.size(), lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void gracefulValueTestWildy()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFullGracefulItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.AMULET_OF_GLORY6, 1, "Amulet of glory (6)", true, 20000)
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin.wildyLevel = 1;
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
final List<ItemStack> expectedKept = Arrays.asList(
|
||||||
|
new ItemStack(ItemID.AMULET_OF_GLORY6, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_CAPE, 1),
|
||||||
|
new ItemStack(ItemID.GRACEFUL_TOP, 1)
|
||||||
|
);
|
||||||
|
assertEquals(expectedKept, kept);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
assertEquals((inv.length + equip.length) - expectedKept.size(), lost.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lostIfNotProtectedTestLost()
|
||||||
|
{
|
||||||
|
final Item[] inv = getFourExpensiveItems();
|
||||||
|
final Item[] equip = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.SHADOW_SWORD, 1, "Shadow sword", false, 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> lost = deathItems.getLostItems();
|
||||||
|
assertTrue(lost.contains(new ItemStack(ItemID.SHADOW_SWORD, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lostIfNotProtectedTestKept()
|
||||||
|
{
|
||||||
|
final Item[] inv = new Item[]
|
||||||
|
{
|
||||||
|
mItem(ItemID.SHADOW_SWORD, 1, "Shadow sword", false, 1)
|
||||||
|
};
|
||||||
|
final Item[] equip = new Item[0];
|
||||||
|
|
||||||
|
final DeathItems deathItems = plugin.calculateKeptLostItems(inv, equip);
|
||||||
|
|
||||||
|
final List<ItemStack> kept = deathItems.getKeptItems();
|
||||||
|
assertTrue(kept.contains(new ItemStack(ItemID.SHADOW_SWORD, 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -162,7 +162,7 @@ public class MotherlodePluginTest
|
|||||||
when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory);
|
when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory);
|
||||||
|
|
||||||
// Trigger comparison
|
// Trigger comparison
|
||||||
motherlodePlugin.onItemContainerChanged(new ItemContainerChanged(inventory));
|
motherlodePlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.INVENTORY.getId(), inventory));
|
||||||
|
|
||||||
verify(motherlodeSession).updateOreFound(ItemID.RUNITE_ORE, 1);
|
verify(motherlodeSession).updateOreFound(ItemID.RUNITE_ORE, 1);
|
||||||
verify(motherlodeSession).updateOreFound(ItemID.GOLDEN_NUGGET, 4);
|
verify(motherlodeSession).updateOreFound(ItemID.GOLDEN_NUGGET, 4);
|
||||||
|
|||||||
@@ -163,6 +163,9 @@ public abstract class RSClientMixin implements RSClient
|
|||||||
@Inject
|
@Inject
|
||||||
private static boolean interpolateObjectAnimations;
|
private static boolean interpolateObjectAnimations;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private static boolean interpolateWidgetAnimations;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private static RSPlayer[] oldPlayers = new RSPlayer[2048];
|
private static RSPlayer[] oldPlayers = new RSPlayer[2048];
|
||||||
|
|
||||||
@@ -307,6 +310,20 @@ public abstract class RSClientMixin implements RSClient
|
|||||||
interpolateObjectAnimations = interpolate;
|
interpolateObjectAnimations = interpolate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public boolean isInterpolateWidgetAnimations()
|
||||||
|
{
|
||||||
|
return interpolateWidgetAnimations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Override
|
||||||
|
public void setInterpolateWidgetAnimations(boolean interpolate)
|
||||||
|
{
|
||||||
|
interpolateWidgetAnimations = interpolate;
|
||||||
|
}
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Override
|
@Override
|
||||||
public void setInventoryDragDelay(int delay)
|
public void setInventoryDragDelay(int delay)
|
||||||
|
|||||||
@@ -24,11 +24,13 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.mixins;
|
package net.runelite.mixins;
|
||||||
|
|
||||||
|
import net.runelite.api.InventoryID;
|
||||||
import net.runelite.api.Item;
|
import net.runelite.api.Item;
|
||||||
import net.runelite.api.events.ItemContainerChanged;
|
import net.runelite.api.events.ItemContainerChanged;
|
||||||
import net.runelite.api.mixins.FieldHook;
|
import net.runelite.api.mixins.Copy;
|
||||||
import net.runelite.api.mixins.Inject;
|
import net.runelite.api.mixins.Inject;
|
||||||
import net.runelite.api.mixins.Mixin;
|
import net.runelite.api.mixins.Mixin;
|
||||||
|
import net.runelite.api.mixins.Replace;
|
||||||
import net.runelite.api.mixins.Shadow;
|
import net.runelite.api.mixins.Shadow;
|
||||||
import net.runelite.rs.api.RSClient;
|
import net.runelite.rs.api.RSClient;
|
||||||
import net.runelite.rs.api.RSGroundItem;
|
import net.runelite.rs.api.RSGroundItem;
|
||||||
@@ -41,7 +43,7 @@ public abstract class RSItemContainerMixin implements RSItemContainer
|
|||||||
private static RSClient client;
|
private static RSClient client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private int rl$lastCycle;
|
static private int rl$lastCycle;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Override
|
@Override
|
||||||
@@ -62,21 +64,27 @@ public abstract class RSItemContainerMixin implements RSItemContainer
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FieldHook("quantities")
|
@Copy("itemContainerSetItem")
|
||||||
@Inject
|
static void rs$itemContainerSetItem(int itemContainerId, int index, int itemId, int itemQuantity)
|
||||||
public void stackSizesChanged(int idx)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Replace("itemContainerSetItem")
|
||||||
|
static void rl$itemContainerSetItem(int itemContainerId, int index, int itemId, int itemQuantity)
|
||||||
|
{
|
||||||
|
rs$itemContainerSetItem(itemContainerId, index, itemId, itemQuantity);
|
||||||
|
|
||||||
int cycle = client.getGameCycle();
|
int cycle = client.getGameCycle();
|
||||||
if (rl$lastCycle == cycle)
|
if (rl$lastCycle == cycle)
|
||||||
{
|
{
|
||||||
// Limit item container updates to one per cycle
|
// Limit item container updates to one per cycle
|
||||||
|
// No need to repeatedly update. The game just needs to know that containers changed once per cycle
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rl$lastCycle = cycle;
|
rl$lastCycle = cycle;
|
||||||
|
ItemContainerChanged event = new ItemContainerChanged(itemContainerId, client.getItemContainer(InventoryID.getValue(itemContainerId)));
|
||||||
ItemContainerChanged event = new ItemContainerChanged(this);
|
|
||||||
client.getCallbacks().postDeferred(event);
|
client.getCallbacks().postDeferred(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ public abstract class RSSequenceDefinitionMixin implements RSSequenceDefinition
|
|||||||
@Shadow("client")
|
@Shadow("client")
|
||||||
private static RSClient client;
|
private static RSClient client;
|
||||||
|
|
||||||
@Copy("animateSequence2")
|
@Copy("applyTransformations")
|
||||||
public abstract RSModel rs$applyTransformations(RSModel model, int actionFrame, RSSequenceDefinition poseSeq, int poseFrame);
|
public abstract RSModel rs$applyTransformations(RSModel model, int actionFrame, RSSequenceDefinition poseSeq, int poseFrame);
|
||||||
|
|
||||||
@Replace("animateSequence2")
|
@Replace("applyTransformations")
|
||||||
public RSModel rl$applyTransformations(RSModel model, int actionFrame, RSSequenceDefinition poseSeq, int poseFrame)
|
public RSModel rl$applyTransformations(RSModel model, int actionFrame, RSSequenceDefinition poseSeq, int poseFrame)
|
||||||
{
|
{
|
||||||
// reset frame ids because we're not interpolating this
|
// reset frame ids because we're not interpolating this
|
||||||
@@ -35,185 +35,253 @@ public abstract class RSSequenceDefinitionMixin implements RSSequenceDefinition
|
|||||||
return rs$applyTransformations(model, actionFrame, poseSeq, poseFrame);
|
return rs$applyTransformations(model, actionFrame, poseSeq, poseFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Copy("animateSequence")
|
@Copy("transformActorModel")
|
||||||
public abstract RSModel rs$transformActorModel(RSModel model, int frameIdx);
|
public abstract RSModel rs$transformActorModel(RSModel model, int frameIdx);
|
||||||
|
|
||||||
@Replace("animateSequence")
|
@Replace("transformActorModel")
|
||||||
public RSModel rl$transformActorModel(RSModel model, int frame)
|
public RSModel rl$transformActorModel(RSModel model, int frame)
|
||||||
{
|
{
|
||||||
// check if the frame has been modified
|
// check if the frame has not been modified
|
||||||
if (frame < 0)
|
if (frame >= 0)
|
||||||
{
|
|
||||||
// remove flag to check if the frame has been modified
|
|
||||||
int packed = frame ^ Integer.MIN_VALUE;
|
|
||||||
int interval = packed >> 16;
|
|
||||||
frame = packed & 0xFFFF;
|
|
||||||
int nextFrame = frame + 1;
|
|
||||||
if (nextFrame >= getFrameIDs().length)
|
|
||||||
{
|
|
||||||
// dont interpolate last frame
|
|
||||||
nextFrame = -1;
|
|
||||||
}
|
|
||||||
int[] frameIds = getFrameIDs();
|
|
||||||
int frameId = frameIds[frame];
|
|
||||||
RSFrames frames = client.getFrames(frameId >> 16);
|
|
||||||
int frameIdx = frameId & 0xFFFF;
|
|
||||||
|
|
||||||
int nextFrameIdx = -1;
|
|
||||||
RSFrames nextFrames = null;
|
|
||||||
if (nextFrame != -1)
|
|
||||||
{
|
|
||||||
int nextFrameId = frameIds[nextFrame];
|
|
||||||
nextFrames = client.getFrames(nextFrameId >> 16);
|
|
||||||
nextFrameIdx = nextFrameId & 0xFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frames == null)
|
|
||||||
{
|
|
||||||
// not sure what toSharedModel does but it is needed
|
|
||||||
return model.toSharedModel(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RSModel animatedModel = model.toSharedModel(!frames.getFrames()[frameIdx].isShowing());
|
|
||||||
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
|
||||||
getFrameLenths()[frame]);
|
|
||||||
return animatedModel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return rs$transformActorModel(model, frame);
|
return rs$transformActorModel(model, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove flag to check if the frame has been modified
|
||||||
|
int packed = frame ^ Integer.MIN_VALUE;
|
||||||
|
int interval = packed >> 16;
|
||||||
|
frame = packed & 0xFFFF;
|
||||||
|
int nextFrame = frame + 1;
|
||||||
|
if (nextFrame >= getFrameIDs().length)
|
||||||
|
{
|
||||||
|
// dont interpolate last frame
|
||||||
|
nextFrame = -1;
|
||||||
|
}
|
||||||
|
int[] frameIds = getFrameIDs();
|
||||||
|
int frameId = frameIds[frame];
|
||||||
|
RSFrames frames = client.getFrames(frameId >> 16);
|
||||||
|
int frameIdx = frameId & 0xFFFF;
|
||||||
|
|
||||||
|
int nextFrameIdx = -1;
|
||||||
|
RSFrames nextFrames = null;
|
||||||
|
if (nextFrame != -1)
|
||||||
|
{
|
||||||
|
int nextFrameId = frameIds[nextFrame];
|
||||||
|
nextFrames = client.getFrames(nextFrameId >> 16);
|
||||||
|
nextFrameIdx = nextFrameId & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frames == null)
|
||||||
|
{
|
||||||
|
// not sure what toSharedModel does but it is needed
|
||||||
|
return model.toSharedModel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RSModel animatedModel = model.toSharedModel(!frames.getFrames()[frameIdx].isShowing());
|
||||||
|
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
||||||
|
getFrameLenths()[frame]);
|
||||||
|
return animatedModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Copy("animateObject")
|
@Copy("transformObjectModel")
|
||||||
public abstract RSModel rs$transformObjectModel(RSModel model, int frame, int rotation);
|
public abstract RSModel rs$transformObjectModel(RSModel model, int frame, int rotation);
|
||||||
|
|
||||||
@Replace("animateObject")
|
@Replace("transformObjectModel")
|
||||||
public RSModel rl$transformObjectModel(RSModel model, int frame, int rotation)
|
public RSModel rl$transformObjectModel(RSModel model, int frame, int rotation)
|
||||||
{
|
{
|
||||||
// check if the frame has been modified
|
// check if the frame has not been modified
|
||||||
if (frame < 0)
|
if (frame >= 0)
|
||||||
{
|
|
||||||
// remove flag to check if the frame has been modified
|
|
||||||
int packed = frame ^ Integer.MIN_VALUE;
|
|
||||||
int interval = packed >> 16;
|
|
||||||
frame = packed & 0xFFFF;
|
|
||||||
|
|
||||||
int nextFrame = frame + 1;
|
|
||||||
if (nextFrame >= getFrameIDs().length)
|
|
||||||
{
|
|
||||||
// dont interpolate last frame
|
|
||||||
nextFrame = -1;
|
|
||||||
}
|
|
||||||
int[] frameIds = getFrameIDs();
|
|
||||||
int frameId = frameIds[frame];
|
|
||||||
RSFrames frames = client.getFrames(frameId >> 16);
|
|
||||||
int frameIdx = frameId & 0xFFFF;
|
|
||||||
|
|
||||||
int nextFrameIdx = -1;
|
|
||||||
RSFrames nextFrames = null;
|
|
||||||
if (nextFrame != -1)
|
|
||||||
{
|
|
||||||
int nextFrameId = frameIds[nextFrame];
|
|
||||||
nextFrames = client.getFrames(nextFrameId >> 16);
|
|
||||||
nextFrameIdx = nextFrameId & 0xFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frames == null)
|
|
||||||
{
|
|
||||||
return model.toSharedModel(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RSModel animatedModel = model.toSharedModel(!frames.getFrames()[frameIdx].isShowing());
|
|
||||||
// reset rotation before animating
|
|
||||||
rotation &= 3;
|
|
||||||
if (rotation == 1)
|
|
||||||
{
|
|
||||||
animatedModel.rotateY270Ccw();
|
|
||||||
}
|
|
||||||
else if (rotation == 2)
|
|
||||||
{
|
|
||||||
animatedModel.rotateY180Ccw();
|
|
||||||
}
|
|
||||||
else if (rotation == 3)
|
|
||||||
{
|
|
||||||
animatedModel.rotateY90Ccw();
|
|
||||||
}
|
|
||||||
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
|
||||||
getFrameLenths()[frame]);
|
|
||||||
// reapply rotation after animating
|
|
||||||
if (rotation == 1)
|
|
||||||
{
|
|
||||||
animatedModel.rotateY90Ccw();
|
|
||||||
}
|
|
||||||
else if (rotation == 2)
|
|
||||||
{
|
|
||||||
animatedModel.rotateY180Ccw();
|
|
||||||
}
|
|
||||||
else if (rotation == 3)
|
|
||||||
{
|
|
||||||
animatedModel.rotateY270Ccw();
|
|
||||||
}
|
|
||||||
return animatedModel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return rs$transformObjectModel(model, frame, rotation);
|
return rs$transformObjectModel(model, frame, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove flag to check if the frame has been modified
|
||||||
|
int packed = frame ^ Integer.MIN_VALUE;
|
||||||
|
int interval = packed >> 16;
|
||||||
|
frame = packed & 0xFFFF;
|
||||||
|
|
||||||
|
int nextFrame = frame + 1;
|
||||||
|
if (nextFrame >= getFrameIDs().length)
|
||||||
|
{
|
||||||
|
// dont interpolate last frame
|
||||||
|
nextFrame = -1;
|
||||||
|
}
|
||||||
|
int[] frameIds = getFrameIDs();
|
||||||
|
int frameId = frameIds[frame];
|
||||||
|
RSFrames frames = client.getFrames(frameId >> 16);
|
||||||
|
int frameIdx = frameId & 0xFFFF;
|
||||||
|
|
||||||
|
int nextFrameIdx = -1;
|
||||||
|
RSFrames nextFrames = null;
|
||||||
|
if (nextFrame != -1)
|
||||||
|
{
|
||||||
|
int nextFrameId = frameIds[nextFrame];
|
||||||
|
nextFrames = client.getFrames(nextFrameId >> 16);
|
||||||
|
nextFrameIdx = nextFrameId & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frames == null)
|
||||||
|
{
|
||||||
|
return model.toSharedModel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RSModel animatedModel = model.toSharedModel(!frames.getFrames()[frameIdx].isShowing());
|
||||||
|
// reset rotation before animating
|
||||||
|
rotation &= 3;
|
||||||
|
if (rotation == 1)
|
||||||
|
{
|
||||||
|
animatedModel.rotateY270Ccw();
|
||||||
|
}
|
||||||
|
else if (rotation == 2)
|
||||||
|
{
|
||||||
|
animatedModel.rotateY180Ccw();
|
||||||
|
}
|
||||||
|
else if (rotation == 3)
|
||||||
|
{
|
||||||
|
animatedModel.rotateY90Ccw();
|
||||||
|
}
|
||||||
|
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
||||||
|
getFrameLenths()[frame]);
|
||||||
|
// reapply rotation after animating
|
||||||
|
if (rotation == 1)
|
||||||
|
{
|
||||||
|
animatedModel.rotateY90Ccw();
|
||||||
|
}
|
||||||
|
else if (rotation == 2)
|
||||||
|
{
|
||||||
|
animatedModel.rotateY180Ccw();
|
||||||
|
}
|
||||||
|
else if (rotation == 3)
|
||||||
|
{
|
||||||
|
animatedModel.rotateY270Ccw();
|
||||||
|
}
|
||||||
|
return animatedModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Copy("animateSpotAnimation")
|
@Copy("transformSpotAnimationModel")
|
||||||
public abstract RSModel rs$transformSpotAnimModel(RSModel model, int frame);
|
public abstract RSModel rs$transformSpotAnimationModel(RSModel model, int frame);
|
||||||
|
|
||||||
@Replace("animateSpotAnimation")
|
@Replace("transformSpotAnimationModel")
|
||||||
public RSModel rl$transformSpotAnimModel(RSModel model, int frame)
|
public RSModel rl$transformSpotAnimationModel(RSModel model, int frame)
|
||||||
{
|
{
|
||||||
// check if the frame has been modified
|
// check if the frame has not been modified
|
||||||
if (frame < 0)
|
if (frame >= 0)
|
||||||
{
|
{
|
||||||
// remove flag to check if the frame has been modified
|
return rs$transformSpotAnimationModel(model, frame);
|
||||||
int packed = frame ^ Integer.MIN_VALUE;
|
|
||||||
int interval = packed >> 16;
|
|
||||||
frame = packed & 0xFFFF;
|
|
||||||
int nextFrame = frame + 1;
|
|
||||||
if (nextFrame >= getFrameIDs().length)
|
|
||||||
{
|
|
||||||
// dont interpolate last frame
|
|
||||||
nextFrame = -1;
|
|
||||||
}
|
|
||||||
int[] frameIds = getFrameIDs();
|
|
||||||
int frameId = frameIds[frame];
|
|
||||||
RSFrames frames = client.getFrames(frameId >> 16);
|
|
||||||
int frameIdx = frameId & 0xFFFF;
|
|
||||||
|
|
||||||
int nextFrameIdx = -1;
|
|
||||||
RSFrames nextFrames = null;
|
|
||||||
if (nextFrame != -1)
|
|
||||||
{
|
|
||||||
int nextFrameId = frameIds[nextFrame];
|
|
||||||
nextFrames = client.getFrames(nextFrameId >> 16);
|
|
||||||
nextFrameIdx = nextFrameId & 0xFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frames == null)
|
|
||||||
{
|
|
||||||
return model.toSharedSpotAnimModel(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RSModel animatedModel = model.toSharedSpotAnimModel(!frames.getFrames()[frameIdx].isShowing());
|
|
||||||
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
|
||||||
getFrameLenths()[frame]);
|
|
||||||
return animatedModel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// remove flag to check if the frame has been modified
|
||||||
|
int packed = frame ^ Integer.MIN_VALUE;
|
||||||
|
int interval = packed >> 16;
|
||||||
|
frame = packed & 0xFFFF;
|
||||||
|
int nextFrame = frame + 1;
|
||||||
|
if (nextFrame >= getFrameIDs().length)
|
||||||
{
|
{
|
||||||
return rs$transformSpotAnimModel(model, frame);
|
// dont interpolate last frame
|
||||||
|
nextFrame = -1;
|
||||||
}
|
}
|
||||||
|
int[] frameIds = getFrameIDs();
|
||||||
|
int frameId = frameIds[frame];
|
||||||
|
RSFrames frames = client.getFrames(frameId >> 16);
|
||||||
|
int frameIdx = frameId & 0xFFFF;
|
||||||
|
|
||||||
|
int nextFrameIdx = -1;
|
||||||
|
RSFrames nextFrames = null;
|
||||||
|
if (nextFrame != -1)
|
||||||
|
{
|
||||||
|
int nextFrameId = frameIds[nextFrame];
|
||||||
|
nextFrames = client.getFrames(nextFrameId >> 16);
|
||||||
|
nextFrameIdx = nextFrameId & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frames == null)
|
||||||
|
{
|
||||||
|
return model.toSharedSpotAnimModel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RSModel animatedModel = model.toSharedSpotAnimModel(!frames.getFrames()[frameIdx].isShowing());
|
||||||
|
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
||||||
|
getFrameLenths()[frame]);
|
||||||
|
return animatedModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Copy("transformWidgetModel")
|
||||||
|
public abstract RSModel rs$transformWidgetModel(RSModel model, int frame);
|
||||||
|
|
||||||
|
@Replace("transformWidgetModel")
|
||||||
|
public RSModel rl$transformWidgetModel(RSModel model, int frame)
|
||||||
|
{
|
||||||
|
// check if the frame has not been modified
|
||||||
|
if (frame >= 0)
|
||||||
|
{
|
||||||
|
return rs$transformWidgetModel(model, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove flag to check if the frame has been modified
|
||||||
|
int packed = frame ^ Integer.MIN_VALUE;
|
||||||
|
int interval = packed >> 16;
|
||||||
|
frame = packed & 0xFFFF;
|
||||||
|
|
||||||
|
int nextFrame = frame + 1;
|
||||||
|
if (nextFrame >= getFrameIDs().length)
|
||||||
|
{
|
||||||
|
// dont interpolate last frame
|
||||||
|
nextFrame = -1;
|
||||||
|
}
|
||||||
|
int[] frameIds = getFrameIDs();
|
||||||
|
int frameId = frameIds[frame];
|
||||||
|
RSFrames frames = client.getFrames(frameId >> 16);
|
||||||
|
int frameIdx = frameId & 0xFFFF;
|
||||||
|
|
||||||
|
int nextFrameIdx = -1;
|
||||||
|
RSFrames nextFrames = null;
|
||||||
|
if (nextFrame != -1)
|
||||||
|
{
|
||||||
|
int nextFrameId = frameIds[nextFrame];
|
||||||
|
nextFrames = client.getFrames(nextFrameId >> 16);
|
||||||
|
nextFrameIdx = nextFrameId & 0xFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frames == null)
|
||||||
|
{
|
||||||
|
return model.toSharedModel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RSFrames chatFrames = null;
|
||||||
|
int chatFrameIdx = 0;
|
||||||
|
if (getChatFrameIds() != null && frame < getChatFrameIds().length)
|
||||||
|
{
|
||||||
|
int chatFrameId = getChatFrameIds()[frame];
|
||||||
|
chatFrames = client.getFrames(chatFrameId >> 16);
|
||||||
|
chatFrameIdx = chatFrameId & 0xFFFF;
|
||||||
|
}
|
||||||
|
if (chatFrames != null && chatFrameIdx != 0xFFFF)
|
||||||
|
{
|
||||||
|
RSFrames nextChatFrames = null;
|
||||||
|
int nextChatFrameIdx = -1;
|
||||||
|
if (nextFrame != -1 && nextFrame < getChatFrameIds().length)
|
||||||
|
{
|
||||||
|
int chatFrameId = getChatFrameIds()[nextFrame];
|
||||||
|
nextChatFrames = client.getFrames(chatFrameId >> 16);
|
||||||
|
nextChatFrameIdx = chatFrameId & 0xFFFF;
|
||||||
|
}
|
||||||
|
// not sure if this can even happen but the client checks for this so to be safe
|
||||||
|
if (nextChatFrameIdx == 0xFFFF)
|
||||||
|
{
|
||||||
|
nextChatFrames = null;
|
||||||
|
}
|
||||||
|
RSModel animatedModel = model.toSharedModel(!frames.getFrames()[frameIdx].isShowing()
|
||||||
|
& !chatFrames.getFrames()[chatFrameIdx].isShowing());
|
||||||
|
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
||||||
|
getFrameLenths()[frame]);
|
||||||
|
animatedModel.interpolateFrames(chatFrames, chatFrameIdx, nextChatFrames, nextChatFrameIdx,
|
||||||
|
interval, getFrameLenths()[frame]);
|
||||||
|
return animatedModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
RSModel animatedModel = model.toSharedModel(!frames.getFrames()[frameIdx].isShowing());
|
||||||
|
animatedModel.interpolateFrames(frames, frameIdx, nextFrames, nextFrameIdx, interval,
|
||||||
|
getFrameLenths()[frame]);
|
||||||
|
return animatedModel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import net.runelite.api.Point;
|
|||||||
import net.runelite.api.WidgetNode;
|
import net.runelite.api.WidgetNode;
|
||||||
import net.runelite.api.events.WidgetHiddenChanged;
|
import net.runelite.api.events.WidgetHiddenChanged;
|
||||||
import net.runelite.api.events.WidgetPositioned;
|
import net.runelite.api.events.WidgetPositioned;
|
||||||
|
import net.runelite.api.mixins.Copy;
|
||||||
|
import net.runelite.api.mixins.Replace;
|
||||||
import net.runelite.api.widgets.Widget;
|
import net.runelite.api.widgets.Widget;
|
||||||
import static net.runelite.api.widgets.WidgetInfo.TO_CHILD;
|
import static net.runelite.api.widgets.WidgetInfo.TO_CHILD;
|
||||||
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
|
import static net.runelite.api.widgets.WidgetInfo.TO_GROUP;
|
||||||
@@ -44,8 +46,11 @@ import net.runelite.api.mixins.Inject;
|
|||||||
import net.runelite.api.mixins.Mixin;
|
import net.runelite.api.mixins.Mixin;
|
||||||
import net.runelite.api.mixins.Shadow;
|
import net.runelite.api.mixins.Shadow;
|
||||||
import net.runelite.rs.api.RSClient;
|
import net.runelite.rs.api.RSClient;
|
||||||
|
import net.runelite.rs.api.RSModel;
|
||||||
import net.runelite.rs.api.RSNode;
|
import net.runelite.rs.api.RSNode;
|
||||||
import net.runelite.rs.api.RSNodeHashTable;
|
import net.runelite.rs.api.RSNodeHashTable;
|
||||||
|
import net.runelite.rs.api.RSPlayerAppearance;
|
||||||
|
import net.runelite.rs.api.RSSequenceDefinition;
|
||||||
import net.runelite.rs.api.RSWidget;
|
import net.runelite.rs.api.RSWidget;
|
||||||
|
|
||||||
@Mixin(RSWidget.class)
|
@Mixin(RSWidget.class)
|
||||||
@@ -581,4 +586,17 @@ public abstract class RSWidgetMixin implements RSWidget
|
|||||||
Arrays.fill(getChildren(), null);
|
Arrays.fill(getChildren(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Copy("getModel")
|
||||||
|
public abstract RSModel rs$getModel(RSSequenceDefinition sequence, int frame, boolean alternate, RSPlayerAppearance playerComposition);
|
||||||
|
|
||||||
|
@Replace("getModel")
|
||||||
|
public RSModel rl$getModel(RSSequenceDefinition sequence, int frame, boolean alternate, RSPlayerAppearance playerComposition)
|
||||||
|
{
|
||||||
|
if (frame != -1 && client.isInterpolateWidgetAnimations())
|
||||||
|
{
|
||||||
|
frame = frame | getModelFrameCycle() << 16 | Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
return rs$getModel(sequence, frame, alternate, playerComposition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,7 @@ public interface RSSequenceDefinition
|
|||||||
|
|
||||||
@Import("frameLengths")
|
@Import("frameLengths")
|
||||||
int[] getFrameLenths();
|
int[] getFrameLenths();
|
||||||
|
|
||||||
|
@Import("chatFrameIds")
|
||||||
|
int[] getChatFrameIds();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,4 +475,10 @@ public interface RSWidget extends Widget
|
|||||||
@Import("noScrollThrough")
|
@Import("noScrollThrough")
|
||||||
@Override
|
@Override
|
||||||
void setNoScrollThrough(boolean noScrollThrough);
|
void setNoScrollThrough(boolean noScrollThrough);
|
||||||
|
|
||||||
|
@Import("modelFrame")
|
||||||
|
int getModelFrame();
|
||||||
|
|
||||||
|
@Import("modelFrameCycle")
|
||||||
|
int getModelFrameCycle();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -424,11 +424,11 @@ public class NPCDefinition extends DualNode {
|
|||||||
|
|
||||||
Model var10;
|
Model var10;
|
||||||
if (var1 != null && var3 != null) {
|
if (var1 != null && var3 != null) {
|
||||||
var10 = var1.animateSequence2(var5, var2, var3, var4);
|
var10 = var1.applyTransformations(var5, var2, var3, var4);
|
||||||
} else if (var1 != null) {
|
} else if (var1 != null) {
|
||||||
var10 = var1.animateSequence(var5, var2);
|
var10 = var1.transformActorModel(var5, var2);
|
||||||
} else if (var3 != null) {
|
} else if (var3 != null) {
|
||||||
var10 = var3.animateSequence(var5, var4);
|
var10 = var3.transformActorModel(var5, var4);
|
||||||
} else {
|
} else {
|
||||||
var10 = var5.toSharedSequenceModel(true);
|
var10 = var5.toSharedSequenceModel(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -662,7 +662,7 @@ public class ObjectDefinition extends DualNode {
|
|||||||
return var11;
|
return var11;
|
||||||
} else {
|
} else {
|
||||||
if (var7 != null) {
|
if (var7 != null) {
|
||||||
var11 = var7.animateObject(var11, var8, var2);
|
var11 = var7.transformObjectModel(var11, var8, var2);
|
||||||
} else {
|
} else {
|
||||||
var11 = var11.toSharedSequenceModel(true);
|
var11 = var11.toSharedSequenceModel(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,11 +321,11 @@ public class PlayerAppearance {
|
|||||||
} else {
|
} else {
|
||||||
Model var16;
|
Model var16;
|
||||||
if (var1 != null && var3 != null) {
|
if (var1 != null && var3 != null) {
|
||||||
var16 = var1.animateSequence2(var15, var2, var3, var4);
|
var16 = var1.applyTransformations(var15, var2, var3, var4);
|
||||||
} else if (var1 != null) {
|
} else if (var1 != null) {
|
||||||
var16 = var1.animateSequence(var15, var2);
|
var16 = var1.transformActorModel(var15, var2);
|
||||||
} else {
|
} else {
|
||||||
var16 = var3.animateSequence(var15, var4);
|
var16 = var3.transformActorModel(var15, var4);
|
||||||
}
|
}
|
||||||
|
|
||||||
return var16;
|
return var16;
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ public class SequenceDefinition extends DualNode {
|
|||||||
@Export("frameIds")
|
@Export("frameIds")
|
||||||
public int[] frameIds;
|
public int[] frameIds;
|
||||||
@ObfuscatedName("g")
|
@ObfuscatedName("g")
|
||||||
@Export("frameIds2")
|
@Export("chatFrameIds")
|
||||||
int[] frameIds2;
|
int[] chatFrameIds;
|
||||||
@ObfuscatedName("l")
|
@ObfuscatedName("l")
|
||||||
@Export("frameLengths")
|
@Export("frameLengths")
|
||||||
public int[] frameLengths;
|
public int[] frameLengths;
|
||||||
@@ -179,14 +179,14 @@ public class SequenceDefinition extends DualNode {
|
|||||||
this.field783 = var1.readUnsignedByte();
|
this.field783 = var1.readUnsignedByte();
|
||||||
} else if (var2 == 12) {
|
} else if (var2 == 12) {
|
||||||
var4 = var1.readUnsignedByte();
|
var4 = var1.readUnsignedByte();
|
||||||
this.frameIds2 = new int[var4];
|
this.chatFrameIds = new int[var4];
|
||||||
|
|
||||||
for (var5 = 0; var5 < var4; ++var5) {
|
for (var5 = 0; var5 < var4; ++var5) {
|
||||||
this.frameIds2[var5] = var1.readUnsignedShort();
|
this.chatFrameIds[var5] = var1.readUnsignedShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var5 = 0; var5 < var4; ++var5) {
|
for (var5 = 0; var5 < var4; ++var5) {
|
||||||
var3 = this.frameIds2;
|
var3 = this.chatFrameIds;
|
||||||
var3[var5] += var1.readUnsignedShort() << 16;
|
var3[var5] += var1.readUnsignedShort() << 16;
|
||||||
}
|
}
|
||||||
} else if (var2 == 13) {
|
} else if (var2 == 13) {
|
||||||
@@ -230,8 +230,8 @@ public class SequenceDefinition extends DualNode {
|
|||||||
signature = "(Ldu;II)Ldu;",
|
signature = "(Ldu;II)Ldu;",
|
||||||
garbageValue = "128527714"
|
garbageValue = "128527714"
|
||||||
)
|
)
|
||||||
@Export("animateSequence")
|
@Export("transformActorModel")
|
||||||
public Model animateSequence(Model model, int frame) {
|
public Model transformActorModel(Model model, int frame) {
|
||||||
frame = this.frameIds[frame];
|
frame = this.frameIds[frame];
|
||||||
Frames var3 = ItemContainer.getFrames(frame >> 16);
|
Frames var3 = ItemContainer.getFrames(frame >> 16);
|
||||||
frame &= 65535;
|
frame &= 65535;
|
||||||
@@ -249,8 +249,8 @@ public class SequenceDefinition extends DualNode {
|
|||||||
signature = "(Ldu;IIB)Ldu;",
|
signature = "(Ldu;IIB)Ldu;",
|
||||||
garbageValue = "-65"
|
garbageValue = "-65"
|
||||||
)
|
)
|
||||||
@Export("animateObject")
|
@Export("transformObjectModel")
|
||||||
Model animateObject(Model model, int frame, int orientation) {
|
Model transformObjectModel(Model model, int frame, int orientation) {
|
||||||
frame = this.frameIds[frame];
|
frame = this.frameIds[frame];
|
||||||
Frames var4 = ItemContainer.getFrames(frame >> 16);
|
Frames var4 = ItemContainer.getFrames(frame >> 16);
|
||||||
frame &= 65535;
|
frame &= 65535;
|
||||||
@@ -285,8 +285,8 @@ public class SequenceDefinition extends DualNode {
|
|||||||
signature = "(Ldu;II)Ldu;",
|
signature = "(Ldu;II)Ldu;",
|
||||||
garbageValue = "-1692496767"
|
garbageValue = "-1692496767"
|
||||||
)
|
)
|
||||||
@Export("animateSpotAnimation")
|
@Export("transformSpotAnimationModel")
|
||||||
Model animateSpotAnimation(Model model, int frame) {
|
Model transformSpotAnimationModel(Model model, int frame) {
|
||||||
frame = this.frameIds[frame];
|
frame = this.frameIds[frame];
|
||||||
Frames var3 = ItemContainer.getFrames(frame >> 16);
|
Frames var3 = ItemContainer.getFrames(frame >> 16);
|
||||||
frame &= 65535;
|
frame &= 65535;
|
||||||
@@ -304,13 +304,13 @@ public class SequenceDefinition extends DualNode {
|
|||||||
signature = "(Ldu;ILjh;II)Ldu;",
|
signature = "(Ldu;ILjh;II)Ldu;",
|
||||||
garbageValue = "-386360993"
|
garbageValue = "-386360993"
|
||||||
)
|
)
|
||||||
@Export("animateSequence2")
|
@Export("applyTransformations")
|
||||||
public Model animateSequence2(Model model, int frame, SequenceDefinition sequence, int sequenceFrame) {
|
public Model applyTransformations(Model model, int frame, SequenceDefinition sequence, int sequenceFrame) {
|
||||||
frame = this.frameIds[frame];
|
frame = this.frameIds[frame];
|
||||||
Frames var5 = ItemContainer.getFrames(frame >> 16);
|
Frames var5 = ItemContainer.getFrames(frame >> 16);
|
||||||
frame &= 65535;
|
frame &= 65535;
|
||||||
if (var5 == null) {
|
if (var5 == null) {
|
||||||
return sequence.animateSequence(model, sequenceFrame);
|
return sequence.transformActorModel(model, sequenceFrame);
|
||||||
} else {
|
} else {
|
||||||
sequenceFrame = sequence.frameIds[sequenceFrame];
|
sequenceFrame = sequence.frameIds[sequenceFrame];
|
||||||
Frames var6 = ItemContainer.getFrames(sequenceFrame >> 16);
|
Frames var6 = ItemContainer.getFrames(sequenceFrame >> 16);
|
||||||
@@ -333,8 +333,8 @@ public class SequenceDefinition extends DualNode {
|
|||||||
signature = "(Ldu;II)Ldu;",
|
signature = "(Ldu;II)Ldu;",
|
||||||
garbageValue = "-15433768"
|
garbageValue = "-15433768"
|
||||||
)
|
)
|
||||||
@Export("animateWidget")
|
@Export("transformWidgetModel")
|
||||||
public Model animateWidget(Model model, int frame) {
|
public Model transformWidgetModel(Model model, int frame) {
|
||||||
int var3 = this.frameIds[frame];
|
int var3 = this.frameIds[frame];
|
||||||
Frames var4 = ItemContainer.getFrames(var3 >> 16);
|
Frames var4 = ItemContainer.getFrames(var3 >> 16);
|
||||||
var3 &= 65535;
|
var3 &= 65535;
|
||||||
@@ -343,8 +343,8 @@ public class SequenceDefinition extends DualNode {
|
|||||||
} else {
|
} else {
|
||||||
Frames var5 = null;
|
Frames var5 = null;
|
||||||
int var6 = 0;
|
int var6 = 0;
|
||||||
if (this.frameIds2 != null && frame < this.frameIds2.length) {
|
if (this.chatFrameIds != null && frame < this.chatFrameIds.length) {
|
||||||
var6 = this.frameIds2[frame];
|
var6 = this.chatFrameIds[frame];
|
||||||
var5 = ItemContainer.getFrames(var6 >> 16);
|
var5 = ItemContainer.getFrames(var6 >> 16);
|
||||||
var6 &= 65535;
|
var6 &= 65535;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ public class SpotAnimationDefinition extends DualNode {
|
|||||||
|
|
||||||
Model var5;
|
Model var5;
|
||||||
if (this.sequence != -1 && var1 != -1) {
|
if (this.sequence != -1 && var1 != -1) {
|
||||||
var5 = WorldMapAreaData.getSequenceDefinition(this.sequence).animateSpotAnimation(var2, var1);
|
var5 = WorldMapAreaData.getSequenceDefinition(this.sequence).transformSpotAnimationModel(var2, var1);
|
||||||
} else {
|
} else {
|
||||||
var5 = var2.toSharedSpotAnimationModel(true);
|
var5 = var2.toSharedSpotAnimationModel(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1376,11 +1376,11 @@ public class Widget extends Node {
|
|||||||
garbageValue = "1082545676"
|
garbageValue = "1082545676"
|
||||||
)
|
)
|
||||||
@Export("getModel")
|
@Export("getModel")
|
||||||
public Model getModel(SequenceDefinition sequence, int frame, boolean var3, PlayerAppearance appearance) {
|
public Model getModel(SequenceDefinition sequence, int frame, boolean alternate, PlayerAppearance appearance) {
|
||||||
field957 = false;
|
field957 = false;
|
||||||
int var5;
|
int var5;
|
||||||
int var6;
|
int var6;
|
||||||
if (var3) {
|
if (alternate) {
|
||||||
var5 = this.modelType2;
|
var5 = this.modelType2;
|
||||||
var6 = this.modelId2;
|
var6 = this.modelId2;
|
||||||
} else {
|
} else {
|
||||||
@@ -1445,7 +1445,7 @@ public class Widget extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sequence != null) {
|
if (sequence != null) {
|
||||||
var7 = sequence.animateWidget(var7, frame);
|
var7 = sequence.transformWidgetModel(var7, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return var7;
|
return var7;
|
||||||
|
|||||||
Reference in New Issue
Block a user