- 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
1
assets/models/hanging_sandbag.bbmodel
Normal file
33
assets/models/hanging_sandbag.java
Normal 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);
|
||||
}
|
||||
}
|
BIN
assets/models/hanging_sandbag.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
|
@ -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"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -4,6 +4,7 @@ import java.util.List;
|
|||
|
||||
import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.model.*;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
|
@ -14,26 +15,37 @@ import net.minecraft.util.math.MathHelper;
|
|||
public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
|
||||
|
||||
private final ModelPart root;
|
||||
private ModelPart main;
|
||||
|
||||
private float inflation;
|
||||
|
||||
private boolean isBurner;
|
||||
private boolean isBalloon;
|
||||
private boolean isSandbags;
|
||||
|
||||
private final List<ModelPart> ropes;
|
||||
private final List<ModelPart> sandbags;
|
||||
|
||||
public AirBalloonEntityModel(ModelPart root) {
|
||||
this.root = root;
|
||||
isBurner = root.hasChild("burner");
|
||||
isSandbags = root.hasChild("sandbag_ne");
|
||||
isBalloon = root.hasChild("canopy");
|
||||
|
||||
if (isBurner || isBalloon) {
|
||||
ModelPart part = root.getChild(isBalloon ? "canopy" : "burner");
|
||||
ropes = List.of(part.getChild("rope_a"), part.getChild("rope_b"), part.getChild("rope_c"),
|
||||
part.getChild("rope_d"));
|
||||
main = root.getChild(isBalloon ? "canopy" : "burner");
|
||||
ropes = List.of(
|
||||
(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 {
|
||||
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() {
|
||||
|
@ -56,12 +68,34 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
|
|||
public static TexturedModelData getBurnerModelData() {
|
||||
ModelData modelData = new ModelData();
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
root.addChild("strut_a", ModelPartBuilder.create()
|
||||
.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)
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
|
@ -76,14 +110,40 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
|
|||
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
|
||||
public void setAngles(AirBalloonEntity entity, float tickDelta, float limbSwingAmount, float ageInTicks,
|
||||
float netHeadYaw, float headPitch) {
|
||||
public void setAngles(AirBalloonEntity entity, float limbDistance, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) {
|
||||
float tickDelta = MinecraftClient.getInstance().getTickDelta();
|
||||
inflation = entity.getInflation(tickDelta);
|
||||
|
||||
if (isBurner || isBalloon) {
|
||||
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);
|
||||
root.yaw = MathHelper.PI;
|
||||
|
||||
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()) {
|
||||
root.roll *= -1;
|
||||
root.pitch *= -1;
|
||||
|
@ -93,27 +153,44 @@ public class AirBalloonEntityModel extends EntityModel<AirBalloonEntity> {
|
|||
root.roll = 0;
|
||||
}
|
||||
|
||||
for (ModelPart rope : ropes) {
|
||||
rope.resetTransform();
|
||||
}
|
||||
ropes.forEach(ModelPart::resetTransform);
|
||||
|
||||
if (isBurner) {
|
||||
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;
|
||||
ropes.forEach(rope -> {
|
||||
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) {
|
||||
root.pivotY = 0;
|
||||
if (isBalloon || isSandbags) {
|
||||
root.pivotY = burnerWiggleProgress * 3;
|
||||
root.pivotX = inflation * MathHelper.cos(limbSwingAmount + entity.age / 5F) / 4F;
|
||||
if (entity.getBasketType().isOf(BoatEntity.Type.BAMBOO)) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package com.minelittlepony.unicopia.client.render.entity;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.collision.MultiBox;
|
||||
import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -17,15 +19,22 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Box;
|
||||
|
||||
public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity, AirBalloonEntityModel> {
|
||||
public AirBalloonEntityRenderer(EntityRendererFactory.Context context) {
|
||||
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");
|
||||
}));
|
||||
addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, AirBalloonEntity::hasBalloon, e -> getComponentTexture("canopy/" + e.getDesign().asString())));
|
||||
}, (light, entity) -> entity.isAscending() ? 0xFF00FF : light));
|
||||
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
|
||||
|
@ -33,9 +42,9 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity
|
|||
super.render(entity, yaw, tickDelta, matrices, vertices, light);
|
||||
|
||||
if (MinecraftClient.getInstance().getEntityRenderDispatcher().shouldRenderHitboxes() && !entity.isInvisible() && !MinecraftClient.getInstance().hasReducedDebugInfo()) {
|
||||
for (Box box : entity.getBoundingBoxes()) {
|
||||
WorldRenderer.drawBox(matrices, vertices.getBuffer(RenderLayer.getLines()), box.offset(entity.getPos().multiply(-1)), 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
MultiBox.forEach(entity.getBoundingBox(), box -> {
|
||||
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 Predicate<AirBalloonEntity> visibilityTest;
|
||||
private final Function<AirBalloonEntity, Identifier> textureFunc;
|
||||
private final BiFunction<Integer, AirBalloonEntity, Integer> lightFunc;
|
||||
|
||||
public BalloonFeature(AirBalloonEntityModel model,
|
||||
FeatureRendererContext<AirBalloonEntity, AirBalloonEntityModel> context,
|
||||
Predicate<AirBalloonEntity> visibilityTest,
|
||||
Function<AirBalloonEntity, Identifier> textureFunc) {
|
||||
Function<AirBalloonEntity, Identifier> textureFunc,
|
||||
BiFunction<Integer, AirBalloonEntity, Integer> lightFunc) {
|
||||
super(context);
|
||||
this.model = model;
|
||||
this.visibilityTest = visibilityTest;
|
||||
this.textureFunc = textureFunc;
|
||||
this.lightFunc = lightFunc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, AirBalloonEntity entity,
|
||||
float limbAngle, float limbDistance, float tickDelta, float animationProgress, float yaw, float pitch) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import net.minecraft.block.ShapeContext;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.MovementType;
|
||||
import net.minecraft.predicate.entity.EntityPredicates;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -124,6 +125,9 @@ public class Transportation<T extends LivingEntity> implements Tickable {
|
|||
|
||||
@Nullable
|
||||
private Box getVehicleBox() {
|
||||
if (!EntityPredicates.EXCEPT_SPECTATOR.test(living.asEntity())) {
|
||||
return null;
|
||||
}
|
||||
if (vehicle == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.entity.collision;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -24,6 +25,12 @@ public final class MultiBox extends 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) {
|
||||
super(first.minX, first.minY, first.minZ, first.maxX, first.maxY, first.maxZ);
|
||||
this.first = unbox(first);
|
||||
|
@ -148,6 +155,12 @@ public final class MultiBox extends Box {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void forEach(Consumer<Box> consumer) {
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
consumer.accept(children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString.get();
|
||||
|
|
|
@ -39,10 +39,10 @@ import java.util.function.Function;
|
|||
import java.util.function.IntFunction;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.EquineContext;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
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<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 -> {
|
||||
return !(e instanceof PlayerEntity p && p.getAbilities().flying);
|
||||
});
|
||||
|
@ -73,9 +75,17 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
private int prevInflation;
|
||||
private Vec3d manualVelocity = Vec3d.ZERO;
|
||||
|
||||
private int maxFuel = 100;
|
||||
private int maxFuel = 10000;
|
||||
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) {
|
||||
super(type, world);
|
||||
intersectionChecked = true;
|
||||
|
@ -108,12 +118,20 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
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() {
|
||||
return getDesign() != BalloonDesign.NONE;
|
||||
}
|
||||
|
||||
public boolean hasBurner() {
|
||||
return !getStackInHand(Hand.MAIN_HAND).isEmpty();
|
||||
return getHandItems() != null && !getStackInHand(Hand.MAIN_HAND).isEmpty();
|
||||
}
|
||||
|
||||
public float getInflation(float tickDelta) {
|
||||
|
@ -152,6 +170,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
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
|
||||
public void tick() {
|
||||
setAir(getMaxAir());
|
||||
|
@ -179,8 +205,8 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
setInflation(inflation);
|
||||
}
|
||||
|
||||
if (fuel > -6 && age % 60 == 0) {
|
||||
fuel -= boosting ? 10 : 1;
|
||||
if (fuel > -6 && age % 2 == 0) {
|
||||
fuel -= boosting ? 50 : 1;
|
||||
if (fuel <= -6) {
|
||||
setBoostTicks(0);
|
||||
setAscending(false);
|
||||
|
@ -262,15 +288,26 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
setFireTicks(1);
|
||||
}
|
||||
|
||||
for (Animatable bag : sandbags) {
|
||||
bag.tick();
|
||||
}
|
||||
burner.tick();
|
||||
|
||||
super.tick();
|
||||
|
||||
prevXDelta = xDelta;
|
||||
prevZDelta = zDelta;
|
||||
xDelta = getX() - prevX;
|
||||
zDelta = getZ() - prevZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult interactAt(PlayerEntity player, Vec3d hitPos, Hand 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)) {
|
||||
setAscending(!isAscending());
|
||||
if (isAscending()) {
|
||||
|
@ -281,31 +318,45 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
if (!player.isSneaky()) {
|
||||
getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos());
|
||||
}
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
burner.setPulling();
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if (stack.isEmpty() && isAscending()) {
|
||||
setBoostTicks(50);
|
||||
playSound(USounds.ENTITY_HOT_AIR_BALLOON_BOOST, 1, 1);
|
||||
burner.setPulling();
|
||||
if (!player.isSneaky()) {
|
||||
getWorld().emitGameEvent(player, GameEvent.ENTITY_INTERACT, getBlockPos());
|
||||
}
|
||||
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;
|
||||
|
@ -368,6 +419,7 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
if (!player.getAbilities().creativeMode) {
|
||||
stack.decrement(1);
|
||||
}
|
||||
burner.setPulling();
|
||||
playSound(USounds.Vanilla.ENTITY_VILLAGER_YES, 1, 1);
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
@ -486,7 +538,26 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
|
||||
@Override
|
||||
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
|
||||
|
@ -509,6 +580,14 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
.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
|
||||
public List<Box> getGravityZoneBoxes() {
|
||||
Box balloon = getBalloonBoundingBox().expand(0.001);
|
||||
|
@ -528,29 +607,55 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
public List<Box> getBoundingBoxes() {
|
||||
List<Box> boxes = new ArrayList<>();
|
||||
Box box = getInteriorBoundingBox();
|
||||
Box mainBox = MultiBox.unbox(getBoundingBox());
|
||||
|
||||
boxes.add(box);
|
||||
|
||||
double wallheight = box.maxY + 0.72;
|
||||
double wallThickness = 0.2;
|
||||
double wallThickness = 0.3;
|
||||
double halfDoorWidth = 0.5;
|
||||
|
||||
if (!getBasketType().isOf(BoatEntity.Type.BAMBOO)) {
|
||||
|
||||
// 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)
|
||||
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
|
||||
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
|
||||
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
|
||||
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) {
|
||||
boxes.add(getBalloonBoundingBox());
|
||||
if (hasBalloon() && getInflation(1) >= 1) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -574,6 +679,10 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
}
|
||||
|
||||
private void movePassenger(Entity passenger, Vec3d movement) {
|
||||
if (!EntityPredicates.EXCEPT_SPECTATOR.test(passenger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Living<?> living = Living.living(passenger);
|
||||
if (living != null) {
|
||||
if (living.getPhysics().isGravityNegative()) {
|
||||
|
@ -625,10 +734,54 @@ public class AirBalloonEntity extends MobEntity implements EntityCollisions.Comp
|
|||
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) {
|
||||
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")
|
||||
public enum BalloonDesign implements StringIdentifiable {
|
||||
NONE,
|
||||
|
|
|
@ -68,7 +68,7 @@ public class BasketItem extends Item implements Dispensable {
|
|||
}
|
||||
|
||||
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);
|
||||
|
@ -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) {
|
||||
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.setBodyYaw(yaw);
|
||||
entity.setYaw(yaw);
|
||||
entity.setBasketType(type);
|
||||
if (!world.isSpaceEmpty(entity, entity.getBoundingBox())) {
|
||||
return TypedActionResult.fail(stack);
|
||||
|
@ -92,7 +94,6 @@ public class BasketItem extends Item implements Dispensable {
|
|||
stack.decrement(1);
|
||||
}
|
||||
}
|
||||
|
||||
return TypedActionResult.success(stack, world.isClient());
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 1.1 KiB |