Updated to 1.21.5

This commit is contained in:
Tschipp 2025-07-08 10:51:36 +02:00
parent 60594ea3bc
commit d1227d3d87
16 changed files with 183 additions and 82 deletions

View File

@ -112,10 +112,10 @@ public class CarryOnCommon
if (!Constants.COMMON_CONFIG.settings.slownessInCreative && player.isCreative())
return;
player.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 1, potionLevel(carry, player.level()), false, false));
player.addEffect(new MobEffectInstance(MobEffects.SLOWNESS, 1, potionLevel(carry, player.level()), false, false));
Inventory inv = player.getInventory();
inv.selected = carry.getSelected();
inv.setSelectedSlot(carry.getSelected());
}
}

View File

@ -59,7 +59,7 @@ public class CarryOnCommonClient
CarryOnData carry = CarryOnDataManager.getCarryData(player);
if(carry.isCarrying())
{
player.getInventory().selected = carry.getSelected();
player.getInventory().setSelectedSlot(carry.getSelected());
}
}
}

View File

@ -20,21 +20,23 @@
package tschipp.carryon.client.render;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.textures.GpuTexture;
import com.mojang.blaze3d.vertex.*;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderDefines;
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
import net.minecraft.client.renderer.item.ItemStackRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
@ -45,6 +47,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix4f;
import tschipp.carryon.Constants;
import tschipp.carryon.common.carry.CarryOnData;
@ -54,22 +57,20 @@ import tschipp.carryon.common.scripting.CarryOnScript;
import tschipp.carryon.common.scripting.CarryOnScript.ScriptRender;
import tschipp.carryon.platform.Services;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.SequencedMap;
import java.util.*;
public class CarriedObjectRender
{
private static SequencedMap<RenderType, ByteBufferBuilder> builders = new LinkedHashMap<>(Map.of(
RenderType.glint(), new ByteBufferBuilder(RenderType.glint().bufferSize()),
RenderType.armorEntityGlint(), new ByteBufferBuilder(RenderType.armorEntityGlint().bufferSize()),
RenderType.glintTranslucent(), new ByteBufferBuilder(RenderType.glintTranslucent().bufferSize()),
RenderType.entityGlint(), new ByteBufferBuilder(RenderType.entityGlint().bufferSize())
private static final SequencedMap<RenderType, ByteBufferBuilder> builders = new LinkedHashMap<>(Map.of(
RenderType.glint(), new ByteBufferBuilder(CarryOnRenderType.remap(RenderType.glint()).bufferSize()),
RenderType.armorEntityGlint(), new ByteBufferBuilder(CarryOnRenderType.remap(RenderType.armorEntityGlint()).bufferSize()),
RenderType.glintTranslucent(), new ByteBufferBuilder(CarryOnRenderType.remap(RenderType.glintTranslucent()).bufferSize()),
RenderType.entityGlint(), new ByteBufferBuilder(CarryOnRenderType.remap(RenderType.entityGlint()).bufferSize())
//RenderType.entityGlintDirect(), new ByteBufferBuilder(RenderType.entityGlintDirect().bufferSize())
));
public static boolean drawFirstPerson(Player player, MultiBufferSource buffer, PoseStack matrix, int light, float partialTicks)
{
if(Services.PLATFORM.isModLoaded("firstperson") || Services.PLATFORM.isModLoaded("firstpersonmod"))
@ -105,11 +106,13 @@ public class CarriedObjectRender
matrix.pushPose();
matrix.scale(2.5f, 2.5f, 2.5f);
matrix.translate(0, -0.5, -1);
RenderSystem.enableBlend();
RenderSystem.disableCull();
//RenderSystem.enableBlend();
//RenderSystem.disableCull();
CarryOnData carry = CarryOnDataManager.getCarryData(player);
ItemStackRenderState renderState = new ItemStackRenderState();
var layer = renderState.newLayer();
layer.setRenderType(CarryOnRenderType.remap(RenderType.glint()));
if (Constants.CLIENT_CONFIG.facePlayer != CarryRenderHelper.isChest(state.getBlock())) {
matrix.mulPose(Axis.YP.rotationDegrees(180));
@ -121,16 +124,16 @@ public class CarriedObjectRender
if(carry.getActiveScript().isPresent())
CarryRenderHelper.performScriptTransformation(matrix, carry.getActiveScript().get());
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
//RenderSystem.setShaderTexture(0, GpuTexture);
ItemStack renderStack = CarryRenderHelper.getRenderItemStack(player);
Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, false, player.level(), null, 0);
Minecraft.getInstance().getItemModelResolver().updateForTopItem(renderState, renderStack, ItemDisplayContext.NONE, player.level(), null, 0);
renderState.render(matrix, buffer, light, OverlayTexture.NO_OVERLAY);
RenderSystem.enableCull();
RenderSystem.disableBlend();
//RenderSystem.enableCull();
//RenderSystem.disableBlend();
matrix.popPose();
}
@ -197,12 +200,14 @@ public class CarriedObjectRender
PoseStack matrix = new PoseStack();
matrix.mulPose(mat);
RenderSystem.enableBlend();
RenderSystem.disableCull();
RenderSystem.disableDepthTest();
//RenderSystem.enableBlend();
//RenderSystem.disableCull();
//RenderSystem.disableDepthTest();
BufferSource buffer = MultiBufferSource.immediateWithBuffers(builders, builders.get(RenderType.glint()));
ItemStackRenderState renderState = new ItemStackRenderState();
var layer = renderState.newLayer();
layer.setRenderType(RenderType.glint());
for (Player player : level.players())
{
@ -222,16 +227,13 @@ public class CarriedObjectRender
ItemStack renderItemStack = CarryRenderHelper.getRenderItemStack(player);
mc.getItemModelResolver().updateForTopItem(renderState, renderItemStack, ItemDisplayContext.NONE, false, level, null, 0);
mc.getItemModelResolver().updateForTopItem(renderState, renderItemStack, ItemDisplayContext.NONE, level, null, 0);
Optional<CarryOnScript> res = carry.getActiveScript();
if (res.isPresent()) {
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
res.ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
RenderSystem.enableCull();
//RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
//RenderSystem.enableCull();
PoseStack.Pose p = matrix.last();
PoseStack copy = new PoseStack();
@ -252,10 +254,7 @@ public class CarriedObjectRender
manager.setRenderShadow(false);
Optional<CarryOnScript> res = carry.getActiveScript();
if (res.isPresent()) {
CarryOnScript script = res.get();
CarryRenderHelper.performScriptTransformation(matrix, script);
}
res.ifPresent(script -> CarryRenderHelper.performScriptTransformation(matrix, script));
if (entity instanceof LivingEntity le)
le.hurtTime = 0;
@ -283,9 +282,9 @@ public class CarriedObjectRender
buffer.endBatch(RenderType.entityCutoutNoCull(TextureAtlas.LOCATION_BLOCKS));
buffer.endBatch(RenderType.entitySmoothCutout(TextureAtlas.LOCATION_BLOCKS));
RenderSystem.enableDepthTest();
RenderSystem.enableCull();
RenderSystem.disableBlend();
//RenderSystem.enableDepthTest();
//RenderSystem.enableCull();
//RenderSystem.disableBlend();
}
}

View File

@ -0,0 +1,113 @@
package tschipp.carryon.client.render;
import com.mojang.blaze3d.pipeline.BlendFunction;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.DepthTestFunction;
import com.mojang.blaze3d.vertex.MeshData;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.ShaderDefines;
import org.jetbrains.annotations.NotNull;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Optional;
//Credit: klikli
public class CarryOnRenderType extends RenderType {
private static final Map<RenderType, RenderType> remappedTypes = new IdentityHashMap<>();
private final RenderPipeline pipeline;
private final RenderType original;
private CarryOnRenderType(RenderType original, RenderPipeline pipeline) {
super(String.format("%s_carryon", original.toString()), original.bufferSize(), original.affectsCrumbling(), true, original::setupRenderState, original::clearRenderState);
this.pipeline = pipeline;
this.original = original;
}
public static RenderType remap(RenderType in) {
return remappedTypes.computeIfAbsent(in, (type) -> {
//modify the pipeline
var pipeline = toBuilder(in.getRenderPipeline())
.withBlend(BlendFunction.TRANSLUCENT)
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
.withCull(false);
return new CarryOnRenderType(type, pipeline.build());
});
}
private static RenderPipeline.Builder toBuilder(RenderPipeline pipeline) {
RenderPipeline.Builder builder = RenderPipeline.builder();
builder.withLocation(pipeline.getLocation());
builder.withFragmentShader(pipeline.getFragmentShader());
builder.withVertexShader(pipeline.getVertexShader());
if (!pipeline.getShaderDefines().isEmpty()) {
for (Map.Entry<String, String> entry : pipeline.getShaderDefines().values().entrySet()) {
try {
int parsed = Integer.parseInt(entry.getValue());
builder.withShaderDefine(entry.getKey(), parsed);
} catch (NumberFormatException e) {
float parsed = Float.parseFloat(entry.getValue());
builder.withShaderDefine(entry.getKey(), parsed);
}
}
for (String flag : pipeline.getShaderDefines().flags()) {
builder.withShaderDefine(flag);
}
}
if (!pipeline.getSamplers().isEmpty()) {
pipeline.getSamplers().forEach(builder::withSampler);
}
if (!pipeline.getUniforms().isEmpty()) {
pipeline.getUniforms().forEach(u -> builder.withUniform(u.name(), u.type()));
}
builder.withDepthTestFunction(pipeline.getDepthTestFunction());
builder.withPolygonMode(pipeline.getPolygonMode());
builder.withCull(pipeline.isCull());
builder.withColorWrite(pipeline.isWriteColor(), pipeline.isWriteAlpha());
builder.withDepthWrite(pipeline.isWriteDepth());
builder.withColorLogic(pipeline.getColorLogic());
if (pipeline.getBlendFunction().isPresent())
builder.withBlend(pipeline.getBlendFunction().get());
else
builder.withoutBlend();
builder.withVertexFormat(pipeline.getVertexFormat(), pipeline.getVertexFormatMode());
builder.withDepthBias(pipeline.getDepthBiasScaleFactor(), pipeline.getDepthBiasConstant());
return builder;
}
@Override
public void draw(@NotNull MeshData meshData) {
this.original.draw(meshData);
}
@Override
public @NotNull RenderTarget getRenderTarget() {
return this.original.getRenderTarget();
}
@Override
public @NotNull RenderPipeline getRenderPipeline() {
return this.pipeline; //get our own modified pipeline
}
@Override
public @NotNull VertexFormat format() {
return this.original.format();
}
@Override
public VertexFormat.@NotNull Mode mode() {
return this.original.mode();
}
}

View File

@ -23,25 +23,16 @@ package tschipp.carryon.client.render;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.item.ItemStackRenderState;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;

View File

@ -54,14 +54,13 @@ public class CarryOnData {
public CarryOnData(CompoundTag data)
{
if(data.contains("type"))
this.type = CarryType.valueOf(data.getString("type"));
this.type = CarryType.valueOf(data.getStringOr("type", "INVALID"));
else
this.type = CarryType.INVALID;
this.nbt = data;
if(data.contains("keyPressed"))
this.keyPressed = data.getBoolean("keyPressed");
this.keyPressed = data.getBooleanOr("keyPressed", false);
if(data.contains("activeScript"))
{
@ -69,8 +68,7 @@ public class CarryOnData {
this.activeScript = res.getOrThrow((s) -> {throw new RuntimeException("Failed to decode activeScript during CarryOnData serialization: " + s);});
}
if(data.contains("selected"))
this.selectedSlot = data.getInt("selected");
this.selectedSlot = data.getIntOr("selected", 0);
}
@ -91,9 +89,9 @@ public class CarryOnData {
public CompoundTag getContentNbt()
{
if(type == CarryType.BLOCK && nbt.contains("block"))
return nbt.getCompound("block");
return nbt.getCompoundOrEmpty("block");
else if(type == CarryType.ENTITY && nbt.contains("entity"))
return nbt.getCompound("entity");
return nbt.getCompoundOrEmpty("entity");
return null;
}
@ -119,7 +117,7 @@ public class CarryOnData {
if(this.type != CarryType.BLOCK)
throw new IllegalStateException("Called getBlock on data that contained " + this.type);
return NbtUtils.readBlockState(BuiltInRegistries.BLOCK, nbt.getCompound("block"));
return NbtUtils.readBlockState(BuiltInRegistries.BLOCK, nbt.getCompoundOrEmpty("block"));
}
@Nullable
@ -131,7 +129,7 @@ public class CarryOnData {
if(!nbt.contains("tile"))
return null;
return BlockEntity.loadStatic(pos, this.getBlock(), nbt.getCompound("tile"), lookup);
return BlockEntity.loadStatic(pos, this.getBlock(), nbt.getCompoundOrEmpty("tile"), lookup);
}
public void setEntity(Entity entity)
@ -147,7 +145,7 @@ public class CarryOnData {
if(this.type != CarryType.ENTITY)
throw new IllegalStateException("Called getEntity on data that contained " + this.type);
var optionalEntity = EntityType.create(nbt.getCompound("entity"), level, EntitySpawnReason.BUCKET);
var optionalEntity = EntityType.create(nbt.getCompoundOrEmpty("entity"), level, EntitySpawnReason.BUCKET);
if(optionalEntity.isPresent())
return optionalEntity.get();
@ -212,7 +210,7 @@ public class CarryOnData {
{
if(!this.nbt.contains("tick"))
return -1;
return this.nbt.getInt("tick");
return this.nbt.getIntOr("tick", -1);
}
public enum CarryType {

View File

@ -162,7 +162,7 @@ public class PickupHandler {
if (entity instanceof TamableAnimal tame)
{
UUID owner = tame.getOwnerUUID();
UUID owner = tame.getOwnerReference().getUUID();
UUID playerID = player.getGameProfile().getId();
if (owner != null && !owner.equals(playerID))
return false;

View File

@ -283,7 +283,7 @@ public class PlacementHandler
if (((ServerLevel) oldPlayer.level()).getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || !died) {
if (!carry.isCarrying(CarryType.PLAYER)) {
CarryOnDataManager.setCarryData(newPlayer, carry);
newPlayer.getInventory().selected = oldPlayer.getInventory().selected;
newPlayer.getInventory().setSelectedSlot(oldPlayer.getInventory().getSelectedSlot());
return;
}
}

View File

@ -76,7 +76,7 @@ public class InventoryMixin
info.cancel();
}
@Inject(method = "setSelectedHotbarSlot(I)V", at = @At("HEAD"), cancellable = true)
@Inject(method = "setSelectedSlot(I)V", at = @At("HEAD"), cancellable = true)
private void onSwapPaint(int $$0, CallbackInfo info)
{
if(CarryOnDataManager.getCarryData(player).isCarrying())

View File

@ -31,7 +31,7 @@ import tschipp.carryon.common.carry.CarryOnDataManager;
@Mixin(Minecraft.class)
public class MinecraftMixin
{
@WrapWithCondition(method = "handleKeybinds()V", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/player/Inventory;selected:I", ordinal = 0, opcode = 181)) //Opcode for PUTFIELD
@WrapWithCondition(method = "handleKeybinds()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Inventory;setSelectedSlot(I)V", ordinal = 0))
private boolean allowSlotSelection(Inventory inv,int slot)
{
return !CarryOnDataManager.getCarryData(inv.player).isCarrying();

View File

@ -48,7 +48,7 @@ public abstract class PlayerMixin extends LivingEntity implements CarryOnDataMan
@Override
public void setCarryOnData(CarryOnData data)
{
data.setSelected(this.getInventory().selected);
data.setSelected(this.getInventory().getSelectedSlot());
CompoundTag nbt = data.getNbt();
nbt.putInt("tick", tickCount);
this.getEntityData().set(CARRY_DATA_KEY, nbt);
@ -87,7 +87,7 @@ public abstract class PlayerMixin extends LivingEntity implements CarryOnDataMan
private void onReadAdditionalSaveData(CompoundTag tag, CallbackInfo info)
{
if (tag.contains("CarryOnData")) {
CarryOnData data = new CarryOnData(tag.getCompound("CarryOnData"));
CarryOnData data = new CarryOnData(tag.getCompoundOrEmpty("CarryOnData"));
setCarryOnData(data);
}
}

View File

@ -2,7 +2,7 @@ plugins {
id 'java'
id 'maven-publish'
id 'idea'
id 'fabric-loom' version '1.8-SNAPSHOT'
id 'fabric-loom' version '1.10-SNAPSHOT'
}
base {
archivesName = "${mod_id}-fabric-${minecraft_version}"

View File

@ -36,7 +36,7 @@ jarJar.enable()
build.dependsOn tasks.jarJar
minecraft {
mappings channel: 'official', version: "1.21.4"
mappings channel: 'parchment', version: "${parchment_mappings}"
copyIdeResources = true
reobf = false

View File

@ -23,6 +23,7 @@ package tschipp.carryon.events;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.TriState;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntitySpawnReason;
@ -37,7 +38,6 @@ import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.util.BlockSnapshot;
import net.neoforged.neoforge.common.util.TriState;
import net.neoforged.neoforge.event.*;
import net.neoforged.neoforge.event.entity.living.MobSpawnEvent;
import net.neoforged.neoforge.event.entity.player.AttackEntityEvent;

View File

@ -1,33 +1,33 @@
# Project
version=2.3.0
version=2.4.0
group=tschipp.carryon
# Common
minecraft_version=1.21.4
minecraft_version=1.21.5
mod_name=Carry On
mod_author=Tschipp, PurpliciousCow
mod_id=carryon
license=GNU LGPLv3
credits=
description=Carry On is a simple mod that improves game interaction by allowing players to pick up, carry, and place single block Tile Entities using only their empty hands.
minecraft_version_range=[1.21.4, 1.22)
minecraft_version_range=[1.21.5, 1.22)
# Forge
forge_version=54.1.3
forge_loader_version_range=[54,)
forge_version_range=[54,)
parchment_mappings=2025.03.23-1.21.4
forge_version=55.0.6
forge_loader_version_range=[55,)
forge_version_range=[55,)
parchment_mappings=2025.04.19-1.21.5
//forge_ats_enabled=true
# Fabric
fabric_version=0.119.2+1.21.4
fabric_version=0.121.0+1.21.5
fabric_loader_version=0.16.13
parchment_mappings_fabric=1.21.4:2025.03.23
parchment_mappings_fabric=1.21.5:2025.04.19
# Neoforge
neoforge_version=21.4.132
neoforge_version=21.5.78
neoforge_loader_version_range=[4,)
neogradle.subsystems.parchment.minecraftVersion=1.21.4
neogradle.subsystems.parchment.mappingsVersion=2025.03.23
neogradle.subsystems.parchment.minecraftVersion=1.21.5
neogradle.subsystems.parchment.mappingsVersion=2025.04.19
# Gradle

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists