Repository: runelite/runelite
Pull request #17133 (2023-10-22 20:16:48)

Add egniol potion to ItemWithCharge enum
Tested in both regular gauntlet and corrupted


Patch:
diff --git a/runelite-api/src/main/java/net/runelite/api/AnimationID.java b/runelite-api/src/main/java/net/runelite/api/AnimationID.java
index e6fbb2b0e..3ede90537 100644
--- a/runelite-api/src/main/java/net/runelite/api/AnimationID.java
+++ b/runelite-api/src/main/java/net/runelite/api/AnimationID.java
@@ -48,8 +48,19 @@ public final class AnimationID
 	public static final int WOODCUTTING_3A_AXE = 7264;
 	public static final int WOODCUTTING_CRYSTAL = 8324;
 	public static final int WOODCUTTING_TRAILBLAZER = 8778; // Same animation as Infernal axe (or)
+	public static final int WOODCUTTING_2H_BRONZE = 10064;
+	public static final int WOODCUTTING_2H_IRON = 10065;
+	public static final int WOODCUTTING_2H_STEEL = 10066;
+	public static final int WOODCUTTING_2H_BLACK = 10067;
+	public static final int WOODCUTTING_2H_MITHRIL = 10068;
+	public static final int WOODCUTTING_2H_ADAMANT = 10069;
+	public static final int WOODCUTTING_2H_RUNE = 10070;
+	public static final int WOODCUTTING_2H_DRAGON = 10071;
+	public static final int WOODCUTTING_2H_CRYSTAL = 10072;
+	public static final int WOODCUTTING_2H_3A = 10074;
 	public static final int CONSUMING = 829; // consuming consumables
 	public static final int FIREMAKING = 733;
+	public static final int FIREMAKING_FORESTERS_CAMPFIRE = 10572;
 	public static final int DEATH = 836;
 	public static final int COOKING_FIRE = 897;
 	public static final int COOKING_RANGE = 896;
diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java
index 5fcb1bfe6..5b4387375 100644
--- a/runelite-api/src/main/java/net/runelite/api/ItemID.java
+++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java
@@ -13267,7 +13267,7 @@ public final class ItemID
 	public static final int FORESTRY_LEGS = 28171;
 	public static final int FORESTRY_HAT = 28173;
 	public static final int FORESTRY_BOOTS = 28175;
-	public static final int AXE_HANDLE_28177 = 28177;
+	public static final int FELLING_AXE_HANDLE = 28177;
 	public static final int LEPRECHAUN_CHARM = 28179;
 	public static final int CLOVER_INSIGNIA = 28181;
 	public static final int MULCH = 28183;
@@ -13275,17 +13275,17 @@ public final class ItemID
 	public static final int POWDERED_POLLEN = 28190;
 	public static final int STRANGE_POLLEN = 28192;
 	public static final int UNFIRED_CUP = 28193;
-	public static final int BRONZE_2H_AXE = 28196;
-	public static final int IRON_2H_AXE = 28199;
-	public static final int STEEL_2H_AXE = 28202;
-	public static final int BLACK_2H_AXE = 28205;
-	public static final int MITHRIL_2H_AXE = 28208;
-	public static final int ADAMANT_2H_AXE = 28211;
-	public static final int RUNE_2H_AXE = 28214;
-	public static final int DRAGON_2H_AXE = 28217;
-	public static final int CRYSTAL_2H_AXE = 28220;
-	public static final int CRYSTAL_2H_AXE_28223 = 28223;
-	public static final int _3RD_AGE_2H_AXE = 28226;
+	public static final int BRONZE_FELLING_AXE = 28196;
+	public static final int IRON_FELLING_AXE = 28199;
+	public static final int STEEL_FELLING_AXE = 28202;
+	public static final int BLACK_FELLING_AXE = 28205;
+	public static final int MITHRIL_FELLING_AXE = 28208;
+	public static final int ADAMANT_FELLING_AXE = 28211;
+	public static final int RUNE_FELLING_AXE = 28214;
+	public static final int DRAGON_FELLING_AXE = 28217;
+	public static final int CRYSTAL_FELLING_AXE = 28220;
+	public static final int CRYSTAL_FELLING_AXE_INACTIVE = 28223;
+	public static final int _3RD_AGE_FELLING_AXE = 28226;
 	public static final int BEAVER_28229 = 28229;
 	public static final int BEAVER_28230 = 28230;
 	public static final int BEAVER_28231 = 28231;
@@ -13546,5 +13546,37 @@ public final class ItemID
 	public static final int TWISTED_EXTRACT = 28595;
 	public static final int MANGLED_EXTRACT = 28597;
 	public static final int SCARRED_EXTRACT = 28599;
+	public static final int COBWEB_CAPE = 28601;
+	public static final int SPIDER_HAT = 28603;
+	public static final int SPIDER_HAT_28605 = 28605;
+	public static final int SPIDER_HAT_28607 = 28607;
+	public static final int SPIDER_HAT_28609 = 28609;
+	public static final int SPIDER_HAT_28611 = 28611;
+	public static final int CAPE_POUCH = 28613;
+	public static final int PHEASANT_CAPE = 28616;
+	public static final int PHEASANT_BOOTS = 28618;
+	public static final int PHEASANT_HAT = 28620;
+	public static final int PHEASANT_LEGS = 28622;
+	public static final int PHEASANT_TAIL_FEATHERS = 28624;
+	public static final int FOX_WHISTLE = 28626;
+	public static final int SAWMILL_VOUCHER = 28628;
+	public static final int TWITCHERS_GLOVES = 28630;
+	public static final int SMOKER_FUEL = 28644;
+	public static final int SMOKER_CANISTER = 28646;
+	public static final int MULCH_28648 = 28648;
+	public static final int MULCH_28649 = 28649;
+	public static final int PACKED_MULCH = 28650;
+	public static final int CRYSTAL_CHARM = 28651;
+	public static final int PETAL_CIRCLET = 28653;
+	public static final int PETAL_GARLAND = 28655;
+	public static final int PADDED_SPOON = 28657;
+	public static final int EGG_CUSHION = 28659;
+	public static final int PHEASANT_EGG = 28661;
+	public static final int GOLDEN_PHEASANT_EGG = 28663;
+	public static final int TRAP_DISARMER = 28665;
+	public static final int TRAP_DISARMER_BLUEPRINT = 28667;
+	public static final int PHEASANT = 28669;
+	public static final int FOX_28670 = 28670;
+	public static final int WEB_CLOAK = 28671;
 	/* This file is automatically generated. Do not edit. */
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java
index e5f4e6232..59366e25e 100644
--- a/runelite-api/src/main/java/net/runelite/api/NpcID.java
+++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java
@@ -10492,5 +10492,43 @@ public final class NpcID
 	public static final int WARPED_TERRORBIRD_12503 = 12503;
 	public static final int WARPED_TERRORBIRD_12504 = 12504;
 	public static final int HAGUS = 12512;
