Skip to content

Commit b881fa8

Browse files
authored
Improve connection handling (#11423)
Add next/prev sign rendering Improve the way the TEE triggers resync More verbose logging to tell the player what is happening Allow sign stacking Allow some "limited" conditional sign rendering when stacked. Improve model to have signs on both sides and full size post on single sign
1 parent d59a1b7 commit b881fa8

File tree

11 files changed

+552
-117
lines changed

11 files changed

+552
-117
lines changed

src/main/java/com/minecolonies/api/util/constant/NbtTagConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public final class NbtTagConstants
6363
public static final String TAG_TARGET_COLONY_NAME = "targetname";
6464
public static final String TAG_DISTANCE = "distance";
6565
public static final String TAG_TARGET_DISTANCE = "targetdistance";
66+
public static final String TAG_CACHED_ABOVE = "cachedabove";
6667

6768
public static final String TAG_CITIZEN = "citizen";
6869
public static final String TAG_HELD_ITEM_SLOT = "HeldItemSlot";

src/main/java/com/minecolonies/api/util/constant/TranslationConstants.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,18 @@ public final class TranslationConstants
708708
public static final String COM_MINECOLONIES_SIGN_DISRUPTED = "com.minecolonies.core.item.sign.disrupted";
709709
@NonNls
710710
public static final String COM_MINECOLONIES_CONNECTION_PATH_FAILURE = "com.minecolonies.core.colonyconnection.path.failure";
711+
@NonNls
712+
public static final String COM_MINECOLONIES_CONNECTION_PATH_PENDING = "com.minecolonies.core.colonyconnection.path.pending";
713+
@NonNls
714+
public static final String COM_MINECOLONIES_CONNECTION_NO_COLONY = "com.minecolonies.core.colonyconnection.fail.nocolony";
715+
@NonNls
716+
public static final String COM_MINECOLONIES_NEED_COLONY = "com.minecolonies.core.item.sign.needcolony";
717+
@NonNls
718+
public static final String COM_MINECOLONIES_CONNECTION_BROKEN = "com.minecolonies.core.colonyconnection.broken";
719+
@NonNls
720+
public static final String PREVIOUS = "com.minecolonies.core.previous";
721+
@NonNls
722+
public static final String NEXT = "com.minecolonies.core.next";
711723
//<editor-fold desc="Partial keys">
712724

713725
@NonNls

src/main/java/com/minecolonies/core/client/render/TileEntityColonySignRenderer.java

Lines changed: 158 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,40 @@
11
package com.minecolonies.core.client.render;
22

33
import com.minecolonies.api.blocks.ModBlocks;
4+
import com.minecolonies.core.client.render.worldevent.ColonyWorldRenderMacros;
5+
import com.minecolonies.core.client.render.worldevent.WorldEventContext;
46
import com.minecolonies.core.tileentities.TileEntityColonySign;
57
import com.mojang.blaze3d.vertex.PoseStack;
68
import com.mojang.math.Axis;
79
import net.minecraft.client.Minecraft;
810
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
911
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
12+
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
1013
import net.minecraft.client.resources.model.BakedModel;
14+
import net.minecraft.core.BlockPos;
1115
import net.minecraft.network.chat.Component;
1216
import net.minecraft.network.chat.FormattedText;
17+
import net.minecraft.network.chat.MutableComponent;
1318
import net.minecraft.util.RandomSource;
1419
import net.minecraft.world.level.block.state.BlockState;
1520
import net.minecraft.client.gui.Font;
1621
import net.minecraft.client.renderer.MultiBufferSource;
1722
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
1823
import net.minecraft.util.FormattedCharSequence;
1924
import net.minecraft.network.chat.Style;
25+
import net.minecraft.world.phys.AABB;
26+
import net.minecraft.world.phys.BlockHitResult;
27+
import net.minecraft.world.phys.HitResult;
2028
import net.minecraftforge.api.distmarker.Dist;
2129
import net.minecraftforge.api.distmarker.OnlyIn;
2230
import net.minecraftforge.client.model.data.ModelData;
2331
import org.jetbrains.annotations.NotNull;
32+
import org.joml.Matrix4f;
2433

2534
import java.util.List;
2635

36+
import static com.minecolonies.api.util.constant.TranslationConstants.NEXT;
37+
import static com.minecolonies.api.util.constant.TranslationConstants.PREVIOUS;
2738
import static com.minecolonies.core.blocks.BlockColonySign.CONNECTED;
2839

2940
@OnlyIn(Dist.CLIENT)
@@ -57,51 +68,66 @@ public void render(
5768
final int combinedLight,
5869
final int combinedOverlay)
5970
{
60-
if (tileEntity != null)
71+
final float relativeRotationToColony = tileEntity.getRelativeRotation();
72+
final BlockState state = tileEntity.getBlockState();
73+
if (state.getBlock() == ModBlocks.blockColonySign)
6174
{
62-
final float relativeRotationToColony = tileEntity.getRelativeRotation();
63-
final BlockState state = tileEntity.getLevel().getBlockState(tileEntity.getBlockPos());
64-
if (state.getBlock() == ModBlocks.blockColonySign)
75+
matrixStack.pushPose();
76+
matrixStack.translate(0.5, 0.5, 0.5);
77+
matrixStack.mulPose(Axis.YP.rotationDegrees(relativeRotationToColony));
78+
matrixStack.translate(-0.5, -0.5, -0.5);
79+
renderSingleBlock(state, matrixStack, buffer, combinedLight, combinedOverlay, tileEntity.getTargetColonyId() != tileEntity.getCachedSignAboveColony());
80+
matrixStack.popPose();
81+
82+
renderTextOnSide(matrixStack, relativeRotationToColony, tileEntity, buffer, combinedLight, true);
83+
renderTextOnSide(matrixStack, relativeRotationToColony, tileEntity, buffer, combinedLight, false);
84+
}
85+
}
86+
87+
/**
88+
* Render the text on the sign and handle rotation etc.
89+
* @param matrixStack the matrix stack.
90+
* @param relativeRotationToColony the relative rotation.
91+
* @param tileEntity the block entity.
92+
* @param buffer the buffer.
93+
* @param combinedLight the light.
94+
* @param mirrored if mirrored or not.
95+
*/
96+
private void renderTextOnSide(final PoseStack matrixStack, final float relativeRotationToColony, final @NotNull TileEntityColonySign tileEntity, final @NotNull MultiBufferSource buffer, final int combinedLight, final boolean mirrored)
97+
{
98+
matrixStack.pushPose();
99+
matrixStack.translate(0.5f, 0.5F, 0.5f);
100+
matrixStack.mulPose(Axis.YP.rotationDegrees(relativeRotationToColony));
101+
if (mirrored)
102+
{
103+
matrixStack.mulPose(Axis.YP.rotationDegrees(180));
104+
}
105+
matrixStack.translate(-0.0f, -0.1F, 0.2f);
106+
107+
matrixStack.scale(0.007F, -0.007F, 0.007F);
108+
109+
final String colonyName = tileEntity.getColonyName();
110+
final int distance = tileEntity.getColonyDistance();
111+
if (colonyName.isEmpty())
112+
{
113+
renderText(matrixStack, buffer, combinedLight, "Unknown Colony", 0, 0);
114+
renderText(matrixStack, buffer, combinedLight, Component.translatable("com.minecolonies.coremod.dist.blocks",distance).getString(), 3, 0);
115+
}
116+
else
117+
{
118+
final String targetColonyName = tileEntity.getTargetColonyName();
119+
if (!targetColonyName.isEmpty() && tileEntity.getTargetColonyId() != tileEntity.getCachedSignAboveColony())
65120
{
66-
matrixStack.pushPose();
67-
matrixStack.translate(0.5, 0.5, 0.5);
68-
matrixStack.mulPose(Axis.YP.rotationDegrees(relativeRotationToColony));
69-
matrixStack.translate(-0.5, -0.5, -0.5);
70-
renderSingleBlock(state, matrixStack, buffer, combinedLight, combinedOverlay, tileEntity.getTargetColonyId() != -1);
71-
matrixStack.popPose();
72-
73-
matrixStack.pushPose();
74-
matrixStack.translate(0.5f, 0.5F, 0.5f);
75-
matrixStack.mulPose(Axis.YP.rotationDegrees(relativeRotationToColony));
76-
matrixStack.mulPose(Axis.YP.rotationDegrees(180));
77-
matrixStack.translate(-0.0f, -0.1F, 0.2f);
78-
79-
matrixStack.scale(0.007F, -0.007F, 0.007F);
80-
81-
final String colonyName = tileEntity.getColonyName();
82-
final int distance = tileEntity.getColonyDistance();
83-
if (colonyName.isEmpty())
84-
{
85-
renderText(matrixStack, buffer, combinedLight, "Unknown Colony", 0, 0);
86-
renderText(matrixStack, buffer, combinedLight, Component.translatable("com.minecolonies.coremod.dist.blocks",distance).getString(), 3, 0);
87-
}
88-
else
89-
{
90-
final String targetColonyName = tileEntity.getTargetColonyName();
91-
if (!targetColonyName.isEmpty())
92-
{
93-
final int targetColonyDistance = tileEntity.getTargetColonyDistance();
94-
renderColonyNameOnSign(colonyName, matrixStack, buffer, combinedLight, distance, -10);
95-
renderColonyNameOnSign(targetColonyName, matrixStack, buffer, combinedLight, targetColonyDistance, -60);
96-
}
97-
else
98-
{
99-
renderColonyNameOnSign(colonyName, matrixStack, buffer, combinedLight, distance, 0);
100-
}
101-
}
102-
matrixStack.popPose();
121+
final int targetColonyDistance = tileEntity.getTargetColonyDistance();
122+
renderColonyNameOnSign(colonyName, matrixStack, buffer, combinedLight, distance, -10);
123+
renderColonyNameOnSign(targetColonyName, matrixStack, buffer, combinedLight, targetColonyDistance, -60);
124+
}
125+
else
126+
{
127+
renderColonyNameOnSign(colonyName, matrixStack, buffer, combinedLight, distance, -35);
103128
}
104129
}
130+
matrixStack.popPose();
105131
}
106132

107133
/**
@@ -193,4 +219,95 @@ public boolean shouldRenderOffScreen(TileEntityColonySign tileEntityMBE21)
193219
{
194220
return false;
195221
}
222+
223+
public static void renderSignHover(final WorldEventContext context)
224+
{
225+
final HitResult rayTraceResult = Minecraft.getInstance().hitResult;
226+
if (!(rayTraceResult instanceof final BlockHitResult blockRayTraceResult) || blockRayTraceResult.getType() == HitResult.Type.MISS)
227+
return;
228+
229+
final BlockPos posAtCamera = blockRayTraceResult.getBlockPos();
230+
if (context.clientLevel.getBlockState(posAtCamera).getBlock() != ModBlocks.blockColonySign)
231+
{
232+
return;
233+
}
234+
235+
if (context.clientLevel.getBlockEntity(posAtCamera) instanceof TileEntityColonySign tileEntityColonySign)
236+
{
237+
if (!BlockPos.ZERO.equals(tileEntityColonySign.getPreviousPos()))
238+
{
239+
renderTextBoxAtPos(context, tileEntityColonySign.getPreviousPos(), List.of(Component.translatable(PREVIOUS).getString()));
240+
}
241+
if (!BlockPos.ZERO.equals(tileEntityColonySign.getNextPosition()))
242+
{
243+
renderTextBoxAtPos(context, tileEntityColonySign.getNextPosition(), List.of(Component.translatable(NEXT).getString()));
244+
}
245+
}
246+
}
247+
248+
private static void renderTextBoxAtPos(final WorldEventContext context, final BlockPos pos, final List<String> text)
249+
{
250+
final MultiBufferSource.BufferSource buffer = Minecraft.getInstance().renderBuffers().bufferSource();
251+
ColonyWorldRenderMacros.renderLineBox(context.poseStack, buffer, new AABB(pos), 0.05f, 0xffffffff, true);
252+
renderDebugText(pos, text, context.poseStack, true, 3, 2.5f, buffer);
253+
ColonyWorldRenderMacros.endRenderLineBox(buffer);
254+
buffer.endBatch();
255+
}
256+
257+
public static void renderDebugText(final BlockPos renderPos,
258+
final List<String> text,
259+
final PoseStack matrixStack,
260+
final boolean forceWhite,
261+
final int mergeEveryXListElements,
262+
final float scale,
263+
final MultiBufferSource buffer)
264+
{
265+
if (mergeEveryXListElements < 1)
266+
{
267+
throw new IllegalArgumentException("mergeEveryXListElements is less than 1");
268+
}
269+
270+
final EntityRenderDispatcher erm = Minecraft.getInstance().getEntityRenderDispatcher();
271+
final int cap = text.size();
272+
if (cap > 0)
273+
{
274+
final Font fontrenderer = Minecraft.getInstance().font;
275+
276+
matrixStack.pushPose();
277+
matrixStack.translate(renderPos.getX() + 0.5d, renderPos.getY() + 0.6d, renderPos.getZ() + 0.5d);
278+
matrixStack.mulPose(erm.cameraOrientation());
279+
matrixStack.scale(-0.014f, -0.014f, 0.014f);
280+
281+
final float backgroundTextOpacity = Minecraft.getInstance().options.getBackgroundOpacity(0.25F);
282+
final int alphaMask = (int) (backgroundTextOpacity * 255.0F) << 24;
283+
284+
final Matrix4f rawPosMatrix = matrixStack.last().pose();
285+
rawPosMatrix.scale(scale, scale, scale);
286+
287+
for (int i = 0; i < cap; i += mergeEveryXListElements)
288+
{
289+
final MutableComponent renderText = Component.literal(
290+
mergeEveryXListElements == 1 ? text.get(i) : text.subList(i, Math.min(i + mergeEveryXListElements, cap)).toString());
291+
final float textCenterShift = (float) (-fontrenderer.width(renderText) / 2);
292+
293+
fontrenderer.drawInBatch(renderText,
294+
textCenterShift,
295+
0,
296+
forceWhite ? 0xffffffff : 0x20ffffff,
297+
false,
298+
rawPosMatrix,
299+
buffer,
300+
Font.DisplayMode.SEE_THROUGH,
301+
alphaMask,
302+
0x00f000f0);
303+
if (!forceWhite)
304+
{
305+
fontrenderer.drawInBatch(renderText, textCenterShift, 0, 0xffffffff, false, rawPosMatrix, buffer, Font.DisplayMode.NORMAL, 0, 0x00f000f0);
306+
}
307+
matrixStack.translate(0.0d, fontrenderer.lineHeight + 1, 0.0d);
308+
}
309+
310+
matrixStack.popPose();
311+
}
312+
}
196313
}

src/main/java/com/minecolonies/core/client/render/worldevent/WorldEventContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.ldtteam.structurize.util.WorldRenderMacros;
44
import com.minecolonies.api.colony.IColonyManager;
55
import com.minecolonies.api.colony.IColonyView;
6+
import com.minecolonies.core.client.render.TileEntityColonySignRenderer;
67
import com.mojang.blaze3d.vertex.PoseStack;
78
import net.minecraft.client.Minecraft;
89
import net.minecraft.client.multiplayer.ClientLevel;
@@ -74,6 +75,7 @@ else if (event.getStage() == RenderLevelStageEvent.Stage.AFTER_TRIPWIRE_BLOCKS)
7475
ColonyBlueprintRenderer.renderBoxes(this);
7576
ItemOverlayBoxesRenderer.render(this);
7677
HighlightManager.render(this);
78+
TileEntityColonySignRenderer.renderSignHover(this);
7779

7880
bufferSource.endBatch();
7981
}

0 commit comments

Comments
 (0)