Compare commits

...

39 Commits

Author SHA1 Message Date
Sebastian Hartte 5efc085693 Fix tiles that have a "powered" block state from not being able to be broken when
they are connected to a powered grid.
2020-08-24 23:54:37 +02:00
Sebastian Hartte aff94cec8c Fix search box interactions in the interface terminal. 2020-08-24 22:33:04 +02:00
Sebastian Hartte 2184d03d0b Actually save the rotation when a tile is rotated. 2020-08-24 01:06:26 +02:00
Sebastian Hartte 44c0931c02 Fixes #4635: Actually remove requesters when removing requesters. 2020-08-23 20:47:05 +02:00
yueh 423ab81813 Added step to publish to modmaven (#4607)
(cherry picked from commit 7e1bfdb5ac)
2020-08-21 20:40:03 +02:00
shartte 4e42b17e81 Fixes #4590: Crystal seeds (other than certus) don't display their growth stages. (#4618) 2020-08-19 16:43:45 +02:00
shartte fc0f8eab56 Fixes #4611: Use of client-side only method for Tiny TNT explosion. (#4612) 2020-08-18 01:33:47 +02:00
shartte 41b7900706 Fixes #4598: Incorrectly rotated face for determining block lightlevel in ME Chest renderer. (#4599) (#4609)
(cherry picked from commit 954ce1442e)
2020-08-17 21:58:51 +02:00
shartte 7656157b0d Fixes #4602: Prevent encoding invalid patterns and handle corrupted patterns a little more gracefully. (#4608) 2020-08-17 21:49:37 +02:00
Sebastian Hartte 87c2c94bd4 Use minus sign for minus buttons in number widget. 2020-08-11 16:31:20 +02:00
yueh d591a1492c Fixes #4583: Confine fluix crafting into the same block (#4586)
Fluix crystals will now spawn within an area around the center of the block as well as some tuned down motion while still maintaining some randomness.
2020-08-10 11:30:04 +02:00
shartte d1ba26311b One Spatial Dimension (#4570)
* Ported the "one spatial dimension" concept from pre-1.15

* Apply lighting updates after moving chunks.
Mark world data as dirty when changing it.

* Consolidated naming of spatial storage world/dimension.
Use server light manager to update lighting info in chunk.

* Save last transition information,
and add ae2 spatial command to interact with spatial storage.

* Formatting fixes.

* Improved docs for the origin generation.

Inverted condition on when the x/z axis are flipped.
Also added a helper to map a plot to a region file

* Remove TransitionResult since it's only used in lieu of a boolean.
Rework transition to make the checks BEFORE allocating a new cell.

* Removed unused imports.

Co-authored-by: yueh <yueh@users.noreply.github.com>
2020-08-10 11:29:07 +02:00
shartte 8733c2c11f Fix Special Model Registration (#4577)
* Fixes #4575 by updating Forge (ModelRegistryEvent is a modbus event but was misflagged as not being one). And update Forge because their breaking change breaks our mod.

* Update gradle.properties

Co-authored-by: yueh <yueh@users.noreply.github.com>

* Update src/main/resources/META-INF/mods.toml

Co-authored-by: yueh <yueh@users.noreply.github.com>

Co-authored-by: yueh <yueh@users.noreply.github.com>
2020-08-10 11:25:26 +02:00
yueh 4230fc7325 Fixes #4576: Append the amount to each button (#4580) 2020-08-09 13:23:24 +02:00
shartte 484af8baf3 Fixes #4574 by referencing only non-pure fluix crystals in the fluix dust grinder recipe. (#4578) 2020-08-09 12:24:42 +02:00
shartte 9456f639d4 Simplify "unlit" quad loading and move to Mixins (#4569)
* Simplified the UV loader concept: We only need it to make quads "unlit" which means that the lighting system is not applied to them. They always render at their full brightness.

* More documentation and slight cleanups.
2020-08-09 01:27:19 +02:00
shartte fe753c540b Fixes #4571: When not used for displaying localized text, specify Locale.ROOT for toLowerCase/toUpperCase to avoid issues with locale-specific non-ASCII lowercase conversions for ASCII uppercase characters (i.e. turkish lowercase i for uppercase I). (#4573) 2020-08-08 14:56:51 +02:00
Sebastian Hartte 2fabab3a6a Fix AO lighting for faces not fully snapped to block edges. 2020-08-08 02:20:40 +02:00
shartte 6f39bd8fe8 Move the nether quartz dust tag to the forge namespace and use it instead of AE's internal one. (#4568) 2020-08-07 23:13:02 +02:00
yueh c7d3877129 Use the declared power drain for p2p tunnels (#4567) 2020-08-06 20:07:40 +02:00
Sebastian Hartte 822249dda8 Added missing @Override annotations. 2020-08-05 22:11:00 +02:00
yueh 1404806d3d Fixes #4559: Use visual bounding box for overlay (#4561) 2020-08-05 21:52:34 +02:00
yueh 12e3fa9127 Makes formation planes a bit more consistent and less violent. (#4553)
* Makes formation planes a bit more consistent and less violent.

Items will now have a slower speed when spawning as well as a narrower area to avoid having them glitch into a wall and be teleported around

* Removed debug output, added clarifying parenthesis and extracted method.

* Fixes various other issues with the formation plane

Also removed now useless code

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-08-05 17:56:42 +02:00
shartte 8617dc8340 Plane Connection Refactor (#4556)
* Refactors all plane parts to use a common helper for
calculating connections to adjacent planes.
Also fixes problems with updating these connections on neighbor updates.

* Fix conflicting GuiSync ID.

* Slightly refactor PlaneConnectionHelper, and fix an issue where the bounding box was calculated incorrectly by using the wrong up-direction.
2020-08-05 17:45:33 +02:00
shartte 9bc844738c Fixes #4547: Name clash between ITooltip#getWidth, ITooltip#getHeight and Vanilla Widget methods leads to missing methods at runtime, since the implementing methods will be remapped to SRG names, while referees of the interface will try to call the renamed methods by their name in the interface, leading to an AbstractMethodError. (#4557) 2020-08-05 16:33:44 +02:00
Sebastian Hartte eab6483bd7 Fixes #4551: Bounding box of annihilation planes is too small. 2020-08-05 00:54:26 +02:00
yueh 7ca9405c8b Apply the FE tunnel behaviour to the fluid tunnel (#4550) 2020-08-04 17:57:59 +02:00
yueh 39959145a3 Revert "Apply the FE tunnel behaviour to the fluid tunnel (#4545)" (#4549)
This reverts commit 22f552217f.
2020-08-04 08:45:10 +02:00
yueh 22f552217f Apply the FE tunnel behaviour to the fluid tunnel (#4545)
* Apply the FE tunnel behaviour to the fluid tunnel

* Make a second pass to try and get all the requested fill amount sent out to outputs.

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-08-03 21:39:34 +02:00
yueh 8f0e408772 Fixes NPE on empty tooltips (#4546) 2020-08-03 20:57:10 +02:00
Sebastian Hartte 62bbc32763 Minor cleanup. 2020-08-03 20:31:30 +02:00
shartte 872d8d33cb Clean up global state for cable render mode (#4539)
* Clean up the global state used to hack part interaction into respecting
the player's facade render mode. Make the name more indicative of
what is actually happening.

* Fun.
2020-08-03 14:46:39 +02:00
shartte 1801302d8f Fix SkyStone chest model issues that I had introduced back in 1.8. (#4542)
This makes the chest 1 pixel higher to restore the look it had in 1.7.
Since the skystone chest's texture is a grungy mess, only the most
obvious texture problems were fixed, while for the skystone block chest,
the look should be close to what it was now.
Also introduces caching for the skystone chest's block shape.
2020-08-03 14:46:23 +02:00
Sebastian Hartte a85ffec9f9 Unified Parameter-Names for Slots 2020-08-02 22:12:08 +02:00
Sebastian Hartte 5fca946ef3 The lambda has to be replaced with an explicit method to annotate it with @OnlyIn. 2020-08-02 15:45:15 +02:00
Sebastian Hartte f8446209ce Move CraftingMonitor rendering customization out to its own class to circumvent issues with a client-side only lambda method being generated in a common-side class. 2020-08-02 15:40:50 +02:00
Sebastian Hartte 088627aedf Remove client-only methods from ChargerBlock which could potentially create synthetic lambda methods that reference client-only classes (and are not stripped). 2020-08-02 15:13:20 +02:00
shartte c8d08f9726 Fixes sidedness issues that cropped up with 1.16 (#4533) 2020-08-01 22:16:57 +02:00
yueh 259d932946 Fixes 4529: Updated IPart to match new ICapabilityProvider (#4534) 2020-08-01 21:01:19 +02:00
205 changed files with 2744 additions and 2914 deletions
+9 -1
View File
@@ -55,7 +55,15 @@ jobs:
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew publish --no-daemon --max-workers 1
run: ./gradlew publishMavenPublicationToGitHubPackagesRepository --no-daemon --max-workers 1
- name: Publish to modmaven
env:
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
MODMAVEN_USER: ${{ secrets.MODMAVEN_USER }}
MODMAVEN_PASSWORD: ${{ secrets.MODMAVEN_PASSWORD }}
run: ./gradlew publishMavenPublicationToModmavenRepository --no-daemon --max-workers 1
- name: Prepare artifact metadata
id: prepare_artifact_metadata
run: |
+8
View File
@@ -205,5 +205,13 @@ publishing {
name = "GitHubPackages"
url = "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
}
maven {
credentials {
username System.getenv("MODMAVEN_USER")
password System.getenv("MODMAVEN_PASSWORD")
}
name = "modmaven"
url = "https://modmaven.k-4u.nl/artifactory/local-releases/"
}
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ artifact_basename=appliedenergistics2
minecraft_release=1.16
minecraft_version=1.16.1
mcp_mappings=20200723-1.16.1
forge_version=32.0.93
forge_version=32.0.108
#########################################################
# Provided APIs #
@@ -23,6 +23,8 @@
package appeng.api.config;
import java.util.Locale;
/**
* Represent the security systems basic permissions, these are not for
* anti-griefing, they are part of the mod as a gameplay feature.
@@ -58,7 +60,7 @@ public enum SecurityPermissions {
*/
SECURITY;
private final String translationKey = "gui.appliedenergistics2.security." + this.name().toLowerCase();
private final String translationKey = "gui.appliedenergistics2.security." + this.name().toLowerCase(Locale.ROOT);
public String getTranslatedName() {
return this.translationKey + ".name";
@@ -53,6 +53,8 @@ public interface ICraftingHelper {
* @param stack If null, a new item will be created to hold the encoded pattern.
* Otherwise the given item must already contains an encoded
* pattern that will be overwritten.
* @throws IllegalArgumentException If either in or out contain only empty
* ItemStacks.
* @return A new encoded pattern, or the given stack with the pattern encoded in
* it.
*/
@@ -73,6 +75,8 @@ public interface ICraftingHelper {
* operation by the ME system.
* @param allowSubstitutes Controls whether the ME system will allow the use of
* equivalent items to craft this recipe.
* @throws IllegalArgumentException If either in or out contain only empty
* ItemStacks.
*/
ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out,
boolean allowSubstitutes);
@@ -1,38 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.implementations;
/**
* Defines the result of performing a transition from the world into a storage
* cell, if its possible, and what the energy usage is.
*/
public class TransitionResult {
public final boolean success;
public final double energyUsage;
public TransitionResult(final boolean success, final double power) {
this.success = success;
this.energyUsage = power;
}
}
@@ -25,11 +25,8 @@ package appeng.api.implementations.items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.RegistryKey;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import appeng.api.implementations.TransitionResult;
import appeng.api.util.WorldCoord;
/**
@@ -52,13 +49,13 @@ public interface ISpatialStorageCell {
int getMaxStoredDim(ItemStack is);
/**
* get the currently stored Dimension id.
* get the currently stored spatial storage plot id.
*
* @param is spatial storage cell
*
* @return dimension id or -1
* @return plot id or -1
*/
RegistryKey<World> getStoredDimension(ItemStack is);
int getAllocatedPlotId(ItemStack is);
/**
* Perform a spatial swap with the contents of the cell, and the world.
@@ -69,7 +66,7 @@ public interface ISpatialStorageCell {
* @param max max coord
* @param playerId owner of current grid or -1
*
* @return result of transition
* @return success of transition
*/
TransitionResult doSpatialTransition(ItemStack is, ServerWorld w, WorldCoord min, WorldCoord max, int playerId);
boolean doSpatialTransition(ItemStack is, ServerWorld w, WorldCoord min, WorldCoord max, int playerId);
}
+5 -2
View File
@@ -50,6 +50,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import appeng.api.networking.IGridNode;
@@ -346,10 +347,12 @@ public interface IPart extends ICustomCableConnection {
* capabilities on the cable bus will be forwarded to parts on the appropriate
* side.
*
* @see TileEntity#getCapability(Capability, net.minecraft.util.Direction)
* @see CapabilityProvider#getCapability(Capability,
* net.minecraft.util.Direction)
*
* @return The capability or null.
* @return The capability
*/
@Nonnull
default <T> LazyOptional<T> getCapability(Capability<T> capabilityClass) {
return LazyOptional.empty();
}
@@ -1,51 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, 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.api.storage;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
public interface ISpatialDimension {
ServerWorld getWorld(RegistryKey<World> cellDim);
@Nullable
RegistryKey<World> createNewCellDimension(BlockPos capacity);
void deleteCellDimension(RegistryKey<World> cellDim);
boolean isCellDimension(RegistryKey<World> cellDim);
BlockPos getCellDimensionOrigin(RegistryKey<World> cellDim);
BlockPos getCellDimensionSize(RegistryKey<World> cellDim);
/**
* Adds a user-facing tooltip that describes this dimension so that a player can
* keep storage cells apart.
*/
void addCellDimensionTooltip(RegistryKey<World> cellDim, List<ITextComponent> lines);
}
@@ -23,10 +23,8 @@ import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World;
@@ -45,14 +43,6 @@ public class AEBaseBlockItemChargeable extends AEBaseBlockItem implements IAEIte
public AEBaseBlockItemChargeable(Block id, Properties props) {
super(id, props);
ItemModelsProperties.func_239418_a_(this, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> {
double curPower = getAECurrentPower(is);
double maxPower = getAEMaxPower(is);
return (int) Math.round(100 * curPower / maxPower);
});
}
@Override
@@ -0,0 +1,33 @@
package appeng.block.crafting;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
public class CraftingMonitorBlockRendering extends BlockRenderingCustomizer {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer(CraftingMonitorBlockRendering::customizeModel);
}
@OnlyIn(Dist.CLIENT)
private static IBakedModel customizeModel(ResourceLocation path, IBakedModel model) {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
}
}
@@ -19,18 +19,12 @@
package appeng.block.misc;
import java.util.Random;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
@@ -42,8 +36,6 @@ import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
@@ -52,8 +44,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.util.AEAxisAlignedBB;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.renderable.ItemRenderable;
import appeng.client.render.tesr.ModularTESR;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
@@ -175,15 +165,4 @@ public class ChargerBlock extends AEBaseTileBlock<ChargerTileEntity> {
return VoxelShapes.create(new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0));
}
@OnlyIn(Dist.CLIENT)
public static Function<TileEntityRendererDispatcher, TileEntityRenderer<ChargerTileEntity>> createTesr() {
return dispatcher -> new ModularTESR<>(dispatcher, new ItemRenderable<>(ChargerBlock::getRenderedItem));
}
@OnlyIn(Dist.CLIENT)
private static Pair<ItemStack, TransformationMatrix> getRenderedItem(ChargerTileEntity tile) {
TransformationMatrix transform = new TransformationMatrix(new Vector3f(0.5f, 0.375f, 0.5f), null, null, null);
return new ImmutablePair<>(tile.getInternalInventory().getStackInSlot(0), transform);
}
}
@@ -18,6 +18,8 @@
package appeng.block.networking;
import java.util.Locale;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
@@ -51,7 +53,7 @@ public class WirelessBlock extends AEBaseTileBlock<WirelessTileEntity> {
@Override
public String getString() {
return this.name().toLowerCase();
return this.name().toLowerCase(Locale.ROOT);
}
}
@@ -18,6 +18,9 @@
package appeng.block.storage;
import java.util.EnumMap;
import java.util.Map;
import javax.annotation.Nullable;
import net.minecraft.block.BlockRenderType;
@@ -47,7 +50,18 @@ public class SkyChestBlock extends AEBaseTileBlock<SkyChestTileEntity> {
private static final double AABB_OFFSET_BOTTOM = 0.00;
private static final double AABB_OFFSET_SIDES = 0.06;
private static final double AABB_OFFSET_TOP = 0.125;
private static final double AABB_OFFSET_TOP = 0.0625;
// Precomputed bounding boxes of the chest, sorted into the map by the UP
// direction
private static final Map<Direction, VoxelShape> SHAPES = new EnumMap<>(Direction.class);
static {
for (Direction up : Direction.values()) {
AxisAlignedBB aabb = computeAABB(up);
SHAPES.put(up, VoxelShapes.create(aabb));
}
}
public enum SkyChestType {
STONE, BLOCK
@@ -87,37 +101,30 @@ public class SkyChestBlock extends AEBaseTileBlock<SkyChestTileEntity> {
@Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
// TODO Cache this! It can't be that hard!
AxisAlignedBB aabb = computeAABB(worldIn, pos);
return VoxelShapes.create(aabb);
final SkyChestTileEntity sk = this.getTileEntity(worldIn, pos);
Direction up = sk != null ? sk.getUp() : Direction.UP;
return SHAPES.get(up);
}
private AxisAlignedBB computeAABB(final IBlockReader w, final BlockPos pos) {
final SkyChestTileEntity sk = this.getTileEntity(w, pos);
Direction o = Direction.UP;
if (sk != null) {
o = sk.getUp();
}
final double offsetX = o.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = o.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = o.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
private static AxisAlignedBB computeAABB(Direction up) {
final double offsetX = up.getXOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetY = up.getYOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
final double offsetZ = up.getZOffset() == 0 ? AABB_OFFSET_SIDES : 0.0;
// for x/z top and bottom is swapped
final double minX = Math.max(0.0,
offsetX + (o.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getXOffset() * AABB_OFFSET_TOP)));
offsetX + (up.getXOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getXOffset() * AABB_OFFSET_TOP)));
final double minY = Math.max(0.0,
offsetY + (o.getYOffset() < 0 ? AABB_OFFSET_TOP : (o.getYOffset() * AABB_OFFSET_BOTTOM)));
offsetY + (up.getYOffset() < 0 ? AABB_OFFSET_TOP : (up.getYOffset() * AABB_OFFSET_BOTTOM)));
final double minZ = Math.max(0.0,
offsetZ + (o.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getZOffset() * AABB_OFFSET_TOP)));
offsetZ + (up.getZOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getZOffset() * AABB_OFFSET_TOP)));
final double maxX = Math.min(1.0,
1.0 - offsetX - (o.getXOffset() < 0 ? AABB_OFFSET_TOP : (o.getXOffset() * AABB_OFFSET_BOTTOM)));
1.0 - offsetX - (up.getXOffset() < 0 ? AABB_OFFSET_TOP : (up.getXOffset() * AABB_OFFSET_BOTTOM)));
final double maxY = Math.min(1.0,
1.0 - offsetY - (o.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (o.getYOffset() * AABB_OFFSET_TOP)));
1.0 - offsetY - (up.getYOffset() < 0 ? AABB_OFFSET_BOTTOM : (up.getYOffset() * AABB_OFFSET_TOP)));
final double maxZ = Math.min(1.0,
1.0 - offsetZ - (o.getZOffset() < 0 ? AABB_OFFSET_TOP : (o.getZOffset() * AABB_OFFSET_BOTTOM)));
1.0 - offsetZ - (up.getZOffset() < 0 ? AABB_OFFSET_TOP : (up.getZOffset() * AABB_OFFSET_BOTTOM)));
return new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
}
@@ -31,6 +31,8 @@ import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -38,8 +40,10 @@ import appeng.api.definitions.IBlockDefinition;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlock;
import appeng.block.AEBaseBlockItem;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.block.AEBaseTileBlock;
import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.core.AEItemGroup;
@@ -149,6 +153,24 @@ class BlockDefinitionBuilder implements IBlockBuilder {
item.setRegistryName(AppEng.MOD_ID, this.registryName);
}
// Register the client-only item model property for chargeable items
if (item instanceof AEBaseBlockItemChargeable) {
AEBaseBlockItemChargeable chargeable = (AEBaseBlockItemChargeable) item;
this.factory.addBootstrapComponent(new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> {
double curPower = chargeable.getAECurrentPower(is);
double maxPower = chargeable.getAEMaxPower(is);
return (int) Math.round(100 * curPower / maxPower);
});
}
});
}
// Register the item and block with the game
this.factory.addBootstrapComponent((IBlockRegistrationComponent) (side, registry) -> registry.register(block));
if (item != null) {
+3 -1
View File
@@ -1,6 +1,8 @@
package appeng.client;
import java.util.Locale;
import org.lwjgl.glfw.GLFW;
public enum ActionKey {
@@ -13,7 +15,7 @@ public enum ActionKey {
}
public String getTranslationKey() {
return "key." + this.name().toLowerCase() + ".desc";
return "key." + this.name().toLowerCase(Locale.ROOT) + ".desc";
}
public int getDefaultKey() {
@@ -138,15 +138,15 @@ public class ClientHelper extends ServerHelper {
}
@Override
public CableRenderMode getRenderMode() {
public CableRenderMode getCableRenderMode() {
if (Platform.isServer()) {
return super.getRenderMode();
return super.getCableRenderMode();
}
final Minecraft mc = Minecraft.getInstance();
final PlayerEntity player = mc.player;
return this.renderModeForPlayer(player);
return this.getCableRenderModeForPlayer(player);
}
@Override
@@ -158,14 +158,14 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
protected void drawGuiSlot(MatrixStack matrixStack, CustomSlotWidget slot, int mouseX, int mouseY,
float partialTicks) {
if (slot.isSlotEnabled()) {
final int left = slot.xPos();
final int top = slot.yPos();
final int right = left + slot.getWidth();
final int bottom = top + slot.getHeight();
final int left = slot.getTooltipAreaX();
final int top = slot.getTooltipAreaY();
final int right = left + slot.getTooltipAreaWidth();
final int bottom = top + slot.getTooltipAreaHeight();
slot.drawContent(matrixStack, getMinecraft(), mouseX, mouseY, partialTicks);
if (this.isPointInRegion(left, top, slot.getWidth(), slot.getHeight(), mouseX, mouseY)
if (this.isPointInRegion(left, top, slot.getTooltipAreaWidth(), slot.getTooltipAreaHeight(), mouseX, mouseY)
&& slot.canClick(getPlayer())) {
RenderSystem.colorMask(true, true, true, false);
this.fillGradient(matrixStack, left, top, right, bottom, -2130706433, -2130706433);
@@ -175,26 +175,30 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
private void drawTooltip(MatrixStack matrixStack, ITooltip tooltip, int mouseX, int mouseY) {
final int x = tooltip.xPos(); // ((GuiImgButton) c).x;
int y = tooltip.yPos(); // ((GuiImgButton) c).y;
final int x = tooltip.getTooltipAreaX();
int y = tooltip.getTooltipAreaY();
if (x < mouseX && x + tooltip.getWidth() > mouseX && tooltip.isVisible()) {
if (y < mouseY && y + tooltip.getHeight() > mouseY) {
if (x < mouseX && x + tooltip.getTooltipAreaWidth() > mouseX && tooltip.isTooltipAreaVisible()) {
if (y < mouseY && y + tooltip.getTooltipAreaHeight() > mouseY) {
if (y < 15) {
y = 15;
}
final ITextComponent msg = tooltip.getMessage();
final ITextComponent msg = tooltip.getTooltipMessage();
this.drawTooltip(matrixStack, x + 11, y + 4, msg);
}
}
}
protected void drawTooltip(MatrixStack matrices, int x, int y, ITextComponent message) {
String[] lines = message.getString().split("\n"); // FIXME FABRIC
List<ITextComponent> textLines = Arrays.stream(lines).map(StringTextComponent::new)
.collect(Collectors.toList());
this.drawTooltip(matrices, x, y, textLines);
String tooltipText = message.getString();
if (!tooltipText.isEmpty()) {
String[] lines = tooltipText.split("\n"); // FIXME FABRIC
List<ITextComponent> textLines = Arrays.stream(lines).map(StringTextComponent::new)
.collect(Collectors.toList());
this.drawTooltip(matrices, x, y, textLines);
}
}
// FIXME FABRIC: move out to json (?)
@@ -281,8 +285,8 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
}
for (CustomSlotWidget slot : this.guiSlots) {
if (this.isPointInRegion(slot.xPos(), slot.yPos(), slot.getWidth(), slot.getHeight(), xCoord, yCoord)
&& slot.canClick(getPlayer())) {
if (this.isPointInRegion(slot.getTooltipAreaX(), slot.getTooltipAreaY(), slot.getTooltipAreaWidth(),
slot.getTooltipAreaHeight(), xCoord, yCoord) && slot.canClick(getPlayer())) {
slot.slotClicked(getPlayer().inventory.getItemStack(), btn);
}
}
@@ -90,7 +90,9 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
this.searchField.setMaxStringLength(25);
this.searchField.setTextColor(0xFFFFFF);
this.searchField.setVisible(true);
this.searchField.setFocused2(true);
this.searchField.setResponder(str -> this.refreshList());
this.addListener(this.searchField);
this.changeFocus(true);
}
@Override
@@ -131,11 +133,8 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
@Override
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
this.refreshList();
}
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
return true;
}
@@ -173,11 +172,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
if (character == ' ' && this.searchField.getText().isEmpty()) {
return true;
}
if (this.searchField.charTyped(character, key)) {
this.refreshList();
return true;
}
return false;
return super.charTyped(character, key);
}
@Override
@@ -245,7 +240,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
/**
* Rebuilds the list of interfaces.
*
* <p>
* Respects a search term if present (ignores case) and adding only matching
* patterns.
*/
@@ -338,12 +333,11 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
/**
* Tries to retrieve a cache for a with search term as keyword.
*
* <p>
* If this cache should be empty, it will populate it with an earlier cache if
* available or at least the cache for the empty string.
*
* @param searchTerm the corresponding search
*
* @return a Set matching a superset of the search term
*/
private Set<Object> getCacheForSearchTerm(final String searchTerm) {
@@ -1,5 +1,7 @@
package appeng.client.gui.implementations;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.LongConsumer;
@@ -24,7 +26,7 @@ import appeng.core.AEConfig;
public class NumberEntryWidget implements ITickingWidget {
private static final ITextComponent PLUS = new StringTextComponent("+");
private static final ITextComponent MINUS = new StringTextComponent("+");
private static final ITextComponent MINUS = new StringTextComponent("-");
private final AEBaseScreen<?> parent;
@@ -33,14 +35,7 @@ public class NumberEntryWidget implements ITickingWidget {
private final NumberBox level;
private final NumberEntryType type;
private Button plus1;
private Button plus10;
private Button plus100;
private Button plus1000;
private Button minus1;
private Button minus10;
private Button minus100;
private Button minus1000;
private List<Button> buttons;
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
LongConsumer changeListener) {
@@ -63,14 +58,7 @@ public class NumberEntryWidget implements ITickingWidget {
public void setActive(boolean active) {
this.level.setEnabled(active);
this.plus1.active = active;
this.plus10.active = active;
this.plus100.active = active;
this.plus1000.active = active;
this.minus1.active = active;
this.minus10.active = active;
this.minus100.active = active;
this.minus1000.active = active;
this.buttons.forEach(b -> b.active = active);
}
public void setTextFieldBounds(int x, int y, int width) {
@@ -93,18 +81,23 @@ public class NumberEntryWidget implements ITickingWidget {
int left = parent.getGuiLeft() + x;
int top = parent.getGuiTop() + y;
addButton.accept(this.plus1 = new Button(left, top, 22, 20, PLUS /* + a */, btn -> addQty(a)));
addButton.accept(this.plus10 = new Button(left + 28, top, 28, 20, PLUS /* + b */, btn -> addQty(b)));
addButton.accept(this.plus100 = new Button(left + 62, top, 32, 20, PLUS /* + c */, btn -> addQty(c)));
addButton.accept(this.plus1000 = new Button(left + 100, top, 38, 20, PLUS/* + d */, btn -> addQty(d)));
List<Button> buttons = new ArrayList<>(8);
buttons.add(new Button(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
buttons.add(new Button(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
buttons.add(new Button(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
buttons.add(new Button(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d)));
// Placing this here will give a sensible tab order
addChildren.accept(this.level);
addButton.accept(this.minus1 = new Button(left, top + 42, 22, 20, MINUS /* + a */, btn -> addQty(-a)));
addButton.accept(this.minus10 = new Button(left + 28, top + 42, 28, 20, MINUS /* + b */, btn -> addQty(-b)));
addButton.accept(this.minus100 = new Button(left + 62, top + 42, 32, 20, MINUS /* + c */, btn -> addQty(-c)));
addButton.accept(this.minus1000 = new Button(left + 100, top + 42, 38, 20, MINUS /* + d */, btn -> addQty(-d)));
buttons.add(new Button(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
buttons.add(new Button(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
buttons.add(new Button(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
buttons.add(new Button(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d)));
this.buttons = buttons;
this.buttons.forEach(addButton);
}
private void addQty(final long i) {
@@ -134,4 +127,8 @@ public class NumberEntryWidget implements ITickingWidget {
this.level.tick();
}
private ITextComponent makeLabel(ITextComponent prefix, int amount) {
return prefix.copyRaw().appendString(String.valueOf(amount));
}
}
@@ -27,7 +27,7 @@ import net.minecraft.util.text.StringTextComponent;
import appeng.api.config.ActionItems;
import appeng.core.localization.ButtonToolTips;
public class ActionButton extends IconButton implements ITooltip {
public class ActionButton extends IconButton {
private static final Pattern PATTERN_NEW_LINE = Pattern.compile("\\n", Pattern.LITERAL);
private final int iconIndex;
@@ -8,6 +8,7 @@ import net.minecraft.client.gui.AbstractGui;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
private final int x;
@@ -38,32 +39,32 @@ public abstract class CustomSlotWidget extends AbstractGui implements ITooltip {
}
@Override
public ITextComponent getMessage() {
return null;
public ITextComponent getTooltipMessage() {
return StringTextComponent.EMPTY;
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return 16;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return 16;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return false;
}
@@ -18,7 +18,10 @@
package appeng.client.gui.widgets;
import javax.annotation.Nonnull;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
/**
* AEBaseGui controlled Tooltip Interface.
@@ -26,42 +29,45 @@ import net.minecraft.util.text.ITextComponent;
public interface ITooltip {
/**
* returns the tooltip message.
* Returns the tooltip message.
*
* Should use {@link StringTextComponent#EMPTY} for no tooltip
*
* @return tooltip message
*/
ITextComponent getMessage();
@Nonnull
ITextComponent getTooltipMessage();
/**
* x Location for the object that triggers the tooltip.
*
* @return xPosition
*/
int xPos();
int getTooltipAreaX();
/**
* y Location for the object that triggers the tooltip.
*
* @return yPosition
*/
int yPos();
int getTooltipAreaY();
/**
* Width of the object that triggers the tooltip.
*
* @return width
*/
int getWidth();
int getTooltipAreaWidth();
/**
* Height for the object that triggers the tooltip.
*
* @return height
*/
int getHeight();
int getTooltipAreaHeight();
/**
* @return true if button being drawn
*/
boolean isVisible();
boolean isTooltipAreaVisible();
}
@@ -25,6 +25,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.fml.client.gui.GuiUtils;
@@ -97,27 +98,32 @@ public abstract class IconButton extends Button implements ITooltip {
protected abstract int getIconIndex();
@Override
public int xPos() {
public ITextComponent getTooltipMessage() {
return getMessage();
}
@Override
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return this.halfSize ? 8 : 16;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return this.halfSize ? 8 : 16;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return this.visible;
}
@@ -81,7 +81,7 @@ public class ProgressBar extends Widget implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
if (this.fullMsg != null) {
return this.fullMsg;
}
@@ -92,27 +92,27 @@ public class ProgressBar extends Widget implements ITooltip {
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x - 2;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y - 2;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return this.width + 4;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return this.height + 4;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -279,7 +279,7 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
ITextComponent displayName = null;
ITextComponent displayValue = null;
@@ -99,27 +99,32 @@ public class TabButton extends Button implements ITooltip {
}
@Override
public int xPos() {
public ITextComponent getTooltipMessage() {
return getMessage();
}
@Override
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return 22;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return 22;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return this.visible;
}
@@ -77,7 +77,7 @@ public class ToggleButton extends Button implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
if (this.displayName != null) {
String name = I18n.format(this.displayName);
String value = I18n.format(this.displayHint);
@@ -106,27 +106,27 @@ public class ToggleButton extends Button implements ITooltip {
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return 16;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return 16;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return this.visible;
}
}
@@ -29,13 +29,13 @@ public class SlotDisconnected extends AppEngSlot {
private final ClientDCInternalInv mySlot;
public SlotDisconnected(final ClientDCInternalInv me, final int which, final int x, final int y) {
super(me.getInventory(), which, x, y);
public SlotDisconnected(final ClientDCInternalInv me, final int invSlot, final int x, final int y) {
super(me.getInventory(), invSlot, x, y);
this.mySlot = me;
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -45,7 +45,7 @@ public class SlotDisconnected extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -18,6 +18,8 @@
package appeng.client.render;
import java.util.Locale;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.util.Direction;
@@ -111,6 +113,6 @@ public enum FacingToRotation implements IStringSerializable {
@Override
public String getString() {
return name().toLowerCase();
return name().toLowerCase(Locale.ROOT);
}
}
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
import java.util.function.Function;
import net.minecraft.client.renderer.model.BakedQuad;
@@ -100,7 +101,7 @@ class CableBuilder {
}
return new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, textureFolder + color.name().toLowerCase()));
new ResourceLocation(AppEng.MOD_ID, textureFolder + color.name().toLowerCase(Locale.ROOT)));
}
/**
@@ -19,6 +19,7 @@
package appeng.client.render.cablebus;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
@@ -74,7 +75,7 @@ public enum CableCoreType {
public RenderMaterial getTexture(AEColor color) {
return new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase()));
new ResourceLocation(AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase(Locale.ROOT)));
}
}
@@ -18,6 +18,8 @@
package appeng.client.render.crafting;
import java.util.Locale;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -48,7 +50,7 @@ public class CraftingCubeModelLoader implements IModelLoader<CraftingCubeModel>
if (typeEl != null) {
String typeName = deserializationContext.deserialize(typeEl, String.class);
if (typeName != null) {
unitType = AbstractCraftingUnitBlock.CraftingUnitType.valueOf(typeName.toUpperCase());
unitType = AbstractCraftingUnitBlock.CraftingUnitType.valueOf(typeName.toUpperCase(Locale.ROOT));
}
}
if (unitType == null) {
@@ -49,7 +49,7 @@ public class EnergyParticleData implements IParticleData {
reader.expect(' ');
boolean forItem = reader.readBoolean();
reader.expect(' ');
AEPartLocation direction = AEPartLocation.valueOf(reader.readString().toUpperCase());
AEPartLocation direction = AEPartLocation.valueOf(reader.readString().toUpperCase(Locale.ROOT));
return new EnergyParticleData(forItem, direction);
}
@@ -74,7 +74,8 @@ public class EnergyParticleData implements IParticleData {
@Override
public String getParameters() {
return String.format(Locale.ROOT, "%s %s", forItem ? "true" : "false", direction.name().toLowerCase());
return String.format(Locale.ROOT, "%s %s", forItem ? "true" : "false",
direction.name().toLowerCase(Locale.ROOT));
}
}
@@ -34,8 +34,6 @@ import com.google.common.collect.ImmutableList;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
@@ -193,7 +191,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
vec.setX(vec.getX() + 0.5f);
vec.setY(vec.getY() + 0.5f);
vec.setZ(vec.getZ() + 0.5f);
return new float[] { vec.getX(), vec.getY(), vec.getZ() };
return new float[] { snap(vec.getX()), snap(vec.getY()), snap(vec.getZ()) };
case 4:
Vector4f vecc = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
vecc.setX(vecc.getX() - 0.5f);
@@ -203,13 +201,32 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
vecc.setX(vecc.getX() + 0.5f);
vecc.setY(vecc.getY() + 0.5f);
vecc.setZ(vecc.getZ() + 0.5f);
return new float[] { vecc.getX(), vecc.getY(), vecc.getZ(), vecc.getW() };
return new float[] { snap(vecc.getX()), snap(vecc.getY()), snap(vecc.getZ()), snap(vecc.getW()) };
default:
return fs;
}
}
/**
* This is the same value used by Vanilla's AO lighter.
*/
private static final float EPS = 0.0001f;
/**
* This tries to snap the coordinate to the edges of the block frame, because
* Vanilla uses direct equals comparisons to 0 and 1 for checking if a face
* extends fully towards the edge. This is used primarily for AO calculations.
*/
private static float snap(float x) {
if (Math.abs(x) <= EPS) {
return 0f;
} else if (Math.abs(x - 1) <= EPS) {
return 1f;
}
return x;
}
private float[] transformNormal(float[] fs) {
if (this.face == null) {
switch (fs.length) {
@@ -220,7 +237,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
case 4:
Vector4f vec4 = new Vector4f(fs[0], fs[1], fs[2], fs[3]);
vec4.transform(this.f2r.getMat());
return new float[] { vec4.getX(), vec4.getY(), vec4.getZ(), 0 };
return new float[] { snap(vec4.getX()), snap(vec4.getY()), snap(vec4.getZ()), 0 };
default:
return fs;
@@ -1,210 +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.model;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.mojang.blaze3d.matrix.MatrixStack;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.BlockFaceUV;
import net.minecraft.client.renderer.model.BlockModel;
import net.minecraft.client.renderer.model.BlockPart;
import net.minecraft.client.renderer.model.BlockPartFace;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ItemOverride;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.model.ItemTransformVec3f;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.model.RenderMaterial;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.Direction;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraftforge.client.model.IModelBuilder;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
import net.minecraftforge.client.model.pipeline.VertexLighterFlat;
import net.minecraftforge.common.model.TransformationHelper;
public class UVLModelLoader implements IModelLoader<UVLModelLoader.UVLModelWrapper> {
public static final UVLModelLoader INSTANCE = new UVLModelLoader();
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {
}
@Override
public UVLModelWrapper read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
modelContents.remove("loader");
BlockModel blockModel = UVLSERIALIZER.fromJson(modelContents, BlockModel.class);
return new UVLModelWrapper(blockModel);
}
final Gson UVLSERIALIZER = (new GsonBuilder())
.registerTypeAdapter(BlockModel.class, new ModelLoaderRegistry.ExpandedBlockModelDeserializer())
.registerTypeAdapter(BlockPart.class, new BlockPart.Deserializer())
.registerTypeAdapter(BlockPartFace.class, new BlockPartFaceOverrideSerializer())
.registerTypeAdapter(BlockFaceUV.class, new BlockFaceUV.Deserializer())
.registerTypeAdapter(ItemTransformVec3f.class, new ItemTransformVec3f.Deserializer())
.registerTypeAdapter(ItemCameraTransforms.class, new ItemCameraTransforms.Deserializer())
.registerTypeAdapter(ItemOverride.class, new ItemOverride.Deserializer())
.registerTypeAdapter(TransformationMatrix.class, new TransformationHelper.Deserializer()).create();
private static class BlockPartFaceOverrideSerializer extends BlockPartFace.Deserializer {
@Override
public BlockPartFace deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_,
JsonDeserializationContext p_deserialize_3_) throws JsonParseException {
BlockPartFace blockFace = super.deserialize(p_deserialize_1_, p_deserialize_2_, p_deserialize_3_);
Pair<Float, Float> uvl = this.parseUVL(p_deserialize_1_.getAsJsonObject());
if (uvl != null) {
return new BlockPartFaceWithUVL(blockFace.cullFace, blockFace.tintIndex, blockFace.texture,
blockFace.blockFaceUV, uvl.getLeft(), uvl.getRight());
}
return blockFace;
}
protected Pair<Float, Float> parseUVL(JsonObject object) {
if (!object.has("uvlightmap")) {
return null;
}
object = object.get("uvlightmap").getAsJsonObject();
return new ImmutablePair<>(JSONUtils.getFloat(object, "sky", 0), JSONUtils.getFloat(object, "block", 0));
}
}
private static class BlockPartFaceWithUVL extends BlockPartFace {
private final float sky;
private final float block;
public BlockPartFaceWithUVL(@Nullable Direction cullFaceIn, int tintIndexIn, String textureIn,
BlockFaceUV blockFaceUVIn, float sky, float block) {
super(cullFaceIn, tintIndexIn, textureIn, blockFaceUVIn);
this.sky = sky;
this.block = block;
}
public float getSky() {
return sky;
}
public float getBlock() {
return block;
}
}
public static class UVLModelWrapper implements IModelGeometry<UVLModelWrapper> {
private final BlockModel parent;
public UVLModelWrapper(BlockModel parent) {
this.parent = parent;
}
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery,
Function<RenderMaterial, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform,
ItemOverrideList overrides, ResourceLocation modelLocation) {
TextureAtlasSprite particle = spriteGetter.apply(owner.resolveTexture("particle"));
IModelBuilder<?> builder = IModelBuilder.of(owner, overrides, particle);
for (BlockPart blockpart : parent.getElements()) {
for (Direction direction : blockpart.mapFaces.keySet()) {
BlockPartFace blockpartface = blockpart.mapFaces.get(direction);
TextureAtlasSprite textureatlassprite1 = spriteGetter
.apply(owner.resolveTexture(blockpartface.texture));
BakedQuad quad = BlockModel.makeBakedQuad(blockpart, blockpartface, textureatlassprite1, direction,
modelTransform, modelLocation);
if (blockpartface instanceof BlockPartFaceWithUVL) {
BlockPartFaceWithUVL uvlFace = (BlockPartFaceWithUVL) blockpartface;
quad = applyPreBakedLighting(quad, textureatlassprite1, uvlFace.sky, uvlFace.block);
}
if (blockpartface.cullFace == null) {
builder.addGeneralQuad(quad);
} else {
builder.addFaceQuad(modelTransform.getRotation().rotateTransform(blockpartface.cullFace), quad);
}
}
}
return builder.build();
}
private BakedQuad applyPreBakedLighting(BakedQuad quad, TextureAtlasSprite sprite, float sky, float block) {
// FIXME: just piping through the quads and manipulating uv index 2 directly
// seems way easier than this
BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
VertexLighterFlat trans = new VertexLighterFlat(Minecraft.getInstance().getBlockColors()) {
@Override
protected void updateLightmap(float[] normal, float[] lightmap, float x, float y, float z) {
lightmap[0] = block;
lightmap[1] = sky;
}
@Override
public void setQuadTint(int tint) {
// Tint requires a block state which we don't have at this point
}
};
MatrixStack identity = new MatrixStack();
trans.setTransform(identity.getLast());
trans.setParent(builder);
quad.pipe(trans);
builder.setQuadTint(quad.getTintIndex());
builder.setQuadOrientation(quad.getFace());
builder.setApplyDiffuseLighting(false);
return builder.build();
}
@Override
public Collection<RenderMaterial> getTextures(IModelConfiguration owner,
Function<ResourceLocation, IUnbakedModel> modelGetter,
Set<com.mojang.datafixers.util.Pair<String, String>> missingTextureErrors) {
return parent.getTextures(modelGetter, missingTextureErrors);
}
}
}
@@ -20,6 +20,7 @@ package appeng.client.render.spatial;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Stream;
@@ -59,7 +60,7 @@ public class SpatialPylonModel implements BasicUnbakedModel<SpatialPylonModel> {
private static RenderMaterial getTexturePath(SpatialPylonTextureType type) {
return new RenderMaterial(AtlasTexture.LOCATION_BLOCKS_TEXTURE,
new ResourceLocation(AppEng.MOD_ID, "block/spatial_pylon/" + type.name().toLowerCase()));
new ResourceLocation(AppEng.MOD_ID, "block/spatial_pylon/" + type.name().toLowerCase(Locale.ROOT)));
}
}
@@ -0,0 +1,30 @@
package appeng.client.render.tesr;
import java.util.function.Function;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.vector.TransformationMatrix;
import net.minecraft.util.math.vector.Vector3f;
import appeng.client.render.renderable.ItemRenderable;
import appeng.tile.misc.ChargerTileEntity;
public final class ChargerTESR {
private ChargerTESR() {
}
public static Function<TileEntityRendererDispatcher, TileEntityRenderer<ChargerTileEntity>> FACTORY = dispatcher -> new ModularTESR<>(
dispatcher, new ItemRenderable<>(ChargerTESR::getRenderedItem));
private static Pair<ItemStack, TransformationMatrix> getRenderedItem(ChargerTileEntity tile) {
TransformationMatrix transform = new TransformationMatrix(new Vector3f(0.5f, 0.375f, 0.5f), null, null, null);
return new ImmutablePair<>(tile.getInternalInventory().getStackInSlot(0), transform);
}
}
@@ -142,7 +142,7 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
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
side = r.resultingRotate(side); // This fixes the incorrect lightmap position
}
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand, extraData));
@@ -60,11 +60,11 @@ public class SkyChestTESR extends TileEntityRenderer<SkyChestTileEntity> {
this.singleBottom.addBox(1.0F, 0.0F, 1.0F, 14.0F, 10.0F, 14.0F, 0.0F);
this.singleLid = new ModelRenderer(64, 64, 0, 0);
this.singleLid.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
this.singleLid.rotationPointY = 9.0F;
this.singleLid.rotationPointY = 10.0F;
this.singleLid.rotationPointZ = 1.0F;
this.singleLatch = new ModelRenderer(64, 64, 0, 0);
this.singleLatch.addBox(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
this.singleLatch.rotationPointY = 8.0F;
this.singleLatch.rotationPointY = 9.0F;
}
@Override
@@ -93,8 +93,6 @@ public abstract class AEBaseContainer extends Container {
private boolean sentCustomName;
private int ticksSinceCheck = 900;
private IAEItemStack clientRequestedTargetItem = null;
// Slots that were created to represent the player inventory
private List<Slot> playerInventorySlots = null;
public AEBaseContainer(ContainerType<?> containerType, int id, final PlayerInventory ip, final TileEntity myTile,
final IPart myPart) {
@@ -52,7 +52,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
return helper.open(player, locator);
}
@GuiSync(6)
@GuiSync(7)
public YesNo placeMode;
public FormationPlaneContainer(int id, final PlayerInventory ip, final FormationPlanePart te) {
@@ -261,13 +261,19 @@ public class PatternTermContainer extends MEMonitorableContainer
return new ItemStack[] { out };
}
} else {
boolean hasValue = false;
final ItemStack[] list = new ItemStack[3];
for (int i = 0; i < this.outputSlots.length; i++) {
final ItemStack out = this.outputSlots[i].getStack();
list[i] = out;
if (!out.isEmpty()) {
hasValue = true;
}
}
if (hasValue) {
return list;
}
return list;
}
return null;
@@ -105,8 +105,8 @@ public class QuartzKnifeContainer extends AEBaseContainer {
}
private class QuartzKniveSlot extends OutputSlot {
QuartzKniveSlot(IItemHandler a, int b, int c, int d, int i) {
super(a, b, c, d, i);
QuartzKniveSlot(IItemHandler inv, int invSlot, int x, int y, int iconIdx) {
super(inv, invSlot, x, y, iconIdx);
}
@Override
@@ -49,8 +49,8 @@ public class AppEngCraftingSlot extends AppEngSlot {
private int amountCrafted;
public AppEngCraftingSlot(final PlayerEntity par1PlayerEntity, final IItemHandler par2IInventory,
final IItemHandler par3IInventory, final int par4, final int par5, final int par6) {
super(par3IInventory, par4, par5, par6);
final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.thePlayer = par1PlayerEntity;
this.craftMatrix = par2IInventory;
}
@@ -60,7 +60,7 @@ public class AppEngCraftingSlot extends AppEngSlot {
* armor slots.
*/
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -33,9 +33,9 @@ import appeng.container.AEBaseContainer;
import appeng.util.helpers.ItemHandlerUtil;
public class AppEngSlot extends Slot {
private static IInventory emptyInventory = new Inventory(0);
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
private final IItemHandler itemHandler;
private final int index;
private final int invSlot;
private final int defX;
private final int defY;
@@ -46,10 +46,10 @@ public class AppEngSlot extends Slot {
private CalculatedValidity isValid;
private boolean isDisplay = false;
public AppEngSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(emptyInventory, idx, x, y);
public AppEngSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(EMPTY_INVENTORY, invSlot, x, y);
this.itemHandler = inv;
this.index = idx;
this.invSlot = invSlot;
this.defX = x;
this.defY = y;
@@ -71,13 +71,13 @@ public class AppEngSlot extends Slot {
}
public void clearStack() {
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.index, ItemStack.EMPTY);
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.invSlot, ItemStack.EMPTY);
}
@Override
public boolean isItemValid(@Nonnull final ItemStack par1ItemStack) {
public boolean isItemValid(@Nonnull final ItemStack stack) {
if (this.isSlotEnabled()) {
return this.itemHandler.isItemValid(this.index, par1ItemStack);
return this.itemHandler.isItemValid(this.invSlot, stack);
}
return false;
}
@@ -98,13 +98,13 @@ public class AppEngSlot extends Slot {
return this.getDisplayStack();
}
return this.itemHandler.getStackInSlot(this.index);
return this.itemHandler.getStackInSlot(this.invSlot);
}
@Override
public void putStack(final ItemStack stack) {
if (this.isSlotEnabled()) {
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.index, stack);
ItemHandlerUtil.setStackInSlot(this.itemHandler, this.invSlot, stack);
this.onSlotChanged();
}
}
@@ -128,7 +128,7 @@ public class AppEngSlot extends Slot {
@Override
public int getSlotStackLimit() {
return this.itemHandler.getSlotLimit(this.index);
return this.itemHandler.getSlotLimit(this.invSlot);
}
@Override
@@ -137,9 +137,9 @@ public class AppEngSlot extends Slot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
if (this.isSlotEnabled()) {
return !this.itemHandler.extractItem(this.index, 1, true).isEmpty();
return !this.itemHandler.extractItem(this.invSlot, 1, true).isEmpty();
}
return false;
}
@@ -147,7 +147,7 @@ public class AppEngSlot extends Slot {
@Override
@Nonnull
public ItemStack decrStackSize(int amount) {
return this.itemHandler.extractItem(this.index, amount, false);
return this.itemHandler.extractItem(this.invSlot, amount, false);
}
@Override
@@ -166,7 +166,7 @@ public class AppEngSlot extends Slot {
}
public ItemStack getDisplayStack() {
return this.itemHandler.getStackInSlot(this.index);
return this.itemHandler.getStackInSlot(this.invSlot);
}
public float getOpacityOfIcon() {
@@ -29,11 +29,11 @@ public class CraftingMatrixSlot extends AppEngSlot {
private final AEBaseContainer c;
private final IInventory wrappedInventory;
public CraftingMatrixSlot(final AEBaseContainer c, final IItemHandler par1iInventory, final int par2,
final int par3, final int par4) {
super(par1iInventory, par2, par3, par4);
public CraftingMatrixSlot(final AEBaseContainer c, final IItemHandler inv, final int invSlot, final int x,
final int y) {
super(inv, invSlot, x, y);
this.c = c;
this.wrappedInventory = new WrapperInvItemHandler(par1iInventory);
this.wrappedInventory = new WrapperInvItemHandler(inv);
}
@Override
@@ -82,7 +82,7 @@ public class CraftingTermSlot extends AppEngCraftingSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -24,17 +24,17 @@ import net.minecraftforge.items.IItemHandler;
public class DisabledSlot extends AppEngSlot {
public DisabledSlot(final IItemHandler par1iInventory, final int slotIndex, final int x, final int y) {
super(par1iInventory, slotIndex, x, y);
public DisabledSlot(final IItemHandler par1iInventory, final int invSlot, final int x, final int y) {
super(par1iInventory, invSlot, x, y);
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
@@ -22,8 +22,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeBlacklistSlot extends FakeTypeOnlySlot {
public FakeBlacklistSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeBlacklistSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -22,7 +22,7 @@ import net.minecraftforge.items.IItemHandler;
public class FakeCraftingMatrixSlot extends FakeSlot {
public FakeCraftingMatrixSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeCraftingMatrixSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
}
@@ -24,8 +24,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeSlot extends AppEngSlot {
public FakeSlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -39,7 +39,7 @@ public class FakeSlot extends AppEngSlot {
}
@Override
public boolean isItemValid(final ItemStack par1ItemStack) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -53,7 +53,7 @@ public class FakeSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
}
@@ -23,8 +23,8 @@ import net.minecraftforge.items.IItemHandler;
public class FakeTypeOnlySlot extends FakeSlot {
public FakeTypeOnlySlot(final IItemHandler inv, final int idx, final int x, final int y) {
super(inv, idx, x, y);
public FakeTypeOnlySlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
}
@Override
@@ -26,12 +26,12 @@ public class InaccessibleSlot extends AppEngSlot {
private ItemStack dspStack = ItemStack.EMPTY;
public InaccessibleSlot(final IItemHandler i, final int slotIdx, final int x, final int y) {
super(i, slotIdx, x, y);
public InaccessibleSlot(final IItemHandler i, final int invSlot, final int x, final int y) {
super(i, invSlot, x, y);
}
@Override
public boolean isItemValid(final ItemStack i) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
@@ -42,7 +42,7 @@ public class InaccessibleSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return false;
}
@@ -27,14 +27,14 @@ public class MolecularAssemblerPatternSlot extends AppEngSlot {
private final MolecularAssemblerContainer mac;
public MolecularAssemblerPatternSlot(final MolecularAssemblerContainer mac, final IItemHandler i, final int slotIdx,
final int x, final int y) {
super(i, slotIdx, x, y);
public MolecularAssemblerPatternSlot(final MolecularAssemblerContainer mac, final IItemHandler inv,
final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.mac = mac;
}
@Override
public boolean isItemValid(final ItemStack i) {
return this.mac.isValidItemForSlot(this.getSlotIndex(), i);
public boolean isItemValid(final ItemStack stack) {
return this.mac.isValidItemForSlot(this.getSlotIndex(), stack);
}
}
@@ -22,7 +22,7 @@ import net.minecraftforge.items.IItemHandler;
public class NormalSlot extends AppEngSlot {
public NormalSlot(final IItemHandler inv, final int slot, final int xPos, final int yPos) {
super(inv, slot, xPos, yPos);
public NormalSlot(final IItemHandler inv, final int invSlot, final int xPos, final int yPos) {
super(inv, invSlot, xPos, yPos);
}
}
@@ -31,9 +31,9 @@ public class OptionalFakeSlot extends FakeSlot implements IOptionalSlot {
private final IOptionalSlotHost host;
private boolean renderDisabled = true;
public OptionalFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, idx, x + offX * 18, y + offY * 18);
public OptionalFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, invSlot, x + offX * 18, y + offY * 18);
this.srcX = x;
this.srcY = y;
this.groupNum = groupNum;
@@ -25,9 +25,9 @@ public class OptionalNormalSlot extends AppEngSlot implements IOptionalSlot {
private final int groupNum;
private final IOptionalSlotHost host;
public OptionalNormalSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int slot,
public OptionalNormalSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int xPos, final int yPos, final int groupNum) {
super(inv, slot, xPos, yPos);
super(inv, invSlot, xPos, yPos);
this.groupNum = groupNum;
this.host = containerBus;
}
@@ -26,9 +26,10 @@ public class OptionalRestrictedInputSlot extends RestrictedInputSlot {
private final int groupNum;
private final IOptionalSlotHost host;
public OptionalRestrictedInputSlot(final PlacableItemType valid, final IItemHandler i, final IOptionalSlotHost host,
final int slotIndex, final int x, final int y, final int grpNum, final PlayerInventory invPlayer) {
super(valid, i, slotIndex, x, y, invPlayer);
public OptionalRestrictedInputSlot(final PlacableItemType valid, final IItemHandler inv,
final IOptionalSlotHost host, final int invSlot, final int x, final int y, final int grpNum,
final PlayerInventory invPlayer) {
super(valid, inv, invSlot, x, y, invPlayer);
this.groupNum = grpNum;
this.host = host;
}
@@ -23,9 +23,9 @@ import net.minecraftforge.items.IItemHandler;
public class OptionalTypeOnlyFakeSlot extends OptionalFakeSlot {
public OptionalTypeOnlyFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx,
public OptionalTypeOnlyFakeSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
super(inv, containerBus, invSlot, x, y, offX, offY, groupNum);
}
@Override
@@ -23,13 +23,13 @@ import net.minecraftforge.items.IItemHandler;
public class OutputSlot extends AppEngSlot {
public OutputSlot(final IItemHandler a, final int b, final int c, final int d, final int i) {
super(a, b, c, d);
this.setIIcon(i);
public OutputSlot(final IItemHandler inv, final int invSlot, final int x, final int y, final int iconIndex) {
super(inv, invSlot, x, y);
this.setIIcon(iconIndex);
}
@Override
public boolean isItemValid(final ItemStack i) {
public boolean isItemValid(final ItemStack stack) {
return false;
}
}
@@ -22,9 +22,9 @@ import net.minecraftforge.items.IItemHandler;
public class PatternOutputsSlot extends OptionalFakeSlot {
public PatternOutputsSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int idx, final int x,
final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, idx, x, y, offX, offY, groupNum);
public PatternOutputsSlot(final IItemHandler inv, final IOptionalSlotHost containerBus, final int invSlot,
final int x, final int y, final int offX, final int offY, final int groupNum) {
super(inv, containerBus, invSlot, x, y, offX, offY, groupNum);
}
@Override
@@ -22,8 +22,8 @@ import net.minecraftforge.items.IItemHandler;
public class PlayerHotBarSlot extends AppEngSlot {
public PlayerHotBarSlot(final IItemHandler par1iInventory, final int par2, final int par3, final int par4) {
super(par1iInventory, par2, par3, par4);
public PlayerHotBarSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.setPlayerSide(true);
}
}
@@ -24,8 +24,8 @@ import net.minecraftforge.items.IItemHandler;
public class PlayerInvSlot extends AppEngSlot {
public PlayerInvSlot(final IItemHandler par1iInventory, final int idx, final int x, final int y) {
super(par1iInventory, idx, x, y);
public PlayerInvSlot(final IItemHandler inv, final int invSlot, final int x, final int y) {
super(inv, invSlot, x, y);
this.setPlayerSide(true);
}
@@ -70,9 +70,9 @@ public class RestrictedInputSlot extends AppEngSlot {
private boolean allowEdit = true;
private int stackLimit = -1;
public RestrictedInputSlot(final PlacableItemType valid, final IItemHandler i, final int slotIndex, final int x,
public RestrictedInputSlot(final PlacableItemType valid, final IItemHandler inv, final int invSlot, final int x,
final int y, final PlayerInventory p) {
super(i, slotIndex, x, y);
super(inv, invSlot, x, y);
this.which = valid;
this.setIIcon(valid.IIcon);
this.p = p;
@@ -99,20 +99,20 @@ public class RestrictedInputSlot extends AppEngSlot {
}
@Override
public boolean isItemValid(final ItemStack i) {
if (!this.getContainer().isValidForSlot(this, i)) {
public boolean isItemValid(final ItemStack stack) {
if (!this.getContainer().isValidForSlot(this, stack)) {
return false;
}
if (i.isEmpty()) {
if (stack.isEmpty()) {
return false;
}
if (i.getItem() == Items.AIR) {
if (stack.getItem() == Items.AIR) {
return false;
}
if (!super.isItemValid(i)) {
if (!super.isItemValid(stack)) {
return false;
}
@@ -127,7 +127,7 @@ public class RestrictedInputSlot extends AppEngSlot {
switch (this.which) {
case ENCODED_CRAFTING_PATTERN:
final ICraftingPatternDetails de = crafting.decodePattern(i, this.p.player.world);
final ICraftingPatternDetails de = crafting.decodePattern(stack, this.p.player.world);
if (de != null) {
return de.isCraftable();
}
@@ -135,19 +135,19 @@ public class RestrictedInputSlot extends AppEngSlot {
case VALID_ENCODED_PATTERN_W_OUTPUT:
case ENCODED_PATTERN_W_OUTPUT:
case ENCODED_PATTERN:
return crafting.isEncodedPattern(i);
return crafting.isEncodedPattern(stack);
case BLANK_PATTERN:
return materials.blankPattern().isSameAs(i);
return materials.blankPattern().isSameAs(stack);
case PATTERN:
return materials.blankPattern().isSameAs(i) || crafting.isEncodedPattern(i);
return materials.blankPattern().isSameAs(stack) || crafting.isEncodedPattern(stack);
case INSCRIBER_PLATE:
if (materials.namePress().isSameAs(i)) {
if (materials.namePress().isSameAs(stack)) {
return true;
}
return InscriberRecipes.isValidOptionalIngredient(p.player.world, i);
return InscriberRecipes.isValidOptionalIngredient(p.player.world, stack);
case INSCRIBER_INPUT:
return true;/*
@@ -157,46 +157,48 @@ public class RestrictedInputSlot extends AppEngSlot {
case METAL_INGOTS:
return isMetalIngot(i);
return isMetalIngot(stack);
case VIEW_CELL:
return items.viewCell().isSameAs(i);
return items.viewCell().isSameAs(stack);
case ORE:
return GrinderRecipes.isValidIngredient(p.player.world, i);
return GrinderRecipes.isValidIngredient(p.player.world, stack);
case FUEL:
return ForgeHooks.getBurnTime(i) > 0;
return ForgeHooks.getBurnTime(stack) > 0;
case POWERED_TOOL:
return Platform.isChargeable(i);
return Platform.isChargeable(stack);
case QE_SINGULARITY:
return materials.qESingularity().isSameAs(i);
return materials.qESingularity().isSameAs(stack);
case RANGE_BOOSTER:
return materials.wirelessBooster().isSameAs(i);
return materials.wirelessBooster().isSameAs(stack);
case SPATIAL_STORAGE_CELLS:
return i.getItem() instanceof ISpatialStorageCell
&& ((ISpatialStorageCell) i.getItem()).isSpatialStorage(i);
return stack.getItem() instanceof ISpatialStorageCell
&& ((ISpatialStorageCell) stack.getItem()).isSpatialStorage(stack);
case STORAGE_CELLS:
return Api.instance().registries().cell().isCellHandled(i);
return Api.instance().registries().cell().isCellHandled(stack);
case WORKBENCH_CELL:
return i.getItem() instanceof ICellWorkbenchItem && ((ICellWorkbenchItem) i.getItem()).isEditable(i);
return stack.getItem() instanceof ICellWorkbenchItem
&& ((ICellWorkbenchItem) stack.getItem()).isEditable(stack);
case STORAGE_COMPONENT:
return i.getItem() instanceof IStorageComponent
&& ((IStorageComponent) i.getItem()).isStorageComponent(i);
return stack.getItem() instanceof IStorageComponent
&& ((IStorageComponent) stack.getItem()).isStorageComponent(stack);
case TRASH:
if (Api.instance().registries().cell().isCellHandled(i)) {
if (Api.instance().registries().cell().isCellHandled(stack)) {
return false;
}
return !(i.getItem() instanceof IStorageComponent
&& ((IStorageComponent) i.getItem()).isStorageComponent(i));
return !(stack.getItem() instanceof IStorageComponent
&& ((IStorageComponent) stack.getItem()).isStorageComponent(stack));
case ENCODABLE_ITEM:
return i.getItem() instanceof INetworkEncodable
|| Api.instance().registries().wireless().isWirelessTerminal(i);
return stack.getItem() instanceof INetworkEncodable
|| Api.instance().registries().wireless().isWirelessTerminal(stack);
case BIOMETRIC_CARD:
return i.getItem() instanceof IBiometricCard;
return stack.getItem() instanceof IBiometricCard;
case UPGRADES:
return i.getItem() instanceof IUpgradeModule && ((IUpgradeModule) i.getItem()).getType(i) != null;
return stack.getItem() instanceof IUpgradeModule
&& ((IUpgradeModule) stack.getItem()).getType(stack) != null;
default:
break;
}
@@ -205,7 +207,7 @@ public class RestrictedInputSlot extends AppEngSlot {
}
@Override
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
public boolean canTakeStack(final PlayerEntity player) {
return this.isAllowEdit();
}
+1 -57
View File
@@ -19,7 +19,6 @@
package appeng.core;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import javax.annotation.Nonnull;
@@ -40,8 +39,6 @@ import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
@@ -56,29 +53,10 @@ import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import appeng.block.paint.PaintSplotchesModel;
import appeng.block.qnb.QnbFormedModel;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.components.IPostInitComponent;
import appeng.capabilities.Capabilities;
import appeng.client.ClientHelper;
import appeng.client.render.DummyFluidItemModel;
import appeng.client.render.FacadeItemModel;
import appeng.client.render.SimpleModelLoader;
import appeng.client.render.cablebus.CableBusModelLoader;
import appeng.client.render.cablebus.P2PTunnelFrequencyModel;
import appeng.client.render.crafting.CraftingCubeModelLoader;
import appeng.client.render.crafting.EncodedPatternModelLoader;
import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.ColorApplicatorModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.GlassModel;
import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.model.UVLModelLoader;
import appeng.client.render.spatial.SpatialPylonModel;
import appeng.core.features.registries.PartModels;
import appeng.core.stats.AdvancementTriggers;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.worlddata.WorldData;
@@ -90,7 +68,6 @@ import appeng.entity.TinyTNTPrimedRenderer;
import appeng.hooks.TickHandler;
import appeng.integration.Integrations;
import appeng.parts.PartPlacement;
import appeng.parts.automation.PlaneModelLoader;
import appeng.server.ServerHelper;
@Mod(AppEng.MOD_ID)
@@ -117,7 +94,7 @@ public final class AppEng {
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, AEConfig.CLIENT_SPEC);
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AEConfig.COMMON_SPEC);
proxy = DistExecutor.safeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
proxy = DistExecutor.unsafeRunForDist(() -> ClientHelper::new, () -> ServerHelper::new);
CreativeTab.init();
new FacadeItemGroup(); // This call has a side-effect (adding it to the creative screen)
@@ -181,39 +158,6 @@ public final class AppEng {
RenderingRegistry.registerEntityRenderingHandler(ChargedQuartzEntity.TYPE,
m -> new ItemRenderer(m, Minecraft.getInstance().getItemRenderer()));
// TODO: Do not use the internal API
final ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
.forEachRemaining(IClientSetupComponent::setup);
addBuiltInModel("glass", GlassModel::new);
addBuiltInModel("sky_compass", SkyCompassModel::new);
addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
addBuiltInModel("memory_card", MemoryCardModel::new);
addBuiltInModel("biometric_card", BiometricCardModel::new);
addBuiltInModel("drive", DriveModel::new);
addBuiltInModel("color_applicator", ColorApplicatorModel::new);
addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
addBuiltInModel("facade", FacadeItemModel::new);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "encoded_pattern"),
EncodedPatternModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "part_plane"),
PlaneModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "crafting_cube"),
CraftingCubeModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "uvlightmap"), UVLModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "cable_bus"),
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
}
@OnlyIn(Dist.CLIENT)
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, id),
new SimpleModelLoader<>(modelFactory));
}
@Nonnull
+10 -2
View File
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.client.util.InputMappings;
import net.minecraft.entity.player.PlayerEntity;
@@ -55,11 +56,18 @@ public abstract class CommonHelper {
public abstract void postInit();
public abstract CableRenderMode getRenderMode();
public abstract CableRenderMode getCableRenderMode();
public abstract void triggerUpdates();
public abstract void updateRenderMode(PlayerEntity player);
/**
* Sets the player that is currently interacting with a cable or part attached
* to a cable. This will return that player's cable render mode from calls to
* {@link #getCableRenderMode()}, until another player or null is set.
*
* @param player Null to revert to the default cable render mode.
*/
public abstract void setPartInteractionPlayer(@Nullable PlayerEntity player);
public abstract boolean isActionKey(@Nonnull final ActionKey key, InputMappings.Input input);
+65 -8
View File
@@ -18,6 +18,8 @@
package appeng.core;
import java.util.function.Supplier;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -50,7 +52,8 @@ import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.ParticleFactoryRegisterEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.IEventBus;
@@ -79,7 +82,10 @@ import appeng.api.networking.security.ISecurityGrid;
import appeng.api.networking.spatial.ISpatialCache;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.ITickManager;
import appeng.block.paint.PaintSplotchesModel;
import appeng.block.qnb.QnbFormedModel;
import appeng.bootstrap.components.IBlockRegistrationComponent;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.bootstrap.components.IEntityRegistrationComponent;
import appeng.bootstrap.components.IItemColorRegistrationComponent;
import appeng.bootstrap.components.IItemRegistrationComponent;
@@ -118,6 +124,13 @@ import appeng.client.gui.implementations.UpgradeableScreen;
import appeng.client.gui.implementations.VibrationChamberScreen;
import appeng.client.gui.implementations.WirelessScreen;
import appeng.client.gui.implementations.WirelessTermScreen;
import appeng.client.render.DummyFluidItemModel;
import appeng.client.render.FacadeItemModel;
import appeng.client.render.SimpleModelLoader;
import appeng.client.render.cablebus.CableBusModelLoader;
import appeng.client.render.cablebus.P2PTunnelFrequencyModel;
import appeng.client.render.crafting.CraftingCubeModelLoader;
import appeng.client.render.crafting.EncodedPatternModelLoader;
import appeng.client.render.effects.ChargedOreFX;
import appeng.client.render.effects.CraftingFx;
import appeng.client.render.effects.EnergyFx;
@@ -126,6 +139,13 @@ import appeng.client.render.effects.LightningFX;
import appeng.client.render.effects.MatterCannonFX;
import appeng.client.render.effects.ParticleTypes;
import appeng.client.render.effects.VibrantFX;
import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.ColorApplicatorModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.GlassModel;
import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.spatial.SpatialPylonModel;
import appeng.client.render.tesr.InscriberTESR;
import appeng.client.render.tesr.SkyChestTESR;
import appeng.container.AEBaseContainer;
@@ -194,20 +214,21 @@ import appeng.me.cache.SecurityCache;
import appeng.me.cache.SpatialPylonCache;
import appeng.me.cache.TickManagerCache;
import appeng.mixins.StructureAccessor;
import appeng.parts.automation.PlaneModelLoader;
import appeng.recipes.game.DisassembleRecipe;
import appeng.recipes.game.FacadeRecipe;
import appeng.recipes.handlers.GrinderRecipe;
import appeng.recipes.handlers.GrinderRecipeSerializer;
import appeng.recipes.handlers.InscriberRecipe;
import appeng.recipes.handlers.InscriberRecipeSerializer;
import appeng.server.AECommand;
import appeng.spatial.StorageCellBiome;
import appeng.spatial.StorageChunkGenerator;
import appeng.spatial.SpatialStorageBiome;
import appeng.spatial.SpatialStorageChunkGenerator;
import appeng.spatial.SpatialStorageDimensionIds;
import appeng.tile.AEBaseTileEntity;
import appeng.tile.crafting.MolecularAssemblerRenderer;
import appeng.worldgen.ChargedQuartzOreConfig;
import appeng.worldgen.ChargedQuartzOreFeature;
import appeng.worldgen.meteorite.MeteoriteStructure;
import appeng.worldgen.meteorite.MeteoriteStructurePiece;
final class Registration {
@@ -239,6 +260,39 @@ final class Registration {
@OnlyIn(Dist.CLIENT)
public void modelRegistryEvent(ModelRegistryEvent event) {
registerSpecialModels();
// TODO: Do not use the internal API
final ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents(IClientSetupComponent.class)
.forEachRemaining(IClientSetupComponent::setup);
addBuiltInModel("glass", GlassModel::new);
addBuiltInModel("sky_compass", SkyCompassModel::new);
addBuiltInModel("dummy_fluid_item", DummyFluidItemModel::new);
addBuiltInModel("memory_card", MemoryCardModel::new);
addBuiltInModel("biometric_card", BiometricCardModel::new);
addBuiltInModel("drive", DriveModel::new);
addBuiltInModel("color_applicator", ColorApplicatorModel::new);
addBuiltInModel("spatial_pylon", SpatialPylonModel::new);
addBuiltInModel("paint_splotches", PaintSplotchesModel::new);
addBuiltInModel("quantum_bridge_formed", QnbFormedModel::new);
addBuiltInModel("p2p_tunnel_frequency", P2PTunnelFrequencyModel::new);
addBuiltInModel("facade", FacadeItemModel::new);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "encoded_pattern"),
EncodedPatternModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "part_plane"),
PlaneModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "crafting_cube"),
CraftingCubeModelLoader.INSTANCE);
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, "cable_bus"),
new CableBusModelLoader((PartModels) Api.INSTANCE.registries().partModels()));
}
@OnlyIn(Dist.CLIENT)
private static <T extends IModelGeometry<T>> void addBuiltInModel(String id, Supplier<T> modelFactory) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(AppEng.MOD_ID, id),
new SimpleModelLoader<>(modelFactory));
}
/**
@@ -628,6 +682,8 @@ final class Registration {
new ResourceLocation(dimension));
}
MeteoriteStructurePiece.register();
ForgeRegistries.BIOMES.forEach(b -> {
addMeteoriteWorldGen(b);
addQuartzWorldGen(b);
@@ -687,11 +743,12 @@ final class Registration {
MeteoriteStructure.INSTANCE.setRegistryName(MeteoriteStructure.ID),
GenerationStage.Decoration.TOP_LAYER_MODIFICATION);
Registry.register(Registry.CHUNK_GENERATOR_CODEC, AppEng.makeId("storage"), StorageChunkGenerator.CODEC);
Registry.register(Registry.CHUNK_GENERATOR_CODEC, SpatialStorageDimensionIds.CHUNK_GENERATOR_ID,
SpatialStorageChunkGenerator.CODEC);
}
public void registerBiomes(RegistryEvent.Register<Biome> evt) {
evt.getRegistry().register(StorageCellBiome.INSTANCE.setRegistryName(AppEng.makeId("storage")));
evt.getRegistry().register(SpatialStorageBiome.INSTANCE.setRegistryName(SpatialStorageDimensionIds.BIOME_ID));
}
@OnlyIn(Dist.CLIENT)
@@ -726,7 +783,7 @@ final class Registration {
modEventBus.addListener(this::registerParticleFactories);
modEventBus.addListener(this::registerTextures);
MinecraftForge.EVENT_BUS.addListener(this::modelRegistryEvent);
modEventBus.addListener(this::modelRegistryEvent);
modEventBus.addListener(this::registerItemColors);
modEventBus.addListener(this::handleModelBake);
}
@@ -115,7 +115,12 @@ public class ApiCrafting implements ICraftingHelper {
// We use the shared itemstack for an identity lookup.
IAEItemStack ais = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(is);
return new CraftingPatternDetails(ais, world);
try {
return new CraftingPatternDetails(ais, world);
} catch (IllegalStateException e) {
AELog.warn("Could not decode an invalid pattern %s: %s", is, e);
return null;
}
}
private boolean attemptRecovery(EncodedPatternItem patternItem, ItemStack itemStack, World world) {
+1 -1
View File
@@ -41,6 +41,6 @@ public class ApiPart implements IPartHelper {
@Override
public CableRenderMode getCableRenderMode() {
return AppEng.proxy.getRenderMode();
return AppEng.proxy.getCableRenderMode();
}
}
@@ -39,6 +39,7 @@ import appeng.api.features.AEFeature;
import appeng.block.AEBaseBlockItemChargeable;
import appeng.block.crafting.AbstractCraftingUnitBlock.CraftingUnitType;
import appeng.block.crafting.CraftingMonitorBlock;
import appeng.block.crafting.CraftingMonitorBlockRendering;
import appeng.block.crafting.CraftingStorageBlock;
import appeng.block.crafting.CraftingStorageItem;
import appeng.block.crafting.CraftingUnitBlock;
@@ -94,9 +95,8 @@ import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.client.render.crafting.CraftingCubeRendering;
import appeng.client.render.crafting.CraftingMonitorTESR;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
import appeng.client.render.spatial.SpatialPylonRendering;
import appeng.client.render.tesr.ChargerTESR;
import appeng.client.render.tesr.ChestTileEntityRenderer;
import appeng.client.render.tesr.CrankTESR;
import appeng.client.render.tesr.DriveLedTileEntityRenderer;
@@ -371,7 +371,7 @@ public final class ApiBlocks implements IBlocks {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(TileEntityRendering<ChargerTileEntity> rendering) {
rendering.tileEntityRenderer(ChargerBlock.createTesr());
rendering.tileEntityRenderer(ChargerTESR.FACTORY);
}
}).build())
.build();
@@ -532,20 +532,7 @@ public final class ApiBlocks implements IBlocks {
rendering.tileEntityRenderer(CraftingMonitorTESR::new);
}
}).build())
.rendering(new BlockRenderingCustomizer() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer((path, model) -> {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
});
}
}).build();
.rendering(new CraftingMonitorBlockRendering()).build();
this.molecularAssembler = registry
.block("molecular_assembler", () -> new MolecularAssemblerBlock(defaultProps(Material.IRON).notSolid()))
@@ -23,6 +23,9 @@ import java.util.function.Consumer;
import net.minecraft.entity.EntityClassification;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.Rarity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ToolType;
@@ -35,6 +38,8 @@ import appeng.api.util.AEColoredItemDefinition;
import appeng.bootstrap.FeatureFactory;
import appeng.bootstrap.IItemRendering;
import appeng.bootstrap.ItemRenderingCustomizer;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.core.AppEng;
import appeng.core.features.ActivityState;
import appeng.core.features.ColoredItemDefinition;
import appeng.core.features.ItemStackSrc;
@@ -51,6 +56,7 @@ import appeng.hooks.BlockToolDispenseItemBehavior;
import appeng.hooks.MatterCannonDispenseItemBehavior;
import appeng.items.materials.MaterialType;
import appeng.items.misc.CrystalSeedItem;
import appeng.items.misc.CrystalSeedRendering;
import appeng.items.misc.EncodedPatternItem;
import appeng.items.misc.PaintBallItem;
import appeng.items.misc.PaintBallItemRendering;
@@ -210,7 +216,22 @@ public final class ApiItems implements IItems {
.addFeatures(AEFeature.PORTABLE_CELL, AEFeature.STORAGE_CELLS).build();
this.colorApplicator = powerTools.item("color_applicator", ColorApplicatorItem::new).props(chargedDefaults)
.addFeatures(AEFeature.COLOR_APPLICATOR).dispenserBehavior(BlockToolDispenseItemBehavior::new)
.rendering(new ColorApplicatorItemRendering()).build();
.bootstrap(item -> new IClientSetupComponent() {
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item;
ItemModelsProperties.func_239418_a_(item, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> {
// If the stack has no color, don't use the colored model since the impact of
// calling getColor for every quad is extremely high, if the stack tries to
// re-search its
// inventory for a new paintball everytime
AEColor col = colorApplicatorItem.getActiveColor(itemStack);
return (col != null) ? 1 : 0;
});
}
}).rendering(new ColorApplicatorItemRendering()).build();
this.biometricCard = registry.item("biometric_card", BiometricCardItem::new)
.props(props -> props.maxStackSize(1)).features(AEFeature.SECURITY).build();
@@ -221,7 +242,8 @@ public final class ApiItems implements IItems {
.features(AEFeature.NETWORK_TOOL).build();
this.cellCreative = registry.item("creative_storage_cell", CreativeStorageCellItem::new)
.props(props -> props.maxStackSize(1)).features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
.props(props -> props.maxStackSize(1).rarity(Rarity.EPIC))
.features(AEFeature.STORAGE_CELLS, AEFeature.CREATIVE).build();
this.viewCell = registry.item("view_cell", ViewCellItem::new).props(props -> props.maxStackSize(1))
.features(AEFeature.VIEW_CELL).build();
@@ -278,15 +300,15 @@ public final class ApiItems implements IItems {
this.certusCrystalSeed = registry
.item("certus_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedCertusQuartzCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
this.fluixCrystalSeed = registry
.item("fluix_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedFluixCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
this.netherQuartzSeed = registry
.item("nether_quartz_seed",
props -> new CrystalSeedItem(props, materials.purifiedNetherQuartzCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
GrowingCrystalEntity.TYPE = registry
.<GrowingCrystalEntity>entity("growing_crystal", GrowingCrystalEntity::new, EntityClassification.MISC)
@@ -68,11 +68,14 @@ public class PartPlacementPacket extends BasePacket {
@Override
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
final ServerPlayerEntity sender = (ServerPlayerEntity) player;
AppEng.proxy.updateRenderMode(sender);
PartPlacement.setEyeHeight(this.eyeHeight);
PartPlacement.place(sender.getHeldItem(this.hand), new BlockPos(this.x, this.y, this.z),
Direction.values()[this.face], sender, this.hand, sender.world,
PartPlacement.PlaceType.INTERACT_FIRST_PASS, 0);
AppEng.proxy.updateRenderMode(null);
AppEng.proxy.setPartInteractionPlayer(sender);
try {
PartPlacement.setEyeHeight(this.eyeHeight);
PartPlacement.place(sender.getHeldItem(this.hand), new BlockPos(this.x, this.y, this.z),
Direction.values()[this.face], sender, this.hand, sender.world,
PartPlacement.PlaceType.INTERACT_FIRST_PASS, 0);
} finally {
AppEng.proxy.setPartInteractionPlayer(null);
}
}
}
@@ -19,6 +19,7 @@
package appeng.entity;
import java.util.List;
import java.util.Random;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
@@ -42,6 +43,8 @@ import appeng.util.Platform;
public final class ChargedQuartzEntity extends AEBaseItemEntity {
private static final Random RANDOM = new Random();
public static EntityType<ChargedQuartzEntity> TYPE;
private int delay = 0;
@@ -135,9 +138,15 @@ public final class ChargedQuartzEntity extends AEBaseItemEntity {
}
materials.fluixCrystal().maybeStack(2).ifPresent(is -> {
final ItemEntity entity = new ItemEntity(this.world, this.getPosX(), this.getPosY(), this.getPosZ(),
is);
final double x = Math.floor(this.getPosX()) + .25d + RANDOM.nextDouble() * .5;
final double y = Math.floor(this.getPosY()) + .25d + RANDOM.nextDouble() * .5;
final double z = Math.floor(this.getPosZ()) + .25d + RANDOM.nextDouble() * .5;
final double xSpeed = RANDOM.nextDouble() * .25 - 0.125;
final double ySpeed = RANDOM.nextDouble() * .25 - 0.125;
final double zSpeed = RANDOM.nextDouble() * .25 - 0.125;
final ItemEntity entity = new ItemEntity(this.world, x, y, z, is);
entity.setMotion(xSpeed, ySpeed, zSpeed);
this.world.addEntity(entity);
});
@@ -140,8 +140,8 @@ public final class TinyTNTPrimedEntity extends TNTEntity implements IEntityAddit
return;
}
final Explosion ex = new Explosion(this.world, this, this.getPosX(), this.getPosY(), this.getPosZ(), 0.2f,
false, Mode.BREAK);
final Explosion ex = new Explosion(this.world, this, null, null, this.getPosX(), this.getPosY(), this.getPosZ(),
0.2f, false, Explosion.Mode.BREAK);
final AxisAlignedBB area = new AxisAlignedBB(this.getPosX() - 1.5, this.getPosY() - 1.5f, this.getPosZ() - 1.5,
this.getPosX() + 1.5, this.getPosY() + 1.5, this.getPosZ() + 1.5);
final List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, area);
+1 -1
View File
@@ -49,7 +49,7 @@ public class FacadePart implements IFacadePart {
@Override
public void getBoxes(final IPartCollisionHelper ch, boolean livingEntity) {
if (livingEntity) {
if (livingEntity || !ch.isBBCollision()) {
// prevent weird snag behavior
ch.addBox(0.0, 0.0, 14, 16.0, 16.0, 16.0);
} else {
@@ -12,6 +12,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
@@ -55,7 +56,8 @@ public class FluidSlotWidget extends CustomSlotWidget {
final float blue = (attributes.getColor() & 255) / 255.0F;
RenderSystem.color3f(red, green, blue);
blit(matrixStack, xPos(), yPos(), this.getBlitOffset(), getWidth(), getHeight(), sprite);
blit(matrixStack, getTooltipAreaX(), getTooltipAreaY(), this.getBlitOffset(), getTooltipAreaWidth(),
getTooltipAreaHeight(), sprite);
}
}
@@ -79,16 +81,16 @@ public class FluidSlotWidget extends CustomSlotWidget {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
final IAEFluidStack fluid = this.getFluidStack();
if (fluid != null) {
return new TranslationTextComponent(fluid.getFluidStack().getTranslationKey());
}
return null;
return StringTextComponent.EMPTY;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -89,7 +89,7 @@ public class FluidTankWidget extends Widget implements ITooltip {
}
@Override
public ITextComponent getMessage() {
public ITextComponent getTooltipMessage() {
final IAEFluidStack fluid = this.tank.getFluidInSlot(this.slot);
if (fluid != null && fluid.getStackSize() > 0) {
return fluid.getFluid().getAttributes().getDisplayName(fluid.getFluidStack()).deepCopy()
@@ -99,27 +99,27 @@ public class FluidTankWidget extends Widget implements ITooltip {
}
@Override
public int xPos() {
public int getTooltipAreaX() {
return this.x - 2;
}
@Override
public int yPos() {
public int getTooltipAreaY() {
return this.y - 2;
}
@Override
public int getWidth() {
public int getTooltipAreaWidth() {
return this.width + 4;
}
@Override
public int getHeight() {
public int getTooltipAreaHeight() {
return this.height + 4;
}
@Override
public boolean isVisible() {
public boolean isTooltipAreaVisible() {
return true;
}
@@ -48,7 +48,8 @@ public class OptionalFluidSlotWidget extends FluidSlotWidget {
} else {
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 0.4F);
}
GuiUtils.drawTexturedModalRect(guileft + this.xPos() - 1, guitop + this.yPos() - 1, this.srcX - 1,
this.srcY - 1, this.getWidth() + 2, this.getHeight() + 2, currentZIndex);
GuiUtils.drawTexturedModalRect(guileft + this.getTooltipAreaX() - 1, guitop + this.getTooltipAreaY() - 1,
this.srcX - 1, this.srcY - 1, this.getTooltipAreaWidth() + 2, this.getTooltipAreaHeight() + 2,
currentZIndex);
}
}
@@ -210,7 +210,7 @@ public class DualityFluidInterface
} else if (capabilityClass == Capabilities.STORAGE_MONITORABLE_ACCESSOR) {
return (LazyOptional<T>) LazyOptional.of(() -> this.accessor);
}
return null;
return LazyOptional.empty();
}
private boolean hasConfig() {
@@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tags.FluidTags;
import net.minecraft.tags.ITag;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
@@ -35,15 +34,12 @@ import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartModel;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IFluidStorageChannel;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.util.AECableType;
import appeng.api.util.AEPartLocation;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.core.settings.TickRates;
@@ -53,6 +49,7 @@ import appeng.items.parts.PartModels;
import appeng.me.GridAccessException;
import appeng.me.helpers.MachineSource;
import appeng.parts.BasicStatePart;
import appeng.parts.automation.PlaneConnectionHelper;
import appeng.parts.automation.PlaneConnections;
import appeng.parts.automation.PlaneModelData;
import appeng.parts.automation.PlaneModels;
@@ -73,115 +70,27 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
private final IActionSource mySrc = new MachineSource(this);
private final PlaneConnectionHelper connectionHelper = new PlaneConnectionHelper(this);
public FluidAnnihilationPlanePart(final ItemStack is) {
super(is);
}
@Override
public void getBoxes(final IPartCollisionHelper bch) {
int minX = 1;
int minY = 1;
int maxX = 15;
int maxY = 15;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
final Direction e = bch.getWorldX();
final Direction u = bch.getWorldY();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e.getOpposite())), this.getSide())) {
minX = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxX = 16;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(u.getOpposite())), this.getSide())) {
minY = 0;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(e)), this.getSide())) {
maxY = 16;
}
}
bch.addBox(5, 5, 14, 11, 11, 15);
bch.addBox(minX, minY, 15, maxX, maxY, 16);
connectionHelper.getBoxes(bch);
}
public PlaneConnections getConnections() {
final Direction facingRight, facingUp;
AEPartLocation location = this.getSide();
switch (location) {
case UP:
facingRight = Direction.EAST;
facingUp = Direction.NORTH;
break;
case DOWN:
facingRight = Direction.WEST;
facingUp = Direction.NORTH;
break;
case NORTH:
facingRight = Direction.WEST;
facingUp = Direction.UP;
break;
case SOUTH:
facingRight = Direction.EAST;
facingUp = Direction.UP;
break;
case WEST:
facingRight = Direction.SOUTH;
facingUp = Direction.UP;
break;
case EAST:
facingRight = Direction.NORTH;
facingUp = Direction.UP;
break;
default:
case INTERNAL:
return PlaneConnections.of(false, false, false, false);
}
boolean left = false, right = false, down = false, up = false;
final IPartHost host = this.getHost();
if (host != null) {
final TileEntity te = host.getTile();
final BlockPos pos = te.getPos();
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight.getOpposite())),
this.getSide())) {
left = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingRight)), this.getSide())) {
right = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp.getOpposite())),
this.getSide())) {
down = true;
}
if (this.isAnnihilationPlane(te.getWorld().getTileEntity(pos.offset(facingUp)), this.getSide())) {
up = true;
}
}
return PlaneConnections.of(up, right, down, left);
return connectionHelper.getConnections();
}
@Override
public void onNeighborChanged(IBlockReader w, BlockPos pos, BlockPos neighbor) {
if (pos.offset(this.getSide().getFacing()).equals(neighbor)) {
this.refresh();
} else {
connectionHelper.updateConnections();
}
}
@@ -190,14 +99,6 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
return 1;
}
private boolean isAnnihilationPlane(final TileEntity blockTileEntity, final AEPartLocation side) {
if (blockTileEntity instanceof IPartHost) {
final IPart p = ((IPartHost) blockTileEntity).getPart(side);
return p != null && p.getClass() == this.getClass();
}
return false;
}
private void refresh() {
try {
this.getProxy().getTick().alertDevice(this.getProxy().getNode());
@@ -1,14 +0,0 @@
package appeng.hooks;
import net.minecraft.util.RegistryKey;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.server.ServerWorld;
public interface DynamicDimensions {
ServerWorld addWorld(RegistryKey<World> worldId, RegistryKey<DimensionType> dimensionTypeId,
ChunkGenerator chunkGenerator);
}
@@ -0,0 +1,127 @@
package appeng.hooks;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.BlockFaceUV;
import net.minecraft.client.renderer.model.BlockPartFace;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.Direction;
import net.minecraft.util.JSONUtils;
import net.minecraft.util.ResourceLocation;
import appeng.core.AppEng;
import appeng.mixins.unlitquad.BakedQuadAccessor;
/**
* Implementation details of allowing quads to be defined as "unlit" in JSON
* models by specifying an "unlit" boolean property on the face.
*/
public class UnlitQuadHooks {
/**
* Offset into the vertex data (which is represented as integers).
*/
private static final int LIGHT_OFFSET = getLightOffset();
// Lightmap texture coordinate with full intensity light leading to no drop in
// brightness
private static final int UNLIT_LIGHT_UV = LightTexture.packLight(15, 15);
/**
* Thread-Local flag to indicate that an enhanced Applied Energistics model is
* currently being deserialized.
*/
private static final ThreadLocal<Boolean> ENABLE_UNLIT_EXTENSIONS = new ThreadLocal<>();
/**
* Notify the unlit model system that a specific model is about to be
* deserialized by {@link net.minecraft.client.renderer.model.ModelBakery}.
*/
public static void beginDeserializingModel(ResourceLocation location) {
String namespace = location.getNamespace();
if (namespace.equals(AppEng.MOD_ID)) {
ENABLE_UNLIT_EXTENSIONS.set(true);
}
}
/**
* Notify the unlit model system that deserialization of a model has ended.
*/
public static void endDeserializingModel() {
ENABLE_UNLIT_EXTENSIONS.set(false);
}
public static boolean isUnlitExtensionEnabled() {
Boolean b = ENABLE_UNLIT_EXTENSIONS.get();
return b != null && b;
}
public static BlockPartFace enhanceModelElementFace(BlockPartFace modelElement, JsonElement jsonElement) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (JSONUtils.getBoolean(jsonObject, "unlit", false)) {
return new UnlitBlockPartFace(modelElement.cullFace, modelElement.tintIndex, modelElement.texture,
modelElement.blockFaceUV);
}
return modelElement;
}
/**
* Creates a new quad from the given quad and pre-bakes it to not be affected by
* lighting (neither diffuse lighting nor the prebaked lightmap). This works on
* the assumption that Vanilla will not modify a quad's lightmap data if it's
* not zero.
*/
public static BakedQuad makeUnlit(BakedQuad quad) {
int[] vertexData = quad.getVertexData().clone();
int stride = DefaultVertexFormats.BLOCK.getIntegerSize();
// Set the pre-baked texture coords for the lightmap.
// Vanilla will not overwrite them if they are non-zero
for (int i = 0; i < 4; i++) {
vertexData[stride * i + LIGHT_OFFSET] = UNLIT_LIGHT_UV;
}
TextureAtlasSprite sprite = ((BakedQuadAccessor) quad).getSprite();
// Copy the quad to disable diffuse lighting
return new BakedQuad(vertexData, quad.getTintIndex(), quad.getFace(), sprite, false /* diffuse lighting */);
}
/**
* This subclass is used as a marker to indicate this face deserialized from
* JSON is supposed to be unlit, which translates to processing by
* {@link #makeUnlit(BakedQuad)}.
*/
public static class UnlitBlockPartFace extends BlockPartFace {
public UnlitBlockPartFace(Direction cullFaceIn, int tintIndexIn, String textureIn, BlockFaceUV blockFaceUVIn) {
super(cullFaceIn, tintIndexIn, textureIn, blockFaceUVIn);
}
}
/**
* Find the index in the BakedQuad vertex data (for vertex 0) where the lightmap
* coordinates are. Assumes the BLOCK vertex format.
*/
private static int getLightOffset() {
VertexFormat format = DefaultVertexFormats.BLOCK;
int offset = 0;
for (VertexFormatElement element : format.getElements()) {
// TEX_2SB is the lightmap vertex element
if (element == DefaultVertexFormats.TEX_2SB) {
if (element.getType() != VertexFormatElement.Type.SHORT) {
throw new UnsupportedOperationException("Expected light map format to be of type SHORT");
}
if (offset % 4 != 0) {
throw new UnsupportedOperationException("Expected light map offset to be 4-byte aligned");
}
return offset / 4;
}
offset += element.getSize();
}
throw new UnsupportedOperationException("Failed to find the lightmap index in the block vertex format");
}
}
@@ -37,7 +37,7 @@ public enum TheOneProbeText {
}
public String getUnlocalized() {
return this.root + '.' + this.name().toLowerCase(Locale.ENGLISH);
return this.root + '.' + this.name().toLowerCase(Locale.ROOT);
}
}
@@ -29,12 +29,10 @@ import net.minecraft.block.material.Material;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.Entity;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
@@ -61,7 +59,7 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
/**
* The number of growth ticks required to finish growing.
*/
private static final int GROWTH_TICKS_REQUIRED = 600;
public static final int GROWTH_TICKS_REQUIRED = 600;
/**
* The item to convert to, when growth finishes.
@@ -71,9 +69,6 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
public CrystalSeedItem(Properties properties, IItemProvider grownItem) {
super(properties);
this.grownItem = Preconditions.checkNotNull(grownItem);
// Expose the growth of the seed to the model system
ItemModelsProperties.func_239418_a_(this, new ResourceLocation("appliedenergistics2:growth"),
(is, w, p) -> getGrowthTicks(is) / (float) GROWTH_TICKS_REQUIRED);
}
@Nullable
@@ -88,7 +83,7 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
}
}
private static int getGrowthTicks(final ItemStack is) {
public static int getGrowthTicks(final ItemStack is) {
CompoundNBT tag = is.getTag();
return tag != null ? tag.getInt(TAG_GROWTH_TICKS) : 0;
}
@@ -0,0 +1,29 @@
package appeng.items.misc;
import net.minecraft.item.Item;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.bootstrap.components.IClientSetupComponent;
/**
* Exposes a predicate "growth", which is used in the item model to
* differentiate the growth stages.
*/
public class CrystalSeedRendering implements IClientSetupComponent {
private final Item item;
public CrystalSeedRendering(Item item) {
this.item = item;
}
@Override
@OnlyIn(Dist.CLIENT)
public void setup() {
// Expose the growth of the seed to the model system
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:growth"),
(is, w, p) -> CrystalSeedItem.getGrowthTicks(is) / (float) CrystalSeedItem.GROWTH_TICKS_REQUIRED);
}
}
@@ -307,14 +307,27 @@ public class EncodedPatternItem extends AEBaseItem {
final ListNBT tagIn = new ListNBT();
final ListNBT tagOut = new ListNBT();
boolean hasInput = false;
for (final ItemStack i : in) {
tagIn.add(createItemTag(i));
if (!i.isEmpty()) {
hasInput = true;
}
}
Preconditions.checkArgument(hasInput, "cannot encode a pattern that has no inputs.");
boolean hasNonEmptyOutput = false;
for (final ItemStack i : out) {
tagOut.add(createItemTag(i));
if (!i.isEmpty()) {
hasNonEmptyOutput = true;
}
}
// Patterns without any outputs are corrupt! Never encode such a pattern.
Preconditions.checkArgument(hasNonEmptyOutput, "cannot encode a pattern that has no output.");
encodedValue.put(EncodedPatternItem.NBT_INGREDIENTS, tagIn);
encodedValue.put(EncodedPatternItem.NBT_PRODUCTS, tagOut);
return encodedValue;
@@ -18,35 +18,40 @@
package appeng.items.storage;
import java.time.Instant;
import java.util.List;
import java.util.Locale;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.Constants;
import appeng.api.implementations.TransitionResult;
import appeng.api.implementations.items.ISpatialStorageCell;
import appeng.api.storage.ISpatialDimension;
import appeng.api.util.WorldCoord;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.items.AEBaseItem;
import appeng.spatial.SpatialDimensionManager;
import appeng.spatial.StorageHelper;
import appeng.spatial.SpatialStorageHelper;
import appeng.spatial.SpatialStoragePlot;
import appeng.spatial.SpatialStoragePlotManager;
import appeng.spatial.TransitionInfo;
public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorageCell {
private static final String TAG_DIMENSION_ID = "dimension_id";
private static final String TAG_PLOT_ID = "plot_id";
/**
* This is only stored in the itemstack to display in the tooltip on the
* client-side.
*/
private static final String TAG_PLOT_SIZE = "plot_size";
private final int maxRegion;
@@ -59,18 +64,22 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
@Override
public void addInformation(final ItemStack stack, final World world, final List<ITextComponent> lines,
final ITooltipFlag advancedTooltips) {
final RegistryKey<World> worldId = this.getStoredDimension(stack);
if (worldId == null) {
int plotId = this.getAllocatedPlotId(stack);
if (plotId == -1) {
lines.add(GuiText.Unformatted.text().deepCopy().mergeStyle(TextFormatting.ITALIC));
lines.add(GuiText.SpatialCapacity.text(maxRegion, maxRegion, maxRegion));
} else {
SpatialDimensionManager.INSTANCE.addCellDimensionTooltip(worldId, lines);
return;
}
if (advancedTooltips.isAdvanced()) {
if (worldId != null && worldId.func_240901_a_() != null) {
lines.add(new StringTextComponent("Dimension: " + worldId.func_240901_a_()));
}
// Add a serial number to allows players to keep different cells apart
// Try to make this a little more flavorful.
String serialNumber = String.format(Locale.ROOT, "SP-%04d", plotId);
lines.add(GuiText.SerialNumber.text(serialNumber));
CompoundNBT tag = stack.getTag();
if (tag != null && tag.contains(TAG_PLOT_SIZE, Constants.NBT.TAG_LONG)) {
BlockPos size = BlockPos.fromLong(tag.getLong(TAG_PLOT_SIZE));
lines.add(GuiText.StoredSize.text(size.getX(), size.getY(), size.getZ()));
}
}
@@ -85,70 +94,80 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
}
@Override
public RegistryKey<World> getStoredDimension(final ItemStack is) {
public int getAllocatedPlotId(final ItemStack is) {
final CompoundNBT c = is.getTag();
if (c != null && c.contains(TAG_DIMENSION_ID)) {
if (c != null && c.contains(TAG_PLOT_ID)) {
try {
ResourceLocation worldId = new ResourceLocation(c.getString(TAG_DIMENSION_ID));
return RegistryKey.func_240903_a_(Registry.WORLD_KEY, worldId);
int plotId = c.getInt(TAG_PLOT_ID);
if (SpatialStoragePlotManager.INSTANCE.getPlot(plotId) == null) {
return -1;
}
return plotId;
} catch (Exception e) {
AELog.warn("Failed to retrieve storage cell dimension.", e);
AELog.warn("Failed to retrieve spatial storage dimension: %s", e);
}
}
return null;
return -1;
}
@Override
public TransitionResult doSpatialTransition(final ItemStack is, final ServerWorld w, final WorldCoord min,
public boolean doSpatialTransition(final ItemStack is, final ServerWorld w, final WorldCoord min,
final WorldCoord max, int playerId) {
final int targetX = max.x - min.x - 1;
final int targetY = max.y - min.y - 1;
final int targetZ = max.z - min.z - 1;
final int maxSize = this.getMaxStoredDim(is);
if (targetX > maxSize && targetY > maxSize && targetZ > maxSize) {
AELog.info(
"Failing spatial transition because the transfer area (%dx%dx%d) exceeds the cell capacity (%s).",
targetX, targetY, targetZ, maxSize);
return false;
}
final BlockPos targetSize = new BlockPos(targetX, targetY, targetZ);
ISpatialDimension manager = SpatialDimensionManager.INSTANCE;
SpatialStoragePlotManager manager = SpatialStoragePlotManager.INSTANCE;
RegistryKey<World> worldId = this.getStoredDimension(is);
if (worldId == null || manager.getWorld(worldId) == null) {
worldId = manager.createNewCellDimension(targetSize);
SpatialStoragePlot plot = SpatialStoragePlotManager.INSTANCE.getPlot(this.getAllocatedPlotId(is));
if (plot != null) {
// Check that the existing plot has the right size
if (!plot.getSize().equals(targetSize)) {
AELog.info(
"Failing spatial transition because the transfer area (%dx%dx%d) does not match the spatial storage plot's size (%s).",
targetX, targetY, targetZ, plot.getSize());
return false;
}
} else {
// Otherwise allocate a new one
plot = manager.allocatePlot(targetSize, playerId);
}
if (worldId == null) {
// Failed to create the dimension
return new TransitionResult(false, 0);
}
// Store some information about this transition in the plot
TransitionInfo info = new TransitionInfo(w.func_234923_W_().func_240901_a_(), min.getBlockPos(),
max.getBlockPos(), Instant.now());
manager.setLastTransition(plot.getId(), info);
try {
if (manager.isCellDimension(worldId)) {
ServerWorld cellWorld = manager.getWorld(worldId);
ServerWorld cellWorld = manager.getWorld();
BlockPos scale = manager.getCellDimensionSize(worldId);
BlockPos offset = plot.getOrigin();
if (scale.equals(targetSize)) {
if (targetX <= maxSize && targetY <= maxSize && targetZ <= maxSize) {
BlockPos offset = manager.getCellDimensionOrigin(worldId);
this.setStoredDimension(is, plot.getId(), plot.getSize());
SpatialStorageHelper.getInstance().swapRegions(w, min.x + 1, min.y + 1, min.z + 1, cellWorld, offset.getX(),
offset.getY(), offset.getZ(), targetX - 1, targetY - 1, targetZ - 1);
this.setStoredDimension(is, worldId);
StorageHelper.getInstance().swapRegions(w, min.x + 1, min.y + 1, min.z + 1, cellWorld,
offset.getX(), offset.getY(), offset.getZ(), targetX - 1, targetY - 1, targetZ - 1);
return new TransitionResult(true, 0);
}
}
}
return new TransitionResult(false, 0);
return true;
} finally {
// clean up newly created dimensions that failed transfer
if (manager.isCellDimension(worldId) && this.getStoredDimension(is) == null) {
manager.deleteCellDimension(worldId);
if (this.getAllocatedPlotId(is) == -1) {
manager.freePlot(plot.getId(), true);
}
}
}
private void setStoredDimension(final ItemStack is, RegistryKey<World> worldId) {
public void setStoredDimension(final ItemStack is, int plotId, BlockPos size) {
final CompoundNBT c = is.getOrCreateTag();
c.putString(TAG_DIMENSION_ID, worldId.func_240901_a_().toString());
c.putInt(TAG_PLOT_ID, plotId);
c.putLong(TAG_PLOT_SIZE, size.toLong());
}
}
@@ -32,7 +32,6 @@ import net.minecraft.block.BlockState;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemModelsProperties;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.item.SnowballItem;
@@ -69,7 +68,6 @@ import appeng.block.networking.CableBusBlock;
import appeng.block.paint.PaintSplotchesBlock;
import appeng.core.AEConfig;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.core.localization.GuiText;
import appeng.helpers.IMouseWheelItem;
import appeng.hooks.IBlockTool;
@@ -107,15 +105,6 @@ public class ColorApplicatorItem extends AEBasePoweredItem
public ColorApplicatorItem(Item.Properties props) {
super(AEConfig.instance().getColorApplicatorBattery(), props);
ItemModelsProperties.func_239418_a_(this, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> {
// If the stack has no color, don't use the colored model since the impact of
// calling getColor for every quad is extremely high, if the stack tries to
// re-search its
// inventory for a new paintball everytime
AEColor col = getActiveColor(itemStack);
return (col != null) ? 1 : 0;
});
}
@Override
-1
View File
@@ -176,7 +176,6 @@ public class Grid implements IGrid {
}
gridNode.getGridProxy().gridChanged();
// postEventTo( gridNode, networkChanged );
}
@Override
+1 -1
View File
@@ -502,7 +502,7 @@ public class EnergyGridCache implements IEnergyGrid {
private void removeRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
this.requesters.add(requester);
this.requesters.remove(requester);
}
private void addProvider(IAEPowerStorage provider) {
@@ -1,105 +0,0 @@
package appeng.mixins;
import java.util.Map;
import java.util.concurrent.Executor;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import net.minecraft.server.IDynamicRegistries;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.Dimension;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraft.world.border.IBorderListener;
import net.minecraft.world.border.WorldBorder;
import net.minecraft.world.chunk.listener.IChunkStatusListener;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.DerivedWorldInfo;
import net.minecraft.world.storage.IServerConfiguration;
import net.minecraft.world.storage.IServerWorldInfo;
import net.minecraft.world.storage.SaveFormat;
import appeng.hooks.DynamicDimensions;
@Mixin(MinecraftServer.class)
public class MinecraftServerMixin implements DynamicDimensions {
@Shadow()
private IDynamicRegistries.Impl field_240767_f_;
@Shadow
private Map<RegistryKey<World>, ServerWorld> worlds;
@Shadow
private IServerConfiguration field_240768_i_;
@Shadow
private Executor backgroundExecutor;
@Shadow
private SaveFormat.LevelSave anvilConverterForAnvilFile;
public ServerWorld addWorld(RegistryKey<World> worldId, RegistryKey<DimensionType> dimensionTypeId,
ChunkGenerator chunkGenerator) {
Preconditions.checkArgument(!worlds.containsKey(worldId), "World with id %s already exists.",
worldId.func_240901_a_());
// Each worlds must have a corresponding dimension options, otherwise they will
// not be re-created on load
DimensionGeneratorSettings generatorOptions = this.field_240768_i_.getDimensionGeneratorSettings();
Preconditions.checkArgument(!generatorOptions.func_236224_e_().containsKey(worldId.func_240901_a_()),
"Dimension config with id %s already exists.", worldId.func_240901_a_());
DimensionType dimensionType = field_240767_f_.func_230520_a_().getValueForKey(dimensionTypeId);
Preconditions.checkArgument(dimensionType != null, "dimensionTypeId %s is not registered", dimensionTypeId);
// Create dimension options with the given world-id and chunk generator
Dimension dimensionOptions = new Dimension(
() -> field_240767_f_.func_230520_a_().getValueForKey(dimensionTypeId), chunkGenerator);
IServerWorldInfo serverWorldProperties = this.field_240768_i_.func_230407_G_();
// This sucks a little, but during startup, the server will use the same
// listener for every world,
// but it is ultimately only stored in the chunk storage. So we retrieve it from
// the overworld to
// mirror the original code as much as possible
ServerWorld overworld = worlds.get(ServerWorld.field_234918_g_);
Preconditions.checkState(overworld != null, "Overworld does not exist!");
IChunkStatusListener worldGenerationProgressListener = ((ThreadedAnvilChunkStorageAccessor) overworld
.getChunkProvider().chunkManager).getWorldGenerationProgressListener();
// Inherit seed + WorldBorder from overworld
long seed = overworld.getSeed();
WorldBorder worldBorder = overworld.getWorldBorder();
MinecraftServer self = (MinecraftServer) (Object) this;
DerivedWorldInfo unmodifiableLevelProperties = new DerivedWorldInfo(this.field_240768_i_,
serverWorldProperties);
ServerWorld world = new ServerWorld(self, this.backgroundExecutor, this.anvilConverterForAnvilFile,
unmodifiableLevelProperties, worldId, dimensionTypeId, dimensionType, worldGenerationProgressListener,
chunkGenerator, false, seed, ImmutableList.of(), false);
worldBorder.addListener(new IBorderListener.Impl(world.getWorldBorder()));
this.worlds.put(worldId, world);
// Adding it here will cause the world to be re-created on server restart
RegistryKey<Dimension> dimOptKey = RegistryKey.func_240903_a_(Registry.DIMENSION_KEY, worldId.func_240901_a_());
generatorOptions.func_236224_e_().register(dimOptKey, dimensionOptions);
generatorOptions.func_236224_e_().func_239662_d_(dimOptKey); // Otherwise it wont be saved
// Ensure the save properties are saved, or the world will potentially be lost
// on restart
this.anvilConverterForAnvilFile.func_237288_a_(this.field_240767_f_, this.field_240768_i_,
self.getPlayerList().getHostPlayerData());
return world;
}
}
@@ -0,0 +1,38 @@
package appeng.mixins.spatial;
import java.util.List;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import net.minecraft.util.RegistryKey;
import net.minecraft.world.Dimension;
import appeng.spatial.SpatialStorageDimensionIds;
/**
* This Mixin tries to hide the screen that warns users about experimental
* features being used, but only if AE2's dimension is the only added dimension.
*/
@Mixin(Dimension.class)
public class DimensionOptionMixin {
/**
* This injects right after the method makes a local copy of all present
* dimensions, and modifies the list by removing our mod-provided dimension from
* it.
* <p>
* This means Vanilla will perform it's check whether it should display an
* experimental warning without considering our dimension.
*/
@ModifyVariable(method = "func_236060_a_", at = @At(value = "INVOKE_ASSIGN", ordinal = 0, target = "Lcom/google/common/collect/Lists;newArrayList(Ljava/lang/Iterable;)Ljava/util/ArrayList;", remap = false), allow = 1)
private static List<Map.Entry<RegistryKey<Dimension>, Dimension>> overrideExperimentalCheck(
List<Map.Entry<RegistryKey<Dimension>, Dimension>> dimensions) {
// this only removes our dimension from the check
dimensions.removeIf(e -> e.getKey() == SpatialStorageDimensionIds.DIMENSION_ID);
return dimensions;
}
}
@@ -1,4 +1,4 @@
package appeng.mixins;
package appeng.mixins.spatial;
import java.util.OptionalLong;
@@ -11,15 +11,20 @@ import net.minecraft.server.IDynamicRegistries;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.DimensionType;
import appeng.spatial.SpatialDimensionManager;
import appeng.spatial.SpatialStorageDimensionIds;
/**
* Adds the storage cell world dimension type as a built-in dimension type. This
* can be registered as a JSON file as well, but doing so will trigger an
* experimental feature warning when the world is being loaded.
*/
@Mixin(value = DimensionType.class)
public class DimensionTypeMixin {
@Inject(method = "func_236027_a_", at = @At("TAIL"))
private static void addRegistryDefaults(IDynamicRegistries.Impl registryTracker, CallbackInfoReturnable<?> cir) {
registryTracker.func_239774_a_(SpatialDimensionManager.STORAGE_DIMENSION_TYPE,
registryTracker.func_239774_a_(SpatialStorageDimensionIds.DIMENSION_TYPE_ID,
new DimensionType(OptionalLong.of(12000), false, false, false, false, false, false, true, false, false,
256, BlockTags.INFINIBURN_OVERWORLD.getName(), 1.0f));
@@ -1,4 +1,4 @@
package appeng.mixins;
package appeng.mixins.spatial;
import java.util.Optional;
@@ -11,7 +11,8 @@ import net.minecraft.client.world.DimensionRenderInfo;
import net.minecraft.util.RegistryKey;
import net.minecraft.world.DimensionType;
import appeng.spatial.SpatialDimensionManager;
import appeng.spatial.SpatialStorageDimensionIds;
import appeng.spatial.SpatialStorageSkyProperties;
@Mixin(DimensionRenderInfo.class)
public class SkyPropertiesMixin {
@@ -19,8 +20,8 @@ public class SkyPropertiesMixin {
@Inject(method = "func_239215_a_", at = @At("HEAD"), cancellable = true)
private static void byDimensionType(Optional<RegistryKey<DimensionType>> optional,
CallbackInfoReturnable<DimensionRenderInfo> ci) {
if (optional.orElse(null) == SpatialDimensionManager.STORAGE_DIMENSION_TYPE) {
ci.setReturnValue(SpatialDimensionManager.STORAGE_SKY);
if (optional.orElse(null) == SpatialStorageDimensionIds.DIMENSION_TYPE_ID) {
ci.setReturnValue(SpatialStorageSkyProperties.INSTANCE);
}
}
@@ -1,4 +1,4 @@
package appeng.mixins;
package appeng.mixins.spatial;
import com.mojang.blaze3d.matrix.MatrixStack;
@@ -12,7 +12,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.WorldRenderer;
import appeng.client.render.SpatialSkyRender;
import appeng.spatial.SpatialDimensionManager;
import appeng.spatial.SpatialStorageDimensionIds;
@Mixin(value = WorldRenderer.class)
public class SkyRenderMixin {
@@ -23,7 +23,7 @@ public class SkyRenderMixin {
@SuppressWarnings("ConstantConditions")
@Inject(method = "renderSky(Lcom/mojang/blaze3d/matrix/MatrixStack;F)V", at = @At("HEAD"), cancellable = true)
public void renderSky(MatrixStack matrices, float tickDelta, CallbackInfo ci) {
if (mc.world.func_234922_V_() == SpatialDimensionManager.STORAGE_DIMENSION_TYPE) {
if (mc.world.func_234922_V_() == SpatialStorageDimensionIds.DIMENSION_TYPE_ID) {
SpatialSkyRender.getInstance().render(matrices);
ci.cancel();
}
@@ -0,0 +1,15 @@
package appeng.mixins.unlitquad;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@Mixin(BakedQuad.class)
public interface BakedQuadAccessor {
@Accessor
TextureAtlasSprite getSprite();
}
@@ -0,0 +1,37 @@
package appeng.mixins.unlitquad;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.BlockModel;
import net.minecraft.client.renderer.model.BlockPart;
import net.minecraft.client.renderer.model.BlockPartFace;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import appeng.hooks.UnlitQuadHooks;
/**
* This mixin hooks into conversion from {@link BlockPartFace} to
* {@link BakedQuad} to apply our unlit extensions if the block part face is an
* instance of our marker class
* {@link appeng.hooks.UnlitQuadHooks.UnlitBlockPartFace}.
*/
@Mixin(BlockModel.class)
public class BlockModelMixin {
@Inject(method = "bakeFace", at = @At("RETURN"), cancellable = true, require = 1, allow = 1)
private static void onBakeFace(BlockPart partIn, BlockPartFace partFaceIn, TextureAtlasSprite spriteIn,
Direction directionIn, IModelTransform transformIn, ResourceLocation locationIn,
CallbackInfoReturnable<BakedQuad> cri) {
if (partFaceIn instanceof UnlitQuadHooks.UnlitBlockPartFace) {
cri.setReturnValue(UnlitQuadHooks.makeUnlit(cri.getReturnValue()));
}
}
}
@@ -0,0 +1,35 @@
package appeng.mixins.unlitquad;
import java.lang.reflect.Type;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.renderer.model.BlockPartFace;
import appeng.hooks.UnlitQuadHooks;
/**
* This mixin will call the hook to deserialize the unlit property, but only if
* we are currently deserializing an AE2 model.
*/
@Mixin(BlockPartFace.Deserializer.class)
public class BlockPartFaceDeserializerMixin {
@Inject(method = "deserialize", at = @At("RETURN"), cancellable = true, allow = 1, remap = false)
public void onDeserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext,
CallbackInfoReturnable<BlockPartFace> cri) {
if (!UnlitQuadHooks.isUnlitExtensionEnabled()) {
return; // Not in a model that activated the deserializer
}
BlockPartFace modelElement = cri.getReturnValue();
cri.setReturnValue(UnlitQuadHooks.enhanceModelElementFace(modelElement, jsonElement));
}
}
@@ -0,0 +1,34 @@
package appeng.mixins.unlitquad;
import java.io.IOException;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.renderer.model.BlockModel;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.util.ResourceLocation;
import appeng.hooks.UnlitQuadHooks;
/**
* The only job of this mixin is to only enable the unlit extensions if the
* model is whitelisted for it, which is decided in {@link UnlitQuadHooks}.
*/
@Mixin(ModelBakery.class)
public class ModelBakeryMixin {
@Inject(method = "loadModel", at = @At("HEAD"), allow = 1)
protected void onBeginLoadModel(ResourceLocation location, CallbackInfoReturnable<BlockModel> cri)
throws IOException {
UnlitQuadHooks.beginDeserializingModel(location);
}
@Inject(method = "loadModel", at = @At("RETURN"))
protected void onEndLoadModel(ResourceLocation location, CallbackInfoReturnable<BlockModel> cri) {
UnlitQuadHooks.endDeserializingModel();
}
}

Some files were not shown because too many files have changed in this diff Show More