mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 14:34:16 +01:00
Wheels are rendered
- Add water wheel rendering - Use NbtUtils to read block states in CopycatBlockEntity and WaterWheelBlockEntity
This commit is contained in:
parent
3756ced16b
commit
9271edf298
@ -85,6 +85,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul
|
||||
import com.simibubi.create.content.contraptions.components.turntable.TurntableBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.components.waterwheel.LargeWaterWheelBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelInstance;
|
||||
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelRenderer;
|
||||
import com.simibubi.create.content.contraptions.fluids.PumpBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.fluids.PumpCogInstance;
|
||||
import com.simibubi.create.content.contraptions.fluids.PumpRenderer;
|
||||
@ -602,16 +604,16 @@ public class AllBlockEntityTypes {
|
||||
|
||||
public static final BlockEntityEntry<WaterWheelBlockEntity> WATER_WHEEL = REGISTRATE
|
||||
.blockEntity("water_wheel", WaterWheelBlockEntity::new)
|
||||
.instance(() -> CutoutRotatingInstance::new, false)
|
||||
.instance(() -> WaterWheelInstance::standard, false)
|
||||
.validBlocks(AllBlocks.WATER_WHEEL)
|
||||
.renderer(() -> KineticBlockEntityRenderer::new)
|
||||
.renderer(() -> WaterWheelRenderer::standard)
|
||||
.register();
|
||||
|
||||
public static final BlockEntityEntry<LargeWaterWheelBlockEntity> LARGE_WATER_WHEEL = REGISTRATE
|
||||
.blockEntity("large_water_wheel", LargeWaterWheelBlockEntity::new)
|
||||
.instance(() -> CutoutRotatingInstance::new, false)
|
||||
.instance(() -> WaterWheelInstance::large, false)
|
||||
.validBlocks(AllBlocks.LARGE_WATER_WHEEL)
|
||||
.renderer(() -> KineticBlockEntityRenderer::new)
|
||||
.renderer(() -> WaterWheelRenderer::large)
|
||||
.register();
|
||||
|
||||
public static final BlockEntityEntry<MechanicalPressBlockEntity> MECHANICAL_PRESS = REGISTRATE
|
||||
|
@ -159,6 +159,11 @@ public class AllPartialModels {
|
||||
WHISTLE_MOUTH_MEDIUM = block("steam_whistle/medium_mouth"),
|
||||
WHISTLE_MOUTH_SMALL = block("steam_whistle/small_mouth"),
|
||||
|
||||
WATER_WHEEL = block("water_wheel/block"),
|
||||
WATER_WHEEL_EXTENSION = block("water_wheel/block_extension"),
|
||||
LARGE_WATER_WHEEL = block("large_water_wheel/block"),
|
||||
LARGE_WATER_WHEEL_EXTENSION = block("large_water_wheel/block_extension"),
|
||||
|
||||
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
|
||||
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
|
||||
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),
|
||||
|
@ -5,6 +5,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.glu
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.TrainHUD;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.render.SBBContraptionManager;
|
||||
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelRenderer;
|
||||
import com.simibubi.create.content.contraptions.goggles.GoggleOverlayRenderer;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
|
||||
import com.simibubi.create.content.curiosities.armor.RemainingAirOverlay;
|
||||
@ -80,6 +81,7 @@ public class CreateClient {
|
||||
BUFFER_CACHE.registerCompartment(CachedBufferer.PARTIAL);
|
||||
BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL);
|
||||
BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK);
|
||||
BUFFER_CACHE.registerCompartment(WaterWheelRenderer.WATER_WHEEL);
|
||||
BUFFER_CACHE.registerCompartment(SBBContraptionManager.CONTRAPTION, 20);
|
||||
BUFFER_CACHE.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20);
|
||||
|
||||
|
@ -10,6 +10,7 @@ public class CutoutRotatingInstance<T extends KineticBlockEntity> extends Single
|
||||
super(materialManager, blockEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Material<RotatingData> getRotatingMaterial() {
|
||||
return materialManager.defaultCutout()
|
||||
.material(AllMaterialSpecs.ROTATING);
|
||||
|
@ -1,13 +1,11 @@
|
||||
package com.simibubi.create.content.contraptions.components.waterwheel;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.simibubi.create.content.contraptions.base.GeneratingKineticBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.base.IRotate;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
@ -22,6 +20,7 @@ import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
@ -34,14 +33,11 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
|
||||
public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
|
||||
|
||||
public static Map<Axis, Set<BlockPos>> SMALL_OFFSETS = new IdentityHashMap<>();
|
||||
public static Map<Axis, Set<BlockPos>> LARGE_OFFSETS = new IdentityHashMap<>();
|
||||
public static final Map<Axis, Set<BlockPos>> SMALL_OFFSETS = new EnumMap<>(Axis.class);
|
||||
public static final Map<Axis, Set<BlockPos>> LARGE_OFFSETS = new EnumMap<>(Axis.class);
|
||||
|
||||
static {
|
||||
for (Axis axis : Iterate.axes) {
|
||||
@ -70,11 +66,11 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
|
||||
}
|
||||
|
||||
public int flowScore;
|
||||
public BlockState baseBlock; // <-- TODO use planks/corresponding logs in rendered instance
|
||||
public BlockState material;
|
||||
|
||||
public WaterWheelBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
baseBlock = Blocks.SPRUCE_PLANKS.defaultBlockState();
|
||||
material = Blocks.SPRUCE_PLANKS.defaultBlockState();
|
||||
}
|
||||
|
||||
protected int getSize() {
|
||||
@ -85,15 +81,15 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
|
||||
return (getSize() == 1 ? SMALL_OFFSETS : LARGE_OFFSETS).get(getAxis());
|
||||
}
|
||||
|
||||
public InteractionResult applyMaterialIfValid(ItemStack item) {
|
||||
if (!(item.getItem() instanceof BlockItem blockItem))
|
||||
public InteractionResult applyMaterialIfValid(ItemStack stack) {
|
||||
if (!(stack.getItem() instanceof BlockItem blockItem))
|
||||
return InteractionResult.PASS;
|
||||
BlockState material = blockItem.getBlock().defaultBlockState();
|
||||
if (material == this.baseBlock)
|
||||
if (material == this.material)
|
||||
return InteractionResult.PASS;
|
||||
if (!material.is(BlockTags.PLANKS))
|
||||
return InteractionResult.PASS;
|
||||
baseBlock = material;
|
||||
this.material = material;
|
||||
notifyUpdate();
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
@ -155,30 +151,6 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
registerAwardables(behaviours, AllAdvancements.LAVA_WHEEL, AllAdvancements.WATER_WHEEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void read(CompoundTag compound, boolean clientPacket) {
|
||||
super.read(compound, clientPacket);
|
||||
flowScore = compound.getInt("FlowScore");
|
||||
|
||||
BlockState prevMaterial = baseBlock;
|
||||
if (!compound.contains("Material"))
|
||||
return;
|
||||
|
||||
JsonOps ops = JsonOps.INSTANCE;
|
||||
BlockState.CODEC.decode(ops, JsonParser.parseString(compound.getString("Material")))
|
||||
.result()
|
||||
.ifPresent(p -> baseBlock = p.getFirst());
|
||||
|
||||
if (clientPacket && prevMaterial != baseBlock)
|
||||
redraw();
|
||||
}
|
||||
|
||||
private void redraw() {
|
||||
if (!isVirtual())
|
||||
requestModelDataUpdate();
|
||||
@ -190,23 +162,32 @@ public class WaterWheelBlockEntity extends GeneratingKineticBlockEntity {
|
||||
}
|
||||
}
|
||||
|
||||
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
registerAwardables(behaviours, AllAdvancements.LAVA_WHEEL, AllAdvancements.WATER_WHEEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelData getModelData() {
|
||||
return new ModelDataMap.Builder().withInitial(MATERIAL_PROPERTY, baseBlock)
|
||||
.build();
|
||||
protected void read(CompoundTag compound, boolean clientPacket) {
|
||||
super.read(compound, clientPacket);
|
||||
flowScore = compound.getInt("FlowScore");
|
||||
|
||||
BlockState prevMaterial = material;
|
||||
if (!compound.contains("Material"))
|
||||
return;
|
||||
|
||||
material = NbtUtils.readBlockState(compound.getCompound("Material"));
|
||||
|
||||
if (clientPacket && prevMaterial != material)
|
||||
redraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
compound.putInt("FlowScore", flowScore);
|
||||
JsonOps ops = JsonOps.INSTANCE;
|
||||
BlockState.CODEC.encode(baseBlock, ops, ops.empty())
|
||||
.result()
|
||||
.map(je -> je.toString())
|
||||
.ifPresent(s -> compound.putString("Material", s));
|
||||
compound.put("Material", NbtUtils.writeBlockState(material));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,13 +1,56 @@
|
||||
package com.simibubi.create.content.contraptions.components.waterwheel;
|
||||
|
||||
import com.jozufozu.flywheel.api.Instancer;
|
||||
import com.jozufozu.flywheel.api.MaterialManager;
|
||||
import com.jozufozu.flywheel.core.model.BlockModel;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.content.contraptions.base.CutoutRotatingInstance;
|
||||
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.base.flwdata.RotatingData;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
|
||||
public class WaterWheelInstance extends CutoutRotatingInstance {
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public WaterWheelInstance(MaterialManager modelManager, KineticBlockEntity tile) {
|
||||
super(modelManager, tile);
|
||||
public class WaterWheelInstance<T extends WaterWheelBlockEntity> extends CutoutRotatingInstance<T> {
|
||||
protected final boolean large;
|
||||
protected final WaterWheelModelKey key;
|
||||
|
||||
public WaterWheelInstance(MaterialManager materialManager, T blockEntity, boolean large) {
|
||||
super(materialManager, blockEntity);
|
||||
this.large = large;
|
||||
key = new WaterWheelModelKey(large, getRenderedBlockState(), blockEntity.material);
|
||||
}
|
||||
|
||||
public static <T extends WaterWheelBlockEntity> WaterWheelInstance<T> standard(MaterialManager materialManager, T blockEntity) {
|
||||
return new WaterWheelInstance<>(materialManager, blockEntity, false);
|
||||
}
|
||||
|
||||
public static <T extends WaterWheelBlockEntity> WaterWheelInstance<T> large(MaterialManager materialManager, T blockEntity) {
|
||||
return new WaterWheelInstance<>(materialManager, blockEntity, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldReset() {
|
||||
return super.shouldReset() || key.material() != blockEntity.material;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Instancer<RotatingData> getModel() {
|
||||
return getRotatingMaterial().model(key, () -> {
|
||||
BakedModel model = WaterWheelRenderer.generateModel(key);
|
||||
BlockState state = key.state();
|
||||
// TODO waterwheels
|
||||
Direction dir;
|
||||
if (key.large()) {
|
||||
dir = Direction.fromAxisAndDirection(state.getValue(LargeWaterWheelBlock.AXIS), AxisDirection.POSITIVE);
|
||||
} else {
|
||||
dir = state.getValue(WaterWheelBlock.FACING);
|
||||
}
|
||||
PoseStack transform = CachedBufferer.rotateToFaceVertical(dir).get();
|
||||
return new BlockModel(model, Blocks.AIR.defaultBlockState(), transform);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
package com.simibubi.create.content.contraptions.components.waterwheel;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public record WaterWheelModelKey(boolean large, BlockState state, BlockState material) {
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
package com.simibubi.create.content.contraptions.components.waterwheel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.jozufozu.flywheel.core.StitchedSprite;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer;
|
||||
import com.simibubi.create.foundation.model.BakedModelHelper;
|
||||
import com.simibubi.create.foundation.render.BakedModelRenderHelper;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBufferCache.Compartment;
|
||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class WaterWheelRenderer<T extends WaterWheelBlockEntity> extends KineticBlockEntityRenderer<T> {
|
||||
public static final Compartment<WaterWheelModelKey> WATER_WHEEL = new Compartment<>();
|
||||
|
||||
public static final StitchedSprite OAK_PLANKS_TEMPLATE = new StitchedSprite(new ResourceLocation("block/oak_planks"));
|
||||
public static final StitchedSprite OAK_LOG_TEMPLATE = new StitchedSprite(new ResourceLocation("block/oak_log"));
|
||||
public static final StitchedSprite OAK_LOG_TOP_TEMPLATE = new StitchedSprite(new ResourceLocation("block/oak_log_top"));
|
||||
|
||||
protected final boolean large;
|
||||
|
||||
public WaterWheelRenderer(Context context, boolean large) {
|
||||
super(context);
|
||||
this.large = large;
|
||||
}
|
||||
|
||||
public static <T extends WaterWheelBlockEntity> WaterWheelRenderer<T> standard(Context context) {
|
||||
return new WaterWheelRenderer<>(context, false);
|
||||
}
|
||||
|
||||
public static <T extends WaterWheelBlockEntity> WaterWheelRenderer<T> large(Context context) {
|
||||
return new WaterWheelRenderer<>(context, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuperByteBuffer getRotatedModel(T be, BlockState state) {
|
||||
WaterWheelModelKey key = new WaterWheelModelKey(large, state, be.material);
|
||||
return CreateClient.BUFFER_CACHE.get(WATER_WHEEL, key, () -> {
|
||||
BakedModel model = WaterWheelRenderer.generateModel(key);
|
||||
BlockState state1 = key.state();
|
||||
// TODO waterwheels
|
||||
Direction dir;
|
||||
if (key.large()) {
|
||||
dir = Direction.fromAxisAndDirection(state1.getValue(LargeWaterWheelBlock.AXIS), AxisDirection.POSITIVE);
|
||||
} else {
|
||||
dir = state1.getValue(WaterWheelBlock.FACING);
|
||||
}
|
||||
PoseStack transform = CachedBufferer.rotateToFaceVertical(dir).get();
|
||||
return BakedModelRenderHelper.standardModelRender(model, Blocks.AIR.defaultBlockState(), transform);
|
||||
});
|
||||
}
|
||||
|
||||
public static PartialModel getTemplateModel(boolean large, boolean extension) {
|
||||
if (large) {
|
||||
if (extension) {
|
||||
return AllPartialModels.LARGE_WATER_WHEEL_EXTENSION;
|
||||
} else {
|
||||
return AllPartialModels.LARGE_WATER_WHEEL;
|
||||
}
|
||||
} else {
|
||||
if (extension) {
|
||||
return AllPartialModels.WATER_WHEEL_EXTENSION;
|
||||
} else {
|
||||
return AllPartialModels.WATER_WHEEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BakedModel generateModel(WaterWheelModelKey key) {
|
||||
// TODO waterwheels
|
||||
// boolean extension = state.getValue(LargeWaterWheelBlock.EXTENSION);
|
||||
boolean extension = key.state().getOptionalValue(LargeWaterWheelBlock.EXTENSION).orElse(false);
|
||||
BakedModel template = getTemplateModel(key.large(), extension).get();
|
||||
|
||||
// TODO waterwheels: improve sprite selection
|
||||
BlockState material = key.material();
|
||||
Block block = material.getBlock();
|
||||
ResourceLocation id = RegisteredObjects.getKeyOrThrow(block);
|
||||
String path = id.getPath();
|
||||
|
||||
if (path.endsWith("_planks")) {
|
||||
String namespace = id.getNamespace();
|
||||
String wood = path.substring(0, path.length() - 7);
|
||||
Function<ResourceLocation, TextureAtlasSprite> spriteFunc = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS);
|
||||
|
||||
Map<TextureAtlasSprite, TextureAtlasSprite> map = new Reference2ReferenceOpenHashMap<>();
|
||||
map.put(OAK_PLANKS_TEMPLATE.get(), spriteFunc.apply(new ResourceLocation(namespace, "block/" + wood + "_planks")));
|
||||
map.put(OAK_LOG_TEMPLATE.get(), spriteFunc.apply(new ResourceLocation(namespace, "block/" + wood + "_log")));
|
||||
map.put(OAK_LOG_TOP_TEMPLATE.get(), spriteFunc.apply(new ResourceLocation(namespace, "block/" + wood + "_log_top")));
|
||||
|
||||
return BakedModelHelper.generateModel(template, map::get);
|
||||
}
|
||||
|
||||
return BakedModelHelper.generateModel(template, sprite -> null);
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.ShaftRenderer;
|
||||
import com.simibubi.create.content.contraptions.relays.gauge.GaugeBlock.Type;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
@ -19,7 +18,7 @@ import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class GaugeRenderer extends ShaftRenderer {
|
||||
public class GaugeRenderer extends ShaftRenderer<GaugeBlockEntity> {
|
||||
|
||||
protected GaugeBlock.Type type;
|
||||
|
||||
@ -37,7 +36,7 @@ public class GaugeRenderer extends ShaftRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderSafe(KineticBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
|
||||
protected void renderSafe(GaugeBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
|
||||
int light, int overlay) {
|
||||
if (Backend.canUseInstancing(be.getLevel())) return;
|
||||
|
||||
|
@ -2,8 +2,6 @@ package com.simibubi.create.content.curiosities.frames;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
@ -18,6 +16,7 @@ import com.simibubi.create.foundation.utility.Iterate;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
@ -136,10 +135,7 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
|
||||
if (!tag.contains("Material"))
|
||||
return;
|
||||
|
||||
JsonOps ops = JsonOps.INSTANCE;
|
||||
BlockState.CODEC.decode(ops, JsonParser.parseString(tag.getString("Material")))
|
||||
.result()
|
||||
.ifPresent(p -> material = p.getFirst());
|
||||
material = NbtUtils.readBlockState(tag.getCompound("Material"));
|
||||
|
||||
if (clientPacket && prevMaterial != material)
|
||||
redraw();
|
||||
@ -148,14 +144,8 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
|
||||
@Override
|
||||
protected void write(CompoundTag tag, boolean clientPacket) {
|
||||
super.write(tag, clientPacket);
|
||||
|
||||
tag.put("Item", consumedItem.serializeNBT());
|
||||
|
||||
JsonOps ops = JsonOps.INSTANCE;
|
||||
BlockState.CODEC.encode(material, ops, ops.empty())
|
||||
.result()
|
||||
.map(je -> je.toString())
|
||||
.ifPresent(s -> tag.putString("Material", s));
|
||||
tag.put("Material", NbtUtils.writeBlockState(material));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,12 +3,25 @@ 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 java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.SimpleBakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class BakedModelHelper {
|
||||
public static void cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
|
||||
@ -79,4 +92,51 @@ public class BakedModelHelper {
|
||||
BakedQuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
|
||||
}
|
||||
}
|
||||
|
||||
public static BakedModel generateModel(BakedModel template, UnaryOperator<TextureAtlasSprite> spriteSwapper) {
|
||||
Random random = new Random();
|
||||
|
||||
Map<Direction, List<BakedQuad>> culledFaces = new EnumMap<>(Direction.class);
|
||||
for (Direction cullFace : Iterate.directions) {
|
||||
random.setSeed(42L);
|
||||
List<BakedQuad> quads = template.getQuads(null, cullFace, random, EmptyModelData.INSTANCE);
|
||||
culledFaces.put(cullFace, swapSprites(quads, spriteSwapper));
|
||||
}
|
||||
|
||||
random.setSeed(42L);
|
||||
List<BakedQuad> quads = template.getQuads(null, null, random, EmptyModelData.INSTANCE);
|
||||
List<BakedQuad> unculledFaces = swapSprites(quads, spriteSwapper);
|
||||
|
||||
TextureAtlasSprite particleSprite = template.getParticleIcon(EmptyModelData.INSTANCE);
|
||||
TextureAtlasSprite swappedParticleSprite = spriteSwapper.apply(particleSprite);
|
||||
if (swappedParticleSprite != null) {
|
||||
particleSprite = swappedParticleSprite;
|
||||
}
|
||||
return new SimpleBakedModel(unculledFaces, culledFaces, template.useAmbientOcclusion(), template.usesBlockLight(), template.isGui3d(), particleSprite, template.getTransforms(), ItemOverrides.EMPTY);
|
||||
}
|
||||
|
||||
public static List<BakedQuad> swapSprites(List<BakedQuad> quads, UnaryOperator<TextureAtlasSprite> spriteSwapper) {
|
||||
List<BakedQuad> newQuads = new ArrayList<>(quads);
|
||||
int size = quads.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
BakedQuad quad = quads.get(i);
|
||||
TextureAtlasSprite sprite = quad.getSprite();
|
||||
TextureAtlasSprite newSprite = spriteSwapper.apply(sprite);
|
||||
if (newSprite == null || sprite == newSprite)
|
||||
continue;
|
||||
|
||||
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||
int[] vertexData = newQuad.getVertices();
|
||||
|
||||
for (int vertex = 0; vertex < 4; vertex++) {
|
||||
float u = BakedQuadHelper.getU(vertexData, vertex);
|
||||
float v = BakedQuadHelper.getV(vertexData, vertex);
|
||||
BakedQuadHelper.setU(vertexData, vertex, newSprite.getU(getUnInterpolatedU(sprite, u)));
|
||||
BakedQuadHelper.setV(vertexData, vertex, newSprite.getV(getUnInterpolatedV(sprite, v)));
|
||||
}
|
||||
|
||||
newQuads.set(i, newQuad);
|
||||
}
|
||||
return newQuads;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user