feat: Add reforge ability to reforge recipes

This commit is contained in:
Linnea Gräf
2025-01-17 18:42:18 +01:00
parent 11eed13b81
commit 5e54ffd424
3 changed files with 69 additions and 59 deletions

View File

@@ -24,6 +24,7 @@ import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtOps import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.NbtString import net.minecraft.nbt.NbtString
import net.minecraft.text.MutableText
import net.minecraft.text.Style import net.minecraft.text.Style
import net.minecraft.text.Text import net.minecraft.text.Text
import moe.nea.firmament.Firmament import moe.nea.firmament.Firmament
@@ -100,7 +101,7 @@ object ItemCache : IReloadable {
} }
} }
fun un189Lore(lore: String): Text { fun un189Lore(lore: String): MutableText {
val base = Text.literal("") val base = Text.literal("")
base.setStyle(Style.EMPTY.withItalic(false)) base.setStyle(Style.EMPTY.withItalic(false))
var lastColorCode = Style.EMPTY var lastColorCode = Style.EMPTY

View File

@@ -5,6 +5,7 @@ import com.mojang.serialization.codecs.RecordCodecBuilder
import io.github.moulberry.repo.constants.PetNumbers import io.github.moulberry.repo.constants.PetNumbers
import io.github.moulberry.repo.data.NEUIngredient import io.github.moulberry.repo.data.NEUIngredient
import io.github.moulberry.repo.data.NEUItem import io.github.moulberry.repo.data.NEUItem
import net.minecraft.client.util.ChatMessages
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.network.RegistryByteBuf import net.minecraft.network.RegistryByteBuf
import net.minecraft.network.codec.PacketCodec import net.minecraft.network.codec.PacketCodec
@@ -17,8 +18,10 @@ import moe.nea.firmament.repo.ItemCache.asItemStack
import moe.nea.firmament.repo.ItemCache.withFallback import moe.nea.firmament.repo.ItemCache.withFallback
import moe.nea.firmament.util.FirmFormatters import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.LegacyFormattingCode import moe.nea.firmament.util.LegacyFormattingCode
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.ReforgeId import moe.nea.firmament.util.ReforgeId
import moe.nea.firmament.util.SkyblockId import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.blue
import moe.nea.firmament.util.directLiteralStringContent import moe.nea.firmament.util.directLiteralStringContent
import moe.nea.firmament.util.extraAttributes import moe.nea.firmament.util.extraAttributes
import moe.nea.firmament.util.getReforgeId import moe.nea.firmament.util.getReforgeId
@@ -27,12 +30,15 @@ import moe.nea.firmament.util.grey
import moe.nea.firmament.util.mc.appendLore import moe.nea.firmament.util.mc.appendLore
import moe.nea.firmament.util.mc.displayNameAccordingToNbt import moe.nea.firmament.util.mc.displayNameAccordingToNbt
import moe.nea.firmament.util.mc.loreAccordingToNbt import moe.nea.firmament.util.mc.loreAccordingToNbt
import moe.nea.firmament.util.mc.modifyLore
import moe.nea.firmament.util.petData import moe.nea.firmament.util.petData
import moe.nea.firmament.util.prepend import moe.nea.firmament.util.prepend
import moe.nea.firmament.util.reconstitute
import moe.nea.firmament.util.skyBlockId import moe.nea.firmament.util.skyBlockId
import moe.nea.firmament.util.skyblock.ItemType import moe.nea.firmament.util.skyblock.ItemType
import moe.nea.firmament.util.skyblock.Rarity import moe.nea.firmament.util.skyblock.Rarity
import moe.nea.firmament.util.skyblockId import moe.nea.firmament.util.skyblockId
import moe.nea.firmament.util.unformattedString
import moe.nea.firmament.util.useMatch import moe.nea.firmament.util.useMatch
import moe.nea.firmament.util.withColor import moe.nea.firmament.util.withColor
@@ -308,6 +314,22 @@ data class SBItemStack constructor(
data.putString("modifier", reforgeId.id) data.putString("modifier", reforgeId.id)
itemStack.extraAttributes = data itemStack.extraAttributes = data
appendEnhancedStats(itemStack, reforgeStats, BuffKind.REFORGE) appendEnhancedStats(itemStack, reforgeStats, BuffKind.REFORGE)
reforge.reforgeAbility?.get(rarity)?.let { reforgeAbility ->
val formattedReforgeAbility = ItemCache.un189Lore(reforgeAbility)
.grey()
itemStack.modifyLore {
val lastBlank = it.indexOfLast { it.unformattedString.isBlank() }
val newList = mutableListOf<Text>()
newList.addAll(it.subList(0, lastBlank))
newList.add(Text.literal(""))
newList.add(Text.literal("${reforge.reforgeName} Bonus").blue())
MC.font.textHandler.wrapLines(formattedReforgeAbility, 180, Style.EMPTY).mapTo(newList) {
it.reconstitute()
}
newList.addAll(it.subList(lastBlank, it.size))
return@modifyLore newList
}
}
} }
// TODO: avoid instantiating the item stack here // TODO: avoid instantiating the item stack here

View File

@@ -1,72 +1,18 @@
package moe.nea.firmament.util package moe.nea.firmament.util
import java.util.Optional
import net.minecraft.text.ClickEvent import net.minecraft.text.ClickEvent
import net.minecraft.text.MutableText import net.minecraft.text.MutableText
import net.minecraft.text.OrderedText
import net.minecraft.text.PlainTextContent import net.minecraft.text.PlainTextContent
import net.minecraft.text.StringVisitable
import net.minecraft.text.Style
import net.minecraft.text.Text import net.minecraft.text.Text
import net.minecraft.text.TextColor import net.minecraft.text.TextColor
import net.minecraft.text.TranslatableTextContent import net.minecraft.text.TranslatableTextContent
import net.minecraft.util.Formatting import net.minecraft.util.Formatting
import moe.nea.firmament.Firmament
class TextMatcher(text: Text) {
data class State(
var iterator: MutableList<Text>,
var currentText: Text?,
var offset: Int,
var textContent: String,
)
var state = State(
mutableListOf(text),
null,
0,
""
)
fun pollChunk(): Boolean {
val firstOrNull = state.iterator.removeFirstOrNull() ?: return false
state.offset = 0
state.currentText = firstOrNull
state.textContent = when (val content = firstOrNull.content) {
is PlainTextContent.Literal -> content.string
else -> {
Firmament.logger.warn("TextContent of type ${content.javaClass} not understood.")
return false
}
}
state.iterator.addAll(0, firstOrNull.siblings)
return true
}
fun pollChunks(): Boolean {
while (state.offset !in state.textContent.indices) {
if (!pollChunk()) {
return false
}
}
return true
}
fun pollChar(): Char? {
if (!pollChunks()) return null
return state.textContent[state.offset++]
}
fun expectString(string: String): Boolean {
var found = ""
while (found.length < string.length) {
if (!pollChunks()) return false
val takeable = state.textContent.drop(state.offset).take(string.length - found.length)
state.offset += takeable.length
found += takeable
}
return found == string
}
}
val formattingChars = "kmolnrKMOLNR".toSet() val formattingChars = "kmolnrKMOLNR".toSet()
fun CharSequence.removeColorCodes(keepNonColorCodes: Boolean = false): String { fun CharSequence.removeColorCodes(keepNonColorCodes: Boolean = false): String {
var nextParagraph = indexOf('§') var nextParagraph = indexOf('§')
@@ -89,6 +35,47 @@ fun CharSequence.removeColorCodes(keepNonColorCodes: Boolean = false): String {
return stringBuffer.toString() return stringBuffer.toString()
} }
fun OrderedText.reconstitute(): MutableText {
val base = Text.literal("")
base.setStyle(Style.EMPTY.withItalic(false))
var lastColorCode = Style.EMPTY
val text = StringBuilder()
this.accept { index, style, codePoint ->
if (style != lastColorCode) {
if (text.isNotEmpty())
base.append(Text.literal(text.toString()).setStyle(lastColorCode))
lastColorCode = style
text.clear()
}
text.append(codePoint.toChar())
true
}
if (text.isNotEmpty())
base.append(Text.literal(text.toString()).setStyle(lastColorCode))
return base
}
fun StringVisitable.reconstitute(): MutableText {
val base = Text.literal("")
base.setStyle(Style.EMPTY.withItalic(false))
var lastColorCode = Style.EMPTY
val text = StringBuilder()
this.visit({ style, string ->
if (style != lastColorCode) {
if (text.isNotEmpty())
base.append(Text.literal(text.toString()).setStyle(lastColorCode))
lastColorCode = style
text.clear()
}
text.append(string)
Optional.empty<Unit>()
}, Style.EMPTY)
if (text.isNotEmpty())
base.append(Text.literal(text.toString()).setStyle(lastColorCode))
return base
}
val Text.unformattedString: String val Text.unformattedString: String
get() = string.removeColorCodes() // TODO: maybe shortcircuit this with .visit get() = string.removeColorCodes() // TODO: maybe shortcircuit this with .visit