diff --git a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java index 4cfeeb37..27c61abb 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java +++ b/src/main/java/com/minelittlepony/unicopia/client/render/entity/AirBalloonEntityRenderer.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.client.render.entity; +import java.util.function.Function; import java.util.function.Predicate; import com.minelittlepony.unicopia.Unicopia; @@ -19,8 +20,8 @@ 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("burner", new AirBalloonEntityModel(AirBalloonEntityModel.getBurnerModelData().createModel()), this, AirBalloonEntity::hasBurner)); - addFeature(new BalloonFeature("canopy", new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, AirBalloonEntity::hasBalloon)); + addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getBurnerModelData().createModel()), this, AirBalloonEntity::hasBurner, e -> getComponentTexture("burner"))); + addFeature(new BalloonFeature(new AirBalloonEntityModel(AirBalloonEntityModel.getCanopyModelData().createModel()), this, AirBalloonEntity::hasBalloon, e -> getComponentTexture("canopy/" + e.getDesign().asString()))); } @Override @@ -36,7 +37,7 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity @Override public Identifier getTexture(AirBalloonEntity entity) { - return getComponentTexture(entity, "basket"); + return getComponentTexture("basket/" + entity.getBasketType().asString()); } @Override @@ -44,29 +45,30 @@ public class AirBalloonEntityRenderer extends MobEntityRenderer<AirBalloonEntity return 0; } - private Identifier getComponentTexture(AirBalloonEntity entity, String componentName) { + private Identifier getComponentTexture(String componentName) { return Unicopia.id("textures/entity/air_balloon/" + componentName + ".png"); } final class BalloonFeature extends FeatureRenderer<AirBalloonEntity, AirBalloonEntityModel> { private final AirBalloonEntityModel model; private final Predicate<AirBalloonEntity> visibilityTest; - private final String componentName; + private final Function<AirBalloonEntity, Identifier> textureFunc; - public BalloonFeature(String componentName, AirBalloonEntityModel model, + public BalloonFeature(AirBalloonEntityModel model, FeatureRendererContext<AirBalloonEntity, AirBalloonEntityModel> context, - Predicate<AirBalloonEntity> visibilityTest) { + Predicate<AirBalloonEntity> visibilityTest, + Function<AirBalloonEntity, Identifier> textureFunc) { super(context); - this.componentName = componentName; this.model = model; this.visibilityTest = visibilityTest; + this.textureFunc = textureFunc; } @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, getComponentTexture(entity, componentName), matrices, vertices, light, entity, limbAngle, limbDistance, 0, yaw, pitch, tickDelta, 1, 1, 1); + render(getModel(), model, textureFunc.apply(entity), matrices, vertices, light, entity, limbAngle, limbDistance, 0, yaw, pitch, tickDelta, 1, 1, 1); } } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/AirBalloonEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/AirBalloonEntity.java index 5bb79eef..948431c6 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/AirBalloonEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/AirBalloonEntity.java @@ -5,36 +5,42 @@ import net.minecraft.entity.*; import net.minecraft.entity.data.*; import net.minecraft.entity.mob.FlyingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.NbtCompound; import net.minecraft.particle.ParticleTypes; import net.minecraft.sound.SoundEvents; -import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.function.ValueLists; import net.minecraft.util.math.*; import net.minecraft.util.math.random.Random; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; import net.minecraft.world.World; +import net.minecraft.world.event.GameEvent; import java.util.List; +import java.util.Locale; import java.util.function.Consumer; +import java.util.function.IntFunction; import com.minelittlepony.unicopia.entity.collision.EntityCollisions; import com.minelittlepony.unicopia.entity.collision.MultiBox; import com.minelittlepony.unicopia.entity.duck.EntityDuck; -import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.HotAirBalloonItem; import com.minelittlepony.unicopia.server.world.WeatherConditions; public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.ComplexCollidable, MultiBoundingBoxEntity { - private static final byte HAS_BALLOON = 1; private static final byte HAS_BURNER = 2; private static final byte BURNER_ACTIVE = 4; - private static final TrackedData<Integer> FLAGS = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); + private static final TrackedData<Integer> BURNER_FLAGS = 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> BASKET_TYPE = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); + private static final TrackedData<Integer> BALLOON_DESIGN = DataTracker.registerData(AirBalloonEntity.class, TrackedDataHandlerRegistry.INTEGER); private boolean prevBoosting; private int prevInflation; @@ -43,23 +49,38 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C public AirBalloonEntity(EntityType<? extends AirBalloonEntity> type, World world) { super(type, world); + intersectionChecked = true; setPersistent(); } @Override protected void initDataTracker() { super.initDataTracker(); - dataTracker.startTracking(FLAGS, 0); + dataTracker.startTracking(BURNER_FLAGS, 0); dataTracker.startTracking(BOOSTING, 0); dataTracker.startTracking(INFLATION, 0); + dataTracker.startTracking(BASKET_TYPE, 0); + dataTracker.startTracking(BALLOON_DESIGN, 0); + } + + public BoatEntity.Type getBasketType() { + return BoatEntity.Type.getType(dataTracker.get(BASKET_TYPE)); + } + + public void setBasketType(BoatEntity.Type type) { + dataTracker.set(BASKET_TYPE, type.ordinal()); + } + + public BalloonDesign getDesign() { + return BalloonDesign.getType(dataTracker.get(BALLOON_DESIGN)); + } + + public void setDesign(BalloonDesign design) { + dataTracker.set(BALLOON_DESIGN, design.ordinal()); } public boolean hasBalloon() { - return getFlag(HAS_BALLOON); - } - - public void setHasBalloon(boolean hasBalloon) { - setFlag(HAS_BALLOON, hasBalloon); + return getDesign() != BalloonDesign.NONE; } public boolean hasBurner() { @@ -87,7 +108,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C } public boolean isBurnerActive() { - return getFlag((byte)(HAS_BURNER | BURNER_ACTIVE | HAS_BALLOON)); + return hasBalloon() && getFlag((byte)(HAS_BURNER | BURNER_ACTIVE)); } public void setBurnerActive(boolean burnerActive) { @@ -103,12 +124,12 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C } private boolean getFlag(byte flag) { - return (dataTracker.get(FLAGS).intValue() & flag) == flag; + return (dataTracker.get(BURNER_FLAGS).intValue() & flag) == flag; } private void setFlag(byte flag, boolean val) { - int v = dataTracker.get(FLAGS); - dataTracker.set(FLAGS, val ? (v | flag) : (v & ~flag)); + int v = dataTracker.get(BURNER_FLAGS); + dataTracker.set(BURNER_FLAGS, val ? (v | flag) : (v & ~flag)); } private boolean isAirworthy() { @@ -212,20 +233,23 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C prevBoosting = boosting; oldPosition = getPos(); - for (Box box : getBoundingBoxes()) { - for (Entity e : getWorld().getOtherEntities(this, box.expand(0, 0.5, 0).stretch(getVelocity().multiply(-1)))) { - updatePassenger(e, box, e.getY() > getY() + 3); - } - } - if (getFireTicks() > 0) { setFireTicks(1); } + updatePassengers(); super.tick(); setBoundingBox(MultiBox.of(getBoundingBox(), getBoundingBoxes())); } + private void updatePassengers() { + for (Box box : getBoundingBoxes()) { + for (Entity e : getWorld().getOtherEntities(this, box.expand(getVelocity().length()).expand(0, 0.5, 0))) { + updatePassenger(e, box, e.getY() > getY() + 3); + } + } + } + private void updatePassenger(Entity e, Box box, boolean inBalloon) { double height = box.getYLength(); @@ -239,7 +263,14 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C } } - e.setVelocity(e.getVelocity().multiply(0.1, 0.5, 0.1)); + if (manualVelocity.length() > 0.01 || getVelocity().length() > 0.3) { + e.setVelocity(e.getVelocity().multiply(0.1, 0.5, 0.1)); + } + + if (getVelocity().y < 0) { + e.addVelocity(0, getVelocity().y, 0); + 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)); @@ -257,8 +288,10 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C if (getWorld().isClient) { if (e.distanceTraveled > ((EntityDuck)e).getNextStepSoundDistance()) { e.distanceTraveled--; - e.playSound(inBalloon ? SoundEvents.BLOCK_WOOL_STEP : SoundEvents.BLOCK_BAMBOO_STEP, 0.5F, 1); + if (!e.isSneaky()) { + getWorld().emitGameEvent(e, GameEvent.STEP, getBlockPos()); + } } } } @@ -276,6 +309,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C } stack.damage(1, player, p -> p.sendEquipmentBreakStatus(hand == Hand.MAIN_HAND ? EquipmentSlot.MAINHAND : EquipmentSlot.OFFHAND)); playSound(SoundEvents.ITEM_FLINTANDSTEEL_USE, 1, 1); + getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos()); return ActionResult.SUCCESS; } @@ -287,11 +321,11 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C } } else if (stack.isEmpty() && isBurnerActive()) { setBoostTicks(50); + getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos()); } } } - player.sendMessage(Text.literal(hitPos + "")); return ActionResult.PASS; } @@ -299,14 +333,13 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C protected ActionResult interactMob(PlayerEntity player, Hand hand) { ItemStack stack = player.getStackInHand(hand); - - - if (stack.isOf(UItems.LARGE_BALLOON) && !hasBalloon()) { + if (stack.getItem() instanceof HotAirBalloonItem balloon && !hasBalloon()) { if (!player.getAbilities().creativeMode) { stack.decrement(1); } playSound(SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 1, 1); - setHasBalloon(true); + getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos()); + setDesign(HotAirBalloonItem.getDesign(getWorld(), stack)); return ActionResult.SUCCESS; } @@ -315,6 +348,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C stack.decrement(1); } playSound(SoundEvents.ENTITY_IRON_GOLEM_DAMAGE, 0.2F, 1); + getWorld().emitGameEvent(this, GameEvent.ENTITY_INTERACT, getBlockPos()); setHasBurner(true); return ActionResult.SUCCESS; } @@ -334,6 +368,7 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C @Override public void pushAwayFrom(Entity entity) { + } @Override @@ -341,6 +376,12 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C } + @Override + protected Entity.MoveEffect getMoveEffect() { + return Entity.MoveEffect.EVENTS; + } + + @Override public Box getVisibilityBoundingBox() { if (hasBalloon()) { @@ -391,7 +432,8 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C @Override public void readCustomDataFromNbt(NbtCompound compound) { super.readCustomDataFromNbt(compound); - setHasBalloon(compound.getBoolean("hasBalloon")); + setBasketType(BoatEntity.Type.getType(compound.getString("basketType"))); + setDesign(BalloonDesign.getType(compound.getString("design"))); setHasBurner(compound.getBoolean("hasBurner")); setBurnerActive(compound.getBoolean("burnerActive")); setBoostTicks(compound.getInt("boostTicks")); @@ -402,12 +444,37 @@ public class AirBalloonEntity extends FlyingEntity implements EntityCollisions.C @Override public void writeCustomDataToNbt(NbtCompound compound) { super.writeCustomDataToNbt(compound); - compound.putBoolean("hasBalloon", hasBalloon()); + compound.putString("design", getDesign().asString()); + compound.putString("basket", getBasketType().asString()); compound.putBoolean("hasBurner", hasBurner()); compound.putBoolean("burnerActive", isBurnerActive()); compound.putInt("boostTicks", getBoostTicks()); compound.putInt("inflationAmount", getInflation()); } + + @SuppressWarnings("deprecation") + public enum BalloonDesign implements StringIdentifiable { + NONE, + LUNA; + + public static final StringIdentifiable.Codec<BalloonDesign> CODEC = StringIdentifiable.createCodec(BalloonDesign::values); + private static final IntFunction<BalloonDesign> BY_ID = ValueLists.<BalloonDesign>createIdToValueFunction(Enum::ordinal, values(), ValueLists.OutOfBoundsHandling.ZERO); + + private final String name = name().toLowerCase(Locale.ROOT); + + @Override + public String asString() { + return name; + } + + public static BalloonDesign getType(int type) { + return BY_ID.apply(type); + } + + public static BalloonDesign getType(String name) { + return CODEC.byId(name, LUNA); + } + } } diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 8dce0045..5679cd66 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -77,6 +77,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste @Nullable private Vec3d supportPositionOffset; + private int ticksOutsideVehicle; @Nullable private Caster<?> attacker; @@ -181,6 +182,9 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste public void setSupportingEntity(Entity supportingEntity) { this.supportingEntity = supportingEntity; + if (supportingEntity != null) { + ticksOutsideVehicle = 0; + } } public void setPositionOffset(@Nullable Vec3d positionOffset) { @@ -191,19 +195,6 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste setPositionOffset(supportingEntity == null ? null : entity.getPos().subtract(supportingEntity.getPos())); } - public static void checkGroundCollission(Entity entity, Box box) { - double height = box.getYLength(); - - if (height < 3 || entity.getBoundingBox().minY > box.minY + height / 2D) { - if (entity.getBoundingBox().minY < box.maxY) { - entity.setPos(entity.getX(), box.maxY - 0.002, entity.getZ()); - } - if (entity.getBoundingBox().minY > box.maxY) { - entity.setPos(entity.getX(), box.maxY - 0.002, entity.getZ()); - } - } - } - public void updateRelativePosition(Box box) { if (supportingEntity == null || supportPositionOffset == null) { return; @@ -251,11 +242,16 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste public void updateSupportingEntity() { if (supportingEntity != null) { - Box ownBox = entity.getBoundingBox().expand(0.1); + Box ownBox = entity.getBoundingBox() + .stretch(entity.getVelocity()) + .expand(0.1, 0.5, 0.1) + .stretch(supportingEntity.getVelocity().multiply(-2)); - MultiBoundingBoxEntity.getBoundingBoxes(supportingEntity).stream().filter(box -> { - return box.expand(0, 0.5, 0).intersects(ownBox); - }).findFirst().ifPresentOrElse(box -> { + MultiBoundingBoxEntity.getBoundingBoxes(supportingEntity).stream() + .filter(box -> box.stretch(supportingEntity.getVelocity()).expand(0, 0.5, 0).intersects(ownBox)) + .findFirst() + .ifPresentOrElse(box -> { + ticksOutsideVehicle = 0; if (supportPositionOffset == null) { updatePositionOffset(); } else { @@ -265,8 +261,14 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste entity.verticalCollision = true; entity.groundCollision = true; }, () -> { - supportingEntity = null; - supportPositionOffset = null; + // Rubberband passengers to try and prevent players falling out when the velocity changes suddenly + if (ticksOutsideVehicle++ > 30) { + supportingEntity = null; + supportPositionOffset = null; + Unicopia.LOGGER.info("Entity left vehicle"); + } else { + supportPositionOffset = supportPositionOffset.multiply(0.25, 1, 0.25); + } }); } @@ -320,7 +322,10 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste } updateDragonBreath(); - updatePositionOffset(); + + if (ticksOutsideVehicle == 0) { + updatePositionOffset(); + } } public void updateAttributeModifier(UUID id, EntityAttribute attribute, float desiredValue, Float2ObjectFunction<EntityAttributeModifier> modifierSupplier, boolean permanent) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java b/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java index 6161eb58..35ee94f6 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/BasketItem.java @@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.util.Dispensable; import net.minecraft.block.DispenserBlock; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.item.BoatItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -31,8 +32,11 @@ public class BasketItem extends Item implements Dispensable { private static final Predicate<Entity> RIDERS = EntityPredicates.EXCEPT_SPECTATOR.and(Entity::canHit); private static final double REACH = 5; - public BasketItem(Item.Settings settings) { + private final BoatEntity.Type type; + + public BasketItem(BoatEntity.Type type, Item.Settings settings) { super(settings); + this.type = type; DispenserBlock.registerBehavior(this, createDispenserBehaviour()); } @@ -71,6 +75,7 @@ public class BasketItem extends Item implements Dispensable { entity.updatePositionAndAngles(x, y, z, 0, 0); entity.setHeadYaw(yaw); entity.setBodyYaw(yaw); + entity.setBasketType(type); if (!world.isSpaceEmpty(entity, entity.getBoundingBox())) { return TypedActionResult.fail(stack); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java b/src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java new file mode 100644 index 00000000..dca94801 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/HotAirBalloonItem.java @@ -0,0 +1,24 @@ +package com.minelittlepony.unicopia.item; + +import com.minelittlepony.unicopia.entity.AirBalloonEntity; + +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public class HotAirBalloonItem extends Item { + + public HotAirBalloonItem(Settings settings) { + super(settings); + } + + public static AirBalloonEntity.BalloonDesign getDesign(World world, ItemStack stack) { + String design; + if (stack.hasNbt() && !(design = stack.getNbt().getString("design")).isEmpty()) { + return AirBalloonEntity.BalloonDesign.getType(design); + } + + int ordinal = 1 + world.getRandom().nextInt(AirBalloonEntity.BalloonDesign.values().length - 1); + return AirBalloonEntity.BalloonDesign.getType(ordinal); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 8e6aa552..5e6a382d 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.item.group.UItemGroups; import com.minelittlepony.unicopia.item.toxin.UFoodComponents; +import net.minecraft.entity.vehicle.BoatEntity; import net.minecraft.item.*; import net.minecraft.item.Item.Settings; import net.fabricmc.fabric.api.item.v1.FabricItemSettings; @@ -118,8 +119,8 @@ public interface UItems { 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 BASKET = register("basket", new BasketItem(new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL); - Item LARGE_BALLOON = register("large_balloon", new Item(new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL); + Item OAK_BASKET = register("oak_basket", new BasketItem(BoatEntity.Type.OAK, new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL); + Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.FUNCTIONAL); AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new PegasusAmuletItem(new FabricItemSettings() .maxCount(1) diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index e0767889..f96d69d2 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -23,6 +23,9 @@ "item.unicopia.friendship_bracelet.issuer": "Signed by %s", "item.unicopia.friendship_bracelet.glowing": "Glowing", + "item.unicopia.oak_basket": "Oak Basket", + "item.unicopia.giant_balloon": "Giant Balloon", + "item.unicopia.spellbook": "Spellbook", "emi.category.unicopia.spellbook": "Spellbook", diff --git a/src/main/resources/assets/unicopia/models/item/giant_balloon.json b/src/main/resources/assets/unicopia/models/item/giant_balloon.json new file mode 100644 index 00000000..4df680ac --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/giant_balloon.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/giant_balloon" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/oak_basket.json b/src/main/resources/assets/unicopia/models/item/oak_basket.json new file mode 100644 index 00000000..6302a186 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/oak_basket.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/oak_basket" + } +} diff --git a/src/main/resources/assets/unicopia/textures/entity/air_balloon/basket.png b/src/main/resources/assets/unicopia/textures/entity/air_balloon/basket/oak.png similarity index 100% rename from src/main/resources/assets/unicopia/textures/entity/air_balloon/basket.png rename to src/main/resources/assets/unicopia/textures/entity/air_balloon/basket/oak.png diff --git a/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy.png b/src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/luna.png similarity index 100% rename from src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy.png rename to src/main/resources/assets/unicopia/textures/entity/air_balloon/canopy/luna.png diff --git a/src/main/resources/assets/unicopia/textures/item/giant_balloon.png b/src/main/resources/assets/unicopia/textures/item/giant_balloon.png new file mode 100644 index 00000000..31c7d9ea Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/item/giant_balloon.png differ diff --git a/src/main/resources/assets/unicopia/textures/item/oak_basket.png b/src/main/resources/assets/unicopia/textures/item/oak_basket.png new file mode 100644 index 00000000..0dd46d28 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/item/oak_basket.png differ