+	public static final int SPIDEY_DOG = 12513;
+	public static final int BEE_KEEPER_12514 = 12514;
+	public static final int UNFINISHED_BEE_HIVE = 12515;
+	public static final int UNFINISHED_BEE_HIVE_12516 = 12516;
+	public static final int COMPLETE_BEE_HIVE = 12517;
+	public static final int WILD_BEE_HIVE = 12518;
+	public static final int DRYAD_12519 = 12519;
+	public static final int RITUAL_CIRCLE_GREEN = 12520;
+	public static final int RITUAL_CIRCLE_YELLOW = 12521;
+	public static final int RITUAL_CIRCLE_BLUE = 12522;
+	public static final int RITUAL_CIRCLE_RED = 12523;
+	public static final int RITUAL_CIRCLE_GREEN_12524 = 12524;
+	public static final int RITUAL_CIRCLE_YELLOW_12525 = 12525;
+	public static final int RITUAL_CIRCLE_BLUE_12526 = 12526;
+	public static final int RITUAL_CIRCLE_RED_12527 = 12527;
+	public static final int RITUAL_CIRCLE_GREEN_12528 = 12528;
+	public static final int RITUAL_CIRCLE_YELLOW_12529 = 12529;
+	public static final int RITUAL_CIRCLE_BLUE_12530 = 12530;
+	public static final int RITUAL_CIRCLE_RED_12531 = 12531;
+	public static final int RITUAL_CIRCLE_GREEN_12532 = 12532;
+	public static final int RITUAL_CIRCLE_YELLOW_12533 = 12533;
+	public static final int RITUAL_CIRCLE_BLUE_12534 = 12534;
+	public static final int RITUAL_CIRCLE_RED_12535 = 12535;
+	public static final int FREAKY_FORESTER_12536 = 12536;
+	public static final int PHEASANT_12537 = 12537;
+	public static final int POACHER = 12538;
+	public static final int POACHER_12539 = 12539;
+	public static final int POACHER_12540 = 12540;
+	public static final int FOX_TRAP = 12541;
+	public static final int FRIGHTENED_FOX = 12542;
+	public static final int ENTLING = 12543;
+	public static final int PRUNED_ENTLING = 12544;
+	public static final int FRIENDLY_ENT = 12545;
+	public static final int FRIENDLY_ENT_12546 = 12546;
+	public static final int PHEASANT_12547 = 12547;
+	public static final int FOX_12548 = 12548;
+	public static final int PHEASANT_12549 = 12549;
+	public static final int FOX_12550 = 12550;
 	/* This file is automatically generated. Do not edit. */
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java
index 9ded846f9..4ba68c844 100644
--- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java
+++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java
@@ -14844,5 +14844,44 @@ public final class NullItemID
 	public static final int NULL_28596 = 28596;
 	public static final int NULL_28598 = 28598;
 	public static final int NULL_28600 = 28600;
+	public static final int NULL_28602 = 28602;
+	public static final int NULL_28604 = 28604;
+	public static final int NULL_28606 = 28606;
+	public static final int NULL_28608 = 28608;
+	public static final int NULL_28610 = 28610;
+	public static final int NULL_28612 = 28612;
+	public static final int NULL_28614 = 28614;
+	public static final int NULL_28615 = 28615;
+	public static final int NULL_28617 = 28617;
+	public static final int NULL_28619 = 28619;
+	public static final int NULL_28621 = 28621;
+	public static final int NULL_28623 = 28623;
+	public static final int NULL_28625 = 28625;
+	public static final int NULL_28627 = 28627;
+	public static final int NULL_28629 = 28629;
+	public static final int NULL_28631 = 28631;
+	public static final int NULL_28632 = 28632;
+	public static final int NULL_28633 = 28633;
+	public static final int NULL_28634 = 28634;
+	public static final int NULL_28635 = 28635;
+	public static final int NULL_28636 = 28636;
+	public static final int NULL_28637 = 28637;
+	public static final int NULL_28638 = 28638;
+	public static final int NULL_28639 = 28639;
+	public static final int NULL_28640 = 28640;
+	public static final int NULL_28641 = 28641;
+	public static final int NULL_28642 = 28642;
+	public static final int NULL_28643 = 28643;
+	public static final int NULL_28645 = 28645;
+	public static final int NULL_28647 = 28647;
+	public static final int NULL_28652 = 28652;
+	public static final int NULL_28654 = 28654;
+	public static final int NULL_28656 = 28656;
+	public static final int NULL_28658 = 28658;
+	public static final int NULL_28660 = 28660;
+	public static final int NULL_28662 = 28662;
+	public static final int NULL_28664 = 28664;
+	public static final int NULL_28666 = 28666;
+	public static final int NULL_28668 = 28668;
 	/* This file is automatically generated. Do not edit. */
 }
diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java
index 488f75ba0..cd98141ac 100644
--- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java
+++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java
@@ -23419,7 +23419,6 @@ public final class ObjectID
 	public static final int FLOWERBED_47474 = 47474;
 	public static final int TABLE_47479 = 47479;
 	public static final int TABLE_47480 = 47480;
-	public static final int CLOVERS = 47481;
 	public static final int TREE_ROOTS = 47482;
 	public static final int ANIMAINFUSED_TREE_ROOTS = 47483;
 	public static final int STRUGGLING_SAPLING = 47484;
@@ -24497,5 +24496,16 @@ public final class ObjectID
 	public static final int PASSAGE_49922 = 49922;
 	public static final int STEPPING_STONE_49924 = 49924;
 	public static final int PASSAGE_49925 = 49925;
+	public static final int FORESTERS_CAMPFIRE = 49927;
+	public static final int FORESTERS_CAMPFIRE_49928 = 49928;
+	public static final int FORESTERS_CAMPFIRE_49929 = 49929;
+	public static final int FORESTERS_CAMPFIRE_49930 = 49930;
+	public static final int FORESTERS_CAMPFIRE_49931 = 49931;
+	public static final int FORESTERS_CAMPFIRE_49932 = 49932;
+	public static final int BEE_HIVE = 49933;
+	public static final int END_OF_RAINBOW = 49934;
+	public static final int CLOVERS = 49935;
+	public static final int PHEASANT_NEST = 49936;
+	public static final int PHEASANT_NEST_49937 = 49937;
 	/* This file is automatically generated. Do not edit. */
 }
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java
index 13db37fe9..dcc738872 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FaladorDiaryRequirement.java
@@ -82,7 +82,7 @@ public class FaladorDiaryRequirement extends GenericDiaryRequirement
 			new SkillRequirement(Skill.MAGIC, 37));
 
 		// HARD
