Jump to content

Zarathul

Members
  • Posts

    15
  • Joined

  • Last visited

Converted

  • Gender
    Undisclosed
  • Personal Text
    I am new!

Zarathul's Achievements

Tree Puncher

Tree Puncher (2/8)

4

Reputation

  1. Teleporting players is a messy business. ServerPlayerEntity#changeDimension() has all kinds of hardcoded stuff that assumes it was called from a vanilla portal, and therefore isn't really suited for general purpose use. You can try ServerPlayerEntity#teleport() instead. Be warned though, ServerPlayerEntity#teleport() will not work from Block#onEntityCollision(). If your are using it only in a command you should be fine.
  2. Now that Item#doesSneakBypassUse() is back in, I've been trying to get my item to work properly again when dual wielding. In 1.12.2 I used PlayerInteractEvent#RightClickBlock to get Block#onBlockActivated() to trigger even when sneaking and holding an item in both hands (by setting UseBlock to Allow and UseItem to Deny under the right circumstances). Without this, half the functionalty of my wrench doesn't work if the player is holding a shield for example and tries to use the wrench while sneaking. This approach doesn't seem to work anymore, because it is now required for both items to return true in doesSneakBypassUse() when sneaking, which is never the case for vanilla items (because the default behavior of IForgeItem#doesSneakBypassUse() is to return false). boolean flag = !p_219441_1_.getHeldItemMainhand().isEmpty() || !p_219441_1_.getHeldItemOffhand().isEmpty(); boolean flag1 = !(p_219441_1_.isSneaking() && flag) || (p_219441_1_.getHeldItemMainhand().doesSneakBypassUse(p_219441_2_,blockpos,p_219441_1_) && p_219441_1_.getHeldItemOffhand().doesSneakBypassUse(p_219441_2_,blockpos,p_219441_1_)); if (event.getUseBlock() != net.minecraftforge.eventbus.api.Event.Result.DENY && flag1 && blockstate.onBlockActivated(p_219441_2_, p_219441_1_, p_219441_4_, p_219441_5_)) { return ActionResultType.SUCCESS; } Is this broken or intended behavior ... or am I missing something ? I mean, isn't the whole purpose of PlayerInteractEvent#RightClickBlock to override default behavior?
  3. I did some further testing. Porting from Item#onItemUse never produces the message, doesn't matter if I'm running around or standing still. @Override public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ) { if (!world.isRemote) { EntityPlayerMP playerMp = (player instanceof EntityPlayerMP) ? (EntityPlayerMP)player : null; if (playerMp != null) { BlockPos destination = playerMp.getPosition().offset(playerMp.getHorizontalFacing(), 10); playerMp.playerNetServerHandler.setPlayerLocation(destination.getX() + 0.5d, destination.getY(), destination.getZ() + 0.5d, player.rotationYaw, player.rotationPitch); } } return true; } While porting from Block#onEntityCollidedWithBlock will produce the message about half the time when walking into the block. Also, sometimes the handler is triggered twice and therefore the player is ported twice the distance. @Override public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) { if (!world.isRemote && entity.ridingEntity == null && entity.riddenByEntity == null && !entity.isDead) { EntityPlayerMP player = (entity instanceof EntityPlayerMP) ? (EntityPlayerMP)entity : null; if (player != null) { BlockPos destination = player.getPosition().offset(player.getHorizontalFacing(), 10); player.playerNetServerHandler.setPlayerLocation(destination.getX() + 0.5d, destination.getY(), destination.getZ() + 0.5d, player.rotationYaw, player.rotationPitch); } } } In my proper code I add a cooldown to ported entities (basically a HashMap of UniquieIDs and Timestamps), so I don't have the problem with the double port. What is strange though, is when I walk into the block while on cooldown and I'm then ported while standing still, I also never get the message.
  4. Ahhh good to know. Hmm very strange. Tried it but still get the message. I looked at #setPositionAndUpdate and it just calls playerNetServerHandler.setPlayerLocation so it's basically the same I do. Still thx for the answers!
  5. When teleporting a moving player I get the "Player moved wrongly!" message on the server. If the player stands still when ported there's no message. Teleportation is done the same way CommandTeleport does it, just from inside a Block#onEntityCollidedWithBlock() handler on the server side. EntityPlayerMP player = (entity instanceof EntityPlayerMP) ? (EntityPlayerMP)entity : null; if (player != null) { player.playerNetServerHandler.setPlayerLocation(destination.getX() + 0.5d, destination.getY(), destination.getZ() + 0.5d, getYaw(facing), player.rotationPitch); } I tried to stop the player and then port but it had no effect. player.motionX = 0; player.motionY = 0; player.motionZ = 0; player.playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(player)); (Why is Entity#setVelocity() client side only btw?) I also tried switching the player to creative mode temporarily (I know .. bad idea) during the port because this would normally suppress this particular movement check (see NetHandlerPlayServer#processPlayer()), but that didn't work either. Probably because the check hasn't been performed yet when I reset the game mode. If anybody has some input on this, what I'm doing wrong or any Ideas on how to get rid of the message I'd appreciate it.
  6. So as promised an (attempted) explanation for what I did. I ended up making two separate models, one for the tank frame and one for the fluid. The tank model has a blockstate json that defines all the connected textures variants. The fluid model has none. In onModelBakeEvent the fluid model is loaded using the ModelLoader and cast to IRetexturableModel. Then .retexture() is called on it for every fluid in the forge fluid registry. The resulting models get baked and cached. Finally all tank variant models in the ModelRegistry get replaced with an ISmartBlockModel that stores the tank variant model. In ISmartBlockModel.handleBlockState() an IBakedModel is returned that gets the variant model from the ISmartBlockModel and the fluid name from the IExtendedBlockState. In getFaceQuads() and getGeneralQuads() the IBakedModel returns the quads of the tank variant model plus the quads of the previously cached fluid model determined by the stored fluid name. There's some additional stuff happening and there is actually more than one fluid model for the different fill levels of the tank, but explaining that would make everything too complicated. For those that prefer looking at code: https://github.com/Zarathul/simplefluidtanks/blob/1.8/src/main/java/net/zarathul/simplefluidtanks/ClientEventHub.java https://github.com/Zarathul/simplefluidtanks/blob/1.8/src/main/java/net/zarathul/simplefluidtanks/rendering/TankModelFactory.java https://github.com/Zarathul/simplefluidtanks/blob/1.8/src/main/java/net/zarathul/simplefluidtanks/rendering/BakedTankModel.java
  7. Thanks ! (Sorry for the late reply.) I almost got everything to work. Once I ironed out the kinks I'll probably make a post explaining what I ended up doing so others can learn from it or at least have a good laugh .
  8. I'm trying to port my multi block fluid tank from 1.7.10. I got connected textures to work using the new model system and blockstates but I can't figure out how to go about rendering the fluid. The problem is the texture. I can't predefine any textures in the .jsons because I don't know what fluids other mods will add. So I looked at ISmartBlockModel in hope of finding a way to change the fluid texture programmatically but I can't figure out how to do it (I also read TheGreyGhosts examples for ISmartBlockModel but they deal only with swapping out entire models or composing them together, no texture changes). I'm aware that in this case going with TESR would probably much easier but I want to avoid the performance hit if at all possible. If someone can point me in the right direction or even give a short example I would be grateful.
  9. Don't know if it's the best way, but it works for me. (preInit) GameRegistry.registerBlock(yourBlock, yourBlockItem.class, yourBlockName); (init) Item yourBlockItem = GameRegistry.findItem(yourModId, yourBlockName); Minecraft.getMinecraft().getRenderItem().getItemModelMesher().modelMesher.register(yourBlockItem , 0, new ModelResourceLocation("yourModId:yourBlockName", "inventory"));
  10. Check your version of Forge. Before 10.12.0.1034 there were quite a lot bugs in the fluid api that resulted in problems like you are describing. The only other thing I can think of is that your itemstack is invalid (null or not a registered fluid container).
  11. This will allow you to place torches, ladders, redstone etc. on top or on the sides of your block respectively . For 1.6.4 @Override public boolean isBlockSolidOnSide(World world, int x, int y, int z, ForgeDirection side) { return true; } and for 1.7.2 @Override public boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side) { return true; }
  12. UPDATE: Turns out when another entity is in the scene the wrong texture map is set (items instead of blocks) . Adding "bindTexture(TextureMap.locationBlocksTexture)" in "renderTileEntityAt()" fixed the problem. I implemented a TileEntitySpecialRenderer and everything is rendered exactly as it should be until any entitys other than my own enter the scene (e.g. any item, any creature and even the player itself in 3rd person view). I first thought I messed up with the Tessellator.draw() and Tessellator.startDrawingQuads() calls but if I do it any other way than in the posted code I get the usual exceptions ("tessellator already tessellating" etc). Hints on what's going on here would be very appreciated. (The transparent blocks are the ones rendered by the TileEntitySpecialRenderer) That's how it's always supposed to look like That's how it looks with an addtional entity in the scene (the bucket on the ground). TileEntitySpecialRenderer package simplefluidtanks; import java.util.ArrayList; import java.util.HashMap; import org.lwjgl.opengl.GL11; import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler; import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.texture.IconRegister; import net.minecraft.client.renderer.texture.SimpleTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.launchwrapper.LogWrapper; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Icon; import net.minecraft.util.ResourceLocation; import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.IItemRenderer; import net.minecraftforge.client.model.AdvancedModelLoader; import net.minecraftforge.client.model.IModelCustom; import net.minecraftforge.fluids.FluidRegistry; import net.minecraftforge.fluids.FluidRegistry.FluidRegisterEvent; import net.minecraftforge.fluids.FluidStack; @SideOnly(Side.CLIENT) public class TankBlockRenderer extends TileEntitySpecialRenderer { public TankBlockRenderer() { super(); } @Override public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f) { if (tileEntity == null || !(tileEntity instanceof TankBlockEntity)) { return; } Block block = tileEntity.getBlockType(); if (block == null || !(block instanceof TankBlock)) { return; } TankBlock tank = (TankBlock)block; TankBlockEntity entity = (TankBlockEntity)tileEntity; Icon[] icons = tank.getIcons(); Tessellator tsr = Tessellator.instance; int brightness = block.getMixedBrightnessForBlock(entity.worldObj, entity.xCoord, entity.yCoord, entity.zCoord); tsr.setBrightness(brightness); TessellationManager.setBaseCoords(x, y, z); if (tsr.isDrawing) tsr.draw(); tsr.startDrawingQuads(); if (!entity.isPartOfTank()) { renderSolid(entity, icons[0]); } else { boolean[] connections = entity.getConnections(); int fillPercentage = entity.getFillPercentage(); double fluidHeight = 16.0 / 100 * fillPercentage; double verticalTextureOffset = 16.0 / 100 * (100 - fillPercentage); Icon fluidIcon = getFluidTexture(entity); renderPositiveXFace(entity, connections, icons, fluidIcon, fillPercentage, fluidHeight, verticalTextureOffset); renderNegativeXFace(entity, connections, icons, fluidIcon, fillPercentage, fluidHeight, verticalTextureOffset); renderPositiveZFace(entity, connections, icons, fluidIcon, fillPercentage, fluidHeight, verticalTextureOffset); renderNegativeZFace(entity, connections, icons, fluidIcon, fillPercentage, fluidHeight, verticalTextureOffset); renderPositiveYFace(entity, connections, icons, fluidIcon, fillPercentage, fluidHeight); renderNegativeYFace(entity, connections, icons, fluidIcon, fillPercentage); } tsr.draw(); } private void renderSolid(TankBlockEntity entity, Icon icon) { TessellationManager.renderCube(1, 0, 1, 14, 14, 14, icon, true, TessellationManager.pixel); } private void renderPositiveXFace(TankBlockEntity entity, boolean[] connections, Icon[] icons, Icon fluidIcon, int fillPercentage, double fluidHeight, double verticalTextureOffset) { // only render this side if there isn't a tank block from the same tank in front of it if (!connections[ConnectedTexturesHelper.XPOS]) { if (fillPercentage > 0 && fluidIcon != null) { TessellationManager.renderPositiveXFace(16, 0, 0, fluidHeight, 16, 0, verticalTextureOffset, 0, 0, fluidIcon, TessellationManager.pixel); } TessellationManager.renderPositiveXFace(16, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.XPOS)]); // inner face TessellationManager.renderNegativeXFace(16, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.XNEG)]); } } private void renderNegativeXFace(TankBlockEntity entity, boolean[] connections, Icon[] icons, Icon fluidIcon, int fillPercentage, double fluidHeight, double verticalTextureOffset) { // only render this side if there isn't a tank block from the same tank in front of it if (!connections[ConnectedTexturesHelper.XNEG]) { if (fillPercentage > 0 && fluidIcon != null) { TessellationManager.renderNegativeXFace(0, 0, 0, fluidHeight, 16, 0, verticalTextureOffset, 0, 0, fluidIcon, TessellationManager.pixel); } TessellationManager.renderNegativeXFace(0, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.XNEG)]); // inner face TessellationManager.renderPositiveXFace(0, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.XPOS)]); } } private void renderPositiveZFace(TankBlockEntity entity, boolean[] connections, Icon[] icons, Icon fluidIcon, int fillPercentage, double fluidHeight, double verticalTextureOffset) { // only render this side if there isn't a tank block from the same tank in front of it if (!connections[ConnectedTexturesHelper.ZPOS]) { if (fillPercentage > 0 && fluidIcon != null) { TessellationManager.renderPositiveZFace(0, 0, 16, 16, fluidHeight, 0, verticalTextureOffset, 0, 0, fluidIcon, TessellationManager.pixel); } TessellationManager.renderPositiveZFace(0, 0, 16, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.ZPOS)]); // inner face TessellationManager.renderNegativeZFace(0, 0, 16, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.ZNEG)]); } } private void renderNegativeZFace(TankBlockEntity entity, boolean[] connections, Icon[] icons, Icon fluidIcon, int fillPercentage, double fluidHeight, double verticalTextureOffset) { // only render this side if there isn't a tank block from the same tank in front of it if (!connections[ConnectedTexturesHelper.ZNEG]) { if (fillPercentage > 0 && fluidIcon != null) { TessellationManager.renderNegativeZFace(0, 0, 0, 16, fluidHeight, 0, verticalTextureOffset, 0, 0, fluidIcon, TessellationManager.pixel); } TessellationManager.renderNegativeZFace(0, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.ZNEG)]); // inner face TessellationManager.renderPositiveZFace(0, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.ZPOS)]); } } private void renderPositiveYFace(TankBlockEntity entity, boolean[] connections, Icon[] icons, Icon fluidIcon, int fillPercentage, double fluidHeight) { if (fillPercentage > 0 && fluidIcon != null) { TessellationManager.renderPositiveYFace(0, fluidHeight, 0, 16, 16, fluidIcon); } // only render this side if there isn't a tank block from the same tank in front of it if (!connections[ConnectedTexturesHelper.YPOS]) { TessellationManager.renderPositiveYFace(0, 16, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.YPOS)]); // inner face TessellationManager.renderNegativeYFace(0, 16, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.YNEG)]); } } private void renderNegativeYFace(TankBlockEntity entity, boolean[] connections, Icon[] icons, Icon fluidIcon, int fillPercentage) { // only render this side if there isn't a tank block from the same tank in front of it if (fillPercentage > 0 && fluidIcon != null && !connections[ConnectedTexturesHelper.YNEG]) { TessellationManager.renderNegativeYFace(0, 0, 0, 16, 16, fluidIcon); } if (!connections[ConnectedTexturesHelper.YNEG]) { TessellationManager.renderNegativeYFace(0, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.YNEG)]); // inner face TessellationManager.renderPositiveYFace(0, 0, 0, 16, 16, icons[entity.getTexture(ConnectedTexturesHelper.YPOS)]); } } private Icon getFluidTexture(TankBlockEntity entity) { ValveBlockEntity valve = entity.getValve(); if (valve != null) { FluidStack fluidStack = valve.getFluid(); if (fluidStack != null) { return fluidStack.getFluid().getIcon(); } } return null; } } TessellationManager (helper class) package simplefluidtanks; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.Icon; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.FluidRegistry; public final class TessellationManager { public static final double pixel = 1d / 16d; private static final Tessellator tr = Tessellator.instance; private static double xBaseCoord; private static double yBaseCoord; private static double zBaseCoord; private TessellationManager() { } public static void setBaseCoords(double ... coords) { if (coords != null && coords.length >= 3) { xBaseCoord = coords[0]; yBaseCoord = coords[1]; zBaseCoord = coords[2]; } } public static void renderCube(double xOffset, double yOffset, double zOffset, double width, double height, double depth, Icon icon) { renderCube(xOffset, yOffset, zOffset, width, height, depth, icon, false, pixel); } public static void renderCube(double xOffset, double yOffset, double zOffset, double width, double height, double depth, Icon icon, boolean renderInside, double scale) { renderPositiveXFace(xOffset + width, yOffset, zOffset, height, depth, icon, scale); renderNegativeXFace(xOffset, yOffset, zOffset, height, depth, icon, scale); renderPositiveYFace(xOffset, yOffset + height, zOffset, width, depth, icon, scale); renderNegativeYFace(xOffset, yOffset, zOffset, width, depth, icon, scale); renderPositiveZFace(xOffset, yOffset, zOffset + depth, width, height, icon, scale); renderNegativeZFace(xOffset, yOffset, zOffset, width, height, icon, scale); if (renderInside) { // positive x back side renderNegativeXFace(xOffset + width, yOffset, zOffset, height, depth, icon, scale); // negative x back side renderPositiveXFace(xOffset, yOffset, zOffset, height, depth, icon, scale); // positive y back side renderNegativeYFace(xOffset, yOffset + height, zOffset, width, depth, icon, scale); // negative y back side renderPositiveYFace(xOffset, yOffset, zOffset, width, depth, icon, scale); // positive z back side renderNegativeZFace(xOffset, yOffset, zOffset + depth, width, height, icon, scale); // negative back side renderPositiveZFace(xOffset, yOffset, zOffset, width, height, icon, scale); } } public static void renderPositiveXFace(double xOffset, double yOffset, double zOffset, double height, double depth, Icon icon) { renderPositiveXFace(xOffset, yOffset, zOffset, height, depth, 0, 0, 0, 0, icon, pixel); } public static void renderPositiveXFace(double xOffset, double yOffset, double zOffset, double height, double depth, Icon icon, double scale) { renderPositiveXFace(xOffset, yOffset, zOffset, height, depth, 0, 0, 0, 0, icon, scale); } public static void renderPositiveXFace(double xOffset, double yOffset, double zOffset, double height, double depth, double uOffset, double vOffset, double uMaxOffset, double vMaxOffset, Icon icon, double scale) { tr.setNormal(1f, 0f, 0f); double x = xBaseCoord + xOffset * scale; // bottom right double zBr = zBaseCoord + zOffset * scale; double yBr = yBaseCoord + yOffset * scale; // top right double zTr = zBaseCoord + zOffset * scale; double yTr = yBaseCoord + (yOffset + height) * scale; // top left double zTl = zBaseCoord + (zOffset + depth) * scale; double yTl = yBaseCoord + (yOffset + height) * scale; // bottom left double zBl = zBaseCoord + (zOffset + depth) * scale; double yBl = yBaseCoord + yOffset * scale; double minU = (uOffset > 0 && uOffset < 16) ? icon.getMinU() + (icon.getInterpolatedU(uOffset) - icon.getMinU()) : icon.getMinU(); double maxU = (uMaxOffset > 0 && uMaxOffset < 16) ? icon.getMaxU() - (icon.getMaxU() - icon.getInterpolatedU(uMaxOffset)) : icon.getMaxU(); double minV = (vOffset > 0 && vOffset < 16) ? icon.getMinV() + (icon.getInterpolatedV(vOffset) - icon.getMinV()) : icon.getMinV(); double maxV = (vMaxOffset > 0 && vMaxOffset < 16) ? icon.getMaxV() - (icon.getMaxV() - icon.getInterpolatedV(vMaxOffset)) : icon.getMaxV(); // bottom right tr.addVertexWithUV(x, yBr, zBr, maxU, maxV); // top right tr.addVertexWithUV(x, yTr, zTr, maxU, minV); // top left tr.addVertexWithUV(x, yTl, zTl, minU, minV); // bottom left tr.addVertexWithUV(x, yBl, zBl, minU, maxV); } public static void renderNegativeXFace(double xOffset, double yOffset, double zOffset, double height, double depth, Icon icon) { renderNegativeXFace(xOffset, yOffset, zOffset, height, depth, 0, 0, 0, 0, icon, pixel); } public static void renderNegativeXFace(double xOffset, double yOffset, double zOffset, double height, double depth, Icon icon, double scale) { renderNegativeXFace(xOffset, yOffset, zOffset, height, depth, 0, 0, 0, 0, icon, scale); } public static void renderNegativeXFace(double xOffset, double yOffset, double zOffset, double height, double depth, double uOffset, double vOffset, double uMaxOffset, double vMaxOffset, Icon icon, double scale) { tr.setNormal(-1f, 0f, 0f); double x = xBaseCoord + xOffset * scale; // bottom left double zBl = zBaseCoord + zOffset * scale; double yBl = yBaseCoord + yOffset * scale; // bottom right double zBr = zBaseCoord + (zOffset + depth) * scale; double yBr = yBaseCoord + yOffset * scale; // top right double zTr = zBaseCoord + (zOffset + depth) * scale; double yTr = yBaseCoord + (yOffset + height) * scale; // top left double zTl = zBaseCoord + zOffset * scale; double yTl = yBaseCoord + (yOffset + height) * scale; double minU = (uOffset > 0 && uOffset < 16) ? icon.getMinU() + (icon.getInterpolatedU(uOffset) - icon.getMinU()) : icon.getMinU(); double maxU = (uMaxOffset > 0 && uMaxOffset < 16) ? icon.getMaxU() - (icon.getMaxU() - icon.getInterpolatedU(uMaxOffset)) : icon.getMaxU(); double minV = (vOffset > 0 && vOffset < 16) ? icon.getMinV() + (icon.getInterpolatedV(vOffset) - icon.getMinV()) : icon.getMinV(); double maxV = (vMaxOffset > 0 && vMaxOffset < 16) ? icon.getMaxV() - (icon.getMaxV() - icon.getInterpolatedV(vMaxOffset)) : icon.getMaxV(); // bottom left tr.addVertexWithUV(x, yBl, zBl, minU, maxV); // bottom right tr.addVertexWithUV(x, yBr, zBr, maxU, maxV); // top right tr.addVertexWithUV(x, yTr, zTr, maxU, minV); // top left tr.addVertexWithUV(x, yTl, zTl, minU, minV); } public static void renderPositiveYFace(double xOffset, double yOffset, double zOffset, double width, double depth, Icon icon) { renderPositiveYFace(xOffset, yOffset, zOffset, width, depth, 0, 0, 0, 0, icon, pixel); } public static void renderPositiveYFace(double xOffset, double yOffset, double zOffset, double width, double depth, Icon icon, double scale) { renderPositiveYFace(xOffset, yOffset, zOffset, width, depth, 0, 0, 0, 0, icon, scale); } public static void renderPositiveYFace(double xOffset, double yOffset, double zOffset, double width, double depth, double uOffset, double vOffset, double uMaxOffset, double vMaxOffset, Icon icon, double scale) { tr.setNormal(0f, 1f, 0f); double y = yBaseCoord + yOffset * scale; // bottom right double xBr = xBaseCoord + xOffset * scale; double zBr = zBaseCoord + zOffset * scale; // top right double xTr = xBaseCoord + xOffset * scale; double zTr = zBaseCoord + (zOffset + depth) * scale; // top left double xTl = xBaseCoord + (xOffset + width) * scale; double zTl = zBaseCoord + (zOffset + depth) * scale; // bottom left double xBl = xBaseCoord + (xOffset + width) * scale; double zBl = zBaseCoord + zOffset * scale; double minU = (uOffset > 0 && uOffset < 16) ? icon.getMinU() + (icon.getInterpolatedU(uOffset) - icon.getMinU()) : icon.getMinU(); double maxU = (uMaxOffset > 0 && uMaxOffset < 16) ? icon.getMaxU() - (icon.getMaxU() - icon.getInterpolatedU(uMaxOffset)) : icon.getMaxU(); double minV = (vOffset > 0 && vOffset < 16) ? icon.getMinV() + (icon.getInterpolatedV(vOffset) - icon.getMinV()) : icon.getMinV(); double maxV = (vMaxOffset > 0 && vMaxOffset < 16) ? icon.getMaxV() - (icon.getMaxV() - icon.getInterpolatedV(vMaxOffset)) : icon.getMaxV(); // bottom right tr.addVertexWithUV(xBr, y, zBr, maxU, maxV); // top right tr.addVertexWithUV(xTr, y, zTr, maxU, minV); // top left tr.addVertexWithUV(xTl, y, zTl, minU, minV); // bottom left tr.addVertexWithUV(xBl, y, zBl, minU, maxV); } public static void renderNegativeYFace(double xOffset, double yOffset, double zOffset, double width, double depth, Icon icon) { renderNegativeYFace(xOffset, yOffset, zOffset, width, depth, 0, 0, 0, 0, icon, pixel); } public static void renderNegativeYFace(double xOffset, double yOffset, double zOffset, double width, double depth, Icon icon, double scale) { renderNegativeYFace(xOffset, yOffset, zOffset, width, depth, 0, 0, 0, 0, icon, scale); } public static void renderNegativeYFace(double xOffset, double yOffset, double zOffset, double width, double depth, double uOffset, double vOffset, double uMaxOffset, double vMaxOffset, Icon icon, double scale) { tr.setNormal(0f, -1f, 0f); double y = yBaseCoord + yOffset * scale; // top right double xTr = xBaseCoord + xOffset * scale; double zTr = zBaseCoord + zOffset * scale; // top left double xTl = xBaseCoord + (xOffset + width) * scale; double zTl = zBaseCoord + zOffset * scale; // bottom left double xBl = xBaseCoord + (xOffset + width) * scale; double zBl = zBaseCoord + (zOffset + depth) * scale; // bottom right double xBr = xBaseCoord + xOffset * scale; double zBr = zBaseCoord + (zOffset + depth) * scale; double minU = (uOffset > 0 && uOffset < 16) ? icon.getMinU() + (icon.getInterpolatedU(uOffset) - icon.getMinU()) : icon.getMinU(); double maxU = (uMaxOffset > 0 && uMaxOffset < 16) ? icon.getMaxU() - (icon.getMaxU() - icon.getInterpolatedU(uMaxOffset)) : icon.getMaxU(); double minV = (vOffset > 0 && vOffset < 16) ? icon.getMinV() + (icon.getInterpolatedV(vOffset) - icon.getMinV()) : icon.getMinV(); double maxV = (vMaxOffset > 0 && vMaxOffset < 16) ? icon.getMaxV() - (icon.getMaxV() - icon.getInterpolatedV(vMaxOffset)) : icon.getMaxV(); // top right tr.addVertexWithUV(xTr, y, zTr, maxU, minV); // top left tr.addVertexWithUV(xTl, y, zTl, minU, minV); // bottom left tr.addVertexWithUV(xBl, y, zBl, minU, maxV); // bottom right tr.addVertexWithUV(xBr, y, zBr, maxU, maxV); } public static void renderPositiveZFace(double xOffset, double yOffset, double zOffset, double width, double height, Icon icon) { renderPositiveZFace(xOffset, yOffset, zOffset, width, height, 0, 0, 0, 0, icon, pixel); } public static void renderPositiveZFace(double xOffset, double yOffset, double zOffset, double width, double height, Icon icon, double scale) { renderPositiveZFace(xOffset, yOffset, zOffset, width, height, 0, 0, 0, 0, icon, scale); } public static void renderPositiveZFace(double xOffset, double yOffset, double zOffset, double width, double height, double uOffset, double vOffset, double uMaxOffset, double vMaxOffset, Icon icon, double scale) { tr.setNormal(0f, 0f, 1f); double z = zBaseCoord + zOffset * scale; // bottom left double xBl = xBaseCoord + xOffset * scale; double yBl = yBaseCoord + yOffset * scale; // bottom right double xBr = xBaseCoord + (xOffset + width) * scale; double yBr = yBaseCoord + yOffset * scale; // top right double xTr = xBaseCoord + (xOffset + width) * scale; double yTr = yBaseCoord + (yOffset + height) * scale; // top left double xTl = xBaseCoord + xOffset * scale; double yTl = yBaseCoord + (yOffset + height) * scale; double minU = (uOffset > 0 && uOffset < 16) ? icon.getMinU() + (icon.getInterpolatedU(uOffset) - icon.getMinU()) : icon.getMinU(); double maxU = (uMaxOffset > 0 && uMaxOffset < 16) ? icon.getMaxU() - (icon.getMaxU() - icon.getInterpolatedU(uMaxOffset)) : icon.getMaxU(); double minV = (vOffset > 0 && vOffset < 16) ? icon.getMinV() + (icon.getInterpolatedV(vOffset) - icon.getMinV()) : icon.getMinV(); double maxV = (vMaxOffset > 0 && vMaxOffset < 16) ? icon.getMaxV() - (icon.getMaxV() - icon.getInterpolatedV(vMaxOffset)) : icon.getMaxV(); // bottom left tr.addVertexWithUV(xBl, yBl, z, minU, maxV); // bottom right tr.addVertexWithUV(xBr, yBr, z, maxU, maxV); // top right tr.addVertexWithUV(xTr, yTr, z, maxU, minV); // top left tr.addVertexWithUV(xTl, yTl, z, minU, minV); } public static void renderNegativeZFace(double xOffset, double yOffset, double zOffset, double width, double height, Icon icon) { renderNegativeZFace(xOffset, yOffset, zOffset, width, height, 0, 0, 0, 0, icon, pixel); } public static void renderNegativeZFace(double xOffset, double yOffset, double zOffset, double width, double height, Icon icon, double scale) { renderNegativeZFace(xOffset, yOffset, zOffset, width, height, 0, 0, 0, 0, icon, scale); } public static void renderNegativeZFace(double xOffset, double yOffset, double zOffset, double width, double height, double uOffset, double vOffset, double uMaxOffset, double vMaxOffset, Icon icon, double scale) { tr.setNormal(0f, 0f, -1f); double z = zBaseCoord + zOffset * scale; // bottom right double xBr = xBaseCoord + xOffset * scale; double yBr = yBaseCoord + yOffset * scale; // top right double xTr = xBaseCoord + xOffset * scale; double yTr = yBaseCoord + (yOffset + height) * scale; // top left double xTl = xBaseCoord + (xOffset + width) * scale; double yTl = yBaseCoord + (yOffset + height) * scale; // bottom left double xBl = xBaseCoord + (xOffset + width) * scale; double yBl = yBaseCoord + yOffset * scale; double minU = (uOffset > 0 && uOffset < 16) ? icon.getMinU() + (icon.getInterpolatedU(uOffset) - icon.getMinU()) : icon.getMinU(); double maxU = (uMaxOffset > 0 && uMaxOffset < 16) ? icon.getMaxU() - (icon.getMaxU() - icon.getInterpolatedU(uMaxOffset)) : icon.getMaxU(); double minV = (vOffset > 0 && vOffset < 16) ? icon.getMinV() + (icon.getInterpolatedV(vOffset) - icon.getMinV()) : icon.getMinV(); double maxV = (vMaxOffset > 0 && vMaxOffset < 16) ? icon.getMaxV() - (icon.getMaxV() - icon.getInterpolatedV(vMaxOffset)) : icon.getMaxV(); // bottom right tr.addVertexWithUV(xBr, yBr, z, maxU, maxV); // top right tr.addVertexWithUV(xTr, yTr, z, maxU, minV); // top left tr.addVertexWithUV(xTl, yTl, z, minU, minV); // bottom left tr.addVertexWithUV(xBl, yBl, z, minU, maxV); } }
  13. Just did that. And thanks for the help.
  14. Yeah that's what I figured. I ended up basically copying the TileFluidHandler code into my own IFluidHandler implementation, switched the NBT read/write around and added the syncing. Seems to work for now. It's neither pretty nor does it do much on it's own but here is the code if someone is interested. package simplefluidtanks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet132TileEntityData; import net.minecraft.tileentity.TileEntity; import net.minecraftforge.common.ForgeDirection; import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidContainerRegistry; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidHandler; public class ValveBlockEntity extends TileEntity implements IFluidHandler { protected FluidTank tank; public ValveBlockEntity() { super(); this.tank = new FluidTank(SimpleFluidTanks.bucketsPerTank * FluidContainerRegistry.BUCKET_VOLUME); } @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); tank.readFromNBT(tag); } @Override public void writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); tank.writeToNBT(tag); } @Override public int fill(ForgeDirection from, FluidStack resource, boolean doFill) { int fillAmount = tank.fill(resource, doFill); this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); return fillAmount; } @Override public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) { if (resource == null || !resource.isFluidEqual(tank.getFluid())) { return null; } FluidStack drainedFluid = tank.drain(resource.amount, doDrain); this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); return drainedFluid; } @Override public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) { this.worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); FluidStack drainedFluid = tank.drain(maxDrain, doDrain); return drainedFluid; } @Override public boolean canFill(ForgeDirection from, Fluid fluid) { return true; } @Override public boolean canDrain(ForgeDirection from, Fluid fluid) { return true; } @Override public FluidTankInfo[] getTankInfo(ForgeDirection from) { return new FluidTankInfo[] { tank.getInfo() }; } @Override public Packet getDescriptionPacket() { NBTTagCompound tag = new NBTTagCompound(); writeToNBT(tag); return new Packet132TileEntityData(xCoord, yCoord, zCoord, 1, tag); } @Override public void onDataPacket(INetworkManager net, Packet132TileEntityData packet) { readFromNBT(packet.data); } public int getCapacity() { return tank.getCapacity(); } public int getFluidAmount() { return tank.getFluidAmount(); } public FluidStack getFluid() { return tank.getFluid(); } }
  15. (forge 9.11.1.965) Pardon me if I'm writing total nonsense (I'm kind of close to madness right now) but I've wasted hours trying to get my TileFluidHandler based TileEntitys to sync up properly when I found this in the TileFluidHandler class @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); tank.writeToNBT(tag); } @Override public void writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); tank.readFromNBT(tag); } Aren't the tank.writeToNBT() and tank.readFromNBT() swapped ?
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.