Skip to content

Commit

Permalink
Added partial BlockEntity and custom screen support
Browse files Browse the repository at this point in the history
  • Loading branch information
LatvianModder committed Oct 18, 2023
1 parent 69f9889 commit a161188
Show file tree
Hide file tree
Showing 30 changed files with 1,042 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import dev.latvian.mods.kubejs.block.custom.WallBlockBuilder;
import dev.latvian.mods.kubejs.block.custom.WoodenButtonBlockBuilder;
import dev.latvian.mods.kubejs.block.custom.WoodenPressurePlateBlockBuilder;
import dev.latvian.mods.kubejs.block.entity.BlockEntityAttachmentType;
import dev.latvian.mods.kubejs.block.entity.InventoryAttachment;
import dev.latvian.mods.kubejs.block.state.BlockStatePredicate;
import dev.latvian.mods.kubejs.client.LangEventJS;
import dev.latvian.mods.kubejs.client.painter.Painter;
Expand Down Expand Up @@ -535,6 +537,11 @@ public void registerRecipeSchemas(RegisterRecipeSchemasEvent event) {
event.mapRecipe("dankStorageUpgrade", "dankstorage:upgrade");
}

@Override
public void registerBlockEntityAttachments(List<BlockEntityAttachmentType> types) {
types.add(InventoryAttachment.TYPE);
}