-		add("Craft 140 Mind runes simultaneously from Essence.",
+		add("Craft 140 Mind runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 56));
 		add("Change your family crest to the Saradomin symbol.",
 			new SkillRequirement(Skill.PRAYER, 70));
@@ -104,7 +104,7 @@ public class FaladorDiaryRequirement extends GenericDiaryRequirement
 			new QuestRequirement(Quest.GRIM_TALES));
 
 		// ELITE
-		add("Craft 252 Air Runes simultaneously from Essence.",
+		add("Craft 252 Air Runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 88));
 		add("Purchase a White 2h Sword from Sir Vyvin.",
 			new QuestRequirement(Quest.WANTED));
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
index f618f5bba..64ac3feb0 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/FremennikDiaryRequirement.java
@@ -111,7 +111,7 @@ public class FremennikDiaryRequirement extends GenericDiaryRequirement
 			new QuestRequirement(Quest.THE_GIANT_DWARF, true));
 
 		// ELITE
-		add("Craft 56 astral runes at once from Essence.",
+		add("Craft 56 astral runes from Essence simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 82),
 			new QuestRequirement(Quest.LUNAR_DIPLOMACY));
 		add("Create a dragonstone amulet in the Neitiznot furnace.",
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java
index c0212f848..9c6bc1eea 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/KaramjaDiaryRequirement.java
@@ -121,7 +121,7 @@ public class KaramjaDiaryRequirement extends GenericDiaryRequirement
 			new QuestRequirement(Quest.SHILO_VILLAGE));
 
 		// ELITE
-		add("Craft 56 Nature runes at once from Essence.",
+		add("Craft 56 Nature runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 91));
 		add("Check the health of a palm tree in Brimhaven.",
 			new SkillRequirement(Skill.FARMING, 68));
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java
index af8e1513f..8a0c77ee6 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/LumbridgeDiaryRequirement.java
@@ -92,7 +92,7 @@ public class LumbridgeDiaryRequirement extends GenericDiaryRequirement
 		add("Squeeze past the jutting wall on your way to the cosmic altar.",
 			new SkillRequirement(Skill.AGILITY, 46),
 			new QuestRequirement(Quest.LOST_CITY));
-		add("Craft 56 Cosmic runes simultaneously from Essence.",
+		add("Craft 56 Cosmic runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 59),
 			new QuestRequirement(Quest.LOST_CITY));
 		add("Travel from Lumbridge to Edgeville on a Waka Canoe.",
@@ -126,7 +126,7 @@ public class LumbridgeDiaryRequirement extends GenericDiaryRequirement
 			new SkillRequirement(Skill.WOODCUTTING, 75));
 		add("Smith an Adamant platebody down Draynor sewer.",
 			new SkillRequirement(Skill.SMITHING, 88));
-		add("Craft 140 or more Water runes at once from Essence.",
+		add("Craft 140 or more Water runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 76));
 	}
 }
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java
index 9ff048dfd..565beb01d 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/achievementdiary/diaries/VarrockDiaryRequirement.java
@@ -112,7 +112,7 @@ public class VarrockDiaryRequirement extends GenericDiaryRequirement
 			new SkillRequirement(Skill.SMITHING, 89),
 			new SkillRequirement(Skill.FLETCHING, 81),
 			new QuestRequirement(Quest.THE_TOURIST_TRAP));
-		add("Craft 100 or more earth runes simultaneously from Essence.",
+		add("Craft 100 or more earth runes simultaneously from Essence without the use of Extracts.",
 			new SkillRequirement(Skill.RUNECRAFT, 78));
 	}
 }
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java
index 2ad8e6ee8..626964562 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java
@@ -251,7 +251,7 @@ public class ChatFilterPlugin extends Plugin
 	@Subscribe
 	public void onOverheadTextChanged(OverheadTextChanged event)
 	{
-		if (!(event.getActor() instanceof Player) || !shouldFilterPlayerMessage(event.getActor().getName()))
+		if (!(event.getActor() instanceof Player) || event.getActor().getName() == null || !shouldFilterPlayerMessage(event.getActor().getName())) // NOPMD: SimplifyConditional
 		{
 			return;
 		}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java
index 38b4d2583..54476e48d 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/CrypticClue.java
@@ -269,7 +269,7 @@ public class CrypticClue extends ClueScroll implements NpcClueScroll, ObjectClue
 		new CrypticClue("Thanks, Grandma!", "Tynan", new WorldPoint(1836, 3786, 0), "Tynan can be found in the north-east corner of Port Piscarilius."),
 		new CrypticClue("In a town where everyone has perfect vision, seek some locked drawers in a house that sits opposite a workshop.", "Chicken", DRAWERS_25766, new WorldPoint(2709, 3478, 0), "The Seers' Village house south of the Elemental Workshop entrance. Kill any Chicken to obtain a key."),
 		new CrypticClue("Search the crates in East Ardougne's general store.", CRATE_357, new WorldPoint(2615, 3291, 0), "Located south of the Ardougne church."),
-		new CrypticClue("Come brave adventurer, your sense is on fire. If you talk to me, it's an old god you desire.", "Viggora", -1, CrypticClue::getViggoraLocation, "Speak to Viggora while wearing a ring of visibility and a Ghostspeak amulet.", null),
+		new CrypticClue("Come brave adventurer, your sense is on fire. If you talk to me, it's an old god you desire.", "Viggora", -1, CrypticClue::getViggoraLocation, "Speak to Viggora while wearing a ring of visibility or ring of shadows, and a Ghostspeak amulet.", null),
 		new CrypticClue("2 musical birds. Dig in front of the spinning light.", new WorldPoint(2671, 10396, 0), "Dig in front of the spinning light in Ping and Pong's room inside the Iceberg"),
 		new CrypticClue("Search the wheelbarrow in Rimmington mine.", WHEELBARROW_9625, new WorldPoint(2978, 3239, 0), "The Rimmington mining site is located north of Rimmington."),
 		new CrypticClue("Belladonna, my dear. If only I had gloves, then I could hold you at last.", "Tool Leprechaun", new WorldPoint(3088, 3357, 0), "Talk to Tool Leprechaun at Draynor Manor."),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java
index 6f77c16e2..0967db86e 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/cluescrolls/clues/EmoteClue.java
@@ -109,7 +109,7 @@ public class EmoteClue extends ClueScroll implements LocationClueScroll
 		new EmoteClue("Beckon on the east coast of the Kharazi Jungle. Beware of double agents! Equip any vestment stole and a heraldic rune shield.", "Kharazi Jungle", NORTHEAST_CORNER_OF_THE_KHARAZI_JUNGLE, new WorldPoint(2954, 2933, 0), DOUBLE_AGENT_108, BECKON, any("Any stole", item(GUTHIX_STOLE), item(SARADOMIN_STOLE), item(ZAMORAK_STOLE), item(ARMADYL_STOLE), item(BANDOS_STOLE), item(ANCIENT_STOLE)), any("Any heraldic rune shield", item(RUNE_SHIELD_H1), item(RUNE_SHIELD_H2), item(RUNE_SHIELD_H3), item(RUNE_SHIELD_H4), item(RUNE_SHIELD_H5))),
 		new EmoteClue("Cheer in the Barbarian Agility Arena. Headbang before you talk to me. Equip a steel platebody, maple shortbow and a Wilderness cape.", "Barbarian Outpost", BARBARIAN_OUTPOST_OBSTACLE_COURSE, new WorldPoint(2552, 3556, 0), CHEER, HEADBANG, item(STEEL_PLATEBODY), item(MAPLE_SHORTBOW), range("Any team cape", TEAM1_CAPE, TEAM50_CAPE)),
 		new EmoteClue("Bow upstairs in the Edgeville Monastery. Equip a completed prayer book.", "Edgeville Monastery", SOUTHEAST_CORNER_OF_THE_MONASTERY, new WorldPoint(3056, 3484, 1), BOW, any("Any god book", item(HOLY_BOOK), item(BOOK_OF_BALANCE), item(UNHOLY_BOOK), item(BOOK_OF_LAW), item(BOOK_OF_WAR), item(BOOK_OF_DARKNESS), item(HOLY_BOOK_OR), item(BOOK_OF_BALANCE_OR), item(UNHOLY_BOOK_OR), item(BOOK_OF_LAW_OR), item(BOOK_OF_WAR_OR), item(BOOK_OF_DARKNESS_OR))),
-		new EmoteClue("Cheer in the Shadow dungeon. Equip a rune crossbow, climbing boots and any mitre.", "Shadow dungeon", ENTRANCE_OF_THE_CAVE_OF_DAMIS, new WorldPoint(2629, 5071, 0), CHEER, any("Any mitre", item(GUTHIX_MITRE), item(SARADOMIN_MITRE), item(ZAMORAK_MITRE), item(ANCIENT_MITRE), item(BANDOS_MITRE), item(ARMADYL_MITRE)), any("Rune crossbow", item(RUNE_CROSSBOW), item(RUNE_CROSSBOW_OR)), any("Climbing boots", item(CLIMBING_BOOTS), item(CLIMBING_BOOTS_G)), any("Ring of visibility", item(RING_OF_VISIBILITY), item(RING_OF_SHADOWS), item(RING_OF_SHADOWS_UNCHARGED))),
+		new EmoteClue("Cheer in the Shadow dungeon. Equip a rune crossbow, climbing boots and any mitre.", "Shadow dungeon", ENTRANCE_OF_THE_CAVE_OF_DAMIS, new WorldPoint(2629, 5071, 0), CHEER, any("Any mitre", item(GUTHIX_MITRE), item(SARADOMIN_MITRE), item(ZAMORAK_MITRE), item(ANCIENT_MITRE), item(BANDOS_MITRE), item(ARMADYL_MITRE)), any("Rune crossbow", item(RUNE_CROSSBOW), item(RUNE_CROSSBOW_OR)), any("Climbing boots", item(CLIMBING_BOOTS), item(CLIMBING_BOOTS_G)), any("Ring of visibility or ring of shadows", item(RING_OF_VISIBILITY), item(RING_OF_SHADOWS), item(RING_OF_SHADOWS_UNCHARGED))),
 		new EmoteClue("Cheer at the top of the agility pyramid. Beware of double agents! Equip a blue mystic robe top, and any rune heraldic shield.", "Agility Pyramid", AGILITY_PYRAMID, new WorldPoint(3043, 4697, 3), DOUBLE_AGENT_108, CHEER, item(MYSTIC_ROBE_TOP), any("Any rune heraldic shield", item(RUNE_SHIELD_H1), item(RUNE_SHIELD_H2), item(RUNE_SHIELD_H3), item(RUNE_SHIELD_H4), item(RUNE_SHIELD_H5))),
 		new EmoteClue("Dance in Iban's temple. Beware of double agents! Equip Iban's staff, a black mystic top and a black mystic bottom.", "Iban's temple", WELL_OF_VOYAGE, new WorldPoint(2011, 4712, 0), DOUBLE_AGENT_141, DANCE, any("Any iban's staff", item(IBANS_STAFF), item(IBANS_STAFF_U)), item(MYSTIC_ROBE_TOP_DARK), item(MYSTIC_ROBE_BOTTOM_DARK)),
 		new EmoteClue("Dance on the Fishing Platform. Equip barrows gloves, an amulet of glory and a dragon med helm.", "Fishing Platform", SOUTHEAST_CORNER_OF_THE_FISHING_PLATFORM, new WorldPoint(2782, 3273, 0), DANCE, any("Any amulet of glory", item(AMULET_OF_GLORY), item(AMULET_OF_GLORY1), item(AMULET_OF_GLORY2), item(AMULET_OF_GLORY3), item(AMULET_OF_GLORY4), item(AMULET_OF_GLORY5), item(AMULET_OF_GLORY6)), item(BARROWS_GLOVES), item(DRAGON_MED_HELM)),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java
index 36fcc0dad..94b461055 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/hiscore/HiscorePanel.java
@@ -119,7 +119,7 @@ public class HiscorePanel extends PluginPanel
 
 	private static final HiscoreEndpoint[] ENDPOINTS = {
 		HiscoreEndpoint.NORMAL, HiscoreEndpoint.IRONMAN, HiscoreEndpoint.HARDCORE_IRONMAN, HiscoreEndpoint.ULTIMATE_IRONMAN,
-		HiscoreEndpoint.DEADMAN, HiscoreEndpoint.PURE, HiscoreEndpoint.LEVEL_3_SKILLER, HiscoreEndpoint.TOURNAMENT
+		HiscoreEndpoint.DEADMAN, HiscoreEndpoint.PURE, HiscoreEndpoint.LEVEL_3_SKILLER, HiscoreEndpoint.LEAGUE
 	};
 
 	private final HiscorePlugin plugin;
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
index 36da18f29..a1162aba3 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/idlenotifier/IdleNotifierPlugin.java
@@ -150,7 +150,19 @@ public class IdleNotifierPlugin extends Plugin
 			case WOODCUTTING_3A_AXE:
 			case WOODCUTTING_CRYSTAL:
 			case WOODCUTTING_TRAILBLAZER:
+			case WOODCUTTING_2H_BRONZE:
+			case WOODCUTTING_2H_IRON:
+			case WOODCUTTING_2H_STEEL:
+			case WOODCUTTING_2H_BLACK:
+			case WOODCUTTING_2H_MITHRIL:
+			case WOODCUTTING_2H_ADAMANT:
+			case WOODCUTTING_2H_RUNE:
+			case WOODCUTTING_2H_DRAGON:
+			case WOODCUTTING_2H_CRYSTAL:
+			case WOODCUTTING_2H_3A:
 			case BLISTERWOOD_JUMP_SCARE:
+			/* Firemaking */
+			case FIREMAKING_FORESTERS_CAMPFIRE:
 			/* Cooking(Fire, Range) */
 			case COOKING_FIRE:
 			case COOKING_RANGE:
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java
index b5d534e65..ed815bb78 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/itemcharges/ItemWithCharge.java
@@ -183,6 +183,10 @@ enum ItemWithCharge
 	DIVINE_SUPER_STRENGTH2(POTION, DIVINE_SUPER_STRENGTH_POTION2, 2),
 	DIVINE_SUPER_STRENGTH3(POTION, DIVINE_SUPER_STRENGTH_POTION3, 3),
 	DIVINE_SUPER_STRENGTH4(POTION, DIVINE_SUPER_STRENGTH_POTION4, 4),
+	EGNIOL1(POTION, EGNIOL_POTION_1, 1),
+	EGNIOL2(POTION, EGNIOL_POTION_2, 2),
+	EGNIOL3(POTION, EGNIOL_POTION_3, 3),
+	EGNIOL4(POTION, EGNIOL_POTION_4, 4),
 	ELYRE1(TELEPORT, ENCHANTED_LYRE1, 1),
 	ELYRE2(TELEPORT, ENCHANTED_LYRE2, 2),
 	ELYRE3(TELEPORT, ENCHANTED_LYRE3, 3),
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java
index 9484baefe..31caeb9e4 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/wintertodt/WintertodtPlugin.java
@@ -39,6 +39,16 @@ import static net.runelite.api.AnimationID.FIREMAKING;
 import static net.runelite.api.AnimationID.FLETCHING_BOW_CUTTING;
 import static net.runelite.api.AnimationID.IDLE;
 import static net.runelite.api.AnimationID.LOOKING_INTO;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_3A;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_ADAMANT;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_BLACK;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_BRONZE;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_CRYSTAL;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_DRAGON;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_IRON;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_MITHRIL;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_RUNE;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_STEEL;
 import static net.runelite.api.AnimationID.WOODCUTTING_3A_AXE;
 import static net.runelite.api.AnimationID.WOODCUTTING_ADAMANT;
 import static net.runelite.api.AnimationID.WOODCUTTING_BLACK;
@@ -425,6 +435,16 @@ public class WintertodtPlugin extends Plugin
 			case WOODCUTTING_3A_AXE:
 			case WOODCUTTING_CRYSTAL:
 			case WOODCUTTING_TRAILBLAZER:
+			case WOODCUTTING_2H_BRONZE:
+			case WOODCUTTING_2H_IRON:
+			case WOODCUTTING_2H_STEEL:
+			case WOODCUTTING_2H_BLACK:
+			case WOODCUTTING_2H_MITHRIL:
+			case WOODCUTTING_2H_ADAMANT:
+			case WOODCUTTING_2H_RUNE:
+			case WOODCUTTING_2H_DRAGON:
+			case WOODCUTTING_2H_CRYSTAL:
+			case WOODCUTTING_2H_3A:
 				setActivity(WintertodtActivity.WOODCUTTING);
 				break;
 
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java
deleted file mode 100644
index 5f4816963..000000000
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/Axe.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2018, Mantautas Jurksa <https://github.com/Juzzed>
- * 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.woodcutting;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import static net.runelite.api.AnimationID.WOODCUTTING_3A_AXE;
-import static net.runelite.api.AnimationID.WOODCUTTING_ADAMANT;
-import static net.runelite.api.AnimationID.WOODCUTTING_BLACK;
-import static net.runelite.api.AnimationID.WOODCUTTING_BRONZE;
-import static net.runelite.api.AnimationID.WOODCUTTING_CRYSTAL;
-import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON;
-import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON_OR;
-import static net.runelite.api.AnimationID.WOODCUTTING_GILDED;
-import static net.runelite.api.AnimationID.WOODCUTTING_INFERNAL;
-import static net.runelite.api.AnimationID.WOODCUTTING_IRON;
-import static net.runelite.api.AnimationID.WOODCUTTING_MITHRIL;
-import static net.runelite.api.AnimationID.WOODCUTTING_RUNE;
-import static net.runelite.api.AnimationID.WOODCUTTING_STEEL;
-import static net.runelite.api.AnimationID.WOODCUTTING_TRAILBLAZER;
-import static net.runelite.api.ItemID.ADAMANT_AXE;
-import static net.runelite.api.ItemID.BLACK_AXE;
-import static net.runelite.api.ItemID.BRONZE_AXE;
-import static net.runelite.api.ItemID.CRYSTAL_AXE;
-import static net.runelite.api.ItemID.DRAGON_AXE;
-import static net.runelite.api.ItemID.DRAGON_AXE_OR;
-import static net.runelite.api.ItemID.GILDED_AXE;
-import static net.runelite.api.ItemID.INFERNAL_AXE;
-import static net.runelite.api.ItemID.IRON_AXE;
-import static net.runelite.api.ItemID.MITHRIL_AXE;
-import static net.runelite.api.ItemID.RUNE_AXE;
-import static net.runelite.api.ItemID.STEEL_AXE;
-import static net.runelite.api.ItemID.INFERNAL_AXE_OR;
-import static net.runelite.api.ItemID._3RD_AGE_AXE;
-import net.runelite.api.Player;
-
-@AllArgsConstructor
-@Getter
-enum Axe
-{
-	BRONZE(WOODCUTTING_BRONZE, BRONZE_AXE),
-	IRON(WOODCUTTING_IRON, IRON_AXE),
-	STEEL(WOODCUTTING_STEEL, STEEL_AXE),
-	BLACK(WOODCUTTING_BLACK, BLACK_AXE),
-	MITHRIL(WOODCUTTING_MITHRIL, MITHRIL_AXE),
-	ADAMANT(WOODCUTTING_ADAMANT, ADAMANT_AXE),
-	RUNE(WOODCUTTING_RUNE, RUNE_AXE),
-	GILDED(WOODCUTTING_GILDED, GILDED_AXE),
-	DRAGON(WOODCUTTING_DRAGON, DRAGON_AXE),
-	DRAGON_OR(WOODCUTTING_DRAGON_OR, DRAGON_AXE_OR),
-	INFERNAL(WOODCUTTING_INFERNAL, INFERNAL_AXE),
-	THIRDAGE(WOODCUTTING_3A_AXE, _3RD_AGE_AXE),
-	CRYSTAL(WOODCUTTING_CRYSTAL, CRYSTAL_AXE),
-	TRAILBLAZER(WOODCUTTING_TRAILBLAZER, INFERNAL_AXE_OR);
-
-	private final Integer animId;
-	private final Integer itemId;
-
-	private static final Map<Integer, Axe> AXE_ANIM_IDS;
-
-	static
-	{
-		ImmutableMap.Builder<Integer, Axe> builder = new ImmutableMap.Builder<>();
-
-		for (Axe axe : values())
-		{
-			builder.put(axe.animId, axe);
-		}
-
-		AXE_ANIM_IDS = builder.build();
-	}
-
-	boolean matchesChoppingAnimation(final Player player)
-	{
-		return player != null && animId == player.getAnimation();
-	}
-
-	static Axe findAxeByAnimId(int animId)
-	{
-		return AXE_ANIM_IDS.get(animId);
-	}
-}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java
index da9af3b34..d668b8ab9 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingConfig.java
@@ -156,6 +156,66 @@ public interface WoodcuttingConfig extends Config
 		return true;
 	}
 
+	@ConfigItem(
+		position = 14,
+		keyName = "forestryPoachersNotification",
+		name = "Poachers notification",
+		description = "Configures whether to notify you of a Poachers event",
+		section = forestrySection
+	)
+	default boolean forestryPoachersNotification()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 15,
+		keyName = "forestryPheasantControlNotification",
+		name = "Pheasant Control notification",
+		description = "Configures whether to notify you of a Pheasant Control event",
+		section = forestrySection
+	)
+	default boolean forestryPheasantControlNotification()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 16,
+		keyName = "forestryBeeHiveNotification",
+		name = "Bee Hive notification",
+		description = "Configures whether to notify you of a Bee Hive event",
+		section = forestrySection
+	)
+	default boolean forestryBeeHiveNotification()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 17,
+		keyName = "forestryEnchantmentRitualNotification",
+		name = "Enchantment Ritual notification",
+		description = "Configures whether to notify you of an Enchantment Ritual event",
+		section = forestrySection
+	)
+	default boolean forestryEnchantmentRitualNotification()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 18,
+		keyName = "forestryFriendlyEntNotification",
+		name = "Friendly Ent notification",
+		description = "Configures whether to notify you of a Friendly Ent event",
+		section = forestrySection
+	)
+	default boolean forestryFriendlyEntNotification()
+	{
+		return true;
+	}
+
 	@ConfigItem(
 		position = 20,
 		keyName = "highlightGlowingRoots",
@@ -191,4 +251,52 @@ public interface WoodcuttingConfig extends Config
 	{
 		return true;
 	}
+
+	@ConfigItem(
+		position = 23,
+		keyName = "highlightFoxTrap",
+		name = "Highlight fox trap",
+		description = "Highlights the fox trap during Poachers events",
+		section = forestrySection
+	)
+	default boolean highlightFoxTrap()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 24,
+		keyName = "highlightPheasantNest",
+		name = "Highlight pheasant nest",
+		description = "Highlights the pheasant next during Pheasant Control events",
+		section = forestrySection
+	)
+	default boolean highlightPheasantNest()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 25,
+		keyName = "highlightBeeHive",
+		name = "Highlight bee hive",
+		description = "Highlights the bee hive during Bee Hive events",
+		section = forestrySection
+	)
+	default boolean highlightBeeHive()
+	{
+		return true;
+	}
+
+	@ConfigItem(
+		position = 26,
+		keyName = "highlightRitualCircle",
+		name = "Highlight ritual circle",
+		description = "Highlights the Ritual Circle during Enchantment Ritual events",
+		section = forestrySection
+	)
+	default boolean highlightRitualCircle()
+	{
+		return true;
+	}
 }
