add basic displays

This commit is contained in:
Sen 2025-07-06 14:55:47 +02:00
parent e18a151f6c
commit 2fbdfde2ee
Signed by: sen
GPG key ID: 3AC50A6F47D1B722

View file

@ -1,10 +1,22 @@
package common.block.tech;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import common.block.Block;
import common.block.BlockContainer;
import common.block.Material;
import common.block.Rotatable;
import common.block.liquid.BlockLiquid;
import common.block.liquid.BlockStaticLiquid;
import common.collect.Sets;
import common.entity.npc.EntityNPC;
import common.entity.types.EntityLiving;
import common.init.Blocks;
import common.item.CheatTab;
import common.model.Model;
import common.model.ModelProvider;
@ -15,6 +27,9 @@ import common.tileentity.TileEntityDisplay;
import common.util.BlockPos;
import common.util.BoundingBox;
import common.util.Facing;
import common.util.Pair;
import common.util.Vec3i;
import common.world.AWorldServer;
import common.world.IWorldAccess;
import common.world.State;
import common.world.World;
@ -24,9 +39,8 @@ public class BlockDisplay extends BlockContainer implements Rotatable
public BlockDisplay()
{
super(Material.SOLID);
float f = 0.25F;
float f1 = 1.0F;
this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f);
this.setLightLevel(1.0f);
this.setBlockBounds(0.0F, 0.0F, 1.0F - 0.0625F, 1.0F, 1.0F, 1.0F);
this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH));
this.setTab(CheatTab.TECHNOLOGY);
}
@ -112,7 +126,7 @@ public class BlockDisplay extends BlockContainer implements Rotatable
}
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, EntityLiving placer) {
return this.getState().withProperty(FACING, facing.getAxis().isVertical() ? placer.getHorizontalFacing() : facing);
return this.getState().withProperty(FACING, facing.getAxis().isVertical() ? placer.getHorizontalFacing().getOpposite() : facing);
}
public int getRenderType() {
@ -133,19 +147,87 @@ public class BlockDisplay extends BlockContainer implements Rotatable
return provider.getModel("iron_block").add(0, 0, 15, 16, 16, 16).n().noCull().s().du().we().rotate(ModelRotation.getNorthRot(state.getValue(FACING)));
}
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ)
{
if (!worldIn.client)
{
TileEntity tileentity = worldIn.getTileEntity(pos);
private boolean test(World world, BlockPos pos, BlockPos origin, Facing dir) {
int radius = 9;
if(pos.getX() < origin.getX() - radius || pos.getX() > origin.getX() + radius)
return false;
if(pos.getY() < origin.getY() - radius || pos.getY() > origin.getY() + radius)
return false;
if(pos.getZ() < origin.getZ() - radius || pos.getZ() > origin.getZ() + radius)
return false;
State state = world.getState(pos);
return state.getBlock() == this && state.getValue(FACING) == dir;
}
if (tileentity instanceof TileEntityDisplay display)
{
display.setPixel(1, 12, 0xff0000);
display.setPixel(2, 12, 0x00ff00);
display.setPixel(3, 12, 0x0000ff);
private Pair<BlockPos, BlockPos> getSpan(World world, BlockPos origin) {
State state = world.getState(origin);
if(state.getBlock() != this)
return null;
Facing dir = state.getValue(FACING);
Queue<BlockPos> queue = new ArrayDeque<BlockPos>();
Set<BlockPos> present = new HashSet<BlockPos>();
Set<BlockPos> visited = new HashSet<BlockPos>();
Facing[] dirs = new Facing[] {Facing.UP, Facing.DOWN, dir.rotateY(), dir.rotateYCCW()};
present.add(origin);
visited.add(origin);
for(Facing off : dirs) {
BlockPos pos = origin.offset(off);
if(!visited.contains(pos)) {
if(test(world, pos, origin, dir))
queue.add(pos);
visited.add(pos);
}
}
BlockPos loc;
int minX = origin.getX();
int minY = origin.getY();
int minZ = origin.getZ();
int maxX = origin.getX();
int maxY = origin.getY();
int maxZ = origin.getZ();
while((loc = queue.poll()) != null) {
present.add(loc);
minX = Math.min(minX, loc.getX());
minY = Math.min(minY, loc.getY());
minZ = Math.min(minZ, loc.getZ());
maxX = Math.max(maxX, loc.getX());
maxY = Math.max(maxY, loc.getY());
maxZ = Math.max(maxZ, loc.getZ());
for(Facing off : dirs) {
BlockPos pos = loc.offset(off);
if(!visited.contains(pos)) {
visited.add(pos);
if(test(world, pos, origin, dir))
queue.add(pos);
}
}
}
if(maxX - minX >= 8 || maxY - minY >= 8 || maxZ - minZ >= 8)
return null;
BlockPos min = new BlockPos(minX, minY, minZ);
BlockPos max = new BlockPos(maxX, maxY, maxZ);
for(BlockPos pos : BlockPos.getAllInBox(min, max)) {
if(!present.contains(pos))
return null;
}
return new Pair(min, max);
}
public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) {
if(!worldIn.client) {
Pair<BlockPos, BlockPos> span = this.getSpan(worldIn, pos);
if(span == null)
return true;
for(BlockPos loc : BlockPos.getAllInBox(span.first(), span.second())) {
TileEntity tileentity = worldIn.getTileEntity(loc);
if(tileentity instanceof TileEntityDisplay display) {
for(int z = 0; z < 16; z++) {
display.setPixel(worldIn.rand.zrange(16), worldIn.rand.zrange(16), worldIn.rand.zrange(0x8000000));
}
display.markDirty();
worldIn.markBlockForUpdate(pos);
worldIn.markBlockForUpdate(loc);
}
}
}
return true;