Broken UVs

- Fixed UV shifts not working consistently with high-res resource packs
- Fixed window panes not connecting their textures with windowlogged blocks
- Fixed buttons and pressure plates not resetting after being moved
- Fixed missing tooltips on custom swords
- Redstone links now move when the block they are attached to is moved
This commit is contained in:
simibubi 2020-04-08 20:31:06 +02:00
parent 810191aa89
commit d1ff9f4e30
11 changed files with 96 additions and 44 deletions

View file

@ -9,6 +9,7 @@ import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour.
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.PaneBlock;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.renderer.vertex.VertexFormat;
@ -55,7 +56,7 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
CTData data = new CTData(); CTData data = new CTData();
for (Direction face : Direction.values()) { for (Direction face : Direction.values()) {
if (!Block.shouldSideBeRendered(state, world, pos, face)) if (!Block.shouldSideBeRendered(state, world, pos, face) && !(state.getBlock() instanceof PaneBlock))
continue; continue;
CTSpriteShiftEntry spriteShift = behaviour.get(state, face); CTSpriteShiftEntry spriteShift = behaviour.get(state, face);
if (spriteShift == null) if (spriteShift == null)
@ -85,9 +86,6 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
if (index == -1) if (index == -1)
continue; continue;
float uShift = spriteShift.getUShift(index);
float vShift = spriteShift.getVShift(index);
BakedQuad newQuad = BakedQuad newQuad =
new BakedQuad(Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), quad.getTintIndex(), new BakedQuad(Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), quad.getTintIndex(),
quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting(), quad.getFormat()); quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting(), quad.getFormat());
@ -100,10 +98,8 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
int vIndex = vertex + uvOffset + 1; int vIndex = vertex + uvOffset + 1;
float u = Float.intBitsToFloat(vertexData[uIndex]); float u = Float.intBitsToFloat(vertexData[uIndex]);
float v = Float.intBitsToFloat(vertexData[vIndex]); float v = Float.intBitsToFloat(vertexData[vIndex]);
u += uShift; vertexData[uIndex] = Float.floatToRawIntBits(spriteShift.getTargetU(u, index));
v += vShift; vertexData[vIndex] = Float.floatToRawIntBits(spriteShift.getTargetV(v, index));
vertexData[uIndex] = Float.floatToIntBits(u);
vertexData[vIndex] = Float.floatToIntBits(v);
} }
quads.set(i, newQuad); quads.set(i, newQuad);
} }

View file

@ -11,14 +11,16 @@ public abstract class CTSpriteShiftEntry extends SpriteShiftEntry {
this.textureSheetSize = sheetSize; this.textureSheetSize = sheetSize;
} }
public float getUShift(int index) { public float getTargetU(float localU, int index) {
return getTarget().getInterpolatedU((index % textureSheetSize) * (16 / textureSheetSize)) float uOffset = (index % textureSheetSize);
- getOriginal().getMinU(); return getTarget().getInterpolatedU(
(getOriginal().getUnInterpolatedU(localU) + (uOffset * 16)) / ((float) textureSheetSize));
} }
public float getVShift(int index) { public float getTargetV(float localV, int index) {
return getTarget().getInterpolatedV((index / textureSheetSize) * (16 / textureSheetSize)) float vOffset = (index / textureSheetSize);
- getOriginal().getMinV(); return getTarget().getInterpolatedV(
(getOriginal().getUnInterpolatedV(localV) + (vOffset * 16)) / ((float) textureSheetSize));
} }
public abstract int getTextureIndex(CTContext context); public abstract int getTextureIndex(CTContext context);

View file

