- Fix hot air balloons not orienting correctly when placed

- add sandbags that you interact with to steer them
- fix various hitbox jankyness
- exclude spectators from hot air balloon collision checks
This commit is contained in:
Sollace 2024-03-29 20:31:49 +00:00
parent f8ff162d6c
commit f500956760
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
16 changed files with 373 additions and 177 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,33 @@
// Made with Blockbench 4.9.4
// Exported for Minecraft version 1.17+ for Yarn
// Paste this class into your mod and generate all required imports
public class hanging_sandbag extends EntityModel<Entity> {
private final ModelPart root;
private final ModelPart bag;
private final ModelPart cube_r1;
private final ModelPart cube_r2;
public hanging_sandbag(ModelPart root) {
this.root = root.getChild("root");
}
public static TexturedModelData getTexturedModelData() {
ModelData modelData = new ModelData();
ModelPartData modelPartData = modelData.getRoot();
ModelPartData root = modelPartData.addChild("root", ModelPartBuilder.create().uv(16, 19).cuboid(-0.5F, 0.0F, -0.5F, 1.0F, 9.0F, 1.0F, new Dilation(0.0F)), ModelTransform.pivot(0.0F, 24.0F, 0.0F));
ModelPartData bag = root.addChild("bag", ModelPartBuilder.create().uv(0, 0).cuboid(-3.0F, 1.0F, -3.0F, 6.0F, 7.0F, 6.0F, new Dilation(0.0F))
.uv(12, 14).cuboid(-2.0F, 0.0F, -2.0F, 4.0F, 1.0F, 4.0F, new Dilation(0.0F))
.uv(0, 13).cuboid(-2.0F, 8.0F, -2.0F, 4.0F, 1.0F, 4.0F, new Dilation(0.0F)), ModelTransform.pivot(0.0F, 9.0F, 0.0F));
ModelPartData cube_r1 = bag.addChild("cube_r1", ModelPartBuilder.create().uv(0, 14).cuboid(0.0F, 8.0F, -2.0F, 0.0F, 4.0F, 4.0F, new Dilation(0.0F)), ModelTransform.of(0.0F, 1.0F, 0.0F, 0.0F, -0.7854F, 0.0F));
ModelPartData cube_r2 = bag.addChild("cube_r2", ModelPartBuilder.create().uv(0, 14).cuboid(0.0F, 8.0F, -2.0F, 0.0F, 4.0F, 4.0F, new Dilation(0.0F)), ModelTransform.of(0.0F, 1.0F, 0.0F, 0.0F, 0.7854F, 0.0F));
return TexturedModelData.of(modelData, 32, 32);
}
@Override
public void setAngles(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
}
@Override
public void render(MatrixStack matrices, VertexConsumer vertexConsumer, int light, int overlay, float red, float green, float blue, float alpha) {
root.render(matrices, vertexConsumer, light, overlay, red, green, blue, alpha);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,113 +0,0 @@
{
"textures": {
"top": "blocks/hay_block_top",
"particle": "blocks/hay_block_side",
"side": "blocks/hay_block_side"
},
"elements": [
{
"name": "bottom_south_east",
"from": [8, 0, 8],
"to": [16, 8, 16],
"faces": {
"north": {"uv": [0, 8, 8, 16], "texture": "#top"},
"east": {"uv": [0, 8, 8, 16], "texture": "#side"},
"south": {"uv": [8, 8, 16, 16], "texture": "#side"},
"west": {"uv": [8, 8, 16, 16], "texture": "#top"},
"up": {"uv": [8, 8, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 8], "texture": "#top"}
}
},
{
"name": "top_south_east",
"from": [8, 8, 8],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 8, 8], "texture": "#top"},
"east": {"uv": [0, 0, 8, 8], "texture": "#side"},
"south": {"uv": [8, 0, 16, 8], "texture": "#side"},
"west": {"uv": [8, 0, 16, 8], "texture": "#top"},
"up": {"uv": [8, 8, 16, 16], "texture": "#top"},
"down": {"uv": [8, 0, 16, 8], "texture": "#top"}
}
},
{
"name": "bottom_north_east",
"from": [8, 0, 0],
"to": [16, 8, 8],
"faces": {
"north": {"uv": [0, 8, 8, 16], "texture": "#side"},
"east": {"uv": [8, 8, 16, 16], "texture": "#side"},
"south": {"uv": [8, 8, 16, 16], "texture": "#top"},
"west": {"uv": [0, 8, 8, 16], "texture": "#top"},
"up": {"uv": [8, 0, 16, 8], "texture": "#top"},
"down": {"uv": [8, 8, 16, 16], "texture": "#top"}
}
},
{
"name": "top_north_east",
"from": [8, 8, 0],
"to": [16, 16, 8],
"faces": {
"north": {"uv": [0, 0, 8, 8], "texture": "#side"},
"east": {"uv": [8, 0, 16, 8], "texture": "#side"},
"south": {"uv": [8, 0, 16, 8], "texture": "#top"},
"west": {"uv": [0, 0, 8, 8], "texture": "#top"},
"up": {"uv": [8, 0, 16, 8], "texture": "#top"},
"down": {"uv": [8, 8, 16, 16], "texture": "#top"}
}
},
{
"name": "bottom_south_west",
"from": [0, 0, 8],
"to": [8, 8, 16],
"faces": {
"north": {"uv": [8, 8, 16, 16], "texture": "#top"},
"east": {"uv": [0, 8, 8, 16], "texture": "#top"},
"south": {"uv": [0, 8, 8, 16], "texture": "#side"},
"west": {"uv": [8, 8, 16, 16], "texture": "#side"},
"up": {"uv": [0, 8, 8, 16], "texture": "#top"},
"down": {"uv": [0, 0, 8, 8], "texture": "#top"}
}
},
{
"name": "top_south_west",
"from": [0, 8, 8],
"to": [8, 16, 16],
"faces": {
"north": {"uv": [8, 0, 16, 8], "texture": "#top"},
"east": {"uv": [0, 0, 8, 8], "texture": "#top"},
"south": {"uv": [0, 0, 8, 8], "texture": "#side"},
"west": {"uv": [8, 0, 16, 8], "texture": "#side"},
"up": {"uv": [0, 8, 8, 16], "texture": "#top"},
"down": {"uv": [0, 0, 8, 8], "texture": "#top"}
}
},
{
"name": "bottom_north_west",
"from": [0, 0, 0],
"to": [8, 8, 8],
"faces": {
"north": {"uv": [8, 8, 16, 16], "texture": "#side"},
"east": {"uv": [8, 8, 16, 16], "texture": "#top"},
"south": {"uv": [0, 8, 8, 16], "texture": "#top"},
"west": {"uv": [0, 8, 8, 16], "texture": "#side"},
"up": {"uv": [0, 0, 8, 8], "texture": "#top"},
"down": {"uv": [0, 8, 8, 16], "texture": "#top"}
}
},
{
"name": "top_north_west",
"from": [0, 8, 0],
"to": [8, 16, 8],
"faces": {
"north": {"uv": [8, 0, 16, 8], "texture": "#side"},
"east": {"uv": [8, 0, 16, 8], "texture": "#top"},
"south": {"uv": [0, 0, 8, 8], "texture": "#top"},
"west": {"uv": [0, 0, 8, 8], "texture": "#side"},
"up": {"uv": [0, 0, 8, 8], "texture": "#top"},
"down": {"uv": [0, 8, 8, 16], "texture": "#top"}
}
}
]
}

