aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/multitileentity/MultiTileEntityRegistry.java
blob: 186110abb739dff6da5df4d94bca761f6cab3fee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package gregtech.api.multitileentity;

import static gregtech.GTMod.GT_FML_LOGGER;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import net.minecraft.block.Block;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;

import com.gtnewhorizon.gtnhlib.util.map.ItemStackMap;

import appeng.core.CreativeTab;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderState;
import gregtech.api.enums.GTValues;
import gregtech.api.multitileentity.base.MultiTileEntity;
import gregtech.api.multitileentity.interfaces.IMultiTileEntity;
import gregtech.api.util.GTLanguageManager;
import gregtech.api.util.GTUtil;
import gregtech.api.util.GTUtility;
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;

public class MultiTileEntityRegistry {

    private static final HashMap<String, MultiTileEntityRegistry> NAMED_REGISTRIES = new HashMap<>();

    // TODO: NBT sensitive or not? Starting with not for now
    private static final ItemStackMap<MultiTileEntityRegistry> REGISTRIES = new ItemStackMap<>(false);
    private static final HashSet<Class<?>> sRegisteredTileEntities = new HashSet<>();

    public HashMap<Short, CreativeTab> creativeTabs = new HashMap<>();
    public final Short2ObjectMap<MultiTileEntityClassContainer> registry = new Short2ObjectOpenHashMap<>();
    public List<MultiTileEntityClassContainer> registrations = new ArrayList<>();

    private final String internalName;
    private final MultiTileEntityBlock block;

    /**
     * @param internalName the internal Name of the Item
     */
    public MultiTileEntityRegistry(String internalName, MultiTileEntityBlock block) {
        if (!Loader.instance()
            .isInState(LoaderState.PREINITIALIZATION)) {
            throw new IllegalStateException(
                "The MultiTileEntity Registry must be initialized during Preload Phase and not before");
        }
        if (!block.isRegistered()) {
            throw new IllegalStateException("Block not registered");
        }
        this.internalName = internalName;
        this.block = block;
        GT_FML_LOGGER.info(internalName + " " + Block.getIdFromBlock(block) + " This is the answer");
        this.block.setRegistry(this);
        REGISTRIES.put(new ItemStack(Item.getItemById(Block.getIdFromBlock(block)), 1, GTValues.W), this);
        NAMED_REGISTRIES.put(internalName, this);
    }

    public static TileEntity getReferenceTileEntity(int aRegistryID, int aMultiTileEntityID) {
        final MultiTileEntityRegistry tRegistry = getRegistry(aRegistryID);
        if (tRegistry == null) return null;
        final MultiTileEntityClassContainer tClassContainer = tRegistry.getClassContainer(aMultiTileEntityID);
        if (tClassContainer == null) return null;
        return tClassContainer.getReferenceTileEntity();
    }

    public MultiTileEntity getReferenceTileEntity(ItemStack stack) {
        return getReferenceTileEntity(Items.feather.getDamage(stack));
    }

    public MultiTileEntity getReferenceTileEntity(int metaId) {
        final MultiTileEntityClassContainer muteClass = registry.get((short) metaId);
        if (muteClass == null) return null;
        return muteClass.getReferenceTileEntity();
    }

    public static MultiTileEntityRegistry getRegistry(int aRegistryID) {
        return REGISTRIES.get(new ItemStack(Item.getItemById(aRegistryID), 1, GTValues.W));
    }

    public static MultiTileEntityRegistry getRegistry(String aRegistryName) {
        return NAMED_REGISTRIES.get(aRegistryName);
    }

    public MultiTileEntityClassContainer create(int aID, Class<? extends MultiTileEntity> aClass) {
        return new MultiTileEntityClassContainer(this, aID, aClass);
    }

