Moving to source sets

This commit is contained in:
Sebastian Hartte
2020-07-01 23:36:51 +02:00
parent f2e3d81fd7
commit 2642ced86b
2924 changed files with 794 additions and 796 deletions
@@ -1,288 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.BakedQuad;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import net.minecraftforge.client.model.data.IDynamicBakedModel;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.tile.crafting.CraftingCubeModelData;
import appeng.util.Platform;
/**
* The base model for baked models used by components of the crafting cube
* multi-block in it's formed state. Primarily this base class handles adding
* the "ring" that frames the multi-block structure and delegates rendering of
* the "inner" part of each block to the subclasses of this class.
*/
abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
private final Sprite ringCorner;
private final Sprite ringHor;
private final Sprite ringVer;
CraftingCubeBakedModel(Sprite ringCorner, Sprite ringHor, Sprite ringVer) {
this.ringCorner = ringCorner;
this.ringHor = ringHor;
this.ringVer = ringVer;
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@Nonnull IModelData extraData) {
if (side == null) {
return Collections.emptyList(); // No generic quads for this model
}
EnumSet<Direction> connections = getConnections(extraData);
List<BakedQuad> quads = new ArrayList<>();
CubeBuilder builder = new CubeBuilder(quads);
builder.setDrawFaces(EnumSet.of(side));
// Add the quads for the ring that frames the entire multi-block structure
this.addRing(builder, side, connections);
// Calculate the bounds of the "inner" block that is framed by the border drawn
// above
float x2 = connections.contains(Direction.EAST) ? 16 : 13.01f;
float x1 = connections.contains(Direction.WEST) ? 0 : 2.99f;
float y2 = connections.contains(Direction.UP) ? 16 : 13.01f;
float y1 = connections.contains(Direction.DOWN) ? 0 : 2.99f;
float z2 = connections.contains(Direction.SOUTH) ? 16 : 13.01f;
float z1 = connections.contains(Direction.NORTH) ? 0 : 2.99f;
// On the axis of the side that we're currently drawing, extend the dimensions
// out to the outer face of the block
switch (side) {
case DOWN:
case UP:
y1 = 0;
y2 = 16;
break;
case NORTH:
case SOUTH:
z1 = 0;
z2 = 16;
break;
case WEST:
case EAST:
x1 = 0;
x2 = 16;
break;
}
this.addInnerCube(side, state, extraData, builder, x1, y1, z1, x2, y2, z2);
return quads;
}
private void addRing(CubeBuilder builder, @Nullable Direction side, EnumSet<Direction> connections) {
// Fill in the corners
builder.setTexture(this.ringCorner);
this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.NORTH);
this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.SOUTH);
this.addCornerCap(builder, connections, side, Direction.UP, Direction.WEST, Direction.NORTH);
this.addCornerCap(builder, connections, side, Direction.UP, Direction.WEST, Direction.SOUTH);
this.addCornerCap(builder, connections, side, Direction.DOWN, Direction.EAST, Direction.NORTH);
this.addCornerCap(builder, connections, side, Direction.DOWN, Direction.EAST, Direction.SOUTH);
this.addCornerCap(builder, connections, side, Direction.DOWN, Direction.WEST, Direction.NORTH);
this.addCornerCap(builder, connections, side, Direction.DOWN, Direction.WEST, Direction.SOUTH);
// Fill in the remaining stripes of the face
for (Direction a : Direction.values()) {
if (a == side || a == side.getOpposite()) {
continue;
}
// Select the horizontal or vertical ring texture depending on which side we're
// filling in
if ((side.getAxis() != Direction.Axis.Y)
&& (a == Direction.NORTH || a == Direction.EAST || a == Direction.WEST || a == Direction.SOUTH)) {
builder.setTexture(this.ringVer);
} else if (side.getAxis() == Direction.Axis.Y && (a == Direction.EAST || a == Direction.WEST)) {
builder.setTexture(this.ringVer);
} else {
builder.setTexture(this.ringHor);
}
// If there's an adjacent crafting cube block on side a, then the core of the
// block already extends
// fully to this side. So only bother drawing the stripe, if there's no
// connection.
if (!connections.contains(a)) {
// Note that since we're drawing something that "looks" 2-dimensional,
// two of the following will always be 0 and 16.
float x1 = 0, y1 = 0, z1 = 0, x2 = 16, y2 = 16, z2 = 16;
switch (a) {
case DOWN:
y1 = 0;
y2 = 3;
break;
case UP:
y1 = 13.0f;
y2 = 16;
break;
case WEST:
x1 = 0;
x2 = 3;
break;
case EAST:
x1 = 13;
x2 = 16;
break;
case NORTH:
z1 = 0;
z2 = 3;
break;
case SOUTH:
z1 = 13;
z2 = 16;
break;
}
// Constraint the stripe in the two directions perpendicular to a in case there
// has been a corner
// drawn in those directions. Since a corner is drawn if the three touching
// faces dont have adjacent
// crafting cube blocks, we'd have to check for a, side, and the perpendicular
// direction. But in this
// block, we've already checked for side (due to face culling) and a (see
// above).
Direction perpendicular = Platform.rotateAround(a, side);
for (Direction cornerCandidate : EnumSet.of(perpendicular, perpendicular.getOpposite())) {
if (!connections.contains(cornerCandidate)) {
// There's a cap in this direction
switch (cornerCandidate) {
case DOWN:
y1 = 3;
break;
case UP:
y2 = 13;
break;
case NORTH:
z1 = 3;
break;
case SOUTH:
z2 = 13;
break;
case WEST:
x1 = 3;
break;
case EAST:
x2 = 13;
break;
}
}
}
builder.addCube(x1, y1, z1, x2, y2, z2);
}
}
}
/**
* Adds a 3x3x3 corner cap to the cube builder if there are no adjacent crafting
* cubes on that corner.
*/
private void addCornerCap(CubeBuilder builder, EnumSet<Direction> connections, Direction side, Direction down,
Direction west, Direction north) {
if (connections.contains(down) || connections.contains(west) || connections.contains(north)) {
return;
}
// Only add faces for sides that can actually be seen (the outside of the cube)
if (side != down && side != west && side != north) {
return;
}
float x1 = (west == Direction.WEST ? 0 : 13);
float y1 = (down == Direction.DOWN ? 0 : 13);
float z1 = (north == Direction.NORTH ? 0 : 13);
float x2 = (west == Direction.WEST ? 3 : 16);
float y2 = (down == Direction.DOWN ? 3 : 16);
float z2 = (north == Direction.NORTH ? 3 : 16);
builder.addCube(x1, y1, z1, x2, y2, z2);
}
// Retrieve the cube connection state from the block state
// If none is present, just assume there are no adjacent crafting cube blocks
private static EnumSet<Direction> getConnections(IModelData modelData) {
if (!(modelData instanceof CraftingCubeModelData)) {
return EnumSet.noneOf(Direction.class);
}
return ((CraftingCubeModelData) modelData).getConnections();
}
protected abstract void addInnerCube(Direction facing, BlockState state, IModelData modelData, CubeBuilder builder,
float x1, float y1, float z1, float x2, float y2, float z2);
@Override
public boolean useAmbientOcclusion() {
return false;
}
@Override
public boolean hasDepth() {
return false;
}
@Override
public boolean isBuiltin() {
return false;
}
@Override
public Sprite getSprite() {
return this.ringCorner;
}
@Override
public boolean isSideLit() {
return false;
}
@Override
public ModelOverrideList getOverrides() {
return ModelOverrideList.EMPTY;
}
}
@@ -1,127 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.IModelTransform;
import net.minecraft.client.render.model.IUnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import appeng.block.crafting.AbstractCraftingUnitBlock;
import appeng.core.AppEng;
/**
* The built-in model for the connected texture crafting cube.
*/
class CraftingCubeModel implements IModelGeometry<CraftingCubeModel> {
private final static SpriteIdentifier RING_CORNER = texture("ring_corner");
private final static SpriteIdentifier RING_SIDE_HOR = texture("ring_side_hor");
private final static SpriteIdentifier RING_SIDE_VER = texture("ring_side_ver");
private final static SpriteIdentifier UNIT_BASE = texture("unit_base");
private final static SpriteIdentifier LIGHT_BASE = texture("light_base");
private final static SpriteIdentifier ACCELERATOR_LIGHT = texture("accelerator_light");
private final static SpriteIdentifier STORAGE_1K_LIGHT = texture("1k_storage_light");
private final static SpriteIdentifier STORAGE_4K_LIGHT = texture("4k_storage_light");
private final static SpriteIdentifier STORAGE_16K_LIGHT = texture("16k_storage_light");
private final static SpriteIdentifier STORAGE_64K_LIGHT = texture("64k_storage_light");
private final static SpriteIdentifier MONITOR_BASE = texture("monitor_base");
private final static SpriteIdentifier MONITOR_LIGHT_DARK = texture("monitor_light_dark");
private final static SpriteIdentifier MONITOR_LIGHT_MEDIUM = texture("monitor_light_medium");
private final static SpriteIdentifier MONITOR_LIGHT_BRIGHT = texture("monitor_light_bright");
private final AbstractCraftingUnitBlock.CraftingUnitType type;
CraftingCubeModel(AbstractCraftingUnitBlock.CraftingUnitType type) {
this.type = type;
}
@Override
public Collection<SpriteIdentifier> getTextures(IModelConfiguration owner,
Function<Identifier, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
return ImmutableList.of(RING_CORNER, RING_SIDE_HOR, RING_SIDE_VER, UNIT_BASE, LIGHT_BASE, ACCELERATOR_LIGHT,
STORAGE_1K_LIGHT, STORAGE_4K_LIGHT, STORAGE_16K_LIGHT, STORAGE_64K_LIGHT, MONITOR_BASE,
MONITOR_LIGHT_DARK, MONITOR_LIGHT_MEDIUM, MONITOR_LIGHT_BRIGHT);
}
@Override
public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
Function<SpriteIdentifier, Sprite> spriteGetter, IModelTransform modelTransform,
ModelOverrideList overrides, Identifier modelLocation) {
// Retrieve our textures and pass them on to the baked model
Sprite ringCorner = spriteGetter.apply(RING_CORNER);
Sprite ringSideHor = spriteGetter.apply(RING_SIDE_HOR);
Sprite ringSideVer = spriteGetter.apply(RING_SIDE_VER);
switch (this.type) {
case UNIT:
return new UnitBakedModel(ringCorner, ringSideHor, ringSideVer, spriteGetter.apply(UNIT_BASE));
case ACCELERATOR:
case STORAGE_1K:
case STORAGE_4K:
case STORAGE_16K:
case STORAGE_64K:
return new LightBakedModel(ringCorner, ringSideHor, ringSideVer, spriteGetter.apply(LIGHT_BASE),
getLightTexture(spriteGetter, this.type));
case MONITOR:
return new MonitorBakedModel(ringCorner, ringSideHor, ringSideVer, spriteGetter.apply(UNIT_BASE),
spriteGetter.apply(MONITOR_BASE), spriteGetter.apply(MONITOR_LIGHT_DARK),
spriteGetter.apply(MONITOR_LIGHT_MEDIUM), spriteGetter.apply(MONITOR_LIGHT_BRIGHT));
default:
throw new IllegalArgumentException("Unsupported crafting unit type: " + this.type);
}
}
private static Sprite getLightTexture(Function<SpriteIdentifier, Sprite> textureGetter,
AbstractCraftingUnitBlock.CraftingUnitType type) {
switch (type) {
case ACCELERATOR:
return textureGetter.apply(ACCELERATOR_LIGHT);
case STORAGE_1K:
return textureGetter.apply(STORAGE_1K_LIGHT);
case STORAGE_4K:
return textureGetter.apply(STORAGE_4K_LIGHT);
case STORAGE_16K:
return textureGetter.apply(STORAGE_16K_LIGHT);
case STORAGE_64K:
return textureGetter.apply(STORAGE_64K_LIGHT);
default:
throw new IllegalArgumentException("Crafting unit type " + type + " does not use a light texture.");
}
}
private static SpriteIdentifier texture(String name) {
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
new Identifier(AppEng.MOD_ID, "block/crafting/" + name));
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.minecraft.resources.IResourceManager;
import net.minecraftforge.client.model.IModelLoader;
import appeng.block.crafting.AbstractCraftingUnitBlock;
/**
* Loader that allows access to the built-in crafting cube model from
* block-model JSONs.
*/
public class CraftingCubeModelLoader implements IModelLoader<CraftingCubeModel> {
public static final CraftingCubeModelLoader INSTANCE = new CraftingCubeModelLoader();
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
@Override
public CraftingCubeModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
AbstractCraftingUnitBlock.CraftingUnitType unitType = null;
JsonElement typeEl = modelContents.get("type");
if (typeEl != null) {
String typeName = deserializationContext.deserialize(typeEl, String.class);
if (typeName != null) {
unitType = AbstractCraftingUnitBlock.CraftingUnitType.valueOf(typeName.toUpperCase());
}
}
if (unitType == null) {
throw new JsonParseException("type property is missing");
}
return new CraftingCubeModel(unitType);
}
}
@@ -1,40 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.RenderLayer;
import net.fabricmc.api.EnvType;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
/**
* Rendering customization for the crafting cube.
*/
public class CraftingCubeRendering extends BlockRenderingCustomizer {
@Override
@Environment(EnvType.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderLayer.getCutout());
// Disable auto-rotation
rendering.modelCustomizer((loc, model) -> model);
}
}
@@ -1,64 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import net.fabricmc.api.Environment;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.util.math.Direction;
import net.fabricmc.api.EnvType;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.render.TesrRenderHelper;
import appeng.tile.crafting.CraftingMonitorBlockEntity;
/**
* Renders the item currently being crafted
*/
@Environment(EnvType.CLIENT)
public class CraftingMonitorTESR extends BlockEntityRenderer<CraftingMonitorBlockEntity> {
public CraftingMonitorTESR(BlockEntityRenderDispatcher rendererDispatcherIn) {
super(rendererDispatcherIn);
}
@Override
public void render(CraftingMonitorBlockEntity te, float partialTicks, MatrixStack matrixStack,
VertexConsumerProvider buffers, int combinedLight, int combinedOverlay) {
Direction facing = te.getForward();
IAEItemStack jobProgress = te.getJobProgress();
if (jobProgress != null) {
matrixStack.push();
matrixStack.translate(0.5, 0.5, 0.5); // Move to the center of the block
TesrRenderHelper.rotateToFace(matrixStack, facing, (byte) 0);
matrixStack.translate(0, 0.08, 0.5);
TesrRenderHelper.renderItem2dWithAmount(matrixStack, buffers, jobProgress, 0.3f, -0.18f, 15728880,
combinedOverlay);
matrixStack.pop();
}
}
}
@@ -1,134 +0,0 @@
package appeng.client.render.crafting;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.AffineTransformation;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.client.model.PerspectiveMapWrapper;
import appeng.client.render.DelegateBakedModel;
import appeng.items.misc.EncodedPatternItem;
/**
* This model is used to substitute the crafting result's item model for our
* encoded pattern model if these two conditions are met: - The player is
* holding shift - The itemstack is being rendered in the UI (not on the ground,
* etc.)
*
* We do this by abusing a custom {@link ModelOverrideList} since it will be
* called each frame with the itemstack that is about to be rendered. We return
* a custom IBakedModel ({@link ShiftHoldingModelWrapper} if the player is
* holding down shift from the override list. This custom baked model implements
* {@link #doesHandlePerspectives()} and returns the crafting result model if
* the model for {@link ModelTransformation.Mode#GUI} is requested.
*/
public class EncodedPatternBakedModel extends DelegateBakedModel {
private final CustomOverrideList overrides;
EncodedPatternBakedModel(BakedModel baseModel) {
super(baseModel);
this.overrides = new CustomOverrideList();
}
@Override
public ModelOverrideList getOverrides() {
return this.overrides;
}
/**
* Since the ItemOverrideList handling comes before handling the perspective
* awareness (which is the first place where we know how we are being rendered)
* we need to remember the model of the crafting output, and make the decision
* on which to render later on. Sadly, Forge is pretty inconsistent when it will
* call the handlePerspective method, so some methods are called even on this
* interim-model. Usually those methods only matter for rendering on the ground
* and other cases, where we wouldn't render the crafting output model anyway,
* so in those cases we delegate to the model of the encoded pattern.
*/
private static class ShiftHoldingModelWrapper extends DelegateBakedModel {
private final BakedModel outputModel;
private ShiftHoldingModelWrapper(BakedModel patternModel, BakedModel outputModel) {
super(patternModel);
this.outputModel = outputModel;
}
@Override
public boolean doesHandlePerspectives() {
return true;
}
@Override
public BakedModel handlePerspective(ModelTransformation.Mode cameraTransformType, MatrixStack mat) {
// No need to re-check for shift being held since this model is only handed out
// in that case
if (cameraTransformType == ModelTransformation.Mode.GUI) {
ImmutableMap<ModelTransformation.Mode, AffineTransformation> transforms = PerspectiveMapWrapper
.getTransforms(outputModel.getTransformation());
return PerspectiveMapWrapper.handlePerspective(this.outputModel, transforms, cameraTransformType, mat);
} else {
return getBaseModel().handlePerspective(cameraTransformType, mat);
}
}
// This determines diffuse lighting in the UI, and since we want to render
// the outputModel in the UI, we need to use it's setting here
@Override
public boolean isSideLit() {
return outputModel.isSideLit();
}
}
@Override
public boolean doesHandlePerspectives() {
return true;
}
@Override
public BakedModel handlePerspective(ModelTransformation.Mode cameraTransformType, MatrixStack mat) {
return getBaseModel().handlePerspective(cameraTransformType, mat);
}
/**
* Item Override Lists are the only point during item rendering where we can
* access the item stack that is being rendered. So this is the point where we
* actually check if shift is being held, and if so, determine the crafting
* output model.
*/
private class CustomOverrideList extends ModelOverrideList {
@Nullable
@Override
public BakedModel getModelWithOverrides(BakedModel originalModel, ItemStack stack, @Nullable World world,
@Nullable LivingEntity entity) {
boolean shiftHeld = Screen.hasShiftDown();
if (shiftHeld && world != null) {
EncodedPatternItem iep = (EncodedPatternItem) stack.getItem();
ItemStack output = iep.getOutput(world, stack);
if (!output.isEmpty()) {
BakedModel realModel = MinecraftClient.getInstance().getItemRenderer().getItemModelMesher()
.getItemModel(output);
// Give the item model a chance to handle the overrides as well
realModel = realModel.getOverrides().getModelWithOverrides(realModel, output, world, entity);
return new ShiftHoldingModelWrapper(getBaseModel(), realModel);
}
}
return getBaseModel().getOverrides().getModelWithOverrides(originalModel, stack, world, entity);
}
}
}
@@ -1,45 +0,0 @@
package appeng.client.render.crafting;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.IModelTransform;
import net.minecraft.client.render.model.IUnbakedModel;
import net.minecraft.client.render.model.json.ModelOverrideList;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.render.model.ModelLoader;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.Identifier;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.geometry.IModelGeometry;
/**
* This model is used to provide the {@link EncodedPatternBakedModel}.
*/
public class EncodedPatternModel implements IModelGeometry<EncodedPatternModel> {
private final Identifier baseModel;
public EncodedPatternModel(Identifier baseModel) {
this.baseModel = baseModel;
}
@Override
public Collection<SpriteIdentifier> getTextures(IModelConfiguration owner,
Function<Identifier, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
return modelGetter.apply(baseModel).getTextures(modelGetter, missingTextureErrors);
}
@Override
public BakedModel bake(IModelConfiguration owner, ModelLoader bakery,
Function<SpriteIdentifier, Sprite> spriteGetter, IModelTransform modelTransform,
ModelOverrideList overrides, Identifier modelLocation) {
BakedModel baseModel = bakery.getBakedModel(this.baseModel, modelTransform, spriteGetter);
return new EncodedPatternBakedModel(baseModel);
}
}
@@ -1,30 +0,0 @@
package appeng.client.render.crafting;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraftforge.client.model.IModelLoader;
/**
* Provides our custom {@link EncodedPatternBakedModel encoded pattern item
* model}.
*/
public class EncodedPatternModelLoader implements IModelLoader<EncodedPatternModel> {
public static final EncodedPatternModelLoader INSTANCE = new EncodedPatternModelLoader();
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
@Override
public EncodedPatternModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
modelContents.remove("loader"); // Avoid recursion
Identifier baseModel = new Identifier(JsonHelper.getString(modelContents, "baseModel"));
return new EncodedPatternModel(baseModel);
}
}
@@ -1,58 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import net.minecraft.block.BlockState;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import appeng.block.crafting.AbstractCraftingUnitBlock;
import appeng.client.render.cablebus.CubeBuilder;
/**
* Crafting cube baked model that adds a full-bright light texture on top of a
* normal base texture onto the inner cube. The light texture is only drawn
* fullbright if the multiblock is currently powered.
*/
class LightBakedModel extends CraftingCubeBakedModel {
private final Sprite baseTexture;
private final Sprite lightTexture;
LightBakedModel(Sprite ringCorner, Sprite ringHor, Sprite ringVer,
Sprite baseTexture, Sprite lightTexture) {
super(ringCorner, ringHor, ringVer);
this.baseTexture = baseTexture;
this.lightTexture = lightTexture;
}
@Override
protected void addInnerCube(Direction facing, BlockState state, IModelData modelData, CubeBuilder builder, float x1,
float y1, float z1, float x2, float y2, float z2) {
builder.setTexture(this.baseTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
boolean powered = state.get(AbstractCraftingUnitBlock.POWERED);
builder.setRenderFullBright(powered);
builder.setTexture(this.lightTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
}
}
@@ -1,110 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import net.minecraft.block.BlockState;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import appeng.api.util.AEColor;
import appeng.block.crafting.CraftingMonitorBlock;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.client.render.model.AEModelData;
import appeng.tile.crafting.CraftingMonitorModelData;
/**
* The baked model for the crafting monitor. Please note that this model doesn't
* handle the item being displayed. That is handled by a TESR. Instead, this
* model adds 3 layered light textures using the [dark|medium|bright] color
* variants of the attached bus color. The textures are full-bright if the cube
* is powered.
*/
public class MonitorBakedModel extends CraftingCubeBakedModel {
private final Sprite chassisTexture;
private final Sprite baseTexture;
private final Sprite lightDarkTexture;
private final Sprite lightMediumTexture;
private final Sprite lightBrightTexture;
MonitorBakedModel(Sprite ringCorner, Sprite ringHor, Sprite ringVer,
Sprite chassisTexture, Sprite baseTexture, Sprite lightDarkTexture,
Sprite lightMediumTexture, Sprite lightBrightTexture) {
super(ringCorner, ringHor, ringVer);
this.chassisTexture = chassisTexture;
this.baseTexture = baseTexture;
this.lightDarkTexture = lightDarkTexture;
this.lightMediumTexture = lightMediumTexture;
this.lightBrightTexture = lightBrightTexture;
}
@Override
protected void addInnerCube(Direction side, BlockState state, IModelData modelData, CubeBuilder builder, float x1,
float y1, float z1, float x2, float y2, float z2) {
Direction forward = getForward(modelData);
// For sides other than the front, use the chassis texture
if (side != forward) {
builder.setTexture(this.chassisTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
return;
}
builder.setTexture(this.baseTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
// Now add the three layered light textures
AEColor color = getColor(modelData);
boolean powered = state.get(CraftingMonitorBlock.POWERED);
builder.setRenderFullBright(powered);
builder.setColorRGB(color.whiteVariant);
builder.setTexture(this.lightBrightTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
builder.setColorRGB(color.mediumVariant);
builder.setTexture(this.lightMediumTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
builder.setColorRGB(color.blackVariant);
builder.setTexture(this.lightDarkTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
}
private static AEColor getColor(IModelData modelData) {
if (modelData instanceof CraftingMonitorModelData) {
return ((CraftingMonitorModelData) modelData).getColor();
}
return AEColor.TRANSPARENT;
}
private static Direction getForward(IModelData modelData) {
if (modelData instanceof AEModelData) {
return ((AEModelData) modelData).getForward();
}
return Direction.NORTH;
}
}
@@ -1,47 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import net.minecraft.block.BlockState;
import net.minecraft.client.texture.Sprite;
import net.minecraft.util.math.Direction;
import appeng.client.render.cablebus.CubeBuilder;
/**
* A simple crafting unit model that uses an un-lit texture for the inner block.
*/
class UnitBakedModel extends CraftingCubeBakedModel {
private final Sprite unitTexture;
UnitBakedModel(Sprite ringCorner, Sprite ringHor, Sprite ringVer,
Sprite unitTexture) {
super(ringCorner, ringHor, ringVer);
this.unitTexture = unitTexture;
}
@Override
protected void addInnerCube(Direction facing, BlockState state, IModelData modelData, CubeBuilder builder, float x1,
float y1, float z1, float x2, float y2, float z2) {
builder.setTexture(this.unitTexture);
builder.addCube(x1, y1, z1, x2, y2, z2);
}
}