\ No newline at end of file
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java
index 53d718caf..75c97a4f0 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingOverlay.java
@@ -66,8 +66,7 @@ class WoodcuttingOverlay extends OverlayPanel
 			return null;
 		}
 
-		Axe axe = plugin.getAxe();
-		if (axe != null && axe.matchesChoppingAnimation(client.getLocalPlayer()))
+		if (WoodcuttingPlugin.WOODCUTTING_ANIMS.contains(client.getLocalPlayer().getAnimation()))
 		{
 			panelComponent.getChildren().add(TitleComponent.builder()
 				.text("Woodcutting")
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java
index 0e4bc3504..69c716173 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingPlugin.java
@@ -24,6 +24,7 @@
  */
 package net.runelite.client.plugins.woodcutting;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.inject.Provides;
 import java.time.Duration;
 import java.time.Instant;
@@ -40,6 +41,30 @@ import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 import net.runelite.api.AnimationID;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_3A;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_ADAMANT;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_BLACK;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_BRONZE;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_CRYSTAL;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_DRAGON;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_IRON;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_MITHRIL;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_RUNE;
+import static net.runelite.api.AnimationID.WOODCUTTING_2H_STEEL;
+import static net.runelite.api.AnimationID.WOODCUTTING_3A_AXE;
+import static net.runelite.api.AnimationID.WOODCUTTING_ADAMANT;
+import static net.runelite.api.AnimationID.WOODCUTTING_BLACK;
+import static net.runelite.api.AnimationID.WOODCUTTING_BRONZE;
+import static net.runelite.api.AnimationID.WOODCUTTING_CRYSTAL;
+import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON;
+import static net.runelite.api.AnimationID.WOODCUTTING_DRAGON_OR;
+import static net.runelite.api.AnimationID.WOODCUTTING_GILDED;
+import static net.runelite.api.AnimationID.WOODCUTTING_INFERNAL;
+import static net.runelite.api.AnimationID.WOODCUTTING_IRON;
+import static net.runelite.api.AnimationID.WOODCUTTING_MITHRIL;
+import static net.runelite.api.AnimationID.WOODCUTTING_RUNE;
+import static net.runelite.api.AnimationID.WOODCUTTING_STEEL;
+import static net.runelite.api.AnimationID.WOODCUTTING_TRAILBLAZER;
 import net.runelite.api.ChatMessageType;
 import net.runelite.api.Client;
 import net.runelite.api.GameObject;
@@ -75,6 +100,15 @@ import net.runelite.client.ui.overlay.OverlayManager;
 @Slf4j
 public class WoodcuttingPlugin extends Plugin
 {
+	static final Set<Integer> WOODCUTTING_ANIMS = ImmutableSet.of(
+		WOODCUTTING_BRONZE, WOODCUTTING_IRON, WOODCUTTING_STEEL, WOODCUTTING_BLACK, WOODCUTTING_MITHRIL,
+		WOODCUTTING_ADAMANT, WOODCUTTING_RUNE, WOODCUTTING_GILDED, WOODCUTTING_DRAGON, WOODCUTTING_DRAGON_OR,
+		WOODCUTTING_INFERNAL, WOODCUTTING_3A_AXE, WOODCUTTING_CRYSTAL, WOODCUTTING_TRAILBLAZER,
+		WOODCUTTING_2H_BRONZE, WOODCUTTING_2H_IRON, WOODCUTTING_2H_STEEL, WOODCUTTING_2H_BLACK,
+		WOODCUTTING_2H_MITHRIL, WOODCUTTING_2H_ADAMANT, WOODCUTTING_2H_RUNE, WOODCUTTING_2H_DRAGON,
+		WOODCUTTING_2H_CRYSTAL, WOODCUTTING_2H_3A
+	);
+
 	private static final Pattern WOOD_CUT_PATTERN = Pattern.compile("You get (?:some|an)[\\w ]+(?:logs?|mushrooms)\\.");
 	private static final Pattern ANIMA_BARK_PATTERN = Pattern.compile("You've been awarded <col=[0-9a-f]+>(\\d+) Anima-infused bark</col>\\.");
 
@@ -91,7 +125,7 @@ public class WoodcuttingPlugin extends Plugin
 	private WoodcuttingOverlay overlay;
 
 	@Inject
-	private WoodcuttingTreesOverlay treesOverlay;
+	private WoodcuttingSceneOverlay treesOverlay;
 
 	@Inject
 	private WoodcuttingConfig config;
@@ -101,10 +135,6 @@ public class WoodcuttingPlugin extends Plugin
 	@Setter(AccessLevel.PACKAGE)
 	private WoodcuttingSession session;
 
-	@Getter
-	@Nullable
-	private Axe axe;
-
 	@Getter
 	private final Set<GameObject> treeObjects = new HashSet<>();
 
@@ -120,6 +150,16 @@ public class WoodcuttingPlugin extends Plugin
 	private final List<GameObject> saplingIngredients = new ArrayList<>(5);
 	@Getter(AccessLevel.PACKAGE)
 	private final GameObject[] saplingOrder = new GameObject[3];
+	@Getter(AccessLevel.PACKAGE)
+	private NPC foxTrap;
+	@Getter(AccessLevel.PACKAGE)
+	private final List<GameObject> pheasantNests = new ArrayList<>(4);
+	@Getter(AccessLevel.PACKAGE)
+	private NPC freakyForester;
+	@Getter(AccessLevel.PACKAGE)
+	private NPC unfinishedBeeHive;
+	private final List<NPC> circles = new ArrayList<>(5);
+	private final List<NPC> entlings = new ArrayList<>(0);
 
 	@Getter(AccessLevel.PACKAGE)
 	private final List<TreeRespawn> respawns = new ArrayList<>();
@@ -152,7 +192,6 @@ public class WoodcuttingPlugin extends Plugin
 		saplingIngredients.clear();
 		Arrays.fill(saplingOrder, null);
 		session = null;
-		axe = null;
 		clueTierSpawned = null;
 	}
 
@@ -170,7 +209,7 @@ public class WoodcuttingPlugin extends Plugin
 			return;
 		}
 
-		if (axe != null && axe.matchesChoppingAnimation(client.getLocalPlayer()))
+		if (WOODCUTTING_ANIMS.contains(client.getLocalPlayer().getAnimation()))
 		{
 			session.setLastChopping();
 			return;
@@ -182,7 +221,6 @@ public class WoodcuttingPlugin extends Plugin
 		if (sinceCut.compareTo(statTimeout) >= 0)
 		{
 			session.setActive(false);
-			axe = null;
 		}
 	}
 
@@ -319,6 +357,10 @@ public class WoodcuttingPlugin extends Plugin
 			case ObjectID.SPLINTERED_BARK:
 				saplingIngredients.add(gameObject);
 				break;
+			case ObjectID.PHEASANT_NEST:
+			case ObjectID.PHEASANT_NEST_49937:
+				pheasantNests.add(gameObject);
+				break;
 		}
 	}
 
