From 9d31588d8d91225923d0a545e8b2bb597109af96 Mon Sep 17 00:00:00 2001 From: Sen Date: Sun, 31 Aug 2025 11:23:30 +0200 Subject: [PATCH] revert some improved rendering --- client/src/main/java/client/Client.java | 18 +- .../java/client/gui/options/GuiGraphics.java | 11 +- .../client/renderer/DefaultVertexFormats.java | 4 +- .../java/client/renderer/RenderBuffer.java | 19 +- .../main/java/client/renderer/Renderer.java | 322 +++++++++++------- .../src/main/java/client/renderer/Shader.java | 54 +-- .../client/renderer/texture/TextureMap.java | 13 +- client/src/main/resources/shaders/grid.fsh | 40 +++ .../resources/shaders/{world.vsh => grid.vsh} | 11 +- client/src/main/resources/shaders/world.fsh | 128 ------- ...ckened_soil.png => 64x_blackened_soil.png} | Bin .../blocks/{grass.png => 64x_grass.png} | Bin ..._soil.png => 64x_snowy_blackened_soil.png} | Bin .../{snowy_grass.png => 64x_snowy_grass.png} | Bin ..._tian_soil.png => 64x_snowy_tian_soil.png} | Bin .../{tian_soil.png => 64x_tian_soil.png} | Bin .../textures/blocks/blackened_soil_side.png | Bin 0 -> 5266 bytes .../{swamp.png => blackened_soil_top.png} | Bin 6070 -> 5915 bytes .../main/resources/textures/blocks/cyber.png | Bin 84807 -> 540 bytes .../resources/textures/blocks/grass_side.png | Bin 0 -> 5115 bytes .../blocks/{grass_2.png => grass_top.png} | Bin .../resources/textures/blocks/gravel_new.png | Bin 0 -> 470 bytes .../main/resources/textures/blocks/ice.png | Bin 314 -> 320 bytes .../textures/blocks/mycelium_side.png | Bin 0 -> 5789 bytes .../blocks/{mycelium.png => mycelium_top.png} | Bin .../resources/textures/blocks/podzol_side.png | Bin 0 -> 5718 bytes .../blocks/{podzol.png => podzol_top.png} | Bin ...smooth_sandstone.png => sandstone_all.png} | Bin .../{sandstone.png => sandstone_bottom.png} | Bin .../textures/blocks/sandstone_carved.png | Bin 0 -> 596 bytes .../textures/blocks/sandstone_normal.png | Bin 0 -> 777 bytes .../textures/blocks/sandstone_smooth.png | Bin 0 -> 544 bytes .../textures/blocks/snowy_mycelium.png | Bin 496 -> 0 bytes .../textures/blocks/snowy_podzol.png | Bin 823 -> 0 bytes .../resources/textures/blocks/swamp_side.png | Bin 0 -> 5860 bytes .../blocks/{snowy_swamp.png => swamp_top.png} | Bin .../textures/blocks/tian_soil_side.png | Bin 0 -> 6230 bytes .../textures/blocks/tian_soil_snowed.png | Bin 0 -> 6090 bytes .../textures/blocks/tian_soil_top.png | Bin 0 -> 2782 bytes common/src/main/java/common/block/Block.java | 18 +- .../main/java/common/block/BlockFalling.java | 3 +- .../main/java/common/block/BlockTreasure.java | 4 +- .../common/block/artificial/BlockDoor.java | 6 + .../common/block/artificial/BlockLadder.java | 6 + .../common/block/artificial/BlockSlab.java | 22 +- .../common/block/artificial/BlockStairs.java | 15 +- .../block/artificial/BlockTrapDoor.java | 6 + .../common/block/artificial/BlockWall.java | 6 - .../block/foliage/BlockBlackenedSoil.java | 42 +-- .../common/block/foliage/BlockBlueShroom.java | 2 +- .../common/block/foliage/BlockCactus.java | 6 + .../java/common/block/foliage/BlockGrass.java | 52 ++- .../common/block/foliage/BlockLeavesBase.java | 3 +- .../common/block/foliage/BlockMushroom.java | 2 +- .../common/block/foliage/BlockMycelium.java | 68 +++- .../common/block/foliage/BlockSnowable.java | 31 -- .../java/common/block/foliage/BlockSwamp.java | 53 ++- .../common/block/foliage/BlockTianSoil.java | 38 ++- .../block/liquid/BlockDynamicLiquid.java | 8 +- .../java/common/block/liquid/BlockLiquid.java | 7 +- .../block/liquid/BlockStaticLiquid.java | 5 +- .../common/block/natural/BlockBedrock.java | 2 +- .../block/natural/BlockBlackenedDirt.java | 2 +- .../block/natural/BlockBlackenedStone.java | 2 +- .../java/common/block/natural/BlockClay.java | 2 +- .../block/natural/BlockColoredClay.java | 2 +- .../java/common/block/natural/BlockCyber.java | 15 +- .../common/block/natural/BlockGlowstone.java | 2 +- .../block/natural/BlockHardenedClay.java | 3 +- .../common/block/natural/BlockHellRock.java | 2 +- .../java/common/block/natural/BlockIce.java | 2 +- .../common/block/natural/BlockNonBlock.java | 19 -- .../common/block/natural/BlockObsidian.java | 33 +- .../java/common/block/natural/BlockOre.java | 3 +- .../common/block/natural/BlockPackedIce.java | 2 +- .../common/block/natural/BlockPodzol.java | 38 ++- .../common/block/natural/BlockSandStone.java | 15 +- .../java/common/block/natural/BlockSlime.java | 2 +- .../java/common/block/natural/BlockSnow.java | 2 +- .../common/block/natural/BlockSnowBlock.java | 2 +- .../common/block/natural/BlockSoulSand.java | 3 +- .../java/common/block/natural/BlockStone.java | 3 +- .../java/common/block/tech/BlockAnvil.java | 10 +- .../java/common/block/tech/BlockDisplay.java | 6 + .../java/common/block/tech/BlockSign.java | 6 + .../main/java/common/init/BlockRegistry.java | 96 +++--- common/src/main/java/common/init/Blocks.java | 33 +- common/src/main/java/common/init/Items.java | 13 +- 88 files changed, 735 insertions(+), 608 deletions(-) create mode 100644 client/src/main/resources/shaders/grid.fsh rename client/src/main/resources/shaders/{world.vsh => grid.vsh} (61%) delete mode 100644 client/src/main/resources/shaders/world.fsh rename client/src/main/resources/textures/blocks/{blackened_soil.png => 64x_blackened_soil.png} (100%) rename client/src/main/resources/textures/blocks/{grass.png => 64x_grass.png} (100%) rename client/src/main/resources/textures/blocks/{snowy_blackened_soil.png => 64x_snowy_blackened_soil.png} (100%) rename client/src/main/resources/textures/blocks/{snowy_grass.png => 64x_snowy_grass.png} (100%) rename client/src/main/resources/textures/blocks/{snowy_tian_soil.png => 64x_snowy_tian_soil.png} (100%) rename client/src/main/resources/textures/blocks/{tian_soil.png => 64x_tian_soil.png} (100%) create mode 100755 client/src/main/resources/textures/blocks/blackened_soil_side.png rename client/src/main/resources/textures/blocks/{swamp.png => blackened_soil_top.png} (56%) create mode 100644 client/src/main/resources/textures/blocks/grass_side.png rename client/src/main/resources/textures/blocks/{grass_2.png => grass_top.png} (100%) create mode 100755 client/src/main/resources/textures/blocks/gravel_new.png create mode 100755 client/src/main/resources/textures/blocks/mycelium_side.png rename client/src/main/resources/textures/blocks/{mycelium.png => mycelium_top.png} (100%) create mode 100755 client/src/main/resources/textures/blocks/podzol_side.png rename client/src/main/resources/textures/blocks/{podzol.png => podzol_top.png} (100%) rename client/src/main/resources/textures/blocks/{smooth_sandstone.png => sandstone_all.png} (100%) rename client/src/main/resources/textures/blocks/{sandstone.png => sandstone_bottom.png} (100%) create mode 100755 client/src/main/resources/textures/blocks/sandstone_carved.png create mode 100755 client/src/main/resources/textures/blocks/sandstone_normal.png create mode 100755 client/src/main/resources/textures/blocks/sandstone_smooth.png delete mode 100755 client/src/main/resources/textures/blocks/snowy_mycelium.png delete mode 100755 client/src/main/resources/textures/blocks/snowy_podzol.png create mode 100755 client/src/main/resources/textures/blocks/swamp_side.png rename client/src/main/resources/textures/blocks/{snowy_swamp.png => swamp_top.png} (100%) create mode 100755 client/src/main/resources/textures/blocks/tian_soil_side.png create mode 100755 client/src/main/resources/textures/blocks/tian_soil_snowed.png create mode 100755 client/src/main/resources/textures/blocks/tian_soil_top.png delete mode 100644 common/src/main/java/common/block/foliage/BlockSnowable.java delete mode 100644 common/src/main/java/common/block/natural/BlockNonBlock.java diff --git a/client/src/main/java/client/Client.java b/client/src/main/java/client/Client.java index ac900321..77362eca 100755 --- a/client/src/main/java/client/Client.java +++ b/client/src/main/java/client/Client.java @@ -311,12 +311,6 @@ public class Client implements IThreadListener { Client.CLIENT.setMidiDebug(); } } - - public static class MaxLightFunction implements IntFunction { - public void apply(IntVar cv, int value) { - Client.CLIENT.lightSetup(); - } - } public static class TextureBoolFunction implements BoolFunction { public void apply(BoolVar cv, boolean value) { @@ -727,7 +721,7 @@ public class Client implements IThreadListener { @Variable(name = "gl_dynlight_viewdist", category = CVarCategory.RENDER, min = 1.0f, max = 10000.0f, display = "Entfernung Licht Kamera") public float lightDistCam = 256.0f; - @Variable(name = "gl_dynlight_max", category = CVarCategory.RENDER, min = 0, max = 112, display = "Max. Dyn. Lichtquellen", callback = MaxLightFunction.class) + @Variable(name = "gl_dynlight_max", category = CVarCategory.RENDER, min = 0, max = 112, display = "Max. Dyn. Lichtquellen") public int lightMaximum = 64; @Variable(name = "gl_dynlight_chunkrange", category = CVarCategory.RENDER, min = 0, max = 64, display = "Lichtq. Sichtweite") public int lightDistance = 8; @@ -741,6 +735,8 @@ public class Client implements IThreadListener { public boolean specularColors = true; @Variable(name = "gl_flat_shading", category = CVarCategory.RENDER, display = "Flaches Shading") public boolean flatShading = false; + @Variable(name = "gl_use_shader", category = CVarCategory.RENDER, display = "Shader verwenden") + public boolean useShader = true; public static final Client CLIENT = new Client(); @@ -3875,14 +3871,6 @@ public class Client implements IThreadListener { return this.tiles; } - public void lightSetup() { - Shader.WORLD.update(); -// if(win->world) { -// glNamedBufferData(win->world->light_buf, LIGHT_SSIZE * gdr.light_max, NULL, GL_DYNAMIC_DRAW); -// light_calc(win->world); -// } - } - public void updateTexture() { this.textureManager.bindTexture(TextureMap.BLOCKS); TextureUtil.setParams(this.textureFiltering, this.mipmapType != MipmapType.NONE, this.mipmapType == MipmapType.LINEAR, Math.min(this.anisotopicFiltering, this.anisotropyMax)); diff --git a/client/src/main/java/client/gui/options/GuiGraphics.java b/client/src/main/java/client/gui/options/GuiGraphics.java index addfcd65..5f380e56 100644 --- a/client/src/main/java/client/gui/options/GuiGraphics.java +++ b/client/src/main/java/client/gui/options/GuiGraphics.java @@ -27,11 +27,12 @@ public class GuiGraphics extends GuiOptions { this.addSelector("gl_dynlight_viewdist", 0, 200, 240, 0); this.addSelector("gl_dynlight_maxdist", 242, 200, 240, 0); - this.addSelector("gl_light_blend", 0, 220, 240, 0); - this.addSelector("gl_specular", 242, 220, 240, 0); - - this.addSelector("gl_flat_shading", 0, 240, 240, 0); - + this.addSelector("gl_use_shader", 0, 220, 240, 0); + this.addSelector("gl_light_blend", 242, 220, 240, 0); + + this.addSelector("gl_specular", 0, 240, 240, 0); + this.addSelector("gl_flat_shading", 242, 240, 240, 0); + this.addSelector("gl_tex_filter", 0, 260, 240, 0); this.addSelector("gl_tex_mipmaps", 242, 260, 240, 0); diff --git a/client/src/main/java/client/renderer/DefaultVertexFormats.java b/client/src/main/java/client/renderer/DefaultVertexFormats.java index f9d00abc..bb1c1232 100755 --- a/client/src/main/java/client/renderer/DefaultVertexFormats.java +++ b/client/src/main/java/client/renderer/DefaultVertexFormats.java @@ -24,9 +24,9 @@ public class DefaultVertexFormats static { BLOCK.addElement(POSITION_3F); - BLOCK.addElement(NORMAL_4B); - BLOCK.addElement(TEX_2F); BLOCK.addElement(COLOR_4UB); + BLOCK.addElement(TEX_2F); + BLOCK.addElement(TEX_2S); ITEM.addElement(POSITION_3F); ITEM.addElement(COLOR_4UB); ITEM.addElement(TEX_2F); diff --git a/client/src/main/java/client/renderer/RenderBuffer.java b/client/src/main/java/client/renderer/RenderBuffer.java index 8a8345f7..4e654d88 100755 --- a/client/src/main/java/client/renderer/RenderBuffer.java +++ b/client/src/main/java/client/renderer/RenderBuffer.java @@ -169,6 +169,11 @@ public class RenderBuffer return this; } + public RenderBuffer lightmap(int light) + { + return this.lightmap(light >> 16 & 65535, light & 65535); + } + public void putBrightness4(int p_178962_1_, int p_178962_2_, int p_178962_3_, int p_178962_4_) { int i = (this.vertexCount - 4) * this.vertexFormat.getIntegerSize() + this.vertexFormat.getUvOffsetById(1) / 4; @@ -251,11 +256,6 @@ public class RenderBuffer return this.color(color >> 16 & 255, color >> 8 & 255, color & 255, color >> 24 & 255); } - public RenderBuffer lightColor(int light) - { - return this.color(light & 255, light >> 8 & 255, light >> 16 & 255, light >> 24 & 255); - } - public RenderBuffer lightNormal(int data) { int i = this.vertexCount * this.vertexFormat.getNextOffset() + this.vertexFormat.getOffset(this.vertexFormatIndex); @@ -328,6 +328,15 @@ public class RenderBuffer this.vertexCount += vertexData.length / this.vertexFormat.getIntegerSize(); } + public void addVertexData(int[] vertexData, int len) + { + this.growBuffer(len); + this.rawIntBuffer.position(this.getBufferSize()); + this.rawIntBuffer.put(vertexData); + this.vertexCount += len / this.vertexFormat.getIntegerSize(); + this.rawIntBuffer.position(this.getBufferSize()); + } + public void endVertex() { ++this.vertexCount; diff --git a/client/src/main/java/client/renderer/Renderer.java b/client/src/main/java/client/renderer/Renderer.java index 356b4903..41e2c561 100755 --- a/client/src/main/java/client/renderer/Renderer.java +++ b/client/src/main/java/client/renderer/Renderer.java @@ -41,7 +41,6 @@ import common.block.artificial.BlockSlab; import common.block.liquid.BlockDynamicLiquid; import common.block.liquid.BlockLiquid; import common.block.liquid.BlockStaticLiquid; -import common.block.tech.BlockAnvil; import common.collect.Lists; import common.collect.Maps; import common.collect.Sets; @@ -62,7 +61,6 @@ import common.sound.Sound; import common.tileentity.TileEntity; import common.util.BlockPos; import common.util.BoundingBox; -import common.util.Clientside; import common.util.ExtMath; import common.util.Facing; import common.util.HitPosition; @@ -74,7 +72,6 @@ import common.util.ParticleType; import common.util.Vec3; import common.util.Vec3i; import common.util.Vector3f; -import common.world.Chunk; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; @@ -2547,7 +2544,7 @@ public class Renderer { private int renderChunks() { - ItemRenderer.disableStandardItemLighting(); + ItemRenderer.disableStandardItemLighting(); int l = 0; int i = this.renderInfos.size(); for (int j = 0; j < i; j++) @@ -2559,66 +2556,144 @@ public class Renderer { this.renderChunks.add(renderchunk); } } - GlState.setActiveTexture(GL46.GL_TEXTURE1); - GL46.glMatrixMode(GL46.GL_TEXTURE); - GL46.glLoadIdentity(); - GL46.glMatrixMode(GL46.GL_MODELVIEW); - this.gm.getTextureManager().bindTexture(TEX_LIGHTMAP); - GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_MIN_FILTER, GL46.GL_LINEAR); - GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_MAG_FILTER, GL46.GL_LINEAR); - GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_WRAP_S, GL46.GL_CLAMP); - GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_WRAP_T, GL46.GL_CLAMP); - GlState.color(1.0F, 1.0F, 1.0F, 1.0F); - GlState.enableTexture2D(); - GlState.setActiveTexture(GL46.GL_TEXTURE0); - if (this.initialized) - { - ShaderContext context = Shader.WORLD.use(); - context.bool("sky_light", this.skyLight); - context.bool("moon_light", this.moonLight); - for (RenderChunk renderchunk : this.renderChunks) + if(this.gm.useShader && this.gm.dimensionName.equals("cyberspace")) { + GlState.setActiveTexture(GL46.GL_TEXTURE1); + GL46.glMatrixMode(GL46.GL_TEXTURE); + GL46.glLoadIdentity(); + GL46.glMatrixMode(GL46.GL_MODELVIEW); + this.gm.getTextureManager().bindTexture(TEX_LIGHTMAP); + GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_MIN_FILTER, GL46.GL_LINEAR); + GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_MAG_FILTER, GL46.GL_LINEAR); + GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_WRAP_S, GL46.GL_CLAMP); + GL46.glTexParameteri(GL46.GL_TEXTURE_2D, GL46.GL_TEXTURE_WRAP_T, GL46.GL_CLAMP); + GlState.color(1.0F, 1.0F, 1.0F, 1.0F); + GlState.enableTexture2D(); + GlState.setActiveTexture(GL46.GL_TEXTURE0); + + if (this.initialized) { - VertexBuffer vertexbuffer = renderchunk.getVertexBuffer(); - - BlockPos blockpos = renderchunk.getPosition(); - context.vec("offset", (float)((double)blockpos.getX() - this.viewEntityX), (float)((double)blockpos.getY() - this.viewEntityY), (float)((double)blockpos.getZ() - this.viewEntityZ)); - // Vec3 cam = MatrixState.project(Client.CLIENT.getRenderViewEntity(), Client.CLIENT.getTickFraction()); - context.vec("cam_pos", (float)this.viewEntityX, (float)this.viewEntityY + this.gm.player.getEyeHeight(), (float)this.viewEntityZ); - context.matrix("model", renderchunk.getModelviewMatrix()); - context.integer("chunk_x", blockpos.getX()); - context.integer("chunk_y", blockpos.getY()); - context.integer("chunk_z", blockpos.getZ()); - - vertexbuffer.bindBuffer(); + ShaderContext context = Shader.GRID.use(); + for (RenderChunk renderchunk : this.renderChunks) + { + VertexBuffer vertexbuffer = renderchunk.getVertexBuffer(); + + BlockPos blockpos = renderchunk.getPosition(); + context.vec("offset", (float)((double)blockpos.getX() - this.viewEntityX), (float)((double)blockpos.getY() - this.viewEntityY), (float)((double)blockpos.getZ() - this.viewEntityZ)); + context.matrix("model", renderchunk.getModelviewMatrix()); + context.integer("chunk_x", blockpos.getX()); + context.integer("chunk_y", blockpos.getY()); + context.integer("chunk_z", blockpos.getZ()); + + vertexbuffer.bindBuffer(); - GL46.glVertexAttribPointer(0, 3, GL46.GL_FLOAT, false, 28, 0L); - GL46.glEnableVertexAttribArray(0); - GL46.glVertexAttribPointer(1, 4, GL46.GL_BYTE, true, 28, 12L); - GL46.glEnableVertexAttribArray(1); - GL46.glVertexAttribPointer(2, 2, GL46.GL_FLOAT, false, 28, 16L); - GL46.glEnableVertexAttribArray(2); - GL46.glVertexAttribPointer(3, 4, GL46.GL_UNSIGNED_BYTE, true, 28, 24L); - GL46.glEnableVertexAttribArray(3); - - vertexbuffer.drawArrays(GL46.GL_QUADS); + GL46.glVertexAttribPointer(0, 3, GL46.GL_FLOAT, false, 28, 0L); + GL46.glEnableVertexAttribArray(0); + GL46.glVertexAttribPointer(1, 4, GL46.GL_BYTE, true, 28, 12L); + GL46.glEnableVertexAttribArray(1); + GL46.glVertexAttribPointer(2, 2, GL46.GL_FLOAT, false, 28, 16L); + GL46.glEnableVertexAttribArray(2); + GL46.glVertexAttribPointer(3, 4, GL46.GL_UNSIGNED_BYTE, true, 28, 24L); + GL46.glEnableVertexAttribArray(3); + + vertexbuffer.drawArrays(GL46.GL_QUADS); - GL46.glDisableVertexAttribArray(0); - GL46.glDisableVertexAttribArray(1); - GL46.glDisableVertexAttribArray(2); - GL46.glDisableVertexAttribArray(3); + GL46.glDisableVertexAttribArray(0); + GL46.glDisableVertexAttribArray(1); + GL46.glDisableVertexAttribArray(2); + GL46.glDisableVertexAttribArray(3); + } + context.finish(); + + GL46.glBindBuffer(GL46.GL_ARRAY_BUFFER, 0); + GlState.resetColor(); + this.renderChunks.clear(); } - context.finish(); + } + else { + this.gm.renderer.enableLightmap(); - GL46.glBindBuffer(GL46.GL_ARRAY_BUFFER, 0); - GlState.resetColor(); - this.renderChunks.clear(); + GL46.glEnableClientState(GL46.GL_VERTEX_ARRAY); + GL46.glClientActiveTexture(GL46.GL_TEXTURE0); + GL46.glEnableClientState(GL46.GL_TEXTURE_COORD_ARRAY); + GL46.glClientActiveTexture(GL46.GL_TEXTURE1); + GL46.glEnableClientState(GL46.GL_TEXTURE_COORD_ARRAY); + GL46.glClientActiveTexture(GL46.GL_TEXTURE0); + GL46.glEnableClientState(GL46.GL_COLOR_ARRAY); + + if (this.initialized) + { + for (RenderChunk renderchunk : this.renderChunks) + { + VertexBuffer vertexbuffer = renderchunk.getVertexBuffer(); + GL46.glPushMatrix(); + this.preRenderChunk(renderchunk); + GL46.glMultMatrixf(renderchunk.getModelviewMatrix()); + vertexbuffer.bindBuffer(); + this.setupArrayPointers(); + vertexbuffer.drawArrays(GL46.GL_QUADS); + GL46.glPopMatrix(); + } + + GL46.glBindBuffer(GL46.GL_ARRAY_BUFFER, 0); + GlState.resetColor(); + this.renderChunks.clear(); + } + + for (VertexFormatElement vertexformatelement : DefaultVertexFormats.BLOCK.getElements()) + { + VertexFormatElement.EnumUsage vertexformatelement$enumusage = vertexformatelement.usage(); + int s = vertexformatelement.index(); + + switch (vertexformatelement$enumusage) + { + case POSITION: + GL46.glDisableClientState(GL46.GL_VERTEX_ARRAY); + break; + + case UV: + GL46.glClientActiveTexture(GL46.GL_TEXTURE0 + s); + GL46.glDisableClientState(GL46.GL_TEXTURE_COORD_ARRAY); + GL46.glClientActiveTexture(GL46.GL_TEXTURE0); + break; + + case COLOR: + GL46.glDisableClientState(GL46.GL_COLOR_ARRAY); + GlState.resetColor(); + } + } } this.gm.renderer.disableLightmap(); return l; } +// private void setupArrayPointers() +// { +// GL46.nglVertexPointer(3, GL46.GL_FLOAT, 32, 0L); +// GL46.glTexCoordPointer(2, GL46.GL_FLOAT, 32, 16L); +// GL46.nglColorPointer(4, GL46.GL_UNSIGNED_BYTE, 32, 24L); +// GL46.glClientActiveTexture(GL46.GL_TEXTURE1); +// GL46.glTexCoordPointer(2, GL46.GL_SHORT, 32, 28L); +// GL46.glClientActiveTexture(GL46.GL_TEXTURE0); +// } + + private void setupArrayPointers() + { + GL46.nglVertexPointer(3, GL46.GL_FLOAT, 28, 0L); + GL46.nglColorPointer(4, GL46.GL_UNSIGNED_BYTE, 28, 12L); + GL46.glTexCoordPointer(2, GL46.GL_FLOAT, 28, 16L); + GL46.glClientActiveTexture(GL46.GL_TEXTURE1); + GL46.glTexCoordPointer(2, GL46.GL_SHORT, 28, 24L); + GL46.glClientActiveTexture(GL46.GL_TEXTURE0); + } + + private void preRenderChunk(RenderChunk renderChunkIn) + { + BlockPos blockpos = renderChunkIn.getPosition(); + GL46.glTranslatef((float)((double)blockpos.getX() - this.viewEntityX), (float)((double)blockpos.getY() - this.viewEntityY), (float)((double)blockpos.getZ() - this.viewEntityZ)); + } + private void renderSkyBox(String texture) { GlState.disableFog(); @@ -3285,6 +3360,26 @@ public class Renderer { } return 0xff000000 | (int)(Math.min(directR, 1.0f) * 255.0f) << 16 | (int)(Math.min(directG, 1.0f) * 255.0f) << 8 | (int)(Math.min(directB, 1.0f) * 255.0f); } + + public int getWorldColor(BlockPos pos, Facing side, int light, boolean flip) { + float sky = this.skyLight ? pos.getY() < 0 ? 0.0f : (pos.getY() < 64 ? (float)pos.getY() / 64.0f : 1.0f) : 1.0f; + float shading = side == null ? 1.0f : FaceBakery.getFaceBrightness(side); + float max = (float)Math.max(Math.max((light >> 16) & 0xff, (light >> 8) & 0xff), light & 0xff) / 255.0f; + max = sky * (1.0f - max * this.gm.lightBlend); + float directR = ((float)(light >> 16 & 0xff) / 255.0f + max) * shading; + float directG = ((float)(light >> 8 & 0xff) / 255.0f + max) * shading; + float directB = ((float)(light & 0xff) / 255.0f + max) * shading; + return 0xff000000 | (int)(Math.min(flip ? directB : directR, 1.0f) * 255.0f) << 16 | (int)(Math.min(directG, 1.0f) * 255.0f) << 8 | (int)(Math.min(flip ? directR : directB, 1.0f) * 255.0f); + } + + public int getSkyBrightness(BlockPos pos) { + int light = this.getCombinedLight(pos); + float sky = this.skyLight ? pos.getY() < 0 ? 0.0f : (pos.getY() < 64 ? (float)pos.getY() / 64.0f : 1.0f) : 1.0f; + float max = (float)Math.max(Math.max((light >> 16) & 0xff, (light >> 8) & 0xff), light & 0xff) / 255.0f; + max = sky * (1.0f - max * this.gm.lightBlend); + light = (int)(max * 255.0f) / 16; + return light << 20 | 1 << 4; + } public int getCombinedBrightness(BlockPos pos) { int light = this.getLightColor(pos, null); @@ -3320,29 +3415,26 @@ public class Renderer { if(!list.isEmpty()) { BlockPos bpos = pos.offset(side); if(!checkSides || block.canRender(world, bpos, side)) { - int light = getLightmapValue(world, bpos); - this.renderModelStandardQuads(world, block, pos, side, light, false, rb, list, bounds); + int light = this.getLightmapValue(world, bpos, side); + int sky = this.getSkyBrightness(bpos); + this.renderModelStandardQuads(world, block, pos, side, light, sky, false, rb, list, bounds); rendered = true; } } } List list = model.getQuads(); if(list.size() > 0) { - this.renderModelStandardQuads(world, block, pos, null, 0xffffffff, true, rb, list, bounds); + this.renderModelStandardQuads(world, block, pos, null, 0xffffffff, 0xffffffff, true, rb, list, bounds); rendered = true; } return rendered; } - public static int getLightColor(int light) { - return Math.max(Math.max((light >> 16) & 0xff, (light >> 8) & 0xff), light & 0xff) << 24 | (light & 0x00ff00) | ((light >> 16) & 0xff) | ((light & 0xff) << 16); - } - public static int componentMax(int lightA, int lightB) { return Math.max((lightA >> 16) & 0xff, (lightB >> 16) & 0xff) << 16 | Math.max((lightA >> 8) & 0xff, (lightB >> 8) & 0xff) << 8 | Math.max(lightA & 0xff, lightB & 0xff); } - private int getLightmapValue(IWorldAccess world, BlockPos pos) { + private int getLightmapValue(IWorldAccess world, BlockPos pos, Facing side) { Block block = world.getState(pos).getBlock(); int light = componentMax(world.getCombinedLight(pos), block.getLight()); if(light == 0 && block instanceof BlockSlab) { @@ -3350,16 +3442,16 @@ public class Renderer { block = world.getState(pos).getBlock(); light = componentMax(world.getCombinedLight(pos), block.getLight()); } - return getLightColor(light); + return getWorldColor(pos, side, light, true); } - private int getLightmapValueLiquid(IWorldAccess world, BlockPos pos) { + private int getLightmapValueLiquid(IWorldAccess world, BlockPos pos, Facing side) { int light = world.getCombinedLight(pos); int up = world.getCombinedLight(pos.up()); - return getLightColor(componentMax(light, up)); + return getWorldColor(pos, side, componentMax(light, up), false); } - private void renderModelStandardQuads(IWorldAccess blockAccessIn, Block blockIn, BlockPos blockPosIn, Facing faceIn, int light, boolean ownLight, RenderBuffer worldRendererIn, List listQuadsIn, BitSet boundsFlags) + private void renderModelStandardQuads(IWorldAccess blockAccessIn, Block blockIn, BlockPos blockPosIn, Facing faceIn, int light, int sky, boolean ownLight, RenderBuffer worldRendererIn, List listQuadsIn, BitSet boundsFlags) { double d0 = (double)blockPosIn.getX(); double d1 = (double)blockPosIn.getY(); @@ -3370,11 +3462,13 @@ public class Renderer { if (ownLight) { this.fillQuadBounds(blockIn, bakedquad.getVertexData(), bakedquad.getFace(), (float[])null, boundsFlags); - light = boundsFlags.get(0) ? getLightmapValue(blockAccessIn, blockPosIn.offset(bakedquad.getFace())) : getLightmapValue(blockAccessIn, blockPosIn); + light = boundsFlags.get(0) ? this.getLightmapValue(blockAccessIn, blockPosIn.offset(bakedquad.getFace()), bakedquad.getFace()) : this.getLightmapValue(blockAccessIn, blockPosIn, bakedquad.getFace()); + sky = this.getSkyBrightness(boundsFlags.get(0) ? blockPosIn.offset(bakedquad.getFace()) : blockPosIn); } worldRendererIn.addVertexData(bakedquad.getVertexData()); worldRendererIn.putColor4Light(light, light, light, light); + worldRendererIn.putBrightness4(sky, sky, sky, sky); worldRendererIn.putPosition(d0, d1, d2); } } @@ -3529,19 +3623,19 @@ public class Renderer { f20 = textureatlassprite.getInterpolatedV((double)(8.0F + (-f22 - f21) * 16.0F)); } - int light = getLightmapValueLiquid(blockAccess, blockPosIn); - int norm = FaceBakery.getFaceNormal(shine, Facing.UP); - worldRendererIn.pos(d0 + 0.0D, d1 + (double)f7, d2 + 0.0D).lightNormal(norm).tex((double)f13, (double)f17).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 0.0D, d1 + (double)f8, d2 + 1.0D).lightNormal(norm).tex((double)f14, (double)f18).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1 + (double)f9, d2 + 1.0D).lightNormal(norm).tex((double)f15, (double)f19).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1 + (double)f10, d2 + 0.0D).lightNormal(norm).tex((double)f16, (double)f20).lightColor(light).endVertex(); + int light = this.getLightmapValueLiquid(blockAccess, blockPosIn, Facing.UP); + int sky = this.getSkyBrightness(blockPosIn); + worldRendererIn.pos(d0 + 0.0D, d1 + (double)f7, d2 + 0.0D).color(light).tex((double)f13, (double)f17).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 0.0D, d1 + (double)f8, d2 + 1.0D).color(light).tex((double)f14, (double)f18).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1 + (double)f9, d2 + 1.0D).color(light).tex((double)f15, (double)f19).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1 + (double)f10, d2 + 0.0D).color(light).tex((double)f16, (double)f20).lightmap(sky).endVertex(); if (blockliquid.shouldRenderSides(blockAccess, blockPosIn.up())) { - worldRendererIn.pos(d0 + 0.0D, d1 + (double)f7, d2 + 0.0D).lightNormal(norm).tex((double)f13, (double)f17).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1 + (double)f10, d2 + 0.0D).lightNormal(norm).tex((double)f16, (double)f20).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1 + (double)f9, d2 + 1.0D).lightNormal(norm).tex((double)f15, (double)f19).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 0.0D, d1 + (double)f8, d2 + 1.0D).lightNormal(norm).tex((double)f14, (double)f18).lightColor(light).endVertex(); + worldRendererIn.pos(d0 + 0.0D, d1 + (double)f7, d2 + 0.0D).color(light).tex((double)f13, (double)f17).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1 + (double)f10, d2 + 0.0D).color(light).tex((double)f16, (double)f20).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1 + (double)f9, d2 + 1.0D).color(light).tex((double)f15, (double)f19).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 0.0D, d1 + (double)f8, d2 + 1.0D).color(light).tex((double)f14, (double)f18).lightmap(sky).endVertex(); } } @@ -3551,12 +3645,12 @@ public class Renderer { float f36 = atextureatlassprite[0].getMaxU(); float f37 = atextureatlassprite[0].getMinV(); float f38 = atextureatlassprite[0].getMaxV(); - int light = getLightmapValueLiquid(blockAccess, blockPosIn.down()); - int norm = FaceBakery.getFaceNormal(shine, Facing.DOWN); - worldRendererIn.pos(d0, d1, d2 + 1.0D).lightNormal(norm).tex((double)f35, (double)f38).lightColor(light).endVertex(); - worldRendererIn.pos(d0, d1, d2).lightNormal(norm).tex((double)f35, (double)f37).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1, d2).lightNormal(norm).tex((double)f36, (double)f37).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1, d2 + 1.0D).lightNormal(norm).tex((double)f36, (double)f38).lightColor(light).endVertex(); + int light = this.getLightmapValueLiquid(blockAccess, blockPosIn.down(), Facing.DOWN); + int sky = this.getSkyBrightness(blockPosIn.down()); + worldRendererIn.pos(d0, d1, d2 + 1.0D).color(light).tex((double)f35, (double)f38).lightmap(sky).endVertex(); + worldRendererIn.pos(d0, d1, d2).color(light).tex((double)f35, (double)f37).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1, d2).color(light).tex((double)f36, (double)f37).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1, d2 + 1.0D).color(light).tex((double)f36, (double)f38).lightmap(sky).endVertex(); rendered = true; } @@ -3640,16 +3734,16 @@ public class Renderer { float f28 = textureatlassprite1.getInterpolatedV((double)((1.0F - f39) * 16.0F * 0.5F)); float f29 = textureatlassprite1.getInterpolatedV((double)((1.0F - f40) * 16.0F * 0.5F)); float f30 = textureatlassprite1.getInterpolatedV(8.0D); - int light = getLightmapValueLiquid(blockAccess, blockpos); - int norm = FaceBakery.getFaceNormal(shine, np == 0 ? Facing.NORTH : (np == 1 ? Facing.SOUTH : (np == 2 ? Facing.WEST : Facing.EAST))); - worldRendererIn.pos(d3, d1 + (double)f39, d4).lightNormal(norm).tex((double)f41, (double)f28).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + (double)f40, d6).lightNormal(norm).tex((double)f27, (double)f29).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + 0.0D, d6).lightNormal(norm).tex((double)f27, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d3, d1 + 0.0D, d4).lightNormal(norm).tex((double)f41, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d3, d1 + 0.0D, d4).lightNormal(norm).tex((double)f41, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + 0.0D, d6).lightNormal(norm).tex((double)f27, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + (double)f40, d6).lightNormal(norm).tex((double)f27, (double)f29).lightColor(light).endVertex(); - worldRendererIn.pos(d3, d1 + (double)f39, d4).lightNormal(norm).tex((double)f41, (double)f28).lightColor(light).endVertex(); + int light = this.getLightmapValueLiquid(blockAccess, blockpos, np == 0 ? Facing.NORTH : (np == 1 ? Facing.SOUTH : (np == 2 ? Facing.WEST : Facing.EAST))); + int sky = this.getSkyBrightness(blockpos); + worldRendererIn.pos(d3, d1 + (double)f39, d4).color(light).tex((double)f41, (double)f28).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + (double)f40, d6).color(light).tex((double)f27, (double)f29).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + 0.0D, d6).color(light).tex((double)f27, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d3, d1 + 0.0D, d4).color(light).tex((double)f41, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d3, d1 + 0.0D, d4).color(light).tex((double)f41, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + 0.0D, d6).color(light).tex((double)f27, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + (double)f40, d6).color(light).tex((double)f27, (double)f29).lightmap(sky).endVertex(); + worldRendererIn.pos(d3, d1 + (double)f39, d4).color(light).tex((double)f41, (double)f28).lightmap(sky).endVertex(); } } @@ -3752,12 +3846,12 @@ public class Renderer { f16 = f15; f20 = f17; - int light = getLightmapValueLiquid(blockAccess, blockPosIn); - int norm = FaceBakery.getFaceNormal(shine, Facing.UP); - worldRendererIn.pos(d0 + 0.0D, d1 + (double)f7, d2 + 0.0D).lightNormal(norm).tex((double)f13, (double)f17).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 0.0D, d1 + (double)f8, d2 + 1.0D).lightNormal(norm).tex((double)f14, (double)f18).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1 + (double)f9, d2 + 1.0D).lightNormal(norm).tex((double)f15, (double)f19).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1 + (double)f10, d2 + 0.0D).lightNormal(norm).tex((double)f16, (double)f20).lightColor(light).endVertex(); + int light = this.getLightmapValueLiquid(blockAccess, blockPosIn, Facing.UP); + int sky = this.getSkyBrightness(blockPosIn); + worldRendererIn.pos(d0 + 0.0D, d1 + (double)f7, d2 + 0.0D).color(light).tex((double)f13, (double)f17).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 0.0D, d1 + (double)f8, d2 + 1.0D).color(light).tex((double)f14, (double)f18).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1 + (double)f9, d2 + 1.0D).color(light).tex((double)f15, (double)f19).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1 + (double)f10, d2 + 0.0D).color(light).tex((double)f16, (double)f20).lightmap(sky).endVertex(); // // if (block.shouldRenderSides(blockAccess, blockPosIn.up())) // { @@ -3774,12 +3868,12 @@ public class Renderer { float f36 = textureatlassprite.getMaxU(); float f37 = textureatlassprite.getMinV(); float f38 = textureatlassprite.getMaxV(); - int light = getLightmapValueLiquid(blockAccess, blockPosIn.down()); - int norm = FaceBakery.getFaceNormal(shine, Facing.DOWN); - worldRendererIn.pos(d0, d1, d2 + 1.0D).lightNormal(norm).tex((double)f35, (double)f38).lightColor(light).endVertex(); - worldRendererIn.pos(d0, d1, d2).lightNormal(norm).tex((double)f35, (double)f37).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1, d2).lightNormal(norm).tex((double)f36, (double)f37).lightColor(light).endVertex(); - worldRendererIn.pos(d0 + 1.0D, d1, d2 + 1.0D).lightNormal(norm).tex((double)f36, (double)f38).lightColor(light).endVertex(); + int light = this.getLightmapValueLiquid(blockAccess, blockPosIn.down(), Facing.DOWN); + int sky = this.getSkyBrightness(blockPosIn.down()); + worldRendererIn.pos(d0, d1, d2 + 1.0D).color(light).tex((double)f35, (double)f38).lightmap(sky).endVertex(); + worldRendererIn.pos(d0, d1, d2).color(light).tex((double)f35, (double)f37).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1, d2).color(light).tex((double)f36, (double)f37).lightmap(sky).endVertex(); + worldRendererIn.pos(d0 + 1.0D, d1, d2 + 1.0D).color(light).tex((double)f36, (double)f38).lightmap(sky).endVertex(); rendered = true; } @@ -3863,16 +3957,16 @@ public class Renderer { float f28 = textureatlassprite1.getInterpolatedV((double)((1.0F - f39) * 16.0F)); float f29 = textureatlassprite1.getInterpolatedV((double)((1.0F - f40) * 16.0F)); float f30 = textureatlassprite1.getInterpolatedV(16.0D); - int light = getLightmapValueLiquid(blockAccess, blockpos); - int norm = FaceBakery.getFaceNormal(shine, np == 0 ? Facing.NORTH : (np == 1 ? Facing.SOUTH : (np == 2 ? Facing.WEST : Facing.EAST))); - worldRendererIn.pos(d3, d1 + (double)f39, d4).lightNormal(norm).tex((double)f41, (double)f28).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + (double)f40, d6).lightNormal(norm).tex((double)f27, (double)f29).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + 0.0D, d6).lightNormal(norm).tex((double)f27, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d3, d1 + 0.0D, d4).lightNormal(norm).tex((double)f41, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d3, d1 + 0.0D, d4).lightNormal(norm).tex((double)f41, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + 0.0D, d6).lightNormal(norm).tex((double)f27, (double)f30).lightColor(light).endVertex(); - worldRendererIn.pos(d5, d1 + (double)f40, d6).lightNormal(norm).tex((double)f27, (double)f29).lightColor(light).endVertex(); - worldRendererIn.pos(d3, d1 + (double)f39, d4).lightNormal(norm).tex((double)f41, (double)f28).lightColor(light).endVertex(); + int light = this.getLightmapValueLiquid(blockAccess, blockpos, np == 0 ? Facing.NORTH : (np == 1 ? Facing.SOUTH : (np == 2 ? Facing.WEST : Facing.EAST))); + int sky = this.getSkyBrightness(blockpos); + worldRendererIn.pos(d3, d1 + (double)f39, d4).color(light).tex((double)f41, (double)f28).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + (double)f40, d6).color(light).tex((double)f27, (double)f29).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + 0.0D, d6).color(light).tex((double)f27, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d3, d1 + 0.0D, d4).color(light).tex((double)f41, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d3, d1 + 0.0D, d4).color(light).tex((double)f41, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + 0.0D, d6).color(light).tex((double)f27, (double)f30).lightmap(sky).endVertex(); + worldRendererIn.pos(d5, d1 + (double)f40, d6).color(light).tex((double)f27, (double)f29).lightmap(sky).endVertex(); + worldRendererIn.pos(d3, d1 + (double)f39, d4).color(light).tex((double)f41, (double)f28).lightmap(sky).endVertex(); } } @@ -3906,7 +4000,7 @@ public class Renderer { if (!material.isNonBlock()) // material != block { - if (!material.canConnectNonBlock()) + if (material == Blocks.air) { ++a; f += 4; diff --git a/client/src/main/java/client/renderer/Shader.java b/client/src/main/java/client/renderer/Shader.java index cc33eaca..5583fbba 100644 --- a/client/src/main/java/client/renderer/Shader.java +++ b/client/src/main/java/client/renderer/Shader.java @@ -15,7 +15,6 @@ import client.Client; import client.util.FileUtils; import common.collect.Maps; import common.log.Log; -import common.util.ExtMath; import common.util.Matrix4f; import common.util.Util; import common.util.Vec3; @@ -23,56 +22,18 @@ import common.util.Vector3f; import common.util.Vector4f; public enum Shader { - WORLD("world", "world", context -> {context.integer("tex", 0); /* GL46.glUniformBlockBinding(context.getProgram(), GL46.glGetUniformBlockIndex(context.getProgram(), "light_block"), 0); */}, context -> { - context.vec("clip_near", Client.CLIENT.renderer.getNearPlane()); - context.vec("clip_far", Client.CLIENT.renderer.getFarPlane()); - context.vec("screen", (float)Client.CLIENT.fbRawX, (float)Client.CLIENT.fbRawY); + GRID("grid", "grid", context -> {context.integer("tex", 0);}, context -> { context.matrix("view", MatrixState.getModelView()); context.matrix("projection", MatrixState.getProjection()); context.vec("time", (float)Util.ftime()); - - float angle = -90.0f + Client.CLIENT.renderer.getCelestialAngle(Client.CLIENT.getTickFraction()); - - float sunX = !Client.CLIENT.world.dimension.hasDaylight() ? 0.0f : ExtMath.cos(angle / 180.0f * (float)Math.PI); - float sunY = !Client.CLIENT.world.dimension.hasDaylight() ? -1.0f : ExtMath.sin(angle / 180.0f * (float)Math.PI); - context.vec("sun_direction", sunX, sunY, 0.0f); - - float moonX = !Client.CLIENT.world.dimension.hasDaylight() ? 0.0f : ExtMath.cos((180.0f + angle) / 180.0f * (float)Math.PI); - float moonY = !Client.CLIENT.world.dimension.hasDaylight() ? -1.0f : ExtMath.sin((180.0f + angle) / 180.0f * (float)Math.PI); - context.vec("moon_direction", moonX, moonY, 0.0f); - - float sunRed = Client.CLIENT.renderer.getSunColorRed(); - float sunGreen = Client.CLIENT.renderer.getSunColorGreen(); - float sunBlue = Client.CLIENT.renderer.getSunColorBlue(); - context.vec("sun_ambient", sunRed, sunGreen, sunBlue); - - float moonRed = Client.CLIENT.renderer.getMoonColorRed(); - float moonGreen = Client.CLIENT.renderer.getMoonColorGreen(); - float moonBlue = Client.CLIENT.renderer.getMoonColorBlue(); - context.vec("moon_ambient", moonRed, moonGreen, moonBlue); - - context.vec("light_factor", Client.CLIENT.lightBlend); - context.vec("max_vert_dist", Client.CLIENT.lightDistVert); - context.vec("max_cam_dist", Client.CLIENT.lightDistCam); - context.integer("n_lights", 0); - - context.color3("specular", Client.CLIENT.specularColors && !Client.CLIENT.setGamma && !Client.CLIENT.xrayActive ? 0xffffff : 0x000000); - context.bool("shade", Client.CLIENT.flatShading || Client.CLIENT.setGamma || Client.CLIENT.xrayActive); - - GlState.setActiveTexture(GL46.GL_TEXTURE0); -// glBindBufferBase(GL_UNIFORM_BUFFER, 0, world->light_buf); - }, "MAX_LIGHTS", (Supplier)() -> Client.CLIENT.lightMaximum), + context.vec("tex_mul", (float)Client.CLIENT.getTextureMapBlocks().getWidth() / 16.0f, (float)Client.CLIENT.getTextureMapBlocks().getHeight() / 16.0f); + }), VIS("vis", "vis", null, context -> { context.matrix("view", MatrixState.getModelView()); context.matrix("projection", MatrixState.getProjection()); }); -// BLIT("blit", "blit", context -> context.integer("tex", 0), context -> { -// GL46.glBindVertexArray(QUAD); -// GlState.setActiveTexture(GL46.GL_TEXTURE0); -// }); - public class ShaderContext { private final int program; @@ -314,13 +275,4 @@ public enum Shader { if(this.program != 0 && !this.load()) Log.RENDER.error("Konnte Shader-Programm '%s' nicht neu laden", this.name()); } - -// void shd_setint(int *pos, const char *vardef, int value) { -// *pos += sprintf(&gdr.shd_include[*pos], "#define %s %d\n", vardef, value); -// } -// -// void shd_setvars() { -// int pos = 0; -// shd_setint(&pos, "MAX_LIGHTS", gdr.light_max < 1 ? 1 : gdr.light_max); -// } } diff --git a/client/src/main/java/client/renderer/texture/TextureMap.java b/client/src/main/java/client/renderer/texture/TextureMap.java index 18c9c9d6..2f47664c 100755 --- a/client/src/main/java/client/renderer/texture/TextureMap.java +++ b/client/src/main/java/client/renderer/texture/TextureMap.java @@ -33,6 +33,9 @@ public class TextureMap extends Texture private final Map tickedTextures; private final Map animTextures; private final Sprite missingImage; + + private int width; + private int height; public TextureMap() { @@ -62,6 +65,14 @@ public class TextureMap extends Texture map.clear(); anim.clear(); } + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } private void initMissingImage() { @@ -146,7 +157,7 @@ public class TextureMap extends Texture } Log.RENDER.info("Textur-Atlas in Größe " + stitcher.getCurrentWidth() + "x" + stitcher.getCurrentHeight() + " erstellt"); - TextureUtil.allocateTexture(this.getGlTextureId(), stitcher.getCurrentWidth(), stitcher.getCurrentHeight()); + TextureUtil.allocateTexture(this.getGlTextureId(), this.width = stitcher.getCurrentWidth(), this.height = stitcher.getCurrentHeight()); Map map = Maps.newHashMap(this.mapRegisteredSprites); for (Sprite textureatlassprite2 : stitcher.getStichSlots()) diff --git a/client/src/main/resources/shaders/grid.fsh b/client/src/main/resources/shaders/grid.fsh new file mode 100644 index 00000000..7ebf58a7 --- /dev/null +++ b/client/src/main/resources/shaders/grid.fsh @@ -0,0 +1,40 @@ +#define GLM_PI 3.14159265358979323846264338327950288 +#define GLM_SQRT2 1.41421356237309504880168872420969808 +#define vis_div 24.0 + +out vec4 FragColor; + +in vec3 vertex; +in vec2 tex_coord; + +uniform vec2 tex_mul; +uniform float time; + +float v2rand(vec2 uv) { + return fract(sin(dot(uv, vec2(12.9898,78.233))) * 43758.5453123); +} + +float avg(vec4 v) { + return ((v.r + v.g + v.b) / 3.0) * v.a; +} + +float gauss(float v, float b, float c) { + return (1.0 / (c * sqrt(2.0 * GLM_PI))) * exp(-(pow(v - b, 2.0) / (2.0 * pow(c, 2.0)))); +} + +float dgauss(float v, float b, float c) { + return b + v * c; +} + +float inside(vec2 vec, vec2 offs, float a, float b, float scale, float x1, float x2, float y1, float y2) { + vec2 cscaled = (mod(vec + offs + 1.0, 1.0)) * scale; + return (x2 < x1 ? (cscaled.x >= x1 || cscaled.x <= x2) : (cscaled.x >= x1 && cscaled.x <= x2)) || (y2 < y1 ? (cscaled.y >= y1 || cscaled.y <= y2) : (cscaled.y >= y1 && cscaled.y <= y2)) || (abs(cscaled.y - (cscaled.x - (x2 < x1 ? (x1 - x2) : (x2 - x1)) * GLM_SQRT2 * (x2 < x1 ? 0.0 : (x1 < scale / 2.0 ? x1 : (x2 - scale))))) < GLM_SQRT2) ? b : a; +} + +void main() { + vec2 coord = fract(tex_coord * tex_mul) * vis_div; + vec2 shift = vec2(v2rand(coord + fract(time)) * 2.0 - 1.0, v2rand(coord + 0.5 + fract(time)) * 2.0 - 1.0); + shift = vec2(dgauss(shift.x, 0.0, 1.0), dgauss(shift.y, 0.0, 1.0)) * 0.015; + vec3 cl = vec3(inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 1.0, 3.0, 1.0, 3.0), inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 63.0, 1.0, 63.0, 1.0), inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 61.0, 63.0, 61.0, 63.0)); + FragColor = vec4(mix(vec3(0.0, 0.0, clamp(0.1 + 0.2 * (vertex.y + 64.0) / 128.0, 0.0, 1.0)), cl, clamp(cl.x + cl.y + cl.z, 0.0, 1.0)), 1.0); +} diff --git a/client/src/main/resources/shaders/world.vsh b/client/src/main/resources/shaders/grid.vsh similarity index 61% rename from client/src/main/resources/shaders/world.vsh rename to client/src/main/resources/shaders/grid.vsh index 13219afe..a6c592d7 100644 --- a/client/src/main/resources/shaders/world.vsh +++ b/client/src/main/resources/shaders/grid.vsh @@ -1,14 +1,10 @@ layout (location = 0) in vec3 pos; -layout (location = 1) in vec4 norm; +layout (location = 1) in vec4 color; layout (location = 2) in vec2 coord; layout (location = 3) in vec4 light; out vec3 vertex; -out vec3 normal; out vec2 tex_coord; -out vec4 light_color; -out float shine; -out float shading; uniform mat4 model; uniform mat4 view; @@ -17,15 +13,10 @@ uniform vec3 offset; uniform int chunk_x; uniform int chunk_y; uniform int chunk_z; -uniform bool shade; void main() { vec3 nvertex = vec3(model * vec4(pos, 1.0)); vertex = vec3(float(chunk_x) + pos.x, float(chunk_y) + pos.y, float(chunk_z) + pos.z); - shading = shade ? (norm.x != 0.0 ? 0.6 : (norm.z != 0.0 ? 0.8 : (norm.y < 0.0 ? 0.5 : 1.0))) : 1.0; - normal = mat3(transpose(inverse(model))) * norm.xyz; - shine = norm.a * 32.0; tex_coord = coord; - light_color = light; gl_Position = projection * view * vec4(offset + nvertex, 1.0); } diff --git a/client/src/main/resources/shaders/world.fsh b/client/src/main/resources/shaders/world.fsh deleted file mode 100644 index 14c8ff8f..00000000 --- a/client/src/main/resources/shaders/world.fsh +++ /dev/null @@ -1,128 +0,0 @@ -#define GLM_PI 3.14159265358979323846264338327950288 -#define GLM_SQRT2 1.41421356237309504880168872420969808 -#define vis_div 24.0 - -out vec4 FragColor; - -struct light_t { - vec4 position; - vec4 ambient; // constant - vec4 diffuse; // linear - vec4 specular; // quadratic - vec4 range; -}; - -in vec3 vertex; -in vec3 normal; -in vec2 tex_coord; -in vec4 light_color; -in float shine; -in float shading; - -uniform vec3 cam_pos; -uniform sampler2D tex; -uniform vec3 specular; -uniform float max_vert_dist; -uniform float max_cam_dist; -uniform float light_factor; -uniform vec3 sun_direction; -uniform vec3 sun_ambient; -uniform vec3 moon_direction; -uniform vec3 moon_ambient; -uniform int n_lights; -uniform bool sky_light; -uniform bool moon_light; -uniform float time; -uniform light_block { - light_t lights[MAX_LIGHTS]; -}; - -float v2rand(vec2 uv) { - return fract(sin(dot(uv, vec2(12.9898,78.233))) * 43758.5453123); -} - -float avg(vec4 v) { - return ((v.r + v.g + v.b) / 3.0) * v.a; -} - -float gauss(float v, float b, float c) { - return (1.0 / (c * sqrt(2.0 * GLM_PI))) * exp(-(pow(v - b, 2.0) / (2.0 * pow(c, 2.0)))); -} - -float dgauss(float v, float b, float c) { - return b + v * c; -} - -float inside(vec2 vec, vec2 offs, float a, float b, float scale, float x1, float x2, float y1, float y2) { - vec2 cscaled = (mod(vec + offs + 1.0, 1.0)) * scale; - return (x2 < x1 ? (cscaled.x >= x1 || cscaled.x <= x2) : (cscaled.x >= x1 && cscaled.x <= x2)) || (y2 < y1 ? (cscaled.y >= y1 || cscaled.y <= y2) : (cscaled.y >= y1 && cscaled.y <= y2)) || (abs(cscaled.y - (cscaled.x - (x2 < x1 ? (x1 - x2) : (x2 - x1)) * GLM_SQRT2 * (x2 < x1 ? 0.0 : (x1 < scale / 2.0 ? x1 : (x2 - scale))))) < GLM_SQRT2) ? b : a; -} - -/* -vec4 pcf_sample(sampler2D stex, vec2 pos) { - vec4 avg = vec4(0.0); - vec2 texel = 1.0 / textureSize(stex, 0); - for(int x = -1; x <= 1; x++) { - for(int y = -1; y <= 1; y++) { - avg += texture(stex, pos + vec2(x, y) * texel); - } - } - return avg /= 9.0; -} -*/ - -vec3 calc_dir_light(vec3 norm, vec3 dir, vec3 rgb, vec3 direction, vec3 color) { - if(shine <= -2.0) - return color * rgb; - vec3 ldir = normalize(-direction); - float diff = max(dot(norm, ldir), 0.0); - vec3 rdir = reflect(-ldir, norm); - float spec = shine <= 0.0 ? 0.0 : pow(max(dot(dir, rdir), 0.0), shine) * (shine < 1.0 ? shine : 1.0); - vec3 ambient = color * rgb; // + clamp(vec3(0.0), 0.0, 1.0); - vec3 diffuse = color * 0.125 * diff * rgb; - vec3 speculars = color * 1.25 * spec * specular * rgb; - return (ambient + diffuse + speculars); -} - -vec3 calc_point_light(light_t light, vec3 norm, vec3 dir, vec3 rgb) { - rgb = clamp(rgb + light_factor, 0.0, 1.0); - vec3 ldir = normalize(light.position.xyz - vertex); - float diff = shine <= -3.0 ? 0.0 : max(dot(norm, ldir), 0.0); - vec3 rdir = reflect(-ldir, norm); - float spec = shine <= -1.0 ? 0.0 : pow(max(dot(dir, rdir), 0.0), shine) * (shine < 1.0 ? shine : 1.0); - float distance = length((light.position.xyz - vertex) / light.range.xyz); - float attenuation = 1.0 / (light.ambient.w + light.diffuse.w * distance + light.specular.w * (distance * distance)); - vec3 ambient = light.ambient.xyz * rgb; - vec3 diffuse = light.diffuse.xyz * diff * rgb; - vec3 speculars = light.specular.xyz * spec * specular * rgb; - ambient *= attenuation; - diffuse *= attenuation; - speculars *= attenuation; - return (ambient + diffuse + speculars); -} - -void main() { - if(shine <= -16.0) { - vec2 coord = fract(tex_coord * textureSize(tex, 0) / 256.0) * vis_div; // vertex.xz + vec2(0.25, 0.5)) * 24.0 / 2.0; - vec2 shift = vec2(v2rand(coord + fract(time)) * 2.0 - 1.0, v2rand(coord + 0.5 + fract(time)) * 2.0 - 1.0); - shift = vec2(dgauss(shift.x, 0.0, 1.0), dgauss(shift.y, 0.0, 1.0)) * 0.015; - vec3 cl = vec3(inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 1.0, 3.0, 1.0, 3.0), inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 63.0, 1.0, 63.0, 1.0), inside(coord / vis_div, shift, 0.0, 1.0, 64.0, 61.0, 63.0, 61.0, 63.0)); - FragColor = vec4(mix(vec3(0.0, 0.0, clamp(0.1 + 0.2 * (vertex.y + 64.0) / 128.0, 0.0, 1.0)), cl, clamp(cl.x + cl.y + cl.z, 0.0, 1.0)), 1.0); - return; - } - - vec3 norm = normalize(normal); - vec3 dir = normalize(cam_pos - vertex); - vec4 texel = texture(tex, tex_coord); - float sky = sky_light ? vertex.y < 0.0 ? 0.0 : (vertex.y < 64.0 ? vertex.y / 64.0 : 1.0) : 1.0; - vec3 rgb = texel.rgb * shading; - vec3 direct = rgb * sky * (1.0 - light_color.a * light_factor); - vec3 result = rgb * light_color.rgb + calc_dir_light(norm, dir, direct, sun_direction, sun_ambient); - if(moon_light) - result += calc_dir_light(norm, dir, direct, moon_direction, moon_ambient); - for(int z = 0; z < n_lights; z++) { - if(distance(vertex, lights[z].position.xyz) <= max_vert_dist && distance(cam_pos, lights[z].position.xyz) <= max_cam_dist) - result += calc_point_light(lights[z], norm, dir, rgb); - } - FragColor = vec4(result, texel.a); -} diff --git a/client/src/main/resources/textures/blocks/blackened_soil.png b/client/src/main/resources/textures/blocks/64x_blackened_soil.png similarity index 100% rename from client/src/main/resources/textures/blocks/blackened_soil.png rename to client/src/main/resources/textures/blocks/64x_blackened_soil.png diff --git a/client/src/main/resources/textures/blocks/grass.png b/client/src/main/resources/textures/blocks/64x_grass.png similarity index 100% rename from client/src/main/resources/textures/blocks/grass.png rename to client/src/main/resources/textures/blocks/64x_grass.png diff --git a/client/src/main/resources/textures/blocks/snowy_blackened_soil.png b/client/src/main/resources/textures/blocks/64x_snowy_blackened_soil.png similarity index 100% rename from client/src/main/resources/textures/blocks/snowy_blackened_soil.png rename to client/src/main/resources/textures/blocks/64x_snowy_blackened_soil.png diff --git a/client/src/main/resources/textures/blocks/snowy_grass.png b/client/src/main/resources/textures/blocks/64x_snowy_grass.png similarity index 100% rename from client/src/main/resources/textures/blocks/snowy_grass.png rename to client/src/main/resources/textures/blocks/64x_snowy_grass.png diff --git a/client/src/main/resources/textures/blocks/snowy_tian_soil.png b/client/src/main/resources/textures/blocks/64x_snowy_tian_soil.png similarity index 100% rename from client/src/main/resources/textures/blocks/snowy_tian_soil.png rename to client/src/main/resources/textures/blocks/64x_snowy_tian_soil.png diff --git a/client/src/main/resources/textures/blocks/tian_soil.png b/client/src/main/resources/textures/blocks/64x_tian_soil.png similarity index 100% rename from client/src/main/resources/textures/blocks/tian_soil.png rename to client/src/main/resources/textures/blocks/64x_tian_soil.png diff --git a/client/src/main/resources/textures/blocks/blackened_soil_side.png b/client/src/main/resources/textures/blocks/blackened_soil_side.png new file mode 100755 index 0000000000000000000000000000000000000000..0620abc9594c821ea2a5dfab32a56886ed54a9c2 GIT binary patch literal 5266 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 N002ovPDHLkV1hKVBZ&Y2 delta 2435 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 literal 84807 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 Iol`;+0K>HqVE_OC delta 47 zcmX@Ww2Ns%Fpn(1l+H8LuQ?11496$NAC}m#fq`Lbf8o9lVc(Ad#TYzY{an^LB{Ts5 DpOg`{ diff --git a/client/src/main/resources/textures/blocks/mycelium_side.png b/client/src/main/resources/textures/blocks/mycelium_side.png new file mode 100755 index 0000000000000000000000000000000000000000..42576193c1121087fb5d96ac043271b66a276396 GIT binary patch literal 5789 zcmeHLdo)yQ8y_7}u0=ZNVvLl^n2Q-^CZkVAuH$~owLLR?m@vc4FherCB`{ZE_!Z%=TuyFZRNR1^L$0uUsiv5 z^s4Tn%0ru*Kc-Dh&0Tox@ZpW7(eu|I?>Lk+=6t&JK5u=bNz{UOclz^&6djLy(IiiM zflkrV+C$p!I-U%A{FbGru4FXh60+Qx438f>@al?`3#~2Gp};a#&*OKZ|MkYEyCEiV z;nA1-H|GXFU1<;%;>!*zP;~Z!a^QpXEl825Z8$ ztOyT3AM1N>P2iOar}_jZV^-G4-RHyV%FFAU17LBi{Hsm{OM1$jrYYrCD-_x#5|-OF zn{4Ua2&1@@Zm7xZhLt#2q~HE=bcZB-sU-f&A#US3IeROkp$)fIV6Utku%=t&((fd- zPqZDTNo`cRSQ4G7uHJMIW3pXa26x}l0#lgoWO;PY9^%MJr+FOz+bTK`sAMt+m*FHBbibKadrks~WCfMV!hwqLMVk=*^<`ro`O1 zlGtfxC^(eS-u$TkNpr^RjWrAP_o}J=8rYfasvP&sy=&ADV482r|68%C?ufeew!w<^ z%8d=Vvz?oa3C5`gph`!pS~2YR(6*6+;rLYhmB!)4XhUNjk;ziJ7$g?dt9Nn%e~1_LI8QUPCEL0LT)mK%`?N-{V;yR<*{K z$)i81CY5X&-+JF|+rNnon4RrSpPI&1g13`;vow7?^LJE^?=zT;+bRi3}rq5rjRQ?#MR;P4Rs|kpm&Mm%Jg&5Z#5Hu>U9Zy z@V%5aSy4KMp6pac`$^YE_G1?7D4r^Gb~Ve@OK&ae+}yG&_{FI$FE@whFnqcyp4%7P z6MDI$!^fB|ex0VKj!iwup($&1{hpBv_Vp(v{>;hP5kY8-qQ^;^KGn&m!}r|R1(XG5X_BE8uh

    4e{hA%AufKAv3{qIn_Vef+|yH1hER@743X zj^*YJ2D5B@-k8pWbEQWrJF4-0WIKGg^16SfQxE$3q;R~f%}*xZWX4tf{L`t->IX{# zwOSiAc*LcbA4i|@E$usFS*=o#>msXb6qL`?c-=#k$W3T_pAcDB{X=d*QgToCrb7oE{o!CS-+S5ymobBQAqUa-{713;{in5&nFBFbRbc2n2cpeLW7>4}~ET zi6}G{g~cKv3nVX`%?E@?Hcv|gv4}wdd2}u-n9t&{;UY|c#tG$<5eP^R|0BMjU@G+s zJe&8K1&9xn5C}$L^w6lFAk^0$Jib{N1oAnczxCibLx(=f5#(_~xpdGh3}o}QzJ_4X zzxW4-as$QbFz6^S5DbD$dC;twzf5UvNwxptA)>&K6%;J?g2?`hC7;FoldQkQCen!0 z`8p8D{R{42tpCVeYz$dZsU!-A9x4jYl0rs^<|i>YbQXgo9uhz_0gom!kwgPL4vE7W zGLS?fhJd8$V~7Sgkch`(h+jcjvUz-fO$S9#5V#%-!l4lehIk^*5NXKJ2az~KECUJP z={O{aB@h8DU|>MRGQNVamfKV{d4Qqfw(hNZZqyZX> zr_mS$G++RTp%`@1P7XH+fXc}V0{lQ!FxyY85D`u?v9}~6uzKh}CH8>;p9wjT5jHG# zsPIpPGb;#m;sYW!F@|`344Qz!5()YSID^Hs#dxkDmj`vC2orED8OUJ%_!{>=UV)eQ^4WhC;29Rzti=d zu5V)Cn~cAA*LS+UiGgo2{@z{xH@am0e4PT>(61l?^s+=ZJtF$!P>N=4PJu1JuEVs) zQjDh|$?{-}T|5{}R#|jOz<$nBg@n?4ORAaln6!$*T16UNaVFfIXs!=X z4pF@|IrH?E_c5=|f+La@ntRmG7hJx)N+x56wRCdwu{MQq`vZu?%u7*8$Ie;{N)g3z z%M==w60MdbB|T_3bIqFD?9CPUN?#}#9DFhw5b;Z^^e^T$RUzgD2n_6Cv%=8;^s%cJ zca6?;RF2KqZ0LqRb8Cz6K02gB?Svbz)n4g1seLowSw5z$Tg}ngOY`iSpnXZI6Q2&d z+n#u8bG*OY*CHVw)^lj^VV4%nsAd`cl$1n$15gyB`*E}38fW7N%VxEY>+gD3VXCB= zG12XLnR@JW_bulSy2)DuW+Rx%(QZ3kCCNjyZA>=_!lO$5%ta0RPZEVb30Q*O(* z$kb>l*YA_Ri+inYs?^9leDlDMln1bP)vWQH$L(0%Go$6ovc)gDDtsSrP;914-|pK~ z_37kFd~{X5%X%NHRQ;c`a$N_slT(+E)#cf&0Gn3F=I5g)S2M~5eSE3T)# z*p!h7FGW!gUh6Pi?bZdezxtDIkz%yZfW&FX?vvNJam-0=J6<>|R1fKq(Ac+w`UaMA zR$}^%LS#ABmykZydc-Tv%6s^1r*b;yhIJCEnt>rwv@6R HyJPs=r4Wm1zomzgFI5iMb zd(DXOOolF zn-Zg8AK2S3a}%~VB~4q)*Th__8nNp;hl_UG@ph5N>c-=y>i`Q_AI$O z+<>2f6{(qhPi%9Gusn7?;S9S1Nw%@ZKA~LqFQI9V$tvmD#gBPp=A}TFzI+-=E{sfc zcAi5aQzBcJ3O1SyXH*4-?OeCHHGPkPVjivFUiyoss<|WmCK;?1nuz_V<5?ynFmsOn z?+vExkfe;+<+Ql=fhm$SGQ?M_iIuWE4%zHJFIuclN{PZ41@;OL-LBU7E~z5{xE`-| za+S~WtX(bHI^Qib$jhdzY}eG!(ji&ixTApa=4Wy4aC^c|Ir$}GzUBAxcP|Wl;o_=;O+S)fl6HrhvbZ6?xS=rcm6x9 z(QGrjvMp^t72LNU7}ifL)HB(zZJxht%2H#b!qusJL)oE*edRsBo>T0czUi8VwBsuL zf6P1o{FYm$W90DbxUM;&b9P*xmmxjumbvXzHD`((d)bWJBgNV257e8nSq?!RVOBV@ z1|!@d{v~;N+(DUuZ76F`R9r4t*HCV-DhEg2O88bI@q%Hqi15J$ zRZD@(Z|H)_hr=0Xh}DNErkg7Saa$Ixzk8n`Y6{F5-o?ofdHZB7u*$80-!$9n?bCg> zwqeVDi^ROjxhJwsT!SxX#+xMVW2YQ5YDupvI+i@ur7pKm-Lpx{}@#CIB2Qcyn8+vYwu0(fBi!#=s4(uM=v}_!_ zkW|O&lWj9UemL7lW2D9p2KDzwygzY_jWajH< zr`mms2Ch!>@+J$AV&}(~1?}>}m0Rrov)dQksBV+Jz2EJroXg%@6dv^I29dhaQzJBv z7!Q1jx}?{FT3``y*JL7}R?~eUBHHjdzU3&YrKqqrFBp*IW}Sf7 zCgdNFPWhwZS%vL*m;YO?&pzXIRXsfxdhqRC5tTV}one!$?P;?p?VBdcM+4U1&U$sB z%xR}_Gqc?M?B?OyvET(;=~Sa$dRlk>7vWjm#M;`Q3n* zBs09F{z?(*4@wq4lz-NLeDOUgueHhHa zSt?+#wt`|f6Ab0>91+iJE+XI@z!9;*&Ku(`a0A0Qp3y?kKiY@Rir&hy2N2Fqx(-qb z1i%Hw47ijV&J$6jjtCVl1-e&?(FnN8M7-4z5#a3$cjF5|H~~dKVUX@pP81H|qziWt z0&I#Ob=7+a=*bZgCKd}QXtYEkK}ql^zAzMxwYRrNV{m934hdNxMKYe4Aw}{;OOy~Z z7*tTi5^@A$4xa~CVltTgNUZ7MoI|O6Su+Aoq{BpILv%U1bbed3#f+d{(3~ zJTIyvLb*N#;IlXYMRiMNGeHtm4e*uTW-=Ws!PF+<5FmSl&=Vo3HRf*pon zhr|DAv>p_SpiWd`VlgN@L8Vcag#sl55zA2aDFmRBL%C4ggdjuA7t;Csa7TnP0Jzfg zquLwVP5?v9pfbcD1Paka!H_68EFDXv;D{6~!4`v~U_P ztzeHQV*r52MB?xu6RIB(fV#lW9*M;h049q8wHh!(-bZv1pDmU!grG|(#3RHN)SfD? z;LBBovi>|4Nf@ZC0z?=R>bJiVhJK$gS~)X5WbAMm!9rp6W$)p_7{K&3j?;|E%J0a7qwmu$Vp<#V~dc)(z1=wp7Rx3CD+xFd? zcaa90B?EGq+F(R-PUlitkh}ViyHVvvqe&0j0G&8(yvDXScka{qzAG2H=*7!VoT}jVq?XdThqr1_l3t@R=a#Q7X`C$I$Ks9Ek=ci4JeK&^2tYW75lzFqlsMnvdu+Z z!$ur;M*I^%f3&r(SxP-LZT_%oUROYFu%6Kw?QzcDU$5FNR&&q3c11U3LjT6BcTyTBUveZQv`*>J`7!j9*T-;+rxW#k9w)*dK!RDpnljrw!L7IB-Y3Zh8j%+D^O9 zTyA@%?O&l|7PmONQj<6b^A=_L)oX^>*1#WZ3WNo&y^1g!yqLtfM~^8!e{uGu7Xg8m zw8XJ+-Lc;)JRYVIQw_TIa~l?r>`@Ck&M<@(rgGBJy4Aau>b?7CFi zPfpyN2}ScpbDO5Kg1oZcXFBdDBDFIR(KV6MPcFF=?te0zm#@`WuU?v(CY@v^`_+To z#WD_g@J2+`EA6*)V{LT}vZkh+Gkyen6PVLxQ!yLckDMGb+Y{urU4hNqK~r?=2M;_S z)!Vb{#O#u-SMzL8!6l2X&Ex7Eyr>!1yJjz{ECb1tNBt7R`D0e6&Z`SgEF4JW`sL|C R$Dl@qdAa*gPq>C8{1->R-irVL literal 0 HcmV?d00001 diff --git a/client/src/main/resources/textures/blocks/podzol.png b/client/src/main/resources/textures/blocks/podzol_top.png similarity index 100% rename from client/src/main/resources/textures/blocks/podzol.png rename to client/src/main/resources/textures/blocks/podzol_top.png diff --git a/client/src/main/resources/textures/blocks/smooth_sandstone.png b/client/src/main/resources/textures/blocks/sandstone_all.png similarity index 100% rename from client/src/main/resources/textures/blocks/smooth_sandstone.png rename to client/src/main/resources/textures/blocks/sandstone_all.png diff --git a/client/src/main/resources/textures/blocks/sandstone.png b/client/src/main/resources/textures/blocks/sandstone_bottom.png similarity index 100% rename from client/src/main/resources/textures/blocks/sandstone.png rename to client/src/main/resources/textures/blocks/sandstone_bottom.png diff --git a/client/src/main/resources/textures/blocks/sandstone_carved.png b/client/src/main/resources/textures/blocks/sandstone_carved.png new file mode 100755 index 0000000000000000000000000000000000000000..9bd7fa1422fc6a057bc8c00cb72b6a4b2cf83463 GIT binary patch literal 596 zcmV-a0;~OrP)mGxmS&o*J$%R=gR z-lM&}h=b-LI@TMOEprK0Ero64Irevwu+1c#-87%?HIfLtRRmx2IO?uIGL!^t5oFb$ zVYBoQ)p87*>Lb*Q$Iwf07)l%!WeR2aE;RWD%*r&(>MXS43{-g%()pZ@!iX^uE@7X1dg>N=KF-!&MQV$iD64r^_^unqC0)#9%@=boF&n< z7ZA82wvqZnKuJWfxO+d*Mbb6Hi zKLNE-(;uMp`8u~ml28|GBuQt*+_lI@ARkF4pmqHm6fPlLV`$Ub{^pNH2wUfw8*@Ao z-2vgin&WnDa~4%K&M}qJ6wdm^%LEim$?BI0@hV^N?B(@45s^}uz~SCICZqGdcwiBM zQn+<-DfgobqJ5i{rz2e?R@H>q$ZNJWaaW#LClk<9rOM-=OB%O{;A%`5C((y~6q4aa iLX7*vErm8!C*N literal 0 HcmV?d00001 diff --git a/client/src/main/resources/textures/blocks/sandstone_normal.png b/client/src/main/resources/textures/blocks/sandstone_normal.png new file mode 100755 index 0000000000000000000000000000000000000000..1b79145ff09417564fca4b205abe6ca015153fb0 GIT binary patch literal 777 zcmV+k1NQuhP) z zG8<5GW`37a7UUAENJc)Rcxgl-WrUPn=ly)z2u-y^t9#I{?n8)(vnbF{xr^-8v86+YL2%k}p$?_6&IFCh9&K7lG$+*ZCc^%4BG`kJS%sWkL#<#X zqFspI7ZBv!52VkR7>UR{6I{^zs^mhe>cr`xfeE6dRa4nVP1->zvyNKnoNS0k zb33TyR?t$mkx4Ax`|n01Ff}A7((DbH1gi`oli%T!G4xd@szuwd?XnHU^cuvY5fax9 zRo+I(_Y!p)hejA9w#i2n)5}OkXZTbdow}3W%TP*Y#6vTr!2zOyafW#K48rg35gyQ# zcX3W3I&nWm#Q&V37l(Wkj6wUD3tRFQZaaR4&~G{@7{^?kj4t51?PRhC@$|x*ZkPp@ z^EMK99$i{@C}53>9YU8{)Cr2I6&|6KHk04hq2DySPEgKnQBIcmAMt3E?tz1BCULVC z2&vc?%Kj`g5=+m&lDFWB0#ujm2pmp8KOi2`)45Hp+t^B<^9coP0|C!d>VR6gZXePm zq41PVhy_0|g5#-|zD1?DfNE(0N2Pfj=uc7BAHz6$1LJrJ<-JAh>(8Lw-IPHDVi&i5 z$lq~=p)s$#pV7#K-z(s^n`ghIKM4i;c3Pfq2ko}={{m7;SgTyrHB)Q}VTGcu{RNk9jzuW$G(SR^X(^Pw7vO~EGI#Ur^{~*%W7yk? zCKzq z>2exD420()V=x$4V79Uc49gmPqlyNfnQdcPfoA-q1qXZ)M~Y~A;r=@4tH+# za%0V6X`c@-eosFSgYOV4i}Qv3*>pzE+y2Jm!h3&fU43iIN#ViOyvUD7JDpDMn~X*t z*es(bW1IoR!p;7Ds51I-;pkL4XQM<+iTH^LRPSSNcU9|&pcm6CYh!1C&&HSDj^3Wy zo$aclvvvUW-mOcoPO|9APesmYm8{L*O$J|0rnbp(0b~L|B$zv(^e-d1T_-DNbJqlW z?T%hBs478TG46*mZDDA!Eqg0+RkfmTkZAsxnNSHPBuR1CWWCGuzY>+~0L_^bT6NJn zz*~3l)&Nm^&-tua?M0Z6r-uD%ll@M;JL#LVMyHlw1!IjC;E-0O12j2+v1u=~JonAk z{$^3}BOX3Pen^ksW8{Gi6jgz+1MB$JD{oq9jh@8|+OB4`^#FoNMD^*#<*@&1!&}Kh zQv~6C542S7!H*`4ljWfZXR!_EbTm>|e|PPP&g%b2@dG|g1`!1SB@nq2 mP}Q{|FhP7Z5&imrQs5ui-aDkkm{PF-0000Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RY2nP!$928mRqW}N`$w@>(R5;5$ zkxg$KWfX;<`@Un(c*c%nH;HSMDh&Y@7mE4;>?#llx+n>0Z*byC~4V~;&w?`1I&cXJn4=UkoV$nE#mHS~pXp_mIX(}NlaXeN+C zScRKg9soc8lam(EYgvBl7j$c2LSN`a1~u@0>oU>C97(}sN?3(2t_R#d$a!#>GfR|S z%d$Hv@I7Ugf@z1s&LAf(l!ph0Ob`w}UhOm8HkXx81iaf26q!3j3f6TM7vg8S$Y*eYF%2)5y_`P3{ z0K-H%StzHO;)#&tf>#BX!`HvgxwK+20H5}JzS~}4t?Xn0hHpsfihV@Xoc)30#_bwqRcV{ zpdAUu2vUU{*jTcdMFD#+m914nB~#WS!-dFT66Mcl1z32i9E{ z(P@GC@W!jO8nD_D)>kbrMvkL_W62i;@GHXKFUoA+?kpI@jx>kJhtw(Nr$6>ssapmy z#G<^+K!J)aY2V!P*j%;jP72yh!z2Mc4zZmXE(T*A9G%fqz!;^|FxYD zQLGi_*;xyB-VV6hwS?<)^xTX_9Y#5vUlCTC0tNhd|0&f%XjowwEB%oJK)%2Gn*Okx z-~@(FQ3Kt&#Zwr~99gD#1*8tDrrgW5GEh4d{sRKUK0Lhf&cOfx002ovPDHLkV1o7! BZjb-~ diff --git a/client/src/main/resources/textures/blocks/swamp_side.png b/client/src/main/resources/textures/blocks/swamp_side.png new file mode 100755 index 0000000000000000000000000000000000000000..cfc7672d7fd1c55ef39dafd7d8bf53dab4cffe7c GIT binary patch literal 5860 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 literal 0 HcmV?d00001 diff --git a/client/src/main/resources/textures/blocks/snowy_swamp.png b/client/src/main/resources/textures/blocks/swamp_top.png similarity index 100% rename from client/src/main/resources/textures/blocks/snowy_swamp.png rename to client/src/main/resources/textures/blocks/swamp_top.png diff --git a/client/src/main/resources/textures/blocks/tian_soil_side.png b/client/src/main/resources/textures/blocks/tian_soil_side.png new file mode 100755 index 0000000000000000000000000000000000000000..24a874ba0f417339e33d86e963aba580adc49e6c GIT binary patch literal 6230 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 literal 0 HcmV?d00001 diff --git a/client/src/main/resources/textures/blocks/tian_soil_top.png b/client/src/main/resources/textures/blocks/tian_soil_top.png new file mode 100755 index 0000000000000000000000000000000000000000..07d6a69725c4d06f7b313826636996df305ba6b2 GIT binary patch literal 2782 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 map) { } +// @Clientside +// public boolean canRender(IWorldAccess world, BlockPos pos, Facing side) { +// return side == Facing.DOWN && this.minY > 0.0D ? true +// : (side == Facing.UP && this.maxY < 1.0D ? true +// : (side == Facing.NORTH && this.minZ > 0.0D ? true +// : (side == Facing.SOUTH && this.maxZ < 1.0D ? true +// : (side == Facing.WEST && this.minX > 0.0D ? true +// : (side == Facing.EAST && this.maxX < 1.0D ? true +// : !world.getState(pos).getBlock().isOpaqueCube()))))); +// } @Clientside public boolean canRender(IWorldAccess world, BlockPos pos, Facing side) { return side == Facing.DOWN && this.minY > 0.0D ? true @@ -1045,6 +1055,12 @@ public class Block { : !world.getState(pos).getBlock().isOpaqueCube() && (!this.isNonBlock() || !world.getState(pos).getBlock().isNonBlock() || !world.getState(pos).getBlock().isVisuallyOpaque())))))); } + @Clientside + public BoundingBox getSelectionBox(World world, BlockPos pos) { + return new BoundingBox((double)pos.getX() + this.minX, (double)pos.getY() + this.minY, (double)pos.getZ() + this.minZ, + (double)pos.getX() + this.maxX, (double)pos.getY() + this.maxY, (double)pos.getZ() + this.maxZ); + } + @Clientside public boolean isXrayVisible() { return false; @@ -1066,7 +1082,7 @@ public class Block { @Clientside public float getShinyness() { - return 0.75f; + return 1.0f; } @Clientside diff --git a/common/src/main/java/common/block/BlockFalling.java b/common/src/main/java/common/block/BlockFalling.java index 32321f22..acf2897f 100755 --- a/common/src/main/java/common/block/BlockFalling.java +++ b/common/src/main/java/common/block/BlockFalling.java @@ -1,7 +1,6 @@ package common.block; import common.block.natural.BlockFire; -import common.block.natural.BlockNonBlock; import common.entity.item.EntityFalling; import common.init.Blocks; import common.rng.Random; @@ -11,7 +10,7 @@ import common.world.State; import common.world.World; import common.world.AWorldServer; -public class BlockFalling extends BlockNonBlock { +public class BlockFalling extends Block { public static boolean fallInstantly; public static boolean canFallInto(World world, BlockPos pos) { diff --git a/common/src/main/java/common/block/BlockTreasure.java b/common/src/main/java/common/block/BlockTreasure.java index f34afbaa..b5548e0b 100755 --- a/common/src/main/java/common/block/BlockTreasure.java +++ b/common/src/main/java/common/block/BlockTreasure.java @@ -1,8 +1,6 @@ package common.block; -import common.block.natural.BlockNonBlock; - -public class BlockTreasure extends BlockNonBlock { +public class BlockTreasure extends Block { public BlockTreasure(Material material) { super(material); } diff --git a/common/src/main/java/common/block/artificial/BlockDoor.java b/common/src/main/java/common/block/artificial/BlockDoor.java index 607274a8..d35d5d25 100755 --- a/common/src/main/java/common/block/artificial/BlockDoor.java +++ b/common/src/main/java/common/block/artificial/BlockDoor.java @@ -94,6 +94,12 @@ public class BlockDoor extends Block implements Rotatable { return false; } + @Clientside + public BoundingBox getSelectionBox(World world, BlockPos pos) { + this.setBlockBounds(world, pos); + return super.getSelectionBox(world, pos); + } + public BoundingBox getCollisionBox(World world, BlockPos pos, State state) { this.setBlockBounds(world, pos); return super.getCollisionBox(world, pos, state); diff --git a/common/src/main/java/common/block/artificial/BlockLadder.java b/common/src/main/java/common/block/artificial/BlockLadder.java index 29de95c4..10677572 100755 --- a/common/src/main/java/common/block/artificial/BlockLadder.java +++ b/common/src/main/java/common/block/artificial/BlockLadder.java @@ -33,6 +33,12 @@ public class BlockLadder extends Block implements Rotatable return super.getCollisionBox(worldIn, pos, state); } + public BoundingBox getSelectionBox(World worldIn, BlockPos pos) + { + this.setBlockBounds(worldIn, pos); + return super.getSelectionBox(worldIn, pos); + } + public void setBlockBounds(IWorldAccess worldIn, BlockPos pos) { State iblockstate = worldIn.getState(pos); diff --git a/common/src/main/java/common/block/artificial/BlockSlab.java b/common/src/main/java/common/block/artificial/BlockSlab.java index 71dad893..2dafad1a 100755 --- a/common/src/main/java/common/block/artificial/BlockSlab.java +++ b/common/src/main/java/common/block/artificial/BlockSlab.java @@ -17,7 +17,6 @@ import common.model.Model.ModelProvider; import common.properties.Property; import common.util.BlockPos; import common.util.BoundingBox; -import common.util.Clientside; import common.util.Facing; import common.util.Facing.Axis; import common.world.IWorldAccess; @@ -30,12 +29,22 @@ public class BlockSlab extends Block implements Directional { private final Block base; private final String textureTop; private final String textureBottom; + private final String textureSide; + private final String textureOverlay; public BlockSlab(Block base) { this(base, null, null); } public BlockSlab(Block base, String bottom, String top) { + this(base, bottom, top, null); + } + + public BlockSlab(Block base, String bottom, String top, String side) { + this(base, bottom, top, side, null); + } + + public BlockSlab(Block base, String bottom, String top, String side, String overlay) { super(base.getMaterial()); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.DOWN)); this.setTab(base.getTab()); @@ -49,6 +58,8 @@ public class BlockSlab extends Block implements Directional { this.setSound(this.base.getSound()); this.textureTop = top; this.textureBottom = bottom; + this.textureSide = side; + this.textureOverlay = overlay; SLABS.add(this); } @@ -157,7 +168,9 @@ public class BlockSlab extends Block implements Directional { public Model getModel(ModelProvider provider, String name, State state) { String primary = this.base.getModel(provider, BlockRegistry.getName(this.base), this.base.getState()).getPrimary(); - Model model = makeSlabModel(provider.getModel(primary), this.textureBottom != null ? this.textureBottom : primary, this.textureTop != null ? this.textureTop : primary, state.getValue(FACING)); + Model model = makeSlabModel(provider.getModel(this.textureSide != null ? this.textureSide : primary), this.textureBottom != null ? this.textureBottom : primary, this.textureTop != null ? this.textureTop : primary, state.getValue(FACING)); + if(this.textureOverlay != null) + makeSlabModel(model, this.textureOverlay, null, state.getValue(FACING)); return model; } @@ -192,9 +205,4 @@ public class BlockSlab extends Block implements Directional { public int getFuelAmount() { return this.material == Material.WOOD ? 150 : 0; } - - @Clientside - public float getShinyness() { - return this.base.getShinyness(); - } } diff --git a/common/src/main/java/common/block/artificial/BlockStairs.java b/common/src/main/java/common/block/artificial/BlockStairs.java index 56ad82ef..81525fe4 100755 --- a/common/src/main/java/common/block/artificial/BlockStairs.java +++ b/common/src/main/java/common/block/artificial/BlockStairs.java @@ -16,7 +16,6 @@ import common.properties.Property; import common.properties.PropertyEnum; import common.util.BlockPos; import common.util.BoundingBox; -import common.util.Clientside; import common.util.Facing; import common.util.HitPosition; import common.util.Identifyable; @@ -34,6 +33,7 @@ public class BlockStairs extends Block implements Rotatable private final Block base; private final String downTex; private final String upTex; + private final String sideTex; private boolean hasRaytraced; private int rayTracePass; @@ -43,6 +43,11 @@ public class BlockStairs extends Block implements Rotatable } public BlockStairs(Block base, String down, String up) + { + this(base, down, up, null); + } + + public BlockStairs(Block base, String down, String up, String side) { super(base.getMaterial()); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH).withProperty(HALF, BlockStairs.EnumHalf.BOTTOM).withProperty(SHAPE, BlockStairs.EnumShape.STRAIGHT)); @@ -54,6 +59,7 @@ public class BlockStairs extends Block implements Rotatable this.setTab(base.getTab()); this.downTex = down; this.upTex = up; + this.sideTex = side; } public void setBlockBounds(IWorldAccess worldIn, BlockPos pos) @@ -677,7 +683,7 @@ public class BlockStairs extends Block implements Rotatable public Model getModel(ModelProvider provider, String name, State state) { String primary = this.base.getModel(provider, BlockRegistry.getName(this.base), this.base.getState()).getPrimary(); - return makeModel(provider.getModel(primary), state.getValue(HALF) == EnumHalf.TOP, state.getValue(SHAPE) == EnumShape.INNER_RIGHT || + return makeModel(provider.getModel(this.sideTex != null ? this.sideTex : primary), state.getValue(HALF) == EnumHalf.TOP, state.getValue(SHAPE) == EnumShape.INNER_RIGHT || state.getValue(SHAPE) == EnumShape.INNER_LEFT, state.getValue(SHAPE) == EnumShape.OUTER_RIGHT || state.getValue(SHAPE) == EnumShape.OUTER_LEFT, state.getValue(SHAPE) == EnumShape.INNER_LEFT || state.getValue(SHAPE) == EnumShape.OUTER_LEFT, state.getValue(FACING), @@ -697,11 +703,6 @@ public class BlockStairs extends Block implements Rotatable return new Property[] {SHAPE}; } - @Clientside - public float getShinyness() { - return this.base.getShinyness(); - } - public static enum EnumHalf implements Identifyable { TOP("top"), diff --git a/common/src/main/java/common/block/artificial/BlockTrapDoor.java b/common/src/main/java/common/block/artificial/BlockTrapDoor.java index 9cbef448..8fd5bcc0 100755 --- a/common/src/main/java/common/block/artificial/BlockTrapDoor.java +++ b/common/src/main/java/common/block/artificial/BlockTrapDoor.java @@ -67,6 +67,12 @@ public class BlockTrapDoor extends Block implements Rotatable return !((Boolean)worldIn.getState(pos).getValue(OPEN)).booleanValue(); } + public BoundingBox getSelectionBox(World worldIn, BlockPos pos) + { + this.setBlockBounds(worldIn, pos); + return super.getSelectionBox(worldIn, pos); + } + public BoundingBox getCollisionBox(World worldIn, BlockPos pos, State state) { this.setBlockBounds(worldIn, pos); diff --git a/common/src/main/java/common/block/artificial/BlockWall.java b/common/src/main/java/common/block/artificial/BlockWall.java index 5539c2d8..08f9a0ef 100755 --- a/common/src/main/java/common/block/artificial/BlockWall.java +++ b/common/src/main/java/common/block/artificial/BlockWall.java @@ -14,7 +14,6 @@ import common.properties.Property; import common.properties.PropertyBool; import common.util.BlockPos; import common.util.BoundingBox; -import common.util.Clientside; import common.util.Facing; import common.world.IBlockAccess; import common.world.IWorldAccess; @@ -304,9 +303,4 @@ public class BlockWall extends Block protected Property[] getUnsavedProperties() { return new Property[] {NORTH, SOUTH, UP, WEST, EAST}; } - - @Clientside - public float getShinyness() { - return this.base.getShinyness(); - } } diff --git a/common/src/main/java/common/block/foliage/BlockBlackenedSoil.java b/common/src/main/java/common/block/foliage/BlockBlackenedSoil.java index c82587a4..ab77347e 100644 --- a/common/src/main/java/common/block/foliage/BlockBlackenedSoil.java +++ b/common/src/main/java/common/block/foliage/BlockBlackenedSoil.java @@ -5,17 +5,20 @@ import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; +import common.model.Model; +import common.model.Model.ModelProvider; import common.rng.Random; import common.util.BlockPos; import common.vars.Vars; import common.world.State; import common.world.AWorldServer; -public class BlockBlackenedSoil extends BlockSnowable +public class BlockBlackenedSoil extends Block { - public BlockBlackenedSoil(boolean snowy) + public BlockBlackenedSoil() { - super(Material.LOOSE, snowy); + super(Material.LOOSE); + this.setTicked(); this.setTab(CheatTab.NATURE); } @@ -26,22 +29,19 @@ public class BlockBlackenedSoil extends BlockSnowable if(Vars.darkSoilDecay) worldIn.setState(pos, Blocks.blackened_dirt.getState()); } - else { - if (Vars.darkSoilSpread) - { - for (int i = 0; i < 4; i++) - { - BlockPos blockpos = pos.add(rand.zrange(3) - 1, rand.zrange(5) - 3, rand.zrange(3) - 1); - Block block = worldIn.getState(blockpos.up()).getBlock(); - State iblockstate = worldIn.getState(blockpos); - - if ((iblockstate.getBlock() == Blocks.dirt || iblockstate.getBlock() == Blocks.grass || iblockstate.getBlock() == Blocks.swamp || iblockstate.getBlock() == Blocks.blackened_dirt) && block.getLightOpacity() <= 6) - { - worldIn.setState(blockpos, Blocks.blackened_soil.getState()); - } - } - } - super.tick(worldIn, pos, state, rand); + else if (Vars.darkSoilSpread) + { + for (int i = 0; i < 4; i++) + { + BlockPos blockpos = pos.add(rand.zrange(3) - 1, rand.zrange(5) - 3, rand.zrange(3) - 1); + Block block = worldIn.getState(blockpos.up()).getBlock(); + State iblockstate = worldIn.getState(blockpos); + + if ((iblockstate.getBlock() == Blocks.dirt || iblockstate.getBlock() == Blocks.grass || iblockstate.getBlock() == Blocks.swamp || iblockstate.getBlock() == Blocks.blackened_dirt) && block.getLightOpacity() <= 6) + { + worldIn.setState(blockpos, Blocks.blackened_soil.getState()); + } + } } } @@ -49,4 +49,8 @@ public class BlockBlackenedSoil extends BlockSnowable { return Blocks.blackened_dirt.getDrop(Blocks.blackened_dirt.getState(), rand, fortune); } + + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("blackened_dirt").add().d().u("blackened_soil_top").nswe("blackened_soil_side"); + } } diff --git a/common/src/main/java/common/block/foliage/BlockBlueShroom.java b/common/src/main/java/common/block/foliage/BlockBlueShroom.java index 18f2fc80..cc7b249d 100755 --- a/common/src/main/java/common/block/foliage/BlockBlueShroom.java +++ b/common/src/main/java/common/block/foliage/BlockBlueShroom.java @@ -67,7 +67,7 @@ public class BlockBlueShroom extends BlockBush protected boolean canPlaceBlockOn(Block ground) { - return ground.isFullBlock() || ground.isNonBlock(); + return ground.isFullBlock(); } public boolean canBlockStay(World worldIn, BlockPos pos, State state) diff --git a/common/src/main/java/common/block/foliage/BlockCactus.java b/common/src/main/java/common/block/foliage/BlockCactus.java index 66068b10..7b0ff364 100755 --- a/common/src/main/java/common/block/foliage/BlockCactus.java +++ b/common/src/main/java/common/block/foliage/BlockCactus.java @@ -69,6 +69,12 @@ public class BlockCactus extends Block return new BoundingBox((double)((float)pos.getX() + f), (double)pos.getY(), (double)((float)pos.getZ() + f), (double)((float)(pos.getX() + 1) - f), (double)((float)(pos.getY() + 1) - f), (double)((float)(pos.getZ() + 1) - f)); } + public BoundingBox getSelectionBox(World worldIn, BlockPos pos) + { + float f = 0.0625F; + return new BoundingBox((double)((float)pos.getX() + f), (double)pos.getY(), (double)((float)pos.getZ() + f), (double)((float)(pos.getX() + 1) - f), (double)(pos.getY() + 1), (double)((float)(pos.getZ() + 1) - f)); + } + public boolean isFullCube() { return false; diff --git a/common/src/main/java/common/block/foliage/BlockGrass.java b/common/src/main/java/common/block/foliage/BlockGrass.java index f57fbe6b..619e12fe 100755 --- a/common/src/main/java/common/block/foliage/BlockGrass.java +++ b/common/src/main/java/common/block/foliage/BlockGrass.java @@ -5,21 +5,36 @@ import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; +import common.model.Model; +import common.model.Model.ModelProvider; +import common.properties.Property; +import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; import common.vars.Vars; +import common.world.IWorldAccess; import common.world.State; import common.world.World; import common.world.AWorldServer; -public class BlockGrass extends BlockSnowable implements IGrowable +public class BlockGrass extends Block implements IGrowable { - public BlockGrass(boolean snowy) + public static final PropertyBool SNOWY = PropertyBool.create("snowy"); + + public BlockGrass() { - super(Material.LOOSE, snowy); + super(Material.LOOSE); + this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); + this.setTicked(); this.setTab(CheatTab.NATURE); } + public State getState(State state, IWorldAccess worldIn, BlockPos pos) + { + Block block = worldIn.getState(pos.up()).getBlock(); + return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.snow || block == Blocks.snow_layer)); + } + public void tick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { if (worldIn.getState(pos.up()).getBlock().getLightOpacity() > 2) @@ -27,14 +42,9 @@ public class BlockGrass extends BlockSnowable implements IGrowable if(Vars.grassDecay) worldIn.setState(pos, Blocks.dirt.getState()); } - else if(worldIn.getTemperatureC(pos) >= 50.0f) { - if(Vars.grassDry) - worldIn.setState(pos, worldIn.rand.chance(20) ? Blocks.coarse_dirt.getState() : - Blocks.dirt.getState()); - } - else + else if(worldIn.getTemperatureC(pos) < 50.0f) { - if (Vars.grassSpread) + if (Vars.grassSpread) { for (int i = 0; i < 4; ++i) { @@ -48,7 +58,11 @@ public class BlockGrass extends BlockSnowable implements IGrowable } } } - super.tick(worldIn, pos, state, rand); + } + else { + if(Vars.grassDry) + worldIn.setState(pos, worldIn.rand.chance(20) ? Blocks.coarse_dirt.getState() : + Blocks.dirt.getState()); } } @@ -71,4 +85,20 @@ public class BlockGrass extends BlockSnowable implements IGrowable { worldIn.growGrass(pos, state, rand); } + + protected Property[] getProperties() + { + return new Property[] {SNOWY}; + } + + public Model getModel(ModelProvider provider, String name, State state) { + if(state.getValue(SNOWY)) + return provider.getModel("dirt").add().d().u("snow").nswe().add().nswe("soil_snowed"); + else + return provider.getModel("dirt").add().d().u("grass_top").nswe().add().nswe("grass_side"); + } + + protected Property[] getUnsavedProperties() { + return new Property[] {SNOWY}; + } } diff --git a/common/src/main/java/common/block/foliage/BlockLeavesBase.java b/common/src/main/java/common/block/foliage/BlockLeavesBase.java index 691b7b2a..28bd923e 100755 --- a/common/src/main/java/common/block/foliage/BlockLeavesBase.java +++ b/common/src/main/java/common/block/foliage/BlockLeavesBase.java @@ -2,9 +2,8 @@ package common.block.foliage; import common.block.Block; import common.block.Material; -import common.block.natural.BlockNonBlock; -public class BlockLeavesBase extends BlockNonBlock +public class BlockLeavesBase extends Block { // public static final List BASE_LEAVES = Lists.newArrayList(); diff --git a/common/src/main/java/common/block/foliage/BlockMushroom.java b/common/src/main/java/common/block/foliage/BlockMushroom.java index 9343e311..5940671f 100755 --- a/common/src/main/java/common/block/foliage/BlockMushroom.java +++ b/common/src/main/java/common/block/foliage/BlockMushroom.java @@ -70,7 +70,7 @@ public class BlockMushroom extends BlockBush implements IGrowable */ protected boolean canPlaceBlockOn(Block ground) { - return ground.isFullBlock() || ground.isNonBlock(); + return ground.isFullBlock(); } public boolean canBlockStay(World worldIn, BlockPos pos, State state) diff --git a/common/src/main/java/common/block/foliage/BlockMycelium.java b/common/src/main/java/common/block/foliage/BlockMycelium.java index d87fc7ad..8f3be81e 100755 --- a/common/src/main/java/common/block/foliage/BlockMycelium.java +++ b/common/src/main/java/common/block/foliage/BlockMycelium.java @@ -5,22 +5,41 @@ import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; +import common.model.Model; +import common.model.Model.ModelProvider; +import common.properties.Property; +import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; import common.util.ParticleType; import common.vars.Vars; +import common.world.IWorldAccess; import common.world.State; import common.world.World; import common.world.AWorldServer; -public class BlockMycelium extends BlockSnowable +public class BlockMycelium extends Block { - public BlockMycelium(boolean snowy) + public static final PropertyBool SNOWY = PropertyBool.create("snowy"); + + public BlockMycelium() { - super(Material.LOOSE, snowy); + super(Material.LOOSE); + this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); + this.setTicked(); this.setTab(CheatTab.NATURE); } + /** + * Get the actual Block state of this Block at the given position. This applies properties not visible in the + * metadata, such as fence connections. + */ + public State getState(State state, IWorldAccess worldIn, BlockPos pos) + { + Block block = worldIn.getState(pos.up()).getBlock(); + return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.snow || block == Blocks.snow_layer)); + } + public void tick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { // if (!worldIn.client) @@ -30,23 +49,20 @@ public class BlockMycelium extends BlockSnowable if(Vars.mycelDecay) worldIn.setState(pos, Blocks.dirt.getState()); } - else { - if(Vars.mycelSpread) - { - for (int i = 0; i < 4; ++i) - { - BlockPos blockpos = pos.add(rand.zrange(3) - 1, rand.zrange(5) - 3, rand.zrange(3) - 1); - State iblockstate = worldIn.getState(blockpos); - Block block = worldIn.getState(blockpos.up()).getBlock(); + else if(Vars.mycelSpread) + { + for (int i = 0; i < 4; ++i) + { + BlockPos blockpos = pos.add(rand.zrange(3) - 1, rand.zrange(5) - 3, rand.zrange(3) - 1); + State iblockstate = worldIn.getState(blockpos); + Block block = worldIn.getState(blockpos.up()).getBlock(); - if (iblockstate.getBlock() == Blocks.dirt && block.getLightOpacity() <= 2) - { - worldIn.setState(blockpos, this.getState()); - } + if (iblockstate.getBlock() == Blocks.dirt && block.getLightOpacity() <= 2) + { + worldIn.setState(blockpos, this.getState()); } - } - super.tick(worldIn, pos, state, rand); - } + } + } // } } @@ -67,4 +83,20 @@ public class BlockMycelium extends BlockSnowable { return Blocks.dirt.getDrop(Blocks.dirt.getState(), rand, fortune); } + + protected Property[] getProperties() + { + return new Property[] {SNOWY}; + } + + public Model getModel(ModelProvider provider, String name, State state) { + if(state.getValue(SNOWY)) + return provider.getModel("dirt").add().d().u("snow").nswe().add().nswe("soil_snowed"); + else + return provider.getModel("dirt").add().d().u("mycelium_top").nswe().add().nswe("mycelium_side"); + } + + protected Property[] getUnsavedProperties() { + return new Property[] {SNOWY}; + } } diff --git a/common/src/main/java/common/block/foliage/BlockSnowable.java b/common/src/main/java/common/block/foliage/BlockSnowable.java deleted file mode 100644 index de9bf6f4..00000000 --- a/common/src/main/java/common/block/foliage/BlockSnowable.java +++ /dev/null @@ -1,31 +0,0 @@ -package common.block.foliage; - -import common.block.Material; -import common.block.natural.BlockNonBlock; -import common.rng.Random; -import common.util.BlockPos; -import common.world.State; -import common.world.AWorldServer; - -public class BlockSnowable extends BlockNonBlock { - private final boolean snowy; - - private BlockSnowable other; - - public BlockSnowable(Material material, boolean snowy) { - super(material); - this.setTicked(); - this.snowy = snowy; - } - - public BlockSnowable setOther(BlockSnowable other) { - this.other = other; - other.other = this; - return this; - } - - public void tick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { - if(this.snowy ? !worldIn.canFreezeAt(pos) : (worldIn.isRaining() || !worldIn.dimension.hasWeather()) && worldIn.canFreezeAt(pos) && worldIn.getPrecipitationHeight(pos).getY() - 1 <= pos.getY()) - worldIn.setState(pos, this.other.getState()); - } -} diff --git a/common/src/main/java/common/block/foliage/BlockSwamp.java b/common/src/main/java/common/block/foliage/BlockSwamp.java index c57e3c07..4936086a 100644 --- a/common/src/main/java/common/block/foliage/BlockSwamp.java +++ b/common/src/main/java/common/block/foliage/BlockSwamp.java @@ -1,25 +1,41 @@ package common.block.foliage; +import common.block.Block; import common.block.Material; import common.entity.Entity; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; +import common.model.Model; +import common.model.Model.ModelProvider; +import common.properties.Property; +import common.properties.PropertyBool; import common.rng.Random; import common.util.BlockPos; import common.util.BoundingBox; import common.vars.Vars; import common.world.AWorldServer; +import common.world.IWorldAccess; import common.world.State; import common.world.World; -public class BlockSwamp extends BlockSnowable +public class BlockSwamp extends Block { - public BlockSwamp(boolean snowy) + public static final PropertyBool SNOWY = PropertyBool.create("snowy"); + + public BlockSwamp() { - super(Material.LOOSE, snowy); + super(Material.LOOSE); + this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); + this.setTicked(); this.setTab(CheatTab.NATURE); } + + public State getState(State state, IWorldAccess worldIn, BlockPos pos) + { + Block block = worldIn.getState(pos.up()).getBlock(); + return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.snow || block == Blocks.snow_layer)); + } public BoundingBox getCollisionBox(World worldIn, BlockPos pos, State state) { @@ -33,6 +49,22 @@ public class BlockSwamp extends BlockSnowable entityIn.motionZ *= 0.6D; } + public Model getModel(ModelProvider provider, String name, State state) { + if(state.getValue(SNOWY)) + return provider.getModel("dirt").add().d().u("snow").nswe().add().nswe("soil_snowed"); + else + return provider.getModel("dirt").add().d().u("swamp_top").nswe().add().nswe("swamp_side"); + } + + protected Property[] getProperties() + { + return new Property[] {SNOWY}; + } + + protected Property[] getUnsavedProperties() { + return new Property[] {SNOWY}; + } + public Item getDrop(State state, Random rand, int fortune) { return Blocks.dirt.getDrop(Blocks.dirt.getState(), rand, fortune); @@ -45,16 +77,11 @@ public class BlockSwamp extends BlockSnowable if(Vars.swampDecay) worldIn.setState(pos, Blocks.dirt.getState()); } - else { - if(Vars.swampDry) { - float temp = worldIn.getTemperatureC(pos); - if(temp >= 38.0f) { - worldIn.setState(pos, temp >= 50.0f ? (worldIn.rand.chance(20) ? Blocks.coarse_dirt.getState() : - Blocks.dirt.getState()) : Blocks.grass.getState()); - return; - } - } - super.tick(worldIn, pos, state, rand); + else if(Vars.swampDry) { + float temp = worldIn.getTemperatureC(pos); + if(temp >= 38.0f) + worldIn.setState(pos, temp >= 50.0f ? (worldIn.rand.chance(20) ? Blocks.coarse_dirt.getState() : + Blocks.dirt.getState()) : Blocks.grass.getState()); } } } diff --git a/common/src/main/java/common/block/foliage/BlockTianSoil.java b/common/src/main/java/common/block/foliage/BlockTianSoil.java index df73a650..86624e80 100755 --- a/common/src/main/java/common/block/foliage/BlockTianSoil.java +++ b/common/src/main/java/common/block/foliage/BlockTianSoil.java @@ -1,22 +1,54 @@ package common.block.foliage; +import common.block.Block; import common.block.Material; import common.init.Blocks; import common.item.CheatTab; import common.item.Item; +import common.model.Model; +import common.model.Model.ModelProvider; +import common.properties.Property; +import common.properties.PropertyBool; import common.rng.Random; +import common.util.BlockPos; +import common.world.IWorldAccess; import common.world.State; -public class BlockTianSoil extends BlockSnowable +public class BlockTianSoil extends Block { - public BlockTianSoil(boolean snowy) + public static final PropertyBool SNOWY = PropertyBool.create("snowy"); + + public BlockTianSoil() { - super(Material.SOLID, snowy); + super(Material.SOLID); + this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); this.setTab(CheatTab.NATURE); } + public State getState(State state, IWorldAccess worldIn, BlockPos pos) + { + Block block = worldIn.getState(pos.up()).getBlock(); + return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.snow || block == Blocks.snow_layer)); + } + public Item getDrop(State state, Random rand, int fortune) { return Blocks.tian.getDrop(Blocks.tian.getState(), rand, fortune); } + + protected Property[] getProperties() + { + return new Property[] {SNOWY}; + } + + public Model getModel(ModelProvider provider, String name, State state) { + if(state.getValue(SNOWY)) + return provider.getModel("tian").add().d().u("snow").nswe().add().nswe("tian_soil_snowed"); + else + return provider.getModel("tian").add().d().u("tian_soil_top").nswe().add().nswe("tian_soil_side"); + } + + protected Property[] getUnsavedProperties() { + return new Property[] {SNOWY}; + } } diff --git a/common/src/main/java/common/block/liquid/BlockDynamicLiquid.java b/common/src/main/java/common/block/liquid/BlockDynamicLiquid.java index e8400379..5f609279 100755 --- a/common/src/main/java/common/block/liquid/BlockDynamicLiquid.java +++ b/common/src/main/java/common/block/liquid/BlockDynamicLiquid.java @@ -42,10 +42,10 @@ public class BlockDynamicLiquid extends BlockLiquid public void tick(AWorldServer worldIn, BlockPos pos, State state, Random rand) { - if(this.material == Material.WATER && !worldIn.getState(pos.up()).getBlock().isOpaqueCube() && worldIn.canBlockFreeze(pos, true) && rand.chance(25)) { - worldIn.setState(pos, Blocks.ice.getState()); - return; - } + if(this.material == Material.WATER && !worldIn.getState(pos.up()).getBlock().isOpaqueCube() && worldIn.canBlockFreeze(pos, true) && rand.chance(25)) { + worldIn.setState(pos, Blocks.ice.getState()); + return; + } if(!Vars.liquidPhysics) return; int i = ((Integer)state.getValue(LEVEL)).intValue(); diff --git a/common/src/main/java/common/block/liquid/BlockLiquid.java b/common/src/main/java/common/block/liquid/BlockLiquid.java index c39d7a08..9e033c60 100755 --- a/common/src/main/java/common/block/liquid/BlockLiquid.java +++ b/common/src/main/java/common/block/liquid/BlockLiquid.java @@ -105,7 +105,7 @@ public abstract class BlockLiquid extends Block public boolean canRender(IWorldAccess worldIn, BlockPos pos, Facing side) { - Block block = worldIn.getState(pos).getBlock(); + Block block = worldIn.getState(pos).getBlock(); Material material = block.getMaterial(); return material.isLiquid() && (material.isColdLiquid() == this.material.isColdLiquid()) ? false : (side == Facing.UP ? true : !block.isNonBlock() && super.canRender(worldIn, pos, side)); } @@ -324,6 +324,11 @@ public abstract class BlockLiquid extends Block { return new Property[] {LEVEL}; } + + public boolean isXrayVisible() + { + return true; + } protected boolean hasRegisteredItem() { return false; diff --git a/common/src/main/java/common/block/liquid/BlockStaticLiquid.java b/common/src/main/java/common/block/liquid/BlockStaticLiquid.java index 8c8ce8ba..31c3284a 100755 --- a/common/src/main/java/common/block/liquid/BlockStaticLiquid.java +++ b/common/src/main/java/common/block/liquid/BlockStaticLiquid.java @@ -93,9 +93,8 @@ public class BlockStaticLiquid extends BlockLiquid } } } - - if(this.material == Material.WATER && !worldIn.getState(pos.up()).getBlock().isOpaqueCube() && worldIn.canBlockFreeze(pos, true)) - worldIn.setState(pos, Blocks.ice.getState()); + if(this.material == Material.WATER && !worldIn.getState(pos.up()).getBlock().isOpaqueCube() && worldIn.canBlockFreeze(pos, true)) + worldIn.setState(pos, Blocks.ice.getState()); } protected boolean isSurroundingBlockFlammable(World worldIn, BlockPos pos) diff --git a/common/src/main/java/common/block/natural/BlockBedrock.java b/common/src/main/java/common/block/natural/BlockBedrock.java index e16a13b1..86d2b9f9 100755 --- a/common/src/main/java/common/block/natural/BlockBedrock.java +++ b/common/src/main/java/common/block/natural/BlockBedrock.java @@ -8,7 +8,7 @@ import common.util.ParticleType; import common.world.State; import common.world.World; -public class BlockBedrock extends BlockNonBlock { +public class BlockBedrock extends Block { public BlockBedrock() { super(Material.SOLID); } diff --git a/common/src/main/java/common/block/natural/BlockBlackenedDirt.java b/common/src/main/java/common/block/natural/BlockBlackenedDirt.java index 3503bf39..b4d370aa 100644 --- a/common/src/main/java/common/block/natural/BlockBlackenedDirt.java +++ b/common/src/main/java/common/block/natural/BlockBlackenedDirt.java @@ -10,7 +10,7 @@ import common.vars.Vars; import common.world.State; import common.world.AWorldServer; -public class BlockBlackenedDirt extends BlockNonBlock +public class BlockBlackenedDirt extends Block { public BlockBlackenedDirt() { diff --git a/common/src/main/java/common/block/natural/BlockBlackenedStone.java b/common/src/main/java/common/block/natural/BlockBlackenedStone.java index fdc47a59..03b216f5 100644 --- a/common/src/main/java/common/block/natural/BlockBlackenedStone.java +++ b/common/src/main/java/common/block/natural/BlockBlackenedStone.java @@ -8,7 +8,7 @@ import common.item.Item; import common.rng.Random; import common.world.State; -public class BlockBlackenedStone extends BlockNonBlock { +public class BlockBlackenedStone extends Block { public BlockBlackenedStone() { super(Material.SOLID); this.setTab(CheatTab.ROCK); diff --git a/common/src/main/java/common/block/natural/BlockClay.java b/common/src/main/java/common/block/natural/BlockClay.java index 6e430889..3c5a637c 100755 --- a/common/src/main/java/common/block/natural/BlockClay.java +++ b/common/src/main/java/common/block/natural/BlockClay.java @@ -8,7 +8,7 @@ import common.item.Item; import common.rng.Random; import common.world.State; -public class BlockClay extends BlockNonBlock +public class BlockClay extends Block { public BlockClay() { diff --git a/common/src/main/java/common/block/natural/BlockColoredClay.java b/common/src/main/java/common/block/natural/BlockColoredClay.java index b429dd79..31e02ebb 100644 --- a/common/src/main/java/common/block/natural/BlockColoredClay.java +++ b/common/src/main/java/common/block/natural/BlockColoredClay.java @@ -8,7 +8,7 @@ import common.model.Model.ModelProvider; import common.util.Color; import common.world.State; -public class BlockColoredClay extends BlockNonBlock { +public class BlockColoredClay extends Block { public static final BlockColoredClay[] CLAY = new BlockColoredClay[Color.values().length]; private final Color color; diff --git a/common/src/main/java/common/block/natural/BlockCyber.java b/common/src/main/java/common/block/natural/BlockCyber.java index 7c728f74..bf579311 100644 --- a/common/src/main/java/common/block/natural/BlockCyber.java +++ b/common/src/main/java/common/block/natural/BlockCyber.java @@ -1,11 +1,12 @@ package common.block.natural; +import common.block.Block; import common.block.Material; import common.block.SoundType; import common.item.CheatTab; import common.util.Clientside; -public class BlockCyber extends BlockNonBlock { +public class BlockCyber extends Block { public BlockCyber() { super(Material.SOLID); this.setTab(CheatTab.ROCK); @@ -17,6 +18,16 @@ public class BlockCyber extends BlockNonBlock { @Clientside public float getShinyness() { - return -32.0f; + return 0.0f; + } + + @Clientside + public boolean isNonBlock() { + return true; + } + + @Clientside + public boolean isOpaqueCube() { + return true; } } diff --git a/common/src/main/java/common/block/natural/BlockGlowstone.java b/common/src/main/java/common/block/natural/BlockGlowstone.java index d8667c0f..ca1677d1 100755 --- a/common/src/main/java/common/block/natural/BlockGlowstone.java +++ b/common/src/main/java/common/block/natural/BlockGlowstone.java @@ -13,7 +13,7 @@ import common.util.Serverside; import common.world.AWorldServer; import common.world.State; -public class BlockGlowstone extends BlockNonBlock +public class BlockGlowstone extends Block { public BlockGlowstone(Material materialIn) { diff --git a/common/src/main/java/common/block/natural/BlockHardenedClay.java b/common/src/main/java/common/block/natural/BlockHardenedClay.java index f3ee6a92..4a29f7e9 100755 --- a/common/src/main/java/common/block/natural/BlockHardenedClay.java +++ b/common/src/main/java/common/block/natural/BlockHardenedClay.java @@ -1,9 +1,10 @@ package common.block.natural; +import common.block.Block; import common.block.Material; import common.item.CheatTab; -public class BlockHardenedClay extends BlockNonBlock +public class BlockHardenedClay extends Block { public BlockHardenedClay() { diff --git a/common/src/main/java/common/block/natural/BlockHellRock.java b/common/src/main/java/common/block/natural/BlockHellRock.java index 5150c789..817dc3d6 100755 --- a/common/src/main/java/common/block/natural/BlockHellRock.java +++ b/common/src/main/java/common/block/natural/BlockHellRock.java @@ -4,7 +4,7 @@ import common.block.Block; import common.block.Material; import common.item.CheatTab; -public class BlockHellRock extends BlockNonBlock +public class BlockHellRock extends Block { public BlockHellRock() { diff --git a/common/src/main/java/common/block/natural/BlockIce.java b/common/src/main/java/common/block/natural/BlockIce.java index fcc4e013..2cab9139 100755 --- a/common/src/main/java/common/block/natural/BlockIce.java +++ b/common/src/main/java/common/block/natural/BlockIce.java @@ -16,7 +16,7 @@ import common.world.World; import common.world.AWorldServer; import common.world.IWorldAccess; -public class BlockIce extends BlockNonBlock { +public class BlockIce extends Block { public BlockIce() { super(Material.LOOSE); this.setSlipperiness(0.98F); diff --git a/common/src/main/java/common/block/natural/BlockNonBlock.java b/common/src/main/java/common/block/natural/BlockNonBlock.java deleted file mode 100644 index cb4ad439..00000000 --- a/common/src/main/java/common/block/natural/BlockNonBlock.java +++ /dev/null @@ -1,19 +0,0 @@ -package common.block.natural; - -import common.block.Block; -import common.block.Material; - -public class BlockNonBlock extends Block { - public BlockNonBlock(Material material) { - super(material); - this.setOpacity(255); - } - - public boolean isOpaqueCube() { - return false; - } - - public boolean isNonBlock() { - return true; - } -} diff --git a/common/src/main/java/common/block/natural/BlockObsidian.java b/common/src/main/java/common/block/natural/BlockObsidian.java index 701273a3..897554b5 100755 --- a/common/src/main/java/common/block/natural/BlockObsidian.java +++ b/common/src/main/java/common/block/natural/BlockObsidian.java @@ -1,15 +1,34 @@ package common.block.natural; +import common.block.Block; import common.block.Material; +import common.init.Items; import common.item.CheatTab; +import common.item.Item; +import common.rng.Random; +import common.world.State; -public class BlockObsidian extends BlockNonBlock { - public BlockObsidian() { - super(Material.SOLID); - this.setTab(CheatTab.ROCK); - } +public class BlockObsidian extends Block +{ + public BlockObsidian() + { + super(Material.SOLID); + this.setTab(CheatTab.ROCK); + } -// public Item getDrop(State state, Random rand, int fortune) { -// return Items.obsidian; + /** + * Get the Item that this Block should drop when harvested. + */ + public Item getDrop(State state, Random rand, int fortune) + { + return Items.obsidian; + } + +// /** +// * Get the MapColor for this Block and the given BlockState +// */ +// public MapColor getMapColor(IBlockState state) +// { +// return MapColor.blackColor; // } } diff --git a/common/src/main/java/common/block/natural/BlockOre.java b/common/src/main/java/common/block/natural/BlockOre.java index ea01a9a5..1eca4564 100755 --- a/common/src/main/java/common/block/natural/BlockOre.java +++ b/common/src/main/java/common/block/natural/BlockOre.java @@ -1,5 +1,6 @@ package common.block.natural; +import common.block.Block; import common.block.Material; import common.item.CheatTab; import common.item.Item; @@ -10,7 +11,7 @@ import common.vars.Vars; import common.world.State; import common.world.World; -public class BlockOre extends BlockNonBlock +public class BlockOre extends Block { private ItemStack smeltItem; private ItemStack dropItem; diff --git a/common/src/main/java/common/block/natural/BlockPackedIce.java b/common/src/main/java/common/block/natural/BlockPackedIce.java index b0f1b3c9..b15822eb 100755 --- a/common/src/main/java/common/block/natural/BlockPackedIce.java +++ b/common/src/main/java/common/block/natural/BlockPackedIce.java @@ -5,7 +5,7 @@ import common.block.Material; import common.item.CheatTab; import common.rng.Random; -public class BlockPackedIce extends BlockNonBlock +public class BlockPackedIce extends Block { public BlockPackedIce() { diff --git a/common/src/main/java/common/block/natural/BlockPodzol.java b/common/src/main/java/common/block/natural/BlockPodzol.java index c85599bc..168a0633 100644 --- a/common/src/main/java/common/block/natural/BlockPodzol.java +++ b/common/src/main/java/common/block/natural/BlockPodzol.java @@ -1,20 +1,50 @@ package common.block.natural; +import common.block.Block; import common.block.Material; -import common.block.foliage.BlockSnowable; +import common.init.Blocks; import common.init.Items; import common.item.CheatTab; import common.item.Item; +import common.model.Model; +import common.model.Model.ModelProvider; +import common.properties.Property; +import common.properties.PropertyBool; import common.rng.Random; +import common.util.BlockPos; +import common.world.IWorldAccess; import common.world.State; -public class BlockPodzol extends BlockSnowable { - public BlockPodzol(boolean snowy) { - super(Material.LOOSE, snowy); +public class BlockPodzol extends Block { + public static final PropertyBool SNOWY = PropertyBool.create("snowy"); + + public BlockPodzol() { + super(Material.LOOSE); + this.setDefaultState(this.getBaseState().withProperty(SNOWY, Boolean.valueOf(false))); this.setTab(CheatTab.NATURE); } + public State getState(State state, IWorldAccess worldIn, BlockPos pos) { + Block block = worldIn.getState(pos.up()).getBlock(); + return state.withProperty(SNOWY, Boolean.valueOf(block == Blocks.snow || block == Blocks.snow_layer)); + } + + protected Property[] getProperties() { + return new Property[] {SNOWY}; + } + public Item getDrop(State state, Random rand, int fortune) { return Items.dirt; } + + public Model getModel(ModelProvider provider, String name, State state) { + if(state.getValue(SNOWY)) + return provider.getModel("dirt").add().d().u("snow").nswe().add().nswe("soil_snowed"); + else + return provider.getModel("dirt").add().d().u("podzol_top").nswe().add().nswe("podzol_side"); + } + + protected Property[] getUnsavedProperties() { + return new Property[] {SNOWY}; + } } diff --git a/common/src/main/java/common/block/natural/BlockSandStone.java b/common/src/main/java/common/block/natural/BlockSandStone.java index 3078a35e..c2fd0d88 100755 --- a/common/src/main/java/common/block/natural/BlockSandStone.java +++ b/common/src/main/java/common/block/natural/BlockSandStone.java @@ -1,11 +1,22 @@ package common.block.natural; +import common.block.Block; import common.block.Material; import common.item.CheatTab; +import common.model.Model; +import common.model.Model.ModelProvider; +import common.world.State; -public class BlockSandStone extends BlockNonBlock { - public BlockSandStone() { +public class BlockSandStone extends Block { + private final String texture; + + public BlockSandStone(String texture) { super(Material.SOLID); + this.texture = texture; this.setTab(CheatTab.ROCK); } + + public Model getModel(ModelProvider provider, String name, State state) { + return provider.getModel("sandstone_" + this.texture).add().nswe().d("sandstone_bottom").u("sandstone_all"); + } } diff --git a/common/src/main/java/common/block/natural/BlockSlime.java b/common/src/main/java/common/block/natural/BlockSlime.java index 8fa32740..4a8bb267 100755 --- a/common/src/main/java/common/block/natural/BlockSlime.java +++ b/common/src/main/java/common/block/natural/BlockSlime.java @@ -7,7 +7,7 @@ import common.item.CheatTab; import common.util.BlockPos; import common.world.World; -public class BlockSlime extends BlockNonBlock { +public class BlockSlime extends Block { public BlockSlime() { super(Material.LOOSE); this.setTab(CheatTab.NATURE); diff --git a/common/src/main/java/common/block/natural/BlockSnow.java b/common/src/main/java/common/block/natural/BlockSnow.java index 06293416..0cddfaea 100755 --- a/common/src/main/java/common/block/natural/BlockSnow.java +++ b/common/src/main/java/common/block/natural/BlockSnow.java @@ -80,7 +80,7 @@ public class BlockSnow extends Block { State iblockstate = worldIn.getState(pos.down()); Block block = iblockstate.getBlock(); - return block != Blocks.ice && block != Blocks.packed_ice ? (block == this && ((Integer)iblockstate.getValue(LAYERS)).intValue() >= 7 ? true : block.isOpaqueCube() && block.getMaterial().blocksMovement()) : false; + return block != Blocks.ice && block != Blocks.packed_ice ? (block.getMaterial() == Material.LEAVES ? true : (block == this && ((Integer)iblockstate.getValue(LAYERS)).intValue() >= 7 ? true : block.isOpaqueCube() && block.getMaterial().blocksMovement())) : false; } /** diff --git a/common/src/main/java/common/block/natural/BlockSnowBlock.java b/common/src/main/java/common/block/natural/BlockSnowBlock.java index 1e59ce08..e9efc9eb 100755 --- a/common/src/main/java/common/block/natural/BlockSnowBlock.java +++ b/common/src/main/java/common/block/natural/BlockSnowBlock.java @@ -11,7 +11,7 @@ import common.vars.Vars; import common.world.State; import common.world.AWorldServer; -public class BlockSnowBlock extends BlockNonBlock { +public class BlockSnowBlock extends Block { public BlockSnowBlock() { super(Material.DIGGABLE); this.setTicked(); diff --git a/common/src/main/java/common/block/natural/BlockSoulSand.java b/common/src/main/java/common/block/natural/BlockSoulSand.java index cbbe9a7e..d1da31d5 100755 --- a/common/src/main/java/common/block/natural/BlockSoulSand.java +++ b/common/src/main/java/common/block/natural/BlockSoulSand.java @@ -1,5 +1,6 @@ package common.block.natural; +import common.block.Block; import common.block.Material; import common.entity.Entity; import common.item.CheatTab; @@ -8,7 +9,7 @@ import common.util.BoundingBox; import common.world.State; import common.world.World; -public class BlockSoulSand extends BlockNonBlock +public class BlockSoulSand extends Block { public BlockSoulSand() { diff --git a/common/src/main/java/common/block/natural/BlockStone.java b/common/src/main/java/common/block/natural/BlockStone.java index 172c1ccd..9ac5e0d6 100755 --- a/common/src/main/java/common/block/natural/BlockStone.java +++ b/common/src/main/java/common/block/natural/BlockStone.java @@ -1,5 +1,6 @@ package common.block.natural; +import common.block.Block; import common.block.Material; import common.init.Items; import common.item.CheatTab; @@ -7,7 +8,7 @@ import common.item.Item; import common.rng.Random; import common.world.State; -public class BlockStone extends BlockNonBlock { +public class BlockStone extends Block { public BlockStone() { super(Material.SOLID); this.setTab(CheatTab.ROCK); diff --git a/common/src/main/java/common/block/tech/BlockAnvil.java b/common/src/main/java/common/block/tech/BlockAnvil.java index c716e142..defab22b 100755 --- a/common/src/main/java/common/block/tech/BlockAnvil.java +++ b/common/src/main/java/common/block/tech/BlockAnvil.java @@ -50,9 +50,13 @@ public class BlockAnvil extends BlockFalling implements Rotatable return false; } - public boolean isNonBlock() { - return false; - } + /** + * Used to determine ambient occlusion and culling when rebuilding chunks for render + */ + public boolean isOpaqueCube() + { + return false; + } public boolean isMagnetic() { return true; diff --git a/common/src/main/java/common/block/tech/BlockDisplay.java b/common/src/main/java/common/block/tech/BlockDisplay.java index 012cc605..f9b95217 100644 --- a/common/src/main/java/common/block/tech/BlockDisplay.java +++ b/common/src/main/java/common/block/tech/BlockDisplay.java @@ -80,6 +80,12 @@ public abstract class BlockDisplay extends Block implements Rotatable return super.getCollisionBox(worldIn, pos, state); } + public BoundingBox getSelectionBox(World worldIn, BlockPos pos) + { + this.setBlockBounds(worldIn, pos); + return super.getSelectionBox(worldIn, pos); + } + public boolean isFullCube() { return false; diff --git a/common/src/main/java/common/block/tech/BlockSign.java b/common/src/main/java/common/block/tech/BlockSign.java index 7d0576e2..9467ebd8 100755 --- a/common/src/main/java/common/block/tech/BlockSign.java +++ b/common/src/main/java/common/block/tech/BlockSign.java @@ -50,6 +50,12 @@ public class BlockSign extends Block implements ITileEntityProvider, Rotatable return null; } + public BoundingBox getSelectionBox(World worldIn, BlockPos pos) + { + this.setBlockBounds(worldIn, pos); + return super.getSelectionBox(worldIn, pos); + } + public boolean isFullCube() { return false; diff --git a/common/src/main/java/common/init/BlockRegistry.java b/common/src/main/java/common/init/BlockRegistry.java index 515febca..1cd2ea75 100755 --- a/common/src/main/java/common/init/BlockRegistry.java +++ b/common/src/main/java/common/init/BlockRegistry.java @@ -132,23 +132,24 @@ public abstract class BlockRegistry { Block stone = register("stone", (new BlockStone()).setHardness(1.5F).setResistance(10.0F).setSound(SoundType.STONE).setDisplay("Stein")); Block bedrock = register("bedrock", (new BlockBedrock()).setHardness(1000.0F).setResistance(100000.0F).setSound(SoundType.STONE) .setDisplay("Grundgestein").setTab(CheatTab.ROCK).setMiningTool(Equipment.PICKAXE, 6)); - Block rock = register("rock", (new BlockNonBlock(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE).setDisplay("Felsen").setTab(CheatTab.ROCK)); - Block smooth_rock = register("smooth_rock", (new BlockNonBlock(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE).setDisplay("Glatter Felsen").setTab(CheatTab.ROCK)); + Block rock = register("rock", (new Block(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE).setDisplay("Felsen").setTab(CheatTab.ROCK)); + Block smooth_rock = register("smooth_rock", (new Block(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE).setDisplay("Glatter Felsen").setTab(CheatTab.ROCK)); Block hellrock = register("hellrock", (new BlockHellRock()).setHardness(0.4F).setSound(SoundType.STONE).setDisplay("Höllenstein")); - Block cell_rock = register("cell_rock", (new BlockNonBlock(Material.LOOSE)).setHardness(1.0F).setResistance(3.0F) + Block cell_rock = register("cell_rock", (new Block(Material.LOOSE)).setHardness(1.0F).setResistance(3.0F) .setSound(SoundType.SLIME).setDisplay("Zellstein").setTab(CheatTab.ROCK)); - Block moon_rock = register("moon_rock", (new BlockNonBlock(Material.SOLID)).setHardness(2.5F).setResistance(10.0F) + Block moon_rock = register("moon_rock", (new Block(Material.SOLID)).setHardness(2.5F).setResistance(10.0F) .setSound(SoundType.STONE).setDisplay("Mondgestein").setTab(CheatTab.ROCK)); - Block cobblestone = (new BlockNonBlock(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setSound(SoundType.STONE) + Block cobblestone = (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setSound(SoundType.STONE) .setDisplay("Bruchstein").setTab(CheatTab.ROCK); register("cobblestone", cobblestone); - Block mossy_cobblestone = (new BlockNonBlock(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setSound(SoundType.STONE) + Block mossy_cobblestone = (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setSound(SoundType.STONE) .setDisplay("Bemooster Bruchstein").setTab(CheatTab.ROCK); register("mossy_cobblestone", mossy_cobblestone); - Block sandstone = (new BlockSandStone()).setSound(SoundType.STONE).setHardness(0.8F).setDisplay("Sandstein"); + Block sandstone = (new BlockSandStone("normal")).setSound(SoundType.STONE).setHardness(0.8F).setDisplay("Sandstein"); register("sandstone", sandstone); Block smooth_sandstone; - register("smooth_sandstone", (smooth_sandstone = new BlockSandStone()).setSound(SoundType.STONE).setHardness(0.8F).setDisplay("Glatter Sandstein")); + register("smooth_sandstone", (smooth_sandstone = new BlockSandStone("smooth")).setSound(SoundType.STONE).setHardness(0.8F).setDisplay("Glatter Sandstein")); + register("carved_sandstone", (new BlockSandStone("carved")).setSound(SoundType.STONE).setHardness(0.8F).setDisplay("Gemeißelter Sandstein")); Block obsidian = register("obsidian", (new BlockObsidian()).setHardness(50.0F).setResistance(2000.0F).setSound(SoundType.STONE) .setDisplay("Obsidian").setMiningTool(Equipment.PICKAXE, 3)); Block clay = register("clay", (new BlockClay()).setHardness(0.6F).setSound(SoundType.GRAVEL).setDisplay("Ton").setMiningTool(Equipment.SHOVEL)); @@ -173,7 +174,7 @@ public abstract class BlockRegistry { register("glowstone", (new BlockGlowstone(Material.TRANSLUCENT)).setHardness(0.3F).setSound(SoundType.GLASS).setLight(0xffff3f) .setDisplay("Glowstone")); Block blackened_stone = register("blackened_stone", (new BlockBlackenedStone()).setHardness(1.5F).setResistance(10.0F).setSound(SoundType.STONE).setDisplay("Schwarzstein")); - Block blackened_cobble = register("blackened_cobble", (new BlockNonBlock(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setSound(SoundType.STONE) + Block blackened_cobble = register("blackened_cobble", (new Block(Material.SOLID)).setHardness(2.0F).setResistance(10.0F).setSound(SoundType.STONE) .setDisplay("Schwarzbruchstein").setTab(CheatTab.ROCK)); @@ -211,38 +212,27 @@ public abstract class BlockRegistry { Block dirt; - register("dirt", (dirt = new BlockNonBlock(Material.LOOSE)).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Erde").setMiningTool(Equipment.SHOVEL).setTab(CheatTab.NATURE)); - BlockSnowable grass; - register("grass", (grass = new BlockGrass(false)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Gras").setMiningTool(Equipment.SHOVEL)); - BlockSnowable snowy_grass; - register("snowy_grass", (snowy_grass = new BlockGrass(true).setOther(grass)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Beschneites Gras").setMiningTool(Equipment.SHOVEL)); + register("dirt", (dirt = new Block(Material.LOOSE)).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Erde").setMiningTool(Equipment.SHOVEL).setTab(CheatTab.NATURE)); + Block grass; + register("grass", (grass = new BlockGrass()).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Gras").setMiningTool(Equipment.SHOVEL)); Block coarse_dirt; - register("coarse_dirt", (coarse_dirt = new BlockNonBlock(Material.LOOSE)).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Grobe Erde").setMiningTool(Equipment.SHOVEL).setTab(CheatTab.NATURE)); - BlockSnowable podzol; - register("podzol", (podzol = new BlockPodzol(false)).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Podsol").setMiningTool(Equipment.SHOVEL)); - BlockSnowable snowy_podzol; - register("snowy_podzol", (snowy_podzol = new BlockPodzol(true).setOther(podzol)).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Beschneiter Podsol").setMiningTool(Equipment.SHOVEL)); - BlockSnowable mycelium; - register("mycelium", (mycelium = new BlockMycelium(false)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Myzel").setMiningTool(Equipment.SHOVEL)); - BlockSnowable snowy_mycelium; - register("snowy_mycelium", (snowy_mycelium = new BlockMycelium(true).setOther(mycelium)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Beschneites Myzel").setMiningTool(Equipment.SHOVEL)); - BlockSnowable swamp; - register("swamp", (swamp = new BlockSwamp(false)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Sumpf").setMiningTool(Equipment.SHOVEL)); - BlockSnowable snowy_swamp; - register("snowy_swamp", (snowy_swamp = new BlockSwamp(true).setOther(swamp)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Beschneiter Sumpf").setMiningTool(Equipment.SHOVEL)); + register("coarse_dirt", (coarse_dirt = new Block(Material.LOOSE)).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Grobe Erde").setMiningTool(Equipment.SHOVEL).setTab(CheatTab.NATURE)); + Block podzol; + register("podzol", (podzol = new BlockPodzol()).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Podsol").setMiningTool(Equipment.SHOVEL)); + Block mycelium; + register("mycelium", (mycelium = new BlockMycelium()).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Myzel").setMiningTool(Equipment.SHOVEL)); + Block swamp; + register("swamp", (swamp = new BlockSwamp()).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Sumpf").setMiningTool(Equipment.SHOVEL)); Block tian; - register("tian", (tian = new BlockNonBlock(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE) + register("tian", (tian = new Block(Material.SOLID)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE) .setDisplay("Tian").setTab(CheatTab.NATURE)); - BlockSnowable tian_soil; - register("tian_soil", (tian_soil = new BlockTianSoil(false)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE).setDisplay("Tianerde").setTab(CheatTab.NATURE)); - BlockSnowable snowy_tian_soil; - register("snowy_tian_soil", (snowy_tian_soil = new BlockTianSoil(true).setOther(tian_soil)).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE).setDisplay("Beschneite Tianerde").setTab(CheatTab.NATURE)); + Block tian_soil; + register("tian_soil", (tian_soil = new BlockTianSoil()).setHardness(2.0F).setResistance(15.0F).setSound(SoundType.STONE) + .setDisplay("Tianerde").setTab(CheatTab.NATURE)); Block blackened_dirt; register("blackened_dirt", (blackened_dirt = new BlockBlackenedDirt()).setHardness(0.5F).setSound(SoundType.GRAVEL).setDisplay("Schwarzerde").setMiningTool(Equipment.SHOVEL)); - BlockSnowable blackened_soil; - register("blackened_soil", (blackened_soil = new BlockBlackenedSoil(false)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Schwarzgrund").setMiningTool(Equipment.SHOVEL)); - BlockSnowable snowy_blackened_soil; - register("snowy_blackened_soil", (snowy_blackened_soil = new BlockBlackenedSoil(true).setOther(blackened_soil)).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Beschneiter Schwarzgrund").setMiningTool(Equipment.SHOVEL)); + Block blackened_soil; + register("blackened_soil", (blackened_soil = new BlockBlackenedSoil()).setHardness(0.6F).setSound(SoundType.GRASS).setDisplay("Schwarzgrund").setMiningTool(Equipment.SHOVEL)); Block slime_block; register("slime_block", (slime_block = new BlockSlime()).setDisplay("Schleimblock").setSound(SoundType.SLIME)); Block cheese; @@ -436,11 +426,11 @@ public abstract class BlockRegistry { register("mossy_cobblestone_stairs", (new BlockStairs(mossy_cobblestone)).setDisplay("Bemooste Bruchsteintreppe")); register("mossy_cobblestone_wall", (new BlockWall(mossy_cobblestone)).setDisplay("Bemooste Bruchsteinmauer")); - register("sandstone_slab", (new BlockSlab(sandstone)).setDisplay("Sandsteinstufe")); - register("sandstone_stairs", (new BlockStairs(sandstone)).setDisplay("Sandsteintreppe")); + register("sandstone_slab", (new BlockSlab(sandstone, "sandstone_bottom", "sandstone_all")).setDisplay("Sandsteinstufe")); + register("sandstone_stairs", (new BlockStairs(sandstone, "sandstone_bottom", "sandstone_all")).setDisplay("Sandsteintreppe")); - register("smooth_sandstone_slab", (new BlockSlab(smooth_sandstone)).setDisplay("Glatte Sandsteinstufe")); - register("smooth_sandstone_stairs", (new BlockStairs(smooth_sandstone)).setDisplay("Glatte Sandsteintreppe")); + register("smooth_sandstone_slab", (new BlockSlab(smooth_sandstone, "sandstone_bottom", "sandstone_all")).setDisplay("Glatte Sandsteinstufe")); + register("smooth_sandstone_stairs", (new BlockStairs(smooth_sandstone, "sandstone_bottom", "sandstone_all")).setDisplay("Glatte Sandsteintreppe")); register("obsidian_slab", (new BlockSlab(obsidian)).setDisplay("Obsidianstufe")); register("obsidian_stairs", (new BlockStairs(obsidian)).setDisplay("Obsidiantreppe")); @@ -469,32 +459,24 @@ public abstract class BlockRegistry { register("dirt_slab", (new BlockSlab(dirt)).setDisplay("Erdstufe")); register("dirt_stairs", (new BlockStairs(dirt)).setDisplay("Erdtreppe")); - register("grass_slab", (new BlockSlab(grass)).setDisplay("Grasstufe")); - register("grass_stairs", (new BlockStairs(grass)).setDisplay("Grastreppe")); + register("grass_slab", (new BlockSlab(grass, "dirt", "grass_top", "dirt", "grass_side")).setDisplay("Grasstufe")); register("coarse_dirt_slab", (new BlockSlab(coarse_dirt)).setDisplay("Grobe Erdstufe")); register("coarse_dirt_stairs", (new BlockStairs(coarse_dirt)).setDisplay("Grobe Erdtreppe")); - - register("podzol_slab", (new BlockSlab(podzol)).setDisplay("Podsolstufe")); - register("podzol_stairs", (new BlockStairs(podzol)).setDisplay("Podsoltreppe")); - - register("mycelium_slab", (new BlockSlab(mycelium)).setDisplay("Myzelstufe")); - register("mycelium_stairs", (new BlockStairs(mycelium)).setDisplay("Myzeltreppe")); - - register("swamp_slab", (new BlockSlab(swamp)).setDisplay("Sumpfstufe")); - register("swamp_stairs", (new BlockStairs(swamp)).setDisplay("Sumpftreppe")); + + register("podzol_slab", (new BlockSlab(podzol, "dirt", "podzol_top", "dirt", "podzol_side")).setDisplay("Podsolstufe")); + + register("mycelium_slab", (new BlockSlab(mycelium, "dirt", "mycelium_top", "dirt", "mycelium_side")).setDisplay("Myzelstufe")); + + register("swamp_slab", (new BlockSlab(swamp, "dirt", "swamp_top", "dirt", "swamp_side")).setDisplay("Sumpfstufe")); register("tian_slab", (new BlockSlab(tian)).setDisplay("Tianstufe")); register("tian_stairs", (new BlockStairs(tian)).setDisplay("Tiantreppe")); - - register("tian_soil_slab", (new BlockSlab(tian_soil)).setDisplay("Tianerdestufe")); - register("tian_soil_stairs", (new BlockStairs(tian_soil)).setDisplay("Tianerdetreppe")); + register("tian_soil_slab", (new BlockSlab(tian_soil, "tian", "tian_soil_top", "tian", "tian_soil_side")).setDisplay("Tianerdestufe")); register("blackened_dirt_slab", (new BlockSlab(blackened_dirt)).setDisplay("Schwarzerdestufe")); register("blackened_dirt_stairs", (new BlockStairs(blackened_dirt)).setDisplay("Schwarzerdetreppe")); - - register("blackened_soil_slab", (new BlockSlab(blackened_soil)).setDisplay("Schwarzgrasstufe")); - register("blackened_soil_stairs", (new BlockStairs(blackened_soil)).setDisplay("Schwarzgrastreppe")); + register("blackened_soil_slab", (new BlockSlab(blackened_soil, "blackened_dirt", "blackened_soil_top", "blackened_dirt", "blackened_soil_side")).setDisplay("Schwarzgrasstufe")); register("slime_slab", (new BlockSlab(slime_block)).setDisplay("Schleimstufe")); register("slime_stairs", (new BlockStairs(slime_block)).setDisplay("Schleimtreppe")); diff --git a/common/src/main/java/common/init/Blocks.java b/common/src/main/java/common/init/Blocks.java index 5d20e069..2137d57d 100755 --- a/common/src/main/java/common/init/Blocks.java +++ b/common/src/main/java/common/init/Blocks.java @@ -84,9 +84,9 @@ public abstract class Blocks { public static final BlockSlab black_quartz_slab = get("black_quartz_slab"); public static final BlockStairs black_quartz_stairs = get("black_quartz_stairs"); public static final BlockWool black_wool = get("black_wool"); + public static final Block blackened_cobble = get("blackened_cobble"); public static final BlockBlackenedDirt blackened_dirt = get("blackened_dirt"); public static final BlockBlackenedSoil blackened_soil = get("blackened_soil"); - public static final BlockBlackenedSoil snowy_blackened_soil = get("snowy_blackened_soil"); public static final BlockBlackenedStone blackened_stone = get("blackened_stone"); public static final BlockDoor black_wood_door = get("black_wood_door"); public static final BlockFence black_wood_fence = get("black_wood_fence"); @@ -130,8 +130,10 @@ public abstract class Blocks { public static final BlockMetalBlock calcium_block = get("calcium_block"); public static final BlockMetalOre calcium_ore = get("calcium_ore"); public static final BlockCarrot carrots = get("carrots"); + public static final BlockSandStone carved_sandstone = get("carved_sandstone"); public static final Block carved_stonebrick = get("carved_stonebrick"); public static final BlockCauldron cauldron = get("cauldron"); + public static final Block cell_rock = get("cell_rock"); public static final BlockDoor cherry_door = get("cherry_door"); public static final BlockFence cherry_fence = get("cherry_fence"); public static final BlockFenceGate cherry_fence_gate = get("cherry_fence_gate"); @@ -151,9 +153,10 @@ public abstract class Blocks { public static final BlockClay clay = get("clay"); public static final BlockCompressable coal_block = get("coal_block"); public static final BlockOre coal_ore = get("coal_ore"); - public static final BlockNonBlock coarse_dirt = get("coarse_dirt"); + public static final Block coarse_dirt = get("coarse_dirt"); public static final BlockMetalBlock cobalt_block = get("cobalt_block"); public static final BlockMetalOre cobalt_ore = get("cobalt_ore"); + public static final Block cobblestone = get("cobblestone"); public static final BlockSlab cobblestone_slab = get("cobblestone_slab"); public static final BlockStairs cobblestone_stairs = get("cobblestone_stairs"); public static final BlockWall cobblestone_wall = get("cobblestone_wall"); @@ -185,7 +188,7 @@ public abstract class Blocks { public static final BlockTallGrass dead_bush = get("dead_bush"); public static final BlockDeadBush deadbush = get("deadbush"); public static final BlockOre diamond_ore = get("diamond_ore"); - public static final BlockNonBlock dirt = get("dirt"); + public static final Block dirt = get("dirt"); public static final BlockDispenser dispenser = get("dispenser"); public static final BlockDragonEgg dragon_egg = get("dragon_egg"); public static final BlockDispenser dropper = get("dropper"); @@ -232,7 +235,6 @@ public abstract class Blocks { public static final BlockMetalOre gold_ore = get("gold_ore"); public static final BlockStaticLiquid goo = get("goo"); public static final BlockGrass grass = get("grass"); - public static final BlockGrass snowy_grass = get("snowy_grass"); public static final BlockGravel gravel = get("gravel"); public static final BlockCarpet gray_carpet = get("gray_carpet"); public static final BlockColoredClay gray_clay = get("gray_clay"); @@ -316,6 +318,8 @@ public abstract class Blocks { public static final BlockStaticLiquid mercury = get("mercury"); public static final BlockMobSpawner mob_spawner = get("mob_spawner"); public static final BlockTreasure cheese = get("cheese"); + public static final Block moon_rock = get("moon_rock"); + public static final Block mossy_cobblestone = get("mossy_cobblestone"); public static final BlockWall mossy_cobblestone_wall = get("mossy_cobblestone_wall"); public static final Block mossy_stonebrick = get("mossy_stonebrick"); public static final BlockMycelium mycelium = get("mycelium"); @@ -395,6 +399,7 @@ public abstract class Blocks { public static final BlockWool red_wool = get("red_wool"); public static final BlockOre charged_ore = get("charged_ore"); public static final BlockReed reeds = get("reeds"); + public static final Block rock = get("rock"); public static final BlockFlower rose = get("rose"); public static final BlockDoublePlant rose_bush = get("rose_bush"); public static final BlockOre ruby_ore = get("ruby_ore"); @@ -412,6 +417,7 @@ public abstract class Blocks { public static final BlockSkull skull = get("skull"); public static final BlockStaticLiquid slime = get("slime"); public static final BlockSlime slime_block = get("slime_block"); + public static final Block smooth_rock = get("smooth_rock"); public static final BlockSandStone smooth_sandstone = get("smooth_sandstone"); public static final BlockSnowBlock snow = get("snow"); public static final BlockSnow snow_layer = get("snow_layer"); @@ -451,7 +457,7 @@ public abstract class Blocks { public static final BlockDoublePlant syringa = get("syringa"); public static final BlockTallGrass tallgrass = get("tallgrass"); public static final BlockOre thetium_ore = get("thetium_ore"); - public static final BlockNonBlock tian = get("tian"); + public static final Block tian = get("tian"); public static final BlockDoor tian_wood_door = get("tian_wood_door"); public static final BlockFence tian_wood_fence = get("tian_wood_fence"); public static final BlockFenceGate tian_wood_fence_gate = get("tian_wood_fence_gate"); @@ -864,25 +870,8 @@ public abstract class Blocks { public static final BlockItemPipe pipe = get("pipe"); public static final BlockSuctionPipe suction_pipe = get("suction_pipe"); public static final BlockCyber cyber = get("cyber"); - public static final BlockMycelium snowy_mycelium = get("snowy_mycelium"); - public static final BlockPodzol snowy_podzol = get("snowy_podzol"); - public static final BlockSwamp snowy_swamp = get("snowy_swamp"); - public static final BlockTianSoil snowy_tian_soil = get("snowy_tian_soil"); - public static final BlockNonBlock blackened_cobble = get("blackened_cobble"); - public static final BlockNonBlock cell_rock = get("cell_rock"); - public static final BlockNonBlock cobblestone = get("cobblestone"); - public static final BlockNonBlock moon_rock = get("moon_rock"); - public static final BlockNonBlock mossy_cobblestone = get("mossy_cobblestone"); - public static final BlockNonBlock rock = get("rock"); - public static final BlockNonBlock smooth_rock = get("smooth_rock"); - public static final BlockStairs blackened_soil_stairs = get("blackened_soil_stairs"); public static final BlockSlab cyber_slab = get("cyber_slab"); public static final BlockStairs cyber_stairs = get("cyber_stairs"); - public static final BlockStairs grass_stairs = get("grass_stairs"); - public static final BlockStairs mycelium_stairs = get("mycelium_stairs"); - public static final BlockStairs podzol_stairs = get("podzol_stairs"); - public static final BlockStairs swamp_stairs = get("swamp_stairs"); - public static final BlockStairs tian_soil_stairs = get("tian_soil_stairs"); private static T get(String id) { T block = (T)BlockRegistry.byNameExact(id); diff --git a/common/src/main/java/common/init/Items.java b/common/src/main/java/common/init/Items.java index d12fa4a9..526f217a 100755 --- a/common/src/main/java/common/init/Items.java +++ b/common/src/main/java/common/init/Items.java @@ -211,6 +211,7 @@ public abstract class Items { public static final ItemCamera camera = get("camera"); public static final ItemSeedFood carrot = get("carrot"); public static final ItemWhip whip = get("whip"); + public static final Item carved_sandstone = get("carved_sandstone"); public static final Item carved_stonebrick = get("carved_stonebrick"); public static final Item cauldron = get("cauldron"); public static final Item cell_rock = get("cell_rock"); @@ -368,7 +369,6 @@ public abstract class Items { public static final ItemAppleGold charged_apple = get("charged_apple"); public static final ItemBucket goo_bucket = get("goo_bucket"); public static final Item grass = get("grass"); - public static final Item snowy_grass = get("snowy_grass"); public static final Item gravel = get("gravel"); public static final Item gray_carpet = get("gray_carpet"); public static final Item gray_clay = get("gray_clay"); @@ -1703,19 +1703,8 @@ public abstract class Items { public static final ItemTool zinc_shovel = get("zinc_shovel"); public static final ItemTool zinc_sword = get("zinc_sword"); public static final Item cyber = get("cyber"); - public static final Item snowy_blackened_soil = get("snowy_blackened_soil"); - public static final Item snowy_mycelium = get("snowy_mycelium"); - public static final Item snowy_podzol = get("snowy_podzol"); - public static final Item snowy_swamp = get("snowy_swamp"); - public static final Item snowy_tian_soil = get("snowy_tian_soil"); - public static final Item blackened_soil_stairs = get("blackened_soil_stairs"); public static final Item cyber_slab = get("cyber_slab"); public static final Item cyber_stairs = get("cyber_stairs"); - public static final Item grass_stairs = get("grass_stairs"); - public static final Item mycelium_stairs = get("mycelium_stairs"); - public static final Item podzol_stairs = get("podzol_stairs"); - public static final Item swamp_stairs = get("swamp_stairs"); - public static final Item tian_soil_stairs = get("tian_soil_stairs"); private static T get(String id) { T item = (T)ItemRegistry.byName(id);