aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml10
-rw-r--r--.github/ISSUE_TEMPLATE/crash_report.yml8
-rw-r--r--.github/workflows/beta.yml2
-rw-r--r--.github/workflows/buildrelease.yml7
-rw-r--r--.github/workflows/webhook_translate.yml2
-rw-r--r--MRREADME.md76
-rw-r--r--build.gradle4
-rw-r--r--gradle.properties2
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java9
-rw-r--r--src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java28
-rw-r--r--src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java92
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java34
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java46
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java28
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/Debug.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java31
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java18
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java31
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java31
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java43
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java15
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java64
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java56
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java99
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java13
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java83
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java42
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java99
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java108
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java55
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java13
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java9
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java53
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java20
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java (renamed from src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java)107
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java (renamed from src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java)4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java (renamed from src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java)78
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ApiUtils.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Constants.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Http.java44
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java23
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java1
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java118
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java36
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java44
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java40
-rw-r--r--src/main/resources/assets/skyblocker/dungeons/secretlocations.json6
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_ca.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json28
-rw-r--r--src/main/resources/assets/skyblocker/lang/fr_fr.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/pt_br.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/ru_ru.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/zh_cn.json4
-rw-r--r--src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_circular.png (renamed from src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background.png)bin198 -> 198 bytes
-rw-r--r--src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.pngbin0 -> 502 bytes
-rw-r--r--src/main/resources/skyblocker.mixins.json7
-rw-r--r--src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java79
-rw-r--r--src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java11
-rw-r--r--src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java38
-rw-r--r--src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java70
103 files changed, 1419 insertions, 948 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 72f0fc8c..57ef4ff2 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -28,16 +28,16 @@ body:
id: logs
attributes:
label: Log output
- description: 'Please upload a client log file by dragging and dropping it into this section. Usually this is found at `.minecraft/logs/latest.log`. If you are not sure how to find `.minecraft`, please see this article: https://minecraft.fandom.com/wiki/.minecraft#Locating_.minecraft. Please do not upload a compressed (`.log.gz`) file, they are very difficult for us to read when viewing issue reports. The log file instantly tells us important information like the versions of any other installed mods or if there are errors so it is very very important that you include it in your report.'
+ description: 'Please upload a client log file by dragging and dropping it into this section. Usually this is found at `.minecraft/logs/latest.log`. If you are not sure how to find `.minecraft`, please see this article: https://minecraft.wiki/w/.minecraft#Locating_.minecraft. Please do not upload a compressed (`.log.gz`) file, they are very difficult for us to read when viewing issue reports. The log file instantly tells us important information like the versions of any other installed mods or if there are errors so it is very very important that you include it in your report.'
- type: dropdown
id: minecraft-version
attributes:
label: Minecraft Version
description: What version of Minecraft are you running? If you do not know what version you are using, look in the bottom left corner of the main menu in game.
options:
- - 1.20.2
- - 1.20.1
- - 1.20
+ - "1.20.2"
+ - "1.20.1"
+ - "1.20"
validations:
required: true
- type: input
@@ -54,4 +54,4 @@ body:
label: Additional context
description: 'Add any other context about the problem here. If you are proficient at reading log files and think there is an especially relevant section, feel free to paste it in a code block here - that is not required, though.'
validations:
- required: false \ No newline at end of file
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/crash_report.yml b/.github/ISSUE_TEMPLATE/crash_report.yml
index ae477210..f35e0be9 100644
--- a/.github/ISSUE_TEMPLATE/crash_report.yml
+++ b/.github/ISSUE_TEMPLATE/crash_report.yml
@@ -16,9 +16,9 @@ body:
label: Minecraft Version
description: What version of Minecraft are you running? If you do not know what version you are using, look in the bottom left corner of the main menu in game.
options:
- - 1.20.2
- - 1.20.1
- - 1.20
+ - "1.20.2"
+ - "1.20.1"
+ - "1.20"
validations:
required: true
- type: input
@@ -79,4 +79,4 @@ body:
label: Additional context
description: Provide any additional information or context which may be relevant to the issue. This is optional
validations:
- required: false \ No newline at end of file
+ required: false
diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml
index cbb98c36..9f0b8490 100644
--- a/.github/workflows/beta.yml
+++ b/.github/workflows/beta.yml
@@ -7,6 +7,8 @@ on:
paths-ignore:
- 'src/main/resources/assets/skyblocker/lang/**'
pull_request:
+ paths-ignore:
+ - 'src/main/resources/assets/skyblocker/lang/**'
jobs:
diff --git a/.github/workflows/buildrelease.yml b/.github/workflows/buildrelease.yml
index fde5785b..4a15fe57 100644
--- a/.github/workflows/buildrelease.yml
+++ b/.github/workflows/buildrelease.yml
@@ -138,4 +138,9 @@ jobs:
https://hysky.de/"
- curl -H "Content-Type: application/json" -d '{"content":"'"${OUTPUT//$'\n'/\\n}"'", "flags": 4}' "${{ secrets.DISCORD_WEBHOOK }}" \ No newline at end of file
+ curl -H "Content-Type: application/json" -d '{"content":"'"${OUTPUT//$'\n'/\\n}"'", "flags": 4}' "${{ secrets.DISCORD_WEBHOOK }}"
+
+ - name: Trigger Modpack
+ shell: bash
+ run: |
+ curl -X POST -H "Authorization:Bearer ${{secrets.MODPACK_TOKEN}}" -H "X-GitHub-Api-Version:2022-11-28" https://api.github.com/repos/SkyblockerMod/Skyblocker-modpack/actions/workflows/update.yml/dispatches --data '{"ref":"main"}'
diff --git a/.github/workflows/webhook_translate.yml b/.github/workflows/webhook_translate.yml
index 146cc704..c901c056 100644
--- a/.github/workflows/webhook_translate.yml
+++ b/.github/workflows/webhook_translate.yml
@@ -49,7 +49,7 @@ jobs:
"url": "https://translate.hysky.de/projects/Skyblocker/skyblocker",
"color": 5808639,
"image": {
- "url": "https://translate.hysky.de/widgets/Skyblocker/-/skyblocker/88x31-grey.png"
+ "url": "https://translate.hysky.de/widgets/Skyblocker/-/skyblocker/88x31-grey.png?uuid='$(uuidgen)'"
}
}
],
diff --git a/MRREADME.md b/MRREADME.md
index 67dd29b2..b8868a59 100644
--- a/MRREADME.md
+++ b/MRREADME.md
@@ -1,4 +1,4 @@
-<img height="150" src="https://hysky.de/skyblocker.png" />
+<img height="150" src="https://hysky.de/skyblocker.png" alt="Skyblocker logo"/>
## Skyblocker
@@ -10,7 +10,7 @@ or **/skyblocker config**
Skyblocker has a variety of configurations. \
To access the configuration menu, you must install [Mod Menu](https://modrinth.com/mod/modmenu).
-<figure><a href="https://cdn.discordapp.com/attachments/895564321520750602/1165269183429361674/Bildschirmfoto_vom_2023-10-21_14-43-26.png"><img src="https://cdn.discordapp.com/attachments/895564321520750602/1165269183429361674/Bildschirmfoto_vom_2023-10-21_14-43-26.png" alt="Mod Menu" style="width:100%"></a><figcaption align = "center"><b>Skyblocker config</b></figcaption></figure>
+<figure><a href="https://raw.githubusercontent.com/SkyblockerMod/Skyblocker-Assets/images/Settings/Page%201%20General.png"><img src="https://raw.githubusercontent.com/SkyblockerMod/Skyblocker-Assets/images/Settings/Page%201%20General.png" alt="Mod Menu" style="width:100%"></a><figcaption align = "center"><b>Skyblocker config</b></figcaption></figure>
### List of Configuration
@@ -39,10 +39,10 @@ To access the configuration menu, you must install [Mod Menu](https://modrinth.c
<details>
<summary> Health, Mana, Defence & XP Bars </summary>
-|Config option|Description|
-|---|---|
-|Enable Bars| Change Minecraft health ui with skyblocker [custom ui](https://user-images.githubusercontent.com/27798256/170806938-f858f0ae-4d8b-4767-9b53-8fe5a65edf56.png)|
-|Configure Bar Position|[Customize Bar Positions](https://cdn.discordapp.com/attachments/1103292463558438993/1103292498345984070/healt-layer.png)|
+| Config option | Description |
+|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Enable Bars | Change Minecraft health ui with skyblocker [custom ui](https://user-images.githubusercontent.com/27798256/170806938-f858f0ae-4d8b-4767-9b53-8fe5a65edf56.png) |
+| Configure Bar Position | [Customize Bar Positions](https://raw.githubusercontent.com/SkyblockerMod/Skyblocker-Assets/images/Health%20and%20Status%20Bars/Status%20Bars.png) |
</details>
<details>
@@ -111,9 +111,9 @@ To access the configuration menu, you must install [Mod Menu](https://modrinth.c
<details>
<summary> Item List </summary>
-| Config option | Description |
-|------------------|--------------------------------------------------------------------------------------------------------------------------|
-| Enable Item List | Acitvate [recipe viewer](https://cdn-raw.modrinth.com/data/y6DuFGwJ/images/cf9f8077067b9781686f23116f163d529c21c404.png) |
+| Config option | Description |
+|------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Enable Item List | Acitvate [recipe viewer](https://raw.githubusercontent.com/SkyblockerMod/Skyblocker-Assets/images/User%20Interface%20Enhancements/Recipe%20Book%202.png) |
</details>
<details>
@@ -363,49 +363,49 @@ Used to display multiple titles at once, Example use: Vampire Slayer
<details>
<summary> Quick Navigation </summary>
-|Config option|Description|
-|---|---|
-|Enable Quick Navigation|Enable [Quicknav](https://cdn.discordapp.com/attachments/1103292463558438993/1103358576870817866/quick-nav.png)|
+| Config option | Description |
+|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
+| Enable Quick Navigation | Enable [Quicknav](https://raw.githubusercontent.com/SkyblockerMod/Skyblocker-Assets/images/User%20Interface%20Enhancements/Quicknav.png) |
<details>
<summary> Button 1-12 </summary>
-|Config option|Description|
-|---|---|
-|Render|To show the tab|
-|Item name| The name of the item e.g. iron_boots |
-|NBT| NBT tag of the item e.g. custom head id on skull item|
-|UI Title| Title of the tab|
-|Click event|The command that is executed when you click the tab|
+| Config option | Description |
+|---------------|-------------------------------------------------------|
+| Render | To show the tab |
+| Item name | The name of the item e.g. iron_boots |
+| NBT | NBT tag of the item e.g. custom head id on skull item |
+| UI Title | Title of the tab |
+| Click event | The command that is executed when you click the tab |
</details>
</details>
<details>
<summary> Messages </summary>
-| Config option | Description |
-|------------------------------------------------|-----------------------------------------|
-| Hide Ability Cooldown | Disable,Filter or Move to action bar |
-| Hide Heal Messages | Disable,Filter or Move to action bar |
-| Hide AOTE Messages | Disable,Filter or Move to action bar |
-| Hide Implosion Message | Disable,Filter or Move to action bar |
-| Hide Molten Wave Message | Disable,Filter or Move to action bar |
-| Hide Ads from Public Chat | Disable,Filter or Move to action bar |
-| Hide Teleport Pad Messages | Disable,Filter or Move to action bar |
-| Hide Combo Messages | Disable,Filter or Move to action bar |
-| Hide Autopet Messages | Disable,Filter or Move to action bar |
+| Config option | Description |
+|------------------------------------------------|-------------------------------------------|
+| Hide Ability Cooldown | Disable,Filter or Move to action bar |
+| Hide Heal Messages | Disable,Filter or Move to action bar |
+| Hide AOTE Messages | Disable,Filter or Move to action bar |
+| Hide Implosion Message | Disable,Filter or Move to action bar |
+| Hide Molten Wave Message | Disable,Filter or Move to action bar |
+| Hide Ads from Public Chat | Disable,Filter or Move to action bar |
+| Hide Teleport Pad Messages | Disable,Filter or Move to action bar |
+| Hide Combo Messages | Disable,Filter or Move to action bar |
+| Hide Autopet Messages | Disable,Filter or Move to action bar |
| Hide Show Off Messages | Filters messages from the `/show command` |
-| Hide Mana Consumption Messages from Action Bar | Activate or deactivate |
+| Hide Mana Consumption Messages from Action Bar | Activate or deactivate |
</details>
<details>
<summary> Discord Rich Presence </summary>
-|Config option|Description|
-|---|---|
-|Enable|Activate [Discord Rich Presence](https://cdn-raw.modrinth.com/data/y6DuFGwJ/images/f6314d0ae0fc24d77fb3371e59b7abfe4774a17e.png)|
-|Skyblock Info|Choose between Location,Purse and Bits|
-|Cycle Skyblock Info| Cycles between the three options|
-|Custom Message| Show a custom message|
+| Config option | Description |
+|---------------------|----------------------------------------------------------------------------------------------------------------------------------|
+| Enable | Activate [Discord Rich Presence](https://cdn-raw.modrinth.com/data/y6DuFGwJ/images/f6314d0ae0fc24d77fb3371e59b7abfe4774a17e.png) |
+| Skyblock Info | Choose between Location,Purse and Bits |
+| Cycle Skyblock Info | Cycles between the three options |
+| Custom Message | Show a custom message |
</details>
## 🖼️ Images
@@ -539,6 +539,6 @@ Looking for an affordable and reliable hosting platform for your Minecraft serve
As a special offer for our audience, you can **<u>[use the discount code "Skyblocker" during checkout to get 15% off your first month](https://billing.kinetichosting.net/aff.php?aff=315)</u>**.
This helps to cover our server costs.
-[![Kinetic-hosting](https://cdn.discordapp.com/attachments/1098004599757099150/1099460202924879902/Skyblocker.png)](https://billing.kinetichosting.net/aff.php?aff=315)
+[![Kinetic-hosting](https://raw.githubusercontent.com/SkyblockerMod/Skyblocker-Assets/images/other/Kinetic-Hosting_Skyblocker.png)](https://billing.kinetichosting.net/aff.php?aff=315)
So what are you waiting for? Click on the **<u>[link](https://billing.kinetichosting.net/aff.php?aff=315)</u>** to check out Kinetic Hosting and start playing with your friends today! \ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 72432203..c28bd1b5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -29,9 +29,7 @@ repositories {
}
maven { url "https://repo.codemc.io/repository/maven-public/" } // For Occlusion Culling library
maven { url "https://repo.nea.moe/releases" } // For neu repoparser
- maven { url "https://oss.sonatype.org/content/repositories/snapshots" } //For YACL
- maven { url "https://maven.quiltmc.org/repository/release" } //For YACL
- maven {url "https://jitpack.io"}
+ maven { url "https://jitpack.io" }
}
dependencies {
diff --git a/gradle.properties b/gradle.properties
index 6c364898..ad21639d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -13,7 +13,7 @@ fabric_api_version=0.89.1+1.20.2
# Minecraft Mods
## YACL (https://github.com/isXander/YetAnotherConfigLib)
-yacl_version=3.2.1+1.20.2
+yacl_version=3.3.0-beta.1+1.20.2
## Mod Menu (https://modrinth.com/mod/modmenu/versions)
mod_menu_version = 8.0.0
## REI (https://modrinth.com/mod/rei/versions?l=fabric)
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index b398e9b6..cbe82667 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -3,8 +3,9 @@ package de.hysky.skyblocker;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.skyblock.*;
-import de.hysky.skyblocker.skyblock.diana.MythologicalRitual;
+import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual;
import de.hysky.skyblocker.skyblock.dungeon.*;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonSecrets;
import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker;
@@ -17,15 +18,17 @@ import de.hysky.skyblocker.skyblock.quicknav.QuickNav;
import de.hysky.skyblocker.skyblock.rift.TheRift;
import de.hysky.skyblocker.skyblock.shortcut.Shortcuts;
import de.hysky.skyblocker.skyblock.special.SpecialEffects;
-import de.hysky.skyblocker.skyblock.spidersden.Relics;
+import de.hysky.skyblocker.skyblock.waypoint.Relics;
import de.hysky.skyblocker.skyblock.tabhud.TabHud;
import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
+import de.hysky.skyblocker.skyblock.waypoint.FairySouls;
import de.hysky.skyblocker.utils.ApiUtils;
import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.chat.ChatMessageListener;
import de.hysky.skyblocker.utils.discord.DiscordRPCManager;
+import de.hysky.skyblocker.utils.render.RenderHelper;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.gui.ContainerSolverManager;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
@@ -113,6 +116,8 @@ public class SkyblockerMod implements ClientModInitializer {
MuseumItemCache.init();
SecretsTracker.init();
ApiUtils.init();
+ Debug.init();
+ RenderHelper.init();
containerSolverManager.init();
statusBarTracker.init();
Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20);
diff --git a/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java
index 145f7ec4..7820dfa4 100644
--- a/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java
+++ b/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java
@@ -1,20 +1,15 @@
package de.hysky.skyblocker.compatibility;
-import java.util.List;
-import java.util.Set;
-
+import net.fabricmc.loader.api.FabricLoader;
import org.objectweb.asm.tree.ClassNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
-import net.fabricmc.loader.api.FabricLoader;
+import java.util.List;
+import java.util.Set;
public class MixinPlugin implements IMixinConfigPlugin {
- private static final Logger LOGGER = LoggerFactory.getLogger(MixinPlugin.class);
private static final boolean OPTIFABRIC_LOADED = FabricLoader.getInstance().isModLoaded("optifabric");
- private static final String YACL_VERSION = FabricLoader.getInstance().getModContainer("yet_another_config_lib_v3").get().getMetadata().getVersion().getFriendlyString();
@Override
public void onLoad(String mixinPackage) {
@@ -29,21 +24,8 @@ public class MixinPlugin implements IMixinConfigPlugin {
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
//OptiFabric Compatibility
- if (mixinClassName.endsWith("WorldRendererMixin") && OPTIFABRIC_LOADED) return false;
-
- //YACL#103 Patch
- if (mixinClassName.endsWith("DoubleFieldControllerMixin") || mixinClassName.endsWith("FloatFieldControllerMixin") || mixinClassName.endsWith("IntegerFieldControllerMixin") || mixinClassName.endsWith("LongFieldControllerMixin") || mixinClassName.endsWith("NumberFieldControllerMixin")) {
- if (YACL_VERSION.equals("3.2.1+1.20.2")) {
- LOGGER.info("[Skyblocker] Applying patch for " + targetClassName + " from " + mixinClassName);
- } else {
- LOGGER.info("[Skyblocker] Skipping patch on " + targetClassName + " due to an Unknown YACL version being found! Version: {}", YACL_VERSION);
-
- return false;
- }
- }
-
- return true;
- }
+ return !mixinClassName.endsWith("WorldRendererMixin") || !OPTIFABRIC_LOADED;
+ }
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java
index b52d6ff5..218eb8d1 100644
--- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java
+++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java
@@ -4,7 +4,6 @@ import de.hysky.skyblocker.skyblock.itemlist.SkyblockCraftingRecipe;
import de.hysky.skyblocker.utils.ItemUtils;
import dev.emi.emi.api.recipe.EmiCraftingRecipe;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
-import dev.emi.emi.api.stack.Comparison;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.widget.WidgetHolder;
@@ -16,7 +15,7 @@ public class SkyblockEmiRecipe extends EmiCraftingRecipe {
private final String craftText;
public SkyblockEmiRecipe(SkyblockCraftingRecipe recipe) {
- super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()).comparison(Comparison.compareNbt()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_') + "_" + recipe.getResult().getCount()));
+ super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_') + "_" + recipe.getResult().getCount()));
this.craftText = recipe.getCraftText();
}
diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java
index 6ed6a32a..8dfc5dc9 100644
--- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java
+++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java
@@ -7,6 +7,7 @@ import dev.emi.emi.api.EmiPlugin;
import dev.emi.emi.api.EmiRegistry;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
import dev.emi.emi.api.render.EmiTexture;
+import dev.emi.emi.api.stack.Comparison;
import dev.emi.emi.api.stack.EmiStack;
import net.minecraft.item.Items;
import net.minecraft.util.Identifier;
@@ -21,7 +22,10 @@ public class SkyblockerEMIPlugin implements EmiPlugin {
@Override
public void register(EmiRegistry registry) {
- ItemRepository.getItemsStream().map(EmiStack::of).forEach(registry::addEmiStack);
+ ItemRepository.getItemsStream().map(EmiStack::of).forEach(emiStack -> {
+ registry.addEmiStack(emiStack);
+ registry.setDefaultComparison(emiStack, Comparison.compareNbt());
+ });
registry.addCategory(SKYBLOCK);
registry.addWorkstation(SKYBLOCK, EmiStack.of(Items.CRAFTING_TABLE));
ItemRepository.getRecipesStream().map(SkyblockEmiRecipe::new).forEach(registry::addRecipe);
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
index 68520cab..1c6bb394 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
@@ -1,5 +1,6 @@
package de.hysky.skyblocker.config;
+import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.skyblock.item.CustomArmorTrims;
import de.hysky.skyblocker.utils.chat.ChatFilterResult;
import de.hysky.skyblocker.utils.waypoint.Waypoint;
@@ -10,6 +11,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
+import net.minecraft.util.Identifier;
import java.util.ArrayList;
import java.util.List;
@@ -187,6 +189,9 @@ public class SkyblockerConfig {
public Shortcuts shortcuts = new Shortcuts();
@SerialEntry
+ public Waypoints waypoints = new Waypoints();
+
+ @SerialEntry
public QuiverWarning quiverWarning = new QuiverWarning();
@SerialEntry
@@ -252,8 +257,8 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case DEFAULT -> "Default";
- case ALPHABETICAL -> "Alphabetical";
+ case DEFAULT -> "Default";
+ case ALPHABETICAL -> "Alphabetical";
};
}
}
@@ -291,10 +296,10 @@ public class SkyblockerConfig {
public int toInt() {
return switch (this) {
- case LAYER1 -> 0;
- case LAYER2 -> 1;
- case RIGHT -> 2;
- case NONE -> -1;
+ case LAYER1 -> 0;
+ case LAYER2 -> 1;
+ case RIGHT -> 2;
+ case NONE -> -1;
};
}
}
@@ -347,6 +352,14 @@ public class SkyblockerConfig {
public boolean enableCommandArgShortcuts = true;
}
+ public static class Waypoints {
+ @SerialEntry
+ public boolean enableWaypoints = true;
+
+ @SerialEntry
+ public Waypoint.Type waypointType = Waypoint.Type.WAYPOINT;
+ }
+
public static class QuiverWarning {
@SerialEntry
public boolean enableQuiverWarning = true;
@@ -360,7 +373,7 @@ public class SkyblockerConfig {
public static class Hitbox {
@SerialEntry
- public boolean oldFarmlandHitbox = true;
+ public boolean oldFarmlandHitbox = false;
@SerialEntry
public boolean oldLeverHitbox = false;
@@ -417,8 +430,8 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case HORIZONTAL -> "Horizontal";
- case VERTICAL -> "Vertical";
+ case HORIZONTAL -> "Horizontal";
+ case VERTICAL -> "Vertical";
};
}
}
@@ -429,9 +442,9 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case LEFT -> "Left";
- case RIGHT -> "Right";
- case MIDDLE -> "Middle";
+ case LEFT -> "Left";
+ case RIGHT -> "Right";
+ case MIDDLE -> "Middle";
};
}
}
@@ -484,7 +497,10 @@ public class SkyblockerConfig {
public boolean enableBazaarPrice = true;
@SerialEntry
- public boolean enableMuseumDate = true;
+ public boolean enableObtainedDate = true;
+
+ @SerialEntry
+ public boolean enableMuseumInfo = true;
@SerialEntry
public boolean enableExoticTooltip = true;
@@ -498,9 +514,31 @@ public class SkyblockerConfig {
public boolean itemRarityBackgrounds = false;
@SerialEntry
+ public RarityBackgroundStyle itemRarityBackgroundStyle = RarityBackgroundStyle.CIRCULAR;
+
+ @SerialEntry
public float itemRarityBackgroundsOpacity = 1f;
}
+ public enum RarityBackgroundStyle {
+ CIRCULAR(new Identifier(SkyblockerMod.NAMESPACE, "item_rarity_background_circular")),
+ SQUARE(new Identifier(SkyblockerMod.NAMESPACE, "item_rarity_background_square"));
+
+ public final Identifier tex;
+
+ RarityBackgroundStyle(Identifier tex) {
+ this.tex = tex;
+ }
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case CIRCULAR -> "Circular";
+ case SQUARE -> "Square";
+ };
+ }
+ }
+
public static class WikiLookup {
@SerialEntry
public boolean enableWikiLookup = true;
@@ -552,7 +590,7 @@ public class SkyblockerConfig {
@SerialEntry
public int mapY = 2;
-
+
@SerialEntry
public boolean playerSecretsTracker = false;
@@ -587,10 +625,10 @@ public class SkyblockerConfig {
@SerialEntry
public boolean noInitSecretWaypoints = false;
-
+
@SerialEntry
public Waypoint.Type waypointType = Waypoint.Type.WAYPOINT;
-
+
@SerialEntry
public boolean showSecretText = true;
@@ -620,10 +658,10 @@ public class SkyblockerConfig {
@SerialEntry
public boolean enableStonkWaypoints = true;
-
+
@SerialEntry
public boolean enableAotvWaypoints = true;
-
+
@SerialEntry
public boolean enablePearlWaypoints = true;
@@ -659,7 +697,10 @@ public class SkyblockerConfig {
public static class LividColor {
@SerialEntry
- public boolean enableLividColor = true;
+ public boolean enableLividColorGlow = true;
+
+ @SerialEntry
+ public boolean enableLividColorText = true;
@SerialEntry
public String lividColorText = "The livid color is [color]";
@@ -713,9 +754,9 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case SIMPLE -> "Simple";
- case FANCY -> "Fancy";
- case CLASSIC -> "Classic";
+ case SIMPLE -> "Simple";
+ case FANCY -> "Fancy";
+ case CLASSIC -> "Classic";
};
}
}
@@ -731,10 +772,13 @@ public class SkyblockerConfig {
public static class Rift {
@SerialEntry
public boolean mirrorverseWaypoints = true;
-
+
+ @SerialEntry
+ public boolean blobbercystGlow = true;
+
@SerialEntry
public boolean enigmaSoulWaypoints = false;
-
+
@SerialEntry
public boolean highlightFoundEnigmaSouls = true;
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
index 98c83975..875090ed 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
@@ -38,11 +38,11 @@ public class SkyblockerConfigManager {
.registerTypeHierarchyAdapter(Identifier.class, new Identifier.Serializer()))
.build())
.build();
-
+
public static SkyblockerConfig get() {
return HANDLER.instance();
}
-
+
/**
* This method is caller sensitive and can only be called by the mod initializer,
* this is enforced.
@@ -51,15 +51,15 @@ public class SkyblockerConfigManager {
if (StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).getCallerClass() != SkyblockerMod.class) {
throw new RuntimeException("Skyblocker: Called config init from an illegal place!");
}
-
+
HANDLER.load();
ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options")))));
}
-
+
public static void save() {
HANDLER.save();
}
-
+
public static Screen createGUI(Screen parent) {
return YetAnotherConfigLib.create(HANDLER, (defaults, config, builder) -> builder
.title(Text.translatable("text.autoconfig.skyblocker.title"))
@@ -72,7 +72,7 @@ public class SkyblockerConfigManager {
.category(MessageFilterCategory.create(defaults, config))
.category(DiscordRPCCategory.create(defaults, config))).generateScreen(parent);
}
-
+
/**
* Registers an options command with the given name. Used for registering both options and config as valid commands.
*
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java
index fcdc3d8d..907291ca 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java
@@ -13,7 +13,7 @@ public class DiscordRPCCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.richPresence"))
-
+
//Uncategorized Options
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.richPresence.enableRichPresence"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java
index 02913a28..7bb6414c 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java
@@ -23,7 +23,7 @@ public class DungeonsCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons"))
-
+
//Dungeon Secret Waypoints
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints"))
@@ -45,8 +45,8 @@ public class DungeonsCategory {
.flag(OptionFlag.GAME_RESTART)
.build())
.option(Option.<Type>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType.@Tooltip")))
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip")))
.binding(defaults.locations.dungeons.secretWaypoints.waypointType,
() -> config.locations.dungeons.secretWaypoints.waypointType,
newValue -> config.locations.dungeons.secretWaypoints.waypointType = newValue)
@@ -146,7 +146,7 @@ public class DungeonsCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.build())
-
+
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit"))
.collapsed(true)
@@ -212,7 +212,7 @@ public class DungeonsCategory {
.controller(EnumDropdownControllerBuilder.getFactory(ConfigUtils.FORMATTING_TO_STRING))
.build())
.build())
-
+
//Others
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper"))
@@ -242,8 +242,8 @@ public class DungeonsCategory {
.controller(FloatFieldControllerBuilder::create)
.build())
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretsTracker"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretsTracker.@Tooltip")))
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip")))
.binding(defaults.locations.dungeons.playerSecretsTracker,
() -> config.locations.dungeons.playerSecretsTracker,
newValue -> config.locations.dungeons.playerSecretsTracker = newValue)
@@ -301,11 +301,19 @@ public class DungeonsCategory {
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor"))
.collapsed(true)
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip")))
- .binding(defaults.locations.dungeons.lividColor.enableLividColor,
- () -> config.locations.dungeons.lividColor.enableLividColor,
- newValue -> config.locations.dungeons.lividColor.enableLividColor = newValue)
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow.@Tooltip")))
+ .binding(defaults.locations.dungeons.lividColor.enableLividColorGlow,
+ () -> config.locations.dungeons.lividColor.enableLividColorGlow,
+ newValue -> config.locations.dungeons.lividColor.enableLividColorGlow = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip")))
+ .binding(defaults.locations.dungeons.lividColor.enableLividColorText,
+ () -> config.locations.dungeons.lividColor.enableLividColorText,
+ newValue -> config.locations.dungeons.lividColor.enableLividColorText = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<String>createBuilder()
@@ -317,7 +325,7 @@ public class DungeonsCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Terminal Solvers
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.terminals"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
index 719cbd79..80d6485b 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
@@ -16,7 +16,7 @@ public class DwarvenMinesCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines"))
-
+
//Uncategorized Options
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.enableDrillFuel"))
@@ -39,7 +39,7 @@ public class DwarvenMinesCategory {
newValue -> config.locations.dwarvenMines.solvePuzzler = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
-
+
//Dwarven HUD
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
index 3cbb1b94..be5f0665 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
@@ -4,6 +4,7 @@ import de.hysky.skyblocker.config.ConfigUtils;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.skyblock.shortcut.ShortcutsConfigScreen;
import de.hysky.skyblocker.utils.render.title.TitleContainerConfigScreen;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import dev.isxander.yacl3.api.*;
import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder;
import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder;
@@ -261,6 +262,27 @@ public class GeneralCategory {
.build())
.build())
+ //Waypoints
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints"))
+ .collapsed(true)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints"))
+ .binding(defaults.general.waypoints.enableWaypoints,
+ () -> config.general.waypoints.enableWaypoints,
+ newValue -> config.general.waypoints.enableWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Waypoint.Type>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote")))
+ .binding(defaults.general.waypoints.waypointType,
+ () -> config.general.waypoints.waypointType,
+ newValue -> config.general.waypoints.waypointType = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
+ .build())
+
//Quiver Warning
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.quiverWarning"))
@@ -350,10 +372,18 @@ public class GeneralCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate"))
- .binding(defaults.general.itemTooltip.enableMuseumDate,
- () -> config.general.itemTooltip.enableMuseumDate,
- newValue -> config.general.itemTooltip.enableMuseumDate = newValue)
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableObtainedDate"))
+ .binding(defaults.general.itemTooltip.enableObtainedDate,
+ () -> config.general.itemTooltip.enableObtainedDate,
+ newValue -> config.general.itemTooltip.enableObtainedDate = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo.@Tooltip")))
+ .binding(defaults.general.itemTooltip.enableMuseumInfo,
+ () -> config.general.itemTooltip.enableMuseumInfo,
+ newValue -> config.general.itemTooltip.enableMuseumInfo = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
@@ -386,6 +416,14 @@ public class GeneralCategory {
newValue -> config.general.itemInfoDisplay.itemRarityBackgrounds = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<SkyblockerConfig.RarityBackgroundStyle>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle.@Tooltip")))
+ .binding(defaults.general.itemInfoDisplay.itemRarityBackgroundStyle,
+ () -> config.general.itemInfoDisplay.itemRarityBackgroundStyle,
+ newValue -> config.general.itemInfoDisplay.itemRarityBackgroundStyle = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
.option(Option.<Float>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundsOpacity"))
.binding(defaults.general.itemInfoDisplay.itemRarityBackgroundsOpacity,
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java
index 5e662fcc..0b388d16 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java
@@ -14,7 +14,7 @@ public class LocationsCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.locations"))
-
+
//Barn
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.barn"))
@@ -34,7 +34,7 @@ public class LocationsCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.build())
-
+
//The Rift
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift"))
@@ -47,6 +47,14 @@ public class LocationsCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow.@Tooltip")))
+ .binding(defaults.locations.rift.blobbercystGlow,
+ () -> config.locations.rift.blobbercystGlow,
+ newValue -> config.locations.rift.blobbercystGlow = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints"))
.description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints.@Tooltip")))
.binding(defaults.locations.rift.enigmaSoulWaypoints,
@@ -70,7 +78,7 @@ public class LocationsCategory {
.controller(opt -> IntegerSliderControllerBuilder.create(opt).range(0, 5).step(1))
.build())
.build())
-
+
//Spider's Den
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.spidersDen"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java
index ba76a903..c63b933d 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java
@@ -13,7 +13,7 @@ public class MessageFilterCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.messages"))
-
+
//Uncategorized Options
.option(Option.<ChatFilterResult>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.messages.hideAbility"))
@@ -31,6 +31,7 @@ public class MessageFilterCategory {
.build())
.option(Option.<ChatFilterResult>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.messages.hideAOTE"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.messages.hideAOTE.@Tooltip")))
.binding(defaults.messages.hideAOTE,
() -> config.messages.hideAOTE,
newValue -> config.messages.hideAOTE = newValue)
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java
index 775a0ae1..e2684115 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java
@@ -14,7 +14,7 @@ public class QuickNavigationCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.quickNav"))
-
+
//Toggle
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.enableQuickNav"))
@@ -23,7 +23,7 @@ public class QuickNavigationCategory {
newValue -> config.quickNav.enableQuickNav = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
-
+
//Button 1
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 1))
@@ -71,7 +71,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 2
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 2))
@@ -119,7 +119,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 3
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 3))
@@ -167,7 +167,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 4
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 4))
@@ -215,7 +215,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 5
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 5))
@@ -263,7 +263,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 6
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 6))
@@ -311,7 +311,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 7
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 7))
@@ -359,7 +359,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 8
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 8))
@@ -407,7 +407,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 9
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 9))
@@ -455,7 +455,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 10
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 10))
@@ -503,7 +503,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 11
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 11))
@@ -551,7 +551,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 12
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 12))
@@ -599,7 +599,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
.build();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
index 2d8b1332..7df95172 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
@@ -16,7 +16,7 @@ public class SlayersCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.slayer"))
-
+
//Vampire Slayer
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.slayer.vampireSlayer"))
@@ -110,7 +110,7 @@ public class SlayersCategory {
.controller(opt -> IntegerSliderControllerBuilder.create(opt).range(1, 10).step(1))
.build())
.build())
-
+
.build();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java
new file mode 100644
index 00000000..1fc22d2a
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java
@@ -0,0 +1,14 @@
+package de.hysky.skyblocker.debug;
+
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.loader.api.FabricLoader;
+
+public class Debug {
+ private static final boolean DEBUG_ENABLED = Boolean.parseBoolean(System.getProperty("skyblocker.debug", "false"));
+
+ public static void init() {
+ if (DEBUG_ENABLED || FabricLoader.getInstance().isDevelopmentEnvironment()) {
+ ClientCommandRegistrationCallback.EVENT.register(DumpPlayersCommand::register);
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java b/src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java
new file mode 100644
index 00000000..5f6e0362
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java
@@ -0,0 +1,31 @@
+package de.hysky.skyblocker.debug;
+
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.CommandDispatcher;
+import de.hysky.skyblocker.SkyblockerMod;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.text.Text;
+
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
+
+public class DumpPlayersCommand {
+
+ static void register(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
+ dispatcher.register(literal(SkyblockerMod.NAMESPACE)
+ .then(literal("debug")
+ .then(literal("dumpPlayers")
+ .executes(context -> {
+ FabricClientCommandSource source = context.getSource();
+
+ source.getWorld().getEntities().forEach(e -> {
+ if (e instanceof PlayerEntity player) {
+ source.sendFeedback(Text.of("'" + player.getName().getString() + "'"));
+ }
+ });
+
+ return Command.SINGLE_SUCCESS;
+ }))));
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
index f68a4e94..384986ae 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
@@ -3,7 +3,7 @@ package de.hysky.skyblocker.mixin;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import de.hysky.skyblocker.skyblock.FishingHelper;
-import de.hysky.skyblocker.skyblock.diana.MythologicalRitual;
+import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonSecrets;
import de.hysky.skyblocker.utils.Utils;
import dev.cbyrne.betterinject.annotations.Inject;
diff --git a/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java b/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java
index 3a60bfbb..cad7cf38 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java
@@ -18,7 +18,7 @@ public class SocialInteractionsPlayerListWidgetMixin {
@WrapOperation(method = "setPlayers", at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", remap = false))
private Object skyblocker$hideInvalidPlayers(Map<Object, Object> map, Object uuid, Object entry, Operation<Object> operation) {
if (Utils.isOnSkyblock() && !((SocialInteractionsPlayerListEntry) entry).getName().matches("[A-Za-z0-9_]+")) return null;
-
+
return operation.call(map, uuid, entry);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java b/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java
index e723c998..42601546 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java
@@ -9,25 +9,21 @@ import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;
-import de.hysky.skyblocker.config.SkyblockerConfigManager;
-import de.hysky.skyblocker.skyblock.dungeon.StarredMobGlow;
+import de.hysky.skyblocker.skyblock.entity.MobGlow;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.entity.Entity;
@Mixin(WorldRenderer.class)
public class WorldRendererMixin {
-
@ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
- private boolean skyblocker$shouldStarredMobGlow(boolean original, @Local Entity entity, @Share("isGlowingStarredMob") LocalBooleanRef isGlowingStarredMob) {
- boolean isAStarredMobThatShouldGlow = SkyblockerConfigManager.get().locations.dungeons.starredMobGlow && StarredMobGlow.shouldMobGlow(entity);
-
- isGlowingStarredMob.set(isAStarredMobThatShouldGlow);
-
- return original || isAStarredMobThatShouldGlow;
+ private boolean skyblocker$shouldMobGlow(boolean original, @Local Entity entity, @Share("hasCustomGlow") LocalBooleanRef hasCustomGlow) {
+ boolean shouldGlow = MobGlow.shouldMobGlow(entity);
+ hasCustomGlow.set(shouldGlow);
+ return original || shouldGlow;
}
@ModifyVariable(method = "render", at = @At("STORE"), ordinal = 0)
- private int skyblocker$modifyGlowColor(int color, @Local Entity entity, @Share("isGlowingStarredMob") LocalBooleanRef isGlowingStarredMob) {
- return isGlowingStarredMob.get() ? StarredMobGlow.getGlowColor(entity) : color;
+ private int skyblocker$modifyGlowColor(int color, @Local Entity entity, @Share("hasCustomGlow") LocalBooleanRef hasCustomGlow) {
+ return hasCustomGlow.get() ? MobGlow.getGlowColor(entity) : color;
}
}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java b/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java
index d38e40cc..3c2bbc9a 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java
@@ -51,7 +51,7 @@ public class YggdrasilServicesKeyInfoMixin {
throw e;
}
}
-
+
@WrapOperation(method = "validateProperty", remap = false, at = @At(value = "INVOKE", target = "org/slf4j/Logger.error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false))
private void skyblocker$dontLogFailedSignatureValidation(Logger logger, String message, Object property, Object exception, Operation<Void> operation) {
if (!Utils.isOnHypixel()) operation.call(logger, message, property, exception);
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java
deleted file mode 100644
index ac24c09f..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.DoubleFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = DoubleFieldController.class, remap = false)
-public abstract class DoubleFieldControllerMixin extends NumberFieldController<Double> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
-
- public DoubleFieldControllerMixin(Option<Double> option, Function<Double, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java
deleted file mode 100644
index d67993c2..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.FloatFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = FloatFieldController.class, remap = false)
-public abstract class FloatFieldControllerMixin extends NumberFieldController<Float> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
-
- public FloatFieldControllerMixin(Option<Float> option, Function<Float, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java
deleted file mode 100644
index b95cbef7..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.IntegerFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = IntegerFieldController.class, remap = false)
-public abstract class IntegerFieldControllerMixin extends NumberFieldController<Integer> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
- public IntegerFieldControllerMixin(Option<Integer> option, Function<Integer, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-
- @Overwrite
- public boolean isInputValid(String input) {
- return super.isInputValid(input);
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java
deleted file mode 100644
index 99871e2e..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.LongFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = LongFieldController.class, remap = false)
-public abstract class LongFieldControllerMixin extends NumberFieldController<Long> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
- public LongFieldControllerMixin(Option<Long> option, Function<Long, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-
- @Overwrite
- public boolean isInputValid(String input) {
- return super.isInputValid(input);
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java
deleted file mode 100644
index 17a99cfd..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.ParsePosition;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.gui.controllers.slider.ISliderController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import dev.isxander.yacl3.impl.utils.YACLConstants;
-import net.minecraft.util.math.MathHelper;
-
-@Mixin(value = NumberFieldController.class, remap = false)
-public abstract class NumberFieldControllerMixin<T extends Number> implements ISliderController<T> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
- private static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance();
-
- @Overwrite
- public void setFromString(String value) {
- try {
- setPendingValue(MathHelper.clamp(NUMBER_FORMAT.parse(value).doubleValue(), min(), max()));
- } catch (ParseException ignore) {
- YACLConstants.LOGGER.warn("Failed to parse number: {}", value);
- }
- }
-
- @Overwrite
- public boolean isInputValid(String input) {
- input = input.replace(DECIMAL_FORMAT_SYMBOLS.getGroupingSeparator() + "", "");
- ParsePosition parsePosition = new ParsePosition(0);
- NUMBER_FORMAT.parse(input, parsePosition);
-
- return parsePosition.getIndex() == input.length();
- }
-
- @Overwrite
- protected String cleanupNumberString(String number) {
- throw new UnsupportedOperationException("This method should no longer be called.");
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java
index 4cd356a8..3456d1ad 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java
@@ -85,12 +85,11 @@ public class FancyStatusBars {
bars[bar].anchorNum = location;
// Count how many bars are in each location
- int layer1Count = 0, layer2Count = 0, rightCount = 0;
+ int layer1Count = 0, layer2Count = 0;
for (int i = 0; i < 4; i++) {
switch (bars[i].anchorNum) {
case 0 -> layer1Count++;
case 1 -> layer2Count++;
- case 2 -> rightCount++;
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java b/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java
index c290e5b8..e572d9dc 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java
@@ -102,7 +102,7 @@ public class TeleportOverlay {
@SuppressWarnings("DataFlowIssue")
BlockState state = client.world.getBlockState(pos);
if (!state.isAir() && client.world.getBlockState(pos.up()).isAir() && client.world.getBlockState(pos.up(2)).isAir()) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ RenderHelper.renderFilled(wrc, pos, COLOR_COMPONENTS, 0.5f, false);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java
index 08c22b27..5c7a01f9 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java
@@ -31,14 +31,13 @@ public class CreeperBeams {
private static final Logger LOGGER = LoggerFactory.getLogger(CreeperBeams.class.getName());
- // "missing, this palette looks like you stole it from a 2018 bootstrap webapp!"
private static final float[][] COLORS = {
DyeColor.LIGHT_BLUE.getColorComponents(),
- DyeColor.PINK.getColorComponents(),
- DyeColor.ORANGE.getColorComponents(),
+ DyeColor.LIME.getColorComponents(),
+ DyeColor.YELLOW.getColorComponents(),
DyeColor.MAGENTA.getColorComponents(),
};
- private static final float[] LIME_COLOR_COMPONENTS = DyeColor.LIME.getColorComponents();
+ private static final float[] GREEN_COLOR_COMPONENTS = DyeColor.GREEN.getColorComponents();
private static final int FLOOR_Y = 68;
private static final int BASE_Y = 74;
@@ -81,7 +80,7 @@ public class CreeperBeams {
if (base == null) {
return;
}
- Vec3d creeperPos = new Vec3d(base.getX() + 0.5, BASE_Y + 3.5, base.getZ() + 0.5);
+ Vec3d creeperPos = new Vec3d(base.getX() + 0.5, BASE_Y + 1.75, base.getZ() + 0.5);
ArrayList<BlockPos> targets = findTargets(world, base);
beams = findLines(creeperPos, targets);
}
@@ -242,9 +241,9 @@ public class CreeperBeams {
RenderHelper.renderOutline(wrc, outlineTwo, color, 3, false);
RenderHelper.renderLinesFromPoints(wrc, line, color, 1, 2);
} else {
- RenderHelper.renderOutline(wrc, outlineOne, LIME_COLOR_COMPONENTS, 1, false);
- RenderHelper.renderOutline(wrc, outlineTwo, LIME_COLOR_COMPONENTS, 1, false);
- RenderHelper.renderLinesFromPoints(wrc, line, LIME_COLOR_COMPONENTS, 0.75f, 1);
+ RenderHelper.renderOutline(wrc, outlineOne, GREEN_COLOR_COMPONENTS, 1, false);
+ RenderHelper.renderOutline(wrc, outlineTwo, GREEN_COLOR_COMPONENTS, 1, false);
+ RenderHelper.renderLinesFromPoints(wrc, line, GREEN_COLOR_COMPONENTS, 0.75f, 1);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
index df5f36ce..02b08254 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
@@ -13,7 +13,7 @@ public class DungeonMapConfigScreen extends Screen {
private int hudX = SkyblockerConfigManager.get().locations.dungeons.mapX;
private int hudY = SkyblockerConfigManager.get().locations.dungeons.mapY;
private final Screen parent;
-
+
protected DungeonMapConfigScreen() {
this(null);
}
@@ -57,7 +57,7 @@ public class DungeonMapConfigScreen extends Screen {
SkyblockerConfigManager.get().locations.dungeons.mapX = hudX;
SkyblockerConfigManager.get().locations.dungeons.mapY = hudY;
SkyblockerConfigManager.save();
-
+
this.client.setScreen(parent);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java
index 762a6e17..f40b7859 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java
@@ -1,18 +1,49 @@
package de.hysky.skyblocker.skyblock.dungeon;
+import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
+import net.minecraft.block.Block;
+import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.registry.Registries;
+import net.minecraft.util.Formatting;
import net.minecraft.util.math.BlockPos;
+import java.util.Map;
+
public class LividColor {
+ private static final Map<Block, Formatting> WOOL_TO_FORMATTING = Map.of(
+ Blocks.RED_WOOL, Formatting.RED,
+ Blocks.YELLOW_WOOL, Formatting.YELLOW,
+ Blocks.LIME_WOOL, Formatting.GREEN,
+ Blocks.GREEN_WOOL, Formatting.DARK_GREEN,
+ Blocks.BLUE_WOOL, Formatting.BLUE,
+ Blocks.MAGENTA_WOOL, Formatting.LIGHT_PURPLE,
+ Blocks.PURPLE_WOOL, Formatting.DARK_PURPLE,
+ Blocks.GRAY_WOOL, Formatting.GRAY,
+ Blocks.WHITE_WOOL, Formatting.WHITE
+ );
+ private static final Map<String, Formatting> LIVID_TO_FORMATTING = Map.of(
+ "Hockey Livid", Formatting.RED,
+ "Arcade Livid", Formatting.YELLOW,
+ "Smile Livid", Formatting.GREEN,
+ "Frog Livid", Formatting.DARK_GREEN,
+ "Scream Livid", Formatting.BLUE,
+ "Crossed Livid", Formatting.LIGHT_PURPLE,
+ "Purple Livid", Formatting.DARK_PURPLE,
+ "Doctor Livid", Formatting.GRAY,
+ "Vendetta Livid", Formatting.WHITE
+ );
private static int tenTicks = 0;
+ private static Formatting color;
public static void init() {
ClientReceiveMessageEvents.GAME.register((message, overlay) -> {
- if (SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColor && message.getString().equals("[BOSS] Livid: I respect you for making it to here, but I'll be your undoing.")) {
+ SkyblockerConfig.LividColor config = SkyblockerConfigManager.get().locations.dungeons.lividColor;
+ if ((config.enableLividColorText || config.enableLividColorGlow) && message.getString().equals("[BOSS] Livid: I respect you for making it to here, but I'll be your undoing.")) {
tenTicks = 8;
}
});
@@ -21,16 +52,15 @@ public class LividColor {
public static void update() {
MinecraftClient client = MinecraftClient.getInstance();
if (tenTicks != 0) {
- if (SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColor && Utils.isInDungeons() && client.world != null) {
+ SkyblockerConfig.LividColor config = SkyblockerConfigManager.get().locations.dungeons.lividColor;
+ if ((config.enableLividColorText || config.enableLividColorGlow) && Utils.isInDungeons() && client.world != null) {
if (tenTicks == 1) {
- MessageScheduler.INSTANCE.sendMessageAfterCooldown(SkyblockerConfigManager.get().locations.dungeons.lividColor.lividColorText.replace("[color]", "red"));
- tenTicks = 0;
+ onLividColorFound(Blocks.RED_WOOL);
return;
}
- String key = client.world.getBlockState(new BlockPos(5, 110, 42)).getBlock().getTranslationKey();
- if (key.startsWith("block.minecraft.") && key.endsWith("wool") && !key.endsWith("red_wool")) {
- MessageScheduler.INSTANCE.sendMessageAfterCooldown(SkyblockerConfigManager.get().locations.dungeons.lividColor.lividColorText.replace("[color]", key.substring(16, key.length() - 5)));
- tenTicks = 0;
+ Block color = client.world.getBlockState(new BlockPos(5, 110, 42)).getBlock();
+ if (WOOL_TO_FORMATTING.containsKey(color) && !color.equals(Blocks.RED_WOOL)) {
+ onLividColorFound(color);
return;
}
tenTicks--;
@@ -39,4 +69,22 @@ public class LividColor {
}
}
}
+
+ private static void onLividColorFound(Block color) {
+ LividColor.color = WOOL_TO_FORMATTING.get(color);
+ if (SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColorText) {
+ String colorString = Registries.BLOCK.getId(color).getPath();
+ MessageScheduler.INSTANCE.sendMessageAfterCooldown(SkyblockerConfigManager.get().locations.dungeons.lividColor.lividColorText.replaceAll("\\[color]", colorString.substring(0, colorString.length() - 5)));
+ }
+ tenTicks = 0;
+ }
+
+ public static boolean shouldGlow(String name) {
+ return SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColorGlow && color == LIVID_TO_FORMATTING.get(name);
+ }
+
+ @SuppressWarnings("DataFlowIssue")
+ public static int getGlowColor(String name) {
+ return LIVID_TO_FORMATTING.containsKey(name) ? LIVID_TO_FORMATTING.get(name).getColorValue() : Formatting.WHITE.getColorValue();
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java
deleted file mode 100644
index 2072017d..00000000
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.hysky.skyblocker.skyblock.dungeon;
-
-import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.decoration.ArmorStandEntity;
-import net.minecraft.entity.passive.BatEntity;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.predicate.entity.EntityPredicates;
-import net.minecraft.util.math.Box;
-
-import java.util.List;
-
-public class StarredMobGlow {
-
- public static boolean shouldMobGlow(Entity entity) {
- Box box = entity.getBoundingBox();
-
- if (Utils.isInDungeons() && !entity.isInvisible() && OcclusionCulling.isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) {
- // Minibosses
- if (entity instanceof PlayerEntity) {
- switch (entity.getName().getString()) {
- case "Lost Adventurer", "Shadow Assassin", "Diamond Guy" -> {
- return true;
- }
- }
- }
-
- // Regular Mobs
- if (!(entity instanceof ArmorStandEntity)) {
- Box searchBox = box.expand(0, 2, 0);
- List<ArmorStandEntity> armorStands = entity.getWorld().getEntitiesByClass(ArmorStandEntity.class, searchBox, EntityPredicates.NOT_MOUNTED);
-
- if (!armorStands.isEmpty() && armorStands.get(0).getName().getString().contains("✯")) return true;
- }
-
- // Bats
- return entity instanceof BatEntity;
- }
-
- return false;
- }
-
- public static int getGlowColor(Entity entity) {
- if (entity instanceof PlayerEntity) {
- return switch (entity.getName().getString()) {
- case "Lost Adventurer" -> 0xfee15c;
- case "Shadow Assassin" -> 0x5b2cb2;
- case "Diamond Guy" -> 0x57c2f7;
- default -> 0xf57738;
- };
- }
-
- return 0xf57738;
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java
index 262d4a4e..53368c14 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java
@@ -1,7 +1,7 @@
package de.hysky.skyblocker.skyblock.dungeon;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
-import de.hysky.skyblocker.skyblock.FairySouls;
+import de.hysky.skyblocker.skyblock.waypoint.FairySouls;
import de.hysky.skyblocker.utils.chat.ChatFilterResult;
import de.hysky.skyblocker.utils.chat.ChatPatternListener;
import net.minecraft.client.MinecraftClient;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java
index eda08cf6..ee517eb8 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java
@@ -255,7 +255,7 @@ public class DungeonSecrets {
dungeonFutures.add(CompletableFuture.runAsync(() -> {
try (BufferedReader customWaypointsReader = Files.newBufferedReader(CUSTOM_WAYPOINTS_DIR)) {
SkyblockerMod.GSON.fromJson(customWaypointsReader, JsonObject.class).asMap().forEach((room, waypointsJson) ->
- addCustomWaypoints(room, SecretWaypoint.LIST_CODEC.parse(JsonOps.INSTANCE, waypointsJson).resultOrPartial(LOGGER::error).orElseThrow())
+ addCustomWaypoints(room, SecretWaypoint.LIST_CODEC.parse(JsonOps.INSTANCE, waypointsJson).resultOrPartial(LOGGER::error).orElseGet(ArrayList::new))
);
LOGGER.debug("[Skyblocker Dungeon Secrets] Loaded custom dungeon secret waypoints");
} catch (Exception e) {
@@ -273,7 +273,7 @@ public class DungeonSecrets {
try (BufferedWriter writer = Files.newBufferedWriter(CUSTOM_WAYPOINTS_DIR)) {
JsonObject customWaypointsJson = new JsonObject();
customWaypoints.rowMap().forEach((room, waypoints) ->
- customWaypointsJson.add(room, SecretWaypoint.LIST_CODEC.encodeStart(JsonOps.INSTANCE, new ArrayList<>(waypoints.values())).resultOrPartial(LOGGER::error).orElseThrow())
+ customWaypointsJson.add(room, SecretWaypoint.LIST_CODEC.encodeStart(JsonOps.INSTANCE, new ArrayList<>(waypoints.values())).resultOrPartial(LOGGER::error).orElseGet(JsonArray::new))
);
SkyblockerMod.GSON.toJson(customWaypointsJson, writer);
LOGGER.info("[Skyblocker Dungeon Secrets] Saved custom dungeon secret waypoints");
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
index ecfcf496..9b95f146 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
@@ -41,6 +41,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Room {
+ private static final Pattern SECRET_INDEX = Pattern.compile("^(\\d+)");
private static final Pattern SECRETS = Pattern.compile("§7(\\d{1,2})/(\\d{1,2}) Secrets");
@NotNull
private final Type type;
@@ -70,11 +71,12 @@ public class Room {
private int doubleCheckBlocks;
/**
* Represents the matching state of the room with the following possible values:
- * <li>{@link TriState#DEFAULT} means that the room has not been checked, is being processed, or does not {@link Type#needsScanning() need to be processed}.
- * <li>{@link TriState#FALSE} means that the room has been checked and there is no match.
- * <li>{@link TriState#TRUE} means that the room has been checked and there is a match.
+ * <li>{@link MatchState#MATCHING} means that the room has not been checked, is being processed, or does not {@link Type#needsScanning() need to be processed}.</li>
+ * <li>{@link MatchState#DOUBLE_CHECKING} means that the room has a unique match and is being double checked.</li>
+ * <li>{@link MatchState#MATCHED} means that the room has a unique match ans has been double checked.</li>
+ * <li>{@link MatchState#FAILED} means that the room has been checked and there is no match.</li>
*/
- private TriState matched = TriState.DEFAULT;
+ private MatchState matchState = MatchState.MATCHING;
private Table<Integer, BlockPos, SecretWaypoint> secretWaypoints;
private String name;
private Direction direction;
@@ -96,7 +98,7 @@ public class Room {
}
public boolean isMatched() {
- return matched == TriState.TRUE;
+ return matchState == MatchState.DOUBLE_CHECKING || matchState == MatchState.MATCHED;
}
/**
@@ -108,7 +110,7 @@ public class Room {
@Override
public String toString() {
- return "Room{type=" + type + ", shape=" + shape + ", matched=" + matched + ", segments=" + Arrays.toString(segments.toArray()) + "}";
+ return "Room{type=%s, segments=%s, shape=%s, matchState=%s, name=%s, direction=%s, physicalCornerPos=%s}".formatted(type, Arrays.toString(segments.toArray()), shape, matchState, name, direction, physicalCornerPos);
}
@NotNull
@@ -208,6 +210,7 @@ public class Room {
/**
* Removes a custom waypoint relative to this room from {@link DungeonSecrets#customWaypoints} and all existing instances of this room.
+ *
* @param pos the position of the secret waypoint relative to this room
* @return the removed secret waypoint or {@code null} if there was no secret waypoint at the given position
*/
@@ -223,6 +226,7 @@ public class Room {
/**
* Removes a custom waypoint relative to this room from this instance of the room.
+ *
* @param secretIndex the index of the secret waypoint
* @param relativePos the position of the secret waypoint relative to this room
*/
@@ -237,7 +241,7 @@ public class Room {
* This method returns immediately if any of the following conditions are met:
* <ul>
* <li> The room does not need to be scanned and matched. (When the room is not of type {@link Type.ROOM}, {@link Type.PUZZLE}, or {@link Type.TRAP}. See {@link Type#needsScanning()}) </li>
- * <li> The room has been matched or failed to match and is on cooldown. See {@link #matched}. </li>
+ * <li> The room has been matched or failed to match and is on cooldown. See {@link #matchState}. </li>
* <li> {@link #findRoom The previous update} has not completed. </li>
* </ul>
* Then this method tries to match this room through:
@@ -251,7 +255,7 @@ public class Room {
@SuppressWarnings("JavadocReference")
protected void update() {
// Logical AND has higher precedence than logical OR
- if (!type.needsScanning() || matched != TriState.DEFAULT || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) {
+ if (!type.needsScanning() || matchState != MatchState.MATCHING && matchState != MatchState.DOUBLE_CHECKING || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) {
return;
}
MinecraftClient client = MinecraftClient.getInstance();
@@ -266,6 +270,9 @@ public class Room {
break;
}
}
+ }).exceptionally(e -> {
+ DungeonSecrets.LOGGER.error("[Skyblocker Dungeon Secrets] Encountered an unknown exception while matching room {}", this, e);
+ return null;
});
}
@@ -297,16 +304,24 @@ public class Room {
* </ul>
* <li> If there are no matching rooms left: </li>
* <ul>
- * <li> Terminate matching by setting {@link #matched} to {@link TriState#FALSE}. </li>
+ * <li> Terminate matching by setting {@link #matchState} to {@link TriState#FALSE}. </li>
* <li> Schedule another matching attempt in 50 ticks (2.5 seconds). </li>
* <li> Reset {@link #possibleRooms} and {@link #checkedBlocks} with {@link #reset()}. </li>
* <li> Return {@code true} </li>
* </ul>
* <li> If there are exactly one room matching: </li>
* <ul>
- * <li> Call {@link #roomMatched()}. </li>
- * <li> Discard the no longer needed fields to save memory. </li>
- * <li> Return {@code true} </li>
+ * <li> If {@link #matchState} is {@link MatchState#MATCHING}: </li>
+ * <ul>
+ * <li> Call {@link #roomMatched()}. </li>
+ * <li> Return {@code false}. </li>
+ * </ul>
+ * <li> If {@link #matchState} is {@link MatchState#DOUBLE_CHECKING}: </li>
+ * <ul>
+ * <li> Set the match state to {@link MatchState#MATCHED}. </li>
+ * <li> Discard the no longer needed fields to save memory. </li>
+ * <li> Return {@code true}. </li>
+ * </ul>
* </ul>
* <li> Return {@code false} </li>
* </ul>
@@ -334,26 +349,29 @@ public class Room {
int matchingRoomsSize = possibleRooms.stream().map(Triple::getRight).mapToInt(Collection::size).sum();
if (matchingRoomsSize == 0) {
// If no rooms match, reset the fields and scan again after 50 ticks.
- matched = TriState.FALSE;
- DungeonSecrets.LOGGER.warn("[Skyblocker] No dungeon room matches after checking {} block(s)", checkedBlocks.size());
- Scheduler.INSTANCE.schedule(() -> matched = TriState.DEFAULT, 50);
+ DungeonSecrets.LOGGER.warn("[Skyblocker Dungeon Secrets] No dungeon room matched after checking {} block(s) including double checking {} block(s)", checkedBlocks.size(), doubleCheckBlocks);
+ Scheduler.INSTANCE.schedule(() -> matchState = MatchState.MATCHING, 50);
reset();
return true;
- } else if (matchingRoomsSize == 1 && ++doubleCheckBlocks >= 10) {
- // If one room matches, load the secrets for that room and discard the no longer needed fields.
- for (Triple<Direction, Vector2ic, List<String>> directionRooms : possibleRooms) {
- if (directionRooms.getRight().size() == 1) {
- name = directionRooms.getRight().get(0);
- direction = directionRooms.getLeft();
- physicalCornerPos = directionRooms.getMiddle();
- roomMatched();
- discard();
- return true;
- }
+ } else if (matchingRoomsSize == 1) {
+ if (matchState == MatchState.MATCHING) {
+ // If one room matches, load the secrets for that room and set state to double-checking.
+ Triple<Direction, Vector2ic, List<String>> directionRoom = possibleRooms.stream().filter(directionRooms -> directionRooms.getRight().size() == 1).findAny().orElseThrow();
+ name = directionRoom.getRight().get(0);
+ direction = directionRoom.getLeft();
+ physicalCornerPos = directionRoom.getMiddle();
+ DungeonSecrets.LOGGER.info("[Skyblocker Dungeon Secrets] Room {} matched after checking {} block(s), starting double checking", name, checkedBlocks.size());
+ roomMatched();
+ return false;
+ } else if (matchState == MatchState.DOUBLE_CHECKING && ++doubleCheckBlocks >= 10) {
+ // If double-checked, set state to matched and discard the no longer needed fields.
+ DungeonSecrets.LOGGER.info("[Skyblocker Dungeon Secrets] Room {} matched after checking {} block(s) including double checking {} block(s)", name, checkedBlocks.size(), doubleCheckBlocks);
+ discard();
+ return true;
}
- return false; // This should never happen, we just checked that there is one possible room, and the return true in the loop should activate
+ return false;
} else {
- DungeonSecrets.LOGGER.debug("[Skyblocker] {} room(s) remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size());
+ DungeonSecrets.LOGGER.debug("[Skyblocker Dungeon Secrets] {} room(s) remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size());
return false;
}
}
@@ -371,7 +389,7 @@ public class Room {
/**
* Loads the secret waypoints for the room from {@link DungeonSecrets#waypointsJson} once it has been matched
- * and sets {@link #matched} to {@link TriState#TRUE}.
+ * and sets {@link #matchState} to {@link MatchState#DOUBLE_CHECKING}.
*
* @param directionRooms the direction, position, and name of the room
*/
@@ -381,25 +399,29 @@ public class Room {
for (JsonElement waypointElement : DungeonSecrets.getRoomWaypoints(name)) {
JsonObject waypoint = waypointElement.getAsJsonObject();
String secretName = waypoint.get("secretName").getAsString();
- int secretIndex = Integer.parseInt(secretName.substring(0, Character.isDigit(secretName.charAt(1)) ? 2 : 1));
+ Matcher secretIndexMatcher = SECRET_INDEX.matcher(secretName);
+ int secretIndex = secretIndexMatcher.find() ? Integer.parseInt(secretIndexMatcher.group(1)) : 0;
BlockPos pos = DungeonMapUtils.relativeToActual(direction, physicalCornerPos, waypoint);
secretWaypoints.put(secretIndex, pos, new SecretWaypoint(secretIndex, waypoint, secretName, pos));
}
DungeonSecrets.getCustomWaypoints(name).values().forEach(this::addCustomWaypoint);
- matched = TriState.TRUE;
-
- DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size());
+ matchState = MatchState.DOUBLE_CHECKING;
}
/**
* Resets fields for another round of matching after room matching fails.
*/
private void reset() {
+ matchState = MatchState.FAILED;
IntSortedSet segmentsX = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::x).toArray()));
IntSortedSet segmentsY = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::y).toArray()));
possibleRooms = getPossibleRooms(segmentsX, segmentsY);
checkedBlocks = new HashSet<>();
doubleCheckBlocks = 0;
+ secretWaypoints = null;
+ name = null;
+ direction = null;
+ physicalCornerPos = null;
}
/**
@@ -407,6 +429,7 @@ public class Room {
* These fields are no longer needed and are discarded to save memory.
*/
private void discard() {
+ matchState = MatchState.MATCHED;
roomsData = null;
possibleRooms = null;
checkedBlocks = null;
@@ -473,7 +496,7 @@ public class Room {
BlockState state = world.getBlockState(hitResult.getBlockPos());
if (state.isOf(Blocks.CHEST) || state.isOf(Blocks.PLAYER_HEAD) || state.isOf(Blocks.PLAYER_WALL_HEAD)) {
secretWaypoints.column(hitResult.getBlockPos()).values().stream().filter(SecretWaypoint::needsInteraction).findAny()
- .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker] Detected {} interaction, setting secret #{} as found", secretWaypoint.category, secretWaypoint.secretIndex));
+ .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} interaction, setting secret #{} as found", secretWaypoint.category, secretWaypoint.secretIndex));
} else if (state.isOf(Blocks.LEVER)) {
secretWaypoints.column(hitResult.getBlockPos()).values().stream().filter(SecretWaypoint::isLever).forEach(SecretWaypoint::setFound);
}
@@ -491,7 +514,7 @@ public class Room {
return;
}
secretWaypoints.values().stream().filter(SecretWaypoint::needsItemPickup).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(collector))).filter(SecretWaypoint.getRangePredicate(collector))
- .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker] Detected {} picked up a {} from a {} secret, setting secret #{} as found", collector.getName().getString(), itemEntity.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
+ .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} picked up a {} from a {} secret, setting secret #{} as found", collector.getName().getString(), itemEntity.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
}
/**
@@ -502,7 +525,7 @@ public class Room {
*/
protected void onBatRemoved(AmbientEntity bat) {
secretWaypoints.values().stream().filter(SecretWaypoint::isBat).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(bat)))
- .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker] Detected {} killed for a {} secret, setting secret #{} as found", bat.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
+ .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} killed for a {} secret, setting secret #{} as found", bat.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
}
/**
@@ -575,4 +598,8 @@ public class Room {
public enum Direction {
NW, NE, SW, SE
}
+
+ public enum MatchState {
+ MATCHING, DOUBLE_CHECKING, MATCHED, FAILED
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
index 0c2d1b34..43f624f6 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
@@ -20,6 +20,8 @@ import net.minecraft.util.dynamic.Codecs;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.function.Predicate;
@@ -27,6 +29,7 @@ import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
public class SecretWaypoint extends Waypoint {
+ protected static final Logger LOGGER = LoggerFactory.getLogger(SecretWaypoint.class);
public static final Codec<SecretWaypoint> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.INT.fieldOf("secretIndex").forGetter(secretWaypoint -> secretWaypoint.secretIndex),
Category.CODEC.fieldOf("category").forGetter(secretWaypoint -> secretWaypoint.category),
@@ -35,8 +38,8 @@ public class SecretWaypoint extends Waypoint {
).apply(instance, SecretWaypoint::new));
public static final Codec<List<SecretWaypoint>> LIST_CODEC = CODEC.listOf();
static final List<String> SECRET_ITEMS = List.of("Decoy", "Defuse Kit", "Dungeon Chest Key", "Healing VIII", "Inflatable Jerry", "Spirit Leap", "Training Weights", "Trap", "Treasure Talisman");
- private static final SkyblockerConfig.SecretWaypoints CONFIG = SkyblockerConfigManager.get().locations.dungeons.secretWaypoints;
- private static final Supplier<Type> TYPE_SUPPLIER = () -> CONFIG.waypointType;
+ private static final Supplier<SkyblockerConfig.SecretWaypoints> CONFIG = () -> SkyblockerConfigManager.get().locations.dungeons.secretWaypoints;
+ private static final Supplier<Type> TYPE_SUPPLIER = () -> CONFIG.get().waypointType;
final int secretIndex;
final Category category;
final Text name;
@@ -95,7 +98,7 @@ public class SecretWaypoint extends Waypoint {
//TODO In the future, shrink the box for wither essence and items so its more realistic
super.render(context);
- if (CONFIG.showSecretText) {
+ if (CONFIG.get().showSecretText) {
Vec3d posUp = centerPos.add(0, 1, 0);
RenderHelper.renderText(context, name, posUp, true);
double distance = context.camera().getPos().distanceTo(centerPos);
@@ -135,8 +138,8 @@ public class SecretWaypoint extends Waypoint {
}
}
- private static Category get(JsonObject waypointJson) {
- return CODEC.parse(JsonOps.INSTANCE, waypointJson.get("category")).resultOrPartial(DungeonSecrets.LOGGER::error).orElseThrow();
+ static Category get(JsonObject waypointJson) {
+ return CODEC.parse(JsonOps.INSTANCE, waypointJson.get("category")).resultOrPartial(LOGGER::error).orElse(Category.DEFAULT);
}
boolean needsInteraction() {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
index 9bd6bef1..6f281ba9 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
@@ -23,7 +23,7 @@ public class DwarvenHudConfigScreen extends Screen {
protected DwarvenHudConfigScreen() {
this(null);
}
-
+
public DwarvenHudConfigScreen(Screen parent) {
super(Text.of("Dwarven HUD Config"));
this.parent = parent;
@@ -62,7 +62,7 @@ public class DwarvenHudConfigScreen extends Screen {
SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x = hudX;
SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y = hudY;
SkyblockerConfigManager.save();
-
+
client.setScreen(parent);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
new file mode 100644
index 00000000..5e0995e6
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
@@ -0,0 +1,83 @@
+package de.hysky.skyblocker.skyblock.entity;
+
+import java.util.List;
+
+import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.dungeon.LividColor;
+import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.decoration.ArmorStandEntity;
+import net.minecraft.entity.passive.BatEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.predicate.entity.EntityPredicates;
+import net.minecraft.util.Formatting;
+import net.minecraft.util.math.Box;
+import net.minecraft.world.World;
+
+public class MobGlow {
+ public static boolean shouldMobGlow(Entity entity) {
+ Box box = entity.getBoundingBox();
+
+ if (!entity.isInvisible() && OcclusionCulling.isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) {
+ String name = entity.getName().getString();
+
+ // Dungeons
+ if (Utils.isInDungeons()) {
+
+ // Minibosses
+ if (entity instanceof PlayerEntity) {
+ switch (name) {
+ case "Lost Adventurer", "Shadow Assassin", "Diamond Guy": return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow;
+ case "Arcade Livid", "Crossed Livid", "Doctor Livid", "Frog Livid", "Hockey Livid",
+ "Purple Livid", "Scream Livid", "Smile Livid", "Vendetta Livid": return LividColor.shouldGlow(name);
+ }
+ }
+
+ // Regular Mobs
+ if (!(entity instanceof ArmorStandEntity)) {
+ List<ArmorStandEntity> armorStands = getArmorStands(entity.getWorld(), box);
+
+ if (!armorStands.isEmpty() && armorStands.get(0).getName().getString().contains("✯")) return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow;
+ }
+
+ // Bats
+ return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow && entity instanceof BatEntity;
+ }
+
+ // Rift
+ if (Utils.isInTheRift()) {
+ if (entity instanceof PlayerEntity) {
+ switch (name) {
+ // They have a space in their name for some reason...
+ case "Blobbercyst ": return SkyblockerConfigManager.get().locations.rift.blobbercystGlow;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static List<ArmorStandEntity> getArmorStands(World world, Box box) {
+ return world.getEntitiesByClass(ArmorStandEntity.class, box.expand(0, 2, 0), EntityPredicates.NOT_MOUNTED);
+ }
+
+ public static int getGlowColor(Entity entity) {
+ String name = entity.getName().getString();
+
+ if (entity instanceof PlayerEntity) {
+ return switch (name) {
+ case "Lost Adventurer" -> 0xfee15c;
+ case "Shadow Assassin" -> 0x5b2cb2;
+ case "Diamond Guy" -> 0x57c2f7;
+ case "Arcade Livid", "Crossed Livid", "Doctor Livid", "Frog Livid", "Hockey Livid",
+ "Purple Livid", "Scream Livid", "Smile Livid", "Vendetta Livid" -> LividColor.getGlowColor(name);
+ case "Blobbercyst " -> Formatting.GREEN.getColorValue();
+ default -> 0xf57738;
+ };
+ }
+
+ return 0xf57738;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java
index 5fd6f741..d6a40d2d 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java
@@ -5,8 +5,8 @@ import de.hysky.skyblocker.utils.chat.ChatFilterResult;
public class ComboFilter extends SimpleChatFilter {
public ComboFilter() {
- super("^(\\+\\d+ Kill Combo \\+\\d+(% ✯ Magic Find| coins per kill|% Combat Exp)" +
- "|Your Kill Combo has expired! You reached a \\d+ Kill Combo!)$");
+ // ^(\+\d+ Kill Combo( \+\d+(✯ Magic Find| coins per kill|☯ Combat Wisdom))?|Your Kill Combo has expired! You reached a \d+ Kill Combo!)$
+ super("^(\\+\\d+ Kill Combo( \\+\\d+(✯ Magic Find| coins per kill|☯ Combat Wisdom))?|Your Kill Combo has expired! You reached a \\d+ Kill Combo!)$");
}
@Override
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java b/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java
index cec84b38..3434f026 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java
@@ -145,7 +145,7 @@ public class CustomArmorTrims {
Identifier.CODEC.fieldOf("material").forGetter(ArmorTrimId::material),
Identifier.CODEC.fieldOf("pattern").forGetter(ArmorTrimId::pattern))
.apply(instance, ArmorTrimId::new));
-
+
@Override
public Identifier left() {
return material();
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
index 9e1df2bb..8867af91 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
@@ -1,8 +1,14 @@
package de.hysky.skyblocker.skyblock.item;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
import com.google.common.collect.ImmutableMap;
import com.mojang.blaze3d.systems.RenderSystem;
-import de.hysky.skyblocker.SkyblockerMod;
+
+import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
@@ -16,16 +22,10 @@ import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.texture.Sprite;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
-import net.minecraft.util.Identifier;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
public class ItemRarityBackgrounds {
- private static final Identifier RARITY_BG_TEX = new Identifier(SkyblockerMod.NAMESPACE, "item_rarity_background");
- private static final Supplier<Sprite> SPRITE = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(RARITY_BG_TEX);
+ private static final SkyblockerConfig.ItemInfoDisplay CONFIG = SkyblockerConfigManager.get().general.itemInfoDisplay;
+ private static final Supplier<Sprite> SPRITE = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(CONFIG.itemRarityBackgroundStyle.tex);
private static final ImmutableMap<String, SkyblockItemRarity> LORE_RARITIES = ImmutableMap.ofEntries(
Map.entry("ADMIN", SkyblockItemRarity.ADMIN),
Map.entry("SPECIAL", SkyblockItemRarity.SPECIAL), //Very special is the same color so this will cover it
@@ -39,27 +39,27 @@ public class ItemRarityBackgrounds {
Map.entry("COMMON", SkyblockItemRarity.COMMON)
);
private static final Int2ReferenceOpenHashMap<SkyblockItemRarity> CACHE = new Int2ReferenceOpenHashMap<>();
-
+
public static void init() {
//Clear the cache every 5 minutes, ints are very compact!
Scheduler.INSTANCE.scheduleCyclic(CACHE::clear, 4800);
-
+
//Clear cache after a screen where items can be upgraded in rarity closes
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
String title = screen.getTitle().getString();
-
+
if (Utils.isOnSkyblock() && (title.equals("The Hex") || title.equals("Craft Item") || title.equals("Anvil") || title.equals("Reforge Anvil"))) {
ScreenEvents.remove(screen).register(screen1 -> CACHE.clear());
}
});
}
-
+
public static void tryDraw(ItemStack stack, DrawContext context, int x, int y) {
MinecraftClient client = MinecraftClient.getInstance();
-
+
if (client.player != null) {
SkyblockItemRarity itemRarity = getItemRarity(stack, client.player);
-
+
if (itemRarity != null) draw(context, x, y, itemRarity);
}
}
@@ -73,30 +73,30 @@ public class ItemRarityBackgrounds {
int hashCode = itemUuid.isEmpty() ? System.identityHashCode(stack) : itemUuid.hashCode();
if (CACHE.containsKey(hashCode)) return CACHE.get(hashCode);
-
+
List<Text> tooltip = stack.getTooltip(player, TooltipContext.BASIC);
String[] stringifiedTooltip = tooltip.stream().map(Text::getString).toArray(String[]::new);
-
+
for (String rarityString : LORE_RARITIES.keySet()) {
if (Arrays.stream(stringifiedTooltip).anyMatch(line -> line.contains(rarityString))) {
SkyblockItemRarity rarity = LORE_RARITIES.get(rarityString);
-
+
CACHE.put(hashCode, rarity);
return rarity;
}
}
-
+
CACHE.put(hashCode, null);
return null;
}
-
+
private static void draw(DrawContext context, int x, int y, SkyblockItemRarity rarity) {
//Enable blending to handle HUD translucency
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
context.drawSprite(x, y, 0, 16, 16, SPRITE.get(), rarity.r, rarity.g, rarity.b, SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgroundsOpacity);
-
+
RenderSystem.disableBlend();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java b/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java
index ac9b1bf0..823c4c99 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java
@@ -40,18 +40,19 @@ public class MuseumItemCache {
private static final Path CACHE_FILE = SkyblockerMod.CONFIG_DIR.resolve("museum_item_cache.json");
private static final Object2ObjectOpenHashMap<String, Object2ObjectOpenHashMap<String, ProfileMuseumData>> MUSEUM_ITEM_CACHE = new Object2ObjectOpenHashMap<>();
private static final Type MAP_TYPE = new TypeToken<Object2ObjectOpenHashMap<String, Object2ObjectOpenHashMap<String, ProfileMuseumData>>>() {}.getType();
-
+ private static final String ERROR_LOG_TEMPLATE = "[Skyblocker] Failed to refresh museum item data for profile {}";
+
private static CompletableFuture<Void> loaded;
public static void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(MuseumItemCache::load);
}
-
+
private static void load(MinecraftClient client) {
loaded = CompletableFuture.runAsync(() -> {
try (BufferedReader reader = Files.newBufferedReader(CACHE_FILE)) {
Object2ObjectOpenHashMap<String, Object2ObjectOpenHashMap<String, ProfileMuseumData>> cachedData = SkyblockerMod.GSON.fromJson(reader, MAP_TYPE);
-
+
MUSEUM_ITEM_CACHE.putAll(cachedData);
LOGGER.info("[Skyblocker] Loaded museum items cache");
} catch (NoSuchFileException ignored) {
@@ -60,7 +61,7 @@ public class MuseumItemCache {
}
});
}
-
+
private static void save() {
CompletableFuture.runAsync(() -> {
try (BufferedWriter writer = Files.newBufferedWriter(CACHE_FILE)) {
@@ -70,48 +71,70 @@ public class MuseumItemCache {
}
});
}
-
+
private static void updateData4ProfileMember(String uuid, String profileId) {
CompletableFuture.runAsync(() -> {
try (ApiResponse response = Http.sendHypixelRequest("skyblock/museum", "?profile=" + profileId)) {
//The request was successful
if (response.ok()) {
JsonObject profileData = JsonParser.parseString(response.content()).getAsJsonObject();
- JsonObject memberData = profileData.get("members").getAsJsonObject().get(uuid).getAsJsonObject();
-
- //We call them sets because it could either be a singular item or an entire armour set
- Map<String, JsonElement> donatedSets = memberData.get("items").getAsJsonObject().asMap();
-
- //Set of all found item ids on profile
- ObjectOpenHashSet<String> itemIds = new ObjectOpenHashSet<>();
-
- for (Map.Entry<String, JsonElement> donatedSet : donatedSets.entrySet()) {
- //Item is plural here because the nbt is a list
- String itemsData = donatedSet.getValue().getAsJsonObject().get("items").getAsJsonObject().get("data").getAsString();
- NbtList items = NbtIo.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(itemsData))).getList("i", NbtElement.COMPOUND_TYPE);
-
- for (int i = 0; i < items.size(); i++) {
- NbtCompound tag = items.getCompound(i).getCompound("tag");
-
- if (tag.contains("ExtraAttributes")) {
- NbtCompound extraAttributes = tag.getCompound("ExtraAttributes");
-
- if (extraAttributes.contains("id")) itemIds.add(extraAttributes.getString("id"));
+ JsonObject members = profileData.getAsJsonObject("members");
+
+ if (members.has(uuid)) {
+ JsonObject memberData = members.get(uuid).getAsJsonObject();
+
+ //We call them sets because it could either be a singular item or an entire armour set
+ Map<String, JsonElement> donatedSets = memberData.get("items").getAsJsonObject().asMap();
+
+ //Set of all found item ids on profile
+ ObjectOpenHashSet<String> itemIds = new ObjectOpenHashSet<>();
+
+ for (Map.Entry<String, JsonElement> donatedSet : donatedSets.entrySet()) {
+ //Item is plural here because the nbt is a list
+ String itemsData = donatedSet.getValue().getAsJsonObject().get("items").getAsJsonObject().get("data").getAsString();
+ NbtList items = NbtIo.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(itemsData))).getList("i", NbtElement.COMPOUND_TYPE);
+
+ for (int i = 0; i < items.size(); i++) {
+ NbtCompound tag = items.getCompound(i).getCompound("tag");
+
+ if (tag.contains("ExtraAttributes")) {
+ NbtCompound extraAttributes = tag.getCompound("ExtraAttributes");
+
+ if (extraAttributes.contains("id")) itemIds.add(extraAttributes.getString("id"));
+ }
}
}
+
+ MUSEUM_ITEM_CACHE.get(uuid).put(profileId, new ProfileMuseumData(System.currentTimeMillis(), itemIds));
+ save();
+
+ LOGGER.info("[Skyblocker] Successfully updated museum item cache for profile {}", profileId);
+ } else {
+ //If the player's Museum API is disabled
+ putEmpty(uuid, profileId);
+
+ LOGGER.warn(ERROR_LOG_TEMPLATE + " because the Museum API is disabled!", profileId);
}
-
- MUSEUM_ITEM_CACHE.get(uuid).put(profileId, new ProfileMuseumData(System.currentTimeMillis(), itemIds));
- save();
-
- LOGGER.info("[Skyblocker] Successfully updated museum item cache for profile {}", profileId);
+ } else {
+ //If the request returns a non 200 status code
+ putEmpty(uuid, profileId);
+
+ LOGGER.error(ERROR_LOG_TEMPLATE + " because a non 200 status code was encountered! Status Code: {}", profileId, response.statusCode());
}
} catch (Exception e) {
- LOGGER.error("[Skyblocker] Failed to refresh museum item data for profile {}", profileId, e);
+ //If an exception was somehow thrown
+ putEmpty(uuid, profileId);
+
+ LOGGER.error(ERROR_LOG_TEMPLATE, profileId, e);
}
});
}
-
+
+ private static void putEmpty(String uuid, String profileId) {
+ MUSEUM_ITEM_CACHE.get(uuid).put(profileId, new ProfileMuseumData(System.currentTimeMillis(), ObjectOpenHashSet.of()));
+ save();
+ }
+
/**
* The cache is ticked upon switching skyblock servers
*/
@@ -121,22 +144,22 @@ public class MuseumItemCache {
Object2ObjectOpenHashMap<String, ProfileMuseumData> playerData = MUSEUM_ITEM_CACHE.computeIfAbsent(uuid, uuid1 -> Util.make(new Object2ObjectOpenHashMap<>(), map -> {
map.put(profileId, ProfileMuseumData.EMPTY);
}));
-
+
if (playerData.get(profileId).stale()) updateData4ProfileMember(uuid, profileId);
}
}
-
+
public static boolean hasItemInMuseum(String id) {
String uuid = UndashedUuid.toString(MinecraftClient.getInstance().getSession().getUuidOrNull());
- ObjectOpenHashSet<String> collectedItemIds = MUSEUM_ITEM_CACHE.get(uuid).get(Utils.getProfileId()).collectedItemIds();
-
+ ObjectOpenHashSet<String> collectedItemIds = (!MUSEUM_ITEM_CACHE.containsKey(uuid) || Utils.getProfileId().isBlank() || !MUSEUM_ITEM_CACHE.get(uuid).containsKey(Utils.getProfileId())) ? null : MUSEUM_ITEM_CACHE.get(uuid).get(Utils.getProfileId()).collectedItemIds();
+
return collectedItemIds != null && collectedItemIds.contains(id);
}
-
+
private record ProfileMuseumData(long lastUpdated, ObjectOpenHashSet<String> collectedItemIds) {
private static final ProfileMuseumData EMPTY = new ProfileMuseumData(0L, null);
private static final long MAX_AGE = 86_400_000;
-
+
private boolean stale() {
return System.currentTimeMillis() > lastUpdated + MAX_AGE;
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
index 08cc5377..07a566af 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
@@ -13,7 +13,7 @@ public enum SkyblockItemRarity {
RARE(Formatting.BLUE),
UNCOMMON(Formatting.GREEN),
COMMON(Formatting.WHITE);
-
+
public final float r;
public final float g;
public final float b;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
index e050aff5..adc23bbb 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
@@ -4,6 +4,7 @@ import com.google.gson.JsonObject;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.item.MuseumItemCache;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
@@ -146,26 +147,41 @@ public class ItemTooltip {
.append(getMotesMessage(TooltipInfoType.MOTES.getData().get(internalID).getAsInt(), count)));
}
- if (TooltipInfoType.MUSEUM.isTooltipEnabled() && !bazaarOpened) {
+ if (TooltipInfoType.OBTAINED.isTooltipEnabled()) {
String timestamp = getTimestamp(stack);
- if (TooltipInfoType.MUSEUM.hasOrNullWarning(internalID)) {
- String itemCategory = TooltipInfoType.MUSEUM.getData().get(internalID).getAsString();
- String format = switch (itemCategory) {
- case "Weapons" -> "%-18s";
- case "Armor" -> "%-19s";
- default -> "%-20s";
- };
- lines.add(Text.literal(String.format(format, "Museum: (" + itemCategory + ")"))
- .formatted(Formatting.LIGHT_PURPLE)
- .append(Text.literal(timestamp).formatted(Formatting.RED)));
- } else if (!timestamp.isEmpty()) {
+ if (!timestamp.isEmpty()) {
lines.add(Text.literal(String.format("%-21s", "Obtained: "))
.formatted(Formatting.LIGHT_PURPLE)
.append(Text.literal(timestamp).formatted(Formatting.RED)));
}
}
+ if (TooltipInfoType.MUSEUM.isTooltipEnabledAndHasOrNullWarning(internalID) && !bazaarOpened) {
+ String itemCategory = TooltipInfoType.MUSEUM.getData().get(internalID).getAsString();
+ String format = switch (itemCategory) {
+ case "Weapons" -> "%-18s";
+ case "Armor" -> "%-19s";
+ default -> "%-20s";
+ };
+
+ //Special case the special category so that it doesn't always display not donated
+ if (itemCategory.equals("Special")) {
+ lines.add(Text.literal(String.format(format, "Museum: (" + itemCategory + ")"))
+ .formatted(Formatting.LIGHT_PURPLE));
+ } else {
+ NbtCompound extraAttributes = ItemUtils.getExtraAttributes(stack);
+ boolean isInMuseum = (extraAttributes.contains("donated_museum") && extraAttributes.getBoolean("donated_museum")) || MuseumItemCache.hasItemInMuseum(internalID);
+
+ Formatting donatedIndicatorFormatting = isInMuseum ? Formatting.GREEN : Formatting.RED;
+
+ lines.add(Text.literal(String.format(format, "Museum (" + itemCategory + "):"))
+ .formatted(Formatting.LIGHT_PURPLE)
+ .append(Text.literal(isInMuseum ? "✔" : "✖").formatted(donatedIndicatorFormatting, Formatting.BOLD))
+ .append(Text.literal(isInMuseum ? " Donated" : " Not Donated").formatted(donatedIndicatorFormatting)));
+ }
+ }
+
if (TooltipInfoType.COLOR.isTooltipEnabledAndHasOrNullWarning(internalID) && stack.getNbt() != null) {
final NbtElement color = stack.getNbt().getCompound("display").get("color");
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
index 086fcb00..38dcb762 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
@@ -20,7 +20,8 @@ public enum TooltipInfoType implements Runnable {
ONE_DAY_AVERAGE("https://moulberry.codes/auction_averages_lbin/1day.json", itemTooltip -> itemTooltip.enableAvgBIN, false),
THREE_DAY_AVERAGE("https://moulberry.codes/auction_averages_lbin/3day.json", itemTooltip -> itemTooltip.enableAvgBIN, false),
MOTES("https://hysky.de/api/motesprice", itemTooltip -> itemTooltip.enableMotesPrice, itemTooltip -> itemTooltip.enableMotesPrice && Utils.isInTheRift(), true),
- MUSEUM("https://hysky.de/api/museum", itemTooltip -> itemTooltip.enableMuseumDate, true),
+ OBTAINED(itemTooltip -> itemTooltip.enableObtainedDate),
+ MUSEUM("https://hysky.de/api/museum", itemTooltip -> itemTooltip.enableMuseumInfo, true),
COLOR("https://hysky.de/api/color", itemTooltip -> itemTooltip.enableExoticTooltip, true);
private final String address;
@@ -31,6 +32,13 @@ public enum TooltipInfoType implements Runnable {
private long hash;
/**
+ * Use this for when you're adding tooltip info that has no data associated with it
+ */
+ TooltipInfoType(Predicate<SkyblockerConfig.ItemTooltip> enabled) {
+ this(null, itemTooltip -> false, enabled, null, false);
+ }
+
+ /**
* @param address the address to download the data from
* @param enabled the predicate to check if the data should be downloaded and the tooltip should be shown
* @param cacheable whether the data should be cached
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java
index a0e1a0f2..95e08c80 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java
@@ -30,15 +30,15 @@ public class EffigyWaypoints {
if (!SkyblockerConfigManager.get().slayer.vampireSlayer.enableEffigyWaypoints || !Utils.isOnSkyblock() || !Utils.isInTheRift() || !Utils.getIslandArea().contains("Stillgore Château")) return;
UNBROKEN_EFFIGIES.clear();
-
+
try {
for (int i = 0; i < Utils.STRING_SCOREBOARD.size(); i++) {
String line = Utils.STRING_SCOREBOARD.get(i);
-
+
if (line.contains("Effigies")) {
List<Text> effigiesText = new ArrayList<>();
List<Text> prefixAndSuffix = Utils.TEXT_SCOREBOARD.get(i).getSiblings();
-
+
//Add contents of prefix and suffix to list
effigiesText.addAll(prefixAndSuffix.get(0).getSiblings());
effigiesText.addAll(prefixAndSuffix.get(1).getSiblings());
@@ -58,11 +58,11 @@ public class EffigyWaypoints {
for (BlockPos effigy : UNBROKEN_EFFIGIES) {
float[] colorComponents = DyeColor.RED.getColorComponents();
if (SkyblockerConfigManager.get().slayer.vampireSlayer.compactEffigyWaypoints) {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, effigy.down(6), colorComponents, 0.5F);
+ RenderHelper.renderFilledWithBeaconBeam(context, effigy.down(6), colorComponents, 0.5F, true);
} else {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, effigy, colorComponents, 0.5F);
+ RenderHelper.renderFilledWithBeaconBeam(context, effigy, colorComponents, 0.5F, true);
for (int i = 1; i < 6; i++) {
- RenderHelper.renderFilledThroughWalls(context, effigy.down(i), colorComponents, 0.5F - (0.075F * i));
+ RenderHelper.renderFilled(context, effigy.down(i), colorComponents, 0.5F - (0.075F * i), true);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java
index 744edd4c..aa55a4e3 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java
@@ -1,38 +1,19 @@
package de.hysky.skyblocker.skyblock.rift;
-import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
-
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.PosUtils;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
-import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
-import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
@@ -43,13 +24,27 @@ import net.minecraft.util.DyeColor;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
+
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class EnigmaSouls {
private static final Logger LOGGER = LoggerFactory.getLogger(EnigmaSouls.class);
+ private static final Supplier<Waypoint.Type> TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType;
private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "rift/enigma_soul_waypoints.json");
- private static final BlockPos[] SOUL_WAYPOINTS = new BlockPos[42];
+ private static final Map<BlockPos, ProfileAwareWaypoint> SOUL_WAYPOINTS = new HashMap<>(42);
private static final Path FOUND_SOULS_FILE = SkyblockerMod.CONFIG_DIR.resolve("found_enigma_souls.json");
- private static final Object2ObjectOpenHashMap<String, ObjectOpenHashSet<BlockPos>> FOUND_SOULS = new Object2ObjectOpenHashMap<>();
private static final float[] GREEN = DyeColor.GREEN.getColorComponents();
private static final float[] RED = DyeColor.RED.getColorComponents();
@@ -64,7 +59,8 @@ public class EnigmaSouls {
for (int i = 0; i < waypoints.size(); i++) {
JsonObject waypoint = waypoints.get(i).getAsJsonObject();
- SOUL_WAYPOINTS[i] = new BlockPos(waypoint.get("x").getAsInt(), waypoint.get("y").getAsInt(), waypoint.get("z").getAsInt());
+ BlockPos pos = new BlockPos(waypoint.get("x").getAsInt(), waypoint.get("y").getAsInt(), waypoint.get("z").getAsInt());
+ SOUL_WAYPOINTS.put(pos, new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, GREEN, RED));
}
} catch (IOException e) {
@@ -74,13 +70,9 @@ public class EnigmaSouls {
//Load found souls
try (BufferedReader reader = Files.newBufferedReader(FOUND_SOULS_FILE)) {
for (Map.Entry<String, JsonElement> profile : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) {
- ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = new ObjectOpenHashSet<>();
-
for (JsonElement foundSoul : profile.getValue().getAsJsonArray().asList()) {
- foundSoulsOnProfile.add(PosUtils.parsePosString(foundSoul.getAsString()));
+ SOUL_WAYPOINTS.get(PosUtils.parsePosString(foundSoul.getAsString())).setFound();
}
-
- FOUND_SOULS.put(profile.getKey(), foundSoulsOnProfile);
}
} catch (NoSuchFileException ignored) {
} catch (IOException e) {
@@ -90,9 +82,16 @@ public class EnigmaSouls {
}
static void save(MinecraftClient client) {
- JsonObject json = new JsonObject();
+ Map<String, Set<BlockPos>> foundSouls = new HashMap<>();
+ for (ProfileAwareWaypoint soul : SOUL_WAYPOINTS.values()) {
+ for (String profile : soul.foundProfiles) {
+ foundSouls.computeIfAbsent(profile, profile_ -> new HashSet<>());
+ foundSouls.get(profile).add(soul.pos);
+ }
+ }
- for (Map.Entry<String, ObjectOpenHashSet<BlockPos>> foundSoulsForProfile : FOUND_SOULS.entrySet()) {
+ JsonObject json = new JsonObject();
+ for (Map.Entry<String, Set<BlockPos>> foundSoulsForProfile : foundSouls.entrySet()) {
JsonArray foundSoulsJson = new JsonArray();
for (BlockPos foundSoul : foundSoulsForProfile.getValue()) {
@@ -109,15 +108,15 @@ public class EnigmaSouls {
}
}
- static void render(WorldRenderContext wrc) {
+ static void render(WorldRenderContext context) {
SkyblockerConfig.Rift config = SkyblockerConfigManager.get().locations.rift;
if (Utils.isInTheRift() && config.enigmaSoulWaypoints && soulsLoaded.isDone()) {
- for (BlockPos pos : SOUL_WAYPOINTS) {
- if (isSoulMissing(pos)) {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, GREEN, 0.5f);
+ for (Waypoint soul : SOUL_WAYPOINTS.values()) {
+ if (soul.shouldRender()) {
+ soul.render(context);
} else if (config.highlightFoundEnigmaSouls) {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, RED, 0.5f);
+ soul.render(context);
}
}
}
@@ -127,7 +126,8 @@ public class EnigmaSouls {
if (Utils.isInTheRift() && !overlay) {
String message = text.getString();
- if (message.equals("You have already found that Enigma Soul!") || Formatting.strip(message).equals("SOUL! You unlocked an Enigma Soul!")) markClosestSoulAsFound();
+ if (message.equals("You have already found that Enigma Soul!") || Formatting.strip(message).equals("SOUL! You unlocked an Enigma Soul!"))
+ markClosestSoulAsFound();
}
}
@@ -136,13 +136,13 @@ public class EnigmaSouls {
.then(literal("rift")
.then(literal("enigmaSouls")
.then(literal("markAllFound").executes(context -> {
- markAllFound();
+ SOUL_WAYPOINTS.values().forEach(Waypoint::setFound);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllFound")));
return Command.SINGLE_SUCCESS;
}))
.then(literal("markAllMissing").executes(context -> {
- markAllMissing();
+ SOUL_WAYPOINTS.values().forEach(Waypoint::setMissing);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllMissing")));
return Command.SINGLE_SUCCESS;
@@ -154,30 +154,10 @@ public class EnigmaSouls {
if (!soulsLoaded.isDone() || player == null) return;
- Arrays.stream(SOUL_WAYPOINTS)
- .filter(EnigmaSouls::isSoulMissing)
- .min(Comparator.comparingDouble(soulPos -> soulPos.getSquaredDistance(player.getPos())))
- .filter(soulPos -> soulPos.getSquaredDistance(player.getPos()) <= 16)
- .ifPresent(soulPos -> {
- FOUND_SOULS.computeIfAbsent(Utils.getProfile(), profile -> new ObjectOpenHashSet<>());
- FOUND_SOULS.get(Utils.getProfile()).add(soulPos);
- });
- }
-
- private static boolean isSoulMissing(BlockPos soulPos) {
- ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile());
-
- return foundSoulsOnProfile == null || !foundSoulsOnProfile.contains(soulPos);
- }
-
- private static void markAllFound() {
- FOUND_SOULS.computeIfAbsent(Utils.getProfile(), profile -> new ObjectOpenHashSet<>());
- FOUND_SOULS.get(Utils.getProfile()).addAll(List.of(SOUL_WAYPOINTS));
- }
-
- private static void markAllMissing() {
- ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile());
-
- if (foundSoulsOnProfile != null) foundSoulsOnProfile.clear();
+ SOUL_WAYPOINTS.values().stream()
+ .filter(Waypoint::shouldRender)
+ .min(Comparator.comparingDouble(soul -> soul.pos.getSquaredDistance(player.getPos())))
+ .filter(soul -> soul.pos.getSquaredDistance(player.getPos()) <= 16)
+ .ifPresent(Waypoint::setFound);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java
index 7dda741f..83199e99 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java
@@ -6,7 +6,7 @@ import com.google.gson.JsonParser;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.DyeColor;
@@ -18,13 +18,15 @@ import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
public class MirrorverseWaypoints {
private static final Logger LOGGER = LoggerFactory.getLogger("skyblocker");
+ private static final Supplier<Waypoint.Type> WAYPOINT_TYPE = () -> Waypoint.Type.HIGHLIGHT;
private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "rift/mirrorverse_waypoints.json");
- private static final BlockPos[] LAVA_PATH_WAYPOINTS = new BlockPos[107];
- private static final BlockPos[] UPSIDE_DOWN_WAYPOINTS = new BlockPos[66];
- private static final BlockPos[] TURBULATOR_WAYPOINTS = new BlockPos[27];
+ private static Waypoint[] LAVA_PATH_WAYPOINTS;
+ private static Waypoint[] UPSIDE_DOWN_WAYPOINTS;
+ private static Waypoint[] TURBULATOR_WAYPOINTS;
private static final float[] COLOR_COMPONENTS = DyeColor.RED.getColorComponents();
private static CompletableFuture<Void> waypointsLoaded;
@@ -35,51 +37,44 @@ public class MirrorverseWaypoints {
static void load(MinecraftClient client) {
waypointsLoaded = CompletableFuture.runAsync(() -> {
try (BufferedReader reader = client.getResourceManager().openAsReader(WAYPOINTS_JSON)) {
- JsonObject file = JsonParser.parseReader(reader).getAsJsonObject();
- JsonArray sections = file.get("sections").getAsJsonArray();
+ JsonArray sections = JsonParser.parseReader(reader).getAsJsonObject().get("sections").getAsJsonArray();
/// Lava Path
- JsonArray lavaPathWaypoints = sections.get(0).getAsJsonObject().get("waypoints").getAsJsonArray();
-
- for (int i = 0; i < lavaPathWaypoints.size(); i++) {
- JsonObject point = lavaPathWaypoints.get(i).getAsJsonObject();
- LAVA_PATH_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt());
- }
+ LAVA_PATH_WAYPOINTS = loadWaypoints(sections.get(0).getAsJsonObject().get("waypoints").getAsJsonArray());
/// Upside Down Parkour
- JsonArray upsideDownParkourWaypoints = sections.get(1).getAsJsonObject().get("waypoints").getAsJsonArray();
-
- for (int i = 0; i < upsideDownParkourWaypoints.size(); i++) {
- JsonObject point = upsideDownParkourWaypoints.get(i).getAsJsonObject();
- UPSIDE_DOWN_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt());
- }
+ UPSIDE_DOWN_WAYPOINTS = loadWaypoints(sections.get(1).getAsJsonObject().get("waypoints").getAsJsonArray());
/// Turbulator Parkour
- JsonArray turbulatorParkourWaypoints = sections.get(2).getAsJsonObject().get("waypoints").getAsJsonArray();
-
- for (int i = 0; i < turbulatorParkourWaypoints.size(); i++) {
- JsonObject point = turbulatorParkourWaypoints.get(i).getAsJsonObject();
- TURBULATOR_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt());
- }
+ TURBULATOR_WAYPOINTS = loadWaypoints(sections.get(2).getAsJsonObject().get("waypoints").getAsJsonArray());
} catch (IOException e) {
LOGGER.error("[Skyblocker] Mirrorverse Waypoints failed to load ;(", e);
}
});
}
+ private static Waypoint[] loadWaypoints(JsonArray waypointsJson) {
+ Waypoint[] waypoints = new Waypoint[waypointsJson.size()];
+ for (int i = 0; i < waypointsJson.size(); i++) {
+ JsonObject point = waypointsJson.get(i).getAsJsonObject();
+ waypoints[i] = new Waypoint(new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt()), WAYPOINT_TYPE, COLOR_COMPONENTS, false);
+ }
+ return waypoints;
+ }
+
protected static void render(WorldRenderContext wrc) {
//I would also check for the mirrorverse location but the scoreboard stuff is not performant at all...
if (Utils.isInTheRift() && SkyblockerConfigManager.get().locations.rift.mirrorverseWaypoints && waypointsLoaded.isDone()) {
- for (BlockPos pos : LAVA_PATH_WAYPOINTS) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ for (Waypoint waypoint : LAVA_PATH_WAYPOINTS) {
+ waypoint.render(wrc);
}
- for (BlockPos pos : UPSIDE_DOWN_WAYPOINTS) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ for (Waypoint waypoint : UPSIDE_DOWN_WAYPOINTS) {
+ waypoint.render(wrc);
}
- for (BlockPos pos : TURBULATOR_WAYPOINTS) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ for (Waypoint waypoint : TURBULATOR_WAYPOINTS) {
+ waypoint.render(wrc);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java
index 9c058a4f..c2c952cf 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java
@@ -21,6 +21,9 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.reflect.Type;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -30,7 +33,7 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.lit
public class Shortcuts {
private static final Logger LOGGER = LoggerFactory.getLogger(Shortcuts.class);
- private static final File SHORTCUTS_FILE = SkyblockerMod.CONFIG_DIR.resolve("shortcuts.json").toFile();
+ private static final Path SHORTCUTS_FILE = SkyblockerMod.CONFIG_DIR.resolve("shortcuts.json");
@Nullable
private static CompletableFuture<Void> shortcutsLoaded;
public static final Map<String, String> commands = new HashMap<>();
@@ -52,7 +55,7 @@ public class Shortcuts {
return;
}
shortcutsLoaded = CompletableFuture.runAsync(() -> {
- try (BufferedReader reader = new BufferedReader(new FileReader(SHORTCUTS_FILE))) {
+ try (BufferedReader reader = Files.newBufferedReader(SHORTCUTS_FILE)) {
Type shortcutsType = new TypeToken<Map<String, Map<String, String>>>() {
}.getType();
Map<String, Map<String, String>> shortcuts = SkyblockerMod.GSON.fromJson(reader, shortcutsType);
@@ -61,7 +64,7 @@ public class Shortcuts {
commands.putAll(shortcuts.get("commands"));
commandArgs.putAll(shortcuts.get("commandArgs"));
LOGGER.info("[Skyblocker] Loaded {} command shortcuts and {} command argument shortcuts", commands.size(), commandArgs.size());
- } catch (FileNotFoundException e) {
+ } catch (NoSuchFileException e) {
registerDefaultShortcuts();
LOGGER.warn("[Skyblocker] Shortcuts file not found, using default shortcuts. This is normal when using for the first time.");
} catch (IOException e) {
@@ -140,7 +143,7 @@ public class Shortcuts {
JsonObject shortcutsJson = new JsonObject();
shortcutsJson.add("commands", SkyblockerMod.GSON.toJsonTree(commands));
shortcutsJson.add("commandArgs", SkyblockerMod.GSON.toJsonTree(commandArgs));
- try (BufferedWriter writer = new BufferedWriter(new FileWriter(SHORTCUTS_FILE))) {
+ try (BufferedWriter writer = Files.newBufferedWriter(SHORTCUTS_FILE)) {
SkyblockerMod.GSON.toJson(shortcutsJson, writer);
LOGGER.info("[Skyblocker] Saved {} command shortcuts and {} command argument shortcuts", commands.size(), commandArgs.size());
} catch (IOException e) {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
index 196ad0d6..a5f8ae2d 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
@@ -19,7 +19,7 @@ public class ShortcutsConfigScreen extends Screen {
private boolean initialized;
private double scrollAmount;
private final Screen parent;
-
+
public ShortcutsConfigScreen() {
this(null);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java b/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
index fba447ea..bc4f98c2 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
@@ -1,8 +1,8 @@
package de.hysky.skyblocker.skyblock.special;
-import com.mojang.blaze3d.systems.RenderSystem;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.render.RenderHelper;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.enchantment.Enchantments;
@@ -58,15 +58,10 @@ public class SpecialEffects {
ItemStack stack = getStackFromName(matcher.group("item"));
if (!stack.isEmpty()) {
- if (RenderSystem.isOnRenderThread()) {
+ RenderHelper.runOnRenderThread(() -> {
client.particleManager.addEmitter(client.player, ParticleTypes.PORTAL, 30);
client.gameRenderer.showFloatingItem(stack);
- } else {
- RenderSystem.recordRenderCall(() -> {
- client.particleManager.addEmitter(client.player, ParticleTypes.PORTAL, 30);
- client.gameRenderer.showFloatingItem(stack);
- });
- }
+ });
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java
new file mode 100644
index 00000000..0de3e45f
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java
@@ -0,0 +1,14 @@
+package de.hysky.skyblocker.skyblock.tabhud.util;
+
+import net.minecraft.util.math.MathHelper;
+
+public class Colors {
+
+ /**
+ * @param pcnt Percentage between 0% and 100%, NOT 0-1!
+ * @return an int representing a color, where 100% = green and 0% = red
+ */
+ public static int pcntToCol(float pcnt) {
+ return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java
index 24883d77..82394a78 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java
@@ -10,6 +10,7 @@ public class Ico {
public static final ItemStack MAP = new ItemStack(Items.FILLED_MAP);
public static final ItemStack NTAG = new ItemStack(Items.NAME_TAG);
public static final ItemStack EMERALD = new ItemStack(Items.EMERALD);
+ public static final ItemStack AMETHYST_SHARD = new ItemStack(Items.AMETHYST_SHARD);
public static final ItemStack CLOCK = new ItemStack(Items.CLOCK);
public static final ItemStack DIASWORD = new ItemStack(Items.DIAMOND_SWORD);
public static final ItemStack DBUSH = new ItemStack(Items.DEAD_BUSH);
@@ -48,8 +49,10 @@ public class Ico {
public static final ItemStack B_ROD = new ItemStack(Items.BLAZE_ROD);
public static final ItemStack BOW = new ItemStack(Items.BOW);
public static final ItemStack COPPER = new ItemStack(Items.COPPER_INGOT);
+ public static final ItemStack NETHERITE_UPGRADE_ST = new ItemStack(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE);
public static final ItemStack COMPOSTER = new ItemStack(Items.COMPOSTER);
public static final ItemStack SAPLING = new ItemStack(Items.OAK_SAPLING);
+ public static final ItemStack SEEDS = new ItemStack(Items.WHEAT_SEEDS);
public static final ItemStack MILESTONE = new ItemStack(Items.LODESTONE);
public static final ItemStack PICKAXE = new ItemStack(Items.IRON_PICKAXE);
public static final ItemStack NETHER_STAR = new ItemStack(Items.NETHER_STAR);
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
index f577f2d3..3ef968a3 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
@@ -35,7 +35,7 @@ public class PlayerListMgr {
ClientPlayNetworkHandler cpnwh = MinecraftClient.getInstance().getNetworkHandler();
- // check is needed, else game crash on server leave
+ // check is needed, else game crashes on server leave
if (cpnwh != null) {
playerList = cpnwh.getPlayerList().stream().sorted(PlayerListHudAccessor.getOrdering()).toList();
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java
index e8bf91ab..a5fb4d32 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java
@@ -3,14 +3,14 @@ package de.hysky.skyblocker.skyblock.tabhud.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent;
-import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
+import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent;
+import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
// this widget shows the status of the king's commissions.
// (dwarven mines and crystal hollows)
@@ -47,17 +47,13 @@ public class CommsWidget extends Widget {
String progress = m.group("progress");
if (progress.equals("DONE")) {
- pc = new ProgressComponent(Ico.BOOK, Text.of(name), Text.of(progress), 100f, pcntToCol(100));
+ pc = new ProgressComponent(Ico.BOOK, Text.of(name), Text.of(progress), 100f, Colors.pcntToCol(100));
} else {
float pcnt = Float.parseFloat(progress.substring(0, progress.length() - 1));
- pc = new ProgressComponent(Ico.BOOK, Text.of(name), pcnt, pcntToCol(pcnt));
+ pc = new ProgressComponent(Ico.BOOK, Text.of(name), pcnt, Colors.pcntToCol(pcnt));
}
this.addComponent(pc);
}
}
- private int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
- }
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java
index fbeb5ae5..f50b617b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java
@@ -2,7 +2,7 @@ package de.hysky.skyblocker.skyblock.tabhud.widget;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
-
+import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -20,11 +20,11 @@ public class ComposterWidget extends Widget {
@Override
public void updateContent() {
- this.addSimpleIcoText(Ico.SAPLING, "Organic Matter:", Formatting.YELLOW, 48);
- this.addSimpleIcoText(Ico.FURNACE, "Fuel:", Formatting.BLUE, 49);
- this.addSimpleIcoText(Ico.CLOCK, "Time Left:", Formatting.RED, 50);
- this.addSimpleIcoText(Ico.COMPOSTER, "Stored Compost:", Formatting.DARK_GREEN, 51);
+ int offset = (PlayerListMgr.strAt(46) != null) ? 1 : 0;
+ this.addSimpleIcoText(Ico.SAPLING, "Organic Matter:", Formatting.YELLOW, 48 + offset);
+ this.addSimpleIcoText(Ico.FURNACE, "Fuel:", Formatting.BLUE, 49 + offset);
+ this.addSimpleIcoText(Ico.CLOCK, "Time Left:", Formatting.RED, 50 + offset);
+ this.addSimpleIcoText(Ico.COMPOSTER, "Stored Compost:", Formatting.DARK_GREEN, 51 + offset);
}
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java
index 1b3b8644..53f84f71 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java
@@ -37,16 +37,21 @@ public class DungeonPuzzleWidget extends Widget {
if (m == null) {
break;
}
+
+ Formatting statcol = switch (m.group("status")) {
+ case "✦" -> Formatting.GOLD; // Unsolved
+ case "✔" -> Formatting.GREEN; // Solved
+ case "✖" -> Formatting.RED; // Failed
+ default -> Formatting.WHITE; // Who knows if they'll add another puzzle state or not?
+ };
+
Text t = Text.literal(m.group("name") + ": ")
.append(Text.literal("[").formatted(Formatting.GRAY))
- .append(m.group("status"))
+ .append(Text.literal(m.group("status")).formatted(statcol, Formatting.BOLD))
.append(Text.literal("]").formatted(Formatting.GRAY));
IcoTextComponent itc = new IcoTextComponent(Ico.SIGN, t);
this.addComponent(itc);
pos++;
- // code points for puzzle status chars unsolved and solved: 10022, 10004
- // not sure which one is which
- // still need to find out codepoint for the puzzle failed char
}
if (pos == 48) {
this.addComponent(
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java
index 0211cbd6..e08b4acf 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java
@@ -3,14 +3,13 @@ package de.hysky.skyblocker.skyblock.tabhud.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
-
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
-import net.minecraft.util.math.MathHelper;
import net.minecraft.util.Formatting;
// this widget shows info about fire sales when in the hub.
@@ -55,14 +54,10 @@ public class FireSaleWidget extends Widget {
float total = Float.parseFloat(m.group("total")) * 1000;
Text prgressTxt = Text.literal(String.format("%s/%.0f", avail, total));
float pcnt = (Float.parseFloat(avail) / (total)) * 100f;
- ProgressComponent pc = new ProgressComponent(Ico.GOLD, itemTxt, prgressTxt, pcnt, pcntToCol(pcnt));
+ ProgressComponent pc = new ProgressComponent(Ico.GOLD, itemTxt, prgressTxt, pcnt, Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
}
- private int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb( pcnt / 300f, 0.9f, 0.9f);
- }
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java
index 1a4683f5..adae7daf 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java
@@ -69,7 +69,11 @@ public class ForgeWidget extends Widget {
c = new IcoFatTextComponent();
} else {
l1 = Text.literal(parts[0].substring(3)).formatted(Formatting.YELLOW);
- l2 = Text.literal("Done in: ").formatted(Formatting.GRAY).append(Text.literal(parts[1]).formatted(Formatting.WHITE));
+ if (parts[1].equals("Ready!")) {
+ l2 = Text.literal("Done!").formatted(Formatting.GREEN);
+ } else {
+ l2 = Text.literal("Done in: ").formatted(Formatting.GRAY).append(Text.literal(parts[1]).formatted(Formatting.WHITE));
+ }
c = new IcoFatTextComponent(Ico.FIRE, l1, l2);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java
index 221f8b08..b6b65896 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java
@@ -6,7 +6,7 @@ import java.util.regex.Pattern;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent;
-
+import de.hysky.skyblocker.utils.Constants;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -14,13 +14,14 @@ import net.minecraft.util.Formatting;
// this widget shows info about the garden server
public class GardenServerWidget extends Widget {
-
private static final MutableText TITLE = Text.literal("Server Info").formatted(Formatting.DARK_AQUA,
Formatting.BOLD);
+ //From the armor trim tooltip
+ private static final int COPPER_COLOR = 11823181;
// match the next visitor in the garden
// group 1: visitor name
- private static final Pattern VISITOR_PATTERN = Pattern.compile("Next Visitor: (?<vis>.*)");
+ private static final Pattern VISITOR_PATTERN = Pattern.compile("Visitors: (?<vis>.*)");
public GardenServerWidget() {
super(TITLE, Formatting.DARK_AQUA.getColorValue());
@@ -31,17 +32,29 @@ public class GardenServerWidget extends Widget {
this.addSimpleIcoText(Ico.MAP, "Area:", Formatting.DARK_AQUA, 41);
this.addSimpleIcoText(Ico.NTAG, "Server ID:", Formatting.GRAY, 42);
this.addSimpleIcoText(Ico.EMERALD, "Gems:", Formatting.GREEN, 43);
- this.addSimpleIcoText(Ico.COPPER, "Copper:", Formatting.GOLD, 44);
- Matcher m = PlayerListMgr.regexAt(45, VISITOR_PATTERN);
+ Text copperText = Widget.simpleEntryText(44, "Copper:", Formatting.WHITE);
+ ((MutableText) copperText.getSiblings().get(0)).styled(Constants.WITH_COLOR.apply(COPPER_COLOR));
+
+ this.addComponent(new IcoTextComponent(Ico.COPPER, copperText));
+
+ boolean hasPesthunterBonus = PlayerListMgr.strAt(46) != null;
+
+ if (hasPesthunterBonus) {
+ this.addComponent(new IcoTextComponent(Ico.NETHERITE_UPGRADE_ST, PlayerListMgr.textAt(46)));
+ }
+
+ int offset = hasPesthunterBonus ? 1 : 0;
+
+ Matcher m = PlayerListMgr.regexAt(53 + offset, VISITOR_PATTERN);
if (m == null ) {
this.addComponent(new IcoTextComponent());
return;
}
- String vis = m.group("vis");
+ String vis = m.group("vis").replaceAll("[()]*", "");
Formatting col;
- if (vis.equals("Not Unlocked!")) {
+ if (vis.equals("Not Unlocked!") || vis.equals("Queue Full!")) {
col = Formatting.RED;
} else {
col = Formatting.GREEN;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java
index 41eee8d6..75652b33 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java
@@ -26,6 +26,8 @@ public class GardenSkillsWidget extends Widget {
private static final Pattern SKILL_PATTERN = Pattern
.compile("Skills: (?<skill>[A-Za-z]* [0-9]*): (?<progress>[0-9.MAX]*)%?");
+ private static final Pattern GARDEN_LEVEL_PATTERN = Pattern.compile("Garden Level: (?<level>[IVX0-9]+)(?: \\((?<progress>[0-9.]+)% to [IVX0-9]+\\))?");
+
// same, more or less
private static final Pattern MS_PATTERN = Pattern
.compile("Milestone: (?<milestone>[A-Za-z ]* [0-9]*): (?<progress>[0-9.]*)%");
@@ -36,26 +38,46 @@ public class GardenSkillsWidget extends Widget {
@Override
public void updateContent() {
- ProgressComponent pc;
- Matcher m = PlayerListMgr.regexAt(66, SKILL_PATTERN);
- if (m == null) {
- pc = new ProgressComponent();
+ ProgressComponent spc;
+ Matcher skillMatcher = PlayerListMgr.regexAt(66, SKILL_PATTERN);
+ if (skillMatcher == null) {
+ spc = new ProgressComponent();
} else {
- String strpcnt = m.group("progress");
- String skill = m.group("skill");
+ String strpcnt = skillMatcher.group("progress");
+ String skill = skillMatcher.group("skill");
if (strpcnt.equals("MAX")) {
- pc = new ProgressComponent(Ico.LANTERN, Text.of(skill), Text.of("MAX"), 100f,
+ spc = new ProgressComponent(Ico.LANTERN, Text.of(skill), Text.of("MAX"), 100f,
Formatting.RED.getColorValue());
} else {
float pcnt = Float.parseFloat(strpcnt);
- pc = new ProgressComponent(Ico.LANTERN, Text.of(skill), pcnt,
+ spc = new ProgressComponent(Ico.LANTERN, Text.of(skill), pcnt,
Formatting.GOLD.getColorValue());
}
}
- this.addComponent(pc);
+ this.addComponent(spc);
+
+ ProgressComponent glpc;
+ Matcher glMatcher = PlayerListMgr.regexAt(45, GARDEN_LEVEL_PATTERN);
+
+ if (glMatcher == null) {
+ glpc = new ProgressComponent();
+ } else {
+ String level = glMatcher.group("level");
+
+ if (level.equals("15") || level.equals("XV")) {
+ glpc = new ProgressComponent(Ico.SEEDS, Text.literal("Garden Level " + level), 100f, Formatting.RED.getColorValue());
+ } else {
+ String strpcnt = glMatcher.group("progress");
+ float pcnt = Float.parseFloat(strpcnt);
+
+ glpc = new ProgressComponent(Ico.SEEDS, Text.literal("Garden Level " + level), pcnt, Formatting.DARK_GREEN.getColorValue());
+ }
+ }
+
+ this.addComponent(glpc);
Text speed = Widget.simpleEntryText(67, "SPD", Formatting.WHITE);
IcoTextComponent spd = new IcoTextComponent(Ico.SUGAR, speed);
@@ -66,22 +88,21 @@ public class GardenSkillsWidget extends Widget {
tc.addToCell(0, 0, spd);
tc.addToCell(1, 0, ffo);
this.addComponent(tc);
+
+ this.addComponent(new IcoTextComponent(Ico.HOE, PlayerListMgr.textAt(70)));
ProgressComponent pc2;
- m = PlayerListMgr.regexAt(69, MS_PATTERN);
- if (m == null) {
+ Matcher milestoneMatcher = PlayerListMgr.regexAt(69, MS_PATTERN);
+ if (milestoneMatcher == null) {
pc2 = new ProgressComponent();
} else {
- String strpcnt = m.group("progress");
- String milestone = m.group("milestone");
+ String strpcnt = milestoneMatcher.group("progress");
+ String milestone = milestoneMatcher.group("milestone");
float pcnt = Float.parseFloat(strpcnt);
pc2 = new ProgressComponent(Ico.MILESTONE, Text.of(milestone), pcnt,
Formatting.GREEN.getColorValue());
-
}
this.addComponent(pc2);
-
}
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
index cfbd6cd0..2b0036ad 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
@@ -15,16 +15,17 @@ public class GardenVisitorsWidget extends Widget {
@Override
public void updateContent() {
- if (PlayerListMgr.textAt(54) == null) {
+ int offset = (PlayerListMgr.strAt(46) != null) ? 1 : 0;
+
+ if (PlayerListMgr.textAt(54 + offset) == null) {
this.addComponent(new PlainTextComponent(Text.literal("No visitors!").formatted(Formatting.GRAY)));
return;
}
- for (int i = 54; i < 59; i++) {
+ for (int i = 54 + offset; i < 59 + offset; i++) {
String text = PlayerListMgr.strAt(i);
if (text != null)
this.addComponent(new PlainTextComponent(Text.literal(text)));
}
-
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java
index 5ae0bd3d..472e6d61 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java
@@ -1,6 +1,8 @@
package de.hysky.skyblocker.skyblock.tabhud.widget;
import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
@@ -19,6 +21,9 @@ public class JacobsContestWidget extends Widget {
private static final MutableText TITLE = Text.literal("Jacob's Contest").formatted(Formatting.YELLOW,
Formatting.BOLD);
+ //TODO Properly match the contest placement and display it
+ private static final Pattern CROP_PATTERN = Pattern.compile("(?:☘|○) (?<crop>[A-Za-z ]+)(?:.+)?");
+
private static final HashMap<String, ItemStack> FARM_DATA = new HashMap<>();
// again, there HAS to be a better way to do this
@@ -41,22 +46,27 @@ public class JacobsContestWidget extends Widget {
@Override
public void updateContent() {
- this.addSimpleIcoText(Ico.CLOCK, "Starts in:", Formatting.GOLD, 76);
+ Text jacobStatus = PlayerListMgr.textAt(76);
+
+ if (jacobStatus.getString().equals("ACTIVE")) {
+ this.addComponent(new IcoTextComponent(Ico.CLOCK, jacobStatus));
+ } else {
+ this.addSimpleIcoText(Ico.CLOCK, "Starts in:", Formatting.GOLD, 76);
+ }
TableComponent tc = new TableComponent(1, 3, Formatting.YELLOW .getColorValue());
for (int i = 77; i < 80; i++) {
- String item = PlayerListMgr.strAt(i);
+ Matcher item = PlayerListMgr.regexAt(i, CROP_PATTERN);
IcoTextComponent itc;
if (item == null) {
itc = new IcoTextComponent();
} else {
- itc = new IcoTextComponent(FARM_DATA.get(item), Text.of(item));
+ String cropName = item.group("crop").trim(); //Trimming is needed because during a contest the space separator will be caught
+ itc = new IcoTextComponent(FARM_DATA.get(cropName), Text.of(cropName));
}
tc.addToCell(0, i - 77, itc);
}
this.addComponent(tc);
-
}
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
index 44635fbe..ec176a98 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
@@ -22,7 +22,7 @@ public class PowderWidget extends Widget {
@Override
public void updateContent() {
this.addSimpleIcoText(Ico.MITHRIL, "Mithril:", Formatting.AQUA, 46);
- this.addSimpleIcoText(Ico.EMERALD, "Gemstone:", Formatting.DARK_PURPLE, 47);
+ this.addSimpleIcoText(Ico.AMETHYST_SHARD, "Gemstone:", Formatting.DARK_PURPLE, 47);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java
index 6aa363c9..442f12ca 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java
@@ -2,16 +2,16 @@ package de.hysky.skyblocker.skyblock.tabhud.widget.hud;
import java.util.List;
-import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud.Commission;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
+import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.Component;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
// this widget shows the status of the king's commissions.
// (dwarven mines and crystal hollows)
@@ -56,7 +56,7 @@ public class HudCommsWidget extends Widget {
Component comp;
if (isFancy) {
- comp = new ProgressComponent(Ico.BOOK, c, p, pcntToCol(p));
+ comp = new ProgressComponent(Ico.BOOK, c, p, Colors.pcntToCol(p));
} else {
comp = new PlainTextComponent(
Text.literal(comm.commission() + ": ")
@@ -66,8 +66,4 @@ public class HudCommsWidget extends Widget {
}
}
- private int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
- }
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java
index 93ade5cb..6cd7736b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java
@@ -3,15 +3,15 @@ package de.hysky.skyblocker.skyblock.tabhud.widget.rift;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
+import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
public class RiftProgressWidget extends Widget {
@@ -75,10 +75,6 @@ public class RiftProgressWidget extends Widget {
}
- private static int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
- }
-
private void addTimecharmsComponent(int pos) {
Matcher m = PlayerListMgr.regexAt(pos, TIMECHARMS_PATTERN);
@@ -88,7 +84,7 @@ public class RiftProgressWidget extends Widget {
Text progressText = Text.literal(current + "/" + total);
ProgressComponent pc = new ProgressComponent(Ico.NETHER_STAR, Text.literal("Timecharms"), progressText,
- pcnt, pcntToCol(pcnt));
+ pcnt, Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
@@ -102,7 +98,7 @@ public class RiftProgressWidget extends Widget {
Text progressText = Text.literal(current + "/" + total);
ProgressComponent pc = new ProgressComponent(Ico.HEART_OF_THE_SEA, Text.literal("Enigma Souls"),
- progressText, pcnt, pcntToCol(pcnt));
+ progressText, pcnt, Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
@@ -116,7 +112,7 @@ public class RiftProgressWidget extends Widget {
Text progressText = Text.literal(current + "/" + total);
ProgressComponent pc = new ProgressComponent(Ico.BONE, Text.literal("Montezuma"), progressText, pcnt,
- pcntToCol(pcnt));
+ Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
index cef17d8e..f0e94770 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
@@ -1,4 +1,4 @@
-package de.hysky.skyblocker.skyblock;
+package de.hysky.skyblocker.skyblock.waypoint;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -12,7 +12,8 @@ import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.PosUtils;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
@@ -29,19 +30,24 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class FairySouls {
private static final Logger LOGGER = LoggerFactory.getLogger(FairySouls.class);
+ private static final Supplier<Waypoint.Type> TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType;
private static CompletableFuture<Void> fairySoulsLoaded;
private static int maxSouls = 0;
- private static final Map<String, Set<BlockPos>> fairySouls = new HashMap<>();
- private static final Map<String, Map<String, Set<BlockPos>>> foundFairies = new HashMap<>();
+ private static final Map<String, Map<BlockPos, ProfileAwareWaypoint>> fairySouls = new HashMap<>();
@SuppressWarnings("UnusedReturnValue")
public static CompletableFuture<Void> runAsyncAfterFairySoulsLoad(Runnable runnable) {
@@ -67,32 +73,41 @@ public class FairySouls {
private static void loadFairySouls() {
fairySoulsLoaded = NEURepoManager.runAsyncAfterLoad(() -> {
maxSouls = NEURepoManager.NEU_REPO.getConstants().getFairySouls().getMaxSouls();
- NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairySoulsForLocation) -> fairySouls.put(location, fairySoulsForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableSet())));
- LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size());
+ NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairiesForLocation) -> fairySouls.put(location, fairiesForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableMap(pos -> pos, pos -> new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, DyeColor.GREEN.getColorComponents(), DyeColor.RED.getColorComponents())))));
+ LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size());
- try (BufferedReader reader = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile()))) {
+ try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) {
for (Map.Entry<String, JsonElement> foundFairiesForProfileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) {
- Map<String, Set<BlockPos>> foundFairiesForProfile = new HashMap<>();
for (Map.Entry<String, JsonElement> foundFairiesForLocationJson : foundFairiesForProfileJson.getValue().getAsJsonObject().asMap().entrySet()) {
- Set<BlockPos> foundFairiesForLocation = new HashSet<>();
+ String profile = foundFairiesForLocationJson.getKey();
+ Map<BlockPos, ProfileAwareWaypoint> fairiesForLocation = fairySouls.get(profile);
for (JsonElement foundFairy : foundFairiesForLocationJson.getValue().getAsJsonArray().asList()) {
- foundFairiesForLocation.add(PosUtils.parsePosString(foundFairy.getAsString()));
+ fairiesForLocation.get(PosUtils.parsePosString(foundFairy.getAsString())).setFound(profile);
}
- foundFairiesForProfile.put(foundFairiesForLocationJson.getKey(), foundFairiesForLocation);
}
- foundFairies.put(foundFairiesForProfileJson.getKey(), foundFairiesForProfile);
}
LOGGER.debug("[Skyblocker] Loaded found fairy souls");
- } catch (FileNotFoundException ignored) {
+ } catch (NoSuchFileException ignored) {
} catch (IOException e) {
LOGGER.error("[Skyblocker] Failed to load found fairy souls", e);
}
- LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations and {} found fairy souls across {} locations in {} profiles", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size(), foundFairies.values().stream().map(Map::values).flatMap(Collection::stream).mapToInt(Set::size).sum(), foundFairies.values().stream().mapToInt(Map::size).sum(), foundFairies.size());
+ LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size());
});
}
private static void saveFoundFairySouls(MinecraftClient client) {
- try (BufferedWriter writer = new BufferedWriter(new FileWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile()))) {
+ Map<String, Map<String, Set<BlockPos>>> foundFairies = new HashMap<>();
+ for (Map.Entry<String, Map<BlockPos, ProfileAwareWaypoint>> fairiesForLocation : fairySouls.entrySet()) {
+ for (ProfileAwareWaypoint fairySoul : fairiesForLocation.getValue().values()) {
+ for (String profile : fairySoul.foundProfiles) {
+ foundFairies.computeIfAbsent(profile, profile_ -> new HashMap<>());
+ foundFairies.get(profile).computeIfAbsent(fairiesForLocation.getKey(), location_ -> new HashSet<>());
+ foundFairies.get(profile).get(fairiesForLocation.getKey()).add(fairySoul.pos);
+ }
+ }
+ }
+
+ try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) {
JsonObject foundFairiesJson = new JsonObject();
for (Map.Entry<String, Map<String, Set<BlockPos>>> foundFairiesForProfile : foundFairies.entrySet()) {
JsonObject foundFairiesForProfileJson = new JsonObject();
@@ -106,7 +121,6 @@ public class FairySouls {
foundFairiesJson.add(foundFairiesForProfile.getKey(), foundFairiesForProfileJson);
}
SkyblockerMod.GSON.toJson(foundFairiesJson, writer);
- writer.close();
LOGGER.info("[Skyblocker] Saved found fairy souls");
} catch (IOException e) {
LOGGER.error("[Skyblocker] Failed to write found fairy souls to file", e);
@@ -132,13 +146,12 @@ public class FairySouls {
SkyblockerConfig.FairySouls fairySoulsConfig = SkyblockerConfigManager.get().general.fairySouls;
if (fairySoulsConfig.enableFairySoulsHelper && fairySoulsLoaded.isDone() && fairySouls.containsKey(Utils.getLocationRaw())) {
- for (BlockPos fairySoulPos : fairySouls.get(Utils.getLocationRaw())) {
- boolean fairySoulNotFound = isFairySoulMissing(fairySoulPos);
- if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoulPos.getSquaredDistance(context.camera().getPos()) > 2500) {
+ for (Waypoint fairySoul : fairySouls.get(Utils.getLocationRaw()).values()) {
+ boolean fairySoulNotFound = fairySoul.shouldRender();
+ if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoul.pos.getSquaredDistance(context.camera().getPos()) > 2500) {
continue;
}
- float[] colorComponents = fairySoulNotFound ? DyeColor.GREEN.getColorComponents() : DyeColor.RED.getColorComponents();
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F);
+ fairySoul.render(context);
}
}
}
@@ -152,51 +165,37 @@ public class FairySouls {
private static void markClosestFairyFound() {
if (!fairySoulsLoaded.isDone()) return;
+
PlayerEntity player = MinecraftClient.getInstance().player;
if (player == null) {
LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because player is null");
return;
}
- fairySouls.get(Utils.getLocationRaw()).stream()
- .filter(FairySouls::isFairySoulMissing)
- .min(Comparator.comparingDouble(fairySoulPos -> fairySoulPos.getSquaredDistance(player.getPos())))
- .filter(fairySoulPos -> fairySoulPos.getSquaredDistance(player.getPos()) <= 16)
- .ifPresent(fairySoulPos -> {
- initializeFoundFairiesForCurrentProfileAndLocation();
- foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).add(fairySoulPos);
- });
- }
- private static boolean isFairySoulMissing(BlockPos fairySoulPos) {
- Map<String, Set<BlockPos>> foundFairiesForProfile = foundFairies.get(Utils.getProfile());
- if (foundFairiesForProfile == null) {
- return true;
- }
- Set<BlockPos> foundFairiesForProfileAndLocation = foundFairiesForProfile.get(Utils.getLocationRaw());
- if (foundFairiesForProfileAndLocation == null) {
- return true;
+ Map<BlockPos, ProfileAwareWaypoint> fairiesOnCurrentIsland = fairySouls.get(Utils.getLocationRaw());
+ if (fairiesOnCurrentIsland == null) {
+ LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because there are no fairy souls loaded on the current island. NEU repo probably failed to load.");
+ return;
}
- return !foundFairiesForProfileAndLocation.contains(fairySoulPos);
+
+ fairiesOnCurrentIsland.values().stream()
+ .filter(Waypoint::shouldRender)
+ .min(Comparator.comparingDouble(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos())))
+ .filter(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos()) <= 16)
+ .ifPresent(Waypoint::setFound);
}
public static void markAllFairiesOnCurrentIslandFound() {
- initializeFoundFairiesForCurrentProfileAndLocation();
- foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).addAll(fairySouls.get(Utils.getLocationRaw()));
+ Map<BlockPos, ProfileAwareWaypoint> fairiesForLocation = fairySouls.get(Utils.getLocationRaw());
+ if (fairiesForLocation != null) {
+ fairiesForLocation.values().forEach(ProfileAwareWaypoint::setFound);
+ }
}
public static void markAllFairiesOnCurrentIslandMissing() {
- Map<String, Set<BlockPos>> foundFairiesForProfile = foundFairies.get(Utils.getProfile());
- if (foundFairiesForProfile != null) {
- foundFairiesForProfile.remove(Utils.getLocationRaw());
+ Map<BlockPos, ProfileAwareWaypoint> fairiesForLocation = fairySouls.get(Utils.getLocationRaw());
+ if (fairiesForLocation != null) {
+ fairiesForLocation.values().forEach(ProfileAwareWaypoint::setMissing);
}
}
-
- private static void initializeFoundFairiesForCurrentProfileAndLocation() {
- initializeFoundFairiesForProfileAndLocation(Utils.getProfile(), Utils.getLocationRaw());
- }
-
- private static void initializeFoundFairiesForProfileAndLocation(String profile, String location) {
- foundFairies.computeIfAbsent(profile, profileKey -> new HashMap<>());
- foundFairies.get(profile).computeIfAbsent(location, locationKey -> new HashSet<>());
- }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java
index e2962702..5b5f4715 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java
@@ -1,4 +1,4 @@
-package de.hysky.skyblocker.skyblock.diana;
+package de.hysky.skyblocker.skyblock.waypoint;
import com.mojang.brigadier.Command;
import de.hysky.skyblocker.SkyblockerMod;
@@ -108,7 +108,7 @@ public class MythologicalRitual {
burrow.nextBurrowPlane[1] = Vec3d.of(pos).subtract(nextBurrowDirection).subtract(0, 50, 0);
burrow.nextBurrowPlane[2] = burrow.nextBurrowPlane[1].add(0, 100, 0);
burrow.nextBurrowPlane[3] = burrow.nextBurrowPlane[0].add(0, 100, 0);
- } else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType())) {
+ } else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType()) && packet.getCount() == 2) {
if (System.currentTimeMillis() > lastEchoTime + 10_000) {
return;
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java
index aaf4d77c..952f2f59 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java
@@ -1,4 +1,4 @@
-package de.hysky.skyblocker.skyblock.spidersden;
+package de.hysky.skyblocker.skyblock.waypoint;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -11,7 +11,8 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.PosUtils;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
@@ -28,19 +29,24 @@ import net.minecraft.util.math.BlockPos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class Relics {
private static final Logger LOGGER = LoggerFactory.getLogger(Relics.class);
+ private static final Supplier<Waypoint.Type> TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType;
private static CompletableFuture<Void> relicsLoaded;
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private static int totalRelics = 0;
- private static final List<BlockPos> relics = new ArrayList<>();
- private static final Map<String, Set<BlockPos>> foundRelics = new HashMap<>();
+ private static final Map<BlockPos, ProfileAwareWaypoint> relics = new HashMap<>();
public static void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(Relics::loadRelics);
@@ -59,7 +65,8 @@ public class Relics {
} else if (json.getKey().equals("locations")) {
for (JsonElement locationJson : json.getValue().getAsJsonArray().asList()) {
JsonObject posData = locationJson.getAsJsonObject();
- relics.add(new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt()));
+ BlockPos pos = new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt());
+ relics.put(pos, new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, DyeColor.YELLOW.getColorComponents(), DyeColor.BROWN.getColorComponents()));
}
}
}
@@ -68,16 +75,14 @@ public class Relics {
LOGGER.error("[Skyblocker] Failed to load relics locations", e);
}
- try (BufferedReader reader = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json").toFile()))) {
+ try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) {
for (Map.Entry<String, JsonElement> profileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) {
- Set<BlockPos> foundRelicsForProfile = new HashSet<>();
for (JsonElement foundRelicsJson : profileJson.getValue().getAsJsonArray().asList()) {
- foundRelicsForProfile.add(PosUtils.parsePosString(foundRelicsJson.getAsString()));
+ relics.get(PosUtils.parsePosString(foundRelicsJson.getAsString())).setFound(profileJson.getKey());
}
- foundRelics.put(profileJson.getKey(), foundRelicsForProfile);
}
LOGGER.debug("[Skyblocker] Loaded found relics");
- } catch (FileNotFoundException ignored) {
+ } catch (NoSuchFileException ignored) {
} catch (IOException e) {
LOGGER.error("[Skyblocker] Failed to load found relics", e);
}
@@ -85,7 +90,15 @@ public class Relics {
}
private static void saveFoundRelics(MinecraftClient client) {
- try (BufferedWriter writer = new BufferedWriter(new FileWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json").toFile()))) {
+ Map<String, Set<BlockPos>> foundRelics = new HashMap<>();
+ for (ProfileAwareWaypoint relic : relics.values()) {
+ for (String profile : relic.foundProfiles) {
+ foundRelics.computeIfAbsent(profile, profile_ -> new HashSet<>());
+ foundRelics.get(profile).add(relic.pos);
+ }
+ }
+
+ try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) {
JsonObject json = new JsonObject();
for (Map.Entry<String, Set<BlockPos>> foundRelicsForProfile : foundRelics.entrySet()) {
JsonArray foundRelicsJson = new JsonArray();
@@ -105,12 +118,12 @@ public class Relics {
dispatcher.register(literal(SkyblockerMod.NAMESPACE)
.then(literal("relics")
.then(literal("markAllFound").executes(context -> {
- Relics.markAllFound();
+ relics.values().forEach(ProfileAwareWaypoint::setFound);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllFound")));
return 1;
}))
.then(literal("markAllMissing").executes(context -> {
- Relics.markAllMissing();
+ relics.values().forEach(ProfileAwareWaypoint::setMissing);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllMissing")));
return 1;
}))));
@@ -120,11 +133,10 @@ public class Relics {
SkyblockerConfig.Relics config = SkyblockerConfigManager.get().locations.spidersDen.relics;
if (config.enableRelicsHelper && relicsLoaded.isDone() && Utils.getLocationRaw().equals("combat_1")) {
- for (BlockPos fairySoulPos : relics) {
- boolean isRelicMissing = isRelicMissing(fairySoulPos);
+ for (ProfileAwareWaypoint relic : relics.values()) {
+ boolean isRelicMissing = relic.shouldRender();
if (!isRelicMissing && !config.highlightFoundRelics) continue;
- float[] colorComponents = isRelicMissing ? DyeColor.YELLOW.getColorComponents() : DyeColor.BROWN.getColorComponents();
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F);
+ relic.render(context);
}
}
}
@@ -143,30 +155,10 @@ public class Relics {
LOGGER.warn("[Skyblocker] Failed to mark closest relic as found because player is null");
return;
}
- relics.stream()
- .filter(Relics::isRelicMissing)
- .min(Comparator.comparingDouble(relicPos -> relicPos.getSquaredDistance(player.getPos())))
- .filter(relicPos -> relicPos.getSquaredDistance(player.getPos()) <= 16)
- .ifPresent(relicPos -> {
- foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>());
- foundRelics.get(Utils.getProfile()).add(relicPos);
- });
- }
-
- private static boolean isRelicMissing(BlockPos relicPos) {
- Set<BlockPos> foundRelicsForProfile = foundRelics.get(Utils.getProfile());
- return foundRelicsForProfile == null || !foundRelicsForProfile.contains(relicPos);
- }
-
- private static void markAllFound() {
- foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>());
- foundRelics.get(Utils.getProfile()).addAll(relics);
- }
-
- private static void markAllMissing() {
- Set<BlockPos> foundRelicsForProfile = foundRelics.get(Utils.getProfile());
- if (foundRelicsForProfile != null) {
- foundRelicsForProfile.clear();
- }
+ relics.values().stream()
+ .filter(Waypoint::shouldRender)
+ .min(Comparator.comparingDouble(relic -> relic.pos.getSquaredDistance(player.getPos())))
+ .filter(relic -> relic.pos.getSquaredDistance(player.getPos()) <= 16)
+ .ifPresent(Waypoint::setFound);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
index c0648eba..0121f8ad 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
@@ -21,33 +21,33 @@ public class ApiUtils {
* Do not iterate over this map, it will be accessed and modified by multiple threads.
*/
private static final Object2ObjectOpenHashMap<String, String> NAME_2_UUID_CACHE = new Object2ObjectOpenHashMap<>();
-
+
public static void init() {
//Clear cache every 20 minutes
Scheduler.INSTANCE.scheduleCyclic(NAME_2_UUID_CACHE::clear, 24_000, true);
}
-
+
/**
* Multithreading is to be handled by the method caller
*/
public static String name2Uuid(String name) {
Session session = MinecraftClient.getInstance().getSession();
-
+
if (session.getUsername().equals(name)) return UndashedUuid.toString(session.getUuidOrNull());
if (NAME_2_UUID_CACHE.containsKey(name)) return NAME_2_UUID_CACHE.get(name);
-
+
try (ApiResponse response = Http.sendName2UuidRequest(name)) {
if (response.ok()) {
String uuid = JsonParser.parseString(response.content()).getAsJsonObject().get("id").getAsString();
-
+
NAME_2_UUID_CACHE.put(name, uuid);
-
+
return uuid;
}
} catch (Exception e) {
LOGGER.error("[Skyblocker] Name to uuid lookup failed! Name: {}", name, e);
}
-
+
return "";
}
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Constants.java b/src/main/java/de/hysky/skyblocker/utils/Constants.java
index 94eacf49..134b7888 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Constants.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Constants.java
@@ -14,7 +14,7 @@ import net.minecraft.util.Formatting;
* Holds generic static constants
*/
public interface Constants {
- String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u12DE";
+ String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u0FC7\uA56A\u12DE";
IntFunction<UnaryOperator<Style>> WITH_COLOR = color -> style -> style.withColor(color);
Supplier<MutableText> PREFIX = () -> Text.empty()
.append(Text.literal("[").formatted(Formatting.GRAY))
diff --git a/src/main/java/de/hysky/skyblocker/utils/Http.java b/src/main/java/de/hysky/skyblocker/utils/Http.java
index 573c3458..eced3c08 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Http.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Http.java
@@ -26,17 +26,17 @@ import net.minecraft.SharedConstants;
*/
public class Http {
private static final String NAME_2_UUID = "https://api.minecraftservices.com/minecraft/profile/lookup/name/";
- private static final String HYPIXEL_PROXY = "https://hysky.de/api/hypixel/";
+ private static final String HYPIXEL_PROXY = "https://hysky.de/api/hypixel/v2/";
private static final String USER_AGENT = "Skyblocker/" + SkyblockerMod.VERSION + " (" + SharedConstants.getGameVersion().getName() + ")";
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.followRedirects(Redirect.NORMAL)
.build();
-
+
public static String sendGetRequest(String url) throws IOException, InterruptedException {
return sendCacheableGetRequest(url).content();
}
-
+
private static ApiResponse sendCacheableGetRequest(String url) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.GET()
@@ -46,16 +46,16 @@ public class Http {
.version(Version.HTTP_2)
.uri(URI.create(url))
.build();
-
+
HttpResponse<InputStream> response = HTTP_CLIENT.send(request, BodyHandlers.ofInputStream());
InputStream decodedInputStream = getDecodedInputStream(response);
-
+
String body = new String(decodedInputStream.readAllBytes());
HttpHeaders headers = response.headers();
-
+
return new ApiResponse(body, response.statusCode(), getCacheStatus(headers), getAge(headers));
}
-
+
public static HttpHeaders sendHeadRequest(String url) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.method("HEAD", BodyPublishers.noBody())
@@ -63,27 +63,29 @@ public class Http {
.version(Version.HTTP_2)
.uri(URI.create(url))
.build();
-
- HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding());
+
+ HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding());
return response.headers();
}
-
+
public static ApiResponse sendName2UuidRequest(String name) throws IOException, InterruptedException {
return sendCacheableGetRequest(NAME_2_UUID + name);
}
-
+
/**
* @param endpoint the endpoint - do not include any leading or trailing slashes
* @param query the query string - use empty string if n/a
* @return the requested data with zero pre-processing applied
+ *
+ * @implNote the {@code v2} prefix is automatically added
*/
public static ApiResponse sendHypixelRequest(String endpoint, @NotNull String query) throws IOException, InterruptedException {
return sendCacheableGetRequest(HYPIXEL_PROXY + endpoint + query);
}
-
+
private static InputStream getDecodedInputStream(HttpResponse<InputStream> response) {
String encoding = getContentEncoding(response.headers());
-
+
try {
switch (encoding) {
case "":
@@ -99,19 +101,19 @@ public class Http {
throw new UncheckedIOException(e);
}
}
-
+
private static String getContentEncoding(HttpHeaders headers) {
return headers.firstValue("Content-Encoding").orElse("");
}
-
+
public static String getEtag(HttpHeaders headers) {
return headers.firstValue("Etag").orElse("");
}
-
+
public static String getLastModified(HttpHeaders headers) {
return headers.firstValue("Last-Modified").orElse("");
}
-
+
/**
* Returns the cache status of the resource
*
@@ -120,18 +122,18 @@ public class Http {
private static String getCacheStatus(HttpHeaders headers) {
return headers.firstValue("CF-Cache-Status").orElse("UNKNOWN");
}
-
+
private static int getAge(HttpHeaders headers) {
return Integer.parseInt(headers.firstValue("Age").orElse("-1"));
}
-
+
//TODO If ever needed, we could just replace cache status with the response headers and go from there
public record ApiResponse(String content, int statusCode, String cacheStatus, int age) implements AutoCloseable {
-
+
public boolean ok() {
return statusCode == 200;
}
-
+
public boolean cached() {
return cacheStatus.equals("HIT");
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
index 6d78b3f3..870e94da 100644
--- a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
+++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
@@ -14,10 +14,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
/**
* Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized.
@@ -74,8 +76,7 @@ public class NEURepoManager {
CompletableFuture.runAsync(() -> {
try {
ItemRepository.setFilesImported(false);
- File dir = NEURepoManager.LOCAL_REPO_DIR.toFile();
- recursiveDelete(dir);
+ recursiveDelete(NEURepoManager.LOCAL_REPO_DIR);
} catch (Exception ex) {
if (MinecraftClient.getInstance().player != null)
MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.updaterepository.failed")), false);
@@ -86,14 +87,18 @@ public class NEURepoManager {
}
@SuppressWarnings("ResultOfMethodCallIgnored")
- private static void recursiveDelete(File dir) {
- File[] children;
- if (dir.isDirectory() && !Files.isSymbolicLink(dir.toPath()) && (children = dir.listFiles()) != null) {
- for (File child : children) {
- recursiveDelete(child);
- }
+ private static void recursiveDelete(Path dir) throws IOException {
+ if (Files.isDirectory(dir) && !Files.isSymbolicLink(dir)) {
+ Files.list(dir).forEach(child -> {
+ try {
+ recursiveDelete(child);
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker] Encountered an exception while deleting a file! Path: {}", child.toAbsolutePath(), e);
+ }
+ });
}
- dir.delete();
+
+ Files.delete(dir);
}
/**
diff --git a/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java b/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java
index 0a42c6ae..2edd61f1 100644
--- a/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java
@@ -42,13 +42,13 @@ public class SlayerUtils {
try {
for (int i = 0; i < Utils.STRING_SCOREBOARD.size(); i++) {
String line = Utils.STRING_SCOREBOARD.get(i);
-
+
if (line.contains("Slay the boss!")) return true;
}
} catch (NullPointerException e) {
LOGGER.error("[Skyblocker] Error while checking if player is in slayer", e);
}
-
+
return false;
}
} \ No newline at end of file
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index 71e08865..02b1637b 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -363,7 +363,7 @@ public class Utils {
if (isOnSkyblock && message.startsWith("Profile ID: ")) {
profileId = message.replace("Profile ID: ", "");
-
+
MuseumItemCache.tick(profileId);
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
index 7892445e..2c75ef0a 100644
--- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
+++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
@@ -9,7 +9,6 @@ import de.hysky.skyblocker.skyblock.dungeon.ThreeWeirdos;
import de.hysky.skyblocker.skyblock.dungeon.Trivia;
import de.hysky.skyblocker.skyblock.dwarven.Fetchur;
import de.hysky.skyblocker.skyblock.dwarven.Puzzler;
-import de.hysky.skyblocker.skyblock.filters.*;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
index 064b564c..43d595a5 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
@@ -1,11 +1,16 @@
package de.hysky.skyblocker.utils.render;
import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.logging.LogUtils;
+
+import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.title.Title;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.fabricmc.fabric.api.event.Event;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.render.*;
@@ -14,65 +19,63 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
+import org.slf4j.Logger;
public class RenderHelper {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final Identifier TRANSLUCENT_DRAW = new Identifier(SkyblockerMod.NAMESPACE, "translucent_draw");
+ private static final MethodHandle SCHEDULE_DEFERRED_RENDER_TASK = getDeferredRenderTaskHandle();
private static final Vec3d ONE = new Vec3d(1, 1, 1);
private static final int MAX_OVERWORLD_BUILD_HEIGHT = 319;
private static final MinecraftClient client = MinecraftClient.getInstance();
- public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- renderFilledThroughWalls(context, pos, colorComponents, alpha);
- renderBeaconBeam(context, pos, colorComponents);
+ public static void init() {
+ WorldRenderEvents.AFTER_TRANSLUCENT.addPhaseOrdering(Event.DEFAULT_PHASE, TRANSLUCENT_DRAW);
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(TRANSLUCENT_DRAW, RenderHelper::drawTranslucents);
}
- public static void renderFilledThroughWalls(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
- renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, true);
- }
+ public static void renderFilledWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha, boolean throughWalls) {
+ renderFilled(context, pos, colorComponents, alpha, throughWalls);
+ renderBeaconBeam(context, pos, colorComponents);
}
- public static void renderFilledIfVisible(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
- renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false);
+ public static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha, boolean throughWalls) {
+ if (throughWalls) {
+ if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, true);
+ }
+ } else {
+ if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false);
+ }
}
}
-
+
private static void renderFilled(WorldRenderContext context, Vec3d pos, Vec3d dimensions, float[] colorComponents, float alpha, boolean throughWalls) {
MatrixStack matrices = context.matrixStack();
Vec3d camera = context.camera().getPos();
- Tessellator tessellator = RenderSystem.renderThreadTesselator();
- BufferBuilder buffer = tessellator.getBuffer();
-
+
matrices.push();
matrices.translate(-camera.x, -camera.y, -camera.z);
-
- RenderSystem.setShader(GameRenderer::getPositionColorProgram);
- RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
- RenderSystem.polygonOffset(-1f, -10f);
- RenderSystem.enablePolygonOffset();
- RenderSystem.enableBlend();
- RenderSystem.defaultBlendFunc();
- RenderSystem.enableDepthTest();
- RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
- RenderSystem.disableCull();
-
- buffer.begin(DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
+
+ VertexConsumerProvider consumers = context.consumers();
+ VertexConsumer buffer = consumers.getBuffer(throughWalls ? SkyblockerRenderLayers.FILLED_THROUGH_WALLS : SkyblockerRenderLayers.FILLED);
+
WorldRenderer.renderFilledBox(matrices, buffer, pos.x, pos.y, pos.z, pos.x + dimensions.x, pos.y + dimensions.y, pos.z + dimensions.z, colorComponents[0], colorComponents[1], colorComponents[2], alpha);
- tessellator.draw();
-
+
matrices.pop();
- RenderSystem.polygonOffset(0f, 0f);
- RenderSystem.disablePolygonOffset();
- RenderSystem.disableBlend();
- RenderSystem.disableDepthTest();
- RenderSystem.depthFunc(GL11.GL_LEQUAL);
- RenderSystem.enableCull();
}
private static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
@@ -83,13 +86,8 @@ public class RenderHelper {
matrices.push();
matrices.translate(pos.getX() - camera.getX(), pos.getY() - camera.getY(), pos.getZ() - camera.getZ());
- Tessellator tessellator = RenderSystem.renderThreadTesselator();
- BufferBuilder buffer = tessellator.getBuffer();
- VertexConsumerProvider.Immediate consumer = VertexConsumerProvider.immediate(buffer);
-
- BeaconBlockEntityRendererInvoker.renderBeam(matrices, consumer, context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
+ BeaconBlockEntityRendererInvoker.renderBeam(matrices, context.consumers(), context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
- consumer.draw();
matrices.pop();
}
}
@@ -259,6 +257,28 @@ public class RenderHelper {
}
/**
+ * This is called after all {@link WorldRenderEvents#AFTER_TRANSLUCENT} listeners have been called so that we can draw all remaining render layers.
+ */
+ private static void drawTranslucents(WorldRenderContext context) {
+ //Draw all render layers that haven't been drawn yet - drawing a specific layer does nothing and idk why
+ ((VertexConsumerProvider.Immediate) context.consumers()).draw();
+ }
+
+ public static void runOnRenderThread(Runnable runnable) {
+ if (RenderSystem.isOnRenderThread()) {
+ runnable.run();
+ } else if (SCHEDULE_DEFERRED_RENDER_TASK != null) { //Sodium
+ try {
+ SCHEDULE_DEFERRED_RENDER_TASK.invokeExact(runnable);
+ } catch (Throwable t) {
+ LOGGER.error("[Skyblocker] Failed to schedule a render task!", t);
+ }
+ } else { //Vanilla
+ RenderSystem.recordRenderCall(runnable::run);
+ }
+ }
+
+ /**
* Adds the title to {@link TitleContainer} and {@link #playNotificationSound() plays the notification sound} if the title is not in the {@link TitleContainer} already.
* No checking needs to be done on whether the title is in the {@link TitleContainer} already by the caller.
*
@@ -284,12 +304,26 @@ public class RenderHelper {
}
private static void playNotificationSound() {
- if (MinecraftClient.getInstance().player != null) {
- MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 100f, 0.1f);
+ if (client.player != null) {
+ client.player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 100f, 0.1f);
}
}
public static boolean pointIsInArea(double x, double y, double x1, double y1, double x2, double y2) {
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
+
+ // TODO Get rid of reflection once the new Sodium is released
+ private static MethodHandle getDeferredRenderTaskHandle() {
+ try {
+ Class<?> deferredTaskClass = Class.forName("me.jellysquid.mods.sodium.client.render.util.DeferredRenderTask");
+
+ MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(void.class, Runnable.class);
+
+ return lookup.findStatic(deferredTaskClass, "schedule", mt);
+ } catch (Throwable ignored) {}
+
+ return null;
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java
new file mode 100644
index 00000000..ee113cc4
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java
@@ -0,0 +1,36 @@
+package de.hysky.skyblocker.utils.render;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.RenderLayer.MultiPhase;
+import net.minecraft.client.render.RenderLayer.MultiPhaseParameters;
+import net.minecraft.client.render.RenderPhase;
+import net.minecraft.client.render.RenderPhase.Cull;
+import net.minecraft.client.render.RenderPhase.DepthTest;
+import net.minecraft.client.render.RenderPhase.Transparency;
+import net.minecraft.client.render.VertexFormat.DrawMode;
+import net.minecraft.client.render.VertexFormats;
+
+public class SkyblockerRenderLayers {
+ private static final Transparency DEFAULT_TRANSPARENCY = new Transparency("default_transparency", () -> {
+ RenderSystem.enableBlend();
+ RenderSystem.defaultBlendFunc();
+ }, RenderSystem::disableBlend);
+
+ public static final MultiPhase FILLED = RenderLayer.of("filled", VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP, RenderLayer.CUTOUT_BUFFER_SIZE, false, true, MultiPhaseParameters.builder()
+ .program(RenderPhase.COLOR_PROGRAM)
+ .cull(Cull.DISABLE_CULLING)
+ .layering(RenderPhase.POLYGON_OFFSET_LAYERING)
+ .transparency(DEFAULT_TRANSPARENCY)
+ .depthTest(DepthTest.LEQUAL_DEPTH_TEST)
+ .build(false));
+
+ public static final MultiPhase FILLED_THROUGH_WALLS = RenderLayer.of("filled_through_walls", VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP, RenderLayer.CUTOUT_BUFFER_SIZE, false, true, MultiPhaseParameters.builder()
+ .program(RenderPhase.COLOR_PROGRAM)
+ .cull(Cull.DISABLE_CULLING)
+ .layering(RenderPhase.POLYGON_OFFSET_LAYERING)
+ .transparency(DEFAULT_TRANSPARENCY)
+ .depthTest(DepthTest.ALWAYS_DEPTH_TEST)
+ .build(false));
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
index 19d41c91..cc80f74c 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
@@ -27,7 +27,7 @@ public class TitleContainerConfigScreen extends Screen {
private float hudY = SkyblockerConfigManager.get().general.titleContainer.y;
private final Screen parent;
private boolean changedScale;
-
+
protected TitleContainerConfigScreen() {
this(null);
}
@@ -173,18 +173,18 @@ public class TitleContainerConfigScreen extends Screen {
public void close() {
SkyblockerConfigManager.get().general.titleContainer.x = (int) hudX;
SkyblockerConfigManager.get().general.titleContainer.y = (int) hudY;
-
+
//TODO Come up with a better, less hacky solution for this in the future (:
if (parent instanceof YACLScreen yaclScreen) {
ConfigCategory category = yaclScreen.config.categories().stream().filter(cat -> cat.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.category.general"))).findFirst().orElseThrow();
OptionGroup group = category.groups().stream().filter(grp -> grp.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.option.general.titleContainer"))).findFirst().orElseThrow();
-
+
Option<?> scaleOpt = group.options().get(0);
-
+
// Refresh the value in the config with the bound value
if (changedScale) scaleOpt.forgetPendingValue();
}
-
+
SkyblockerConfigManager.save();
this.client.setScreen(parent);
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java
index b254f524..139ac05e 100644
--- a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java
+++ b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java
@@ -28,14 +28,14 @@ public class Scheduler {
protected Scheduler() {
}
-
+
/**
* @see #schedule(Runnable, int, boolean)
*/
public void schedule(Runnable task, int delay) {
schedule(task, delay, false);
}
-
+
/**
* @see #scheduleCyclic(Runnable, int, boolean)
*/
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java
new file mode 100644
index 00000000..7aa99d14
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java
@@ -0,0 +1,44 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import de.hysky.skyblocker.utils.Utils;
+import net.minecraft.util.math.BlockPos;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Supplier;
+
+public class ProfileAwareWaypoint extends Waypoint {
+ public final Set<String> foundProfiles = new HashSet<>();
+ private final float[] missingColor;
+ private final float[] foundColor;
+
+ public ProfileAwareWaypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] missingColor, float[] foundColor) {
+ super(pos, typeSupplier, null);
+ this.missingColor = missingColor;
+ this.foundColor = foundColor;
+ }
+
+ @Override
+ public boolean shouldRender() {
+ return !foundProfiles.contains(Utils.getProfile());
+ }
+
+ @Override
+ public void setFound() {
+ foundProfiles.add(Utils.getProfile());
+ }
+
+ public void setFound(String profile) {
+ foundProfiles.add(profile);
+ }
+
+ @Override
+ public void setMissing() {
+ foundProfiles.remove(Utils.getProfile());
+ }
+
+ @Override
+ protected float[] getColorComponents() {
+ return foundProfiles.contains(Utils.getProfile()) ? foundColor : missingColor;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
index e7858f05..eb30cf8d 100644
--- a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
@@ -11,30 +11,30 @@ public class Waypoint {
protected static final float DEFAULT_HIGHLIGHT_ALPHA = 0.5f;
protected static final float DEFAULT_LINE_WIDTH = 5f;
public final BlockPos pos;
- private final Box box;
- private final Supplier<Type> typeSupplier;
- private final float[] colorComponents;
- private final float alpha;
- private final float lineWidth;
- private final boolean throughWalls;
+ final Box box;
+ final Supplier<Type> typeSupplier;
+ final float[] colorComponents;
+ final float alpha;
+ final float lineWidth;
+ final boolean throughWalls;
private boolean shouldRender;
protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents) {
- this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA);
+ this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA, DEFAULT_LINE_WIDTH);
}
protected Waypoint(BlockPos pos, Type type, float[] colorComponents, float alpha) {
- this(pos, () -> type, colorComponents, alpha);
- }
-
- protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha) {
- this(pos, typeSupplier, colorComponents, alpha, DEFAULT_LINE_WIDTH);
+ this(pos, () -> type, colorComponents, alpha, DEFAULT_LINE_WIDTH);
}
protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth) {
this(pos, typeSupplier, colorComponents, alpha, lineWidth, true);
}
+ public Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, boolean throughWalls) {
+ this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA, DEFAULT_LINE_WIDTH, throughWalls);
+ }
+
protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth, boolean throughWalls) {
this(pos, typeSupplier, colorComponents, alpha, lineWidth, throughWalls, true);
}
@@ -62,19 +62,25 @@ public class Waypoint {
this.shouldRender = true;
}
+ protected float[] getColorComponents() {
+ return colorComponents;
+ }
+
public void render(WorldRenderContext context) {
switch (typeSupplier.get()) {
- case WAYPOINT -> RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha);
+ case WAYPOINT -> RenderHelper.renderFilledWithBeaconBeam(context, pos, getColorComponents(), alpha, throughWalls);
case OUTLINED_WAYPOINT -> {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha);
+ float[] colorComponents = getColorComponents();
+ RenderHelper.renderFilledWithBeaconBeam(context, pos, colorComponents, alpha, throughWalls);
RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
}
- case HIGHLIGHT -> RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha);
+ case HIGHLIGHT -> RenderHelper.renderFilled(context, pos, getColorComponents(), alpha, throughWalls);
case OUTLINED_HIGHLIGHT -> {
- RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha);
+ float[] colorComponents = getColorComponents();
+ RenderHelper.renderFilled(context, pos, colorComponents, alpha, throughWalls);
RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
}
- case OUTLINE -> RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
+ case OUTLINE -> RenderHelper.renderOutline(context, box, getColorComponents(), lineWidth, throughWalls);
}
}
diff --git a/src/main/resources/assets/skyblocker/dungeons/secretlocations.json b/src/main/resources/assets/skyblocker/dungeons/secretlocations.json
index a0a97c67..0f22f597 100644
--- a/src/main/resources/assets/skyblocker/dungeons/secretlocations.json
+++ b/src/main/resources/assets/skyblocker/dungeons/secretlocations.json
@@ -2173,7 +2173,7 @@
},
{
"secretName":"3 - Lever 2",
- "category":"Lever",
+ "category":"lever",
"x":31,
"y":53,
"z":24
@@ -2375,7 +2375,7 @@
},
{
"secretName":"2 - Item",
- "category":"Item",
+ "category":"item",
"x":27,
"y":56,
"z":19
@@ -3936,7 +3936,7 @@
},
{
"secretName":"4/5/6 - Entrance 3",
- "category":"",
+ "category":"entrance",
"x":31,
"y":142,
"z":39
diff --git a/src/main/resources/assets/skyblocker/lang/en_ca.json b/src/main/resources/assets/skyblocker/lang/en_ca.json
index 5ecbd676..883de5dc 100644
--- a/src/main/resources/assets/skyblocker/lang/en_ca.json
+++ b/src/main/resources/assets/skyblocker/lang/en_ca.json
@@ -2,8 +2,8 @@
"text.autoconfig.skyblocker.option.general.bars": "Health, Mana, Defence & XP Bars",
"text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Grey out chests that have already been opened.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Colour",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Enable Livid Colour",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Send the livid colour in the chat during the Livid boss fight.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Enable Livid Colour",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Send the livid colour in the chat during the Livid boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Livid Colour Text",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Text which will be sent in the chat during the Livid boss fight. The string \"[color]\" will be replaced with the livid colour.",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveColor": "Solve Select Coloured",
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index 31e7bb9c..b0d70a2d 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -50,6 +50,11 @@
"text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts": "Enable Command Argument Shortcuts",
"text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts.@Tooltip": "Shortcuts that replace one or more word(s)/argument(s) of a command which has multiple words/arguments. Edit shortcuts with \"/skyblocker shortcuts\". Shortcuts must be enabled for this to take effect.",
"text.autoconfig.skyblocker.option.general.shortcuts.config": "Shortcuts Config...",
+ "text.autoconfig.skyblocker.option.general.waypoints": "Waypoints",
+ "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "Enable Waypoints",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "Waypoint Type",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and a beacon beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Only displays an outline.",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote": "\n\n\nThis option does not apply to all waypoints. Some waypoints such as secret waypoints have their own waypoint type option.",
"text.autoconfig.skyblocker.option.general.quiverWarning": "Quiver Warning",
"text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarning": "Enable Quiver Warning",
"text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarningInDungeons": "Enable Quiver Warning In Dungeons",
@@ -76,7 +81,9 @@
"text.autoconfig.skyblocker.option.general.itemTooltip.avg.BOTH": "Both",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableLowestBIN": "Enable Lowest BIN Price",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableBazaarPrice": "Enable Bazaar buy/sell Price",
- "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate": "Enable Museum & Date",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableObtainedDate": "Enable Obtained Date",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo": "Enable Museum Info",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo.@Tooltip": "If this item is donatable to the museum, then the item's category in the musuem is displayed. It also displays a marker indicating whether you've donated that item to your musuem or not (freebies not yet supported).\n\nMake sure to enable your Museum API for accurate information!",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableExoticTooltip": "Enable Exotic Tooltip",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableExoticTooltip.@Tooltip": "Displays the type of exotic below the item's name if an armor piece is exotic.",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay": "Item Info Display",
@@ -84,6 +91,8 @@
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.attributeShardInfo.@Tooltip": "Displays the attribute's level as the stack count and the initials of the attribute's name.",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds": "Item Rarity Backgrounds",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds.@Tooltip": "Displays a colored background behind an item, the color represents the item's rarity.",
+ "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle": "Item Rarity Background Style",
+ "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle.@Tooltip": "Choose between a circular or a square background style!",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundsOpacity": "Item Rarity Backgrounds Opacity",
"text.autoconfig.skyblocker.option.general.wikiLookup": "Wiki Lookup",
"text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup": "Enable Wiki Lookup",
@@ -152,8 +161,6 @@
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSecretWaypoints": "Enable Dungeon Secret Waypoints",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints": "Do Not Initialize Secret Waypoints",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.",
- "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType": "Waypoint Type",
- "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Outlines the secret in a box.",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.showSecretText": "Show Secret Text",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableEntranceWaypoints" : "Enable Entrance Waypoints",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSuperboomWaypoints" : "Enable Superboom Waypoints",
@@ -188,6 +195,8 @@
"text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScreen": "Dungeon Map Placement Config...",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Map Scaling",
+ "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker": "Player Secrets Tracker",
+ "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip": "Tracks the amount of secrets people in your dungeon run are doing.",
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Starred Mob Glow",
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow.@Tooltip": "Applies the glowing effect to starred mobs that are visible.",
"text.autoconfig.skyblocker.option.locations.dungeons.solveThreeWeirdos": "Solve Three Weirdos Puzzle",
@@ -199,8 +208,10 @@
"text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe": "Solve Tic Tac Toe Puzzle",
"text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe.@Tooltip": "Puts a red box around the next best move for you to make!",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Color",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Enable Livid Color",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Send the livid color in the chat during the Livid boss fight.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow": "Enable Livid Color Glow",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow.@Tooltip": "Applies the glowing effect to the correct Livid in F5/M5.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Enable Livid Color Text",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Send the livid color in the chat during the Livid boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Livid Color Text",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Text which will be sent in the chat during the Livid boss fight. The string \"[color]\" will be replaced with the livid color.",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Terminal Solvers",
@@ -222,6 +233,8 @@
"text.autoconfig.skyblocker.option.locations.rift": "The Rift",
"text.autoconfig.skyblocker.option.locations.rift.mirrorverseWaypoints": "Enable Mirrorverse Waypoints",
+ "text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow": "Blobbercyst Glow",
+ "text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow.@Tooltip": "Applies the glowing effect to the Blobbercysts from the BACTE fight.",
"text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints": "Enable Enigma Soul Waypoints",
"text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints.@Tooltip": "Note: Many enigma souls have a small task you must complete in order to get it, so its recommended to also watch a YouTube video when finding them.",
"text.autoconfig.skyblocker.option.locations.rift.highlightFoundEnigmaSouls": "Highlight Found Enigma Souls",
@@ -234,7 +247,8 @@
"text.autoconfig.skyblocker.option.messages.chatFilterResult.ACTION_BAR": "Move to action bar",
"text.autoconfig.skyblocker.option.messages.hideAbility": "Hide Ability Cooldown",
"text.autoconfig.skyblocker.option.messages.hideHeal": "Hide Heal Messages",
- "text.autoconfig.skyblocker.option.messages.hideAOTE": "Hide AOTE Messages",
+ "text.autoconfig.skyblocker.option.messages.hideAOTE": "Hide Teleport Ability Messages",
+ "text.autoconfig.skyblocker.option.messages.hideAOTE.@Tooltip": "Hides those pesky \"There are blocks in the way!\" messages.",
"text.autoconfig.skyblocker.option.messages.hideImplosion": "Hide Implosion Message",
"text.autoconfig.skyblocker.option.messages.hideMoltenWave": "Hide Molten Wave Message",
"text.autoconfig.skyblocker.option.messages.hideAds": "Hide Ads From Public Chat",
@@ -315,7 +329,7 @@
"skyblocker.shortcuts.deleteQuestion": "Are you sure you want to remove this shortcut?",
"skyblocker.shortcuts.deleteWarning": "Shortcut '%s' will be lost forever! (A long time!)",
"skyblocker.shortcuts.new": "New Shortcut",
- "skyblocker.shortcuts.commandSuggestionTooltip": "Due to limitations of Minecraft, command suggestions will only work after a restart of the game.",
+ "skyblocker.shortcuts.commandSuggestionTooltip": "Due to limitations of Minecraft, command suggestions will only work after joining a new world.",
"skyblocker.customItemNames.removed": "§fRemoved this item's custom name.",
"skyblocker.customItemNames.neverHad": "§fThis item doesn't have a custom name set, but why not add one? ;)",
diff --git a/src/main/resources/assets/skyblocker/lang/fr_fr.json b/src/main/resources/assets/skyblocker/lang/fr_fr.json
index 207852ac..a08371b3 100644
--- a/src/main/resources/assets/skyblocker/lang/fr_fr.json
+++ b/src/main/resources/assets/skyblocker/lang/fr_fr.json
@@ -67,8 +67,8 @@
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Taille de la Carte",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Texte qui sera envoyé dans le chat lors du boss Livid. Le string \"[color]\" sera remplacé par la couleur Livid.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Couleur Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Activer la Couleur Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Envoyer la Couler Livid dans le chat durant le boss Livid.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Activer la Couleur Livid",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Envoyer la Couler Livid dans le chat durant le boss Livid.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Texte de la Couleur Livid",
"text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER1": "Couche 1",
"text.autoconfig.skyblocker.option.general.bars.barpositions.NONE": "Désactivé",
diff --git a/src/main/resources/assets/skyblocker/lang/pt_br.json b/src/main/resources/assets/skyblocker/lang/pt_br.json
index d0371642..f6362986 100644
--- a/src/main/resources/assets/skyblocker/lang/pt_br.json
+++ b/src/main/resources/assets/skyblocker/lang/pt_br.json
@@ -184,7 +184,7 @@
"text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Ativar mapa",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Tamanho do mapa",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Cor do Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Ativar cor para Livid",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Ativar cor para Livid",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Guia dos terminais",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveColor": "Guia de seleção colorido",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveOrder": "Guia de clique em ordem",
@@ -238,5 +238,5 @@
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Brilho em Mobs com estrela",
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow.@Tooltip": "Aplicar o efeito de brilho para Mobs estrelados que estão visíveis.",
"text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe": "Guia para o Puzzle do jogo da velha",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Mandar a cor do Livid no chat durante a luta contra Livid."
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Mandar a cor do Livid no chat durante a luta contra Livid."
}
diff --git a/src/main/resources/assets/skyblocker/lang/ru_ru.json b/src/main/resources/assets/skyblocker/lang/ru_ru.json
index 980c130a..d22f6274 100644
--- a/src/main/resources/assets/skyblocker/lang/ru_ru.json
+++ b/src/main/resources/assets/skyblocker/lang/ru_ru.json
@@ -82,9 +82,9 @@
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Текст, который будет отправлен в чат во время боя с Livid. Вместо \"[color]\" отправится цвет босса.",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[1]": "\nКрасивый: Показывает название, процент и шкалу выполнения, а также иконку.",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Размер Карты",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Включить Цвет Босса Livid",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Включить Цвет Босса Livid",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Цвет Босса Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Отправляет в чат информацию о том, какого цвета босс Livid.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Отправляет в чат информацию о том, какого цвета босс Livid.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Текст О Цвете Livid",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style": "Стиль HUD",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[0]": "Упрощенный: Показывает название и процент выполнения.",
diff --git a/src/main/resources/assets/skyblocker/lang/zh_cn.json b/src/main/resources/assets/skyblocker/lang/zh_cn.json
index 4a3abde3..9f8bb08c 100644
--- a/src/main/resources/assets/skyblocker/lang/zh_cn.json
+++ b/src/main/resources/assets/skyblocker/lang/zh_cn.json
@@ -88,9 +88,9 @@
"text.autoconfig.skyblocker.option.general.fishing": "钓鱼助手",
"text.autoconfig.skyblocker.option.general.fishing.enableFishingHelper": "启用钓鱼助手",
"skyblocker.fishing.reelNow": "收竿!",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "启用真 Livid 的颜色提示",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "启用真 Livid 的颜色提示",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "提示真 Livid 的颜色",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "将真 Livid 的颜色发送到聊天栏。",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "将真 Livid 的颜色发送到聊天栏。",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "真 Livid 颜色提示信息",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Livid Boss战时发送到聊天栏的信息, 字段 “[color]” 将被替换为真 Livid 的颜色",
"key.skyblocker.defaultTgl": "将tab键所显示的列表改为默认空岛生存列表",
diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_circular.png
index fd8e8604..fd8e8604 100644
--- a/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background.png
+++ b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_circular.png
Binary files differ
diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.png
new file mode 100644
index 00000000..0392b56c
--- /dev/null
+++ b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.png
Binary files differ
diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json
index 5bafb324..4e7bfe16 100644
--- a/src/main/resources/skyblocker.mixins.json
+++ b/src/main/resources/skyblocker.mixins.json
@@ -36,12 +36,7 @@
"accessor.PlayerListHudAccessor",
"accessor.RecipeBookWidgetAccessor",
"accessor.ScreenAccessor",
- "accessor.WorldRendererAccessor",
- "yacl.DoubleFieldControllerMixin",
- "yacl.FloatFieldControllerMixin",
- "yacl.IntegerFieldControllerMixin",
- "yacl.LongFieldControllerMixin",
- "yacl.NumberFieldControllerMixin"
+ "accessor.WorldRendererAccessor"
],
"injectors": {
"defaultRequire": 1
diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java
new file mode 100644
index 00000000..0870e744
--- /dev/null
+++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java
@@ -0,0 +1,79 @@
+package de.hysky.skyblocker.skyblock.dungeon.secrets;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.mojang.serialization.JsonOps;
+import net.minecraft.util.math.BlockPos;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+public class SecretWaypointTest {
+ private final Gson gson = new Gson();
+
+ @Test
+ void testCodecSerialize() {
+ SecretWaypoint waypoint = new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN);
+ JsonElement json = SecretWaypoint.CODEC.encodeStart(JsonOps.INSTANCE, waypoint).result().orElseThrow();
+ String expectedJson = "{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]}";
+
+ Assertions.assertEquals(expectedJson, json.toString());
+ }
+
+ @Test
+ void testCodecDeserialize() {
+ String json = "{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]}";
+ SecretWaypoint waypoint = SecretWaypoint.CODEC.parse(JsonOps.INSTANCE, gson.fromJson(json, JsonElement.class)).result().orElseThrow();
+ SecretWaypoint expectedWaypoint = new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN);
+
+ equal(expectedWaypoint, waypoint);
+ }
+
+ @Test
+ void testListCodecSerialize() {
+ List<SecretWaypoint> waypoints = List.of(new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN), new SecretWaypoint(1, SecretWaypoint.Category.CHEST, "name", new BlockPos(-1, 0, 1)));
+ JsonElement json = SecretWaypoint.LIST_CODEC.encodeStart(JsonOps.INSTANCE, waypoints).result().orElseThrow();
+ String expectedJson = "[{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]},{\"secretIndex\":1,\"category\":\"chest\",\"name\":{\"text\":\"name\"},\"pos\":[-1,0,1]}]";
+
+ Assertions.assertEquals(expectedJson, json.toString());
+ }
+
+ @Test
+ void testListCodecDeserialize() {
+ String json = "[{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]},{\"secretIndex\":1,\"category\":\"chest\",\"name\":{\"text\":\"name\"},\"pos\":[-1,0,1]}]";
+ List<SecretWaypoint> waypoints = SecretWaypoint.LIST_CODEC.parse(JsonOps.INSTANCE, gson.fromJson(json, JsonElement.class)).result().orElseThrow();
+ List<SecretWaypoint> expectedWaypoints = List.of(new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN), new SecretWaypoint(1, SecretWaypoint.Category.CHEST, "name", new BlockPos(-1, 0, 1)));
+
+ Assertions.assertEquals(expectedWaypoints.size(), waypoints.size());
+ for (int i = 0; i < expectedWaypoints.size(); i++) {
+ SecretWaypoint expectedWaypoint = expectedWaypoints.get(i);
+ SecretWaypoint waypoint = waypoints.get(i);
+ equal(expectedWaypoint, waypoint);
+ }
+ }
+
+ @Test
+ void testGetCategory() {
+ JsonObject waypointJson = new JsonObject();
+ waypointJson.addProperty("category", "chest");
+ SecretWaypoint.Category category = SecretWaypoint.Category.get(waypointJson);
+ Assertions.assertEquals(SecretWaypoint.Category.CHEST, category);
+ }
+
+ @Test
+ void testGetCategoryDefault() {
+ JsonObject waypointJson = new JsonObject();
+ waypointJson.addProperty("category", "");
+ SecretWaypoint.Category category = SecretWaypoint.Category.get(waypointJson);
+ Assertions.assertEquals(SecretWaypoint.Category.DEFAULT, category);
+ }
+
+ private static void equal(SecretWaypoint expectedWaypoint, SecretWaypoint waypoint) {
+ Assertions.assertEquals(expectedWaypoint.secretIndex, waypoint.secretIndex);
+ Assertions.assertEquals(expectedWaypoint.category, waypoint.category);
+ Assertions.assertEquals(expectedWaypoint.name, waypoint.name);
+ Assertions.assertEquals(expectedWaypoint.pos, waypoint.pos);
+ }
+}
diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java
index 85b01b4b..93d33070 100644
--- a/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java
+++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java
@@ -9,7 +9,7 @@ public class ComboFilterTest extends ChatFilterTest<ComboFilter> {
@Test
void testComboMF() {
- assertMatches("+5 Kill Combo +3% ✯ Magic Find");
+ assertMatches("+5 Kill Combo +3✯ Magic Find");
}
@Test
@@ -18,8 +18,13 @@ public class ComboFilterTest extends ChatFilterTest<ComboFilter> {
}
@Test
- void testComboEXP() {
- assertMatches("+20 Kill Combo +15% Combat Exp");
+ void testComboWisdom() {
+ assertMatches("+20 Kill Combo +15☯ Combat Wisdom");
+ }
+
+ @Test
+ void testComboNoBonus() {
+ assertMatches("+50 Kill Combo");
}
@Test
diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java
new file mode 100644
index 00000000..9dc5b2b9
--- /dev/null
+++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java
@@ -0,0 +1,38 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import net.minecraft.util.math.BlockPos;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ProfileAwareWaypointTest {
+ @Test
+ void testShouldRender() {
+ ProfileAwareWaypoint waypoint = new ProfileAwareWaypoint(BlockPos.ORIGIN, null, null, null);
+ waypoint.setFound("profile");
+ Assertions.assertTrue(waypoint.shouldRender());
+ waypoint.setFound("");
+ Assertions.assertFalse(waypoint.shouldRender());
+ waypoint.setMissing();
+ Assertions.assertTrue(waypoint.shouldRender());
+ }
+
+ @Test
+ void testGetColorComponents() {
+ ProfileAwareWaypoint waypoint = new ProfileAwareWaypoint(BlockPos.ORIGIN, null, new float[]{0f, 0.5f, 1f}, new float[]{1f, 0.5f, 0f});
+ waypoint.setFound("profile");
+ float[] colorComponents = waypoint.getColorComponents();
+ Assertions.assertEquals(0f, colorComponents[0]);
+ Assertions.assertEquals(0.5f, colorComponents[1]);
+ Assertions.assertEquals(1f, colorComponents[2]);
+ waypoint.setFound("");
+ colorComponents = waypoint.getColorComponents();
+ Assertions.assertEquals(1f, colorComponents[0]);
+ Assertions.assertEquals(0.5f, colorComponents[1]);
+ Assertions.assertEquals(0f, colorComponents[2]);
+ waypoint.setMissing();
+ colorComponents = waypoint.getColorComponents();
+ Assertions.assertEquals(0f, colorComponents[0]);
+ Assertions.assertEquals(0.5f, colorComponents[1]);
+ Assertions.assertEquals(1f, colorComponents[2]);
+ }
+}
diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java
new file mode 100644
index 00000000..d8839951
--- /dev/null
+++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java
@@ -0,0 +1,70 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class WaypointTest {
+ private Waypoint.Type type;
+ private final float[] colorComponents = new float[]{0f, 0.5f, 1f};
+
+ @Test
+ void testDefaultConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents);
+ Assertions.assertEquals(BlockPos.ORIGIN, waypoint.pos);
+ Assertions.assertEquals(new Box(BlockPos.ORIGIN), waypoint.box);
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ Assertions.assertEquals(0f, waypoint.colorComponents[0]);
+ Assertions.assertEquals(0.5f, waypoint.colorComponents[1]);
+ Assertions.assertEquals(1f, waypoint.colorComponents[2]);
+ Assertions.assertEquals(Waypoint.DEFAULT_HIGHLIGHT_ALPHA, waypoint.alpha);
+ Assertions.assertEquals(Waypoint.DEFAULT_LINE_WIDTH, waypoint.lineWidth);
+ Assertions.assertTrue(waypoint.throughWalls);
+ Assertions.assertTrue(waypoint.shouldRender());
+ }
+
+ @Test
+ void testTypeConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, Waypoint.Type.WAYPOINT, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA);
+ Assertions.assertEquals(Waypoint.Type.WAYPOINT, waypoint.typeSupplier.get());
+ }
+
+ @Test
+ void testLineWidthConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, 10f);
+ Assertions.assertEquals(10f, waypoint.lineWidth);
+ }
+
+ @Test
+ void testThroughWallsConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, false);
+ Assertions.assertFalse(waypoint.throughWalls);
+ }
+
+ @Test
+ void testShouldRenderConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, true, false);
+ Assertions.assertFalse(waypoint.shouldRender());
+ }
+
+ @Test
+ void testFound() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents);
+ Assertions.assertTrue(waypoint.shouldRender());
+ waypoint.setFound();
+ Assertions.assertFalse(waypoint.shouldRender());
+ waypoint.setMissing();
+ Assertions.assertTrue(waypoint.shouldRender());
+ }
+
+ @Test
+ void testType() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents);
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ type = Waypoint.Type.WAYPOINT;
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ type = Waypoint.Type.OUTLINED_HIGHLIGHT;
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ }
+}