Skip to content

Commit

Permalink
Add 'children' configuration in image.
Browse files Browse the repository at this point in the history
  • Loading branch information
toxicity188 committed Nov 24, 2024
1 parent 57e236c commit 4d12e6d
Show file tree
Hide file tree
Showing 31 changed files with 391 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@
* @param pixel pixel
*/
public record PixelComponent(@NotNull WidthComponent component, int pixel) {
public @NotNull PixelComponent plus(@NotNull WidthComponent other) {
return new PixelComponent(
component.plus(other),
pixel
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ class BukkitBootstrapImpl : BukkitBootstrap, JavaPlugin() {
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
DATA_FOLDER.subFolder("placeholders").forEachAllYaml(CONSOLE) { file, s, yamlObject ->
runWithExceptionHandling(CONSOLE, "Unable to read this placeholder task: $s in ${file.name}") {
val variable = yamlObject.get("variable")?.asString().ifNull("variable not set.")
val placeholder = yamlObject.get("placeholder")?.asString().ifNull("placeholder not set.")
val variable = yamlObject["variable"]?.asString().ifNull("variable not set.")
val placeholder = yamlObject["placeholder"]?.asString().ifNull("placeholder not set.")
val update = yamlObject.getAsInt("update", 1).coerceAtLeast(1)
val async = yamlObject.getAsBoolean("async", false)
updateTask.add(object : PlaceholderTask {
Expand Down
42 changes: 42 additions & 0 deletions changelog/1.10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# BetterHud 1.10

## Notice
- Now support about Oraxen is dropped.
- Now support about Nexo is available.

## Add
- Add 'children' in image.
```yaml
children_full:
type: single
file: "children/full.png" #parent image
setting:
children: #define the children you want use.
- children_half
- children_container
children-mapper: #replace the image to child if this condition is matched.
children_container:
1:
first: health_percentage
second: 0.33
operation: "<"
children_half:
1:
first: health_percentage
second: 0.66
operation: "<"
children_half:
type: single
file: "children/half.png"
children_container:
type: single
file: "children/container.png"
```
```yaml
children_full:
type: single
file: "children/full.png"
setting:
children: * #wild card(*) defines all available image.
follow: "skript_variable:your_value" #If you want to show image depend on some placeholder, set 'follow' section.
```
36 changes: 18 additions & 18 deletions dist/src/main/kotlin/kr/toxicity/hud/compass/type/CircleCompass.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,25 @@ class CircleCompass(
private val scale = section.getAsDouble("scale", 1.0).apply {
if (this <= 0) throw RuntimeException("scale cannot be <= 0")
}
private val scaleEquation = section.get("scale-equation")?.asString()?.let {
private val scaleEquation = section["scale-equation"]?.asString()?.let {
TEquation(it)
} ?: TEquation.one
private val colorEquation = section.get("color-equation")?.asObject()?.let {
private val colorEquation = section["color-equation"]?.asObject()?.let {
ColorEquation(it)
} ?: defaultColorEquation
private val space = section.getAsInt("space", 2).coerceAtLeast(0)

private val pixel = PixelLocation(section.get("pixel")?.asObject().ifNull("pixel value not set.")) + PixelLocation.hotBarHeight
private val pixel = PixelLocation(section["pixel"]?.asObject().ifNull("pixel value not set.")) + PixelLocation.hotBarHeight
private val shader = HudShader(
GuiLocation(section.get("gui")?.asObject().ifNull("gui value not set.")),
GuiLocation(section["gui"]?.asObject().ifNull("gui value not set.")),
RenderScale.fromConfig(pixel, section),
section.getAsInt("layer", 0),
section.getAsBoolean("outline", false),
pixel.opacity,
ShaderProperty.properties(section.get("properties")?.asArray())
ShaderProperty.properties(section["properties"]?.asArray())
)
private var array: JsonArray? = JsonArray()
private val images = CompassImage(assets, section.get("file")?.asObject().ifNull("file value not set."))
private val images = CompassImage(assets, section["file"]?.asObject().ifNull("file value not set."))
private val conditions = section.toConditions().build(UpdateEvent.EMPTY)
private val isDefault = ConfigManagerImpl.defaultCompass.contains(internalName) || section.getAsBoolean("default", false)

Expand Down Expand Up @@ -119,37 +119,37 @@ class CircleCompass(
override fun getName(): String = internalName

private inner class CompassImage(assets: File, section: YamlObject) {
val n = section.get("n")?.asObject()?.let {
val n = section["n"]?.asObject()?.let {
CompassImageMap(assets, "n", it)
}
val e = section.get("e")?.asObject()?.let {
val e = section["e"]?.asObject()?.let {
CompassImageMap(assets, "e", it)
}
val s = section.get("s")?.asObject()?.let {
val s = section["s"]?.asObject()?.let {
CompassImageMap(assets, "s", it)
}
val w = section.get("w")?.asObject()?.let {
val w = section["w"]?.asObject()?.let {
CompassImageMap(assets, "w", it)
}
val nw = section.get("nw")?.asObject()?.let {
val nw = section["nw"]?.asObject()?.let {
CompassImageMap(assets, "nw", it)
}
val ne = section.get("ne")?.asObject()?.let {
val ne = section["ne"]?.asObject()?.let {
CompassImageMap(assets, "ne", it)
}
val sw = section.get("sw")?.asObject()?.let {
val sw = section["sw"]?.asObject()?.let {
CompassImageMap(assets, "sw", it)
}
val se = section.get("se")?.asObject()?.let {
val se = section["se"]?.asObject()?.let {
CompassImageMap(assets, "se", it)
}
val chain = section.get("chain")?.asObject()?.let {
val chain = section["chain"]?.asObject()?.let {
CompassImageMap(assets, "chain", it)
}
val point = section.get("point")?.asObject()?.let {
val point = section["point"]?.asObject()?.let {
CompassImageMap(assets, "point", it)
}
val customIcon = section.get("custom-icon")?.asObject()?.associate {
val customIcon = section["custom-icon"]?.asObject()?.associate {
it.key to CompassImageMap(assets, "custom_icon_${it.key}", it.value.asObject())
} ?: emptyMap()

Expand Down Expand Up @@ -199,7 +199,7 @@ class CircleCompass(
section: YamlObject
) {
val map = run {
val fileName = section.get("name")?.asString().ifNull("name value not set.").replace('/', File.separatorChar)
val fileName = section["name"]?.asString().ifNull("name value not set.").replace('/', File.separatorChar)
val scale = section.getAsDouble("scale", 1.0).apply {
if (this <= 0.0) throw RuntimeException("scale cannot be <= 0.0")
}
Expand Down
4 changes: 2 additions & 2 deletions dist/src/main/kotlin/kr/toxicity/hud/equation/EquationPair.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class EquationPair(val x: TEquation, val y: TEquation) {
fun evaluate(d: Double) = x.evaluate(d) to y.evaluate(d)

constructor(section: YamlObject): this(
section.get("x-equation")?.asString().ifNull("x-equation value not set.").toEquation(),
section.get("y-equation")?.asString().ifNull("y-equation value not set.").toEquation()
section["x-equation"]?.asString().ifNull("x-equation value not set.").toEquation(),
section["y-equation"]?.asString().ifNull("y-equation value not set.").toEquation()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ class EquationPairLocation(

constructor(section: YamlObject): this(
section.getAsInt("duration", 1).coerceAtLeast(1),
section.get("gui")?.asObject()?.let {
section["gui"]?.asObject()?.let {
EquationPair(it)
} ?: EquationPair.zero,
section.get("pixel")?.asObject()?.let {
section["pixel"]?.asObject()?.let {
EquationTriple(it)
} ?: EquationTriple.zero
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class EquationTriple(val x: TEquation, val y: TEquation, val opacity: TEquation)
fun evaluate(d: Double) = Triple(x.evaluate(d), y.evaluate(d), opacity.evaluate(d))

constructor(section: YamlObject): this(
section.get("x-equation")?.asString().ifNull("x-equation value not set.").toEquation(),
section.get("y-equation")?.asString().ifNull("y-equation value not set.").toEquation(),
section.get("opacity-equation")?.asString()?.toEquation() ?: TEquation.one
section["x-equation"]?.asString().ifNull("x-equation value not set.").toEquation(),
section["y-equation"]?.asString().ifNull("y-equation value not set.").toEquation(),
section["opacity-equation"]?.asString()?.toEquation() ?: TEquation.one
)
}
2 changes: 1 addition & 1 deletion dist/src/main/kotlin/kr/toxicity/hud/hud/HudHeadElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class HudHeadElement(parent: HudImpl, private val head: HeadLayout, gui: GuiLoca
head.type,
head.follow,
head.cancelIfFollowerNotExists,
head.conditions.and(head.head.conditions)
head.conditions and head.head.conditions
).getHead(UpdateEvent.EMPTY)
}

Expand Down
101 changes: 53 additions & 48 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudImageElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import kr.toxicity.hud.api.component.PixelComponent
import kr.toxicity.hud.api.component.WidthComponent
import kr.toxicity.hud.api.player.HudPlayer
import kr.toxicity.hud.api.update.UpdateEvent
import kr.toxicity.hud.image.HudImage
import kr.toxicity.hud.image.ImageComponent
import kr.toxicity.hud.location.PixelLocation
import kr.toxicity.hud.layout.ImageLayout
import kr.toxicity.hud.manager.ImageManager
Expand All @@ -15,68 +17,71 @@ import kr.toxicity.hud.util.*
import net.kyori.adventure.text.Component
import kotlin.math.roundToInt

class HudImageElement(parent: HudImpl, private val image: ImageLayout, gui: GuiLocation, pixel: PixelLocation) {
class HudImageElement(parent: HudImpl, private val imageLayout: ImageLayout, gui: GuiLocation, pixel: PixelLocation) {

private val chars = run {
val hud = image.image
val finalPixel = image.location + pixel
val hud = imageLayout.image
val finalPixel = imageLayout.location + pixel

val shader = HudShader(
gui,
image.renderScale,
image.layer,
image.outline,
imageLayout.renderScale,
imageLayout.layer,
imageLayout.outline,
finalPixel.opacity,
image.property
imageLayout.property
)

val list = ArrayList<PixelComponent>()
if (hud.listener != null) {
list.add(EMPTY_PIXEL_COMPONENT)
}
val negativeSpace = parent.getOrCreateSpace(-1)
hud.image.forEach { pair ->
val fileName = "$NAME_SPACE_ENCODED:${pair.name}"
val height = (pair.image.image.height.toDouble() * image.scale).roundToInt()
val scale = height.toDouble() / pair.image.image.height
val ascent = finalPixel.y.coerceAtLeast(-HudImpl.ADD_HEIGHT).coerceAtMost(HudImpl.ADD_HEIGHT)
val shaderGroup = ShaderGroup(shader, fileName, image.scale, ascent)
fun HudImage.toComponent(): ImageComponent {
val list = ArrayList<PixelComponent>()
if (hud.listener != null) {
list.add(EMPTY_PIXEL_COMPONENT)
}
image.forEach { pair ->
val fileName = "$NAME_SPACE_ENCODED:${pair.name}"
val height = (pair.image.image.height.toDouble() * imageLayout.scale).roundToInt()
val scale = height.toDouble() / pair.image.image.height
val ascent = finalPixel.y.coerceAtLeast(-HudImpl.ADD_HEIGHT).coerceAtMost(HudImpl.ADD_HEIGHT)
val shaderGroup = ShaderGroup(shader, fileName, imageLayout.scale, ascent)

val component = ImageManager.getImage(shaderGroup) ?: run {
val c = (++parent.imageChar).parseChar()
val comp = Component.text()
.font(parent.imageKey)
val finalWidth = WidthComponent(
if (BOOTSTRAP.useLegacyFont()) comp.content(c).append(NEGATIVE_ONE_SPACE_COMPONENT.component) else comp.content("$c$negativeSpace"),
(pair.image.image.width.toDouble() * scale).roundToInt()
)
parent.jsonArray?.let { array ->
HudImpl.createBit(shader, ascent) { y ->
array.add(jsonObjectOf(
"type" to "bitmap",
"file" to fileName,
"ascent" to y,
"height" to height,
"chars" to jsonArrayOf(c)
))
val component = ImageManager.getImage(shaderGroup) ?: run {
val c = (++parent.imageChar).parseChar()
val comp = Component.text()
.font(parent.imageKey)
val finalWidth = WidthComponent(
if (BOOTSTRAP.useLegacyFont()) comp.content(c).append(NEGATIVE_ONE_SPACE_COMPONENT.component) else comp.content("$c$negativeSpace"),
(pair.image.image.width.toDouble() * scale).roundToInt()
)
parent.jsonArray?.let { array ->
HudImpl.createBit(shader, ascent) { y ->
array.add(jsonObjectOf(
"type" to "bitmap",
"file" to fileName,
"ascent" to y,
"height" to height,
"chars" to jsonArrayOf(c)
))
}
}
ImageManager.setImage(shaderGroup, finalWidth)
finalWidth
}
ImageManager.setImage(shaderGroup, finalWidth)
finalWidth
}

list.add(component.toPixelComponent(finalPixel.x + (pair.image.xOffset * scale).roundToInt()))
list.add(component.toPixelComponent(finalPixel.x + (pair.image.xOffset * scale).roundToInt()))
}
return ImageComponent(this, list, children.entries.associate {
it.key to it.value.toComponent()
})
}
val renderer = ImageRenderer(
hud,
image.color,
image.space,
image.stack,
image.maxStack,
list,
image.follow,
image.cancelIfFollowerNotExists,
image.conditions.and(image.image.conditions)
imageLayout.color,
imageLayout.space,
imageLayout.stack,
imageLayout.maxStack,
imageLayout.image.toComponent(),
imageLayout.follow,
imageLayout.cancelIfFollowerNotExists,
imageLayout.conditions and imageLayout.image.conditions
)
renderer.max() to renderer.getComponent(UpdateEvent.EMPTY)
}
Expand Down
8 changes: 4 additions & 4 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ class HudImpl(
(++imageChar).parseChar()
}

private val elements = section.get("layouts")?.asObject().ifNull("layout configuration not set.").mapSubConfiguration { s, yamlObject ->
val layout = yamlObject.get("name")?.asString().ifNull("name value not set: $s").let {
private val elements = section["layouts"]?.asObject().ifNull("layout configuration not set.").mapSubConfiguration { s, yamlObject ->
val layout = yamlObject["name"]?.asString().ifNull("name value not set: $s").let {
LayoutManager.getLayout(it).ifNull("this layout doesn't exist: $it")
}
var gui = GuiLocation(yamlObject)
yamlObject.get("gui")?.asObject()?.let {
yamlObject["gui"]?.asObject()?.let {
gui += GuiLocation(it)
}
val pixel = yamlObject.get("pixel")?.asObject()?.let {
val pixel = yamlObject["pixel"]?.asObject()?.let {
PixelLocation(it)
} ?: PixelLocation.zero
HudAnimation(
Expand Down
31 changes: 30 additions & 1 deletion dist/src/main/kotlin/kr/toxicity/hud/image/HudImage.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package kr.toxicity.hud.image

import kr.toxicity.hud.api.yaml.YamlArray
import kr.toxicity.hud.api.yaml.YamlElement
import kr.toxicity.hud.api.yaml.YamlObject
import kr.toxicity.hud.configuration.HudConfiguration
import kr.toxicity.hud.image.enums.ImageType
import kr.toxicity.hud.manager.ImageManager
import kr.toxicity.hud.manager.ListenerManagerImpl
import kr.toxicity.hud.manager.PlaceholderManagerImpl
import kr.toxicity.hud.placeholder.Conditions
import kr.toxicity.hud.util.ifNull
import kr.toxicity.hud.util.toConditions

class HudImage(
Expand All @@ -14,7 +20,30 @@ class HudImage(
setting: YamlObject
) : HudConfiguration {
val conditions = setting.toConditions()
val listener = setting.get("listener")?.asObject()?.let {
val listener = setting["listener"]?.asObject()?.let {
ListenerManagerImpl.getListener(it)
}
val children by lazy {
fun Iterable<YamlElement>.asMap() = associate {
val str = it.asString()
if (str == name) throw RuntimeException("circular image reference: $name")
str to ImageManager.getImage(str).ifNull("This children image doesn't exist in $name: $str")
}
when (val child = setting["children"]) {
is YamlArray -> child.asMap()
is YamlElement -> if (child.asString() == "*") ImageManager.allImage.associateBy {
it.name
} else listOf(child).asMap()
null -> emptyMap<String, HudImage>()
else -> throw RuntimeException("Unsupported children section: $name")
}
}
val follow = setting["follow"]?.asString()?.let {
PlaceholderManagerImpl.find(it).apply {
if (!java.lang.String::class.java.isAssignableFrom(clazz)) throw RuntimeException("This placeholder is not a string in image $name: $it")
}
}
val childrenMapper = setting["children-mapper"]?.asObject()?.map {
it.key to Conditions.parse(it.value.asObject())
}
}
Loading

0 comments on commit 4d12e6d

Please sign in to comment.