View file

@ -4,6 +4,7 @@ import java.util.List;
import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.*; import net.minecraft.client.model.*;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.render.entity.model.EntityModel;
@ -14,26 +15,37 @@ import net.minecraft.util.math.MathHelper;
public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> { public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
private final ModelPart root; private final ModelPart root;
private ModelPart main;
private float inflation; private float inflation;
private boolean isBurner; private boolean isBurner;
private boolean isBalloon; private boolean isBalloon;
private boolean isSandbags;
private final List<ModelPart> ropes; private final List<ModelPart> ropes;
private final List<ModelPart> sandbags;
public AirBalloonEntityModel(ModelPart root) { public AirBalloonEntityModel(ModelPart root) {
this.root = root; this.root = root;
isBurner = root.hasChild("burner"); isBurner = root.hasChild("burner");
isSandbags = root.hasChild("sandbag_ne");
isBalloon = root.hasChild("canopy"); isBalloon = root.hasChild("canopy");
if (isBurner || isBalloon) { if (isBurner || isBalloon) {
ModelPart part = root.getChild(isBalloon ? "canopy" : "burner"); main = root.getChild(isBalloon ? "canopy" : "burner");
ropes = List.of(part.getChild("rope_a"), part.getChild("rope_b"), part.getChild("rope_c"), ropes = List.of(
part.getChild("rope_d")); (isBurner ? root : main).getChild("rope_a"), (isBurner ? root : main).getChild("rope_b"),
(isBurner ? root : main).getChild("rope_c"), (isBurner ? root : main).getChild("rope_d")
);
} else { } else {
ropes = List.of(); ropes = List.of();
} }
sandbags = isSandbags ? List.of(
root.getChild("sandbag_nw"), root.getChild("sandbag_sw"),
root.getChild("sandbag_ne"), root.getChild("sandbag_se")
) : List.of();
} }
public static TexturedModelData getBasketModelData() { public static TexturedModelData getBasketModelData() {
@ -56,12 +68,34 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
public static TexturedModelData getBurnerModelData() { public static TexturedModelData getBurnerModelData() {
ModelData modelData = new ModelData(); ModelData modelData = new ModelData();
ModelPartData root = modelData.getRoot(); ModelPartData root = modelData.getRoot();
root.addChild("burner", ModelPartBuilder.create().uv(8, 0).cuboid(-5.5F, -47, -5.5F, 11, 15, 11, Dilation.NONE), ModelTransform.pivot(0, 24, 0));
float angle = 0.37854F;
float half = MathHelper.HALF_PI;
root.addChild("rope_d", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of(-0, -20, -0, angle, 0, -angle));
root.addChild("rope_c", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of(-0, -20, -0, -angle, 0, -angle));
root.addChild("rope_b", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of( 0, -20, 0, -angle, 0, angle));
root.addChild("rope_a", ModelPartBuilder.create().cuboid(0, -68, 0, 2, 66, 2, Dilation.NONE), ModelTransform.of( 0, -20, 0, angle, 0, angle));
ModelPartData burner = root.addChild("burner", ModelPartBuilder.create().uv(8, 0).cuboid(-6, -47, -6, 11, 15, 11, Dilation.NONE), ModelTransform.pivot(0, 24, 0)); root.addChild("strut_a", ModelPartBuilder.create()
burner.addChild("rope_d", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-5, -46, -6, 0.7854F, 0, -0.7854F)); .cuboid(-27, -40, -30, 2, 40, 2, Dilation.NONE)
burner.addChild("rope_c", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(-4, -44, 3, -0.7854F, 0, -0.7854F)); .cuboid(-27, 0, -30, 2, 40, 2, Dilation.NONE)
burner.addChild("rope_b", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(5, -46, 1, -0.7854F, 0, 0.7854F)); .cuboid( 27, -40, -30, 2, 40, 2, Dilation.NONE)
burner.addChild("rope_a", ModelPartBuilder.create().cuboid(-2, -68, 0, 2, 68, 2, Dilation.NONE), ModelTransform.of(5, -45, -6, 0.7854F, 0, 0.7854F)); .cuboid( 27, 0, -30, 2, 40, 2, Dilation.NONE)
.cuboid(-27, -40, 26, 2, 40, 2, Dilation.NONE)
.cuboid(-27, 0, 26, 2, 40, 2, Dilation.NONE)
.cuboid( 27, -40, 26, 2, 40, 2, Dilation.NONE)
.cuboid( 27, 0, 26, 2, 40, 2, Dilation.NONE), ModelTransform.of(0, -80, 0, half, 0, 0));
root.addChild("strut_b", ModelPartBuilder.create()
.cuboid(-27, -40, -20, 2, 40, 2, Dilation.NONE)
.cuboid(-27, 0, -20, 2, 40, 2, Dilation.NONE)
.cuboid( 27, -40, -20, 2, 40, 2, Dilation.NONE)
.cuboid( 27, 0, -20, 2, 40, 2, Dilation.NONE)
.cuboid(-27, -40, 30, 2, 40, 2, Dilation.NONE)
.cuboid(-27, 0, 30, 2, 40, 2, Dilation.NONE)
.cuboid( 27, -40, 30, 2, 40, 2, Dilation.NONE)
.cuboid( 27, 0, 30, 2, 40, 2, Dilation.NONE), ModelTransform.of(0, -80, 0, half, half, 0));
return TexturedModelData.of(modelData, 64, 128); return TexturedModelData.of(modelData, 64, 128);
} }
@ -76,14 +110,40 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
return TexturedModelData.of(modelData, 512, 256); return TexturedModelData.of(modelData, 512, 256);
} }
public static TexturedModelData getSandbagsModelData() {
ModelData modelData = new ModelData();
ModelPartData root = modelData.getRoot();
float offset = 40;
getHangingBagModelData("sandbag_ne", root, -offset, -offset);
getHangingBagModelData("sandbag_nw", root, -offset, offset);
getHangingBagModelData("sandbag_se", root, offset, -offset);
getHangingBagModelData("sandbag_sw", root, offset, offset);
return TexturedModelData.of(modelData, 32, 32);
}
public static void getHangingBagModelData(String name, ModelPartData root, float x, float z) {
ModelPartData bag = root.addChild(name, ModelPartBuilder.create()
.uv(16, 19).cuboid(-0.5F, 0, -0.5F, 1, 9, 1, Dilation.NONE), ModelTransform.pivot(x, -35, z));
ModelPartData knot = bag.addChild("knot", ModelPartBuilder.create()
.uv(0, 0).cuboid(-3, 1, -3, 6, 7, 6, Dilation.NONE)
.uv(12, 14).cuboid(-2, 0, -2, 4, 1, 4, Dilation.NONE)
.uv(0, 13).cuboid(-2, 8, -2, 4, 1, 4, Dilation.NONE), ModelTransform.pivot(0, 9, 0));
knot.addChild("cube_r1", ModelPartBuilder.create().uv(8, 14).cuboid(0, 8, -2, 0, 4, 4, Dilation.NONE), ModelTransform.of(0, 1, 0, 0, -0.7854F, 0));
knot.addChild("cube_r2", ModelPartBuilder.create().uv(8, 14).cuboid(0, 8, -2, 0, 4, 4, Dilation.NONE), ModelTransform.of(0, 1, 0, 0, 0.7854F, 0));
}
@Override @Override
public void setAngles(AirBalloonEntity entity, float tickDelta, float limbSwingAmount, float ageInTicks, public void setAngles(AirBalloonEntity entity, float limbDistance, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
float netHeadYaw, float headPitch) { float tickDelta = MinecraftClient.getInstance().getTickDelta();
inflation = entity.getInflation(tickDelta); inflation = entity.getInflation(tickDelta);
if (isBurner || isBalloon) { root.yaw = MathHelper.PI;
root.roll = MathHelper.clamp((float) (entity.getX() - entity.lastRenderX), -0.5F, 0.5F);
root.pitch = MathHelper.clamp((float) (entity.getZ() - entity.lastRenderZ), -0.5F, 0.5F); float burnerWiggleProgress = entity.getBurner().getPullProgress(tickDelta);
if (isBurner || isBalloon || isSandbags) {
root.roll = MathHelper.clamp(entity.getXVelocity(tickDelta), -0.5F, 0.5F);
root.pitch = MathHelper.clamp(entity.getZVelocity(tickDelta), -0.5F, 0.5F);
if (entity.isLeashed()) { if (entity.isLeashed()) {
root.roll *= -1; root.roll *= -1;
root.pitch *= -1; root.pitch *= -1;
@ -93,27 +153,44 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
root.roll = 0; root.roll = 0;
} }
for (ModelPart rope : ropes) { ropes.forEach(ModelPart::resetTransform);
rope.resetTransform();
}
if (isBurner) { if (isBurner) {
boolean lifted = inflation > 0.8F; boolean lifted = inflation > 0.8F;
root.pivotY = 32 * (1 - inflation); root.pivotY = 32 * (1 - inflation) - (9 * inflation);
root.pivotX = inflation * MathHelper.sin(limbSwingAmount + entity.age / 5F) / 4F; root.pivotX = inflation * MathHelper.sin(limbSwingAmount + entity.age / 5F) / 4F;
ropes.forEach(rope -> { ropes.forEach(rope -> {
rope.visible = lifted; rope.visible = lifted;
rope.pitch *= 0.125;
rope.roll *= 0.125;
}); });
root.pivotX += burnerWiggleProgress * MathHelper.sin((entity.age + tickDelta)) * 2.5F;
root.pivotX += burnerWiggleProgress * MathHelper.cos((entity.age + tickDelta)) * 2.5F;
root.pivotY += burnerWiggleProgress * 7;
} }
if (isBalloon) { if (isBalloon || isSandbags) {
root.pivotY = 0; root.pivotY = burnerWiggleProgress * 3;
root.pivotX = inflation * MathHelper.cos(limbSwingAmount + entity.age / 5F) / 4F; root.pivotX = inflation * MathHelper.cos(limbSwingAmount + entity.age / 5F) / 4F;
if (entity.getBasketType().isOf(BoatEntity.Type.BAMBOO)) { if (entity.getBasketType().isOf(BoatEntity.Type.BAMBOO)) {
ropes.forEach(rope -> rope.pivotY = 0); ropes.forEach(rope -> rope.pivotY = 0);
} else { }
ropes.forEach(ModelPart::resetTransform); }
if (isSandbags) {
float cosWiggle = MathHelper.cos(limbSwingAmount + entity.age / 5F) / 80F;
float sinWiggle = MathHelper.sin(limbSwingAmount + entity.age / 5F) / 80F;
for (int i = 0; i < sandbags.size(); i++) {
ModelPart bag = sandbags.get(i);
float pullProgress = entity.getSandbag(i).getPullProgress(tickDelta);
bag.resetTransform();
bag.pitch -= root.pitch * 2.5F * (1 + pullProgress) + cosWiggle;
bag.roll -= root.roll * 2.5F * (1 + pullProgress) + sinWiggle;
if (entity.isLeashed()) {
bag.roll *= -1;
bag.pitch *= -1;
}
float pullAmount = 2 + (2 * pullProgress);
bag.yScale = pullAmount;
bag.getChild("knot").yScale = 1/pullAmount;
} }
} }
@ -138,6 +215,16 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
if (i == 0 || i == 1) { if (i == 0 || i == 1) {
rope.pivotX += 5 * rollRatio; rope.pivotX += 5 * rollRatio;
} }
if (isBalloon) {
double speed = Math.abs(entity.getVelocity().getY()) * 3F;
rope.zScale = MathHelper.clamp((float)speed, 0.25F, 1F);
rope.xScale = 0.001F;
} else {
rope.xScale = 0.3F;
rope.zScale = 0.3F;
}
} }
} }

