Skip to content

Commit aacd527

Browse files
committed
refactor: Refactor stat blocks
1 parent 207161d commit aacd527

File tree

3 files changed

+182
-133
lines changed

3 files changed

+182
-133
lines changed

src/compat/rei/java/moe/nea/firmament/compat/rei/recipes/SBReforgeRecipe.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import moe.nea.firmament.repo.ReforgeStore
3131
import moe.nea.firmament.repo.RepoItemTypeCache
3232
import moe.nea.firmament.repo.RepoManager
3333
import moe.nea.firmament.repo.SBItemStack
34+
import moe.nea.firmament.repo.item.StatBlock
3435
import moe.nea.firmament.util.AprilFoolsUtil
3536
import moe.nea.firmament.util.FirmFormatters
3637
import moe.nea.firmament.util.SkyblockId
@@ -106,7 +107,10 @@ class SBReforgeRecipe(
106107
for ((i, statId) in display.reforge.statUniverse.withIndex()) {
107108
val label = Widgets.createLabel(
108109
Point(bounds.minX + 10 + 24 + 24 + 20, bounds.minY + 8 + i * 11),
109-
SBItemStack.Companion.StatLine(SBItemStack.statIdToName(statId), null).reconstitute(7))
110+
StatBlock.StatLine( // TODO: add helper methods for constructing stat lines
111+
StatBlock.findStatFormatting(SBItemStack.statIdToName(statId)),
112+
0.0
113+
).reconstitute(7))
110114
.horizontalAlignment(Label.LEFT_ALIGNED)
111115
statToLineMappings.add(statId to label)
112116
list.add(label)
@@ -116,9 +120,9 @@ class SBReforgeRecipe(
116120
val stats = display.reforge.reforgeStats?.get(entry.rarity) ?: mapOf()
117121
for ((stat, label) in statToLineMappings) {
118122
label.message =
119-
SBItemStack.Companion.StatLine(
120-
SBItemStack.statIdToName(stat), null,
121-
valueNum = stats[stat]
123+
StatBlock.StatLine(
124+
StatBlock.findStatFormatting(SBItemStack.statIdToName(stat)),
125+
stats[stat] ?: 0.0
122126
).reconstitute(7)
123127
}
124128
}

src/main/kotlin/repo/SBItemStack.kt

Lines changed: 11 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@ import net.minecraft.network.codec.PacketCodec
1111
import net.minecraft.network.codec.PacketCodecs
1212
import net.minecraft.text.Style
1313
import net.minecraft.text.Text
14-
import net.minecraft.text.TextColor
1514
import net.minecraft.util.Formatting
1615
import moe.nea.firmament.repo.ItemCache.asItemStack
1716
import moe.nea.firmament.repo.ItemCache.withFallback
17+
import moe.nea.firmament.repo.item.StatBlock
1818
import moe.nea.firmament.util.FirmFormatters
1919
import moe.nea.firmament.util.LegacyFormattingCode
2020
import moe.nea.firmament.util.MC
2121
import moe.nea.firmament.util.ReforgeId
2222
import moe.nea.firmament.util.SkyblockId
2323
import moe.nea.firmament.util.blue
24-
import moe.nea.firmament.util.directLiteralStringContent
2524
import moe.nea.firmament.util.extraAttributes
2625
import moe.nea.firmament.util.getReforgeId
2726
import moe.nea.firmament.util.getUpgradeStars
@@ -107,95 +106,30 @@ data class SBItemStack constructor(
107106
return SBItemStack(SkyblockId.NULL, null, itemStack.count, null, fallback = itemStack)
108107
}
109108

110-
fun parseStatBlock(itemStack: ItemStack): List<StatLine> {
111-
return itemStack.loreAccordingToNbt
112-
.map { parseStatLine(it) }
113-
.takeWhile { it != null }
114-
.filterNotNull()
115-
}
116-
117109
fun appendEnhancedStats(
118110
itemStack: ItemStack,
119111
reforgeStats: Map<String, Double>,
120112
buffKind: BuffKind,
121113
) {
122114
val namedReforgeStats = reforgeStats
123115
.mapKeysTo(mutableMapOf()) { statIdToName(it.key) }
116+
124117
val loreMut = itemStack.loreAccordingToNbt.toMutableList()
125-
var statBlockLastIndex = -1
126-
for (i in loreMut.indices) {
127-
val statLine = parseStatLine(loreMut[i])
128-
if (statLine == null && statBlockLastIndex >= 0) {
129-
break
130-
}
131-
if (statLine == null) {
132-
continue
133-
}
134-
statBlockLastIndex = i
135-
val statBuff = namedReforgeStats.remove(statLine.statName) ?: continue
136-
loreMut[i] = statLine.addStat(statBuff, buffKind).reconstitute()
137-
}
138-
if (namedReforgeStats.isNotEmpty() && statBlockLastIndex == -1) {
139-
loreMut.add(0, Text.literal(""))
140-
}
141-
// If there is no stat block the statBlockLastIndex falls through to -1
142-
// TODO: this is good enough for some items. some other items might have their stats at a different place.
118+
val statBlock = StatBlock.fromLore(loreMut)
143119
for ((statName, statBuff) in namedReforgeStats) {
144-
val statLine = StatLine(statName, null).addStat(statBuff, buffKind)
145-
loreMut.add(statBlockLastIndex + 1, statLine.reconstitute())
120+
statBlock.modify(statName) { it.addStat(statBuff, buffKind) }
146121
}
122+
statBlock.applyModifications(loreMut)
147123
itemStack.loreAccordingToNbt = loreMut
148124
}
149125

150126
data class StatFormatting(
127+
val name: String,
151128
val postFix: String,
152129
val color: Formatting,
153130
val isStarAffected: Boolean = true,
154131
)
155132

156-
val formattingOverrides = mapOf(
157-
"Sea Creature Chance" to StatFormatting("%", Formatting.RED),
158-
"Strength" to StatFormatting("", Formatting.RED),
159-
"Damage" to StatFormatting("", Formatting.RED),
160-
"Bonus Attack Speed" to StatFormatting("%", Formatting.RED),
161-
"Shot Cooldown" to StatFormatting("s", Formatting.GREEN, false),
162-
"Ability Damage" to StatFormatting("%", Formatting.RED),
163-
"Crit Damage" to StatFormatting("%", Formatting.RED),
164-
"Crit Chance" to StatFormatting("%", Formatting.RED),
165-
"Ability Damage" to StatFormatting("%", Formatting.RED),
166-
"Trophy Fish Chance" to StatFormatting("%", Formatting.GREEN),
167-
"Health" to StatFormatting("", Formatting.GREEN),
168-
"Defense" to StatFormatting("", Formatting.GREEN),
169-
"Fishing Speed" to StatFormatting("", Formatting.GREEN),
170-
"Double Hook Chance" to StatFormatting("%", Formatting.GREEN),
171-
"Mining Speed" to StatFormatting("", Formatting.GREEN),
172-
"Mining Fortune" to StatFormatting("", Formatting.GREEN),
173-
"Heat Resistance" to StatFormatting("", Formatting.GREEN),
174-
"Swing Range" to StatFormatting("", Formatting.GREEN),
175-
"Rift Time" to StatFormatting("", Formatting.GREEN),
176-
"Speed" to StatFormatting("", Formatting.GREEN),
177-
"Farming Fortune" to StatFormatting("", Formatting.GREEN),
178-
"True Defense" to StatFormatting("", Formatting.GREEN),
179-
"Mending" to StatFormatting("", Formatting.GREEN),
180-
"Foraging Wisdom" to StatFormatting("", Formatting.GREEN),
181-
"Farming Wisdom" to StatFormatting("", Formatting.GREEN),
182-
"Foraging Fortune" to StatFormatting("", Formatting.GREEN),
183-
"Magic Find" to StatFormatting("", Formatting.GREEN),
184-
"Ferocity" to StatFormatting("", Formatting.GREEN),
185-
"Bonus Pest Chance" to StatFormatting("%", Formatting.GREEN),
186-
"Cold Resistance" to StatFormatting("", Formatting.GREEN),
187-
"Pet Luck" to StatFormatting("", Formatting.GREEN),
188-
"Fear" to StatFormatting("", Formatting.GREEN),
189-
"Mana Regen" to StatFormatting("%", Formatting.GREEN),
190-
"Rift Damage" to StatFormatting("", Formatting.GREEN),
191-
"Hearts" to StatFormatting("", Formatting.GREEN),
192-
"Vitality" to StatFormatting("", Formatting.GREEN),
193-
// TODO: make this a repo json
194-
)
195-
196-
197-
private val statLabelRegex = "(?<statName>.*): ".toPattern()
198-
199133
enum class BuffKind(
200134
val color: Formatting,
201135
val prefix: String,
@@ -208,62 +142,10 @@ data class SBItemStack constructor(
208142
;
209143
}
210144

211-
data class StatLine(
212-
val statName: String,
213-
val value: Text?,
214-
val rest: List<Text> = listOf(),
215-
val valueNum: Double? = value?.directLiteralStringContent?.trim(' ', 's', '%', '+')?.toDoubleOrNull()
216-
) {
217-
fun addStat(amount: Double, buffKind: BuffKind): StatLine {
218-
val formattedAmount = FirmFormatters.formatCommas(amount, 1, includeSign = true)
219-
return copy(
220-
valueNum = (valueNum ?: 0.0) + amount,
221-
value = null,
222-
rest = rest +
223-
if (buffKind.isHidden) emptyList()
224-
else listOf(
225-
Text.literal(
226-
buffKind.prefix + formattedAmount +
227-
statFormatting.postFix +
228-
buffKind.postFix + " ")
229-
.withColor(buffKind.color)))
230-
}
231-
232-
fun formatValue() =
233-
Text.literal(FirmFormatters.formatCommas(valueNum ?: 0.0,
234-
1,
235-
includeSign = true) + statFormatting.postFix + " ")
236-
.setStyle(Style.EMPTY.withColor(statFormatting.color))
237-
238-
val statFormatting = formattingOverrides[statName] ?: StatFormatting("", Formatting.GREEN)
239-
private fun abbreviate(abbreviateTo: Int): String {
240-
if (abbreviateTo >= statName.length) return statName
241-
val segments = statName.split(" ")
242-
return segments.joinToString(" ") {
243-
it.substring(0, maxOf(1, abbreviateTo / segments.size))
244-
}
245-
}
246-
247-
fun reconstitute(abbreviateTo: Int = Int.MAX_VALUE): Text =
248-
Text.literal("").setStyle(Style.EMPTY.withItalic(false))
249-
.append(Text.literal("${abbreviate(abbreviateTo)}: ").grey())
250-
.append(value ?: formatValue())
251-
.also { rest.forEach(it::append) }
252-
}
253-
254145
fun statIdToName(statId: String): String {
255146
val segments = statId.split("_")
256147
return segments.joinToString(" ") { it.replaceFirstChar { it.uppercaseChar() } }
257148
}
258-
259-
private fun parseStatLine(line: Text): StatLine? {
260-
val sibs = line.siblings
261-
val stat = sibs.firstOrNull() ?: return null
262-
if (stat.style.color != TextColor.fromFormatting(Formatting.GRAY)) return null
263-
val statLabel = stat.directLiteralStringContent ?: return null
264-
val statName = statLabelRegex.useMatch(statLabel) { group("statName") } ?: return null
265-
return StatLine(statName, sibs[1], sibs.subList(2, sibs.size))
266-
}
267149
}
268150

269151
constructor(skyblockId: SkyblockId, petData: PetData) : this(
@@ -369,7 +251,7 @@ data class SBItemStack constructor(
369251
val baseItem = neuItem.asItemStack(idHint = skyblockId, replacementData)
370252
.withFallback(fallback)
371253
.copyWithCount(stackSize)
372-
val baseStats = parseStatBlock(baseItem)
254+
val baseStats = StatBlock.fromLore(baseItem.loreAccordingToNbt)
373255
appendReforgeInfo(baseItem)
374256
baseItem.appendLore(extraLore)
375257
enhanceStatsByStars(baseItem, stars, baseStats)
@@ -403,9 +285,8 @@ data class SBItemStack constructor(
403285
return starString
404286
}
405287

406-
private fun enhanceStatsByStars(itemStack: ItemStack, stars: Int, baseStats: List<StatLine>) {
288+
private fun enhanceStatsByStars(itemStack: ItemStack, stars: Int, baseStats: StatBlock) {
407289
if (stars == 0) return
408-
// TODO: increase stats and add the star level into the nbt data so star displays work
409290
itemStack.modifyExtraAttributes {
410291
it.putInt("upgrade_level", stars)
411292
}
@@ -415,9 +296,10 @@ data class SBItemStack constructor(
415296
val truncatedStarCount = if (isDungeon) minOf(5, stars) else stars
416297
appendEnhancedStats(itemStack,
417298
baseStats
418-
.filter { it.statFormatting.isStarAffected }
299+
.indexedByName.values
300+
.filter { it.stat.isStarAffected }
419301
.associate {
420-
it.statName to ((it.valueNum ?: 0.0) * (truncatedStarCount * 0.02))
302+
it.statName to (it.value * (truncatedStarCount * 0.02))
421303
},
422304
BuffKind.STAR_BUFF)
423305
}

0 commit comments

Comments
 (0)