WIP: Reforge Recipes
This commit is contained in:
@@ -39,6 +39,7 @@ import moe.nea.firmament.util.TestUtil
|
||||
import moe.nea.firmament.util.directLiteralStringContent
|
||||
import moe.nea.firmament.util.mc.FirmamentDataComponentTypes
|
||||
import moe.nea.firmament.util.mc.appendLore
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||
import moe.nea.firmament.util.mc.modifyLore
|
||||
import moe.nea.firmament.util.mc.setCustomName
|
||||
@@ -131,6 +132,7 @@ object ItemCache : IReloadable {
|
||||
val itemInstance =
|
||||
ItemStack.fromNbt(MC.defaultRegistries, modernItemTag).getOrNull() ?: return brokenItemStack(this)
|
||||
itemInstance.loreAccordingToNbt = lore.map { un189Lore(it) }
|
||||
itemInstance.displayNameAccordingToNbt = un189Lore(displayName)
|
||||
val extraAttributes = oldItemTag.getCompound("tag").getCompound("ExtraAttributes")
|
||||
if (extraAttributes != null)
|
||||
itemInstance.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraAttributes))
|
||||
|
||||
@@ -108,6 +108,8 @@ data class Reforge(
|
||||
|
||||
@Serializable(with = RarityMapped.Serializer::class)
|
||||
sealed interface RarityMapped<T> {
|
||||
fun get(rarity: Rarity): T?
|
||||
|
||||
class Serializer<T>(
|
||||
val values: KSerializer<T>
|
||||
) : KSerializer<RarityMapped<T>> {
|
||||
@@ -137,10 +139,18 @@ data class Reforge(
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Direct<T>(val value: T) : RarityMapped<T>
|
||||
data class Direct<T>(val value: T) : RarityMapped<T> {
|
||||
override fun get(rarity: Rarity): T {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class PerRarity<T>(val values: Map<Rarity, T>) : RarityMapped<T>
|
||||
data class PerRarity<T>(val values: Map<Rarity, T>) : RarityMapped<T> {
|
||||
override fun get(rarity: Rarity): T? {
|
||||
return values[rarity]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,22 +9,31 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraft.network.RegistryByteBuf
|
||||
import net.minecraft.network.codec.PacketCodec
|
||||
import net.minecraft.network.codec.PacketCodecs
|
||||
import net.minecraft.text.Style
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.text.TextColor
|
||||
import net.minecraft.util.Formatting
|
||||
import moe.nea.firmament.repo.ItemCache.asItemStack
|
||||
import moe.nea.firmament.util.FirmFormatters
|
||||
import moe.nea.firmament.util.LegacyFormattingCode
|
||||
import moe.nea.firmament.util.ReforgeId
|
||||
import moe.nea.firmament.util.SkyblockId
|
||||
import moe.nea.firmament.util.blue
|
||||
import moe.nea.firmament.util.directLiteralStringContent
|
||||
import moe.nea.firmament.util.extraAttributes
|
||||
import moe.nea.firmament.util.getReforgeId
|
||||
import moe.nea.firmament.util.getUpgradeStars
|
||||
import moe.nea.firmament.util.grey
|
||||
import moe.nea.firmament.util.mc.appendLore
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||
import moe.nea.firmament.util.petData
|
||||
import moe.nea.firmament.util.prepend
|
||||
import moe.nea.firmament.util.skyBlockId
|
||||
import moe.nea.firmament.util.skyblock.ItemType
|
||||
import moe.nea.firmament.util.skyblock.Rarity
|
||||
import moe.nea.firmament.util.skyblockId
|
||||
import moe.nea.firmament.util.useMatch
|
||||
import moe.nea.firmament.util.withColor
|
||||
|
||||
data class SBItemStack constructor(
|
||||
@@ -84,6 +93,117 @@ data class SBItemStack constructor(
|
||||
}
|
||||
return SBItemStack(neuIngredient.skyblockId, neuIngredient.amount.toInt())
|
||||
}
|
||||
|
||||
fun appendEnhancedStats(
|
||||
itemStack: ItemStack,
|
||||
reforgeStats: Map<String, Double>,
|
||||
buffKind: BuffKind,
|
||||
) {
|
||||
val namedReforgeStats = reforgeStats
|
||||
.mapKeysTo(mutableMapOf()) { statIdToName(it.key) }
|
||||
val loreMut = itemStack.loreAccordingToNbt.toMutableList()
|
||||
var statBlockLastIndex = -1
|
||||
for (i in loreMut.indices) {
|
||||
val statLine = parseStatLine(loreMut[i])
|
||||
if (statLine == null && statBlockLastIndex >= 0) {
|
||||
break
|
||||
}
|
||||
if (statLine == null) {
|
||||
continue
|
||||
}
|
||||
statBlockLastIndex = i
|
||||
val statBuff = namedReforgeStats.remove(statLine.statName) ?: continue
|
||||
loreMut[i] = statLine.addStat(statBuff, buffKind).reconstitute()
|
||||
}
|
||||
if (namedReforgeStats.isNotEmpty() && statBlockLastIndex == -1) {
|
||||
loreMut.add(0, Text.literal(""))
|
||||
}
|
||||
// If there is no stat block the statBlockLastIndex falls through to -1
|
||||
// TODO: this is good enough for some items. some other items might have their stats at a different place.
|
||||
for ((statName, statBuff) in namedReforgeStats) {
|
||||
val statLine = StatLine(statName, null).addStat(statBuff, buffKind)
|
||||
loreMut.add(statBlockLastIndex + 1, statLine.reconstitute())
|
||||
}
|
||||
itemStack.loreAccordingToNbt = loreMut
|
||||
}
|
||||
|
||||
data class StatFormatting(
|
||||
val postFix: String,
|
||||
val color: Formatting,
|
||||
)
|
||||
|
||||
val formattingOverrides = mapOf(
|
||||
"Sea Creature Chance" to StatFormatting("%", Formatting.RED),
|
||||
"Strength" to StatFormatting("", Formatting.RED),
|
||||
"Damage" to StatFormatting("", Formatting.RED),
|
||||
"Bonus Attack Speed" to StatFormatting("%", Formatting.RED),
|
||||
"Shot Cooldown" to StatFormatting("s", Formatting.RED),
|
||||
"Ability Damage" to StatFormatting("%", Formatting.RED),
|
||||
"Crit Damage" to StatFormatting("%", Formatting.RED),
|
||||
"Crit Chance" to StatFormatting("%", Formatting.RED),
|
||||
"Trophy Fish Chance" to StatFormatting("%", Formatting.GREEN),
|
||||
// TODO: add other types and make this a repo json
|
||||
)
|
||||
|
||||
|
||||
private val statLabelRegex = "(?<statName>.*): ".toPattern()
|
||||
|
||||
enum class BuffKind(
|
||||
val color: Formatting,
|
||||
val prefix: String,
|
||||
val postFix: String,
|
||||
) {
|
||||
REFORGE(Formatting.BLUE, "(", ")"),
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
data class StatLine(
|
||||
val statName: String,
|
||||
val value: Text?,
|
||||
val rest: List<Text> = listOf(),
|
||||
val valueNum: Double? = value?.directLiteralStringContent?.trim(' ', '%', '+')?.toDoubleOrNull()
|
||||
) {
|
||||
fun addStat(amount: Double, buffKind: BuffKind): StatLine {
|
||||
val formattedAmount = FirmFormatters.formatCommas(amount, 1, includeSign = true)
|
||||
return copy(
|
||||
valueNum = (valueNum ?: 0.0) + amount,
|
||||
value = null,
|
||||
rest = rest +
|
||||
listOf(
|
||||
Text.literal(
|
||||
buffKind.prefix + formattedAmount +
|
||||
statFormatting.postFix +
|
||||
buffKind.postFix + " ")
|
||||
.withColor(buffKind.color)))
|
||||
}
|
||||
|
||||
fun formatValue() =
|
||||
Text.literal(FirmFormatters.formatCommas(valueNum ?: 0.0, 1, includeSign = true) + statFormatting.postFix + " ")
|
||||
.setStyle(Style.EMPTY.withColor(statFormatting.color))
|
||||
|
||||
val statFormatting = formattingOverrides[statName] ?: StatFormatting("", Formatting.GREEN)
|
||||
fun reconstitute(): Text =
|
||||
Text.literal("").setStyle(Style.EMPTY.withItalic(false))
|
||||
.append(Text.literal("$statName: ").grey())
|
||||
.append(value ?: formatValue())
|
||||
.also { rest.forEach(it::append) }
|
||||
}
|
||||
|
||||
private fun statIdToName(statId: String): String {
|
||||
return statId.split("_").joinToString(" ") {
|
||||
it.replaceFirstChar { it.uppercaseChar() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseStatLine(line: Text): StatLine? {
|
||||
val sibs = line.siblings
|
||||
val stat = sibs.firstOrNull() ?: return null
|
||||
if (stat.style.color != TextColor.fromFormatting(Formatting.GRAY)) return null
|
||||
val statLabel = stat.directLiteralStringContent ?: return null
|
||||
val statName = statLabelRegex.useMatch(statLabel) { group("statName") } ?: return null
|
||||
return StatLine(statName, sibs[1], sibs.subList(2, sibs.size))
|
||||
}
|
||||
}
|
||||
|
||||
constructor(skyblockId: SkyblockId, petData: PetData) : this(
|
||||
@@ -134,11 +254,19 @@ data class SBItemStack constructor(
|
||||
}
|
||||
|
||||
|
||||
private fun appendReforgeStatsToLore(
|
||||
private fun appendReforgeInfo(
|
||||
itemStack: ItemStack,
|
||||
) {
|
||||
val rarity = itemStack.rarity
|
||||
val lore = itemStack.loreAccordingToNbt
|
||||
val rarity = Rarity.fromItem(itemStack) ?: return
|
||||
val reforgeId = this.reforge ?: return
|
||||
val reforge = ReforgeStore.modifierLut[reforgeId] ?: return
|
||||
val reforgeStats = reforge.reforgeStats?.get(rarity) ?: mapOf()
|
||||
itemStack.displayNameAccordingToNbt = itemStack.displayNameAccordingToNbt.copy()
|
||||
.prepend(Text.literal(reforge.reforgeName + " ").formatted(Rarity.colourMap[rarity] ?: Formatting.WHITE))
|
||||
val data = itemStack.extraAttributes.copy()
|
||||
data.putString("modifier", reforgeId.id)
|
||||
itemStack.extraAttributes = data
|
||||
appendEnhancedStats(itemStack, reforgeStats, BuffKind.REFORGE)
|
||||
}
|
||||
|
||||
// TODO: avoid instantiating the item stack here
|
||||
@@ -156,8 +284,8 @@ data class SBItemStack constructor(
|
||||
injectReplacementDataForPets(replacementData)
|
||||
return@run neuItem.asItemStack(idHint = skyblockId, replacementData)
|
||||
.copyWithCount(stackSize)
|
||||
.also { appendReforgeInfo(it) }
|
||||
.also { it.appendLore(extraLore) }
|
||||
.also { if (reforge != null) it.appendLore(listOf(Text.literal("Reforge: $reforge"))) } // TODO: use this for proper rendering
|
||||
.also { enhanceStatsByStars(it, stars) }
|
||||
}
|
||||
if (itemStack_ == null)
|
||||
|
||||
Reference in New Issue
Block a user