View file

@ -1,9 +1,11 @@
package com.minelittlepony.unicopia.client.render.entity; package com.minelittlepony.unicopia.client.render.entity;
import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.entity.collision.MultiBox;
import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
@ -17,15 +19,22 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Box;
public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity, AirBalloonEntityModel> { public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity, AirBalloonEntityModel> {
public AirBalloonEntityRenderer(EntityRendererFactory.Context context) { public AirBalloonEntityRenderer(EntityRendererFactory.Context context) {
super(context, new AirBalloonEntityModel(AirBalloonEntityModel.getBasketModelData().createModel()), 0); super(context, new AirBalloonEntityModel(AirBalloonEntityModel.getBasketModelData().createModel()), 0);
addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getBurnerModelData().createModel()), this, AirBalloonEntity::hasBurner, e -> { addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getBurnerModelData().createModel()), this,
AirBalloonEntity::hasBurner, e -> {
return getComponentTexture(e.getStackInHand(Hand.MAIN_HAND).isOf(Items.SOUL_LANTERN) ? "soul_burner" : "burner"); return getComponentTexture(e.getStackInHand(Hand.MAIN_HAND).isOf(Items.SOUL_LANTERN) ? "soul_burner" : "burner");
})); }, (light, entity) -> entity.isAscending() ? 0xFF00FF : light));
addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, AirBalloonEntity::hasBalloon, e -> getComponentTexture("canopy/" + e.getDesign().asString()))); addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this,
AirBalloonEntity::hasBalloon,
e -> getComponentTexture("canopy/" + e.getDesign().asString()),
(light, entity) -> entity.hasBurner() && entity.isAscending() ? light | 0x00005F : light)
);
addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getSandbagsModelData().createModel()),
this, e -> e.hasBalloon() && e.getInflation(1) >= 1, e -> getComponentTexture("sandbags"),
(light, entity) -> entity.hasBurner() && entity.isAscending() ? light | 0x00003F : light));
} }
@Override @Override
@ -33,9 +42,9 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity
super.render(entity, yaw, tickDelta, matrices, vertices, light); super.render(entity, yaw, tickDelta, matrices, vertices, light);
if (MinecraftClient.getInstance().getEntityRenderDispatcher().shouldRenderHitboxes() && !entity.isInvisible() && !MinecraftClient.getInstance().hasReducedDebugInfo()) { if (MinecraftClient.getInstance().getEntityRenderDispatcher().shouldRenderHitboxes() && !entity.isInvisible() && !MinecraftClient.getInstance().hasReducedDebugInfo()) {
for (Box box : entity.getBoundingBoxes()) { MultiBox.forEach(entity.getBoundingBox(), box -> {
WorldRenderer.drawBox(matrices, vertices.getBuffer(RenderLayer.getLines()), box.offset(entity.getPos().multiply(-1)), 1.0f, 1.0f, 1.0f, 1.0f); WorldRenderer.drawBox(matrices, vertices.getBuffer(RenderLayer.getLines()), box.offset(entity.getPos().multiply(-1)), 1, 1, 1, 1);
} });
} }
} }
@ -57,22 +66,30 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity
private final AirBalloonEntityModel model; private final AirBalloonEntityModel model;
private final Predicate<AirBalloonEntity> visibilityTest; private final Predicate<AirBalloonEntity> visibilityTest;
private final Function<AirBalloonEntity, Identifier> textureFunc; private final Function<AirBalloonEntity, Identifier> textureFunc;
private final BiFunction<Integer, AirBalloonEntity, Integer> lightFunc;
public BalloonFeature(AirBalloonEntityModel model, public BalloonFeature(AirBalloonEntityModel model,
FeatureRendererContext<AirBalloonEntity, AirBalloonEntityModel> context, FeatureRendererContext<AirBalloonEntity, AirBalloonEntityModel> context,
Predicate<AirBalloonEntity> visibilityTest, Predicate<AirBalloonEntity> visibilityTest,
Function<AirBalloonEntity, Identifier> textureFunc) { Function<AirBalloonEntity, Identifier> textureFunc,
BiFunction<Integer, AirBalloonEntity, Integer> lightFunc) {
super(context); super(context);
this.model = model; this.model = model;
this.visibilityTest = visibilityTest; this.visibilityTest = visibilityTest;
this.textureFunc = textureFunc; this.textureFunc = textureFunc;
this.lightFunc = lightFunc;
} }
@Override @Override
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, AirBalloonEntity entity, public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, AirBalloonEntity entity,
float limbAngle, float limbDistance, float tickDelta, float animationProgress, float yaw, float pitch) { float limbAngle, float limbDistance, float tickDelta, float animationProgress, float yaw, float pitch) {
if (visibilityTest.test(entity)) { if (visibilityTest.test(entity)) {
render(getModel(), model, textureFunc.apply(entity), matrices, vertices, light, entity, limbAngle, limbDistance, 0, yaw, pitch, tickDelta, 1, 1, 1); Identifier texture = textureFunc.apply(entity);
var model = this.model;
if (texture.getPath().indexOf("sandbags") != -1) {
model = new AirBalloonEntityModel(AirBalloonEntityModel.getSandbagsModelData().createModel());
}
render(getModel(), model, texture, matrices, vertices, lightFunc.apply(light, entity), entity, limbAngle, limbDistance, 0, yaw, pitch, tickDelta, 1, 1, 1);
} }
} }
} }

