Freezetimers: add immunity timer, fix freeze durations (#1064)

* freezetimers: add immunity timer, fix freeze durations

* freezetimers: refactoring

* freezetimers: fix tb removal

* freezetimers: make travis happy

* freezetimers: add immunity timer

* freezetimers: add immune images

* freezetimers: fix logic, add tb immunity
This commit is contained in:
Alexander
2019-07-22 09:40:58 +02:00
committed by Kyleeld
parent 4db6403e65
commit 5f9f554bce
9 changed files with 235 additions and 86 deletions

View File

@@ -26,8 +26,6 @@
package net.runelite.client.plugins.freezetimers;
import java.awt.Color;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
@@ -46,6 +44,9 @@ 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.ImageUtil;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
@Singleton
public class FreezeTimersOverlay extends Overlay
{
@@ -53,7 +54,9 @@ public class FreezeTimersOverlay extends Overlay
private final Client client;
private final Font timerFont = FontManager.getRunescapeBoldFont().deriveFont(14.0f);
private final BufferedImage FREEZE_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "freeze.png");
private final BufferedImage FREEZE_IMMUNE_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "freezeimmune.png");
private final BufferedImage TB_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "teleblock.png");
private final BufferedImage TB_IMMUNE_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "teleblockimmune.png");
private final BufferedImage VENG_IMAGE = ImageUtil.getResourceStreamFromClass(getClass(), "veng.png");
private final Timers timers;
@@ -108,89 +111,114 @@ public class FreezeTimersOverlay extends Overlay
private boolean drawFreezeOverlay(Graphics2D g, Actor actor, int overlaysDrawn)
{
long currentTick = System.currentTimeMillis();
if (timers.getTimerEnd(actor, TimerType.FREEZE) <= currentTick)
final long currentTick = System.currentTimeMillis();
if (timers.getTimerReApply(actor, TimerType.FREEZE) <= currentTick)
{
return false;
}
long finishedAt = timers.getTimerEnd(actor, TimerType.FREEZE);
String text = processTickCounter(finishedAt);
int test = Integer.parseInt(text);
Point poi = actor.getCanvasTextLocation(g, text, 0);
long finishedAt;
BufferedImage image;
if (timers.getTimerEnd(actor, TimerType.FREEZE) > currentTick)
{
finishedAt = timers.getTimerEnd(actor, TimerType.FREEZE);
image = FREEZE_IMAGE;
}
else
{
finishedAt = timers.getTimerReApply(actor, TimerType.FREEZE);
image = FREEZE_IMMUNE_IMAGE;
}
final String text = processTickCounter(finishedAt);
final Point poi = actor.getCanvasTextLocation(g, text, 0);
if (poi == null)
{
return false;
}
Point FixedPoint = new Point(poi.getX(), poi.getY());
final Point fixedPoint = new Point(poi.getX(), poi.getY());
if (plugin.isNoImage())
{
if (test > 3)
if (image == FREEZE_IMAGE)
{
OverlayUtil.renderTextLocation(g, text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.WHITE, FixedPoint, false, 0);
OverlayUtil.renderTextLocation(g, text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.WHITE, fixedPoint, false, 0);
}
else
{
OverlayUtil.renderTextLocation(g, text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.YELLOW, FixedPoint, false, 0);
OverlayUtil.renderTextLocation(g, text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.YELLOW, fixedPoint, false, 0);
}
}
else
{
renderActorText(g, actor, text, overlaysDrawn, FREEZE_IMAGE);
renderActorText(g, actor, text, overlaysDrawn, image);
}
return true;
}
private boolean drawTBOverlay(Graphics2D g, Actor actor, int overlaysDrawn)
{
long currentTick = System.currentTimeMillis();
final long currentTick = System.currentTimeMillis();
if (!plugin.isTB())
{
return false;
}
if (timers.getTimerEnd(actor, TimerType.TELEBLOCK) <= currentTick)
if (timers.getTimerReApply(actor, TimerType.TELEBLOCK) <= currentTick)
{
return false;
}
long finishedAt = timers.getTimerEnd(actor, TimerType.TELEBLOCK);
String text = processTickCounter(finishedAt);
Point poi = actor.getCanvasTextLocation(g, text, 0);
long finishedAt;
BufferedImage image;
if (timers.getTimerEnd(actor, TimerType.TELEBLOCK) > currentTick)
{
finishedAt = timers.getTimerEnd(actor, TimerType.TELEBLOCK);
image = TB_IMAGE;
}
else
{
finishedAt = timers.getTimerReApply(actor, TimerType.TELEBLOCK);
image = TB_IMMUNE_IMAGE;
}
final String text = processTickCounter(finishedAt);
final Point poi = actor.getCanvasTextLocation(g, text, 0);
if (poi == null)
{
return false;
}
Point FixedPoint = new Point(poi.getX() + 20, poi.getY());
final Point fixedPoint = new Point(poi.getX() + 20, poi.getY());
if (plugin.isNoImage())
{
if (timers.getTimerEnd(actor, TimerType.FREEZE) <= currentTick)
if (timers.getTimerReApply(actor, TimerType.FREEZE) <= currentTick)
{
OverlayUtil.renderTextLocation(g, text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.CYAN, poi, false, 0);
}
if (timers.getTimerEnd(actor, TimerType.FREEZE) >= currentTick)
else
{
OverlayUtil.renderTextLocation(g, " | " + text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.CYAN, FixedPoint, false, 0);
OverlayUtil.renderTextLocation(g, " | " + text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.CYAN, fixedPoint, false, 0);
}
if (timers.getTimerEnd(actor, TimerType.VENG) >= currentTick)
if (timers.getTimerReApply(actor, TimerType.VENG) >= currentTick)
{
OverlayUtil.renderTextLocation(g, " | " + text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.CYAN, FixedPoint, false, 0);
OverlayUtil.renderTextLocation(g, " | " + text, plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.CYAN, fixedPoint, false, 0);
}
}
else
{
renderActorText(g, actor, text, overlaysDrawn, TB_IMAGE);
renderActorText(g, actor, text, overlaysDrawn, image);
}
return true;
}
private boolean drawVengOverlay(Graphics2D g, Actor actor, int overlaysDrawn)
{
long currentTick = System.currentTimeMillis();
final long currentTick = System.currentTimeMillis();
if (!plugin.isVeng())
{
return false;
@@ -199,17 +227,17 @@ public class FreezeTimersOverlay extends Overlay
{
return false;
}
long finishedAt = timers.getTimerEnd(actor, TimerType.VENG);
final long finishedAt = timers.getTimerEnd(actor, TimerType.VENG);
String text = processTickCounter(finishedAt);
Point poi = actor.getCanvasTextLocation(g, text, 0);
final String text = processTickCounter(finishedAt);
final Point poi = actor.getCanvasTextLocation(g, text, 0);
if (poi == null)
{
return false;
}
Point FixedPoint = new Point(poi.getX() - 20, poi.getY());
final Point fixedPoint = new Point(poi.getX() - 20, poi.getY());
if (plugin.isNoImage())
{
if (timers.getTimerEnd(actor, TimerType.FREEZE) <= currentTick)
@@ -218,11 +246,11 @@ public class FreezeTimersOverlay extends Overlay
}
if (timers.getTimerEnd(actor, TimerType.FREEZE) >= currentTick)
{
OverlayUtil.renderTextLocation(g, text + " | ", plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.RED, FixedPoint, false, 0);
OverlayUtil.renderTextLocation(g, text + " | ", plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.RED, fixedPoint, false, 0);
}
if (timers.getTimerEnd(actor, TimerType.TELEBLOCK) >= currentTick)
{
OverlayUtil.renderTextLocation(g, text + " | ", plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.RED, FixedPoint, false, 0);
OverlayUtil.renderTextLocation(g, text + " | ", plugin.getTextSize(), plugin.getFontStyle().getFont(), Color.RED, fixedPoint, false, 0);
}
}
else
@@ -242,25 +270,25 @@ public class FreezeTimersOverlay extends Overlay
OverlayUtil.renderPolygon(g, poly, RED);
OverlayUtil.renderTextLocation(g, new Point((int) poly.getBounds2D().getCenterX(),
(int) poly.getBounds2D().getCenterY()), actor.getName(), RED);
(int) poly.getBounds2D().getCenterY()), actor.getName(), RED);
}
return true;
}
private void renderActorText(Graphics2D g, Actor actor, String text, int overlaysDrawn, BufferedImage image)
{
int yOffset = (overlaysDrawn * 18);
final int yOffset = (overlaysDrawn * 18);
g.setFont(timerFont);
g.setColor(WHITE);
int xOffset = plugin.getOffset();
final int xOffset = plugin.getOffset();
renderActorTextAndImage(g, actor, text, Color.WHITE, image, yOffset,
xOffset);
xOffset);
}
private void renderImageLocation(Graphics2D graphics, Point imgLoc, BufferedImage image)
{
int x = imgLoc.getX();
int y = imgLoc.getY();
final int x = imgLoc.getX();
final int y = imgLoc.getY();
graphics.drawImage(image, x, y, null);
}
@@ -272,16 +300,16 @@ public class FreezeTimersOverlay extends Overlay
xOffset = image.getWidth() + 1;
yOffset = (image.getHeight() - (int) graphics.getFontMetrics().getStringBounds(text, graphics).getHeight());
textLocation = new Point(textLocation.getX() + xOffset, textLocation.getY() + image.getHeight() - yOffset);
net.runelite.client.ui.overlay.OverlayUtil.renderTextLocation(graphics, textLocation, text, color);
OverlayUtil.renderTextLocation(graphics, textLocation, text, color);
}
private String processTickCounter(long finishedAt)
{
long currentTick = System.currentTimeMillis();
long tickDifference = finishedAt - currentTick;
final long currentTick = System.currentTimeMillis();
final long tickDifference = finishedAt - currentTick;
long seconds = tickDifference / 1000;
seconds++;
int minutes = (int) (seconds / 60);
final int minutes = (int) (seconds / 60);
seconds = seconds % 60;
String text = seconds > 9 ? seconds + "" : "0" + seconds;
if (minutes > 0)

View File

@@ -25,15 +25,23 @@
package net.runelite.client.plugins.freezetimers;
import com.google.inject.Provides;
import java.util.EnumSet;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AccessLevel;
import lombok.Getter;
import net.runelite.api.Actor;
import net.runelite.api.ChatMessageType;
import net.runelite.api.Client;
import net.runelite.api.NPC;
import net.runelite.api.Player;
import net.runelite.api.WorldType;
import net.runelite.api.coords.WorldPoint;
import net.runelite.api.events.ChatMessage;
import net.runelite.api.events.ConfigChanged;
import net.runelite.api.events.GameTick;
import net.runelite.api.events.LocalPlayerDeath;
import net.runelite.api.events.NpcDespawned;
import net.runelite.api.events.SpotAnimationChanged;
import net.runelite.client.config.ConfigManager;
@@ -41,7 +49,9 @@ import net.runelite.client.eventbus.EventBus;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.PluginType;
import net.runelite.client.plugins.multiindicators.MapLocations;
import net.runelite.client.ui.overlay.OverlayManager;
import net.runelite.client.util.PvPUtil;
import org.apache.commons.lang3.ArrayUtils;
@PluginDescriptor(
@@ -58,22 +68,16 @@ public class FreezeTimersPlugin extends Plugin
@Inject
private Client client;
@Inject
private OverlayManager overlayManager;
@Inject
private Timers timers;
@Inject
private PrayerTracker prayerTracker;
@Inject
private FreezeTimersOverlay overlay;
@Inject
private FreezeTimersConfig config;
@Inject
private EventBus eventBus;
@@ -121,39 +125,50 @@ public class FreezeTimersPlugin extends Plugin
eventBus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
eventBus.subscribe(SpotAnimationChanged.class, this, this::onSpotAnimationChanged);
eventBus.subscribe(GameTick.class, this, this::onGameTick);
eventBus.subscribe(LocalPlayerDeath.class, this, this::onLocalPlayerDeath);
eventBus.subscribe(NpcDespawned.class, this, this::onNpcDespawned);
eventBus.subscribe(ChatMessage.class, this, this::onChatMessage);
}
private void onSpotAnimationChanged(SpotAnimationChanged graphicChanged)
public void onSpotAnimationChanged(SpotAnimationChanged graphicChanged)
{
int oldGraphic = prayerTracker.getSpotanimLastTick(graphicChanged.getActor());
int newGraphic = graphicChanged.getActor().getSpotAnimation();
final int oldGraphic = prayerTracker.getSpotanimLastTick(graphicChanged.getActor());
final int newGraphic = graphicChanged.getActor().getSpotAnimation();
if (oldGraphic == newGraphic)
{
return;
}
PlayerSpellEffect effect = PlayerSpellEffect.getFromSpotAnim(newGraphic);
final PlayerSpellEffect effect = PlayerSpellEffect.getFromSpotAnim(newGraphic);
if (effect == PlayerSpellEffect.NONE)
{
return;
}
final long currentTime = System.currentTimeMillis();
if (timers.getTimerReApply(graphicChanged.getActor(), effect.getType()) > currentTime)
{
return;
}
long length = effect.getTimerLengthTicks();
if (effect.isHalvable() && prayerTracker.getPrayerIconLastTick(graphicChanged.getActor()) == 2)
{
length /= 2;
}
if (timers.getTimerEnd(graphicChanged.getActor(), effect.getType()) > System.currentTimeMillis())
{
return;
}
timers.setTimerEnd(graphicChanged.getActor(), effect.getType(),
System.currentTimeMillis() + length);
currentTime + length);
}
private void onGameTick(GameTick tickEvent)
public void onGameTick(GameTick tickEvent)
{
timers.gameTick();
prayerTracker.gameTick();
for (Actor actor : client.getPlayers())
{
if (prayerTracker.getSpotanimLastTick(actor) != actor.getSpotAnimation())
@@ -163,9 +178,52 @@ public class FreezeTimersPlugin extends Plugin
client.getCallbacks().post(SpotAnimationChanged.class, callback);
}
}
List<Actor> teleblocked = timers.getAllActorsOnTimer(TimerType.TELEBLOCK);
if (!teleblocked.isEmpty())
{
final EnumSet<WorldType> worldTypes = client.getWorldType();
for (Actor actor : teleblocked)
{
final WorldPoint actorLoc = actor.getWorldLocation();
if (!WorldType.isAllPvpWorld(worldTypes) && (actorLoc.getY() < 3525 || PvPUtil.getWildernessLevelFrom(actorLoc) <= 0))
{
timers.setTimerReApply(actor, TimerType.TELEBLOCK, System.currentTimeMillis());
}
else if (WorldType.isPvpWorld(worldTypes) &&
MapLocations.getPvpSafeZones(actorLoc.getPlane()).contains(actorLoc.getX(), actorLoc.getY()))
{
timers.setTimerReApply(actor, TimerType.TELEBLOCK, System.currentTimeMillis());
}
else if (WorldType.isDeadmanWorld(worldTypes) &&
MapLocations.getDeadmanSafeZones(actorLoc.getPlane()).contains(actorLoc.getX(), actorLoc.getY()))
{
timers.setTimerReApply(actor, TimerType.TELEBLOCK, System.currentTimeMillis());
}
}
}
}
private void onNpcDespawned(NpcDespawned event)
public void onLocalPlayerDeath(LocalPlayerDeath event)
{
final Player localPlayer = client.getLocalPlayer();
final long currentTime = System.currentTimeMillis();
for (TimerType type : TimerType.values())
{
if (timers.getTimerReApply(localPlayer, type) <= currentTime)
{
continue;
}
timers.setTimerReApply(localPlayer, type, currentTime);
}
}
public void onNpcDespawned(NpcDespawned event)
{
if (!isAtVorkath())
{
@@ -181,11 +239,22 @@ public class FreezeTimersPlugin extends Plugin
if (npc.getName().equals("Zombified Spawn"))
{
timers.setTimerEnd(client.getLocalPlayer(), TimerType.FREEZE,
timers.setTimerReApply(client.getLocalPlayer(), TimerType.FREEZE,
System.currentTimeMillis());
}
}
public void onChatMessage(ChatMessage event)
{
if (event.getType() != ChatMessageType.GAMEMESSAGE
|| !event.getMessage().contains("Your Tele Block has been removed"))
{
return;
}
timers.setTimerReApply(client.getLocalPlayer(), TimerType.TELEBLOCK, System.currentTimeMillis());
}
private boolean isAtVorkath()
{
return ArrayUtils.contains(client.getMapRegions(), VORKATH_REGION);

View File

@@ -31,13 +31,13 @@ import lombok.Getter;
@AllArgsConstructor
public enum PlayerSpellEffect
{
BIND("Bind", 181, 5000, true, 0, TimerType.FREEZE),
SNARE("Snare", 180, 10000, true, 1, TimerType.FREEZE),
ENTANGLE("Entangle", 179, 15000, true, 2, TimerType.FREEZE),
RUSH("Ice Rush", 361, 5000, false, 3, TimerType.FREEZE),
BURST("Ice Burst", 363, 10000, false, 4, TimerType.FREEZE),
BLITZ("Ice Blitz", 367, 15000, false, 5, TimerType.FREEZE),
BARRAGE("Ice Barrage", 369, 22200, false, 6, TimerType.FREEZE),
BIND("Bind", 181, 4800, true, 0, TimerType.FREEZE),
SNARE("Snare", 180, 9600, true, 1, TimerType.FREEZE),
ENTANGLE("Entangle", 179, 14400, true, 2, TimerType.FREEZE),
RUSH("Ice Rush", 361, 4800, false, 3, TimerType.FREEZE),
BURST("Ice Burst", 363, 9600, false, 4, TimerType.FREEZE),
BLITZ("Ice Blitz", 367, 14400, false, 5, TimerType.FREEZE),
BARRAGE("Ice Barrage", 369, 19200, false, 6, TimerType.FREEZE),
TELEBLOCK("Teleblock", 345, 300000, true, 7, TimerType.TELEBLOCK),
VENG("Vengeance", 726, 30000, false, 8, TimerType.VENG),
VENG_OTHER("Vengeance Other", 725, 30000, false, 9, TimerType.VENG),

View File

@@ -23,10 +23,21 @@
*/
package net.runelite.client.plugins.freezetimers;
import lombok.AccessLevel;
import lombok.Getter;
public enum TimerType
{
FREEZE,
VENG,
TELEBLOCK,
THIS_SHIT_BROKE
FREEZE(3000),
VENG(0),
TELEBLOCK(45000),
THIS_SHIT_BROKE(-1);
@Getter(AccessLevel.PACKAGE)
private final int immunityTime;
TimerType(int immunityTime)
{
this.immunityTime = immunityTime;
}
}

View File

@@ -23,7 +23,9 @@
*/
package net.runelite.client.plugins.freezetimers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@@ -31,43 +33,82 @@ import net.runelite.api.Actor;
@Slf4j
@Singleton
class Timers
public class Timers
{
private final Map<Actor, HashMap<TimerType, Long>> timerMap = new HashMap<>();
void gameTick()
{
}
void setTimerEnd(Actor actor, TimerType type, long n)
public void setTimerEnd(Actor actor, TimerType type, long n)
{
if (!timerMap.containsKey(actor))
{
timerMap.put(actor, new HashMap<>());
}
timerMap.get(actor).put(type, n + type.getImmunityTime());
}
public void setTimerReApply(Actor actor, TimerType type, long n)
{
if (!timerMap.containsKey(actor))
{
timerMap.put(actor, new HashMap<>());
}
timerMap.get(actor).put(type, n);
}
long getTimerEnd(Actor actor, TimerType type)
public long getTimerEnd(Actor actor, TimerType type)
{
if (!timerMap.containsKey(actor))
{
timerMap.put(actor, new HashMap<>());
return 0;
}
return timerMap.get(actor).getOrDefault(type, (long) type.getImmunityTime()) - type.getImmunityTime();
}
public long getTimerReApply(Actor actor, TimerType type)
{
if (!timerMap.containsKey(actor))
{
return 0;
}
return timerMap.get(actor).getOrDefault(type, (long) 0);
}
boolean areAllTimersZero(Actor actor)
public List<Actor> getAllActorsOnTimer(TimerType type)
{
List<Actor> actors = new ArrayList<Actor>();
for (Actor actor : timerMap.keySet())
{
if (areAllTimersZero(actor))
{
continue;
}
final long end = getTimerReApply(actor, type);
if (end > System.currentTimeMillis())
{
actors.add(actor);
}
}
return actors;
}
public boolean areAllTimersZero(Actor actor)
{
for (TimerType type : TimerType.values())
{
if (getTimerEnd(actor, type) != 0)
if (getTimerReApply(actor, type) > System.currentTimeMillis())
{
return false;
}
}
timerMap.remove(actor);
return true;
}
}

View File

@@ -33,7 +33,7 @@ import java.util.ArrayList;
import java.util.List;
import net.runelite.api.Constants;
class MapLocations
public class MapLocations
{
private static final List<Shape>[] MULTICOMBAT = new List[Constants.MAX_Z];
private static final List<Shape>[] NOT_MULTICOMBAT = new List[Constants.MAX_Z];

View File

@@ -36,7 +36,7 @@ public class PvPUtil
* @param point the point in the world to get the wilderness level for
* @return the int representing the wilderness level
*/
private static int getWildernessLevelFrom(WorldPoint point)
public static int getWildernessLevelFrom(WorldPoint point)
{
int y = point.getY();

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 B