@Subscribe
	public void onVarbitChanged(VarbitChanged event)
	{
		if (event.getVarbitId() == Varbits.IN_RAID)
		{
			removeVarTimer(OVERLOAD_RAID);
			removeGameTimer(PRAYER_ENHANCE);
		}

		if (event.getVarbitId() == Varbits.VENGEANCE_COOLDOWN && config.showVengeance())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(VENGEANCE);
			}
			else
			{
				removeGameTimer(VENGEANCE);
			}
		}

		if (event.getVarbitId() == Varbits.SPELLBOOK_SWAP && config.showSpellbookSwap())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(SPELLBOOK_SWAP);
			}
			else
			{
				removeGameTimer(SPELLBOOK_SWAP);
			}
		}

		if (event.getVarbitId() == Varbits.HEAL_GROUP_COOLDOWN && config.showHealGroup())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(HEAL_GROUP);
			}
			else
			{
				removeGameTimer(HEAL_GROUP);
			}
		}

		if (event.getVarbitId() == Varbits.DEATH_CHARGE_COOLDOWN && config.showArceuusCooldown())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(DEATH_CHARGE_COOLDOWN);
			}
			else
			{
				removeGameTimer(DEATH_CHARGE_COOLDOWN);
			}
		}

		if (event.getVarbitId() == Varbits.CORRUPTION_COOLDOWN && config.showArceuusCooldown())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(CORRUPTION_COOLDOWN);
			}
			else
			{
				removeGameTimer(CORRUPTION_COOLDOWN);
			}
		}

		if (event.getVarbitId() == Varbits.RESURRECT_THRALL_COOLDOWN && config.showArceuusCooldown())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(RESURRECT_THRALL_COOLDOWN);
			}
			else
			{
				removeGameTimer(RESURRECT_THRALL_COOLDOWN);
			}
		}

		if (event.getVarbitId() == Varbits.SHADOW_VEIL_COOLDOWN && config.showArceuusCooldown())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(SHADOW_VEIL_COOLDOWN);
			}
			else
			{
				removeGameTimer(SHADOW_VEIL_COOLDOWN);
			}
		}

		if (event.getVarbitId() == Varbits.WARD_OF_ARCEUUS_COOLDOWN && config.showArceuusCooldown())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(WARD_OF_ARCEUUS_COOLDOWN);
			}
			else
			{
				removeGameTimer(WARD_OF_ARCEUUS_COOLDOWN);
			}
		}

		if (event.getVarbitId() == Varbits.VENGEANCE_ACTIVE && config.showVengeanceActive())
		{
			updateVarCounter(VENGEANCE_ACTIVE, event.getValue());
		}

		if (event.getVarbitId() == Varbits.DEATH_CHARGE && config.showArceuus())
		{
			if (event.getValue() == 1)
			{
				createGameTimer(DEATH_CHARGE, Duration.of(client.getRealSkillLevel(Skill.MAGIC), RSTimeUnit.GAME_TICKS));
			}
			else
			{
				removeGameTimer(DEATH_CHARGE);
			}
		}

		if (event.getVarbitId() == Varbits.RESURRECT_THRALL && event.getValue() == 0 && config.showArceuus())
		{
			removeGameTimer(RESURRECT_THRALL);
		}

		if (event.getVarbitId() == Varbits.SHADOW_VEIL && event.getValue() == 0 && config.showArceuus())
		{
			removeGameTimer(SHADOW_VEIL);
		}

		if (event.getVarpId() == VarPlayer.POISON && config.showAntiPoison())
		{
			final int poisonVarp = event.getValue();
			final int tickCount = client.getTickCount();

			if (poisonVarp == 0)
			{
				nextPoisonTick = -1;
			}
			else if (nextPoisonTick - tickCount <= 0)
			{
				nextPoisonTick = tickCount + POISON_TICK_LENGTH;
			}

			updateVarTimer(ANTIPOISON, event.getValue(),
				i -> i >= 0 || i < VENOM_VALUE_CUTOFF,
				i -> nextPoisonTick - tickCount + Math.abs((i + 1) * POISON_TICK_LENGTH));
			updateVarTimer(ANTIVENOM, event.getValue(),
				i -> i >= VENOM_VALUE_CUTOFF,
				i -> nextPoisonTick - tickCount + Math.abs((i + 1 - VENOM_VALUE_CUTOFF) * POISON_TICK_LENGTH));
		}

		if ((event.getVarbitId() == Varbits.NMZ_OVERLOAD_REFRESHES_REMAINING
			|| event.getVarbitId() == Varbits.COX_OVERLOAD_REFRESHES_REMAINING) && config.showOverload())
		{
			final int overloadVarb = event.getValue();
			final int tickCount = client.getTickCount();

			if (overloadVarb <= 0)
			{
				nextOverloadRefreshTick = -1;
			}
			else if (nextOverloadRefreshTick - tickCount <= 0)
			{
				nextOverloadRefreshTick = tickCount + OVERLOAD_TICK_LENGTH;
			}

			GameTimer overloadTimer = client.getVarbitValue(Varbits.IN_RAID) == 1 ? OVERLOAD_RAID : OVERLOAD;
			updateVarTimer(overloadTimer, overloadVarb, i -> nextOverloadRefreshTick - tickCount + (i - 1) * OVERLOAD_TICK_LENGTH);
		}

		if (event.getVarbitId() == Varbits.TELEBLOCK && config.showTeleblock())
		{
			updateVarTimer(TELEBLOCK, event.getValue() - 100, i -> i <= 0, IntUnaryOperator.identity());
		}

		if (event.getVarpId() == VarPlayer.CHARGE_GOD_SPELL && config.showCharge())
		{
			updateVarTimer(CHARGE, event.getValue(), i -> i * 2);
		}

		if (event.getVarbitId() == Varbits.IMBUED_HEART_COOLDOWN && config.showImbuedHeart())
		{
			updateVarTimer(IMBUEDHEART, event.getValue(), i -> i * 10);
		}

		if (event.getVarbitId() == Varbits.DRAGONFIRE_SHIELD_COOLDOWN && config.showDFSSpecial())
		{
			updateVarTimer(DRAGON_FIRE_SHIELD, event.getValue(), i -> i * 8);
		}

		if (event.getVarpId() == LAST_HOME_TELEPORT && config.showHomeMinigameTeleports())
		{
			checkTeleport(LAST_HOME_TELEPORT);
		}

		if (event.getVarpId() == LAST_MINIGAME_TELEPORT && config.showHomeMinigameTeleports())
		{
			checkTeleport(LAST_MINIGAME_TELEPORT);
		}

		if (event.getVarbitId() == Varbits.RUN_SLOWED_DEPLETION_ACTIVE
			|| event.getVarbitId() == Varbits.STAMINA_EFFECT
			|| event.getVarbitId() == Varbits.RING_OF_ENDURANCE_EFFECT)
		{
			// staminaEffectActive is checked to match https://github.com/Joshua-F/cs2-scripts/blob/741271f0c3395048c1bad4af7881a13734516adf/scripts/%5Bproc%2Cbuff_bar_get_value%5D.cs2#L25
			int staminaEffectActive = client.getVarbitValue(Varbits.RUN_SLOWED_DEPLETION_ACTIVE);
			int staminaPotionEffectVarb = client.getVarbitValue(Varbits.STAMINA_EFFECT);
			int enduranceRingEffectVarb = client.getVarbitValue(Varbits.RING_OF_ENDURANCE_EFFECT);

			final int totalStaminaEffect = staminaPotionEffectVarb + enduranceRingEffectVarb;
			if (staminaEffectActive == 1 && config.showStamina())
			{
				updateVarTimer(STAMINA, totalStaminaEffect, i -> i * 10);
			}
		}

		if (event.getVarbitId() == Varbits.ANTIFIRE && config.showAntiFire())
		{
			final int antifireVarb = event.getValue();
			final int tickCount = client.getTickCount();

			if (antifireVarb == 0)
			{
				nextAntifireTick = -1;
			}
			else if (nextAntifireTick - tickCount <= 0)
			{
				nextAntifireTick = tickCount + ANTIFIRE_TICK_LENGTH;
			}

			updateVarTimer(ANTIFIRE, antifireVarb, i -> nextAntifireTick - tickCount + (i - 1) * ANTIFIRE_TICK_LENGTH);
		}

		if (event.getVarbitId() == Varbits.SUPER_ANTIFIRE && config.showAntiFire())
		{
			final int superAntifireVarb = event.getValue();
			final int tickCount = client.getTickCount();

			if (superAntifireVarb == 0)
			{
				nextSuperAntifireTick = -1;
			}
			else if (nextSuperAntifireTick - tickCount <= 0)
			{
				nextSuperAntifireTick = tickCount + SUPERANTIFIRE_TICK_LENGTH;
			}

			updateVarTimer(SUPERANTIFIRE, event.getValue(), i -> nextSuperAntifireTick - tickCount + (i - 1) * SUPERANTIFIRE_TICK_LENGTH);
		}

		if (event.getVarbitId() == Varbits.MAGIC_IMBUE && config.showMagicImbue())
		{
			updateVarTimer(MAGICIMBUE, event.getValue(), i -> i * 10);
		}

		if (event.getVarbitId() == Varbits.DIVINE_SUPER_ATTACK && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_COMBAT) > event.getValue())
			{
				return;
			}

			updateVarTimer(DIVINE_SUPER_ATTACK, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_SUPER_STRENGTH && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_COMBAT) > event.getValue())
			{
				return;
			}

			updateVarTimer(DIVINE_SUPER_STRENGTH, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_SUPER_DEFENCE && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_COMBAT) > event.getValue()
				|| client.getVarbitValue(Varbits.DIVINE_BASTION) > event.getValue()
				|| client.getVarbitValue(Varbits.DIVINE_BATTLEMAGE) > event.getValue()
				// When drinking a dose of moonlight potion while already under its effects, desync between
				// Varbits.MOONLIGHT_POTION and Varbits.DIVINE_SUPER_DEFENCE can occur, with the latter being 1 tick
				// greater
				|| client.getVarbitValue(Varbits.MOONLIGHT_POTION) >= event.getValue())
			{
				return;
			}

			if (client.getVarbitValue(Varbits.MOONLIGHT_POTION) < event.getValue())
			{
				removeVarTimer(MOONLIGHT_POTION);
			}

			updateVarTimer(DIVINE_SUPER_DEFENCE, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_RANGING && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_BASTION) > event.getValue())
			{
				return;
			}

			updateVarTimer(DIVINE_RANGING, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_MAGIC && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_BATTLEMAGE) > event.getValue())
			{
				return;
			}

			updateVarTimer(DIVINE_MAGIC, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_SUPER_COMBAT && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_ATTACK) == event.getValue())
			{
				removeVarTimer(DIVINE_SUPER_ATTACK);
			}
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_STRENGTH) == event.getValue())
			{
				removeVarTimer(DIVINE_SUPER_STRENGTH);
			}
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_DEFENCE) == event.getValue())
			{
				removeVarTimer(DIVINE_SUPER_DEFENCE);
			}

			updateVarTimer(DIVINE_SUPER_COMBAT, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_BASTION && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_RANGING) == event.getValue())
			{
				removeVarTimer(DIVINE_RANGING);
			}
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_DEFENCE) == event.getValue())
			{
				removeVarTimer(DIVINE_SUPER_DEFENCE);
			}

			updateVarTimer(DIVINE_BASTION, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.DIVINE_BATTLEMAGE && config.showDivine())
		{
			if (client.getVarbitValue(Varbits.DIVINE_MAGIC) == event.getValue())
			{
				removeVarTimer(DIVINE_MAGIC);
			}
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_DEFENCE) == event.getValue())
			{
				removeVarTimer(DIVINE_SUPER_DEFENCE);
			}

			updateVarTimer(DIVINE_BATTLEMAGE, event.getValue(), IntUnaryOperator.identity());
		}

		if (event.getVarbitId() == Varbits.BUFF_STAT_BOOST && config.showOverload())
		{
			updateVarTimer(SMELLING_SALTS, event.getValue(), i -> i * 25);
		}

		if (event.getVarbitId() == Varbits.MENAPHITE_REMEDY && config.showMenaphiteRemedy())
		{
			updateVarTimer(MENAPHITE_REMEDY, event.getValue(), i -> i * 25);
		}

		if (event.getVarbitId() == Varbits.LIQUID_ADERNALINE_ACTIVE && event.getValue() == 0 && config.showLiquidAdrenaline())
		{
			removeGameTimer(LIQUID_ADRENALINE);
		}

		if (event.getVarbitId() == Varbits.FARMERS_AFFINITY && config.showFarmersAffinity())
		{
			updateVarTimer(FARMERS_AFFINITY, event.getValue(), i -> i * 20);
		}

		if (event.getVarbitId() == Varbits.GOD_WARS_ALTAR_COOLDOWN && config.showGodWarsAltar())
		{
			updateVarTimer(GOD_WARS_ALTAR, event.getValue(), i -> i * 100);
		}

		if (event.getVarbitId() == Varbits.CURSE_OF_THE_MOONS && config.showCurseOfTheMoons())
		{
			final int regionID = WorldPoint.fromLocal(client, client.getLocalPlayer().getLocalLocation()).getRegionID();
			if (regionID == ECLIPSE_MOON_REGION_ID)
			{
				updateVarCounter(CURSE_OF_THE_MOONS_ECLIPSE, event.getValue());
			}
			else
			{
				updateVarCounter(CURSE_OF_THE_MOONS_BLUE, event.getValue());
			}
		}

		if (event.getVarbitId() == Varbits.COLOSSEUM_DOOM && config.showColosseumDoom())
		{
			updateVarCounter(COLOSSEUM_DOOM, event.getValue());
		}

		if (event.getVarbitId() == Varbits.MOONLIGHT_POTION && config.showMoonlightPotion())
		{
			int moonlightValue = event.getValue();
			// Increase the timer by 1 tick in case of desync due to drinking a dose of moonlight potion while already
			// under its effects. Otherwise, the timer would be 1 tick shorter than it is meant to be.
			if (client.getVarbitValue(Varbits.DIVINE_SUPER_DEFENCE) == moonlightValue + 1)
			{
				moonlightValue++;
			}

			updateVarTimer(MOONLIGHT_POTION, moonlightValue, IntUnaryOperator.identity());
		}
	}
@Test
	public void testArceuusWardCooldown()
	{
		when(timersAndBuffsConfig.showArceuusCooldown()).thenReturn(true);

		VarbitChanged varbitChanged = new VarbitChanged();
		varbitChanged.setVarbitId(Varbits.WARD_OF_ARCEUUS_COOLDOWN);
		varbitChanged.setValue(1);
		timersAndBuffsPlugin.onVarbitChanged(varbitChanged);

		ArgumentCaptor<InfoBox> captor = ArgumentCaptor.forClass(InfoBox.class);
		verify(infoBoxManager).addInfoBox(captor.capture());
		TimerTimer infoBox = (TimerTimer) captor.getValue();
		assertEquals(GameTimer.WARD_OF_ARCEUUS_COOLDOWN, infoBox.getTimer());
	}