aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/misc/CustomCapes.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/features/misc/CustomCapes.kt')
-rw-r--r--src/main/kotlin/features/misc/CustomCapes.kt172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/main/kotlin/features/misc/CustomCapes.kt b/src/main/kotlin/features/misc/CustomCapes.kt
new file mode 100644
index 0000000..fe54e6b
--- /dev/null
+++ b/src/main/kotlin/features/misc/CustomCapes.kt
@@ -0,0 +1,172 @@
+package moe.nea.firmament.features.misc
+
+import util.render.CustomRenderPipelines
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.seconds
+import net.minecraft.client.player.AbstractClientPlayer
+import net.minecraft.client.renderer.RenderType
+import com.mojang.blaze3d.vertex.VertexConsumer
+import net.minecraft.client.renderer.MultiBufferSource
+import net.minecraft.client.renderer.entity.state.AvatarRenderState
+import com.mojang.blaze3d.vertex.PoseStack
+import net.minecraft.world.entity.player.PlayerSkin
+import net.minecraft.core.ClientAsset
+import net.minecraft.resources.ResourceLocation
+import moe.nea.firmament.Firmament
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.TimeMark
+import moe.nea.firmament.util.data.Config
+import moe.nea.firmament.util.data.ManagedConfig
+import moe.nea.firmament.util.mc.CustomRenderPassHelper
+
+object CustomCapes {
+ val identifier: String
+ get() = "developer-capes"
+
+ @Config
+ object TConfig : ManagedConfig(identifier, Category.DEV) {
+ val showCapes by toggle("show-cape") { true }
+ }
+
+ interface CustomCapeRenderer {
+ fun replaceRender(
+ renderLayer: RenderType,
+ vertexConsumerProvider: MultiBufferSource,
+ matrixStack: PoseStack,
+ model: (VertexConsumer) -> Unit
+ )
+ }
+
+ data class TexturedCapeRenderer(
+ val location: ResourceLocation
+ ) : CustomCapeRenderer {
+ override fun replaceRender(
+ renderLayer: RenderType,
+ vertexConsumerProvider: MultiBufferSource,
+ matrixStack: PoseStack,
+ model: (VertexConsumer) -> Unit
+ ) {
+ model(vertexConsumerProvider.getBuffer(RenderType.entitySolid(location)))
+ }
+ }
+
+ data class ParallaxedHighlightCapeRenderer(
+ val template: ResourceLocation,
+ val background: ResourceLocation,
+ val overlay: ResourceLocation,
+ val animationSpeed: Duration,
+ ) : CustomCapeRenderer {
+ override fun replaceRender(
+ renderLayer: RenderType,
+ vertexConsumerProvider: MultiBufferSource,
+ matrixStack: PoseStack,
+ model: (VertexConsumer) -> Unit
+ ) {
+ val animationValue = (startTime.passedTime() / animationSpeed).mod(1F)
+ CustomRenderPassHelper(
+ { "Firmament Cape Renderer" },
+ renderLayer.mode(),
+ renderLayer.format(),
+ MC.instance.mainRenderTarget,
+ true,
+ ).use { renderPass ->
+ renderPass.setPipeline(CustomRenderPipelines.PARALLAX_CAPE_SHADER)
+ renderPass.setAllDefaultUniforms()
+ renderPass.setUniform("Animation", 4) {
+ it.putFloat(animationValue.toFloat())
+ }
+ renderPass.bindSampler("Sampler0", template)
+ renderPass.bindSampler("Sampler1", background)
+ renderPass.bindSampler("Sampler3", overlay)
+ renderPass.uploadVertices(2048, model)
+ renderPass.draw()
+ }
+ }
+ }
+
+ interface CapeStorage {
+ companion object {
+ @JvmStatic
+ fun cast(playerEntityRenderState: AvatarRenderState) =
+ playerEntityRenderState as CapeStorage
+
+ }
+
+ var cape_firmament: CustomCape?
+ }
+
+ data class CustomCape(
+ val id: String,
+ val label: String,
+ val render: CustomCapeRenderer,
+ )
+
+ enum class AllCapes(val label: String, val render: CustomCapeRenderer) {
+ FIRMAMENT_ANIMATED(
+ "Animated Firmament", ParallaxedHighlightCapeRenderer(
+ Firmament.identifier("textures/cape/parallax_template.png"),
+ Firmament.identifier("textures/cape/parallax_background.png"),
+ Firmament.identifier("textures/cape/firmament_star.png"),
+ 110.seconds
+ )
+ ),
+ UNPLEASANT_GRADIENT(
+ "unpleasant_gradient",
+ TexturedCapeRenderer(Firmament.identifier("textures/cape/unpleasant_gradient.png"))
+ ),
+ FURFSKY_STATIC(
+ "FurfSky",
+ TexturedCapeRenderer(Firmament.identifier("textures/cape/fsr_static.png"))
+ ),
+
+ FIRMAMENT_STATIC(
+ "Firmament",
+ TexturedCapeRenderer(Firmament.identifier("textures/cape/firm_static.png"))
+ ),
+ HYPIXEL_PLUS(
+ "Hypixel+",
+ TexturedCapeRenderer(Firmament.identifier("textures/cape/h_plus.png"))
+ ),
+ ;
+
+ val cape = CustomCape(name, label, render)
+ }
+
+ val byId = AllCapes.entries.associateBy { it.cape.id }
+ val byUuid =
+ listOf(
+ listOf(
+ Devs.nea to AllCapes.UNPLEASANT_GRADIENT,
+ Devs.kath to AllCapes.FIRMAMENT_STATIC,
+ Devs.jani to AllCapes.FIRMAMENT_ANIMATED,
+ Devs.nat to AllCapes.FIRMAMENT_ANIMATED,
+ Devs.HPlus.ic22487 to AllCapes.HYPIXEL_PLUS,
+ ),
+ Devs.FurfSky.all.map { it to AllCapes.FURFSKY_STATIC },
+ ).flatten().flatMap { (dev, cape) -> dev.uuids.map { it to cape.cape } }.toMap()
+
+ @JvmStatic
+ fun addCapeData(
+ player: AbstractClientPlayer,
+ playerEntityRenderState: AvatarRenderState
+ ) {
+ if (true) return // TODO: see capefeaturerenderer mixin
+ val cape = if (TConfig.showCapes) byUuid[player.uuid] else null
+ val capeStorage = CapeStorage.cast(playerEntityRenderState)
+ if (cape == null) {
+ capeStorage.cape_firmament = null
+ } else {
+ capeStorage.cape_firmament = cape
+ playerEntityRenderState.skin = PlayerSkin(
+ playerEntityRenderState.skin.body,
+ ClientAsset.ResourceTexture(Firmament.identifier("placeholder/fake_cape"), Firmament.identifier("placeholder/fake_cape")),
+ playerEntityRenderState.skin.elytra,
+ playerEntityRenderState.skin.model,
+ playerEntityRenderState.skin.secure,
+ )
+ playerEntityRenderState.showCape = true
+ }
+ }
+
+ val startTime = TimeMark.now()
+}