aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/kotlin/util/json/CodecSerializer.kt26
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/TreeishTextReplacer.kt40
-rw-r--r--web/src/pages/docs/_texture-pack-format.md19
3 files changed, 55 insertions, 30 deletions
diff --git a/src/main/kotlin/util/json/CodecSerializer.kt b/src/main/kotlin/util/json/CodecSerializer.kt
new file mode 100644
index 0000000..9ea08ad
--- /dev/null
+++ b/src/main/kotlin/util/json/CodecSerializer.kt
@@ -0,0 +1,26 @@
+package util.json
+
+import com.mojang.serialization.Codec
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import kotlinx.serialization.json.JsonElement
+import moe.nea.firmament.util.json.KJsonOps
+
+abstract class CodecSerializer<T>(val codec: Codec<T>) : KSerializer<T> {
+ override val descriptor: SerialDescriptor
+ get() = JsonElement.serializer().descriptor
+
+ override fun serialize(encoder: Encoder, value: T) {
+ encoder.encodeSerializableValue(
+ JsonElement.serializer(),
+ codec.encodeStart(KJsonOps.INSTANCE, value).orThrow
+ )
+ }
+
+ override fun deserialize(decoder: Decoder): T {
+ return codec.decode(KJsonOps.INSTANCE, decoder.decodeSerializableValue(JsonElement.serializer()))
+ .orThrow.first
+ }
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/TreeishTextReplacer.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/TreeishTextReplacer.kt
index 0a59451..95c277c 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/TreeishTextReplacer.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/TreeishTextReplacer.kt
@@ -1,17 +1,12 @@
package moe.nea.firmament.features.texturepack
-import java.lang.StringBuilder
import java.util.regex.Matcher
-import kotlinx.serialization.KSerializer
+import util.json.CodecSerializer
import kotlinx.serialization.Serializable
-import kotlinx.serialization.descriptors.SerialDescriptor
-import kotlinx.serialization.encoding.Decoder
-import kotlinx.serialization.encoding.Encoder
-import kotlinx.serialization.json.JsonElement
+import net.minecraft.text.Style
import net.minecraft.text.Text
import net.minecraft.text.TextCodecs
import moe.nea.firmament.util.directLiteralStringContent
-import moe.nea.firmament.util.json.KJsonOps
import moe.nea.firmament.util.transformEachRecursively
@Serializable
@@ -22,26 +17,12 @@ data class TreeishTextReplacer(
@Serializable
data class SubPartReplacement(
val match: StringMatcher,
+ val style: @Serializable(StyleSerializer::class) Style?,
val replace: @Serializable(TextSerializer::class) Text,
)
- object TextSerializer : KSerializer<Text> {
- override val descriptor: SerialDescriptor
- get() = JsonElement.serializer().descriptor
-
- override fun serialize(encoder: Encoder, value: Text) {
- encoder.encodeSerializableValue(
- JsonElement.serializer(),
- TextCodecs.CODEC.encodeStart(KJsonOps.INSTANCE, value).orThrow
- )
- }
-
- override fun deserialize(decoder: Decoder): Text {
- return TextCodecs.CODEC.decode(KJsonOps.INSTANCE, decoder.decodeSerializableValue(JsonElement.serializer()))
- .orThrow.first
- }
- }
-
+ object TextSerializer : CodecSerializer<Text>(TextCodecs.CODEC)
+ object StyleSerializer : CodecSerializer<Style>(Style.Codecs.CODEC)
companion object {
val pattern = "(?!<\\$([$]{2})*)[$]\\{(?<name>[^}])\\}".toPattern()
fun injectMatchResults(text: Text, matches: Matcher): Text {
@@ -67,6 +48,17 @@ data class TreeishTextReplacer(
var part: Text = part
for (replacement in replacements) {
val rawPartText = part.string
+ replacement.style?.let { expectedStyle ->
+ val parentStyle = part.style
+ val parented = expectedStyle.withParent(parentStyle)
+ if (parented.isStrikethrough != parentStyle.isStrikethrough
+ || parented.isObfuscated != parentStyle.isObfuscated
+ || parented.isBold != parentStyle.isBold
+ || parented.isUnderlined != parentStyle.isUnderlined
+ || parented.isItalic != parentStyle.isItalic
+ || parented.color?.rgb != parentStyle.color?.rgb)
+ continue
+ }
val matcher = replacement.match.asRegex.matcher(rawPartText)
if (!matcher.find()) continue
val p = Text.literal("")
diff --git a/web/src/pages/docs/_texture-pack-format.md b/web/src/pages/docs/_texture-pack-format.md
index 129ec14..26274c2 100644
--- a/web/src/pages/docs/_texture-pack-format.md
+++ b/web/src/pages/docs/_texture-pack-format.md
@@ -799,12 +799,19 @@ Our finalized text looks like this:
Which rendered out looks like ` <newIcon> Strength 510.45`, with all colours original, except the `<newIcon>` which not only has new text but also a new colour.
-| Field | Required | Description |
-|--------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `match` | yes | A top level [string matcher](#string-matcher). Allows for testing parts of the text unrelated to the replacement and improves performance. |
-| `replacements` | yes | A list of replacements to apply to each part of the text |
-| `replacements.*.match` | yes | A [string matcher](#string-matcher) substring to replace in each component of the text. Notabene: Unlike most string matchers, this one is not anchored to the beginning and end of the element, so if the entire component needs to be matched a regex with `^$` needs to be used. |
-| `replacements.*.replace` | yes | A vanilla [text](https://minecraft.wiki/w/Text_component_format#Java_Edition) that is inserted to replace the substring matched in the match. If literal texts (not translated texts) are used, then `${name}` can be used to access named groups in the match regex (if a regex matcher was used). |
+| Field | Required | Description |
+|--------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `match` | yes | A top level [string matcher](#string-matcher). Allows for testing parts of the text unrelated to the replacement and improves performance. |
+| `replacements` | yes | A list of replacements to apply to each part of the text |
+| `replacements.*.match` | yes | A [string matcher](#string-matcher) substring to replace in each component of the text. Notabene: Unlike most string matchers, this one is not anchored to the beginning and end of the element, so if the entire component needs to be matched a regex with `^$` needs to be used. |
+| `replacements.*.style` | yes | A vanilla [style](https://minecraft.wiki/w/Text_component_format#Java_Edition) (where only the fields `color`, `italic`, `bold`, `underlined`, `strikethrough` and `obfuscated` are set). Checks if this specific subcomponent is of the correct style |
+| `replacements.*.style.color` | no | A vanilla color name (as set in a text) that checks that the subcomponent is of that colour. |
+| `replacements.*.style.italic` | no | A boolean that can be set `true` or `false` to require this text to be italic or not. |
+| `replacements.*.style.bold` | no | A boolean that can be set `true` or `false` to require this text to be bold or not. |
+| `replacements.*.style.underlined` | no | A boolean that can be set `true` or `false` to require this text to be underlined or not. |
+| `replacements.*.style.strikethrough` | no | A boolean that can be set `true` or `false` to require this text to be strikethrough or not. |
+| `replacements.*.style.obfuscated` | no | A boolean that can be set `true` or `false` to require this text to be obfuscated or not. |
+| `replacements.*.replace` | yes | A vanilla [text](https://minecraft.wiki/w/Text_component_format#Java_Edition) that is inserted to replace the substring matched in the match. If literal texts (not translated texts) are used, then `${name}` can be used to access named groups in the match regex (if a regex matcher was used). |