diff --git a/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java b/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java index 7ff17cd..4f995c3 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java +++ b/src/main/java/net/shadowfacts/simplemultipart/SimpleMultipart.java @@ -1,6 +1,7 @@ package net.shadowfacts.simplemultipart; import net.fabricmc.api.ModInitializer; +import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.Identifier; import net.minecraft.util.registry.IdRegistry; @@ -9,14 +10,13 @@ import net.minecraft.world.loot.context.LootContextType; import net.minecraft.world.loot.context.LootContextTypes; import net.minecraft.world.loot.context.Parameter; import net.minecraft.world.loot.context.Parameters; -import net.shadowfacts.simplemultipart.container.ContainerBlockEntity; -import net.shadowfacts.simplemultipart.container.ContainerEventHandler; -import net.shadowfacts.simplemultipart.container.ContainerBlock; +import net.shadowfacts.simplemultipart.container.*; import net.shadowfacts.simplemultipart.multipart.Multipart; import net.shadowfacts.simplemultipart.multipart.MultipartState; import java.lang.reflect.Method; import java.util.function.Consumer; +import java.util.function.Supplier; /** * @author shadowfacts @@ -31,7 +31,8 @@ public class SimpleMultipart implements ModInitializer { public static final LootContextType MULTIPART_LOOT_CONTEXT = createMultipartLootContextType(); public static final ContainerBlock containerBlock = new ContainerBlock(); - public static final BlockEntityType containerBlockEntity = createBlockEntityType(); + public static final BlockEntityType containerBlockEntity = createBlockEntityType("container", ContainerBlockEntity::new); + public static final BlockEntityType tickableContainerBlockEntity = createBlockEntityType("tickable_container", TickableContainerBlockEntity::new); @Override public void onInitialize() { @@ -46,9 +47,9 @@ public class SimpleMultipart implements ModInitializer { return registry; } - private static BlockEntityType createBlockEntityType() { - BlockEntityType.Builder builder = BlockEntityType.Builder.create(ContainerBlockEntity::new); - return Registry.register(Registry.BLOCK_ENTITY, new Identifier(MODID, "container"), builder.method_11034(null)); + private static BlockEntityType createBlockEntityType(String name, Supplier supplier) { + BlockEntityType.Builder builder = BlockEntityType.Builder.create(supplier); + return Registry.register(Registry.BLOCK_ENTITY, new Identifier(MODID, name), builder.method_11034(null)); } private static LootContextType createMultipartLootContextType() { diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java new file mode 100644 index 0000000..77de8ca --- /dev/null +++ b/src/main/java/net/shadowfacts/simplemultipart/container/AbstractContainerBlockEntity.java @@ -0,0 +1,218 @@ +package net.shadowfacts.simplemultipart.container; + +import com.google.common.collect.ImmutableSet; +import net.fabricmc.fabric.api.util.NbtType; +import net.fabricmc.fabric.block.entity.ClientSerializable; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.Tickable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.world.loot.context.LootContext; +import net.minecraft.world.loot.context.Parameters; +import net.shadowfacts.simplemultipart.SimpleMultipart; +import net.shadowfacts.simplemultipart.api.MultipartContainer; +import net.shadowfacts.simplemultipart.multipart.MultipartState; +import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntity; +import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntityProvider; +import net.shadowfacts.simplemultipart.util.MultipartHelper; +import net.shadowfacts.simplemultipart.api.MultipartView; +import net.shadowfacts.simplemultipart.util.ShapeUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author shadowfacts + */ +public abstract class AbstractContainerBlockEntity extends BlockEntity implements MultipartContainer, ClientSerializable { + + protected Set parts = new HashSet<>(); + + public AbstractContainerBlockEntity(BlockEntityType type) { + super(type); + } + + @Override + public Set getParts() { + return ImmutableSet.copyOf(parts); + } + + @Override + public boolean canInsert(MultipartState partState) { + VoxelShape newShape = partState.getBoundingShape(null); + for (Entry e : parts) { + VoxelShape existingShape = e.state.getBoundingShape(e); + if (ShapeUtils.intersect(newShape, existingShape)) { + return false; + } + } + + return true; + } + + @Override + public void insert(MultipartState partState) { + if (!canInsert(partState)) { + return; + } + + MultipartEntity entity = null; + if (partState.getMultipart() instanceof MultipartEntityProvider) { + entity = ((MultipartEntityProvider)partState.getMultipart()).createMultipartEntity(partState, this); + } + parts.add(new Entry(this, partState, entity)); + + updateWorld(); + } + + @Override + public void remove(MultipartState partState) { + parts.removeIf(e -> e.state == partState); + + if (parts.isEmpty()) { + world.setBlockState(pos, Blocks.AIR.getDefaultState()); + } else { + updateWorld(); + } + } + + @Override + public boolean breakPart(MultipartState partState) { + Optional entry = parts.stream().filter(e -> e.state == partState).findFirst(); + if (!entry.isPresent()) { + return false; + } + + if (world instanceof ServerWorld) { + List drops = getDroppedStacks(entry.get(), (ServerWorld)world, pos); + drops.forEach(stack -> Block.dropStack(world, pos, stack)); + // TODO: don't drop if player is creative + } + + remove(partState); + + updateWorld(); + + return true; + } + + @Override + public void schedulePartSave() { + markDirty(); // see yarn #360 + } + + private void updateWorld() { + boolean hasTickableParts = parts.stream().anyMatch(e -> e.getEntity() != null && e.getEntity() instanceof Tickable); + boolean currentlyTickable = this instanceof Tickable; + if (hasTickableParts != currentlyTickable) { + AbstractContainerBlockEntity newContainer = hasTickableParts ? new TickableContainerBlockEntity() : new ContainerBlockEntity(); + world.setBlockEntity(pos, newContainer); + newContainer.parts = parts.stream() + .map(e -> new Entry(newContainer, e.state, e.entity)) + .collect(Collectors.toSet()); + } + + world.markDirty(pos, world.getBlockEntity(pos)); + world.scheduleBlockRender(pos); + BlockState blockState = world.getBlockState(pos); + world.updateListeners(pos, blockState, blockState, 3); + } + + private List getDroppedStacks(Entry e, ServerWorld world, BlockPos pos) { + LootContext.Builder builder = new LootContext.Builder(world); + builder.setRandom(world.random); + builder.put(SimpleMultipart.MULTIPART_STATE_PARAMETER, e.state); + builder.put(Parameters.POSITION, pos); + return e.state.getDroppedStacks(e, builder); + } + + private ListTag partsToTag() { + ListTag list = new ListTag(); + for (Entry e : parts) { + CompoundTag tag = new CompoundTag(); + tag.put("part", MultipartHelper.serializeMultipartState(e.state)); + if (e.entity != null) { + tag.put("entity", e.entity.toTag(new CompoundTag())); + } + list.add(tag); + } + return list; + } + + private void partsFromTag(ListTag list) { + parts.clear(); + for (Tag tag : list) { + CompoundTag compound = (CompoundTag)tag; + MultipartState state = MultipartHelper.deserializeMultipartState(compound.getCompound("part")); + MultipartEntity entity = null; + if (state.getMultipart() instanceof MultipartEntityProvider && compound.containsKey("entity", NbtType.COMPOUND)) { + entity = ((MultipartEntityProvider)state.getMultipart()).createMultipartEntity(state, this); + entity.fromTag(compound.getCompound("entity")); + } + parts.add(new Entry(this, state, entity)); + } + } + + @Override + public CompoundTag toTag(CompoundTag tag) { + tag.put("parts", partsToTag()); + return super.toTag(tag); + } + + @Override + public void fromTag(CompoundTag tag) { + super.fromTag(tag); + ListTag list = tag.getList("parts", NbtType.COMPOUND); + partsFromTag(list); + } + + @Override + public CompoundTag toClientTag(CompoundTag tag) { + tag.put("parts", partsToTag()); + return tag; + } + + @Override + public void fromClientTag(CompoundTag tag) { + ListTag list = tag.getList("parts", NbtType.COMPOUND); + partsFromTag(list); + updateWorld(); + } + + public static class Entry implements MultipartView { + public final MultipartContainer container; + public final MultipartState state; + public final MultipartEntity entity; + + private Entry(MultipartContainer container, MultipartState state, MultipartEntity entity) { + this.container = container; + this.state = state; + this.entity = entity; + } + + @Override + public MultipartContainer getContainer() { + return container; + } + + @Override + public MultipartState getState() { + return state; + } + + @Override + public MultipartEntity getEntity() { + return entity; + } + } + +} diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java index 47e513f..d068639 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java +++ b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlock.java @@ -71,7 +71,7 @@ public class ContainerBlock extends Block implements BlockEntityProvider, Render } @Override - public ContainerBlockEntity createBlockEntity(BlockView world) { + public AbstractContainerBlockEntity createBlockEntity(BlockView world) { return new ContainerBlockEntity(); } } diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlockEntity.java b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlockEntity.java index 5cdeb8a..ae1f0c8 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlockEntity.java +++ b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerBlockEntity.java @@ -1,197 +1,14 @@ package net.shadowfacts.simplemultipart.container; -import com.google.common.collect.ImmutableSet; -import net.fabricmc.fabric.api.util.NbtType; -import net.fabricmc.fabric.block.entity.ClientSerializable; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.world.loot.context.LootContext; -import net.minecraft.world.loot.context.Parameters; import net.shadowfacts.simplemultipart.SimpleMultipart; -import net.shadowfacts.simplemultipart.api.MultipartContainer; -import net.shadowfacts.simplemultipart.multipart.MultipartState; -import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntity; -import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntityProvider; -import net.shadowfacts.simplemultipart.util.MultipartHelper; -import net.shadowfacts.simplemultipart.api.MultipartView; -import net.shadowfacts.simplemultipart.util.ShapeUtils; - -import java.util.*; /** * @author shadowfacts */ -public class ContainerBlockEntity extends BlockEntity implements MultipartContainer, ClientSerializable { - - private Set parts = new HashSet<>(); +public class ContainerBlockEntity extends AbstractContainerBlockEntity { public ContainerBlockEntity() { super(SimpleMultipart.containerBlockEntity); } - @Override - public Set getParts() { - return ImmutableSet.copyOf(parts); - } - - @Override - public boolean canInsert(MultipartState partState) { - VoxelShape newShape = partState.getBoundingShape(null); - for (Entry e : parts) { - VoxelShape existingShape = e.state.getBoundingShape(e); - if (ShapeUtils.intersect(newShape, existingShape)) { - return false; - } - } - - return true; - } - - @Override - public void insert(MultipartState partState) { - if (!canInsert(partState)) { - return; - } - - MultipartEntity entity = null; - if (partState.getMultipart() instanceof MultipartEntityProvider) { - entity = ((MultipartEntityProvider)partState.getMultipart()).createMultipartEntity(partState, this); - } - parts.add(new Entry(partState, entity)); - markDirty(); - world.scheduleBlockRender(pos); - } - - @Override - public void remove(MultipartState partState) { - parts.removeIf(e -> e.state == partState); - - if (parts.isEmpty()) { - world.setBlockState(pos, Blocks.AIR.getDefaultState()); - } - } - - @Override - public boolean breakPart(MultipartState partState) { - Optional entry = parts.stream().filter(e -> e.state == partState).findFirst(); - if (!entry.isPresent()) { - return false; - } - - if (world instanceof ServerWorld) { - List drops = getDroppedStacks(entry.get(), (ServerWorld)world, pos); - drops.forEach(stack -> Block.dropStack(world, pos, stack)); - // TODO: don't drop if player is creative - } - - remove(partState); - - world.markDirty(pos, this); - world.scheduleBlockRender(pos); - BlockState blockState = world.getBlockState(pos); - world.updateListeners(pos, blockState, blockState, 3); - - return true; - } - - @Override - public void schedulePartSave() { - markDirty(); // see yarn #360 - } - - private List getDroppedStacks(ContainerBlockEntity.Entry e, ServerWorld world, BlockPos pos) { - LootContext.Builder builder = new LootContext.Builder(world); - builder.setRandom(world.random); - builder.put(SimpleMultipart.MULTIPART_STATE_PARAMETER, e.state); - builder.put(Parameters.POSITION, pos); - return e.state.getDroppedStacks(e, builder); - } - - private ListTag partsToTag() { - ListTag list = new ListTag(); - for (Entry e : parts) { - CompoundTag tag = new CompoundTag(); - tag.put("part", MultipartHelper.serializeMultipartState(e.state)); - if (e.entity != null) { - tag.put("entity", e.entity.toTag(new CompoundTag())); - } - list.add(tag); - } - return list; - } - - private void partsFromTag(ListTag list) { - parts.clear(); - for (Tag tag : list) { - CompoundTag compound = (CompoundTag)tag; - MultipartState state = MultipartHelper.deserializeMultipartState(compound.getCompound("part")); - MultipartEntity entity = null; - if (state.getMultipart() instanceof MultipartEntityProvider && compound.containsKey("entity", NbtType.COMPOUND)) { - entity = ((MultipartEntityProvider)state.getMultipart()).createMultipartEntity(state, this); - entity.fromTag(compound.getCompound("entity")); - } - parts.add(new Entry(state, entity)); - } - } - - @Override - public CompoundTag toTag(CompoundTag tag) { - tag.put("parts", partsToTag()); - return super.toTag(tag); - } - - @Override - public void fromTag(CompoundTag tag) { - super.fromTag(tag); - ListTag list = tag.getList("parts", NbtType.COMPOUND); - partsFromTag(list); - } - - @Override - public CompoundTag toClientTag(CompoundTag tag) { - tag.put("parts", partsToTag()); - return tag; - } - - @Override - public void fromClientTag(CompoundTag tag) { - ListTag list = tag.getList("parts", NbtType.COMPOUND); - partsFromTag(list); - world.scheduleBlockRender(pos); - } - - public class Entry implements MultipartView { - public final MultipartState state; - public final MultipartEntity entity; - - private Entry(MultipartState state, MultipartEntity entity) { - this.state = state; - this.entity = entity; - } - - @Override - public ContainerBlockEntity getContainer() { - return ContainerBlockEntity.this; // TODO: is this bad? - } - - @Override - public MultipartState getState() { - return state; - } - - @Override - public MultipartEntity getEntity() { - return entity; - } - } - } diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java index 9bf7a63..ef74789 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java +++ b/src/main/java/net/shadowfacts/simplemultipart/container/ContainerEventHandler.java @@ -1,6 +1,7 @@ package net.shadowfacts.simplemultipart.container; import net.fabricmc.fabric.events.PlayerInteractionEvent; +import net.minecraft.block.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; diff --git a/src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlockEntity.java b/src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlockEntity.java new file mode 100644 index 0000000..527bd76 --- /dev/null +++ b/src/main/java/net/shadowfacts/simplemultipart/container/TickableContainerBlockEntity.java @@ -0,0 +1,24 @@ +package net.shadowfacts.simplemultipart.container; + +import net.minecraft.util.Tickable; +import net.shadowfacts.simplemultipart.SimpleMultipart; + +/** + * @author shadowfacts + */ +public class TickableContainerBlockEntity extends AbstractContainerBlockEntity implements Tickable { + + public TickableContainerBlockEntity() { + super(SimpleMultipart.tickableContainerBlockEntity); + } + + @Override + public void tick() { + for (Entry e : parts) { + if (e.getEntity() != null && e.getEntity() instanceof Tickable) { + ((Tickable)e.getEntity()).tick(); + } + } + } + +} diff --git a/src/main/java/net/shadowfacts/simplemultipart/item/ItemMultipart.java b/src/main/java/net/shadowfacts/simplemultipart/item/ItemMultipart.java index 512d275..64a161e 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/item/ItemMultipart.java +++ b/src/main/java/net/shadowfacts/simplemultipart/item/ItemMultipart.java @@ -6,7 +6,6 @@ import net.minecraft.item.ItemUsageContext; import net.minecraft.util.ActionResult; import net.shadowfacts.simplemultipart.SimpleMultipart; import net.shadowfacts.simplemultipart.api.MultipartContainer; -import net.shadowfacts.simplemultipart.container.ContainerBlockEntity; import net.shadowfacts.simplemultipart.multipart.Multipart; import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.util.MultipartPlacementContext; diff --git a/src/main/java/net/shadowfacts/simplemultipart/util/MultipartHelper.java b/src/main/java/net/shadowfacts/simplemultipart/util/MultipartHelper.java index 4ec29e4..250f33f 100644 --- a/src/main/java/net/shadowfacts/simplemultipart/util/MultipartHelper.java +++ b/src/main/java/net/shadowfacts/simplemultipart/util/MultipartHelper.java @@ -15,7 +15,6 @@ import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.World; import net.shadowfacts.simplemultipart.SimpleMultipart; import net.shadowfacts.simplemultipart.api.MultipartContainer; -import net.shadowfacts.simplemultipart.container.ContainerBlockEntity; import net.shadowfacts.simplemultipart.multipart.Multipart; import net.shadowfacts.simplemultipart.multipart.MultipartState; diff --git a/src/test/java/net/shadowfacts/simplemultipart/test/EntityTestPart.java b/src/test/java/net/shadowfacts/simplemultipart/test/EntityTestPart.java index 0892578..49334f6 100644 --- a/src/test/java/net/shadowfacts/simplemultipart/test/EntityTestPart.java +++ b/src/test/java/net/shadowfacts/simplemultipart/test/EntityTestPart.java @@ -6,7 +6,8 @@ import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShapes; -import net.shadowfacts.simplemultipart.container.ContainerBlockEntity; +import net.shadowfacts.simplemultipart.api.MultipartContainer; +import net.shadowfacts.simplemultipart.container.AbstractContainerBlockEntity; import net.shadowfacts.simplemultipart.multipart.Multipart; import net.shadowfacts.simplemultipart.multipart.MultipartState; import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntity; @@ -33,17 +34,17 @@ public class EntityTestPart extends Multipart implements MultipartEntityProvider } @Override - public MultipartEntity createMultipartEntity(MultipartState state, ContainerBlockEntity container) { + public MultipartEntity createMultipartEntity(MultipartState state, MultipartContainer container) { return new Entity(container); } public static class Entity extends MultipartEntity { - public Entity(ContainerBlockEntity container) { + public Entity(MultipartContainer container) { super(container); } public BlockPos getPos() { - return container.getPos(); + return ((AbstractContainerBlockEntity)container).getPos(); } } diff --git a/src/test/java/net/shadowfacts/simplemultipart/test/MultipartTestMod.java b/src/test/java/net/shadowfacts/simplemultipart/test/MultipartTestMod.java index 6d83faf..690ae38 100644 --- a/src/test/java/net/shadowfacts/simplemultipart/test/MultipartTestMod.java +++ b/src/test/java/net/shadowfacts/simplemultipart/test/MultipartTestMod.java @@ -19,11 +19,13 @@ public class MultipartTestMod implements ModInitializer { public static final SlabMultipart ironSlab = new SlabMultipart(); public static final SlabMultipart goldSlab = new SlabMultipart(); public static final EntityTestPart entityTest = new EntityTestPart(); + public static final TickableEntityTestPart tickableEntityTest = new TickableEntityTestPart(); public static final ItemMultipart testItem = new ItemMultipart(testPart); public static final ItemMultipart ironSlabItem = new ItemMultipart(ironSlab); public static final ItemMultipart goldSlabItem = new ItemMultipart(goldSlab); public static final ItemMultipart entityTestItem = new ItemMultipart(entityTest); + public static final ItemMultipart tickableEntityTestItem = new ItemMultipart(tickableEntityTest); @Override public void onInitialize() { @@ -31,6 +33,7 @@ public class MultipartTestMod implements ModInitializer { registerPartAndItem("iron_slab", ironSlab, ironSlabItem); registerPartAndItem("gold_slab", goldSlab, goldSlabItem); registerPartAndItem("entity_test", entityTest, entityTestItem); + registerPartAndItem("tickable_entity_test", tickableEntityTest, tickableEntityTestItem); } private void registerPartAndItem(String name, Multipart part, Item item) { diff --git a/src/test/java/net/shadowfacts/simplemultipart/test/TickableEntityTestPart.java b/src/test/java/net/shadowfacts/simplemultipart/test/TickableEntityTestPart.java new file mode 100644 index 0000000..8295222 --- /dev/null +++ b/src/test/java/net/shadowfacts/simplemultipart/test/TickableEntityTestPart.java @@ -0,0 +1,53 @@ +package net.shadowfacts.simplemultipart.test; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.text.StringTextComponent; +import net.minecraft.util.Hand; +import net.minecraft.util.Tickable; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.shadowfacts.simplemultipart.api.MultipartContainer; +import net.shadowfacts.simplemultipart.api.MultipartView; +import net.shadowfacts.simplemultipart.multipart.Multipart; +import net.shadowfacts.simplemultipart.multipart.MultipartState; +import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntity; +import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntityProvider; + +/** + * @author shadowfacts + */ +public class TickableEntityTestPart extends Multipart implements MultipartEntityProvider { + + @Override + @Deprecated + public VoxelShape getBoundingShape(MultipartState state, MultipartView view) { + return VoxelShapes.cube(6/16f, 6/16f, 6/16f, 10/16f, 10/16f, 10/16f); + } + + @Override + @Deprecated + public boolean activate(MultipartState state, MultipartView view, PlayerEntity player, Hand hand) { + int timer = ((Entity)view.getEntity()).timer; + player.addChatMessage(new StringTextComponent("Timer: " + timer), false); + return true; + } + + @Override + public MultipartEntity createMultipartEntity(MultipartState state, MultipartContainer container) { + return new Entity(container); + } + + public static class Entity extends MultipartEntity implements Tickable { + public int timer = 0; + + public Entity(MultipartContainer container) { + super(container); + } + + @Override + public void tick() { + timer++; + } + } + +} diff --git a/src/test/resources/assets/multipart_test/models/multipart/tickable_entity_test.json b/src/test/resources/assets/multipart_test/models/multipart/tickable_entity_test.json new file mode 100644 index 0000000..2266055 --- /dev/null +++ b/src/test/resources/assets/multipart_test/models/multipart/tickable_entity_test.json @@ -0,0 +1,6 @@ +{ + "parent": "multipart_test:multipart/center", + "textures": { + "texture": "block/redstone_block" + } +} \ No newline at end of file diff --git a/src/test/resources/assets/multipart_test/multipartstates/tickable_entity_test.json b/src/test/resources/assets/multipart_test/multipartstates/tickable_entity_test.json new file mode 100644 index 0000000..21ea693 --- /dev/null +++ b/src/test/resources/assets/multipart_test/multipartstates/tickable_entity_test.json @@ -0,0 +1,6 @@ +{ + "variants": { + "": { "model": "multipart_test:multipart/tickable_entity_test" }, + "inventory": { "model": "multipart_test:multipart/tickable_entity_test" } + } +} \ No newline at end of file