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

add dwarven event widget #47

Merged
merged 2 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions beta-changelog.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
## Features
- update powders from tablist more often
- rework powder calculation for powder grinding widget
- use better prefix for chat messages
- add event forecast widget for dwarves, crystals and mineshafts

## Bug Fixes
- disable delete button of waypoint on deletion in location screen
none

## Technical changes
- update to konfig 2.0.2
- rework event api to be hot-swappable
- redo all calculations to apis
- make constructor parameters of TableHudWidget to variables to allow resizable table widgets
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ plugins {
`maven-publish`
}

val beta: Int = 31 // Pattern is '1.0.0-beta1-1.20.6-pre.2'; when beta == 0 beta is null
val beta: Int = 32 // Pattern is '1.0.0-beta1-1.20.6-pre.2'; when beta == 0 beta is null
val featureVersion = "1.0.0${if (beta != 0) "-beta$beta" else ""}"
val mcVersion = property("mcVersion")!!.toString()
val mcVersionRange = property("mcVersionRange")!!.toString()
Expand Down
8 changes: 7 additions & 1 deletion constants/island_groups.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
"GOLD_MINE",
"DEEP_CAVERNS",
"DWARVEN_MINES",
"CRYSTAL_HOLLOWS"
"CRYSTAL_HOLLOWS",
"MINESHAFT"
],
"mining_events": [
"DWARVEN_MINES",
"CRYSTAL_HOLLOWS",
"MINESHAFT"
]
}
4 changes: 4 additions & 0 deletions src/main/kotlin/dev/nyon/skylper/config/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ data class Config(val mining: MiningConfig = MiningConfig(), val menu: Menu = Me
var miningAbilityNotificationOnMiningIslands: Boolean = true,
var miningAbilityIndicator: Boolean = true,
val totalPowderOverlay: TotalPowderOverlay = TotalPowderOverlay(),
val eventOverlay: EventOverlay = EventOverlay(),
var highlightCompletedCommissions: Boolean = true,
var completedCommissionsHighlightColor: @Contextual Color = Color(255, 0, 0, 50)
)
Expand Down Expand Up @@ -88,6 +89,9 @@ data class Config(val mining: MiningConfig = MiningConfig(), val menu: Menu = Me
@Serializable
data class TotalPowderOverlay(var enabled: Boolean = true, var x: Int = 5, var y: Int = 300)

@Serializable
data class EventOverlay(var enabled: Boolean = true, var x: Int = 5, var y: Int = 500)

@Serializable
data class Menu(val collections: Collections = Collections(), val bestiary: Bestiary = Bestiary()) {
@Serializable
Expand Down
32 changes: 32 additions & 0 deletions src/main/kotlin/dev/nyon/skylper/config/screen/MiningYaclScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,38 @@ fun RootDsl.appendMiningCategory() {
}
}

val miningEventOverlay by groups.registering {
descriptionBuilder {
addDefaultText(1)
}

val enabled by options.registering {
binding(true,
{ config.mining.eventOverlay.enabled },
{ config.mining.eventOverlay.enabled = it })
controller = tickBox()
descriptionBuilder {
addDefaultText(1)
}
}

val x by options.registering {
binding(5, { config.mining.eventOverlay.x }, { config.mining.eventOverlay.x = it })
controller = numberField(0 as Int)
descriptionBuilder {
addDefaultText(1)
}
}

val y by options.registering {
binding(300, { config.mining.eventOverlay.y }, { config.mining.eventOverlay.y = it })
controller = numberField(0 as Int)
descriptionBuilder {
addDefaultText(1)
}
}
}

val highlightCompletedCommissions by rootOptions.registering {
binding(true,
{ config.mining.highlightCompletedCommissions },
Expand Down
13 changes: 13 additions & 0 deletions src/main/kotlin/dev/nyon/skylper/extensions/Serializers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package dev.nyon.skylper.extensions

import kotlinx.datetime.Instant
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.DoubleArraySerializer
Expand Down Expand Up @@ -52,4 +53,16 @@ object Vec3Serializer : KSerializer<Vec3> {
val data = doubleArrayOf(value.x, value.y, value.z)
encoder.encodeSerializableValue(delegateSerializer, data)
}
}

object InstantMillisSerializer : KSerializer<Instant> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("instant", PrimitiveKind.FLOAT)

override fun deserialize(decoder: Decoder): Instant {
return Instant.fromEpochMilliseconds(decoder.decodeFloat().toLong())
}

override fun serialize(encoder: Encoder, value: Instant) {
encoder.encodeFloat(value.toEpochMilliseconds().toFloat())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import kotlin.math.max
* @param rows The rows the table should have.
* @param columns The columns the table should have.
*/
abstract class TableHudWidget(override var title: Component, private val rows: Int, private val columns: Int) :
abstract class TableHudWidget(override var title: Component, var rows: Int, var columns: Int) :
HudWidget {
val components: MutableMap<Int, HudComponent> = mutableMapOf()
private val mutex = Mutex()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package dev.nyon.skylper.skyblock.data.api

import dev.nyon.skylper.extensions.httpClient
import dev.nyon.skylper.extensions.json
import dev.nyon.skylper.independentScope
import dev.nyon.skylper.skyblock.data.session.PlayerSessionData
import dev.nyon.skylper.skyblock.models.mining.SoopyEvent
import io.ktor.client.request.*
import io.ktor.client.statement.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.time.Duration.Companion.seconds

object MiningEventApi {
private var soopyEventData: SoopyEvent? = null
val currentEvents: List<SoopyEvent.MiningEvent>
get() = soopyEventData?.data?.runningEvents?.get(PlayerSessionData.currentArea) ?: emptyList()

@Suppress("unused")
private val updater = independentScope.launch {
while (true) {
val soopyEvent = runCatching {
val response = httpClient.get("https://api.soopy.dev/skyblock/chevents/get").bodyAsText()
json.decodeFromString<SoopyEvent>(response)
}.onFailure { it.printStackTrace() }.getOrNull()
soopyEventData = soopyEvent
delay(45.seconds)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package dev.nyon.skylper.skyblock.data.online

import dev.nyon.skylper.skyblock.models.Area
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

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

var groups: IslandGroupsData = IslandGroupsData(listOf())
var groups: IslandGroupsData = IslandGroupsData(listOf(), listOf())

override fun setData(data: IslandGroupsData?) {
groups = data ?: return
}
}

@Serializable
data class IslandGroupsData(val mining: List<Area>)
data class IslandGroupsData(val mining: List<Area>, @SerialName("mining_events") val miningEvents: List<Area>)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.nyon.skylper.skyblock.models.mining

import kotlinx.serialization.Serializable
import net.minecraft.ChatFormatting
import net.minecraft.network.chat.Component

@Serializable
enum class MiningEventType(private val colorChar: Char) {
GONE_WITH_THE_WIND('9'),
BETTER_TOGETHER('d'),
DOUBLE_POWDER('b'),
RAFFLE('6'),
GOBLIN_RAID('c'),
MITHRIL_GOURMAND('b');

fun getDisplayName(): Component {
return Component.literal(name.replace("_", " ")).withStyle(ChatFormatting.getByCode(colorChar)!!)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dev.nyon.skylper.skyblock.models.mining

import dev.nyon.skylper.extensions.InstantMillisSerializer
import dev.nyon.skylper.skyblock.models.Area
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class SoopyEvent(val success: Boolean, val data: Data) {
@Serializable
data class Data(
@SerialName("running_events")
val runningEvents: Map<Area, List<MiningEvent>>
)

@Serializable
data class MiningEvent(
val event: MiningEventType,
@SerialName("ends_at")
val endsAt: @Serializable(with = InstantMillisSerializer::class) Instant,
@SerialName("lobby_count")
val lobbyCount: Int
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.nyon.skylper.skyblock.render
import dev.nyon.skylper.extensions.event.RenderHudEvent
import dev.nyon.skylper.extensions.event.SkylperEvent
import dev.nyon.skylper.extensions.render.hud.HudWidget
import dev.nyon.skylper.skyblock.render.mining.MiningEventWidget
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.CrystalCompletionWidget
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.TotalPowderWidget
import dev.nyon.skylper.skyblock.tracker.mining.crystalHollows.powder.PowderGrindingTracker
Expand All @@ -15,6 +16,7 @@ object SkylperHud {
context.renderWidget(CrystalCompletionWidget)
context.renderWidget(PowderGrindingTracker)
context.renderWidget(TotalPowderWidget)
context.renderWidget(MiningEventWidget)
}

private fun GuiGraphics.renderWidget(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.nyon.skylper.skyblock.render
import dev.nyon.konfig.config.saveConfig
import dev.nyon.skylper.config.config
import dev.nyon.skylper.extensions.render.hud.HudWidget
import dev.nyon.skylper.skyblock.render.mining.MiningEventWidget
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.CrystalCompletionWidget
import dev.nyon.skylper.skyblock.render.mining.crystalHollows.TotalPowderWidget
import dev.nyon.skylper.skyblock.tracker.mining.crystalHollows.powder.PowderGrindingTracker
Expand All @@ -18,6 +19,7 @@ class SkylperHudModifier(private val parent: Screen?) :
if (config.mining.crystalHollows.crystalOverlay.enabled) add(CrystalCompletionWidget)
if (config.mining.crystalHollows.powderGrindingOverlay.enabled) add(PowderGrindingTracker)
if (config.mining.totalPowderOverlay.enabled) add(TotalPowderWidget)
if (config.mining.eventOverlay.enabled) add(MiningEventWidget)
}.onEach(HudWidget::update)

override fun render(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package dev.nyon.skylper.skyblock.render.mining

import dev.nyon.skylper.config.config
import dev.nyon.skylper.extensions.math.toPrettyString
import dev.nyon.skylper.extensions.render.hud.TableHudWidget
import dev.nyon.skylper.extensions.render.hud.components.PlainTextHudComponent
import dev.nyon.skylper.skyblock.data.api.MiningEventApi
import dev.nyon.skylper.skyblock.data.online.IslandGroups
import dev.nyon.skylper.skyblock.data.session.PlayerSessionData
import kotlinx.datetime.Clock
import net.minecraft.network.chat.Component

object MiningEventWidget : TableHudWidget(Component.translatable("menu.skylper.overlay.mining.events.title"), 1, 3) {
override var x: Double = config.mining.eventOverlay.x.toDouble()
set(value) {
config.mining.eventOverlay.x = value.toInt()
field = value
}
override var y: Double = config.mining.eventOverlay.x.toDouble()
set(value) {
config.mining.eventOverlay.x = value.toInt()
field = value
}

override fun update() {
super.update()
val data = MiningEventApi.currentEvents

rows = data.size
data.forEachIndexed { index, event ->
addComponent(index, 0, PlainTextHudComponent(event.event.getDisplayName()))
val remaining = event.endsAt - Clock.System.now()
addComponent(
index,
1,
PlainTextHudComponent(
Component.translatable(
"menu.skylper.overlay.mining.events.ends_in",
remaining.toPrettyString()
)
)
)
addComponent(
index,
2,
PlainTextHudComponent(
Component.translatable(
"menu.skylper.overlay.mining.events.lobby_count.${if (event.lobbyCount == 1) "single" else "multiple"}",
event.lobbyCount
)
)
)
}
}

override fun shouldRender(): Boolean {
return IslandGroups.groups.miningEvents.contains(PlayerSessionData.currentArea) && config.mining.eventOverlay.enabled
}

init {
init()
}
}
Loading