package com.infinityraider.infinitylib.block.tile;

import com.google.common.collect.Sets;
import com.infinityraider.infinitylib.render.tile.ITileRenderer;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import java.util.function.Supplier;

public class InfinityTileEntityType<T extends TileEntity> extends TileEntityType<T> implements IInfinityTileEntityType {
    private final String name;
    private final IRenderFactory<T> renderFactory;

    @OnlyIn(Dist.CLIENT)
    private ITileRenderer<T> renderer;

    private InfinityTileEntityType(String name, Supplier<? extends T> factory, Set<Block> validBlocks, IRenderFactory<T> renderFactory) {
        super(factory, validBlocks, null);
        this.name = name;
        this.renderFactory = renderFactory;
    }

    @Nonnull
    @Override
    public String getInternalName() {
        return this.name;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    @Nullable
    @OnlyIn(Dist.CLIENT)
    public ITileRenderer<T> getRenderer() {
        if(this.renderer == null) {
            this.renderer = this.renderFactory.createRenderer();
        }
        return this.renderer;
    }

    public static <T extends TileEntity> Builder<T> builder(String name, Supplier<? extends T> factory) {
        return new Builder<>(name, factory);
    }

    public static final class Builder<T extends TileEntity> {
        private final String name;
        private final Supplier<? extends T> factory;
        private final Set<Block> blocks;

        private IRenderFactory<T> renderFactory;

        private Builder(String name, Supplier<? extends T> factory) {
            this.name = name;
            this.factory = factory;
            this.blocks = Sets.newIdentityHashSet();
            this.renderFactory = () -> null;
        }

        public Builder<T> addBlock(Block block) {
            this.blocks.add(block);
            return this;
        }

        public Builder<T> addBlocks(Collection<Block> block) {
            this.blocks.addAll(block);
            return this;
        }

        public Builder<T> addBlocks(Block... blocks) {
            Arrays.stream(blocks).forEach(this::addBlock);
            return this;
        }

        public Builder<T> setRenderFactory(IRenderFactory<T> factory) {
            this.renderFactory = factory;
            return this;
        }

        public InfinityTileEntityType<T> build() {
            return new InfinityTileEntityType<T>(this.name, this.factory, this.blocks, this.renderFactory);
        }
    }

    public interface IRenderFactory<T extends TileEntity> {
        @Nullable
        @OnlyIn(Dist.CLIENT)
        ITileRenderer<T> createRenderer();
    }
}

@@ -1359,16 +1359,17 @@
       if
+ 
 (this.re
@@ -2124,18 +2124,20 @@
 y = 
-() -%3E null
+noRenderer()
 ;%0A  
@@ -2873,32 +2873,153 @@
        %7D%0A    %7D%0A%0A
+    public static %3CT extends TileEntity%3E IRenderFactory%3CT%3E noRenderer() %7B%0A        return new NoRenderFactory%3C%3E();%0A    %7D%0A%0A
     public inter
@@ -3157,11 +3157,269 @@
 );%0A    %7D
+%0A%0A    private static final class NoRenderFactory%3CT extends TileEntity%3E implements IRenderFactory%3CT%3E %7B%0A        @Override%0A        @Nullable%0A        @OnlyIn(Dist.CLIENT)%0A        public ITileRenderer%3CT%3E createRenderer() %7B%0A            return null;%0A        %7D%0A    %7D
 %0A%7D%0A

Fix server crash