diff options
19 files changed, 398 insertions, 50 deletions
diff --git a/src/compat/moulconfig/java/MCConfigEditorIntegration.kt b/src/compat/moulconfig/java/MCConfigEditorIntegration.kt index 2d71aa0..874e58d 100644 --- a/src/compat/moulconfig/java/MCConfigEditorIntegration.kt +++ b/src/compat/moulconfig/java/MCConfigEditorIntegration.kt @@ -1,6 +1,7 @@ package moe.nea.firmament.compat.moulconfig import com.google.auto.service.AutoService +import io.github.notenoughupdates.moulconfig.ChromaColour import io.github.notenoughupdates.moulconfig.Config import io.github.notenoughupdates.moulconfig.DescriptionRendereringBehaviour import io.github.notenoughupdates.moulconfig.Social @@ -20,6 +21,7 @@ import io.github.notenoughupdates.moulconfig.gui.editors.ComponentEditor import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorAccordion import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorBoolean import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorButton +import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorColour import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorDropdown import io.github.notenoughupdates.moulconfig.gui.editors.GuiOptionEditorText import io.github.notenoughupdates.moulconfig.observer.GetSetter @@ -39,6 +41,7 @@ import moe.nea.firmament.gui.config.AllConfigsGui import moe.nea.firmament.gui.config.BooleanHandler import moe.nea.firmament.gui.config.ChoiceHandler import moe.nea.firmament.gui.config.ClickHandler +import moe.nea.firmament.gui.config.ColourHandler import moe.nea.firmament.gui.config.DurationHandler import moe.nea.firmament.gui.config.FirmamentConfigScreenProvider import moe.nea.firmament.gui.config.HudMeta @@ -186,6 +189,26 @@ class MCConfigEditorIntegration : FirmamentConfigScreenProvider { } } } + register(ColourHandler::class.java) { handler, option, accordionId, configObject -> + object : ProcessedEditableOptionFirm<ChromaColour>(option, accordionId, configObject) { + override fun fromT(t: ChromaColour): Any { + return t + } + + override fun toT(any: Any?): ChromaColour? { + return any as ChromaColour? + } + + override fun createEditor(): GuiOptionEditor { + return GuiOptionEditorColour(this) + } + + override fun getType(): Type? { + return ChromaColour::class.java + } + } + + } register(ClickHandler::class.java) { handler, option, categoryAccordionId, configObject -> object : ProcessedEditableOptionFirm<Unit>(option, categoryAccordionId, configObject) { override fun createEditor(): GuiOptionEditor { diff --git a/src/compat/yacl/java/YaclIntegration.kt b/src/compat/yacl/java/YaclIntegration.kt index a022ffd..285d60c 100644 --- a/src/compat/yacl/java/YaclIntegration.kt +++ b/src/compat/yacl/java/YaclIntegration.kt @@ -9,6 +9,7 @@ import dev.isxander.yacl3.api.Option import dev.isxander.yacl3.api.OptionDescription import dev.isxander.yacl3.api.OptionGroup import dev.isxander.yacl3.api.YetAnotherConfigLib +import dev.isxander.yacl3.api.controller.ColorControllerBuilder import dev.isxander.yacl3.api.controller.ControllerBuilder import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder import dev.isxander.yacl3.api.controller.EnumControllerBuilder @@ -18,6 +19,8 @@ import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder import dev.isxander.yacl3.api.controller.ValueFormatter import dev.isxander.yacl3.gui.YACLScreen import dev.isxander.yacl3.gui.tab.ListHolderWidget +import io.github.notenoughupdates.moulconfig.ChromaColour +import java.awt.Color import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlin.time.DurationUnit @@ -27,6 +30,7 @@ import net.minecraft.text.Text import moe.nea.firmament.gui.config.BooleanHandler import moe.nea.firmament.gui.config.ChoiceHandler import moe.nea.firmament.gui.config.ClickHandler +import moe.nea.firmament.gui.config.ColourHandler import moe.nea.firmament.gui.config.DurationHandler import moe.nea.firmament.gui.config.EnumRenderer import moe.nea.firmament.gui.config.FirmamentConfigScreenProvider @@ -39,6 +43,8 @@ import moe.nea.firmament.gui.config.ManagedOption import moe.nea.firmament.gui.config.StringHandler import moe.nea.firmament.keybindings.SavedKeyBinding import moe.nea.firmament.util.FirmFormatters +import moe.nea.firmament.util.getRGBAWithoutAnimation +import moe.nea.firmament.util.toChromaWithoutAnimation @AutoService(FirmamentConfigScreenProvider::class) @@ -56,20 +62,22 @@ class YaclIntegration : FirmamentConfigScreenProvider { OptionGroup.createBuilder() .name(it.labelText) .options(buildOptions(it.sortedOptions)) - .build()) + .build() + ) } } .build() } fun buildOptions(options: List<ManagedOption<*>>): Collection<Option<*>> = - options.map { buildOption(it) } + options.flatMap { buildOption(it) } - private fun <T : Any> buildOption(managedOption: ManagedOption<T>): Option<*> { + private fun <T : Any> buildOption(managedOption: ManagedOption<T>): Collection<Option<*>> { val handler = managedOption.handler - val binding = Binding.generic(managedOption.default(), - managedOption::value, - { managedOption.value = it; managedOption.element.save() }) + val binding = Binding.generic( + managedOption.default(), + managedOption::value, + { managedOption.value = it; managedOption.element.save() }) fun <T> createDefaultBinding(function: (Option<T>) -> ControllerBuilder<T>): Option.Builder<T> { return Option.createBuilder<T>() @@ -78,30 +86,72 @@ class YaclIntegration : FirmamentConfigScreenProvider { .binding(binding as Binding<T>) .controller { function(it) } } + + fun Option<out Any>.single() = listOf(this) + fun ButtonOption.Builder.single() = build().single() + fun Option.Builder<out Any>.single() = build().single() when (handler) { is ClickHandler -> return ButtonOption.createBuilder() .name(managedOption.labelText) .action { t, u -> handler.runnable() } - .build() + .single() is HudMetaHandler -> return ButtonOption.createBuilder() .name(managedOption.labelText) .action { t, u -> handler.openEditor(managedOption as ManagedOption<HudMeta>, t) } - .build() + .single() is ChoiceHandler<*> -> return createDefaultBinding { createChoiceBinding(handler as ChoiceHandler<*>, managedOption as ManagedOption<*>, it as Option<*>) - }.build() + }.single() + + is ColourHandler -> { + managedOption as ManagedOption<ChromaColour> + val colorBinding = + Binding.generic( + managedOption.default().getRGBAWithoutAnimation(), + { managedOption.value.getRGBAWithoutAnimation() }, + { + managedOption.value = + it.toChromaWithoutAnimation(managedOption.value.timeForFullRotationInMillis) + managedOption.element.save() + }) + val speedBinding = + Binding.generic( + managedOption.default().timeForFullRotationInMillis, + { managedOption.value.timeForFullRotationInMillis }, + { + managedOption.value = managedOption.value.copy(timeForFullRotationInMillis = it) + managedOption.element.save() + } + ) + + return listOf( + Option.createBuilder<Color>() + .name(managedOption.labelText) + .binding(colorBinding) + .controller { + ColorControllerBuilder.create(it) + .allowAlpha(true) + } + .build(), + Option.createBuilder<Int>() + .name(managedOption.labelText) + .binding(speedBinding) + .controller { IntegerSliderControllerBuilder.create(it).range(0, 60_000).step(10) } + .build(), + ) + } - is BooleanHandler -> return createDefaultBinding(TickBoxControllerBuilder::create).build() - is StringHandler -> return createDefaultBinding(StringControllerBuilder::create).build() + is BooleanHandler -> return createDefaultBinding(TickBoxControllerBuilder::create).single() + is StringHandler -> return createDefaultBinding(StringControllerBuilder::create).single() is IntegerHandler -> return createDefaultBinding { IntegerSliderControllerBuilder.create(it).range(handler.min, handler.max).step(1) - }.build() + }.single() is DurationHandler -> return Option.createBuilder<Double>() .name(managedOption.labelText) @@ -112,13 +162,13 @@ class YaclIntegration : FirmamentConfigScreenProvider { .step(0.1) .range(handler.min.toDouble(DurationUnit.SECONDS), handler.max.toDouble(DurationUnit.SECONDS)) } - .build() + .single() is KeyBindingHandler -> return createDefaultBinding { KeybindingBuilder(it, managedOption as ManagedOption<SavedKeyBinding>) - }.build() + }.single() - else -> return LabelOption.create(Text.literal("This option is currently unhandled for this config menu. Please report this as a bug.")) + else -> return listOf(LabelOption.create(Text.literal("This option is currently unhandled for this config menu. Please report this as a bug."))) } } diff --git a/src/main/kotlin/features/inventory/PetFeatures.kt b/src/main/kotlin/features/inventory/PetFeatures.kt index bb39fbc..9393b03 100644 --- a/src/main/kotlin/features/inventory/PetFeatures.kt +++ b/src/main/kotlin/features/inventory/PetFeatures.kt @@ -13,6 +13,7 @@ import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.util.FirmFormatters.formatPercent import moe.nea.firmament.util.FirmFormatters.shortFormat import moe.nea.firmament.util.MC +import moe.nea.firmament.util.SBData import moe.nea.firmament.util.petData import moe.nea.firmament.util.render.drawGuiTexture import moe.nea.firmament.util.skyblock.Rarity @@ -52,7 +53,7 @@ object PetFeatures : FirmamentFeature { @Subscribe fun onRenderHud(it: HudRenderEvent) { - if (!TConfig.petOverlay) return + if (!TConfig.petOverlay || !SBData.isOnSkyblock) return val itemStack = petItemStack ?: return val petData = petItemStack?.petData ?: return val rarity = Rarity.fromNeuRepo(petData.tier) diff --git a/src/main/kotlin/features/inventory/WardrobeKeybinds.kt b/src/main/kotlin/features/inventory/WardrobeKeybinds.kt index d797600..6e2b4a9 100644 --- a/src/main/kotlin/features/inventory/WardrobeKeybinds.kt +++ b/src/main/kotlin/features/inventory/WardrobeKeybinds.kt @@ -2,14 +2,12 @@ package moe.nea.firmament.features.inventory import org.lwjgl.glfw.GLFW import net.minecraft.item.Items -import net.minecraft.screen.slot.SlotActionType import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.HandledScreenKeyPressedEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.util.MC import moe.nea.firmament.util.mc.SlotUtils.clickLeftMouseButton -import moe.nea.firmament.util.mc.SlotUtils.clickMiddleMouseButton object WardrobeKeybinds : FirmamentFeature { override val identifier: String @@ -17,6 +15,9 @@ object WardrobeKeybinds : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.INVENTORY) { val wardrobeKeybinds by toggle("wardrobe-keybinds") { false } + val changePageKeybind by keyBinding("change-page") { GLFW.GLFW_KEY_ENTER } + val nextPage by keyBinding("next-page") { GLFW.GLFW_KEY_D } + val previousPage by keyBinding("previous-page") { GLFW.GLFW_KEY_A } val slotKeybinds = (1..9).map { keyBinding("slot-$it") { GLFW.GLFW_KEY_0 + it } } @@ -37,6 +38,29 @@ object WardrobeKeybinds : FirmamentFeature { if (!regex.matches(event.screen.title.string)) return if (!TConfig.wardrobeKeybinds) return + if ( + event.matches(TConfig.changePageKeybind) || + event.matches(TConfig.previousPage) || + event.matches(TConfig.nextPage) + ) { + event.cancel() + + val handler = event.screen.screenHandler + val previousSlot = handler.getSlot(45) + val nextSlot = handler.getSlot(53) + + val backPressed = event.matches(TConfig.changePageKeybind) || event.matches(TConfig.previousPage) + val nextPressed = event.matches(TConfig.changePageKeybind) || event.matches(TConfig.nextPage) + + if (backPressed && previousSlot.stack.item == Items.ARROW) { + previousSlot.clickLeftMouseButton(handler) + } else if (nextPressed && nextSlot.stack.item == Items.ARROW) { + nextSlot.clickLeftMouseButton(handler) + } + } + + + val slot = slotKeybindsWithSlot .find { event.matches(it.second.get()) } diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt index ec62aa6..548552c 100644 --- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt +++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt @@ -1,5 +1,6 @@ package moe.nea.firmament.features.inventory.storageoverlay +import io.github.notenoughupdates.moulconfig.ChromaColour import java.util.SortedMap import kotlinx.serialization.serializer import net.minecraft.client.gui.screen.ingame.GenericContainerScreen @@ -28,6 +29,15 @@ object StorageOverlay : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.INVENTORY) { val alwaysReplace by toggle("always-replace") { true } val outlineActiveStoragePage by toggle("outline-active-page") { false } + val outlineActiveStoragePageColour by colour("outline-active-page-colour") { + ChromaColour.fromRGB( + 255, + 255, + 0, + 0, + 255 + ) + } val columns by integer("rows", 1, 10) { 3 } val height by integer("height", 80, 3000) { 3 * 18 * 6 } val scrollSpeed by integer("scroll-speed", 1, 50) { 10 } diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt index 84d0f2b..460a949 100644 --- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt +++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlayScreen.kt @@ -499,7 +499,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) { y + 3 + textRenderer.fontHeight, PAGE_WIDTH, inv.rows * SLOT_SIZE + 4, - 0xFFFF00FF.toInt() + StorageOverlay.TConfig.outlineActiveStoragePageColour.getEffectiveColourRGB() ) context.drawText( textRenderer, Text.literal(name), x + 6, y + 3, diff --git a/src/main/kotlin/features/items/BonemerangOverlay.kt b/src/main/kotlin/features/items/BonemerangOverlay.kt new file mode 100644 index 0000000..ffdffe3 --- /dev/null +++ b/src/main/kotlin/features/items/BonemerangOverlay.kt @@ -0,0 +1,101 @@ +package moe.nea.firmament.features.items + +import me.shedaniel.math.Color +import moe.nea.jarvis.api.Point +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.decoration.ArmorStandEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.Formatting +import net.minecraft.util.math.Box +import moe.nea.firmament.annotations.Subscribe +import moe.nea.firmament.events.ClientStartedEvent +import moe.nea.firmament.events.EntityRenderTintEvent +import moe.nea.firmament.events.HudRenderEvent +import moe.nea.firmament.features.FirmamentFeature +import moe.nea.firmament.gui.config.ManagedConfig +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.render.TintedOverlayTexture +import moe.nea.firmament.util.skyBlockId +import moe.nea.firmament.util.skyblock.SkyBlockItems +import moe.nea.firmament.util.tr + +object BonemerangOverlay : FirmamentFeature { + override val identifier: String + get() = "bonemerang-overlay" + + object TConfig : ManagedConfig(identifier, Category.ITEMS) { + var bonemerangOverlay by toggle("bonemerang-overlay") { false } + val bonemerangOverlayHud by position("bonemerang-overlay-hud", 80, 10) { Point(0.1, 1.0) } + var highlightHitEntities by toggle("highlight-hit-entities") { false } + } + + @Subscribe + fun onInit(event: ClientStartedEvent) { + } + + override val config: ManagedConfig + get() = TConfig + + fun getEntities(): MutableSet<LivingEntity> { + val entities = mutableSetOf<LivingEntity>() + val camera = MC.camera as? PlayerEntity ?: return entities + val player = MC.player ?: return entities + val world = player.world ?: return entities + + val cameraPos = camera.eyePos + val rayDirection = camera.rotationVector.normalize() + val endPos = cameraPos.add(rayDirection.multiply(15.0)) + val foundEntities = world.getOtherEntities(camera, Box(cameraPos, endPos).expand(1.0)) + + for (entity in foundEntities) { + if (entity !is LivingEntity || entity is ArmorStandEntity || entity.isInvisible) continue + val hitResult = entity.boundingBox.expand(0.35).raycast(cameraPos, endPos).orElse(null) + if (hitResult != null) entities.add(entity) + } + + return entities + } + + + val throwableWeapons = listOf( + SkyBlockItems.BONE_BOOMERANG, SkyBlockItems.STARRED_BONE_BOOMERANG, + SkyBlockItems.TRIBAL_SPEAR, + ) + + + @Subscribe + fun onEntityRender(event: EntityRenderTintEvent) { + if (!TConfig.highlightHitEntities) return + if (MC.stackInHand.skyBlockId !in throwableWeapons) return + + val entities = getEntities() + if (entities.isEmpty()) return + if (event.entity !in entities) return + + val tintOverlay by lazy { + TintedOverlayTexture().setColor(Color.ofOpaque(Formatting.BLUE.colorValue!!)) + } + + event.renderState.overlayTexture_firmament = tintOverlay + } + + + @Subscribe + fun onRenderHud(it: HudRenderEvent) { + if (!TConfig.bonemerangOverlay) return + if (MC.stackInHand.skyBlockId !in throwableWeapons) return + + val entities = getEntities() + + it.context.matrices.push() + TConfig.bonemerangOverlayHud.applyTransformations(it.context.matrices) + it.context.drawText( + MC.font, String.format( + tr( + "firmament.bonemerang-overlay.bonemerang-overlay.display", "Bonemerang Targets: %s" + ).string, entities.size + ), 0, 0, -1, true + ) + it.context.matrices.pop() + } +} diff --git a/src/main/kotlin/features/items/EtherwarpOverlay.kt b/src/main/kotlin/features/items/EtherwarpOverlay.kt index d560ad6..b1f695a 100644 --- a/src/main/kotlin/features/items/EtherwarpOverlay.kt +++ b/src/main/kotlin/features/items/EtherwarpOverlay.kt @@ -1,11 +1,13 @@ package moe.nea.firmament.features.items +import io.github.notenoughupdates.moulconfig.ChromaColour +import me.shedaniel.math.Color +import net.minecraft.util.hit.BlockHitResult import moe.nea.firmament.annotations.Subscribe +import moe.nea.firmament.events.WorldRenderLastEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig import moe.nea.firmament.util.MC -import net.minecraft.util.hit.BlockHitResult -import moe.nea.firmament.events.WorldRenderLastEvent import moe.nea.firmament.util.extraAttributes import moe.nea.firmament.util.render.RenderInWorldContext import moe.nea.firmament.util.skyBlockId @@ -18,6 +20,7 @@ object EtherwarpOverlay : FirmamentFeature { object TConfig : ManagedConfig(identifier, Category.ITEMS) { var etherwarpOverlay by toggle("etherwarp-overlay") { false } var cube by toggle("cube") { true } + val cubeColour by colour("cube-colour") { ChromaColour.fromStaticRGB(172, 0, 255, 60) } var wireframe by toggle("wireframe") { false } } @@ -43,7 +46,7 @@ object EtherwarpOverlay : FirmamentFeature { if (!world.getBlockState(blockPos.up()).isAir) return if (!world.getBlockState(blockPos.up(2)).isAir) return RenderInWorldContext.renderInWorld(event) { - if (TConfig.cube) block(blockPos, 0xFFFFFF00.toInt()) + if (TConfig.cube) block(blockPos, TConfig.cubeColour.getEffectiveColourRGB()) if (TConfig.wireframe) wireframeCube(blockPos, 10f) } } diff --git a/src/main/kotlin/features/world/FairySouls.kt b/src/main/kotlin/features/world/FairySouls.kt index 1263074..d4bf560 100644 --- a/src/main/kotlin/features/world/FairySouls.kt +++ b/src/main/kotlin/features/world/FairySouls.kt @@ -3,6 +3,7 @@ package moe.nea.firmament.features.world import io.github.moulberry.repo.data.Coordinate +import me.shedaniel.math.Color import kotlinx.serialization.Serializable import kotlinx.serialization.serializer import net.minecraft.text.Text @@ -100,7 +101,7 @@ object FairySouls : FirmamentFeature { if (!TConfig.displaySouls) return renderInWorld(it) { currentMissingSouls.forEach { - block(it.blockPos, 0x80FFFF00.toInt()) + block(it.blockPos, Color.ofRGBA(176, 0, 255, 128).color) } color(1f, 0f, 1f, 1f) currentLocationSouls.forEach { diff --git a/src/main/kotlin/features/world/TemporaryWaypoints.kt b/src/main/kotlin/features/world/TemporaryWaypoints.kt index b36c49d..3c8e895 100644 --- a/src/main/kotlin/features/world/TemporaryWaypoints.kt +++ b/src/main/kotlin/features/world/TemporaryWaypoints.kt @@ -1,5 +1,6 @@ package moe.nea.firmament.features.world +import me.shedaniel.math.Color import kotlin.compareTo import kotlin.text.clear import kotlin.time.Duration.Companion.seconds @@ -38,7 +39,7 @@ object TemporaryWaypoints { if (temporaryPlayerWaypointList.isEmpty()) return RenderInWorldContext.renderInWorld(event) { temporaryPlayerWaypointList.forEach { (_, waypoint) -> - block(waypoint.pos, 0xFFFFFF00.toInt()) + block(waypoint.pos, Color.ofRGBA(255, 255, 0, 128).color) } temporaryPlayerWaypointList.forEach { (player, waypoint) -> val skin = diff --git a/src/main/kotlin/features/world/Waypoints.kt b/src/main/kotlin/features/world/Waypoints.kt index b5c2b66..b4f91b0 100644 --- a/src/main/kotlin/features/world/Waypoints.kt +++ b/src/main/kotlin/features/world/Waypoints.kt @@ -45,7 +45,7 @@ object Waypoints : FirmamentFeature { RenderInWorldContext.renderInWorld(event) { if (!w.isOrdered) { w.waypoints.withIndex().forEach { - block(it.value.blockPos, 0x800050A0.toInt()) + block(it.value.blockPos, Color.ofRGBA(0, 80, 160, 128).color) if (TConfig.showIndex) withFacingThePlayer(it.value.blockPos.toCenterPos()) { text(Text.literal(it.index.toString())) } diff --git a/src/main/kotlin/gui/config/ColourHandler.kt b/src/main/kotlin/gui/config/ColourHandler.kt new file mode 100644 index 0000000..7d121ab --- /dev/null +++ b/src/main/kotlin/gui/config/ColourHandler.kt @@ -0,0 +1,82 @@ +package moe.nea.firmament.gui.config + +import io.github.notenoughupdates.moulconfig.ChromaColour +import io.github.notenoughupdates.moulconfig.gui.component.ColorSelectComponent +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonElement + +class ColourHandler(val config: ManagedConfig) : + ManagedConfig.OptionHandler<ChromaColour> { + @Serializable + data class ChromaDelegate( + @SerialName("h") + val hue: Float, + @SerialName("s") + val saturation: Float, + @SerialName("b") + val brightness: Float, + @SerialName("a") + val alpha: Int, + @SerialName("c") + val timeForFullRotationInMillis: Int, + ) { + constructor(delegate: ChromaColour) : this( + delegate.hue, + delegate.saturation, + delegate.brightness, + delegate.alpha, + delegate.timeForFullRotationInMillis + ) + + fun into(): ChromaColour = ChromaColour(hue, saturation, brightness, alpha, timeForFullRotationInMillis) + } + + object ChromaSerializer : KSerializer<ChromaColour> { + override val descriptor: SerialDescriptor + get() = SerialDescriptor("FirmChromaColour", ChromaDelegate.serializer().descriptor) + + override fun serialize( + encoder: Encoder, + value: ChromaColour + ) { + encoder.encodeSerializableValue(ChromaDelegate.serializer(), ChromaDelegate(value)) + } + + override fun deserialize(decoder: Decoder): ChromaColour { + return decoder.decodeSerializableValue(ChromaDelegate.serializer()).into() + } + } + + override fun toJson(element: ChromaColour): JsonElement? { + return Json.encodeToJsonElement(ChromaSerializer, element) + } + + override fun fromJson(element: JsonElement): ChromaColour { + return Json.decodeFromJsonElement(ChromaSerializer, element) + } + + override fun emitGuiElements( + opt: ManagedOption<ChromaColour>, + guiAppender: GuiAppender + ) { + guiAppender.appendLabeledRow( + opt.labelText, + ColorSelectComponent( + 0, + 0, + opt.value.toLegacyString(), + { + opt.value = ChromaColour.forLegacyString(it) + config.save() + }, + { } + ) + ) + } +} diff --git a/src/main/kotlin/gui/config/ManagedConfig.kt b/src/main/kotlin/gui/config/ManagedConfig.kt index ba6792d..12b82d6 100644 --- a/src/main/kotlin/gui/config/ManagedConfig.kt +++ b/src/main/kotlin/gui/config/ManagedConfig.kt @@ -1,6 +1,7 @@ package moe.nea.firmament.gui.config import com.mojang.serialization.Codec +import io.github.notenoughupdates.moulconfig.ChromaColour import io.github.notenoughupdates.moulconfig.gui.CloseEventListener import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper import io.github.notenoughupdates.moulconfig.gui.GuiContext @@ -118,6 +119,10 @@ abstract class ManagedConfig( return option(propertyName, default, BooleanHandler(this)) } + protected fun colour(propertyName: String, default: ()-> ChromaColour) : ManagedOption<ChromaColour> { + return option(propertyName, default, ColourHandler(this)) + } + protected fun <E> choice( propertyName: String, enumClass: Class<E>, diff --git a/src/main/kotlin/util/ChromaColourUtil.kt b/src/main/kotlin/util/ChromaColourUtil.kt new file mode 100644 index 0000000..0130326 --- /dev/null +++ b/src/main/kotlin/util/ChromaColourUtil.kt @@ -0,0 +1,10 @@ +package moe.nea.firmament.util + +import io.github.notenoughupdates.moulconfig.ChromaColour +import java.awt.Color + +fun ChromaColour.getRGBAWithoutAnimation() = + Color(ChromaColour.specialToSimpleRGB(toLegacyString()), true) + +fun Color.toChromaWithoutAnimation(timeForFullRotationInMillis: Int = 0) = + ChromaColour.fromRGB(red, green, blue, timeForFullRotationInMillis, alpha) diff --git a/src/main/kotlin/util/IntUtil.kt b/src/main/kotlin/util/IntUtil.kt new file mode 100644 index 0000000..2695906 --- /dev/null +++ b/src/main/kotlin/util/IntUtil.kt @@ -0,0 +1,12 @@ +package moe.nea.firmament.util + +object IntUtil { + data class RGBA(val r: Int, val g: Int, val b: Int, val a: Int) + + fun Int.toRGBA(): RGBA { + return RGBA( + r = (this shr 16) and 0xFF, g = (this shr 8) and 0xFF, b = this and 0xFF, a = (this shr 24) and 0xFF + ) + } + +} diff --git a/src/main/kotlin/util/render/CustomRenderLayers.kt b/src/main/kotlin/util/render/CustomRenderLayers.kt index 3d9e598..f713a81 100644 --- a/src/main/kotlin/util/render/CustomRenderLayers.kt +++ b/src/main/kotlin/util/render/CustomRenderLayers.kt @@ -39,6 +39,7 @@ object CustomRenderPipelines { .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) .withCull(false) .withDepthWrite(false) + .withBlend(BlendFunction.TRANSLUCENT) .build() val CIRCLE_FILTER_TRANSLUCENT_GUI_TRIS = diff --git a/src/main/kotlin/util/render/RenderInWorldContext.kt b/src/main/kotlin/util/render/RenderInWorldContext.kt index 98b10ca..4963920 100644 --- a/src/main/kotlin/util/render/RenderInWorldContext.kt +++ b/src/main/kotlin/util/render/RenderInWorldContext.kt @@ -20,6 +20,7 @@ import net.minecraft.util.math.BlockPos import net.minecraft.util.math.Vec3d import moe.nea.firmament.events.WorldRenderLastEvent import moe.nea.firmament.util.FirmFormatters +import moe.nea.firmament.util.IntUtil.toRGBA import moe.nea.firmament.util.MC @RenderContextDSL @@ -204,37 +205,39 @@ class RenderInWorldContext private constructor( } } - private fun buildCube(matrix: Matrix4f, buf: VertexConsumer, color: Int) { + private fun buildCube(matrix: Matrix4f, buf: VertexConsumer, colorInt: Int) { + val (r, g, b, a) = colorInt.toRGBA() + // Y- - buf.vertex(matrix, 0F, 0F, 0F).color(color) - buf.vertex(matrix, 0F, 0F, 1F).color(color) - buf.vertex(matrix, 1F, 0F, 1F).color(color) - buf.vertex(matrix, 1F, 0F, 0F).color(color) + buf.vertex(matrix, 0F, 0F, 0F).color(r, g, b, a) + buf.vertex(matrix, 0F, 0F, 1F).color(r, g, b, a) + buf.vertex(matrix, 1F, 0F, 1F).color(r, g, b, a) + buf.vertex(matrix, 1F, 0F, 0F).color(r, g, b, a) // Y+ - buf.vertex(matrix, 0F, 1F, 0F).color(color) - buf.vertex(matrix, 1F, 1F, 0F).color(color) - buf.vertex(matrix, 1F, 1F, 1F).color(color) - buf.vertex(matrix, 0F, 1F, 1F).color(color) + buf.vertex(matrix, 0F, 1F, 0F).color(r, g, b, a) + buf.vertex(matrix, 1F, 1F, 0F).color(r, g, b, a) + buf.vertex(matrix, 1F, 1F, 1F).color(r, g, b, a) + buf.vertex(matrix, 0F, 1F, 1F).color(r, g, b, a) // X- - buf.vertex(matrix, 0F, 0F, 0F).color(color) - buf.vertex(matrix, 0F, 0F, 1F).color(color) - buf.vertex(matrix, 0F, 1F, 1F).color(color) - buf.vertex(matrix, 0F, 1F, 0F).color(color) + buf.vertex(matrix, 0F, 0F, 0F).color(r, g, b, a) + buf.vertex(matrix, 0F, 0F, 1F).color(r, g, b, a) + buf.vertex(matrix, 0F, 1F, 1F).color(r, g, b, a) + buf.vertex(matrix, 0F, 1F, 0F).color(r, g, b, a) // X+ - buf.vertex(matrix, 1F, 0F, 0F).color(color) - buf.vertex(matrix, 1F, 1F, 0F).color(color) - buf.vertex(matrix, 1F, 1F, 1F).color(color) - buf.vertex(matrix, 1F, 0F, 1F).color(color) + buf.vertex(matrix, 1F, 0F, 0F).color(r, g, b, a) + buf.vertex(matrix, 1F, 1F, 0F).color(r, g, b, a) + buf.vertex(matrix, 1F, 1F, 1F).color(r, g, b, a) + buf.vertex(matrix, 1F, 0F, 1F).color(r, g, b, a) // Z- - buf.vertex(matrix, 0F, 0F, 0F).color(color) - buf.vertex(matrix, 1F, 0F, 0F).color(color) - buf.vertex(matrix, 1F, 1F, 0F).color(color) - buf.vertex(matrix, 0F, 1F, 0F).color(color) + buf.vertex(matrix, 0F, 0F, 0F).color(r, g, b, a) + buf.vertex(matrix, 1F, 0F, 0F).color(r, g, b, a) + buf.vertex(matrix, 1F, 1F, 0F).color(r, g, b, a) + buf.vertex(matrix, 0F, 1F, 0F).color(r, g, b, a) // Z+ - buf.vertex(matrix, 0F, 0F, 1F).color(color) - buf.vertex(matrix, 0F, 1F, 1F).color(color) - buf.vertex(matrix, 1F, 1F, 1F).color(color) - buf.vertex(matrix, 1F, 0F, 1F).color(color) + buf.vertex(matrix, 0F, 0F, 1F).color(r, g, b, a) + buf.vertex(matrix, 0F, 1F, 1F).color(r, g, b, a) + buf.vertex(matrix, 1F, 1F, 1F).color(r, g, b, a) + buf.vertex(matrix, 1F, 0F, 1F).color(r, g, b, a) } diff --git a/src/main/kotlin/util/skyblock/SkyBlockItems.kt b/src/main/kotlin/util/skyblock/SkyBlockItems.kt index 9854be0..4f208dd 100644 --- a/src/main/kotlin/util/skyblock/SkyBlockItems.kt +++ b/src/main/kotlin/util/skyblock/SkyBlockItems.kt @@ -16,4 +16,7 @@ object SkyBlockItems { val SLICE_OF_STRAWBERRY_SHORTCAKE = SkyblockId("SLICE_OF_STRAWBERRY_SHORTCAKE") val ASPECT_OF_THE_VOID = SkyblockId("ASPECT_OF_THE_VOID") val ASPECT_OF_THE_END = SkyblockId("ASPECT_OF_THE_END") + val BONE_BOOMERANG = SkyblockId("BONE_BOOMERANG") + val STARRED_BONE_BOOMERANG = SkyblockId("STARRED_BONE_BOOMERANG") + val TRIBAL_SPEAR = SkyblockId("TRIBAL_SPEAR") } diff --git a/translations/en_us.json b/translations/en_us.json index c474d23..6299181 100644 --- a/translations/en_us.json +++ b/translations/en_us.json @@ -24,6 +24,14 @@ "firmament.config.auto-completions.warp-complete.description": "Auto complete warp destinations in chat. This may include warps you have not yet unlocked.", "firmament.config.auto-completions.warp-is": "Redirect /warp is to /warp island", "firmament.config.auto-completions.warp-is.description": "Redirects /warp is to /warp island, since hypixel does not recognize /warp is as a warp destination.", + "firmament.config.bonemerang-overlay": "Bonemerang Overlay", + "firmament.config.bonemerang-overlay.bonemerang-overlay": "Bonemerang Overlay", + "firmament.config.bonemerang-overlay.bonemerang-overlay-hud": "Bonemerang Overlay Hud", + "firmament.config.bonemerang-overlay.bonemerang-overlay-hud.description": "Shows how many targets your bonemerang will hit", + "firmament.config.bonemerang-overlay.bonemerang-overlay.description": "Display an overlay that tells you what block you will warp to.", + "firmament.config.bonemerang-overlay.bonemerang-overlay.display": "Bonemerang Targets: %s", + "firmament.config.bonemerang-overlay.highlight-hit-entities": "Highlight Target Entities", + "firmament.config.bonemerang-overlay.highlight-hit-entities.description": "Highlight entities that will be hit", "firmament.config.carnival": "Carnival Features", "firmament.config.carnival.bombs-solver": "Minesweeper Helper", "firmament.config.carnival.bombs-solver.description": "Display bombs surrounding each block in minesweeper.", @@ -122,6 +130,8 @@ "firmament.config.diana.nearby-waypoints.description": "Highlight nearby diana burrows.", "firmament.config.etherwarp-overlay": "Etherwarp Overlay", "firmament.config.etherwarp-overlay.cube": "Cube", + "firmament.config.etherwarp-overlay.cube-colour": "Cube Color", + "firmament.config.etherwarp-overlay.cube-colour.description": "Choose the colour of the etherwarp target block.", "firmament.config.etherwarp-overlay.cube.description": "Displays a full cube on the block", "firmament.config.etherwarp-overlay.etherwarp-overlay": "Etherwarp Overlay", "firmament.config.etherwarp-overlay.etherwarp-overlay.description": "Display an overlay that tells you what block you will warp to.", @@ -347,6 +357,8 @@ "firmament.config.storage-overlay.margin": "Margin", "firmament.config.storage-overlay.margin.description": "Margin inside of the storage overview.", "firmament.config.storage-overlay.outline-active-page": "Outline Active Page", + "firmament.config.storage-overlay.outline-active-page-colour": "Outline Colour", + "firmament.config.storage-overlay.outline-active-page-colour.description": "Change the colour of the border around your selected storage page.", "firmament.config.storage-overlay.outline-active-page.description": "Put a border around the selected storage page in the storage overlay.", "firmament.config.storage-overlay.padding": "Padding", "firmament.config.storage-overlay.padding.description": "Padding inside of the storage overview.", @@ -355,6 +367,12 @@ "firmament.config.storage-overlay.scroll-speed": "Scroll Speed", "firmament.config.storage-overlay.scroll-speed.description": "Scroll speed inside of the storage overlay and overview.", "firmament.config.wardrobe-keybinds": "Wardrobe Keybinds", + "firmament.config.wardrobe-keybinds.change-page": "Change Page", + "firmament.config.wardrobe-keybinds.change-page.description": "Changes the active page", + "firmament.config.wardrobe-keybinds.next-page": "Next Page", + "firmament.config.wardrobe-keybinds.next-page.description": "Goes to the next page", + "firmament.config.wardrobe-keybinds.previous-page": "Previous Page", + "firmament.config.wardrobe-keybinds.previous-page.description": "Goes to the previous page", "firmament.config.wardrobe-keybinds.slot-1": "Slot 1", "firmament.config.wardrobe-keybinds.slot-1.description": "Keybind to toggle the first set in your wardrobe", "firmament.config.wardrobe-keybinds.slot-2": "Slot 2", |