@@ -236,6 +236,16 @@ public enum VarPlayer
|
||||
SETTINGS_TRANSPARENT_CHAT_TRADE_REQUEST(3006),
|
||||
SETTINGS_TRANSPARENT_CHAT_CHALLENGE_REQUEST(3007),
|
||||
|
||||
/**
|
||||
* The difference, measured in minutes, between the time home teleport spell was last used and midnight, January 1, 1970 UTC.
|
||||
*/
|
||||
LAST_HOME_TELEPORT(892),
|
||||
|
||||
/**
|
||||
* The difference, measured in minutes, between the time minigame teleport was last used and midnight, January 1, 1970 UTC.
|
||||
*/
|
||||
LAST_MINIGAME_TELEPORT(888),
|
||||
|
||||
;
|
||||
|
||||
private final int id;
|
||||
|
||||
@@ -30,5 +30,6 @@ import lombok.Value;
|
||||
@Value
|
||||
public class PartyChanged
|
||||
{
|
||||
private final String passphrase;
|
||||
private final UUID partyId;
|
||||
}
|
||||
|
||||
@@ -94,8 +94,8 @@ public enum FishingSpot
|
||||
SACRED_EEL("Sacred eel", ItemID.SACRED_EEL,
|
||||
FISHING_SPOT_6488
|
||||
),
|
||||
CAVE_EEL("Cave eel", ItemID.RAW_CAVE_EEL,
|
||||
FISHING_SPOT_1497, FISHING_SPOT_1498, FISHING_SPOT_1499
|
||||
CAVE_EEL("Frog spawn, Cave eel", ItemID.RAW_CAVE_EEL,
|
||||
FISHING_SPOT_1497, FISHING_SPOT_1498, FISHING_SPOT_1499, FISHING_SPOT_1500
|
||||
),
|
||||
SLIMY_EEL("Slimy eel", ItemID.RAW_SLIMY_EEL,
|
||||
FISHING_SPOT_2653, FISHING_SPOT_2654, FISHING_SPOT_2655
|
||||
|
||||
@@ -37,7 +37,6 @@ import java.time.temporal.ChronoUnit;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.inject.Named;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -50,11 +49,8 @@ import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.StatChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.discord.DiscordService;
|
||||
import net.runelite.client.discord.events.DiscordJoinGame;
|
||||
import net.runelite.client.discord.events.DiscordReady;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.events.PartyChanged;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.task.Schedule;
|
||||
@@ -65,8 +61,7 @@ import net.runelite.client.util.LinkBrowser;
|
||||
import net.runelite.client.ws.PartyMember;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import net.runelite.client.ws.WSClient;
|
||||
import net.runelite.http.api.ws.messages.party.UserJoin;
|
||||
import net.runelite.http.api.ws.messages.party.UserPart;
|
||||
import net.runelite.discord.DiscordUser;
|
||||
import net.runelite.http.api.ws.messages.party.UserSync;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
@@ -137,11 +132,6 @@ public class DiscordPlugin extends Plugin
|
||||
checkForGameStateUpdate();
|
||||
checkForAreaUpdate();
|
||||
|
||||
if (discordService.getCurrentUser() != null)
|
||||
{
|
||||
partyService.setUsername(discordService.getCurrentUser().username + "#" + discordService.getCurrentUser().discriminator);
|
||||
}
|
||||
|
||||
wsClient.registerMessage(DiscordUserInfo.class);
|
||||
}
|
||||
|
||||
@@ -150,7 +140,6 @@ public class DiscordPlugin extends Plugin
|
||||
{
|
||||
clientToolbar.removeNavigation(discordButton);
|
||||
resetState();
|
||||
partyService.changeParty(null);
|
||||
wsClient.unregisterMessage(DiscordUserInfo.class);
|
||||
}
|
||||
|
||||
@@ -209,30 +198,9 @@ public class DiscordPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDiscordReady(DiscordReady event)
|
||||
{
|
||||
partyService.setUsername(event.getUsername() + "#" + event.getDiscriminator());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDiscordJoinGame(DiscordJoinGame joinGame)
|
||||
{
|
||||
UUID partyId = UUID.fromString(joinGame.getJoinSecret());
|
||||
partyService.changeParty(partyId);
|
||||
updatePresence();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDiscordUserInfo(final DiscordUserInfo event)
|
||||
{
|
||||
final PartyMember memberById = partyService.getMemberById(event.getMemberId());
|
||||
|
||||
if (memberById == null || memberById.getAvatar() != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final CharMatcher matcher = CharMatcher.anyOf("abcdef0123456789");
|
||||
|
||||
// animated avatars contain a_ as prefix so we need to get rid of that first to check against matcher
|
||||
@@ -246,13 +214,7 @@ public class DiscordPlugin extends Plugin
|
||||
|
||||
if (Strings.isNullOrEmpty(event.getAvatarId()))
|
||||
{
|
||||
final String[] split = memberById.getName().split("#", 2);
|
||||
if (split.length != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int disc = Integer.parseInt(split[1]);
|
||||
int disc = Integer.parseInt(event.getDiscriminator());
|
||||
int avatarId = disc % 5;
|
||||
url = "https://cdn.discordapp.com/embed/avatars/" + avatarId + ".png";
|
||||
}
|
||||
@@ -292,7 +254,7 @@ public class DiscordPlugin extends Plugin
|
||||
image = ImageIO.read(inputStream);
|
||||
}
|
||||
|
||||
partyService.setPartyMemberAvatar(memberById.getMemberId(), image);
|
||||
partyService.setPartyMemberAvatar(event.getMemberId(), image);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -302,12 +264,6 @@ public class DiscordPlugin extends Plugin
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onUserJoin(final UserJoin event)
|
||||
{
|
||||
updatePresence();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onUserSync(final UserSync event)
|
||||
{
|
||||
@@ -315,30 +271,21 @@ public class DiscordPlugin extends Plugin
|
||||
|
||||
if (localMember != null)
|
||||
{
|
||||
if (discordService.getCurrentUser() != null)
|
||||
final DiscordUser discordUser = discordService.getCurrentUser();
|
||||
if (discordUser != null)
|
||||
{
|
||||
final DiscordUserInfo userInfo = new DiscordUserInfo(
|
||||
discordService.getCurrentUser().userId,
|
||||
discordService.getCurrentUser().avatar);
|
||||
|
||||
discordUser.userId,
|
||||
discordUser.username,
|
||||
discordUser.discriminator,
|
||||
discordUser.avatar
|
||||
);
|
||||
userInfo.setMemberId(localMember.getMemberId());
|
||||
wsClient.send(userInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onUserPart(final UserPart event)
|
||||
{
|
||||
updatePresence();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPartyChanged(final PartyChanged event)
|
||||
{
|
||||
updatePresence();
|
||||
}
|
||||
|
||||
@Schedule(
|
||||
period = 1,
|
||||
unit = ChronoUnit.MINUTES
|
||||
@@ -348,11 +295,6 @@ public class DiscordPlugin extends Plugin
|
||||
discordState.checkForTimeout();
|
||||
}
|
||||
|
||||
private void updatePresence()
|
||||
{
|
||||
discordState.refresh();
|
||||
}
|
||||
|
||||
private void resetState()
|
||||
{
|
||||
discordState.reset();
|
||||
|
||||
@@ -38,8 +38,6 @@ import javax.inject.Named;
|
||||
import lombok.Data;
|
||||
import net.runelite.client.discord.DiscordPresence;
|
||||
import net.runelite.client.discord.DiscordService;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import static net.runelite.client.ws.PartyService.PARTY_MAX;
|
||||
|
||||
/**
|
||||
* This class contains data about currently active discord state.
|
||||
@@ -57,7 +55,6 @@ class DiscordState
|
||||
private final List<EventWithTime> events = new ArrayList<>();
|
||||
private final DiscordService discordService;
|
||||
private final DiscordConfig config;
|
||||
private final PartyService party;
|
||||
private final String runeliteTitle;
|
||||
private final String runeliteVersion;
|
||||
private DiscordPresence lastPresence;
|
||||
@@ -66,14 +63,12 @@ class DiscordState
|
||||
private DiscordState(
|
||||
final DiscordService discordService,
|
||||
final DiscordConfig config,
|
||||
final PartyService party,
|
||||
@Named("runelite.title") final String runeliteTitle,
|
||||
@Named("runelite.version") final String runeliteVersion
|
||||
)
|
||||
{
|
||||
this.discordService = discordService;
|
||||
this.config = config;
|
||||
this.party = party;
|
||||
this.runeliteTitle = runeliteTitle;
|
||||
this.runeliteVersion = runeliteVersion;
|
||||
}
|
||||
@@ -88,30 +83,6 @@ class DiscordState
|
||||
lastPresence = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force refresh discord presence
|
||||
*/
|
||||
void refresh()
|
||||
{
|
||||
if (lastPresence == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final DiscordPresence.DiscordPresenceBuilder presenceBuilder = DiscordPresence.builder()
|
||||
.state(lastPresence.getState())
|
||||
.details(lastPresence.getDetails())
|
||||
.largeImageText(lastPresence.getLargeImageText())
|
||||
.startTimestamp(lastPresence.getStartTimestamp())
|
||||
.smallImageKey(lastPresence.getSmallImageKey())
|
||||
.partyMax(lastPresence.getPartyMax());
|
||||
|
||||
|
||||
setPresencePartyInfo(presenceBuilder);
|
||||
|
||||
discordService.updatePresence(presenceBuilder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger new discord state update.
|
||||
*
|
||||
@@ -197,8 +168,7 @@ class DiscordState
|
||||
.state(MoreObjects.firstNonNull(state, ""))
|
||||
.details(MoreObjects.firstNonNull(details, ""))
|
||||
.largeImageText(runeliteTitle + " v" + versionShortHand)
|
||||
.smallImageKey(imageKey)
|
||||
.partyMax(PARTY_MAX);
|
||||
.smallImageKey(imageKey);
|
||||
|
||||
final Instant startTime;
|
||||
switch (config.elapsedTimeType())
|
||||
@@ -225,8 +195,6 @@ class DiscordState
|
||||
|
||||
presenceBuilder.startTimestamp(startTime);
|
||||
|
||||
setPresencePartyInfo(presenceBuilder);
|
||||
|
||||
final DiscordPresence presence = presenceBuilder.build();
|
||||
|
||||
// This is to reduce amount of RPC calls
|
||||
@@ -263,16 +231,4 @@ class DiscordState
|
||||
updatePresenceWithLatestEvent();
|
||||
}
|
||||
}
|
||||
|
||||
private void setPresencePartyInfo(DiscordPresence.DiscordPresenceBuilder presenceBuilder)
|
||||
{
|
||||
if (party.isInParty())
|
||||
{
|
||||
presenceBuilder.partySize(party.getMembers().size());
|
||||
|
||||
// Set public party id and secret
|
||||
presenceBuilder.partyId(party.getPublicPartyId().toString());
|
||||
presenceBuilder.joinSecret(party.getPartyId().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,5 +33,7 @@ import net.runelite.http.api.ws.messages.party.PartyMemberMessage;
|
||||
class DiscordUserInfo extends PartyMemberMessage
|
||||
{
|
||||
private final String userId;
|
||||
private final String username;
|
||||
private final String discriminator;
|
||||
private final String avatarId;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ public class DpsCounterPlugin extends Plugin
|
||||
}
|
||||
|
||||
// If not in a party, user local player name
|
||||
final String name = localMember == null ? player.getName() : localMember.getName();
|
||||
final String name = localMember == null ? player.getName() : localMember.getDisplayName();
|
||||
DpsMember dpsMember = members.computeIfAbsent(name, DpsMember::new);
|
||||
dpsMember.addDamage(hit);
|
||||
|
||||
@@ -240,7 +240,7 @@ public class DpsCounterPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
String name = partyService.getMemberById(dpsUpdate.getMemberId()).getName();
|
||||
String name = partyService.getMemberById(dpsUpdate.getMemberId()).getDisplayName();
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -76,9 +76,6 @@ public class HunterPlugin extends Plugin
|
||||
@Getter
|
||||
private final Map<WorldPoint, HunterTrap> traps = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
private Instant lastActionTime = Instant.ofEpochMilli(0);
|
||||
|
||||
private WorldPoint lastTickLocalPlayerLocation;
|
||||
|
||||
@Provides
|
||||
@@ -98,7 +95,6 @@ public class HunterPlugin extends Plugin
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
lastActionTime = Instant.ofEpochMilli(0);
|
||||
traps.clear();
|
||||
}
|
||||
|
||||
@@ -124,7 +120,6 @@ public class HunterPlugin extends Plugin
|
||||
{
|
||||
log.debug("Trap placed by \"{}\" on {}", localPlayer.getName(), trapLocation);
|
||||
traps.put(trapLocation, new HunterTrap(gameObject));
|
||||
lastActionTime = Instant.now();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -140,7 +135,6 @@ public class HunterPlugin extends Plugin
|
||||
{
|
||||
log.debug("Trap placed by \"{}\" on {}", localPlayer.getName(), localPlayer.getWorldLocation());
|
||||
traps.put(trapLocation, new HunterTrap(gameObject));
|
||||
lastActionTime = Instant.now();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -168,7 +162,6 @@ public class HunterPlugin extends Plugin
|
||||
|
||||
log.debug("Trap placed by \"{}\" on {} facing {}", localPlayer.getName(), translatedTrapLocation, trapOrientation);
|
||||
traps.put(translatedTrapLocation, new HunterTrap(gameObject));
|
||||
lastActionTime = Instant.now();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -201,7 +194,6 @@ public class HunterPlugin extends Plugin
|
||||
{
|
||||
myTrap.setState(HunterTrap.State.FULL);
|
||||
myTrap.resetTimer();
|
||||
lastActionTime = Instant.now();
|
||||
|
||||
if (config.maniacalMonkeyNotify() && myTrap.getObjectId() == ObjectID.MONKEY_TRAP)
|
||||
{
|
||||
@@ -222,7 +214,6 @@ public class HunterPlugin extends Plugin
|
||||
{
|
||||
myTrap.setState(HunterTrap.State.EMPTY);
|
||||
myTrap.resetTimer();
|
||||
lastActionTime = Instant.now();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -40,11 +40,6 @@ public class Builders
|
||||
return new Food(p);
|
||||
}
|
||||
|
||||
public static Effect combo(int primaries, SingleEffect... effect)
|
||||
{
|
||||
return new Combo(primaries, effect);
|
||||
}
|
||||
|
||||
public static Effect combo(SingleEffect... effect)
|
||||
{
|
||||
return new Combo(effect);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* Copyright (c) 2022 Hydrox6 <ikada@protonmail.ch>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,47 +22,41 @@
|
||||
* (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.timers;
|
||||
package net.runelite.client.plugins.itemstats;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.Collection;
|
||||
import javax.annotation.Nullable;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.plugins.itemstats.delta.DeltaCalculator;
|
||||
import net.runelite.client.plugins.itemstats.stats.Stat;
|
||||
|
||||
enum TeleportWidget
|
||||
/**
|
||||
* A stat boost using the real stat level, that can only boost a certain amount above the stat level.
|
||||
*/
|
||||
public class CappedStatBoost extends StatBoost
|
||||
{
|
||||
HOME_TELEPORT,
|
||||
MINIGAME_TELEPORT,
|
||||
TRAILBLAZER_AREA_TELEPORT,
|
||||
;
|
||||
private final DeltaCalculator deltaCalculator;
|
||||
private final DeltaCalculator capCalculator;
|
||||
|
||||
private static final Collection HOME_TELEPORT_IDS = ImmutableList.of(
|
||||
WidgetInfo.SPELL_LUMBRIDGE_HOME_TELEPORT.getId(),
|
||||
WidgetInfo.SPELL_EDGEVILLE_HOME_TELEPORT.getId(),
|
||||
WidgetInfo.SPELL_LUNAR_HOME_TELEPORT.getId(),
|
||||
WidgetInfo.SPELL_ARCEUUS_HOME_TELEPORT.getId(),
|
||||
WidgetInfo.SPELL_KOUREND_HOME_TELEPORT.getId(),
|
||||
WidgetInfo.SPELL_CATHERBY_HOME_TELEPORT.getId()
|
||||
);
|
||||
private static final Collection MINIGAME_TELEPORT_IDS = ImmutableList.of(
|
||||
WidgetInfo.MINIGAME_TELEPORT_BUTTON.getId()
|
||||
);
|
||||
|
||||
@Nullable
|
||||
static TeleportWidget of(int widgetId)
|
||||
public CappedStatBoost(Stat stat, DeltaCalculator deltaCalculator, DeltaCalculator capCalculator)
|
||||
{
|
||||
if (HOME_TELEPORT_IDS.contains(widgetId))
|
||||
{
|
||||
return HOME_TELEPORT;
|
||||
}
|
||||
else if (MINIGAME_TELEPORT_IDS.contains(widgetId))
|
||||
{
|
||||
return MINIGAME_TELEPORT;
|
||||
}
|
||||
else if (widgetId == WidgetInfo.TRAILBLAZER_AREA_TELEPORT.getId())
|
||||
{
|
||||
return TRAILBLAZER_AREA_TELEPORT;
|
||||
}
|
||||
return null;
|
||||
super(stat, true);
|
||||
this.deltaCalculator = deltaCalculator;
|
||||
this.capCalculator = capCalculator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int heals(Client client)
|
||||
{
|
||||
final int current = getStat().getValue(client);
|
||||
final int max = getStat().getMaximum(client);
|
||||
final int delta = deltaCalculator.calculateDelta(max);
|
||||
final int cap = capCalculator.calculateDelta(max);
|
||||
|
||||
if (delta + current <= max + cap)
|
||||
{
|
||||
return delta;
|
||||
}
|
||||
|
||||
return max + cap - current;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,36 +24,23 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.itemstats;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.runelite.api.Client;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Combo implements Effect
|
||||
{
|
||||
private final SingleEffect[] calcs;
|
||||
private final int numPrimaries;
|
||||
|
||||
public Combo(SingleEffect[] calcs)
|
||||
{
|
||||
this(1, calcs);
|
||||
}
|
||||
|
||||
public Combo(int numPrimaries, SingleEffect[] calcs)
|
||||
{
|
||||
this.numPrimaries = numPrimaries;
|
||||
this.calcs = calcs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsChanges calculate(Client client)
|
||||
{
|
||||
StatsChanges out = new StatsChanges(calcs.length);
|
||||
StatChange[] statChanges = out.getStatChanges();
|
||||
Positivity positivity = Positivity.NO_CHANGE;
|
||||
for (int i = 0; i < calcs.length; i++)
|
||||
{
|
||||
statChanges[i] = calcs[i].effect(client);
|
||||
}
|
||||
Positivity positivity = Positivity.NO_CHANGE;
|
||||
for (int i = 0; i < numPrimaries; i++)
|
||||
{
|
||||
if (positivity.ordinal() < statChanges[i].getPositivity().ordinal())
|
||||
{
|
||||
positivity = statChanges[i].getPositivity();
|
||||
|
||||
@@ -32,8 +32,11 @@ import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import static net.runelite.api.ItemID.*;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.*;
|
||||
import net.runelite.client.plugins.itemstats.delta.DeltaPercentage;
|
||||
import net.runelite.client.plugins.itemstats.food.Anglerfish;
|
||||
import net.runelite.client.plugins.itemstats.potions.AncientBrew;
|
||||
import net.runelite.client.plugins.itemstats.potions.GauntletPotion;
|
||||
import net.runelite.client.plugins.itemstats.potions.MixedPotion;
|
||||
import net.runelite.client.plugins.itemstats.potions.PrayerPotion;
|
||||
import net.runelite.client.plugins.itemstats.potions.SaradominBrew;
|
||||
import net.runelite.client.plugins.itemstats.potions.StaminaPotion;
|
||||
@@ -62,7 +65,8 @@ public class ItemStatChanges
|
||||
PINEAPPLE_RING, PINEAPPLE_CHUNKS, SPICY_SAUCE, CHEESE, SPINACH_ROLL, LEMON, LEMON_CHUNKS, LEMON_SLICES,
|
||||
LIME, LIME_CHUNKS, LIME_SLICES, DWELLBERRIES, KING_WORM, MINCED_MEAT, SPICY_TOMATO, WHITE_PEARL);
|
||||
add(food(3), SHRIMPS, COOKED_MEAT, COOKED_CHICKEN, ROE, CHOCOLATE_BAR, UGTHANKI_MEAT, TOADS_LEGS, ONION__TOMATO,
|
||||
SPICY_MINCED_MEAT, SLICE_OF_BIRTHDAY_CAKE, LOCUST_MEAT);
|
||||
SPICY_MINCED_MEAT, SLICE_OF_BIRTHDAY_CAKE, LOCUST_MEAT, RELICYMS_MIX1, RELICYMS_MIX2, ANTIPOISON_MIX1,
|
||||
ANTIPOISON_MIX2);
|
||||
add(food(4), SARDINE, CAKE, _23_CAKE, SLICE_OF_CAKE, CHOCOLATEY_MILK, BAKED_POTATO, EDIBLE_SEAWEED, MOONLIGHT_MEAD,
|
||||
MOONLIGHT_MEAD4, MOONLIGHT_MEAD3, MOONLIGHT_MEAD2, MOONLIGHT_MEAD1, MONKEY_NUTS);
|
||||
add(food(5), BREAD, HERRING, CHOCOLATE_CAKE, _23_CHOCOLATE_CAKE, CHOCOLATE_SLICE, COOKED_RABBIT, CHILLI_CON_CARNE,
|
||||
@@ -70,7 +74,9 @@ public class ItemStatChanges
|
||||
SCRAMBLED_EGG, MONKEY_BAR, TCHIKI_MONKEY_NUTS, TCHIKI_NUT_PASTE, RED_BANANA, SLICED_RED_BANANA);
|
||||
add(food(6), CHOCICE, MACKEREL, MEAT_PIE, HALF_A_MEAT_PIE, GUANIC_BAT_0, ROAST_BIRD_MEAT, SQUARE_SANDWICH,
|
||||
ROLL, BAGUETTE, TRIANGLE_SANDWICH, GIANT_CARP, MOONLIGHT_MEADM, MOONLIGHT_MEADM4, MOONLIGHT_MEADM3, MOONLIGHT_MEADM2,
|
||||
MOONLIGHT_MEADM1, STEAK_SANDWICH, GIANT_FROG_LEGS);
|
||||
MOONLIGHT_MEADM1, STEAK_SANDWICH, GIANT_FROG_LEGS, ANTIFIRE_MIX1, ANTIFIRE_MIX2, EXTENDED_ANTIFIRE_MIX1,
|
||||
EXTENDED_ANTIFIRE_MIX2, SUPER_ANTIFIRE_MIX1, SUPER_ANTIFIRE_MIX2, EXTENDED_SUPER_ANTIFIRE_MIX1,
|
||||
EXTENDED_SUPER_ANTIFIRE_MIX2, ANTIPOISON_SUPERMIX1, ANTIPOISON_SUPERMIX2, ANTIDOTE_MIX1, ANTIDOTE_MIX2);
|
||||
add(food(7), TROUT, COD, PLAIN_PIZZA, _12_PLAIN_PIZZA, APPLE_PIE, HALF_AN_APPLE_PIE, ROAST_RABBIT,
|
||||
PREMADE_CH_CRUNCH, CHOCCHIP_CRUNCHIES, PREMADE_SY_CRUNCH, SPICY_CRUNCHIES);
|
||||
add(food(8), PIKE, ROAST_BEAST_MEAT, MEAT_PIZZA, _12_MEAT_PIZZA, PREMADE_WM_CRUN, WORM_CRUNCHIES, PREMADE_TD_CRUNCH,
|
||||
@@ -100,9 +106,9 @@ public class ItemStatChanges
|
||||
add(food(maxHP -> (int) Math.ceil(maxHP * .05)), WATERMELON_SLICE);
|
||||
add(food(perc(.1, 1)), COOKED_SWEETCORN, SWEETCORN_7088 /* Bowl of cooked sweetcorn */);
|
||||
add(combo(food(1), boost(DEFENCE, perc(.02, 1))), CABBAGE_1967 /* Draynor Manor */);
|
||||
add(combo(2, food(8), heal(RUN_ENERGY, 5)), PAPAYA_FRUIT);
|
||||
add(combo(2, food(3), boost(ATTACK, perc(.02, 2))), CUP_OF_TEA_1978 /* Standard tea */);
|
||||
add(combo(2, food(3), new NettleTeaRunEnergy()), NETTLE_TEA, NETTLE_TEA_4240 /* Milky */, CUP_OF_TEA_4242 /* Nettle */, CUP_OF_TEA_4243 /* Milky nettle */);
|
||||
add(combo(food(8), heal(RUN_ENERGY, 5)), PAPAYA_FRUIT);
|
||||
add(combo(food(3), boost(ATTACK, perc(.02, 2))), CUP_OF_TEA_1978 /* Standard tea */);
|
||||
add(combo(food(3), new NettleTeaRunEnergy()), NETTLE_TEA, NETTLE_TEA_4240 /* Milky */, CUP_OF_TEA_4242 /* Nettle */, CUP_OF_TEA_4243 /* Milky nettle */);
|
||||
add(range(food(5), food(7)), THIN_SNAIL_MEAT);
|
||||
add(range(food(5), food(8)), LEAN_SNAIL_MEAT);
|
||||
add(range(food(7), food(9)), FAT_SNAIL_MEAT);
|
||||
@@ -122,39 +128,39 @@ public class ItemStatChanges
|
||||
add(combo(food(11), dec(ATTACK, 2)), JUG_OF_WINE);
|
||||
add(combo(food(14), dec(ATTACK, 3)), BOTTLE_OF_WINE);
|
||||
add(combo(food(7), dec(ATTACK, 2)), HALF_FULL_WINE_JUG);
|
||||
add(combo(dec(ATTACK, 3)), JUG_OF_BAD_WINE);
|
||||
add(combo(3, food(5), new SimpleStatBoost(STRENGTH, true, perc(.05, 1)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_SGG, SHORT_GREEN_GUY, BRANDY, GIN, VODKA, WHISKY);
|
||||
add(combo(3, food(7), new SimpleStatBoost(STRENGTH, true, perc(.05, 2)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_BLURB_SP, BLURBERRY_SPECIAL);
|
||||
add(combo(3, food(5), new SimpleStatBoost(STRENGTH, true, perc(.05, 2)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_DR_DRAGON, DRUNK_DRAGON, PREMADE_CHOC_SDY, CHOC_SATURDAY);
|
||||
add(combo(3, food(5), new SimpleStatBoost(STRENGTH, true, perc(.06, 1)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_WIZ_BLZD, WIZARD_BLIZZARD);
|
||||
add(combo(3, food(3), new SimpleStatBoost(STRENGTH, true, perc(.04, 1)), new BoostedStatBoost(ATTACK, false, perc(.05, -3))), GROG);
|
||||
add(combo(3, food(1), boost(STRENGTH, perc(.02, 1)), new BoostedStatBoost(ATTACK, false, perc(.06, -1))), BEER, BEER_7740);
|
||||
add(combo(3, food(4), boost(STRENGTH, perc(.04, 2)), new BoostedStatBoost(ATTACK, false, perc(.1, -2))), BEER_TANKARD);
|
||||
add(combo(3, food(15), boost(STRENGTH, perc(.1, 2)), new BoostedStatBoost(ATTACK, false, perc(.5, -4))), KEG_OF_BEER_3801 /* Non-quest version */);
|
||||
add(combo(4, boost(ATTACK, 5), boost(STRENGTH, 5), heal(MAGIC, -5), heal(PRAYER, -5)), BLOOD_PINT);
|
||||
add(combo(3, food(1), boost(STRENGTH, 2), new BoostedStatBoost(ATTACK, false, perc(.05, -2))), ASGARNIAN_ALE, ASGARNIAN_ALE1, ASGARNIAN_ALE2, ASGARNIAN_ALE3, ASGARNIAN_ALE4, ASGARNIAN_ALE_7744);
|
||||
add(combo(3, food(1), boost(STRENGTH, 3), new BoostedStatBoost(ATTACK, false, perc(.05, -3))), ASGARNIAN_ALEM, ASGARNIAN_ALEM1, ASGARNIAN_ALEM2, ASGARNIAN_ALEM3, ASGARNIAN_ALEM4);
|
||||
add(combo(4, food(1), boost(WOODCUTTING, 1), new BoostedStatBoost(ATTACK, false, perc(.02, -2)), new BoostedStatBoost(STRENGTH, false, perc(.02, -2))), AXEMANS_FOLLY, AXEMANS_FOLLY1, AXEMANS_FOLLY2, AXEMANS_FOLLY3, AXEMANS_FOLLY4);
|
||||
add(combo(4, food(2), boost(WOODCUTTING, 2), new BoostedStatBoost(ATTACK, false, perc(.02, -3)), new BoostedStatBoost(STRENGTH, false, perc(.02, -3))), AXEMANS_FOLLYM, AXEMANS_FOLLYM1, AXEMANS_FOLLYM2, AXEMANS_FOLLYM3, AXEMANS_FOLLYM4);
|
||||
add(combo(5, food(1), boost(THIEVING, 1), boost(ATTACK, 1), new BoostedStatBoost(DEFENCE, false, perc(.06, -3)), new BoostedStatBoost(STRENGTH, false, perc(.06, -3))), BANDITS_BREW);
|
||||
add(combo(4, food(1), new SimpleStatBoost(COOKING, true, perc(.05, 1)), new BoostedStatBoost(ATTACK, false, perc(.05, -2)), new BoostedStatBoost(STRENGTH, false, perc(.05, -2))), CHEFS_DELIGHT, CHEFS_DELIGHT1, CHEFS_DELIGHT2, CHEFS_DELIGHT3, CHEFS_DELIGHT4, CHEFS_DELIGHT_7754);
|
||||
add(combo(4, food(2), new SimpleStatBoost(COOKING, true, perc(.05, 2)), new BoostedStatBoost(ATTACK, false, perc(.05, -3)), new BoostedStatBoost(STRENGTH, false, perc(.05, -3))), CHEFS_DELIGHTM, CHEFS_DELIGHTM1, CHEFS_DELIGHTM2, CHEFS_DELIGHTM3, CHEFS_DELIGHTM4);
|
||||
add(combo(4, food(1), boost(FARMING, 1), new BoostedStatBoost(ATTACK, false, perc(.02, -2)), new BoostedStatBoost(STRENGTH, false, perc(.02, -2))), CIDER, CIDER1, CIDER2, CIDER3, CIDER4, CIDER_7752);
|
||||
add(combo(4, food(2), boost(FARMING, 2), new BoostedStatBoost(ATTACK, false, perc(.02, -3)), new BoostedStatBoost(STRENGTH, false, perc(.02, -3))), MATURE_CIDER, CIDERM1, CIDERM2, CIDERM3, CIDERM4);
|
||||
add(combo(3, food(1), boost(STRENGTH, 2), new BoostedStatBoost(ATTACK, false, perc(.05, -2))), DRAGON_BITTER, DRAGON_BITTER1, DRAGON_BITTER2, DRAGON_BITTER3, DRAGON_BITTER4, DRAGON_BITTER_7748);
|
||||
add(combo(3, food(2), boost(STRENGTH, 3), new BoostedStatBoost(ATTACK, false, perc(.05, -2))), DRAGON_BITTERM, DRAGON_BITTERM1, DRAGON_BITTERM2, DRAGON_BITTERM3, DRAGON_BITTERM4);
|
||||
add(combo(6, food(1), boost(MINING, 1), boost(SMITHING, 1), new BoostedStatBoost(ATTACK, false, perc(.04, -2)), new BoostedStatBoost(DEFENCE, false, perc(.04, -2)), new BoostedStatBoost(STRENGTH, false, perc(.04, -2))), DWARVEN_STOUT, DWARVEN_STOUT1, DWARVEN_STOUT2, DWARVEN_STOUT3, DWARVEN_STOUT4);
|
||||
add(combo(6, food(2), boost(MINING, 2), boost(SMITHING, 2), new BoostedStatBoost(ATTACK, false, perc(.04, -3)), new BoostedStatBoost(DEFENCE, false, perc(.04, -3)), new BoostedStatBoost(STRENGTH, false, perc(.04, -3))), DWARVEN_STOUTM, DWARVEN_STOUTM1, DWARVEN_STOUTM2, DWARVEN_STOUTM3, DWARVEN_STOUTM4);
|
||||
add(combo(5, food(1), boost(HERBLORE, 1), new BoostedStatBoost(ATTACK, false, perc(.04, -2)), new BoostedStatBoost(DEFENCE, false, perc(.04, -2)), new BoostedStatBoost(STRENGTH, false, perc(.04, -2))), GREENMANS_ALE, GREENMANS_ALE1, GREENMANS_ALE2, GREENMANS_ALE3, GREENMANS_ALE4, GREENMANS_ALE_7746);
|
||||
add(combo(5, food(2), boost(HERBLORE, 2), new BoostedStatBoost(ATTACK, false, perc(.04, -3)), new BoostedStatBoost(DEFENCE, false, perc(.04, -3)), new BoostedStatBoost(STRENGTH, false, perc(.04, -3))), GREENMANS_ALEM, GREENMANS_ALEM1, GREENMANS_ALEM2, GREENMANS_ALEM3, GREENMANS_ALEM4);
|
||||
add(combo(5, food(1), boost(SLAYER, 2), new BoostedStatBoost(ATTACK, false, perc(.02, -2)), new BoostedStatBoost(DEFENCE, false, perc(.02, -2)), new BoostedStatBoost(STRENGTH, false, perc(.02, -2))), SLAYERS_RESPITE, SLAYERS_RESPITE1, SLAYERS_RESPITE2, SLAYERS_RESPITE3, SLAYERS_RESPITE4);
|
||||
add(combo(5, food(2), boost(SLAYER, 4), new BoostedStatBoost(ATTACK, false, perc(.02, -3)), new BoostedStatBoost(DEFENCE, false, perc(.02, -3)), new BoostedStatBoost(STRENGTH, false, perc(.02, -3))), SLAYERS_RESPITEM, SLAYERS_RESPITEM1, SLAYERS_RESPITEM2, SLAYERS_RESPITEM3, SLAYERS_RESPITEM4);
|
||||
add(combo(5, food(1), new SimpleStatBoost(MAGIC, true, perc(.02, 2)), new BoostedStatBoost(ATTACK, false, perc(.05, -1)), new BoostedStatBoost(DEFENCE, false, perc(.05, -1)), new BoostedStatBoost(STRENGTH, false, perc(.05, -1))), WIZARDS_MIND_BOMB, MIND_BOMB1, MIND_BOMB2, MIND_BOMB3, MIND_BOMB4);
|
||||
add(combo(5, food(2), new SimpleStatBoost(MAGIC, true, perc(.02, 3)), new BoostedStatBoost(ATTACK, false, perc(.05, -2)), new BoostedStatBoost(DEFENCE, false, perc(.05, -2)), new BoostedStatBoost(STRENGTH, false, perc(.05, -2))), MATURE_WMB, MIND_BOMBM1, MIND_BOMBM2, MIND_BOMBM3, MIND_BOMBM4);
|
||||
add(combo(10, food(14), boost(STRENGTH, 3), boost(MINING, 1), heal(PRAYER, perc(.06, -1)), new BoostedStatBoost(AGILITY, false, perc(.09, -3)), new BoostedStatBoost(ATTACK, false, perc(.06, -1)), new BoostedStatBoost(DEFENCE, false, perc(.08, -2)), new BoostedStatBoost(HERBLORE, false, perc(.06, -1)), new BoostedStatBoost(MAGIC, false, perc(.05, -1)), new BoostedStatBoost(RANGED, false, perc(.06, -1))), BRAINDEATH_RUM);
|
||||
add(combo(2, food(2), heal(PRAYER, perc(.04, -2))), BLOODY_BRACER);
|
||||
add(combo(3, food(1), boost(AGILITY, 1), heal(STRENGTH, -1)), ELVEN_DAWN);
|
||||
add(combo(3, boost(RANGED, 4), new BoostedStatBoost(STRENGTH, false, perc(.04, -2)), new BoostedStatBoost(MAGIC, false, perc(.04, -2))), LIZARDKICKER);
|
||||
add(dec(ATTACK, 3), JUG_OF_BAD_WINE);
|
||||
add(combo(food(5), new SimpleStatBoost(STRENGTH, true, perc(.05, 1)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_SGG, SHORT_GREEN_GUY, BRANDY, GIN, VODKA, WHISKY);
|
||||
add(combo(food(7), new SimpleStatBoost(STRENGTH, true, perc(.05, 2)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_BLURB_SP, BLURBERRY_SPECIAL);
|
||||
add(combo(food(5), new SimpleStatBoost(STRENGTH, true, perc(.05, 2)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_DR_DRAGON, DRUNK_DRAGON, PREMADE_CHOC_SDY, CHOC_SATURDAY);
|
||||
add(combo(food(5), new SimpleStatBoost(STRENGTH, true, perc(.06, 1)), new BoostedStatBoost(ATTACK, false, perc(.02, -3))), PREMADE_WIZ_BLZD, WIZARD_BLIZZARD);
|
||||
add(combo(food(3), new SimpleStatBoost(STRENGTH, true, perc(.04, 1)), new BoostedStatBoost(ATTACK, false, perc(.05, -3))), GROG);
|
||||
add(combo(food(1), boost(STRENGTH, perc(.02, 1)), new BoostedStatBoost(ATTACK, false, perc(.06, -1))), BEER, BEER_7740);
|
||||
add(combo(food(4), boost(STRENGTH, perc(.04, 2)), new BoostedStatBoost(ATTACK, false, perc(.1, -2))), BEER_TANKARD);
|
||||
add(combo(food(15), boost(STRENGTH, perc(.1, 2)), new BoostedStatBoost(ATTACK, false, perc(.5, -4))), KEG_OF_BEER_3801 /* Non-quest version */);
|
||||
add(combo(boost(ATTACK, 5), boost(STRENGTH, 5), heal(MAGIC, -5), heal(PRAYER, -5)), BLOOD_PINT);
|
||||
add(combo(food(1), boost(STRENGTH, 2), new BoostedStatBoost(ATTACK, false, perc(.05, -2))), ASGARNIAN_ALE, ASGARNIAN_ALE1, ASGARNIAN_ALE2, ASGARNIAN_ALE3, ASGARNIAN_ALE4, ASGARNIAN_ALE_7744);
|
||||
add(combo(food(1), boost(STRENGTH, 3), new BoostedStatBoost(ATTACK, false, perc(.05, -3))), ASGARNIAN_ALEM, ASGARNIAN_ALEM1, ASGARNIAN_ALEM2, ASGARNIAN_ALEM3, ASGARNIAN_ALEM4);
|
||||
add(combo(food(1), boost(WOODCUTTING, 1), new BoostedStatBoost(ATTACK, false, perc(.02, -2)), new BoostedStatBoost(STRENGTH, false, perc(.02, -2))), AXEMANS_FOLLY, AXEMANS_FOLLY1, AXEMANS_FOLLY2, AXEMANS_FOLLY3, AXEMANS_FOLLY4);
|
||||
add(combo(food(2), boost(WOODCUTTING, 2), new BoostedStatBoost(ATTACK, false, perc(.02, -3)), new BoostedStatBoost(STRENGTH, false, perc(.02, -3))), AXEMANS_FOLLYM, AXEMANS_FOLLYM1, AXEMANS_FOLLYM2, AXEMANS_FOLLYM3, AXEMANS_FOLLYM4);
|
||||
add(combo(food(1), boost(THIEVING, 1), boost(ATTACK, 1), new BoostedStatBoost(DEFENCE, false, perc(.06, -3)), new BoostedStatBoost(STRENGTH, false, perc(.06, -3))), BANDITS_BREW);
|
||||
add(combo(food(1), new SimpleStatBoost(COOKING, true, perc(.05, 1)), new BoostedStatBoost(ATTACK, false, perc(.05, -2)), new BoostedStatBoost(STRENGTH, false, perc(.05, -2))), CHEFS_DELIGHT, CHEFS_DELIGHT1, CHEFS_DELIGHT2, CHEFS_DELIGHT3, CHEFS_DELIGHT4, CHEFS_DELIGHT_7754);
|
||||
add(combo(food(2), new SimpleStatBoost(COOKING, true, perc(.05, 2)), new BoostedStatBoost(ATTACK, false, perc(.05, -3)), new BoostedStatBoost(STRENGTH, false, perc(.05, -3))), CHEFS_DELIGHTM, CHEFS_DELIGHTM1, CHEFS_DELIGHTM2, CHEFS_DELIGHTM3, CHEFS_DELIGHTM4);
|
||||
add(combo(food(1), boost(FARMING, 1), new BoostedStatBoost(ATTACK, false, perc(.02, -2)), new BoostedStatBoost(STRENGTH, false, perc(.02, -2))), CIDER, CIDER1, CIDER2, CIDER3, CIDER4, CIDER_7752);
|
||||
add(combo(food(2), boost(FARMING, 2), new BoostedStatBoost(ATTACK, false, perc(.02, -3)), new BoostedStatBoost(STRENGTH, false, perc(.02, -3))), MATURE_CIDER, CIDERM1, CIDERM2, CIDERM3, CIDERM4);
|
||||
add(combo(food(1), boost(STRENGTH, 2), new BoostedStatBoost(ATTACK, false, perc(.05, -2))), DRAGON_BITTER, DRAGON_BITTER1, DRAGON_BITTER2, DRAGON_BITTER3, DRAGON_BITTER4, DRAGON_BITTER_7748);
|
||||
add(combo(food(2), boost(STRENGTH, 3), new BoostedStatBoost(ATTACK, false, perc(.05, -2))), DRAGON_BITTERM, DRAGON_BITTERM1, DRAGON_BITTERM2, DRAGON_BITTERM3, DRAGON_BITTERM4);
|
||||
add(combo(food(1), boost(MINING, 1), boost(SMITHING, 1), new BoostedStatBoost(ATTACK, false, perc(.04, -2)), new BoostedStatBoost(DEFENCE, false, perc(.04, -2)), new BoostedStatBoost(STRENGTH, false, perc(.04, -2))), DWARVEN_STOUT, DWARVEN_STOUT1, DWARVEN_STOUT2, DWARVEN_STOUT3, DWARVEN_STOUT4);
|
||||
add(combo(food(2), boost(MINING, 2), boost(SMITHING, 2), new BoostedStatBoost(ATTACK, false, perc(.04, -3)), new BoostedStatBoost(DEFENCE, false, perc(.04, -3)), new BoostedStatBoost(STRENGTH, false, perc(.04, -3))), DWARVEN_STOUTM, DWARVEN_STOUTM1, DWARVEN_STOUTM2, DWARVEN_STOUTM3, DWARVEN_STOUTM4);
|
||||
add(combo(food(1), boost(HERBLORE, 1), new BoostedStatBoost(ATTACK, false, perc(.04, -2)), new BoostedStatBoost(DEFENCE, false, perc(.04, -2)), new BoostedStatBoost(STRENGTH, false, perc(.04, -2))), GREENMANS_ALE, GREENMANS_ALE1, GREENMANS_ALE2, GREENMANS_ALE3, GREENMANS_ALE4, GREENMANS_ALE_7746);
|
||||
add(combo(food(2), boost(HERBLORE, 2), new BoostedStatBoost(ATTACK, false, perc(.04, -3)), new BoostedStatBoost(DEFENCE, false, perc(.04, -3)), new BoostedStatBoost(STRENGTH, false, perc(.04, -3))), GREENMANS_ALEM, GREENMANS_ALEM1, GREENMANS_ALEM2, GREENMANS_ALEM3, GREENMANS_ALEM4);
|
||||
add(combo(food(1), boost(SLAYER, 2), new BoostedStatBoost(ATTACK, false, perc(.02, -2)), new BoostedStatBoost(DEFENCE, false, perc(.02, -2)), new BoostedStatBoost(STRENGTH, false, perc(.02, -2))), SLAYERS_RESPITE, SLAYERS_RESPITE1, SLAYERS_RESPITE2, SLAYERS_RESPITE3, SLAYERS_RESPITE4);
|
||||
add(combo(food(2), boost(SLAYER, 4), new BoostedStatBoost(ATTACK, false, perc(.02, -3)), new BoostedStatBoost(DEFENCE, false, perc(.02, -3)), new BoostedStatBoost(STRENGTH, false, perc(.02, -3))), SLAYERS_RESPITEM, SLAYERS_RESPITEM1, SLAYERS_RESPITEM2, SLAYERS_RESPITEM3, SLAYERS_RESPITEM4);
|
||||
add(combo(food(1), new SimpleStatBoost(MAGIC, true, perc(.02, 2)), new BoostedStatBoost(ATTACK, false, perc(.05, -1)), new BoostedStatBoost(DEFENCE, false, perc(.05, -1)), new BoostedStatBoost(STRENGTH, false, perc(.05, -1))), WIZARDS_MIND_BOMB, MIND_BOMB1, MIND_BOMB2, MIND_BOMB3, MIND_BOMB4);
|
||||
add(combo(food(2), new SimpleStatBoost(MAGIC, true, perc(.02, 3)), new BoostedStatBoost(ATTACK, false, perc(.05, -2)), new BoostedStatBoost(DEFENCE, false, perc(.05, -2)), new BoostedStatBoost(STRENGTH, false, perc(.05, -2))), MATURE_WMB, MIND_BOMBM1, MIND_BOMBM2, MIND_BOMBM3, MIND_BOMBM4);
|
||||
add(combo(food(14), boost(STRENGTH, 3), boost(MINING, 1), heal(PRAYER, perc(.06, -1)), new BoostedStatBoost(AGILITY, false, perc(.09, -3)), new BoostedStatBoost(ATTACK, false, perc(.06, -1)), new BoostedStatBoost(DEFENCE, false, perc(.08, -2)), new BoostedStatBoost(HERBLORE, false, perc(.06, -1)), new BoostedStatBoost(MAGIC, false, perc(.05, -1)), new BoostedStatBoost(RANGED, false, perc(.06, -1))), BRAINDEATH_RUM);
|
||||
add(combo(food(2), heal(PRAYER, perc(.04, -2))), BLOODY_BRACER);
|
||||
add(combo(food(1), boost(AGILITY, 1), heal(STRENGTH, -1)), ELVEN_DAWN);
|
||||
add(combo(boost(RANGED, 4), new BoostedStatBoost(STRENGTH, false, perc(.04, -2)), new BoostedStatBoost(MAGIC, false, perc(.04, -2))), LIZARDKICKER);
|
||||
|
||||
// Sq'irk Juice
|
||||
add(heal(RUN_ENERGY, 5), WINTER_SQIRKJUICE);
|
||||
@@ -163,86 +169,141 @@ public class ItemStatChanges
|
||||
add(combo(heal(RUN_ENERGY, 20), boost(THIEVING, 3)), SUMMER_SQIRKJUICE);
|
||||
|
||||
// Combat potions
|
||||
add(boost(ATTACK, perc(.10, 3)), ATTACK_POTION1, ATTACK_POTION2, ATTACK_POTION3, ATTACK_POTION4);
|
||||
add(boost(STRENGTH, perc(.10, 3)), STRENGTH_POTION1, STRENGTH_POTION2, STRENGTH_POTION3, STRENGTH_POTION4);
|
||||
add(boost(DEFENCE, perc(.10, 3)), DEFENCE_POTION1, DEFENCE_POTION2, DEFENCE_POTION3, DEFENCE_POTION4);
|
||||
add(boost(MAGIC, 4), MAGIC_POTION1, MAGIC_POTION2, MAGIC_POTION3, MAGIC_POTION4);
|
||||
add(boost(RANGED, perc(.10, 4)), RANGING_POTION1, RANGING_POTION2, RANGING_POTION3, RANGING_POTION4,
|
||||
final SingleEffect attackPot = boost(ATTACK, perc(.10, 3));
|
||||
final SingleEffect strengthPot = boost(STRENGTH, perc(.10, 3));
|
||||
final SingleEffect defencePot = boost(DEFENCE, perc(.10, 3));
|
||||
final Effect combatPot = combo(attackPot, strengthPot);
|
||||
final Effect magicEssence = boost(MAGIC, 3);
|
||||
final SingleEffect magicPot = boost(MAGIC, 4);
|
||||
final SingleEffect imbuedHeart = boost(MAGIC, perc(.10, 1));
|
||||
final SingleEffect rangingPot = boost(RANGED, perc(.10, 4));
|
||||
final SingleEffect superAttackPot = boost(ATTACK, perc(.15, 5));
|
||||
final SingleEffect superStrengthPot = boost(STRENGTH, perc(.15, 5));
|
||||
final SingleEffect superDefencePot = boost(DEFENCE, perc(.15, 5));
|
||||
final SingleEffect superMagicPot = boost(MAGIC, perc(.15, 5));
|
||||
final SingleEffect superRangingPot = boost(RANGED, perc(.15, 5));
|
||||
final SingleEffect divinePot = heal(HITPOINTS, -10);
|
||||
final Effect zamorakBrew = combo(boost(ATTACK, perc(.20, 2)), boost(STRENGTH, perc(.12, 2)), heal(PRAYER, perc(.10, 0)), new BoostedStatBoost(DEFENCE, false, perc(.10, -2)), new BoostedStatBoost(HITPOINTS, false, perc(-.12, 0)));
|
||||
final Effect ancientBrew = new AncientBrew();
|
||||
add(attackPot, ATTACK_POTION1, ATTACK_POTION2, ATTACK_POTION3, ATTACK_POTION4);
|
||||
add(strengthPot, STRENGTH_POTION1, STRENGTH_POTION2, STRENGTH_POTION3, STRENGTH_POTION4);
|
||||
add(defencePot, DEFENCE_POTION1, DEFENCE_POTION2, DEFENCE_POTION3, DEFENCE_POTION4);
|
||||
add(magicPot, MAGIC_POTION1, MAGIC_POTION2, MAGIC_POTION3, MAGIC_POTION4);
|
||||
add(rangingPot, RANGING_POTION1, RANGING_POTION2, RANGING_POTION3, RANGING_POTION4,
|
||||
RANGING_POTION4_23551, RANGING_POTION3_23553, RANGING_POTION2_23555, RANGING_POTION1_23557 /* LMS */);
|
||||
add(combo(2, boost(ATTACK, perc(.10, 3)), boost(STRENGTH, perc(.10, 3))),
|
||||
COMBAT_POTION1, COMBAT_POTION2, COMBAT_POTION3, COMBAT_POTION4,
|
||||
add(combatPot, COMBAT_POTION1, COMBAT_POTION2, COMBAT_POTION3, COMBAT_POTION4,
|
||||
COMBAT_POTION4_26150, COMBAT_POTION3_26151, COMBAT_POTION2_26152, COMBAT_POTION1_26153 /* Deadman starter pack */);
|
||||
add(boost(ATTACK, perc(.15, 5)), SUPER_ATTACK1, SUPER_ATTACK2, SUPER_ATTACK3, SUPER_ATTACK4);
|
||||
add(boost(STRENGTH, perc(.15, 5)), SUPER_STRENGTH1, SUPER_STRENGTH2, SUPER_STRENGTH3, SUPER_STRENGTH4);
|
||||
add(boost(DEFENCE, perc(.15, 5)), SUPER_DEFENCE1, SUPER_DEFENCE2, SUPER_DEFENCE3, SUPER_DEFENCE4);
|
||||
add(boost(MAGIC, 3), MAGIC_ESSENCE1, MAGIC_ESSENCE2, MAGIC_ESSENCE3, MAGIC_ESSENCE4);
|
||||
add(combo(3, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5))), SUPER_COMBAT_POTION1, SUPER_COMBAT_POTION2, SUPER_COMBAT_POTION3, SUPER_COMBAT_POTION4);
|
||||
add(combo(3, boost(ATTACK, perc(.20, 2)), boost(STRENGTH, perc(.12, 2)), heal(PRAYER, perc(.10, 0)), new BoostedStatBoost(DEFENCE, false, perc(.10, -2)), new BoostedStatBoost(HITPOINTS, false, perc(-.12, 0))), ZAMORAK_BREW1, ZAMORAK_BREW2, ZAMORAK_BREW3, ZAMORAK_BREW4);
|
||||
add(superAttackPot, SUPER_ATTACK1, SUPER_ATTACK2, SUPER_ATTACK3, SUPER_ATTACK4);
|
||||
add(superStrengthPot, SUPER_STRENGTH1, SUPER_STRENGTH2, SUPER_STRENGTH3, SUPER_STRENGTH4);
|
||||
add(superDefencePot, SUPER_DEFENCE1, SUPER_DEFENCE2, SUPER_DEFENCE3, SUPER_DEFENCE4);
|
||||
add(magicEssence, MAGIC_ESSENCE1, MAGIC_ESSENCE2, MAGIC_ESSENCE3, MAGIC_ESSENCE4);
|
||||
add(combo(superAttackPot, superStrengthPot, superDefencePot), SUPER_COMBAT_POTION1, SUPER_COMBAT_POTION2, SUPER_COMBAT_POTION3, SUPER_COMBAT_POTION4);
|
||||
add(zamorakBrew, ZAMORAK_BREW1, ZAMORAK_BREW2, ZAMORAK_BREW3, ZAMORAK_BREW4);
|
||||
add(new SaradominBrew(0.15, 0.2, 0.1, 2, 2), SARADOMIN_BREW1, SARADOMIN_BREW2, SARADOMIN_BREW3,
|
||||
SARADOMIN_BREW4, SARADOMIN_BREW4_23575, SARADOMIN_BREW3_23577, SARADOMIN_BREW2_23579, SARADOMIN_BREW1_23581 /* LMS */);
|
||||
add(boost(RANGED, perc(.15, 5)), SUPER_RANGING_1, SUPER_RANGING_2, SUPER_RANGING_3, SUPER_RANGING_4);
|
||||
add(boost(MAGIC, perc(.15, 5)), SUPER_MAGIC_POTION_1, SUPER_MAGIC_POTION_2, SUPER_MAGIC_POTION_3, SUPER_MAGIC_POTION_4);
|
||||
add(combo(2, boost(RANGED, perc(0.1, 4)), boost(DEFENCE, perc(0.15, 5))), BASTION_POTION1, BASTION_POTION2, BASTION_POTION3, BASTION_POTION4);
|
||||
add(combo(2, boost(MAGIC, 4), boost(DEFENCE, perc(0.15, 5))), BATTLEMAGE_POTION1, BATTLEMAGE_POTION2, BATTLEMAGE_POTION3, BATTLEMAGE_POTION4);
|
||||
add(combo(boost(MAGIC, 4), heal(HITPOINTS, -10)), DIVINE_MAGIC_POTION1, DIVINE_MAGIC_POTION2, DIVINE_MAGIC_POTION3, DIVINE_MAGIC_POTION4);
|
||||
add(combo(boost(RANGED, perc(.10, 4)), heal(HITPOINTS, -10)), DIVINE_RANGING_POTION1, DIVINE_RANGING_POTION2, DIVINE_RANGING_POTION3, DIVINE_RANGING_POTION4);
|
||||
add(combo(boost(ATTACK, perc(.15, 5)), heal(HITPOINTS, -10)), DIVINE_SUPER_ATTACK_POTION1, DIVINE_SUPER_ATTACK_POTION2, DIVINE_SUPER_ATTACK_POTION3, DIVINE_SUPER_ATTACK_POTION4);
|
||||
add(combo(boost(STRENGTH, perc(.15, 5)), heal(HITPOINTS, -10)), DIVINE_SUPER_STRENGTH_POTION1, DIVINE_SUPER_STRENGTH_POTION2, DIVINE_SUPER_STRENGTH_POTION3, DIVINE_SUPER_STRENGTH_POTION4);
|
||||
add(combo(boost(DEFENCE, perc(.15, 5)), heal(HITPOINTS, -10)), DIVINE_SUPER_DEFENCE_POTION1, DIVINE_SUPER_DEFENCE_POTION2, DIVINE_SUPER_DEFENCE_POTION3, DIVINE_SUPER_DEFENCE_POTION4);
|
||||
add(combo(3, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), heal(HITPOINTS, -10)), DIVINE_SUPER_COMBAT_POTION1, DIVINE_SUPER_COMBAT_POTION2, DIVINE_SUPER_COMBAT_POTION3, DIVINE_SUPER_COMBAT_POTION4);
|
||||
add(combo(2, boost(RANGED, perc(0.1, 4)), boost(DEFENCE, perc(0.15, 5)), heal(HITPOINTS, -10)), DIVINE_BASTION_POTION1, DIVINE_BASTION_POTION2, DIVINE_BASTION_POTION3, DIVINE_BASTION_POTION4);
|
||||
add(combo(2, boost(MAGIC, 4), boost(DEFENCE, perc(0.15, 5)), heal(HITPOINTS, -10)), DIVINE_BATTLEMAGE_POTION1, DIVINE_BATTLEMAGE_POTION2, DIVINE_BATTLEMAGE_POTION3, DIVINE_BATTLEMAGE_POTION4);
|
||||
add(combo(5, boost(ATTACK, perc(0.15, 5)), boost(STRENGTH, perc(0.15, 5)), boost(DEFENCE, perc(0.15, 5)), boost(RANGED, perc(0.1, 4)), boost(MAGIC, perc(0.1, 1))),
|
||||
add(superRangingPot, SUPER_RANGING_1, SUPER_RANGING_2, SUPER_RANGING_3, SUPER_RANGING_4);
|
||||
add(superMagicPot, SUPER_MAGIC_POTION_1, SUPER_MAGIC_POTION_2, SUPER_MAGIC_POTION_3, SUPER_MAGIC_POTION_4);
|
||||
add(combo(rangingPot, superDefencePot), BASTION_POTION1, BASTION_POTION2, BASTION_POTION3, BASTION_POTION4);
|
||||
add(combo(magicPot, superDefencePot), BATTLEMAGE_POTION1, BATTLEMAGE_POTION2, BATTLEMAGE_POTION3, BATTLEMAGE_POTION4);
|
||||
add(combo(magicPot, divinePot), DIVINE_MAGIC_POTION1, DIVINE_MAGIC_POTION2, DIVINE_MAGIC_POTION3, DIVINE_MAGIC_POTION4);
|
||||
add(combo(rangingPot, divinePot), DIVINE_RANGING_POTION1, DIVINE_RANGING_POTION2, DIVINE_RANGING_POTION3, DIVINE_RANGING_POTION4);
|
||||
add(combo(superAttackPot, divinePot), DIVINE_SUPER_ATTACK_POTION1, DIVINE_SUPER_ATTACK_POTION2, DIVINE_SUPER_ATTACK_POTION3, DIVINE_SUPER_ATTACK_POTION4);
|
||||
add(combo(superStrengthPot, divinePot), DIVINE_SUPER_STRENGTH_POTION1, DIVINE_SUPER_STRENGTH_POTION2, DIVINE_SUPER_STRENGTH_POTION3, DIVINE_SUPER_STRENGTH_POTION4);
|
||||
add(combo(superDefencePot, divinePot), DIVINE_SUPER_DEFENCE_POTION1, DIVINE_SUPER_DEFENCE_POTION2, DIVINE_SUPER_DEFENCE_POTION3, DIVINE_SUPER_DEFENCE_POTION4);
|
||||
add(combo(superAttackPot, superStrengthPot, superDefencePot, divinePot), DIVINE_SUPER_COMBAT_POTION1, DIVINE_SUPER_COMBAT_POTION2, DIVINE_SUPER_COMBAT_POTION3, DIVINE_SUPER_COMBAT_POTION4);
|
||||
add(combo(rangingPot, superDefencePot, divinePot), DIVINE_BASTION_POTION1, DIVINE_BASTION_POTION2, DIVINE_BASTION_POTION3, DIVINE_BASTION_POTION4);
|
||||
add(combo(magicPot, superDefencePot, divinePot), DIVINE_BATTLEMAGE_POTION1, DIVINE_BATTLEMAGE_POTION2, DIVINE_BATTLEMAGE_POTION3, DIVINE_BATTLEMAGE_POTION4);
|
||||
add(combo(superAttackPot, superStrengthPot, superDefencePot, rangingPot, imbuedHeart),
|
||||
CASTLEWARS_BREW4, CASTLEWARS_BREW3, CASTLEWARS_BREW2, CASTLEWARS_BREW1);
|
||||
add(combo(2, boost(ATTACK, perc(0.15, 5)), boost(STRENGTH, perc(0.15, 5))),
|
||||
add(combo(superAttackPot, superStrengthPot),
|
||||
SUPER_COMBAT_POTION4_23543, SUPER_COMBAT_POTION3_23545, SUPER_COMBAT_POTION2_23547, SUPER_COMBAT_POTION1_23549 /* LMS */);
|
||||
add(ancientBrew, ANCIENT_BREW1, ANCIENT_BREW2, ANCIENT_BREW3, ANCIENT_BREW4);
|
||||
|
||||
// Mixed combat potions
|
||||
add(new MixedPotion(3, attackPot), ATTACK_MIX1, ATTACK_MIX2);
|
||||
add(new MixedPotion(3, strengthPot), STRENGTH_MIX1, STRENGTH_MIX2);
|
||||
add(new MixedPotion(6, defencePot), DEFENCE_MIX1, DEFENCE_MIX2);
|
||||
add(new MixedPotion(6, magicPot), MAGIC_MIX1, MAGIC_MIX2);
|
||||
add(new MixedPotion(6, rangingPot), RANGING_MIX1, RANGING_MIX2);
|
||||
add(new MixedPotion(6, combatPot), COMBAT_MIX1, COMBAT_MIX2);
|
||||
add(new MixedPotion(6, superAttackPot), SUPERATTACK_MIX1, SUPERATTACK_MIX2);
|
||||
add(new MixedPotion(6, superStrengthPot), SUPER_STR_MIX1, SUPER_STR_MIX2);
|
||||
add(new MixedPotion(6, superDefencePot), SUPER_DEF_MIX1, SUPER_DEF_MIX2);
|
||||
add(new MixedPotion(6, magicEssence), MAGIC_ESSENCE_MIX1, MAGIC_ESSENCE_MIX2);
|
||||
add(new MixedPotion(6, zamorakBrew), ZAMORAK_MIX1, ZAMORAK_MIX2);
|
||||
add(new MixedPotion(6, ancientBrew), ANCIENT_MIX1, ANCIENT_MIX2);
|
||||
|
||||
// Regular overload (NMZ)
|
||||
add(combo(5, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(HITPOINTS, -50)), OVERLOAD_1, OVERLOAD_2, OVERLOAD_3, OVERLOAD_4);
|
||||
add(combo(superAttackPot, superStrengthPot, superDefencePot, superRangingPot, superMagicPot, heal(HITPOINTS, -50)), OVERLOAD_1, OVERLOAD_2, OVERLOAD_3, OVERLOAD_4);
|
||||
|
||||
// Bandages (Castle Wars)
|
||||
add(new CastleWarsBandage(), BANDAGES);
|
||||
|
||||
// Bandages (Theatre of Blood entry mode)
|
||||
add(combo(8, food(20), heal(PRAYER, perc(0.25, 5)), heal(RUN_ENERGY, 20), boost(ATTACK, perc(0.15, 4)), boost(STRENGTH, perc(0.15, 4)), boost(DEFENCE, perc(0.15, 4)), boost(RANGED, perc(0.1, 4)), boost(MAGIC, 4)), BANDAGES_25730);
|
||||
add(combo(food(20), heal(PRAYER, perc(0.25, 5)), heal(RUN_ENERGY, 20), boost(ATTACK, perc(0.15, 4)), boost(STRENGTH, perc(0.15, 4)), boost(DEFENCE, perc(0.15, 4)), rangingPot, magicPot), BANDAGES_25730);
|
||||
|
||||
// Recovery potions
|
||||
add(combo(5, heal(ATTACK, perc(.30, 10)), heal(STRENGTH, perc(.30, 10)), heal(DEFENCE, perc(.30, 10)), heal(RANGED, perc(.30, 10)), heal(MAGIC, perc(.30, 10))), RESTORE_POTION1, RESTORE_POTION2, RESTORE_POTION3, RESTORE_POTION4);
|
||||
add(heal(RUN_ENERGY, 10), ENERGY_POTION1, ENERGY_POTION2, ENERGY_POTION3, ENERGY_POTION4);
|
||||
add(new PrayerPotion(7), PRAYER_POTION1, PRAYER_POTION2, PRAYER_POTION3, PRAYER_POTION4);
|
||||
add(heal(RUN_ENERGY, 20), SUPER_ENERGY1, SUPER_ENERGY2, SUPER_ENERGY3, SUPER_ENERGY4);
|
||||
add(new SuperRestore(.25, 8), SUPER_RESTORE1, SUPER_RESTORE2, SUPER_RESTORE3, SUPER_RESTORE4,
|
||||
final Effect restorePot = combo(heal(ATTACK, perc(.30, 10)), heal(STRENGTH, perc(.30, 10)), heal(DEFENCE, perc(.30, 10)), heal(RANGED, perc(.30, 10)), heal(MAGIC, perc(.30, 10)));
|
||||
final Effect energyPot = heal(RUN_ENERGY, 10);
|
||||
final Effect prayerPot = new PrayerPotion(7);
|
||||
final Effect superEnergyPot = heal(RUN_ENERGY, 20);
|
||||
final Effect superRestorePot = new SuperRestore(.25, 8);
|
||||
final Effect staminaPot = new StaminaPotion();
|
||||
add(restorePot, RESTORE_POTION1, RESTORE_POTION2, RESTORE_POTION3, RESTORE_POTION4);
|
||||
add(energyPot, ENERGY_POTION1, ENERGY_POTION2, ENERGY_POTION3, ENERGY_POTION4);
|
||||
add(prayerPot, PRAYER_POTION1, PRAYER_POTION2, PRAYER_POTION3, PRAYER_POTION4);
|
||||
add(superEnergyPot, SUPER_ENERGY1, SUPER_ENERGY2, SUPER_ENERGY3, SUPER_ENERGY4);
|
||||
add(superRestorePot, SUPER_RESTORE1, SUPER_RESTORE2, SUPER_RESTORE3, SUPER_RESTORE4,
|
||||
BLIGHTED_SUPER_RESTORE1, BLIGHTED_SUPER_RESTORE2, BLIGHTED_SUPER_RESTORE3, BLIGHTED_SUPER_RESTORE4,
|
||||
SUPER_RESTORE4_23567, SUPER_RESTORE3_23569, SUPER_RESTORE2_23571, SUPER_RESTORE1_23573 /* LMS */);
|
||||
add(new SuperRestore(.30, 4), SANFEW_SERUM1, SANFEW_SERUM2, SANFEW_SERUM3, SANFEW_SERUM4,
|
||||
SANFEW_SERUM4_23559, SANFEW_SERUM3_23561, SANFEW_SERUM2_23563, SANFEW_SERUM1_23565 /* LMS */);
|
||||
add(new StaminaPotion(), STAMINA_POTION1, STAMINA_POTION2, STAMINA_POTION3, STAMINA_POTION4);
|
||||
add(staminaPot, STAMINA_POTION1, STAMINA_POTION2, STAMINA_POTION3, STAMINA_POTION4);
|
||||
|
||||
// Mixed recovery potions
|
||||
add(new MixedPotion(3, restorePot), RESTORE_MIX1, RESTORE_MIX2);
|
||||
add(new MixedPotion(6, energyPot), ENERGY_MIX1, ENERGY_MIX2);
|
||||
add(new MixedPotion(6, prayerPot), PRAYER_MIX1, PRAYER_MIX2);
|
||||
add(new MixedPotion(6, superEnergyPot), SUPER_ENERGY_MIX1, SUPER_ENERGY_MIX2);
|
||||
add(new MixedPotion(6, superRestorePot), SUPER_RESTORE_MIX1, SUPER_RESTORE_MIX2);
|
||||
add(new MixedPotion(6, staminaPot), STAMINA_MIX1, STAMINA_MIX2);
|
||||
|
||||
// Raids potions (+)
|
||||
add(combo(5, boost(ATTACK, perc(.16, 6)), boost(STRENGTH, perc(.16, 6)), boost(DEFENCE, perc(.16, 6)), boost(RANGED, perc(.16, 6)), boost(MAGIC, perc(.16, 6)), heal(HITPOINTS, -50)), OVERLOAD_1_20993, OVERLOAD_2_20994, OVERLOAD_3_20995, OVERLOAD_4_20996);
|
||||
add(combo(3, boost(ATTACK, perc(.16, 6)), boost(STRENGTH, perc(.16, 6)), boost(DEFENCE, perc(.16, 6))), ELDER_1_20921, ELDER_2_20922, ELDER_3_20923, ELDER_4_20924);
|
||||
add(combo(2, boost(RANGED, perc(.16, 6)), boost(DEFENCE, perc(.16, 6))), TWISTED_1_20933, TWISTED_2_20934, TWISTED_3_20935, TWISTED_4_20936);
|
||||
add(combo(2, boost(MAGIC, perc(.16, 6)), boost(DEFENCE, perc(.16, 6))), KODAI_1_20945, KODAI_2_20946, KODAI_3_20947, KODAI_4_20948);
|
||||
final DeltaPercentage coxPlusPotionBoost = perc(.16, 6);
|
||||
add(combo(boost(ATTACK, coxPlusPotionBoost), boost(STRENGTH, coxPlusPotionBoost), boost(DEFENCE, coxPlusPotionBoost), boost(RANGED, coxPlusPotionBoost), boost(MAGIC, coxPlusPotionBoost), heal(HITPOINTS, -50)), OVERLOAD_1_20993, OVERLOAD_2_20994, OVERLOAD_3_20995, OVERLOAD_4_20996);
|
||||
add(combo(boost(ATTACK, coxPlusPotionBoost), boost(STRENGTH, coxPlusPotionBoost), boost(DEFENCE, coxPlusPotionBoost)), ELDER_1_20921, ELDER_2_20922, ELDER_3_20923, ELDER_4_20924);
|
||||
add(combo(boost(RANGED, coxPlusPotionBoost), boost(DEFENCE, coxPlusPotionBoost)), TWISTED_1_20933, TWISTED_2_20934, TWISTED_3_20935, TWISTED_4_20936);
|
||||
add(combo(boost(MAGIC, coxPlusPotionBoost), boost(DEFENCE, coxPlusPotionBoost)), KODAI_1_20945, KODAI_2_20946, KODAI_3_20947, KODAI_4_20948);
|
||||
add(new SuperRestore(.30, 11), REVITALISATION_1_20957, REVITALISATION_2_20958, REVITALISATION_3_20959, REVITALISATION_4_20960);
|
||||
add(new SaradominBrew(0.15, 0.2, 0.1, 5, 4), XERICS_AID_1_20981, XERICS_AID_2_20982, XERICS_AID_3_20983, XERICS_AID_4_20984);
|
||||
|
||||
// Raids potions
|
||||
add(combo(5, boost(ATTACK, perc(.13, 5)), boost(STRENGTH, perc(.13, 5)), boost(DEFENCE, perc(.13, 5)), boost(RANGED, perc(.13, 5)), boost(MAGIC, perc(.13, 5)), heal(HITPOINTS, -50)), OVERLOAD_1_20989, OVERLOAD_2_20990, OVERLOAD_3_20991, OVERLOAD_4_20992);
|
||||
add(combo(3, boost(ATTACK, perc(.13, 5)), boost(STRENGTH, perc(.13, 5)), boost(DEFENCE, perc(.13, 5))), ELDER_POTION_1, ELDER_POTION_2, ELDER_POTION_3, ELDER_POTION_4);
|
||||
add(combo(2, boost(RANGED, perc(.13, 5)), boost(DEFENCE, perc(.13, 5))), TWISTED_POTION_1, TWISTED_POTION_2, TWISTED_POTION_3, TWISTED_POTION_4);
|
||||
add(combo(2, boost(MAGIC, perc(.13, 5)), boost(DEFENCE, perc(.13, 5))), KODAI_POTION_1, KODAI_POTION_2, KODAI_POTION_3, KODAI_POTION_4);
|
||||
final DeltaPercentage coxPotionBoost = perc(.13, 5);
|
||||
add(combo(boost(ATTACK, coxPotionBoost), boost(STRENGTH, coxPotionBoost), boost(DEFENCE, coxPotionBoost), boost(RANGED, coxPotionBoost), boost(MAGIC, coxPotionBoost), heal(HITPOINTS, -50)), OVERLOAD_1_20989, OVERLOAD_2_20990, OVERLOAD_3_20991, OVERLOAD_4_20992);
|
||||
add(combo(boost(ATTACK, coxPotionBoost), boost(STRENGTH, coxPotionBoost), boost(DEFENCE, coxPotionBoost)), ELDER_POTION_1, ELDER_POTION_2, ELDER_POTION_3, ELDER_POTION_4);
|
||||
add(combo(boost(RANGED, coxPotionBoost), boost(DEFENCE, coxPotionBoost)), TWISTED_POTION_1, TWISTED_POTION_2, TWISTED_POTION_3, TWISTED_POTION_4);
|
||||
add(combo(boost(MAGIC, coxPotionBoost), boost(DEFENCE, coxPotionBoost)), KODAI_POTION_1, KODAI_POTION_2, KODAI_POTION_3, KODAI_POTION_4);
|
||||
|
||||
// Raids potions (-)
|
||||
add(combo(5, boost(ATTACK, perc(.10, 4)), boost(STRENGTH, perc(.10, 4)), boost(DEFENCE, perc(.10, 4)), boost(RANGED, perc(.10, 4)), boost(MAGIC, perc(.10, 4)), heal(HITPOINTS, -50)), OVERLOAD_1_20985, OVERLOAD_2_20986, OVERLOAD_3_20987, OVERLOAD_4_20988);
|
||||
add(combo(3, boost(ATTACK, perc(.10, 4)), boost(STRENGTH, perc(.10, 4)), boost(DEFENCE, perc(.10, 4))), ELDER_1, ELDER_2, ELDER_3, ELDER_4);
|
||||
add(combo(3, boost(RANGED, perc(.10, 4)), boost(DEFENCE, perc(.10, 4))), TWISTED_1, TWISTED_2, TWISTED_3, TWISTED_4);
|
||||
add(combo(3, boost(MAGIC, perc(.10, 4)), boost(DEFENCE, perc(.10, 4))), KODAI_1, KODAI_2, KODAI_3, KODAI_4);
|
||||
final DeltaPercentage coxMinusPotionBoost = perc(.10, 4);
|
||||
add(combo(boost(ATTACK, coxMinusPotionBoost), boost(STRENGTH, coxMinusPotionBoost), boost(DEFENCE, coxMinusPotionBoost), boost(RANGED, coxMinusPotionBoost), boost(MAGIC, coxMinusPotionBoost), heal(HITPOINTS, -50)), OVERLOAD_1_20985, OVERLOAD_2_20986, OVERLOAD_3_20987, OVERLOAD_4_20988);
|
||||
add(combo(boost(ATTACK, coxMinusPotionBoost), boost(STRENGTH, coxMinusPotionBoost), boost(DEFENCE, coxMinusPotionBoost)), ELDER_1, ELDER_2, ELDER_3, ELDER_4);
|
||||
add(combo(boost(RANGED, coxMinusPotionBoost), boost(DEFENCE, coxMinusPotionBoost)), TWISTED_1, TWISTED_2, TWISTED_3, TWISTED_4);
|
||||
add(combo(boost(MAGIC, coxMinusPotionBoost), boost(DEFENCE, coxMinusPotionBoost)), KODAI_1, KODAI_2, KODAI_3, KODAI_4);
|
||||
|
||||
// Skill potions
|
||||
add(boost(AGILITY, 3), AGILITY_POTION1, AGILITY_POTION2, AGILITY_POTION3, AGILITY_POTION4);
|
||||
add(boost(FISHING, 3), FISHING_POTION1, FISHING_POTION2, FISHING_POTION3, FISHING_POTION4);
|
||||
add(boost(HUNTER, 3), HUNTER_POTION1, HUNTER_POTION2, HUNTER_POTION3, HUNTER_POTION4);
|
||||
add(combo(2, boost(HITPOINTS, 5), heal(RUN_ENERGY, 5)), GUTHIX_REST1, GUTHIX_REST2, GUTHIX_REST3, GUTHIX_REST4);
|
||||
final Effect agilityPot = boost(AGILITY, 3);
|
||||
final Effect fishingPot = boost(FISHING, 3);
|
||||
final Effect hunterPot = boost(HUNTER, 3);
|
||||
add(agilityPot, AGILITY_POTION1, AGILITY_POTION2, AGILITY_POTION3, AGILITY_POTION4);
|
||||
add(fishingPot, FISHING_POTION1, FISHING_POTION2, FISHING_POTION3, FISHING_POTION4);
|
||||
add(hunterPot, HUNTER_POTION1, HUNTER_POTION2, HUNTER_POTION3, HUNTER_POTION4);
|
||||
add(combo(boost(HITPOINTS, 5), heal(RUN_ENERGY, 5)), GUTHIX_REST1, GUTHIX_REST2, GUTHIX_REST3, GUTHIX_REST4);
|
||||
|
||||
// Mixed skill potions
|
||||
add(new MixedPotion(6, agilityPot), AGILITY_MIX1, AGILITY_MIX2);
|
||||
add(new MixedPotion(6, fishingPot), FISHING_MIX1, FISHING_MIX2);
|
||||
add(new MixedPotion(6, hunterPot), HUNTING_MIX1, HUNTING_MIX2);
|
||||
|
||||
// Misc/run energy
|
||||
add(combo(food(3), range(heal(RUN_ENERGY, 5), heal(RUN_ENERGY, 10))), WHITE_TREE_FRUIT);
|
||||
@@ -251,19 +312,19 @@ public class ItemStatChanges
|
||||
add(combo(food(12), heal(RUN_ENERGY, 50)), GOUT_TUBER);
|
||||
|
||||
// Pies
|
||||
add(combo(2, heal(HITPOINTS, 6), boost(FARMING, 3)), GARDEN_PIE, HALF_A_GARDEN_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 6), boost(FISHING, 3)), FISH_PIE, HALF_A_FISH_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 7), boost(HERBLORE, 4)), BOTANICAL_PIE, HALF_A_BOTANICAL_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 8), boost(CRAFTING, 4)), MUSHROOM_PIE, HALF_A_MUSHROOM_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 8), boost(FISHING, 5)), ADMIRAL_PIE, HALF_AN_ADMIRAL_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 11), boost(SLAYER, 5), boost(RANGED, 4)), WILD_PIE, HALF_A_WILD_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 11), boost(AGILITY, 5), heal(RUN_ENERGY, 10)), SUMMER_PIE, HALF_A_SUMMER_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 10), boost(FLETCHING, 4)), DRAGONFRUIT_PIE, HALF_A_DRAGONFRUIT_PIE);
|
||||
add(combo(heal(HITPOINTS, 6), boost(FARMING, 3)), GARDEN_PIE, HALF_A_GARDEN_PIE);
|
||||
add(combo(heal(HITPOINTS, 6), boost(FISHING, 3)), FISH_PIE, HALF_A_FISH_PIE);
|
||||
add(combo(heal(HITPOINTS, 7), boost(HERBLORE, 4)), BOTANICAL_PIE, HALF_A_BOTANICAL_PIE);
|
||||
add(combo(heal(HITPOINTS, 8), boost(CRAFTING, 4)), MUSHROOM_PIE, HALF_A_MUSHROOM_PIE);
|
||||
add(combo(heal(HITPOINTS, 8), boost(FISHING, 5)), ADMIRAL_PIE, HALF_AN_ADMIRAL_PIE);
|
||||
add(combo(heal(HITPOINTS, 11), boost(SLAYER, 5), boost(RANGED, 4)), WILD_PIE, HALF_A_WILD_PIE);
|
||||
add(combo(heal(HITPOINTS, 11), boost(AGILITY, 5), heal(RUN_ENERGY, 10)), SUMMER_PIE, HALF_A_SUMMER_PIE);
|
||||
add(combo(heal(HITPOINTS, 10), boost(FLETCHING, 4)), DRAGONFRUIT_PIE, HALF_A_DRAGONFRUIT_PIE);
|
||||
|
||||
// Other
|
||||
add(combo(range(food(1), food(3)), heal(RUN_ENERGY, 10)), PURPLE_SWEETS_10476);
|
||||
add(new SpicyStew(), SPICY_STEW);
|
||||
add(boost(MAGIC, perc(.10, 1)), IMBUED_HEART);
|
||||
add(imbuedHeart, IMBUED_HEART);
|
||||
add(combo(boost(ATTACK, 2), boost(STRENGTH, 1), heal(PRAYER, 1), heal(DEFENCE, -1)), JANGERBERRIES);
|
||||
add(new CaveNightshade(), CAVE_NIGHTSHADE);
|
||||
|
||||
@@ -273,8 +334,8 @@ public class ItemStatChanges
|
||||
add(new GauntletPotion(), EGNIOL_POTION_1, EGNIOL_POTION_2, EGNIOL_POTION_3, EGNIOL_POTION_4);
|
||||
|
||||
// Soul Wars
|
||||
add(combo(2, heal(HITPOINTS, perc(.15, 1)), heal(RUN_ENERGY, 100)), BANDAGES_25202);
|
||||
add(combo(6, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(PRAYER, perc(.25, 8))), POTION_OF_POWER1, POTION_OF_POWER2, POTION_OF_POWER3, POTION_OF_POWER4);
|
||||
add(combo(heal(HITPOINTS, perc(.15, 1)), heal(RUN_ENERGY, 100)), BANDAGES_25202);
|
||||
add(combo(boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(PRAYER, perc(.25, 8))), POTION_OF_POWER1, POTION_OF_POWER2, POTION_OF_POWER3, POTION_OF_POWER4);
|
||||
|
||||
log.debug("{} items; {} behaviours loaded", effects.size(), new HashSet<>(effects.values()).size());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Hydrox6 <ikada@protonmail.ch>
|
||||
* 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.itemstats.potions;
|
||||
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.client.plugins.itemstats.BoostedStatBoost;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.perc;
|
||||
import net.runelite.client.plugins.itemstats.CappedStatBoost;
|
||||
import net.runelite.client.plugins.itemstats.Effect;
|
||||
import net.runelite.client.plugins.itemstats.SimpleStatBoost;
|
||||
import net.runelite.client.plugins.itemstats.StatChange;
|
||||
import net.runelite.client.plugins.itemstats.StatsChanges;
|
||||
import net.runelite.client.plugins.itemstats.stats.Stat;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.ATTACK;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.DEFENCE;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.MAGIC;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.PRAYER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.STRENGTH;
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@NoArgsConstructor
|
||||
public class AncientBrew implements Effect
|
||||
{
|
||||
private static final Stat[] LOWERED_STATS = {
|
||||
ATTACK, STRENGTH, DEFENCE
|
||||
};
|
||||
private static final CappedStatBoost PRAYER_BOOST = new CappedStatBoost(PRAYER, perc(.1, 2), perc(.05, 0));
|
||||
private static final SimpleStatBoost MAGIC_BOOST = new SimpleStatBoost(MAGIC, true, perc(.05, 2));
|
||||
private static final BoostedStatBoost MELEE_DRAIN = new BoostedStatBoost(null, false, perc(.1, -2));
|
||||
|
||||
@Override
|
||||
public StatsChanges calculate(Client client)
|
||||
{
|
||||
StatsChanges changes = new StatsChanges(0);
|
||||
changes.setStatChanges(Stream.of(
|
||||
Stream.of(PRAYER_BOOST.effect(client)),
|
||||
Stream.of(MAGIC_BOOST.effect(client)),
|
||||
Stream.of(LOWERED_STATS)
|
||||
.filter(stat -> 1 < stat.getValue(client))
|
||||
.map(stat ->
|
||||
{
|
||||
MELEE_DRAIN.setStat(stat);
|
||||
return MELEE_DRAIN.effect(client);
|
||||
}))
|
||||
.reduce(Stream::concat)
|
||||
.orElseGet(Stream::empty)
|
||||
.toArray(StatChange[]::new));
|
||||
changes.setPositivity(Stream.of(changes.getStatChanges())
|
||||
.map(StatChange::getPositivity)
|
||||
.max(Comparator.naturalOrder()).get());
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Jordan Atwood <nightfirecat@nightfirec.at>
|
||||
* 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.itemstats.potions;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nonnull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.food;
|
||||
import net.runelite.client.plugins.itemstats.Effect;
|
||||
import net.runelite.client.plugins.itemstats.Positivity;
|
||||
import net.runelite.client.plugins.itemstats.StatChange;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HITPOINTS;
|
||||
import net.runelite.client.plugins.itemstats.StatsChanges;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class MixedPotion implements Effect
|
||||
{
|
||||
private final int heal;
|
||||
|
||||
@Nonnull
|
||||
private final Effect potion;
|
||||
|
||||
@Override
|
||||
public StatsChanges calculate(Client client)
|
||||
{
|
||||
final StatsChanges changes = new StatsChanges(0);
|
||||
final StatChange mixedPotionHpBoost = food(heal).effect(client);
|
||||
final StatsChanges potionChanges = potion.calculate(client);
|
||||
final int mixedPotionHitpointsHealing = mixedPotionHpBoost.getRelative();
|
||||
|
||||
if (Stream.of(potionChanges.getStatChanges()).anyMatch(statChange -> statChange.getStat() == HITPOINTS))
|
||||
{
|
||||
changes.setStatChanges(Stream.of(potionChanges.getStatChanges())
|
||||
.map(change ->
|
||||
{
|
||||
/*
|
||||
* Mixed potions do not exist ingame for all types of potions. In fact, at the time of writing, the
|
||||
* Zamorak mix is the only mixed potion which includes base potion effects which affect a player's
|
||||
* Hitpoints. Working from what we know of how these behave, this code assumes that mixed potions
|
||||
* including Hitpoints changes will only include negative HP effects as the
|
||||
* absolute/relative/theoretical end values cannot be determined otherwise. For this reason, potions
|
||||
* with positive HP effects will not have their stat changes affected here.
|
||||
*/
|
||||
if (change.getStat() != HITPOINTS || mixedPotionHitpointsHealing == 0 || change.getTheoretical() >= 0)
|
||||
{
|
||||
return change;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mixed potions apply two hitpoints changes, both based on the current hitpoints value. Because of
|
||||
* this, the two effects are calculated independently of each other, both against the same starting
|
||||
* hitpoints value and later combined. These effects are:
|
||||
* 1. A food effect of `heal` amount
|
||||
* 2. Deduct hitpoints equal to the potion's boost amount
|
||||
*/
|
||||
|
||||
final int max = HITPOINTS.getMaximum(client);
|
||||
final int absolute = change.getAbsolute();
|
||||
final int relative = change.getRelative();
|
||||
|
||||
if (absolute + mixedPotionHitpointsHealing > max)
|
||||
{
|
||||
change.setPositivity(Positivity.BETTER_CAPPED);
|
||||
}
|
||||
else if (relative + mixedPotionHitpointsHealing > 0)
|
||||
{
|
||||
change.setPositivity(Positivity.BETTER_UNCAPPED);
|
||||
}
|
||||
else if (relative + mixedPotionHitpointsHealing == 0)
|
||||
{
|
||||
change.setPositivity(Positivity.NO_CHANGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
change.setPositivity(Positivity.WORSE);
|
||||
}
|
||||
|
||||
change.setAbsolute(Math.min(max, absolute + mixedPotionHitpointsHealing));
|
||||
change.setRelative(change.getRelative() + mixedPotionHitpointsHealing);
|
||||
change.setTheoretical(change.getTheoretical() + mixedPotionHitpointsHealing);
|
||||
|
||||
return change;
|
||||
})
|
||||
.toArray(StatChange[]::new));
|
||||
}
|
||||
else
|
||||
{
|
||||
changes.setStatChanges(ArrayUtils.addAll(new StatChange[] { mixedPotionHpBoost }, potionChanges.getStatChanges()));
|
||||
}
|
||||
|
||||
changes.setPositivity(Stream.of(changes.getStatChanges())
|
||||
.map(StatChange::getPositivity)
|
||||
.max(Comparator.naturalOrder()).get());
|
||||
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,8 @@ public class SaradominBrew implements Effect
|
||||
SimpleStatBoost hitpoints = new SimpleStatBoost(HITPOINTS, true, perc(percH, deltaB));
|
||||
SimpleStatBoost defence = new SimpleStatBoost(DEFENCE, true, perc(percD, deltaB));
|
||||
BoostedStatBoost calc = new BoostedStatBoost(null, false, perc(percSD, -deltaR));
|
||||
changes.setStatChanges(Stream.concat(
|
||||
changes.setStatChanges(Stream.of(
|
||||
Stream.of(hitpoints.effect(client)),
|
||||
Stream.concat(
|
||||
Stream.of(defence.effect(client)),
|
||||
Stream.of(saradominBrewStats)
|
||||
.filter(stat -> 1 < stat.getValue(client))
|
||||
@@ -67,12 +66,13 @@ public class SaradominBrew implements Effect
|
||||
{
|
||||
calc.setStat(stat);
|
||||
return calc.effect(client);
|
||||
})
|
||||
)
|
||||
).toArray(StatChange[]::new));
|
||||
}))
|
||||
.reduce(Stream::concat)
|
||||
.orElseGet(Stream::empty)
|
||||
.toArray(StatChange[]::new));
|
||||
changes.setPositivity(Stream.of(changes.getStatChanges())
|
||||
.map(sc -> sc.getPositivity())
|
||||
.map(StatChange::getPositivity)
|
||||
.max(Comparator.naturalOrder()).get());
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,17 +56,6 @@ public interface PartyConfig extends Config
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "messages",
|
||||
name = "Join messages",
|
||||
description = "Enables members join/leave game messages",
|
||||
position = 3
|
||||
)
|
||||
default boolean messages()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "recolorNames",
|
||||
name = "Recolor names",
|
||||
@@ -78,28 +67,6 @@ public interface PartyConfig extends Config
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "autoOverlay",
|
||||
name = "Auto overlay",
|
||||
description = "Automatically add an overlay with player data when a member joins",
|
||||
position = 5
|
||||
)
|
||||
default boolean autoOverlay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "includeSelf",
|
||||
name = "Include yourself",
|
||||
description = "Shows yourself in the panel as part of the party",
|
||||
position = 6
|
||||
)
|
||||
default boolean includeSelf()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "previousPartyId",
|
||||
name = "",
|
||||
|
||||
@@ -32,9 +32,7 @@ import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
@@ -47,6 +45,7 @@ import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.components.MouseDragEventForwarder;
|
||||
import net.runelite.client.ui.components.ProgressBar;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.ws.PartyMember;
|
||||
|
||||
class PartyMemberBox extends JPanel
|
||||
{
|
||||
@@ -61,9 +60,7 @@ class PartyMemberBox extends JPanel
|
||||
private final ProgressBar hpBar = new ProgressBar();
|
||||
private final ProgressBar prayerBar = new ProgressBar();
|
||||
|
||||
private final JLabel topName = new JLabel();
|
||||
private final JLabel bottomName = new JLabel();
|
||||
|
||||
private final JLabel name = new JLabel();
|
||||
private final JLabel avatar = new JLabel();
|
||||
|
||||
private final PartyConfig config;
|
||||
@@ -84,15 +81,6 @@ class PartyMemberBox extends JPanel
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
container.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
|
||||
// Create Toggle overlay
|
||||
final JMenuItem overlay = new JMenuItem("Toggle overlay");
|
||||
overlay.addActionListener(e -> memberPartyData.setShowOverlay(!memberPartyData.isShowOverlay()));
|
||||
|
||||
// Create popup menu
|
||||
final JPopupMenu popupMenu = new JPopupMenu();
|
||||
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
popupMenu.add(overlay);
|
||||
|
||||
// create a line border with the specified color and width
|
||||
Border border = BorderFactory.createLineBorder(Color.gray, 1);
|
||||
avatar.setBorder(border);
|
||||
@@ -113,14 +101,10 @@ class PartyMemberBox extends JPanel
|
||||
namesPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
namesPanel.setBorder(new EmptyBorder(2, 5, 2, 5));
|
||||
|
||||
topName.setFont(FontManager.getRunescapeSmallFont());
|
||||
bottomName.setFont(FontManager.getRunescapeSmallFont());
|
||||
name.setFont(FontManager.getRunescapeSmallFont());
|
||||
name.putClientProperty("html.disable", Boolean.TRUE);
|
||||
|
||||
topName.putClientProperty("html.disable", Boolean.TRUE);
|
||||
bottomName.putClientProperty("html.disable", Boolean.TRUE);
|
||||
|
||||
namesPanel.add(topName); // top
|
||||
namesPanel.add(bottomName); // bottom
|
||||
namesPanel.add(name);
|
||||
|
||||
headerPanel.add(avatar, BorderLayout.WEST);
|
||||
headerPanel.add(namesPanel, BorderLayout.CENTER);
|
||||
@@ -141,8 +125,6 @@ class PartyMemberBox extends JPanel
|
||||
container.add(headerPanel, BorderLayout.NORTH);
|
||||
container.add(progressWrapper, BorderLayout.SOUTH);
|
||||
|
||||
container.setComponentPopupMenu(popupMenu);
|
||||
|
||||
// forward mouse drag events to parent panel for drag and drop reordering
|
||||
MouseDragEventForwarder mouseDragEventForwarder = new MouseDragEventForwarder(panel);
|
||||
container.addMouseListener(mouseDragEventForwarder);
|
||||
@@ -155,10 +137,12 @@ class PartyMemberBox extends JPanel
|
||||
|
||||
void update()
|
||||
{
|
||||
final PartyMember member = memberPartyData.getMember();
|
||||
|
||||
// Avatar
|
||||
if (!avatarSet && memberPartyData.getMember().getAvatar() != null)
|
||||
if (!avatarSet && member.getAvatar() != null)
|
||||
{
|
||||
ImageIcon icon = new ImageIcon(ImageUtil.resizeImage(memberPartyData.getMember().getAvatar(), 32, 32));
|
||||
ImageIcon icon = new ImageIcon(ImageUtil.resizeImage(member.getAvatar(), 32, 32));
|
||||
icon.getImage().flush();
|
||||
avatar.setIcon(icon);
|
||||
|
||||
@@ -174,15 +158,12 @@ class PartyMemberBox extends JPanel
|
||||
prayerBar.setMaximumValue(memberPartyData.getMaxPrayer());
|
||||
prayerBar.setCenterLabel(progressBarLabel(memberPartyData.getPrayer(), memberPartyData.getMaxPrayer()));
|
||||
|
||||
// Update name labels
|
||||
// Update name label
|
||||
Color playerColor = config.recolorNames() ? memberPartyData.getColor() : Color.WHITE;
|
||||
boolean isLoggedIn = !memberPartyData.getCharacterName().isEmpty();
|
||||
boolean isLoggedIn = member.isLoggedIn();
|
||||
|
||||
topName.setForeground(playerColor);
|
||||
topName.setText(memberPartyData.getMember().getName());
|
||||
|
||||
bottomName.setForeground(isLoggedIn ? playerColor : Color.GRAY);
|
||||
bottomName.setText(isLoggedIn ? memberPartyData.getCharacterName() : "Logged out");
|
||||
name.setForeground(isLoggedIn ? playerColor : Color.GRAY);
|
||||
name.setText(member.getDisplayName());
|
||||
}
|
||||
|
||||
private static String progressBarLabel(int current, int max)
|
||||
|
||||
@@ -41,6 +41,7 @@ import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.plugins.party.data.PartyData;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.PluginPanel;
|
||||
@@ -51,13 +52,12 @@ import net.runelite.client.ws.PartyService;
|
||||
class PartyPanel extends PluginPanel
|
||||
{
|
||||
private static final String BTN_CREATE_TEXT = "Create party";
|
||||
private static final String BTN_LEAVE_TEXT = "Leave party";
|
||||
private static final String BTN_LEAVE_TEXT = "Leave";
|
||||
|
||||
private final PartyPlugin plugin;
|
||||
private final PartyService party;
|
||||
private final PartyConfig config;
|
||||
|
||||
private final Map<String, PartyRequestBox> requestBoxes = new HashMap<>();
|
||||
private final Map<UUID, PartyMemberBox> memberBoxes = new HashMap<>();
|
||||
|
||||
private final JButton startButton = new JButton();
|
||||
@@ -68,10 +68,9 @@ class PartyPanel extends PluginPanel
|
||||
private final PluginErrorPanel noPartyPanel = new PluginErrorPanel();
|
||||
private final PluginErrorPanel partyEmptyPanel = new PluginErrorPanel();
|
||||
private final JComponent memberBoxPanel = new DragAndDropReorderPane();
|
||||
private final JComponent requestBoxPanel = new DragAndDropReorderPane();
|
||||
|
||||
@Inject
|
||||
PartyPanel(final PartyPlugin plugin, final PartyConfig config, final PartyService party)
|
||||
PartyPanel(final ClientThread clientThread, final PartyPlugin plugin, final PartyConfig config, final PartyService party)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.party = party;
|
||||
@@ -113,7 +112,6 @@ class PartyPanel extends PluginPanel
|
||||
topPanel.add(rejoinPartyButton, c);
|
||||
|
||||
layoutPanel.add(topPanel);
|
||||
layoutPanel.add(requestBoxPanel);
|
||||
layoutPanel.add(memberBoxPanel);
|
||||
|
||||
startButton.setText(party.isInParty() ? BTN_LEAVE_TEXT : BTN_CREATE_TEXT);
|
||||
@@ -125,7 +123,7 @@ class PartyPanel extends PluginPanel
|
||||
rejoinPartyButton.setText("Join previous party");
|
||||
rejoinPartyButton.setFocusable(false);
|
||||
|
||||
copyPartyIdButton.setText("Copy party id");
|
||||
copyPartyIdButton.setText("Copy passphrase");
|
||||
copyPartyIdButton.setFocusable(false);
|
||||
|
||||
startButton.addActionListener(e ->
|
||||
@@ -146,7 +144,7 @@ class PartyPanel extends PluginPanel
|
||||
else
|
||||
{
|
||||
// Create party
|
||||
party.changeParty(party.getLocalPartyId());
|
||||
clientThread.invokeLater(() -> party.changeParty(party.generatePasspharse()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -156,8 +154,8 @@ class PartyPanel extends PluginPanel
|
||||
{
|
||||
String s = (String) JOptionPane.showInputDialog(
|
||||
joinPartyButton,
|
||||
"Please enter the party id:",
|
||||
"Party Id",
|
||||
"Please enter the party passphrase:",
|
||||
"Party Passphrase",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
null,
|
||||
null,
|
||||
@@ -168,15 +166,7 @@ class PartyPanel extends PluginPanel
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
party.changeParty(UUID.fromString(s));
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
party.changeParty(s);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -184,17 +174,7 @@ class PartyPanel extends PluginPanel
|
||||
{
|
||||
if (!party.isInParty())
|
||||
{
|
||||
try
|
||||
{
|
||||
party.changeParty(UUID.fromString(config.previousPartyId()));
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
JOptionPane.showMessageDialog(rejoinPartyButton,
|
||||
"Failed to join your previous party, create a new party or join a new one.",
|
||||
"Failed to Join Party",
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
party.changeParty(config.previousPartyId());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -203,12 +183,11 @@ class PartyPanel extends PluginPanel
|
||||
if (party.isInParty())
|
||||
{
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null);
|
||||
clipboard.setContents(new StringSelection(party.getPartyPassphrase()), null);
|
||||
}
|
||||
});
|
||||
|
||||
noPartyPanel.setContent("Not in a party", "Create a party to begin.");
|
||||
partyEmptyPanel.setContent("Party created", "You can now invite friends!");
|
||||
|
||||
updateParty();
|
||||
}
|
||||
@@ -229,6 +208,8 @@ class PartyPanel extends PluginPanel
|
||||
}
|
||||
else if (plugin.getPartyDataMap().size() <= 1)
|
||||
{
|
||||
partyEmptyPanel.setContent("Party created", "You can now invite friends!<br/>" +
|
||||
"Your party passphrase is: " + party.getPartyPassphrase() + ".");
|
||||
add(partyEmptyPanel);
|
||||
}
|
||||
}
|
||||
@@ -280,30 +261,4 @@ class PartyPanel extends PluginPanel
|
||||
{
|
||||
memberBoxes.forEach((key, value) -> value.update());
|
||||
}
|
||||
|
||||
void addRequest(String userId, String userName)
|
||||
{
|
||||
PartyRequestBox partyRequestBox = new PartyRequestBox(plugin, requestBoxPanel, userId, userName);
|
||||
requestBoxes.put(userId, partyRequestBox);
|
||||
requestBoxPanel.add(partyRequestBox);
|
||||
requestBoxPanel.revalidate();
|
||||
}
|
||||
|
||||
void removeAllRequests()
|
||||
{
|
||||
requestBoxes.forEach((key, value) -> requestBoxPanel.remove(value));
|
||||
requestBoxPanel.revalidate();
|
||||
requestBoxes.clear();
|
||||
}
|
||||
|
||||
void removeRequest(String userId)
|
||||
{
|
||||
final PartyRequestBox requestBox = requestBoxes.remove(userId);
|
||||
|
||||
if (requestBox != null)
|
||||
{
|
||||
requestBoxPanel.remove(requestBox);
|
||||
requestBoxPanel.revalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,13 +58,9 @@ import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.MenuOptionClicked;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.discord.DiscordService;
|
||||
import net.runelite.client.discord.events.DiscordJoinRequest;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.ConfigChanged;
|
||||
import net.runelite.client.events.OverlayMenuClicked;
|
||||
@@ -114,9 +110,6 @@ public class PartyPlugin extends Plugin
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private PartyStatsOverlay partyStatsOverlay;
|
||||
|
||||
@Inject
|
||||
private PartyPingOverlay partyPingOverlay;
|
||||
|
||||
@@ -138,9 +131,6 @@ public class PartyPlugin extends Plugin
|
||||
@Inject
|
||||
private ClientToolbar clientToolbar;
|
||||
|
||||
@Inject
|
||||
private DiscordService discordService;
|
||||
|
||||
@Inject
|
||||
@Named("developerMode")
|
||||
boolean developerMode;
|
||||
@@ -157,7 +147,6 @@ public class PartyPlugin extends Plugin
|
||||
private int lastHp, lastPray;
|
||||
private String lastCharacterName = "";
|
||||
private WorldPoint lastLocation;
|
||||
private boolean sendAlert;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
@@ -181,7 +170,6 @@ public class PartyPlugin extends Plugin
|
||||
|
||||
clientToolbar.addNavigation(navButton);
|
||||
|
||||
overlayManager.add(partyStatsOverlay);
|
||||
overlayManager.add(partyPingOverlay);
|
||||
wsClient.registerMessage(SkillUpdate.class);
|
||||
wsClient.registerMessage(TilePing.class);
|
||||
@@ -201,13 +189,11 @@ public class PartyPlugin extends Plugin
|
||||
partyDataMap.clear();
|
||||
pendingTilePings.clear();
|
||||
worldMapManager.removeIf(PartyWorldMapPoint.class::isInstance);
|
||||
overlayManager.remove(partyStatsOverlay);
|
||||
overlayManager.remove(partyPingOverlay);
|
||||
wsClient.unregisterMessage(SkillUpdate.class);
|
||||
wsClient.unregisterMessage(TilePing.class);
|
||||
wsClient.unregisterMessage(LocationUpdate.class);
|
||||
wsClient.unregisterMessage(CharacterNameUpdate.class);
|
||||
sendAlert = false;
|
||||
lastLocation = null;
|
||||
}
|
||||
|
||||
@@ -231,21 +217,6 @@ public class PartyPlugin extends Plugin
|
||||
void leaveParty()
|
||||
{
|
||||
party.changeParty(null);
|
||||
|
||||
if (!config.messages())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String leaveMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("You have left the party.")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(leaveMessage)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -253,22 +224,6 @@ public class PartyPlugin extends Plugin
|
||||
{
|
||||
if (event.getGroup().equals(PartyConfig.GROUP))
|
||||
{
|
||||
final PartyMember localMember = party.getLocalMember();
|
||||
|
||||
if (localMember != null)
|
||||
{
|
||||
if (config.includeSelf())
|
||||
{
|
||||
final PartyData partyData = getPartyData(localMember.getMemberId());
|
||||
assert partyData != null;
|
||||
SwingUtilities.invokeLater(() -> panel.addMember(partyData));
|
||||
}
|
||||
else
|
||||
{
|
||||
SwingUtilities.invokeLater(() -> panel.removeMember(localMember.getMemberId()));
|
||||
}
|
||||
}
|
||||
|
||||
// rebuild the panel in the event the "Recolor names" option changes
|
||||
SwingUtilities.invokeLater(panel::updateAll);
|
||||
}
|
||||
@@ -314,35 +269,12 @@ public class PartyPlugin extends Plugin
|
||||
wsClient.send(tilePing);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onDiscordJoinRequest(DiscordJoinRequest request)
|
||||
{
|
||||
final String requestMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("New join request received. Check your Party panel.")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(requestMessage)
|
||||
.build());
|
||||
|
||||
String userName = request.getUsername() + "#" + request.getDiscriminator();
|
||||
SwingUtilities.invokeLater(() -> panel.addRequest(request.getUserId(), userName));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
checkStateChanged(false);
|
||||
}
|
||||
|
||||
public void replyToRequest(String userId, int reply)
|
||||
{
|
||||
discordService.respondToRequest(userId, reply);
|
||||
panel.removeRequest(userId);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onTilePing(TilePing event)
|
||||
{
|
||||
@@ -400,12 +332,6 @@ public class PartyPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onGameTick(final GameTick event)
|
||||
{
|
||||
if (sendAlert && client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
sendAlert = false;
|
||||
sendInstructionMessage();
|
||||
}
|
||||
|
||||
checkStateChanged(false);
|
||||
}
|
||||
|
||||
@@ -430,11 +356,22 @@ public class PartyPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
String name = event.getCharacterName();
|
||||
name = Text.removeTags(Text.toJagexName(name));
|
||||
final String name = Text.removeTags(Text.toJagexName(event.getCharacterName()));
|
||||
final PartyMember member = partyData.getMember();
|
||||
|
||||
partyData.setCharacterName(name);
|
||||
SwingUtilities.invokeLater(() -> panel.updateMember(partyData.getMember().getMemberId()));
|
||||
if (!name.isEmpty())
|
||||
{
|
||||
member.setDisplayName(name);
|
||||
member.setLoggedIn(true);
|
||||
partyData.setColor(ColorUtil.fromObject(name));
|
||||
}
|
||||
else
|
||||
{
|
||||
member.setLoggedIn(false);
|
||||
partyData.setColor(Color.WHITE);
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.updateMember(member.getMemberId()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -477,30 +414,8 @@ public class PartyPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onUserJoin(final UserJoin event)
|
||||
{
|
||||
final PartyData partyData = getPartyData(event.getMemberId());
|
||||
|
||||
if (partyData == null || !config.messages())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String joinMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(partyData.getMember().getName())
|
||||
.append(" has joined the party!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(joinMessage)
|
||||
.build());
|
||||
|
||||
final PartyMember localMember = party.getLocalMember();
|
||||
|
||||
if (localMember != null && partyData.getMember().getMemberId().equals(localMember.getMemberId()))
|
||||
{
|
||||
sendAlert = true;
|
||||
}
|
||||
// this has a side effect of creating the party data
|
||||
getPartyData(event.getMemberId());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -557,20 +472,6 @@ public class PartyPlugin extends Plugin
|
||||
|
||||
if (removed != null)
|
||||
{
|
||||
if (config.messages())
|
||||
{
|
||||
final String joinMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(removed.getMember().getName())
|
||||
.append(" has left the party!")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(joinMessage)
|
||||
.build());
|
||||
}
|
||||
|
||||
worldMapManager.remove(removed.getWorldMapPoint());
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.removeMember(event.getMemberId()));
|
||||
@@ -587,14 +488,10 @@ public class PartyPlugin extends Plugin
|
||||
|
||||
if (event.getPartyId() != null)
|
||||
{
|
||||
config.setPreviousPartyId(String.valueOf(event.getPartyId()));
|
||||
config.setPreviousPartyId(event.getPassphrase());
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() ->
|
||||
{
|
||||
panel.removeAllMembers();
|
||||
panel.removeAllRequests();
|
||||
});
|
||||
SwingUtilities.invokeLater(panel::removeAllMembers);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -605,12 +502,11 @@ public class PartyPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Party " + party.getPartyId()).build());
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local Party " + party.getLocalPartyId()).build());
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Party " + party.getPartyPassphrase() + " ID " + party.getPartyId()).build());
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local ID " + party.getLocalMember().getMemberId()).build());
|
||||
for (PartyMember partyMember : party.getMembers())
|
||||
{
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value(" " + partyMember.getName() + " " + partyMember.getMemberId()).build());
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Member " + partyMember.getName() + " " + partyMember.getDisplayName() + " " + partyMember.getMemberId()).build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -636,7 +532,6 @@ public class PartyPlugin extends Plugin
|
||||
return partyDataMap.computeIfAbsent(uuid, (u) ->
|
||||
{
|
||||
final WorldMapPoint worldMapPoint = new PartyWorldMapPoint(new WorldPoint(0, 0, 0), memberById);
|
||||
worldMapPoint.setTooltip(memberById.getName());
|
||||
|
||||
// When first joining a party, other members can join before getting a join for self
|
||||
PartyMember partyMember = party.getLocalMember();
|
||||
@@ -648,32 +543,10 @@ public class PartyPlugin extends Plugin
|
||||
worldMapManager.add(worldMapPoint);
|
||||
}
|
||||
|
||||
PartyData partyData = new PartyData(memberById, worldMapPoint, ColorUtil.fromObject(memberById.getName()));
|
||||
partyData.setShowOverlay(config.autoOverlay());
|
||||
|
||||
if (config.includeSelf() || !isSelf)
|
||||
{
|
||||
SwingUtilities.invokeLater(() -> panel.addMember(partyData));
|
||||
}
|
||||
else
|
||||
{
|
||||
SwingUtilities.invokeLater(panel::updateParty);
|
||||
}
|
||||
PartyData partyData = new PartyData(memberById, worldMapPoint);
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.addMember(partyData));
|
||||
return partyData;
|
||||
});
|
||||
}
|
||||
|
||||
private void sendInstructionMessage()
|
||||
{
|
||||
final String helpMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append("To leave the party, click \"Leave party\" on the party panel.")
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHATNOTIFICATION)
|
||||
.runeLiteFormattedMessage(helpMessage)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Jonathan Rousseau <https://github.com/JoRouss>
|
||||
* 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.party;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.DynamicGridLayout;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.components.MouseDragEventForwarder;
|
||||
import net.runelite.client.ui.components.shadowlabel.JShadowedLabel;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.SwingUtil;
|
||||
import net.runelite.discord.DiscordRPC;
|
||||
|
||||
class PartyRequestBox extends JPanel
|
||||
{
|
||||
private static final ImageIcon CONFIRM_ICON = new ImageIcon(ImageUtil.loadImageResource(PartyPlugin.class, "confirm_icon.png"));
|
||||
private static final ImageIcon CONFIRM_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(ImageUtil.bufferedImageFromImage(CONFIRM_ICON.getImage()), 0.54f));
|
||||
private static final ImageIcon CANCEL_ICON = new ImageIcon(ImageUtil.loadImageResource(PartyPlugin.class, "cancel_icon.png"));
|
||||
private static final ImageIcon CANCEL_HOVER_ICON = new ImageIcon(ImageUtil.alphaOffset(ImageUtil.bufferedImageFromImage(CANCEL_ICON.getImage()), 0.6f));
|
||||
|
||||
PartyRequestBox(final PartyPlugin plugin, final JComponent panel, String userId, String userName)
|
||||
{
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(5, 0, 0, 0));
|
||||
|
||||
/* The box's wrapping container */
|
||||
final JPanel container = new JPanel();
|
||||
container.setLayout(new BorderLayout());
|
||||
container.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
container.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
|
||||
JPanel namesPanel = new JPanel();
|
||||
namesPanel.setLayout(new DynamicGridLayout(2, 1));
|
||||
namesPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
namesPanel.setBorder(new EmptyBorder(2, 5, 2, 5));
|
||||
|
||||
JShadowedLabel nameLabel = new JShadowedLabel();
|
||||
nameLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
nameLabel.setForeground(Color.WHITE);
|
||||
nameLabel.setText(userName);
|
||||
|
||||
JShadowedLabel messageLabel = new JShadowedLabel();
|
||||
messageLabel.setFont(FontManager.getRunescapeSmallFont());
|
||||
messageLabel.setForeground(Color.WHITE);
|
||||
messageLabel.setText("Wants to join your party!");
|
||||
|
||||
namesPanel.add(nameLabel);
|
||||
namesPanel.add(messageLabel);
|
||||
|
||||
JPanel actionsContainer = new JPanel(new GridLayout(1, 2, 8, 0));
|
||||
actionsContainer.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||
|
||||
JButton confirmButton = new JButton(CONFIRM_ICON);
|
||||
SwingUtil.removeButtonDecorations(confirmButton);
|
||||
confirmButton.setToolTipText("Invite");
|
||||
confirmButton.setRolloverIcon(CONFIRM_HOVER_ICON);
|
||||
confirmButton.addActionListener(e -> plugin.replyToRequest(userId, DiscordRPC.DISCORD_REPLY_YES));
|
||||
confirmButton.setPreferredSize(new Dimension(18, 18));
|
||||
|
||||
JButton cancelButton = new JButton(CANCEL_ICON);
|
||||
SwingUtil.removeButtonDecorations(cancelButton);
|
||||
cancelButton.setToolTipText("Reject");
|
||||
cancelButton.setRolloverIcon(CANCEL_HOVER_ICON);
|
||||
cancelButton.addActionListener(e -> plugin.replyToRequest(userId, DiscordRPC.DISCORD_REPLY_NO));
|
||||
cancelButton.setPreferredSize(new Dimension(18, 18));
|
||||
|
||||
actionsContainer.add(confirmButton);
|
||||
actionsContainer.add(cancelButton);
|
||||
|
||||
container.add(namesPanel, BorderLayout.WEST);
|
||||
container.add(actionsContainer, BorderLayout.EAST);
|
||||
|
||||
// forward mouse drag events to parent panel for drag and drop reordering
|
||||
MouseDragEventForwarder mouseDragEventForwarder = new MouseDragEventForwarder(panel);
|
||||
container.addMouseListener(mouseDragEventForwarder);
|
||||
container.addMouseMotionListener(mouseDragEventForwarder);
|
||||
|
||||
add(container, BorderLayout.NORTH);
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2021, Jonathan Rousseau <https://github.com/JoRouss>
|
||||
* 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.party;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.client.plugins.party.data.PartyData;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPanel;
|
||||
import net.runelite.client.ui.overlay.components.ComponentConstants;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.ProgressBarComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
|
||||
public class PartyStatsOverlay extends OverlayPanel
|
||||
{
|
||||
private static final Color HP_FG = new Color(0, 146, 54, 230);
|
||||
private static final Color HP_BG = new Color(102, 15, 16, 230);
|
||||
private static final Color PRAY_FG = new Color(0, 149, 151);
|
||||
private static final Color PRAY_BG = Color.black;
|
||||
|
||||
private final PartyPlugin plugin;
|
||||
private final PartyService party;
|
||||
private final PartyConfig config;
|
||||
|
||||
@Inject
|
||||
private PartyStatsOverlay(final PartyPlugin plugin, final PartyService party, final PartyConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
this.party = party;
|
||||
this.config = config;
|
||||
panelComponent.setBorder(new Rectangle());
|
||||
panelComponent.setGap(new Point(0, ComponentConstants.STANDARD_BORDER / 2));
|
||||
getMenuEntries().add(new OverlayMenuEntry(MenuAction.RUNELITE_OVERLAY, "Leave", "Party"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final Map<UUID, PartyData> partyDataMap = plugin.getPartyDataMap();
|
||||
if (partyDataMap.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.setBackgroundColor(null);
|
||||
|
||||
synchronized (plugin.getPartyDataMap())
|
||||
{
|
||||
partyDataMap.forEach((k, v) ->
|
||||
{
|
||||
boolean isSelf = party.getLocalMember() != null && party.getLocalMember().getMemberId().equals(k);
|
||||
|
||||
if (!v.isShowOverlay() || (!config.includeSelf() && isSelf))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final PanelComponent panel = v.getPanel();
|
||||
panel.getChildren().clear();
|
||||
|
||||
final TitleComponent name = TitleComponent.builder()
|
||||
.text(v.getCharacterName().isEmpty() ? v.getMember().getName() : v.getCharacterName())
|
||||
.color(config.recolorNames() ? v.getColor() : Color.WHITE)
|
||||
.build();
|
||||
|
||||
panel.getChildren().add(name);
|
||||
|
||||
if (v.getMaxHitpoints() > 0)
|
||||
{
|
||||
final ProgressBarComponent hpBar = new ProgressBarComponent();
|
||||
hpBar.setBackgroundColor(HP_BG);
|
||||
hpBar.setForegroundColor(HP_FG);
|
||||
hpBar.setMaximum(v.getMaxHitpoints());
|
||||
hpBar.setValue(v.getHitpoints());
|
||||
hpBar.setLabelDisplayMode(ProgressBarComponent.LabelDisplayMode.FULL);
|
||||
panel.getChildren().add(hpBar);
|
||||
}
|
||||
|
||||
if (v.getMaxPrayer() > 0)
|
||||
{
|
||||
final ProgressBarComponent prayBar = new ProgressBarComponent();
|
||||
prayBar.setBackgroundColor(PRAY_BG);
|
||||
prayBar.setForegroundColor(PRAY_FG);
|
||||
prayBar.setMaximum(v.getMaxPrayer());
|
||||
prayBar.setValue(v.getPrayer());
|
||||
prayBar.setLabelDisplayMode(ProgressBarComponent.LabelDisplayMode.FULL);
|
||||
panel.getChildren().add(prayBar);
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(panel);
|
||||
});
|
||||
}
|
||||
|
||||
return super.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -45,12 +45,23 @@ class PartyWorldMapPoint extends WorldMapPoint
|
||||
this.member = member;
|
||||
this.setSnapToEdge(true);
|
||||
this.setJumpOnClick(true);
|
||||
this.setName(member.getName());
|
||||
this.setImagePoint(new Point(
|
||||
ARROW.getWidth() / 2,
|
||||
ARROW.getHeight()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return member.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTooltip()
|
||||
{
|
||||
return member.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage getImage()
|
||||
{
|
||||
|
||||
@@ -41,12 +41,10 @@ public class PartyData
|
||||
private final PartyMember member;
|
||||
private final WorldMapPoint worldMapPoint;
|
||||
private final PanelComponent panel = new PanelComponent();
|
||||
private final Color color;
|
||||
private Color color = Color.WHITE;
|
||||
|
||||
private int hitpoints;
|
||||
private int maxHitpoints;
|
||||
private int prayer;
|
||||
private int maxPrayer;
|
||||
private String characterName = "";
|
||||
private boolean showOverlay;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Hexagon <hexagon@fking.work>
|
||||
* 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.specialcounter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.image.BufferedImage;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
class PlayerInfoDrop
|
||||
{
|
||||
private final int startCycle;
|
||||
private final int endCycle;
|
||||
private final int playerIdx;
|
||||
private final String text;
|
||||
private final int startHeightOffset;
|
||||
private final int endHeightOffset;
|
||||
private final Font font;
|
||||
private final Color color;
|
||||
private final BufferedImage image;
|
||||
|
||||
public static Builder builder(int startCycle, int endCycle, int playerIdx, String text)
|
||||
{
|
||||
return new Builder(startCycle, endCycle, playerIdx, text);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Accessors(fluent = true)
|
||||
@Setter
|
||||
static class Builder
|
||||
{
|
||||
private final int startCycle;
|
||||
private final int endCycle;
|
||||
private final int playerIdx;
|
||||
private final String text;
|
||||
private int startHeightOffset = 0;
|
||||
private int endHeightOffset = 200;
|
||||
private Font font = FontManager.getRunescapeBoldFont();
|
||||
private Color color = Color.WHITE;
|
||||
private BufferedImage image;
|
||||
|
||||
public PlayerInfoDrop build()
|
||||
{
|
||||
if (startCycle > endCycle)
|
||||
{
|
||||
throw new IllegalArgumentException("endCycle must be after startCycle");
|
||||
}
|
||||
if (playerIdx < 0 || playerIdx > 2047)
|
||||
{
|
||||
throw new IllegalArgumentException("playerIdx must be between 0-2047");
|
||||
}
|
||||
return new PlayerInfoDrop(startCycle, endCycle, playerIdx, text, startHeightOffset, endHeightOffset, font, color, image);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Hexagon <hexagon@fking.work>
|
||||
* 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.specialcounter;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@Singleton
|
||||
class PlayerInfoDropOverlay extends Overlay
|
||||
{
|
||||
private final SpecialCounterPlugin plugin;
|
||||
private final SpecialCounterConfig config;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
private PlayerInfoDropOverlay(SpecialCounterPlugin plugin, SpecialCounterConfig config, Client client)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.MED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
final List<PlayerInfoDrop> infoDrops = plugin.getPlayerInfoDrops();
|
||||
if (infoDrops.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final int cycle = client.getGameCycle();
|
||||
for (Iterator<PlayerInfoDrop> iterator = infoDrops.iterator(); iterator.hasNext();)
|
||||
{
|
||||
PlayerInfoDrop infoDrop = iterator.next();
|
||||
|
||||
if (cycle < infoDrop.getStartCycle())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cycle > infoDrop.getEndCycle())
|
||||
{
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config.specDrops())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Player player = client.getCachedPlayers()[infoDrop.getPlayerIdx()];
|
||||
if (player == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int elapsed = cycle - infoDrop.getStartCycle();
|
||||
int percent = elapsed * 100 / (infoDrop.getEndCycle() - infoDrop.getStartCycle());
|
||||
int currentHeight = infoDrop.getEndHeightOffset() * percent / 100;
|
||||
String text = infoDrop.getText();
|
||||
|
||||
graphics.setFont(infoDrop.getFont());
|
||||
Point textLocation = player.getCanvasTextLocation(graphics, text, player.getLogicalHeight() + infoDrop.getStartHeightOffset() + currentHeight);
|
||||
if (textLocation == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int alpha = 255 - (255 * percent / 100);
|
||||
BufferedImage image = infoDrop.getImage();
|
||||
if (image != null)
|
||||
{
|
||||
int textHeight = graphics.getFontMetrics().getHeight() - graphics.getFontMetrics().getMaxDescent();
|
||||
int textMargin = image.getWidth() / 2;
|
||||
int x = textLocation.getX() - textMargin - 1;
|
||||
int y = textLocation.getY() - textHeight / 2 - image.getHeight() / 2;
|
||||
Point imageLocation = new Point(x, y);
|
||||
|
||||
textLocation = new Point(textLocation.getX() + textMargin, textLocation.getY());
|
||||
|
||||
OverlayUtil.renderImageLocation(graphics, imageLocation, ImageUtil.alphaOffset(image, alpha - 255));
|
||||
}
|
||||
|
||||
drawText(graphics, textLocation, text, infoDrop.getColor(), alpha);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void drawText(Graphics2D g, Point point, String text, Color color, int colorAlpha)
|
||||
{
|
||||
g.setColor(ColorUtil.colorWithAlpha(Color.BLACK, colorAlpha));
|
||||
g.drawString(text, point.getX() + 1, point.getY() + 1);
|
||||
g.setColor(ColorUtil.colorWithAlpha(color, colorAlpha));
|
||||
g.drawString(text, point.getX(), point.getY());
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.specialcounter;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
@@ -45,6 +46,28 @@ public interface SpecialCounterConfig extends Config
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "specDrops",
|
||||
name = "Spec Drops",
|
||||
description = "Draws an overlay over the player when a special attack hits"
|
||||
)
|
||||
default boolean specDrops()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "specDropColor",
|
||||
name = "Spec Drop Color",
|
||||
description = "Text color for spec drops"
|
||||
)
|
||||
default Color specDropColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 10,
|
||||
keyName = "dragonWarhammerThreshold",
|
||||
name = "Dragon Warhammer",
|
||||
description = "Threshold for Dragon Warhammer (0 to disable)"
|
||||
@@ -55,7 +78,7 @@ public interface SpecialCounterConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
position = 20,
|
||||
keyName = "arclightThreshold",
|
||||
name = "Arclight",
|
||||
description = "Threshold for Arclight (0 to disable)"
|
||||
@@ -66,7 +89,7 @@ public interface SpecialCounterConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
position = 30,
|
||||
keyName = "darklightThreshold",
|
||||
name = "Darklight",
|
||||
description = "Threshold for Darklight (0 to disable)"
|
||||
@@ -77,7 +100,7 @@ public interface SpecialCounterConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
position = 40,
|
||||
keyName = "bandosGodswordThreshold",
|
||||
name = "Bandos Godsword",
|
||||
description = "Threshold for Bandos Godsword (0 to disable)"
|
||||
@@ -88,7 +111,7 @@ public interface SpecialCounterConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
position = 50,
|
||||
keyName = "bulwarkThreshold",
|
||||
name = "Dinh's Bulwark",
|
||||
description = "Threshold for Dinh's Bulwark (0 to disable)"
|
||||
|
||||
@@ -26,11 +26,17 @@ package net.runelite.client.plugins.specialcounter;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
@@ -44,6 +50,7 @@ import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.VarPlayer;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.api.events.CommandExecuted;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.events.HitsplatApplied;
|
||||
@@ -57,7 +64,9 @@ import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import net.runelite.client.ws.WSClient;
|
||||
|
||||
@@ -95,6 +104,9 @@ public class SpecialCounterPlugin extends Plugin
|
||||
private final Set<Integer> interactedNpcIds = new HashSet<>();
|
||||
private final SpecialCounter[] specialCounter = new SpecialCounter[SpecialWeapon.values().length];
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final List<PlayerInfoDrop> playerInfoDrops = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@@ -119,6 +131,16 @@ public class SpecialCounterPlugin extends Plugin
|
||||
@Inject
|
||||
private SpecialCounterConfig config;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private PlayerInfoDropOverlay playerInfoDropOverlay;
|
||||
|
||||
@Inject
|
||||
@Named("developerMode")
|
||||
boolean developerMode;
|
||||
|
||||
@Provides
|
||||
SpecialCounterConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
@@ -128,6 +150,7 @@ public class SpecialCounterPlugin extends Plugin
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
overlayManager.add(playerInfoDropOverlay);
|
||||
wsClient.registerMessage(SpecialCounterUpdate.class);
|
||||
currentWorld = -1;
|
||||
specialPercentage = -1;
|
||||
@@ -140,6 +163,7 @@ public class SpecialCounterPlugin extends Plugin
|
||||
protected void shutDown()
|
||||
{
|
||||
removeCounters();
|
||||
overlayManager.remove(playerInfoDropOverlay);
|
||||
wsClient.unregisterMessage(SpecialCounterUpdate.class);
|
||||
}
|
||||
|
||||
@@ -267,15 +291,18 @@ public class SpecialCounterPlugin extends Plugin
|
||||
if (wasSpec && specialWeapon != null && hitsplat.getAmount() > 0)
|
||||
{
|
||||
int hit = getHit(specialWeapon, hitsplat);
|
||||
int localPlayerId = client.getLocalPlayer().getId();
|
||||
|
||||
updateCounter(specialWeapon, null, hit);
|
||||
|
||||
if (!party.getMembers().isEmpty())
|
||||
{
|
||||
final SpecialCounterUpdate specialCounterUpdate = new SpecialCounterUpdate(interactingId, specialWeapon, hit);
|
||||
final SpecialCounterUpdate specialCounterUpdate = new SpecialCounterUpdate(interactingId, specialWeapon, hit, client.getWorld(), localPlayerId);
|
||||
specialCounterUpdate.setMemberId(party.getLocalMember().getMemberId());
|
||||
wsClient.send(specialCounterUpdate);
|
||||
}
|
||||
|
||||
playerInfoDrops.add(createSpecInfoDrop(specialWeapon, hit, localPlayerId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +342,7 @@ public class SpecialCounterPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
String name = party.getMemberById(event.getMemberId()).getName();
|
||||
String name = party.getMemberById(event.getMemberId()).getDisplayName();
|
||||
if (name == null)
|
||||
{
|
||||
return;
|
||||
@@ -334,9 +361,23 @@ public class SpecialCounterPlugin extends Plugin
|
||||
{
|
||||
updateCounter(event.getWeapon(), name, event.getHit());
|
||||
}
|
||||
|
||||
if (event.getWorld() == client.getWorld())
|
||||
{
|
||||
playerInfoDrops.add(createSpecInfoDrop(event.getWeapon(), event.getHit(), event.getPlayerId()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onCommandExecuted(CommandExecuted commandExecuted)
|
||||
{
|
||||
if (developerMode && commandExecuted.getCommand().equals("spec"))
|
||||
{
|
||||
playerInfoDrops.add(createSpecInfoDrop(SpecialWeapon.BANDOS_GODSWORD, 42, client.getLocalPlayer().getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private SpecialWeapon usedSpecialWeapon()
|
||||
{
|
||||
ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
@@ -424,4 +465,17 @@ public class SpecialCounterPlugin extends Plugin
|
||||
{
|
||||
return specialWeapon.isDamage() ? hitsplat.getAmount() : 1;
|
||||
}
|
||||
|
||||
private PlayerInfoDrop createSpecInfoDrop(SpecialWeapon weapon, int hit, int playerId)
|
||||
{
|
||||
int cycle = client.getGameCycle();
|
||||
BufferedImage image = ImageUtil.resizeImage(itemManager.getImage(weapon.getItemID()[0]), 24, 24);
|
||||
|
||||
return PlayerInfoDrop.builder(cycle, cycle + 100, playerId, Integer.toString(hit))
|
||||
.color(config.specDropColor())
|
||||
.startHeightOffset(100)
|
||||
.endHeightOffset(400)
|
||||
.image(image)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -35,4 +35,6 @@ public class SpecialCounterUpdate extends PartyMemberMessage
|
||||
private final int npcId;
|
||||
private final SpecialWeapon weapon;
|
||||
private final int hit;
|
||||
private final int world;
|
||||
private final int playerId;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.Experience;
|
||||
import net.runelite.api.MenuEntry;
|
||||
import net.runelite.api.Point;
|
||||
import net.runelite.api.Prayer;
|
||||
@@ -117,7 +118,7 @@ class StatusBarsOverlay extends Overlay
|
||||
{
|
||||
barRenderers.put(BarMode.DISABLED, null);
|
||||
barRenderers.put(BarMode.HITPOINTS, new BarRenderer(
|
||||
() -> client.getRealSkillLevel(Skill.HITPOINTS),
|
||||
() -> inLms() ? Experience.MAX_REAL_LEVEL : client.getRealSkillLevel(Skill.HITPOINTS),
|
||||
() -> client.getBoostedSkillLevel(Skill.HITPOINTS),
|
||||
() -> getRestoreValue(Skill.HITPOINTS.getName()),
|
||||
() ->
|
||||
@@ -170,7 +171,7 @@ class StatusBarsOverlay extends Overlay
|
||||
}
|
||||
));
|
||||
barRenderers.put(BarMode.PRAYER, new BarRenderer(
|
||||
() -> client.getRealSkillLevel(Skill.PRAYER),
|
||||
() -> inLms() ? Experience.MAX_REAL_LEVEL : client.getRealSkillLevel(Skill.PRAYER),
|
||||
() -> client.getBoostedSkillLevel(Skill.PRAYER),
|
||||
() -> getRestoreValue(Skill.PRAYER.getName()),
|
||||
() ->
|
||||
@@ -349,4 +350,9 @@ class StatusBarsOverlay extends Overlay
|
||||
|
||||
return ImageUtil.resizeCanvas(image, ICON_DIMENSIONS.width, ICON_DIMENSIONS.height);
|
||||
}
|
||||
|
||||
private boolean inLms()
|
||||
{
|
||||
return client.getWidget(WidgetInfo.LMS_KDA) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ package net.runelite.client.plugins.timers;
|
||||
import com.google.inject.Provides;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.inject.Inject;
|
||||
@@ -45,7 +46,6 @@ import net.runelite.api.ItemContainer;
|
||||
import net.runelite.api.ItemID;
|
||||
import static net.runelite.api.ItemID.FIRE_CAPE;
|
||||
import static net.runelite.api.ItemID.INFERNAL_CAPE;
|
||||
import net.runelite.api.MenuAction;
|
||||
import net.runelite.api.NPC;
|
||||
import net.runelite.api.NpcID;
|
||||
import net.runelite.api.Player;
|
||||
@@ -152,11 +152,12 @@ public class TimersPlugin extends Plugin
|
||||
private int lastPoisonVarp;
|
||||
private int lastPvpVarb;
|
||||
private int lastCorruptionVarb;
|
||||
private int lastHomeTeleport;
|
||||
private int lastMinigameTeleport;
|
||||
private int lastImbuedHeartVarb;
|
||||
private boolean imbuedHeartTimerActive;
|
||||
private int nextPoisonTick;
|
||||
private WorldPoint lastPoint;
|
||||
private TeleportWidget lastTeleportClicked;
|
||||
private int lastAnimation;
|
||||
private boolean widgetHiddenChangedOnPvpWorld;
|
||||
private ElapsedTimer tzhaarTimer;
|
||||
@@ -185,6 +186,11 @@ public class TimersPlugin extends Plugin
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
if (config.showHomeMinigameTeleports())
|
||||
{
|
||||
checkTeleport(VarPlayer.LAST_HOME_TELEPORT);
|
||||
checkTeleport(VarPlayer.LAST_MINIGAME_TELEPORT);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,7 +199,6 @@ public class TimersPlugin extends Plugin
|
||||
infoBoxManager.removeIf(t -> t instanceof TimerTimer);
|
||||
lastRaidVarb = -1;
|
||||
lastPoint = null;
|
||||
lastTeleportClicked = null;
|
||||
lastAnimation = -1;
|
||||
widgetHiddenChangedOnPvpWorld = false;
|
||||
lastPoisonVarp = 0;
|
||||
@@ -202,6 +207,8 @@ public class TimersPlugin extends Plugin
|
||||
staminaTimer = null;
|
||||
imbuedHeartTimerActive = false;
|
||||
lastImbuedHeartVarb = 0;
|
||||
lastHomeTeleport = 0;
|
||||
lastMinigameTeleport = 0;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -214,6 +221,8 @@ public class TimersPlugin extends Plugin
|
||||
int pvpVarb = client.getVarbitValue(Varbits.PVP_SPEC_ORB);
|
||||
int corruptionCooldownVarb = client.getVarbitValue(Varbits.CORRUPTION_COOLDOWN);
|
||||
int imbuedHeartCooldownVarb = client.getVarbitValue(Varbits.IMBUED_HEART_COOLDOWN);
|
||||
int homeTeleportVarp = client.getVar(VarPlayer.LAST_HOME_TELEPORT);
|
||||
int minigameTeleportVarp = client.getVar(VarPlayer.LAST_MINIGAME_TELEPORT);
|
||||
|
||||
if (lastRaidVarb != raidVarb)
|
||||
{
|
||||
@@ -320,6 +329,18 @@ public class TimersPlugin extends Plugin
|
||||
|
||||
lastImbuedHeartVarb = imbuedHeartCooldownVarb;
|
||||
}
|
||||
|
||||
if (lastHomeTeleport != homeTeleportVarp)
|
||||
{
|
||||
checkTeleport(VarPlayer.LAST_HOME_TELEPORT);
|
||||
lastHomeTeleport = homeTeleportVarp;
|
||||
}
|
||||
|
||||
if (lastMinigameTeleport != minigameTeleportVarp)
|
||||
{
|
||||
checkTeleport(VarPlayer.LAST_MINIGAME_TELEPORT);
|
||||
lastMinigameTeleport = minigameTeleportVarp;
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -335,6 +356,11 @@ public class TimersPlugin extends Plugin
|
||||
removeGameTimer(HOME_TELEPORT);
|
||||
removeGameTimer(MINIGAME_TELEPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
checkTeleport(VarPlayer.LAST_HOME_TELEPORT);
|
||||
checkTeleport(VarPlayer.LAST_MINIGAME_TELEPORT);
|
||||
}
|
||||
|
||||
if (!config.showAntiFire())
|
||||
{
|
||||
@@ -491,15 +517,6 @@ public class TimersPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getMenuAction() == MenuAction.CC_OP)
|
||||
{
|
||||
TeleportWidget teleportWidget = TeleportWidget.of(event.getParam1());
|
||||
if (teleportWidget != null)
|
||||
{
|
||||
lastTeleportClicked = teleportWidget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -877,6 +894,37 @@ public class TimersPlugin extends Plugin
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTeleport(VarPlayer varPlayer)
|
||||
{
|
||||
final GameTimer teleport;
|
||||
switch (varPlayer)
|
||||
{
|
||||
case LAST_HOME_TELEPORT:
|
||||
teleport = HOME_TELEPORT;
|
||||
break;
|
||||
case LAST_MINIGAME_TELEPORT:
|
||||
teleport = MINIGAME_TELEPORT;
|
||||
break;
|
||||
default:
|
||||
// Other var changes are not handled as teleports
|
||||
return;
|
||||
}
|
||||
|
||||
int lastTeleport = client.getVar(varPlayer);
|
||||
long lastTeleportSeconds = (long) lastTeleport * 60;
|
||||
Instant teleportExpireInstant = Instant.ofEpochSecond(lastTeleportSeconds).plus(teleport.getDuration().getSeconds(), ChronoUnit.SECONDS);
|
||||
Duration remainingTime = Duration.between(Instant.now(), teleportExpireInstant);
|
||||
|
||||
if (remainingTime.getSeconds() > 0)
|
||||
{
|
||||
createGameTimer(teleport, remainingTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
removeGameTimer(teleport);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
@@ -956,23 +1004,6 @@ public class TimersPlugin extends Plugin
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.showHomeMinigameTeleports()
|
||||
&& client.getLocalPlayer().getAnimation() == AnimationID.IDLE
|
||||
&& (lastAnimation == AnimationID.BOOK_HOME_TELEPORT_5
|
||||
|| lastAnimation == AnimationID.COW_HOME_TELEPORT_6
|
||||
|| lastAnimation == AnimationID.LEAGUE_HOME_TELEPORT_6
|
||||
|| lastAnimation == AnimationID.SHATTERED_LEAGUE_HOME_TELEPORT_6))
|
||||
{
|
||||
if (lastTeleportClicked == TeleportWidget.HOME_TELEPORT)
|
||||
{
|
||||
createGameTimer(HOME_TELEPORT);
|
||||
}
|
||||
else if (lastTeleportClicked == TeleportWidget.MINIGAME_TELEPORT)
|
||||
{
|
||||
createGameTimer(MINIGAME_TELEPORT);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.showDFSSpecial() && lastAnimation == AnimationID.DRAGONFIRE_SHIELD_SPECIAL)
|
||||
{
|
||||
createGameTimer(DRAGON_FIRE_SHIELD);
|
||||
|
||||
@@ -33,5 +33,7 @@ public class PartyMember
|
||||
{
|
||||
private final UUID memberId;
|
||||
private final String name;
|
||||
private String displayName = "<unknown>";
|
||||
private boolean loggedIn;
|
||||
private BufferedImage avatar;
|
||||
}
|
||||
|
||||
@@ -25,20 +25,25 @@
|
||||
*/
|
||||
package net.runelite.client.ws;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.hash.Hashing;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.ItemComposition;
|
||||
import net.runelite.client.account.AccountSession;
|
||||
import net.runelite.client.account.SessionManager;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
@@ -46,8 +51,8 @@ import net.runelite.client.chat.QueuedMessage;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.events.PartyChanged;
|
||||
import net.runelite.client.util.Text;
|
||||
import net.runelite.client.events.PartyMemberAvatar;
|
||||
import net.runelite.client.util.Text;
|
||||
import static net.runelite.client.util.Text.JAGEX_PRINTABLE_CHAR_MATCHER;
|
||||
import net.runelite.http.api.ws.messages.party.Join;
|
||||
import net.runelite.http.api.ws.messages.party.Part;
|
||||
@@ -60,31 +65,27 @@ import net.runelite.http.api.ws.messages.party.UserSync;
|
||||
@Singleton
|
||||
public class PartyService
|
||||
{
|
||||
public static final int PARTY_MAX = 15;
|
||||
private static final int MAX_MESSAGE_LEN = 150;
|
||||
private static final int MAX_USERNAME_LEN = 32; // same as Discord
|
||||
private static final String USERNAME = "rluser-" + new Random().nextInt(Integer.MAX_VALUE);
|
||||
private static final String ALPHABET = "bcdfghjklmnpqrstvwxyz";
|
||||
|
||||
private final Client client;
|
||||
private final WSClient wsClient;
|
||||
private final SessionManager sessionManager;
|
||||
private final EventBus eventBus;
|
||||
private final ChatMessageManager chat;
|
||||
private final List<PartyMember> members = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private UUID localPartyId = UUID.randomUUID();
|
||||
|
||||
@Getter
|
||||
private UUID publicPartyId; // public party id, for advertising on discord, derived from the secret
|
||||
|
||||
@Getter
|
||||
private UUID partyId; // secret party id
|
||||
|
||||
@Setter
|
||||
private String username;
|
||||
@Getter
|
||||
private String partyPassphrase;
|
||||
|
||||
@Inject
|
||||
private PartyService(final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat)
|
||||
private PartyService(final Client client, final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat)
|
||||
{
|
||||
this.client = client;
|
||||
this.wsClient = wsClient;
|
||||
this.sessionManager = sessionManager;
|
||||
this.eventBus = eventBus;
|
||||
@@ -92,36 +93,89 @@ public class PartyService
|
||||
eventBus.register(this);
|
||||
}
|
||||
|
||||
public void changeParty(@Nullable UUID newParty)
|
||||
public String generatePasspharse()
|
||||
{
|
||||
if (username == null)
|
||||
assert client.isClientThread();
|
||||
|
||||
Random r = new Random();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (client.getGameState().getState() >= GameState.LOGIN_SCREEN.getState())
|
||||
{
|
||||
log.warn("Tried to join a party with no username");
|
||||
return;
|
||||
int len = 0;
|
||||
final CharMatcher matcher = CharMatcher.javaLetter();
|
||||
do
|
||||
{
|
||||
final int itemId = r.nextInt(client.getItemCount());
|
||||
final ItemComposition def = client.getItemDefinition(itemId);
|
||||
final String name = def.getName();
|
||||
if (name == null || name.isEmpty() || name.equals("null"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final String[] split = name.split(" ");
|
||||
final String token = split[r.nextInt(split.length)];
|
||||
if (!matcher.matchesAllOf(token) || token.length() <= 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sb.length() > 0)
|
||||
{
|
||||
sb.append('-');
|
||||
}
|
||||
sb.append(token.toLowerCase(Locale.US));
|
||||
++len;
|
||||
}
|
||||
while (len < 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = 0;
|
||||
do
|
||||
{
|
||||
if (sb.length() > 0)
|
||||
{
|
||||
sb.append('-');
|
||||
}
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
sb.append(ALPHABET.charAt(r.nextInt(ALPHABET.length())));
|
||||
}
|
||||
++len;
|
||||
}
|
||||
while (len < 4);
|
||||
}
|
||||
|
||||
String partyPassphrase = sb.toString();
|
||||
log.debug("Generated party passpharse {}", partyPassphrase);
|
||||
return partyPassphrase;
|
||||
}
|
||||
|
||||
public void changeParty(@Nullable String passphrase)
|
||||
{
|
||||
if (wsClient.sessionExists())
|
||||
{
|
||||
wsClient.send(new Part());
|
||||
}
|
||||
|
||||
log.debug("Party change to {}", newParty);
|
||||
UUID id = passphrase != null ? passphraseToId(passphrase) : null;
|
||||
|
||||
log.debug("Party change to {} (id {})", passphrase, id);
|
||||
members.clear();
|
||||
partyId = newParty;
|
||||
// The public party ID needs to be consistent across party members, but not a secret
|
||||
publicPartyId = newParty != null ? UUID.nameUUIDFromBytes(Hashing.sha256().hashString(newParty.toString(), Charsets.UTF_8).asBytes()) : null;
|
||||
partyId = id;
|
||||
partyPassphrase = passphrase;
|
||||
|
||||
if (partyId == null)
|
||||
{
|
||||
localPartyId = UUID.randomUUID(); // cycle local party id so that a new party is created now
|
||||
|
||||
// close the websocket if the session id isn't for an account
|
||||
if (sessionManager.getAccountSession() == null)
|
||||
{
|
||||
wsClient.changeSession(null);
|
||||
}
|
||||
|
||||
eventBus.post(new PartyChanged(partyId));
|
||||
eventBus.post(new PartyChanged(partyPassphrase, partyId));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,8 +188,8 @@ public class PartyService
|
||||
wsClient.changeSession(uuid);
|
||||
}
|
||||
|
||||
eventBus.post(new PartyChanged(partyId));
|
||||
wsClient.send(new Join(partyId, username));
|
||||
eventBus.post(new PartyChanged(partyPassphrase, partyId));
|
||||
wsClient.send(new Join(partyId, USERNAME));
|
||||
}
|
||||
|
||||
@Subscribe(priority = 1) // run prior to plugins so that the member is joined by the time the plugins see it.
|
||||
@@ -171,11 +225,18 @@ public class PartyService
|
||||
@Subscribe
|
||||
public void onPartyChatMessage(final PartyChatMessage message)
|
||||
{
|
||||
final PartyMember member = getMemberById(message.getMemberId());
|
||||
if (member == null || !member.isLoggedIn())
|
||||
{
|
||||
log.debug("Dropping party chat from non logged-in member");
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove non-printable characters, and <img> tags from message
|
||||
String sentMesage = JAGEX_PRINTABLE_CHAR_MATCHER.retainFrom(message.getValue())
|
||||
.replaceAll("<img=.+>", "");
|
||||
|
||||
// Cap the mesage length
|
||||
// Cap the message length
|
||||
if (sentMesage.length() > MAX_MESSAGE_LEN)
|
||||
{
|
||||
sentMesage = sentMesage.substring(0, MAX_MESSAGE_LEN);
|
||||
@@ -184,14 +245,14 @@ public class PartyService
|
||||
chat.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.FRIENDSCHAT)
|
||||
.sender("Party")
|
||||
.name(getMemberById(message.getMemberId()).getName())
|
||||
.name(member.getDisplayName())
|
||||
.runeLiteFormattedMessage(sentMesage)
|
||||
.build());
|
||||
}
|
||||
|
||||
public PartyMember getLocalMember()
|
||||
{
|
||||
return getMemberByName(username);
|
||||
return getMemberByName(USERNAME);
|
||||
}
|
||||
|
||||
public PartyMember getMemberById(final UUID id)
|
||||
@@ -230,11 +291,6 @@ public class PartyService
|
||||
return partyId != null;
|
||||
}
|
||||
|
||||
public boolean isPartyOwner()
|
||||
{
|
||||
return localPartyId.equals(partyId);
|
||||
}
|
||||
|
||||
public void setPartyMemberAvatar(UUID memberID, BufferedImage image)
|
||||
{
|
||||
final PartyMember memberById = getMemberById(memberID);
|
||||
@@ -255,4 +311,13 @@ public class PartyService
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
private static UUID passphraseToId(String passphrase)
|
||||
{
|
||||
return UUID.nameUUIDFromBytes(
|
||||
Hashing.sha256().hashBytes(
|
||||
passphrase.getBytes(StandardCharsets.UTF_8)
|
||||
).asBytes()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,10 @@ package net.runelite.client.plugins.specialcounter;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import com.google.inject.testing.fieldbinder.Bind;
|
||||
import com.google.inject.testing.fieldbinder.BoundFieldModule;
|
||||
import java.awt.image.BufferedImage;
|
||||
import net.runelite.api.Actor;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.EquipmentInventorySlot;
|
||||
@@ -44,13 +46,16 @@ import net.runelite.api.events.InteractingChanged;
|
||||
import net.runelite.api.events.VarbitChanged;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import net.runelite.client.util.AsyncBufferedImage;
|
||||
import net.runelite.client.ws.PartyService;
|
||||
import net.runelite.client.ws.WSClient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import org.mockito.Mock;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
@@ -66,6 +71,10 @@ public class SpecialCounterPluginTest
|
||||
@Bind
|
||||
private Client client;
|
||||
|
||||
@Bind
|
||||
@Named("developerMode")
|
||||
boolean developerMode;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private InfoBoxManager infoBoxManager;
|
||||
@@ -90,6 +99,14 @@ public class SpecialCounterPluginTest
|
||||
@Bind
|
||||
private SpecialCounterConfig specialCounterConfig;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Mock
|
||||
@Bind
|
||||
private PlayerInfoDropOverlay playerInfoDropOverlay;
|
||||
|
||||
@Inject
|
||||
private SpecialCounterPlugin specialCounterPlugin;
|
||||
|
||||
@@ -107,6 +124,8 @@ public class SpecialCounterPluginTest
|
||||
when(client.getVar(VarPlayer.SPECIAL_ATTACK_PERCENT)).thenReturn(100);
|
||||
specialCounterPlugin.onVarbitChanged(new VarbitChanged());
|
||||
|
||||
// Set up item image for spec info drop
|
||||
when(itemManager.getImage(anyInt())).thenReturn(new AsyncBufferedImage(24, 24, BufferedImage.TYPE_INT_ARGB));
|
||||
}
|
||||
|
||||
private static HitsplatApplied hitsplat(Actor target, Hitsplat.HitsplatType type)
|
||||
|
||||
Reference in New Issue
Block a user