aboutsummaryrefslogtreecommitdiff
path: root/src/texturePacks
diff options
context:
space:
mode:
Diffstat (limited to 'src/texturePacks')
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt4
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/HeadModelChooser.kt90
-rw-r--r--src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt2
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ItemRenderStateExtraInfo.java28
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceHeadModel.java51
-rw-r--r--src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java2
6 files changed, 176 insertions, 1 deletions
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt
index 4529d1d..fe7951c 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/CustomModelOverrideParser.kt
@@ -110,6 +110,10 @@ object CustomModelOverrideParser {
Firmament.identifier("predicates/legacy"),
PredicateModel.Unbaked.CODEC
)
+ ItemModelTypes.ID_MAPPER.put(
+ Firmament.identifier("head_model"),
+ HeadModelChooser.Unbaked.CODEC
+ )
}
}
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/HeadModelChooser.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/HeadModelChooser.kt
new file mode 100644
index 0000000..b5f2bfe
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/HeadModelChooser.kt
@@ -0,0 +1,90 @@
+package moe.nea.firmament.features.texturepack
+
+import com.google.gson.JsonObject
+import com.mojang.serialization.MapCodec
+import com.mojang.serialization.codecs.RecordCodecBuilder
+import net.minecraft.client.item.ItemModelManager
+import net.minecraft.client.render.item.ItemRenderState
+import net.minecraft.client.render.item.model.BasicItemModel
+import net.minecraft.client.render.item.model.ItemModel
+import net.minecraft.client.render.item.model.ItemModelTypes
+import net.minecraft.client.render.model.ResolvableModel
+import net.minecraft.client.world.ClientWorld
+import net.minecraft.entity.LivingEntity
+import net.minecraft.item.ItemStack
+import net.minecraft.item.ModelTransformationMode
+import net.minecraft.util.Identifier
+
+object HeadModelChooser {
+ val IS_CHOOSING_HEAD_MODEL = ThreadLocal.withInitial { false }
+
+ interface HasExplicitHeadModelMarker {
+ fun markExplicitHead_Firmament()
+ fun isExplicitHeadModel_Firmament(): Boolean
+ companion object{
+ @JvmStatic
+ fun cast(state: ItemRenderState) = state as HasExplicitHeadModelMarker
+ }
+ }
+
+ data class Baked(val head: ItemModel, val regular: ItemModel) : ItemModel {
+ override fun update(
+ state: ItemRenderState,
+ stack: ItemStack?,
+ resolver: ItemModelManager?,
+ transformationMode: ModelTransformationMode?,
+ world: ClientWorld?,
+ user: LivingEntity?,
+ seed: Int
+ ) {
+ val instance =
+ if (IS_CHOOSING_HEAD_MODEL.get()) {
+ HasExplicitHeadModelMarker.cast(state).markExplicitHead_Firmament()
+ head
+ } else {
+ regular
+ }
+ instance.update(state, stack, resolver, transformationMode, world, user, seed)
+ }
+ }
+
+ data class Unbaked(
+ val head: ItemModel.Unbaked,
+ val regular: ItemModel.Unbaked,
+ ) : ItemModel.Unbaked {
+ override fun getCodec(): MapCodec<out ItemModel.Unbaked> {
+ return CODEC
+ }
+
+ override fun bake(context: ItemModel.BakeContext): ItemModel {
+ return Baked(
+ head.bake(context),
+ regular.bake(context)
+ )
+ }
+
+ override fun resolve(resolver: ResolvableModel.Resolver) {
+ head.resolve(resolver)
+ regular.resolve(resolver)
+ }
+
+ companion object {
+ @JvmStatic
+ fun fromLegacyJson(jsonObject: JsonObject, unbakedModel: ItemModel.Unbaked): ItemModel.Unbaked {
+ val model = jsonObject["firmament:head_model"] ?: return unbakedModel
+ val modelUrl = model.asJsonPrimitive.asString
+ val headModel = BasicItemModel.Unbaked(Identifier.of(modelUrl), listOf())
+ return Unbaked(headModel, unbakedModel)
+ }
+
+ val CODEC = RecordCodecBuilder.mapCodec {
+ it.group(
+ ItemModelTypes.CODEC.fieldOf("head")
+ .forGetter(Unbaked::head),
+ ItemModelTypes.CODEC.fieldOf("regular")
+ .forGetter(Unbaked::regular),
+ ).apply(it, ::Unbaked)
+ }
+ }
+ }
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt
index 2b79c1a..321f87c 100644
--- a/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt
+++ b/src/texturePacks/java/moe/nea/firmament/features/texturepack/predicates/CastPredicate.kt
@@ -16,7 +16,7 @@ class CastPredicate : FirmamentModelPredicate {
}
override fun test(stack: ItemStack, holder: LivingEntity?): Boolean {
- return (holder as? PlayerEntity)?.fishHook != null && holder.activeItem === stack
+ return (holder as? PlayerEntity)?.fishHook != null && holder.mainHandStack === stack
}
override fun test(stack: ItemStack): Boolean {
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ItemRenderStateExtraInfo.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ItemRenderStateExtraInfo.java
new file mode 100644
index 0000000..2872dd1
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ItemRenderStateExtraInfo.java
@@ -0,0 +1,28 @@
+package moe.nea.firmament.mixins.custommodels;
+
+import moe.nea.firmament.features.texturepack.HeadModelChooser;
+import net.minecraft.client.render.item.ItemRenderState;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(ItemRenderState.class)
+public class ItemRenderStateExtraInfo implements HeadModelChooser.HasExplicitHeadModelMarker {
+ boolean hasExplicitHead_firmament = false;
+
+ @Inject(method = "clear", at = @At("HEAD"))
+ private void clear(CallbackInfo ci) {
+ hasExplicitHead_firmament = false;
+ }
+
+ @Override
+ public void markExplicitHead_Firmament() {
+ hasExplicitHead_firmament = true;
+ }
+
+ @Override
+ public boolean isExplicitHeadModel_Firmament() {
+ return hasExplicitHead_firmament;
+ }
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceHeadModel.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceHeadModel.java
new file mode 100644
index 0000000..8381227
--- /dev/null
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/ReplaceHeadModel.java
@@ -0,0 +1,51 @@
+package moe.nea.firmament.mixins.custommodels;
+
+import moe.nea.firmament.features.texturepack.HeadModelChooser;
+import net.minecraft.client.item.ItemModelManager;
+import net.minecraft.client.render.entity.LivingEntityRenderer;
+import net.minecraft.client.render.entity.model.EntityModel;
+import net.minecraft.client.render.entity.state.LivingEntityRenderState;
+import net.minecraft.client.render.item.ItemRenderState;
+import net.minecraft.entity.EquipmentSlot;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.item.ModelTransformationMode;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(LivingEntityRenderer.class)
+public class ReplaceHeadModel<T extends LivingEntity, S extends LivingEntityRenderState, M extends EntityModel<? super S>> {
+ @Shadow
+ @Final
+ protected ItemModelManager itemModelResolver;
+
+ @Unique
+ private ItemRenderState tempRenderState = new ItemRenderState();
+
+ @Inject(
+ method = "updateRenderState(Lnet/minecraft/entity/LivingEntity;Lnet/minecraft/client/render/entity/state/LivingEntityRenderState;F)V",
+ at = @At("TAIL")
+ )
+ private void replaceHeadModel(
+ T livingEntity, S livingEntityRenderState, float f, CallbackInfo ci
+ ) {
+ var headItemStack = livingEntity.getEquippedStack(EquipmentSlot.HEAD);
+
+ HeadModelChooser.INSTANCE.getIS_CHOOSING_HEAD_MODEL().set(true);
+ tempRenderState.clear();
+ this.itemModelResolver.updateForLivingEntity(tempRenderState, headItemStack, ModelTransformationMode.HEAD, false, livingEntity);
+ HeadModelChooser.INSTANCE.getIS_CHOOSING_HEAD_MODEL().set(false);
+
+ if (HeadModelChooser.HasExplicitHeadModelMarker.cast(tempRenderState)
+ .isExplicitHeadModel_Firmament()) {
+ livingEntityRenderState.wearingSkullType = null;
+ var temp = livingEntityRenderState.headItemRenderState;
+ livingEntityRenderState.headItemRenderState = tempRenderState;
+ tempRenderState = temp;
+ }
+ }
+}
diff --git a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java
index 850ea53..75cedf8 100644
--- a/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java
+++ b/src/texturePacks/java/moe/nea/firmament/mixins/custommodels/SupplyFakeModelPatch.java
@@ -5,6 +5,7 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.sugar.Local;
import moe.nea.firmament.Firmament;
import moe.nea.firmament.features.texturepack.CustomSkyBlockTextures;
+import moe.nea.firmament.features.texturepack.HeadModelChooser;
import moe.nea.firmament.features.texturepack.PredicateModel;
import moe.nea.firmament.util.ErrorUtil;
import net.minecraft.client.item.ItemAsset;
@@ -61,6 +62,7 @@ public class SupplyFakeModelPatch {
try (var is = resource.getInputStream()) {
var jsonObject = Firmament.INSTANCE.getGson().fromJson(new InputStreamReader(is), JsonObject.class);
unbakedModel = PredicateModel.Unbaked.fromLegacyJson(jsonObject, unbakedModel);
+ unbakedModel = HeadModelChooser.Unbaked.fromLegacyJson(jsonObject, unbakedModel);
} catch (Exception e) {
ErrorUtil.INSTANCE.softError("Could not create resource for fake model supplication: " + model.getKey(), e);
}