From 88a90aada79ad72cf52b23b70cb194c1faa8b4a3 Mon Sep 17 00:00:00 2001 From: George Paton Date: Thu, 8 Feb 2024 18:01:59 +1100 Subject: [PATCH] Add new Spotlight block type, spawns SpotlightBeam blocks away from the wall that it is placed on --- src/main/java/com/hbm/blocks/ModBlocks.java | 8 ++ .../com/hbm/blocks/machine/Spotlight.java | 126 ++++++++++++++++ .../com/hbm/blocks/machine/SpotlightBeam.java | 134 ++++++++++++++++++ .../com/hbm/tileentity/TileEntityData.java | 26 ++++ .../java/com/hbm/tileentity/TileMappings.java | 6 +- 5 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/hbm/blocks/machine/Spotlight.java create mode 100644 src/main/java/com/hbm/blocks/machine/SpotlightBeam.java create mode 100644 src/main/java/com/hbm/tileentity/TileEntityData.java diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index 403ff7508..b2d396730 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -335,6 +335,9 @@ public class ModBlocks { public static Block lantern; public static Block lantern_behemoth; + public static Block spotlight; + public static Block spotlight_beam; + public static Block reinforced_stone; public static Block concrete_smooth; public static Block concrete_colored; @@ -1559,6 +1562,9 @@ public class ModBlocks { lamp_demon = new DemonLamp().setBlockName("lamp_demon").setStepSound(Block.soundTypeMetal).setCreativeTab(MainRegistry.blockTab).setLightLevel(1F).setHardness(3.0F).setBlockTextureName(RefStrings.MODID + ":lamp_demon"); lantern = new BlockLantern().setBlockName("lantern").setStepSound(Block.soundTypeMetal).setCreativeTab(MainRegistry.blockTab).setLightLevel(1F).setHardness(3.0F).setBlockTextureName(RefStrings.MODID + ":block_steel"); lantern_behemoth = new BlockLanternBehemoth().setBlockName("lantern_behemoth").setStepSound(Block.soundTypeMetal).setCreativeTab(null).setHardness(3.0F).setBlockTextureName(RefStrings.MODID + ":block_rust"); + + spotlight = new Spotlight(Material.iron, 8).setBlockName("spotlight").setCreativeTab(MainRegistry.blockTab).setBlockTextureName(RefStrings.MODID + ":reinforced_light"); + spotlight_beam = new SpotlightBeam().setBlockName("spotlight_beam"); reinforced_stone = new BlockGeneric(Material.rock).setBlockName("reinforced_stone").setCreativeTab(MainRegistry.blockTab).setHardness(15.0F).setResistance(100.0F).setBlockTextureName(RefStrings.MODID + ":reinforced_stone"); concrete_smooth = new BlockRadResistant(Material.rock).setBlockName("concrete_smooth").setCreativeTab(MainRegistry.blockTab).setHardness(15.0F).setResistance(140.0F).setBlockTextureName(RefStrings.MODID + ":concrete"); @@ -2738,6 +2744,8 @@ public class ModBlocks { GameRegistry.registerBlock(lamp_demon, lamp_demon.getUnlocalizedName()); GameRegistry.registerBlock(lantern, lantern.getUnlocalizedName()); GameRegistry.registerBlock(lantern_behemoth, lantern_behemoth.getUnlocalizedName()); + GameRegistry.registerBlock(spotlight, spotlight.getUnlocalizedName()); + GameRegistry.registerBlock(spotlight_beam, spotlight_beam.getUnlocalizedName()); //Reinforced Blocks GameRegistry.registerBlock(asphalt, ItemBlockBlastInfo.class, asphalt.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/blocks/machine/Spotlight.java b/src/main/java/com/hbm/blocks/machine/Spotlight.java new file mode 100644 index 000000000..03e6b4244 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/Spotlight.java @@ -0,0 +1,126 @@ +package com.hbm.blocks.machine; + +import com.hbm.blocks.ModBlocks; +import com.hbm.main.MainRegistry; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class Spotlight extends Block { + + public int beamLength; + + public Spotlight(Material mat, int beamLength) { + super(mat); + setLightLevel(1.0F); + + this.beamLength = beamLength; + } + + @Override + public int onBlockPlaced(World world, int x, int y, int z, int side, float hx, float hy, float hz, int initData) { + return side << 1; + } + + @Override + public void onBlockAdded(World world, int x, int y, int z) { + updateBeam(world, x, y, z); + } + + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int metadata) { + ForgeDirection dir = getDirection(metadata); + super.breakBlock(world, x, y, z, block, metadata); + + if (world.isRemote) return; + + unpropagateBeam(world, x, y, z, dir); + } + + // Repropagate the beam if we've become unblocked + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block neighborBlock) { + if (world.isRemote) return; + if (neighborBlock instanceof SpotlightBeam) return; + updateBeam(world, x, y, z); + } + + public void updateBeam(World world, int x, int y, int z) { + if (world.isRemote) return; + + ForgeDirection dir = getDirection(world, x, y, z); + propagateBeam(world, x, y, z, dir, beamLength); + } + + private ForgeDirection getDirection(World world, int x, int y, int z) { + int metadata = world.getBlockMetadata(x, y, z); + return getDirection(metadata); + } + + private ForgeDirection getDirection(int metadata) { + return ForgeDirection.getOrientation(metadata >> 1); + } + + // Recursively add beam blocks, updating any that already exist with new incoming light directions + public static void propagateBeam(World world, int x, int y, int z, ForgeDirection dir, int distance) { + distance--; + if (distance <= 0) return; + + x += dir.offsetX; + y += dir.offsetY; + z += dir.offsetZ; + + Block block = world.getBlock(x, y, z); + if (!block.isAir(world, x, y, z)) return; + + // If we encounter a beam, add a new INCOMING direction to the metadata + // Otherwise, spawn a new beam + if (!(block instanceof SpotlightBeam)) { + world.setBlock(x, y, z, ModBlocks.spotlight_beam); + } + + int meta = SpotlightBeam.setDirection(world, x, y, z, dir, true); + + MainRegistry.logger.info("block meta set to: " + meta + " - should be at least: " + dir.flag); + + propagateBeam(world, x, y, z, dir, distance); + } + + // Recursively delete beam blocks, if they aren't still illuminated from a different direction + public static void unpropagateBeam(World world, int x, int y, int z, ForgeDirection dir) { + x += dir.offsetX; + y += dir.offsetY; + z += dir.offsetZ; + + Block block = world.getBlock(x, y, z); + if (!(block instanceof SpotlightBeam)) return; + + // Remove the metadata associated with this direction + // If all directions are set to zero, delete the beam + if (SpotlightBeam.setDirection(world, x, y, z, dir, false) == 0) { + world.setBlockToAir(x, y, z); + } + + unpropagateBeam(world, x, y, z, dir); + } + + // Travels back through a beam to the source, and if found, repropagates the beam + public static void backPropagate(World world, int x, int y, int z, ForgeDirection dir) { + x -= dir.offsetX; + y -= dir.offsetY; + z -= dir.offsetZ; + + Block block = world.getBlock(x, y, z); + if (block instanceof Spotlight) { + Spotlight spot = (Spotlight) block; + propagateBeam(world, x, y, z, dir, spot.beamLength); + } else if (!(block instanceof SpotlightBeam)) { + return; + } + + backPropagate(world, x, y, z, dir); + } + +} diff --git a/src/main/java/com/hbm/blocks/machine/SpotlightBeam.java b/src/main/java/com/hbm/blocks/machine/SpotlightBeam.java new file mode 100644 index 000000000..a1a9d1569 --- /dev/null +++ b/src/main/java/com/hbm/blocks/machine/SpotlightBeam.java @@ -0,0 +1,134 @@ +package com.hbm.blocks.machine; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import com.hbm.tileentity.TileEntityData; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.material.Material; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; + +public class SpotlightBeam extends BlockContainer { + + public SpotlightBeam() { + super(Material.air); + setLightLevel(1.0F); + setLightOpacity(0); + setHardness(-1); + setResistance(1_000_000); + setBlockBounds(0, 0, 0, 0, 0, 0); + } + + // If a block is placed onto the beam, handle the new cutoff + @Override + public void breakBlock(World world, int x, int y, int z, Block block, int metadata) { + super.breakBlock(world, x, y, z, block, metadata); + if (world.isRemote) return; + + for (ForgeDirection dir : getDirections(metadata)) { + Spotlight.unpropagateBeam(world, x, y, z, dir); + } + } + + // If a block in the beam path is removed, repropagate beam + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block neighborBlock) { + if (world.isRemote) return; + if (neighborBlock instanceof SpotlightBeam) return; + + for (ForgeDirection dir : getDirections(world, x, y, z)) { + Spotlight.backPropagate(world, x, y, z, dir); + } + } + + // Directions are stored as a set of 6 bits: + // 000000 -> no incoming light directions are set, will be removed + // 010000 -> UP bit set, at least one direction is providing light + // 111111 -> ALL directions illuminated, all incoming lights need to be disabled to turn off the beam + public static List getDirections(World world, int x, int y, int z) { + TileEntityData te = (TileEntityData) world.getTileEntity(x, y, z); + return getDirections(te.metadata); + } + + public static List getDirections(int metadata) { + List directions = new ArrayList(6); + for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) { + if ((metadata & dir.flag) == dir.flag) directions.add(dir); + } + return directions; + } + + // Returns the final metadata, so the caller can optionally remove the block + public static int setDirection(World world, int x, int y, int z, ForgeDirection dir, boolean state) { + TileEntityData te = (TileEntityData) world.getTileEntity(x, y, z); + int transformedMetadata = applyDirection(te.metadata, dir, state); + te.metadata = transformedMetadata; + return transformedMetadata; + } + + // Sets the metadata bit for a given direction + public static int applyDirection(int metadata, ForgeDirection direction, boolean state) { + if (state) { + return metadata | direction.flag; + } else { + return metadata & ~direction.flag; + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityData(); + } + + @Override + public boolean isOpaqueCube() { + return false; + } + + @Override + public boolean isAir(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public boolean canBeReplacedByLeaves(IBlockAccess world, int x, int y, int z) { + return true; + } + + @Override + public boolean isLeaves(IBlockAccess world, int x, int y, int z) { + // This was taken from GregsLighting (cargo cult behaviour) + // This is a bit screwy, but it's needed so that trees are not prevented from growing + // near a floodlight beam. + return true; + } + + + @Override + public boolean renderAsNormalBlock() { + return false; + } + + @Override + public int quantityDropped(Random par1Random) { + return 0; + } + + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) { + return null; + } + + @Override + public int getRenderType() { + return -1; + } + +} diff --git a/src/main/java/com/hbm/tileentity/TileEntityData.java b/src/main/java/com/hbm/tileentity/TileEntityData.java new file mode 100644 index 000000000..1356d66c3 --- /dev/null +++ b/src/main/java/com/hbm/tileentity/TileEntityData.java @@ -0,0 +1,26 @@ +package com.hbm.tileentity; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +// A whole ass TE just for 2 extra bits +// My kingdom for 2 fucking flags + +// Use this TE if you need more bits, that's it. Blame Mojang +public class TileEntityData extends TileEntity { + + public int metadata; + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + metadata = nbt.getInteger("meta"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setInteger("meta", metadata); + } + +} diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index 3686a7b31..b21b0c50f 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -45,8 +45,8 @@ import net.minecraft.tileentity.TileEntity; public class TileMappings { - public static HashMap, String[]> map = new HashMap(); - public static List> configurables = new ArrayList(); + public static HashMap, String[]> map = new HashMap, String[]>(); + public static List> configurables = new ArrayList>(); public static void writeMappings() { put(TileEntityTestBombAdvanced.class, "tilentity_testbombadvanced"); @@ -223,6 +223,8 @@ public class TileMappings { put(TileEntityBlockPWR.class, "tileentity_block_pwr"); put(TileEntityPWRController.class, "tileentity_pwr_controller"); + + put(TileEntityData.class, "tileentity_data"); putNetwork(); putBombs();