@@ -367,6 +409,14 @@ public class WoodcuttingPlugin extends Plugin
 					log.debug("Struggling Sapling event is over");
 				}
 				break;
+			case ObjectID.PHEASANT_NEST:
+			case ObjectID.PHEASANT_NEST_49937:
+				pheasantNests.remove(object);
+				if (pheasantNests.isEmpty())
+				{
+					log.debug("Pheasant event is over");
+				}
+				break;
 		}
 	}
 
@@ -375,8 +425,17 @@ public class WoodcuttingPlugin extends Plugin
 	{
 		switch (event.getGameState())
 		{
+			case LOGIN_SCREEN:
 			case HOPPING:
 				respawns.clear();
+				flowers.clear();
+				activeFlowers.clear();
+				foxTrap = null;
+				freakyForester = null;
+				unfinishedBeeHive = null;
+				circles.clear();
+				entlings.clear();
+				// fallthrough
 			case LOADING:
 				treeObjects.clear();
 				roots.clear();
@@ -396,16 +455,6 @@ public class WoodcuttingPlugin extends Plugin
 	public void onAnimationChanged(final AnimationChanged event)
 	{
 		var actor = event.getActor();
-		if (client.getLocalPlayer() == actor)
-		{
-			int animId = actor.getAnimation();
-			Axe axe = Axe.findAxeByAnimId(animId);
-			if (axe != null)
-			{
-				this.axe = axe;
-			}
-		}
-
 		if (actor.getAnimation() == AnimationID.LOOKING_INTO && flowers.contains(actor.getInteracting()))
 		{
 			var flower = (NPC) actor.getInteracting();
@@ -427,7 +476,8 @@ public class WoodcuttingPlugin extends Plugin
 	public void onNpcSpawned(NpcSpawned event)
 	{
 		NPC npc = event.getNpc();
-		if (isFloweringBush(npc.getId()))
+		var id = npc.getId();
+		if (isFloweringBush(id))
 		{
 			if (flowers.isEmpty() && config.forestryFloweringTreeNotification())
 			{
@@ -436,10 +486,57 @@ public class WoodcuttingPlugin extends Plugin
 
 			flowers.add(npc);
 		}
-		else if (npc.getId() == NpcID.WOODCUTTING_LEPRECHAUN && config.forestryLeprechaunNotification())
+		else if (id == NpcID.WOODCUTTING_LEPRECHAUN && config.forestryLeprechaunNotification())
 		{
 			notifier.notify("A Leprechaun event spawned!");
 		}
+		else if (id == NpcID.FRIGHTENED_FOX && config.forestryPoachersNotification())
+		{
+			notifier.notify("A Poachers event spawned!");
+		}
+		else if (id == NpcID.FOX_TRAP)
+		{
+			foxTrap = npc;
+		}
+		else if (id == NpcID.FREAKY_FORESTER_12536)
+		{
+			freakyForester = npc;
+
+			if (config.forestryPheasantControlNotification())
+			{
+				notifier.notify("A Pheasant Control event has spawned!");
+			}
+		}
+		else if (id == NpcID.WILD_BEE_HIVE)
+		{
+			if (config.forestryBeeHiveNotification())
+			{
+				notifier.notify("A Bee Hive event has spawned!");
+			}
+		}
+		else if (id == NpcID.UNFINISHED_BEE_HIVE || id == NpcID.UNFINISHED_BEE_HIVE_12516)
+		{
+			unfinishedBeeHive = npc;
+		}
+		else if (id >= NpcID.RITUAL_CIRCLE_GREEN && id <= NpcID.RITUAL_CIRCLE_RED_12535)
+		{
+			circles.add(npc);
+		}
+		else if (id == NpcID.DRYAD_12519)
+		{
+			if (config.forestryEnchantmentRitualNotification())
+			{
+				notifier.notify("An Enchantment Ritual event has spawned!");
+			}
+		}
+		else if (id == NpcID.ENTLING)
+		{
+			entlings.add(npc);
+			if (entlings.size() == 1 && config.forestryFriendlyEntNotification())
+			{
+				notifier.notify("A Friendly Ent event has spawned!");
+			}
+		}
 	}
 
 	@Subscribe
@@ -457,6 +554,20 @@ public class WoodcuttingPlugin extends Plugin
 				lastInteractFlower = null;
 			}
 		}
+		if (foxTrap == npc)
+		{
+			foxTrap = null;
+		}
+		if (freakyForester == npc)
+		{
+			freakyForester = null;
+		}
+		if (unfinishedBeeHive == npc)
+		{
+			unfinishedBeeHive = null;
+		}
+		circles.remove(npc);
+		entlings.remove(npc);
 	}
 
 	@Subscribe
@@ -483,4 +594,29 @@ public class WoodcuttingPlugin extends Plugin
 			npcId == NpcID.FLOWERING_BUSH_GREEN ||
 			npcId == NpcID.FLOWERING_BUSH_BLUE;
 	}
+
+	NPC solveCircles()
+	{
+		int s = 0;
+		for (var npc : circles)
+		{
+			int off = npc.getId() - NpcID.RITUAL_CIRCLE_GREEN;
+			int shape = off / 4;
+			int color = off % 4;
+			int id = (16 << shape) | (1 << color);
+			s ^= id;
+		}
+		for (var npc : circles)
+		{
+			int off = npc.getId() - NpcID.RITUAL_CIRCLE_GREEN;
+			int shape = off / 4;
+			int color = off % 4;
+			int id = (16 << shape) | (1 << color);
+			if ((id & s) == id)
+			{
+				return npc;
+			}
+		}
+		return null;
+	}
 }
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingSceneOverlay.java
similarity index 80%
rename from runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java
rename to runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingSceneOverlay.java
index c6ee9f3db..d2cae6a74 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingTreesOverlay.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/woodcutting/WoodcuttingSceneOverlay.java
@@ -36,6 +36,7 @@ import java.util.List;
 import javax.inject.Inject;
 import net.runelite.api.Client;
 import net.runelite.api.GameObject;
