Initial tickable multipart entity implementation
This commit is contained in:
parent
17a5a8d6ee
commit
5759262d07
|
@ -1,6 +1,7 @@
|
||||||
package net.shadowfacts.simplemultipart;
|
package net.shadowfacts.simplemultipart;
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.IdRegistry;
|
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.LootContextTypes;
|
||||||
import net.minecraft.world.loot.context.Parameter;
|
import net.minecraft.world.loot.context.Parameter;
|
||||||
import net.minecraft.world.loot.context.Parameters;
|
import net.minecraft.world.loot.context.Parameters;
|
||||||
import net.shadowfacts.simplemultipart.container.ContainerBlockEntity;
|
import net.shadowfacts.simplemultipart.container.*;
|
||||||
import net.shadowfacts.simplemultipart.container.ContainerEventHandler;
|
|
||||||
import net.shadowfacts.simplemultipart.container.ContainerBlock;
|
|
||||||
import net.shadowfacts.simplemultipart.multipart.Multipart;
|
import net.shadowfacts.simplemultipart.multipart.Multipart;
|
||||||
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -31,7 +31,8 @@ public class SimpleMultipart implements ModInitializer {
|
||||||
public static final LootContextType MULTIPART_LOOT_CONTEXT = createMultipartLootContextType();
|
public static final LootContextType MULTIPART_LOOT_CONTEXT = createMultipartLootContextType();
|
||||||
|
|
||||||
public static final ContainerBlock containerBlock = new ContainerBlock();
|
public static final ContainerBlock containerBlock = new ContainerBlock();
|
||||||
public static final BlockEntityType<ContainerBlockEntity> containerBlockEntity = createBlockEntityType();
|
public static final BlockEntityType<ContainerBlockEntity> containerBlockEntity = createBlockEntityType("container", ContainerBlockEntity::new);
|
||||||
|
public static final BlockEntityType<TickableContainerBlockEntity> tickableContainerBlockEntity = createBlockEntityType("tickable_container", TickableContainerBlockEntity::new);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
@ -46,9 +47,9 @@ public class SimpleMultipart implements ModInitializer {
|
||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockEntityType<ContainerBlockEntity> createBlockEntityType() {
|
private static <T extends BlockEntity> BlockEntityType<T> createBlockEntityType(String name, Supplier<T> supplier) {
|
||||||
BlockEntityType.Builder<ContainerBlockEntity> builder = BlockEntityType.Builder.create(ContainerBlockEntity::new);
|
BlockEntityType.Builder<T> builder = BlockEntityType.Builder.create(supplier);
|
||||||
return Registry.register(Registry.BLOCK_ENTITY, new Identifier(MODID, "container"), builder.method_11034(null));
|
return Registry.register(Registry.BLOCK_ENTITY, new Identifier(MODID, name), builder.method_11034(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LootContextType createMultipartLootContextType() {
|
private static LootContextType createMultipartLootContextType() {
|
||||||
|
|
|
@ -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<Entry> parts = new HashSet<>();
|
||||||
|
|
||||||
|
public AbstractContainerBlockEntity(BlockEntityType<?> type) {
|
||||||
|
super(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<MultipartView> 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> entry = parts.stream().filter(e -> e.state == partState).findFirst();
|
||||||
|
if (!entry.isPresent()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (world instanceof ServerWorld) {
|
||||||
|
List<ItemStack> 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<ItemStack> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -71,7 +71,7 @@ public class ContainerBlock extends Block implements BlockEntityProvider, Render
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerBlockEntity createBlockEntity(BlockView world) {
|
public AbstractContainerBlockEntity createBlockEntity(BlockView world) {
|
||||||
return new ContainerBlockEntity();
|
return new ContainerBlockEntity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,197 +1,14 @@
|
||||||
package net.shadowfacts.simplemultipart.container;
|
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.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
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
public class ContainerBlockEntity extends BlockEntity implements MultipartContainer, ClientSerializable {
|
public class ContainerBlockEntity extends AbstractContainerBlockEntity {
|
||||||
|
|
||||||
private Set<Entry> parts = new HashSet<>();
|
|
||||||
|
|
||||||
public ContainerBlockEntity() {
|
public ContainerBlockEntity() {
|
||||||
super(SimpleMultipart.containerBlockEntity);
|
super(SimpleMultipart.containerBlockEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<MultipartView> 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> entry = parts.stream().filter(e -> e.state == partState).findFirst();
|
|
||||||
if (!entry.isPresent()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (world instanceof ServerWorld) {
|
|
||||||
List<ItemStack> 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<ItemStack> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.shadowfacts.simplemultipart.container;
|
package net.shadowfacts.simplemultipart.container;
|
||||||
|
|
||||||
import net.fabricmc.fabric.events.PlayerInteractionEvent;
|
import net.fabricmc.fabric.events.PlayerInteractionEvent;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import net.minecraft.item.ItemUsageContext;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.ActionResult;
|
||||||
import net.shadowfacts.simplemultipart.SimpleMultipart;
|
import net.shadowfacts.simplemultipart.SimpleMultipart;
|
||||||
import net.shadowfacts.simplemultipart.api.MultipartContainer;
|
import net.shadowfacts.simplemultipart.api.MultipartContainer;
|
||||||
import net.shadowfacts.simplemultipart.container.ContainerBlockEntity;
|
|
||||||
import net.shadowfacts.simplemultipart.multipart.Multipart;
|
import net.shadowfacts.simplemultipart.multipart.Multipart;
|
||||||
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
||||||
import net.shadowfacts.simplemultipart.util.MultipartPlacementContext;
|
import net.shadowfacts.simplemultipart.util.MultipartPlacementContext;
|
||||||
|
|
|
@ -15,7 +15,6 @@ import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.shadowfacts.simplemultipart.SimpleMultipart;
|
import net.shadowfacts.simplemultipart.SimpleMultipart;
|
||||||
import net.shadowfacts.simplemultipart.api.MultipartContainer;
|
import net.shadowfacts.simplemultipart.api.MultipartContainer;
|
||||||
import net.shadowfacts.simplemultipart.container.ContainerBlockEntity;
|
|
||||||
import net.shadowfacts.simplemultipart.multipart.Multipart;
|
import net.shadowfacts.simplemultipart.multipart.Multipart;
|
||||||
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.util.shape.VoxelShapes;
|
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.Multipart;
|
||||||
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
import net.shadowfacts.simplemultipart.multipart.MultipartState;
|
||||||
import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntity;
|
import net.shadowfacts.simplemultipart.multipart.entity.MultipartEntity;
|
||||||
|
@ -33,17 +34,17 @@ public class EntityTestPart extends Multipart implements MultipartEntityProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MultipartEntity createMultipartEntity(MultipartState state, ContainerBlockEntity container) {
|
public MultipartEntity createMultipartEntity(MultipartState state, MultipartContainer container) {
|
||||||
return new Entity(container);
|
return new Entity(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Entity extends MultipartEntity {
|
public static class Entity extends MultipartEntity {
|
||||||
public Entity(ContainerBlockEntity container) {
|
public Entity(MultipartContainer container) {
|
||||||
super(container);
|
super(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockPos getPos() {
|
public BlockPos getPos() {
|
||||||
return container.getPos();
|
return ((AbstractContainerBlockEntity)container).getPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@ public class MultipartTestMod implements ModInitializer {
|
||||||
public static final SlabMultipart ironSlab = new SlabMultipart();
|
public static final SlabMultipart ironSlab = new SlabMultipart();
|
||||||
public static final SlabMultipart goldSlab = new SlabMultipart();
|
public static final SlabMultipart goldSlab = new SlabMultipart();
|
||||||
public static final EntityTestPart entityTest = new EntityTestPart();
|
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 testItem = new ItemMultipart(testPart);
|
||||||
public static final ItemMultipart ironSlabItem = new ItemMultipart(ironSlab);
|
public static final ItemMultipart ironSlabItem = new ItemMultipart(ironSlab);
|
||||||
public static final ItemMultipart goldSlabItem = new ItemMultipart(goldSlab);
|
public static final ItemMultipart goldSlabItem = new ItemMultipart(goldSlab);
|
||||||
public static final ItemMultipart entityTestItem = new ItemMultipart(entityTest);
|
public static final ItemMultipart entityTestItem = new ItemMultipart(entityTest);
|
||||||
|
public static final ItemMultipart tickableEntityTestItem = new ItemMultipart(tickableEntityTest);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
@ -31,6 +33,7 @@ public class MultipartTestMod implements ModInitializer {
|
||||||
registerPartAndItem("iron_slab", ironSlab, ironSlabItem);
|
registerPartAndItem("iron_slab", ironSlab, ironSlabItem);
|
||||||
registerPartAndItem("gold_slab", goldSlab, goldSlabItem);
|
registerPartAndItem("gold_slab", goldSlab, goldSlabItem);
|
||||||
registerPartAndItem("entity_test", entityTest, entityTestItem);
|
registerPartAndItem("entity_test", entityTest, entityTestItem);
|
||||||
|
registerPartAndItem("tickable_entity_test", tickableEntityTest, tickableEntityTestItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerPartAndItem(String name, Multipart part, Item item) {
|
private void registerPartAndItem(String name, Multipart part, Item item) {
|
||||||
|
|
|
@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "multipart_test:multipart/center",
|
||||||
|
"textures": {
|
||||||
|
"texture": "block/redstone_block"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": { "model": "multipart_test:multipart/tickable_entity_test" },
|
||||||
|
"inventory": { "model": "multipart_test:multipart/tickable_entity_test" }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue