Skip to content

Commit

Permalink
Implement proper multiblock assembling / breaking
Browse files Browse the repository at this point in the history
  • Loading branch information
Rearth committed Jan 29, 2024
1 parent 15dffed commit b89e986
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 30 deletions.
15 changes: 6 additions & 9 deletions src/main/java/rearth/oritech/block/base/MachineBlockEntity.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package rearth.oritech.block.base;

import io.wispforest.owo.particles.ClientParticles;
import io.wispforest.owo.particles.systems.ParticleSystem;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
Expand All @@ -15,7 +13,6 @@
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.screen.ScreenHandler;
Expand All @@ -25,12 +22,8 @@
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import rearth.oritech.block.custom.MachineCoreBlock;
import rearth.oritech.client.init.ParticleContent;
import rearth.oritech.client.ui.BasicMachineScreenHandler;
import rearth.oritech.init.recipes.OritechRecipe;
import rearth.oritech.network.NetworkContent;
Expand Down Expand Up @@ -68,7 +61,7 @@ public MachineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState stat
@Override
public void tick(World world, BlockPos pos, BlockState state, BlockEntity blockEntity) {

if (world.isClient) return;
if (world.isClient || !isActive(state)) return;

var recipeCandidate = getRecipe();
if (recipeCandidate.isEmpty()) currentRecipe = OritechRecipe.DUMMY; // reset recipe when invalid or no input is given
Expand Down Expand Up @@ -260,6 +253,7 @@ public boolean canExtract(int slot, ItemStack stack, Direction side) {

@Override
public boolean canInsert(int slot, ItemStack stack, @Nullable Direction side) {

var mode = inventoryInputMode;
var config = getSlots();

Expand Down Expand Up @@ -391,7 +385,6 @@ private int findLowestMatchingSlot(ItemStack stack, List<ItemStack> inv, boolean

@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {

}

@Override
Expand Down Expand Up @@ -476,4 +469,8 @@ public InventoryInputMode getInventoryInputMode() {

public abstract int getInventorySize();

public boolean isActive(BlockState state) {
return true;
}

}
20 changes: 18 additions & 2 deletions src/main/java/rearth/oritech/block/base/MultiblockMachine.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rearth.oritech.block.base;

import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.StateManager;
Expand All @@ -14,6 +15,7 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;

public abstract class MultiblockMachine extends MachineBlock {

Expand All @@ -37,18 +39,32 @@ public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEnt

var entity = world.getBlockEntity(pos);
if (!(entity instanceof MultiblockMachineEntity machineEntity)) {
return ActionResult.FAIL;
return ActionResult.SUCCESS;
}

var isAssembled = machineEntity.initMultiblock(state);

if (!isAssembled) {
player.sendMessage(Text.literal("Machine is not assembled"));
return ActionResult.FAIL;
return ActionResult.SUCCESS;
}

}

return super.onUse(state, world, pos, player, hand, hit);
}

@Override
public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {

if (!world.isClient() && state.get(ASSEMBLED)) {

var entity = world.getBlockEntity(pos);
if (entity instanceof MultiblockMachineEntity machineEntity) {
machineEntity.onControllerBroken(state);
}
}

return super.onBreak(world, pos, state, player);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
Expand All @@ -15,10 +18,42 @@

public abstract class MultiblockMachineEntity extends MachineBlockEntity {

private final ArrayList<BlockPos> coreBlocksConnected = new ArrayList<>();

public MultiblockMachineEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}

@Override
public void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);

var posList = new NbtList();
for (var pos : coreBlocksConnected) {
var posTag = new NbtCompound();
posTag.putInt("x", pos.getX());
posTag.putInt("y", pos.getY());
posTag.putInt("z", pos.getZ());
posList.add(posTag);
}
nbt.put("connectedCores", posList);
}

@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);

var posList = nbt.getList("connectedCores", NbtElement.COMPOUND_TYPE);

for (var posTag : posList) {
var posCompound = (NbtCompound) posTag;
var x = posCompound.getInt("x");
var y = posCompound.getInt("y");
var z = posCompound.getInt("z");
var pos = new BlockPos(x, y, z);
coreBlocksConnected.add(pos);
}
}

