Skip to content
This repository was archived by the owner on Nov 27, 2024. It is now read-only.

Commit 2ea7166

Browse files
committed
add dwarven event widget
1 parent 8ddd769 commit 2ea7166

File tree

15 files changed

+375
-170
lines changed

15 files changed

+375
-170
lines changed

beta-changelog.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
## Features
2-
- update powders from tablist more often
3-
- rework powder calculation for powder grinding widget
4-
- use better prefix for chat messages
2+
- add event forecast widget for dwarves, crystals and mineshafts
53

64
## Bug Fixes
7-
- disable delete button of waypoint on deletion in location screen
5+
none
86

97
## Technical changes
10-
- update to konfig 2.0.2
11-
- rework event api to be hot-swappable
12-
- redo all calculations to apis
8+
none

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ plugins {
1515
`maven-publish`
1616
}
1717

18-
val beta: Int = 31 // Pattern is '1.0.0-beta1-1.20.6-pre.2'; when beta == 0 beta is null
18+
val beta: Int = 32 // Pattern is '1.0.0-beta1-1.20.6-pre.2'; when beta == 0 beta is null
1919
val featureVersion = "1.0.0${if (beta != 0) "-beta$beta" else ""}"
2020
val mcVersion = property("mcVersion")!!.toString()
2121
val mcVersionRange = property("mcVersionRange")!!.toString()

constants/island_groups.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
"GOLD_MINE",
44
"DEEP_CAVERNS",
55
"DWARVEN_MINES",
6-
"CRYSTAL_HOLLOWS"
6+
"CRYSTAL_HOLLOWS",
7+
"MINESHAFT"
8+
],
9+
"mining_events": [
10+
"DWARVEN_MINES",
11+
"CRYSTAL_HOLLOWS",
12+
"MINESHAFT"
713
]
814
}