    /**
     * Adds a new MultiTileEntity. It is highly recommended to do this in either the PreInit or the Init Phase. PostInit
     * might not work well.
     */
    public ItemStack add(String aLocalised, MultiTileEntityClassContainer aClassContainer) {
        boolean tFailed = false;
        if (GTUtility.isStringInvalid(aLocalised)) {
            GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Localisation Missing!");
            tFailed = true;
        }
        if (aClassContainer == null) {
            GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Class Container is null!");
            tFailed = true;
        } else {
            if (aClassContainer.getMuteClass() == null) {
                GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Class inside Class Container is null!");
                tFailed = true;
            }
            if (aClassContainer.getMuteID() == GTValues.W) {
                GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Class Container uses Wildcard MetaData!");
                tFailed = true;
            }
            if (aClassContainer.getMuteID() < 0) {
                GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: Class Container uses negative MetaData!");
                tFailed = true;
            }
            if (registry.containsKey(aClassContainer.getMuteID())) {
                GT_FML_LOGGER.error(
                    "MULTI-TILE REGISTRY ERROR: Class Container uses occupied MetaData! (" + aClassContainer.getMuteID()
                        + ")");
                tFailed = true;
            }
        }
        if (tFailed) {
            GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR " + aLocalised + " : STACKTRACE START");
            int i = 0;
            for (StackTraceElement tElement : new Exception().getStackTrace()) if (i++ < 5 && !tElement.getClassName()
                .startsWith("sun")) GT_FML_LOGGER.error("\tat " + tElement);
            else break;
            GT_FML_LOGGER.error("MULTI-TILE REGISTRY ERROR: STACKTRACE END");
            return null;
        }

        GTLanguageManager.addStringLocalization(internalName + "." + aClassContainer.getMuteID() + ".name", aLocalised);
        registry.put(aClassContainer.getMuteID(), aClassContainer);
        mLastRegisteredID = aClassContainer.getMuteID();
        registrations.add(aClassContainer);

        if (sRegisteredTileEntities.add(
            aClassContainer.getReferenceTileEntity()
                .getClass())) {
            aClassContainer.getReferenceTileEntity()
                .onRegistrationFirst(this, aClassContainer.getMuteID());
        }

        return getItem(aClassContainer.getMuteID());
    }

    public short mLastRegisteredID = GTValues.W;

    public ItemStack getItem() {
        return getItem(mLastRegisteredID, 1, null);
    }

    public ItemStack getItem(int aID) {
        return getItem(aID, 1, null);
    }

    public ItemStack getItem(int aID, NBTTagCompound nbt) {
        return getItem(aID, 1, nbt);
    }

    public ItemStack getItem(int aID, long aAmount) {
        return getItem(aID, aAmount, null);
    }

    public ItemStack getItem(int metaID, long amount, NBTTagCompound nbt) {
        final ItemStack stack = new ItemStack(block, (int) amount, metaID);
        if (nbt == null || nbt.hasNoTags()) {
            nbt = new NBTTagCompound();
            final TileEntity tileEntity = getNewTileEntity(metaID, nbt);
            ((IMultiTileEntity) tileEntity).writeItemNBT(nbt);
        }
        stack.setTagCompound(nbt);
        return stack;
    }

    public String getLocal(int aID) {
        return StatCollector.translateToLocal(internalName + "." + aID + ".name");
    }

    public MultiTileEntityClassContainer getClassContainer(int aID) {
        return registry.get((short) aID);
    }

    public MultiTileEntityClassContainer getClassContainer(ItemStack stack) {
        return registry.get((short) Items.feather.getDamage(stack));
    }

    public TileEntity getNewTileEntity(int aID) {
        return getNewTileEntity(null, 0, 0, 0, aID);
    }

    public TileEntity getNewTileEntity(World aWorld, int x, int y, int z, int metaID) {
        return getNewTileEntity(aWorld, x, y, z, metaID, null);
    }

    public TileEntity getNewTileEntity(World aWorld, int x, int y, int z, int metaID, NBTTagCompound nbt) {
        final MultiTileEntityClassContainer container = registry.get((short) metaID);
        if (container == null) return null;
        final MultiTileEntity te = (MultiTileEntity) GTUtility
            .callConstructor(container.getMuteClass(), -1, null, true);
        te.setWorldObj(aWorld);
        te.xCoord = x;
        te.yCoord = y;
        te.zCoord = z;
        nbt = (nbt == null || nbt.hasNoTags()) ? container.getParameters()
            : GTUtil.fuseNBT(nbt, container.getParameters());
        te.initFromNBT(nbt, (short) metaID, (short) Block.getIdFromBlock(block));
        return te;
    }

    public TileEntity getNewTileEntity(int meta, NBTTagCompound nbt) {
        return getNewTileEntity(null, 0, 0, 0, meta, nbt);
    }

    public String getInternalName() {
        return internalName;
    }

    public MultiTileEntityBlock getBlock() {
        return block;
    }
}