Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 494367d

Browse files
Feature/extensions blockentity (#162)
* Add extensions-blockentity module * implements IForgeTileEntity.onLoad and onChunkUnloaded * Impl IForgeTileEntity.getTileData() * Implements IForgeTileEntity.getRenderBoundingBox and canRenderBreaking * Add FastTESR support and Forge's BER registration method * Add BlockEntityRender register method to the god class, Add readme * Fix potential ThreadLocal memory leakage * Update patchwork-extensions-blockentity/src/main/java/net/minecraftforge/common/extensions/IForgeTileEntity.java Co-authored-by: Glitch <glitchieproductionsofficial@gmail.com> * Apply suggestions * Revert "Apply suggestions" This reverts commit 5188613. * Apply suggestions Co-authored-by: Glitch <glitchieproductionsofficial@gmail.com>
1 parent a86a132 commit 494367d

18 files changed

Lines changed: 986 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
archivesBaseName = "patchwork-extensions-blockentity"
2+
version = getSubprojectVersion(project, "0.1.0")
3+
4+
dependencies {
5+
compile project(path: ':patchwork-capabilities', configuration: 'dev')
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
This module implements:
2+
1. Everything in `IForgeTileEntity`
3+
2. Hooks for BlockEntityRenderer registration. (We cannot reuse Fabric hooks for this, the Fabric registration event is fired much earlier than Forge's)
4+
3. FastTESR in 1.14.4, will be removed and replaced with vanilla BlockEntityRenderer in 1.15 and above.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.client.model.animation;
21+
22+
import com.mojang.blaze3d.platform.GlStateManager;
23+
import org.lwjgl.opengl.GL11;
24+
25+
import net.minecraft.client.MinecraftClient;
26+
import net.minecraft.client.render.BufferBuilder;
27+
import net.minecraft.client.render.DiffuseLighting;
28+
import net.minecraft.client.render.Tessellator;
29+
import net.minecraft.client.texture.SpriteAtlasTexture;
30+
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
31+
import net.minecraft.client.render.VertexFormats;
32+
import net.minecraft.block.entity.BlockEntity;
33+
34+
import net.patchworkmc.impl.extensions.blockentity.ForgeBlockEntityRenderer;
35+
36+
/**
37+
* TODO: The FastTESR is removed in 1.15.
38+
* The new vanilla BlockEntityRender is identical to Forge's FastTESR, see the "Disadvantages" section.
39+
* Patchwork API will not implement proper batch rendering for FastTESR,
40+
* however, FastTESRs can still be displayed.
41+
*
42+
* <p>A special case which can be batched with other
43+
* renderers that are also instances of this class.
44+
*
45+
* <p>Advantages:
46+
* <ul>
47+
* <li>All batched renderers are drawn with a single draw call</li>
48+
* <li>Renderers have their vertices depth sorted for better translucency
49+
* support</li>
50+
* </ul>
51+
*
52+
* <p>Disadvantages:
53+
* <ul>
54+
* <li>OpenGL operations are not permitted</li>
55+
* <li>All renderers must use the same {@link VertexFormat}
56+
* ({@link VertexFormats#POSITION_COLOR_TEXTURE_LIGHT_NORMAL})</li>
57+
* </ul>
58+
*
59+
* @param <T> The type of {@link BlockEntity} being rendered.
60+
*/
61+
@Deprecated
62+
public abstract class TileEntityRendererFast<T extends BlockEntity> extends BlockEntityRenderer<T> implements ForgeBlockEntityRenderer<T> {
63+
@Override
64+
public final void render(T te, double x, double y, double z, float partialTicks, int destroyStage) {
65+
Tessellator tessellator = Tessellator.getInstance();
66+
BufferBuilder buffer = tessellator.getBuffer();
67+
this.bindTexture(SpriteAtlasTexture.BLOCK_ATLAS_TEX);
68+
DiffuseLighting.disable();
69+
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
70+
GlStateManager.enableBlend();
71+
GlStateManager.disableCull();
72+
73+
if (MinecraftClient.isAmbientOcclusionEnabled()) {
74+
GlStateManager.shadeModel(GL11.GL_SMOOTH);
75+
} else {
76+
GlStateManager.shadeModel(GL11.GL_FLAT);
77+
}
78+
79+
buffer.begin(GL11.GL_QUADS, VertexFormats.POSITION_COLOR_UV_LMAP);
80+
81+
renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
82+
buffer.setOffset(0, 0, 0);
83+
84+
tessellator.draw();
85+
86+
DiffuseLighting.enable();
87+
}
88+
89+
/**
90+
* Draw this renderer to the passed {@link BufferBuilder}. <strong>DO
91+
* NOT</strong> draw to any buffers other than the one passed, or use any OpenGL
92+
* operations as they will not be applied when this renderer is batched.
93+
*/
94+
@Override
95+
public abstract void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer);
96+
}
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.minecraftforge.common.extensions;
21+
22+
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
23+
24+
import net.minecraft.block.AbstractSignBlock;
25+
import net.minecraft.block.Block;
26+
import net.minecraft.block.BlockState;
27+
import net.minecraft.block.Blocks;
28+
import net.minecraft.block.ChestBlock;
29+
import net.minecraft.block.EnderChestBlock;
30+
import net.minecraft.block.SkullBlock;
31+
import net.minecraft.nbt.CompoundTag;
32+
import net.minecraft.network.ClientConnection;
33+
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
34+
import net.minecraft.block.entity.BlockEntity;
35+
import net.minecraft.util.math.Box;
36+
import net.minecraft.util.math.BlockPos;
37+
import net.minecraft.world.World;
38+
39+
import net.fabricmc.api.EnvType;
40+
import net.fabricmc.api.Environment;
41+
42+
public interface IForgeTileEntity extends ICapabilitySerializable<CompoundTag> {
43+
/**
44+
* Sometimes default render bounding box: infinite in scope. Used to control rendering on {@link TileEntitySpecialRenderer}.
45+
*/
46+
Box INFINITE_EXTENT_AABB = new Box(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
47+
48+
default BlockEntity getTileEntity() {
49+
return (BlockEntity) this;
50+
}
51+
52+
@Override
53+
default void deserializeNBT(CompoundTag nbt) {
54+
getTileEntity().fromTag(nbt);
55+
}
56+
57+
@Override
58+
default CompoundTag serializeNBT() {
59+
CompoundTag ret = new CompoundTag();
60+
getTileEntity().toTag(ret);
61+
return ret;
62+
}
63+
64+
/**
65+
* Called when you receive a TileEntityData packet for the location this
66+
* TileEntity is currently in. On the client, the NetworkManager will always
67+
* be the remote server. On the server, it will be whomever is responsible for
68+
* sending the packet.
69+
*
70+
* @param net The NetworkManager the packet originated from
71+
* @param pkt The data packet
72+
*/
73+
default void onDataPacket(ClientConnection net, BlockEntityUpdateS2CPacket pkt) {
74+
}
75+
76+
/**
77+
* Called when the chunk's TE update tag, gotten from {@link #getUpdateTag()}, is received on the client.
78+
*
79+
* <p>Used to handle this tag in a special way. By default this simply calls {@link #readFromNBT(NBTTagCompound)}.
80+
*
81+
* @param tag The {@link NBTTagCompound} sent from {@link #getUpdateTag()}
82+
*/
83+
default void handleUpdateTag(CompoundTag tag) {
84+
getTileEntity().fromTag(tag);
85+
}
86+
87+
/**
88+
* Gets a {@link NBTTagCompound} that can be used to store custom data for this tile entity.
89+
* It will be written, and read from disc, so it persists over world saves.
90+
*
91+
* @return A compound tag for custom data
92+
*/
93+
CompoundTag getTileData();
94+
95+
default void onChunkUnloaded() {
96+
}
97+
98+
/**
99+
* Called when this is first added to the world (by {@link World#addTileEntity(TileEntity)}).
100+
* Override instead of adding {@code if (firstTick)} stuff in update.
101+
*/
102+
default void onLoad() {
103+
requestModelDataUpdate();
104+
}
105+
106+
/**
107+
* Return an {@link AxisAlignedBB} that controls the visible scope of a {@link TileEntitySpecialRenderer} associated with this {@link TileEntity}
108+
* Defaults to the collision bounding box {@link Block#getCollisionBoundingBoxFromPool(World, int, int, int)} associated with the block
109+
* at this location.
110+
*
111+
* @return an appropriately size {@link AxisAlignedBB} for the {@link TileEntity}
112+
*/
113+
@Environment(EnvType.CLIENT)
114+
default Box getRenderBoundingBox() {
115+
Box bb = INFINITE_EXTENT_AABB;
116+
BlockState state = getTileEntity().getCachedState();
117+
Block block = state.getBlock();
118+
BlockPos pos = getTileEntity().getPos();
119+
120+
if (block == Blocks.ENCHANTING_TABLE) {
121+
bb = new Box(pos, pos.add(1, 1, 1));
122+
} else if (block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST) {
123+
bb = new Box(pos.add(-1, 0, -1), pos.add(2, 2, 2));
124+
} else if (block == Blocks.STRUCTURE_BLOCK) {
125+
bb = INFINITE_EXTENT_AABB;
126+
} else if (block != null && block != Blocks.BEACON) {
127+
Box cbb = null;
128+
129+
try {
130+
cbb = state.getCollisionShape(getTileEntity().getWorld(), pos).getBoundingBox().offset(pos);
131+
} catch (Exception e) {
132+
// We have to capture any exceptions that may occur here because BUKKIT servers like to send
133+
// the tile entity data BEFORE the chunk data, you know, the OPPOSITE of what vanilla does!
134+
// So we can not GUARANTEE that the world state is the real state for the block...
135+
// So, once again in the long line of US having to accommodate BUKKIT breaking things,
136+
// here it is, assume that the TE is only 1 cubic block. Problem with this is that it may
137+
// cause the TileEntity renderer to error further down the line! But alas, nothing we can do.
138+
cbb = new Box(pos.add(-1, 0, -1), pos.add(1, 1, 1));
139+
}
140+
141+
if (cbb != null) {
142+
bb = cbb;
143+
}
144+
}
145+
146+
return bb;
147+
}
148+
149+
/**
150+
* Checks if this tile entity knows how to render its 'breaking' overlay effect.
151+
* If this returns true, The TileEntitySpecialRenderer will be called again with break progress set.
152+
*
153+
* @return True to re-render tile with breaking effect.
154+
*/
155+
default boolean canRenderBreaking() {
156+
Block block = getTileEntity().getCachedState().getBlock();
157+
return (block instanceof ChestBlock
158+
|| block instanceof EnderChestBlock
159+
|| block instanceof AbstractSignBlock
160+
|| block instanceof SkullBlock);
161+
}
162+
163+
/**
164+
* TODO: Deprecated, in Patchwork API 1.14.4, vanilla 1.15 and above,
165+
* this is never called. See {@link net.minecraftforge.client.model.animation.TileEntityRendererFast}.
166+
*
167+
* <p>If the TileEntitySpecialRenderer associated with this TileEntity can be batched in with another renderers, and won't access the GL state.
168+
* If TileEntity returns true, then TESR should have the same functionality as (and probably extend) the FastTESR class.
169+
*/
170+
@Deprecated
171+
default boolean hasFastRenderer() {
172+
return false;
173+
}
174+
175+
/**
176+
* Requests a refresh for the model data of your TE
177+
* Call this every time your {@link #getModelData()} changes.
178+
*/
179+
default void requestModelDataUpdate() {
180+
BlockEntity te = getTileEntity();
181+
World world = te.getWorld();
182+
183+
if (world != null && world.isClient) {
184+
// ModelDataManager.requestModelDataRefresh(te);
185+
}
186+
}
187+
188+
/**
189+
* Allows you to return additional model data.
190+
* This data can be used to provide additional functionality in your {@link net.minecraft.client.renderer.model.IBakedModel}
191+
* You need to schedule a refresh of you model data via {@link #requestModelDataUpdate()} if the result of this function changes.
192+
* <b>Note that this method may be called on a chunk render thread instead of the main client thread</b>
193+
*
194+
* @return Your model data
195+
*/
196+
//@Nonnull
197+
//default IModelData getModelData() {
198+
// return EmptyModelData.INSTANCE;
199+
//}
200+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.impl.extensions.blockentity;
21+
22+
import net.minecraft.block.entity.BlockEntity;
23+
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
24+
25+
public interface ForgeBlockEntityRenderDispatcher {
26+
/**
27+
* Forge Internal, Do not call, Use ClientRegistry.
28+
*/
29+
<T extends BlockEntity> void setSpecialRenderer(Class<T> clsBlockEntity, BlockEntityRenderer<? super T> ber);
30+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Minecraft Forge, Patchwork Project
3+
* Copyright (c) 2016-2020, 2019-2020
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation version 2.1
8+
* of the License.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
package net.patchworkmc.impl.extensions.blockentity;
21+
22+
import net.minecraft.block.entity.BlockEntity;
23+
import net.minecraft.client.render.BufferBuilder;
24+
25+
@Deprecated
26+
public interface ForgeBlockEntityRenderer<T extends BlockEntity> {
27+
default void renderTileEntityFast(T te, double x, double y, double z, float partialTicks, int destroyStage, BufferBuilder buffer) {
28+
}
29+
}

0 commit comments

Comments
 (0)