@Override
public void generateDataJsons(DataJsonGenerator generator) {
for (var builder : RegistryInfo.ALL_BUILDERS) {
Expand Down
2 changes: 2 additions & 0 deletions common/src/main/java/dev/latvian/mods/kubejs/KubeJS.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import dev.latvian.mods.kubejs.client.KubeJSClient;
import dev.latvian.mods.kubejs.entity.KubeJSEntityEventHandler;
import dev.latvian.mods.kubejs.event.StartupEventJS;
import dev.latvian.mods.kubejs.gui.KubeJSMenu;
import dev.latvian.mods.kubejs.item.KubeJSItemEventHandler;
import dev.latvian.mods.kubejs.level.KubeJSWorldEventHandler;
import dev.latvian.mods.kubejs.net.KubeJSNet;
Expand Down Expand Up @@ -153,6 +154,7 @@ public KubeJS() throws Throwable {
KubeJSItemEventHandler.init();
KubeJSServerEventHandler.init();
KubeJSRecipeEventHandler.init();
KubeJSMenu.init();

PROXY.init();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.latvian.mods.kubejs;

import dev.latvian.mods.kubejs.block.entity.BlockEntityAttachmentType;
import dev.latvian.mods.kubejs.client.ClientProperties;
import dev.latvian.mods.kubejs.client.LangEventJS;
import dev.latvian.mods.kubejs.event.EventGroup;
Expand All @@ -23,6 +24,7 @@
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;

import java.util.List;
import java.util.Map;

public class KubeJSPlugin {
Expand Down Expand Up @@ -68,6 +70,9 @@ public void registerCustomJavaToJsWrappers(CustomJavaToJsWrappersEvent event) {
public void registerRecipeSchemas(RegisterRecipeSchemasEvent event) {
}

public void registerBlockEntityAttachments(List<BlockEntityAttachmentType> types) {
}

public void attachServerData(AttachedData<MinecraftServer> event) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import dev.latvian.mods.kubejs.block.callbacks.CanBeReplacedCallbackJS;
import dev.latvian.mods.kubejs.block.callbacks.EntityFallenOnBlockCallbackJS;
import dev.latvian.mods.kubejs.block.callbacks.EntitySteppedOnBlockCallbackJS;
import dev.latvian.mods.kubejs.block.entity.BlockEntityBuilder;
import dev.latvian.mods.kubejs.block.entity.BlockEntityInfo;
import dev.latvian.mods.kubejs.client.ModelGenerator;
import dev.latvian.mods.kubejs.client.VariantBlockStateGenerator;
import dev.latvian.mods.kubejs.generator.AssetJsonGenerator;
Expand Down Expand Up @@ -97,9 +99,10 @@ public abstract class BlockBuilder extends BuilderBase<Block> {
public transient Consumer<EntityFallenOnBlockCallbackJS> fallOnCallback;
public transient Consumer<AfterEntityFallenOnBlockCallbackJS> afterFallenOnCallback;
public transient Consumer<BlockExplodedCallbackJS> explodedCallback;

public transient Consumer<BlockStateRotateCallbackJS> rotateStateModification;
public transient Consumer<BlockStateMirrorCallbackJS> mirrorStateModification;
public transient Consumer<BlockRightClickedEventJS> rightClick;
public transient BlockEntityInfo blockEntityInfo;

public BlockBuilder(ResourceLocation i) {
super(i);
Expand Down Expand Up @@ -154,6 +157,10 @@ public void createAdditionalObjects() {
if (itemBuilder != null) {
RegistryInfo.ITEM.addBuilder(itemBuilder);
}

if (blockEntityInfo != null) {
RegistryInfo.BLOCK_ENTITY_TYPE.addBuilder(new BlockEntityBuilder(id, blockEntityInfo));
}
}

@Override
Expand Down Expand Up @@ -791,6 +798,19 @@ public BlockBuilder mirrorState(Consumer<BlockStateMirrorCallbackJS> callbackJS)
return this;
}

@Info("Set the callback used for right-clicking on the block")
public BlockBuilder rightClick(Consumer<BlockRightClickedEventJS> callbackJS) {
rightClick = callbackJS;
return this;
}

@Info("Creates a Block Entity for this block")
public BlockBuilder blockEntity(Consumer<BlockEntityInfo> callback) {
blockEntityInfo = new BlockEntityInfo(this);
callback.accept(blockEntityInfo);
return this;
}

public Block.Properties createProperties() {
if (material == null) {
material = MaterialListJS.INSTANCE.map.get("wood");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.latvian.mods.kubejs.block.custom;

import dev.latvian.mods.kubejs.block.BlockBuilder;
import dev.latvian.mods.kubejs.block.BlockRightClickedEventJS;
import dev.latvian.mods.kubejs.block.KubeJSBlockProperties;
import dev.latvian.mods.kubejs.block.RandomTickCallbackJS;
import dev.latvian.mods.kubejs.block.callbacks.AfterEntityFallenOnBlockCallbackJS;
Expand All @@ -12,6 +13,7 @@
import dev.latvian.mods.kubejs.block.callbacks.CanBeReplacedCallbackJS;
import dev.latvian.mods.kubejs.block.callbacks.EntityFallenOnBlockCallbackJS;
import dev.latvian.mods.kubejs.block.callbacks.EntitySteppedOnBlockCallbackJS;
import dev.latvian.mods.kubejs.block.entity.BlockEntityJS;
import dev.latvian.mods.kubejs.core.BlockKJS;
import dev.latvian.mods.kubejs.level.BlockContainerJS;
import dev.latvian.mods.kubejs.script.ScriptType;
Expand All @@ -21,23 +23,32 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
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.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
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.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.Fluid;
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.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
Expand All @@ -55,7 +66,25 @@ public Builder(ResourceLocation i) {

@Override
public Block createObject() {
return new BasicBlockJS(this);
return blockEntityInfo != null ? new WithEntity(this) : new BasicBlockJS(this);
}
}

public static class WithEntity extends BasicBlockJS implements EntityBlock {
public WithEntity(BlockBuilder p) {
super(p);
}

@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return blockBuilder.blockEntityInfo.createBlockEntity(blockPos, blockState);
}

@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState blockState, BlockEntityType<T> blockEntityType) {
return blockBuilder.blockEntityInfo.getTicker(level);
}
}

Expand Down Expand Up @@ -293,4 +322,41 @@ public BlockState mirror(BlockState blockState, Mirror mirror) {

return super.mirror(blockState, mirror);
}

@Override
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (blockBuilder.rightClick != null) {
if (!level.isClientSide()) {
blockBuilder.rightClick.accept(new BlockRightClickedEventJS(player, hand, pos, hit.getDirection()));
}

return InteractionResult.SUCCESS;
}

return InteractionResult.PASS;
}

@Override
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean bl) {
if (!state.is(newState.getBlock())) {
if (level.getBlockEntity(pos) instanceof BlockEntityJS entity) {
if (level instanceof ServerLevel) {
for (var attachment : entity.attachments) {
attachment.onRemove(newState);
}
}

level.updateNeighbourForOutputSignal(pos, this);
}

super.onRemove(state, level, pos, newState, bl);
}
}

@Override
public void setPlacedBy(Level level, BlockPos blockPos, BlockState blockState, @Nullable LivingEntity livingEntity, ItemStack itemStack) {
if (livingEntity != null && !level.isClientSide() && level.getBlockEntity(blockPos) instanceof BlockEntityJS e) {
e.placerId = livingEntity.getUUID();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
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.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
Expand All @@ -20,6 +25,7 @@
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -80,7 +86,7 @@ private String getTextureOrDefault(String name, String defaultTexture) {

@Override
public Block createObject() {
return new HorizontalDirectionalBlockJS(this);
return blockEntityInfo != null ? new WithEntity(this) : new HorizontalDirectionalBlockJS(this);
}

public static class HorizontalDirectionalBlockJS extends BasicBlockJS {
Expand Down Expand Up @@ -136,6 +142,23 @@ private boolean hasCustomShape() {
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return hasCustomShape() ? shapes.get(state.getValue(FACING)) : shape;
}
}

public static class WithEntity extends HorizontalDirectionalBlockJS implements EntityBlock {
public WithEntity(BlockBuilder p) {
super(p);
}

@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return blockBuilder.blockEntityInfo.createBlockEntity(blockPos, blockState);
}

@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState blockState, BlockEntityType<T> blockEntityType) {
return blockBuilder.blockEntityInfo.getTicker(level);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.latvian.mods.kubejs.block.entity;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.state.BlockState;

public interface BlockEntityAttachment {
BlockEntityAttachment[] EMPTY_ARRAY = new BlockEntityAttachment[0];

interface Factory {
BlockEntityAttachment create(BlockEntityJS entity);
}

default CompoundTag writeAttachment() {
return new CompoundTag();
}

default void readAttachment(CompoundTag tag) {
}

default void onRemove(BlockState newState) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.latvian.mods.kubejs.block.entity;

public record BlockEntityAttachmentHolder(int index, BlockEntityAttachment.Factory factory) {
@Override
public String toString() {
return "attachment_" + index;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package dev.latvian.mods.kubejs.block.entity;

import dev.latvian.mods.kubejs.typings.desc.ObjectDescJS;
import dev.latvian.mods.kubejs.util.KubeJSPlugins;
import dev.latvian.mods.kubejs.util.Lazy;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

public record BlockEntityAttachmentType(String type, ObjectDescJS input, Function<Map<String, Object>, BlockEntityAttachment.Factory> factory) {
public static final Lazy<Map<String, BlockEntityAttachmentType>> ALL = Lazy.of(() -> {
var map = new HashMap<String, BlockEntityAttachmentType>();
var list = new ArrayList<BlockEntityAttachmentType>();
KubeJSPlugins.forEachPlugin(p -> p.registerBlockEntityAttachments(list));

for (var type : list) {
map.put(type.type, type);
}

return map;
});

@Override
public String toString() {
return type;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package dev.latvian.mods.kubejs.block.entity;

import dev.latvian.mods.kubejs.registry.BuilderBase;
import dev.latvian.mods.kubejs.registry.RegistryInfo;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.entity.BlockEntityType;

public class BlockEntityBuilder extends BuilderBase<BlockEntityType<?>> {
public BlockEntityInfo info;

public BlockEntityBuilder(ResourceLocation i, BlockEntityInfo info) {
super(i);
this.info = info;
}

@Override
public RegistryInfo getRegistryType() {
return RegistryInfo.BLOCK_ENTITY_TYPE;
}

@Override
public BlockEntityType<?> createObject() {
info.entityType = BlockEntityType.Builder.of(info::createBlockEntity, info.blockBuilder.get()).build(null);
return info.entityType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dev.latvian.mods.kubejs.block.entity;

public interface BlockEntityCallback {
void accept(BlockEntityJS entity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dev.latvian.mods.kubejs.block.entity;

public interface BlockEntityEventCallback {
void accept(BlockEntityJS entity, int data);
}
Loading

0 comments on commit a161188

Please sign in to comment.