mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 06:24:12 +01:00
Flywheel ECS
- Add SimpleEntityVisual which is composed of many EntityComponents. - Would be nice to expand on this system, particularly to add components when registering visualizers. - Misc. doc updates.
This commit is contained in:
parent
cdfe144131
commit
82470debb4
@ -5,28 +5,30 @@ import java.util.function.LongConsumer;
|
|||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A non-moving visual that listens to light updates.
|
* A visual that listens to light updates.
|
||||||
* <br>
|
*
|
||||||
* If your visual moves around in the world at all, you should use {@link TickableVisual} or {@link DynamicVisual},
|
* <p>If your visual moves around in the world at all, you should use {@link TickableVisual} or {@link DynamicVisual},
|
||||||
* and poll for light yourself rather than listening for updates.
|
* and poll for light yourself along with listening for updates. When your visual moves to a different section, call
|
||||||
|
* {@link Notifier#notifySectionsChanged}.</p>
|
||||||
*/
|
*/
|
||||||
public interface LitVisual extends Visual {
|
public interface LitVisual extends Visual {
|
||||||
/**
|
/**
|
||||||
* Called when a section this visual is contained in receives a light update.
|
* Called when a section this visual is contained in receives a light update.
|
||||||
* <br>
|
*
|
||||||
* Even if multiple sections are updated at the same time, this method will only be called once.
|
* <p>Even if multiple sections are updated at the same time, this method will only be called once.</p>
|
||||||
* <br>
|
*
|
||||||
* The implementation is free to parallelize calls to this method, as well as call into
|
* <p>The implementation is free to parallelize calls to this method, as well as call into
|
||||||
* {@link DynamicVisual#beginFrame} simultaneously. It is safe to query/update light here,
|
* {@link DynamicVisual#beginFrame} simultaneously. It is safe to query/update light here,
|
||||||
* but you must ensure proper synchronization if you want to mutate anything outside this
|
* but you must ensure proper synchronization if you want to mutate anything outside this
|
||||||
* visual or anything that is also mutated by {@link DynamicVisual#beginFrame}.
|
* visual or anything that is also mutated by {@link DynamicVisual#beginFrame}.</p>
|
||||||
*/
|
*/
|
||||||
void updateLight();
|
void updateLight();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect the sections that this visual is contained in.
|
* Collect the sections that this visual is contained in.
|
||||||
* <br>
|
*
|
||||||
* This method is called upon visual creation, and the frame after {@link Notifier#notifySectionsChanged} is called.
|
* <p>This method is called upon visual creation, and the frame after
|
||||||
|
* {@link Notifier#notifySectionsChanged} is called.</p>
|
||||||
*
|
*
|
||||||
* @param consumer The consumer to provide the sections to.
|
* @param consumer The consumer to provide the sections to.
|
||||||
* @see SectionPos#asLong
|
* @see SectionPos#asLong
|
||||||
@ -35,9 +37,9 @@ public interface LitVisual extends Visual {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the notifier object.
|
* Set the notifier object.
|
||||||
* <br>
|
*
|
||||||
* This method is only called once, upon visual creation,
|
* <p>This method is only called once, upon visual creation,
|
||||||
* after {@link #init} and before {@link #collectLightSections}.
|
* after {@link #init} and before {@link #collectLightSections}.</p>
|
||||||
*
|
*
|
||||||
* @param notifier The notifier.
|
* @param notifier The notifier.
|
||||||
*/
|
*/
|
||||||
|
@ -11,13 +11,17 @@ package com.jozufozu.flywheel.api.visual;
|
|||||||
public interface Visual {
|
public interface Visual {
|
||||||
/**
|
/**
|
||||||
* Initialize instances here.
|
* Initialize instances here.
|
||||||
|
*
|
||||||
|
* <p>This method will be called exactly once upon visual creation.</p>
|
||||||
*/
|
*/
|
||||||
void init(float partialTick);
|
void init(float partialTick);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update instances here. Good for when instances don't change very often and when animations are GPU based.
|
* Update instances here.
|
||||||
* <br>
|
*
|
||||||
* <br> If your animations are complex or more CPU driven, see {@link DynamicVisual} or {@link TickableVisual}.
|
* <p>Good for when instances don't change very often and when animations are GPU based.
|
||||||
|
*
|
||||||
|
* <br>If your animations are complex or more CPU driven, see {@link DynamicVisual} or {@link TickableVisual}.</p>
|
||||||
*/
|
*/
|
||||||
void update(float partialTick);
|
void update(float partialTick);
|
||||||
|
|
||||||
|
@ -33,17 +33,11 @@ import net.minecraft.world.phys.Vec3;
|
|||||||
public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVisual implements EntityVisual<T> {
|
public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVisual implements EntityVisual<T> {
|
||||||
protected final T entity;
|
protected final T entity;
|
||||||
protected final EntityVisibilityTester visibilityTester;
|
protected final EntityVisibilityTester visibilityTester;
|
||||||
protected final ShadowComponent shadow;
|
|
||||||
protected final FireComponent fire;
|
|
||||||
protected final BoundingBoxComponent boundingBox;
|
|
||||||
|
|
||||||
public AbstractEntityVisual(VisualizationContext ctx, T entity) {
|
public AbstractEntityVisual(VisualizationContext ctx, T entity) {
|
||||||
super(ctx, entity.level());
|
super(ctx, entity.level());
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
visibilityTester = new EntityVisibilityTester(entity, ctx.renderOrigin(), 1.5f);
|
visibilityTester = new EntityVisibilityTester(entity, ctx.renderOrigin(), 1.5f);
|
||||||
shadow = new ShadowComponent(ctx, entity);
|
|
||||||
fire = new FireComponent(ctx, entity);
|
|
||||||
boundingBox = new BoundingBoxComponent(ctx, entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -93,11 +87,4 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||||||
public boolean isVisible(FrustumIntersection frustum) {
|
public boolean isVisible(FrustumIntersection frustum) {
|
||||||
return entity.noCulling || visibilityTester.check(frustum);
|
return entity.noCulling || visibilityTester.check(frustum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void _delete() {
|
|
||||||
shadow.delete();
|
|
||||||
fire.delete();
|
|
||||||
boundingBox.delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.jozufozu.flywheel.lib.visual;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.visual.VisualFrameContext;
|
||||||
|
|
||||||
|
public interface EntityComponent {
|
||||||
|
void beginFrame(VisualFrameContext context);
|
||||||
|
|
||||||
|
void delete();
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.jozufozu.flywheel.lib.visual;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.visual.DynamicVisual;
|
||||||
|
import com.jozufozu.flywheel.api.visual.VisualFrameContext;
|
||||||
|
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
public class SimpleEntityVisual<T extends Entity> extends AbstractEntityVisual<T> implements DynamicVisual {
|
||||||
|
protected final List<EntityComponent> components = new ArrayList<>();
|
||||||
|
|
||||||
|
public SimpleEntityVisual(VisualizationContext ctx, T entity) {
|
||||||
|
super(ctx, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComponent(EntityComponent component) {
|
||||||
|
components.add(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginFrame(VisualFrameContext ctx) {
|
||||||
|
for (EntityComponent component : components) {
|
||||||
|
component.beginFrame(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void _delete() {
|
||||||
|
for (EntityComponent component : components) {
|
||||||
|
component.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.jozufozu.flywheel.lib.visual;
|
package com.jozufozu.flywheel.lib.visual.components;
|
||||||
|
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.joml.Vector4fc;
|
import org.joml.Vector4fc;
|
||||||
@ -15,6 +15,8 @@ import com.jozufozu.flywheel.lib.material.StandardMaterialShaders;
|
|||||||
import com.jozufozu.flywheel.lib.math.MoreMath;
|
import com.jozufozu.flywheel.lib.math.MoreMath;
|
||||||
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
||||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.EntityComponent;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.InstanceRecycler;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
@ -22,7 +24,7 @@ import net.minecraft.util.Mth;
|
|||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
|
||||||
public class BoundingBoxComponent {
|
public class BoundingBoxComponent implements EntityComponent {
|
||||||
private static final Material MATERIAL = SimpleMaterial.builder()
|
private static final Material MATERIAL = SimpleMaterial.builder()
|
||||||
.shaders(StandardMaterialShaders.WIREFRAME)
|
.shaders(StandardMaterialShaders.WIREFRAME)
|
||||||
.backfaceCulling(false)
|
.backfaceCulling(false)
|
||||||
@ -53,10 +55,12 @@ public class BoundingBoxComponent {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showEyeBox(boolean renderEyeBox) {
|
public BoundingBoxComponent showEyeBox(boolean renderEyeBox) {
|
||||||
this.showEyeBox = renderEyeBox;
|
this.showEyeBox = renderEyeBox;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void beginFrame(VisualFrameContext context) {
|
public void beginFrame(VisualFrameContext context) {
|
||||||
recycler.resetCount();
|
recycler.resetCount();
|
||||||
|
|
||||||
@ -93,6 +97,7 @@ public class BoundingBoxComponent {
|
|||||||
recycler.discardExtra();
|
recycler.discardExtra();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
recycler.delete();
|
recycler.delete();
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.jozufozu.flywheel.lib.visual;
|
package com.jozufozu.flywheel.lib.visual.components;
|
||||||
|
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.joml.Vector4fc;
|
import org.joml.Vector4fc;
|
||||||
@ -14,6 +14,8 @@ import com.jozufozu.flywheel.lib.material.SimpleMaterial;
|
|||||||
import com.jozufozu.flywheel.lib.model.ModelCache;
|
import com.jozufozu.flywheel.lib.model.ModelCache;
|
||||||
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
||||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.EntityComponent;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.InstanceRecycler;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Axis;
|
import com.mojang.math.Axis;
|
||||||
|
|
||||||
@ -26,7 +28,7 @@ import net.minecraft.world.entity.Entity;
|
|||||||
/**
|
/**
|
||||||
* A component that uses instances to render the fire animation on an entity.
|
* A component that uses instances to render the fire animation on an entity.
|
||||||
*/
|
*/
|
||||||
public class FireComponent {
|
public class FireComponent implements EntityComponent {
|
||||||
private static final Material FIRE_MATERIAL = SimpleMaterial.builderOf(Materials.CHUNK_CUTOUT_UNSHADED)
|
private static final Material FIRE_MATERIAL = SimpleMaterial.builderOf(Materials.CHUNK_CUTOUT_UNSHADED)
|
||||||
.backfaceCulling(false) // Disable backface because we want to be able to flip the model.
|
.backfaceCulling(false) // Disable backface because we want to be able to flip the model.
|
||||||
.build();
|
.build();
|
||||||
@ -66,6 +68,7 @@ public class FireComponent {
|
|||||||
*
|
*
|
||||||
* @param context The frame context.
|
* @param context The frame context.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void beginFrame(VisualFrameContext context) {
|
public void beginFrame(VisualFrameContext context) {
|
||||||
fire0.resetCount();
|
fire0.resetCount();
|
||||||
fire1.resetCount();
|
fire1.resetCount();
|
||||||
@ -118,6 +121,7 @@ public class FireComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
fire0.delete();
|
fire0.delete();
|
||||||
fire1.delete();
|
fire1.delete();
|
@ -1,4 +1,4 @@
|
|||||||
package com.jozufozu.flywheel.lib.visual;
|
package com.jozufozu.flywheel.lib.visual.components;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
@ -16,6 +16,8 @@ import com.jozufozu.flywheel.lib.instance.ShadowInstance;
|
|||||||
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
|
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
|
||||||
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
||||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.EntityComponent;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.InstanceRecycler;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
@ -40,7 +42,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
|||||||
* <br>
|
* <br>
|
||||||
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.</p>
|
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.</p>
|
||||||
*/
|
*/
|
||||||
public class ShadowComponent {
|
public class ShadowComponent implements EntityComponent {
|
||||||
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
|
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
|
||||||
.texture(new ResourceLocation("textures/misc/shadow.png"))
|
.texture(new ResourceLocation("textures/misc/shadow.png"))
|
||||||
.mipmap(false)
|
.mipmap(false)
|
||||||
@ -88,8 +90,9 @@ public class ShadowComponent {
|
|||||||
*
|
*
|
||||||
* @param radius The radius of the shadow, in blocks.
|
* @param radius The radius of the shadow, in blocks.
|
||||||
*/
|
*/
|
||||||
public void radius(float radius) {
|
public ShadowComponent radius(float radius) {
|
||||||
this.radius = Math.min(radius, 32);
|
this.radius = Math.min(radius, 32);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,8 +100,9 @@ public class ShadowComponent {
|
|||||||
*
|
*
|
||||||
* @param strength The strength of the shadow.
|
* @param strength The strength of the shadow.
|
||||||
*/
|
*/
|
||||||
public void strength(float strength) {
|
public ShadowComponent strength(float strength) {
|
||||||
this.strength = strength;
|
this.strength = strength;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -107,6 +111,7 @@ public class ShadowComponent {
|
|||||||
*
|
*
|
||||||
* @param context The frame context.
|
* @param context The frame context.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void beginFrame(VisualFrameContext context) {
|
public void beginFrame(VisualFrameContext context) {
|
||||||
instances.resetCount();
|
instances.resetCount();
|
||||||
|
|
||||||
@ -210,6 +215,7 @@ public class ShadowComponent {
|
|||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
instances.delete();
|
instances.delete();
|
||||||
}
|
}
|
@ -14,7 +14,10 @@ import com.jozufozu.flywheel.lib.model.ModelHolder;
|
|||||||
import com.jozufozu.flywheel.lib.model.Models;
|
import com.jozufozu.flywheel.lib.model.Models;
|
||||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||||
import com.jozufozu.flywheel.lib.model.part.ModelPartConverter;
|
import com.jozufozu.flywheel.lib.model.part.ModelPartConverter;
|
||||||
import com.jozufozu.flywheel.lib.visual.AbstractEntityVisual;
|
import com.jozufozu.flywheel.lib.visual.SimpleEntityVisual;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.components.BoundingBoxComponent;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.components.FireComponent;
|
||||||
|
import com.jozufozu.flywheel.lib.visual.components.ShadowComponent;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.math.Axis;
|
import com.mojang.math.Axis;
|
||||||
|
|
||||||
@ -26,7 +29,7 @@ import net.minecraft.world.level.block.RenderShape;
|
|||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class MinecartVisual<T extends AbstractMinecart> extends AbstractEntityVisual<T> implements TickableVisual, DynamicVisual {
|
public class MinecartVisual<T extends AbstractMinecart> extends SimpleEntityVisual<T> implements TickableVisual, DynamicVisual {
|
||||||
public static final ModelHolder CHEST_BODY_MODEL = createBodyModelHolder(ModelLayers.CHEST_MINECART);
|
public static final ModelHolder CHEST_BODY_MODEL = createBodyModelHolder(ModelLayers.CHEST_MINECART);
|
||||||
public static final ModelHolder COMMAND_BLOCK_BODY_MODEL = createBodyModelHolder(ModelLayers.COMMAND_BLOCK_MINECART);
|
public static final ModelHolder COMMAND_BLOCK_BODY_MODEL = createBodyModelHolder(ModelLayers.COMMAND_BLOCK_MINECART);
|
||||||
public static final ModelHolder FURNACE_BODY_MODEL = createBodyModelHolder(ModelLayers.FURNACE_MINECART);
|
public static final ModelHolder FURNACE_BODY_MODEL = createBodyModelHolder(ModelLayers.FURNACE_MINECART);
|
||||||
@ -48,7 +51,6 @@ public class MinecartVisual<T extends AbstractMinecart> extends AbstractEntityVi
|
|||||||
public MinecartVisual(VisualizationContext ctx, T entity, ModelHolder bodyModel) {
|
public MinecartVisual(VisualizationContext ctx, T entity, ModelHolder bodyModel) {
|
||||||
super(ctx, entity);
|
super(ctx, entity);
|
||||||
this.bodyModel = bodyModel;
|
this.bodyModel = bodyModel;
|
||||||
shadow.radius(0.7f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ModelHolder createBodyModelHolder(ModelLayerLocation layer) {
|
private static ModelHolder createBodyModelHolder(ModelLayerLocation layer) {
|
||||||
@ -59,6 +61,10 @@ public class MinecartVisual<T extends AbstractMinecart> extends AbstractEntityVi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(float partialTick) {
|
public void init(float partialTick) {
|
||||||
|
addComponent(new ShadowComponent(visualizationContext, entity).radius(0.7f));
|
||||||
|
addComponent(new FireComponent(visualizationContext, entity));
|
||||||
|
addComponent(new BoundingBoxComponent(visualizationContext, entity));
|
||||||
|
|
||||||
body = createBodyInstance();
|
body = createBodyInstance();
|
||||||
blockState = entity.getDisplayBlockState();
|
blockState = entity.getDisplayBlockState();
|
||||||
contents = createContentsInstance();
|
contents = createContentsInstance();
|
||||||
@ -109,9 +115,7 @@ public class MinecartVisual<T extends AbstractMinecart> extends AbstractEntityVi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginFrame(VisualFrameContext context) {
|
public void beginFrame(VisualFrameContext context) {
|
||||||
shadow.beginFrame(context);
|
super.beginFrame(context);
|
||||||
fire.beginFrame(context);
|
|
||||||
boundingBox.beginFrame(context);
|
|
||||||
|
|
||||||
if (!isVisible(context.frustum())) {
|
if (!isVisible(context.frustum())) {
|
||||||
return;
|
return;
|
||||||
@ -210,7 +214,6 @@ public class MinecartVisual<T extends AbstractMinecart> extends AbstractEntityVi
|
|||||||
if (contents != null) {
|
if (contents != null) {
|
||||||
contents.delete();
|
contents.delete();
|
||||||
}
|
}
|
||||||
super._delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shouldSkipRender(AbstractMinecart minecart) {
|
public static boolean shouldSkipRender(AbstractMinecart minecart) {
|
||||||
|
Loading…
Reference in New Issue
Block a user