+import net.runelite.api.ItemID;
 import net.runelite.api.NPC;
 import net.runelite.api.ObjectComposition;
 import net.runelite.api.ObjectID;
@@ -51,7 +52,7 @@ import net.runelite.client.ui.overlay.OverlayUtil;
 import net.runelite.client.ui.overlay.components.ProgressPieComponent;
 import net.runelite.client.util.ColorUtil;
 
-class WoodcuttingTreesOverlay extends Overlay
+class WoodcuttingSceneOverlay extends Overlay
 {
 	private static final Color ROTTING_LEAVES = new Color(179, 0, 0);
 	private static final Color GREEN_LEAVES = new Color(0, 179, 0);
@@ -65,7 +66,7 @@ class WoodcuttingTreesOverlay extends Overlay
 	private final WoodcuttingPlugin plugin;
 
 	@Inject
-	private WoodcuttingTreesOverlay(final Client client, final WoodcuttingConfig config, final ItemManager itemManager, final WoodcuttingPlugin plugin)
+	private WoodcuttingSceneOverlay(final Client client, final WoodcuttingConfig config, final ItemManager itemManager, final WoodcuttingPlugin plugin)
 	{
 		this.client = client;
 		this.config = config;
@@ -78,11 +79,15 @@ class WoodcuttingTreesOverlay extends Overlay
 	@Override
 	public Dimension render(Graphics2D graphics)
 	{
-		renderAxes(graphics);
+		renderRedwoods(graphics);
 		renderTimers(graphics);
 		renderForestryRoots(graphics);
 		renderForestrySapling(graphics);
 		renderForestryFlowers(graphics);
+		renderForestryPoachers(graphics);
+		renderForestryPheasants(graphics);
+		renderForestryBeeHive(graphics);
+		renderEnchantmentRitual(graphics);
 		return null;
 	}
 
@@ -219,15 +224,76 @@ class WoodcuttingTreesOverlay extends Overlay
 		}
 	}
 