// positive x = forward
// positive y = up
Expand Down Expand Up @@ -48,7 +83,7 @@ public boolean initMultiblock(BlockState state) {
var checkState = Objects.requireNonNull(world).getBlockState(checkPos);

var blockType = checkState.getBlock();
if (blockType instanceof MachineCoreBlock coreBlock) {
if (blockType instanceof MachineCoreBlock coreBlock && !checkState.get(MachineCoreBlock.USED)) {
coreBlocks.add(new MultiBlockElement(checkState, coreBlock, checkPos));
} else {
highlightBlock(checkPos);
Expand All @@ -65,6 +100,7 @@ public boolean initMultiblock(BlockState state) {
.with(MachineCoreBlock.CONTROLLER_Y, offset.getY() + 4)
.with(MachineCoreBlock.CONTROLLER_Z, offset.getZ() + 4);
world.setBlockState(core.pos, newState);
coreBlocksConnected.add(core.pos);
}

Objects.requireNonNull(world).setBlockState(pos, state.with(MultiblockMachine.ASSEMBLED, true));
Expand All @@ -80,12 +116,30 @@ public boolean initMultiblock(BlockState state) {

public void onCoreBroken(BlockPos corePos, BlockState coreState) {

System.out.println("registering broken core!");
Objects.requireNonNull(world).setBlockState(pos, world.getBlockState(pos).with(MultiblockMachine.ASSEMBLED, false));

for (var core : coreBlocksConnected) {
if (core.equals(corePos)) continue;

var state = world.getBlockState(core);
if (state.getBlock() instanceof MachineCoreBlock) {
world.setBlockState(core, state.with(MachineCoreBlock.USED, false));
}
}

coreBlocksConnected.clear();
}

public void onControllerBroken(BlockState controllerState) {

// set assembled to false
// go through all existing cores
// set used to false
for (var core : coreBlocksConnected) {
var state = Objects.requireNonNull(world).getBlockState(core);
if (state.getBlock() instanceof MachineCoreBlock) {
world.setBlockState(core, state.with(MachineCoreBlock.USED, false));
}
}

coreBlocksConnected.clear();
}

private void highlightBlock(BlockPos block) {
Expand All @@ -102,6 +156,11 @@ private Vec3i rotatePosition(Vec3i relativePos, Direction facing) {
};
}

@Override
public boolean isActive(BlockState state) {
return state.get(MultiblockMachine.ASSEMBLED);
}

private record MultiBlockElement(BlockState state, MachineCoreBlock coreBlock, BlockPos pos) {
}
}
15 changes: 3 additions & 12 deletions src/main/java/rearth/oritech/block/custom/MachineCoreBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,15 @@ public BlockRenderType getRenderType(BlockState state) {
return state.get(USED) ? BlockRenderType.INVISIBLE : BlockRenderType.MODEL;
}

@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {

if (!world.isClient) {
world.setBlockState(pos, state.with(USED, !state.get(USED)));
}

return ActionResult.SUCCESS;
}

@Override
public BlockState onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {

if (state.get(USED)) {
if (!world.isClient() && state.get(USED)) {
var offset = new Vec3i(state.get(CONTROLLER_X) - 4, state.get(CONTROLLER_Y) - 4, state.get(CONTROLLER_Z) - 4);

var controllerPos = pos.add(offset);
System.out.println("notifying machine controller that core has been removed");
var controllerEntity = world.getBlockEntity(controllerPos);

if (controllerEntity instanceof MultiblockMachineEntity machineEntity) {
machineEntity.onCoreBroken(pos, state);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ public int getInventorySize() {
public List<Vec3i> getCorePositions() {
return List.of(
new Vec3i(1, 0,0),
new Vec3i(2, 0,0),
new Vec3i(0, 1, 0)
new Vec3i(2, 0,0)
);
}
}

0 comments on commit b89e986

Please sign in to comment.