Skip to content

Commit b6960a5

Browse files
authored
Implement Registry for Custom Coils (#2874)
1 parent abb8645 commit b6960a5

34 files changed

+1244
-172
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ thumbs.db
1616
*.war
1717
*.ear
1818
*.txt
19+
*.ase
1920

2021
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
2122
hs_err_pid*

src/main/java/gregtech/api/GregTechAPI.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import gregtech.api.advancement.IAdvancementManager;
44
import gregtech.api.block.ICleanroomFilter;
55
import gregtech.api.block.IHeatingCoilBlockStats;
6+
import gregtech.api.block.coil.CoilManager;
67
import gregtech.api.command.ICommandManager;
78
import gregtech.api.cover.CoverDefinition;
89
import gregtech.api.event.HighTierEvent;
@@ -56,6 +57,8 @@ public class GregTechAPI {
5657
public static MarkerMaterialRegistry markerMaterialRegistry;
5758
/** Will be available at the Pre-Initialization stage */
5859
public static MTEManager mteManager;
60+
/** Will be available at the Pre-Initialization stage */
61+
public static CoilManager coilManager;
5962
/** GT's data migrations API */
6063
public static final MigrationAPI MIGRATIONS = new MigrationAPI();
6164
public static final RecipePropertyRegistry RECIPE_PROPERTIES = new RecipePropertyRegistry();

src/main/java/gregtech/api/block/IHeatingCoilBlockStats.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
import gregtech.api.recipes.properties.impl.TemperatureProperty;
44
import gregtech.api.unification.material.Material;
5+
import gregtech.client.model.ActiveVariantBlockBakedModel;
56

67
import org.jetbrains.annotations.NotNull;
78
import org.jetbrains.annotations.Nullable;
89

10+
import java.util.function.BooleanSupplier;
11+
912
/**
1013
* Implement this interface on the Block Enum for your Heating Coil block
1114
*
@@ -52,4 +55,12 @@ public interface IHeatingCoilBlockStats {
5255
*/
5356
@Nullable
5457
Material getMaterial();
58+
59+
default int getColor() {
60+
return getMaterial() == null ? 0xFFFFFFFF : getMaterial().getMaterialRGB();
61+
}
62+
63+
default ActiveVariantBlockBakedModel createModel(BooleanSupplier bloomConfig) {
64+
return null;
65+
}
5566
}

src/main/java/gregtech/api/block/VariantActiveBlock.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import net.minecraft.block.material.Material;
99
import net.minecraft.block.properties.IProperty;
1010
import net.minecraft.block.properties.PropertyBool;
11-
import net.minecraft.block.properties.PropertyEnum;
1211
import net.minecraft.block.state.BlockStateContainer;
1312
import net.minecraft.block.state.IBlockState;
1413
import net.minecraft.client.Minecraft;
@@ -25,21 +24,20 @@
2524
import net.minecraftforge.fml.relauncher.Side;
2625
import net.minecraftforge.fml.relauncher.SideOnly;
2726

27+
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
2828
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
2929
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
3030
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
3131
import it.unimi.dsi.fastutil.objects.ObjectSet;
3232
import org.jetbrains.annotations.NotNull;
3333
import team.chisel.ctm.client.state.CTMExtendedState;
3434

35-
import java.util.EnumMap;
36-
import java.util.Map;
3735
import java.util.Objects;
3836
import java.util.concurrent.locks.ReadWriteLock;
3937
import java.util.concurrent.locks.ReentrantReadWriteLock;
4038
import java.util.stream.Collectors;
4139

42-
public class VariantActiveBlock<T extends Enum<T> & IStringSerializable> extends VariantBlock<T> {
40+
public abstract class VariantActiveBlock<T extends IStringSerializable & Comparable<T>> extends VariantBlock<T> {
4341

4442
private static final Int2ObjectMap<ObjectSet<BlockPos>> ACTIVE_BLOCKS = new Int2ObjectOpenHashMap<>();
4543
private static final ReadWriteLock ACTIVE_BLOCKS_LOCK = new ReentrantReadWriteLock();
@@ -92,12 +90,17 @@ protected boolean canSilkHarvest() {
9290
@NotNull
9391
@Override
9492
public BlockRenderLayer getRenderLayer() {
93+
return getRenderLayer(VALUES[0]);
94+
}
95+
96+
@NotNull
97+
public BlockRenderLayer getRenderLayer(T value) {
9598
return BlockRenderLayer.CUTOUT;
9699
}
97100

98101
@Override
99102
public boolean canRenderInLayer(@NotNull IBlockState state, @NotNull BlockRenderLayer layer) {
100-
return layer == getRenderLayer() ||
103+
return layer == getRenderLayer(getState(state)) ||
101104
layer == BloomEffectUtil.getEffectiveBloomLayer(isBloomEnabled(getState(state)));
102105
}
103106

@@ -113,16 +116,15 @@ public int getMetaFromState(IBlockState state) {
113116
if (state.getValue(ACTIVE_DEPRECATED)) {
114117
meta += 8;
115118
}
116-
return meta + state.getValue(VARIANT).ordinal();
119+
return meta + state.getValue(VARIANT);
117120
}
118121

119122
@NotNull
120123
@Override
121124
protected BlockStateContainer createBlockState() {
122-
Class<T> enumClass = getActualTypeParameter(getClass(), VariantActiveBlock.class);
123-
this.VARIANT = PropertyEnum.create("variant", enumClass);
124-
this.VALUES = enumClass.getEnumConstants();
125-
return new ExtendedBlockState(this, new IProperty[] { VARIANT, ACTIVE_DEPRECATED },
125+
super.createBlockState();
126+
return new ExtendedBlockState(this,
127+
new IProperty[] { VARIANT, ACTIVE_DEPRECATED },
126128
new IUnlistedProperty[] { ACTIVE });
127129
}
128130

@@ -144,17 +146,18 @@ public IExtendedBlockState getExtendedState(@NotNull IBlockState state, @NotNull
144146

145147
@SideOnly(Side.CLIENT)
146148
public void onModelRegister() {
147-
Map<T, ModelResourceLocation> models = new EnumMap<>(VALUES[0].getDeclaringClass());
149+
Int2ObjectMap<ModelResourceLocation> models = new Int2ObjectArrayMap<>();
148150
for (T value : VALUES) {
151+
int index = VARIANT.getIndexOf(value);
149152
ModelResourceLocation inactiveModel = model(false, value);
150153
ModelResourceLocation activeModel = model(true, value);
151154

152155
ActiveVariantBlockBakedModel model = new ActiveVariantBlockBakedModel(inactiveModel, activeModel,
153156
() -> isBloomEnabled(value));
154-
models.put(value, model.getModelLocation());
157+
models.put(index, model.getModelLocation());
155158

156159
Item item = Item.getItemFromBlock(this);
157-
ModelLoader.setCustomModelResourceLocation(item, value.ordinal(), inactiveModel);
160+
ModelLoader.setCustomModelResourceLocation(item, index, inactiveModel);
158161
ModelLoader.registerItemVariants(item, activeModel);
159162
}
160163
ModelLoader.setCustomStateMapper(this,
@@ -166,11 +169,11 @@ public void onModelRegister() {
166169
private ModelResourceLocation model(boolean active, T variant) {
167170
return new ModelResourceLocation(
168171
Objects.requireNonNull(getRegistryName()),
169-
"active=" + active + ",variant=" + VARIANT.getName(variant));
172+
"active=" + active + ",variant=" + variant.getName());
170173
}
171174

172175
@SideOnly(Side.CLIENT)
173-
protected boolean isBloomEnabled(T value) {
176+
public boolean isBloomEnabled(T value) {
174177
return ConfigHolder.client.machinesEmissiveTextures;
175178
}
176179
}

src/main/java/gregtech/api/block/VariantBlock.java

Lines changed: 120 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import net.minecraft.block.Block;
77
import net.minecraft.block.SoundType;
88
import net.minecraft.block.material.Material;
9-
import net.minecraft.block.properties.PropertyEnum;
9+
import net.minecraft.block.properties.PropertyHelper;
1010
import net.minecraft.block.state.BlockStateContainer;
1111
import net.minecraft.block.state.IBlockState;
1212
import net.minecraft.client.resources.I18n;
@@ -23,31 +23,42 @@
2323
import net.minecraftforge.fml.relauncher.Side;
2424
import net.minecraftforge.fml.relauncher.SideOnly;
2525

26+
import com.google.common.base.Optional;
27+
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
28+
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
29+
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
30+
import it.unimi.dsi.fastutil.objects.Object2IntMap;
2631
import org.jetbrains.annotations.NotNull;
2732
import org.jetbrains.annotations.Nullable;
2833

34+
import java.lang.reflect.Array;
2935
import java.lang.reflect.ParameterizedType;
3036
import java.lang.reflect.Type;
37+
import java.util.Arrays;
38+
import java.util.Collection;
3139
import java.util.Collections;
3240
import java.util.List;
3341

34-
public class VariantBlock<T extends Enum<T> & IStringSerializable> extends Block {
42+
public abstract class VariantBlock<T extends IStringSerializable & Comparable<T>> extends Block {
3543

36-
protected PropertyEnum<T> VARIANT;
44+
protected PropertyIntMap<T> VARIANT;
3745
protected T[] VALUES;
3846

3947
public VariantBlock(@NotNull Material materialIn) {
4048
super(materialIn);
41-
if (VALUES.length > 0 && VALUES[0] instanceof IStateHarvestLevel) {
49+
updateHarvestLevels();
50+
setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
51+
setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, 0));
52+
}
53+
54+
protected void updateHarvestLevels() {
55+
if (VALUES.length > 0 && VALUES[0] instanceof IStateHarvestLevel stateHarvestLevel) {
4256
for (T t : VALUES) {
43-
IStateHarvestLevel stateHarvestLevel = (IStateHarvestLevel) t;
4457
IBlockState state = getState(t);
45-
setHarvestLevel(stateHarvestLevel.getHarvestTool(state), stateHarvestLevel.getHarvestLevel(state),
46-
state);
58+
setHarvestLevel(stateHarvestLevel.getHarvestTool(state),
59+
stateHarvestLevel.getHarvestLevel(state), state);
4760
}
4861
}
49-
setCreativeTab(GTCreativeTabs.TAB_GREGTECH);
50-
setDefaultState(this.blockState.getBaseState().withProperty(VARIANT, VALUES[0]));
5162
}
5263

5364
@Override
@@ -58,11 +69,11 @@ public void getSubBlocks(@NotNull CreativeTabs tab, @NotNull NonNullList<ItemSta
5869
}
5970

6071
public IBlockState getState(T variant) {
61-
return getDefaultState().withProperty(VARIANT, variant);
72+
return getDefaultState().withProperty(VARIANT, VARIANT.getIndexOf(variant));
6273
}
6374

6475
public T getState(IBlockState blockState) {
65-
return blockState.getValue(VARIANT);
76+
return VARIANT.getValue(blockState.getValue(VARIANT));
6677
}
6778

6879
public T getState(ItemStack stack) {
@@ -74,18 +85,34 @@ public ItemStack getItemVariant(T variant) {
7485
}
7586

7687
public ItemStack getItemVariant(T variant, int amount) {
77-
return new ItemStack(this, amount, variant.ordinal());
88+
return new ItemStack(this, amount, VARIANT.getIndexOf(variant));
7889
}
7990

8091
@NotNull
8192
@Override
8293
protected BlockStateContainer createBlockState() {
83-
Class<T> enumClass = getActualTypeParameter(getClass(), VariantBlock.class);
84-
this.VARIANT = PropertyEnum.create("variant", enumClass);
85-
this.VALUES = enumClass.getEnumConstants();
94+
this.VARIANT = new PropertyIntMap<>("variant", computeVariants());
95+
this.VALUES = VARIANT.getValues();
8696
return new BlockStateContainer(this, VARIANT);
8797
}
8898

99+
@NotNull
100+
protected Collection<T> computeVariants() {
101+
Class<T> enumClass = null;
102+
for (Class<?> innerClazz : getClass().getClasses()) {
103+
var enums = innerClazz.getEnumConstants();
104+
if (enums != null && enums[0] instanceof IStringSerializable) {
105+
// noinspection unchecked
106+
enumClass = (Class<T>) innerClazz;
107+
break;
108+
}
109+
}
110+
if (enumClass == null) {
111+
enumClass = getActualTypeParameter(getClass(), VariantBlock.class);;
112+
}
113+
return Arrays.asList(enumClass.getEnumConstants());
114+
}
115+
89116
@Override
90117
@SideOnly(Side.CLIENT)
91118
public void addInformation(@NotNull ItemStack stack, @Nullable World player, @NotNull List<String> tooltip,
@@ -109,12 +136,12 @@ public int damageDropped(@NotNull IBlockState state) {
109136
@Override
110137
@SuppressWarnings("deprecation")
111138
public IBlockState getStateFromMeta(int meta) {
112-
return getDefaultState().withProperty(VARIANT, VALUES[meta % VALUES.length]);
139+
return getDefaultState().withProperty(VARIANT, meta % VALUES.length);
113140
}
114141

115142
@Override
116143
public int getMetaFromState(IBlockState state) {
117-
return state.getValue(VARIANT).ordinal();
144+
return state.getValue(VARIANT);
118145
}
119146

120147
@NotNull
@@ -141,13 +168,87 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces
141168
protected static <T, R> Class<T> getActualTypeParameter(Class<? extends R> thisClass, Class<R> declaringClass) {
142169
Type type = thisClass.getGenericSuperclass();
143170

144-
while (!(type instanceof ParameterizedType) || ((ParameterizedType) type).getRawType() != declaringClass) {
171+
while (!(type instanceof ParameterizedType pType) || pType.getRawType() != declaringClass) {
145172
if (type instanceof ParameterizedType) {
146173
type = ((Class<?>) ((ParameterizedType) type).getRawType()).getGenericSuperclass();
147174
} else {
148175
type = ((Class<?>) type).getGenericSuperclass();
149176
}
150177
}
151-
return (Class<T>) ((ParameterizedType) type).getActualTypeArguments()[0];
178+
var arg = pType.getActualTypeArguments()[0];
179+
if (!(arg instanceof Class<?>)) {
180+
throw new ClassCastException(String.format("cannot cast %s to a class!", arg));
181+
}
182+
return (Class<T>) pType.getActualTypeArguments()[0];
183+
}
184+
185+
protected static class PropertyIntMap<O extends Comparable<O> & IStringSerializable>
186+
extends PropertyHelper<Integer> {
187+
188+
private final Int2ObjectMap<O> intMap;
189+
private final Object2IntMap<O> reverse;
190+
private final O[] allowedObjects;
191+
192+
@SuppressWarnings("unchecked")
193+
protected PropertyIntMap(String name, Collection<O> values) {
194+
super(name, Integer.class);
195+
if (values.isEmpty()) throw new IllegalArgumentException("values are empty!");
196+
if (values.size() > 16) throw new IllegalArgumentException("values cannot be greater than 16!");
197+
198+
this.intMap = new Int2ObjectArrayMap<>(values.size());
199+
this.reverse = new Object2IntArrayMap<>(values.size());
200+
201+
O first = values.iterator().next();
202+
this.allowedObjects = (O[]) Array.newInstance(first.getClass(), values.size());
203+
204+
for (O value : values) {
205+
int size = this.intMap.size();
206+
this.allowedObjects[size] = value;
207+
this.intMap.put(size, value);
208+
this.reverse.put(value, size);
209+
}
210+
}
211+
212+
@Override
213+
public @NotNull Collection<Integer> getAllowedValues() {
214+
return this.intMap.keySet();
215+
}
216+
217+
public @NotNull O[] getValues() {
218+
return this.allowedObjects;
219+
}
220+
221+
@Override
222+
@Deprecated
223+
public @NotNull String getName(@NotNull Integer value) {
224+
return getNameByInt(value);
225+
}
226+
227+
public @NotNull String getNameByInt(int value) {
228+
return getValue(value).getName();
229+
}
230+
231+
@Override
232+
public @NotNull Optional<Integer> parseValue(@NotNull String value) {
233+
for (O object : reverse.keySet()) {
234+
if (object.getName().equals(value)) {
235+
return Optional.of(getIndexOf(object));
236+
}
237+
}
238+
return Optional.absent();
239+
}
240+
241+
@Override
242+
public int hashCode() {
243+
return 31 * super.hashCode() + this.allowedObjects.hashCode();
244+
}
245+
246+
public int getIndexOf(O value) {
247+
return this.reverse.getInt(value);
248+
}
249+
250+
public O getValue(int index) {
251+
return this.intMap.get(index);
252+
}
152253
}
153254
}

src/main/java/gregtech/api/block/VariantItemBlock.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77

88
import org.jetbrains.annotations.NotNull;
99

10-
public class VariantItemBlock<R extends Enum<R> & IStringSerializable, T extends VariantBlock<R>> extends ItemBlock {
10+
public class VariantItemBlock<R extends IStringSerializable & Comparable<R>, T extends VariantBlock<R>>
11+
extends ItemBlock {
1112

1213
private final T genericBlock;
1314

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package gregtech.api.block.coil;
2+
3+
public interface BuilderFactory {
4+
5+
CoilBlockBuilder makeBuilder(int id, String name);
6+
}

0 commit comments

Comments
 (0)