Merge remote-tracking branch 'origin/master' into fabric-1.16

# Conflicts:
#	build.gradle
#	gradle.properties
#	src/api/java/appeng/api/config/Upgrades.java
#	src/api/java/appeng/api/recipes/ResolverResult.java
#	src/main/java/appeng/block/AEBaseBlockItemChargeable.java
#	src/main/java/appeng/block/crafting/CraftingStorageItem.java
#	src/main/java/appeng/block/misc/ChargerBlock.java
#	src/main/java/appeng/block/networking/CableBusBlock.java
#	src/main/java/appeng/block/storage/ChestBlock.java
#	src/main/java/appeng/block/storage/DriveSlotCellType.java
#	src/main/java/appeng/capabilities/Capabilities.java
#	src/main/java/appeng/client/me/ItemRepo.java
#	src/main/java/appeng/client/render/cablebus/FacadeBuilder.java
#	src/main/java/appeng/client/render/effects/ChargedOreFX.java
#	src/main/java/appeng/client/render/effects/CraftingFx.java
#	src/main/java/appeng/client/render/effects/EnergyFx.java
#	src/main/java/appeng/client/render/effects/LightningArcFX.java
#	src/main/java/appeng/client/render/effects/LightningFX.java
#	src/main/java/appeng/client/render/effects/MatterCannonFX.java
#	src/main/java/appeng/client/render/effects/VibrantFX.java
#	src/main/java/appeng/client/render/spatial/SpatialPylonRendering.java
#	src/main/java/appeng/client/render/tesr/DriveLedTileEntityRenderer.java
#	src/main/java/appeng/container/AEBaseContainer.java
#	src/main/java/appeng/container/implementations/CellWorkbenchContainer.java
#	src/main/java/appeng/container/implementations/MolecularAssemblerContainer.java
#	src/main/java/appeng/container/implementations/PatternTermContainer.java
#	src/main/java/appeng/container/implementations/QuartzKnifeContainer.java
#	src/main/java/appeng/core/AEConfig.java
#	src/main/java/appeng/core/AEItemGroup.java
#	src/main/java/appeng/core/Api.java
#	src/main/java/appeng/core/AppEng.java
#	src/main/java/appeng/core/Registration.java
#	src/main/java/appeng/core/api/definitions/ApiBlocks.java
#	src/main/java/appeng/core/api/definitions/ApiParts.java
#	src/main/java/appeng/core/features/registries/MovableTileRegistry.java
#	src/main/java/appeng/core/features/registries/P2PTunnelRegistry.java
#	src/main/java/appeng/core/features/registries/WirelessRegistry.java
#	src/main/java/appeng/core/features/registries/WorldGenRegistry.java
#	src/main/java/appeng/core/features/registries/cell/BasicItemCellGuiHandler.java
#	src/main/java/appeng/core/sync/BasePacketHandler.java
#	src/main/java/appeng/core/sync/packets/ClickPacket.java
#	src/main/java/appeng/core/sync/packets/PatternSlotPacket.java
#	src/main/java/appeng/crafting/CraftingTreeProcess.java
#	src/main/java/appeng/debug/ReplicatorCardItem.java
#	src/main/java/appeng/entity/ChargedQuartzEntity.java
#	src/main/java/appeng/entity/SingularityEntity.java
#	src/main/java/appeng/entity/TinyTNTPrimedEntity.java
#	src/main/java/appeng/fluids/helper/DualityFluidInterface.java
#	src/main/java/appeng/fluids/helper/FluidCellConfig.java
#	src/main/java/appeng/fluids/parts/FluidFormationPlanePart.java
#	src/main/java/appeng/fluids/parts/FluidHandlerAdapter.java
#	src/main/java/appeng/forge/data/providers/IAE2DataProvider.java
#	src/main/java/appeng/forge/data/providers/recipes/SlabStairRecipes.java
#	src/main/java/appeng/helpers/CraftingPatternDetails.java
#	src/main/java/appeng/helpers/DualityInterface.java
#	src/main/java/appeng/helpers/WirelessTerminalGuiObject.java
#	src/main/java/appeng/hooks/IBlockTool.java
#	src/main/java/appeng/hooks/TickHandler.java
#	src/main/java/appeng/integration/modules/jei/CondenserCategory.java
#	src/main/java/appeng/integration/modules/jei/JEIPlugin.java
#	src/main/java/appeng/items/misc/EncodedPatternItem.java
#	src/main/java/appeng/items/parts/FacadeItem.java
#	src/main/java/appeng/items/parts/PartItem.java
#	src/main/java/appeng/items/storage/AbstractStorageCell.java
#	src/main/java/appeng/items/storage/CreativeStorageCellItem.java
#	src/main/java/appeng/items/tools/powered/ColorApplicatorItem.java
#	src/main/java/appeng/items/tools/powered/EntropyManipulatorItem.java
#	src/main/java/appeng/items/tools/powered/MatterCannonItem.java
#	src/main/java/appeng/items/tools/powered/WirelessTerminalItem.java
#	src/main/java/appeng/me/cluster/implementations/CraftingCPUCluster.java
#	src/main/java/appeng/me/storage/MEMonitorIFluidHandler.java
#	src/main/java/appeng/parts/PartPlacement.java
#	src/main/java/appeng/parts/automation/FormationPlanePart.java
#	src/main/java/appeng/parts/p2p/FluidP2PTunnelPart.java
#	src/main/java/appeng/parts/reporting/PatternTerminalPart.java
#	src/main/java/appeng/spatial/CachedPlane.java
#	src/main/java/appeng/spatial/StorageChunkGenerator.java
#	src/main/java/appeng/spatial/StorageHelper.java
#	src/main/java/appeng/tile/crafting/CraftingBlockEntity.java
#	src/main/java/appeng/tile/crafting/CraftingStorageBlockEntity.java
#	src/main/java/appeng/tile/crafting/MolecularAssemblerBlockEntity.java
#	src/main/java/appeng/tile/inventory/AppEngInternalAEInventory.java
#	src/main/java/appeng/tile/misc/ChargerBlockEntity.java
#	src/main/java/appeng/tile/misc/CondenserBlockEntity.java
#	src/main/java/appeng/tile/misc/InscriberBlockEntity.java
#	src/main/java/appeng/tile/misc/InscriberRecipes.java
#	src/main/java/appeng/tile/qnb/QuantumBridgeBlockEntity.java
#	src/main/java/appeng/tile/storage/ChestBlockEntity.java
#	src/main/java/appeng/tile/storage/DriveBlockEntity.java
#	src/main/java/appeng/util/Platform.java
#	src/main/java/team/chisel/ctm/api/IFacade.java
#	src/main/resources/assets/appliedenergistics2/models/block/chest/base.json
#	src/unported/java/appeng/client/render/FacadeItemModel.java
#	src/unported/java/appeng/client/render/model/DriveBakedModel.java
#	src/unported/java/appeng/client/render/model/DriveModel.java
#	src/unported/java/appeng/core/PluginLoader.java
This commit is contained in:
Sebastian Hartte
2020-07-18 01:45:43 +02:00
233 changed files with 2321 additions and 1937 deletions
@@ -8,7 +8,6 @@ import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.item.ItemStack;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IParts;
import appeng.client.gui.AEBaseScreen;
@@ -18,6 +17,7 @@ import appeng.container.implementations.CraftingTermContainer;
import appeng.container.implementations.MEMonitorableContainer;
import appeng.container.implementations.PatternTermContainer;
import appeng.container.implementations.WirelessTermContainer;
import appeng.core.Api;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.SwitchGuisPacket;
import appeng.helpers.IPriorityHost;
@@ -45,7 +45,7 @@ final class AESubScreen {
public AESubScreen(AEBaseScreen<?> gui, Object containerTarget) {
this.gui = gui;
final IDefinitions definitions = AEApi.instance().definitions();
final IDefinitions definitions = Api.instance().definitions();
final IParts parts = definitions.parts();
if (containerTarget instanceof ChestBlockEntity) {
@@ -34,13 +34,13 @@ import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.client.gui.AEBaseScreen;
import appeng.client.gui.widgets.Scrollbar;
import appeng.container.implementations.CraftConfirmContainer;
import appeng.core.Api;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -52,11 +52,11 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
private final int rows = 5;
private final IItemList<IAEItemStack> storage = AEApi.instance().storage()
private final IItemList<IAEItemStack> storage = Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final IItemList<IAEItemStack> pending = AEApi.instance().storage()
private final IItemList<IAEItemStack> pending = Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final IItemList<IAEItemStack> missing = AEApi.instance().storage()
private final IItemList<IAEItemStack> missing = Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createList();
private final List<IAEItemStack> visual = new ArrayList<>();
@@ -35,7 +35,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
@@ -48,6 +47,7 @@ import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.Scrollbar;
import appeng.container.implementations.CraftingCPUContainer;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.localization.GuiText;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.ConfigValuePacket;
@@ -80,11 +80,11 @@ public class CraftingCPUScreen<T extends CraftingCPUContainer> extends AEBaseScr
private static final int ITEMSTACK_LEFT_OFFSET = 9;
private static final int ITEMSTACK_TOP_OFFSET = 22;
private IItemList<IAEItemStack> storage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private IItemList<IAEItemStack> storage = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private IItemList<IAEItemStack> active = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private IItemList<IAEItemStack> active = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private IItemList<IAEItemStack> pending = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private IItemList<IAEItemStack> pending = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private List<IAEItemStack> visual = new ArrayList<>();
@@ -101,9 +101,9 @@ public class CraftingCPUScreen<T extends CraftingCPUContainer> extends AEBaseScr
}
public void clearItems() {
this.storage = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.active = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.pending = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.storage = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.active = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.pending = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createList();
this.visual = new ArrayList<>();
}
@@ -22,7 +22,6 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.config.FullnessMode;
import appeng.api.config.OperationMode;
import appeng.api.config.RedstoneMode;
@@ -31,6 +30,7 @@ import appeng.api.definitions.IDefinitions;
import appeng.client.gui.widgets.ServerSettingToggleButton;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.container.implementations.IOPortContainer;
import appeng.core.Api;
import appeng.core.localization.GuiText;
public class IOPortScreen extends UpgradeableScreen<IOPortContainer> {
@@ -79,7 +79,7 @@ public class IOPortScreen extends UpgradeableScreen<IOPortContainer> {
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY, float partialTicks) {
super.drawBG(matrices, offsetX, offsetY, mouseX, mouseY, partialTicks);
final IDefinitions definitions = AEApi.instance().definitions();
final IDefinitions definitions = Api.instance().definitions();
definitions.items().cell1k().maybeStack(1)
.ifPresent(cell1kStack -> this.drawItem(offsetX + 66 - 8, offsetY + 17, cell1kStack));
@@ -42,7 +42,6 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseScreen;
@@ -51,6 +50,7 @@ import appeng.client.gui.widgets.Scrollbar;
import appeng.client.me.ClientDCInternalInv;
import appeng.client.me.SlotDisconnected;
import appeng.container.implementations.InterfaceTerminalContainer;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
@@ -321,7 +321,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
final ItemStack parsedItemStack = ItemStack.fromTag(outTag.getCompound(i));
if (!parsedItemStack.isEmpty()) {
final String displayName = Platform.getItemDisplayName(AEApi.instance().storage()
final String displayName = Platform.getItemDisplayName(Api.instance().storage()
.getStorageChannel(IItemStorageChannel.class).createStack(parsedItemStack)).getString()
.toLowerCase();
if (displayName.contains(searchTerm)) {
@@ -29,7 +29,12 @@ import net.minecraft.screen.slot.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import appeng.api.config.*;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.TerminalStyle;
import appeng.api.config.ViewItems;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.api.implementations.tiles.IMEChest;
import appeng.api.implementations.tiles.IViewCellStorage;
@@ -38,7 +43,11 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseMEScreen;
import appeng.client.gui.widgets.*;
import appeng.client.gui.widgets.AETextField;
import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.Scrollbar;
import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton;
import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo;
import appeng.container.implementations.CraftingStatusContainer;
@@ -27,8 +27,6 @@ import javax.annotation.Nonnull;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.config.Settings;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.config.YesNo;
@@ -38,6 +36,7 @@ import appeng.api.storage.data.IItemList;
import appeng.client.gui.widgets.IScrollSource;
import appeng.client.gui.widgets.ISortSource;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.fluids.util.FluidSorters;
import appeng.util.Platform;
import appeng.util.prioritylist.IPartitionList;
@@ -48,8 +47,8 @@ import appeng.util.prioritylist.IPartitionList;
* @since rv6 22/05/2018
*/
public class FluidRepo {
private final IItemList<IAEFluidStack> list = AEApi.instance().storage()
.getStorageChannel(IFluidStorageChannel.class).createList();
private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)
.createList();
private final ArrayList<IAEFluidStack> view = new ArrayList<>();
private final IScrollSource src;
private final ISortSource sortSrc;
+2 -2
View File
@@ -28,7 +28,6 @@ import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import appeng.api.AEApi;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
@@ -39,6 +38,7 @@ import appeng.api.storage.data.IItemList;
import appeng.client.gui.widgets.IScrollSource;
import appeng.client.gui.widgets.ISortSource;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.integration.abstraction.ReiFacade;
import appeng.items.storage.ViewCellItem;
import appeng.util.ItemSorters;
@@ -47,7 +47,7 @@ import appeng.util.prioritylist.IPartitionList;
public class ItemRepo {
private final IItemList<IAEItemStack> list = AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)
private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
.createList();
private final ArrayList<IAEItemStack> view = new ArrayList<>();
private final IScrollSource src;
@@ -50,8 +50,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
import appeng.core.Api;
import appeng.parts.misc.CableAnchorPart;
/**
* The FacadeBuilder builds for facades..
@@ -99,7 +99,7 @@ public class FacadeBuilder {
RenderContext context, Function<Identifier, BakedModel> modelLookup) {
//FIXME BakedPipeline pipeline = this.pipelines.get();
//FIXME Quad collectorQuad = this.collectors.get();
boolean transparent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
boolean transparent = Api.instance().partHelper().getCableRenderMode().transparentFacades;
Map<Direction, FacadeRenderState> facadeStates = renderState.getFacades();
List<Box> partBoxes = renderState.getBoundingBoxes();
Set<Direction> sidesWithParts = renderState.getAttachments().keySet();
@@ -22,7 +22,11 @@ import net.minecraft.client.render.VertexConsumer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.*;
import net.minecraft.client.particle.IAnimatedSprite;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.SpriteTexturedParticle;
import net.minecraft.client.render.Camera;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.math.MathHelper;
@@ -0,0 +1,106 @@
package appeng.client.render.tesr;
import java.util.EnumMap;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import appeng.api.implementations.tiles.IChestOrDrive;
import appeng.block.storage.DriveSlotState;
/**
* Utility class to render LEDs for storage cells from a Tile Entity Renderer.
*/
class CellLedRenderer {
private static final EnumMap<DriveSlotState, Vector3f> STATE_COLORS;
// Color used for the cell indicator for blinking during recent activity
private static final Vector3f BLINK_COLOR = new Vector3f(1, 0.5f, 0.5f);
static {
STATE_COLORS = new EnumMap<>(DriveSlotState.class);
STATE_COLORS.put(DriveSlotState.OFFLINE, new Vector3f(0, 0, 0));
STATE_COLORS.put(DriveSlotState.ONLINE, new Vector3f(0, 1, 0));
STATE_COLORS.put(DriveSlotState.NOT_EMPTY, new Vector3f(0f, 0.667f, 1));
STATE_COLORS.put(DriveSlotState.TYPES_FULL, new Vector3f(1, 0.667f, 0));
STATE_COLORS.put(DriveSlotState.FULL, new Vector3f(1, 0, 0));
}
// The positions are based on the upper left slot in a drive
private static final float L = 5 / 16.f; // left (x-axis)
private static final float R = 4 / 16.f; // right (x-axis)
private static final float T = 1 / 16.f; // top (y-axis)
private static final float B = -0.001f / 16.f; // bottom (y-axis)
private static final float FR = -0.001f / 16.f; // front (z-axis)
private static final float BA = 0.499f / 16.f; // back (z-axis)
// Vertex data for the LED cuboid (has no back)
// Directions are when looking from the front onto the LED
private static final float[] LED_QUADS = {
// Front Face
R, T, FR, L, T, FR, L, B, FR, R, B, FR,
// Left Face
L, T, FR, L, T, BA, L, B, BA, L, B, FR,
// Right Face
R, T, BA, R, T, FR, R, B, FR, R, B, BA,
// Top Face
R, T, BA, L, T, BA, L, T, FR, R, T, FR,
// Bottom Face
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
public static final RenderType RENDER_LAYER = RenderType.makeType("ae_drive_leds",
DefaultVertexFormats.POSITION_COLOR, 7, 32565, false, true, RenderType.State.getBuilder().build(false));
public static void renderLed(IChestOrDrive drive, int slot, IVertexBuilder buffer, MatrixStack ms,
float partialTicks) {
Vector3f color = getColorForSlot(drive, slot, partialTicks);
if (color == null) {
return;
}
for (int i = 0; i < LED_QUADS.length; i += 3) {
float x = LED_QUADS[i];
float y = LED_QUADS[i + 1];
float z = LED_QUADS[i + 2];
buffer.pos(ms.getLast().getMatrix(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
.endVertex();
}
}
private static Vector3f getColorForSlot(IChestOrDrive drive, int slot, float partialTicks) {
DriveSlotState state = DriveSlotState.fromCellStatus(drive.getCellStatus(slot));
if (state == DriveSlotState.EMPTY) {
return null;
}
if (!drive.isPowered()) {
return STATE_COLORS.get(DriveSlotState.OFFLINE);
}
Vector3f col = STATE_COLORS.get(state);
if (drive.isCellBlinking(slot)) {
// 200 ms interval (100ms to get to red, then 100ms back)
long t = System.currentTimeMillis() % 200;
float f = (t - 100) / 200.0f + 0.5f;
f = easeInOutCubic(f);
col = col.copy();
col.lerp(BLINK_COLOR, f);
}
return col;
}
private static float easeInOutCubic(float x) {
return x < 0.5f ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
}
private CellLedRenderer() {
}
}
@@ -0,0 +1,154 @@
/*
* 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.tesr;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelRenderer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ModelManager;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import appeng.api.client.ICellModelRegistry;
import appeng.block.storage.DriveSlotsState;
import appeng.client.render.DelegateBakedModel;
import appeng.client.render.FacingToRotation;
import appeng.core.Api;
import appeng.tile.storage.ChestTileEntity;
/**
* The tile entity renderer for ME chests takes care of rendering the right
* model for the inserted cell, as well as the LED.
*/
public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity> {
private final ICellModelRegistry cellModelRegistry = Api.instance().client().cells();
private final ModelManager modelManager;
private final BlockModelRenderer blockRenderer;
public ChestTileEntityRenderer(TileEntityRendererDispatcher rendererDispatcherIn) {
super(rendererDispatcherIn);
Minecraft client = Minecraft.getInstance();
modelManager = client.getModelManager();
blockRenderer = client.getBlockRendererDispatcher().getBlockModelRenderer();
}
@Override
public void render(ChestTileEntity chest, float partialTicks, MatrixStack matrices, IRenderTypeBuffer buffers,
int combinedLight, int combinedOverlay) {
World world = chest.getWorld();
if (world == null) {
return;
}
DriveSlotsState driveSlotState = DriveSlotsState.fromChestOrDrive(chest);
Item cellItem = driveSlotState.getCell(0);
if (cellItem == null || cellItem == Items.AIR) {
return; // No cell inserted into chest
}
ResourceLocation cellModelLocation = cellModelRegistry.model(cellItem);
if (cellModelLocation == null) {
cellModelLocation = cellModelRegistry.getDefaultModel();
}
IBakedModel model = modelManager.getModel(cellModelLocation);
matrices.push();
matrices.translate(0.5, 0.5, 0.5);
FacingToRotation rotation = FacingToRotation.get(chest.getForward(), chest.getUp());
rotation.push(matrices);
matrices.translate(-0.5, -0.5, -0.5);
// The models are created for the top-left slot of the drive model,
// we need to move them into place for the slot on the ME chest
matrices.translate(5 / 16.0, 4 / 16.0, 0);
// Render the cell model as-if it was a block model
IVertexBuilder buffer = buffers.getBuffer(RenderType.getCutout());
// We "fake" the position here to make it use the light-value in front of the
// drive
FaceRotatingModel rotatedModel = new FaceRotatingModel(model, rotation);
blockRenderer.renderModel(world, rotatedModel, chest.getBlockState(), chest.getPos(), matrices, buffer, false,
new Random(), 0L, combinedOverlay, EmptyModelData.INSTANCE);
IVertexBuilder ledBuffer = buffers.getBuffer(CellLedRenderer.RENDER_LAYER);
CellLedRenderer.renderLed(chest, 0, ledBuffer, matrices, partialTicks);
matrices.pop();
}
/**
* The actual vertex data will be transformed using the matrix stack, but the
* faces will not be correctly rotated so the incorrect lighting data would be
* used to apply diffuse lighting and the lightmap texture.
*/
private static class FaceRotatingModel extends DelegateBakedModel {
private final FacingToRotation r;
protected FaceRotatingModel(IBakedModel base, FacingToRotation r) {
super(base);
this.r = r;
}
@Nonnull
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
@Nonnull IModelData extraData) {
if (side != null) {
side = r.rotate(side); // This fixes the incorrect lightmap position
}
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand, extraData));
for (int i = 0; i < quads.size(); i++) {
BakedQuad quad = quads.get(i);
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()),
quad.func_187508_a(), quad.shouldApplyDiffuseLighting()));
}
return quads;
}
}
}
@@ -1,7 +1,5 @@
package appeng.client.render.tesr;
import java.util.EnumMap;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexFormats;
@@ -14,8 +12,8 @@ import net.minecraft.client.util.math.Vector3f;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import appeng.block.storage.DriveSlotState;
import appeng.client.render.FacingToRotation;
import appeng.client.render.model.DriveBakedModel;
import appeng.tile.storage.DriveBlockEntity;
/**
@@ -24,46 +22,8 @@ import appeng.tile.storage.DriveBlockEntity;
@Environment(EnvType.CLIENT)
public class DriveLedTileEntityRenderer extends BlockEntityRenderer<DriveBlockEntity> {
private static final EnumMap<DriveSlotState, Vector3f> STATE_COLORS;
// Color used for the cell indicator for blinking during recent activity
private static final Vector3f BLINK_COLOR = new Vector3f(1, 0.5f, 0.5f);
static {
STATE_COLORS = new EnumMap<>(DriveSlotState.class);
STATE_COLORS.put(DriveSlotState.OFFLINE, new Vector3f(0, 0, 0));
STATE_COLORS.put(DriveSlotState.ONLINE, new Vector3f(0, 1, 0));
STATE_COLORS.put(DriveSlotState.NOT_EMPTY, new Vector3f(0f, 0.667f, 1));
STATE_COLORS.put(DriveSlotState.TYPES_FULL, new Vector3f(1, 0.667f, 0));
STATE_COLORS.put(DriveSlotState.FULL, new Vector3f(1, 0, 0));
}
private static final float L = 14 / 16.f; // left (x-axis)
private static final float R = 13 / 16.f; // right (x-axis)
private static final float T = 14 / 16.f; // top (x-axis)
private static final float B = 12.999f / 16.f; // bottom (x-axis)
private static final float FR = 0.999f / 16.f; // front (z-axis)
private static final float BA = 1.499f / 16.f; // back (z-axis)
// Vertex data for the LED cuboid (has no back)
// Directions are when looking from the front onto the LED
private static final float[] LED_QUADS = {
// Front Face
R, T, FR, L, T, FR, L, B, FR, R, B, FR,
// Left Face
L, T, FR, L, T, BA, L, B, BA, L, B, FR,
// Right Face
R, T, BA, R, T, FR, R, B, FR, R, B, BA,
// Top Face
R, T, BA, L, T, BA, L, T, FR, R, T, FR,
// Bottom Face
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
private static final RenderLayer STATE = RenderLayer.of("ae_drive_leds", VertexFormats.POSITION_COLOR, 7,
32565, false, true, RenderLayer.MultiPhaseParameters.builder().build(false));
public DriveLedTileEntityRenderer(BlockEntityRenderDispatcher rendererDispatcherIn) {
super(rendererDispatcherIn);
public DriveLedTileEntityRenderer(BlockEntityRendererDispatcher rendererDispatcher) {
super(rendererDispatcher);
}
@Override
@@ -79,32 +39,18 @@ public class DriveLedTileEntityRenderer extends BlockEntityRenderer<DriveBlockEn
FacingToRotation.get(drive.getForward(), drive.getUp()).push(ms);
ms.translate(-0.5, -0.5, -0.5);
VertexConsumer buffer = buffers.getBuffer(STATE);
VertexConsumer buffer = buffers.getBuffer(CellLedRenderer.RENDER_LAYER);
Vector3f slotTranslation = new Vector3f();
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 2; col++) {
int slot = row * 2 + col;
Vector3f color = getColorForSlot(drive, slot, partialTicks);
if (color == null) {
continue;
}
ms.push();
// Position this drive model copy at the correct slot. The transform is based on
// the
// cell-model being in slot 0,0 at the top left of the drive.
float xOffset = -col * 8 / 16.0f;
float yOffset = -row * 3 / 16.0f;
ms.translate(xOffset, yOffset, 0);
DriveBakedModel.getSlotOrigin(row, col, slotTranslation);
ms.translate(slotTranslation.getX(), slotTranslation.getY(), slotTranslation.getZ());
for (int i = 0; i < LED_QUADS.length; i += 3) {
float x = LED_QUADS[i];
float y = LED_QUADS[i + 1];
float z = LED_QUADS[i + 2];
buffer.vertex(ms.peek().getModel(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
.next();
}
int slot = row * 2 + col;
CellLedRenderer.renderLed(drive, slot, buffer, ms, partialTicks);
ms.pop();
}
@@ -113,31 +59,4 @@ public class DriveLedTileEntityRenderer extends BlockEntityRenderer<DriveBlockEn
ms.pop();
}
private Vector3f getColorForSlot(DriveBlockEntity drive, int slot, float partialTicks) {
DriveSlotState state = DriveSlotState.fromCellStatus(drive.getCellStatus(slot));
if (state == DriveSlotState.EMPTY) {
return null;
}
if (!drive.isPowered()) {
return STATE_COLORS.get(DriveSlotState.OFFLINE);
}
Vector3f col = STATE_COLORS.get(state);
if (drive.isCellBlinking(slot)) {
// 200 ms interval (100ms to get to red, then 100ms back)
long t = System.currentTimeMillis() % 200;
float f = (t - 100) / 200.0f + 0.5f;
f = easeInOutCubic(f);
col = col.copy();
col.lerp(BLINK_COLOR, f);
}
return col;
}
private static float easeInOutCubic(float x) {
return x < 0.5f ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
}
}