Gathererenderer

- Data gatherers now briefly light up when sending information
- Stations now render a Schedule item when an Auto-Schedule is present
This commit is contained in:
simibubi 2022-04-08 17:16:27 +02:00
parent a883551473
commit 4638148560
9 changed files with 232 additions and 4 deletions

View file

@ -133,6 +133,7 @@ public class AllBlockPartials {
ENGINE_CONNECTOR = block("steam_engine/shaft_connector"), BOILER_GAUGE = block("steam_engine/gauge"),
SIGNAL_ON = block("track_signal/indicator_on"), SIGNAL_OFF = block("track_signal/indicator_off"),
DATA_GATHERER_TUBE = block("data_gatherer/tube"), DATA_GATHERER_GLOW = block("data_gatherer/glow"),
SIGNAL_PANEL = block("track_signal/panel"), SIGNAL_WHITE_CUBE = block("track_signal/white_cube"),
SIGNAL_WHITE_GLOW = block("track_signal/white_glow"), SIGNAL_WHITE = block("track_signal/white_tube"),
@ -143,7 +144,7 @@ public class AllBlockPartials {
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),
TRAIN_HAT = entity("train_hat"),
COUPLING_ATTACHMENT = entity("minecart_coupling/attachment"), COUPLING_RING = entity("minecart_coupling/ring"),

View file

@ -145,6 +145,7 @@ import com.simibubi.create.content.logistics.block.chute.ChuteRenderer;
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
import com.simibubi.create.content.logistics.block.chute.SmartChuteRenderer;
import com.simibubi.create.content.logistics.block.chute.SmartChuteTileEntity;
import com.simibubi.create.content.logistics.block.data.DataGathererRenderer;
import com.simibubi.create.content.logistics.block.data.DataGathererTileEntity;
import com.simibubi.create.content.logistics.block.data.source.NixieTubeDataSource;
import com.simibubi.create.content.logistics.block.data.target.NixieTubeDataTarget;
@ -673,6 +674,7 @@ public class AllTileEntities {
public static final BlockEntityEntry<DataGathererTileEntity> DATA_GATHERER = Create.registrate()
.tileEntity("data_gatherer", DataGathererTileEntity::new)
.validBlocks(AllBlocks.DATA_GATHERER)
.renderer(() -> DataGathererRenderer::new)
.register();
public static final BlockEntityEntry<StockpileSwitchTileEntity> STOCKPILE_SWITCH = Create.registrate()

View file

@ -0,0 +1,65 @@
package com.simibubi.create.content.logistics.block.data;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
public class DataGathererRenderer extends SafeTileEntityRenderer<DataGathererTileEntity> {
public DataGathererRenderer(BlockEntityRendererProvider.Context context) {}
@Override
protected void renderSafe(DataGathererTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
float glow = te.glow.getValue(partialTicks);
if (glow < .125f)
return;
glow = (float) (1 - (2 * Math.pow(glow - .75f, 2)));
glow = Mth.clamp(glow, -1, 1);
int color = (int) (200 * glow);
BlockState blockState = te.getBlockState();
TransformStack msr = TransformStack.cast(ms);
Direction face = blockState.getOptionalValue(DataGathererBlock.FACING)
.orElse(Direction.UP);
if (face.getAxis()
.isHorizontal())
face = face.getOpposite();
ms.pushPose();
msr.centre()
.rotateY(AngleHelper.horizontalAngle(face))
.rotateX(-AngleHelper.verticalAngle(face) - 90)
.unCentre();
CachedBufferer.partial(AllBlockPartials.DATA_GATHERER_TUBE, blockState)
.light(LightTexture.FULL_BRIGHT)
.renderInto(ms, buffer.getBuffer(RenderType.translucent()));
CachedBufferer.partial(AllBlockPartials.DATA_GATHERER_GLOW, blockState)
.light(LightTexture.FULL_BRIGHT)
.color(color, color, color, 255)
.disableDiffuseMult()
.renderInto(ms, buffer.getBuffer(RenderTypes.getAdditive()));
ms.popPose();
}
}

View file

@ -6,6 +6,9 @@ import com.simibubi.create.content.logistics.block.data.source.DataGathererSourc
import com.simibubi.create.content.logistics.block.data.target.DataGathererTarget;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -25,6 +28,9 @@ public class DataGathererTileEntity extends SmartTileEntity {
public DataGathererTarget activeTarget;
public int targetLine;
public LerpedFloat glow;
private boolean sendPulse;
public int refreshTicks;
public DataGathererTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
@ -32,6 +38,9 @@ public class DataGathererTileEntity extends SmartTileEntity {
targetOffset = BlockPos.ZERO;
sourceConfig = new CompoundTag();
targetLine = 0;
glow = LerpedFloat.linear()
.startWithValue(0);
glow.chase(0, 0.5f, Chaser.EXP);
}
@Override
@ -40,8 +49,11 @@ public class DataGathererTileEntity extends SmartTileEntity {
if (activeSource == null)
return;
if (level.isClientSide)
if (level.isClientSide) {
glow.tickChaser();
return;
}
refreshTicks++;
if (refreshTicks < activeSource.getPassiveRefreshTicks())
return;
@ -94,6 +106,8 @@ public class DataGathererTileEntity extends SmartTileEntity {
DataGathererContext context = new DataGathererContext(level, this);
activeSource.transferData(context, activeTarget, targetLine);
sendPulse = true;
sendData();
}
@Override
@ -109,8 +123,12 @@ public class DataGathererTileEntity extends SmartTileEntity {
protected void write(CompoundTag tag, boolean clientPacket) {
super.write(tag, clientPacket);
writeGatheredData(tag, clientPacket);
if (clientPacket && activeTarget != null)
if (clientPacket && activeTarget != null)
tag.putString("TargetType", activeTarget.id.toString());
if (clientPacket && sendPulse) {
sendPulse = false;
NBTHelper.putMarker(tag, "Pulse");
}
}
private void writeGatheredData(CompoundTag tag, boolean clientPacket) {
@ -132,6 +150,8 @@ public class DataGathererTileEntity extends SmartTileEntity {
if (clientPacket && tag.contains("TargetType"))
activeTarget = AllDataGathererBehaviours.getTarget(new ResourceLocation(tag.getString("TargetType")));
if (clientPacket && tag.contains("Pulse"))
glow.setValue(2);
if (!tag.contains("Source"))
return;

View file

@ -80,7 +80,8 @@ public class StationBlock extends HorizontalDirectionalBlock implements ITE<Stat
if (pLevel.isClientSide)
return InteractionResult.SUCCESS;
pPlayer.getInventory()
.placeItemBackInInventory(autoSchedule);
.placeItemBackInInventory(autoSchedule.copy());
station.autoSchedule.setStackInSlot(0, ItemStack.EMPTY);
AllSoundEvents.playItemPickup(pPlayer);
return InteractionResult.SUCCESS;
});

View file

@ -1,8 +1,10 @@
package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Vector3f;
import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour.RenderedTrackOverlayType;
@ -10,16 +12,23 @@ import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
@ -33,6 +42,10 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
TrackTargetingBehaviour<GlobalStation> target = te.edgePoint;
BlockPos targetPosition = target.getGlobalPosition();
Level level = te.getLevel();
ItemStack autoSchedule = te.getAutoSchedule();
if (!autoSchedule.isEmpty())
renderItem(autoSchedule, te, partialTicks, ms, buffer, light, overlay);
BlockState trackState = level.getBlockState(targetPosition);
Block block = trackState.getBlock();
@ -94,6 +107,31 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
ms.popPose();
}
public static void renderItem(ItemStack itemStack, StationTileEntity te, float partialTicks, PoseStack ms,
MultiBufferSource buffer, int light, int overlay) {
ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer();
TransformStack msr = TransformStack.cast(ms);
ms.pushPose();
msr.centre();
Entity renderViewEntity = Minecraft.getInstance().cameraEntity;
if (renderViewEntity != null) {
Vec3 positionVec = renderViewEntity.position();
Vec3 vectorForOffset = Vec3.atCenterOf(te.getBlockPos());
Vec3 diff = vectorForOffset.subtract(positionVec);
float yRot = (float) (Mth.atan2(diff.x, diff.z) + Math.PI);
ms.mulPose(Vector3f.YP.rotation(yRot));
}
ms.translate(0, 3 / 32d, 2 / 16f);
ms.scale(.75f, .75f, .75f);
itemRenderer.renderStatic(itemStack, TransformType.FIXED, light, overlay, ms, buffer, 0);
ms.popPose();
}
@Override
public boolean shouldRenderOffScreen(StationTileEntity pBlockEntity) {
return true;

View file

@ -45,7 +45,9 @@ import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
@ -599,6 +601,13 @@ public class StationTileEntity extends SmartTileEntity {
return;
imminentTrain.runtime.setSchedule(schedule, true);
AllSoundEvents.CONFIRM.playOnServer(level, worldPosition, 1, 1);
if (!(level instanceof ServerLevel server))
return;
Vec3 v = Vec3.atCenterOf(worldPosition);
server.sendParticles(ParticleTypes.HAPPY_VILLAGER, v.x, v.y, v.z, 8, 0.35, 0.05, 0.35, 1);
server.sendParticles(ParticleTypes.END_ROD, v.x, v.y + .25f, v.z, 10, 0.05, 1, 0.05, 0.005f);
}
private class StationInventory extends ItemStackHandler {

View file

@ -0,0 +1,46 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/data_gatherer"
},
"elements": [
{
"from": [2, 7.5, 7],
"to": [8, 13.5, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
"faces": {
"north": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"east": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"south": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"west": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"up": {"uv": [16, 6, 13.5, 8.5], "texture": "#0"},
"down": {"uv": [16, 11, 13.5, 13.5], "texture": "#0"}
}
},
{
"from": [2.5, 8, 9],
"to": [7.5, 13, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 7.5, 19]},
"faces": {
"south": {"uv": [16, 13.5, 13.5, 16], "texture": "#0"}
}
},
{
"from": [2.5, 8, 10],
"to": [7.5, 13, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
"faces": {
"north": {"uv": [16, 13.5, 13.5, 16], "texture": "#0"}
}
}
],
"groups": [
{
"name": "group",
"origin": [16, 0, 0],
"color": 0,
"children": [0, 1, 2]
}
]
}

View file

@ -0,0 +1,46 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/data_gatherer"
},
"elements": [
{
"from": [2.5, 8, 7.5],
"to": [7.5, 13, 12.5],
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
"faces": {
"north": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"east": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"south": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"west": {"uv": [16, 8.5, 13.5, 11], "texture": "#0"},
"up": {"uv": [16, 6, 13.5, 8.5], "texture": "#0"},
"down": {"uv": [16, 11, 13.5, 13.5], "texture": "#0"}
}
},
{
"from": [2.5, 8, 9],
"to": [7.5, 13, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 7.5, 19]},
"faces": {
"south": {"uv": [16, 13.5, 13.5, 16], "texture": "#0"}
}
},
{
"from": [2.5, 8, 10],
"to": [7.5, 13, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [16, 0, 0]},
"faces": {
"north": {"uv": [16, 13.5, 13.5, 16], "texture": "#0"}
}
}
],
"groups": [
{
"name": "group",
"origin": [16, 0, 0],
"color": 0,
"children": [0, 1, 2]
}
]
}