@ -22,7 +22,9 @@ import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.TieredItem;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
public class TooltipHelper { public class TooltipHelper {
@ -169,11 +171,11 @@ public class TooltipHelper {
} }
public static String getTooltipTranslationKey(ItemStack stack) { public static String getTooltipTranslationKey(ItemStack stack) {
Item item = stack.getItem();
if (stack.getItem() instanceof AbstractToolItem) { if (item instanceof TieredItem) {
AbstractToolItem abstractToolItem = (AbstractToolItem) stack.getItem(); TieredItem tieredItem = (TieredItem) stack.getItem();
if (abstractToolItem.getTier() instanceof AllToolTiers) { if (tieredItem.getTier() instanceof AllToolTiers) {
AllToolTiers allToolTiers = (AllToolTiers) abstractToolItem.getTier(); AllToolTiers allToolTiers = (AllToolTiers) tieredItem.getTier();
return "tool.create." + Lang.asId(allToolTiers.name()) + ".tooltip"; return "tool.create." + Lang.asId(allToolTiers.name()) + ".tooltip";
} }
} }

View file

@ -4,9 +4,10 @@ import java.nio.ByteBuffer;
import javax.vecmath.Matrix4f; import javax.vecmath.Matrix4f;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
@ -26,7 +27,9 @@ public class SuperByteBuffer {
// Vertex Texture Coords // Vertex Texture Coords
private boolean shouldShiftUV; private boolean shouldShiftUV;
private float uShift, vShift; private boolean resetUV;
private SpriteShiftEntry spriteShift;
private float uTarget, vTarget;
// Vertex Lighting // Vertex Lighting
private boolean shouldLight; private boolean shouldLight;
@ -37,6 +40,7 @@ public class SuperByteBuffer {
// Vertex Coloring // Vertex Coloring
private boolean shouldColor; private boolean shouldColor;
private int r, g, b, a; private int r, g, b, a;
private float sheetSize;
public SuperByteBuffer(ByteBuffer original) { public SuperByteBuffer(ByteBuffer original) {
original.rewind(); original.rewind();
@ -80,8 +84,18 @@ public class SuperByteBuffer {
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) a); putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) a);
} }
if (shouldShiftUV) if (shouldShiftUV) {
putUV(mutable, vertex, getU(original, vertex) + uShift, getV(original, vertex) + vShift); float u = getU(original, vertex);
float v = getV(original, vertex);
float targetU = spriteShift.getTarget()
.getInterpolatedU((spriteShift.getOriginal().getUnInterpolatedU(u) / sheetSize) + uTarget * 16);
float targetV = spriteShift.getTarget()
.getInterpolatedV((spriteShift.getOriginal().getUnInterpolatedV(v) / sheetSize) + vTarget * 16);
putUV(mutable, vertex, targetU, targetV);
}
if (resetUV)
putUV(mutable, vertex, getU(original, vertex), getV(original, vertex));
if (shouldLight) { if (shouldLight) {
if (vertexLighter != null) if (vertexLighter != null)
@ -134,24 +148,29 @@ public class SuperByteBuffer {
return translate(-.5f, -.5f, -.5f).rotate(axis, angle).translate(.5f, .5f, .5f); return translate(-.5f, -.5f, -.5f).rotate(axis, angle).translate(.5f, .5f, .5f);
} }
public SuperByteBuffer shiftUV(TextureAtlasSprite from, TextureAtlasSprite to) { public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
shouldShiftUV = true; shouldShiftUV = true;
uShift = to.getMinU() - from.getMinU(); resetUV = false;
vShift = to.getMinV() - from.getMinV(); spriteShift = entry;
uTarget = 0;
vTarget = 0;
sheetSize = 1;
return this; return this;
} }
public SuperByteBuffer shiftUVtoSheet(TextureAtlasSprite from, TextureAtlasSprite to, int sheetX, int sheetY) { public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) {
shouldShiftUV = true; shouldShiftUV = true;
uShift = to.getInterpolatedU(sheetX * 16f / to.getWidth()) - from.getMinU(); resetUV = false;
vShift = to.getInterpolatedV(sheetY * 16f / to.getHeight()) - from.getMinV(); spriteShift = entry;
this.uTarget = uTarget;
this.vTarget = vTarget;
this.sheetSize = sheetSize;
return this; return this;
} }
public SuperByteBuffer dontShiftUV() { public SuperByteBuffer dontShiftUV() {
shouldShiftUV = false; shouldShiftUV = false;
uShift = 0; resetUV = true;
vShift = 0;
return this; return this;
} }

View file

@ -5,6 +5,7 @@ import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
import com.simibubi.create.modules.logistics.block.funnel.FunnelBlock; import com.simibubi.create.modules.logistics.block.funnel.FunnelBlock;
import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock; import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock;
@ -94,6 +95,8 @@ public class BlockMovementTraits {
return true; return true;
if (block instanceof RedstoneWireBlock) if (block instanceof RedstoneWireBlock)
return true; return true;
if (block instanceof RedstoneLinkBlock)
return true;
return false; return false;
} }
@ -112,6 +115,8 @@ public class BlockMovementTraits {
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock)) if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock))
return direction == AttachedLogisticalBlock.getBlockFacing(state); return direction == AttachedLogisticalBlock.getBlockFacing(state);
if (block instanceof RedstoneLinkBlock)
return direction.getOpposite() == state.get(RedstoneLinkBlock.FACING);
if (block instanceof FlowerPotBlock) if (block instanceof FlowerPotBlock)
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (block instanceof RedstoneDiodeBlock) if (block instanceof RedstoneDiodeBlock)

