Skip to content

Commit

Permalink
Add player's head display.
Browse files Browse the repository at this point in the history
  • Loading branch information
toxicity188 committed Mar 17, 2024
1 parent dc87025 commit da0ce28
Show file tree
Hide file tree
Showing 17 changed files with 322 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Set;

public interface HudPlayer {
@NotNull HudPlayerHead getHead();
@NotNull Player getBukkitPlayer();
@NotNull WidthComponent getHudComponent();
void setAdditionalComponent(@Nullable WidthComponent component);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
package kr.toxicity.hud.api.player;

import net.kyori.adventure.text.format.TextColor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;

import java.util.List;

public interface HudPlayerHead {
@NotNull @Unmodifiable List<TextColor> getColors();
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ allprojects {
apply(plugin = "kotlin")

group = "kr.toxicity.hud"
version = "beta-4.2"
version = "beta-4.3"

repositories {
mavenCentral()
Expand Down
18 changes: 13 additions & 5 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@ package kr.toxicity.hud.hud
import kr.toxicity.hud.api.player.HudPlayer
import kr.toxicity.hud.api.update.UpdateEvent
import kr.toxicity.hud.component.LayoutComponentContainer
import kr.toxicity.hud.image.ImageLocation
import kr.toxicity.hud.layout.LayoutGroup
import kr.toxicity.hud.shader.GuiLocation
import kr.toxicity.hud.util.EMPTY_WIDTH_COMPONENT
import kr.toxicity.hud.util.subFolder
import java.io.File

class HudElement(hud: HudImpl, name: String, file: File, private val layout: LayoutGroup, x: Double, y: Double) {
class HudElement(hud: HudImpl, name: String, file: File, private val layout: LayoutGroup, gui: GuiLocation, pixel: ImageLocation) {
private val imageElement = layout.image.map {image ->
HudImageElement(hud, image, x, y, layout.animation)
HudImageElement(hud, image, gui, pixel)
}
private val textElement = run {
val subFile = file.subFolder("text")
layout.text.mapIndexed { index, textLayout ->
HudTextElement(hud, name, subFile, textLayout, index, x, y, layout.animation)
HudTextElement(hud, name, subFile, textLayout, index, gui, pixel)
}
}
private val headElement = layout.head.map {image ->
HudHeadElement(hud, image, gui, pixel)
}

val conditions = layout.conditions.build(UpdateEvent.EMPTY)

private val max = imageElement.maxOf {
private val max = imageElement.maxOfOrNull {
it.max
}
} ?: 0

fun getComponent(player: HudPlayer) = if (conditions(player)) LayoutComponentContainer(layout.align, max)
.append(imageElement.map {
Expand All @@ -32,5 +37,8 @@ class HudElement(hud: HudImpl, name: String, file: File, private val layout: Lay
.append(textElement.map {
it.getText(player)
})
.append(headElement.map {
it.getHead(player)
})
.build() else EMPTY_WIDTH_COMPONENT
}
45 changes: 45 additions & 0 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudHeadElement.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package kr.toxicity.hud.hud

import com.google.gson.JsonArray
import com.google.gson.JsonObject
import kr.toxicity.hud.api.player.HudPlayer
import kr.toxicity.hud.api.update.UpdateEvent
import kr.toxicity.hud.image.ImageLocation
import kr.toxicity.hud.layout.HeadLayout
import kr.toxicity.hud.renderer.HeadRenderer
import kr.toxicity.hud.shader.GuiLocation
import kr.toxicity.hud.shader.HudShader
import kr.toxicity.hud.util.NAME_SPACE
import kr.toxicity.hud.util.parseChar
import net.kyori.adventure.text.Component

class HudHeadElement(parent: HudImpl, private val head: HeadLayout, gui: GuiLocation, pixel: ImageLocation) {
private val renderer = run {
val final = head.location + pixel
val shader = HudShader(
gui,
head.layer,
head.outline
)
HeadRenderer(
(0..7).map { i ->
val char = (++parent.imageChar).parseChar()
parent.jsonArray.add(JsonObject().apply {
addProperty("type", "bitmap")
addProperty("file", "$NAME_SPACE:head/pixel_${head.head.pixel}.png")
addProperty("ascent", HudImpl.createBit(final.y - (7 - i) * head.head.pixel, shader))
addProperty("height", head.head.pixel)
add("chars", JsonArray().apply {
add(char)
})
})
Component.text(char).font(parent.imageKey)
},
head.head.pixel,
final.x,
head.conditions.and(head.head.conditions)
)
}

fun getHead(player: HudPlayer) = renderer.getHead(UpdateEvent.EMPTY)(player)
}
62 changes: 29 additions & 33 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudImageElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,56 +16,52 @@ import kr.toxicity.hud.util.*
import net.kyori.adventure.text.Component
import kotlin.math.round

class HudImageElement(parent: HudImpl, private val image: ImageLayout, x: Double, y: Double, animation: List<ImageLocation>) {
class HudImageElement(parent: HudImpl, private val image: ImageLayout, gui: GuiLocation, pixel: ImageLocation) {


private val chars = run {
val hud = image.image
val isSingle = hud.image.size == 1

val shader = HudShader(
GuiLocation(x, y),
gui,
image.layer,
image.outline
)

val list = ArrayList<PixelComponent>()
if (hud is ListenerHudImage) {
list.add(EMPTY_PIXEL_COMPONENT)
}
val finalPixel = image.location + pixel
hud.image.forEach { pair ->

animation.map { imageLocation ->
val list = ArrayList<PixelComponent>()
if (hud is ListenerHudImage) {
list.add(EMPTY_PIXEL_COMPONENT)
}
hud.image.forEach { pair ->
val c = (++parent.imageChar).parseChar()
val height = round(pair.image.image.height.toDouble() * image.scale).toInt()
val scale = height.toDouble() / pair.image.image.height
val finalWidth = WidthComponent(Component.text(c).font(parent.imageKey), round((pair.image.image.width).toDouble() * scale).toInt()) + NEGATIVE_ONE_SPACE_COMPONENT + NEW_LAYER
parent.jsonArray.add(JsonObject().apply {
addProperty("type", "bitmap")
if (isSingle) addProperty("file", "$NAME_SPACE:image/${pair.name}")
else addProperty("file", "$NAME_SPACE:image/${hud.name}/${pair.name}")
addProperty("ascent", HudImpl.createBit((image.location.y + imageLocation.y).coerceAtLeast(-HudImpl.ADD_HEIGHT).coerceAtMost(HudImpl.ADD_HEIGHT), shader))
addProperty("height", height)
add("chars", JsonArray().apply {
add(c)
})
val c = (++parent.imageChar).parseChar()
val height = round(pair.image.image.height.toDouble() * image.scale).toInt()
val scale = height.toDouble() / pair.image.image.height
val finalWidth = WidthComponent(Component.text(c).font(parent.imageKey), round((pair.image.image.width).toDouble() * scale).toInt()) + NEGATIVE_ONE_SPACE_COMPONENT + NEW_LAYER
parent.jsonArray.add(JsonObject().apply {
addProperty("type", "bitmap")
if (isSingle) addProperty("file", "$NAME_SPACE:image/${pair.name}")
else addProperty("file", "$NAME_SPACE:image/${hud.name}/${pair.name}")
addProperty("ascent", HudImpl.createBit((finalPixel.y).coerceAtLeast(-HudImpl.ADD_HEIGHT).coerceAtMost(HudImpl.ADD_HEIGHT), shader))
addProperty("height", height)
add("chars", JsonArray().apply {
add(c)
})
list.add(finalWidth.toPixelComponent(image.location.x + imageLocation.x + round(pair.image.xOffset * scale).toInt()))
}
ImageRenderer(
hud,
list,
image.conditions.and(image.image.conditions)
)
})
list.add(finalWidth.toPixelComponent(finalPixel.x + round(pair.image.xOffset * scale).toInt()))
}

ImageRenderer(
hud,
list,
image.conditions.and(image.image.conditions)
)
}

val max = chars.maxOf {
it.max()
}
val max = chars.max()

fun getComponent(player: HudPlayer): PixelComponent = chars[(player.tick % chars.size).toInt()].getComponent(
fun getComponent(player: HudPlayer): PixelComponent = chars.getComponent(
UpdateEvent.EMPTY)(player)

}
30 changes: 18 additions & 12 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import kr.toxicity.hud.api.component.WidthComponent
import kr.toxicity.hud.api.hud.Hud
import kr.toxicity.hud.api.player.HudPlayer
import kr.toxicity.hud.api.update.UpdateEvent
import kr.toxicity.hud.image.ImageLocation
import kr.toxicity.hud.manager.ConfigManager
import kr.toxicity.hud.manager.LayoutManager
import kr.toxicity.hud.manager.ShaderManager
import kr.toxicity.hud.shader.GuiLocation
import kr.toxicity.hud.shader.HudShader
import kr.toxicity.hud.util.*
import net.kyori.adventure.key.Key
Expand All @@ -34,18 +36,22 @@ class HudImpl(private val internalName: String, file: File, section: Configurati

private val elements = run {
val subFile = file.subFolder(internalName)
ArrayList<HudElement>().apply {
ArrayList<List<HudElement>>().apply {
section.getConfigurationSection("layouts").ifNull("layout configuration not set.").forEachSubConfiguration { s, configurationSection ->
add(HudElement(
this@HudImpl,
internalName,
subFile,
configurationSection.getString("name").ifNull("name value not set: $s").let {
LayoutManager.getLayout(it).ifNull("this layout doesn't exist: $it")
},
configurationSection.getDouble("x").coerceAtLeast(0.0).coerceAtMost(100.0),
configurationSection.getDouble("y").coerceAtLeast(0.0).coerceAtMost(100.0)
))
val layout = configurationSection.getString("name").ifNull("name value not set: $s").let {
LayoutManager.getLayout(it).ifNull("this layout doesn't exist: $it")
}
val gui = GuiLocation(configurationSection)
add(layout.animation.map {
HudElement(
this@HudImpl,
internalName,
subFile,
layout,
gui,
ImageLocation(it.x, it.y)
)
})
}
}.ifEmpty {
throw RuntimeException("layout is empty.")
Expand All @@ -63,7 +69,7 @@ class HudImpl(private val internalName: String, file: File, section: Configurati
override fun getComponents(player: HudPlayer): List<WidthComponent> {
if (!conditions(player)) return emptyList()
return elements.map {
it.getComponent(player)
it[(player.tick % it.size).toInt()].getComponent(player)
}
}

Expand Down
85 changes: 42 additions & 43 deletions dist/src/main/kotlin/kr/toxicity/hud/hud/HudTextElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,59 +18,58 @@ import net.kyori.adventure.text.format.Style
import java.io.File
import kotlin.math.ceil

class HudTextElement(parent: HudImpl, name: String, file: File, private val text: TextLayout, index: Int, x: Double, y: Double, animation: List<ImageLocation>) {
class HudTextElement(parent: HudImpl, name: String, file: File, private val text: TextLayout, index: Int, gui: GuiLocation, pixel: ImageLocation) {

private val renderer = run {
val shader = HudShader(
GuiLocation(x, y),
gui,
text.layer,
text.outline
)
animation.map { imageLocation ->
val yAxis = (text.location.y + imageLocation.y).coerceAtLeast(-HudImpl.ADD_HEIGHT).coerceAtMost(HudImpl.ADD_HEIGHT)
val group = ShaderGroup(shader, text.text.name, yAxis)
val scale = ceil(text.text.height * text.scale).toInt()
val key = TextManager.getKey(group) ?: run {
val index2 = (++parent.textIndex)
val key = Key.key("$NAME_SPACE:hud/$name/text/text_${index + 1}_${index2 + 1}")
val array = JsonArray().apply {
add(JsonObject().apply {
addProperty("type", "space")
add("advances", JsonObject().apply {
addProperty(" ", 4)
})
val loc = text.location + pixel
val yAxis = (loc.y).coerceAtLeast(-HudImpl.ADD_HEIGHT).coerceAtMost(HudImpl.ADD_HEIGHT)
val group = ShaderGroup(shader, text.text.name, yAxis)
val scale = ceil(text.text.height * text.scale).toInt()
val key = TextManager.getKey(group) ?: run {
val index2 = (++parent.textIndex)
val key = Key.key("$NAME_SPACE:hud/$name/text/text_${index + 1}_${index2 + 1}")
val array = JsonArray().apply {
add(JsonObject().apply {
addProperty("type", "space")
add("advances", JsonObject().apply {
addProperty(" ", 4)
})
}
text.text.array.forEach {
array.add(JsonObject().apply {
addProperty("type", "bitmap")
addProperty("file", "$NAME_SPACE:text/${text.text.fontName}/${it.file}")
addProperty("ascent", HudImpl.createBit(yAxis, shader))
addProperty("height", scale)
add("chars", it.chars)
})
}
JsonObject().apply {
add("providers", array)
}.save(File(file, "text_${index + 1}_${index2 + 1}.json"))
TextManager.setKey(group, key)
key
})
}
text.text.array.forEach {
array.add(JsonObject().apply {
addProperty("type", "bitmap")
addProperty("file", "$NAME_SPACE:text/${text.text.fontName}/${it.file}")
addProperty("ascent", HudImpl.createBit(yAxis, shader))
addProperty("height", scale)
add("chars", it.chars)
})
}
TextRenderer(
text.text.charWidth,
Style.style(text.color).font(key),
text.pattern,
text.align,
scale.toDouble() / text.text.height,
text.location.x + imageLocation.x,
text.space,
text.numberEquation,
text.numberFormat,
text.conditions.and(text.text.conditions)
)
JsonObject().apply {
add("providers", array)
}.save(File(file, "text_${index + 1}_${index2 + 1}.json"))
TextManager.setKey(group, key)
key
}
TextRenderer(
text.text.charWidth,
Style.style(text.color).font(key),
text.pattern,
text.align,
scale.toDouble() / text.text.height,
loc.x,
text.space,
text.numberEquation,
text.numberFormat,
text.conditions.and(text.text.conditions)
)
}

fun getText(player: HudPlayer): PixelComponent = renderer[(player.tick % renderer.size).toInt()].getText(
fun getText(player: HudPlayer): PixelComponent = renderer.getText(
UpdateEvent.EMPTY)(player)
}
13 changes: 13 additions & 0 deletions dist/src/main/kotlin/kr/toxicity/hud/layout/HeadLayout.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package kr.toxicity.hud.layout

import kr.toxicity.hud.image.ImageLocation
import kr.toxicity.hud.placeholder.ConditionBuilder
import kr.toxicity.hud.player.HudHead

class HeadLayout(
val head: HudHead,
val location: ImageLocation,
val outline: Boolean,
val layer: Int,
val conditions: ConditionBuilder
)
Loading

0 comments on commit da0ce28

Please sign in to comment.