Skip to content

Commit

Permalink
Version 1.3.2.6
Browse files Browse the repository at this point in the history
  • Loading branch information
EssentialGGBot committed Jun 13, 2024
1 parent 3cb8800 commit 219f348
Show file tree
Hide file tree
Showing 206 changed files with 3,022 additions and 1,415 deletions.
14 changes: 7 additions & 7 deletions api/api/api.api
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,13 @@ public abstract interface class gg/essential/api/utils/GuiUtil {
public abstract fun openScreen (Lnet/minecraft/client/gui/screens/Screen;)V
@1.17.1-forge,1.18.2-forge,1.19.2-forge,1.19.3-forge,1.19.4-forge,1.20.1-forge,1.20.2-forge,1.20.4-forge
public abstract fun openedScreen ()Lnet/minecraft/client/gui/screens/Screen;
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public static fun getOpenedScreen ()Lnet/minecraft/client/gui/screen/Screen;
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public static fun open (Lnet/minecraft/client/gui/screen/Screen;)V
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public abstract fun openScreen (Lnet/minecraft/client/gui/screen/Screen;)V
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public abstract fun openedScreen ()Lnet/minecraft/client/gui/screen/Screen;
@1.12.2-forge,1.8.9-forge
public static fun getOpenedScreen ()Lnet/minecraft/client/gui/GuiScreen;
Expand All @@ -446,9 +446,9 @@ public final class gg/essential/api/utils/GuiUtil$Companion {
public final fun getOpenedScreen ()Lnet/minecraft/client/gui/screens/Screen;
@1.17.1-forge,1.18.2-forge,1.19.2-forge,1.19.3-forge,1.19.4-forge,1.20.1-forge,1.20.2-forge,1.20.4-forge
public final fun open (Lnet/minecraft/client/gui/screens/Screen;)V
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public final fun getOpenedScreen ()Lnet/minecraft/client/gui/screen/Screen;
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.16.2-forge,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public final fun open (Lnet/minecraft/client/gui/screen/Screen;)V
@1.12.2-forge,1.8.9-forge
public final fun getOpenedScreen ()Lnet/minecraft/client/gui/GuiScreen;
Expand Down Expand Up @@ -512,7 +512,7 @@ public final class gg/essential/api/utils/KotlinAdapter : net/minecraftforge/fml
public abstract interface class gg/essential/api/utils/MinecraftUtils {
@1.17.1-forge,1.18.2-forge,1.19.2-forge,1.19.3-forge,1.19.4-forge,1.20.1-forge,1.20.2-forge,1.20.4-forge
public abstract fun getResourceImage (Lnet/minecraft/resources/ResourceLocation;)Ljava/awt/image/BufferedImage;
@1.16.2-fabric,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric
@1.16.2-fabric,1.17.1-fabric,1.18.1-fabric,1.18.2-fabric,1.19-fabric,1.19.2-fabric,1.19.3-fabric,1.19.4-fabric,1.20-fabric,1.20.1-fabric,1.20.2-fabric,1.20.4-fabric,1.20.6-fabric,1.21-fabric
public abstract fun getResourceImage (Lnet/minecraft/util/Identifier;)Ljava/awt/image/BufferedImage;
@1.12.2-forge,1.16.2-forge,1.8.9-forge
public abstract fun getResourceImage (Lnet/minecraft/util/ResourceLocation;)Ljava/awt/image/BufferedImage;
Expand Down
2 changes: 1 addition & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dependencies {

// Core Gui Libraries
val ucMcVersion = when (platform.mcVersion) {
11900, 11902, 11903, 11904, 12000, 12001, 12002, 12004, 12006 -> mcVersionStr.also {
11900, 11902, 11903, 11904, 12000, 12001, 12002, 12004, 12006, 12100 -> mcVersionStr.also {
// Elementa and Vigilance 1.18.1 are good enough for MC 1.19 so we only update UC.
// We do need to exclude the tranitive 1.18 UC though.
configurations.modApi.configure { exclude("gg.essential", "universalcraft-1.18.1-${platform.loaderStr}") }
Expand Down
2 changes: 2 additions & 0 deletions build-logic/src/main/kotlin/essential/preprocessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import java.io.File

fun Project.configurePreprocessTree(versions: File) {
configure<RootPreprocessExtension> {
val fabric12100 = createNode("1.21-fabric", 12100, "yarn")
val fabric12006 = createNode("1.20.6-fabric", 12006, "yarn")
val forge12004 = createNode("1.20.4-forge", 12004, "srg")
val fabric12004 = createNode("1.20.4-fabric", 12004, "yarn")
Expand All @@ -43,6 +44,7 @@ fun Project.configurePreprocessTree(versions: File) {
val forge11202 = createNode("1.12.2-forge", 11202, "srg")
val forge10809 = createNode("1.8.9-forge", 10809, "srg")

fabric12100.link(fabric12006)
fabric12006.link(fabric12004)
forge12004.link(fabric12004)
fabric12004.link(fabric12002, versions.resolve("1.20.4-1.20.2.txt"))
Expand Down
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ dependencies {
if (platform.isFabric && platform.mcVersion >= 12006) {
val fapiVersion = when (platform.mcVersion) {
12006 -> "0.97.8+1.20.6"
12100 -> "0.99.2+1.21"
else -> error("No fabric API version configured!")
}
include(modImplementation(fabricApi.module("fabric-api-base", fapiVersion))!!)
Expand Down
19 changes: 19 additions & 0 deletions changelog/release-1.3.2.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Title: Bug Patch
Summary: Minor bug fixes

## New Versions
- Added support for 1.21 Fabric

## Wardrobe
- Removed "You need..." coin pack option

## UI
- Improved Settings menu design

## Bug Fixes
- Fixed messages not being marked as un-read in certain situations
- Fixed final kick shockwave effect of "Tornado Kick" emote being invisible when viewed from behind
- Fixed armor/cape/elytra/etc. being invisible when behind translucent cosmetics
- Fixed the "Pictures" text being misaligned in the Social Menu
- Fixed skin sometimes changing unexpectedly when switching between accounts
- Fixed incompatibility with MixinBooter 8.9+ and some other mods on 1.12.2 (the fix in Essential 1.3.2.5 was ineffective)
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ import gg.essential.model.util.now
import gg.essential.network.cosmetics.Cosmetic

object CapeModel {
val GEOMETRY_ID = "__internal_cape_model__"

private val capeModelJson =
"""
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.cape",
"identifier": "$GEOMETRY_ID",
"texture_width": 64,
"texture_height": 32,
"visible_bounds_width": 3,
Expand All @@ -40,10 +42,28 @@ object CapeModel {
{
"name": "cape",
"parent": "root",
"pivot": [0, 24, 2.5],
"pivot": [0, 24, 2],
"rotation": [-6, 180, 0],
"cubes": [
{"origin": [-5, 8, 2], "size": [10, 16, 1], "uv": [0, 0]}
{"origin": [-5, 8, 1], "size": [10, 16, 1], "uv": [0, 0]}
]
},
{
"name": "left_wing",
"parent": "root",
"pivot": [0, 24, 2],
"rotation": [-15, 0, -15],
"cubes": [
{"origin": [-5, 4, 2], "size": [10, 20, 2], "uv": [22, 0], "inflate": 1}
]
},
{
"name": "right_wing",
"parent": "root",
"pivot": [0, 24, 2],
"rotation": [-15, 0, 15],
"cubes": [
{"origin": [-5, 4, 2], "size": [10, 20, 2], "uv": [22, 0], "mirror": true, "inflate": 1}
]
}
]
Expand Down Expand Up @@ -74,15 +94,18 @@ object CapeModel {
0,
)

private val dummyTexture = object : RenderBackend.Texture {
private fun dummyTexture(height: Int) = object : RenderBackend.Texture {
override val width: Int
get() = 64
override val height: Int
get() = 32
get() = height
}

val capeModel = BedrockModel(cosmetic, "", capeModelFile, null, emptyList(), null, dummyTexture)
init {
private val models = mutableMapOf<Int, BedrockModel>()

fun get(textureHeight: Int) = models.getOrPut(textureHeight) {
val capeModel = BedrockModel(cosmetic, "", capeModelFile, null, emptyList(), null, dummyTexture(textureHeight))
capeModel.texture = null
capeModel
}
}
28 changes: 21 additions & 7 deletions cosmetics/src/commonMain/kotlin/gg/essential/model/Animation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,9 @@ class ModelAnimationState(
}

val matrixStack = UMatrixStack()
matrixStack.translate(parentLocator.position)
matrixStack.rotate(parentLocator.rotation)
val (position, rotation) = parentLocator.positionAndRotation
matrixStack.translate(position)
matrixStack.rotate(rotation)
matrixStack.scale(scale)
matrixStack.scale(-1f, -1f, 1f) // see RenderLivingBase.prepareScale
matrixStack.scale(0.9375f) // see RenderPlayer.preRenderCallback
Expand All @@ -177,9 +178,19 @@ class ModelAnimationState(
/** Emits effect keyframes into [pendingEvents]. */
fun updateEffects(untilLifeTime: Float = entity.lifeTime) {
for (state in active) {
if (state.animation.effects.isEmpty()) {
continue
}
while (true) {
val (nextTime, effects) = state.animation.effects.higherEntry(state.lastEffectTime) ?: break
val nextLifeTime = state.animStartTime + nextTime
val (nextTime, effects) = state.animation.effects.higherEntry(state.lastEffectTime)
?: if (state.animation.loop == AnimationFile.Loop.True) {
state.effectLoops++
state.lastEffectTime = Float.NEGATIVE_INFINITY
continue
} else {
break
}
val nextLifeTime = state.animStartTime + state.effectLoopsDuration + nextTime
if (nextLifeTime > untilLifeTime) {
break
}
Expand Down Expand Up @@ -214,11 +225,14 @@ class ModelAnimationState(
get() = entity.lifeTime - animStartTime
override val animLoopTime: Float
get() =
if (animation.holdOnLastFrame) animTime.coerceAtMost(animation.animationLength)
if (animation.loop == AnimationFile.Loop.HoldOnLastFrame) animTime.coerceAtMost(animation.animationLength)
else animTime % animation.animationLength

/** Effects up to and including this time have already been emitted. */
internal var lastEffectTime = Float.NEGATIVE_INFINITY
internal var effectLoops = 0
internal val effectLoopsDuration: Float
get() = if (animation.loop == AnimationFile.Loop.True) effectLoops * animation.animationLength else 0f
}

sealed interface Event {
Expand Down Expand Up @@ -256,7 +270,7 @@ class ModelAnimationState(
data class Animation(
val name: String,
val animationLength: Float,
val holdOnLastFrame: Boolean,
val loop: AnimationFile.Loop,
val bones: Map<String, Channels>,
val effects: TreeMap<Float, List<Event>>,
val affectsPoseParts: Set<EnumPart>,
Expand All @@ -273,7 +287,7 @@ data class Animation(
) : this(
name,
file.animationLength ?: file.bones.calcAnimationLength(),
file.loop == AnimationFile.Loop.HoldOnLastFrame,
file.loop,
file.bones,
TreeMap(mutableMapOf<Float, MutableList<Event>>().also { events ->
file.particleEffects.forEach { (time, effects) ->
Expand Down
31 changes: 28 additions & 3 deletions cosmetics/src/commonMain/kotlin/gg/essential/model/BedrockModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class BedrockModel(
soundData: SoundDefinitionsFile?,
var texture: RenderBackend.Texture?,
) {
val errors: List<String>

@JvmField
var boundingBoxes: List<Pair<Box3, Side?>>
var rootBone: Bone
Expand All @@ -55,6 +57,8 @@ class BedrockModel(
get() = sideOptions.isNotEmpty()

init {
val errors = mutableListOf<String>()

val texture = texture
if (data != null) {
val parser = ModelParser(cosmetic, texture?.width ?: 64, texture?.height ?: 64)
Expand Down Expand Up @@ -117,12 +121,31 @@ class BedrockModel(
}

if (animationData != null) {
val referencedAnimations = animationData.triggers.flatMapTo(mutableSetOf()) { trigger ->
generateSequence(trigger) { it.onComplete }.map { it.name }
}

animations = animationData.animations.map { Animation(it.key, it.value, getBones(rootBone), particleEffects, soundEffects) }
.filter { animation ->
when {
animation.name !in referencedAnimations -> {
errors.add("Animation `${animation.name}` is unused.")
false
}
animation.animationLength <= 0f -> {
errors.add("Animation `${animation.name}` has zero or negative duration.")
false
}
else -> true
}
}
animationEvents = animationData.triggers
} else {
animations = emptyList()
animationEvents = emptyList()
}

this.errors = errors
}

fun getAnimationByName(name: String): Animation? {
Expand Down Expand Up @@ -281,6 +304,8 @@ class BedrockModel(
/**
* Renders the model
*
* Note: [Bone.resetAnimationOffsets] or equivalent must be called before calling this method.
*
* @param matrixStack
*/
fun render(
Expand Down Expand Up @@ -374,7 +399,7 @@ class BedrockModel(
private val LEFT_ARM = Offset(5f, -22f, 0f, -5f, 2f, 0f)
private val LEFT_LEG = Offset(1.9f, -12f, 0f, -1.9f, 12f, 0f)
private val RIGHT_LEG = Offset(-1.9f, -12f, 0f, 1.9f, 12f, 0f)
private val CAPE = Offset(0f, -24f, 2.5f, 0f, 0f, -2f)
private val CAPE = Offset(0f, -24f, 2f, 0f, 0f, -2f)
private val OFFSETS =
mapOf(
EnumPart.HEAD to BASE,
Expand All @@ -385,8 +410,8 @@ class BedrockModel(
EnumPart.RIGHT_LEG to RIGHT_LEG,
EnumPart.LEFT_SHOULDER_ENTITY to BASE,
EnumPart.RIGHT_SHOULDER_ENTITY to BASE,
EnumPart.LEFT_WING to BASE,
EnumPart.RIGHT_WING to BASE,
EnumPart.LEFT_WING to Offset(5f, -24f, 2f, -5f, 0f, -2f),
EnumPart.RIGHT_WING to Offset(-5f, -24f, 2f, 5f, 0f, -2f),
EnumPart.CAPE to CAPE,
)
const val TEXTURE_ANIMATION_FPS = 7f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ class ModelInstance(
// Locators are fairly expensive to update, so only do it if we need to
if (animationState.locatorsNeedUpdating()) {
val pose = PlayerPose.neutral() // no way for us to get the real pose if we didn't actually render
.copy(
// Also no way to know if cape/elytra/etc. are visible (not if you consider modded items anyway),
// so we'll move those far away so any events they spawn won't be visible.
rightShoulderEntity = PlayerPose.Part.MISSING,
leftShoulderEntity = PlayerPose.Part.MISSING,
rightWing = PlayerPose.Part.MISSING,
leftWing = PlayerPose.Part.MISSING,
cape = PlayerPose.Part.MISSING,
)
val rootBone = model.rootBone
animationState.apply(rootBone, false)
model.applyPose(rootBone, pose)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*/
package gg.essential.model

import gg.essential.mod.cosmetics.CapeModel
import gg.essential.mod.cosmetics.CosmeticSlot
import gg.essential.model.file.ModelFile
import gg.essential.network.cosmetics.Cosmetic
Expand Down Expand Up @@ -98,6 +99,14 @@ class ModelParser(
boneModel.cubeList.add(cubeModel)
}

// For capes, we render the actual cape separately (so conceptually, the model only includes *extra*
// geometry). However, for backwards compatibility, we still include the cape cube in the cosmetic file, so
// we need to remove it from the model.
// (except for the internal CapeModel which we use in place of the vanilla cape renderer in certain cases)
if (EnumPart.fromBoneName(bone.name) == EnumPart.CAPE && geometry.description.identifier != CapeModel.GEOMETRY_ID) {
boneModel.cubeList.removeFirstOrNull()
}

(boneByName[bone.parent] ?: rootBone).addChild(boneModel)
}

Expand Down
Loading

0 comments on commit 219f348

Please sign in to comment.