src/main/kotlin/dev/nyon/skylper/config/Config.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ data class Config(val mining: MiningConfig = MiningConfig(), val menu: Menu = Me
3131
var miningAbilityNotificationOnMiningIslands: Boolean = true,
3232
var miningAbilityIndicator: Boolean = true,
3333
val totalPowderOverlay: TotalPowderOverlay = TotalPowderOverlay(),
34+
val eventOverlay: EventOverlay = EventOverlay(),
3435
var highlightCompletedCommissions: Boolean = true,
3536
var completedCommissionsHighlightColor: @Contextual Color = Color(255, 0, 0, 50)
3637
)
@@ -88,6 +89,9 @@ data class Config(val mining: MiningConfig = MiningConfig(), val menu: Menu = Me
8889
@Serializable
8990
data class TotalPowderOverlay(var enabled: Boolean = true, var x: Int = 5, var y: Int = 300)
9091

92+
@Serializable
93+
data class EventOverlay(var enabled: Boolean = true, var x: Int = 5, var y: Int = 500)
94+
9195
@Serializable
9296
data class Menu(val collections: Collections = Collections(), val bestiary: Bestiary = Bestiary()) {
9397
@Serializable

src/main/kotlin/dev/nyon/skylper/config/screen/MiningYaclScreen.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,38 @@ fun RootDsl.appendMiningCategory() {
6666
}
6767
}
6868

69+
val miningEventOverlay by groups.registering {
70+
descriptionBuilder {
71+
addDefaultText(1)
72+
}
73+
74+
val enabled by options.registering {
75+
binding(true,
76+
{ config.mining.eventOverlay.enabled },
77+
{ config.mining.eventOverlay.enabled = it })
78+
controller = tickBox()
79+
descriptionBuilder {
80+
addDefaultText(1)
81+
}
82+
}
83+
84+
val x by options.registering {
85+
binding(5, { config.mining.eventOverlay.x }, { config.mining.eventOverlay.x = it })
86+
controller = numberField(0 as Int)
87+
descriptionBuilder {
88+
addDefaultText(1)
89+
}
90+
}
91+
92+
val y by options.registering {
93+
binding(300, { config.mining.eventOverlay.y }, { config.mining.eventOverlay.y = it })
94+
controller = numberField(0 as Int)
95+
descriptionBuilder {
96+
addDefaultText(1)
97+
}
98+
}
99+
}
100+
69101
val highlightCompletedCommissions by rootOptions.registering {
70102
binding(true,
71103
{ config.mining.highlightCompletedCommissions },

src/main/kotlin/dev/nyon/skylper/extensions/Serializers.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
package dev.nyon.skylper.extensions
44

5+
import kotlinx.datetime.Instant
56
import kotlinx.serialization.ExperimentalSerializationApi
67
import kotlinx.serialization.KSerializer
78
import kotlinx.serialization.builtins.DoubleArraySerializer
@@ -52,4 +53,16 @@ object Vec3Serializer : KSerializer<Vec3> {
5253
val data = doubleArrayOf(value.x, value.y, value.z)
5354
encoder.encodeSerializableValue(delegateSerializer, data)
5455
}
56+
}
57+
58+
object InstantMillisSerializer : KSerializer<Instant> {
59+
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("instant", PrimitiveKind.FLOAT)
60+
61+
override fun deserialize(decoder: Decoder): Instant {
62+
return Instant.fromEpochMilliseconds(decoder.decodeFloat().toLong())
63+
}
64+
65+
override fun serialize(encoder: Encoder, value: Instant) {
66+
encoder.encodeFloat(value.toEpochMilliseconds().toFloat())
67+
}
5568
}

src/main/kotlin/dev/nyon/skylper/extensions/render/hud/TableHudWidget.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import kotlin.math.max
1414
* @param rows The rows the table should have.
1515
* @param columns The columns the table should have.
1616
*/
17-
abstract class TableHudWidget(override var title: Component, private val rows: Int, private val columns: Int) :
17+
abstract class TableHudWidget(override var title: Component, var rows: Int, var columns: Int) :
1818
HudWidget {
1919
val components: MutableMap<Int, HudComponent> = mutableMapOf()
2020
private val mutex = Mutex()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package dev.nyon.skylper.skyblock.data.api
2+
3+
import dev.nyon.skylper.extensions.httpClient
4+
import dev.nyon.skylper.extensions.json
5+
import dev.nyon.skylper.independentScope
6+
import dev.nyon.skylper.skyblock.data.session.PlayerSessionData
7+
import dev.nyon.skylper.skyblock.models.mining.SoopyEvent
8+
import io.ktor.client.request.*
9+
import io.ktor.client.statement.*
10+
import kotlinx.coroutines.delay
11+
import kotlinx.coroutines.launch
12+
import kotlin.time.Duration.Companion.seconds
13+
14+
object MiningEventApi {
15+
private var soopyEventData: SoopyEvent? = null
16+
val currentEvents: List<SoopyEvent.MiningEvent>
17+
get() = soopyEventData?.data?.runningEvents?.get(PlayerSessionData.currentArea) ?: emptyList()
18+
19+
@Suppress("unused")
20+
private val updater = independentScope.launch {
21+
while (true) {
22+
val soopyEvent = runCatching {
23+
val response = httpClient.get("https://api.soopy.dev/skyblock/chevents/get").bodyAsText()
24+
json.decodeFromString<SoopyEvent>(response)
25+
}.onFailure { it.printStackTrace() }.getOrNull()
26+
soopyEventData = soopyEvent
27+
delay(45.seconds)
28+
}
29+
}
30+
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
package dev.nyon.skylper.skyblock.data.online
22

33
import dev.nyon.skylper.skyblock.models.Area
4+
import kotlinx.serialization.SerialName
45
import kotlinx.serialization.Serializable
56

67
object IslandGroups : OnlineData<IslandGroupsData>(IslandGroupsData::class) {
78
override val url: String = SKYLPER_REPO_URL
89
override val path: String = "island_groups.json"
910

10-
var groups: IslandGroupsData = IslandGroupsData(listOf())
11+
var groups: IslandGroupsData = IslandGroupsData(listOf(), listOf())
1112

1213
override fun setData(data: IslandGroupsData?) {
1314
groups = data ?: return
1415
}
1516
}
1617

1718
@Serializable
18-
data class IslandGroupsData(val mining: List<Area>)
19+
data class IslandGroupsData(val mining: List<Area>, @SerialName("mining_events") val miningEvents: List<Area>)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package dev.nyon.skylper.skyblock.models.mining
2+
3+
import kotlinx.serialization.Serializable
4+
import net.minecraft.ChatFormatting
5+
import net.minecraft.network.chat.Component
6+
7+
@Serializable
8+
enum class MiningEventType(private val colorChar: Char) {
9+
GONE_WITH_THE_WIND('9'),
10+
BETTER_TOGETHER('d'),
11+
DOUBLE_POWDER('b'),
12+
RAFFLE('6'),
13+
GOBLIN_RAID('c'),
14+
MITHRIL_GOURMAND('b');
15+
16+
fun getDisplayName(): Component {
17+
return Component.literal(name.replace("_", " ")).withStyle(ChatFormatting.getByCode(colorChar)!!)
18+
}
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dev.nyon.skylper.skyblock.models.mining
2+
3+
import dev.nyon.skylper.extensions.InstantMillisSerializer
4+
import dev.nyon.skylper.skyblock.models.Area
5+
import kotlinx.datetime.Instant
6+
import kotlinx.serialization.SerialName
7+
import kotlinx.serialization.Serializable
8+
9+
@Serializable
10+
data class SoopyEvent(val success: Boolean, val data: Data) {
11+
@Serializable
12+
data class Data(
13+
@SerialName("running_events")
14+
val runningEvents: Map<Area, List<MiningEvent>>
15+
)
16+
17+
@Serializable
18+
data class MiningEvent(
19+
val event: MiningEventType,
20+
@SerialName("ends_at")
21+
val endsAt: @Serializable(with = InstantMillisSerializer::class) Instant,
22+
@SerialName("lobby_count")
23+
val lobbyCount: Int
24+
)
25+
}

src/main/kotlin/dev/nyon/skylper/skyblock/render/SkylperHud.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dev.nyon.skylper.skyblock.render
33
import dev.nyon.skylper.extensions.event.RenderHudEvent
44
import dev.nyon.skylper.extensions.event.SkylperEvent
55
import dev.nyon.skylper.extensions.render.hud.HudWidget
6+
import dev.nyon.skylper.skyblock.render.mining.MiningEventWidget
67
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.CrystalCompletionWidget
78
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.TotalPowderWidget
89
import dev.nyon.skylper.skyblock.tracker.mining.crystalHollows.powder.PowderGrindingTracker
@@ -15,6 +16,7 @@ object SkylperHud {
1516
context.renderWidget(CrystalCompletionWidget)
1617
context.renderWidget(PowderGrindingTracker)
1718
context.renderWidget(TotalPowderWidget)
19+
context.renderWidget(MiningEventWidget)
1820
}
1921

2022
private fun GuiGraphics.renderWidget(

src/main/kotlin/dev/nyon/skylper/skyblock/render/SkylperHudModifier.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dev.nyon.skylper.skyblock.render
33
import dev.nyon.konfig.config.saveConfig
44
import dev.nyon.skylper.config.config
55
import dev.nyon.skylper.extensions.render.hud.HudWidget
6+
import dev.nyon.skylper.skyblock.render.mining.MiningEventWidget
67
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.CrystalCompletionWidget
78
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.TotalPowderWidget
89
import dev.nyon.skylper.skyblock.tracker.mining.crystalHollows.powder.PowderGrindingTracker
@@ -18,6 +19,7 @@ class SkylperHudModifier(private val parent: Screen?) :
1819
if (config.mining.crystalHollows.crystalOverlay.enabled) add(CrystalCompletionWidget)
1920
if (config.mining.crystalHollows.powderGrindingOverlay.enabled) add(PowderGrindingTracker)
2021
if (config.mining.totalPowderOverlay.enabled) add(TotalPowderWidget)
22+
if (config.mining.eventOverlay.enabled) add(MiningEventWidget)
2123
}.onEach(HudWidget::update)
2224

2325
override fun render(
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package dev.nyon.skylper.skyblock.render.mining
2+
3+
import dev.nyon.skylper.config.config
4+
import dev.nyon.skylper.extensions.math.toPrettyString
5+
import dev.nyon.skylper.extensions.render.hud.TableHudWidget
6+
import dev.nyon.skylper.extensions.render.hud.components.PlainTextHudComponent
7+
import dev.nyon.skylper.skyblock.data.api.MiningEventApi
8+
import dev.nyon.skylper.skyblock.data.online.IslandGroups
9+
import dev.nyon.skylper.skyblock.data.session.PlayerSessionData
10+
import kotlinx.datetime.Clock
11+
import net.minecraft.network.chat.Component
12+
13+
object MiningEventWidget : TableHudWidget(Component.translatable("menu.skylper.overlay.mining.events.title"), 1, 3) {
14+
override var x: Double = config.mining.eventOverlay.x.toDouble()
15+
set(value) {
16+
config.mining.eventOverlay.x = value.toInt()
17+
field = value
18+
}
19+
override var y: Double = config.mining.eventOverlay.x.toDouble()
20+
set(value) {
21+
config.mining.eventOverlay.x = value.toInt()
22+
field = value
23+
}
24+
25+
override fun update() {
26+
super.update()
27+
val data = MiningEventApi.currentEvents
28+
29+
rows = data.size
30+
data.forEachIndexed { index, event ->
31+
addComponent(index, 0, PlainTextHudComponent(event.event.getDisplayName()))
32+
val remaining = event.endsAt - Clock.System.now()
33+
addComponent(
34+
index,
35+
1,
36+
PlainTextHudComponent(
37+
Component.translatable(
38+
"menu.skylper.overlay.mining.events.ends_in",
39+
remaining.toPrettyString()
40+
)
41+
)
42+
)
43+
addComponent(
44+
index,
45+
2,
46+
PlainTextHudComponent(
47+
Component.translatable(
48+
"menu.skylper.overlay.mining.events.lobby_count.${if (event.lobbyCount == 1) "single" else "multiple"}",
49+
event.lobbyCount
50+
)
51+
)
52+
)
53+
}
54+
}
55+
56+
override fun shouldRender(): Boolean {
57+
return IslandGroups.groups.miningEvents.contains(PlayerSessionData.currentArea) && config.mining.eventOverlay.enabled
58+
}
59+
60+
init {
61+
init()
62+
}
63+
}

0 commit comments

Comments
 (0)