From c0939ca51f4c80a9425882ebd63b16119ed6bd27 Mon Sep 17 00:00:00 2001 From: RandyParedis Date: Thu, 9 Nov 2023 02:04:57 +0100 Subject: [PATCH 1/7] Balloon Updates Fixes #595, #417 (partially; there is still a visual bug) and #406 --- .../be/minelabs/entity/mob/BalloonEntity.java | 68 +++++++++++++------ .../be/minelabs/item/items/BalloonItem.java | 44 ++++++++++-- .../be/minelabs/mixin/MobEntityMixin.java | 25 +++++++ src/main/resources/minelabs.mixins.json | 1 + 4 files changed, 114 insertions(+), 24 deletions(-) create mode 100644 src/main/java/be/minelabs/mixin/MobEntityMixin.java diff --git a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java index 097a4e228..03e7b27a9 100644 --- a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java +++ b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java @@ -4,23 +4,33 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.goal.SwimGoal; import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.decoration.AbstractDecorationEntity; +import net.minecraft.entity.decoration.LeashKnotEntity; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.mob.Monster; +import net.minecraft.entity.passive.HorseEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; +import net.minecraft.sound.SoundEvents; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +import java.io.Console; public class BalloonEntity extends MobEntity { private static final double MAX_DISTANCE = 10.0; private static final double MAX_HEIGHT = 320.0; - private float rotationY; + private final float rotationY; private boolean helium = true; private double max_mob_distance = 2.0; - private MobEntity target = null; + private Entity target = null; public BalloonEntity(EntityType entityType, World world) { super(entityType, world); @@ -38,6 +48,7 @@ public float getRotationY() { @Override public void onDeath(DamageSource source) { detachLeash(true, false); + dropItem(Items.RABBIT_HIDE); super.onDeath(source); } @@ -76,8 +87,10 @@ protected void removeFromDimension() { public void tick() { super.tick(); - addStatusEffect(new StatusEffectInstance(StatusEffects.LEVITATION, 10, 3, false, false)); - MobEntity target = this.target; // Prevent crashes when the target becomes null during the tick + if(helium) { + addStatusEffect(new StatusEffectInstance(StatusEffects.LEVITATION, 10, 3, false, false)); + } + Entity target = this.target; // Prevent crashes when the target becomes null during the tick if(target != null) { if(!target.isAlive()) { kill(); @@ -97,35 +110,52 @@ public void tick() { } if(distance >= max_mob_distance) { double x = (tpos.getX() - this.getX()) / (double)distance; - double y = (tpos.getY() - this.getY()) / (double)distance; double z = (tpos.getZ() - this.getZ()) / (double)distance; // Fixes Issue #401 - Vec3d xz = new Vec3d(x, 0.0, z).normalize().multiply(-0.1); - Vec3d vertical = new Vec3d(0.0, Math.copySign(y * y, y), 0.0).normalize(); - if(target.isAiDisabled() || !helium) { - this.setVelocity(xz.add(vertical.multiply(0.1))); - } else if(this.target != null) { - this.target.setVelocity(xz.add(vertical.multiply(-0.18))); + Vec3d xz = new Vec3d(x, 0.0, z).normalize().multiply(0.1); + this.setVelocity(xz); + + if(!(target instanceof LeashKnotEntity) && !(target instanceof MobEntity && ((MobEntity) target).isAiDisabled())) { + // The target might move around and should follow the levitation + + if(this.target != null) { + // So apparently untamed rideables cannot be lifted in the air once ridden + // There is no reason for this, they just... can't... + // Let's just call this a feature :) + + this.target.setVelocity(new Vec3d(-xz.x, 0.11, -xz.z)); + } } } } } // LEASH - + @Override + public boolean canBeLeashedBy(PlayerEntity player) { + return false; + } @Override public void attachLeash(Entity entity, boolean sendPacket) { // By attaching a leash to the target, all positions appear to be valid // Fixes Issues #404 and #399 - target = ((MobEntity) entity); - target.attachLeash(this, sendPacket); - Box bbox = entity.getBoundingBox(); - double a = bbox.getXLength(); - double b = bbox.getYLength(); - double c = bbox.getZLength(); - max_mob_distance = Math.sqrt(a * a + b * b + c * c); + target = entity; + if(target instanceof LeashKnotEntity) { + max_mob_distance = 2.0; + } else if (target instanceof MobEntity tgt) { + if(!tgt.isLeashed()) { + tgt.attachLeash(this, sendPacket); + } + + // Longer leashes for larger mobs + Box bbox = entity.getBoundingBox(); + double a = bbox.getXLength(); + double b = bbox.getYLength(); + double c = bbox.getZLength(); + max_mob_distance = Math.sqrt(a * a + b * b + c * c); + } } @Override diff --git a/src/main/java/be/minelabs/item/items/BalloonItem.java b/src/main/java/be/minelabs/item/items/BalloonItem.java index bb9e35ef8..852776480 100644 --- a/src/main/java/be/minelabs/item/items/BalloonItem.java +++ b/src/main/java/be/minelabs/item/items/BalloonItem.java @@ -2,16 +2,27 @@ import be.minelabs.entity.mob.BalloonEntity; import be.minelabs.entity.Entities; +import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.decoration.LeashKnotEntity; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.registry.tag.BlockTags; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; import net.minecraft.world.World; +import net.minecraft.world.event.GameEvent; + +import java.util.Iterator; +import java.util.List; public class BalloonItem extends Item { @@ -19,11 +30,10 @@ public BalloonItem(Item.Settings settings) { super(settings); } - private BalloonEntity summon(World world, LivingEntity entity) { + private BalloonEntity summon(World world, Entity entity) { BalloonEntity balloon = Entities.BALLOON.create(world); balloon.refreshPositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), 0.0F, 0.0F); world.spawnEntity(balloon); - balloon.attachLeash(entity, true); return balloon; } @@ -51,13 +61,37 @@ public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity if(!(entity instanceof PlayerEntity) && !(entity instanceof BalloonEntity)) { World world = user.getWorld(); if(!world.isClient) { - summon(world, entity); - stack.decrement(1); + if(!((MobEntity)entity).isLeashed()) { + BalloonEntity be = summon(world, entity); + be.attachLeash(entity, true); + stack.decrement(1); + } else { + return ActionResult.FAIL; + } } return ActionResult.success(world.isClient); } return ActionResult.PASS; } - // TODO: connect to fence? => see LeadItem + public ActionResult useOnBlock(ItemUsageContext context) { + World world = context.getWorld(); + BlockPos blockPos = context.getBlockPos(); + BlockState blockState = world.getBlockState(blockPos); + if (blockState.isIn(BlockTags.FENCES)) { + PlayerEntity playerEntity = context.getPlayer(); + if (!world.isClient && playerEntity != null) { + LeashKnotEntity leashKnotEntity = LeashKnotEntity.getOrCreate(world, blockPos); + leashKnotEntity.onPlace(); + BalloonEntity be = summon(world, leashKnotEntity); + be.attachLeash(leashKnotEntity, true); + + world.emitGameEvent(GameEvent.BLOCK_ATTACH, blockPos, GameEvent.Emitter.of(playerEntity)); + } + + return ActionResult.success(world.isClient); + } else { + return ActionResult.PASS; + } + } } diff --git a/src/main/java/be/minelabs/mixin/MobEntityMixin.java b/src/main/java/be/minelabs/mixin/MobEntityMixin.java new file mode 100644 index 000000000..b66c38a04 --- /dev/null +++ b/src/main/java/be/minelabs/mixin/MobEntityMixin.java @@ -0,0 +1,25 @@ +package be.minelabs.mixin; + +import be.minelabs.item.Items; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +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.CallbackInfoReturnable; + +@Mixin(MobEntity.class) +public abstract class MobEntityMixin { + @Inject(method="interactWithItem", at=@At(value="HEAD"), cancellable = true) + private void interactItemInject(PlayerEntity player, Hand hand, CallbackInfoReturnable ci) { + // Makes sure that Untamed Horses, Donkeys, Llamas and Camels are also balloonable + ItemStack itemStack = player.getStackInHand(hand); + if (itemStack.isOf(Items.BALLOON)) { + ActionResult ar = itemStack.getItem().useOnEntity(itemStack, player, ((MobEntity)((Object)(this))), hand); + ci.setReturnValue(ar); + } + } +} diff --git a/src/main/resources/minelabs.mixins.json b/src/main/resources/minelabs.mixins.json index d7f96890a..5afcf9f79 100644 --- a/src/main/resources/minelabs.mixins.json +++ b/src/main/resources/minelabs.mixins.json @@ -17,6 +17,7 @@ "FishingBobberEntityAccessor", "IceBlockMixin", "LivingEntityMixin", + "MobEntityMixin", "ThrownEntityMixin" ] } \ No newline at end of file From 2e14d684466e650fadbf5119475a364c493778e8 Mon Sep 17 00:00:00 2001 From: RandyParedis Date: Thu, 9 Nov 2023 20:53:24 +0100 Subject: [PATCH 2/7] Bugfixes --- .../be/minelabs/entity/mob/BalloonEntity.java | 13 ++++++--- .../be/minelabs/item/items/BalloonItem.java | 6 ++--- .../loot_tables/entities/balloon.json | 27 +++++++++++++++++++ 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 src/main/resources/data/minelabs/loot_tables/entities/balloon.json diff --git a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java index 03e7b27a9..ecc37d40f 100644 --- a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java +++ b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java @@ -47,8 +47,10 @@ public float getRotationY() { @Override public void onDeath(DamageSource source) { + if(target != null && target instanceof LeashKnotEntity) { + target.discard(); + } detachLeash(true, false); - dropItem(Items.RABBIT_HIDE); super.onDeath(source); } @@ -120,14 +122,17 @@ public void tick() { // The target might move around and should follow the levitation if(this.target != null) { - // So apparently untamed rideables cannot be lifted in the air once ridden + // So apparently untamed rideables cannot be lifted in the air once saddled // There is no reason for this, they just... can't... // Let's just call this a feature :) - - this.target.setVelocity(new Vec3d(-xz.x, 0.11, -xz.z)); + if(getY() - tpos.getY() > max_mob_distance) { + this.target.setVelocity(new Vec3d(-xz.x, 0.11, -xz.z)); + } } } } + } else { + kill(); } } diff --git a/src/main/java/be/minelabs/item/items/BalloonItem.java b/src/main/java/be/minelabs/item/items/BalloonItem.java index 852776480..94dd49f30 100644 --- a/src/main/java/be/minelabs/item/items/BalloonItem.java +++ b/src/main/java/be/minelabs/item/items/BalloonItem.java @@ -48,6 +48,7 @@ public void inventoryTick(ItemStack itemStack, World world, Entity entity, int s // TODO FIX custom effect (temp fix: use levitation) //System.out.println("Try to fly: call effect"); //StatusEffectInstance sei = new StatusEffectInstance(Effects.FLYING, 2, 2, false, false); + StatusEffectInstance sei = new StatusEffectInstance(StatusEffects.LEVITATION, 4, 2, false, false); pe.addStatusEffect(sei); } @@ -65,11 +66,10 @@ public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity BalloonEntity be = summon(world, entity); be.attachLeash(entity, true); stack.decrement(1); - } else { - return ActionResult.FAIL; + return ActionResult.SUCCESS; } + return ActionResult.FAIL; } - return ActionResult.success(world.isClient); } return ActionResult.PASS; } diff --git a/src/main/resources/data/minelabs/loot_tables/entities/balloon.json b/src/main/resources/data/minelabs/loot_tables/entities/balloon.json new file mode 100644 index 000000000..71a8e2d76 --- /dev/null +++ b/src/main/resources/data/minelabs/loot_tables/entities/balloon.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:entity", + "pools": [ + { + "rolls": 2, + "entries": [ + { + "type": "minecraft:item", + "name": "minecraft:rabbit_hide", + "functions": [ + { + "function": "minecraft:set_count", + "count": { + "min": 1, + "max": 3 + } + } + ] + }, + { + "type": "minecraft:item", + "name": "minecraft:string" + } + ] + } + ] +} \ No newline at end of file From 51061b1720125c25b4eb4a3eba98cc08d576eb96 Mon Sep 17 00:00:00 2001 From: RandyParedis Date: Fri, 10 Nov 2023 01:14:31 +0100 Subject: [PATCH 3/7] Visual String Fix + more --- .../entity/BalloonEntityRenderer.java | 15 +- .../be/minelabs/entity/mob/BalloonEntity.java | 180 ++++++++++++------ .../be/minelabs/item/items/BalloonItem.java | 12 +- 3 files changed, 125 insertions(+), 82 deletions(-) diff --git a/src/client/java/be/minelabs/client/renderer/entity/BalloonEntityRenderer.java b/src/client/java/be/minelabs/client/renderer/entity/BalloonEntityRenderer.java index 3a496acb1..904b87430 100644 --- a/src/client/java/be/minelabs/client/renderer/entity/BalloonEntityRenderer.java +++ b/src/client/java/be/minelabs/client/renderer/entity/BalloonEntityRenderer.java @@ -6,17 +6,13 @@ import be.minelabs.entity.mob.BalloonEntity; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.MobEntityRenderer; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; -import net.minecraft.util.math.RotationAxis; -import org.joml.Quaternionf; @Environment(EnvType.CLIENT) public class BalloonEntityRenderer extends MobEntityRenderer { - + private static final Identifier TEXTURE = new Identifier(Minelabs.MOD_ID, "textures/entity/balloon/balloon.png"); public BalloonEntityRenderer(EntityRendererFactory.Context context) { super(context, new BalloonEntityModel(context.getPart(EntityModelLayers.BALLOON_MODEL)), 0.7F); @@ -24,13 +20,6 @@ public BalloonEntityRenderer(EntityRendererFactory.Context context) { @Override public Identifier getTexture(BalloonEntity entity) { - return new Identifier(Minelabs.MOD_ID, "textures/entity/balloon/balloon.png"); - } - - @Override - public void render(BalloonEntity mobEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i) { - Quaternionf rot = RotationAxis.POSITIVE_Y.rotationDegrees(mobEntity.getRotationY()); - matrixStack.multiply(rot); - super.render(mobEntity, f, g, matrixStack, vertexConsumerProvider, i); + return TEXTURE; } } \ No newline at end of file diff --git a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java index ecc37d40f..d52fc2d34 100644 --- a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java +++ b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java @@ -4,56 +4,41 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.ai.goal.SwimGoal; import net.minecraft.entity.damage.DamageSource; -import net.minecraft.entity.decoration.AbstractDecorationEntity; import net.minecraft.entity.decoration.LeashKnotEntity; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.mob.MobEntity; -import net.minecraft.entity.mob.Monster; -import net.minecraft.entity.passive.HorseEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; -import net.minecraft.sound.SoundEvents; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; -import java.io.Console; +import java.util.UUID; public class BalloonEntity extends MobEntity { private static final double MAX_DISTANCE = 10.0; private static final double MAX_HEIGHT = 320.0; - private final float rotationY; private boolean helium = true; private double max_mob_distance = 2.0; - private Entity target = null; + private Entity owner = null; + + @Nullable + private NbtCompound ownerNbt; public BalloonEntity(EntityType entityType, World world) { super(entityType, world); - rotationY = getRandom().nextFloat() * 360.0F; - setHealth(1.0f); + setHealth(1.0F); setNoGravity(true); } - // GENERAL - - public float getRotationY() { - return rotationY; - } - - @Override - public void onDeath(DamageSource source) { - if(target != null && target instanceof LeashKnotEntity) { - target.discard(); - } - detachLeash(true, false); - super.onDeath(source); - } - + // GETTERS AND SETTERS public void setHelium(boolean new_value) { helium = new_value; } @@ -62,6 +47,20 @@ public boolean getHelium() { return helium; } + public Entity getOwner() { + return owner; + } + + + // GENERAL + public void heal(float amount) {} + + @Override + public void onDeath(DamageSource source) { + detachOwner(); + super.onDeath(source); + } + protected void initGoals() { // Fixes #398 this.goalSelector.add(0, new SwimGoal(this)); @@ -82,29 +81,29 @@ protected boolean canStartRiding(Entity entity) { @Override protected void removeFromDimension() { super.removeFromDimension(); - this.detachLeash(true, false); + this.detachOwner(); } @Override public void tick() { super.tick(); + if (!this.world.isClient) { + updateOwner(); + } + if(helium) { addStatusEffect(new StatusEffectInstance(StatusEffects.LEVITATION, 10, 3, false, false)); } - Entity target = this.target; // Prevent crashes when the target becomes null during the tick + Entity target = owner; // Prevent crashes when the target becomes null during the tick if(target != null) { - if(!target.isAlive()) { - kill(); - } - Vec3d mpos = getPos(); - if(mpos.getY() >= MAX_HEIGHT) { + if(getY() >= MAX_HEIGHT) { // POP GOES THE BALLOON kill(); return; } Vec3d tpos = target.getPos(); - double distance = tpos.distanceTo(mpos); + double distance = tpos.distanceTo(getPos()); if(distance >= MAX_DISTANCE) { // Fixes Issue #406 kill(); @@ -121,12 +120,12 @@ public void tick() { if(!(target instanceof LeashKnotEntity) && !(target instanceof MobEntity && ((MobEntity) target).isAiDisabled())) { // The target might move around and should follow the levitation - if(this.target != null) { + if(owner != null) { // So apparently untamed rideables cannot be lifted in the air once saddled // There is no reason for this, they just... can't... // Let's just call this a feature :) if(getY() - tpos.getY() > max_mob_distance) { - this.target.setVelocity(new Vec3d(-xz.x, 0.11, -xz.z)); + owner.setVelocity(new Vec3d(-xz.x, 0.11, -xz.z)); } } } @@ -136,51 +135,90 @@ public void tick() { } } - // LEASH + // LEASH & OWNER @Override public boolean canBeLeashedBy(PlayerEntity player) { return false; } + public Vec3d getLeashOffset() { + return new Vec3d(0.0D, (double)(0.15F * this.getHeight()), 0.01D); + } + @Override - public void attachLeash(Entity entity, boolean sendPacket) { - // By attaching a leash to the target, all positions appear to be valid - // Fixes Issues #404 and #399 - target = entity; - if(target instanceof LeashKnotEntity) { - max_mob_distance = 2.0; - } else if (target instanceof MobEntity tgt) { - if(!tgt.isLeashed()) { - tgt.attachLeash(this, sendPacket); - } + public boolean isLeashed() { + return true; + } - // Longer leashes for larger mobs - Box bbox = entity.getBoundingBox(); - double a = bbox.getXLength(); - double b = bbox.getYLength(); - double c = bbox.getZLength(); - max_mob_distance = Math.sqrt(a * a + b * b + c * c); + protected void updateOwner() { + if (ownerNbt != null) { + readOwnerNbt(); } - } - @Override - public void detachLeash(boolean sendPacket, boolean dropItem) { - super.detachLeash(sendPacket, dropItem); - target = null; + if(getHoldingEntity() != null) { + owner = getHoldingEntity(); + updateLeash(); + } + + if (owner != null) { + if (!isAlive() || !owner.isAlive()) { + detachOwner(); + kill(); + } + } } - public Vec3d getLeashOffset() { - return new Vec3d(0.0D, (double)(0.15F * this.getHeight()), 0.01D); + public void attachOwner(Entity entity) { + // By attaching a leash to the target, all positions appear to be valid + // Fixes Issues #404 and #399 + owner = entity; + if (!this.world.isClient && world instanceof ServerWorld) { + // Send this to update all data? + attachLeash(owner, true); + } + + if(owner != null) { + ownerNbt = null; + if(owner instanceof LeashKnotEntity) { + max_mob_distance = 2.0; + } else if (owner instanceof MobEntity) { + // Longer leashes for larger mobs + Box bbox = entity.getBoundingBox(); + double a = bbox.getXLength(); + double b = bbox.getYLength(); + double c = bbox.getZLength(); + max_mob_distance = 1.3 * Math.sqrt(a * a + b * b + c * c); + } + } } - @Override - public boolean isLeashed() { - return true; + public void detachOwner() { + detachLeash(true, false); + if(owner != null && owner instanceof LeashKnotEntity) { + owner.discard(); + } + owner = null; } public void writeCustomDataToNbt(NbtCompound nbt) { super.writeCustomDataToNbt(nbt); nbt.putBoolean("CanLiftOff", helium); + if(owner != null) { + NbtCompound nbtCompound = new NbtCompound(); + if(owner instanceof LeashKnotEntity) { + BlockPos blockPos = ((LeashKnotEntity)owner).getDecorationBlockPos(); + nbtCompound.putInt("X", blockPos.getX()); + nbtCompound.putInt("Y", blockPos.getY()); + nbtCompound.putInt("Z", blockPos.getZ()); + } else { + UUID uUID = owner.getUuid(); + nbtCompound.putUuid("UUID", uUID); + } + + nbt.put("Owner", nbtCompound); + } else if (ownerNbt != null) { + nbt.put("Owner", ownerNbt.copy()); + } } public void readCustomDataFromNbt(NbtCompound nbt) { @@ -188,5 +226,23 @@ public void readCustomDataFromNbt(NbtCompound nbt) { if(nbt.contains("CanLiftOff")) { helium = nbt.getBoolean("CanLiftOff"); } + if(nbt.contains("Owner", 10)) { + ownerNbt = nbt.getCompound("Owner"); + } + } + + private void readOwnerNbt() { + if (ownerNbt != null && this.world instanceof ServerWorld) { + if (ownerNbt.containsUuid("UUID")) { + UUID uUID = ownerNbt.getUuid("UUID"); + Entity entity = ((ServerWorld)this.world).getEntity(uUID); + if (entity != null) { + attachOwner(entity); + } + } else if (ownerNbt.contains("X", 99) && ownerNbt.contains("Y", 99) && ownerNbt.contains("Z", 99)) { + BlockPos blockPos = NbtHelper.toBlockPos(ownerNbt); + attachOwner(LeashKnotEntity.getOrCreate(this.world, blockPos)); + } + } } } \ No newline at end of file diff --git a/src/main/java/be/minelabs/item/items/BalloonItem.java b/src/main/java/be/minelabs/item/items/BalloonItem.java index 94dd49f30..59d320f28 100644 --- a/src/main/java/be/minelabs/item/items/BalloonItem.java +++ b/src/main/java/be/minelabs/item/items/BalloonItem.java @@ -17,13 +17,9 @@ import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; -import java.util.Iterator; -import java.util.List; - public class BalloonItem extends Item { public BalloonItem(Item.Settings settings) { @@ -32,7 +28,7 @@ public BalloonItem(Item.Settings settings) { private BalloonEntity summon(World world, Entity entity) { BalloonEntity balloon = Entities.BALLOON.create(world); - balloon.refreshPositionAndAngles(entity.getX(), entity.getY(), entity.getZ(), 0.0F, 0.0F); + balloon.refreshPositionAndAngles(entity.getX(), entity.getY() + 1.0, entity.getZ(), 0.0F, 0.0F); world.spawnEntity(balloon); return balloon; } @@ -64,7 +60,7 @@ public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity if(!world.isClient) { if(!((MobEntity)entity).isLeashed()) { BalloonEntity be = summon(world, entity); - be.attachLeash(entity, true); + be.attachOwner(entity); stack.decrement(1); return ActionResult.SUCCESS; } @@ -84,9 +80,11 @@ public ActionResult useOnBlock(ItemUsageContext context) { LeashKnotEntity leashKnotEntity = LeashKnotEntity.getOrCreate(world, blockPos); leashKnotEntity.onPlace(); BalloonEntity be = summon(world, leashKnotEntity); - be.attachLeash(leashKnotEntity, true); + be.attachOwner(leashKnotEntity); world.emitGameEvent(GameEvent.BLOCK_ATTACH, blockPos, GameEvent.Emitter.of(playerEntity)); + + return ActionResult.SUCCESS; } return ActionResult.success(world.isClient); From 198cbf2228f09a2a3c2ae3a53e62422a18be390b Mon Sep 17 00:00:00 2001 From: RandyParedis Date: Sat, 11 Nov 2023 01:08:58 +0100 Subject: [PATCH 4/7] Balloon in player hand --- .../be/minelabs/client/item/ItemModels.java | 7 + .../java/be/minelabs/entity/Entities.java | 2 +- .../be/minelabs/entity/mob/BalloonEntity.java | 43 +++--- .../be/minelabs/item/items/BalloonItem.java | 78 ++++++++--- .../assets/minelabs/models/item/balloon.json | 131 ++---------------- .../minelabs/models/item/balloon_2d.json | 6 + .../minelabs/models/item/balloon_3d.json | 127 +++++++++++++++++ .../assets/minelabs/textures/item/balloon.png | Bin 223 -> 953 bytes .../minelabs/textures/item/balloon_3d.png | Bin 0 -> 223 bytes 9 files changed, 238 insertions(+), 156 deletions(-) create mode 100644 src/main/resources/assets/minelabs/models/item/balloon_2d.json create mode 100644 src/main/resources/assets/minelabs/models/item/balloon_3d.json create mode 100644 src/main/resources/assets/minelabs/textures/item/balloon_3d.png diff --git a/src/client/java/be/minelabs/client/item/ItemModels.java b/src/client/java/be/minelabs/client/item/ItemModels.java index 69d5f33e6..ed64e1e2a 100644 --- a/src/client/java/be/minelabs/client/item/ItemModels.java +++ b/src/client/java/be/minelabs/client/item/ItemModels.java @@ -17,6 +17,8 @@ public static void onInitializeClient() { registerBond(Items.BOND); registerValence(Items.VALENCEE); + + registerBalloon(Items.BALLOON); } /** @@ -74,4 +76,9 @@ private static void registerValence(Item item) { }); } } + + private static void registerBalloon(Item item) { + ModelPredicateProviderRegistry.register(item, new Identifier("filled"), + (stack, world, entity, seed) -> entity != null && entity.isUsingItem() && entity.getActiveItem() == stack ? 0.0f : 1.0f); + } } diff --git a/src/main/java/be/minelabs/entity/Entities.java b/src/main/java/be/minelabs/entity/Entities.java index 69e8c216f..b5edbff8d 100644 --- a/src/main/java/be/minelabs/entity/Entities.java +++ b/src/main/java/be/minelabs/entity/Entities.java @@ -40,7 +40,7 @@ public class Entities { .dimensions(EntityDimensions.fixed(0.6f, 1.7f)).build(), "entropy_creeper"); public static final EntityType BALLOON = register(FabricEntityTypeBuilder.create(SpawnGroup.MISC, BalloonEntity::new) - .dimensions(EntityDimensions.fixed(1.0f, 1.0f)).build(), "balloon"); + .dimensions(EntityDimensions.fixed(0.8f, 1.0f)).disableSummon().build(), "balloon"); public static final EntityType CORROSIVE_ENTITY = register(FabricEntityTypeBuilder.create(SpawnGroup.MISC, CorrosiveEntity::new) .dimensions(EntityDimensions.fixed(1.0f, 1.0f)).disableSummon().fireImmune().build(), "corrosive"); diff --git a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java index d52fc2d34..5458c2dcb 100644 --- a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java +++ b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java @@ -23,6 +23,7 @@ public class BalloonEntity extends MobEntity { private static final double MAX_DISTANCE = 10.0; private static final double MAX_HEIGHT = 320.0; + public static final double LEVITATION_SPEED = 0.11; private boolean helium = true; @@ -93,7 +94,7 @@ public void tick() { } if(helium) { - addStatusEffect(new StatusEffectInstance(StatusEffects.LEVITATION, 10, 3, false, false)); + setVelocity(new Vec3d(0.0, LEVITATION_SPEED, 0.0)); } Entity target = owner; // Prevent crashes when the target becomes null during the tick if(target != null) { @@ -109,25 +110,35 @@ public void tick() { kill(); return; } - if(distance >= max_mob_distance) { - double x = (tpos.getX() - this.getX()) / (double)distance; - double z = (tpos.getZ() - this.getZ()) / (double)distance; - // Fixes Issue #401 - Vec3d xz = new Vec3d(x, 0.0, z).normalize().multiply(0.1); - this.setVelocity(xz); + // Stop the jiggle + double x = tpos.getX() - this.getX(); + double z = tpos.getZ() - this.getZ(); + double d2 = Math.sqrt(x*x+z*z); + double factor; + if(d2 < 0.2) { + factor = 0; + } else if(d2 <= 1) { + factor = d2 * d2; + } else { + factor = Math.sqrt(d2); + } + Vec3d xz = new Vec3d(x, 0.0, z).normalize().multiply(factor/10); + addVelocity(xz); + if(distance >= max_mob_distance) { if(!(target instanceof LeashKnotEntity) && !(target instanceof MobEntity && ((MobEntity) target).isAiDisabled())) { - // The target might move around and should follow the levitation - - if(owner != null) { - // So apparently untamed rideables cannot be lifted in the air once saddled - // There is no reason for this, they just... can't... - // Let's just call this a feature :) - if(getY() - tpos.getY() > max_mob_distance) { - owner.setVelocity(new Vec3d(-xz.x, 0.11, -xz.z)); - } + // So apparently untamed rideables cannot be lifted in the air once saddled + // There is no reason for this, they just... can't... + // Let's just call this a feature for now... + if(getY() - tpos.getY() > max_mob_distance / 2.0) { + target.setVelocity(new Vec3d(0.0, LEVITATION_SPEED, 0.0)); + target.onLanding(); // prevent infinite fall damage accumulation } + } else { + // Don't go up anymore + Vec3d vel = getVelocity(); + setVelocity(vel.x, 0.0, vel.z); } } } else { diff --git a/src/main/java/be/minelabs/item/items/BalloonItem.java b/src/main/java/be/minelabs/item/items/BalloonItem.java index 59d320f28..dfc84ae88 100644 --- a/src/main/java/be/minelabs/item/items/BalloonItem.java +++ b/src/main/java/be/minelabs/item/items/BalloonItem.java @@ -3,27 +3,60 @@ import be.minelabs.entity.mob.BalloonEntity; import be.minelabs.entity.Entities; import net.minecraft.block.BlockState; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.DispenserBehavior; +import net.minecraft.block.dispenser.ItemDispenserBehavior; import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.decoration.LeashKnotEntity; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; +import net.minecraft.item.*; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.predicate.item.ItemPredicate; import net.minecraft.registry.tag.BlockTags; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.UseAction; +import net.minecraft.util.math.*; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; +import org.spongepowered.include.com.google.common.base.Predicates; + +import java.util.List; public class BalloonItem extends Item { + public BalloonItem(Item.Settings settings) { super(settings); + DispenserBlock.registerBehavior(this, BalloonItem.DISPENSER_BEHAVIOR); + } + + public static final DispenserBehavior DISPENSER_BEHAVIOR = new ItemDispenserBehavior() { + protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + if(stack.getItem() instanceof BalloonItem bi) { + return bi.dispense(pointer, stack) ? stack : super.dispenseSilently(pointer, stack); + } + return super.dispenseSilently(pointer, stack); + } + }; + + public boolean dispense(BlockPointer pointer, ItemStack balloon) { + BlockPos blockPos = pointer.getPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); + List list = pointer.getWorld().getEntitiesByClass(LivingEntity.class, new Box(blockPos), EntityPredicates.EXCEPT_SPECTATOR); + if (list.isEmpty()) { + return false; + } else { + LivingEntity livingEntity = (LivingEntity)list.get(0); + useOnEntity(balloon, balloon.getHolder(), livingEntity); + return true; + } } private BalloonEntity summon(World world, Entity entity) { @@ -34,27 +67,30 @@ private BalloonEntity summon(World world, Entity entity) { } @Override - public void inventoryTick(ItemStack itemStack, World world, Entity entity, int slot, boolean selected) { - super.inventoryTick(itemStack, world, entity, slot, selected); - if (!world.isClient()) { - if (entity instanceof PlayerEntity pe) { - if (!(pe.getAbilities().creativeMode)) { - if (pe.getOffHandStack().getItem() instanceof BalloonItem - || pe.getMainHandStack().getItem() instanceof BalloonItem) { - // TODO FIX custom effect (temp fix: use levitation) - //System.out.println("Try to fly: call effect"); - //StatusEffectInstance sei = new StatusEffectInstance(Effects.FLYING, 2, 2, false, false); - - StatusEffectInstance sei = new StatusEffectInstance(StatusEffects.LEVITATION, 4, 2, false, false); - pe.addStatusEffect(sei); - } - } - } + public void usageTick(World world, LivingEntity user, ItemStack stack, int remainingUseTicks) { + if (user instanceof PlayerEntity pe) { + Vec3d vel = pe.getVelocity(); + user.setVelocity(vel.x * 1.02, BalloonEntity.LEVITATION_SPEED, vel.z * 1.02); + user.onLanding(); } } + public int getMaxUseTime(ItemStack stack) { + return 7200; + } + + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + user.setCurrentHand(hand); + return ItemUsage.consumeHeldItem(world, user, hand); + } + @Override public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { + return useOnEntity(stack, user, entity); + } + + public ActionResult useOnEntity(ItemStack stack, Entity user, LivingEntity entity) { if(!(entity instanceof PlayerEntity) && !(entity instanceof BalloonEntity)) { World world = user.getWorld(); if(!world.isClient) { @@ -82,6 +118,8 @@ public ActionResult useOnBlock(ItemUsageContext context) { BalloonEntity be = summon(world, leashKnotEntity); be.attachOwner(leashKnotEntity); + context.getStack().decrement(1); + world.emitGameEvent(GameEvent.BLOCK_ATTACH, blockPos, GameEvent.Emitter.of(playerEntity)); return ActionResult.SUCCESS; diff --git a/src/main/resources/assets/minelabs/models/item/balloon.json b/src/main/resources/assets/minelabs/models/item/balloon.json index a66f5ea10..39591aa77 100644 --- a/src/main/resources/assets/minelabs/models/item/balloon.json +++ b/src/main/resources/assets/minelabs/models/item/balloon.json @@ -1,127 +1,20 @@ { - "credit": "Made with Blockbench", - "texture_size": [32, 32], + "parent": "item/generated", "textures": { - "0": "minelabs:item/balloon_string", - "1": "minelabs:item/balloon", - "particle": "minelabs:item/balloon" + "layer0": "minelabs:entity/balloon" }, - "elements": [ + "overrides": [ { - "from": [5, 11, 4], - "to": [11, 19, 10], - "faces": { - "north": {"uv": [0, 0, 3, 4], "texture": "#1"}, - "east": {"uv": [3, 0, 6, 4], "texture": "#1"}, - "south": {"uv": [0, 4, 3, 8], "texture": "#1"}, - "west": {"uv": [3, 4, 6, 8], "texture": "#1"}, - "up": {"uv": [9, 3, 6, 0], "texture": "#1"}, - "down": {"uv": [9, 3, 6, 6], "texture": "#1"} - } + "predicate": { + "filled": 0.0 + }, + "model": "minelabs:item/balloon_3d" }, { - "from": [6, 13, 10], - "to": [10, 18, 11], - "faces": { - "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} - } - }, - { - "from": [4, 13, 5], - "to": [5, 18, 9], - "faces": { - "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} - } - }, - { - "from": [6, 13, 3], - "to": [10, 18, 4], - "faces": { - "north": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} - } - }, - { - "from": [11, 13, 5], - "to": [12, 18, 9], - "faces": { - "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "east": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} - } - }, - { - "from": [6, 10, 5], - "to": [10, 11, 9], - "faces": { - "north": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "east": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "south": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 2], "texture": "#1"} - } - }, - { - "from": [7, 19, 6], - "to": [9, 20, 8], - "faces": { - "north": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "east": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "south": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "west": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, - "down": {"uv": [0, 0, 1, 1], "texture": "#1"} - } - }, - { - "from": [8, -9, 7], - "to": [8.25, 10.25, 7.25], - "faces": { - "north": {"uv": [0, 0, 1, 11], "texture": "#0"}, - "east": {"uv": [1, 0, 2, 11], "texture": "#0"}, - "south": {"uv": [2, 0, 3, 11], "texture": "#0"}, - "west": {"uv": [3, 0, 4, 11], "texture": "#0"}, - "up": {"uv": [5, 1, 4, 0], "texture": "#0"}, - "down": {"uv": [5, 1, 4, 2], "texture": "#0"} - } - } - ], - "display": { - "thirdperson_righthand": { - "rotation": [69, 0, 0], - "translation": [0, 5.5, 17] - }, - "thirdperson_lefthand": { - "rotation": [69, 0, 0], - "translation": [0, 5.5, 17] - }, - "firstperson_righthand": { - "translation": [0, 17, 0], - "scale": [1, 1.1, 1] - }, - "firstperson_lefthand": { - "translation": [0, 17, 0], - "scale": [1, 1.1, 1] - }, - "gui": { - "translation": [0, -6.25, 0] - }, - "fixed": { - "translation": [0, -3.75, 0] + "predicate": { + "filled": 1.0 + }, + "model": "minelabs:item/balloon_2d" } - } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/models/item/balloon_2d.json b/src/main/resources/assets/minelabs/models/item/balloon_2d.json new file mode 100644 index 000000000..2cfdd5e2a --- /dev/null +++ b/src/main/resources/assets/minelabs/models/item/balloon_2d.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "minelabs:item/balloon" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/models/item/balloon_3d.json b/src/main/resources/assets/minelabs/models/item/balloon_3d.json new file mode 100644 index 000000000..ecd6bf91a --- /dev/null +++ b/src/main/resources/assets/minelabs/models/item/balloon_3d.json @@ -0,0 +1,127 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "minelabs:item/balloon_string", + "1": "minelabs:item/balloon_3d", + "particle": "minelabs:item/balloon" + }, + "elements": [ + { + "from": [5, 11, 4], + "to": [11, 19, 10], + "faces": { + "north": {"uv": [0, 0, 3, 4], "texture": "#1"}, + "east": {"uv": [3, 0, 6, 4], "texture": "#1"}, + "south": {"uv": [0, 4, 3, 8], "texture": "#1"}, + "west": {"uv": [3, 4, 6, 8], "texture": "#1"}, + "up": {"uv": [9, 3, 6, 0], "texture": "#1"}, + "down": {"uv": [9, 3, 6, 6], "texture": "#1"} + } + }, + { + "from": [6, 13, 10], + "to": [10, 18, 11], + "faces": { + "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} + } + }, + { + "from": [4, 13, 5], + "to": [5, 18, 9], + "faces": { + "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 13, 3], + "to": [10, 18, 4], + "faces": { + "north": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} + } + }, + { + "from": [11, 13, 5], + "to": [12, 18, 9], + "faces": { + "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 10, 5], + "to": [10, 11, 9], + "faces": { + "north": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + }, + { + "from": [7, 19, 6], + "to": [9, 20, 8], + "faces": { + "north": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [8, -9, 7], + "to": [8.25, 10.25, 7.25], + "faces": { + "north": {"uv": [0, 0, 1, 11], "texture": "#0"}, + "east": {"uv": [1, 0, 2, 11], "texture": "#0"}, + "south": {"uv": [2, 0, 3, 11], "texture": "#0"}, + "west": {"uv": [3, 0, 4, 11], "texture": "#0"}, + "up": {"uv": [5, 1, 4, 0], "texture": "#0"}, + "down": {"uv": [5, 1, 4, 2], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [69, 0, 0], + "translation": [0, 5.5, 17] + }, + "thirdperson_lefthand": { + "rotation": [69, 0, 0], + "translation": [0, 5.5, 17] + }, + "firstperson_righthand": { + "translation": [0, 17, 0], + "scale": [1, 1.1, 1] + }, + "firstperson_lefthand": { + "translation": [0, 17, 0], + "scale": [1, 1.1, 1] + }, + "gui": { + "translation": [0, -6.25, 0] + }, + "fixed": { + "translation": [0, -3.75, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/textures/item/balloon.png b/src/main/resources/assets/minelabs/textures/item/balloon.png index d7cd51f29349e9750abe246a93579364876c3b0a..dd5adee0dc29b8ed356481b2ff95a14960b626fa 100644 GIT binary patch delta 932 zcmV;V16%yx0l5c|BYy#IX+uL$X=7sm04R}lkvmHRK@^3*B#IIvDHIj4ND;*%0Z|Z3 ziJ*;I#0W-hvYVHX$FjRYf~{a<5wH+#d=>r!Z3SBeK~Mw{J9}S^g!N7$M8wQ8dq2+1 zx!gSq?%AB4w^}A4U$D*SOeC-rUkTOu{YJTtE z)sakDI=I?}$92QBg=HFM*KI@bws5zeO(ca6g+rzcD14=Kt^sWPb)n(TJP?QKmmFaZeo0-%=7D-;_|K^{0lZ?WE<35C)^xAs}BX2m@3sLxaG7)v2Hk$)BIU9C(I)4^f(D>HH+>D^0*+iiNJ3in*(Rg`F-E-*7IA2pN`PL zt5JO3{aCc^!3hcxOM}_*wts>Dgg|^gpCi<+X&SZcStgX@wJ5|>`r<*nuIt^|4p6F( zzJDBdeRIZZtDAJ)AUlxh4O9DK)~7P&B^U$%Z3-cY_ccGltg5QJrV!>P* zy4Y}0jJ`*p{-+rq_ocuYn~yh~bj|OX=0K{sU_DOjA#K64N^oR%)0}Yhf`=Jk1vRgu zcINhbe1>_zXTo3yNH@m}0~$}VIXYp^%pJQB8K(BV7V8hP1`zX;GdHgQ0000GV-;)CT(1s@`dOBRbz zGPFZU2crxLqFVGO^O5;)5bAP_ZzvFR?ymg10l<(FhLkist_c9ZYnto?tjd1^EtOdu zKFU=EDl?XK70abuRbVf9Zkt%%=Bfe~7@n^oktD>HK4T0i!>;CL!JTO71 zZHkG_I!=ZI*|XlTtT|QBq&qcI#_m)otCsP!Qqj{(V?q=3EAwVY+ Date: Sun, 12 Nov 2023 22:56:54 +0100 Subject: [PATCH 5/7] Fixed dispenser + balloon in gui/hand split --- .../be/minelabs/client/item/ItemModels.java | 7 - .../client/mixin/ItemRendererMixin.java | 70 ++++++++++ .../resources/minelabs.client.mixins.json | 1 + src/main/java/be/minelabs/item/Items.java | 1 + .../be/minelabs/item/items/BalloonItem.java | 2 +- .../assets/minelabs/models/item/balloon.json | 131 ++++++++++++++++-- .../minelabs/models/item/balloon_3d.json | 127 ----------------- .../{balloon_2d.json => balloon_in_hand.json} | 0 8 files changed, 192 insertions(+), 147 deletions(-) create mode 100644 src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java delete mode 100644 src/main/resources/assets/minelabs/models/item/balloon_3d.json rename src/main/resources/assets/minelabs/models/item/{balloon_2d.json => balloon_in_hand.json} (100%) diff --git a/src/client/java/be/minelabs/client/item/ItemModels.java b/src/client/java/be/minelabs/client/item/ItemModels.java index ed64e1e2a..69d5f33e6 100644 --- a/src/client/java/be/minelabs/client/item/ItemModels.java +++ b/src/client/java/be/minelabs/client/item/ItemModels.java @@ -17,8 +17,6 @@ public static void onInitializeClient() { registerBond(Items.BOND); registerValence(Items.VALENCEE); - - registerBalloon(Items.BALLOON); } /** @@ -76,9 +74,4 @@ private static void registerValence(Item item) { }); } } - - private static void registerBalloon(Item item) { - ModelPredicateProviderRegistry.register(item, new Identifier("filled"), - (stack, world, entity, seed) -> entity != null && entity.isUsingItem() && entity.getActiveItem() == stack ? 0.0f : 1.0f); - } } diff --git a/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java b/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java new file mode 100644 index 000000000..f5af55b56 --- /dev/null +++ b/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java @@ -0,0 +1,70 @@ +package be.minelabs.client.mixin; + +import be.minelabs.item.Items; +import net.minecraft.block.Block; +import net.minecraft.block.StainedGlassPaneBlock; +import net.minecraft.block.TransparentBlock; +import net.minecraft.client.render.*; +import net.minecraft.client.render.item.ItemModels; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.render.model.json.ModelTransformationMode; +import net.minecraft.client.util.ModelIdentifier; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.Registries; +import net.minecraft.util.ActionResult; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(ItemRenderer.class) +public class ItemRendererMixin { + + @Shadow + private void renderBakedItemModel(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrices, VertexConsumer vertices) {} + + @Inject(method="getModel", at=@At(value="HEAD"), cancellable = true) + private void getModelInject(ItemStack stack, @Nullable World world, @Nullable LivingEntity entity, int seed, + CallbackInfoReturnable ci) { + // Always yield the balloon item in hand -- will ensure GUI lightning to be correct + if(stack.isOf(Items.BALLOON)) { + ItemModels models = ((ItemRenderer)(Object)this).getModels(); + ci.setReturnValue(models.getModel(Items.BALLOON_IN_HAND)); + } + } + + @Inject(method="renderItem", at=@At(value="INVOKE", target="Lnet/minecraft/client/render/item/ItemRenderer;renderBakedItemModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V"), + cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) + private void renderItemInject(ItemStack stack, ModelTransformationMode renderMode, boolean leftHanded, MatrixStack matrices, + VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, + CallbackInfo ci, boolean bl, boolean bl2, RenderLayer renderLayer, VertexConsumer vertexConsumer) { + // When the balloon is not in hand: obtain the other model + if(stack.isOf(Items.BALLOON) && !bl) { + // NOTE: might ignore enchanting... not tested + matrices.pop(); // cancels previous setup + + matrices.push(); + ItemModels models = ((ItemRenderer)(Object)this).getModels(); + model = models.getModel(Items.BALLOON); + model.getTransformation().getTransformation(renderMode).apply(leftHanded, matrices); + matrices.translate(-0.5f, -0.5f, -0.5f); + this.renderBakedItemModel(model, stack, light, overlay, matrices, vertexConsumer); + matrices.pop(); + + ci.cancel(); + } + } +} diff --git a/src/client/resources/minelabs.client.mixins.json b/src/client/resources/minelabs.client.mixins.json index cff08f18c..e9d105aad 100644 --- a/src/client/resources/minelabs.client.mixins.json +++ b/src/client/resources/minelabs.client.mixins.json @@ -4,6 +4,7 @@ "compatibilityLevel": "JAVA_17", "client": [ "InGameHudMixin", + "ItemRendererMixin", "LabCoatArmorItemMixin" ], "injectors": { diff --git a/src/main/java/be/minelabs/item/Items.java b/src/main/java/be/minelabs/item/Items.java index 1620167eb..07ba19726 100644 --- a/src/main/java/be/minelabs/item/Items.java +++ b/src/main/java/be/minelabs/item/Items.java @@ -232,6 +232,7 @@ public class Items { public static final Item MOLOGRAM = register(new BlockItem(Blocks.MOLOGRAM_BLOCK, new FabricItemSettings()), "mologram"); public static final Item BALLOON = register(new BalloonItem(new Item.Settings().maxCount(1)), "balloon"); + public static final Item BALLOON_IN_HAND = register(new Item(new Item.Settings()), "balloon_in_hand"); public static final Item BOHR_BLUEPRINT = register(new BlockItem(Blocks.BOHR_BLUEPRINT, new Item.Settings()), "bohr_block"); diff --git a/src/main/java/be/minelabs/item/items/BalloonItem.java b/src/main/java/be/minelabs/item/items/BalloonItem.java index dfc84ae88..ffc5b7d7c 100644 --- a/src/main/java/be/minelabs/item/items/BalloonItem.java +++ b/src/main/java/be/minelabs/item/items/BalloonItem.java @@ -54,7 +54,7 @@ public boolean dispense(BlockPointer pointer, ItemStack balloon) { return false; } else { LivingEntity livingEntity = (LivingEntity)list.get(0); - useOnEntity(balloon, balloon.getHolder(), livingEntity); + useOnEntity(balloon, livingEntity, livingEntity); return true; } } diff --git a/src/main/resources/assets/minelabs/models/item/balloon.json b/src/main/resources/assets/minelabs/models/item/balloon.json index 39591aa77..ecd6bf91a 100644 --- a/src/main/resources/assets/minelabs/models/item/balloon.json +++ b/src/main/resources/assets/minelabs/models/item/balloon.json @@ -1,20 +1,127 @@ { - "parent": "item/generated", + "credit": "Made with Blockbench", + "texture_size": [32, 32], "textures": { - "layer0": "minelabs:entity/balloon" + "0": "minelabs:item/balloon_string", + "1": "minelabs:item/balloon_3d", + "particle": "minelabs:item/balloon" }, - "overrides": [ + "elements": [ { - "predicate": { - "filled": 0.0 - }, - "model": "minelabs:item/balloon_3d" + "from": [5, 11, 4], + "to": [11, 19, 10], + "faces": { + "north": {"uv": [0, 0, 3, 4], "texture": "#1"}, + "east": {"uv": [3, 0, 6, 4], "texture": "#1"}, + "south": {"uv": [0, 4, 3, 8], "texture": "#1"}, + "west": {"uv": [3, 4, 6, 8], "texture": "#1"}, + "up": {"uv": [9, 3, 6, 0], "texture": "#1"}, + "down": {"uv": [9, 3, 6, 6], "texture": "#1"} + } }, { - "predicate": { - "filled": 1.0 - }, - "model": "minelabs:item/balloon_2d" + "from": [6, 13, 10], + "to": [10, 18, 11], + "faces": { + "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} + } + }, + { + "from": [4, 13, 5], + "to": [5, 18, 9], + "faces": { + "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 13, 3], + "to": [10, 18, 4], + "faces": { + "north": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} + } + }, + { + "from": [11, 13, 5], + "to": [12, 18, 9], + "faces": { + "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 10, 5], + "to": [10, 11, 9], + "faces": { + "north": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + }, + { + "from": [7, 19, 6], + "to": [9, 20, 8], + "faces": { + "north": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [8, -9, 7], + "to": [8.25, 10.25, 7.25], + "faces": { + "north": {"uv": [0, 0, 1, 11], "texture": "#0"}, + "east": {"uv": [1, 0, 2, 11], "texture": "#0"}, + "south": {"uv": [2, 0, 3, 11], "texture": "#0"}, + "west": {"uv": [3, 0, 4, 11], "texture": "#0"}, + "up": {"uv": [5, 1, 4, 0], "texture": "#0"}, + "down": {"uv": [5, 1, 4, 2], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [69, 0, 0], + "translation": [0, 5.5, 17] + }, + "thirdperson_lefthand": { + "rotation": [69, 0, 0], + "translation": [0, 5.5, 17] + }, + "firstperson_righthand": { + "translation": [0, 17, 0], + "scale": [1, 1.1, 1] + }, + "firstperson_lefthand": { + "translation": [0, 17, 0], + "scale": [1, 1.1, 1] + }, + "gui": { + "translation": [0, -6.25, 0] + }, + "fixed": { + "translation": [0, -3.75, 0] } - ] + } } \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/models/item/balloon_3d.json b/src/main/resources/assets/minelabs/models/item/balloon_3d.json deleted file mode 100644 index ecd6bf91a..000000000 --- a/src/main/resources/assets/minelabs/models/item/balloon_3d.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "credit": "Made with Blockbench", - "texture_size": [32, 32], - "textures": { - "0": "minelabs:item/balloon_string", - "1": "minelabs:item/balloon_3d", - "particle": "minelabs:item/balloon" - }, - "elements": [ - { - "from": [5, 11, 4], - "to": [11, 19, 10], - "faces": { - "north": {"uv": [0, 0, 3, 4], "texture": "#1"}, - "east": {"uv": [3, 0, 6, 4], "texture": "#1"}, - "south": {"uv": [0, 4, 3, 8], "texture": "#1"}, - "west": {"uv": [3, 4, 6, 8], "texture": "#1"}, - "up": {"uv": [9, 3, 6, 0], "texture": "#1"}, - "down": {"uv": [9, 3, 6, 6], "texture": "#1"} - } - }, - { - "from": [6, 13, 10], - "to": [10, 18, 11], - "faces": { - "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} - } - }, - { - "from": [4, 13, 5], - "to": [5, 18, 9], - "faces": { - "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} - } - }, - { - "from": [6, 13, 3], - "to": [10, 18, 4], - "faces": { - "north": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} - } - }, - { - "from": [11, 13, 5], - "to": [12, 18, 9], - "faces": { - "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "east": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} - } - }, - { - "from": [6, 10, 5], - "to": [10, 11, 9], - "faces": { - "north": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "east": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "south": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 2], "texture": "#1"} - } - }, - { - "from": [7, 19, 6], - "to": [9, 20, 8], - "faces": { - "north": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "east": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "south": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "west": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, - "down": {"uv": [0, 0, 1, 1], "texture": "#1"} - } - }, - { - "from": [8, -9, 7], - "to": [8.25, 10.25, 7.25], - "faces": { - "north": {"uv": [0, 0, 1, 11], "texture": "#0"}, - "east": {"uv": [1, 0, 2, 11], "texture": "#0"}, - "south": {"uv": [2, 0, 3, 11], "texture": "#0"}, - "west": {"uv": [3, 0, 4, 11], "texture": "#0"}, - "up": {"uv": [5, 1, 4, 0], "texture": "#0"}, - "down": {"uv": [5, 1, 4, 2], "texture": "#0"} - } - } - ], - "display": { - "thirdperson_righthand": { - "rotation": [69, 0, 0], - "translation": [0, 5.5, 17] - }, - "thirdperson_lefthand": { - "rotation": [69, 0, 0], - "translation": [0, 5.5, 17] - }, - "firstperson_righthand": { - "translation": [0, 17, 0], - "scale": [1, 1.1, 1] - }, - "firstperson_lefthand": { - "translation": [0, 17, 0], - "scale": [1, 1.1, 1] - }, - "gui": { - "translation": [0, -6.25, 0] - }, - "fixed": { - "translation": [0, -3.75, 0] - } - } -} \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/models/item/balloon_2d.json b/src/main/resources/assets/minelabs/models/item/balloon_in_hand.json similarity index 100% rename from src/main/resources/assets/minelabs/models/item/balloon_2d.json rename to src/main/resources/assets/minelabs/models/item/balloon_in_hand.json From a27d98c1afdf1318017c3877f198c1c42e25dd4e Mon Sep 17 00:00:00 2001 From: RandyParedis Date: Sat, 18 Nov 2023 15:44:44 +0100 Subject: [PATCH 6/7] Addressed PR comments --- .../client/mixin/ItemRendererAccessor.java | 12 ++ .../client/mixin/ItemRendererMixin.java | 64 ++------- .../client/mixin/ModelLoaderMixin.java | 28 ++++ .../resources/minelabs.client.mixins.json | 4 +- .../block/ExtraDispenserBehavior.java | 26 +++- .../be/minelabs/entity/mob/BalloonEntity.java | 8 ++ src/main/java/be/minelabs/item/Items.java | 1 - .../be/minelabs/item/items/BalloonItem.java | 66 +++------ .../assets/minelabs/models/item/balloon.json | 125 +---------------- .../minelabs/models/item/balloon_3d.json | 127 ++++++++++++++++++ .../minelabs/models/item/balloon_in_hand.json | 6 - .../loot_tables/entities/balloon.json | 8 +- 12 files changed, 238 insertions(+), 237 deletions(-) create mode 100644 src/client/java/be/minelabs/client/mixin/ItemRendererAccessor.java create mode 100644 src/client/java/be/minelabs/client/mixin/ModelLoaderMixin.java create mode 100644 src/main/resources/assets/minelabs/models/item/balloon_3d.json delete mode 100644 src/main/resources/assets/minelabs/models/item/balloon_in_hand.json diff --git a/src/client/java/be/minelabs/client/mixin/ItemRendererAccessor.java b/src/client/java/be/minelabs/client/mixin/ItemRendererAccessor.java new file mode 100644 index 000000000..dda2b23e2 --- /dev/null +++ b/src/client/java/be/minelabs/client/mixin/ItemRendererAccessor.java @@ -0,0 +1,12 @@ +package be.minelabs.client.mixin; + +import net.minecraft.client.render.item.ItemModels; +import net.minecraft.client.render.item.ItemRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ItemRenderer.class) +public interface ItemRendererAccessor { + @Accessor("models") + ItemModels getModels(); +} diff --git a/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java b/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java index f5af55b56..bdd16394c 100644 --- a/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java +++ b/src/client/java/be/minelabs/client/mixin/ItemRendererMixin.java @@ -1,70 +1,30 @@ package be.minelabs.client.mixin; +import be.minelabs.Minelabs; import be.minelabs.item.Items; -import net.minecraft.block.Block; -import net.minecraft.block.StainedGlassPaneBlock; -import net.minecraft.block.TransparentBlock; -import net.minecraft.client.render.*; -import net.minecraft.client.render.item.ItemModels; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.json.ModelTransformationMode; import net.minecraft.client.util.ModelIdentifier; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.LivingEntity; -import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; -import net.minecraft.registry.Registries; -import net.minecraft.util.ActionResult; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(ItemRenderer.class) -public class ItemRendererMixin { +public abstract class ItemRendererMixin { + @ModifyVariable(method = "renderItem", at = @At(value = "HEAD"), argsOnly = true) + public BakedModel useBalloonModel(BakedModel value, ItemStack stack, ModelTransformationMode renderMode, + boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, + int light, int overlay) { - @Shadow - private void renderBakedItemModel(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrices, VertexConsumer vertices) {} - - @Inject(method="getModel", at=@At(value="HEAD"), cancellable = true) - private void getModelInject(ItemStack stack, @Nullable World world, @Nullable LivingEntity entity, int seed, - CallbackInfoReturnable ci) { - // Always yield the balloon item in hand -- will ensure GUI lightning to be correct - if(stack.isOf(Items.BALLOON)) { - ItemModels models = ((ItemRenderer)(Object)this).getModels(); - ci.setReturnValue(models.getModel(Items.BALLOON_IN_HAND)); - } - } - - @Inject(method="renderItem", at=@At(value="INVOKE", target="Lnet/minecraft/client/render/item/ItemRenderer;renderBakedItemModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V"), - cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) - private void renderItemInject(ItemStack stack, ModelTransformationMode renderMode, boolean leftHanded, MatrixStack matrices, - VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, - CallbackInfo ci, boolean bl, boolean bl2, RenderLayer renderLayer, VertexConsumer vertexConsumer) { - // When the balloon is not in hand: obtain the other model - if(stack.isOf(Items.BALLOON) && !bl) { - // NOTE: might ignore enchanting... not tested - matrices.pop(); // cancels previous setup - - matrices.push(); - ItemModels models = ((ItemRenderer)(Object)this).getModels(); - model = models.getModel(Items.BALLOON); - model.getTransformation().getTransformation(renderMode).apply(leftHanded, matrices); - matrices.translate(-0.5f, -0.5f, -0.5f); - this.renderBakedItemModel(model, stack, light, overlay, matrices, vertexConsumer); - matrices.pop(); - - ci.cancel(); + // Do not render the balloon in 3D if it is in the GUI, on the ground, or in an item frame/armor stand + boolean bl = renderMode == ModelTransformationMode.GUI || renderMode == ModelTransformationMode.GROUND || renderMode == ModelTransformationMode.FIXED; + if (stack.isOf(Items.BALLOON) && !bl) { + return ((ItemRendererAccessor) this).getModels().getModelManager().getModel(new ModelIdentifier(Minelabs.MOD_ID, "balloon_3d", "inventory")); } + return value; } } diff --git a/src/client/java/be/minelabs/client/mixin/ModelLoaderMixin.java b/src/client/java/be/minelabs/client/mixin/ModelLoaderMixin.java new file mode 100644 index 000000000..795ca9270 --- /dev/null +++ b/src/client/java/be/minelabs/client/mixin/ModelLoaderMixin.java @@ -0,0 +1,28 @@ +package be.minelabs.client.mixin; + +import be.minelabs.Minelabs; +import net.minecraft.client.color.block.BlockColors; +import net.minecraft.client.render.model.ModelLoader; +import net.minecraft.client.render.model.json.JsonUnbakedModel; +import net.minecraft.client.util.ModelIdentifier; +import net.minecraft.util.Identifier; +import net.minecraft.util.profiler.Profiler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.Map; + +@Mixin(ModelLoader.class) +public abstract class ModelLoaderMixin { + @Shadow + protected abstract void addModel(ModelIdentifier modelId); + + @Inject(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/ModelLoader;addModel(Lnet/minecraft/client/util/ModelIdentifier;)V", ordinal = 3, shift = At.Shift.AFTER)) + public void addBalloon(BlockColors blockColors, Profiler profiler, Map jsonUnbakedModels, Map> blockStates, CallbackInfo ci) { + this.addModel(new ModelIdentifier(Minelabs.MOD_ID, "balloon_3d", "inventory")); + } +} diff --git a/src/client/resources/minelabs.client.mixins.json b/src/client/resources/minelabs.client.mixins.json index e9d105aad..5f8d6c851 100644 --- a/src/client/resources/minelabs.client.mixins.json +++ b/src/client/resources/minelabs.client.mixins.json @@ -4,8 +4,10 @@ "compatibilityLevel": "JAVA_17", "client": [ "InGameHudMixin", + "ItemRendererAccessor", "ItemRendererMixin", - "LabCoatArmorItemMixin" + "LabCoatArmorItemMixin", + "ModelLoaderMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/java/be/minelabs/block/ExtraDispenserBehavior.java b/src/main/java/be/minelabs/block/ExtraDispenserBehavior.java index ab1cf4f3a..c5f7ece68 100644 --- a/src/main/java/be/minelabs/block/ExtraDispenserBehavior.java +++ b/src/main/java/be/minelabs/block/ExtraDispenserBehavior.java @@ -2,21 +2,24 @@ import be.minelabs.entity.projectile.thrown.SubatomicParticleEntity; import be.minelabs.item.Items; +import be.minelabs.item.items.BalloonItem; import net.minecraft.block.DispenserBlock; import net.minecraft.block.dispenser.ItemDispenserBehavior; import net.minecraft.block.dispenser.ProjectileDispenserBehavior; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.SpawnEggItem; -import net.minecraft.util.math.BlockPointer; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.Position; +import net.minecraft.predicate.entity.EntityPredicates; +import net.minecraft.util.math.*; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; +import java.util.List; + public class ExtraDispenserBehavior { /** * Main class method @@ -59,6 +62,23 @@ protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { return stack; } }); + + DispenserBlock.registerBehavior(Items.BALLOON, new ItemDispenserBehavior() { + protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + if(stack.getItem() instanceof BalloonItem bi) { + BlockPos blockPos = pointer.getPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); + List list = pointer.getWorld().getEntitiesByClass(LivingEntity.class, new Box(blockPos), EntityPredicates.EXCEPT_SPECTATOR); + if (list.isEmpty()) { + return super.dispenseSilently(pointer, stack); + } else { + LivingEntity livingEntity = (LivingEntity)list.get(0); + bi.useOnEntity(stack, null, livingEntity, null); + return stack; + } + } + return super.dispenseSilently(pointer, stack); + } + }); } /** diff --git a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java index 5458c2dcb..795b92bfd 100644 --- a/src/main/java/be/minelabs/entity/mob/BalloonEntity.java +++ b/src/main/java/be/minelabs/entity/mob/BalloonEntity.java @@ -2,6 +2,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.ai.goal.SwimGoal; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.decoration.LeashKnotEntity; @@ -9,6 +10,7 @@ import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtHelper; import net.minecraft.server.world.ServerWorld; @@ -37,6 +39,7 @@ public BalloonEntity(EntityType entityType, World world) { super(entityType, world); setHealth(1.0F); setNoGravity(true); + setPersistent(); } // GETTERS AND SETTERS @@ -56,6 +59,11 @@ public Entity getOwner() { // GENERAL public void heal(float amount) {} + @Override + public boolean canPickupItem(ItemStack stack) { + return false; + } + @Override public void onDeath(DamageSource source) { detachOwner(); diff --git a/src/main/java/be/minelabs/item/Items.java b/src/main/java/be/minelabs/item/Items.java index 07ba19726..1620167eb 100644 --- a/src/main/java/be/minelabs/item/Items.java +++ b/src/main/java/be/minelabs/item/Items.java @@ -232,7 +232,6 @@ public class Items { public static final Item MOLOGRAM = register(new BlockItem(Blocks.MOLOGRAM_BLOCK, new FabricItemSettings()), "mologram"); public static final Item BALLOON = register(new BalloonItem(new Item.Settings().maxCount(1)), "balloon"); - public static final Item BALLOON_IN_HAND = register(new Item(new Item.Settings()), "balloon_in_hand"); public static final Item BOHR_BLUEPRINT = register(new BlockItem(Blocks.BOHR_BLUEPRINT, new Item.Settings()), "bohr_block"); diff --git a/src/main/java/be/minelabs/item/items/BalloonItem.java b/src/main/java/be/minelabs/item/items/BalloonItem.java index ffc5b7d7c..1b8faeb3c 100644 --- a/src/main/java/be/minelabs/item/items/BalloonItem.java +++ b/src/main/java/be/minelabs/item/items/BalloonItem.java @@ -4,59 +4,25 @@ import be.minelabs.entity.Entities; import net.minecraft.block.BlockState; import net.minecraft.block.DispenserBlock; -import net.minecraft.block.dispenser.DispenserBehavior; -import net.minecraft.block.dispenser.ItemDispenserBehavior; import net.minecraft.entity.Entity; -import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.decoration.LeashKnotEntity; -import net.minecraft.entity.effect.StatusEffectInstance; -import net.minecraft.entity.effect.StatusEffects; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.*; -import net.minecraft.nbt.NbtCompound; import net.minecraft.predicate.entity.EntityPredicates; -import net.minecraft.predicate.item.ItemPredicate; import net.minecraft.registry.tag.BlockTags; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; -import net.minecraft.util.UseAction; +import net.minecraft.util.*; import net.minecraft.util.math.*; import net.minecraft.world.World; import net.minecraft.world.event.GameEvent; -import org.spongepowered.include.com.google.common.base.Predicates; import java.util.List; - public class BalloonItem extends Item { public BalloonItem(Item.Settings settings) { super(settings); - DispenserBlock.registerBehavior(this, BalloonItem.DISPENSER_BEHAVIOR); - } - - public static final DispenserBehavior DISPENSER_BEHAVIOR = new ItemDispenserBehavior() { - protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { - if(stack.getItem() instanceof BalloonItem bi) { - return bi.dispense(pointer, stack) ? stack : super.dispenseSilently(pointer, stack); - } - return super.dispenseSilently(pointer, stack); - } - }; - - public boolean dispense(BlockPointer pointer, ItemStack balloon) { - BlockPos blockPos = pointer.getPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); - List list = pointer.getWorld().getEntitiesByClass(LivingEntity.class, new Box(blockPos), EntityPredicates.EXCEPT_SPECTATOR); - if (list.isEmpty()) { - return false; - } else { - LivingEntity livingEntity = (LivingEntity)list.get(0); - useOnEntity(balloon, livingEntity, livingEntity); - return true; - } } private BalloonEntity summon(World world, Entity entity) { @@ -82,28 +48,34 @@ public int getMaxUseTime(ItemStack stack) { @Override public TypedActionResult use(World world, PlayerEntity user, Hand hand) { user.setCurrentHand(hand); - return ItemUsage.consumeHeldItem(world, user, hand); + return TypedActionResult.pass(user.getStackInHand(hand)); } @Override public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { - return useOnEntity(stack, user, entity); - } - - public ActionResult useOnEntity(ItemStack stack, Entity user, LivingEntity entity) { if(!(entity instanceof PlayerEntity) && !(entity instanceof BalloonEntity)) { - World world = user.getWorld(); + World world = entity.getWorld(); if(!world.isClient) { - if(!((MobEntity)entity).isLeashed()) { + List list = entity.getWorld().getEntitiesByClass(BalloonEntity.class, + new Box(entity.getBlockPos()).expand(10), EntityPredicates.EXCEPT_SPECTATOR); + boolean isLeashed = false; + for(BalloonEntity be: list) { + if(be.getOwner().equals(entity)) { + isLeashed = true; + break; + } + } + + if(!isLeashed) { BalloonEntity be = summon(world, entity); be.attachOwner(entity); stack.decrement(1); - return ActionResult.SUCCESS; + return ActionResult.success(true); } - return ActionResult.FAIL; } + return ActionResult.success(false); } - return ActionResult.PASS; + return super.useOnEntity(stack, user, entity, hand); } public ActionResult useOnBlock(ItemUsageContext context) { @@ -122,12 +94,12 @@ public ActionResult useOnBlock(ItemUsageContext context) { world.emitGameEvent(GameEvent.BLOCK_ATTACH, blockPos, GameEvent.Emitter.of(playerEntity)); - return ActionResult.SUCCESS; + return ActionResult.CONSUME; } return ActionResult.success(world.isClient); } else { - return ActionResult.PASS; + return super.useOnBlock(context); } } } diff --git a/src/main/resources/assets/minelabs/models/item/balloon.json b/src/main/resources/assets/minelabs/models/item/balloon.json index ecd6bf91a..2cfdd5e2a 100644 --- a/src/main/resources/assets/minelabs/models/item/balloon.json +++ b/src/main/resources/assets/minelabs/models/item/balloon.json @@ -1,127 +1,6 @@ { - "credit": "Made with Blockbench", - "texture_size": [32, 32], + "parent": "item/generated", "textures": { - "0": "minelabs:item/balloon_string", - "1": "minelabs:item/balloon_3d", - "particle": "minelabs:item/balloon" - }, - "elements": [ - { - "from": [5, 11, 4], - "to": [11, 19, 10], - "faces": { - "north": {"uv": [0, 0, 3, 4], "texture": "#1"}, - "east": {"uv": [3, 0, 6, 4], "texture": "#1"}, - "south": {"uv": [0, 4, 3, 8], "texture": "#1"}, - "west": {"uv": [3, 4, 6, 8], "texture": "#1"}, - "up": {"uv": [9, 3, 6, 0], "texture": "#1"}, - "down": {"uv": [9, 3, 6, 6], "texture": "#1"} - } - }, - { - "from": [6, 13, 10], - "to": [10, 18, 11], - "faces": { - "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} - } - }, - { - "from": [4, 13, 5], - "to": [5, 18, 9], - "faces": { - "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} - } - }, - { - "from": [6, 13, 3], - "to": [10, 18, 4], - "faces": { - "north": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} - } - }, - { - "from": [11, 13, 5], - "to": [12, 18, 9], - "faces": { - "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "east": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, - "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, - "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} - } - }, - { - "from": [6, 10, 5], - "to": [10, 11, 9], - "faces": { - "north": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "east": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "south": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "west": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, - "down": {"uv": [0, 0, 2, 2], "texture": "#1"} - } - }, - { - "from": [7, 19, 6], - "to": [9, 20, 8], - "faces": { - "north": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "east": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "south": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "west": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, - "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, - "down": {"uv": [0, 0, 1, 1], "texture": "#1"} - } - }, - { - "from": [8, -9, 7], - "to": [8.25, 10.25, 7.25], - "faces": { - "north": {"uv": [0, 0, 1, 11], "texture": "#0"}, - "east": {"uv": [1, 0, 2, 11], "texture": "#0"}, - "south": {"uv": [2, 0, 3, 11], "texture": "#0"}, - "west": {"uv": [3, 0, 4, 11], "texture": "#0"}, - "up": {"uv": [5, 1, 4, 0], "texture": "#0"}, - "down": {"uv": [5, 1, 4, 2], "texture": "#0"} - } - } - ], - "display": { - "thirdperson_righthand": { - "rotation": [69, 0, 0], - "translation": [0, 5.5, 17] - }, - "thirdperson_lefthand": { - "rotation": [69, 0, 0], - "translation": [0, 5.5, 17] - }, - "firstperson_righthand": { - "translation": [0, 17, 0], - "scale": [1, 1.1, 1] - }, - "firstperson_lefthand": { - "translation": [0, 17, 0], - "scale": [1, 1.1, 1] - }, - "gui": { - "translation": [0, -6.25, 0] - }, - "fixed": { - "translation": [0, -3.75, 0] - } + "layer0": "minelabs:item/balloon" } } \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/models/item/balloon_3d.json b/src/main/resources/assets/minelabs/models/item/balloon_3d.json new file mode 100644 index 000000000..ecd6bf91a --- /dev/null +++ b/src/main/resources/assets/minelabs/models/item/balloon_3d.json @@ -0,0 +1,127 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "minelabs:item/balloon_string", + "1": "minelabs:item/balloon_3d", + "particle": "minelabs:item/balloon" + }, + "elements": [ + { + "from": [5, 11, 4], + "to": [11, 19, 10], + "faces": { + "north": {"uv": [0, 0, 3, 4], "texture": "#1"}, + "east": {"uv": [3, 0, 6, 4], "texture": "#1"}, + "south": {"uv": [0, 4, 3, 8], "texture": "#1"}, + "west": {"uv": [3, 4, 6, 8], "texture": "#1"}, + "up": {"uv": [9, 3, 6, 0], "texture": "#1"}, + "down": {"uv": [9, 3, 6, 6], "texture": "#1"} + } + }, + { + "from": [6, 13, 10], + "to": [10, 18, 11], + "faces": { + "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} + } + }, + { + "from": [4, 13, 5], + "to": [5, 18, 9], + "faces": { + "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 13, 3], + "to": [10, 18, 4], + "faces": { + "north": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "east": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#1"} + } + }, + { + "from": [11, 13, 5], + "to": [12, 18, 9], + "faces": { + "north": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "south": {"uv": [0, 0, 0.5, 2.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 2.5], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 0.5], "rotation": 270, "texture": "#1"}, + "down": {"uv": [0, 0, 2, 0.5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 10, 5], + "to": [10, 11, 9], + "faces": { + "north": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 0.5], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + }, + { + "from": [7, 19, 6], + "to": [9, 20, 8], + "faces": { + "north": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 0.5], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [8, -9, 7], + "to": [8.25, 10.25, 7.25], + "faces": { + "north": {"uv": [0, 0, 1, 11], "texture": "#0"}, + "east": {"uv": [1, 0, 2, 11], "texture": "#0"}, + "south": {"uv": [2, 0, 3, 11], "texture": "#0"}, + "west": {"uv": [3, 0, 4, 11], "texture": "#0"}, + "up": {"uv": [5, 1, 4, 0], "texture": "#0"}, + "down": {"uv": [5, 1, 4, 2], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [69, 0, 0], + "translation": [0, 5.5, 17] + }, + "thirdperson_lefthand": { + "rotation": [69, 0, 0], + "translation": [0, 5.5, 17] + }, + "firstperson_righthand": { + "translation": [0, 17, 0], + "scale": [1, 1.1, 1] + }, + "firstperson_lefthand": { + "translation": [0, 17, 0], + "scale": [1, 1.1, 1] + }, + "gui": { + "translation": [0, -6.25, 0] + }, + "fixed": { + "translation": [0, -3.75, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/minelabs/models/item/balloon_in_hand.json b/src/main/resources/assets/minelabs/models/item/balloon_in_hand.json deleted file mode 100644 index 2cfdd5e2a..000000000 --- a/src/main/resources/assets/minelabs/models/item/balloon_in_hand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "minelabs:item/balloon" - } -} \ No newline at end of file diff --git a/src/main/resources/data/minelabs/loot_tables/entities/balloon.json b/src/main/resources/data/minelabs/loot_tables/entities/balloon.json index 71a8e2d76..5179639b0 100644 --- a/src/main/resources/data/minelabs/loot_tables/entities/balloon.json +++ b/src/main/resources/data/minelabs/loot_tables/entities/balloon.json @@ -2,17 +2,17 @@ "type": "minecraft:entity", "pools": [ { - "rolls": 2, + "rolls": 1, "entries": [ { "type": "minecraft:item", - "name": "minecraft:rabbit_hide", + "name": "minecraft:leather", "functions": [ { "function": "minecraft:set_count", "count": { - "min": 1, - "max": 3 + "min": 0, + "max": 1 } } ] From 4e17e50b5fc3162a53fefe5df7dadd971dd1ed44 Mon Sep 17 00:00:00 2001 From: pixar02 Date: Tue, 21 Nov 2023 20:51:33 +0100 Subject: [PATCH 7/7] Update version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index edf28a845..b671044c7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19.4 yarn_mappings=1.19.4+build.2 loader_version=0.14.21 # Mod Properties -mod_version=1.0.1 +mod_version=1.0.2 maven_group=be.uantwerpen mod_id=minelabs archives_base_name=minelabs