View file

@ -31,11 +31,13 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.ChestBlock; import net.minecraft.block.ChestBlock;
import net.minecraft.block.DoorBlock; import net.minecraft.block.DoorBlock;
import net.minecraft.block.PressurePlateBlock;
import net.minecraft.block.SlimeBlock; import net.minecraft.block.SlimeBlock;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
@ -216,6 +218,14 @@ public abstract class Contraption {
blockstate = blockstate.with(FlexcrateBlock.DOUBLE, false); blockstate = blockstate.with(FlexcrateBlock.DOUBLE, false);
if (AllBlocks.CONTACT.typeOf(blockstate)) if (AllBlocks.CONTACT.typeOf(blockstate))
blockstate = blockstate.with(ContactBlock.POWERED, true); blockstate = blockstate.with(ContactBlock.POWERED, true);
if (blockstate.getBlock() instanceof AbstractButtonBlock) {
blockstate = blockstate.with(AbstractButtonBlock.POWERED, false);
world.getPendingBlockTicks().scheduleTick(pos, blockstate.getBlock(), -1);
}
if (blockstate.getBlock() instanceof PressurePlateBlock) {
blockstate = blockstate.with(PressurePlateBlock.POWERED, false);
world.getPendingBlockTicks().scheduleTick(pos, blockstate.getBlock(), -1);
}
CompoundNBT compoundnbt = getTileEntityNBT(world, pos); CompoundNBT compoundnbt = getTileEntityNBT(world, pos);
TileEntity tileentity = world.getTileEntity(pos); TileEntity tileentity = world.getTileEntity(pos);
return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity); return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity);

View file

@ -162,10 +162,9 @@ public class MechanicalCrafterTileEntityRenderer extends SafeTileEntityRenderer<
if (te.phase == Phase.EXPORTING) { if (te.phase == Phase.EXPORTING) {
int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks)); int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks));
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), beltBuffer.shiftUVtoSheet(animatedTexture, (textureIndex % 4) / 4f, 0, 1);
(textureIndex % 4) * 4, 0);
} else { } else {
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), 0, 0); beltBuffer.dontShiftUV();
} }
beltBuffer.translate(x, y, z).renderInto(buffer); beltBuffer.translate(x, y, z).renderInto(buffer);

View file

@ -74,10 +74,9 @@ public class BeltTileEntityRenderer extends SafeTileEntityRenderer<BeltTileEntit
if (textureIndex < 0) if (textureIndex < 0)
textureIndex += 16; textureIndex += 16;
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), beltBuffer.shiftUVtoSheet(animatedTexture, (textureIndex % 4) / 4f, (textureIndex / 4) / 4f, 4);
(textureIndex % 4) * 16, (textureIndex / 4) * 16);
} else { } else {
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), 0, 0); beltBuffer.dontShiftUV();
} }
int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), te.getPos()); int packedLightmapCoords = blockState.getPackedLightmapCoords(getWorld(), te.getPos());

View file

