Rewrite drive model to support custom cell models (#4459)

* Rewrite driver model to support custom cell models

Each cell can now register a mapping Item -> ResourceLocation for a
custom cell model. Fallback will always be a 1k item cell.
This commit is contained in:
yueh
2020-07-11 23:07:20 +02:00
committed by GitHub
parent e8143d3618
commit 06735f5c39
30 changed files with 319 additions and 95 deletions
@@ -31,22 +31,22 @@ import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.Direction;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import appeng.api.definitions.IItems;
import appeng.block.storage.DriveSlotCellType;
import appeng.block.storage.DriveSlotsState;
import appeng.client.render.DelegateBakedModel;
import appeng.core.Api;
public class DriveBakedModel extends DelegateBakedModel {
private final Map<DriveSlotCellType, IBakedModel> bakedCells;
private final Map<Item, IBakedModel> bakedCells;
private final IBakedModel defaultCell;
public DriveBakedModel(IBakedModel bakedBase, Map<DriveSlotCellType, IBakedModel> bakedCells) {
public DriveBakedModel(IBakedModel bakedBase, Map<Item, IBakedModel> cellModels, IBakedModel defaultCell) {
super(bakedBase);
this.bakedCells = bakedCells;
this.bakedCells = cellModels;
this.defaultCell = defaultCell;
}
@Nonnull
@@ -92,23 +92,18 @@ public class DriveBakedModel extends DelegateBakedModel {
public boolean isAmbientOcclusion() {
// We have faces inside the chassis that are facing east, but should not receive
// ambient occlusion from the east-side, but sadly this cannot be fine-tuned on
// a
// face-by-face basis.
// a face-by-face basis.
return false;
}
// Determine which drive chassis to show based on the used cell
private IBakedModel getCellChassisModel(Item cell) {
IItems items = Api.INSTANCE.definitions().items();
if (cell == null) {
return bakedCells.get(DriveSlotCellType.EMPTY);
} else if (items.fluidCell1k().item() == cell || items.fluidCell4k().item() == cell
|| items.fluidCell16k().item() == cell || items.fluidCell64k().item() == cell) {
return bakedCells.get(DriveSlotCellType.FLUID);
} else {
// Fall back to an item model
return bakedCells.get(DriveSlotCellType.ITEM);
return bakedCells.get(Items.AIR);
}
final IBakedModel model = bakedCells.get(cell);
return model != null ? model : defaultCell;
}
private static void addModel(@Nullable BlockState state, @Nonnull Random rand, @Nonnull IModelData extraData,
@@ -20,13 +20,12 @@ package appeng.client.render.model;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.model.IBakedModel;
@@ -36,39 +35,41 @@ import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import appeng.block.storage.DriveSlotCellType;
import appeng.api.client.ICellModelRegistry;
import appeng.core.Api;
public class DriveModel implements IModelGeometry<DriveModel> {
private static final ResourceLocation MODEL_BASE = new ResourceLocation(
"appliedenergistics2:block/drive/drive_base");
private static final Map<DriveSlotCellType, ResourceLocation> MODELS_CELLS = ImmutableMap.of(
DriveSlotCellType.EMPTY, new ResourceLocation("appliedenergistics2:block/drive/drive_cell_empty"),
DriveSlotCellType.ITEM, new ResourceLocation("appliedenergistics2:block/drive/drive_cell_items"),
DriveSlotCellType.FLUID, new ResourceLocation("appliedenergistics2:block/drive/drive_cell_fluids"));
public static final Set<ResourceLocation> DEPENDENCIES = ImmutableSet.<ResourceLocation>builder()
.addAll(MODELS_CELLS.values()).add(MODEL_BASE).build();
private static final ResourceLocation MODEL_CELL_EMPTY = new ResourceLocation(
"appliedenergistics2:block/drive/drive_cell_empty");
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery,
Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform,
ItemOverrideList overrides, ResourceLocation modelLocation) {
EnumMap<DriveSlotCellType, IBakedModel> cellModels = new EnumMap<>(DriveSlotCellType.class);
final ICellModelRegistry cellRegistry = Api.instance().client().cells();
final Map<Item, IBakedModel> cellModels = new IdentityHashMap<>();
// Load the base model and the model for each cell state.
for (DriveSlotCellType cellType : MODELS_CELLS.keySet()) {
IBakedModel cellModel = bakery.getBakedModel(MODELS_CELLS.get(cellType), modelTransform, spriteGetter);
cellModels.put(cellType, cellModel);
// Load the base model and the model for each cell model.
for (Entry<Item, ResourceLocation> entry : cellRegistry.models().entrySet()) {
IBakedModel cellModel = bakery.getBakedModel(entry.getValue(), modelTransform, spriteGetter);
cellModels.put(entry.getKey(), cellModel);
}
IBakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
return new DriveBakedModel(baseModel, cellModels);
final IBakedModel baseModel = bakery.getBakedModel(MODEL_BASE, modelTransform, spriteGetter);
final IBakedModel defaultCell = bakery.getBakedModel(cellRegistry.getDefaultModel(), modelTransform,
spriteGetter);
cellModels.put(Items.AIR, bakery.getBakedModel(MODEL_CELL_EMPTY, modelTransform, spriteGetter));
return new DriveBakedModel(baseModel, cellModels, defaultCell);
}
@Override