diff --git a/src/main/java/com/minelittlepony/unicopia/EquineContext.java b/src/main/java/com/minelittlepony/unicopia/EquineContext.java index a28433c4..ed307b09 100644 --- a/src/main/java/com/minelittlepony/unicopia/EquineContext.java +++ b/src/main/java/com/minelittlepony/unicopia/EquineContext.java @@ -17,7 +17,14 @@ public interface EquineContext { return getSpecies().composite(); } + default float getCloudWalkingStrength() { + return 0; + } + static EquineContext of(ShapeContext context) { + if (context == ShapeContext.absent()) { + return Unicopia.SIDE.getPony().map(EquineContext.class::cast).orElse(ABSENT); + } return context instanceof EquineContext c ? c : ABSENT; } diff --git a/src/main/java/com/minelittlepony/unicopia/block/RockCropBlock.java b/src/main/java/com/minelittlepony/unicopia/block/RockCropBlock.java index 0a9995e5..b89e89b5 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/RockCropBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/RockCropBlock.java @@ -1,12 +1,17 @@ package com.minelittlepony.unicopia.block; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.EquineContext; import com.minelittlepony.unicopia.EquinePredicates; +import com.minelittlepony.unicopia.Race; import com.minelittlepony.unicopia.item.UItems; import net.minecraft.block.BlockState; import net.minecraft.block.CropBlock; import net.minecraft.block.ShapeContext; import net.minecraft.item.ItemConvertible; +import net.minecraft.item.ItemPlacementContext; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.random.Random; @@ -102,4 +107,14 @@ public class RockCropBlock extends CropBlock { protected ItemConvertible getSeedsItem() { return UItems.PEBBLES; } + + @Override + @Nullable + public final BlockState getPlacementState(ItemPlacementContext context) { + if (!EquineContext.of(context).getCompositeRace().any(Race::canUseEarth)) { + return null; + } + + return super.getPlacementState(context); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java index d8859c97..b77cefd4 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/block/UBlocks.java @@ -5,6 +5,8 @@ import java.util.Collections; import java.util.List; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.block.cloud.CloudBlock; +import com.minelittlepony.unicopia.block.cloud.CloudPillarBlock; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.server.world.UTreeGen; @@ -125,6 +127,10 @@ public interface UBlocks { Block MYSTERIOUS_EGG = register("mysterious_egg", new PileBlock(Settings.copy(Blocks.SLIME_BLOCK), PileBlock.MYSTERIOUS_EGG_SHAPES), ItemGroups.NATURAL); Block SLIME_PUSTULE = register("slime_pustule", new SlimePustuleBlock(Settings.copy(Blocks.SLIME_BLOCK)), ItemGroups.NATURAL); + Block CLOUD = register("cloud", new CloudBlock(Settings.create().mapColor(MapColor.OFF_WHITE).replaceable().hardness(0.3F).resistance(0).sounds(BlockSoundGroup.WOOL))); + Block DENSE_CLOUD = register("dense_cloud", new CloudBlock(Settings.create().mapColor(MapColor.GRAY).replaceable().hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL))); + Block CLOUD_PILLAR = register("cloud_pillar", new CloudPillarBlock(Settings.create().mapColor(MapColor.GRAY).replaceable().hardness(0.5F).resistance(0).sounds(BlockSoundGroup.WOOL))); + SegmentedCropBlock OATS = register("oats", SegmentedCropBlock.create(11, 5, AbstractBlock.Settings.copy(Blocks.WHEAT), () -> UItems.OAT_SEEDS, null, null)); SegmentedCropBlock OATS_STEM = register("oats_stem", OATS.createNext(5)); SegmentedCropBlock OATS_CROWN = register("oats_crown", OATS_STEM.createNext(5)); diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java new file mode 100644 index 00000000..0325568d --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java @@ -0,0 +1,146 @@ +package com.minelittlepony.unicopia.block.cloud; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.EquineContext; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.block.UBlocks; +import com.minelittlepony.unicopia.entity.player.Pony; + +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.TransparentBlock; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.ai.pathing.NavigationType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.EmptyBlockView; +import net.minecraft.world.World; + +public class CloudBlock extends TransparentBlock { + public CloudBlock(Settings settings) { + super(settings.nonOpaque()); + } + + @Override + public void onEntityLand(BlockView world, Entity entity) { + boolean bounce = Math.abs(entity.getVelocity().y) > 0.3; + super.onEntityLand(world, entity); + if (bounce) { + entity.addVelocity(0, 0.2F, 0); + } + BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getTranslucent(), + UBlocks.MYSTERIOUS_EGG, UBlocks.SLIME_PUSTULE, + UBlocks.CLOUD, UBlocks.DENSE_CLOUD, UBlocks.CLOUD_PILLAR + ); + } + + @Override + public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { + entity.handleFallDamage(fallDistance, 0, world.getDamageSources().fall()); + } + + @Override + @Deprecated + public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + + if (entity instanceof PlayerEntity player && (player.getAbilities().flying || Pony.of(player).getPhysics().isFlying())) { + return; + } + + if (entity.getVelocity().y < 0) { + float cloudWalking = EquineContext.of(entity).getCloudWalkingStrength(); + if (cloudWalking > 0) { + entity.setVelocity(entity.getVelocity().multiply(1, 1 - cloudWalking, 1)); + entity.addVelocity(0, 0.07, 0); + entity.setOnGround(true); + } + entity.setVelocity(entity.getVelocity().multiply(0.9F, 1, 0.9F)); + } else { + entity.setVelocity(entity.getVelocity().multiply(0.9F)); + } + } + + @Override + public final VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + EquineContext equineContext = EquineContext.of(context); + if (!canInteract(state, world, pos, equineContext)) { + return VoxelShapes.empty(); + } + return getOutlineShape(state, world, pos, context, equineContext); + } + + @Override + @Deprecated + public final VoxelShape getCullingShape(BlockState state, BlockView world, BlockPos pos) { + return getOutlineShape(state, world, pos, ShapeContext.absent(), EquineContext.ABSENT); + } + + @Override + @Deprecated + public VoxelShape getCollisionShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return this.collidable ? state.getOutlineShape(world, pos, context) : VoxelShapes.empty(); + } + + @Override + @Nullable + public final BlockState getPlacementState(ItemPlacementContext context) { + EquineContext equineContext = EquineContext.of(context); + if (!canInteract(getDefaultState(), context.getWorld(), context.getBlockPos(), equineContext)) { + return null; + } + return getPlacementState(context, equineContext); + } + + @Deprecated + @Override + public boolean canReplace(BlockState state, ItemPlacementContext context) { + EquineContext equineContext = EquineContext.of(context); + if (canInteract(state, context.getWorld(), context.getBlockPos(), equineContext)) { + return canReplace(state, context, equineContext); + } + return true; + } + + @Deprecated + @Override + public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { + if (stateFrom.isOf(this)) { + return true; + } + VoxelShape shape = state.getCullingShape(EmptyBlockView.INSTANCE, BlockPos.ORIGIN); + VoxelShape shapeFrom = stateFrom.getCullingShape(EmptyBlockView.INSTANCE, BlockPos.ORIGIN); + return !shape.isEmpty() && !shapeFrom.isEmpty() && VoxelShapes.isSideCovered(shape, shapeFrom, direction); + } + + @Override + @Deprecated + public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { + return true; + } + + protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, EquineContext equineContext) { + return VoxelShapes.fullCube(); + } + + protected boolean canInteract(BlockState state, BlockView world, BlockPos pos, EquineContext context) { + return context.getCompositeRace().any(Race::canInteractWithClouds); + } + + @SuppressWarnings("deprecation") + protected boolean canReplace(BlockState state, ItemPlacementContext context, EquineContext equineContext) { + return super.canReplace(state, context); + } + + @Nullable + protected BlockState getPlacementState(ItemPlacementContext placementContext, EquineContext equineContext) { + return super.getPlacementState(placementContext); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java new file mode 100644 index 00000000..8e85985d --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudPillarBlock.java @@ -0,0 +1,78 @@ +package com.minelittlepony.unicopia.block.cloud; + +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.EquineContext; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.WorldAccess; + +public class CloudPillarBlock extends CloudBlock { + private static final BooleanProperty NORTH = BooleanProperty.of("north"); + private static final BooleanProperty SOUTH = BooleanProperty.of("south"); + private static final Map DIRECTION_PROPERTIES = Map.of( + Direction.UP, NORTH, + Direction.DOWN, SOUTH + ); + + private static final VoxelShape CORE_SHAPE = Block.createCuboidShape(1, 0, 1, 15, 16, 15); + private static final VoxelShape FOOT_SHAPE = Block.createCuboidShape(0, 0, 0, 16, 5, 16); + private static final VoxelShape CAP_SHAPE = FOOT_SHAPE.offset(0, 11F / 16F, 0); + + private static final VoxelShape[] SHAPES = new VoxelShape[] { + CORE_SHAPE, + VoxelShapes.union(CORE_SHAPE, FOOT_SHAPE), + VoxelShapes.union(CORE_SHAPE, CAP_SHAPE), + VoxelShapes.union(CORE_SHAPE, FOOT_SHAPE, CAP_SHAPE) + }; + // [0,0] [0,1] + // [1,0] [1,1] + + public CloudPillarBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(NORTH, true).with(SOUTH, true)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(NORTH, SOUTH); + } + + @Override + protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, EquineContext equineContext) { + return SHAPES[(state.get(NORTH) ? 0 : 2) + (state.get(SOUTH) ? 0 : 1)]; + } + + @Override + @Nullable + protected BlockState getPlacementState(ItemPlacementContext placementContext, EquineContext equineContext) { + BlockPos pos = placementContext.getBlockPos(); + BlockState state = super.getPlacementState(placementContext, equineContext); + for (var property : DIRECTION_PROPERTIES.entrySet()) { + state = state.with(property.getValue(), placementContext.getWorld().getBlockState(pos.offset(property.getKey())).isOf(this)); + } + return state; + } + + @Deprecated + @Override + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState neighborState, WorldAccess world, BlockPos pos, BlockPos neighborPos) { + if (direction.getAxis() == Direction.Axis.Y) { + return state.with(DIRECTION_PROPERTIES.get(direction), neighborState.isOf(this)); + } + + return state; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java new file mode 100644 index 00000000..232743c3 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/StormyCloudBlock.java @@ -0,0 +1,36 @@ +package com.minelittlepony.unicopia.block.cloud; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.Entity; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.IntProperty; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class StormyCloudBlock extends CloudBlock { + private static final int MAX_CHARGE = 6; + private static final IntProperty CHARGE = IntProperty.of("charge", 0, MAX_CHARGE); + + public StormyCloudBlock(Settings settings) { + super(settings); + setDefaultState(getDefaultState().with(CHARGE, 0)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(CHARGE); + } + + @Override + public void onLandedUpon(World world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { + super.onLandedUpon(world, state, pos, entity, fallDistance); + if (state.get(CHARGE) < MAX_CHARGE) { + if (world.random.nextInt(5) == 0) { + world.setBlockState(pos, state.cycle(CHARGE)); + } + } else { + + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index cb118590..c747b2aa 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -172,7 +172,10 @@ public interface URenderers { }, TintedBlock.REGISTRY.stream().map(Block::asItem).filter(i -> i != Items.AIR).toArray(Item[]::new)); BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), UBlocks.TRANSLUCENT_BLOCKS.stream().toArray(Block[]::new)); - BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getTranslucent(), UBlocks.MYSTERIOUS_EGG, UBlocks.SLIME_PUSTULE); + BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getTranslucent(), + UBlocks.MYSTERIOUS_EGG, UBlocks.SLIME_PUSTULE, + UBlocks.CLOUD, UBlocks.DENSE_CLOUD, UBlocks.CLOUD_PILLAR + ); // for lava boats BlockRenderLayerMap.INSTANCE.putFluids(RenderLayer.getTranslucent(), Fluids.LAVA, Fluids.FLOWING_LAVA); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 17d53f73..0b721be2 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -36,6 +36,8 @@ import com.minelittlepony.unicopia.util.*; import it.unimi.dsi.fastutil.floats.Float2ObjectFunction; import net.minecraft.block.BlockState; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.*; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeInstance; @@ -548,6 +550,14 @@ public abstract class Living implements Equine, Caste }); } + @Override + public float getCloudWalkingStrength() { + Enchantment featherFalling = net.minecraft.enchantment.Enchantments.FEATHER_FALLING; + int maxLevel = featherFalling.getMaxLevel(); + int level = EnchantmentHelper.getEquipmentLevel(featherFalling, entity); + return MathHelper.clamp(level / (float)maxLevel, 0, 1); + } + @Override public void setDirty() {} diff --git a/src/main/java/com/minelittlepony/unicopia/item/RacePredicatedAliasedBlockItem.java b/src/main/java/com/minelittlepony/unicopia/item/RacePredicatedAliasedBlockItem.java deleted file mode 100644 index f2abdf67..00000000 --- a/src/main/java/com/minelittlepony/unicopia/item/RacePredicatedAliasedBlockItem.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.minelittlepony.unicopia.item; - -import java.util.function.Predicate; - -import com.minelittlepony.unicopia.Race; -import com.minelittlepony.unicopia.entity.player.Pony; - -import net.minecraft.block.Block; -import net.minecraft.item.AliasedBlockItem; -import net.minecraft.item.ItemUsageContext; -import net.minecraft.util.ActionResult; - -public class RacePredicatedAliasedBlockItem extends AliasedBlockItem { - - private Predicate predicate; - - public RacePredicatedAliasedBlockItem(Block block, Settings settings, Predicate predicate) { - super(block, settings); - this.predicate = predicate; - } - - @Override - public ActionResult useOnBlock(ItemUsageContext context) { - Pony pony = Pony.of(context.getPlayer()); - if (pony == null || !predicate.test(pony.getObservedSpecies())) { - return ActionResult.FAIL; - } - - return super.useOnBlock(context); - } -} diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 041811ca..dd29fa11 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -6,6 +6,7 @@ import com.minelittlepony.unicopia.block.UBlocks; import com.minelittlepony.unicopia.block.UWoodTypes; import com.minelittlepony.unicopia.entity.mob.AirBalloonEntity; import com.minelittlepony.unicopia.entity.mob.UEntities; +import com.minelittlepony.unicopia.item.cloud.CloudBlockItem; import com.minelittlepony.unicopia.item.enchantment.UEnchantments; import com.minelittlepony.unicopia.item.group.ItemGroupRegistry; import com.minelittlepony.unicopia.item.group.UItemGroups; @@ -81,7 +82,7 @@ public interface UItems { Item PINEAPPLE = register("pineapple", new PineappleItem(new Item.Settings().food(UFoodComponents.BANANA).maxDamage(3)), ItemGroups.FOOD_AND_DRINK); Item PINEAPPLE_CROWN = register("pineapple_crown", new AliasedBlockItem(UBlocks.PINEAPPLE, new Item.Settings()), ItemGroups.NATURAL); - Item PEBBLES = register("pebbles", new RacePredicatedAliasedBlockItem(UBlocks.ROCKS, new Item.Settings(), Race::canUseEarth), ItemGroups.NATURAL); + Item PEBBLES = register("pebbles", new AliasedBlockItem(UBlocks.ROCKS, new Item.Settings()), ItemGroups.NATURAL); Item ROCK = register("rock", new HeavyProjectileItem(new Item.Settings(), 3), ItemGroups.NATURAL); Item WEIRD_ROCK = register("weird_rock", new BluntWeaponItem(new Item.Settings(), ImmutableMultimap.of( EntityAttributes.GENERIC_LUCK, new EntityAttributeModifier(BluntWeaponItem.LUCK_MODIFIER_ID, "Weapon modifier", 9, EntityAttributeModifier.Operation.ADDITION) @@ -143,6 +144,10 @@ public interface UItems { Item GIANT_BALLOON = register("giant_balloon", new HotAirBalloonItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS); + Item CLOUD = register("cloud", new CloudBlockItem(UBlocks.CLOUD, new Item.Settings()), ItemGroups.NATURAL); + Item DENSE_CLOUD = register("dense_cloud", new CloudBlockItem(UBlocks.DENSE_CLOUD, new Item.Settings()), ItemGroups.NATURAL); + Item CLOUD_PILLAR = register("cloud_pillar", new CloudBlockItem(UBlocks.CLOUD_PILLAR, new Item.Settings()), ItemGroups.NATURAL); + AmuletItem PEGASUS_AMULET = register("pegasus_amulet", new PegasusAmuletItem(new FabricItemSettings() .maxCount(1) .maxDamage(890) diff --git a/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java b/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java new file mode 100644 index 00000000..3a59c0fc --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/cloud/CloudBlockItem.java @@ -0,0 +1,61 @@ +package com.minelittlepony.unicopia.item.cloud; + +import com.minelittlepony.unicopia.block.cloud.CloudBlock; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +public class CloudBlockItem +extends BlockItem { + public CloudBlockItem(Block block, Item.Settings settings) { + super(block, settings); + } + + @Override + public ActionResult useOnBlock(ItemUsageContext context) { + BlockState state = context.getWorld().getBlockState(context.getBlockPos()); + + if (state.getBlock() instanceof CloudBlock) { + return super.useOnBlock(context); + } + + return ActionResult.PASS; + } + + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + + ItemPlacementContext context = new ItemPlacementContext(user, hand, user.getStackInHand(hand), new BlockHitResult( + user.getEyePos(), + Direction.UP, + BlockPos.ofFloored(user.getEyePos()), + true + )); + + ActionResult actionResult = place(context); + + if (actionResult.isAccepted()) { + return TypedActionResult.success(context.getStack(), world.isClient); + } + + return TypedActionResult.pass(user.getStackInHand(hand)); + } + + @Override + protected boolean canPlace(ItemPlacementContext context, BlockState state) { + return !checkStatePlacement() || state.canPlaceAt(context.getWorld(), context.getBlockPos()); + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java index fbd059ad..93647abb 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntityShapeContext.java @@ -34,4 +34,9 @@ abstract class MixinEntityShapeContext implements EquineContext { public Race.Composite getCompositeRace() { return equineContext.getCompositeRace(); } + + @Override + public float getCloudWalkingStrength() { + return equineContext.getCloudWalkingStrength(); + } } diff --git a/src/main/resources/assets/unicopia/blockstates/cloud.json b/src/main/resources/assets/unicopia/blockstates/cloud.json new file mode 100644 index 00000000..3afda0a3 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/cloud.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "unicopia:block/cloud" } + } +} diff --git a/src/main/resources/assets/unicopia/blockstates/cloud_pillar.json b/src/main/resources/assets/unicopia/blockstates/cloud_pillar.json new file mode 100644 index 00000000..46dafadc --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/cloud_pillar.json @@ -0,0 +1,28 @@ +{ + "multipart": [ + { + "apply": { + "model": "unicopia:block/cloud_pillar_middle" + } + }, + { + "apply": { + "model": "unicopia:block/cloud_pillar_end", + "uvlock": true, + "x": 180 + }, + "when": { + "north": false + } + }, + { + "apply": { + "model": "unicopia:block/cloud_pillar_end", + "uvlock": true + }, + "when": { + "south": false + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/blockstates/dense_cloud.json b/src/main/resources/assets/unicopia/blockstates/dense_cloud.json new file mode 100644 index 00000000..53ceace7 --- /dev/null +++ b/src/main/resources/assets/unicopia/blockstates/dense_cloud.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "unicopia:block/dense_cloud" } + } +} diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 88bf1146..1e847754 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -216,6 +216,10 @@ "block.unicopia.chiselled_chitin_hull": "Chiselled Chitin Hull", "block.unicopia.chiselled_chitin_slab": "Chiselled Chitin Slab", "block.unicopia.chiselled_chitin_stairs": "Chiselled Chitin Stairs", + + "block.unicopia.cloud": "Cloud", + "block.unicopia.cloud_pillar": "Cloud Pillar", + "block.unicopia.dense_cloud": "Dense Cloud", "block.unicopia.oats": "Oats", "block.unicopia.oats_stem": "Oats", diff --git a/src/main/resources/assets/unicopia/models/block/cloud.json b/src/main/resources/assets/unicopia/models/block/cloud.json new file mode 100644 index 00000000..73923250 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/cloud.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "unicopia:block/cloud" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/cloud_pillar_end.json b/src/main/resources/assets/unicopia/models/block/cloud_pillar_end.json new file mode 100644 index 00000000..d07524e5 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/cloud_pillar_end.json @@ -0,0 +1,21 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "unicopia:block/cloud_pillar_top", + "side": "unicopia:block/cloud_pillar_side_end" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 5, 16], + "faces": { + "north": {"uv": [0, 11, 16, 16], "texture": "#side"}, + "east": {"uv": [0, 11, 16, 16], "texture": "#side"}, + "south": {"uv": [0, 11, 16, 16], "texture": "#side"}, + "west": {"uv": [0, 11, 16, 16], "texture": "#side"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#top", "cullface": "down"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/cloud_pillar_middle.json b/src/main/resources/assets/unicopia/models/block/cloud_pillar_middle.json new file mode 100644 index 00000000..a4803ce6 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/cloud_pillar_middle.json @@ -0,0 +1,21 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "unicopia:block/cloud_pillar_top", + "side": "unicopia:block/cloud_pillar_side" + }, + "elements": [ + { + "from": [1, 0, 1], + "to": [15, 16, 15], + "faces": { + "north": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "east": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "south": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "west": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "up": {"uv": [1, 1, 15, 15], "texture": "#top", "cullface": "up"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#top", "cullface": "down"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/block/dense_cloud.json b/src/main/resources/assets/unicopia/models/block/dense_cloud.json new file mode 100644 index 00000000..e37ff40b --- /dev/null +++ b/src/main/resources/assets/unicopia/models/block/dense_cloud.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "unicopia:block/dense_cloud" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/item/cloud.json b/src/main/resources/assets/unicopia/models/item/cloud.json new file mode 100644 index 00000000..7babfca8 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/cloud.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/cloud" +} diff --git a/src/main/resources/assets/unicopia/models/item/cloud_pillar.json b/src/main/resources/assets/unicopia/models/item/cloud_pillar.json new file mode 100644 index 00000000..2bbe230b --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/cloud_pillar.json @@ -0,0 +1,47 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "top": "unicopia:block/cloud_pillar_top", + "side": "unicopia:block/cloud_pillar_side", + "side_end": "unicopia:block/cloud_pillar_side_end", + "particle": "unicopia:block/cloud_pillar_side" + }, + "elements": [ + { + "from": [2, 1, 2], + "to": [14, 15, 14], + "faces": { + "north": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "east": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "south": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "west": {"uv": [1, 0, 15, 16], "texture": "#side"}, + "up": {"uv": [1, 1, 15, 15], "texture": "#top"}, + "down": {"uv": [1, 1, 15, 15], "texture": "#top"} + } + }, + { + "from": [0, 0, 0], + "to": [16, 5, 16], + "faces": { + "north": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "east": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "south": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "west": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#top"} + } + }, + { + "from": [0, 11, 0], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "east": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "south": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "west": {"uv": [0, 11, 16, 16], "texture": "#side_end"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#top"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/unicopia/models/item/dense_cloud.json b/src/main/resources/assets/unicopia/models/item/dense_cloud.json new file mode 100644 index 00000000..e7d67c42 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/dense_cloud.json @@ -0,0 +1,3 @@ +{ + "parent": "unicopia:block/dense_cloud" +} diff --git a/src/main/resources/assets/unicopia/textures/block/cloud.png b/src/main/resources/assets/unicopia/textures/block/cloud.png new file mode 100644 index 00000000..637090c2 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/block/cloud.png differ diff --git a/src/main/resources/assets/unicopia/textures/block/cloud_pillar_side.png b/src/main/resources/assets/unicopia/textures/block/cloud_pillar_side.png new file mode 100644 index 00000000..35b96c48 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/block/cloud_pillar_side.png differ diff --git a/src/main/resources/assets/unicopia/textures/block/cloud_pillar_side_end.png b/src/main/resources/assets/unicopia/textures/block/cloud_pillar_side_end.png new file mode 100644 index 00000000..9f753ec7 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/block/cloud_pillar_side_end.png differ diff --git a/src/main/resources/assets/unicopia/textures/block/cloud_pillar_top.png b/src/main/resources/assets/unicopia/textures/block/cloud_pillar_top.png new file mode 100644 index 00000000..2210ff1e Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/block/cloud_pillar_top.png differ diff --git a/src/main/resources/assets/unicopia/textures/block/dense_cloud.png b/src/main/resources/assets/unicopia/textures/block/dense_cloud.png new file mode 100644 index 00000000..8bb716e1 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/block/dense_cloud.png differ