From c6ea13d8178c8a30007a22ebe01b9af20a68ef79 Mon Sep 17 00:00:00 2001 From: Pierce Corcoran Date: Mon, 11 Jan 2016 16:48:26 -0800 Subject: [PATCH 1/5] Make drawcoloredrect use the WorldRenderer --- .../practicalities/book/gui/GuideEntry.java | 2 +- .../practicalities/helpers/GuiHelper.java | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/practicalities/book/gui/GuideEntry.java b/src/main/java/practicalities/book/gui/GuideEntry.java index 1a8c79b..0dcae5b 100644 --- a/src/main/java/practicalities/book/gui/GuideEntry.java +++ b/src/main/java/practicalities/book/gui/GuideEntry.java @@ -84,7 +84,7 @@ public void drawForeground(int paramInt1, int paramInt2) { double p = h.tickAnimate(animateStart, 5); h.loadInterpolationFraction(Math.min(p, 1)); - h.drawColoredRect(posX+h.intr(mouseEnterX, 0), posY, posX+ h.intr(mouseEnterX, sizeX), posY+sizeY, 0,0,0, h.intr(0, 0.1)); + h.drawColoredRect(posX+h.intr(mouseEnterX, 0), posY, posX+ h.intr(mouseEnterX, sizeX), posY+sizeY, 0,0,0, (float)h.intr(0, 0.1)); } } diff --git a/src/main/java/practicalities/helpers/GuiHelper.java b/src/main/java/practicalities/helpers/GuiHelper.java index a896388..26e27ee 100644 --- a/src/main/java/practicalities/helpers/GuiHelper.java +++ b/src/main/java/practicalities/helpers/GuiHelper.java @@ -214,21 +214,22 @@ public void drawHoveringText(List lines, int x, int y, FontRenderer font public void drawColoredRect(int x1, int y1, int x2, int y2, int color) { Color c = Color.rgba(color); - drawColoredRect(x1, y1, x2, y2, c.r, c.g, c.b, c.a); + drawColoredRect(x1, y1, x2, y2, (float)c.r, (float)c.g, (float)c.b, (float)c.a); } - public void drawColoredRect(int x1, int y1, int x2, int y2, double r, double g, double b, double a) { - GL11.glColor4d(r, g, b, a); + public void drawColoredRect(int left, int top, int right, int bottom, float r, float g, float b, float a) { GlStateManager.enableBlend(); GlStateManager.disableTexture2D(); - GL11.glBegin(GL11.GL_QUADS); - GL11.glVertex2d(x1, y1); - GL11.glVertex2d(x1, y2); - GL11.glVertex2d(x2, y2); - GL11.glVertex2d(x2, y1); - - GL11.glEnd(); + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer worldrenderer = tessellator.getWorldRenderer(); + worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR); + worldrenderer.pos(right, top, this.zLevel).color(r, g, b, a).endVertex(); + worldrenderer.pos(left, top, this.zLevel).color(r, g, b, a).endVertex(); + worldrenderer.pos(left, bottom, this.zLevel).color(r, g, b, a).endVertex(); + worldrenderer.pos(right, bottom, this.zLevel).color(r, g, b, a).endVertex(); + tessellator.draw(); + GlStateManager.enableTexture2D(); } From e8428563d6c2f3c029870c1d8b59b1e5d28406bc Mon Sep 17 00:00:00 2001 From: Pierce Corcoran Date: Thu, 14 Jan 2016 14:26:26 -0800 Subject: [PATCH 2/5] Beginning lasers --- .../blocks/BlockLaserEmmiter.java | 110 ++++++++++++++++++ .../practicalities/blocks/ILaserReciver.java | 12 ++ .../java/practicalities/blocks/TileLaser.java | 28 +++++ .../client/render/RenderLaser.java | 13 +++ .../registers/BlockRegister.java | 8 +- 5 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 src/main/java/practicalities/blocks/BlockLaserEmmiter.java create mode 100644 src/main/java/practicalities/blocks/ILaserReciver.java create mode 100644 src/main/java/practicalities/blocks/TileLaser.java create mode 100644 src/main/java/practicalities/client/render/RenderLaser.java diff --git a/src/main/java/practicalities/blocks/BlockLaserEmmiter.java b/src/main/java/practicalities/blocks/BlockLaserEmmiter.java new file mode 100644 index 0000000..9fdb3ae --- /dev/null +++ b/src/main/java/practicalities/blocks/BlockLaserEmmiter.java @@ -0,0 +1,110 @@ +package practicalities.blocks; + +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.state.BlockState; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import practicalities.PracticalitiesMod; + +public class BlockLaserEmmiter extends Block { + + public static final PropertyDirection FACING = PropertyDirection.create("facing"); + public static final PropertyBool POWERED = PropertyBool.create("powered"); + + public BlockLaserEmmiter() { + super(Material.glass); + setCreativeTab(PracticalitiesMod.tab); + GameRegistry.registerBlock(this, "laserEmmiter"); + } + + @Override + protected BlockState createBlockState() { + return new BlockState(this, FACING, POWERED); + } + + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(FACING, getFacing(meta).getOpposite()).withProperty(POWERED, Boolean.valueOf((meta & 8) > 0)); + } + + public static EnumFacing getFacing(int meta) { + int i = meta & 7; + return i > 5 ? null : EnumFacing.getFront(i); + } + + @SideOnly(Side.CLIENT) + public IBlockState getStateForEntityRender(IBlockState state) { + return this.getDefaultState().withProperty(FACING, EnumFacing.UP); + } + + + public int getMetaFromState(IBlockState state) { + int i = 0; + i = i | ((EnumFacing)state.getValue(FACING)).getIndex(); + + if (((Boolean)state.getValue(POWERED)).booleanValue()) + { + i |= 8; + } + + return i; + } + + @Override + public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) { + + if(worldIn.isRemote) + return; + + EnumFacing facing = state.getValue(FACING); + boolean wasPowered = state.getValue(POWERED); + boolean isPowered = worldIn.isBlockPowered(pos); + + if(wasPowered != isPowered) { + updateLaser(worldIn, pos, facing, isPowered); + IBlockState newState = state.withProperty(POWERED, isPowered); + worldIn.setBlockState(pos, newState); + } + + } + + public void updateLaser(World world, BlockPos pos, EnumFacing facing, boolean powered) { + + } + + // DIRECTIONAL PLACING + + public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { + worldIn.setBlockState(pos, state.withProperty(FACING, getFacingFromEntity(worldIn, pos, placer)), 2); + } + + public static EnumFacing getFacingFromEntity(World worldIn, BlockPos clickedBlock, EntityLivingBase entityIn) { + if (MathHelper.abs((float)entityIn.posX - (float)clickedBlock.getX()) < 2.0F && MathHelper.abs((float)entityIn.posZ - (float)clickedBlock.getZ()) < 2.0F) + { + double d0 = entityIn.posY + (double)entityIn.getEyeHeight(); + + if (d0 - (double)clickedBlock.getY() > 2.0D) + { + return EnumFacing.UP; + } + + if ((double)clickedBlock.getY() - d0 > 0.0D) + { + return EnumFacing.DOWN; + } + } + + return entityIn.getHorizontalFacing().getOpposite(); + } + +} diff --git a/src/main/java/practicalities/blocks/ILaserReciver.java b/src/main/java/practicalities/blocks/ILaserReciver.java new file mode 100644 index 0000000..a9e9ce0 --- /dev/null +++ b/src/main/java/practicalities/blocks/ILaserReciver.java @@ -0,0 +1,12 @@ +package practicalities.blocks; + +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import practicalities.entity.EntityLaser; + +public interface ILaserReciver { + + public void laserHit(World world, BlockPos pos, EnumFacing sideHit, EntityLaser laser); + +} diff --git a/src/main/java/practicalities/blocks/TileLaser.java b/src/main/java/practicalities/blocks/TileLaser.java new file mode 100644 index 0000000..7622aa2 --- /dev/null +++ b/src/main/java/practicalities/blocks/TileLaser.java @@ -0,0 +1,28 @@ +package practicalities.blocks; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ITickable; + +public class TileLaser extends TileEntity implements ITickable { + + List oldLasers = new ArrayList<>(); + Laser currentLaser = null; + public static class Laser { + public double start, end; + public EnumFacing direction; + } + + public void updatePower(boolean powered) { + + } + + @Override + public void update() { + // TODO Auto-generated method stub + + } +} diff --git a/src/main/java/practicalities/client/render/RenderLaser.java b/src/main/java/practicalities/client/render/RenderLaser.java new file mode 100644 index 0000000..627dac0 --- /dev/null +++ b/src/main/java/practicalities/client/render/RenderLaser.java @@ -0,0 +1,13 @@ +package practicalities.client.render; + +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.tileentity.TileEntity; + +public class RenderLaser extends TileEntitySpecialRenderer { + + @Override + public void renderTileEntityAt(TileEntity te, double x, double y, double z, float partialTicks, int destroyStage) { + + } + +} diff --git a/src/main/java/practicalities/registers/BlockRegister.java b/src/main/java/practicalities/registers/BlockRegister.java index 3dbfbab..9f6077a 100755 --- a/src/main/java/practicalities/registers/BlockRegister.java +++ b/src/main/java/practicalities/registers/BlockRegister.java @@ -2,26 +2,26 @@ import net.minecraft.block.Block; import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.model.ModelBakery; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import practicalities.Logger; import practicalities.PracticalitiesMod; +import practicalities.blocks.BlockLaserEmmiter; public final class BlockRegister { + public static Block laserEmitter; public static void init(){ + laserEmitter = new BlockLaserEmmiter(); } @SideOnly(Side.CLIENT) public static void registerRenders(){ - - Logger.info("Registering Blocks"); + Logger.info("Registering Block Renderers"); } @SideOnly(Side.CLIENT) From 6c51e09ea2a384f1aac339127b8a0b20f21ddee0 Mon Sep 17 00:00:00 2001 From: Pierce Corcoran Date: Fri, 15 Jan 2016 00:17:49 -0800 Subject: [PATCH 3/5] Half implemented laser and tracking system --- src/main/java/practicalities/Logger.java | 12 + .../practicalities/PracticalitiesMod.java | 4 +- src/main/java/practicalities/ProxyClient.java | 14 +- src/main/java/practicalities/ProxyCommon.java | 33 +- ...BlockLaserEmmiter.java => BlockLaser.java} | 112 ++-- .../practicalities/blocks/ILaserReciver.java | 3 +- .../java/practicalities/blocks/TileLaser.java | 89 +++- .../client/render/RenderLaser.java | 32 +- .../lib/util/WorldTraceUtil.java | 197 +++++++ .../lib/util/math/MathHelper.java | 181 +++++++ .../lib/util/track/Tracker.java | 9 + .../lib/util/track/TrackerClient.java | 59 +++ .../lib/util/track/TrackerRelease.java | 15 + .../lib/util/track/TrackerServer.java | 26 + .../lib/util/vec/ExtendedVector3.java | 31 ++ .../practicalities/lib/util/vec/Quat.java | 159 ++++++ .../practicalities/lib/util/vec/Vector3.java | 498 ++++++++++++++++++ .../network/MessageTracker.java | 46 ++ .../practicalities/network/NetHandler.java | 16 + .../registers/BlockRegister.java | 24 +- 20 files changed, 1498 insertions(+), 62 deletions(-) rename src/main/java/practicalities/blocks/{BlockLaserEmmiter.java => BlockLaser.java} (57%) create mode 100644 src/main/java/practicalities/lib/util/WorldTraceUtil.java create mode 100644 src/main/java/practicalities/lib/util/math/MathHelper.java create mode 100644 src/main/java/practicalities/lib/util/track/Tracker.java create mode 100644 src/main/java/practicalities/lib/util/track/TrackerClient.java create mode 100644 src/main/java/practicalities/lib/util/track/TrackerRelease.java create mode 100644 src/main/java/practicalities/lib/util/track/TrackerServer.java create mode 100644 src/main/java/practicalities/lib/util/vec/ExtendedVector3.java create mode 100644 src/main/java/practicalities/lib/util/vec/Quat.java create mode 100644 src/main/java/practicalities/lib/util/vec/Vector3.java create mode 100644 src/main/java/practicalities/network/MessageTracker.java create mode 100644 src/main/java/practicalities/network/NetHandler.java diff --git a/src/main/java/practicalities/Logger.java b/src/main/java/practicalities/Logger.java index e05dba7..39331d5 100755 --- a/src/main/java/practicalities/Logger.java +++ b/src/main/java/practicalities/Logger.java @@ -2,7 +2,9 @@ import org.apache.logging.log4j.Level; +import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.relauncher.Side; public class Logger { @@ -34,4 +36,14 @@ public static void debug(String format, Object... data) { public static void trace(String format, Object... data) { log(Level.TRACE, format, data); } + + public static void track(String name, String format, Object... data) { + if(!ConfigMan.isDev) + throw new UnsupportedOperationException("Practicalities: Tried to call Logger.track outside of a dev environment! This is just plain bad!"); + if(FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { + PracticalitiesMod.proxy.trackerServer.track(name, String.format(format, data)); + } else { + PracticalitiesMod.proxy.trackerClient.track(name, String.format(format, data)); + } + } } diff --git a/src/main/java/practicalities/PracticalitiesMod.java b/src/main/java/practicalities/PracticalitiesMod.java index 87c777d..823d2d1 100755 --- a/src/main/java/practicalities/PracticalitiesMod.java +++ b/src/main/java/practicalities/PracticalitiesMod.java @@ -13,6 +13,7 @@ import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import practicalities.network.NetHandler; import practicalities.registers.GuiHandler; import practicalities.registers.ItemRegister; @@ -34,8 +35,9 @@ public class PracticalitiesMod { @EventHandler public void preInit(FMLPreInitializationEvent event) { - proxy.preInit(); ConfigMan.init(new Configuration(event.getSuggestedConfigurationFile())); + proxy.preInit(); + NetHandler.init(); } @EventHandler diff --git a/src/main/java/practicalities/ProxyClient.java b/src/main/java/practicalities/ProxyClient.java index 7b06127..b448429 100755 --- a/src/main/java/practicalities/ProxyClient.java +++ b/src/main/java/practicalities/ProxyClient.java @@ -9,9 +9,12 @@ import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StringTranslate; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; import practicalities.lib.util.AdvancedLangLoader; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; +import practicalities.lib.util.track.Tracker; +import practicalities.lib.util.track.TrackerClient; import practicalities.registers.BlockRegister; import practicalities.registers.GuideRegister; import practicalities.registers.ItemRegister; @@ -22,6 +25,13 @@ public class ProxyClient extends ProxyCommon implements IResourceManagerReloadLi public void preInit() { super.preInit(); registerRenders(); + + } + + @Override + public void registerTickHandlers() { + super.registerTickHandlers(); + MinecraftForge.EVENT_BUS.register(trackerClient); } @Override diff --git a/src/main/java/practicalities/ProxyCommon.java b/src/main/java/practicalities/ProxyCommon.java index 7ea087b..9956e45 100755 --- a/src/main/java/practicalities/ProxyCommon.java +++ b/src/main/java/practicalities/ProxyCommon.java @@ -7,19 +7,28 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.LivingDropsEvent; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import practicalities.items.netherbane.EntityNetherbane; +import practicalities.lib.util.track.Tracker; +import practicalities.lib.util.track.TrackerClient; +import practicalities.lib.util.track.TrackerRelease; +import practicalities.lib.util.track.TrackerServer; import practicalities.registers.BlockRegister; import practicalities.registers.ItemRegister; import practicalities.registers.RecipeRegister; public class ProxyCommon { - + public void preInit() { ItemRegister.init(); BlockRegister.init(); - + if(!ConfigMan.isDev) { + trackerClient = trackerServer = new TrackerRelease(); + } } public void init() { @@ -81,5 +90,21 @@ public void onItemToss(ItemTossEvent event) { } } } - + + public Tracker trackerClient = new TrackerClient(); + public Tracker trackerServer = new TrackerServer(); + + int timer = 20; + + @SubscribeEvent + public void onTick(TickEvent.WorldTickEvent evt) { + if(evt.phase == Phase.END) { + if(timer == 0) { + timer = 100; + trackerClient.clear(); + trackerServer.clear(); + } + timer--; + } + } } diff --git a/src/main/java/practicalities/blocks/BlockLaserEmmiter.java b/src/main/java/practicalities/blocks/BlockLaser.java similarity index 57% rename from src/main/java/practicalities/blocks/BlockLaserEmmiter.java rename to src/main/java/practicalities/blocks/BlockLaser.java index 9fdb3ae..c1a4fc2 100644 --- a/src/main/java/practicalities/blocks/BlockLaserEmmiter.java +++ b/src/main/java/practicalities/blocks/BlockLaser.java @@ -1,6 +1,7 @@ package practicalities.blocks; import net.minecraft.block.Block; +import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.material.Material; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyDirection; @@ -8,78 +9,85 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import practicalities.PracticalitiesMod; +import practicalities.Logger; +import practicalities.machines.shippingcrate.TileShippingCrate; -public class BlockLaserEmmiter extends Block { +public class BlockLaser extends BlockBase implements ITileEntityProvider, ILaserReciver { public static final PropertyDirection FACING = PropertyDirection.create("facing"); - public static final PropertyBool POWERED = PropertyBool.create("powered"); +// public static final PropertyBool POWERED = PropertyBool.create("powered"); - public BlockLaserEmmiter() { - super(Material.glass); - setCreativeTab(PracticalitiesMod.tab); - GameRegistry.registerBlock(this, "laserEmmiter"); + public BlockLaser() { + super(Material.glass, "laser"); } @Override protected BlockState createBlockState() { - return new BlockState(this, FACING, POWERED); + return new BlockState(this, FACING); } - public IBlockState getStateFromMeta(int meta) { - return this.getDefaultState().withProperty(FACING, getFacing(meta).getOpposite()).withProperty(POWERED, Boolean.valueOf((meta & 8) > 0)); - } - - public static EnumFacing getFacing(int meta) { - int i = meta & 7; - return i > 5 ? null : EnumFacing.getFront(i); - } - @SideOnly(Side.CLIENT) public IBlockState getStateForEntityRender(IBlockState state) { return this.getDefaultState().withProperty(FACING, EnumFacing.UP); } - - - public int getMetaFromState(IBlockState state) { - int i = 0; - i = i | ((EnumFacing)state.getValue(FACING)).getIndex(); - - if (((Boolean)state.getValue(POWERED)).booleanValue()) - { - i |= 8; - } - - return i; - } + @Override + public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { + TileLaser tile = (TileLaser) worldIn.getTileEntity(pos); + tile.onBreak(); + } + @Override public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) { +// if(worldIn.isRemote) +// return; - if(worldIn.isRemote) - return; + updateLaser(worldIn, pos); + } + + @Override + public void laserHit(World world, BlockPos pos, EnumFacing sideHit, BlockPos laserPos, boolean powered) { +// if(world.isRemote) +// return; - EnumFacing facing = state.getValue(FACING); - boolean wasPowered = state.getValue(POWERED); - boolean isPowered = worldIn.isBlockPowered(pos); + TileLaser tile = (TileLaser) world.getTileEntity(pos); + tile.laserHit(powered); + + updateLaser(world, pos); + } + + public void updateLaser(World world, BlockPos pos) { +// IBlockState state = world.getBlockState(pos); + + TileLaser tile = (TileLaser) world.getTileEntity(pos); + + boolean wasPowered = tile.powered; + boolean isPowered = world.isBlockPowered(pos) || tile.isPoweredByLaser(); if(wasPowered != isPowered) { - updateLaser(worldIn, pos, facing, isPowered); - IBlockState newState = state.withProperty(POWERED, isPowered); - worldIn.setBlockState(pos, newState); +// IBlockState newState = state.withProperty(POWERED, isPowered); + tile.updatePower(isPowered); +// if(!world.isRemote) +// world.setBlockState(pos, newState); } - } - public void updateLaser(World world, BlockPos pos, EnumFacing facing, boolean powered) { - + @Override + public boolean hasTileEntity() { + return true; + } + + + @Override + public TileEntity createNewTileEntity(World worldIn, int meta) { + return new TileLaser(); } // DIRECTIONAL PLACING @@ -107,4 +115,24 @@ public static EnumFacing getFacingFromEntity(World worldIn, BlockPos clickedBloc return entityIn.getHorizontalFacing().getOpposite(); } + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(FACING, getFacing(meta).getOpposite());//.withProperty(POWERED, Boolean.valueOf((meta & 8) > 0)); + } + + public static EnumFacing getFacing(int meta) { + int i = meta & 7; + return i > 5 ? null : EnumFacing.getFront(i); + } + + public int getMetaFromState(IBlockState state) { + int i = 0; + i = i | ((EnumFacing)state.getValue(FACING)).getIndex(); + +// if (((Boolean)state.getValue(POWERED)).booleanValue()) +// { +// i |= 8; +// } + + return i; + } } diff --git a/src/main/java/practicalities/blocks/ILaserReciver.java b/src/main/java/practicalities/blocks/ILaserReciver.java index a9e9ce0..edf1454 100644 --- a/src/main/java/practicalities/blocks/ILaserReciver.java +++ b/src/main/java/practicalities/blocks/ILaserReciver.java @@ -3,10 +3,9 @@ import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; -import practicalities.entity.EntityLaser; public interface ILaserReciver { - public void laserHit(World world, BlockPos pos, EnumFacing sideHit, EntityLaser laser); + public void laserHit(World world, BlockPos pos, EnumFacing sideHit, BlockPos laserPos, boolean powered); } diff --git a/src/main/java/practicalities/blocks/TileLaser.java b/src/main/java/practicalities/blocks/TileLaser.java index 7622aa2..ce2a99f 100644 --- a/src/main/java/practicalities/blocks/TileLaser.java +++ b/src/main/java/practicalities/blocks/TileLaser.java @@ -1,28 +1,113 @@ package practicalities.blocks; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.function.Consumer; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.registry.GameRegistry; +import practicalities.Logger; +import practicalities.lib.util.WorldTraceUtil; +import practicalities.lib.util.vec.Vector3; public class TileLaser extends TileEntity implements ITickable { + int hitCounter = 0; + List oldLasers = new ArrayList<>(); Laser currentLaser = null; + + public boolean powered = false; + public static class Laser { public double start, end; public EnumFacing direction; + + public BlockPos moveEnd(World w, Vector3 origin, double speed) { + Vector3 endVec = origin.copy().add(new Vector3(this.direction, this.end)); + double amountToMove = WorldTraceUtil.rayHitDistance(w, endVec, speed, this.direction); + end += amountToMove; + if(amountToMove != speed) { + endVec = origin.copy().add(new Vector3(this.direction, this.end)).floor(); + + return new BlockPos(endVec.vec3()); + } + return null; + } + } + + public void eachLaser(Consumer r) { + if(currentLaser != null) r.accept(currentLaser); + oldLasers.forEach(r); } public void updatePower(boolean powered) { + if(powered) { + currentLaser = new Laser(); + currentLaser.direction = worldObj.getBlockState(pos).getValue(BlockLaser.FACING); + } else { + oldLasers.add(currentLaser); + currentLaser = null; + } + this.powered = powered; + } + + public void laserHit(boolean power) { + if(power) { + hitCounter++; + } else { + hitCounter--; + } + } + + public boolean isPoweredByLaser() { + return hitCounter > 0; + } + + public void onBreak() { } - + + boolean firstTick = true; + @Override public void update() { - // TODO Auto-generated method stub + if(firstTick) { // yeah, yeah, I know I'm not supposed to do this, but it caused a stack overflow in onLoad. + this.powered = worldObj.isBlockPowered(pos); + firstTick = false; + } + + Vector3 origin = Vector3.fromTileCenter(this); + + double speed = .1; + + + if(currentLaser != null) { + currentLaser.end += WorldTraceUtil.rayHitDistance(worldObj, origin.copy().add(new Vector3(currentLaser.direction, currentLaser.end)), speed, currentLaser.direction); + } + + for (Laser laser : oldLasers) { + laser.start += speed; + laser.end += WorldTraceUtil.rayHitDistance(worldObj, origin.copy().add(new Vector3(laser.direction, laser.end)), speed, laser.direction); + } + + for (Iterator iterator = oldLasers.iterator(); iterator.hasNext();) { + Laser laser = iterator.next(); + if (laser.start >= laser.end) { + iterator.remove(); + } + } } + + public static void initialize() { + Logger.info(" Registering Laser"); + GameRegistry.registerTileEntity(TileLaser.class, "p2.laser"); + } + } diff --git a/src/main/java/practicalities/client/render/RenderLaser.java b/src/main/java/practicalities/client/render/RenderLaser.java index 627dac0..eb9f845 100644 --- a/src/main/java/practicalities/client/render/RenderLaser.java +++ b/src/main/java/practicalities/client/render/RenderLaser.java @@ -1,13 +1,39 @@ package practicalities.client.render; +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.tileentity.TileEntity; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import practicalities.Logger; +import practicalities.blocks.TileLaser; +import practicalities.lib.util.vec.Vector3; -public class RenderLaser extends TileEntitySpecialRenderer { +public class RenderLaser extends TileEntitySpecialRenderer { @Override - public void renderTileEntityAt(TileEntity te, double x, double y, double z, float partialTicks, int destroyStage) { + public void renderTileEntityAt(TileLaser te, double x, double y, double z, float partialTicks, int destroyStage) { + Tessellator t = Tessellator.getInstance(); + WorldRenderer r = t.getWorldRenderer(); + + r.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR); + + Vector3 origin = Vector3.fromTile(te); + + te.eachLaser( (TileLaser.Laser l) -> renderLaser(l, origin) ); // why? BECAUSE I CAN!!! 1.8 baby! + + t.draw(); + } + + public void renderLaser(TileLaser.Laser laser, Vector3 origin) { + WorldRenderer r = Tessellator.getInstance().getWorldRenderer(); + Vector3 start = origin.copy().add(laser.direction, laser.start); + Vector3 end = origin.copy().add(laser.direction, laser.end); + + r.pos(start.x, start.y, start.z).color(1, 0, 0, 1); + r.pos(end.x, end.y, end.z) .color(1, 0, 0, 1); } } diff --git a/src/main/java/practicalities/lib/util/WorldTraceUtil.java b/src/main/java/practicalities/lib/util/WorldTraceUtil.java new file mode 100644 index 0000000..2fbfc35 --- /dev/null +++ b/src/main/java/practicalities/lib/util/WorldTraceUtil.java @@ -0,0 +1,197 @@ +package practicalities.lib.util; + +import java.util.ArrayList; +import java.util.List; + +import com.google.common.collect.Lists; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; +import practicalities.Logger; +import practicalities.lib.util.vec.ExtendedVector3; +import practicalities.lib.util.vec.Vector3; + +public class WorldTraceUtil { +private static List collidingBoundingBoxes = new ArrayList(); + + public static float MARGIN_OF_ERROR = 1/16f; + + private static void addCollidingBoundingBoxes(Entity e, World w, AxisAlignedBB bb) { + List list = Lists.newArrayList(); + int i = MathHelper.floor_double(bb.minX); + int j = MathHelper.floor_double(bb.maxX + 1.0D); // floor(x+1) == ceiling(x) + int k = MathHelper.floor_double(bb.minY); + int l = MathHelper.floor_double(bb.maxY + 1.0D); // floor(x+1) == ceiling(x) + int i1 = MathHelper.floor_double(bb.minZ); + int j1 = MathHelper.floor_double(bb.maxZ + 1.0D); // floor(x+1) == ceiling(x) + + BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); + + for (int k1 = i; k1 < j; ++k1) + { + for (int l1 = i1; l1 < j1; ++l1) + { + if (w.isBlockLoaded(blockpos$mutableblockpos.set(k1, 64, l1))) + { + for (int i2 = k - 1; i2 < l; ++i2) + { + blockpos$mutableblockpos.set(k1, i2, l1); + + IBlockState iblockstate1 = w.getBlockState(blockpos$mutableblockpos); + + iblockstate1.getBlock().addCollisionBoxesToList(w, blockpos$mutableblockpos, iblockstate1, bb, list, e); + } + } + } + } + + collidingBoundingBoxes = list; + } + + private static ExtendedVector3 traceAABB(Vector3 start, Vector3 end, AxisAlignedBB aabb) { + if(aabb == null || start == null || end == null) + return null; + MovingObjectPosition mop = aabb.expand(MARGIN_OF_ERROR, MARGIN_OF_ERROR, MARGIN_OF_ERROR).calculateIntercept(start.vec3(), end.vec3()); + if(mop == null) + return null; + else + return ( new ExtendedVector3(mop.hitVec) ).setData(mop); + } + + public static ExtendedVector3 collisionRayCast(World world, Vector3 start, Vector3 offset, Entity e) + { + Vector3 end = start.copy().add(offset); + + double minX = Math.min(start.x, end.x); + double minY = Math.min(start.y, end.y); + double minZ = Math.min(start.z, end.z); + + double maxX = Math.max(start.x, end.x); + double maxY = Math.max(start.y, end.y); + double maxZ = Math.max(start.z, end.z); + +// collidingBoundingBoxes.clear(); + List scanBBs = new ArrayList(); + double magS = offset.magSquared(); + if(magS > 50) { + double count = Math.ceil( magS/50.0 ); // this is a double so the division below doesn't round + for(int i = 0; i <= count; i++) { + scanBBs.add( + AxisAlignedBB.fromBounds( + minX+( offset.x * i/count), minY+( offset.y * i/count), minZ+( offset.z * i/count), + maxX-( offset.x * (count-i)/count), maxY-( offset.y * (count-i)/count), maxZ-( offset.z * (count-i)/count) + ).expand(1, 1, 1) + ); + } + } else { + scanBBs.add( + AxisAlignedBB.fromBounds( + minX, minY, minZ, + maxX, maxY, maxZ + ).expand(0.5, 0.5, 0.5) + ); + } + for (AxisAlignedBB aabb : scanBBs) + { + collidingBoundingBoxes = new ArrayList(); + aabb.expand(MARGIN_OF_ERROR, MARGIN_OF_ERROR, MARGIN_OF_ERROR); + addCollidingBoundingBoxes(e, world, aabb); + + Vector3 shortestHit = null; + double shortestMagSquared = Double.MAX_VALUE; + EnumFacing shortestSide = null; + for (int i = 0; i < collidingBoundingBoxes.size(); i++) + { + AxisAlignedBB currentBB = (AxisAlignedBB)collidingBoundingBoxes.get(i); + ExtendedVector3 currentHit = traceAABB(start, end, currentBB); + if(currentHit != null) + { + double currentMagS = currentHit.copy().sub(start).magSquared(); + if(currentMagS < shortestMagSquared) { + shortestHit = currentHit; + shortestMagSquared = currentMagS; + shortestSide = currentHit.getData().sideHit; + } + } + } + if(shortestHit != null) { + return new ExtendedVector3(shortestHit.sub(start)).setData(shortestSide); + } + } + return new ExtendedVector3(offset).setData(null); + } + + public static double rayHitDistance(World w, Vector3 vec, double distance, EnumFacing direction) { + + AxisAlignedBB aabb = AxisAlignedBB.fromBounds( + vec.x, vec.y, vec.z, + vec.x+(direction.getFrontOffsetX()*distance), vec.y+(direction.getFrontOffsetY()*distance), vec.z+(direction.getFrontOffsetZ()*distance) + ); + + collidingBoundingBoxes = new ArrayList(); + aabb.expand(MARGIN_OF_ERROR, MARGIN_OF_ERROR, MARGIN_OF_ERROR); + addCollidingBoundingBoxes(new EntityItem(w), w, aabb); + + double minDistance = distance; + for (AxisAlignedBB bb : collidingBoundingBoxes) { + double collideDistance = collideWithSide(bb, vec, direction); + if(collideDistance < minDistance) + minDistance = collideDistance; + } + + return minDistance; + } + + public static double collideWithSide(AxisAlignedBB bb, Vector3 vec, EnumFacing dir) { + double distance = Double.POSITIVE_INFINITY; + switch (dir) { + case DOWN: + if( bb.minX <= vec.x && bb.maxX >= vec.x && + bb.minZ <= vec.z && bb.maxZ >= vec.z && bb.maxY <= vec.y) { + distance = vec.y - bb.maxY; + } + break; + case UP: + if( bb.minX <= vec.x && bb.maxX >= vec.x && + bb.minZ <= vec.z && bb.maxZ >= vec.z && bb.minY >= vec.y) { + distance = bb.minY - vec.y; + } + break; + + case WEST: + if( bb.minY <= vec.y && bb.maxY >= vec.y && + bb.minZ <= vec.z && bb.maxZ >= vec.z && bb.maxX <= vec.x) { + distance = vec.x - bb.maxX; + } + break; + case EAST: + if( bb.minY <= vec.y && bb.maxY >= vec.y && + bb.minZ <= vec.z && bb.maxZ >= vec.z && bb.minX >= vec.x) { + distance = bb.minX - vec.x; + } + break; + + case NORTH: + if( bb.minY <= vec.y && bb.maxY >= vec.y && + bb.minX <= vec.x && bb.maxX >= vec.x && bb.maxZ <= vec.z) { + distance = vec.z - bb.maxZ; + } + break; + case SOUTH: + if( bb.minY <= vec.y && bb.maxY >= vec.y && + bb.minX <= vec.x && bb.maxX >= vec.x && bb.minZ >= vec.z) { + distance = bb.minZ - vec.z; + } + break; + } + return distance; + } +} diff --git a/src/main/java/practicalities/lib/util/math/MathHelper.java b/src/main/java/practicalities/lib/util/math/MathHelper.java new file mode 100644 index 0000000..2942ec5 --- /dev/null +++ b/src/main/java/practicalities/lib/util/math/MathHelper.java @@ -0,0 +1,181 @@ +package practicalities.lib.util.math; + +/** + * @author ChickenBones + */ +public class MathHelper +{ + public static final double phi = 1.618033988749894; + public static final double pi = Math.PI; + public static final double todeg = 57.29577951308232; + public static final double torad = 0.017453292519943; + public static final double sqrt2 = 1.414213562373095; + + public static double[] SIN_TABLE = new double[65536]; + static + { + for (int i = 0; i < 65536; ++i) + SIN_TABLE[i] = Math.sin(i / 65536D * 2 * Math.PI); + + SIN_TABLE[0] = 0; + SIN_TABLE[16384] = 1; + SIN_TABLE[32768] = 0; + SIN_TABLE[49152] = 1; + } + + public static double sin(double d) + { + return SIN_TABLE[(int)((float)d * 10430.378F) & 65535]; + } + + public static double cos(double d) + { + return SIN_TABLE[(int)((float)d * 10430.378F + 16384.0F) & 65535]; + } + + /** + * @param a The value + * @param b The value to approach + * @param max The maximum step + * @return the closed value to b no less than max from a + */ + public static float approachLinear(float a, float b, float max) + { + return (a > b) ? + (a - b < max ? b : a-max) : + (b - a < max ? b : a+max); + } + + /** + * @param a The value + * @param b The value to approach + * @param max The maximum step + * @return the closed value to b no less than max from a + */ + public static double approachLinear(double a, double b, double max) + { + return (a > b) ? + (a - b < max ? b : a-max) : + (b - a < max ? b : a+max); + } + + /** + * @param a The first value + * @param b The second value + * @param d The interpolation factor, between 0 and 1 + * @return a+(b-a)*d + */ + public static float interpolate(float a, float b, float d) + { + return a+(b-a)*d; + } + + /** + * @param a The first value + * @param b The second value + * @param d The interpolation factor, between 0 and 1 + * @return a+(b-a)*d + */ + public static double interpolate(double a, double b, double d) + { + return a+(b-a)*d; + } + + /** + * @param a The value + * @param b The value to approach + * @param ratio The ratio to reduce the difference by + * @return a+(b-a)*ratio + */ + public static double approachExp(double a, double b, double ratio) + { + return a+(b-a)*ratio; + } + + /** + * @param a The value + * @param b The value to approach + * @param ratio The ratio to reduce the difference by + * @param cap The maximum amount to advance by + * @return a+(b-a)*ratio + */ + public static double approachExp(double a, double b, double ratio, double cap) + { + double d = (b-a)*ratio; + if(Math.abs(d) > cap) + d = Math.signum(d)*cap; + return a+d; + } + + /** + * @param a The value + * @param b The value to approach + * @param ratio The ratio to reduce the difference by + * @param c The value to retreat from + * @param kick The difference when a == c + * @return + */ + public static double retreatExp(double a, double b, double c, double ratio, double kick) + { + double d = (Math.abs(c-a)+kick)*ratio; + if(d > Math.abs(b-a)) + return b; + return a+Math.signum(b-a)*d; + } + + /** + * + * @param value The value + * @param min The min value + * @param max The max value + * @return The clipped value between min and max + */ + public static double clip(double value, double min, double max) + { + if(value > max) + value = max; + if(value < min) + value = min; + return value; + } + + /** + * @return a <= x <= b + */ + public static boolean between(double a, double x, double b) + { + return a <= x && x <= b; + } + + public static int approachExpI(int a, int b, double ratio) + { + int r = (int)Math.round(approachExp(a, b, ratio)); + return r == a ? b : r; + } + + public static int retreatExpI(int a, int b, int c, double ratio, int kick) + { + int r = (int)Math.round(retreatExp(a, b, c, ratio, kick)); + return r == a ? b : r; + } + + public static int floor_double(double d) + { + return net.minecraft.util.MathHelper.floor_double(d); + } + + public static int roundAway(double d) + { + return (int) (d < 0 ? Math.floor(d) : Math.ceil(d)); + } + + public static int compare(int a, int b) + { + return a == b ? 0 : a < b ? -1 : 1; + } + + public static int compare(double a, double b) + { + return a == b ? 0 : a < b ? -1 : 1; + } +} diff --git a/src/main/java/practicalities/lib/util/track/Tracker.java b/src/main/java/practicalities/lib/util/track/Tracker.java new file mode 100644 index 0000000..8dc996f --- /dev/null +++ b/src/main/java/practicalities/lib/util/track/Tracker.java @@ -0,0 +1,9 @@ +package practicalities.lib.util.track; + +public abstract class Tracker { + + public abstract void clear(); + + public abstract void track(String key, String value); + +} diff --git a/src/main/java/practicalities/lib/util/track/TrackerClient.java b/src/main/java/practicalities/lib/util/track/TrackerClient.java new file mode 100644 index 0000000..8a0d083 --- /dev/null +++ b/src/main/java/practicalities/lib/util/track/TrackerClient.java @@ -0,0 +1,59 @@ +package practicalities.lib.util.track; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class TrackerClient extends Tracker { + + Map tracks = new HashMap<>(); + Map packetTracks = new HashMap<>(); + boolean needToClear = true; + + @Override + public void clear() { + if(needToClear) { + tracks.clear(); + packetTracks.clear(); + } + needToClear = true; + } + + @Override + public void track(String key, String value) { + if(needToClear) { + tracks.clear(); + packetTracks.clear(); + needToClear = false; + } + tracks.put(key, value); + } + + public void trackPacket(String key, String value) { + if(needToClear) { + tracks.clear(); + packetTracks.clear(); + needToClear = false; + } + packetTracks.put(key, value); + } + + @SubscribeEvent + public void onDebugText(RenderGameOverlayEvent.Text event) { + if(!Minecraft.getMinecraft().gameSettings.showDebugInfo) + return; + Set keys = new HashSet<>(); + keys.addAll(tracks.keySet()); + keys.addAll(packetTracks.keySet()); + + event.left.add("KEY: §4SERVER §9CLIENT"); + for(String key : keys) { + event.left.add(key + ": §4" + packetTracks.get(key) + " §9" + tracks.get(key)); + } + } +} diff --git a/src/main/java/practicalities/lib/util/track/TrackerRelease.java b/src/main/java/practicalities/lib/util/track/TrackerRelease.java new file mode 100644 index 0000000..e06d1ab --- /dev/null +++ b/src/main/java/practicalities/lib/util/track/TrackerRelease.java @@ -0,0 +1,15 @@ +package practicalities.lib.util.track; + +public class TrackerRelease extends Tracker { + + @Override + public void clear() { + throw new UnsupportedOperationException("Practicalities: Tried to call Tracker.clear outside of a dev environment! This is just plain bad!"); + } + + @Override + public void track(String key, String value) { + throw new UnsupportedOperationException("Practicalities: Tried to call Tracker.track outside of a dev environment! This is just plain bad!"); + } + +} diff --git a/src/main/java/practicalities/lib/util/track/TrackerServer.java b/src/main/java/practicalities/lib/util/track/TrackerServer.java new file mode 100644 index 0000000..d487b85 --- /dev/null +++ b/src/main/java/practicalities/lib/util/track/TrackerServer.java @@ -0,0 +1,26 @@ +package practicalities.lib.util.track; + +import java.util.HashMap; +import java.util.Map; + +import practicalities.network.MessageTracker; +import practicalities.network.NetHandler; + +public class TrackerServer extends Tracker { + + Map tracks = new HashMap<>(); + + @Override + public void clear() { + tracks.clear(); + } + + @Override + public void track(String key, String value) { + if(!value.equals(tracks.get(key))) { + NetHandler.network.sendToAll(new MessageTracker(key, value)); + } + tracks.put(key, value); + } + +} diff --git a/src/main/java/practicalities/lib/util/vec/ExtendedVector3.java b/src/main/java/practicalities/lib/util/vec/ExtendedVector3.java new file mode 100644 index 0000000..4dc03bd --- /dev/null +++ b/src/main/java/practicalities/lib/util/vec/ExtendedVector3.java @@ -0,0 +1,31 @@ +package practicalities.lib.util.vec; + +import net.minecraft.util.BlockPos; +import net.minecraft.util.Vec3; + +public class ExtendedVector3 extends Vector3 +{ + public ExtendedVector3() { } + + public ExtendedVector3(double d, double d1, double d2) { super(d, d1, d2); } + + public ExtendedVector3(Vector3 vec) { super(vec); } + + public ExtendedVector3(double[] da) { super(da); } + + public ExtendedVector3(Vec3 vec) { super(vec); } + + public ExtendedVector3(BlockPos coord) { super(coord); } + + D data; + + public D getData() + { + return data; + } + public ExtendedVector3 setData(D data) + { + this.data = data; + return this; + } +} diff --git a/src/main/java/practicalities/lib/util/vec/Quat.java b/src/main/java/practicalities/lib/util/vec/Quat.java new file mode 100644 index 0000000..8f117e6 --- /dev/null +++ b/src/main/java/practicalities/lib/util/vec/Quat.java @@ -0,0 +1,159 @@ +package practicalities.lib.util.vec; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; + +import net.minecraft.util.MathHelper; + +/** + * @author ChickenBones + */ +public class Quat +{ + public double x; + public double y; + public double z; + public double s; + + public Quat() + { + s = 1; + x = 0; + y = 0; + z = 0; + } + + public Quat(Quat quat) + { + x = quat.x; + y = quat.y; + z = quat.z; + s = quat.s; + } + + public Quat(double d, double d1, double d2, double d3) + { + x = d1; + y = d2; + z = d3; + s = d; + } + + public Quat set(Quat quat) + { + x = quat.x; + y = quat.y; + z = quat.z; + s = quat.s; + + return this; + } + + public Quat set(double d, double d1, double d2, double d3) + { + x = d1; + y = d2; + z = d3; + s = d; + + return this; + } + + public static Quat aroundAxis(double ax, double ay, double az, double angle) + { + return new Quat().setAroundAxis(ax, ay, az, angle); + } + + public static Quat aroundAxis(Vector3 axis, double angle) + { + return aroundAxis(axis.x, axis.y, axis.z, angle); + } + + public Quat setAroundAxis(double ax, double ay, double az, double angle) + { + angle *= 0.5; + double d4 = MathHelper.sin((float)angle); + return set(MathHelper.cos((float)angle), ax * d4, ay * d4, az * d4); + } + + public Quat setAroundAxis(Vector3 axis, double angle) + { + return setAroundAxis(axis.x, axis.y, axis.z, angle); + } + + public Quat multiply(Quat quat) + { + double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z; + double d1 = s * quat.x + x * quat.s - y * quat.z + z * quat.y; + double d2 = s * quat.y + x * quat.z + y * quat.s - z * quat.x; + double d3 = s * quat.z - x * quat.y + y * quat.x + z * quat.s; + s = d; + x = d1; + y = d2; + z = d3; + + return this; + } + + public Quat rightMultiply(Quat quat) + { + double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z; + double d1 = s * quat.x + x * quat.s + y * quat.z - z * quat.y; + double d2 = s * quat.y - x * quat.z + y * quat.s + z * quat.x; + double d3 = s * quat.z + x * quat.y - y * quat.x + z * quat.s; + s = d; + x = d1; + y = d2; + z = d3; + + return this; + } + + public double mag() + { + return Math.sqrt(x * x + y * y + z * z + s * s); + } + + public Quat normalize() + { + double d = mag(); + if(d != 0) + { + d = 1 / d; + x *= d; + y *= d; + z *= d; + s *= d; + } + + return this; + } + + public Quat copy() + { + return new Quat(this); + } + + public void rotate(Vector3 vec) + { + double d = -x * vec.x - y * vec.y - z * vec.z; + double d1 = s * vec.x + y * vec.z - z * vec.y; + double d2 = s * vec.y - x * vec.z + z * vec.x; + double d3 = s * vec.z + x * vec.y - y * vec.x; + vec.x = d1 * s - d * x - d2 * z + d3 * y; + vec.y = d2 * s - d * y + d1 * z - d3 * x; + vec.z = d3 * s - d * z - d1 * y + d2 * x; + } + + public String toString() + { + MathContext cont = new MathContext(4, RoundingMode.HALF_UP); + return "Quat("+new BigDecimal(s, cont)+", "+new BigDecimal(x, cont)+", "+new BigDecimal(y, cont)+", "+new BigDecimal(z, cont)+")"; + } + +// public Rotation rotation() +// { +// return new Rotation(this); +// } +} diff --git a/src/main/java/practicalities/lib/util/vec/Vector3.java b/src/main/java/practicalities/lib/util/vec/Vector3.java new file mode 100644 index 0000000..673d4c4 --- /dev/null +++ b/src/main/java/practicalities/lib/util/vec/Vector3.java @@ -0,0 +1,498 @@ +package practicalities.lib.util.vec; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.vector.Vector3f; +import org.lwjgl.util.vector.Vector4f; + +import net.minecraft.entity.Entity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.Vec3; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import practicalities.lib.util.math.MathHelper; + + +/** + * @author ChickenBones + */ +public class Vector3 +{ + public static Vector3 zero = new Vector3(); + public static Vector3 one = new Vector3(1, 1, 1); + public static Vector3 center = new Vector3(0.5, 0.5, 0.5); + + public double x; + public double y; + public double z; + + public Vector3() { + } + + public Vector3(double d, double d1, double d2) { + x = d; + y = d1; + z = d2; + } + + public Vector3(Vector3 vec) { + x = vec.x; + y = vec.y; + z = vec.z; + } + + public Vector3(double[] da) { + this(da[0], da[1], da[2]); + } + + public Vector3(Vec3 vec) { + x = vec.xCoord; + y = vec.yCoord; + z = vec.zCoord; + } + + public Vector3(BlockPos pos) { + x = pos.getX(); + y = pos.getY(); + z = pos.getZ(); + } + + public Vector3(EnumFacing direction, double amount) { + x = direction.getFrontOffsetX() * amount; + y = direction.getFrontOffsetY() * amount; + z = direction.getFrontOffsetZ() * amount; + } + + public Vector3 copy() { + return new Vector3(this); + } + + public static Vector3 fromEntity(Entity e) { + return new Vector3(e.posX, e.posY, e.posZ); + } + + public static Vector3 fromEntityCenter(Entity e) { + return new Vector3(e.posX, e.posY - e.getYOffset() + e.height / 2, e.posZ); + } + + public static Vector3 fromTile(TileEntity tile) { + return new Vector3(tile.getPos()); + } + + public static Vector3 fromTileCenter(TileEntity tile) { + return fromTile(tile).add(0.5); + } + + public static Vector3 fromAxes(double[] da) { + return new Vector3(da[2], da[0], da[1]); + } + + public Vector3 set(double d, double d1, double d2) { + x = d; + y = d1; + z = d2; + return this; + } + + public Vector3 set(Vector3 vec) { + x = vec.x; + y = vec.y; + z = vec.z; + return this; + } + + public double getSide(int side) { + switch (side) { + case 0: + case 1: + return y; + case 2: + case 3: + return z; + case 4: + case 5: + return x; + } + throw new IndexOutOfBoundsException("Switch Falloff"); + } + + public Vector3 setSide(int s, double v) { + switch (s) { + case 0: + case 1: + y = v; + break; + case 2: + case 3: + z = v; + break; + case 4: + case 5: + x = v; + break; + default: + throw new IndexOutOfBoundsException("Switch Falloff"); + } + return this; + } + + public double dotProduct(Vector3 vec) { + double d = vec.x * x + vec.y * y + vec.z * z; + + if (d > 1 && d < 1.00001) + d = 1; + else if (d < -1 && d > -1.00001) + d = -1; + return d; + } + + public double dotProduct(double d, double d1, double d2) { + return d * x + d1 * y + d2 * z; + } + + public Vector3 crossProduct(Vector3 vec) { + double d = y * vec.z - z * vec.y; + double d1 = z * vec.x - x * vec.z; + double d2 = x * vec.y - y * vec.x; + x = d; + y = d1; + z = d2; + return this; + } + + public Vector3 add(double d, double d1, double d2) { + x += d; + y += d1; + z += d2; + return this; + } + + public Vector3 add(Vector3 vec) { + x += vec.x; + y += vec.y; + z += vec.z; + return this; + } + + public Vector3 add(double d) { + return add(d, d, d); + } + + public Vector3 add(EnumFacing dir, double amount) { + return add(dir.getFrontOffsetX()*amount, dir.getFrontOffsetY()*amount, dir.getFrontOffsetZ()*amount); + } + + public Vector3 sub(double d, double d1, double d2) { + x -= d; + y -= d1; + z -= d2; + return this; + } + + public Vector3 sub(Vector3 vec) { + return subtract(vec); + } + + public Vector3 subtract(Vector3 vec) { + x -= vec.x; + y -= vec.y; + z -= vec.z; + return this; + } + + public Vector3 sub(double d) { + return sub(d, d, d); + } + + public Vector3 sub(EnumFacing dir, double amount) { + return sub(dir.getFrontOffsetX()*amount, dir.getFrontOffsetY()*amount, dir.getFrontOffsetZ()*amount); + } + + public Vector3 negate(Vector3 vec) { + x = -x; + y = -y; + z = -z; + return this; + } + + public Vector3 multiply(double d) { + x *= d; + y *= d; + z *= d; + return this; + } + + public Vector3 multiply(Vector3 f) { + x *= f.x; + y *= f.y; + z *= f.z; + return this; + } + + public Vector3 multiply(double fx, double fy, double fz) { + x *= fx; + y *= fy; + z *= fz; + return this; + } + + public Vector3 ceil() { + x = Math.ceil(x); + y = Math.ceil(y); + z = Math.ceil(z); + return this; + } + + public Vector3 floor() { + x = Math.floor(x); + y = Math.floor(y); + z = Math.floor(z); + return this; + } + + public double mag() { + return Math.sqrt(x * x + y * y + z * z); + } + + public double magSquared() { + return x * x + y * y + z * z; + } + + public Vector3 normalize() { + double d = mag(); + if (d != 0) { + multiply(1 / d); + } + return this; + } + + public String toString() { + MathContext cont = new MathContext(4, RoundingMode.HALF_UP); + return "Vector3(" + new BigDecimal(x, cont) + ", " + new BigDecimal(y, cont) + ", " + new BigDecimal(z, cont) + ")"; + } + + public Vector3 perpendicular() { + if (z == 0) + return zCrossProduct(); + return xCrossProduct(); + } + + public Vector3 xCrossProduct() { + double d = z; + double d1 = -y; + x = 0; + y = d; + z = d1; + return this; + } + + public Vector3 zCrossProduct() { + double d = y; + double d1 = -x; + x = d; + y = d1; + z = 0; + return this; + } + + public Vector3 yCrossProduct() { + double d = -z; + double d1 = x; + x = d; + y = 0; + z = d1; + return this; + } + + public Vector3 rotate(double angle, Vector3 axis) { + Quat.aroundAxis(axis.copy().normalize(), angle).rotate(this); + return this; + } + + public Vector3 rotate(Quat rotator) { + rotator.rotate(this); + return this; + } + + public Vec3 vec3() { + return new Vec3(x, y, z); + } + + public double angle(Vector3 vec) { + return Math.acos(copy().normalize().dotProduct(vec.copy().normalize())); + } + + public boolean isZero() { + return x == 0 && y == 0 && z == 0; + } + + public boolean isAxial() { + return x == 0 ? (y == 0 || z == 0) : (y == 0 && z == 0); + } + + @SideOnly(Side.CLIENT) + public Vector3f vector3f() { + return new Vector3f((float) x, (float) y, (float) z); + } + + @SideOnly(Side.CLIENT) + public Vector4f vector4f() { + return new Vector4f((float) x, (float) y, (float) z, 1); + } + + @SideOnly(Side.CLIENT) + public void glVertex() { + GL11.glVertex3d(x, y, z); + } + + public Vector3 YZintercept(Vector3 end, double px) { + double dx = end.x - x; + double dy = end.y - y; + double dz = end.z - z; + + if (dx == 0) + return null; + + double d = (px - x) / dx; + if (MathHelper.between(-1E-5, d, 1E-5)) + return this; + + if (!MathHelper.between(0, d, 1)) + return null; + + x = px; + y += d * dy; + z += d * dz; + return this; + } + + public Vector3 XZintercept(Vector3 end, double py) { + double dx = end.x - x; + double dy = end.y - y; + double dz = end.z - z; + + if (dy == 0) + return null; + + double d = (py - y) / dy; + if (MathHelper.between(-1E-5, d, 1E-5)) + return this; + + if (!MathHelper.between(0, d, 1)) + return null; + + x += d * dx; + y = py; + z += d * dz; + return this; + } + + public Vector3 XYintercept(Vector3 end, double pz) { + double dx = end.x - x; + double dy = end.y - y; + double dz = end.z - z; + + if (dz == 0) + return null; + + double d = (pz - z) / dz; + if (MathHelper.between(-1E-5, d, 1E-5)) + return this; + + if (!MathHelper.between(0, d, 1)) + return null; + + x += d * dx; + y += d * dy; + z = pz; + return this; + } + + public Vector3 negate() { + x = -x; + y = -y; + z = -z; + return this; + } + +// public Translation translation() { +// return new Translation(this); +// } + + public double scalarProject(Vector3 b) { + double l = b.mag(); + return l == 0 ? 0 : dotProduct(b) / l; + } + + public Vector3 project(Vector3 b) { + double l = b.magSquared(); + if (l == 0) { + set(0, 0, 0); + return this; + } + double m = dotProduct(b) / l; + set(b).multiply(m); + return this; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Vector3)) + return false; + Vector3 v = (Vector3) o; + return x == v.x && y == v.y && z == v.z; + } + + /** + * Equals method with tolerance + * + * @return true if this is equal to v within +-1E-5 + */ + public boolean equalsT(Vector3 v) { + return MathHelper.between(x - 1E-5, v.x, x + 1E-5) && + MathHelper.between(y - 1E-5, v.y, y + 1E-5) && + MathHelper.between(z - 1E-5, v.z, z + 1E-5); + } + +// public Vector3 apply(Transformation t) { +// t.apply(this); +// return this; +// } + + public Vector3 $tilde() { + return normalize(); + } + + public Vector3 unary_$tilde() { + return normalize(); + } + + public Vector3 $plus(Vector3 v) { + return add(v); + } + + public Vector3 $minus(Vector3 v) { + return subtract(v); + } + + public Vector3 $times(double d) { + return multiply(d); + } + + public Vector3 $div(double d) { + return multiply(1 / d); + } + + public Vector3 $times(Vector3 v) { + return crossProduct(v); + } + + public double $dot$times(Vector3 v) { + return dotProduct(v); + } +} diff --git a/src/main/java/practicalities/network/MessageTracker.java b/src/main/java/practicalities/network/MessageTracker.java new file mode 100644 index 0000000..6f977f1 --- /dev/null +++ b/src/main/java/practicalities/network/MessageTracker.java @@ -0,0 +1,46 @@ +package practicalities.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.util.IThreadListener; +import net.minecraftforge.fml.common.network.ByteBufUtils; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import practicalities.Logger; +import practicalities.PracticalitiesMod; +import practicalities.lib.util.track.TrackerClient; + +public class MessageTracker implements IMessage, IMessageHandler{ + + String key, value; + + public MessageTracker() {} + + public MessageTracker(String key, String value) { + this.key = key; + this.value = value; + } + + @Override + public IMessage onMessage(MessageTracker message, MessageContext ctx) { + IThreadListener thread = (IThreadListener) Minecraft.getMinecraft(); + thread.addScheduledTask( ()->{ + ( (TrackerClient)PracticalitiesMod.proxy.trackerClient ).trackPacket(message.key, message.value); + }); + return null; + } + + @Override + public void fromBytes(ByteBuf buf) { + key = ByteBufUtils.readUTF8String(buf); + value = ByteBufUtils.readUTF8String(buf); + } + + @Override + public void toBytes(ByteBuf buf) { + ByteBufUtils.writeUTF8String(buf, key); + ByteBufUtils.writeUTF8String(buf, value); + } + +} diff --git a/src/main/java/practicalities/network/NetHandler.java b/src/main/java/practicalities/network/NetHandler.java new file mode 100644 index 0000000..140c88f --- /dev/null +++ b/src/main/java/practicalities/network/NetHandler.java @@ -0,0 +1,16 @@ +package practicalities.network; + +import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; +import net.minecraftforge.fml.relauncher.Side; +import practicalities.ConfigMan; + +public class NetHandler { + public static SimpleNetworkWrapper network; + + public static void init() { + network = new SimpleNetworkWrapper("Practicalities"); + if(ConfigMan.isDev) { + network.registerMessage(MessageTracker.class, MessageTracker.class, 200, Side.CLIENT); + } + } +} diff --git a/src/main/java/practicalities/registers/BlockRegister.java b/src/main/java/practicalities/registers/BlockRegister.java index 86723e8..7c6e3b4 100755 --- a/src/main/java/practicalities/registers/BlockRegister.java +++ b/src/main/java/practicalities/registers/BlockRegister.java @@ -1,26 +1,35 @@ package practicalities.registers; -import net.minecraft.block.Block; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import practicalities.Logger; import practicalities.blocks.BlockBase; -import practicalities.blocks.BlockLaserEmmiter; +import practicalities.blocks.BlockLaser; +import practicalities.blocks.TileLaser; +import practicalities.client.render.RenderLaser; import practicalities.machines.shippingcrate.BlockShippingCrate; import practicalities.machines.shippingcrate.TileShippingCrate; public final class BlockRegister { public static BlockBase shippingcrate; - public static Block laserEmitter; + public static BlockBase laser; + public static BlockBase laserActivator; + + @SideOnly(Side.CLIENT) + public static TileEntitySpecialRenderer laserRender; + private static void initTileEntities(){ Logger.info("Registering TileEntities"); - TileShippingCrate.initialize(); + TileShippingCrate.initialize(); + TileLaser.initialize(); } public static void init(){ shippingcrate = new BlockShippingCrate(); - laserEmitter = new BlockLaserEmmiter(); + laser = new BlockLaser(); initTileEntities(); } @@ -29,7 +38,10 @@ public static void init(){ public static void registerRenders(){ Logger.info("Registering Block Renderers"); - shippingcrate.initModel(); + shippingcrate.initModel(); + laser.initModel(); + laserRender = new RenderLaser(); + ClientRegistry.bindTileEntitySpecialRenderer(TileLaser.class, laserRender); } } From c60dd2d1e6ccf36ac39bbfb9807fa3d0a7ff65b6 Mon Sep 17 00:00:00 2001 From: Pierce Corcoran Date: Fri, 15 Jan 2016 14:33:17 -0800 Subject: [PATCH 4/5] Tracking code is more modular --- build.gradle | 4 +- src/main/java/practicalities/Logger.java | 5 ++- src/main/java/practicalities/ProxyClient.java | 1 - src/main/java/practicalities/ProxyCommon.java | 28 -------------- .../lib/util/track/TrackerManager.java | 38 +++++++++++++++++++ .../lib/util/track/TrackerRelease.java | 15 -------- .../network/MessageTracker.java | 3 +- 7 files changed, 45 insertions(+), 49 deletions(-) create mode 100644 src/main/java/practicalities/lib/util/track/TrackerManager.java delete mode 100644 src/main/java/practicalities/lib/util/track/TrackerRelease.java diff --git a/build.gradle b/build.gradle index 2978c3d..c8decff 100755 --- a/build.gradle +++ b/build.gradle @@ -25,8 +25,8 @@ version = "1.8.9-2.0.0-b6" group= "practicalities" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "practicalities" -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = 1.8 +targetCompatibility = 1.8 minecraft { version = "1.8.9-11.15.0.1694" diff --git a/src/main/java/practicalities/Logger.java b/src/main/java/practicalities/Logger.java index 39331d5..fc74ef6 100755 --- a/src/main/java/practicalities/Logger.java +++ b/src/main/java/practicalities/Logger.java @@ -5,6 +5,7 @@ import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.relauncher.Side; +import practicalities.lib.util.track.TrackerManager; public class Logger { @@ -41,9 +42,9 @@ public static void track(String name, String format, Object... data) { if(!ConfigMan.isDev) throw new UnsupportedOperationException("Practicalities: Tried to call Logger.track outside of a dev environment! This is just plain bad!"); if(FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { - PracticalitiesMod.proxy.trackerServer.track(name, String.format(format, data)); + TrackerManager.server.track(name, String.format(format, data)); } else { - PracticalitiesMod.proxy.trackerClient.track(name, String.format(format, data)); + TrackerManager.client.track(name, String.format(format, data)); } } } diff --git a/src/main/java/practicalities/ProxyClient.java b/src/main/java/practicalities/ProxyClient.java index b448429..4093122 100755 --- a/src/main/java/practicalities/ProxyClient.java +++ b/src/main/java/practicalities/ProxyClient.java @@ -31,7 +31,6 @@ public void preInit() { @Override public void registerTickHandlers() { super.registerTickHandlers(); - MinecraftForge.EVENT_BUS.register(trackerClient); } @Override diff --git a/src/main/java/practicalities/ProxyCommon.java b/src/main/java/practicalities/ProxyCommon.java index 9956e45..49006ba 100755 --- a/src/main/java/practicalities/ProxyCommon.java +++ b/src/main/java/practicalities/ProxyCommon.java @@ -8,15 +8,7 @@ import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.LivingDropsEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import practicalities.items.netherbane.EntityNetherbane; -import practicalities.lib.util.track.Tracker; -import practicalities.lib.util.track.TrackerClient; -import practicalities.lib.util.track.TrackerRelease; -import practicalities.lib.util.track.TrackerServer; import practicalities.registers.BlockRegister; import practicalities.registers.ItemRegister; import practicalities.registers.RecipeRegister; @@ -26,9 +18,6 @@ public class ProxyCommon { public void preInit() { ItemRegister.init(); BlockRegister.init(); - if(!ConfigMan.isDev) { - trackerClient = trackerServer = new TrackerRelease(); - } } public void init() { @@ -90,21 +79,4 @@ public void onItemToss(ItemTossEvent event) { } } } - - public Tracker trackerClient = new TrackerClient(); - public Tracker trackerServer = new TrackerServer(); - - int timer = 20; - - @SubscribeEvent - public void onTick(TickEvent.WorldTickEvent evt) { - if(evt.phase == Phase.END) { - if(timer == 0) { - timer = 100; - trackerClient.clear(); - trackerServer.clear(); - } - timer--; - } - } } diff --git a/src/main/java/practicalities/lib/util/track/TrackerManager.java b/src/main/java/practicalities/lib/util/track/TrackerManager.java new file mode 100644 index 0000000..2e76bf3 --- /dev/null +++ b/src/main/java/practicalities/lib/util/track/TrackerManager.java @@ -0,0 +1,38 @@ +package practicalities.lib.util.track; + +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; +import practicalities.ConfigMan; + +public class TrackerManager { + + public static TrackerServer server; + public static TrackerClient client; + + public void init() { + if(ConfigMan.isDev) { + server = new TrackerServer(); + client = new TrackerClient(); + + MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.EVENT_BUS.register(client); + } + } + + int timer = 20; + + @SubscribeEvent + public void onTick(TickEvent.WorldTickEvent evt) { + if(evt.phase == Phase.END) { + if(timer == 0) { + timer = 100; + client.clear(); + server.clear(); + } + timer--; + } + } + +} diff --git a/src/main/java/practicalities/lib/util/track/TrackerRelease.java b/src/main/java/practicalities/lib/util/track/TrackerRelease.java deleted file mode 100644 index e06d1ab..0000000 --- a/src/main/java/practicalities/lib/util/track/TrackerRelease.java +++ /dev/null @@ -1,15 +0,0 @@ -package practicalities.lib.util.track; - -public class TrackerRelease extends Tracker { - - @Override - public void clear() { - throw new UnsupportedOperationException("Practicalities: Tried to call Tracker.clear outside of a dev environment! This is just plain bad!"); - } - - @Override - public void track(String key, String value) { - throw new UnsupportedOperationException("Practicalities: Tried to call Tracker.track outside of a dev environment! This is just plain bad!"); - } - -} diff --git a/src/main/java/practicalities/network/MessageTracker.java b/src/main/java/practicalities/network/MessageTracker.java index 6f977f1..2b73935 100644 --- a/src/main/java/practicalities/network/MessageTracker.java +++ b/src/main/java/practicalities/network/MessageTracker.java @@ -10,6 +10,7 @@ import practicalities.Logger; import practicalities.PracticalitiesMod; import practicalities.lib.util.track.TrackerClient; +import practicalities.lib.util.track.TrackerManager; public class MessageTracker implements IMessage, IMessageHandler{ @@ -26,7 +27,7 @@ public MessageTracker(String key, String value) { public IMessage onMessage(MessageTracker message, MessageContext ctx) { IThreadListener thread = (IThreadListener) Minecraft.getMinecraft(); thread.addScheduledTask( ()->{ - ( (TrackerClient)PracticalitiesMod.proxy.trackerClient ).trackPacket(message.key, message.value); + TrackerManager.client.trackPacket(message.key, message.value); }); return null; } From 656b6568c0154ce1e035eabde7d6726af7fddb12 Mon Sep 17 00:00:00 2001 From: Pierce Corcoran Date: Tue, 19 Jan 2016 15:32:53 -0800 Subject: [PATCH 5/5] Get lasers working, kinda. I still haven't implemented a receiver yet. :P --- .../practicalities/PracticalitiesMod.java | 2 + src/main/java/practicalities/ProxyClient.java | 16 +- .../practicalities/blocks/BlockLaser.java | 133 ++++++----- .../blocks/BlockLaserReciver.java | 31 +++ .../java/practicalities/blocks/TileLaser.java | 208 ++++++++++++++++-- .../client/render/LaserModel.java | 125 +++++++++++ .../client/render/RenderLaser.java | 77 ++++++- .../lib/client/RenderUtils.java | 15 ++ .../java/practicalities/lib/util/Util.java | 20 ++ .../lib/util/math/MathHelper.java | 59 +++++ .../lib/util/track/TrackerClient.java | 11 +- .../lib/util/track/TrackerManager.java | 9 +- .../lib/util/track/TrackerServer.java | 2 +- .../practicalities/lib/util/vec/Vector3.java | 4 + .../practicalities/network/NetHandler.java | 4 + .../network/message/MessageSyncLasers.java | 98 +++++++++ .../network/{ => message}/MessageTracker.java | 2 +- .../practicalities/blockstates/laser.json | 43 ++++ .../practicalities/models/block/crystal.mtl | 11 + .../practicalities/models/block/crystal.obj | 177 +++++++++++++++ .../practicalities/models/block/other.json | 7 + .../textures/blocks/crystal/crystal.png | Bin 0 -> 593 bytes .../textures/blocks/crystal/off.png | Bin 0 -> 556 bytes .../textures/blocks/crystal/on.png | Bin 0 -> 553 bytes .../textures/blocks/crystal_square.png | Bin 0 -> 556 bytes .../practicalities/textures/misc/laser.png | Bin 0 -> 185 bytes 26 files changed, 969 insertions(+), 85 deletions(-) create mode 100644 src/main/java/practicalities/blocks/BlockLaserReciver.java create mode 100644 src/main/java/practicalities/client/render/LaserModel.java create mode 100644 src/main/java/practicalities/lib/client/RenderUtils.java create mode 100644 src/main/java/practicalities/lib/util/Util.java create mode 100644 src/main/java/practicalities/network/message/MessageSyncLasers.java rename src/main/java/practicalities/network/{ => message}/MessageTracker.java (97%) create mode 100644 src/main/resources/assets/practicalities/blockstates/laser.json create mode 100644 src/main/resources/assets/practicalities/models/block/crystal.mtl create mode 100644 src/main/resources/assets/practicalities/models/block/crystal.obj create mode 100644 src/main/resources/assets/practicalities/models/block/other.json create mode 100644 src/main/resources/assets/practicalities/textures/blocks/crystal/crystal.png create mode 100644 src/main/resources/assets/practicalities/textures/blocks/crystal/off.png create mode 100644 src/main/resources/assets/practicalities/textures/blocks/crystal/on.png create mode 100644 src/main/resources/assets/practicalities/textures/blocks/crystal_square.png create mode 100644 src/main/resources/assets/practicalities/textures/misc/laser.png diff --git a/src/main/java/practicalities/PracticalitiesMod.java b/src/main/java/practicalities/PracticalitiesMod.java index 823d2d1..e1ad205 100755 --- a/src/main/java/practicalities/PracticalitiesMod.java +++ b/src/main/java/practicalities/PracticalitiesMod.java @@ -13,6 +13,7 @@ import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import practicalities.lib.util.track.TrackerManager; import practicalities.network.NetHandler; import practicalities.registers.GuiHandler; import practicalities.registers.ItemRegister; @@ -36,6 +37,7 @@ public class PracticalitiesMod { @EventHandler public void preInit(FMLPreInitializationEvent event) { ConfigMan.init(new Configuration(event.getSuggestedConfigurationFile())); + TrackerManager.init(); proxy.preInit(); NetHandler.init(); } diff --git a/src/main/java/practicalities/ProxyClient.java b/src/main/java/practicalities/ProxyClient.java index 4093122..8b9d956 100755 --- a/src/main/java/practicalities/ProxyClient.java +++ b/src/main/java/practicalities/ProxyClient.java @@ -9,12 +9,10 @@ import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StringTranslate; -import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.client.event.ModelBakeEvent; +import net.minecraftforge.client.model.obj.OBJLoader; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; import practicalities.lib.util.AdvancedLangLoader; -import practicalities.lib.util.track.Tracker; -import practicalities.lib.util.track.TrackerClient; import practicalities.registers.BlockRegister; import practicalities.registers.GuideRegister; import practicalities.registers.ItemRegister; @@ -42,9 +40,19 @@ public void init() { @Override public void registerRenders() { + OBJLoader.instance.addDomain(PracticalitiesMod.MODID); ItemRegister.registerRenders(); BlockRegister.registerRenders(); } + +// @SubscribeEvent +// public void onModelBakeEvent(ModelBakeEvent event) { +// Object object = event.modelRegistry.getObject(LaserModel.resourceLocation); +// if (object != null) { +// ExampleISBM customModel = new ExampleISBM(); +// event.modelRegistry.putObject(ExampleISBM.modelResourceLocation, customModel); +// } +// } @Override public void onResourceManagerReload(IResourceManager resourceManager) { diff --git a/src/main/java/practicalities/blocks/BlockLaser.java b/src/main/java/practicalities/blocks/BlockLaser.java index c1a4fc2..fdc4026 100644 --- a/src/main/java/practicalities/blocks/BlockLaser.java +++ b/src/main/java/practicalities/blocks/BlockLaser.java @@ -8,21 +8,23 @@ import net.minecraft.block.state.BlockState; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; -import net.minecraft.util.MathHelper; +import net.minecraft.util.EnumWorldBlockLayer; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import practicalities.Logger; -import practicalities.machines.shippingcrate.TileShippingCrate; +import practicalities.lib.util.Util; public class BlockLaser extends BlockBase implements ITileEntityProvider, ILaserReciver { public static final PropertyDirection FACING = PropertyDirection.create("facing"); -// public static final PropertyBool POWERED = PropertyBool.create("powered"); + public static final PropertyDirection ATTACHED = PropertyDirection.create("attached"); + public static final PropertyBool POWERED = PropertyBool.create("powered"); public BlockLaser() { super(Material.glass, "laser"); @@ -30,7 +32,7 @@ public BlockLaser() { @Override protected BlockState createBlockState() { - return new BlockState(this, FACING); + return new BlockState(this, POWERED, FACING, ATTACHED); } @SideOnly(Side.CLIENT) @@ -46,16 +48,16 @@ public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { @Override public void onNeighborBlockChange(World worldIn, BlockPos pos, IBlockState state, Block neighborBlock) { -// if(worldIn.isRemote) -// return; + if(worldIn.isRemote) + return; updateLaser(worldIn, pos); } @Override public void laserHit(World world, BlockPos pos, EnumFacing sideHit, BlockPos laserPos, boolean powered) { -// if(world.isRemote) -// return; + if(world.isRemote) + return; TileLaser tile = (TileLaser) world.getTileEntity(pos); tile.laserHit(powered); @@ -64,75 +66,104 @@ public void laserHit(World world, BlockPos pos, EnumFacing sideHit, BlockPos las } public void updateLaser(World world, BlockPos pos) { -// IBlockState state = world.getBlockState(pos); - TileLaser tile = (TileLaser) world.getTileEntity(pos); boolean wasPowered = tile.powered; boolean isPowered = world.isBlockPowered(pos) || tile.isPoweredByLaser(); if(wasPowered != isPowered) { -// IBlockState newState = state.withProperty(POWERED, isPowered); tile.updatePower(isPowered); -// if(!world.isRemote) -// world.setBlockState(pos, newState); + world.setBlockState(pos, world.getBlockState(pos).withProperty(POWERED, isPowered)); } } + @Override + public boolean canConnectRedstone(IBlockAccess world, BlockPos pos, EnumFacing side) { + return false; + } + @Override public boolean hasTileEntity() { return true; } - + + @Override + public EnumWorldBlockLayer getBlockLayer() { + return EnumWorldBlockLayer.TRANSLUCENT; + } @Override public TileEntity createNewTileEntity(World worldIn, int meta) { return new TileLaser(); } + @Override + public boolean isOpaqueCube() { + return false; + } + // DIRECTIONAL PLACING + @Override + public IBlockState onBlockPlaced(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, + int meta, EntityLivingBase placer) { + return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, meta, placer).withProperty(ATTACHED, facing.getOpposite()); + } + + @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { - worldIn.setBlockState(pos, state.withProperty(FACING, getFacingFromEntity(worldIn, pos, placer)), 2); - } + TileLaser laser = (TileLaser) worldIn.getTileEntity(pos); + + laser.attached = state.getValue(ATTACHED); + laser.facing = placer.getHorizontalFacing().getOpposite(); + + updateLaser(worldIn, pos); + super.onBlockPlacedBy(worldIn, pos, state, placer, stack); + } - public static EnumFacing getFacingFromEntity(World worldIn, BlockPos clickedBlock, EntityLivingBase entityIn) { - if (MathHelper.abs((float)entityIn.posX - (float)clickedBlock.getX()) < 2.0F && MathHelper.abs((float)entityIn.posZ - (float)clickedBlock.getZ()) < 2.0F) - { - double d0 = entityIn.posY + (double)entityIn.getEyeHeight(); - - if (d0 - (double)clickedBlock.getY() > 2.0D) - { - return EnumFacing.UP; - } + @Override + public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, + EnumFacing side, float hitX, float hitY, float hitZ) { + boolean somethingHappened = false; + + if(Util.isHoldingWrench(playerIn)) { + somethingHappened = true; + TileLaser te = (TileLaser)worldIn.getTileEntity(pos); + if(te.facing == te.attached.getOpposite()) { + te.facing = side; + } else { + te.facing = te.attached.getOpposite(); + } + } + + return somethingHappened; + } + + @Override + public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos) { + TileLaser laser = (TileLaser) worldIn.getTileEntity(pos); + + state = state.withProperty(FACING, laser.facing); + state = state.withProperty(ATTACHED, laser.attached); + return state; + } + + @Override + public int getMetaFromState(IBlockState state) { + int i = 0; + i = i | ((EnumFacing)state.getValue(ATTACHED)).getIndex(); - if ((double)clickedBlock.getY() - d0 > 0.0D) - { - return EnumFacing.DOWN; - } + if (((Boolean)state.getValue(POWERED)).booleanValue()) + { + i |= 8; } - return entityIn.getHorizontalFacing().getOpposite(); - } - - public IBlockState getStateFromMeta(int meta) { - return this.getDefaultState().withProperty(FACING, getFacing(meta).getOpposite());//.withProperty(POWERED, Boolean.valueOf((meta & 8) > 0)); - } - - public static EnumFacing getFacing(int meta) { - int i = meta & 7; - return i > 5 ? null : EnumFacing.getFront(i); - } - - public int getMetaFromState(IBlockState state) { - int i = 0; - i = i | ((EnumFacing)state.getValue(FACING)).getIndex(); - -// if (((Boolean)state.getValue(POWERED)).booleanValue()) -// { -// i |= 8; -// } - return i; } + + + @Override + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(ATTACHED, EnumFacing.VALUES[meta & 7]).withProperty(POWERED, Boolean.valueOf((meta & 8) > 0)); + } } diff --git a/src/main/java/practicalities/blocks/BlockLaserReciver.java b/src/main/java/practicalities/blocks/BlockLaserReciver.java new file mode 100644 index 0000000..11c04a0 --- /dev/null +++ b/src/main/java/practicalities/blocks/BlockLaserReciver.java @@ -0,0 +1,31 @@ +package practicalities.blocks; + +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.state.BlockState; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; + +public class BlockLaserReciver extends BlockBase implements ILaserReciver { + + public static final PropertyDirection ATTACHED = PropertyDirection.create("attached"); + public static final PropertyBool POWERED = PropertyBool.create("powered"); + + public BlockLaserReciver() { + super(Material.glass, "laserReciver"); + } + + @Override + protected BlockState createBlockState() { + return new BlockState(this, POWERED, ATTACHED); + } + + @Override + public void laserHit(World world, BlockPos pos, EnumFacing sideHit, BlockPos laserPos, boolean powered) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/practicalities/blocks/TileLaser.java b/src/main/java/practicalities/blocks/TileLaser.java index ce2a99f..f7dd227 100644 --- a/src/main/java/practicalities/blocks/TileLaser.java +++ b/src/main/java/practicalities/blocks/TileLaser.java @@ -5,40 +5,68 @@ import java.util.List; import java.util.function.Consumer; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.world.World; +import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint; import net.minecraftforge.fml.common.registry.GameRegistry; import practicalities.Logger; import practicalities.lib.util.WorldTraceUtil; import practicalities.lib.util.vec.Vector3; +import practicalities.network.NetHandler; +import practicalities.network.message.MessageSyncLasers; public class TileLaser extends TileEntity implements ITickable { int hitCounter = 0; + public EnumFacing facing = EnumFacing.UP, attached = EnumFacing.DOWN; + List oldLasers = new ArrayList<>(); Laser currentLaser = null; public boolean powered = false; public static class Laser { - public double start, end; - public EnumFacing direction; + public double start, end, lastStart, lastEnd; - public BlockPos moveEnd(World w, Vector3 origin, double speed) { - Vector3 endVec = origin.copy().add(new Vector3(this.direction, this.end)); - double amountToMove = WorldTraceUtil.rayHitDistance(w, endVec, speed, this.direction); + public BlockPos moveEnd(World w, Vector3 origin, double speed, EnumFacing direction) { + Vector3 endVec = origin.copy().add(new Vector3(direction, this.end)); + double amountToMove = WorldTraceUtil.rayHitDistance(w, endVec, speed, direction); end += amountToMove; if(amountToMove != speed) { - endVec = origin.copy().add(new Vector3(this.direction, this.end)).floor(); + endVec = origin.copy().add(new Vector3(direction, this.end)).floor(); return new BlockPos(endVec.vec3()); } return null; } + + public NBTTagCompound tag() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setDouble(START_TAG, start); + tag.setDouble(END_TAG, end); + return tag; + } + + public static Laser fromTag(NBTTagCompound tag) { + Laser laser = new Laser(); + laser.start = tag.getDouble(START_TAG); + laser.end = tag.getDouble(END_TAG); + return laser; + } + + public static final String START_TAG = "s", END_TAG = "e"; } public void eachLaser(Consumer r) { @@ -47,14 +75,17 @@ public void eachLaser(Consumer r) { } public void updatePower(boolean powered) { + if(powered == this.powered) + return; + if(powered) { currentLaser = new Laser(); - currentLaser.direction = worldObj.getBlockState(pos).getValue(BlockLaser.FACING); } else { oldLasers.add(currentLaser); currentLaser = null; } this.powered = powered; + sync(); } public void laserHit(boolean power) { @@ -63,6 +94,9 @@ public void laserHit(boolean power) { } else { hitCounter--; } + if(hitCounter > 1) + Logger.track("HIT - " + pos, "%d", hitCounter); + sync(); } public boolean isPoweredByLaser() { @@ -70,10 +104,20 @@ public boolean isPoweredByLaser() { } public void onBreak() { - + if(currentLaser != null) + handleHit(currentLaser, false); + for (Laser laser : oldLasers) { + if(laser != null) { + handleHit(laser, false); + } + } } boolean firstTick = true; + public static final double RANGE = 32; + public static final int RESYNC_INTERVAL = 3*(20); // resyncs lasers every three seconds + public static double SPEED = 1; + int reSyncTimer = RESYNC_INTERVAL; @Override public void update() { @@ -82,32 +126,168 @@ public void update() { firstTick = false; } - Vector3 origin = Vector3.fromTileCenter(this); + SPEED = 2; - double speed = .1; + IBlockState state = worldObj.getBlockState(pos); + if(!( state.getBlock() instanceof BlockLaser)) + return; + Vector3 origin = Vector3.fromTileCenter(this); + + double d = 0.0; if(currentLaser != null) { - currentLaser.end += WorldTraceUtil.rayHitDistance(worldObj, origin.copy().add(new Vector3(currentLaser.direction, currentLaser.end)), speed, currentLaser.direction); + if( currentLaser.end > RANGE ) { + currentLaser.end = RANGE; + currentLaser.lastEnd = RANGE; + } else if( currentLaser.end < RANGE ) { + double dist = WorldTraceUtil.rayHitDistance(worldObj, origin.copy().add(new Vector3(facing, currentLaser.end-d)), SPEED+d, facing)-d; + currentLaser.lastEnd = currentLaser.end; + currentLaser.end += dist; + if(dist != SPEED && dist != 0) { + handleHit(currentLaser, true); + } + } + } for (Laser laser : oldLasers) { - laser.start += speed; - laser.end += WorldTraceUtil.rayHitDistance(worldObj, origin.copy().add(new Vector3(laser.direction, laser.end)), speed, laser.direction); + if(laser == null) continue; // shouldn't happen, but just in case. + laser.lastStart = laser.start; + laser.start += SPEED; + if( laser.end > RANGE ) { + laser.end = RANGE; + laser.lastEnd = RANGE; + } else if( laser.end < RANGE ) { + double dist = WorldTraceUtil.rayHitDistance(worldObj, origin.copy().add(new Vector3(facing, laser.end-d)), SPEED+d, facing)-d; + laser.lastEnd = laser.end; + laser.end += dist; + if(dist != SPEED && dist != 0) { + handleHit(laser, true); + } + } } + if(currentLaser != null && currentLaser.start >= currentLaser.end) { + handleHit(currentLaser, false); + currentLaser = null; + } for (Iterator iterator = oldLasers.iterator(); iterator.hasNext();) { Laser laser = iterator.next(); - if (laser.start >= laser.end) { + if (laser == null || laser.start >= laser.end) { + if(laser != null) handleHit(laser, false); iterator.remove(); } } + if(reSyncTimer == 0) { + sync(); + } + reSyncTimer--; + + } + + public void handleHit(Laser laser, boolean power) { + Vector3 hit = Vector3.fromTileCenter(this).add(new Vector3(facing, laser.end+0.1)).floor(); + + Block hitBlock = worldObj.getBlockState(hit.blockPos()).getBlock(); + if(hitBlock instanceof ILaserReciver) { + ( (ILaserReciver) hitBlock).laserHit(worldObj, hit.blockPos(), facing.getOpposite(), pos, power); + } + } + + public void sync() { + reSyncTimer = RESYNC_INTERVAL; + NetHandler.network.sendToAllAround(new MessageSyncLasers(pos, currentLaser, oldLasers), + new TargetPoint(this.worldObj.provider.getDimensionId(), pos.getX(), pos.getY(), pos.getZ(), RANGE+16)); + } + + public void syncFrom(MessageSyncLasers packet) { + this.currentLaser = packet.current; + this.oldLasers = new ArrayList<>(packet.old); + } + + AxisAlignedBB renderBox = AxisAlignedBB.fromBounds( + -RANGE, -RANGE, -RANGE, + RANGE, RANGE, RANGE); + + @Override + public AxisAlignedBB getRenderBoundingBox() { + return renderBox.offset(pos.getX(), pos.getY(), pos.getZ());//new AxisAlignedBB(pos, pos.add(1, 1, 1)).expand(RANGE, RANGE, RANGE); + } + + @Override + public double getMaxRenderDistanceSquared() { + return (RANGE*3)*(RANGE*3); } public static void initialize() { Logger.info(" Registering Laser"); GameRegistry.registerTileEntity(TileLaser.class, "p2.laser"); } + + @Override + public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) { + return false; + } + + @Override + public void writeToNBT(NBTTagCompound compound) { + if(currentLaser != null){ + compound.setTag(CURRENT_TAG, currentLaser.tag()); + } + + compound.setInteger(FACING_TAG, facing.ordinal()); + compound.setInteger(ATTACHED_TAG, attached.ordinal()); + + compound.setInteger(HITS_TAG, hitCounter); + + if(oldLasers.size() != 0) { + NBTTagList list = new NBTTagList(); + for (Laser laser : oldLasers) { + if(laser == null) continue; // don't know why this would happen, but if it does. + list.appendTag(laser.tag()); + } + compound.setTag(OLD_TAG, list); + } + super.writeToNBT(compound); + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound tag = new NBTTagCompound(); + tag.setInteger(FACING_TAG, facing.ordinal()); + return new S35PacketUpdateTileEntity(pos, 0, tag); + } + + @Override + public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) { + facing = EnumFacing.VALUES[pkt.getNbtCompound().getInteger(FACING_TAG)]; + super.onDataPacket(net, pkt); + } + + @Override + public void readFromNBT(NBTTagCompound compound) { + currentLaser = null; + oldLasers.clear(); + + if(compound.hasKey(CURRENT_TAG)) { + currentLaser = Laser.fromTag(compound.getCompoundTag(CURRENT_TAG)); + } + + facing = EnumFacing.VALUES[compound.getInteger(FACING_TAG)]; + attached = EnumFacing.VALUES[compound.getInteger(ATTACHED_TAG)]; + hitCounter = compound.getInteger(HITS_TAG); + + if(compound.hasKey(OLD_TAG)) { + NBTTagList list = compound.getTagList(OLD_TAG, 10); + for (int i = 0; i < list.tagCount(); i++) { + oldLasers.add( Laser.fromTag(list.getCompoundTagAt(i)) ); + } + } + super.readFromNBT(compound); + } + + public static final String CURRENT_TAG = "c", OLD_TAG = "o", FACING_TAG = "f", ATTACHED_TAG = "a", HITS_TAG = "h"; } diff --git a/src/main/java/practicalities/client/render/LaserModel.java b/src/main/java/practicalities/client/render/LaserModel.java new file mode 100644 index 0000000..f6c4270 --- /dev/null +++ b/src/main/java/practicalities/client/render/LaserModel.java @@ -0,0 +1,125 @@ +package practicalities.client.render; + +import java.util.List; + +import javax.vecmath.Matrix4f; + +import org.apache.commons.lang3.tuple.Pair; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.IFlexibleBakedModel; +import net.minecraftforge.client.model.IPerspectiveAwareModel; +import net.minecraftforge.client.model.ISmartBlockModel; +import net.minecraftforge.client.model.ISmartItemModel; + +@SuppressWarnings("deprecation") +public class LaserModel implements IFlexibleBakedModel, ISmartBlockModel, ISmartItemModel, IPerspectiveAwareModel { + + public static final ResourceLocation modelResourceLocation = new ResourceLocation("practicalities:crystal.obj"); + + Object m; + + public LaserModel(Object existingModel) { + this.m = existingModel; + } + + @Override + public List getFaceQuads(EnumFacing p_177551_1_) { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).getFaceQuads(p_177551_1_); + } + return null; + } + + @Override + public List getGeneralQuads() { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).getGeneralQuads(); + } + return null; + } + + @Override + public boolean isAmbientOcclusion() { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).isAmbientOcclusion(); + } + return false; + } + + @Override + public boolean isGui3d() { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).isGui3d(); + } + return false; + } + + @Override + public boolean isBuiltInRenderer() { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).isBuiltInRenderer(); + } + return false; + } + + @Override + public TextureAtlasSprite getParticleTexture() { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).getParticleTexture(); + } + return null; + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() { + if(m instanceof IBakedModel) { + return ((IBakedModel) m).getItemCameraTransforms(); + } + return null; + } + + // ISMARTBLOCKMODEL + + @Override + public IBakedModel handleBlockState(IBlockState state) { + if(m instanceof ISmartBlockModel) { + return ((ISmartBlockModel) m).handleBlockState(state); + } + return null; + } + + @Override + public Pair handlePerspective(TransformType cameraTransformType) { + if(m instanceof IPerspectiveAwareModel) { + return ((IPerspectiveAwareModel) m).handlePerspective(cameraTransformType); + } + return null; + } + + @Override + public IBakedModel handleItemState(ItemStack stack) { + if(m instanceof ISmartItemModel) { + return ((ISmartItemModel) m).handleItemState(stack); + } + return null; + } + + @Override + public VertexFormat getFormat() { + if(m instanceof IFlexibleBakedModel) { + return ((IFlexibleBakedModel) m).getFormat(); + } + return null; + } + +} diff --git a/src/main/java/practicalities/client/render/RenderLaser.java b/src/main/java/practicalities/client/render/RenderLaser.java index eb9f845..a6f64f7 100644 --- a/src/main/java/practicalities/client/render/RenderLaser.java +++ b/src/main/java/practicalities/client/render/RenderLaser.java @@ -2,38 +2,93 @@ import org.lwjgl.opengl.GL11; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import practicalities.Logger; +import net.minecraft.client.resources.model.IBakedModel; +import net.minecraft.init.Blocks; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumFacing.Axis; +import net.minecraft.util.ResourceLocation; +import practicalities.PracticalitiesMod; import practicalities.blocks.TileLaser; +import practicalities.lib.client.RenderUtils; import practicalities.lib.util.vec.Vector3; public class RenderLaser extends TileEntitySpecialRenderer { + private final ResourceLocation laserTexture = new ResourceLocation(PracticalitiesMod.MODID, "textures/misc/laser.png"); + @Override public void renderTileEntityAt(TileLaser te, double x, double y, double z, float partialTicks, int destroyStage) { Tessellator t = Tessellator.getInstance(); WorldRenderer r = t.getWorldRenderer(); - r.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_COLOR); + GlStateManager.pushMatrix(); + GlStateManager.translate(x, y, z); + + GlStateManager.enableBlend(); + GlStateManager.disableLighting(); + + GlStateManager.resetColor(); + GL11.glColor3f(1, 1, 1); + + Minecraft.getMinecraft().getTextureManager().bindTexture(laserTexture); + + RenderUtils.setBrightnessByBlockLight(15); + + GlStateManager.color(1, 1, 1, 1); + GlStateManager.disableCull(); + r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + r.noColor(); - Vector3 origin = Vector3.fromTile(te); + EnumFacing direction = te.facing; + Vector3 origin = Vector3.center; - te.eachLaser( (TileLaser.Laser l) -> renderLaser(l, origin) ); // why? BECAUSE I CAN!!! 1.8 baby! + te.eachLaser( (TileLaser.Laser l) -> renderLaser(l, origin, direction, partialTicks) ); // why? BECAUSE I CAN!!! Java 8 baby! - t.draw(); + t.draw(); + + GlStateManager.enableCull(); + GlStateManager.disableBlend(); + GlStateManager.enableLighting(); + + GlStateManager.popMatrix(); } - public void renderLaser(TileLaser.Laser laser, Vector3 origin) { + public void renderLaser(TileLaser.Laser laser, Vector3 origin, EnumFacing direction, float partialTicks) { WorldRenderer r = Tessellator.getInstance().getWorldRenderer(); - Vector3 start = origin.copy().add(laser.direction, laser.start); - Vector3 end = origin.copy().add(laser.direction, laser.end); - + Vector3 start = origin.copy().add(direction, laser.lastStart + ( (laser.start - laser.lastStart)*partialTicks ) ); + Vector3 end = origin.copy().add(direction, laser.lastEnd + ( (laser.end - laser.lastEnd)*partialTicks ) ); + + double d = 1F/8F; + + if(direction.getAxis() != Axis.Y) { + r.pos(start.x, start.y-d, start.z).tex(1, 1).endVertex(); + r.pos(start.x, start.y+d, start.z).tex(1, 0).endVertex(); + r.pos(end.x, end.y+d, end.z) .tex(0, 0).endVertex(); + r.pos(end.x, end.y-d, end.z) .tex(0, 1).endVertex(); + } + + if(direction.getAxis() != Axis.Z) { + r.pos(start.x, start.y, start.z-d).tex(1, 1).endVertex(); + r.pos(start.x, start.y, start.z+d).tex(1, 0).endVertex(); + r.pos(end.x, end.y, end.z+d) .tex(0, 0).endVertex(); + r.pos(end.x, end.y, end.z-d) .tex(0, 1).endVertex(); + } - r.pos(start.x, start.y, start.z).color(1, 0, 0, 1); - r.pos(end.x, end.y, end.z) .color(1, 0, 0, 1); + if(direction.getAxis() != Axis.X) { + r.pos(start.x-d, start.y, start.z).tex(1, 1).endVertex(); + r.pos(start.x+d, start.y, start.z).tex(1, 0).endVertex(); + r.pos(end.x+d, end.y, end.z) .tex(0, 0).endVertex(); + r.pos(end.x-d, end.y, end.z) .tex(0, 1).endVertex(); + } } } diff --git a/src/main/java/practicalities/lib/client/RenderUtils.java b/src/main/java/practicalities/lib/client/RenderUtils.java new file mode 100644 index 0000000..bd6c21e --- /dev/null +++ b/src/main/java/practicalities/lib/client/RenderUtils.java @@ -0,0 +1,15 @@ +package practicalities.lib.client; + +import net.minecraft.client.renderer.OpenGlHelper; + +public class RenderUtils { + + public static void setBrightnessByBlockLight(int lightValue) { + int i = lightValue << 20 | lightValue << 4; + int j = i % 65536; + int k = i / 65536; + + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, j/1.0F, k/1.0F); + } + +} diff --git a/src/main/java/practicalities/lib/util/Util.java b/src/main/java/practicalities/lib/util/Util.java new file mode 100644 index 0000000..a1eb028 --- /dev/null +++ b/src/main/java/practicalities/lib/util/Util.java @@ -0,0 +1,20 @@ +package practicalities.lib.util; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +public class Util { + + public static boolean isWrench(ItemStack stack) { + return stack != null && stack.getItem() == Items.stick; + } + + public static boolean isHoldingWrench(EntityLivingBase entity) { + if(entity != null && isWrench( entity.getHeldItem() )) { + return true; + } + return false; + } + +} diff --git a/src/main/java/practicalities/lib/util/math/MathHelper.java b/src/main/java/practicalities/lib/util/math/MathHelper.java index 2942ec5..18b7243 100644 --- a/src/main/java/practicalities/lib/util/math/MathHelper.java +++ b/src/main/java/practicalities/lib/util/math/MathHelper.java @@ -178,4 +178,63 @@ public static int compare(double a, double b) { return a == b ? 0 : a < b ? -1 : 1; } + + public static float shortToFloat( short value ) + { + + int mant = value & 0x03ff; // 10 bits mantissa + int exp = value & 0x7c00; // 5 bits exponent + if( exp == 0x7c00 ) // NaN/Inf + exp = 0x3fc00; // -> NaN/Inf + else if( exp != 0 ) // normalized value + { + exp += 0x1c000; // exp - 15 + 127 + if( mant == 0 && exp > 0x1c400 ) // smooth transition + return Float.intBitsToFloat( ( value & 0x8000 ) << 16 + | exp << 13 | 0x3ff ); + } + else if( mant != 0 ) // && exp==0 -> subnormal + { + exp = 0x1c400; // make it normal + do { + mant <<= 1; // mantissa * 2 + exp -= 0x400; // decrease exp by 1 + } while( ( mant & 0x400 ) == 0 ); // while not normal + mant &= 0x3ff; // discard subnormal bit + } // else +/-0 -> +/-0 + return Float.intBitsToFloat( // combine all parts + ( value & 0x8000 ) << 16 // sign << ( 31 - 15 ) + | ( exp | mant ) << 13 ); // value << ( 23 - 10 ) + } + + public static short floatToShort( float value ) { + return (short) fromFloat_internal(value); + } + + private static int fromFloat_internal( float fval ) + { + int fbits = Float.floatToIntBits( fval ); + int sign = fbits >>> 16 & 0x8000; // sign only + int val = ( fbits & 0x7fffffff ) + 0x1000; // rounded value + + if( val >= 0x47800000 ) // might be or become NaN/Inf + { // avoid Inf due to rounding + if( ( fbits & 0x7fffffff ) >= 0x47800000 ) + { // is or must become NaN/Inf + if( val < 0x7f800000 ) // was value but too large + return sign | 0x7c00; // make it +/-Inf + return sign | 0x7c00 | // remains +/-Inf or NaN + ( fbits & 0x007fffff ) >>> 13; // keep NaN (and Inf) bits + } + return sign | 0x7bff; // unrounded not quite Inf + } + if( val >= 0x38800000 ) // remains normalized value + return sign | val - 0x38000000 >>> 13; // exp - 127 + 15 + if( val < 0x33000000 ) // too small for subnormal + return sign; // becomes +/-0 + val = ( fbits & 0x7fffffff ) >>> 23; // tmp exp for subnormal calc + return sign | ( ( fbits & 0x7fffff | 0x800000 ) // add subnormal bit + + ( 0x800000 >>> val - 102 ) // round depending on cut off + >>> 126 - val ); // div by 2^(1-(exp-127+15)) and >> 13 | exp=0 + } } diff --git a/src/main/java/practicalities/lib/util/track/TrackerClient.java b/src/main/java/practicalities/lib/util/track/TrackerClient.java index 8a0d083..80be3e8 100644 --- a/src/main/java/practicalities/lib/util/track/TrackerClient.java +++ b/src/main/java/practicalities/lib/util/track/TrackerClient.java @@ -51,9 +51,18 @@ public void onDebugText(RenderGameOverlayEvent.Text event) { keys.addAll(tracks.keySet()); keys.addAll(packetTracks.keySet()); + if(keys.size() == 0) + return; + event.left.add("KEY: §4SERVER §9CLIENT"); for(String key : keys) { - event.left.add(key + ": §4" + packetTracks.get(key) + " §9" + tracks.get(key)); + String server = packetTracks.get(key); + String client = tracks.get(key); + + boolean equal = server == null ? client.equals(server) : server.equals(client); + String sep = equal ? " " : "§d!!"; + + event.left.add(" " + key + ":" + sep + "§4" + server + " §9" + client); } } } diff --git a/src/main/java/practicalities/lib/util/track/TrackerManager.java b/src/main/java/practicalities/lib/util/track/TrackerManager.java index 2e76bf3..162a1df 100644 --- a/src/main/java/practicalities/lib/util/track/TrackerManager.java +++ b/src/main/java/practicalities/lib/util/track/TrackerManager.java @@ -11,12 +11,17 @@ public class TrackerManager { public static TrackerServer server; public static TrackerClient client; - public void init() { + private static TrackerManager instance; + + public static void init() { if(ConfigMan.isDev) { + if(instance == null) + instance = new TrackerManager(); + server = new TrackerServer(); client = new TrackerClient(); - MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.EVENT_BUS.register(instance); MinecraftForge.EVENT_BUS.register(client); } } diff --git a/src/main/java/practicalities/lib/util/track/TrackerServer.java b/src/main/java/practicalities/lib/util/track/TrackerServer.java index d487b85..b545c07 100644 --- a/src/main/java/practicalities/lib/util/track/TrackerServer.java +++ b/src/main/java/practicalities/lib/util/track/TrackerServer.java @@ -3,8 +3,8 @@ import java.util.HashMap; import java.util.Map; -import practicalities.network.MessageTracker; import practicalities.network.NetHandler; +import practicalities.network.message.MessageTracker; public class TrackerServer extends Tracker { diff --git a/src/main/java/practicalities/lib/util/vec/Vector3.java b/src/main/java/practicalities/lib/util/vec/Vector3.java index 673d4c4..d3e1502 100644 --- a/src/main/java/practicalities/lib/util/vec/Vector3.java +++ b/src/main/java/practicalities/lib/util/vec/Vector3.java @@ -323,6 +323,10 @@ public Vec3 vec3() { return new Vec3(x, y, z); } + public BlockPos blockPos() { + return new BlockPos(x, y, z); + } + public double angle(Vector3 vec) { return Math.acos(copy().normalize().dotProduct(vec.copy().normalize())); } diff --git a/src/main/java/practicalities/network/NetHandler.java b/src/main/java/practicalities/network/NetHandler.java index 140c88f..988d5f4 100644 --- a/src/main/java/practicalities/network/NetHandler.java +++ b/src/main/java/practicalities/network/NetHandler.java @@ -3,14 +3,18 @@ import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; import net.minecraftforge.fml.relauncher.Side; import practicalities.ConfigMan; +import practicalities.network.message.MessageSyncLasers; +import practicalities.network.message.MessageTracker; public class NetHandler { public static SimpleNetworkWrapper network; public static void init() { + int i = 0; network = new SimpleNetworkWrapper("Practicalities"); if(ConfigMan.isDev) { network.registerMessage(MessageTracker.class, MessageTracker.class, 200, Side.CLIENT); } + network.registerMessage(MessageSyncLasers.class, MessageSyncLasers.class, i++, Side.CLIENT); } } diff --git a/src/main/java/practicalities/network/message/MessageSyncLasers.java b/src/main/java/practicalities/network/message/MessageSyncLasers.java new file mode 100644 index 0000000..b0da39f --- /dev/null +++ b/src/main/java/practicalities/network/message/MessageSyncLasers.java @@ -0,0 +1,98 @@ +package practicalities.network.message; + +import java.util.ArrayList; +import java.util.List; + +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockPos; +import net.minecraft.util.IThreadListener; +import net.minecraft.world.World; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import practicalities.blocks.TileLaser; +import practicalities.blocks.TileLaser.Laser; +import practicalities.lib.util.math.MathHelper; + +public class MessageSyncLasers implements IMessage, IMessageHandler{ + + BlockPos pos; + public Laser current; + public List old; + + public MessageSyncLasers() {} + + public MessageSyncLasers(BlockPos pos, Laser current, List old) { + this.pos = pos; + this.current = current; + this.old = old; + } + + @Override + public IMessage onMessage(MessageSyncLasers message, MessageContext ctx) { + IThreadListener thread = (IThreadListener) Minecraft.getMinecraft(); + thread.addScheduledTask( ()->{ + + World world = Minecraft.getMinecraft().theWorld; + TileEntity te = world.getTileEntity(message.pos); + if(te != null && te instanceof TileLaser) { // in case for some reason we get a packet for a world other than theWorld + TileLaser tileLaser = (TileLaser) te; + tileLaser.syncFrom(message); + } + + }); + return null; + } + + @Override + public void fromBytes(ByteBuf buf) { + old = new ArrayList<>(); + + pos = BlockPos.fromLong(buf.readLong()); + boolean hasCurrent = buf.readBoolean(); + if(hasCurrent) { + current = decodeLaser(buf); + } + int count = buf.readByte(); + for (int i = 0; i < count; i++) { + old.add(decodeLaser(buf)); + } + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeLong(pos.toLong()); + buf.writeBoolean(current != null); + if(current != null) { + encodeLaser(current, buf); + } + int size = old.size(); + for (Laser laser : old) { + if(laser == null) size--; + } + buf.writeByte(size); + for (Laser laser : old) { + if(laser == null) continue; + encodeLaser(laser, buf); + } + } + + public void encodeLaser(Laser laser, ByteBuf buf) { + // the client only needs an approximation, so 16 bits is enough. We don't need to send 64 bits for each. + buf.writeShort(MathHelper.floatToShort((float)laser.start)); + buf.writeShort(MathHelper.floatToShort((float)laser.end )); + } + + public Laser decodeLaser(ByteBuf buf) { + Laser laser = new Laser(); + + // the client only needs an approximation, so 16 bits is enough. We don't need to send 64 bits for each. + laser.lastStart = laser.start = MathHelper.shortToFloat(buf.readShort()); + laser.lastEnd = laser.end = MathHelper.shortToFloat(buf.readShort()); + + return laser; + } + +} diff --git a/src/main/java/practicalities/network/MessageTracker.java b/src/main/java/practicalities/network/message/MessageTracker.java similarity index 97% rename from src/main/java/practicalities/network/MessageTracker.java rename to src/main/java/practicalities/network/message/MessageTracker.java index 2b73935..ec9ab49 100644 --- a/src/main/java/practicalities/network/MessageTracker.java +++ b/src/main/java/practicalities/network/message/MessageTracker.java @@ -1,4 +1,4 @@ -package practicalities.network; +package practicalities.network.message; import io.netty.buffer.ByteBuf; import net.minecraft.client.Minecraft; diff --git a/src/main/resources/assets/practicalities/blockstates/laser.json b/src/main/resources/assets/practicalities/blockstates/laser.json new file mode 100644 index 0000000..3c735d1 --- /dev/null +++ b/src/main/resources/assets/practicalities/blockstates/laser.json @@ -0,0 +1,43 @@ +{ + "forge_marker": 1, + "defaults": { + "custom": { "flip-v": true }, + "model": "practicalities:crystal.obj", + "textures": { + "#tex": "practicalities:blocks/crystal/off" + } + }, + "variants": { + "normal": [{}], + "inventory": [{}], + + "powered": { + "true":{ + "textures": { + "#tex": "practicalities:blocks/crystal/on" + } + }, + "false":{} + }, + + "facing": { + "north": {}, + "south": {}, + "west": {}, + "east": {}, + "up": {}, + "down": {} + }, + + "attached": { + "north": {}, + "south": {"y": 180}, + "west": {"y": 270}, + "east": {"y": 90}, + "up": {"x": -90}, + "down": {"x": 90} + } + + + } +} diff --git a/src/main/resources/assets/practicalities/models/block/crystal.mtl b/src/main/resources/assets/practicalities/models/block/crystal.mtl new file mode 100644 index 0000000..01903ac --- /dev/null +++ b/src/main/resources/assets/practicalities/models/block/crystal.mtl @@ -0,0 +1,11 @@ +# Blender MTL File: 'Crystal.blend' +# Material Count: 1 + +newmtl tex +Ns 96.078431 +Ka 0.000000 0.000000 0.000000 +Kd 0.640000 0.640000 0.640000 +Ks 0.500000 0.500000 0.500000 +Ni 1.000000 +d 1.000000 +illum 2 \ No newline at end of file diff --git a/src/main/resources/assets/practicalities/models/block/crystal.obj b/src/main/resources/assets/practicalities/models/block/crystal.obj new file mode 100644 index 0000000..c849635 --- /dev/null +++ b/src/main/resources/assets/practicalities/models/block/crystal.obj @@ -0,0 +1,177 @@ +# Blender v2.73 (sub 0) OBJ File: 'Crystal.blend' +# www.blender.org +mtllib crystal.mtl +o OBJECT_Circle.002 +v 0.875000 0.500000 0.500000 +v 0.750000 0.375000 0.500000 +v 0.750000 0.437500 0.608253 +v 0.750000 0.562500 0.608253 +v 0.750000 0.625000 0.500000 +v 0.750000 0.562500 0.391747 +v 0.750000 0.437500 0.391747 +v 0.250000 0.500000 0.500000 +v 0.250000 0.375000 0.500000 +v 0.250000 0.437500 0.608253 +v 0.250000 0.562500 0.608253 +v 0.250000 0.625000 0.500000 +v 0.250000 0.562500 0.391747 +v 0.250000 0.437500 0.391747 +v 0.562500 1.000000 0.000000 +v 0.562500 0.000000 0.000000 +v 0.437500 0.000000 0.000000 +v 0.437500 1.000000 0.000000 +v 0.562500 1.000000 0.031250 +v 0.562500 0.000000 0.031250 +v 0.437500 0.000000 0.031250 +v 0.437500 1.000000 0.031250 +v 0.000000 0.562500 0.000000 +v 1.000000 0.562500 0.000000 +v 1.000000 0.437500 0.000000 +v 0.000000 0.437500 0.000000 +v 0.000000 0.562500 0.031250 +v 1.000000 0.562500 0.031250 +v 1.000000 0.437500 0.031250 +v 0.000000 0.437500 0.031250 +v 0.531250 0.531250 0.031250 +v 0.531250 0.468750 0.031250 +v 0.468750 0.468750 0.031250 +v 0.468750 0.531250 0.031250 +v 0.484375 0.515625 0.468750 +v 0.484375 0.484375 0.468750 +v 0.515625 0.484375 0.468750 +v 0.515625 0.515625 0.468750 +v 0.468750 0.437500 0.031250 +v 0.437500 0.437500 0.031250 +v 0.437500 0.468750 0.031250 +v 0.437500 0.468750 0.406250 +v 0.437500 0.437500 0.406250 +v 0.468750 0.437500 0.406250 +v 0.468750 0.468750 0.406250 +v 0.562500 0.468750 0.031250 +v 0.562500 0.437500 0.031250 +v 0.531250 0.437500 0.031250 +v 0.531250 0.468750 0.406250 +v 0.531250 0.437500 0.406250 +v 0.562500 0.437500 0.406250 +v 0.562500 0.468750 0.406250 +v 0.468750 0.562500 0.031250 +v 0.437500 0.531250 0.031250 +v 0.437500 0.562500 0.031250 +v 0.437500 0.562500 0.406250 +v 0.437500 0.531250 0.406250 +v 0.468750 0.531250 0.406250 +v 0.468750 0.562500 0.406250 +v 0.562500 0.562500 0.031250 +v 0.562500 0.531250 0.031250 +v 0.531250 0.562500 0.031250 +v 0.531250 0.562500 0.406250 +v 0.531250 0.531250 0.406250 +v 0.562500 0.531250 0.406250 +v 0.562500 0.562500 0.406250 +v 0.531250 0.468750 0.437500 +v 0.468750 0.531250 0.437500 +v 0.468750 0.468750 0.437500 +v 0.531250 0.531250 0.437500 +vt 0.031250 0.687500 +vt 0.062503 0.750036 +vt 0.000000 0.749986 +vt 0.062500 0.999826 +vt -0.000000 0.999848 +vt 0.500000 0.515633 +vt 0.000018 0.515633 +vt 0.000018 0.500009 +vt 0.500000 0.500009 +vt 0.781200 0.515637 +vt 0.718750 0.515638 +vt 0.718750 0.500025 +vt 0.781200 0.500025 +vt 0.718750 0.984375 +vt 0.781250 0.984375 +vt 0.781250 1.000000 +vt 0.718750 1.000000 +vt 0.515625 0.718750 +vt 0.515625 0.781250 +vt 0.500000 0.781250 +vt 0.500000 0.718750 +vt 0.984375 0.781263 +vt 0.984375 0.718763 +vt 1.000000 0.718763 +vt 1.000000 0.781263 +vt 0.999965 0.781246 +vt 0.109375 0.906215 +vt 0.101562 0.921840 +vt 0.085938 0.921840 +vt 0.078125 0.906215 +vt 0.093750 0.921875 +vt 0.093750 0.937500 +vt 0.078125 0.937500 +vt 0.078125 0.921875 +vt 0.078125 0.734340 +vt 0.078125 0.921840 +vt 0.062500 0.921840 +vt 0.062500 0.734340 +vt 0.062500 0.937500 +vt 0.062500 0.921875 +vt 0.109375 0.703090 +vt 0.078125 0.703090 +usemtl tex +s off +f 1/1 3/2 2/3 +f 1/1 4/2 3/3 +f 1/1 5/2 4/3 +f 1/1 6/2 5/3 +f 1/1 7/2 6/3 +f 1/1 2/2 7/3 +f 8/1 9/3 10/2 +f 8/1 10/3 11/2 +f 8/1 11/3 12/2 +f 8/1 12/3 13/2 +f 8/1 13/3 14/2 +f 8/1 14/3 9/2 +f 7/3 2/2 9/4 14/5 +f 6/3 7/2 14/4 13/5 +f 5/3 6/2 13/4 12/5 +f 4/3 5/2 12/4 11/5 +f 3/3 4/2 11/4 10/5 +f 2/3 3/2 10/4 9/5 +f 19/6 20/7 16/8 15/9 +f 20/10 21/11 17/12 16/13 +f 21/7 22/6 18/9 17/8 +f 22/14 19/15 15/16 18/17 +f 15/5 16/5 17/5 18/5 +f 22/17 21/12 20/13 19/16 +f 27/6 28/7 24/8 23/9 +f 28/18 29/19 25/20 24/21 +f 29/7 30/6 26/9 25/8 +f 30/22 27/23 23/24 26/25 +f 23/5 24/5 25/5 26/5 +f 30/26 29/20 28/21 27/24 +f 67/27 37/28 36/29 69/30 +f 69/27 36/28 35/29 68/30 +f 35/31 36/32 37/33 38/34 +f 68/27 35/28 38/29 70/30 +f 70/27 38/28 37/29 67/30 +f 39/35 44/36 43/37 40/38 +f 40/35 43/36 42/37 41/38 +f 42/34 43/33 44/39 45/40 +f 47/35 51/36 50/37 48/38 +f 49/34 50/33 51/39 52/40 +f 46/35 52/36 51/37 47/38 +f 54/35 57/36 56/37 55/38 +f 56/34 57/33 58/39 59/40 +f 55/35 56/36 59/37 53/38 +f 63/34 64/33 65/39 66/40 +f 62/35 63/36 66/37 60/38 +f 60/35 66/36 65/37 61/38 +f 41/35 42/36 45/37 33/38 +f 33/35 45/36 44/37 39/38 +f 48/35 50/36 49/37 32/38 +f 32/35 49/36 52/37 46/38 +f 34/35 58/36 57/37 54/38 +f 53/35 59/36 58/37 34/38 +f 61/35 65/36 64/37 31/38 +f 31/35 64/36 63/37 62/38 +f 31/41 70/27 67/30 32/42 +f 34/41 68/27 70/30 31/42 +f 33/41 69/27 68/30 34/42 +f 32/41 67/27 69/30 33/42 diff --git a/src/main/resources/assets/practicalities/models/block/other.json b/src/main/resources/assets/practicalities/models/block/other.json new file mode 100644 index 0000000..3657892 --- /dev/null +++ b/src/main/resources/assets/practicalities/models/block/other.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "practicalities:blocks/shippingcrate/shippingcrate_side", + "up": "practicalities:blocks/shippingcrate/shippingcrate_top" + } +} diff --git a/src/main/resources/assets/practicalities/textures/blocks/crystal/crystal.png b/src/main/resources/assets/practicalities/textures/blocks/crystal/crystal.png new file mode 100644 index 0000000000000000000000000000000000000000..557966a8469046f7cbf4f603bc6e50c2c4b6cd63 GIT binary patch literal 593 zcmV-X0WFU8GbZ8()Nlj2>E@cM*00Fg0L_t(&-tCx6N&`U< zhQFRXJAu45GK0H_hwvP6uecOkdk!z)0d(aVJca{V$e4|q1o9?RZk#cX0nJQ^3DZ9m z^b}o9Q}b7M{f!_ZaPeazp67+ep2G7yX<10H-?-~os}A?YWjGv$w(mH%RHFFos-sjY zaR?|B3R_ucjRCe}9~1+UA{$i#x2GpO`lx;0_+&EK76a5}R0*^!gcQI!)QwN4)5vjZ z5|DZZRIAmwAQrSZCUhdtt00L8Y1W<|2+X$_4rrV-K$3?li}JvN>T!H54;CvJN7|Qcs`%U zj_vqD7S!3IQ=wFg-RXdiFFbvGG9HfsC>DzV^!xoK>aLc6)|#7RCuBl!5dKyI%XlOE z{pXkP;7j6%hQHz&r5cUR<6PI3#Xg|fY^u12;93F{O5vyE7ElohFj~NLf~FHR4A^(f zW;4TpR5PGftA*oArD7P6x&#F35eVC8!+EaktaqI0&TkpdGB5m`xe0#j@!Zp35g4I8|=fude zrvGoOb}u*oAGFYUr=HL)r(d4E!7A4}W?Y+9aX;N^XUw68ALiZpe6K>#X3~S3w^l#d z{QkF`<&h}qyYqfBd~r7`p67m>d-F}6=|4gm+!hCR9Le5#>%GW+wDv2#9u>6-rh z$n?`s({%KA)L!#{`uf!O^4+TA{&0I zRCuUO_GA%gQ)D=sCfx9`g2!QL5aWWVwa0$j+b~NcOYpS^7TuMYyvzQZz(OQS#=b5uFPx^6jbn84ko3^=_yXCgHLi-m+etkxU?xRc%ReSjklvw>$xcgSj z;Mjyc0-g3P_qRH{6S?rV%y{Ryg9!qv&l}>_KYzQH^;2H!_bRT60)71jo&l2=hy<8i zd%acU!4@W~x#z0yWNlr-@SICv_wgqZx~w}w8h+eU$XsC5d&p71CGu{>t%Og(=F_g< kfA7Sh*dl;R{IK7{$aHN&*`BBMRiH@oboFyt=akR{06c`~zW@LL literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/practicalities/textures/blocks/crystal/on.png b/src/main/resources/assets/practicalities/textures/blocks/crystal/on.png new file mode 100644 index 0000000000000000000000000000000000000000..08f5d147ef45f300c46faf84205ec67e0b32b96c GIT binary patch literal 553 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPNqcEES+g-D{$AChznIRD+&iT2ysd*(pE(3#eQEFmI zYKlU6W=V#EyQgnJie4%^0|R5Pr;B4q#jUq9&t@HR5NX|?@mI1{Lrm+enO*4p_5G?l zyv!9t75^z+_H|y|yQTM<+T71;)7lbu#GE^O$M~a;&E&_bUGqMDR^YJF@(^+TX2`K= zhWGKx@?9IE))sX7bH4amwUuMf<(Gf_nC65tI9SYl&=~&o!1mj3L(gT-(Pren#>#5) zO6o`6c5NB!$qdg$4J3HDjt4bpb4IMc-kPlGu)RT~pi;fUTdcd4)#I{AL*0J<12uN+ z3$A7{UdY?N`LBC1Lo(0in`fR~?=@`wZOlKhbW;61hW~%LKKoxk|7O4aws$78edUfl z-u#?@|H6hX=Y;HJ_{66>RQ+No@|OQFONAlFOqyZWT|I`=Pd|C=TCSSVqxfH8QZ2`R zt;SQD2_{lgi{@T_dF9#f1_PeGt2G!_>=6}nkU4&>X=}n`3%%G)uUM{fdNF=Y*?-@g z(N8LeV~wRW=KSdbAE1aYF-JD%fR4Vl$uzQ znxasiS(2gP?&%wlqL<3fz`!`c)5S5Q;?~=lw%&&WMB3(W`Sy6*g=>0A1*?B_&xw&` zP5<9m?OtyFKWL%zPCcPpPQN^RgH^6|%(ynI;(of-&X_|FKg_%H`Cf&f&7=o6Z>@f^ z`TcJ>%Og?Jcjx_N_~LF>JkR|$_vV{C(|?3CxGfIsIFh~f)_aiym8=YRV&{DR(l!10 zk?E(O#@!44wTe~G+eJ@fLCBRO;j2Tl-uN)i33u3i*ROXeLpYbg{PV%dnhwhwL^k|Z zsqj#n?8zd~rpRzMO}OD>1&_nhAjSnzYmfc5w_%n@mf&j-EV?T(d6)e+fsZObpR?|; zJ6G58)qPsg&NF9Up7i75=+=37Hf?h;cgt;Yh4wFu{Q8Ux-A9=ks`m07D6#shaQCg4 z!LbQ@1Ul_o?r(K?CvxF!neonZ2NMKTpEty!-Zd?^RqC1^W66JOd^#5D753 z_Ij(xgDp%}bI(=Z$=bSv;W?MU?&D7+bXj+VH2k=ykh#F9_mHE2OXS^%TM3_n&8JFVdQ&MBb@01m_HG5`Po literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/practicalities/textures/misc/laser.png b/src/main/resources/assets/practicalities/textures/misc/laser.png new file mode 100644 index 0000000000000000000000000000000000000000..3932b4cc04e08311e04c486e70ce8984b3961f3a GIT binary patch literal 185 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPNqkt%*TAGlQ7EnkwGbEzKIX^cyHLnE7WngeFN=+