View file

@ -14,6 +14,7 @@ import net.minecraft.block.ShapeContext;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.MovementType; import net.minecraft.entity.MovementType;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -124,6 +125,9 @@ public class Transportation<T extends LivingEntity> implements Tickable {
@Nullable @Nullable
private Box getVehicleBox() { private Box getVehicleBox() {
if (!EntityPredicates.EXCEPT_SPECTATOR.test(living.asEntity())) {
return null;
}
if (vehicle == null) { if (vehicle == null) {
return null; return null;
} }

View file

@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.entity.collision;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -24,6 +25,12 @@ public final class MultiBox extends Box {
return box instanceof MultiBox m ? m.first : box; return box instanceof MultiBox m ? m.first : box;
} }
public static void forEach(Box box, Consumer<Box> consumer) {
if (box instanceof MultiBox m) {
m.children.forEach(consumer);
}
}
private MultiBox(Box first, BoxChildren children) { private MultiBox(Box first, BoxChildren children) {
super(first.minX, first.minY, first.minZ, first.maxX, first.maxY, first.maxZ); super(first.minX, first.minY, first.minZ, first.maxX, first.maxY, first.maxZ);
this.first = unbox(first); this.first = unbox(first);
@ -148,6 +155,12 @@ public final class MultiBox extends Box {
return false; return false;
} }
public void forEach(Consumer<Box> consumer) {
for (int i = 0; i < children.length; i++) {
consumer.accept(children[i]);
}
}
@Override @Override
public String toString() { public String toString() {
return toString.get(); return toString.get();

View file

@ -39,10 +39,10 @@ import java.util.function.Function;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.EquineContext; import com.minelittlepony.unicopia.EquineContext;
import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.USounds; import com.minelittlepony.unicopia.USounds;
@ -65,6 +65,8 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
private static final TrackedData<String> BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.STRING); private static final TrackedData<String> BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.STRING);
private static final TrackedData<Integer> BALLOON_DESIGN = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); private static final TrackedData<Integer> BALLOON_DESIGN = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
public static final byte STATUS_BURNER_INTERACT = (byte)105;
private static final Predicate<Entity> RIDER_PREDICATE = EntityPredicates.EXCEPT_SPECTATOR.and(e -> { private static final Predicate<Entity> RIDER_PREDICATE = EntityPredicates.EXCEPT_SPECTATOR.and(e -> {
return !(e instanceof PlayerEntity p && p.getAbilities().flying); return !(e instanceof PlayerEntity p && p.getAbilities().flying);
}); });
@ -73,9 +75,17 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
private int prevInflation; private int prevInflation;
private Vec3d manualVelocity = Vec3d.ZERO; private Vec3d manualVelocity = Vec3d.ZERO;
private int maxFuel = 100; private int maxFuel = 10000;
private int fuel; private int fuel;
private final Animatable[] sandbags = IntStream.range(0, 5).mapToObj(Animatable::new).toArray(Animatable[]::new);
private final Animatable burner = new Animatable(5);
private double prevXDelta;
private double xDelta;
private double prevZDelta;
private double zDelta;
public AirBalloonEntity(EntityType<? extends AirBalloonEntity> type, World world) { public AirBalloonEntity(EntityType<? extends AirBalloonEntity> type, World world) {
super(type, world); super(type, world);
intersectionChecked = true; intersectionChecked = true;
@ -108,12 +118,20 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
dataTracker.set(BALLOON_DESIGN, design.ordinal()); dataTracker.set(BALLOON_DESIGN, design.ordinal());
} }
public Animatable getSandbag(int index) {
return sandbags[MathHelper.clamp(index, 0, sandbags.length - 1)];
}
public Animatable getBurner() {
return burner;
}
public boolean hasBalloon() { public boolean hasBalloon() {
return getDesign() != BalloonDesign.NONE; return getDesign() != BalloonDesign.NONE;
} }
public boolean hasBurner() { public boolean hasBurner() {
return !getStackInHand(Hand.MAIN_HAND).isEmpty(); return getHandItems() != null && !getStackInHand(Hand.MAIN_HAND).isEmpty();
} }
public float getInflation(float tickDelta) { public float getInflation(float tickDelta) {
@ -152,6 +170,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
return hasBalloon() && hasBurner() && getInflation() >= getMaxInflation(); return hasBalloon() && hasBurner() && getInflation() >= getMaxInflation();
} }
public float getXVelocity(float tickDelta) {
return (float)MathHelper.lerp(tickDelta, prevXDelta, xDelta);
}
public float getZVelocity(float tickDelta) {
return (float)MathHelper.lerp(tickDelta, prevZDelta, zDelta);
}
@Override @Override
public void tick() { public void tick() {
setAir(getMaxAir()); setAir(getMaxAir());
@ -179,8 +205,8 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
setInflation(inflation); setInflation(inflation);
} }
if (fuel > -6 && age % 60 == 0) { if (fuel > -6 && age % 2 == 0) {
fuel -= boosting ? 10 : 1; fuel -= boosting ? 50 : 1;
if (fuel <= -6) { if (fuel <= -6) {
setBoostTicks(0); setBoostTicks(0);
setAscending(false); setAscending(false);
@ -262,15 +288,26 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
setFireTicks(1); setFireTicks(1);
} }
for (Animatable bag : sandbags) {
bag.tick();
}
burner.tick();
super.tick(); super.tick();
prevXDelta = xDelta;
prevZDelta = zDelta;
xDelta = getX() - prevX;
zDelta = getZ() - prevZ;
} }
@Override @Override
public ActionResult interactAt(PlayerEntity player, Vec3d hitPos, Hand hand) { public ActionResult interactAt(PlayerEntity player, Vec3d hitPos, Hand hand) {
ItemStack stack = player.getStackInHand(hand); ItemStack stack = player.getStackInHand(hand);
if (hitPos.y > (3 * getInflation(1))) { if (hasBalloon() && hasBurner()) {
if (hasBalloon() && hasBurner()) {
if (getBurnerBoundingBox().expand(0.7).contains(getPos().add(hitPos))) {
if (stack.isOf(Items.FLINT_AND_STEEL)) { if (stack.isOf(Items.FLINT_AND_STEEL)) {
setAscending(!isAscending()); setAscending(!isAscending());
if (isAscending()) { if (isAscending()) {
@ -281,31 +318,45 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
if (!player.isSneaky()) { if (!player.isSneaky()) {
getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos());
} }
return ActionResult.SUCCESS; burner.setPulling();
}
if (stack.isEmpty() && Math.abs(hitPos.x) > 1 && Math.abs(hitPos.z) > 1) {
double xPush = Math.signum(hitPos.x);
double zPush = Math.signum(hitPos.z);
if (!getWorld().isClient) {
manualVelocity = manualVelocity.add(0.3 * xPush, 0, 0.3 * zPush);
}
getWorld().playSound(null, getX() + hitPos.getX(), getY() + hitPos.getY(), getZ() + hitPos.getZ(), USounds.Vanilla.ENTITY_LEASH_KNOT_PLACE, getSoundCategory(), 1, 1);
if (!player.isSneaky()) {
getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos());
}
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
if (stack.isEmpty() && isAscending()) { if (stack.isEmpty() && isAscending()) {
setBoostTicks(50); setBoostTicks(50);
playSound(USounds.ENTITY_HOT_AIR_BALLOON_BOOST, 1, 1); playSound(USounds.ENTITY_HOT_AIR_BALLOON_BOOST, 1, 1);
burner.setPulling();
if (!player.isSneaky()) { if (!player.isSneaky()) {
getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos()); getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos());
} }
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
} }
if (getInflation(1) >= 1) {
int xPush = (int)Math.signum(hitPos.x);
int zPush = (int)Math.signum(hitPos.z);
Vec3d absHitPos = getPos().add(hitPos);
if (stack.isEmpty() && MultiBox.unbox(getBoundingBox()).expand(0.5, 1, 0.5).offset(2 * xPush, 3, 2 * zPush).contains(absHitPos)) {
if (!getWorld().isClient) {
manualVelocity = manualVelocity.add(1.7 * xPush, 0, 1.7 * zPush);
}
getWorld().playSound(null, getX() + hitPos.getX(), getY() + hitPos.getY(), getZ() + hitPos.getZ(), USounds.Vanilla.ENTITY_LEASH_KNOT_PLACE, getSoundCategory(), 1, 1);
if (!player.isSneaky()) {
getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos());
}
Vec3d interactCoordinate = new Vec3d(xPush, 0, zPush)
.rotateY((180 + getHorizontalFacing().asRotation()) * MathHelper.RADIANS_PER_DEGREE)
;
getSandbag(MathHelper.clamp((int)interactCoordinate.getX(), 0, 1) + MathHelper.clamp((int)interactCoordinate.getZ(), 0, 1) * 2).setPulling();
return ActionResult.SUCCESS;
}
}
} }
return ActionResult.PASS; return ActionResult.PASS;
@ -368,6 +419,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
if (!player.getAbilities().creativeMode) { if (!player.getAbilities().creativeMode) {
stack.decrement(1); stack.decrement(1);
} }
burner.setPulling();
playSound(USounds.Vanilla.ENTITY_VILLAGER_YES, 1, 1); playSound(USounds.Vanilla.ENTITY_VILLAGER_YES, 1, 1);
return ActionResult.SUCCESS; return ActionResult.SUCCESS;
} }
@ -486,7 +538,26 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
@Override @Override
protected Box calculateBoundingBox() { protected Box calculateBoundingBox() {
return MultiBox.of(super.calculateBoundingBox(), getBoundingBoxes()); List<Box> boxes = getBoundingBoxes();
Box box = super.calculateBoundingBox();
if (hasBalloon() && getInflation(1) > 0.999F) {
double horScale = -0.5;
// x+ z+
boxes.add(box.expand(horScale, 1, horScale).offset(2, 3, 2));
// x- z+
boxes.add(box.expand(horScale, 1, horScale).offset(-2, 3, 2));
// x+ z-
boxes.add(box.expand(horScale, 1, horScale).offset(2, 3, -2));
// x- z-
boxes.add(box.expand(horScale, 1, horScale).offset(-2, 3, -2));
}
if (hasBurner()) {
boxes.add(getBurnerBoundingBox());
}
return MultiBox.of(box, boxes);
} }
@Override @Override
@ -509,6 +580,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
.expand(2.25, 3.7 * inflation, 2.25); .expand(2.25, 3.7 * inflation, 2.25);
} }
protected Box getBurnerBoundingBox() {
float inflation = getInflation(1);
float horScale = -0.9F;
return MultiBox.unbox(getBoundingBox())
.offset(0, 2.6F * inflation + 0.4F, 0)
.expand(horScale, 0.4, horScale);
}
@Override @Override
public List<Box> getGravityZoneBoxes() { public List<Box> getGravityZoneBoxes() {
Box balloon = getBalloonBoundingBox().expand(0.001); Box balloon = getBalloonBoundingBox().expand(0.001);
@ -528,29 +607,55 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
public List<Box> getBoundingBoxes() { public List<Box> getBoundingBoxes() {
List<Box> boxes = new ArrayList<>(); List<Box> boxes = new ArrayList<>();
Box box = getInteriorBoundingBox(); Box box = getInteriorBoundingBox();
Box mainBox = MultiBox.unbox(getBoundingBox());
boxes.add(box); boxes.add(box);
double wallheight = box.maxY + 0.72; double wallheight = box.maxY + 0.72;
double wallThickness = 0.2; double wallThickness = 0.3;
double halfDoorWidth = 0.5;
if (!getBasketType().isOf(BoatEntity.Type.BAMBOO)) { if (!getBasketType().isOf(BoatEntity.Type.BAMBOO)) {
// front left (next to door) // front left (next to door)
boxes.add(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness + 0.4, wallheight, box.minZ + wallThickness)); boxes.add(new Box(mainBox.minX, mainBox.minY, mainBox.minZ, mainBox.minX + wallThickness + halfDoorWidth, wallheight, box.minZ + wallThickness));
// front right (next to door) // front right (next to door)
boxes.add(new Box(box.maxX - wallThickness - 0.4, box.minY, box.minZ, box.maxX, wallheight, box.minZ + wallThickness)); boxes.add(new Box(mainBox.maxX - wallThickness - halfDoorWidth, mainBox.minY, mainBox.minZ, mainBox.maxX, wallheight, box.minZ + wallThickness));
// back // back
boxes.add(new Box(box.minX, box.minY, box.maxZ - wallThickness, box.maxX, wallheight, box.maxZ)); boxes.add(new Box(mainBox.minX, mainBox.minY, box.maxZ - wallThickness, mainBox.maxX, wallheight, mainBox.maxZ));
// left // left
boxes.add(new Box(box.maxX - wallThickness, box.minY, box.minZ, box.maxX, wallheight, box.maxZ)); boxes.add(new Box(box.maxX - wallThickness, mainBox.minY, mainBox.minZ, mainBox.maxX, wallheight, mainBox.maxZ));
// right // right
boxes.add(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness, wallheight, box.maxZ)); boxes.add(new Box(mainBox.minX, mainBox.minY, mainBox.minZ, box.minX + wallThickness, wallheight, mainBox.maxZ));
} }
if (hasBalloon() && getInflation(1) > 0.999F) { if (hasBalloon() && getInflation(1) >= 1) {
boxes.add(getBalloonBoundingBox()); Box balloonBox = getBalloonBoundingBox();
boxes.add(balloonBox.withMinY(balloonBox.maxY - 0.5));
boxes.add(balloonBox.withMaxX(balloonBox.minX + 0.5));
boxes.add(balloonBox.withMinX(balloonBox.maxX - 0.5));
boxes.add(balloonBox.withMaxZ(balloonBox.minZ + 0.5));
boxes.add(balloonBox.withMinZ(balloonBox.maxZ - 0.5));
boxes.add(balloonBox.withMaxX(balloonBox.minX + 2).withMaxY(balloonBox.minY + 0.2));
boxes.add(balloonBox.withMinX(balloonBox.maxX - 2).withMaxY(balloonBox.minY + 0.2));
boxes.add(balloonBox.withMaxZ(balloonBox.minZ + 2).withMaxY(balloonBox.minY + 0.2));
boxes.add(balloonBox.withMinZ(balloonBox.maxZ - 2).withMaxY(balloonBox.minY + 0.2));
} }
float yaw = (180 - getHorizontalFacing().asRotation()) * MathHelper.RADIANS_PER_DEGREE;
if (yaw != 0) {
Vec3d center = getPos();
for (int i = 0; i < boxes.size(); i++) {
Box b = boxes.get(i);
Vec3d min = new Vec3d(b.minX, b.minY, b.minZ).subtract(center).rotateY(yaw).add(center);
Vec3d max = new Vec3d(b.maxX, b.maxY, b.maxZ).subtract(center).rotateY(yaw).add(center);
boxes.set(i, new Box(min.x, min.y, min.z, max.x, max.y, max.z));
}
}
return boxes; return boxes;
} }
@ -574,6 +679,10 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
} }
private void movePassenger(Entity passenger, Vec3d movement) { private void movePassenger(Entity passenger, Vec3d movement) {
if (!EntityPredicates.EXCEPT_SPECTATOR.test(passenger)) {
return;
}
Living<?> living = Living.living(passenger); Living<?> living = Living.living(passenger);
if (living != null) { if (living != null) {
if (living.getPhysics().isGravityNegative()) { if (living.getPhysics().isGravityNegative()) {
@ -625,10 +734,54 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
compound.putInt("fuel", fuel); compound.putInt("fuel", fuel);
} }
@Override
public void handleStatus(byte status) {
if (status >= 100 && status < 100 + sandbags.length) {
getSandbag(status % sandbags.length).setPulling();
} else if (status == STATUS_BURNER_INTERACT) {
} else {
super.handleStatus(status);
}
}
static boolean isBetween(double value, double min, double max) { static boolean isBetween(double value, double min, double max) {
return value >= min && value <= max; return value >= min && value <= max;
} }
public class Animatable {
private final int id;
private int pullTicks;
private int prevPullTicks;
private boolean pulling;
public Animatable(int id) {
this.id = id;
}
public void setPulling() {
if (!getWorld().isClient) {
getWorld().sendEntityStatus(AirBalloonEntity.this, (byte)(100 + id));
}
pulling = true;
}
public float getPullProgress(float tickDelta) {
return MathHelper.lerp(tickDelta, (float)prevPullTicks, pullTicks) / 6F;
}
public void tick() {
prevPullTicks = pullTicks;
if (pulling && pullTicks < 6) {
pullTicks++;
} else {
pulling = false;
if (pullTicks > 0) {
pullTicks--;
}
}
}
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public enum BalloonDesign implements StringIdentifiable { public enum BalloonDesign implements StringIdentifiable {
NONE, NONE,

View file

@ -68,7 +68,7 @@ public class BasketItem extends Item implements Dispensable {
} }
if (hit.getType() == HitResult.Type.BLOCK) { if (hit.getType() == HitResult.Type.BLOCK) {
return placeEntity(stack, world, hit.getPos().x, hit.getPos().y, hit.getPos().z, user.getYaw() + 180, user); return placeEntity(stack, world, hit.getPos().x, hit.getPos().y, hit.getPos().z, user.getHorizontalFacing().asRotation(), user);
} }
return TypedActionResult.pass(stack); return TypedActionResult.pass(stack);
@ -76,9 +76,11 @@ public class BasketItem extends Item implements Dispensable {
private TypedActionResult<ItemStack> placeEntity(ItemStack stack, World world, double x, double y, double z, float yaw, @Nullable PlayerEntity user) { private TypedActionResult<ItemStack> placeEntity(ItemStack stack, World world, double x, double y, double z, float yaw, @Nullable PlayerEntity user) {
AirBalloonEntity entity = UEntities.AIR_BALLOON.create(world); AirBalloonEntity entity = UEntities.AIR_BALLOON.create(world);
entity.updatePositionAndAngles(x, y, z, 0, 0); yaw += 180;
entity.updatePositionAndAngles(x, y, z, yaw, 0);
entity.setHeadYaw(yaw); entity.setHeadYaw(yaw);
entity.setBodyYaw(yaw); entity.setBodyYaw(yaw);
entity.setYaw(yaw);
entity.setBasketType(type); entity.setBasketType(type);
if (!world.isSpaceEmpty(entity, entity.getBoundingBox())) { if (!world.isSpaceEmpty(entity, entity.getBoundingBox())) {
return TypedActionResult.fail(stack); return TypedActionResult.fail(stack);
@ -92,7 +94,6 @@ public class BasketItem extends Item implements Dispensable {
stack.decrement(1); stack.decrement(1);
} }
} }
return TypedActionResult.success(stack, world.isClient()); return TypedActionResult.success(stack, world.isClient());
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB