Implement the different types of baskets
|
@ -14,13 +14,17 @@ import net.minecraft.client.render.entity.*;
|
||||||
import net.minecraft.client.render.entity.feature.FeatureRenderer;
|
import net.minecraft.client.render.entity.feature.FeatureRenderer;
|
||||||
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
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.Identifier;
|
||||||
import net.minecraft.util.math.Box;
|
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 -> getComponentTexture("burner")));
|
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())));
|
addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, AirBalloonEntity::hasBalloon, e -> getComponentTexture("canopy/" + e.getDesign().asString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package com.minelittlepony.unicopia.entity;
|
package com.minelittlepony.unicopia.entity;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.ShapeContext;
|
import net.minecraft.block.ShapeContext;
|
||||||
import net.minecraft.entity.*;
|
import net.minecraft.entity.*;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import net.minecraft.entity.data.*;
|
import net.minecraft.entity.data.*;
|
||||||
import net.minecraft.entity.mob.FlyingEntity;
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.vehicle.BoatEntity;
|
import net.minecraft.entity.vehicle.BoatEntity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
@ -11,6 +13,7 @@ import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.particle.ParticleTypes;
|
import net.minecraft.particle.ParticleTypes;
|
||||||
|
import net.minecraft.predicate.entity.EntityPredicates;
|
||||||
import net.minecraft.sound.SoundEvents;
|
import net.minecraft.sound.SoundEvents;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
@ -27,6 +30,7 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.entity.collision.EntityCollisions;
|
import com.minelittlepony.unicopia.entity.collision.EntityCollisions;
|
||||||
import com.minelittlepony.unicopia.entity.collision.MultiBox;
|
import com.minelittlepony.unicopia.entity.collision.MultiBox;
|
||||||
|
@ -35,10 +39,10 @@ import com.minelittlepony.unicopia.item.HotAirBalloonItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.server.world.WeatherConditions;
|
import com.minelittlepony.unicopia.server.world.WeatherConditions;
|
||||||
|
|
||||||
public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.ComplexCollidable, MultiBoundingBoxEntity {
|
public class AirBalloonEntity extends MobEntity implements EntityCollisions.ComplexCollidable, MultiBoundingBoxEntity {
|
||||||
private static final byte HAS_BURNER = 2;
|
private static final Predicate<Entity> CRUSHABLE_PREDICATE = EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR.and(EntityPredicates.VALID_LIVING_ENTITY);
|
||||||
private static final byte BURNER_ACTIVE = 4;
|
|
||||||
private static final TrackedData<Integer> BURNER_FLAGS = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
private static final TrackedData<Boolean> ASCENDING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||||
private static final TrackedData<Integer> BOOSTING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
private static final TrackedData<Integer> BOOSTING = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||||
private static final TrackedData<Integer> INFLATION = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
private static final TrackedData<Integer> INFLATION = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||||
private static final TrackedData<Integer> BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
private static final TrackedData<Integer> BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||||
|
@ -58,7 +62,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
@Override
|
@Override
|
||||||
protected void initDataTracker() {
|
protected void initDataTracker() {
|
||||||
super.initDataTracker();
|
super.initDataTracker();
|
||||||
dataTracker.startTracking(BURNER_FLAGS, 0);
|
dataTracker.startTracking(ASCENDING, false);
|
||||||
dataTracker.startTracking(BOOSTING, 0);
|
dataTracker.startTracking(BOOSTING, 0);
|
||||||
dataTracker.startTracking(INFLATION, 0);
|
dataTracker.startTracking(INFLATION, 0);
|
||||||
dataTracker.startTracking(BASKET_TYPE, 0);
|
dataTracker.startTracking(BASKET_TYPE, 0);
|
||||||
|
@ -86,11 +90,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasBurner() {
|
public boolean hasBurner() {
|
||||||
return getFlag(HAS_BURNER);
|
return !getStackInHand(Hand.MAIN_HAND).isEmpty();
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasBurner(boolean hasBurner) {
|
|
||||||
setFlag(HAS_BURNER, hasBurner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getInflation(float tickDelta) {
|
public float getInflation(float tickDelta) {
|
||||||
|
@ -109,12 +109,12 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBurnerActive() {
|
public boolean isAscending() {
|
||||||
return hasBalloon() && getFlag((byte)(HAS_BURNER | BURNER_ACTIVE));
|
return hasBalloon() && dataTracker.get(ASCENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBurnerActive(boolean burnerActive) {
|
public void setAscending(boolean ascending) {
|
||||||
setFlag(BURNER_ACTIVE, burnerActive);
|
dataTracker.set(ASCENDING, ascending);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBoostTicks() {
|
public int getBoostTicks() {
|
||||||
|
@ -125,17 +125,8 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
dataTracker.set(BOOSTING, ticks);
|
dataTracker.set(BOOSTING, ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getFlag(byte flag) {
|
|
||||||
return (dataTracker.get(BURNER_FLAGS).intValue() & flag) == flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setFlag(byte flag, boolean val) {
|
|
||||||
int v = dataTracker.get(BURNER_FLAGS);
|
|
||||||
dataTracker.set(BURNER_FLAGS, val ? (v | flag) : (v & ~flag));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isAirworthy() {
|
private boolean isAirworthy() {
|
||||||
return hasBalloon() && isBurnerActive();
|
return hasBalloon() && hasBurner() && getInflation() >= getMaxInflation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -164,7 +155,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
|
|
||||||
boolean boosting = boostTicks > 0;
|
boolean boosting = boostTicks > 0;
|
||||||
|
|
||||||
if (hasBurner() && isBurnerActive()) {
|
if (hasBurner() && isAscending()) {
|
||||||
if (inflation < getMaxInflation()) {
|
if (inflation < getMaxInflation()) {
|
||||||
inflation++;
|
inflation++;
|
||||||
if (boosting) {
|
if (boosting) {
|
||||||
|
@ -178,21 +169,26 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addVelocity(0, isBurnerActive() && inflation >= getMaxInflation() ? 0.005 : -0.013, 0);
|
if (isAirworthy()) {
|
||||||
|
addVelocity(0, isAscending() && inflation >= getMaxInflation() ? 0.005 : -0.013, 0);
|
||||||
addVelocity(manualVelocity.multiply(0.1));
|
addVelocity(manualVelocity.multiply(0.1));
|
||||||
|
}
|
||||||
manualVelocity = manualVelocity.multiply(0.9);
|
manualVelocity = manualVelocity.multiply(0.9);
|
||||||
|
|
||||||
if (!isAirworthy() && isSubmergedInWater()) {
|
if (!(hasBalloon() && isAscending()) && isSubmergedInWater()) {
|
||||||
setVelocity(getVelocity().multiply(0.9, 0.4, 0.9).add(0, 0.02, 0));
|
setVelocity(getVelocity().multiply(0.9, 0.4, 0.9).add(0, 0.02, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
Random rng = getWorld().random;
|
Random rng = getWorld().random;
|
||||||
|
|
||||||
if (getWorld().isClient()) {
|
if (getWorld().isClient()) {
|
||||||
if (hasBurner() && isBurnerActive()) {
|
if (hasBurner() && isAscending()) {
|
||||||
Vec3d burnerPos = getPos().add(0, 3, 0);
|
Vec3d burnerPos = getPos().add(0, 3, 0);
|
||||||
for (int i = 0; i < (boosting ? 6 : 1); i++) {
|
for (int i = 0; i < (boosting ? 6 : 1); i++) {
|
||||||
getWorld().addParticle(ParticleTypes.FLAME,
|
getWorld().addParticle(
|
||||||
|
getStackInHand(Hand.MAIN_HAND).isOf(Items.SOUL_LANTERN)
|
||||||
|
? ParticleTypes.SOUL_FIRE_FLAME
|
||||||
|
: ParticleTypes.FLAME,
|
||||||
rng.nextTriangular(burnerPos.x, 0.25),
|
rng.nextTriangular(burnerPos.x, 0.25),
|
||||||
rng.nextTriangular(burnerPos.y, 1),
|
rng.nextTriangular(burnerPos.y, 1),
|
||||||
rng.nextTriangular(burnerPos.z, 0.25),
|
rng.nextTriangular(burnerPos.z, 0.25),
|
||||||
|
@ -203,7 +199,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (inflation >= getMaxInflation()) {
|
} else if (inflation >= getMaxInflation()) {
|
||||||
if (hasBurner() && isBurnerActive()) {
|
if (hasBurner() && isAscending()) {
|
||||||
addVelocity(WeatherConditions.getAirflow(getBlockPos(), getWorld()).multiply(0.2));
|
addVelocity(WeatherConditions.getAirflow(getBlockPos(), getWorld()).multiply(0.2));
|
||||||
setVelocity(getVelocity().multiply(0.3, 1, 0.3));
|
setVelocity(getVelocity().multiply(0.3, 1, 0.3));
|
||||||
}
|
}
|
||||||
|
@ -217,7 +213,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1, 1);
|
playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBurnerActive() && age % 15 + rng.nextInt(5) == 0) {
|
if (isAscending() && age % 15 + rng.nextInt(5) == 0) {
|
||||||
playSound(SoundEvents.ENTITY_GHAST_SHOOT, 0.2F, 1);
|
playSound(SoundEvents.ENTITY_GHAST_SHOOT, 0.2F, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +223,11 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
|
|
||||||
if (leashPost.distanceTo(pos) >= 5) {
|
if (leashPost.distanceTo(pos) >= 5) {
|
||||||
Vec3d newVel = leashPost.subtract(pos).multiply(0.01);
|
Vec3d newVel = leashPost.subtract(pos).multiply(0.01);
|
||||||
|
if (isAirworthy()) {
|
||||||
setVelocity(newVel.lengthSquared() < 0.03 ? Vec3d.ZERO : newVel);
|
setVelocity(newVel.lengthSquared() < 0.03 ? Vec3d.ZERO : newVel);
|
||||||
|
} else {
|
||||||
|
setVelocity(getVelocity().multiply(0.9).add(newVel));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +245,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
|
|
||||||
private void updatePassengers() {
|
private void updatePassengers() {
|
||||||
for (Box box : getBoundingBoxes()) {
|
for (Box box : getBoundingBoxes()) {
|
||||||
for (Entity e : getWorld().getOtherEntities(this, box.expand(getVelocity().length()).expand(0, 0.5, 0))) {
|
for (Entity e : getWorld().getOtherEntities(this, box.stretch(getVelocity()).expand(0, 0.5, 0))) {
|
||||||
updatePassenger(e, box, e.getY() > getY() + 3);
|
updatePassenger(e, box, e.getY() > getY() + 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,38 +253,40 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
|
|
||||||
private void updatePassenger(Entity e, Box box, boolean inBalloon) {
|
private void updatePassenger(Entity e, Box box, boolean inBalloon) {
|
||||||
|
|
||||||
|
if (e instanceof AirBalloonEntity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isOnGround() && (isAirworthy() || isSubmergedInWater() || isLeashed())) {
|
||||||
|
Vec3d vel = getVelocity();
|
||||||
|
|
||||||
double height = box.getYLength();
|
double height = box.getYLength();
|
||||||
|
|
||||||
if (height < 3 || e.getBoundingBox().minY > box.minY + height / 2D) {
|
if (height < 3 || e.getBoundingBox().minY > box.minY + height / 2D) {
|
||||||
if (getVelocity().y > 0 && e.getBoundingBox().minY < box.maxY + 0.02) {
|
if (vel.y > 0 && e.getBoundingBox().minY < box.maxY + 0.02) {
|
||||||
e.setPos(e.getX(), box.maxY, e.getZ());
|
e.setPos(e.getX(), box.maxY, e.getZ());
|
||||||
}
|
}
|
||||||
if (getVelocity().y < 0 && e.getBoundingBox().minY > box.maxY) {
|
if (vel.y < 0 && e.getBoundingBox().minY > box.maxY) {
|
||||||
e.setPos(e.getX(), box.maxY, e.getZ());
|
e.setPos(e.getX(), box.maxY, e.getZ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (manualVelocity.length() > 0.01 || getVelocity().length() > 0.3) {
|
if (manualVelocity.length() > 0.01 || vel.length() > 0.3) {
|
||||||
e.setVelocity(e.getVelocity().multiply(0.1, 0.5, 0.1));
|
e.setVelocity(vel.multiply(0.1, 0.5, 0.1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getVelocity().y < 0) {
|
if (vel.y < 0) {
|
||||||
e.addVelocity(0, getVelocity().y, 0);
|
e.addVelocity(0, vel.y, 0);
|
||||||
Living.updateVelocity(e);
|
Living.updateVelocity(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inBalloon && !e.isSneaky() && Math.abs(e.getVelocity().y) > 0.079) {
|
|
||||||
e.setVelocity(e.getVelocity().multiply(1, e.getVelocity().y < 0 ? -0.9 : 1.2, 1).add(0, 0.8, 0));
|
|
||||||
if (Math.abs(e.getVelocity().y) > 2) {
|
|
||||||
e.setVelocity(e.getVelocity().x, MathHelper.clamp(e.getVelocity().y, -2, 2), e.getVelocity().z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Living.getOrEmpty(e).ifPresent(living -> {
|
Living.getOrEmpty(e).ifPresent(living -> {
|
||||||
living.setSupportingEntity(this);
|
living.setSupportingEntity(this);
|
||||||
living.setPositionOffset(e.getPos().subtract(oldPosition));
|
living.setPositionOffset(e.getPos().subtract(oldPosition));
|
||||||
living.updateRelativePosition(box);
|
living.updateRelativePosition(box);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (getWorld().isClient) {
|
if (getWorld().isClient) {
|
||||||
if (e.distanceTraveled > ((EntityDuck)e).getNextStepSoundDistance()) {
|
if (e.distanceTraveled > ((EntityDuck)e).getNextStepSoundDistance()) {
|
||||||
|
@ -304,8 +306,8 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
if (hitPos.y > (3 * getInflation(1))) {
|
if (hitPos.y > (3 * getInflation(1))) {
|
||||||
if (hasBalloon() && hasBurner()) {
|
if (hasBalloon() && hasBurner()) {
|
||||||
if (stack.isOf(Items.FLINT_AND_STEEL)) {
|
if (stack.isOf(Items.FLINT_AND_STEEL)) {
|
||||||
setBurnerActive(!isBurnerActive());
|
setAscending(!isAscending());
|
||||||
if (isBurnerActive()) {
|
if (isAscending()) {
|
||||||
playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1, 1);
|
playSound(SoundEvents.ENTITY_GHAST_SHOOT, 1, 1);
|
||||||
}
|
}
|
||||||
stack.damage(1, player, p -> p.sendEquipmentBreakStatus(hand == Hand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND));
|
stack.damage(1, player, p -> p.sendEquipmentBreakStatus(hand == Hand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND));
|
||||||
|
@ -320,7 +322,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
if (!getWorld().isClient) {
|
if (!getWorld().isClient) {
|
||||||
manualVelocity = manualVelocity.add(0.3 * xPush, 0, 0.3 * zPush);
|
manualVelocity = manualVelocity.add(0.3 * xPush, 0, 0.3 * zPush);
|
||||||
}
|
}
|
||||||
} else if (stack.isEmpty() && isBurnerActive()) {
|
} else if (stack.isEmpty() && isAscending()) {
|
||||||
setBoostTicks(50);
|
setBoostTicks(50);
|
||||||
getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos());
|
getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos());
|
||||||
}
|
}
|
||||||
|
@ -351,7 +353,6 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
}
|
}
|
||||||
playSound(SoundEvents.ENTITY_IRON_GOLEM_DAMAGE, 0.2F, 1);
|
playSound(SoundEvents.ENTITY_IRON_GOLEM_DAMAGE, 0.2F, 1);
|
||||||
getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos());
|
getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos());
|
||||||
setHasBurner(true);
|
|
||||||
return ActionResult.SUCCESS;
|
return ActionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,19 +391,18 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPushable() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pushAwayFrom(Entity entity) {
|
public void pushAwayFrom(Entity entity) {
|
||||||
|
if (entity instanceof AirBalloonEntity) {
|
||||||
|
super.pushAwayFrom(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pushAway(Entity entity) {
|
public void pushAway(Entity entity) {
|
||||||
|
if (entity instanceof AirBalloonEntity) {
|
||||||
|
super.pushAway(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -410,6 +410,38 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
return Entity.MoveEffect.EVENTS;
|
return Entity.MoveEffect.EVENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fall(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void travel(Vec3d movementInput) {
|
||||||
|
if (!this.isAirworthy()) {
|
||||||
|
super.travel(movementInput);
|
||||||
|
} else {
|
||||||
|
final float speed = 0.02F;
|
||||||
|
final float momentum = 0.91F;
|
||||||
|
if (isLogicalSideForUpdatingMovement()) {
|
||||||
|
if (isTouchingWater() || isInLava()) {
|
||||||
|
updateVelocity(speed, movementInput);
|
||||||
|
move(MovementType.SELF, getVelocity());
|
||||||
|
setVelocity(getVelocity().multiply(isTouchingWater() ? 0.8 : 0.5));
|
||||||
|
} else {
|
||||||
|
float slipperyness = (isOnGround() ? getWorld().getBlockState(getVelocityAffectingPos()).getBlock().getSlipperiness() : 1) * momentum;
|
||||||
|
float drag = isOnGround() ? 0.1F * (0.16277137F / (slipperyness * slipperyness * slipperyness)) : speed;
|
||||||
|
updateVelocity(drag, movementInput);
|
||||||
|
move(MovementType.SELF, getVelocity());
|
||||||
|
setVelocity(getVelocity().multiply(slipperyness));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateLimbs(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClimbing() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Box getVisibilityBoundingBox() {
|
public Box getVisibilityBoundingBox() {
|
||||||
|
@ -439,6 +471,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
double wallheight = box.maxY + 0.7;
|
double wallheight = box.maxY + 0.7;
|
||||||
double wallThickness = 0.7;
|
double wallThickness = 0.7;
|
||||||
|
|
||||||
|
if (getBasketType() != BoatEntity.Type.BAMBOO) {
|
||||||
// front left (next to door)
|
// front left (next to door)
|
||||||
output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness + 0.2, wallheight, box.minZ + wallThickness)));
|
output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness + 0.2, wallheight, box.minZ + wallThickness)));
|
||||||
// front right (next to door)
|
// front right (next to door)
|
||||||
|
@ -451,6 +484,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
output.accept(VoxelShapes.cuboid(new Box(box.maxX - wallThickness, box.minY, box.minZ, box.maxX, wallheight, box.maxZ)));
|
output.accept(VoxelShapes.cuboid(new Box(box.maxX - wallThickness, box.minY, box.minZ, box.maxX, wallheight, box.maxZ)));
|
||||||
// right
|
// right
|
||||||
output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness, wallheight, box.maxZ)));
|
output.accept(VoxelShapes.cuboid(new Box(box.minX, box.minY, box.minZ, box.minX + wallThickness, wallheight, box.maxZ)));
|
||||||
|
}
|
||||||
|
|
||||||
// top of balloon
|
// top of balloon
|
||||||
if (hasBalloon() && getInflation() > 0) {
|
if (hasBalloon() && getInflation() > 0) {
|
||||||
|
@ -463,8 +497,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
super.readCustomDataFromNbt(compound);
|
super.readCustomDataFromNbt(compound);
|
||||||
setBasketType(BoatEntity.Type.getType(compound.getString("basketType")));
|
setBasketType(BoatEntity.Type.getType(compound.getString("basketType")));
|
||||||
setDesign(BalloonDesign.getType(compound.getString("design")));
|
setDesign(BalloonDesign.getType(compound.getString("design")));
|
||||||
setHasBurner(compound.getBoolean("hasBurner"));
|
setAscending(compound.getBoolean("burnerActive"));
|
||||||
setBurnerActive(compound.getBoolean("burnerActive"));
|
|
||||||
setBoostTicks(compound.getInt("boostTicks"));
|
setBoostTicks(compound.getInt("boostTicks"));
|
||||||
prevInflation = compound.getInt("inflationAmount");
|
prevInflation = compound.getInt("inflationAmount");
|
||||||
setInflation(prevInflation);
|
setInflation(prevInflation);
|
||||||
|
@ -475,8 +508,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C
|
||||||
super.writeCustomDataToNbt(compound);
|
super.writeCustomDataToNbt(compound);
|
||||||
compound.putString("design", getDesign().asString());
|
compound.putString("design", getDesign().asString());
|
||||||
compound.putString("basket", getBasketType().asString());
|
compound.putString("basket", getBasketType().asString());
|
||||||
compound.putBoolean("hasBurner", hasBurner());
|
compound.putBoolean("burnerActive", isAscending());
|
||||||
compound.putBoolean("burnerActive", isBurnerActive());
|
|
||||||
compound.putInt("boostTicks", getBoostTicks());
|
compound.putInt("boostTicks", getBoostTicks());
|
||||||
compound.putInt("inflationAmount", getInflation());
|
compound.putInt("inflationAmount", getInflation());
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,17 +119,17 @@ public interface UItems {
|
||||||
Item BUTTERFLY = register("butterfly", new Item(new Item.Settings().food(UFoodComponents.INSECTS)), ItemGroups.FOOD_AND_DRINK);
|
Item BUTTERFLY = register("butterfly", new Item(new Item.Settings().food(UFoodComponents.INSECTS)), ItemGroups.FOOD_AND_DRINK);
|
||||||
|
|
||||||
Item SPELLBOOK = register("spellbook", new SpellbookItem(new Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS);
|
Item SPELLBOOK = register("spellbook", new SpellbookItem(new Item.Settings().maxCount(1).rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS);
|
||||||
Item OAK_BASKET = register("oak_basket", new BasketItem(BoatEntity.Type.OAK, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item OAK_BASKET = register("oak_basket", new BasketItem(BoatEntity.Type.OAK, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item SPRUCE_BASKET = register("spruce_basket", new BasketItem(BoatEntity.Type.SPRUCE, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item SPRUCE_BASKET = register("spruce_basket", new BasketItem(BoatEntity.Type.SPRUCE, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item BIRCH_BASKET = register("birch_basket", new BasketItem(BoatEntity.Type.BIRCH, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item BIRCH_BASKET = register("birch_basket", new BasketItem(BoatEntity.Type.BIRCH, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item JUNGLE_BASKET = register("jungle_basket", new BasketItem(BoatEntity.Type.JUNGLE, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item JUNGLE_BASKET = register("jungle_basket", new BasketItem(BoatEntity.Type.JUNGLE, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item ACACIA_BASKET = register("acacia_basket", new BasketItem(BoatEntity.Type.ACACIA, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item ACACIA_BASKET = register("acacia_basket", new BasketItem(BoatEntity.Type.ACACIA, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item CHERRY_BASKET = register("cherry_basket", new BasketItem(BoatEntity.Type.CHERRY, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item CHERRY_BASKET = register("cherry_basket", new BasketItem(BoatEntity.Type.CHERRY, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item DARK_OAK_BASKET = register("dark_oak_basket", new BasketItem(BoatEntity.Type.DARK_OAK, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item DARK_OAK_BASKET = register("dark_oak_basket", new BasketItem(BoatEntity.Type.DARK_OAK, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item MANGROVE_BASKET = register("mangrove_basket", new BasketItem(BoatEntity.Type.MANGROVE, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item MANGROVE_BASKET = register("mangrove_basket", new BasketItem(BoatEntity.Type.MANGROVE, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item BAMBOO_BASKET = register("bamboo_basket", new BasketItem(BoatEntity.Type.BAMBOO, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item BAMBOO_BASKET = register("bamboo_basket", new BasketItem(BoatEntity.Type.BAMBOO, new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
|
|
||||||
Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL);
|
Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
|
|
||||||
AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new PegasusAmuletItem(new FabricItemSettings()
|
AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new PegasusAmuletItem(new FabricItemSettings()
|
||||||
.maxCount(1)
|
.maxCount(1)
|
||||||
|
|
|
@ -24,6 +24,14 @@
|
||||||
"item.unicopia.friendship_bracelet.glowing": "Glowing",
|
"item.unicopia.friendship_bracelet.glowing": "Glowing",
|
||||||
|
|
||||||
"item.unicopia.oak_basket": "Oak Basket",
|
"item.unicopia.oak_basket": "Oak Basket",
|
||||||
|
"item.unicopia.spruce_basket": "Spruce Basket",
|
||||||
|
"item.unicopia.birch_basket": "Birch Basket",
|
||||||
|
"item.unicopia.jungle_basket": "Jungle Basket",
|
||||||
|
"item.unicopia.acacia_basket": "Acacia Basket",
|
||||||
|
"item.unicopia.cherry_basket": "Cherry Basket",
|
||||||
|
"item.unicopia.dark_oak_basket": "Dark Oak Basket",
|
||||||
|
"item.unicopia.mangrove_basket": "Mangrove Basket",
|
||||||
|
"item.unicopia.bamboo_basket": "Bamboo Basket",
|
||||||
"item.unicopia.giant_balloon": "Giant Balloon",
|
"item.unicopia.giant_balloon": "Giant Balloon",
|
||||||
|
|
||||||
"item.unicopia.spellbook": "Spellbook",
|
"item.unicopia.spellbook": "Spellbook",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/acacia_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/bamboo_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/birch_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/cherry_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/dark_oak_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/jungle_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/mangrove_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/spruce_basket"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.5 KiB |
BIN
src/main/resources/assets/unicopia/textures/item/palm_basket.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 6.7 KiB |
18
src/main/resources/data/unicopia/recipes/acacia_basket.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:acacia_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:acacia_basket"
|
||||||
|
}
|
||||||
|
}
|
18
src/main/resources/data/unicopia/recipes/bamboo_basket.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:bamboo_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:bamboo_basket"
|
||||||
|
}
|
||||||
|
}
|
18
src/main/resources/data/unicopia/recipes/birch_basket.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:birch_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:birch_basket"
|
||||||
|
}
|
||||||
|
}
|
18
src/main/resources/data/unicopia/recipes/cherry_basket.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:cherry_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:cherry_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:dark_oak_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:dark_oak_basket"
|
||||||
|
}
|
||||||
|
}
|
18
src/main/resources/data/unicopia/recipes/jungle_basket.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:jungle_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:jungle_basket"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:mangrove_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:mangrove_basket"
|
||||||
|
}
|
||||||
|
}
|
18
src/main/resources/data/unicopia/recipes/spruce_basket.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"group": "basket",
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:spruce_planks"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pattern": [
|
||||||
|
"# #",
|
||||||
|
"# #",
|
||||||
|
"###"
|
||||||
|
],
|
||||||
|
"result": {
|
||||||
|
"count": 1,
|
||||||
|
"item": "unicopia:spruce_basket"
|
||||||
|
}
|
||||||
|
}
|