@@ -11,17 +11,16 @@ import net.minecraft.network.codec.PacketCodec
1111import net.minecraft.network.codec.PacketCodecs
1212import net.minecraft.text.Style
1313import net.minecraft.text.Text
14- import net.minecraft.text.TextColor
1514import net.minecraft.util.Formatting
1615import moe.nea.firmament.repo.ItemCache.asItemStack
1716import moe.nea.firmament.repo.ItemCache.withFallback
17+ import moe.nea.firmament.repo.item.StatBlock
1818import moe.nea.firmament.util.FirmFormatters
1919import moe.nea.firmament.util.LegacyFormattingCode
2020import moe.nea.firmament.util.MC
2121import moe.nea.firmament.util.ReforgeId
2222import moe.nea.firmament.util.SkyblockId
2323import moe.nea.firmament.util.blue
24- import moe.nea.firmament.util.directLiteralStringContent
2524import moe.nea.firmament.util.extraAttributes
2625import moe.nea.firmament.util.getReforgeId
2726import 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