-	private void renderAxes(Graphics2D graphics)
+	private void renderForestryPoachers(Graphics2D graphics)
 	{
-		if (plugin.getSession() == null || !config.showRedwoodTrees())
+		if (plugin.getFoxTrap() != null && config.highlightFoxTrap())
 		{
-			return;
+			var foxTrap = plugin.getFoxTrap();
+			var poly = foxTrap.getCanvasTilePoly();
+			if (poly != null)
+			{
+				OverlayUtil.renderPolygon(graphics, poly, Color.RED);
+			}
+		}
+	}
+
+	private void renderForestryPheasants(Graphics2D graphics)
+	{
+		if (!plugin.getPheasantNests().isEmpty() && config.highlightPheasantNest())
+		{
+			for (var nest : plugin.getPheasantNests())
+			{
+				if (nest.getId() == ObjectID.PHEASANT_NEST_49937)
+				{
+					var poly = nest.getCanvasTilePoly();
+					if (poly != null)
+					{
+						OverlayUtil.renderPolygon(graphics, poly, Color.GREEN);
+					}
+				}
+			}
+
+			var forester = plugin.getFreakyForester();
+			if (forester != null)
+			{
+				var poly = forester.getCanvasTilePoly();
+				if (poly != null)
+				{
+					OverlayUtil.renderPolygon(graphics, poly, Color.GREEN);
+				}
+			}
+		}
+	}
+
+	private void renderForestryBeeHive(Graphics2D graphics)
+	{
+		if (plugin.getUnfinishedBeeHive() != null && config.highlightBeeHive())
+		{
+			var beehive = plugin.getUnfinishedBeeHive();
+			var poly = beehive.getCanvasTilePoly();
+			if (poly != null)
+			{
+				OverlayUtil.renderPolygon(graphics, poly, Color.ORANGE);
+			}
 		}
+	}
 
