started lotus, seashell, giant lilypad, improved krakens grasp

This commit is contained in:
craisinlord committed 2026-07-16 00:02:48 -05:00
1 parent 5aa77a2d01
commit 361bf005f3
64 files changed
+2287 -55

No files matched your search

@@ -29,6 +29,7 @@ import com.craisinlord.antarchy.content.entity.ReverieEntity;
import com.craisinlord.antarchy.content.entity.ScorpionEntity;
import com.craisinlord.antarchy.content.block.entity.AntNestBlockEntity;
import com.craisinlord.antarchy.content.block.entity.DreamCampfireBlockEntity;
import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity;
import com.craisinlord.antarchy.content.block.entity.WaspNestBlockEntity;
import java.util.function.Supplier;
import net.minecraft.core.Holder;
@@ -292,6 +293,10 @@ public final class AntarchyObjects {
@SuppressWarnings("unchecked")
public static Supplier<Block> GIANT_LILY_PAD = (Supplier<Block>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<Block> LOTUS = (Supplier<Block>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<Block> SEASHELL = (Supplier<Block>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<BlockEntityType<AntNestBlockEntity>> ANT_NEST_BLOCK_ENTITY = (Supplier<BlockEntityType<AntNestBlockEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<BlockEntityType<DreamCampfireBlockEntity>> DREAM_CAMPFIRE_BLOCK_ENTITY = (Supplier<BlockEntityType<DreamCampfireBlockEntity>>) UNBOUND;
@@ -300,6 +305,8 @@ public final class AntarchyObjects {
@SuppressWarnings("unchecked")
public static Supplier<BlockEntityType<HushweedBlockEntity>> HUSHWEED_BLOCK_ENTITY = (Supplier<BlockEntityType<HushweedBlockEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<BlockEntityType<SeashellBlockEntity>> SEASHELL_BLOCK_ENTITY = (Supplier<BlockEntityType<SeashellBlockEntity>>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<SimpleParticleType> STINKY_GAS = (Supplier<SimpleParticleType>) UNBOUND;
@SuppressWarnings("unchecked")
public static Supplier<SimpleParticleType> STINKY_FLY = (Supplier<SimpleParticleType>) UNBOUND;
@@ -401,10 +408,12 @@ public final class AntarchyObjects {
Supplier<Block> squirrelNestBlock,
Supplier<Block> brutalflyCocoonSpawner,
Supplier<Block> giantLilyPad,
Supplier<Block> seashell,
Supplier<BlockEntityType<AntNestBlockEntity>> antNestBlockEntity,
Supplier<BlockEntityType<DreamCampfireBlockEntity>> dreamCampfireBlockEntity,
Supplier<BlockEntityType<WaspNestBlockEntity>> waspNestBlockEntity,
Supplier<BlockEntityType<HushweedBlockEntity>> hushweedBlockEntity,
Supplier<BlockEntityType<SeashellBlockEntity>> seashellBlockEntity,
Supplier<SimpleParticleType> stinkyGas,
Supplier<SimpleParticleType> stinkyFly,
Supplier<SimpleParticleType> peachLeaves,
@@ -500,10 +509,12 @@ public final class AntarchyObjects {
SQUIRREL_NEST_BLOCK = squirrelNestBlock;
BRUTALFLY_COCOON_SPAWNER = brutalflyCocoonSpawner;
GIANT_LILY_PAD = giantLilyPad;
SEASHELL = seashell;
ANT_NEST_BLOCK_ENTITY = antNestBlockEntity;
DREAM_CAMPFIRE_BLOCK_ENTITY = dreamCampfireBlockEntity;
WASP_NEST_BLOCK_ENTITY = waspNestBlockEntity;
HUSHWEED_BLOCK_ENTITY = hushweedBlockEntity;
SEASHELL_BLOCK_ENTITY = seashellBlockEntity;
STINKY_GAS = stinkyGas;
STINKY_FLY = stinkyFly;
PEACH_LEAVES_PARTICLE = peachLeaves;
@@ -524,6 +535,10 @@ public final class AntarchyObjects {
TENTACLE = supplier;
}
public static void setLotus(Supplier<Block> supplier) {
LOTUS = supplier;
}
public static void setKrakensGraspTrident(Supplier<EntityType<KrakensGraspThrownTrident>> supplier) {
KRAKENS_GRASP_TRIDENT = supplier;
}
@@ -59,7 +59,7 @@ public final class CreativeTabOrder {
"myrmite", "broodstone", "chiten_block", "chiten_spike", "amber_moss_block", "amber_moss_carpet" -> 8;
case "ouranwood_leaves", "peach_leaves" -> 9;
case "duplicator_sapling", "ouranwood_acorn", "peach_sapling", "corn_seeds" -> 10;
case "orange_milkweed", "pink_milkweed", "camellia", "spider_lily", "hushweed", "amber_lichen", "creepvine",
case "orange_milkweed", "pink_milkweed", "camellia", "spider_lily", "lotus", "hushweed", "amber_lichen", "creepvine",
"triffid_goo_block", "cloud_block", "wasp_nest",
"red_ant_nest", "brown_ant_nest", "rainbow_ant_nest", "termite_nest",
"star_coral", "star_coral_fan", "star_coral_block",
@@ -179,6 +179,7 @@ public final class CreativeTabOrder {
case "dead_star_coral" -> 17;
case "dead_star_coral_fan" -> 18;
case "dead_star_coral_block" -> 19;
case "lotus" -> 20;
case "blood_crystal_block" -> 0;
case "small_blood_crystal_bud" -> 1;
case "medium_blood_crystal_bud" -> 2;
@@ -1,5 +1,6 @@
package com.craisinlord.antarchy.content.block;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.AntarchyTags;
import com.mojang.serialization.MapCodec;
import java.util.ArrayList;
@@ -8,6 +9,7 @@ import java.util.List;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
@@ -15,6 +17,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.BonemealableBlock;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockBehaviour;
@@ -25,7 +28,7 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
public final class GiantLilyPadBlock extends Block {
public final class GiantLilyPadBlock extends Block implements BonemealableBlock {
public static final MapCodec<GiantLilyPadBlock> CODEC = Block.simpleCodec(GiantLilyPadBlock::new);
public static final EnumProperty<Shape> SHAPE = EnumProperty.create("shape", Shape.class);
public static final EnumProperty<TilePosition> TILE_POSITION = EnumProperty.create("tile_position", TilePosition.class);
@@ -73,6 +76,68 @@ public final class GiantLilyPadBlock extends Block {
return isSupported(level, pos);
}
@Override
public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) {
if (isThreeByThreeCenter(state)) {
return level.isEmptyBlock(pos.above());
}
return state.getValue(SHAPE) != Shape.THREE_BY_THREE;
}
@Override
public boolean isBonemealSuccess(Level level, RandomSource random, BlockPos pos, BlockState state) {
return true;
}
@Override
public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) {
if (isThreeByThreeCenter(state)) {
growLotus(level, pos);
return;
}
if (state.getValue(SHAPE) == Shape.THREE_BY_THREE) {
return;
}
spreadNearby(level, random, pos);
}
private static boolean isThreeByThreeCenter(BlockState state) {
return state.getValue(SHAPE) == Shape.THREE_BY_THREE && state.getValue(TILE_POSITION) == TilePosition.CENTER;
}
private static void growLotus(ServerLevel level, BlockPos padPos) {
BlockPos abovePos = padPos.above();
if (!level.isEmptyBlock(abovePos)) {
return;
}
BlockState lotusState = AntarchyObjects.LOTUS.get().defaultBlockState();
if (lotusState.canSurvive(level, abovePos)) {
level.setBlock(abovePos, lotusState, Block.UPDATE_ALL);
}
}
private static void spreadNearby(ServerLevel level, RandomSource random, BlockPos origin) {
for (int attempt = 0; attempt < 6; attempt++) {
int dx = random.nextInt(5) - 2;
int dz = random.nextInt(5) - 2;
if (dx == 0 && dz == 0) {
continue;
}
BlockPos candidate = origin.offset(dx, 0, dz);
if (!level.isEmptyBlock(candidate) || !isSupported(level, candidate)) {
continue;
}
level.setBlock(candidate, AntarchyObjects.GIANT_LILY_PAD.get().defaultBlockState(), Block.UPDATE_ALL);
return;
}
}
@Override
protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos pos, BlockPos neighborPos) {
if (!state.canSurvive(level, pos)) {
@@ -0,0 +1,107 @@
package com.craisinlord.antarchy.content.block;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.DustParticleOptions;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.joml.Vector3f;
public class LotusBlock extends Block {
public static final MapCodec<LotusBlock> CODEC = simpleCodec(LotusBlock::new);
public static final BooleanProperty HANGING = BlockStateProperties.HANGING;
private static final VoxelShape SHAPE = Block.box(3.0D, 0.0D, 3.0D, 13.0D, 13.0D, 13.0D);
private static final Vector3f POLLEN_COLOR = new Vector3f(1.0F, 0.85F, 0.2F);
public LotusBlock(BlockBehaviour.Properties properties) {
super(properties);
this.registerDefaultState(this.stateDefinition.any().setValue(HANGING, false));
}
@Override
public MapCodec<LotusBlock> codec() {
return CODEC;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(HANGING);
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
boolean canHang = canSurvive(this.defaultBlockState().setValue(HANGING, true), level, pos);
boolean canStand = canSurvive(this.defaultBlockState().setValue(HANGING, false), level, pos);
if (context.getClickedFace() == Direction.DOWN && canHang) {
return this.defaultBlockState().setValue(HANGING, true);
}
if (canStand) {
return this.defaultBlockState().setValue(HANGING, false);
}
return canHang ? this.defaultBlockState().setValue(HANGING, true) : null;
}
@Override
protected RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
}
@Override
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return SHAPE;
}
@Override
protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) {
if (state.getValue(HANGING)) {
BlockPos abovePos = pos.above();
return level.getBlockState(abovePos).isFaceSturdy(level, abovePos, Direction.DOWN);
}
BlockPos belowPos = pos.below();
return level.getBlockState(belowPos).isFaceSturdy(level, belowPos, Direction.UP);
}
@Override
protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos pos, BlockPos neighborPos) {
Direction supportDirection = state.getValue(HANGING) ? Direction.UP : Direction.DOWN;
if (direction == supportDirection && !state.canSurvive(level, pos)) {
return Blocks.AIR.defaultBlockState();
}
return super.updateShape(state, direction, neighborState, level, pos, neighborPos);
}
@Override
public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
if (random.nextInt(10) != 0) {
return;
}
double x = pos.getX() + 0.5D + (random.nextDouble() - 0.5D) * 0.6D;
double z = pos.getZ() + 0.5D + (random.nextDouble() - 0.5D) * 0.6D;
double y = state.getValue(HANGING) ? pos.getY() + 0.2D : pos.getY() + 0.8D;
double motionY = state.getValue(HANGING) ? -0.02D : 0.015D;
level.addParticle(new DustParticleOptions(POLLEN_COLOR, 1.0F), x, y, z, 0.0D, motionY, 0.0D);
}
}
@@ -0,0 +1,240 @@
package com.craisinlord.antarchy.content.block;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity;
import com.mojang.serialization.MapCodec;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.ItemInteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
public final class SeashellBlock extends BaseEntityBlock implements SimpleWaterloggedBlock {
public static final MapCodec<SeashellBlock> CODEC = Block.simpleCodec(SeashellBlock::new);
public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
private static final VoxelShape SHAPE = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 5.333333D, 15.0D);
public SeashellBlock(BlockBehaviour.Properties properties) {
super(properties);
this.registerDefaultState(this.stateDefinition.any()
.setValue(FACING, Direction.NORTH)
.setValue(POWERED, false)
.setValue(WATERLOGGED, false));
}
@Override
public MapCodec<SeashellBlock> codec() {
return CODEC;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(FACING, POWERED, WATERLOGGED);
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos());
boolean powered = context.getLevel().hasNeighborSignal(context.getClickedPos());
return this.defaultBlockState()
.setValue(FACING, context.getHorizontalDirection().getOpposite())
.setValue(POWERED, powered)
.setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER);
}
@Override
protected RenderShape getRenderShape(BlockState state) {
return RenderShape.ENTITYBLOCK_ANIMATED;
}
@Override
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return SHAPE;
}
@Override
protected VoxelShape getCollisionShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return SHAPE;
}
@Override
protected VoxelShape getOcclusionShape(BlockState state, BlockGetter level, BlockPos pos) {
return SHAPE;
}
@Override
protected BlockState rotate(BlockState state, net.minecraft.world.level.block.Rotation rotation) {
return state.setValue(FACING, rotation.rotate(state.getValue(FACING)));
}
@Override
protected BlockState mirror(BlockState state, net.minecraft.world.level.block.Mirror mirror) {
return state.rotate(mirror.getRotation(state.getValue(FACING)));
}
@Override
protected FluidState getFluidState(BlockState state) {
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
}
@Override
protected BlockState updateShape(
BlockState state,
Direction direction,
BlockState neighborState,
LevelAccessor level,
BlockPos pos,
BlockPos neighborPos
) {
if (state.getValue(WATERLOGGED)) {
level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
}
if (!state.canSurvive(level, pos)) {
return Blocks.AIR.defaultBlockState();
}
if (level instanceof Level actualLevel && !actualLevel.isClientSide) {
this.updatePowerState(actualLevel, pos, state);
}
return super.updateShape(state, direction, neighborState, level, pos, neighborPos);
}
@Override
protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) {
return level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP);
}
@Override
protected void neighborChanged(
BlockState state,
Level level,
BlockPos pos,
Block block,
BlockPos neighborPos,
boolean movedByPiston
) {
super.neighborChanged(state, level, pos, block, neighborPos, movedByPiston);
if (!level.isClientSide) {
this.updatePowerState(level, pos, state);
}
}
@Override
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
super.onPlace(state, level, pos, oldState, movedByPiston);
if (!level.isClientSide) {
this.updatePowerState(level, pos, state);
}
}
@Override
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
if (!state.is(newState.getBlock()) && level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell) {
seashell.dropContents(level, pos);
}
super.onRemove(state, level, pos, newState, movedByPiston);
}
@Override
protected ItemInteractionResult useItemOn(
ItemStack stack,
BlockState state,
Level level,
BlockPos pos,
Player player,
InteractionHand hand,
BlockHitResult hitResult
) {
if (!(level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell)) {
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}
if (!stack.isEmpty()) {
if (level.isClientSide) {
return seashell.canAcceptItem(player, stack) ? ItemInteractionResult.SUCCESS : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}
if (seashell.tryInsert(player, hand, stack)) {
level.playSound(null, pos, SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, 0.6F, 0.95F + level.random.nextFloat() * 0.1F);
return ItemInteractionResult.CONSUME;
}
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}
if (level.isClientSide) {
return seashell.hasAnyContents() ? ItemInteractionResult.SUCCESS : ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}
if (seashell.tryRemove(player, hand)) {
level.playSound(null, pos, SoundEvents.ITEM_FRAME_REMOVE_ITEM, SoundSource.BLOCKS, 0.6F, 0.95F + level.random.nextFloat() * 0.1F);
return ItemInteractionResult.CONSUME;
}
return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}
@Override
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new SeashellBlockEntity(pos, state);
}
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state, BlockEntityType<T> blockEntityType) {
return level.isClientSide
? createTickerHelper(blockEntityType, AntarchyObjects.SEASHELL_BLOCK_ENTITY.get(), SeashellBlockEntity::clientTick)
: createTickerHelper(blockEntityType, AntarchyObjects.SEASHELL_BLOCK_ENTITY.get(), SeashellBlockEntity::serverTick);
}
private void updatePowerState(Level level, BlockPos pos, BlockState state) {
boolean powered = level.hasNeighborSignal(pos);
if (state.getValue(POWERED) == powered) {
if (level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell) {
seashell.syncVisualState(powered);
}
return;
}
BlockState updatedState = state.setValue(POWERED, powered);
level.setBlock(pos, updatedState, Block.UPDATE_ALL);
if (level.getBlockEntity(pos) instanceof SeashellBlockEntity seashell) {
seashell.onPowerStateChanged(powered);
}
}
}
@@ -0,0 +1,261 @@
package com.craisinlord.antarchy.content.block.entity;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.block.SeashellBlock;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
import software.bernie.geckolib.animatable.GeoBlockEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.animation.AnimationController;
import software.bernie.geckolib.animation.PlayState;
import software.bernie.geckolib.animation.RawAnimation;
import software.bernie.geckolib.util.GeckoLibUtil;
public final class SeashellBlockEntity extends RandomizableContainerBlockEntity implements GeoBlockEntity {
private static final String MAIN_CONTROLLER = "main_controller";
private static final String TRANSITION_CONTROLLER = "transition_controller";
private static final String OPEN_TRIGGER = "close_to_open";
private static final String CLOSE_TRIGGER = "open_to_close";
private static final RawAnimation OPEN_ANIM = RawAnimation.begin().thenPlayAndHold("open");
private static final RawAnimation CLOSED_ANIM = RawAnimation.begin().thenPlayAndHold("closed");
private static final Component TITLE = Component.translatable("block.antarchy.seashell");
private final AnimatableInstanceCache animatableCache = GeckoLibUtil.createInstanceCache(this);
private NonNullList<ItemStack> items = NonNullList.withSize(9, ItemStack.EMPTY);
private boolean visualOpen;
private boolean initializedVisualState;
public SeashellBlockEntity(BlockPos pos, BlockState blockState) {
super(AntarchyObjects.SEASHELL_BLOCK_ENTITY.get(), pos, blockState);
this.visualOpen = blockState.getValue(SeashellBlock.POWERED);
}
public static void serverTick(Level level, BlockPos pos, BlockState state, SeashellBlockEntity seashell) {
seashell.syncVisualState(state.getValue(SeashellBlock.POWERED));
}
public static void clientTick(Level level, BlockPos pos, BlockState state, SeashellBlockEntity seashell) {
seashell.syncVisualState(state.getValue(SeashellBlock.POWERED));
}
public boolean canAcceptItem(@Nullable Player player, ItemStack stack) {
this.unpackLootTable(player);
return !stack.isEmpty() && this.getFirstEmptySlot() >= 0;
}
public boolean tryInsert(@Nullable Player player, InteractionHand hand, ItemStack heldStack) {
this.unpackLootTable(player);
int slot = this.getFirstEmptySlot();
if (slot < 0 || heldStack.isEmpty()) {
return false;
}
ItemStack inserted = heldStack.copyWithCount(1);
this.items.set(slot, inserted);
if (player == null || !player.getAbilities().instabuild) {
heldStack.shrink(1);
}
this.setChangedAndSync();
return true;
}
public boolean tryRemove(Player player, InteractionHand hand) {
this.unpackLootTable(player);
int slot = this.getLastFilledSlot();
if (slot < 0) {
return false;
}
ItemStack removed = this.items.get(slot);
this.items.set(slot, ItemStack.EMPTY);
if (player.getItemInHand(hand).isEmpty()) {
player.setItemInHand(hand, removed);
} else if (!player.addItem(removed)) {
player.drop(removed, false);
}
this.setChangedAndSync();
return true;
}
public boolean hasAnyContents() {
return this.items.stream().anyMatch(stack -> !stack.isEmpty());
}
public void dropContents(Level level, BlockPos pos) {
this.unpackLootTable(null);
Containers.dropContents(level, pos, this.items);
this.items = NonNullList.withSize(9, ItemStack.EMPTY);
this.setChanged();
}
public void onPowerStateChanged(boolean open) {
this.syncVisualState(open);
this.triggerAnim(TRANSITION_CONTROLLER, open ? OPEN_TRIGGER : CLOSE_TRIGGER);
this.setChangedAndSync();
}
public void syncVisualState(boolean open) {
if (!this.initializedVisualState) {
this.visualOpen = open;
this.initializedVisualState = true;
return;
}
this.visualOpen = open;
}
public boolean isVisualOpen() {
return this.visualOpen;
}
public List<DisplayedStack> getDisplayedStacks() {
List<ItemStack> inserted = new ArrayList<>();
for (ItemStack stack : this.items) {
if (!stack.isEmpty()) {
inserted.add(stack);
}
}
List<DisplayedStack> displayed = new ArrayList<>(inserted.size());
for (int i = 0; i < inserted.size(); i++) {
displayed.add(new DisplayedStack(inserted.get(i), displayOffsetFor(i)));
}
return displayed;
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, MAIN_CONTROLLER, state ->
state.setAndContinue(this.visualOpen ? OPEN_ANIM : CLOSED_ANIM)));
controllers.add(new AnimationController<>(this, TRANSITION_CONTROLLER, state -> PlayState.STOP)
.triggerableAnim(OPEN_TRIGGER, RawAnimation.begin().thenPlay(OPEN_TRIGGER))
.triggerableAnim(CLOSE_TRIGGER, RawAnimation.begin().thenPlay(CLOSE_TRIGGER)));
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.animatableCache;
}
@Override
protected Component getDefaultName() {
return TITLE;
}
@Override
protected NonNullList<ItemStack> getItems() {
return this.items;
}
@Override
protected void setItems(NonNullList<ItemStack> items) {
this.items = items;
}
@Override
protected AbstractContainerMenu createMenu(int containerId, Inventory inventory) {
return ChestMenu.threeRows(containerId, inventory, this);
}
@Override
public int getMaxStackSize() {
return 1;
}
@Override
public boolean canPlaceItem(int slot, ItemStack stack) {
return !stack.isEmpty() && this.items.get(slot).isEmpty();
}
@Override
public int getContainerSize() {
return this.items.size();
}
@Override
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.saveAdditional(tag, registries);
tag.putBoolean("VisualOpen", this.visualOpen);
tag.putBoolean("VisualInitialized", this.initializedVisualState);
}
@Override
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
super.loadAdditional(tag, registries);
this.visualOpen = tag.getBoolean("VisualOpen");
this.initializedVisualState = tag.getBoolean("VisualInitialized");
}
private void setChangedAndSync() {
this.setChanged();
if (this.level != null) {
BlockState state = this.getBlockState();
this.level.sendBlockUpdated(this.worldPosition, state, state, Block.UPDATE_CLIENTS);
}
}
private int getFirstEmptySlot() {
for (int i = 0; i < this.items.size(); i++) {
if (this.items.get(i).isEmpty()) {
return i;
}
}
return -1;
}
private int getLastFilledSlot() {
for (int i = this.items.size() - 1; i >= 0; i--) {
if (!this.items.get(i).isEmpty()) {
return i;
}
}
return -1;
}
private static Vec3 displayOffsetFor(int insertionIndex) {
return switch (insertionIndex) {
case 0 -> offset(1, 0);
case 1 -> offset(0, 0);
case 2 -> offset(2, 0);
case 3 -> offset(1, 1);
case 4 -> offset(0, 1);
case 5 -> offset(2, 1);
case 6 -> offset(1, 2);
case 7 -> offset(0, 2);
case 8 -> offset(2, 2);
default -> Vec3.ZERO;
};
}
private static Vec3 offset(int column, int row) {
double x = -0.22D + column * 0.22D;
double z = -0.22D + row * 0.22D;
return new Vec3(x, 0.155D, z);
}
public record DisplayedStack(ItemStack stack, Vec3 offset) {
}
}
@@ -0,0 +1,22 @@
package com.craisinlord.antarchy.content.client.model;
import com.craisinlord.antarchy.content.entity.kraken.KrakensGraspThrownTrident;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class KrakensGraspThrownTridentModel extends GeoModel<KrakensGraspThrownTrident> {
@Override
public ResourceLocation getModelResource(KrakensGraspThrownTrident animatable) {
return ResourceLocation.fromNamespaceAndPath("antarchy", "geo/krakens_grasp.geo.json");
}
@Override
public ResourceLocation getTextureResource(KrakensGraspThrownTrident animatable) {
return ResourceLocation.fromNamespaceAndPath("antarchy", "textures/item/krakens_grasp/krakens_grasp.png");
}
@Override
public ResourceLocation getAnimationResource(KrakensGraspThrownTrident animatable) {
return ResourceLocation.fromNamespaceAndPath("antarchy", "animations/static_item.animation.json");
}
}
@@ -0,0 +1,27 @@
package com.craisinlord.antarchy.content.client.model;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public final class SeashellModel extends GeoModel<SeashellBlockEntity> {
private static final ResourceLocation MODEL = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "geo/seashell.geo.json");
private static final ResourceLocation TEXTURE = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "textures/block/seashell.png");
private static final ResourceLocation ANIMATION = ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "animations/seashell.animation.json");
@Override
public ResourceLocation getModelResource(SeashellBlockEntity animatable) {
return MODEL;
}
@Override
public ResourceLocation getTextureResource(SeashellBlockEntity animatable) {
return TEXTURE;
}
@Override
public ResourceLocation getAnimationResource(SeashellBlockEntity animatable) {
return ANIMATION;
}
}
@@ -0,0 +1,13 @@
package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.client.model.KrakensGraspThrownTridentModel;
import com.craisinlord.antarchy.content.entity.kraken.KrakensGraspThrownTrident;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class KrakensGraspThrownTridentRenderer extends GeoEntityRenderer<KrakensGraspThrownTrident> {
public KrakensGraspThrownTridentRenderer(EntityRendererProvider.Context context) {
super(context, new KrakensGraspThrownTridentModel());
this.shadowRadius = 0.0F;
}
}
@@ -0,0 +1,73 @@
package com.craisinlord.antarchy.content.client.renderer;
import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity;
import com.craisinlord.antarchy.content.client.model.SeashellModel;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoBlockRenderer;
public final class SeashellRenderer extends GeoBlockRenderer<SeashellBlockEntity> {
public SeashellRenderer(BlockEntityRendererProvider.Context context) {
super(new SeashellModel());
}
@Override
public void actuallyRender(
PoseStack poseStack,
SeashellBlockEntity animatable,
BakedGeoModel model,
net.minecraft.client.renderer.RenderType renderType,
MultiBufferSource bufferSource,
com.mojang.blaze3d.vertex.VertexConsumer buffer,
boolean isReRender,
float partialTick,
int packedLight,
int packedOverlay,
int colour
) {
super.actuallyRender(poseStack, animatable, model, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, colour);
if (isReRender) {
return;
}
float yaw = -animatable.getBlockState().getValue(com.craisinlord.antarchy.content.block.SeashellBlock.FACING).toYRot();
for (SeashellBlockEntity.DisplayedStack displayedStack : animatable.getDisplayedStacks()) {
this.renderDisplayItem(poseStack, bufferSource, displayedStack.stack(), displayedStack.offset(), yaw, packedLight, packedOverlay);
}
}
private void renderDisplayItem(
PoseStack poseStack,
MultiBufferSource bufferSource,
ItemStack stack,
Vec3 localOffset,
float yaw,
int packedLight,
int packedOverlay
) {
poseStack.pushPose();
poseStack.translate(0.5D, 0.0D, 0.5D);
poseStack.mulPose(com.mojang.math.Axis.YP.rotationDegrees(yaw));
poseStack.translate(localOffset.x(), localOffset.y(), localOffset.z());
poseStack.mulPose(com.mojang.math.Axis.XP.rotationDegrees(90.0F));
poseStack.scale(0.22F, 0.22F, 0.22F);
Minecraft.getInstance().getItemRenderer().renderStatic(
stack,
ItemDisplayContext.FIXED,
packedLight,
packedOverlay,
poseStack,
bufferSource,
null,
0
);
poseStack.popPose();
}
}
@@ -11,16 +11,20 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.ItemSupplier;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.util.GeckoLibUtil;
public class KrakensGraspThrownTrident extends AbstractArrow implements ItemSupplier {
public class KrakensGraspThrownTrident extends AbstractArrow implements GeoEntity {
private boolean dealtDamage;
private boolean returning;
private final AnimatableInstanceCache geoCache = GeckoLibUtil.createInstanceCache(this);
public KrakensGraspThrownTrident(EntityType<? extends KrakensGraspThrownTrident> entityType, Level level) {
super(entityType, level);
@@ -32,8 +36,12 @@ public class KrakensGraspThrownTrident extends AbstractArrow implements ItemSupp
}
@Override
public ItemStack getItem() {
return new ItemStack(AntarchyObjects.KRAKENS_GRASP.get());
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.geoCache;
}
@Override
@@ -94,6 +102,8 @@ public class KrakensGraspThrownTrident extends AbstractArrow implements ItemSupp
boolean hurt = target.hurt(damageSource, (float) AntarchySettings.krakensGraspThrownDamage());
if (hurt) {
KrakensGraspItem.strikeLightning(target, serverLevel);
TentacleEntity.spawnAt(serverLevel, new Vec3(target.getX(), target.getY(), target.getZ()),
owner instanceof LivingEntity livingOwner ? livingOwner : null);
}
this.dealtDamage = true;
@@ -58,11 +58,6 @@ public class KrakensGraspItem extends TridentItem implements GeoItem {
.build();
}
@Override
public net.minecraft.world.item.UseAnim getUseAnimation(ItemStack stack) {
return net.minecraft.world.item.UseAnim.NONE;
}
@Override
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) {
super.inventoryTick(stack, level, entity, slotId, isSelected);
@@ -0,0 +1,101 @@
package com.craisinlord.antarchy.content.worldgen.elythia;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
import java.util.ArrayList;
import java.util.List;
public final class GiantLilyPadPatchFeature extends Feature<NoneFeatureConfiguration> {
public GiantLilyPadPatchFeature(Codec<NoneFeatureConfiguration> codec) {
super(codec);
}
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
WorldGenLevel level = context.level();
RandomSource random = context.random();
BlockPos origin = context.origin();
boolean placedAny = false;
for (int i = 0; i < 12; i++) {
int anchorX = origin.getX() + random.nextInt(17) - 8;
int anchorZ = origin.getZ() + random.nextInt(17) - 8;
int surfaceY = level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, anchorX, anchorZ) - 1;
BlockPos anchorFluidPos = new BlockPos(anchorX, surfaceY, anchorZ);
if (!level.getFluidState(anchorFluidPos).is(FluidTags.WATER) || !level.getFluidState(anchorFluidPos).isSource()) {
continue;
}
int size = rollFootprintSize(random);
List<BlockPos> footprint = new ArrayList<>(size * size);
boolean valid = true;
for (int row = 0; row < size && valid; row++) {
for (int column = 0; column < size; column++) {
BlockPos fluidPos = new BlockPos(anchorX + column, surfaceY, anchorZ + row);
if (!level.getFluidState(fluidPos).is(FluidTags.WATER) || !level.getFluidState(fluidPos).isSource()) {
valid = false;
break;
}
BlockPos padPos = fluidPos.above();
if (!level.isEmptyBlock(padPos)) {
valid = false;
break;
}
footprint.add(padPos);
}
}
if (!valid) {
continue;
}
Block giantLilyPad = AntarchyObjects.GIANT_LILY_PAD.get();
BlockState padState = giantLilyPad.defaultBlockState();
for (BlockPos padPos : footprint) {
level.setBlock(padPos, padState, Block.UPDATE_ALL);
}
placedAny = true;
if (size == 3 && random.nextFloat() < 0.5F) {
BlockPos centerPos = new BlockPos(anchorX + 1, surfaceY, anchorZ + 1).above();
placeLotus(level, centerPos.above());
}
}
return placedAny;
}
private static int rollFootprintSize(RandomSource random) {
float roll = random.nextFloat();
if (roll < 0.5F) {
return 1;
}
return roll < 0.8F ? 2 : 3;
}
private void placeLotus(WorldGenLevel level, BlockPos pos) {
if (!level.isEmptyBlock(pos)) {
return;
}
BlockState lotusState = AntarchyObjects.LOTUS.get().defaultBlockState();
if (lotusState.canSurvive(level, pos)) {
level.setBlock(pos, lotusState, Block.UPDATE_ALL);
}
}
}
@@ -0,0 +1,65 @@
package com.craisinlord.antarchy.content.worldgen.ocean;
import com.craisinlord.antarchy.Antarchy;
import com.craisinlord.antarchy.content.AntarchyObjects;
import com.craisinlord.antarchy.content.block.SeashellBlock;
import com.craisinlord.antarchy.content.block.entity.SeashellBlockEntity;
import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
public final class SeashellFeature extends Feature<NoneFeatureConfiguration> {
private static final ResourceKey<LootTable> LOOT_TABLE = ResourceKey.create(
Registries.LOOT_TABLE,
ResourceLocation.fromNamespaceAndPath(Antarchy.MODID, "chests/seashell")
);
public SeashellFeature(Codec<NoneFeatureConfiguration> codec) {
super(codec);
}
@Override
public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
WorldGenLevel level = context.level();
RandomSource random = context.random();
BlockPos origin = context.origin();
boolean placedAny = false;
for (int i = 0; i < 8; i++) {
int x = origin.getX() + random.nextInt(17) - 8;
int z = origin.getZ() + random.nextInt(17) - 8;
int floorY = level.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, x, z);
BlockPos shellPos = new BlockPos(x, floorY, z);
if (!level.getFluidState(shellPos).isSource()) {
continue;
}
BlockState state = AntarchyObjects.SEASHELL.get().defaultBlockState()
.setValue(SeashellBlock.FACING, net.minecraft.core.Direction.Plane.HORIZONTAL.getRandomDirection(random))
.setValue(SeashellBlock.WATERLOGGED, true)
.setValue(SeashellBlock.POWERED, false);
if (!state.canSurvive(level, shellPos)) {
continue;
}
level.setBlock(shellPos, state, 2);
if (level.getBlockEntity(shellPos) instanceof SeashellBlockEntity seashell) {
seashell.setLootTable(LOOT_TABLE, random.nextLong());
}
placedAny = true;
}
return placedAny;
}
}
@@ -0,0 +1,62 @@
{
"format_version": "1.8.0",
"animations": {
"close_to_open": {
"loop": "hold_on_last_frame",
"animation_length": 0.375,
"bones": {
"upper_moving": {
"rotation": {
"0.0": {
"vector": [0, 0, 0]
},
"0.375": {
"vector": [-90, 0, 0],
"easing": "easeOutBack"
}
}
}
}
},
"closed": {
"loop": "hold_on_last_frame",
"bones": {
"upper_moving": {
"rotation": {
"vector": [0, 0, 0]
}
}
}
},
"open_to_close": {
"loop": "hold_on_last_frame",
"animation_length": 0.4167,
"bones": {
"upper_moving": {
"rotation": {
"0.0": {
"vector": [-90, 0, 0],
"easing": "easeOutBack"
},
"0.4167": {
"vector": [0, 0, 0],
"easing": "easeInOutBack",
"easingArgs": [0.5]
}
}
}
}
},
"open": {
"loop": "hold_on_last_frame",
"bones": {
"upper_moving": {
"rotation": {
"vector": [-90, 0, 0],
"easing": "easeOutBack"
}
}
}
}
}
}
@@ -0,0 +1,6 @@
{
"variants": {
"hanging=false": { "model": "antarchy:block/lotus" },
"hanging=true": { "model": "antarchy:block/lotus", "x": 180 }
}
}
@@ -0,0 +1,20 @@
{
"variants": {
"facing=north,powered=false,waterlogged=false": { "model": "builtin/entity" },
"facing=north,powered=false,waterlogged=true": { "model": "builtin/entity" },
"facing=north,powered=true,waterlogged=false": { "model": "builtin/entity" },
"facing=north,powered=true,waterlogged=true": { "model": "builtin/entity" },
"facing=south,powered=false,waterlogged=false": { "model": "builtin/entity" },
"facing=south,powered=false,waterlogged=true": { "model": "builtin/entity" },
"facing=south,powered=true,waterlogged=false": { "model": "builtin/entity" },
"facing=south,powered=true,waterlogged=true": { "model": "builtin/entity" },
"facing=east,powered=false,waterlogged=false": { "model": "builtin/entity" },
"facing=east,powered=false,waterlogged=true": { "model": "builtin/entity" },
"facing=east,powered=true,waterlogged=false": { "model": "builtin/entity" },
"facing=east,powered=true,waterlogged=true": { "model": "builtin/entity" },
"facing=west,powered=false,waterlogged=false": { "model": "builtin/entity" },
"facing=west,powered=false,waterlogged=true": { "model": "builtin/entity" },
"facing=west,powered=true,waterlogged=false": { "model": "builtin/entity" },
"facing=west,powered=true,waterlogged=true": { "model": "builtin/entity" }
}
}
@@ -0,0 +1,173 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.unknown",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "seashell",
"pivot": [0, 0, 0]
},
{
"name": "lower",
"parent": "seashell",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-7, 0, -7],
"size": [14, 2, 14],
"uv": {
"north": {"uv": [14, 15], "uv_size": [14, 2]},
"east": {"uv": [0, 15], "uv_size": [14, 2]},
"south": {"uv": [42, 15], "uv_size": [14, 2]},
"west": {"uv": [28, 15], "uv_size": [14, 2]},
"up": {"uv": [14, 0], "uv_size": [14, 14]},
"down": {"uv": [28, 14], "uv_size": [14, -14]}
}
},
{
"origin": [-7, 2, -7],
"size": [14, 1, 1],
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [13, 14], "uv_size": [1, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [28, 14], "uv_size": [1, 1]},
"up": {"uv": [14, 0], "uv_size": [14, 1]},
"down": {"uv": [28, 14], "uv_size": [14, -14]}
}
},
{
"origin": [-7, 2, -6],
"size": [1, 1, 12],
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [1, 14], "uv_size": [12, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [29, 14], "uv_size": [12, 1]},
"up": {"uv": [14, 1], "uv_size": [1, 12]},
"down": {"uv": [28, 14], "uv_size": [14, -14]}
}
},
{
"origin": [6, 2, -6],
"size": [1, 1, 12],
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [1, 14], "uv_size": [12, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [29, 14], "uv_size": [12, 1]},
"up": {"uv": [27, 1], "uv_size": [1, 12]},
"down": {"uv": [28, 14], "uv_size": [14, -14]}
}
},
{
"origin": [-7, 2, 6],
"size": [14, 1, 1],
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [13, 14], "uv_size": [1, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [28, 14], "uv_size": [1, 1]},
"up": {"uv": [14, 0], "uv_size": [14, 1]},
"down": {"uv": [28, 14], "uv_size": [14, -14]}
}
}
]
},
{
"name": "upper_moving",
"parent": "seashell",
"pivot": [0, 2.5, 7],
"cubes": [
{
"origin": [-2, 1.5, 7],
"size": [4, 2, 1],
"inflate": 0.01,
"uv": {
"north": {"uv": [2, 34], "uv_size": [4, 2]},
"east": {"uv": [1, 34], "uv_size": [1, 2]},
"south": {"uv": [7, 34], "uv_size": [4, 2]},
"west": {"uv": [6, 34], "uv_size": [1, 2]},
"up": {"uv": [2, 33], "uv_size": [4, 1]},
"down": {"uv": [6, 34], "uv_size": [4, -1]}
}
},
{
"origin": [-7, 3.5, -7],
"size": [14, 1, 14],
"inflate": 0.01,
"uv": {
"north": {"uv": [14, 31], "uv_size": [14, 1]},
"east": {"uv": [0, 31], "uv_size": [14, 1]},
"south": {"uv": [42, 31], "uv_size": [14, 1]},
"west": {"uv": [28, 31], "uv_size": [14, 1]},
"up": {"uv": [14, 17], "uv_size": [14, 14]},
"down": {"uv": [28, 31], "uv_size": [14, -14]}
}
},
{
"origin": [-7, 2.5, 6],
"size": [14, 1, 1],
"inflate": 0.01,
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [13, 14], "uv_size": [1, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [28, 14], "uv_size": [1, 1]},
"up": {"uv": [14, 0], "uv_size": [14, 1]},
"down": {"uv": [28, 1], "uv_size": [14, -1]}
}
},
{
"origin": [6, 2.5, -6],
"size": [1, 1, 12],
"inflate": 0.01,
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [1, 14], "uv_size": [12, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [29, 32], "uv_size": [12, 1]},
"up": {"uv": [27, 1], "uv_size": [1, 12]},
"down": {"uv": [41, 13], "uv_size": [1, -12]}
}
},
{
"origin": [-7, 2.5, -7],
"size": [14, 1, 1],
"inflate": 0.01,
"uv": {
"north": {"uv": [14, 32], "uv_size": [14, 1]},
"east": {"uv": [13, 14], "uv_size": [1, 1]},
"south": {"uv": [42, 32], "uv_size": [14, 1]},
"west": {"uv": [28, 32], "uv_size": [1, 1]},
"up": {"uv": [14, 0], "uv_size": [14, 1]},
"down": {"uv": [28, 1], "uv_size": [14, -1]}
}
},
{
"origin": [-7, 2.5, -6],
"size": [1, 1, 12],
"inflate": 0.01,
"uv": {
"north": {"uv": [14, 14], "uv_size": [14, 1]},
"east": {"uv": [1, 32], "uv_size": [12, 1]},
"south": {"uv": [42, 14], "uv_size": [14, 1]},
"west": {"uv": [29, 14], "uv_size": [12, 1]},
"up": {"uv": [14, 1], "uv_size": [1, 12]},
"down": {"uv": [28, 13], "uv_size": [1, -12]}
}
}
]
}
]
}
]
}
@@ -41,7 +41,10 @@
"block.antarchy.pink_milkweed": "Pink Milkweed",
"block.antarchy.camellia": "Camellia",
"block.antarchy.spider_lily": "Spider Lily",
"block.antarchy.lotus": "Lotus",
"item.antarchy.lotus": "Lotus",
"block.antarchy.giant_lily_pad": "Giant Lily Pad",
"block.antarchy.seashell": "Seashell",
"block.antarchy.hushweed": "Hushweed",
"block.antarchy.umbral_moss_block": "Umbral Moss Block",
"block.antarchy.umbral_moss_carpet": "Umbral Moss Carpet",
@@ -233,6 +236,7 @@
"item.antarchy.dream_lantern": "Dream Lantern",
"item.antarchy.dream_campfire": "Dream Campfire",
"item.antarchy.giant_lily_pad": "Giant Lily Pad",
"item.antarchy.seashell": "Seashell",
"item.antarchy.nightmare_scale": "Nightmare Scale",
"item.antarchy.nightmare_helmet": "Nightmare Helmet",
"item.antarchy.nightmare_chestplate": "Nightmare Chestplate",
@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cross",
"textures": {
"cross": "antarchy:block/lotus"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "antarchy:item/cheep"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "antarchy:block/lotus"
}
}
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "antarchy:block/seashell"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,18 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"conditions": [
{ "condition": "minecraft:survives_explosion" }
],
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:lotus"
}
]
}
],
"random_sequence": "antarchy:blocks/lotus"
}
@@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:seashell"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}
@@ -0,0 +1,23 @@
{
"type": "minecraft:chest",
"pools": [
{
"rolls": {
"type": "minecraft:uniform",
"min": 2,
"max": 5
},
"entries": [
{ "type": "minecraft:item", "name": "minecraft:nautilus_shell", "weight": 8 },
{ "type": "minecraft:item", "name": "minecraft:prismarine_shard", "weight": 10 },
{ "type": "minecraft:item", "name": "minecraft:prismarine_crystals", "weight": 8 },
{ "type": "minecraft:item", "name": "minecraft:kelp", "weight": 12 },
{ "type": "minecraft:item", "name": "minecraft:seagrass", "weight": 10 },
{ "type": "minecraft:item", "name": "minecraft:tropical_fish", "weight": 4 },
{ "type": "minecraft:item", "name": "minecraft:bone_meal", "weight": 8 },
{ "type": "minecraft:item", "name": "antarchy:star_coral", "weight": 3 },
{ "type": "minecraft:item", "name": "antarchy:giant_lily_pad", "weight": 1 }
]
}
]
}
@@ -1,5 +1,15 @@
{
"type": "minecraft:entity",
"pools": [],
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "antarchy:cheep"
}
]
}
],
"random_sequence": "antarchy:entities/cheep"
}
@@ -0,0 +1,11 @@
{
"type": "minecraft:crafting_shapeless",
"category": "misc",
"ingredients": [
{ "item": "antarchy:lotus" }
],
"result": {
"count": 2,
"id": "minecraft:pink_dye"
}
}
@@ -0,0 +1,14 @@
{
"replace": false,
"values": [
"#minecraft:is_ocean",
{
"id": "#neoforge:is_ocean",
"required": false
},
{
"id": "#c:ocean",
"required": false
}
]
}
@@ -54,7 +54,8 @@
[
"minecraft:sea_pickle",
"minecraft:warm_ocean_vegetation",
"minecraft:kelp_warm"
"minecraft:kelp_warm",
"antarchy:giant_lily_pad_patch"
],
[]
],
@@ -55,7 +55,8 @@
[],
[
"antarchy:elythia_meadow_flora",
"minecraft:patch_sugar_cane"
"minecraft:patch_sugar_cane",
"antarchy:giant_lily_pad_patch"
],
[]
],
@@ -0,0 +1,4 @@
{
"type": "antarchy:giant_lily_pad_patch",
"config": {}
}
@@ -0,0 +1,4 @@
{
"type": "antarchy:seashell_patch",
"config": {}
}
@@ -0,0 +1,9 @@
{
"feature": "antarchy:giant_lily_pad_patch",
"placement": [
{ "type": "minecraft:rarity_filter", "chance": 6 },
{ "type": "minecraft:in_square" },
{ "type": "minecraft:heightmap", "heightmap": "MOTION_BLOCKING_NO_LEAVES" },
{ "type": "minecraft:biome" }
]
}
@@ -0,0 +1,19 @@
{
"feature": "antarchy:seashell_patch",
"placement": [
{
"type": "minecraft:rarity_filter",
"chance": 10
},
{
"type": "minecraft:in_square"
},
{
"type": "minecraft:heightmap",
"heightmap": "OCEAN_FLOOR_WG"
},
{
"type": "minecraft:biome"
}
]
}
@@ -2,6 +2,7 @@
"replace": false,
"values": [
"antarchy:camellia",
"antarchy:lotus",
"antarchy:orange_milkweed",
"antarchy:pink_milkweed",
"antarchy:spider_lily"
@@ -1,6 +1,7 @@
{
"replace": false,
"values": [
"antarchy:lotus",
"antarchy:spider_lily"
]
}
@@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"antarchy:cheep"
]
}
@@ -2,6 +2,7 @@
"replace": false,
"values": [
"antarchy:camellia",
"antarchy:lotus",
"antarchy:orange_milkweed",
"antarchy:pink_milkweed",
"antarchy:spider_lily"
@@ -1,6 +1,7 @@
{
"replace": false,
"values": [
"antarchy:lotus",
"antarchy:spider_lily"
]
}