Repository: runelite/runelite (java)

Issue:
[Loot Tracker] Wintertodt cart loot does not track uniques
### Type

Incorrect behavior

### Operating System

None

### OS Version

_No response_

### Bug description

When pulling rewards from the Wintertodt cart, uniques do not display in the loot tracker.
The text for uniques is colored while the regular loot is not.

Relevant commit: https://github.com/runelite/runelite/commit/7dd96d7868fc7606b1c86e4218201c735b23b3c4


### Screenshots or videos

![Image](https://github.com/user-attachments/assets/ab437247-e2ee-4b65-89b2-ba06921449f2)

### RuneLite version

RuneLite Version: 1.10.48
Launcher: 2.7.1

### Logs

_No response_

Pull request description:
loot tracker: capture unique wintertodt rewards
This PR resolves an uncaught case within the loot tracker plugin, when collecting Wintertodt rewards.
A test for Wintertodt loot tracking was also added.

```
2025-02-23 15:40:07 CET [Client] DEBUG injected-client - Chat message type SPAM: <col=ef1020>You found some loot: 17 x Burnt page
2025-02-23 15:40:07 CET [Client] DEBUG n.r.c.p.l.LootTrackerPlugin - Inv change: [ItemStack(id=20718, quantity=17)] Ground items: []

2025-02-23 15:47:15 CET [Client] DEBUG injected-client - Chat message type SPAM: You found some loot: 4,694 x Coins
2025-02-23 15:47:15 CET [Client] DEBUG n.r.c.p.l.LootTrackerPlugin - Inv change: [ItemStack(id=995, quantity=4694)] Ground items: []
```

The reward message for rare loot is identical on both opaque and transparent chats.

<details>
  <summary>Spoiler</summary>
  
![image](https://github.com/user-attachments/assets/c5254d1b-1509-4ee4-bdbf-084009cabfab)
![image](https://github.com/user-attachments/assets/7684adb2-477e-42cc-b020-f2523099390c)

</details>

Fixes #18687 

Patch:
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
index 18e580509..8cc6d5906 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/loottracker/LootTrackerPlugin.java
@@ -1164,7 +1164,7 @@ public class LootTrackerPlugin extends Plugin
 			return;
 		}
 
-		if (regionID == WINTERTODT_REGION && message.startsWith(WINTERTODT_LOOT_STRING))
+		if (regionID == WINTERTODT_REGION && message.contains(WINTERTODT_LOOT_STRING))
 		{
 			onInvChange(collectInvItems(LootRecordType.EVENT, WINTERTODT_REWARD_CART_EVENT, client.getBoostedSkillLevel(Skill.FIREMAKING)));
 			return;


Test patch:
diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/loottracker/LootTrackerPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/loottracker/LootTrackerPluginTest.java
index df1e9a869..b2be7cba8 100644
--- a/runelite-client/src/test/java/net/runelite/client/plugins/loottracker/LootTrackerPluginTest.java
+++ b/runelite-client/src/test/java/net/runelite/client/plugins/loottracker/LootTrackerPluginTest.java
@@ -553,4 +553,54 @@ public class LootTrackerPluginTest
 
 		verify(lootTrackerPlugin).addLoot("Barbarian Assault high gamble", -1, LootRecordType.EVENT, null, items);
 	}
+
+	@Test
+	public void testWintertodtRewardCart()
+	{
+		Player player = mock(Player.class);
+		when(player.getWorldLocation()).thenReturn(new WorldPoint(1636, 3944, 0));
+		when(client.getLocalPlayer()).thenReturn(player);
+		when(client.getBoostedSkillLevel(Skill.FIREMAKING)).thenReturn(99);
+
+		doNothing().when(lootTrackerPlugin).addLoot(any(), anyInt(), any(), any(), anyCollection());
+
+		ItemContainer itemContainer = mock(ItemContainer.class);
+		when(itemContainer.getItems()).thenReturn(new Item[]{
+			new Item(ItemID.KNIFE, 1),
+			new Item(ItemID.BRUMA_TORCH, 1),
+			new Item(ItemID.HAMMER, 1)
+		});
+		when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(itemContainer);
+
+		ChatMessage chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "<col=ef1020>You found some loot: 17 x Burnt page", "", 0);
+		lootTrackerPlugin.onChatMessage(chatMessage);
+
+		when(itemContainer.getItems()).thenReturn(new Item[]{
+			new Item(ItemID.BURNT_PAGE, 17),
+			new Item(ItemID.KNIFE, 1),
+			new Item(ItemID.BRUMA_TORCH, 1),
+			new Item(ItemID.HAMMER, 1)
+		});
+		lootTrackerPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.INVENTORY.getId(), itemContainer));
+
+		verify(lootTrackerPlugin).addLoot("Reward cart (Wintertodt)", -1, LootRecordType.EVENT, 99, Collections.singletonList(
+			new ItemStack(ItemID.BURNT_PAGE, 17)
+		));
+
+		chatMessage = new ChatMessage(null, ChatMessageType.SPAM, "", "You found some loot: 4,694 x Coins", "", 0);
+		lootTrackerPlugin.onChatMessage(chatMessage);
+
+		when(itemContainer.getItems()).thenReturn(new Item[]{
+			new Item(ItemID.BURNT_PAGE, 17),
+			new Item(ItemID.COINS_995, 4694),
+			new Item(ItemID.KNIFE, 1),
+			new Item(ItemID.BRUMA_TORCH, 1),
+			new Item(ItemID.HAMMER, 1)
+		});
+		lootTrackerPlugin.onItemContainerChanged(new ItemContainerChanged(InventoryID.INVENTORY.getId(), itemContainer));
+
+		verify(lootTrackerPlugin).addLoot("Reward cart (Wintertodt)", -1, LootRecordType.EVENT, 99, Collections.singletonList(
+			new ItemStack(ItemID.COINS_995, 4694)
+		));
+	}
 }