webdisplays/src/main/java/net/montoyo/wd/utilities/Multiblock.java
GiantLuigi4 a9d9dcfecf format.
2023-11-10 23:50:06 -05:00

179 lines
5.0 KiB
Java

/*
* Copyright (C) 2018 BARBOTIN Nicolas
*/
package net.montoyo.wd.utilities;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelAccessor;
import net.montoyo.wd.registry.BlockRegistry;
public abstract class Multiblock {
public enum OverrideAction {
NONE,
SIMULATE,
IGNORE
}
public static class BlockOverride {
final Vector3i pos;
final OverrideAction action;
public BlockOverride(Vector3i p, OverrideAction act) {
pos = p;
action = act;
}
public boolean apply(Vector3i bp, boolean originalResult) {
if(action == OverrideAction.NONE || !bp.equals(pos))
return originalResult;
else if(action == OverrideAction.SIMULATE)
return true;
else //action == OverrideAction.IGNORE
return false;
}
}
public static final BlockOverride NULL_OVERRIDE = new BlockOverride(null, OverrideAction.NONE);
//Modifies pos
public static void findOrigin(LevelAccessor world, Vector3i pos, BlockSide side, BlockOverride override)
{
if(override == null)
override = NULL_OVERRIDE;
BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
//Go left
do {
pos.add(side.left);
pos.toBlock(bp);
} while(override.apply(pos, world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get()));
pos.add(side.right);
//Go down
do {
pos.add(side.down);
pos.toBlock(bp);
} while(override.apply(pos, world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get()));
pos.add(side.up);
}
//Origin stays constant
public static Vector2i measure(LevelAccessor world, Vector3i origin, BlockSide side)
{
Vector2i ret = new Vector2i();
Vector3i pos = origin.clone();
BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
pos.toBlock(bp);
//Go up
do {
pos.add(side.up);
pos.toBlock(bp);
ret.y++;
} while(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get());
pos.add(side.down);
//Go right
do {
pos.add(side.right);
pos.toBlock(bp);
ret.x++;
} while(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get());
return ret;
}
//Origin and size stays constant.
//Returns null if structure is okay, otherwise the erroring block pos.
public static Vector3i check(LevelAccessor world, Vector3i origin, Vector2i size, BlockSide side)
{
Vector3i pos = origin.clone();
BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
//Check inner
for(int y = 0; y < size.y; y++) {
for(int x = 0; x < size.x; x++) {
pos.toBlock(bp);
if(!(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get()))
return pos; //Hole
pos.add(side.forward);
pos.toBlock(bp);
if(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get())
return pos; //Back should be empty
pos.addMul(side.backward, 2);
pos.toBlock(bp);
if(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get())
return pos; //Front should be empty
pos.add(side.forward);
pos.add(side.right);
}
pos.addMul(side.left, size.x);
pos.add(side.up);
}
//Check left edge
pos.set(origin);
pos.add(side.left);
for(int y = 0; y < size.y; y++) {
pos.toBlock(bp);
if(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get())
return pos; //Left edge should be empty
pos.add(side.up);
}
//Check right edge
pos.set(origin);
pos.addMul(side.right, size.x);
for(int y = 0; y < size.y; y++) {
pos.toBlock(bp);
if(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get())
return pos; //Left edge should be empty
pos.add(side.up);
}
//Check bottom edge
pos.set(origin);
pos.add(side.down);
for(int x = 0; x < size.x; x++) {
pos.toBlock(bp);
if(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get())
return pos; //Left edge should be empty
pos.add(side.right);
}
//Check top edge
pos.set(origin);
pos.addMul(side.up, size.y);
for(int x = 0; x < size.x; x++) {
pos.toBlock(bp);
if(world.getBlockState(bp).getBlock() == BlockRegistry.SCREEN_BLOCk.get())
return pos; //Left edge should be empty
pos.add(side.right);
}
//All good.
return null;
}
}