-		Axe axe = plugin.getAxe();
-		if (axe == null)
+	private void renderEnchantmentRitual(Graphics2D graphics)
+	{
+		var solution = plugin.solveCircles();
+		if (solution != null && config.highlightRitualCircle())
+		{
+			var poly = solution.getCanvasTilePoly();
+			if (poly != null)
+			{
+				OverlayUtil.renderPolygon(graphics, poly, Color.GREEN);
+			}
+		}
+	}
+
+	private void renderRedwoods(Graphics2D graphics)
+	{
+		if (plugin.getSession() == null || !config.showRedwoodTrees())
 		{
 			return;
 		}
@@ -243,7 +309,7 @@ class WoodcuttingTreesOverlay extends Overlay
 				{
 					continue;
 				}
-				OverlayUtil.renderImageLocation(client, graphics, treeObject.getLocalLocation(), itemManager.getImage(axe.getItemId()), 120);
+				OverlayUtil.renderImageLocation(client, graphics, treeObject.getLocalLocation(), itemManager.getImage(ItemID.REDWOOD_LOGS), 120);
 			}
 		}
 	}
diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json
index 792f43c6a..ac640b7fa 100644
--- a/runelite-client/src/main/resources/item_variations.json
+++ b/runelite-client/src/main/resources/item_variations.json
@@ -559,8 +559,7 @@
   ],
   "axe handle": [
     492,
-    7952,
-    28177
+    7952
   ],
   "broken axe": [
     494,
@@ -4616,6 +4615,10 @@
     5599,
     5600
   ],
+  "fox": [
+    5608,
+    28670
+  ],
   "hourglass": [
     5610,
     12841
@@ -11482,7 +11485,12 @@
     28143,
     28145
   ],
-  "crystalh axe": [
+  "mulch": [
+    28183,
+    28648,
+    28649
+  ],
+  "crystal felling axe": [
     28220,
     28223
   ],
@@ -11631,5 +11639,12 @@
     28588,
     28589,
     28590
+  ],
+  "spider hat": [
+    28603,
+    28605,
+    28607,
+    28609,
+    28611
   ]
 }
\ No newline at end of file


Test patch:
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java
index 9a0d6c0dc..59ef70d7d 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/woodcutting/WoodcuttingPluginTest.java
@@ -82,7 +82,7 @@ public class WoodcuttingPluginTest
 
 	@Mock
 	@Bind
-	WoodcuttingTreesOverlay woodcuttingTreesOverlay;
+	WoodcuttingSceneOverlay woodcuttingSceneOverlay;
 
 	@Mock
 	@Bind