@ -26,6 +26,7 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.IModelData;
public class WindowInABlockModel extends WrappedBakedModel { public class WindowInABlockModel extends WrappedBakedModel {
@ -48,13 +49,20 @@ public class WindowInABlockModel extends WrappedBakedModel {
BlockRenderLayer renderLayer = MinecraftForgeClient.getRenderLayer(); BlockRenderLayer renderLayer = MinecraftForgeClient.getRenderLayer();
if (partialState.canRenderInLayer(renderLayer) && partialState != null) { if (partialState.canRenderInLayer(renderLayer) && partialState != null) {
quads.addAll(dispatcher.getModelForState(partialState).getQuads(partialState, side, rand, data)); IBakedModel partialModel = dispatcher.getModelForState(partialState);
IModelData modelData = partialModel.getModelData(Minecraft.getInstance().world, position, partialState,
EmptyModelData.INSTANCE);
quads.addAll(partialModel.getQuads(partialState, side, rand, modelData));
} }
if (windowState.canRenderInLayer(renderLayer) && windowState != null) { if (windowState.canRenderInLayer(renderLayer) && windowState != null) {
quads.addAll(dispatcher.getModelForState(windowState).getQuads(windowState, side, rand, data).stream() IBakedModel windowModel = dispatcher.getModelForState(windowState);
IModelData modelData =
windowModel.getModelData(Minecraft.getInstance().world, position, windowState, EmptyModelData.INSTANCE);
quads.addAll(dispatcher.getModelForState(windowState).getQuads(windowState, side, rand, modelData).stream()
.filter(q -> { .filter(q -> {
Direction face = q.getFace(); Direction face = q.getFace();
if (face != null && windowState.isSideInvisible(world.getBlockState(position), face)) if (face != null
&& world.getBlockState(position.offset(face)).isSideInvisible(windowState, face))
return false; return false;
if (face != null && Block.hasSolidSide(partialState, world, position, face)) if (face != null && Block.hasSolidSide(partialState, world, position, face))
return false; return false;

View file

@ -193,8 +193,11 @@ public class FlexcrateTileEntity extends SyncedTileEntity implements INamedConta
@Override @Override
public <T> LazyOptional<T> getCapability(Capability<T> capability, Direction facing) { public <T> LazyOptional<T> getCapability(Capability<T> capability, Direction facing) {
if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
return getMainCrate().invHandler.cast(); FlexcrateTileEntity mainCrate = getMainCrate();
if (mainCrate != null && mainCrate.invHandler.isPresent())
return mainCrate.invHandler.cast();
}
return super.getCapability(capability, facing); return super.getCapability(capability, facing);
} }

View file

@ -4,10 +4,12 @@ import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour; import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
import com.simibubi.create.foundation.block.connected.IHaveConnectedTextures; import com.simibubi.create.foundation.block.connected.IHaveConnectedTextures;
import com.simibubi.create.foundation.block.connected.StandardCTBehaviour; import com.simibubi.create.foundation.block.connected.StandardCTBehaviour;
import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
@ -35,14 +37,21 @@ public class CTGlassPaneBlock extends GlassPaneBlock implements IHaveConnectedTe
return super.isSideInvisible(state, adjacentBlockState, side); return super.isSideInvisible(state, adjacentBlockState, side);
} }
protected ConnectedTextureBehaviour createBehaviour() { protected ConnectedTextureBehaviour createBehaviour() {
for (CTSpriteShiftEntry ctSpriteShiftEntry : ctGlass.getBehaviour().getAllCTShifts()) { for (CTSpriteShiftEntry ctSpriteShiftEntry : ctGlass.getBehaviour().getAllCTShifts()) {
return new StandardCTBehaviour(ctSpriteShiftEntry) { return new StandardCTBehaviour(ctSpriteShiftEntry) {
@Override @Override
public boolean connectsTo(BlockState state, BlockState other, IEnviromentBlockReader reader, public boolean connectsTo(BlockState state, BlockState other, IEnviromentBlockReader reader,
BlockPos pos, BlockPos otherPos, Direction face) { BlockPos pos, BlockPos otherPos, Direction face) {
TileEntity te = reader.getTileEntity(pos);
if (te instanceof WindowInABlockTileEntity)
state = ((WindowInABlockTileEntity) te).getWindowBlock();
TileEntity otherTE = reader.getTileEntity(otherPos);
if (otherTE instanceof WindowInABlockTileEntity)
other = ((WindowInABlockTileEntity) otherTE).getWindowBlock();
return state.getBlock() == other.getBlock(); return state.getBlock() == other.getBlock();
} }