feat: Add descriptions for config options

This commit is contained in:
Linnea Gräf
2024-11-12 21:38:31 +01:00
parent b774daef5b
commit fc88e54a2e
16 changed files with 511 additions and 288 deletions

View File

@@ -2,7 +2,10 @@ package moe.nea.firmament.compat.moulconfig
import com.google.auto.service.AutoService
import io.github.notenoughupdates.moulconfig.Config
import io.github.notenoughupdates.moulconfig.DescriptionRendereringBehaviour
import io.github.notenoughupdates.moulconfig.Social
import io.github.notenoughupdates.moulconfig.common.IMinecraft
import io.github.notenoughupdates.moulconfig.common.MyResourceLocation
import io.github.notenoughupdates.moulconfig.gui.GuiComponent
import io.github.notenoughupdates.moulconfig.gui.GuiElementWrapper
import io.github.notenoughupdates.moulconfig.gui.GuiOptionEditor
@@ -22,10 +25,14 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter
import io.github.notenoughupdates.moulconfig.processor.ProcessedCategory
import io.github.notenoughupdates.moulconfig.processor.ProcessedOption
import java.lang.reflect.Type
import java.net.URI
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
import net.minecraft.client.gui.screen.Screen
import net.minecraft.util.Identifier
import net.minecraft.util.Util
import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.config.BooleanHandler
import moe.nea.firmament.gui.config.ClickHandler
import moe.nea.firmament.gui.config.DurationHandler
@@ -37,6 +44,7 @@ import moe.nea.firmament.gui.config.KeyBindingHandler
import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.gui.config.ManagedOption
import moe.nea.firmament.gui.config.StringHandler
import moe.nea.firmament.gui.toMoulConfig
import moe.nea.firmament.keybindings.SavedKeyBinding
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.FirmFormatters
@@ -287,6 +295,47 @@ class MCConfigEditorIntegration : FirmamentConfigScreenProvider {
override fun shouldAutoFocusSearchbar(): Boolean {
return true
}
override fun getTitle(): String {
return "Firmament"
}
@Deprecated("Deprecated in java")
override fun executeRunnable(runnableId: Int) {
if (runnableId >= 0)
ErrorUtil.softError("Executed runnable $runnableId")
}
override fun getDescriptionBehaviour(option: ProcessedOption?): DescriptionRendereringBehaviour {
return DescriptionRendereringBehaviour.EXPAND_PANEL
}
fun mkSocial(name: String, identifier: Identifier, link: String) = object : Social() {
override fun onClick() {
Util.getOperatingSystem().open(URI(link))
}
override fun getTooltip(): List<String> {
return listOf(name)
}
override fun getIcon(): MyResourceLocation {
return identifier.toMoulConfig()
}
}
private val socials = listOf<Social>(
mkSocial("Discord", Firmament.identifier("textures/socials/discord.png"),
Firmament.modContainer.metadata.contact.get("discord").get()),
mkSocial("Source Code", Firmament.identifier("textures/socials/git.png"),
Firmament.modContainer.metadata.contact.get("sources").get()),
mkSocial("Modrinth", Firmament.identifier("textures/socials/modrinth.png"),
Firmament.modContainer.metadata.contact.get("modrinth").get()),
)
override fun getSocials(): List<Social> {
return socials
}
}
val categories = ManagedConfig.Category.entries.map {
val options = mutableListOf<ProcessedOptionFirm>()
@@ -295,7 +344,7 @@ class MCConfigEditorIntegration : FirmamentConfigScreenProvider {
val categoryAccordionId = nextAccordionId++
options.add(object : ProcessedOptionFirm(-1, configObject) {
override fun getDebugDeclarationLocation(): String {
return "FirmamentConfig:$config.name"
return "FirmamentConfig:${config.name}"
}
override fun getName(): String {

View File

@@ -26,7 +26,7 @@ class ProcessedCategoryFirm(
}
override fun getDescription(): String {
return "Missing description" // TODO: add description
return category.description.string
}
override fun getIdentifier(): String {

View File

@@ -18,7 +18,7 @@ abstract class ProcessedEditableOptionFirm<T : Any>(
}
override fun getDescription(): String {
return "Missing description" // TODO: add description
return managedOption.labelDescription.string
}
override fun explicitNotifyChange() {

View File

@@ -6,6 +6,7 @@ import dev.isxander.yacl3.api.ButtonOption
import dev.isxander.yacl3.api.ConfigCategory
import dev.isxander.yacl3.api.LabelOption
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.ControllerBuilder
@@ -69,6 +70,7 @@ class YaclIntegration : FirmamentConfigScreenProvider {
fun <T> createDefaultBinding(function: (Option<T>) -> ControllerBuilder<T>): Option.Builder<T> {
return Option.createBuilder<T>()
.name(managedOption.labelText)
.description(OptionDescription.of(managedOption.labelDescription))
.binding(binding as Binding<T>)
.controller { function(it) }
}

View File

@@ -0,0 +1,19 @@
package moe.nea.firmament.mixins.devenv;
import net.minecraft.text.TranslatableTextContent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(TranslatableTextContent.class)
public abstract class EarlyInstantiateTranslations {
@Shadow
protected abstract void updateTranslations();
@Inject(method = "<init>", at = @At("TAIL"))
private void onInit(String key, String fallback, Object[] args, CallbackInfo ci) {
updateTranslations();
}
}

View File

@@ -0,0 +1,38 @@
package moe.nea.firmament.mixins.devenv;
import moe.nea.firmament.features.debug.DeveloperFeatures;
import moe.nea.firmament.util.MC;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Set;
import java.util.TreeSet;
@Mixin(TranslationStorage.class)
public abstract class WarnOnMissingTranslations {
@Shadow
public abstract boolean hasTranslation(String key);
@Unique
private final Set<String> missingTranslations = new TreeSet<>();
@Inject(method = "get", at = @At("HEAD"))
private void onGetTranslationKey(String key, String fallback, CallbackInfoReturnable<String> cir) {
warnForMissingTranslation(key);
}
@Unique
private void warnForMissingTranslation(String key) {
if (!key.contains("firmament")) return;
if (hasTranslation(key)) return;
if (!missingTranslations.add(key)) return;
MC.INSTANCE.sendChat(Text.literal("Missing firmament translation: " + key));
DeveloperFeatures.hookMissingTranslations(missingTranslations);
}
}

View File

@@ -49,6 +49,7 @@ import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.data.IDataHolder
object Firmament {
val modContainer by lazy { FabricLoader.getInstance().getModContainer(MOD_ID).get() }
const val MOD_ID = "firmament"
val DEBUG = System.getProperty("firmament.debug") == "true"

View File

@@ -1,12 +1,16 @@
package moe.nea.firmament.features.debug
import java.io.File
import java.nio.file.Path
import java.util.concurrent.CompletableFuture
import kotlinx.serialization.json.encodeToStream
import kotlin.io.path.absolute
import kotlin.io.path.exists
import net.minecraft.client.MinecraftClient
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.util.MC
@@ -14,41 +18,57 @@ import moe.nea.firmament.util.TimeMark
import moe.nea.firmament.util.iterate
object DeveloperFeatures : FirmamentFeature {
override val identifier: String
get() = "developer"
override val config: TConfig
get() = TConfig
override val defaultEnabled: Boolean
get() = Firmament.DEBUG
override val identifier: String
get() = "developer"
override val config: TConfig
get() = TConfig
override val defaultEnabled: Boolean
get() = Firmament.DEBUG
val gradleDir =
Path.of(".").absolute()
.iterate { it.parent }
.find { it.resolve("settings.gradle.kts").exists() }
val gradleDir =
Path.of(".").absolute()
.iterate { it.parent }
.find { it.resolve("settings.gradle.kts").exists() }
object TConfig : ManagedConfig("developer", Category.DEV) {
val autoRebuildResources by toggle("auto-rebuild") { false }
}
object TConfig : ManagedConfig("developer", Category.DEV) {
val autoRebuildResources by toggle("auto-rebuild") { false }
}
@JvmStatic
fun hookOnBeforeResourceReload(client: MinecraftClient): CompletableFuture<Void> {
val reloadFuture = if (TConfig.autoRebuildResources && isEnabled && gradleDir != null) {
val builder = ProcessBuilder("./gradlew", ":processResources")
builder.directory(gradleDir.toFile())
builder.inheritIO()
val process = builder.start()
MC.sendChat(Text.translatable("firmament.dev.resourcerebuild.start"))
val startTime = TimeMark.now()
process.toHandle().onExit().thenApply {
MC.sendChat(Text.stringifiedTranslatable(
"firmament.dev.resourcerebuild.done",
startTime.passedTime()))
Unit
}
} else {
CompletableFuture.completedFuture(Unit)
}
return reloadFuture.thenCompose { client.reloadResources() }
}
var missingTranslations: Set<String>? = null
@JvmStatic
fun hookMissingTranslations(missingTranslations: Set<String>) {
this.missingTranslations = missingTranslations
}
@Subscribe
fun dumpMissingTranslations(tickEvent: TickEvent) {
val toDump = missingTranslations ?: return
missingTranslations = null
File("missing_translations.json").outputStream().use {
Firmament.json.encodeToStream(toDump.associateWith { "Mis" + "sing translation" }, it)
}
}
@JvmStatic
fun hookOnBeforeResourceReload(client: MinecraftClient): CompletableFuture<Void> {
val reloadFuture = if (TConfig.autoRebuildResources && isEnabled && gradleDir != null) {
val builder = ProcessBuilder("./gradlew", ":processResources")
builder.directory(gradleDir.toFile())
builder.inheritIO()
val process = builder.start()
MC.sendChat(Text.translatable("firmament.dev.resourcerebuild.start"))
val startTime = TimeMark.now()
process.toHandle().onExit().thenApply {
MC.sendChat(Text.stringifiedTranslatable(
"firmament.dev.resourcerebuild.done",
startTime.passedTime()))
Unit
}
} else {
CompletableFuture.completedFuture(Unit)
}
return reloadFuture.thenCompose { client.reloadResources() }
}
}

View File

@@ -44,6 +44,7 @@ abstract class ManagedConfig(
;
val labelText: Text = Text.translatable("firmament.config.category.${name.lowercase()}")
val description: Text = Text.translatable("firmament.config.category.${name.lowercase()}.description")
val configs: MutableList<ManagedConfig> = mutableListOf()
}

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.gui.config
import io.github.notenoughupdates.moulconfig.observer.GetSetter
@@ -9,54 +7,57 @@ import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.util.ErrorUtil
class ManagedOption<T : Any>(
val element: ManagedConfig,
val propertyName: String,
val default: () -> T,
val handler: ManagedConfig.OptionHandler<T>
val element: ManagedConfig,
val propertyName: String,
val default: () -> T,
val handler: ManagedConfig.OptionHandler<T>
) : ReadWriteProperty<Any?, T>, GetSetter<T> {
override fun set(newValue: T) {
this.value = newValue
}
override fun set(newValue: T) {
this.value = newValue
}
override fun get(): T {
return this.value
}
override fun get(): T {
return this.value
}
val rawLabelText = "firmament.config.${element.name}.${propertyName}"
val labelText = Text.translatable(rawLabelText)
val rawLabelText = "firmament.config.${element.name}.${propertyName}"
val labelText: Text = Text.translatable(rawLabelText)
val descriptionTranslationKey = "firmament.config.${element.name}.${propertyName}.description"
val labelDescription: Text = Text.translatable(descriptionTranslationKey)
lateinit var value: T
lateinit var value: T
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = value
}
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value
}
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value
}
fun load(root: JsonElement) {
if (root is JsonObject && root.containsKey(propertyName)) {
try {
value = handler.fromJson(root[propertyName]!!)
return
} catch (e: Exception) {
Firmament.logger.error(
"Exception during loading of config file ${element.name}. This will reset this config.",
e
)
}
}
value = default()
}
fun load(root: JsonElement) {
if (root is JsonObject && root.containsKey(propertyName)) {
try {
value = handler.fromJson(root[propertyName]!!)
return
} catch (e: Exception) {
ErrorUtil.softError(
"Exception during loading of config file ${element.name}. This will reset this config.",
e
)
}
}
value = default()
}
fun toJson(): JsonElement? {
return handler.toJson(value)
}
fun toJson(): JsonElement? {
return handler.toJson(value)
}
fun appendToGui(guiapp: GuiAppender) {
handler.emitGuiElements(this, guiapp)
}
fun appendToGui(guiapp: GuiAppender) {
handler.emitGuiElements(this, guiapp)
}
}

View File

@@ -3,6 +3,7 @@ package moe.nea.firmament.util
import io.github.moulberry.repo.data.Coordinate
import java.util.concurrent.ConcurrentLinkedQueue
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.hud.InGameHud
import net.minecraft.client.gui.screen.Screen
import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.client.network.ClientPlayerEntity
@@ -28,9 +29,10 @@ object MC {
init {
TickEvent.subscribe("MC:push") {
while (true) {
inGameHud.chatHud.addMessage(messageQueue.poll() ?: break)
}
if (inGameHud.chatHud != null && world != null)
while (true) {
inGameHud.chatHud.addMessage(messageQueue.poll() ?: break)
}
while (true) {
(nextTickTodos.poll() ?: break).invoke()
}
@@ -41,7 +43,7 @@ object MC {
}
fun sendChat(text: Text) {
if (instance.isOnThread)
if (instance.isOnThread && inGameHud.chatHud != null && world != null)
inGameHud.chatHud.addMessage(text)
else
messageQueue.add(text)
@@ -86,7 +88,7 @@ object MC {
inline val interactionManager get() = instance.interactionManager
inline val textureManager get() = instance.textureManager
inline val options get() = instance.options
inline val inGameHud get() = instance.inGameHud
inline val inGameHud: InGameHud get() = instance.inGameHud
inline val font get() = instance.textRenderer
inline val soundManager get() = instance.soundManager
inline val player: ClientPlayerEntity? get() = instance.player

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -14,7 +14,8 @@
],
"contact": {
"discord": "https://discord.gg/64pFP94AWA",
"sources": "https://git.nea.moe/nea/firmament/"
"sources": "https://github.com/nea89o/Firmament",
"modrinth": "https://modrinth.com/mod/firmament"
},
"license": "GPL 3.0 or Later",
"accessWidener": "firmament.accesswidener",

View File

@@ -1,242 +1,331 @@
{
"firmament.dev.resourcerebuild.start": "Invoking gradle resource rebuild (./gradlew :processResources)",
"firmament.dev.resourcerebuild.done": "Gradle resource rebuild done in %s",
"firmament.carnival.tutorial.minesweeper": "§eClick here to check out Firmaments Tutorial for this minigame!",
"firmament.command.toggle.no-config-found": "Could not find config %s",
"firmament.command.toggle.no-property-found": "Could not find property %s",
"firmament.command.toggle.not-a-toggle": "Property %s is not a toggle",
"firmament.command.toggle.toggled": "Toggled %s / %s %s",
"firmament.command.waypoint.added": "Added waypoint %s %s %s.",
"firmament.command.waypoint.clear": "Cleared waypoints.",
"firmament.command.waypoint.import": "Imported %s waypoints from clipboard.",
"firmament.command.waypoint.import.error": "Could not import waypoints from clipboard. Make sure they are on ColeWeight format:\n[{\"x\": 69, \"y\":420, \"z\": 36}]",
"firmament.command.waypoint.clear": "Cleared waypoints.",
"firmament.command.waypoint.added": "Added waypoint %s %s %s.",
"firmament.command.waypoint.remove": "Removed waypoint %s. Other waypoints may have different indexes now.",
"firmament.command.waypoint.remove.error": "Could not find waypoint with that index to delete.",
"firmament.command.waypoint.skip.error": "Could not skip a waypoint. Are you in ordered waypoint mode with waypoints loaded?",
"firmament.command.waypoint.skip": "Skipped 1 waypoint",
"firmament.poweruser.entity.fail": "No entity found under cursor",
"firmament.poweruser.entity.type": "Entity Type: %s",
"firmament.poweruser.entity.name": "Entity Name: %s",
"firmament.poweruser.entity.position": "Position: %s",
"firmament.poweruser.entity.armor": "Entity Armor:",
"firmament.poweruser.entity.armor.item": " - %s",
"firmament.poweruser.entity.passengers": "%s Passengers",
"firmament.mixins.start": "Applied firmament mixins:",
"firmament.command.waypoint.skip.error": "Could not skip a waypoint. Are you in ordered waypoint mode with waypoints loaded?",
"firmament.config.all-configs": "- All Configs -",
"firmament.config.anniversary": "Anniversary Features",
"firmament.config.anniversary.shiny-pigs": "Shiny Pigs Tracker",
"firmament.config.anniversary.pig-hud": "Pig Tracker Hud",
"firmament.pristine-profit.collection": "Collection: %s/h",
"firmament.pristine-profit.money": "Money: %s/h",
"firmament.toggle.true": "On",
"firmament.toggle.false": "Off",
"firmament.config.developer": "Developer Settings",
"firmament.config.developer.auto-rebuild": "Automatically rebuild resources",
"firmament.price": "Checking price for %s",
"firmament.price.bazaar": "Bazaar stats:",
"firmament.price.bazaar.productid": "Stock id: %s",
"firmament.price.bazaar.buy.price": "Buy Price: %s",
"firmament.price.bazaar.buy.order": "Buy orders: %d",
"firmament.tooltip.bazaar.sell-order": "Bazaar Sell Order: %s",
"firmament.tooltip.bazaar.buy-order": "Bazaar Buy Order: %s",
"firmament.tooltip.ah.lowestbin": "Lowest BIN: %d",
"firmament.pv.pets": "Pets",
"firmament.reiwarning.disable": "Click here to disable this warning",
"firmament.reiwarning.disabled": "Disabled the RoughlyEnoughItems warning. Keep in mind that you will not have an item list without REI.",
"firmament.download": "Click here to download %s",
"firmament.download.already": " (Already downloaded)",
"firmament.reiwarning": "Firmament needs RoughlyEnoughItems to display its item list!",
"firmament.config.diana": "Diana",
"firmament.config.diana.ancestral-teleport": "Warp near guess",
"firmament.config.diana.ancestral-spade": "Ancestral Spade Solver",
"firmament.config.diana.nearby-waypoints": "Nearby Waypoints Highlighter",
"firmament.config.pristine-profit": "Pristine Profit Tracker",
"firmament.config.pristine-profit.timeout": "Timeout (0 = disabled)",
"firmament.config.pristine-profit.position": "Position",
"firmament.debug.skyblockid": "SkyBlock ID: %s",
"firmament.debug.skyblockid.copy": "Click to copy SkyBlock ID",
"firmament.price.bazaar.sell.price": "Sell Price: %s",
"firmament.price.bazaar.sell.order": "Sell orders: %d",
"firmament.price.lowestbin": "Lowest BIN: %s",
"firmament.repo.reload.network": "Trying to redownload the repository",
"firmament.repo.reload.disk": "Reloading repository from disk. This may lag a bit.",
"firmament.repo.cache": "Recaching items",
"firmament.repo.brokenitem": "Failed to render item: %s",
"firmament.config.anniversary.pig-hud.description": "A HUD showing rewards pulled from shiny pigs",
"firmament.config.anniversary.shiny-pigs": "Shiny Pigs Tracker",
"firmament.config.anniversary.shiny-pigs.description": "Track rewards from shiny pigs, as well as how much time you have left to collect your pig.",
"firmament.config.auto-completions": "Hypixel Command Improvements",
"firmament.config.auto-completions.warp-complete": "Auto Complete /warp",
"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",
"firmanent.config.edit": "Edit",
"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.carnival": "Carnival Features",
"firmament.config.carnival.bombs-solver": "Bombs Solver",
"firmament.config.carnival.bombs-solver": "Minesweeper Helper",
"firmament.config.carnival.bombs-solver.description": "Display bombs surrounding each block in minesweeper.",
"firmament.config.carnival.tutorials": "Tutorial Reminder",
"firmament.carnival.tutorial.minesweeper": "§eClick here to check out Firmaments Tutorial for this minigame!",
"firmament.config.repo": "Firmament Repo Settings",
"firmament.config.repo.autoUpdate": "Auto Update",
"firmament.config.repo.username": "Repo Username",
"firmament.config.repo.username.hint": "NotEnoughUpdates",
"firmament.config.repo.reponame": "Repo Name",
"firmament.config.repo.reponame.hint": "NotEnoughUpdates-REPO",
"firmament.config.configconfig.enable-yacl": "Use YACL Config",
"firmament.config.repo.branch": "Repo Branch",
"firmament.config.configconfig": "Firmaments Config",
"firmament.config.carnival.tutorials.description": "Show a tutorial hint every time you start a game with a Firmament tutorial.",
"firmament.config.category.chat": "Chat",
"firmament.config.category.chat.description": "Chat related features",
"firmament.config.category.dev": "Developer & Debug",
"firmament.config.category.dev.description": "Settings for texture pack devs and programmers",
"firmament.config.category.events": "Events",
"firmament.config.category.events.description": "Settings for temporary or repeating events",
"firmament.config.category.integrations": "Integrations & Textures",
"firmament.config.category.integrations.description": "Integrations with other mods, as well as texture packs",
"firmament.config.category.inventory": "Inventory",
"firmament.config.category.inventory.description": "Features for anything that happens in a chest or inventory",
"firmament.config.category.meta": "Meta & Firmament",
"firmament.config.category.meta.description": "Settings for Firmament and the item repo",
"firmament.config.category.mining": "Mining",
"firmament.config.category.mining.description": "Mining related features",
"firmament.config.category.misc": "Miscellaneous",
"firmament.config.category.misc.description": "Miscellaneous features that don't fit elsewhere",
"firmament.config.chat-links": "Chat Links",
"firmament.config.chat-links.allow-all-hosts": "Allow all Image Hosts",
"firmament.config.chat-links.allow-all-hosts.description": "Allow displaying images no matter where it is hosted.",
"firmament.config.chat-links.allowed-hosts": "Allowed Image Hosts",
"firmament.config.chat-links.allowed-hosts.description": "Prevent yourself from requesting images from other servers, to prevent your IP from being leaked.",
"firmament.config.chat-links.image-enabled": "Enable Image Preview",
"firmament.config.chat-links.image-enabled.description": "Show a preview of images when hovering over links in chat",
"firmament.config.chat-links.links-enabled": "Enable Clickable Links",
"firmament.config.chat-links.links-enabled.description": "Make links in chat clickable",
"firmament.config.chat-links.position": "Chat Image Preview",
"firmament.config.chat-links.position.description": "Edit where the images are shown",
"firmament.config.commissions": "Commissions",
"firmament.config.commissions.highlight-completed": "Highlight Completed",
"firmament.config.repo.branch.hint": "dangerous",
"firmament.config.repo.reset": "Reset",
"firmament.config.repo.disable-item-groups": "Disable Item Groups",
"firmament.config.repo.enable-super-craft": "Always use Super Craft",
"firmament.config.repo.reload": "Reload Item List",
"firmament.config.repo.redownload": "Redownload Item List",
"firmament.config.pets": "Pets",
"firmament.config.pets.highlight-pet": "Highlight active pet",
"firmament.config.category.misc": "Miscellaneous",
"firmament.config.category.mining": "Mining",
"firmament.config.category.events": "Events",
"firmament.config.category.chat": "Chat",
"firmament.config.category.inventory": "Inventory",
"firmament.config.category.integrations": "Integrations & Textures",
"firmament.config.category.meta": "Meta & Firmament",
"firmament.config.category.dev": "Developer & Debug",
"firmament.ursa.debugrequest.start": "Ursa request launched",
"firmament.hotmpreset.openinghotm": "Opening /hotm menu for export.",
"firmament.hotmpreset.scrollprompt": "We need to scroll! Please click anywhere to continue.",
"firmament.hotmpreset.scrolled": "Just scrolled. Waiting on server to update items.",
"firmament.hotmpreset.copied": "Collected all HOTM perks to clipboard. Use /firm importhotm to import.",
"firmament.hotmpreset.okayimport": "Imported a HOTM perk preset.",
"firmament.hotmpreset.failedimport": "Could not find a HOTM perk preset in your clipboard. You can export your current HOTM perks with /firm exporthotm",
"firmament.ursa.debugrequest.result": "Ursa request succeeded: %s",
"firmament.sbinfo.nolocraw": "No locraw data available",
"firmament.sbinfo.profile": "Current profile cutename: %s",
"firmament.sbinfo.server": "Locraw Server: %s",
"firmament.sbinfo.gametype": "Locraw Gametype: %s",
"firmament.sbinfo.mode": "Locraw Mode: %s",
"firmament.sbinfo.map": "Locraw Map: %s",
"firmament.config.price-data": "Price data",
"firmament.config.price-data.enable-always": "Enable Item Price",
"firmament.config.price-data.enable-keybind": "Enable only with Keybinding",
"firmament.config.commissions.highlight-completed.description": "Highlight completed commissions in the commission menu",
"firmament.config.compatibility": "Intermod Features",
"firmament.config.compatibility.explosion-enabled": "Redirect Enhanced Explosions",
"firmament.config.compatibility.explosion-enabled.description": "Redirect explosion particles to be rendered by enhanced explosions.",
"firmament.config.compatibility.explosion-power": "Enhanced Explosion Power",
"firmament.config.compatibility.explosion-power.description": "Choose how big explosions will be rendered by enhanced explosions",
"firmament.config.configconfig": "Firmaments Config",
"firmament.config.configconfig.enable-moulconfig": "Use MoulConfig",
"firmament.config.configconfig.enable-moulconfig.description": "Uses the MoulConfig config UI. Turn off to fall back to the built in config.",
"firmament.config.configconfig.enable-yacl": "Use YACL Config",
"firmament.config.configconfig.enable-yacl.description": "Uses the YACL config UI. Turn off to fall back to the built in config.",
"firmament.config.custom-skyblock-textures": "Custom SkyBlock Item Textures",
"firmament.config.custom-skyblock-textures.armor-overrides": "Enable Armor re-texturing",
"firmament.config.custom-skyblock-textures.armor-overrides.description": "Allows texture pack authors to re-texture (but not re-model) SkyBlock armors.",
"firmament.config.custom-skyblock-textures.block-overrides": "Enable Block re-modelling",
"firmament.config.custom-skyblock-textures.block-overrides.description": "Allows texture pack authors replacing block models depending on block position and SkyBlock island.",
"firmament.config.custom-skyblock-textures.cache-duration": "Model Cache Duration",
"firmament.config.custom-skyblock-textures.cache-duration.description": "How long texture models should be cached for.",
"firmament.config.custom-skyblock-textures.cache-forever": "Disable cache clearing",
"firmament.config.custom-skyblock-textures.cache-forever.description": "Disables clearing the cache entirely. Since you will be sent new item stacks from the server if something changes, this should not cause issues.",
"firmament.config.custom-skyblock-textures.enabled": "Enable Custom Item Textures",
"firmament.config.custom-skyblock-textures.enabled.description": "Allow replacing items for texture packs. Turning this off does not disable custom predicates",
"firmament.config.custom-skyblock-textures.legacy-cit": "Enable legacy CIT Resewn compat",
"firmament.config.custom-skyblock-textures.legacy-cit.description": "Allow CIT resewn texture packs written for 1.20.4 to be loaded on newer versions.",
"firmament.config.custom-skyblock-textures.model-overrides": "Enable model overrides/predicates",
"firmament.config.custom-skyblock-textures.model-overrides.description": "Enable Firmament's model predicates. This will apply to vanilla models as well, if that vanilla model has Firmament predicates.",
"firmament.config.custom-skyblock-textures.recolor-text": "Allow packs to recolor text",
"firmament.config.custom-skyblock-textures.recolor-text.description": "Allows texture packs to recolor UI texts.",
"firmament.config.custom-skyblock-textures.skulls-enabled": "Enable Custom Placed Skull Textures",
"firmament.config.custom-skyblock-textures.skulls-enabled.description": "Allow replacing the textures of placed skulls.",
"firmament.config.developer": "Developer Settings",
"firmament.config.developer.auto-rebuild": "Automatically rebuild resources",
"firmament.config.developer.auto-rebuild.description": "Executes ./gradlew processResources before F3+T is executed.",
"firmament.config.diana": "Diana",
"firmament.config.diana.ancestral-spade": "Ancestral Spade Solver",
"firmament.config.diana.ancestral-spade.description": "Automatically guess your next burrow based on particles and sounds spawned from the Ancestral Spade's Echo ability.",
"firmament.config.diana.ancestral-teleport": "Warp near guess",
"firmament.config.diana.ancestral-teleport.description": "Click to teleport near the guessed burrow.",
"firmament.config.diana.nearby-waypoints": "Nearby Waypoints Highlighter",
"firmament.config.diana.nearby-waypoints.description": "Highlight nearby diana burrows.",
"firmament.config.fairy-souls": "Fairy Souls",
"firmament.config.fairy-souls.show": "Show Fairy Soul Waypoints",
"firmament.config.fairy-souls.reset": "Reset Collected Fairy Souls",
"firmament.config.fairy-souls.reset.description": "Reset all collected fairy souls, allowing you to restart from null.",
"firmament.config.fairy-souls.show": "Show Fairy Soul Waypoints",
"firmament.config.fairy-souls.show.description": "Show unclaimed Fairy Soul waypoints in the world you are currently in.",
"firmament.config.fishing-warning": "Fishing Warning",
"firmament.config.fishing-warning.display-warning": "Display a warning when you are about to hook a fish",
"firmament.config.fishing-warning.highlight-wake-chain": "Highlight fishing particles",
"firmament.protectitem": "Firmament protected your item: ",
"firmament.inventory-buttons.save-preset": "Save Preset",
"firmament.inventory-buttons.load-preset": "Load Preset",
"firmament.inventory-buttons.import-failed": "One of your buttons could only be imported partially",
"firmament.config.fixes": "Fixes",
"firmament.config.fixes.auto-sprint": "Auto Sprint",
"firmament.config.fixes.auto-sprint-hud": "Sprint State Hud",
"firmament.config.fixes.auto-sprint-hud.description": "Show your current sprint state on your screen. Only visible if no auto sprint keybind is set.",
"firmament.config.fixes.auto-sprint-keybinding": "Auto Sprint KeyBinding",
"firmament.config.fixes.auto-sprint-keybinding.description": "Toggle auto sprint via this keybinding.",
"firmament.config.fixes.auto-sprint.description": "This is different from vanilla sprint in the way that it only marks the keybinding pressed for the first tick of walking.",
"firmament.config.fixes.peek-chat": "Peek Chat",
"firmament.config.fixes.peek-chat.description": "Hold this keybinding to view the chat as if you have it opened, but while still being able to control your character.",
"firmament.config.fixes.player-skins": "Fix unsigned Player Skins",
"firmament.config.fixes.player-skins.description": "Mark all player skins as signed, preventing console spam, and some rendering issues.",
"firmament.config.inventory-buttons": "Inventory buttons",
"firmament.config.inventory-buttons.open-editor": "Open Editor",
"firmament.warp-util.mark-excluded": "Firmament: Tried to warp to %s, but it was not unlocked. I will avoid warping there again.",
"firmament.waypoint.temporary": "Temporary Waypoint: %s",
"firmament.config.waypoints": "Waypoints",
"firmament.config.waypoints.temp-waypoint-duration": "Temporary Waypoint Duration",
"firmament.config.waypoints.show-index": "Show ordered waypoint indexes",
"firmament.config.waypoints.skip-to-nearest": "Allow skipping waypoints",
"firmament.recipe.forge.time": "Forging Time: %s",
"firmament.recipe.mobs.drops": "§e§lDrop Chance: %s",
"firmament.recipe.mobs.name": "§8[§7Lv %d§8] §c%s",
"firmament.recipe.mobs.name.nolevel": "§c%s",
"firmament.recipe.mobs.coins": "§eCoins: %s",
"firmament.recipe.mobs.combat": "§bCombat Experience: %s",
"firmament.recipe.mobs.exp": "§6Experience: %s",
"firmament.pv.skills": "Skills",
"firmament.pv.skills.farming": "Farming",
"firmament.pv.skills.foraging": "Foraging",
"firmament.pv.skills.mining": "Mining",
"firmament.pv.skills.alchemy": "Alchemy",
"firmament.pv.skills.taming": "Taming",
"firmament.pv.skills.fishing": "Fishing",
"firmament.pv.skills.runecrafting": "Runecrafting",
"firmament.pv.skills.carpentry": "Carpentry",
"firmament.pv.skills.combat": "Combat",
"firmament.pv.skills.social": "Social",
"firmament.pv.skills.rift": "Rift",
"firmament.pv.skills.enchanting": "Enchanting",
"firmament.pv.skills.total": "Total Exp: %s",
"firmament.pv.lookingup": "Looking up %s",
"firmament.pv.noprofile": "%s has no SkyBlock profiles",
"firmament.pv.noplayer": "%s is not a Minecraft player",
"firmament.config.save-cursor-position.enable": "Enable",
"firmament.config.save-cursor-position.tolerance": "Tolerance",
"firmament.config.save-cursor-position": "Save Cursor Position",
"firmament.config.storage-overlay": "Storage Overlay",
"firmament.config.storage-overlay.rows": "Columns",
"firmament.config.storage-overlay.always-replace": "Always Open Overlay",
"firmament.config.storage-overlay.padding": "Padding",
"firmament.config.storage-overlay.scroll-speed": "Scroll Speed",
"firmament.config.storage-overlay.inverse-scroll": "Invert Scroll",
"firmament.config.storage-overlay.margin": "Margin",
"firmament.config.chat-links": "Chat Links",
"firmament.config.chat-links.links-enabled": "Enable Clickable Links",
"firmament.config.chat-links.image-enabled": "Enable Image Preview",
"firmament.config.chat-links.allow-all-hosts": "Allow all Image Hosts",
"firmament.config.chat-links.allowed-hosts": "Allowed Image Hosts",
"firmament.config.chat-links.position": "Chat Image Preview",
"firmament.config.inventory-buttons.open-editor.description": "Click anywhere to create a new inventory button or to edit one. Hold SHIFT to grid align.",
"firmament.config.item-rarity-cosmetics": "Item Rarity Cosmetics",
"firmament.config.item-rarity-cosmetics.background": "Slot Background Rarity",
"firmament.config.item-rarity-cosmetics.background-hotbar": "Hotbar Background Rarity",
"firmament.hud.edit": "Edit %s",
"firmament.key.category": "Firmament",
"firmament.keybinding.external": "%s",
"firmament.config.slot-locking": "Slot Locking",
"firmament.config.slot-locking.lock": "Lock Slot",
"firmament.config.slot-locking.lock-uuid": "Lock UUID (Lock Item)",
"firmament.config.slot-locking.bind": "Bind Slot",
"firmament.config.slot-locking.require-quick-move": "Require Shift-Click for Bound Slots",
"firmament.config.fixes.auto-sprint": "Auto Sprint",
"firmament.config.fixes.auto-sprint-keybinding": "Auto Sprint KeyBinding",
"firmament.config.fixes.auto-sprint-hud": "Sprint State Hud",
"firmament.config.fixes.peek-chat": "Peek Chat",
"firmament.config.fixes.clientside-lefthand": "Fix Left Handed",
"firmament.fixes.auto-sprint.on": "Sprint toggled",
"firmament.fixes.auto-sprint.sprinting": "Sprinting",
"firmament.fixes.auto-sprint.not-sprinting": "Not Sprinting",
"firmament.recipe.novanilla": "Hypixel cannot super craft vanilla recipes",
"firmament.config.custom-skyblock-textures": "Custom SkyBlock Item Textures",
"firmament.config.custom-skyblock-textures.cache-duration": "Model Cache Duration",
"firmament.config.custom-skyblock-textures.model-overrides": "Enable model overrides/predicates",
"firmament.config.custom-skyblock-textures.legacy-cit": "Enable legacy CIT Resewn compat",
"firmament.config.custom-skyblock-textures.recolor-text": "Allow packs to recolor text",
"firmament.config.custom-skyblock-textures.armor-overrides": "Enable Armor re-texturing",
"firmament.config.custom-skyblock-textures.block-overrides": "Enable Block re-modelling",
"firmament.config.custom-skyblock-textures.enabled": "Enable Custom Item Textures",
"firmament.config.custom-skyblock-textures.skulls-enabled": "Enable Custom Placed Skull Textures",
"firmament.config.custom-skyblock-textures.cache-forever": "Disable cache clearing",
"firmament.config.fixes": "Fixes",
"firmament.config.fixes.player-skins": "Fix unsigned Player Skins",
"firmament.config.power-user.show-item-id": "Show SkyBlock Ids",
"firmament.config.power-user.copy-item-id": "Copy SkyBlock Id",
"firmament.modapi.event": "Received mod API event: %s",
"firmament.config.power-user.copy-texture-pack-id": "Copy Texture Pack Id",
"firmament.config.power-user.copy-skull-texture": "Copy Placed Skull Id",
"firmament.config.power-user.entity-data": "Show Entity Data",
"firmament.config.power-user.copy-nbt-data": "Copy ExtraAttributes data",
"firmament.config.power-user.copy-lore": "Copy Name + Lore",
"firmament.config.power-user.copy-item-stack": "Copy ItemStack",
"firmament.config.power-user": "Power Users",
"firmament.tooltip.skyblockid": "SkyBlock Id: %s",
"firmament.tooltip.copied.skyblockid.fail": "Failed to copy SkyBlock Id",
"firmament.tooltip.copied.skyblockid": "Copied SkyBlock Id: %s",
"firmament.tooltip.copied.modelid.fail": "Failed to copy Texture Id",
"firmament.tooltip.copied.modelid": "Copied Texture Id: %s",
"firmament.tooltip.copied.skull": "Copied Skull Id: %s",
"firmament.tooltip.copied.skull.fail": "Failed to copy skull id.",
"firmament.tooltip.copied.nbt": "Copied NBT data",
"firmament.tooltip.copied.lore": "Copied Name and Lore",
"firmament.tooltip.copied.stack": "Copied ItemStack",
"firmament.config.compatibility": "Intermod Features",
"firmament.config.compatibility.explosion-enabled": "Redirect Enhanced Explosions",
"firmament.config.compatibility.explosion-power": "Enhanced Explosion Power",
"firmament.quick-commands.join.unknown": "Could not find instance for %s",
"firmament.quick-commands.join.success": "Joining: %s",
"firmament.quick-commands.join.explain": "Join a dungeon or kuudra floor by using commands like /join f1, /join m7, /join fe or /join khot",
"firmament.quick-commands.join.unknown-kuudra": "Unknown kuudra floor %s",
"firmament.quick-commands.join.unknown-catacombs": "Unknown catacombs floor %s",
"firmament.config.item-rarity-cosmetics.background-hotbar.description": "Show item rarity background in the hotbar.",
"firmament.config.item-rarity-cosmetics.background.description": "Show a background behind each item, depending on its rarity.",
"firmament.config.pets": "Pets",
"firmament.config.pets.highlight-pet": "Highlight active pet",
"firmament.config.pets.highlight-pet.description": "Highlight your currently selected pet in the /pets menu.",
"firmament.config.pickaxe-info": "Pickaxes",
"firmament.config.pickaxe-info.ability-cooldown": "Pickaxe Ability Cooldown",
"firmament.config.pickaxe-info.ability-cooldown.description": "Show a cooldown on your cross-hair for your pickaxe ability.",
"firmament.config.pickaxe-info.ability-scale": "Ability Cooldown Scale",
"firmament.config.pickaxe-info.ability-scale.description": "Resize the cooldown around your cross-hair for your pickaxe ability.",
"firmament.config.pickaxe-info.fuel-bar": "Drill Fuel Durability Bar",
"firmament.warp-util.no-warp-found": "Could not find an unlocked warp in %s",
"firmament.config.pickaxe-info.fuel-bar.description": "Replace the item durability bar of your drills with one that shows the remaining fuel.",
"firmament.config.power-user": "Power Users",
"firmament.config.power-user.copy-item-id": "Copy SkyBlock Id",
"firmament.config.power-user.copy-item-id.description": "Press this button to copy the NEU repo SkyBlock id. This is not the raw id, but instead contains some extra transformations for things like runes, pets and enchant books.",
"firmament.config.power-user.copy-item-stack": "Copy ItemStack",
"firmament.config.power-user.copy-item-stack.description": "Copy the entire item stack metadata. This can be used in tests to recreate the item in code.",
"firmament.config.power-user.copy-lore": "Copy Name + Lore",
"firmament.config.power-user.copy-lore.description": "Copy the items name and lore as json encoded text",
"firmament.config.power-user.copy-nbt-data": "Copy ExtraAttributes data",
"firmament.config.power-user.copy-nbt-data.description": "Copy only the ExtraAttributes, so the hypixel specific item data.",
"firmament.config.power-user.copy-skull-texture": "Copy Placed Skull Id",
"firmament.config.power-user.copy-skull-texture.description": "Copy the texture location that can be used to re-texture the skull under your cross-hair.",
"firmament.config.power-user.copy-texture-pack-id": "Copy Texture Pack Id",
"firmament.config.power-user.copy-texture-pack-id.description": "Copy the texture pack id that is used for the item stack under your cursor.",
"firmament.config.power-user.entity-data": "Show Entity Data",
"firmament.config.power-user.entity-data.description": "Print out information about the entity under your cross-hair.",
"firmament.config.power-user.show-item-id": "Show SkyBlock Ids",
"firmament.config.power-user.show-item-id.description": "Show the SkyBlock id of items underneath them.",
"firmament.config.price-data": "Price data",
"firmament.config.price-data.enable-always": "Enable Item Price",
"firmament.config.price-data.enable-always.description": "Show item auction/bazaar prices on SkyBlock items",
"firmament.config.price-data.enable-keybind": "Enable only with Keybinding",
"firmament.config.price-data.enable-keybind.description": "Only show auction/bazaar prices when holding this keybinding. Unbind to always show.",
"firmament.config.pristine-profit": "Pristine Profit Tracker",
"firmament.config.pristine-profit.position": "Position",
"firmament.config.pristine-profit.position.description": "Edit the pristine profit hud location.",
"firmament.config.pristine-profit.timeout": "Timeout (0 = disabled)",
"firmament.config.pristine-profit.timeout.description": "Track the profit you make from pristine gemstones while mining. Set to 0 seconds to disable the HUD.",
"firmament.config.repo": "Firmament Repo Settings",
"firmament.config.repo.autoUpdate": "Auto Update",
"firmament.config.repo.autoUpdate.description": "Automatically download new items for the item list on every startup.",
"firmament.config.repo.branch": "Repo Branch",
"firmament.config.repo.branch.description": "Git Branch to pull item data from.",
"firmament.config.repo.branch.hint": "dangerous",
"firmament.config.repo.disable-item-groups": "Disable Item Groups",
"firmament.config.repo.disable-item-groups.description": "Disabling item groups can increase performance, but will no longer collect similar items (like minions, enchantments) together.",
"firmament.config.repo.enable-super-craft": "Always use Super Craft",
"firmament.config.repo.enable-super-craft.description": "Always use super craft when clicking the craft button in REI, instead of just when holding shift.",
"firmament.config.repo.redownload": "Redownload Item List",
"firmament.config.repo.redownload.description": "Force re-download the item list. This is automatically done on restart.",
"firmament.config.repo.reload": "Reload Item List",
"firmament.config.repo.reload.description": "Force reload the item list. This will not download the item list again.",
"firmament.config.repo.reponame": "Repo Name",
"firmament.config.repo.reponame.description": "The GitHub repository name to pull item data from.",
"firmament.config.repo.reponame.hint": "NotEnoughUpdates-REPO",
"firmament.config.repo.reset": "Reset",
"firmament.config.repo.reset.description": "Reset the Git download location.",
"firmament.config.repo.username": "Repo Username",
"firmament.config.repo.username.description": "The GitHub repository organization to pull item data from.",
"firmament.config.repo.username.hint": "NotEnoughUpdates",
"firmament.config.repo.warn-for-missing-item-list-mod": "Warn for missing item list",
"firmament.config.repo.warn-for-missing-item-list-mod.description": "Warn if there is no compatible item list mod, like REI, installed.",
"firmament.config.save-cursor-position": "Save Cursor Position",
"firmament.config.save-cursor-position.enable": "Enable",
"firmament.config.save-cursor-position.enable.description": "Save your cursor position when switching GUIs.",
"firmament.config.save-cursor-position.tolerance": "Tolerance",
"firmament.config.save-cursor-position.tolerance.description": "Select how long your cursor position last between GUIs before resetting back to the middle of the screen.",
"firmament.config.slot-locking": "Slot Locking",
"firmament.config.slot-locking.bind": "Bind Slot",
"firmament.config.slot-locking.bind.description": "Bind a hotbar slot to another slot. This allows quick switching between the slots by shift clicking on either slot.",
"firmament.config.slot-locking.lock": "Lock Slot",
"firmament.config.slot-locking.lock-uuid": "Lock UUID (Lock Item)",
"firmament.config.slot-locking.lock-uuid.description": "Lock a SkyBlock item by it's UUID. This blocks a specific item from being dropped/sold, but still allows moving it around.",
"firmament.config.slot-locking.lock.description": "Lock a slot, preventing any item from being moved from, dropped from, or placed into this slot.",
"firmament.config.slot-locking.require-quick-move": "Require Shift-Click for Bound Slots",
"firmament.config.slot-locking.require-quick-move.description": "If turned off, allows to switch between bound slots without holding shift.",
"firmament.config.storage-overlay": "Storage Overlay",
"firmament.config.storage-overlay.always-replace": "Always Open Overlay",
"firmament.config.storage-overlay.always-replace.description": "Always replace the ender chest with Firmament's storage overlay.",
"firmament.config.storage-overlay.inverse-scroll": "Invert Scroll",
"firmament.config.storage-overlay.inverse-scroll.description": "Invert the mouse wheel scrolling in Firmament's storage overlay.",
"firmament.config.storage-overlay.margin": "Margin",
"firmament.config.storage-overlay.margin.description": "Margin inside of the storage overview.",
"firmament.config.storage-overlay.padding": "Padding",
"firmament.config.storage-overlay.padding.description": "Padding inside of the storage overview.",
"firmament.config.storage-overlay.rows": "Columns",
"firmament.config.storage-overlay.rows.description": "Max columns used by the storage overlay and overview.",
"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.waypoints": "Waypoints",
"firmament.config.waypoints.show-index": "Show ordered waypoint indexes",
"firmament.config.waypoints.show-index.description": "Show the number of an ordered waypoint in the world.",
"firmament.config.waypoints.skip-to-nearest": "Allow skipping waypoints",
"firmament.config.waypoints.skip-to-nearest.description": "Allow skipping waypoints in an ordered list. If disabled you will need to walk to the next point, before being allowed to the next one after.",
"firmament.config.waypoints.temp-waypoint-duration": "Temporary Waypoint Duration",
"firmament.config.waypoints.temp-waypoint-duration.description": "Display waypoints sent by other players using /firm sendcoords in the world.",
"firmament.debug.skyblockid": "SkyBlock ID: %s",
"firmament.debug.skyblockid.copy": "Click to copy SkyBlock ID",
"firmament.dev.resourcerebuild.done": "Gradle resource rebuild done in %s",
"firmament.dev.resourcerebuild.start": "Invoking gradle resource rebuild (./gradlew :processResources)",
"firmament.download": "Click here to download %s",
"firmament.download.already": " (Already downloaded)",
"firmament.fixes.auto-sprint.not-sprinting": "Not Sprinting",
"firmament.fixes.auto-sprint.on": "Sprint toggled",
"firmament.fixes.auto-sprint.sprinting": "Sprinting",
"firmament.hotmpreset.copied": "Collected all HOTM perks to clipboard. Use /firm importhotm to import.",
"firmament.hotmpreset.failedimport": "Could not find a HOTM perk preset in your clipboard. You can export your current HOTM perks with /firm exporthotm",
"firmament.hotmpreset.okayimport": "Imported a HOTM perk preset.",
"firmament.hotmpreset.openinghotm": "Opening /hotm menu for export.",
"firmament.hotmpreset.scrolled": "Just scrolled. Waiting on server to update items.",
"firmament.hotmpreset.scrollprompt": "We need to scroll! Please click anywhere to continue.",
"firmament.hud.edit": "Edit %s",
"firmament.inventory-buttons.import-failed": "One of your buttons could only be imported partially",
"firmament.inventory-buttons.load-preset": "Load Preset",
"firmament.inventory-buttons.save-preset": "Save Preset",
"firmament.key.category": "Firmament",
"firmament.keybinding.external": "%s",
"firmament.mixins.start": "Applied firmament mixins:",
"firmament.modapi.event": "Received mod API event: %s",
"firmament.poweruser.entity.armor": "Entity Armor:",
"firmament.poweruser.entity.armor.item": " - %s",
"firmament.poweruser.entity.fail": "No entity found under cursor",
"firmament.poweruser.entity.name": "Entity Name: %s",
"firmament.poweruser.entity.passengers": "%s Passengers",
"firmament.poweruser.entity.position": "Position: %s",
"firmament.poweruser.entity.type": "Entity Type: %s",
"firmament.price": "Checking price for %s",
"firmament.price.bazaar": "Bazaar stats:",
"firmament.price.bazaar.buy.order": "Buy orders: %d",
"firmament.price.bazaar.buy.price": "Buy Price: %s",
"firmament.price.bazaar.productid": "Stock id: %s",
"firmament.price.bazaar.sell.order": "Sell orders: %d",
"firmament.price.bazaar.sell.price": "Sell Price: %s",
"firmament.price.lowestbin": "Lowest BIN: %s",
"firmament.pristine-profit.collection": "Collection: %s/h",
"firmament.pristine-profit.money": "Money: %s/h",
"firmament.protectitem": "Firmament protected your item: ",
"firmament.pv.lookingup": "Looking up %s",
"firmament.pv.noplayer": "%s is not a Minecraft player",
"firmament.pv.noprofile": "%s has no SkyBlock profiles",
"firmament.pv.pets": "Pets",
"firmament.pv.skills": "Skills",
"firmament.pv.skills.alchemy": "Alchemy",
"firmament.pv.skills.carpentry": "Carpentry",
"firmament.pv.skills.combat": "Combat",
"firmament.pv.skills.enchanting": "Enchanting",
"firmament.pv.skills.farming": "Farming",
"firmament.pv.skills.fishing": "Fishing",
"firmament.pv.skills.foraging": "Foraging",
"firmament.pv.skills.mining": "Mining",
"firmament.pv.skills.rift": "Rift",
"firmament.pv.skills.runecrafting": "Runecrafting",
"firmament.pv.skills.social": "Social",
"firmament.pv.skills.taming": "Taming",
"firmament.pv.skills.total": "Total Exp: %s",
"firmament.quick-commands.join.explain": "Join a dungeon or kuudra floor by using commands like /join f1, /join m7, /join fe or /join khot",
"firmament.quick-commands.join.success": "Joining: %s",
"firmament.quick-commands.join.unknown": "Could not find instance for %s",
"firmament.quick-commands.join.unknown-catacombs": "Unknown catacombs floor %s",
"firmament.quick-commands.join.unknown-kuudra": "Unknown kuudra floor %s",
"firmament.recipe.forge.time": "Forging Time: %s",
"firmament.recipe.mobs.coins": "§eCoins: %s",
"firmament.recipe.mobs.combat": "§bCombat Experience: %s",
"firmament.recipe.mobs.drops": "§e§lDrop Chance: %s",
"firmament.recipe.mobs.exp": "§6Experience: %s",
"firmament.recipe.mobs.name": "§8[§7Lv %d§8] §c%s",
"firmament.recipe.mobs.name.nolevel": "§c%s",
"firmament.recipe.novanilla": "Hypixel cannot super craft vanilla recipes",
"firmament.reiwarning": "Firmament needs RoughlyEnoughItems to display its item list!",
"firmament.reiwarning.disable": "Click here to disable this warning",
"firmament.reiwarning.disabled": "Disabled the RoughlyEnoughItems warning. Keep in mind that you will not have an item list without REI.",
"firmament.repo.brokenitem": "Failed to render item: %s",
"firmament.repo.cache": "Recaching items",
"firmament.repo.reload.disk": "Reloading repository from disk. This may lag a bit.",
"firmament.repo.reload.network": "Trying to redownload the repository",
"firmament.sbinfo.gametype": "Locraw Gametype: %s",
"firmament.sbinfo.map": "Locraw Map: %s",
"firmament.sbinfo.mode": "Locraw Mode: %s",
"firmament.sbinfo.nolocraw": "No locraw data available",
"firmament.sbinfo.profile": "Current profile cutename: %s",
"firmament.sbinfo.server": "Locraw Server: %s",
"firmament.toggle.false": "Off",
"firmament.toggle.true": "On",
"firmament.tooltip.ah.lowestbin": "Lowest BIN: %d",
"firmament.tooltip.bazaar.buy-order": "Bazaar Buy Order: %s",
"firmament.tooltip.bazaar.sell-order": "Bazaar Sell Order: %s",
"firmament.tooltip.copied.lore": "Copied Name and Lore",
"firmament.tooltip.copied.modelid": "Copied Texture Id: %s",
"firmament.tooltip.copied.modelid.fail": "Failed to copy Texture Id",
"firmament.tooltip.copied.nbt": "Copied NBT data",
"firmament.tooltip.copied.skull": "Copied Skull Id: %s",
"firmament.tooltip.copied.skull.fail": "Failed to copy skull id.",
"firmament.tooltip.copied.skyblockid": "Copied SkyBlock Id: %s",
"firmament.tooltip.copied.skyblockid.fail": "Failed to copy SkyBlock Id",
"firmament.tooltip.copied.stack": "Copied ItemStack",
"firmament.tooltip.skyblockid": "SkyBlock Id: %s",
"firmament.ursa.debugrequest.result": "Ursa request succeeded: %s",
"firmament.ursa.debugrequest.start": "Ursa request launched",
"firmament.warp-util.already-close": "Already closer to destination than /warp %s",
"firmament.warp-util.attempting-to-warp": "Trying to warp to /warp %s",
"firmament.warp-util.clear-excluded": "Marked all /warp commands as potentially available."
"firmament.warp-util.clear-excluded": "Marked all /warp commands as potentially available.",
"firmament.warp-util.mark-excluded": "Firmament: Tried to warp to %s, but it was not unlocked. I will avoid warping there again.",
"firmament.warp-util.no-warp-found": "Could not find an unlocked warp in %s",
"firmament.waypoint.temporary": "Temporary Waypoint: %s",
"firmanent.config.edit": "Edit"
}