mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 06:13:42 +01:00
Clean up and optimize copycat models
- Rename ITransformableTE -> ITransformableBlockEntity
This commit is contained in:
parent
783cd126f7
commit
42675f9511
25 changed files with 296 additions and 301 deletions
|
@ -831,8 +831,8 @@ public class AllBlockEntityTypes {
|
||||||
.validBlocks(AllBlocks.TRAIN_DOOR, AllBlocks.FRAMED_GLASS_DOOR)
|
.validBlocks(AllBlocks.TRAIN_DOOR, AllBlocks.FRAMED_GLASS_DOOR)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
public static final BlockEntityEntry<CopycatBlockEntity> UNIVERSAL_FRAME = REGISTRATE
|
public static final BlockEntityEntry<CopycatBlockEntity> COPYCAT = REGISTRATE
|
||||||
.blockEntity("universal_frame", CopycatBlockEntity::new)
|
.blockEntity("copycat", CopycatBlockEntity::new)
|
||||||
.validBlocks(AllBlocks.COPYCAT_PANEL, AllBlocks.COPYCAT_STEP)
|
.validBlocks(AllBlocks.COPYCAT_PANEL, AllBlocks.COPYCAT_STEP)
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
public interface ITransformableTE {
|
public interface ITransformableBlockEntity {
|
||||||
|
|
||||||
void transform(StructureTransform transform);
|
void transform(StructureTransform transform);
|
||||||
|
|
|
@ -111,8 +111,8 @@ public class StructureTransform {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply(BlockEntity be) {
|
public void apply(BlockEntity be) {
|
||||||
if (be instanceof ITransformableTE)
|
if (be instanceof ITransformableBlockEntity)
|
||||||
((ITransformableTE) be).transform(this);
|
((ITransformableBlockEntity) be).transform(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -10,8 +10,8 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
|
||||||
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes.ComponentPartials;
|
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes.ComponentPartials;
|
||||||
import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeBlock;
|
import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeBlock;
|
||||||
import com.simibubi.create.content.contraptions.relays.elementary.BracketedBlockEntityBehaviour;
|
import com.simibubi.create.content.contraptions.relays.elementary.BracketedBlockEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.block.connected.BakedModelWrapperWithData;
|
|
||||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -34,7 +34,7 @@ public class PipeAttachmentModel extends BakedModelWrapperWithData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
||||||
IModelData blockEntityData) {
|
IModelData blockEntityData) {
|
||||||
PipeModelData data = new PipeModelData();
|
PipeModelData data = new PipeModelData();
|
||||||
FluidTransportBehaviour transport = BlockEntityBehaviour.get(world, pos, FluidTransportBehaviour.TYPE);
|
FluidTransportBehaviour transport = BlockEntityBehaviour.get(world, pos, FluidTransportBehaviour.TYPE);
|
||||||
|
@ -47,7 +47,7 @@ public class PipeAttachmentModel extends BakedModelWrapperWithData {
|
||||||
data.putBracket(bracket.getBracket());
|
data.putBracket(bracket.getBracket());
|
||||||
|
|
||||||
data.setEncased(FluidPipeBlock.shouldDrawCasing(world, pos, state));
|
data.setEncased(FluidPipeBlock.shouldDrawCasing(world, pos, state));
|
||||||
return builder.withInitial(PIPE_PROPERTY, data);
|
builder.withInitial(PIPE_PROPERTY, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.fluids.pipes;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.contraptions.fluids.FluidPropagator;
|
import com.simibubi.create.content.contraptions.fluids.FluidPropagator;
|
||||||
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
|
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
|
||||||
|
@ -17,7 +17,7 @@ import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
public class FluidPipeBlockEntity extends SmartBlockEntity implements ITransformableTE {
|
public class FluidPipeBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
|
||||||
|
|
||||||
public FluidPipeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public FluidPipeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
|
|
|
@ -42,12 +42,13 @@ public class FluidTankModel extends CTModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
||||||
IModelData blockEntityData) {
|
IModelData blockEntityData) {
|
||||||
|
super.gatherModelData(builder, world, pos, state, blockEntityData);
|
||||||
CullData cullData = new CullData();
|
CullData cullData = new CullData();
|
||||||
for (Direction d : Iterate.horizontalDirections)
|
for (Direction d : Iterate.horizontalDirections)
|
||||||
cullData.setCulled(d, ConnectivityHandler.isConnected(world, pos, pos.relative(d)));
|
cullData.setCulled(d, ConnectivityHandler.isConnected(world, pos, pos.relative(d)));
|
||||||
return super.gatherModelData(builder, world, pos, state, blockEntityData).withInitial(CULL_PROPERTY, cullData);
|
builder.withInitial(CULL_PROPERTY, cullData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,7 +67,7 @@ public class FluidTankModel extends CTModel {
|
||||||
return quads;
|
return quads;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CullData {
|
private static class CullData {
|
||||||
boolean[] culledFaces;
|
boolean[] culledFaces;
|
||||||
|
|
||||||
public CullData() {
|
public CullData() {
|
||||||
|
|
|
@ -56,7 +56,6 @@ import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||||
import net.minecraftforge.client.model.data.ModelProperty;
|
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
@ -517,11 +516,9 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final ModelProperty<CasingType> CASING_PROPERTY = new ModelProperty<>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IModelData getModelData() {
|
public IModelData getModelData() {
|
||||||
return new ModelDataMap.Builder().withInitial(CASING_PROPERTY, casing)
|
return new ModelDataMap.Builder().withInitial(BeltModel.CASING_PROPERTY, casing)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package com.simibubi.create.content.contraptions.relays.belt;
|
package com.simibubi.create.content.contraptions.relays.belt;
|
||||||
|
|
||||||
import static com.simibubi.create.content.contraptions.relays.belt.BeltBlockEntity.CASING_PROPERTY;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.simibubi.create.AllSpriteShifts;
|
import com.simibubi.create.AllSpriteShifts;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlockEntity.CasingType;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlockEntity.CasingType;
|
||||||
import com.simibubi.create.foundation.block.render.QuadHelper;
|
|
||||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||||
|
import com.simibubi.create.foundation.model.BakedQuadHelper;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
@ -18,9 +16,12 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.client.model.BakedModelWrapper;
|
import net.minecraftforge.client.model.BakedModelWrapper;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
|
import net.minecraftforge.client.model.data.ModelProperty;
|
||||||
|
|
||||||
public class BeltModel extends BakedModelWrapper<BakedModel> {
|
public class BeltModel extends BakedModelWrapper<BakedModel> {
|
||||||
|
|
||||||
|
public static final ModelProperty<CasingType> CASING_PROPERTY = new ModelProperty<>();
|
||||||
|
|
||||||
private static final SpriteShiftEntry SPRITE_SHIFT = AllSpriteShifts.ANDESIDE_BELT_CASING;
|
private static final SpriteShiftEntry SPRITE_SHIFT = AllSpriteShifts.ANDESIDE_BELT_CASING;
|
||||||
|
|
||||||
public BeltModel(BakedModel template) {
|
public BeltModel(BakedModel template) {
|
||||||
|
@ -44,14 +45,14 @@ public class BeltModel extends BakedModelWrapper<BakedModel> {
|
||||||
if (original != SPRITE_SHIFT.getOriginal())
|
if (original != SPRITE_SHIFT.getOriginal())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BakedQuad newQuad = QuadHelper.clone(quad);
|
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||||
int[] vertexData = newQuad.getVertices();
|
int[] vertexData = newQuad.getVertices();
|
||||||
|
|
||||||
for (int vertex = 0; vertex < 4; vertex++) {
|
for (int vertex = 0; vertex < 4; vertex++) {
|
||||||
float u = QuadHelper.getU(vertexData, vertex);
|
float u = BakedQuadHelper.getU(vertexData, vertex);
|
||||||
float v = QuadHelper.getV(vertexData, vertex);
|
float v = BakedQuadHelper.getV(vertexData, vertex);
|
||||||
QuadHelper.setU(vertexData, vertex, SPRITE_SHIFT.getTargetU(u));
|
BakedQuadHelper.setU(vertexData, vertex, SPRITE_SHIFT.getTargetU(u));
|
||||||
QuadHelper.setV(vertexData, vertex, SPRITE_SHIFT.getTargetV(v));
|
BakedQuadHelper.setV(vertexData, vertex, SPRITE_SHIFT.getTargetV(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
quads.set(i, newQuad);
|
quads.set(i, newQuad);
|
||||||
|
|
|
@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.relays.elementary;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implements ITransformableTE {
|
public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implements ITransformableBlockEntity {
|
||||||
|
|
||||||
public BracketedKineticBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public BracketedKineticBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
|
|
|
@ -81,7 +81,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
||||||
context.getLevel()
|
context.getLevel()
|
||||||
.levelEvent(2001, context.getClickedPos(), Block.getId(ufte.getBlockState()));
|
.levelEvent(2001, context.getClickedPos(), Block.getId(ufte.getBlockState()));
|
||||||
ufte.setMaterial(AllBlocks.COPYCAT_BASE.getDefaultState());
|
ufte.setMaterial(AllBlocks.COPYCAT_BASE.getDefaultState());
|
||||||
ufte.setItem(ItemStack.EMPTY);
|
ufte.setConsumedItem(ItemStack.EMPTY);
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
|
|
||||||
ufte.setMaterial(material);
|
ufte.setMaterial(material);
|
||||||
ufte.setItem(itemInHand);
|
ufte.setConsumedItem(itemInHand);
|
||||||
ufte.getLevel()
|
ufte.getLevel()
|
||||||
.playSound(null, ufte.getBlockPos(), material.getSoundType()
|
.playSound(null, ufte.getBlockPos(), material.getSoundType()
|
||||||
.getPlaceSound(), SoundSource.BLOCKS, 1, .75f);
|
.getPlaceSound(), SoundSource.BLOCKS, 1, .75f);
|
||||||
|
@ -146,7 +146,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ufte.setMaterial(appliedState);
|
ufte.setMaterial(appliedState);
|
||||||
ufte.setItem(offhandItem);
|
ufte.setConsumedItem(offhandItem);
|
||||||
|
|
||||||
if (pPlacer instanceof Player player && player.isCreative())
|
if (pPlacer instanceof Player player && player.isCreative())
|
||||||
return;
|
return;
|
||||||
|
@ -215,7 +215,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
||||||
public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) {
|
public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) {
|
||||||
super.playerWillDestroy(pLevel, pPos, pState, pPlayer);
|
super.playerWillDestroy(pLevel, pPos, pState, pPlayer);
|
||||||
if (pPlayer.isCreative())
|
if (pPlayer.isCreative())
|
||||||
withBlockEntityDo(pLevel, pPos, ufte -> ufte.setItem(ItemStack.EMPTY));
|
withBlockEntityDo(pLevel, pPos, ufte -> ufte.setConsumedItem(ItemStack.EMPTY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -225,7 +225,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntityType<? extends CopycatBlockEntity> getBlockEntityType() {
|
public BlockEntityType<? extends CopycatBlockEntity> getBlockEntityType() {
|
||||||
return AllBlockEntityTypes.UNIVERSAL_FRAME.get();
|
return AllBlockEntityTypes.COPYCAT.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connected Textures
|
// Connected Textures
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.List;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.mojang.serialization.JsonOps;
|
import com.mojang.serialization.JsonOps;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.block.redstone.RoseQuartzLampBlock;
|
import com.simibubi.create.content.logistics.block.redstone.RoseQuartzLampBlock;
|
||||||
import com.simibubi.create.content.schematics.ISpecialBlockEntityItemRequirement;
|
import com.simibubi.create.content.schematics.ISpecialBlockEntityItemRequirement;
|
||||||
|
@ -24,55 +24,46 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||||
import net.minecraftforge.client.model.data.ModelProperty;
|
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBlockEntityItemRequirement, ITransformableTE {
|
public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBlockEntityItemRequirement, ITransformableBlockEntity {
|
||||||
|
|
||||||
ItemStack consumedItem;
|
private BlockState material;
|
||||||
BlockState baseBlock;
|
private ItemStack consumedItem;
|
||||||
|
|
||||||
public CopycatBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public CopycatBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
baseBlock = AllBlocks.COPYCAT_BASE.getDefaultState();
|
material = AllBlocks.COPYCAT_BASE.getDefaultState();
|
||||||
consumedItem = ItemStack.EMPTY;
|
consumedItem = ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setItem(ItemStack item) {
|
public BlockState getMaterial() {
|
||||||
consumedItem = ItemHandlerHelper.copyStackWithSize(item, 1);
|
return material;
|
||||||
setChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getConsumedItem() {
|
public boolean hasCustomMaterial() {
|
||||||
return consumedItem;
|
return !AllBlocks.COPYCAT_BASE.has(getMaterial());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ItemRequirement getRequiredItems(BlockState state) {
|
|
||||||
if (consumedItem.isEmpty())
|
|
||||||
return ItemRequirement.NONE;
|
|
||||||
return new ItemRequirement(ItemUseType.CONSUME, consumedItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaterial(BlockState blockState) {
|
public void setMaterial(BlockState blockState) {
|
||||||
BlockState wrapperState = getBlockState();
|
BlockState wrapperState = getBlockState();
|
||||||
|
|
||||||
if (!baseBlock.is(blockState.getBlock()))
|
if (!material.is(blockState.getBlock()))
|
||||||
for (Direction side : Iterate.directions) {
|
for (Direction side : Iterate.directions) {
|
||||||
BlockPos neighbour = worldPosition.relative(side);
|
BlockPos neighbour = worldPosition.relative(side);
|
||||||
BlockState neighbourState = level.getBlockState(neighbour);
|
BlockState neighbourState = level.getBlockState(neighbour);
|
||||||
if (neighbourState != wrapperState)
|
if (neighbourState != wrapperState)
|
||||||
continue;
|
continue;
|
||||||
if (!(level.getBlockEntity(neighbour)instanceof CopycatBlockEntity ufte))
|
if (!(level.getBlockEntity(neighbour) instanceof CopycatBlockEntity cbe))
|
||||||
continue;
|
continue;
|
||||||
BlockState otherMaterial = ufte.getMaterial();
|
BlockState otherMaterial = cbe.getMaterial();
|
||||||
if (!otherMaterial.is(blockState.getBlock()))
|
if (!otherMaterial.is(blockState.getBlock()))
|
||||||
continue;
|
continue;
|
||||||
blockState = otherMaterial;
|
blockState = otherMaterial;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
baseBlock = blockState;
|
material = blockState;
|
||||||
if (!level.isClientSide()) {
|
if (!level.isClientSide()) {
|
||||||
notifyUpdate();
|
notifyUpdate();
|
||||||
return;
|
return;
|
||||||
|
@ -80,50 +71,32 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCustomMaterial() {
|
|
||||||
return !AllBlocks.COPYCAT_BASE.has(getMaterial());
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockState getMaterial() {
|
|
||||||
return baseBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean cycleMaterial() {
|
public boolean cycleMaterial() {
|
||||||
if (baseBlock.hasProperty(BlockStateProperties.FACING))
|
if (material.hasProperty(BlockStateProperties.FACING))
|
||||||
setMaterial(baseBlock.cycle(BlockStateProperties.FACING));
|
setMaterial(material.cycle(BlockStateProperties.FACING));
|
||||||
else if (baseBlock.hasProperty(BlockStateProperties.HORIZONTAL_FACING))
|
else if (material.hasProperty(BlockStateProperties.HORIZONTAL_FACING))
|
||||||
setMaterial(baseBlock.cycle(BlockStateProperties.HORIZONTAL_FACING));
|
setMaterial(material.cycle(BlockStateProperties.HORIZONTAL_FACING));
|
||||||
else if (baseBlock.hasProperty(BlockStateProperties.AXIS))
|
else if (material.hasProperty(BlockStateProperties.AXIS))
|
||||||
setMaterial(baseBlock.cycle(BlockStateProperties.AXIS));
|
setMaterial(material.cycle(BlockStateProperties.AXIS));
|
||||||
else if (baseBlock.hasProperty(BlockStateProperties.HORIZONTAL_AXIS))
|
else if (material.hasProperty(BlockStateProperties.HORIZONTAL_AXIS))
|
||||||
setMaterial(baseBlock.cycle(BlockStateProperties.HORIZONTAL_AXIS));
|
setMaterial(material.cycle(BlockStateProperties.HORIZONTAL_AXIS));
|
||||||
else if (baseBlock.hasProperty(BlockStateProperties.LIT))
|
else if (material.hasProperty(BlockStateProperties.LIT))
|
||||||
setMaterial(baseBlock.cycle(BlockStateProperties.LIT));
|
setMaterial(material.cycle(BlockStateProperties.LIT));
|
||||||
else if (baseBlock.hasProperty(RoseQuartzLampBlock.POWERING))
|
else if (material.hasProperty(RoseQuartzLampBlock.POWERING))
|
||||||
setMaterial(baseBlock.cycle(RoseQuartzLampBlock.POWERING));
|
setMaterial(material.cycle(RoseQuartzLampBlock.POWERING));
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public ItemStack getConsumedItem() {
|
||||||
protected void read(CompoundTag tag, boolean clientPacket) {
|
return consumedItem;
|
||||||
super.read(tag, clientPacket);
|
}
|
||||||
|
|
||||||
consumedItem = ItemStack.of(tag.getCompound("Item"));
|
public void setConsumedItem(ItemStack stack) {
|
||||||
|
consumedItem = ItemHandlerHelper.copyStackWithSize(stack, 1);
|
||||||
BlockState prevMaterial = baseBlock;
|
setChanged();
|
||||||
if (!tag.contains("Material"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
JsonOps ops = JsonOps.INSTANCE;
|
|
||||||
BlockState.CODEC.decode(ops, JsonParser.parseString(tag.getString("Material")))
|
|
||||||
.result()
|
|
||||||
.ifPresent(p -> baseBlock = p.getFirst());
|
|
||||||
|
|
||||||
if (clientPacket && prevMaterial != baseBlock)
|
|
||||||
redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void redraw() {
|
private void redraw() {
|
||||||
|
@ -137,6 +110,41 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemRequirement getRequiredItems(BlockState state) {
|
||||||
|
if (consumedItem.isEmpty())
|
||||||
|
return ItemRequirement.NONE;
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, consumedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transform(StructureTransform transform) {
|
||||||
|
material = transform.apply(material);
|
||||||
|
notifyUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void read(CompoundTag tag, boolean clientPacket) {
|
||||||
|
super.read(tag, clientPacket);
|
||||||
|
|
||||||
|
consumedItem = ItemStack.of(tag.getCompound("Item"));
|
||||||
|
|
||||||
|
BlockState prevMaterial = material;
|
||||||
|
if (!tag.contains("Material"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
JsonOps ops = JsonOps.INSTANCE;
|
||||||
|
BlockState.CODEC.decode(ops, JsonParser.parseString(tag.getString("Material")))
|
||||||
|
.result()
|
||||||
|
.ifPresent(p -> material = p.getFirst());
|
||||||
|
|
||||||
|
if (clientPacket && prevMaterial != material)
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void write(CompoundTag tag, boolean clientPacket) {
|
protected void write(CompoundTag tag, boolean clientPacket) {
|
||||||
super.write(tag, clientPacket);
|
super.write(tag, clientPacket);
|
||||||
|
@ -144,27 +152,16 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
|
||||||
tag.put("Item", consumedItem.serializeNBT());
|
tag.put("Item", consumedItem.serializeNBT());
|
||||||
|
|
||||||
JsonOps ops = JsonOps.INSTANCE;
|
JsonOps ops = JsonOps.INSTANCE;
|
||||||
BlockState.CODEC.encode(baseBlock, ops, ops.empty())
|
BlockState.CODEC.encode(material, ops, ops.empty())
|
||||||
.result()
|
.result()
|
||||||
.map(je -> je.toString())
|
.map(je -> je.toString())
|
||||||
.ifPresent(s -> tag.putString("Material", s));
|
.ifPresent(s -> tag.putString("Material", s));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IModelData getModelData() {
|
public IModelData getModelData() {
|
||||||
return new ModelDataMap.Builder().withInitial(MATERIAL_PROPERTY, baseBlock)
|
return new ModelDataMap.Builder().withInitial(CopycatModel.MATERIAL_PROPERTY, material)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transform(StructureTransform transform) {
|
|
||||||
baseBlock = transform.apply(baseBlock);
|
|
||||||
notifyUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,13 @@
|
||||||
package com.simibubi.create.content.curiosities.frames;
|
package com.simibubi.create.content.curiosities.frames;
|
||||||
|
|
||||||
import static com.simibubi.create.content.curiosities.frames.CopycatBlockEntity.MATERIAL_PROPERTY;
|
|
||||||
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU;
|
|
||||||
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.foundation.block.connected.BakedModelWrapperWithData;
|
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
|
||||||
import com.simibubi.create.foundation.block.render.QuadHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||||
|
@ -28,177 +21,94 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.AABB;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import net.minecraftforge.client.MinecraftForgeClient;
|
import net.minecraftforge.client.MinecraftForgeClient;
|
||||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||||
import net.minecraftforge.client.model.data.IModelData;
|
import net.minecraftforge.client.model.data.IModelData;
|
||||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
|
||||||
import net.minecraftforge.client.model.data.ModelDataMap.Builder;
|
import net.minecraftforge.client.model.data.ModelDataMap.Builder;
|
||||||
import net.minecraftforge.client.model.data.ModelProperty;
|
import net.minecraftforge.client.model.data.ModelProperty;
|
||||||
|
|
||||||
public abstract class CopycatModel extends BakedModelWrapperWithData {
|
public abstract class CopycatModel extends BakedModelWrapperWithData {
|
||||||
|
|
||||||
private static final ModelProperty<IModelData> WRAPPED_DATA_PROPERTY = new ModelProperty<>();
|
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
|
||||||
private static final ModelProperty<OcclusionData> OCCLUSION_PROPERTY = new ModelProperty<>();
|
private static final ModelProperty<OcclusionData> OCCLUSION_PROPERTY = new ModelProperty<>();
|
||||||
|
private static final ModelProperty<IModelData> WRAPPED_DATA_PROPERTY = new ModelProperty<>();
|
||||||
|
|
||||||
public CopycatModel(BakedModel originalModel) {
|
public CopycatModel(BakedModel originalModel) {
|
||||||
super(originalModel);
|
super(originalModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
||||||
IModelData blockEntityData) {
|
IModelData blockEntityData) {
|
||||||
BlockState wrappedState = getMaterial(world, pos, state);
|
BlockState material = getMaterial(blockEntityData);
|
||||||
|
if (material == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (wrappedState == null)
|
builder.withInitial(MATERIAL_PROPERTY, material);
|
||||||
return builder;
|
|
||||||
if (blockEntityData instanceof ModelDataMap mdm && mdm.hasProperty(MATERIAL_PROPERTY))
|
|
||||||
builder.withInitial(MATERIAL_PROPERTY, mdm.getData(MATERIAL_PROPERTY));
|
|
||||||
|
|
||||||
OcclusionData occlusionData = new OcclusionData();
|
OcclusionData occlusionData = new OcclusionData();
|
||||||
if (state.getBlock()instanceof CopycatBlock ufb) {
|
if (state.getBlock() instanceof CopycatBlock copycatBlock) {
|
||||||
MutableBlockPos mutablePos = new MutableBlockPos();
|
MutableBlockPos mutablePos = new MutableBlockPos();
|
||||||
for (Direction face : Iterate.directions)
|
for (Direction face : Iterate.directions)
|
||||||
if (ufb.canFaceBeOccluded(state, face))
|
if (copycatBlock.canFaceBeOccluded(state, face))
|
||||||
if (!Block.shouldRenderFace(wrappedState, world, pos, face, mutablePos.setWithOffset(pos, face)))
|
if (!Block.shouldRenderFace(material, world, pos, face, mutablePos.setWithOffset(pos, face)))
|
||||||
occlusionData.occlude(face);
|
occlusionData.occlude(face);
|
||||||
builder.withInitial(OCCLUSION_PROPERTY, occlusionData);
|
builder.withInitial(OCCLUSION_PROPERTY, occlusionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
IModelData modelData = getModelOf(wrappedState).getModelData(world, pos, wrappedState, EmptyModelData.INSTANCE);
|
IModelData wrappedData = getModelOf(material).getModelData(world, pos, material, EmptyModelData.INSTANCE);
|
||||||
return builder.withInitial(WRAPPED_DATA_PROPERTY, modelData);
|
builder.withInitial(WRAPPED_DATA_PROPERTY, wrappedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData extraData) {
|
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData data) {
|
||||||
List<BakedQuad> quads = super.getQuads(state, side, rand, extraData);
|
BlockState material = getMaterial(data);
|
||||||
|
|
||||||
BlockState material = getMaterial(extraData);
|
|
||||||
IModelData wrappedData = extraData.getData(WRAPPED_DATA_PROPERTY);
|
|
||||||
|
|
||||||
if (material == null)
|
if (material == null)
|
||||||
return quads;
|
return super.getQuads(state, side, rand, data);
|
||||||
|
|
||||||
|
OcclusionData occlusionData = data.getData(OCCLUSION_PROPERTY);
|
||||||
|
if (occlusionData != null && occlusionData.isOccluded(side))
|
||||||
|
return super.getQuads(state, side, rand, data);
|
||||||
|
|
||||||
RenderType renderType = MinecraftForgeClient.getRenderType();
|
RenderType renderType = MinecraftForgeClient.getRenderType();
|
||||||
if (renderType != null && !ItemBlockRenderTypes.canRenderInLayer(material, renderType))
|
if (renderType != null && !ItemBlockRenderTypes.canRenderInLayer(material, renderType))
|
||||||
return quads;
|
return super.getQuads(state, side, rand, data);
|
||||||
|
|
||||||
|
IModelData wrappedData = data.getData(WRAPPED_DATA_PROPERTY);
|
||||||
if (wrappedData == null)
|
if (wrappedData == null)
|
||||||
wrappedData = EmptyModelData.INSTANCE;
|
wrappedData = EmptyModelData.INSTANCE;
|
||||||
|
|
||||||
OcclusionData occlusionData = extraData.getData(OCCLUSION_PROPERTY);
|
|
||||||
if (occlusionData != null && occlusionData.isOccluded(side))
|
|
||||||
return quads;
|
|
||||||
|
|
||||||
return getCroppedQuads(state, side, rand, material, wrappedData);
|
return getCroppedQuads(state, side, rand, material, wrappedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, Random rand,
|
protected abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, Random rand,
|
||||||
BlockState material, IModelData wrappedData);
|
BlockState material, IModelData wrappedData);
|
||||||
|
|
||||||
public static boolean cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
|
|
||||||
int[] vertexData = quad.getVertices();
|
|
||||||
|
|
||||||
Vec3 xyz0 = QuadHelper.getXYZ(vertexData, 0);
|
|
||||||
Vec3 xyz1 = QuadHelper.getXYZ(vertexData, 1);
|
|
||||||
Vec3 xyz2 = QuadHelper.getXYZ(vertexData, 2);
|
|
||||||
Vec3 xyz3 = QuadHelper.getXYZ(vertexData, 3);
|
|
||||||
|
|
||||||
Vec3 uAxis = xyz3.add(xyz2)
|
|
||||||
.scale(.5);
|
|
||||||
Vec3 vAxis = xyz1.add(xyz2)
|
|
||||||
.scale(.5);
|
|
||||||
Vec3 center = xyz3.add(xyz2)
|
|
||||||
.add(xyz0)
|
|
||||||
.add(xyz1)
|
|
||||||
.scale(.25);
|
|
||||||
|
|
||||||
float u0 = QuadHelper.getU(vertexData, 0);
|
|
||||||
float u3 = QuadHelper.getU(vertexData, 3);
|
|
||||||
float v0 = QuadHelper.getV(vertexData, 0);
|
|
||||||
float v1 = QuadHelper.getV(vertexData, 1);
|
|
||||||
|
|
||||||
TextureAtlasSprite sprite = quad.getSprite();
|
|
||||||
|
|
||||||
float uScale = (float) Math
|
|
||||||
.round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0));
|
|
||||||
float vScale = (float) Math
|
|
||||||
.round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0));
|
|
||||||
|
|
||||||
if (uScale == 0) {
|
|
||||||
float v3 = QuadHelper.getV(vertexData, 3);
|
|
||||||
float u1 = QuadHelper.getU(vertexData, 1);
|
|
||||||
uAxis = xyz1.add(xyz2)
|
|
||||||
.scale(.5);
|
|
||||||
vAxis = xyz3.add(xyz2)
|
|
||||||
.scale(.5);
|
|
||||||
uScale = (float) Math
|
|
||||||
.round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0));
|
|
||||||
vScale = (float) Math
|
|
||||||
.round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
uAxis = uAxis.subtract(center)
|
|
||||||
.normalize();
|
|
||||||
vAxis = vAxis.subtract(center)
|
|
||||||
.normalize();
|
|
||||||
|
|
||||||
Vec3 min = new Vec3(crop.minX, crop.minY, crop.minZ);
|
|
||||||
Vec3 max = new Vec3(crop.maxX, crop.maxY, crop.maxZ);
|
|
||||||
|
|
||||||
for (int vertex = 0; vertex < 4; vertex++) {
|
|
||||||
Vec3 xyz = QuadHelper.getXYZ(vertexData, vertex);
|
|
||||||
Vec3 newXyz = VecHelper.componentMin(max, VecHelper.componentMax(xyz, min));
|
|
||||||
Vec3 diff = newXyz.subtract(xyz);
|
|
||||||
|
|
||||||
if (diff.lengthSqr() > 0) {
|
|
||||||
float u = QuadHelper.getU(vertexData, vertex);
|
|
||||||
float v = QuadHelper.getV(vertexData, vertex);
|
|
||||||
float uDiff = (float) uAxis.dot(diff) * uScale;
|
|
||||||
float vDiff = (float) vAxis.dot(diff) * vScale;
|
|
||||||
QuadHelper.setU(vertexData, vertex, sprite.getU(getUnInterpolatedU(sprite, u) + uDiff));
|
|
||||||
QuadHelper.setV(vertexData, vertex, sprite.getV(getUnInterpolatedV(sprite, v) + vDiff));
|
|
||||||
}
|
|
||||||
|
|
||||||
QuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TextureAtlasSprite getParticleIcon(IModelData data) {
|
public TextureAtlasSprite getParticleIcon(IModelData data) {
|
||||||
BlockState material = getMaterial(data);
|
BlockState material = getMaterial(data);
|
||||||
IModelData wrappedData = data.getData(WRAPPED_DATA_PROPERTY);
|
|
||||||
|
|
||||||
|
if (material == null)
|
||||||
|
return super.getParticleIcon(data);
|
||||||
|
|
||||||
|
IModelData wrappedData = data.getData(WRAPPED_DATA_PROPERTY);
|
||||||
if (wrappedData == null)
|
if (wrappedData == null)
|
||||||
wrappedData = EmptyModelData.INSTANCE;
|
wrappedData = EmptyModelData.INSTANCE;
|
||||||
if (material != null)
|
|
||||||
return getModelOf(material).getParticleIcon(wrappedData);
|
|
||||||
|
|
||||||
return super.getParticleIcon(data);
|
return getModelOf(material).getParticleIcon(wrappedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public BlockState getMaterial(IModelData extraData) {
|
public static BlockState getMaterial(IModelData data) {
|
||||||
BlockState material = extraData.getData(MATERIAL_PROPERTY);
|
BlockState material = data.getData(MATERIAL_PROPERTY);
|
||||||
return material == null ? AllBlocks.COPYCAT_BASE.getDefaultState() : material;
|
return material == null ? AllBlocks.COPYCAT_BASE.getDefaultState() : material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
public static BakedModel getModelOf(BlockState state) {
|
||||||
public BlockState getMaterial(BlockAndTintGetter world, BlockPos pos, BlockState state) {
|
|
||||||
if (!(state.getBlock()instanceof CopycatBlock ufb))
|
|
||||||
return null;
|
|
||||||
return ufb.getBlockEntityOptional(world, pos)
|
|
||||||
.map(CopycatBlockEntity::getMaterial)
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BakedModel getModelOf(BlockState wrappedState) {
|
|
||||||
return Minecraft.getInstance()
|
return Minecraft.getInstance()
|
||||||
.getBlockRenderer()
|
.getBlockRenderer()
|
||||||
.getBlockModel(wrappedState);
|
.getBlockModel(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class OcclusionData {
|
private static class OcclusionData {
|
||||||
|
@ -206,7 +116,6 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
|
||||||
|
|
||||||
public OcclusionData() {
|
public OcclusionData() {
|
||||||
occluded = new boolean[6];
|
occluded = new boolean[6];
|
||||||
Arrays.fill(occluded, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void occlude(Direction face) {
|
public void occlude(Direction face) {
|
||||||
|
|
|
@ -4,7 +4,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.block.render.QuadHelper;
|
import com.simibubi.create.foundation.model.BakedModelHelper;
|
||||||
|
import com.simibubi.create.foundation.model.BakedQuadHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
@ -18,6 +19,8 @@ import net.minecraftforge.client.model.data.IModelData;
|
||||||
|
|
||||||
public class CopycatPanelModel extends CopycatModel {
|
public class CopycatPanelModel extends CopycatModel {
|
||||||
|
|
||||||
|
protected static final AABB CUBE_AABB = new AABB(BlockPos.ZERO);
|
||||||
|
|
||||||
public CopycatPanelModel(BakedModel originalModel) {
|
public CopycatPanelModel(BakedModel originalModel) {
|
||||||
super(originalModel);
|
super(originalModel);
|
||||||
}
|
}
|
||||||
|
@ -28,17 +31,22 @@ public class CopycatPanelModel extends CopycatModel {
|
||||||
Direction facing = state.getOptionalValue(CopycatPanelBlock.FACING)
|
Direction facing = state.getOptionalValue(CopycatPanelBlock.FACING)
|
||||||
.orElse(Direction.UP);
|
.orElse(Direction.UP);
|
||||||
|
|
||||||
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
|
|
||||||
AABB cube = new AABB(BlockPos.ZERO);
|
|
||||||
|
|
||||||
BakedModel model = getModelOf(material);
|
BakedModel model = getModelOf(material);
|
||||||
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData);
|
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData);
|
||||||
int size = templateQuads.size();
|
int size = templateQuads.size();
|
||||||
|
|
||||||
List<BakedQuad> quads = new ArrayList<>();
|
List<BakedQuad> quads = new ArrayList<>();
|
||||||
|
|
||||||
|
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
|
||||||
|
Vec3 normalScaled14 = normal.scale(14 / 16f);
|
||||||
|
|
||||||
// 2 Pieces
|
// 2 Pieces
|
||||||
for (boolean front : Iterate.trueAndFalse) {
|
for (boolean front : Iterate.trueAndFalse) {
|
||||||
|
Vec3 normalScaledN13 = normal.scale(front ? 0 : -13 / 16f);
|
||||||
|
float contract = 16 - (front ? 1 : 2);
|
||||||
|
AABB bb = CUBE_AABB.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16);
|
||||||
|
if (!front)
|
||||||
|
bb = bb.move(normalScaled14);
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
BakedQuad quad = templateQuads.get(i);
|
BakedQuad quad = templateQuads.get(i);
|
||||||
|
@ -49,15 +57,9 @@ public class CopycatPanelModel extends CopycatModel {
|
||||||
if (!front && direction == facing.getOpposite())
|
if (!front && direction == facing.getOpposite())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
float contract = 16 - (front ? 1 : 2);
|
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||||
AABB bb = cube.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16);
|
BakedModelHelper.cropAndMove(newQuad, bb, normalScaledN13);
|
||||||
|
quads.add(newQuad);
|
||||||
if (!front)
|
|
||||||
bb = bb.move(normal.scale(14 / 16f));
|
|
||||||
|
|
||||||
BakedQuad newQuad = QuadHelper.clone(quad);
|
|
||||||
if (cropAndMove(newQuad, bb, normal.scale(front ? 0 : -13 / 16f)));
|
|
||||||
quads.add(newQuad);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,8 @@ import net.minecraftforge.common.ForgeMod;
|
||||||
|
|
||||||
public class CopycatStepBlock extends WaterloggedCopycatBlock {
|
public class CopycatStepBlock extends WaterloggedCopycatBlock {
|
||||||
|
|
||||||
public static EnumProperty<Half> HALF = BlockStateProperties.HALF;
|
public static final EnumProperty<Half> HALF = BlockStateProperties.HALF;
|
||||||
public static DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||||
|
|
||||||
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
|
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.block.render.QuadHelper;
|
import com.simibubi.create.foundation.model.BakedModelHelper;
|
||||||
|
import com.simibubi.create.foundation.model.BakedQuadHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
@ -19,6 +20,11 @@ import net.minecraftforge.client.model.data.IModelData;
|
||||||
|
|
||||||
public class CopycatStepModel extends CopycatModel {
|
public class CopycatStepModel extends CopycatModel {
|
||||||
|
|
||||||
|
protected static final Vec3 VEC_Y_3 = new Vec3(0, .75, 0);
|
||||||
|
protected static final Vec3 VEC_Y_2 = new Vec3(0, .5, 0);
|
||||||
|
protected static final Vec3 VEC_Y_N2 = new Vec3(0, -.5, 0);
|
||||||
|
protected static final AABB CUBE_AABB = new AABB(BlockPos.ZERO);
|
||||||
|
|
||||||
public CopycatStepModel(BakedModel originalModel) {
|
public CopycatStepModel(BakedModel originalModel) {
|
||||||
super(originalModel);
|
super(originalModel);
|
||||||
}
|
}
|
||||||
|
@ -31,21 +37,33 @@ public class CopycatStepModel extends CopycatModel {
|
||||||
boolean upperHalf = state.getOptionalValue(CopycatStepBlock.HALF)
|
boolean upperHalf = state.getOptionalValue(CopycatStepBlock.HALF)
|
||||||
.orElse(Half.BOTTOM) == Half.TOP;
|
.orElse(Half.BOTTOM) == Half.TOP;
|
||||||
|
|
||||||
Vec3 zero = Vec3.ZERO;
|
|
||||||
Vec3 up = new Vec3(0, 1, 0);
|
|
||||||
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
|
|
||||||
|
|
||||||
BakedModel model = getModelOf(material);
|
BakedModel model = getModelOf(material);
|
||||||
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData);
|
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData);
|
||||||
int size = templateQuads.size();
|
int size = templateQuads.size();
|
||||||
AABB cube = new AABB(BlockPos.ZERO);
|
|
||||||
|
|
||||||
List<BakedQuad> quads = new ArrayList<>();
|
List<BakedQuad> quads = new ArrayList<>();
|
||||||
|
|
||||||
|
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
|
||||||
|
Vec3 normalScaled2 = normal.scale(.5);
|
||||||
|
Vec3 normalScaledN3 = normal.scale(-.75);
|
||||||
|
AABB bb = CUBE_AABB.contract(-normal.x * .75, .75, -normal.z * .75);
|
||||||
|
|
||||||
// 4 Pieces
|
// 4 Pieces
|
||||||
for (boolean top : Iterate.trueAndFalse) {
|
for (boolean top : Iterate.trueAndFalse) {
|
||||||
for (boolean front : Iterate.trueAndFalse) {
|
for (boolean front : Iterate.trueAndFalse) {
|
||||||
|
|
||||||
|
AABB bb1 = bb;
|
||||||
|
if (front)
|
||||||
|
bb1 = bb1.move(normalScaledN3);
|
||||||
|
if (top)
|
||||||
|
bb1 = bb1.move(VEC_Y_3);
|
||||||
|
|
||||||
|
Vec3 offset = Vec3.ZERO;
|
||||||
|
if (front)
|
||||||
|
offset = offset.add(normalScaled2);
|
||||||
|
if (top != upperHalf)
|
||||||
|
offset = offset.add(upperHalf ? VEC_Y_2 : VEC_Y_N2);
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
BakedQuad quad = templateQuads.get(i);
|
BakedQuad quad = templateQuads.get(i);
|
||||||
Direction direction = quad.getDirection();
|
Direction direction = quad.getDirection();
|
||||||
|
@ -59,23 +77,9 @@ public class CopycatStepModel extends CopycatModel {
|
||||||
if (top && direction == Direction.DOWN)
|
if (top && direction == Direction.DOWN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
AABB bb = cube.contract(-normal.x * .75, .75, -normal.z * .75);
|
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||||
|
BakedModelHelper.cropAndMove(newQuad, bb1, offset);
|
||||||
if (front)
|
quads.add(newQuad);
|
||||||
bb = bb.move(normal.scale(-.75));
|
|
||||||
if (top)
|
|
||||||
bb = bb.move(up.scale(.75));
|
|
||||||
|
|
||||||
Vec3 offset = zero;
|
|
||||||
|
|
||||||
if (front)
|
|
||||||
offset = offset.add(normal.scale(.5));
|
|
||||||
if (top != upperHalf)
|
|
||||||
offset = offset.add(up.scale(upperHalf ? .5 : -.5));
|
|
||||||
|
|
||||||
BakedQuad newQuad = QuadHelper.clone(quad);
|
|
||||||
if (cropAndMove(newQuad, bb, offset))
|
|
||||||
quads.add(newQuad);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,20 +21,20 @@ import net.minecraftforge.client.model.data.ModelProperty;
|
||||||
|
|
||||||
public class ConnectedGirderModel extends CTModel {
|
public class ConnectedGirderModel extends CTModel {
|
||||||
|
|
||||||
protected static ModelProperty<ConnectionData> CONNECTION_PROPERTY = new ModelProperty<>();
|
protected static final ModelProperty<ConnectionData> CONNECTION_PROPERTY = new ModelProperty<>();
|
||||||
|
|
||||||
public ConnectedGirderModel(BakedModel originalModel) {
|
public ConnectedGirderModel(BakedModel originalModel) {
|
||||||
super(originalModel, new GirderCTBehaviour());
|
super(originalModel, new GirderCTBehaviour());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
||||||
IModelData blockEntityData) {
|
IModelData blockEntityData) {
|
||||||
|
super.gatherModelData(builder, world, pos, state, blockEntityData);
|
||||||
ConnectionData connectionData = new ConnectionData();
|
ConnectionData connectionData = new ConnectionData();
|
||||||
for (Direction d : Iterate.horizontalDirections)
|
for (Direction d : Iterate.horizontalDirections)
|
||||||
connectionData.setConnected(d, GirderBlock.isConnected(world, pos, state, d));
|
connectionData.setConnected(d, GirderBlock.isConnected(world, pos, state, d));
|
||||||
return super.gatherModelData(builder, world, pos, state, blockEntityData).withInitial(CONNECTION_PROPERTY,
|
builder.withInitial(CONNECTION_PROPERTY, connectionData);
|
||||||
connectionData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +52,7 @@ public class ConnectedGirderModel extends CTModel {
|
||||||
return quads;
|
return quads;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ConnectionData {
|
private static class ConnectionData {
|
||||||
boolean[] connectedFaces;
|
boolean[] connectedFaces;
|
||||||
|
|
||||||
public ConnectionData() {
|
public ConnectionData() {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteractionPointTypes.JukeboxPoint;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteractionPointTypes.JukeboxPoint;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
||||||
|
@ -45,7 +45,7 @@ import net.minecraft.world.level.chunk.ChunkSource;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class ArmBlockEntity extends KineticBlockEntity implements ITransformableTE {
|
public class ArmBlockEntity extends KineticBlockEntity implements ITransformableBlockEntity {
|
||||||
|
|
||||||
// Server
|
// Server
|
||||||
List<ArmInteractionPoint> inputs;
|
List<ArmInteractionPoint> inputs;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.transform.TransformStack;
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
||||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
||||||
|
@ -23,7 +23,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class TrackObserverBlockEntity extends SmartBlockEntity implements ITransformableTE {
|
public class TrackObserverBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
|
||||||
|
|
||||||
public TrackTargetingBehaviour<TrackObserver> edgePoint;
|
public TrackTargetingBehaviour<TrackObserver> edgePoint;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
|
||||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
|
||||||
|
@ -19,7 +19,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
public class SignalBlockEntity extends SmartBlockEntity implements ITransformableTE {
|
public class SignalBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
|
||||||
|
|
||||||
public static enum OverlayState {
|
public static enum OverlayState {
|
||||||
RENDER, SKIP, DUAL
|
RENDER, SKIP, DUAL
|
||||||
|
|
|
@ -17,7 +17,7 @@ import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
import com.simibubi.create.AllSoundEvents;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.block.depot.DepotBehaviour;
|
import com.simibubi.create.content.logistics.block.depot.DepotBehaviour;
|
||||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
||||||
|
@ -77,7 +77,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
|
|
||||||
public class StationBlockEntity extends SmartBlockEntity implements ITransformableTE {
|
public class StationBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
|
||||||
|
|
||||||
public TrackTargetingBehaviour<GlobalStation> edgePoint;
|
public TrackTargetingBehaviour<GlobalStation> edgePoint;
|
||||||
public LerpedFloat flag;
|
public LerpedFloat flag;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||||
import com.simibubi.create.content.logistics.trains.BezierConnection;
|
import com.simibubi.create.content.logistics.trains.BezierConnection;
|
||||||
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
||||||
|
@ -46,7 +46,7 @@ import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
|
||||||
public class TrackBlockEntity extends SmartBlockEntity implements ITransformableTE, IMergeableBE {
|
public class TrackBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity, IMergeableBE {
|
||||||
|
|
||||||
Map<BlockPos, BezierConnection> connections;
|
Map<BlockPos, BezierConnection> connections;
|
||||||
boolean cancelDrops;
|
boolean cancelDrops;
|
||||||
|
|
|
@ -7,7 +7,8 @@ import java.util.Random;
|
||||||
|
|
||||||
import com.simibubi.create.content.curiosities.frames.CopycatBlock;
|
import com.simibubi.create.content.curiosities.frames.CopycatBlock;
|
||||||
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour.CTContext;
|
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour.CTContext;
|
||||||
import com.simibubi.create.foundation.block.render.QuadHelper;
|
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
|
||||||
|
import com.simibubi.create.foundation.model.BakedQuadHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
@ -34,9 +35,9 @@ public class CTModel extends BakedModelWrapperWithData {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
|
||||||
IModelData blockEntityData) {
|
IModelData blockEntityData) {
|
||||||
return builder.withInitial(CT_PROPERTY, createCTData(world, pos, state));
|
builder.withInitial(CT_PROPERTY, createCTData(world, pos, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CTData createCTData(BlockAndTintGetter world, BlockPos pos, BlockState state) {
|
protected CTData createCTData(BlockAndTintGetter world, BlockPos pos, BlockState state) {
|
||||||
|
@ -80,14 +81,14 @@ public class CTModel extends BakedModelWrapperWithData {
|
||||||
if (quad.getSprite() != spriteShift.getOriginal())
|
if (quad.getSprite() != spriteShift.getOriginal())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
BakedQuad newQuad = QuadHelper.clone(quad);
|
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||||
int[] vertexData = newQuad.getVertices();
|
int[] vertexData = newQuad.getVertices();
|
||||||
|
|
||||||
for (int vertex = 0; vertex < 4; vertex++) {
|
for (int vertex = 0; vertex < 4; vertex++) {
|
||||||
float u = QuadHelper.getU(vertexData, vertex);
|
float u = BakedQuadHelper.getU(vertexData, vertex);
|
||||||
float v = QuadHelper.getV(vertexData, vertex);
|
float v = BakedQuadHelper.getV(vertexData, vertex);
|
||||||
QuadHelper.setU(vertexData, vertex, spriteShift.getTargetU(u, index));
|
BakedQuadHelper.setU(vertexData, vertex, spriteShift.getTargetU(u, index));
|
||||||
QuadHelper.setV(vertexData, vertex, spriteShift.getTargetV(v, index));
|
BakedQuadHelper.setV(vertexData, vertex, spriteShift.getTargetV(v, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
quads.set(i, newQuad);
|
quads.set(i, newQuad);
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.simibubi.create.foundation.model;
|
||||||
|
|
||||||
|
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU;
|
||||||
|
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public class BakedModelHelper {
|
||||||
|
public static void cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
|
||||||
|
int[] vertexData = quad.getVertices();
|
||||||
|
|
||||||
|
Vec3 xyz0 = BakedQuadHelper.getXYZ(vertexData, 0);
|
||||||
|
Vec3 xyz1 = BakedQuadHelper.getXYZ(vertexData, 1);
|
||||||
|
Vec3 xyz2 = BakedQuadHelper.getXYZ(vertexData, 2);
|
||||||
|
Vec3 xyz3 = BakedQuadHelper.getXYZ(vertexData, 3);
|
||||||
|
|
||||||
|
Vec3 uAxis = xyz3.add(xyz2)
|
||||||
|
.scale(.5);
|
||||||
|
Vec3 vAxis = xyz1.add(xyz2)
|
||||||
|
.scale(.5);
|
||||||
|
Vec3 center = xyz3.add(xyz2)
|
||||||
|
.add(xyz0)
|
||||||
|
.add(xyz1)
|
||||||
|
.scale(.25);
|
||||||
|
|
||||||
|
float u0 = BakedQuadHelper.getU(vertexData, 0);
|
||||||
|
float u3 = BakedQuadHelper.getU(vertexData, 3);
|
||||||
|
float v0 = BakedQuadHelper.getV(vertexData, 0);
|
||||||
|
float v1 = BakedQuadHelper.getV(vertexData, 1);
|
||||||
|
|
||||||
|
TextureAtlasSprite sprite = quad.getSprite();
|
||||||
|
|
||||||
|
float uScale = (float) Math
|
||||||
|
.round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0));
|
||||||
|
float vScale = (float) Math
|
||||||
|
.round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0));
|
||||||
|
|
||||||
|
if (uScale == 0) {
|
||||||
|
float v3 = BakedQuadHelper.getV(vertexData, 3);
|
||||||
|
float u1 = BakedQuadHelper.getU(vertexData, 1);
|
||||||
|
uAxis = xyz1.add(xyz2)
|
||||||
|
.scale(.5);
|
||||||
|
vAxis = xyz3.add(xyz2)
|
||||||
|
.scale(.5);
|
||||||
|
uScale = (float) Math
|
||||||
|
.round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0));
|
||||||
|
vScale = (float) Math
|
||||||
|
.round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uAxis = uAxis.subtract(center)
|
||||||
|
.normalize();
|
||||||
|
vAxis = vAxis.subtract(center)
|
||||||
|
.normalize();
|
||||||
|
|
||||||
|
Vec3 min = new Vec3(crop.minX, crop.minY, crop.minZ);
|
||||||
|
Vec3 max = new Vec3(crop.maxX, crop.maxY, crop.maxZ);
|
||||||
|
|
||||||
|
for (int vertex = 0; vertex < 4; vertex++) {
|
||||||
|
Vec3 xyz = BakedQuadHelper.getXYZ(vertexData, vertex);
|
||||||
|
Vec3 newXyz = VecHelper.componentMin(max, VecHelper.componentMax(xyz, min));
|
||||||
|
Vec3 diff = newXyz.subtract(xyz);
|
||||||
|
|
||||||
|
if (diff.lengthSqr() > 0) {
|
||||||
|
float u = BakedQuadHelper.getU(vertexData, vertex);
|
||||||
|
float v = BakedQuadHelper.getV(vertexData, vertex);
|
||||||
|
float uDiff = (float) uAxis.dot(diff) * uScale;
|
||||||
|
float vDiff = (float) vAxis.dot(diff) * vScale;
|
||||||
|
BakedQuadHelper.setU(vertexData, vertex, sprite.getU(getUnInterpolatedU(sprite, u) + uDiff));
|
||||||
|
BakedQuadHelper.setV(vertexData, vertex, sprite.getV(getUnInterpolatedV(sprite, v) + vDiff));
|
||||||
|
}
|
||||||
|
|
||||||
|
BakedQuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.simibubi.create.foundation.block.connected;
|
package com.simibubi.create.foundation.model;
|
||||||
|
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -21,10 +21,11 @@ public abstract class BakedModelWrapperWithData extends BakedModelWrapper<BakedM
|
||||||
Builder builder = new ModelDataMap.Builder();
|
Builder builder = new ModelDataMap.Builder();
|
||||||
if (originalModel instanceof BakedModelWrapperWithData)
|
if (originalModel instanceof BakedModelWrapperWithData)
|
||||||
((BakedModelWrapperWithData) originalModel).gatherModelData(builder, world, pos, state, blockEntityData);
|
((BakedModelWrapperWithData) originalModel).gatherModelData(builder, world, pos, state, blockEntityData);
|
||||||
return gatherModelData(builder, world, pos, state, blockEntityData).build();
|
gatherModelData(builder, world, pos, state, blockEntityData);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ModelDataMap.Builder gatherModelData(ModelDataMap.Builder builder, BlockAndTintGetter world,
|
protected abstract void gatherModelData(ModelDataMap.Builder builder, BlockAndTintGetter world,
|
||||||
BlockPos pos, BlockState state, IModelData blockEntityData);
|
BlockPos pos, BlockState state, IModelData blockEntityData);
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.simibubi.create.foundation.block.render;
|
package com.simibubi.create.foundation.model;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public final class QuadHelper {
|
public final class BakedQuadHelper {
|
||||||
|
|
||||||
public static final VertexFormat FORMAT = DefaultVertexFormat.BLOCK;
|
public static final VertexFormat FORMAT = DefaultVertexFormat.BLOCK;
|
||||||
public static final int VERTEX_STRIDE = FORMAT.getIntegerSize();
|
public static final int VERTEX_STRIDE = FORMAT.getIntegerSize();
|
||||||
|
@ -22,7 +22,7 @@ public final class QuadHelper {
|
||||||
public static final int LIGHT_OFFSET = 6;
|
public static final int LIGHT_OFFSET = 6;
|
||||||
public static final int NORMAL_OFFSET = 7;
|
public static final int NORMAL_OFFSET = 7;
|
||||||
|
|
||||||
private QuadHelper() {}
|
private BakedQuadHelper() {}
|
||||||
|
|
||||||
public static BakedQuad clone(BakedQuad quad) {
|
public static BakedQuad clone(BakedQuad quad) {
|
||||||
return new BakedQuad(Arrays.copyOf(quad.getVertices(), quad.getVertices().length),
|
return new BakedQuad(Arrays.copyOf(quad.getVertices(), quad.getVertices().length),
|
||||||
|
@ -36,6 +36,12 @@ public final class QuadHelper {
|
||||||
return new Vec3(x, y, z);
|
return new Vec3(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setXYZ(int[] vertexData, int vertex, Vec3 xyz) {
|
||||||
|
vertexData[vertex * VERTEX_STRIDE + X_OFFSET] = Float.floatToRawIntBits((float) xyz.x);
|
||||||
|
vertexData[vertex * VERTEX_STRIDE + Y_OFFSET] = Float.floatToRawIntBits((float) xyz.y);
|
||||||
|
vertexData[vertex * VERTEX_STRIDE + Z_OFFSET] = Float.floatToRawIntBits((float) xyz.z);
|
||||||
|
}
|
||||||
|
|
||||||
public static float getU(int[] vertexData, int vertex) {
|
public static float getU(int[] vertexData, int vertex) {
|
||||||
return Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + U_OFFSET]);
|
return Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + U_OFFSET]);
|
||||||
}
|
}
|
||||||
|
@ -44,12 +50,6 @@ public final class QuadHelper {
|
||||||
return Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + V_OFFSET]);
|
return Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + V_OFFSET]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setXYZ(int[] vertexData, int vertex, Vec3 xyz) {
|
|
||||||
vertexData[vertex * VERTEX_STRIDE + X_OFFSET] = Float.floatToRawIntBits((float) xyz.x);
|
|
||||||
vertexData[vertex * VERTEX_STRIDE + Y_OFFSET] = Float.floatToRawIntBits((float) xyz.y);
|
|
||||||
vertexData[vertex * VERTEX_STRIDE + Z_OFFSET] = Float.floatToRawIntBits((float) xyz.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setU(int[] vertexData, int vertex, float u) {
|
public static void setU(int[] vertexData, int vertex, float u) {
|
||||||
vertexData[vertex * VERTEX_STRIDE + U_OFFSET] = Float.floatToRawIntBits(u);
|
vertexData[vertex * VERTEX_STRIDE + U_OFFSET] = Float.floatToRawIntBits(u);
|
||||||
}
|
}
|
Loading…
Reference in a new issue