Compare commits

...

58 Commits

Author SHA1 Message Date
Sebastian Hartte 252cc859ad Texture Update Credits 2020-10-03 11:55:54 +02:00
yueh 9c0dccca59 Updated grindstone textures 2020-09-27 00:09:09 +02:00
Sebastian Hartte 4eaa0cc5cb Missing files 2020-09-26 23:06:42 +02:00
Sebastian Hartte 7cb6265f9f Updated textures. 2020-09-26 21:39:26 +02:00
yueh 0e02eb6538 Update fluid p2p to use a green texture 2020-09-25 13:29:17 +02:00
yueh 30ac8d59f7 Updated fluid related recipes to use green dye 2020-09-25 13:28:58 +02:00
yueh 915155fb7e Potentially fixed inscriber textures 2020-09-25 12:43:55 +02:00
yueh 197f994dde Fixed quartz ore item missing texture
Also added an _ to all variants for readability
2020-09-25 12:43:55 +02:00
yueh 89173fd94f Update energy cells to now 5 states 2020-09-25 12:43:54 +02:00
yueh 996698c022 Update models for unlit loader 2020-09-25 12:43:54 +02:00
Kal Chikhou 95ea2c6559 AE2 Retexturing (#4610) 2020-09-25 12:43:54 +02:00
Sebastian Hartte b8f48407cd Fix tooltip rendering. 2020-09-20 01:06:53 +02:00
Sebastian Hartte 489b0f635e Merge remote-tracking branch 'origin/8.0.x-1.16.1' 2020-09-20 00:42:52 +02:00
Sebastian Hartte cacd824db3 Remove unused field indicating availability of client classes. 2020-09-19 18:20:11 +02:00
yueh 876bb52087 Update forge mappings to 20200916-1.16.2 (#4749) 2020-09-19 17:32:23 +02:00
Sebastian Hartte 76efe6026d Add an indicator that shows the number of active crafting jobs. 2020-09-18 21:34:42 +02:00
yueh 4e03cbd356 Simply build all branches 2020-09-18 10:32:06 +02:00
yueh 9005db6f1c Fix yaml syntax 2020-09-17 21:42:20 +02:00
yueh 58afe755b8 Build PRs for all release branches (#4746) 2020-09-17 21:37:53 +02:00
Sebastian Hartte 1759f92164 Prevent FG from force-exiting the daemon if runData is used. 2020-09-16 19:51:22 +02:00
Sebastian Hartte e50c13e570 Rolled back the memory change since it'll cause a daemon to launch even during a CI build. 2020-09-16 19:29:47 +02:00
Sebastian Hartte 749dd35f88 Updated forge and increased memory for IDE-sync daemon. 2020-09-16 18:18:22 +02:00
Sebastian Hartte ca79a377bd Merge remote-tracking branch 'origin/8.0.x-1.16.1'
# Conflicts:
#	gradle/scripts/dependencies.gradle
2020-09-16 17:49:59 +02:00
Sebastian Hartte 475c8ff5a1 Adapt the same sorting logic used for items stored in the network for items obtained from patterns, which fixes items from patterns not being able to be shift-clicked into new patterns. 2020-09-16 17:44:49 +02:00
Sebastian Hartte e73dbe4891 Updated Forge / MC to 1.16.3
Keep Mappings
Allow higher range for MC + Forge versions
2020-09-14 02:02:59 +02:00
yueh 621d2ee715 Fixes #4728: Mark all offloading threads as daemons (#4729) 2020-09-13 11:55:18 +02:00
yueh b8e53adf40 Fixes #4719: Take the entity size into account when spawning item entities (#4720) 2020-09-10 17:54:02 +02:00
yueh 44544c598f Fixes #4253: Just transfer the recipe id instead of every ingredient. (#4689)
* Fixes #4253: Just transfer the recipe id instead of every ingredient.
* If possible handle any IRecipe for processing mode
* Improvements and support for AE2 facades.
* Switched to using JEI's displayed stacks (which means we can remove the shapeless variant).

Co-authored-by: Sebastian Hartte <sebastian@hartte.de>
2020-09-09 14:08:24 +02:00
Sebastian Hartte bcee2ec427 Slightly increased the height of the item hitbox for crystals to make their pickup by annihilation planes less "clippy". 2020-09-09 02:23:58 +02:00
Sebastian Hartte 9e41d543f5 Merge remote-tracking branch 'origin/8.0.x-1.16.1' 2020-09-09 00:59:58 +02:00
Sebastian Hartte 0f469e9df6 Bumped Forge version. 2020-09-07 23:34:56 +02:00
Sebastian Hartte 12ca8d109a Merge remote-tracking branch 'origin/8.0.x-1.16.1' 2020-09-02 02:55:12 +02:00
shartte b756d68be1 Implemented a cache with maximum quad-count it will cache for the cable bus, (#4670)
which also fixes concurrent access to the hashmap.
2020-09-01 18:20:51 +02:00
Sebastian Hartte 60b07e5ca5 Merge branch '8.0.x-1.16.1' 2020-09-01 01:07:47 +02:00
shartte 957bc4c5cc Fixes removal of facades not invalidating the cached server-side collision boxes. (#4663) 2020-08-31 23:10:25 +02:00
yueh e90dd2f9c6 Serialize the complete NBT data to avoid mismatches (#4665)
This might increase the network traffic a bit, but the amount of mods actually using the share tag seems to be very limited.
For now it is worth the risk as it solves the problem. In case we run into actual issues, there might still be other solutions, which will be way more complex and can potentially introduce additional problems.
2020-08-31 23:09:14 +02:00
Sebastian Hartte 9719c7ffc3 Bump to Forge 33.0.22 2020-08-29 23:13:29 +02:00
Sebastian Hartte 319d92a371 Merge branch '8.0.x-1.16.1' 2020-08-29 22:18:12 +02:00
Masakitenchi 3a0552c56e Update zh_cn.json (#4653) 2020-08-28 10:49:11 +02:00
Sebastian Hartte 8a0dd192e5 Added Modmaven repository to README.md 2020-08-26 23:19:42 +02:00
Sebastian Hartte a97b35f3d0 Merge branch '8.0.x-1.16.1' 2020-08-26 11:39:20 +02:00
Sebastian Hartte 1394ab0863 Merge branch '8.0.x-1.16.1' 2020-08-24 23:54:57 +02:00
Sebastian Hartte 159f4c7f14 Merge branch '8.0.x-1.16.1' 2020-08-24 22:33:38 +02:00
Sebastian Hartte ee7fe9f40d Merge branch '8.0.x-1.16.1' 2020-08-24 01:06:50 +02:00
Sebastian Hartte 9c9a49f9e7 Merge branch '8.0.x-1.16.1' 2020-08-23 20:48:19 +02:00
Sebastian Hartte b7949e4134 Re-Enabled JEI and TOP in dev. 2020-08-22 19:56:37 +02:00
Sebastian Hartte ea95913ec8 Merge branch '8.0.x-1.16.1' 2020-08-22 19:38:36 +02:00
shartte 33d7f02323 Fixes #4590: Crystal seeds (other than certus) don't display their growth stages. (#4619) 2020-08-19 16:43:47 +02:00
shartte b8d4f0cffa Fixes #4611: Use of client-side only method for Tiny TNT explosion. (#4612) 2020-08-18 01:35:31 +02:00
yueh 7e1bfdb5ac Added step to publish to modmaven (#4607) 2020-08-17 22:28:01 +02:00
shartte 1f9707e256 Fixes #4602: Prevent encoding invalid patterns and handle corrupted patterns a little more gracefully. (#4608) 2020-08-17 21:50:28 +02:00
shartte 954ce1442e Fixes #4598: Incorrectly rotated face for determining block lightlevel in ME Chest renderer. (#4599) 2020-08-17 21:43:16 +02:00
Sebastian Hartte ee67c5ea50 Use different naming for fullbright, and always reset it back after setting it. 2020-08-16 14:05:10 +02:00
Sebastian Hartte 73735c5cd5 Remove use of func_244388_a, which is client-only. 2020-08-15 17:29:36 +02:00
Sebastian Hartte c1713f1682 Bump to Forge 33.0.5 2020-08-15 14:32:53 +02:00
Sebastian Hartte f455fd1994 Initial port to 1.16.2 2020-08-13 23:29:55 +02:00
Sebastian Hartte 1657c88681 Initial port to 1.16.2 2020-08-13 23:15:09 +02:00
Sebastian Hartte fd67e0e5c6 Initial port to 1.16.2 2020-08-13 23:14:49 +02:00
521 changed files with 2388 additions and 1096 deletions
+2 -1
View File
@@ -2,7 +2,8 @@ name: 'Build PRs'
on: on:
pull_request: pull_request:
branches: [ master ] branches:
- '*'
jobs: jobs:
build: build:
+15 -6
View File
@@ -25,9 +25,9 @@ A Mod about Matter, Energy and using them to conquer the world..
## Contacts ## Contacts
* [Website](http://ae-mod.info/) * [Website](http://ae-mod.info/)
* [IRC #appliedenergistics on esper.net](http://webchat.esper.net/?channels=appliedenergistics&prompt=1)
* [GitHub](https://github.com/AppliedEnergistics/Applied-Energistics-2)
* [Discord](https://discord.gg/GygKjjm) * [Discord](https://discord.gg/GygKjjm)
* [GitHub](https://github.com/AppliedEnergistics/Applied-Energistics-2)
* [IRC #appliedenergistics on esper.net](http://webchat.esper.net/?channels=appliedenergistics&prompt=1)
## License ## License
@@ -38,7 +38,7 @@ A Mod about Matter, Energy and using them to conquer the world..
- (c) 2013 - 2020 AlgorithmX2 et al - (c) 2013 - 2020 AlgorithmX2 et al
- [![License](https://img.shields.io/badge/License-LGPLv3-blue.svg?style=flat-square)](https://raw.githubusercontent.com/AppliedEnergistics/Applied-Energistics-2/rv2/LICENSE) - [![License](https://img.shields.io/badge/License-LGPLv3-blue.svg?style=flat-square)](https://raw.githubusercontent.com/AppliedEnergistics/Applied-Energistics-2/rv2/LICENSE)
* Textures and Models * Textures and Models
- (c) 2013 - 2020 AlgorithmX2 et al - (c) 2020, [Ridanisaurus Rid](https://github.com/Ridanisaurus/), (c) 2013 - 2020 AlgorithmX2 et al
- [![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%203.0-yellow.svg?style=flat-square)](https://creativecommons.org/licenses/by-nc-sa/3.0/) - [![License](https://img.shields.io/badge/License-CC%20BY--NC--SA%203.0-yellow.svg?style=flat-square)](https://creativecommons.org/licenses/by-nc-sa/3.0/)
* Text and Translations * Text and Translations
- [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/) - [![License](https://img.shields.io/badge/License-No%20Restriction-green.svg?style=flat-square)](https://creativecommons.org/publicdomain/zero/1.0/)
@@ -72,12 +72,20 @@ The API for Applied Energistics 2. It is open source to discuss changes, improve
### Maven ### Maven
We use Github Packages as maven repository now. You can use the following snippet as example on how to add a repository to your gradle build file. Our authoritative Maven repository is Github Packages, which you can also use in your builds. Use of Github Packages
[requires special setup](https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-gradle-for-use-with-github-packages#authenticating-to-github-packages)
to authenticate with your personal access token.
AE2 is also available without authentication from Modmaven. You can use the following snippet as example on how to add a repository to your gradle build file.
repositories { repositories {
maven { maven {
name "AE2" name "Modmaven"
url "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2" url "https://modmaven.k-4u.nl/"
// For Gradle 5.1 and above, limit it to just AE2
content {
includeGroup 'appeng'
}
} }
} }
@@ -177,4 +185,5 @@ Thanks to
* Notch et al for Minecraft * Notch et al for Minecraft
* Lex et al for MinecraftForge * Lex et al for MinecraftForge
* AlgorithmX2 for AppliedEnergistics2 * AlgorithmX2 for AppliedEnergistics2
* [Ridanisaurus Rid](https://github.com/Ridanisaurus/) for the new 2020 textures
* all [contributors](https://github.com/AppliedEnergistics/Applied-Energistics-2/graphs/contributors) * all [contributors](https://github.com/AppliedEnergistics/Applied-Energistics-2/graphs/contributors)
+5 -2
View File
@@ -54,11 +54,11 @@ dependencies {
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
// compile against provided APIs // compile against provided APIs
compileOnly "mezz.jei:jei-${minecraft_version}:${jei_version}:api" compileOnly "mezz.jei:jei-${jei_minecraft_version}:${jei_version}:api"
compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api" compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api"
// Runtime, Mods // Runtime, Mods
runtimeOnly fg.deobf("mezz.jei:jei-${minecraft_version}:${jei_version}") runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}") runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}")
// unit test dependencies // unit test dependencies
@@ -157,6 +157,9 @@ minecraft {
data { data {
property 'forge.logging.console.level', 'debug' property 'forge.logging.console.level', 'debug'
workingDirectory project.file('run') workingDirectory project.file('run')
// ForgeGradle will just force-exit the Gradle Daemon which fails our builds in case
// a daemon is used for any reason.
forceExit false
args '--mod', 'appliedenergistics2', '--all', '--output', file('src/generated/resources/') args '--mod', 'appliedenergistics2', '--all', '--output', file('src/generated/resources/')
mods { mods {
appliedenergistics2 { appliedenergistics2 {
+8 -7
View File
@@ -9,23 +9,24 @@ artifact_basename=appliedenergistics2
# Minecraft Versions # # Minecraft Versions #
######################################################### #########################################################
minecraft_release=1.16 minecraft_release=1.16
minecraft_version=1.16.1 minecraft_version=1.16.3
mcp_mappings=20200723-1.16.1 mcp_mappings=20200916-1.16.2
forge_version=32.0.108 forge_version=34.0.8
######################################################### #########################################################
# Provided APIs # # Provided APIs #
######################################################### #########################################################
jei_version=7.0.0.6 jei_minecraft_version=1.16.2
top_version=3.0.1-beta-4 jei_version=7.3.2.25
top_version=3.0.3-beta-6
hwyla_version=1.10.8-B72_1.15.2 hwyla_version=1.10.8-B72_1.15.2
ctm_version=MC1.15.2-1.1.0.9 ctm_version=MC1.15.2-1.1.0.9
######################################################### #########################################################
# Deployment # # Deployment #
######################################################### #########################################################
website_version=1.16.1 website_version=1.16.2
curse_versions=1.16.1 curse_versions=1.16.2
curseforge_project=223794 curseforge_project=223794
######################################################### #########################################################
@@ -27,13 +27,14 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType; import net.minecraft.world.DimensionType;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World;
/** /**
* Represents a location in the Minecraft Universe * Represents a location in the Minecraft Universe
*/ */
public class DimensionalCoord extends WorldCoord { public class DimensionalCoord extends WorldCoord {
private final IWorld world; private final World world;
private final DimensionType dimension; private final DimensionType dimension;
public DimensionalCoord(final DimensionalCoord coordinate) { public DimensionalCoord(final DimensionalCoord coordinate) {
@@ -45,19 +46,19 @@ public class DimensionalCoord extends WorldCoord {
public DimensionalCoord(final TileEntity tileEntity) { public DimensionalCoord(final TileEntity tileEntity) {
super(tileEntity); super(tileEntity);
this.world = tileEntity.getWorld(); this.world = tileEntity.getWorld();
this.dimension = this.world.func_230315_m_(); this.dimension = this.world.getDimensionType();
} }
public DimensionalCoord(final IWorld world, final int x, final int y, final int z) { public DimensionalCoord(final World world, final int x, final int y, final int z) {
super(x, y, z); super(x, y, z);
this.world = world; this.world = world;
this.dimension = world.func_230315_m_(); this.dimension = world.getDimensionType();
} }
public DimensionalCoord(final IWorld world, final BlockPos pos) { public DimensionalCoord(final World world, final BlockPos pos) {
super(pos); super(pos);
this.world = world; this.world = world;
this.dimension = world.func_230315_m_(); this.dimension = world.getDimensionType();
} }
@Override @Override
@@ -84,7 +85,7 @@ public class DimensionalCoord extends WorldCoord {
return this.world == world; return this.world == world;
} }
public IWorld getWorld() { public World getWorld() {
return this.world; return this.world;
} }
@@ -111,11 +111,6 @@ public abstract class AEBaseTileBlock<T extends AEBaseTileEntity> extends AEBase
return this.tileEntityFactory.get(); return this.tileEntityFactory.get();
} }
@Override
public void dropXpOnBlockBreak(World worldIn, BlockPos pos, int amount) {
super.dropXpOnBlockBreak(worldIn, pos, amount);
}
@Override @Override
public void onReplaced(BlockState state, World w, BlockPos pos, BlockState newState, boolean isMoving) { public void onReplaced(BlockState state, World w, BlockPos pos, BlockState newState, boolean isMoving) {
if (newState.getBlock() == state.getBlock()) { if (newState.getBlock() == state.getBlock()) {
@@ -35,7 +35,9 @@ import appeng.tile.networking.EnergyCellTileEntity;
public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellTileEntity> { public class EnergyCellBlock extends AEBaseTileBlock<EnergyCellTileEntity> {
public static final IntegerProperty ENERGY_STORAGE = IntegerProperty.create("fullness", 0, 7); public static final int MAX_FULLNESS = 4;
public static final IntegerProperty ENERGY_STORAGE = IntegerProperty.create("fullness", 0, MAX_FULLNESS);
public EnergyCellBlock() { public EnergyCellBlock() {
super(defaultProps(AEMaterials.GLASS)); super(defaultProps(AEMaterials.GLASS));
@@ -79,10 +79,10 @@ class PaintSplotchesBakedModel implements IDynamicBakedModel {
if (s.isLumen()) { if (s.isLumen()) {
builder.setColorRGB(s.getColor().whiteVariant); builder.setColorRGB(s.getColor().whiteVariant);
builder.setRenderFullBright(true); builder.setEmissiveMaterial(true);
} else { } else {
builder.setColorRGB(s.getColor().mediumVariant); builder.setColorRGB(s.getColor().mediumVariant);
builder.setRenderFullBright(false); builder.setEmissiveMaterial(false);
} }
float offset = offsetConstant; float offset = offsetConstant;
@@ -167,7 +167,7 @@ class PaintSplotchesBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -117,7 +117,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
if (formedState.isPowered()) { if (formedState.isPowered()) {
builder.setTexture(this.lightCornerTexture); builder.setTexture(this.lightCornerTexture);
builder.setRenderFullBright(true); builder.setEmissiveMaterial(true);
for (Direction facing : Direction.values()) { for (Direction facing : Direction.values()) {
// Offset the face by a slight amount so that it is drawn over the already drawn // Offset the face by a slight amount so that it is drawn over the already drawn
// ring texture // ring texture
@@ -131,6 +131,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
DEFAULT_RENDER_MIN - zOffset, DEFAULT_RENDER_MAX + xOffset, DEFAULT_RENDER_MIN - zOffset, DEFAULT_RENDER_MAX + xOffset,
DEFAULT_RENDER_MAX + yOffset, DEFAULT_RENDER_MAX + zOffset); DEFAULT_RENDER_MAX + yOffset, DEFAULT_RENDER_MAX + zOffset);
} }
builder.setEmissiveMaterial(false);
} }
} else { } else {
builder.setTexture(this.ringTexture); builder.setTexture(this.ringTexture);
@@ -143,7 +144,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
if (formedState.isPowered()) { if (formedState.isPowered()) {
builder.setTexture(this.lightTexture); builder.setTexture(this.lightTexture);
builder.setRenderFullBright(true); builder.setEmissiveMaterial(true);
for (Direction facing : Direction.values()) { for (Direction facing : Direction.values()) {
// Offset the face by a slight amount so that it is drawn over the already drawn // Offset the face by a slight amount so that it is drawn over the already drawn
// ring texture // ring texture
@@ -202,7 +203,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -160,7 +160,7 @@ class BlockDefinitionBuilder implements IBlockBuilder {
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void setup() { public void setup() {
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:fill_level"), ItemModelsProperties.registerProperty(item, new ResourceLocation("appliedenergistics2:fill_level"),
(is, world, entity) -> { (is, world, entity) -> {
double curPower = chargeable.getAECurrentPower(is); double curPower = chargeable.getAECurrentPower(is);
double maxPower = chargeable.getAEMaxPower(is); double maxPower = chargeable.getAEMaxPower(is);
@@ -22,6 +22,7 @@ import java.text.NumberFormat;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
@@ -72,14 +73,16 @@ public abstract class AEBaseMEScreen<T extends AEBaseContainer> extends AEBaseSc
currentToolTip.add(ButtonToolTips.ItemsRequestable.text(formattedAmount)); currentToolTip.add(ButtonToolTips.ItemsRequestable.text(formattedAmount));
} }
this.renderToolTip(matrixStack, currentToolTip, x, y, this.font); this.renderToolTip(matrixStack, Lists.transform(currentToolTip, ITextComponent::func_241878_f), x, y,
this.font);
return; return;
} else if (stack.getCount() > bigNumber) { } else if (stack.getCount() > bigNumber) {
final String formattedAmount = NumberFormat.getNumberInstance(Locale.US).format(stack.getCount()); final String formattedAmount = NumberFormat.getNumberInstance(Locale.US).format(stack.getCount());
currentToolTip.add(ButtonToolTips.ItemsStored.text(formattedAmount).mergeStyle(TextFormatting.GRAY)); currentToolTip.add(ButtonToolTips.ItemsStored.text(formattedAmount).mergeStyle(TextFormatting.GRAY));
this.renderToolTip(matrixStack, currentToolTip, x, y, this.font); this.renderToolTip(matrixStack, Lists.transform(currentToolTip, ITextComponent::func_241878_f), x, y,
this.font);
return; return;
} }
@@ -147,7 +147,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
RenderSystem.popMatrix(); RenderSystem.popMatrix();
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
this.func_230459_a_(matrixStack, mouseX, mouseY); this.renderHoveredTooltip(matrixStack, mouseX, mouseY);
for (final Object c : this.buttons) { for (final Object c : this.buttons) {
if (c instanceof ITooltip) { if (c instanceof ITooltip) {
@@ -219,7 +219,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
styledLines.add(lines.get(i).deepCopy().modifyStyle(s -> style)); styledLines.add(lines.get(i).deepCopy().modifyStyle(s -> style));
} }
this.renderTooltip(matrices, styledLines, x, y); this.func_243308_b(matrices, styledLines, x, y);
} }
@@ -211,7 +211,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
try { try {
final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX); final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX);
final CompoundNBT invData = in.getCompound(key); final CompoundNBT invData = in.getCompound(key);
ITextComponent un = ITextComponent.Serializer.func_240643_a_(invData.getString("un")); ITextComponent un = ITextComponent.Serializer.getComponentFromJson(invData.getString("un"));
final ClientDCInternalInv current = this.getById(id, invData.getLong("sortBy"), un); final ClientDCInternalInv current = this.getById(id, invData.getLong("sortBy"), un);
for (int x = 0; x < current.getInventory().getSlots(); x++) { for (int x = 0; x < current.getInventory().getSlots(); x++) {
@@ -51,6 +51,7 @@ import appeng.client.gui.widgets.SettingToggleButton;
import appeng.client.gui.widgets.TabButton; import appeng.client.gui.widgets.TabButton;
import appeng.client.me.InternalSlotME; import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo; import appeng.client.me.ItemRepo;
import appeng.client.render.StackSizeRenderer;
import appeng.container.implementations.CraftingStatusContainer; import appeng.container.implementations.CraftingStatusContainer;
import appeng.container.implementations.MEMonitorableContainer; import appeng.container.implementations.MEMonitorableContainer;
import appeng.container.slot.AppEngSlot; import appeng.container.slot.AppEngSlot;
@@ -295,6 +296,16 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
this.currentMouseX = mouseX; this.currentMouseX = mouseX;
this.currentMouseY = mouseY; this.currentMouseY = mouseY;
// Show the number of active crafting jobs
if (this.craftingStatusBtn != null && container.activeCraftingJobs != -1) {
// The stack size renderer expects a 16x16 slot, while the button is normally
// bigger
int x = this.craftingStatusBtn.x + (this.craftingStatusBtn.getWidth() - 16) / 2;
int y = this.craftingStatusBtn.y + (this.craftingStatusBtn.getHeightRealms() - 16) / 2;
StackSizeRenderer.renderSizeLabel(font, x - this.guiLeft, y - this.guiTop,
String.valueOf(container.activeCraftingJobs));
}
} }
@Override @Override
@@ -359,6 +370,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
if (this.searchField != null) { if (this.searchField != null) {
this.searchField.render(matrixStack, mouseX, mouseY, partialTicks); this.searchField.render(matrixStack, mouseX, mouseY, partialTicks);
} }
} }
protected String getBackground() { protected String getBackground() {
@@ -60,6 +60,6 @@ public class ValidationIcon extends IconButton {
return; return;
} }
screen.renderToolTip(matrices, this.tooltip, x, y, client.fontRenderer); screen.func_243308_b(matrices, this.tooltip, x, y);
} }
} }
@@ -47,8 +47,8 @@ public abstract class DelegateBakedModel implements IBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return baseModel.func_230044_c_(); return baseModel.isSideLit();
} }
@Override @Override
@@ -60,7 +60,7 @@ public class DummyFluidBakedModel implements IBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -73,8 +73,8 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return getBaseModel().func_230044_c_(); return getBaseModel().isSideLit();
} }
@Override @Override
@@ -86,7 +86,7 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
if (!(stack.getItem() instanceof FluidDummyItem)) { if (!(stack.getItem() instanceof FluidDummyItem)) {
return originalModel; return originalModel;
@@ -80,7 +80,7 @@ public class FacadeBakedItemModel extends DelegateBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -50,7 +50,7 @@ public class FacadeDispatcherBakedModel extends DelegateBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
if (!(stack.getItem() instanceof FacadeItem)) { if (!(stack.getItem() instanceof FacadeItem)) {
return originalModel; return originalModel;
@@ -342,7 +342,7 @@ class CableBuilder {
this.addBigCoveredCableSizedCube(facing, cubeBuilder); this.addBigCoveredCableSizedCube(facing, cubeBuilder);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setEmissiveMaterial(true);
cubeBuilder.setTexture(oddChannel); cubeBuilder.setTexture(oddChannel);
cubeBuilder.setColorRGB(cableColor.blackVariant); cubeBuilder.setColorRGB(cableColor.blackVariant);
@@ -353,14 +353,14 @@ class CableBuilder {
this.addBigCoveredCableSizedCube(facing, cubeBuilder); this.addBigCoveredCableSizedCube(facing, cubeBuilder);
// Reset back to normal rendering for the rest // Reset back to normal rendering for the rest
cubeBuilder.setRenderFullBright(false); cubeBuilder.setEmissiveMaterial(false);
cubeBuilder.setTexture(texture); cubeBuilder.setTexture(texture);
} }
addCoveredCableSizedCube(facing, cubeBuilder); addCoveredCableSizedCube(facing, cubeBuilder);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setEmissiveMaterial(true);
cubeBuilder.setTexture(oddChannel); cubeBuilder.setTexture(oddChannel);
cubeBuilder.setColorRGB(cableColor.blackVariant); cubeBuilder.setColorRGB(cableColor.blackVariant);
@@ -369,6 +369,9 @@ class CableBuilder {
cubeBuilder.setTexture(evenChannel); cubeBuilder.setTexture(evenChannel);
cubeBuilder.setColorRGB(cableColor.whiteVariant); cubeBuilder.setColorRGB(cableColor.whiteVariant);
addCoveredCableSizedCube(facing, cubeBuilder); addCoveredCableSizedCube(facing, cubeBuilder);
// Reset back to default
cubeBuilder.setEmissiveMaterial(false);
} }
public void addStraightSmartConnection(Direction facing, AEColor cableColor, int channels, public void addStraightSmartConnection(Direction facing, AEColor cableColor, int channels,
@@ -386,7 +389,7 @@ class CableBuilder {
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setEmissiveMaterial(true);
cubeBuilder.setTexture(oddChannel); cubeBuilder.setTexture(oddChannel);
cubeBuilder.setColorRGB(cableColor.blackVariant); cubeBuilder.setColorRGB(cableColor.blackVariant);
@@ -395,6 +398,9 @@ class CableBuilder {
cubeBuilder.setTexture(evenChannel); cubeBuilder.setTexture(evenChannel);
cubeBuilder.setColorRGB(cableColor.whiteVariant); cubeBuilder.setColorRGB(cableColor.whiteVariant);
addStraightCoveredCableSizedCube(facing, cubeBuilder); addStraightCoveredCableSizedCube(facing, cubeBuilder);
// Reset back to default
cubeBuilder.setEmissiveMaterial(false);
} }
public void addConstrainedSmartConnection(Direction facing, AEColor cableColor, int distanceFromEdge, int channels, public void addConstrainedSmartConnection(Direction facing, AEColor cableColor, int distanceFromEdge, int channels,
@@ -417,7 +423,7 @@ class CableBuilder {
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setEmissiveMaterial(true);
cubeBuilder.setTexture(oddChannel); cubeBuilder.setTexture(oddChannel);
cubeBuilder.setColorRGB(cableColor.blackVariant); cubeBuilder.setColorRGB(cableColor.blackVariant);
@@ -426,6 +432,9 @@ class CableBuilder {
cubeBuilder.setTexture(evenChannel); cubeBuilder.setTexture(evenChannel);
cubeBuilder.setColorRGB(cableColor.whiteVariant); cubeBuilder.setColorRGB(cableColor.whiteVariant);
addCoveredCableSizedCube(facing, distanceFromEdge, cubeBuilder); addCoveredCableSizedCube(facing, distanceFromEdge, cubeBuilder);
// Reset back to default
cubeBuilder.setEmissiveMaterial(false);
} }
public void addDenseCoveredConnection(Direction facing, AEColor cableColor, AECableType connectionType, public void addDenseCoveredConnection(Direction facing, AEColor cableColor, AECableType connectionType,
@@ -449,7 +458,7 @@ class CableBuilder {
addDenseCableSizedCube(facing, cubeBuilder); addDenseCableSizedCube(facing, cubeBuilder);
// Reset back to normal rendering for the rest // Reset back to normal rendering for the rest
cubeBuilder.setRenderFullBright(false); cubeBuilder.setEmissiveMaterial(false);
cubeBuilder.setTexture(texture); cubeBuilder.setTexture(texture);
} }
@@ -485,7 +494,7 @@ class CableBuilder {
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setEmissiveMaterial(true);
cubeBuilder.setTexture(oddChannel); cubeBuilder.setTexture(oddChannel);
cubeBuilder.setColorRGB(cableColor.blackVariant); cubeBuilder.setColorRGB(cableColor.blackVariant);
@@ -496,7 +505,7 @@ class CableBuilder {
addDenseCableSizedCube(facing, cubeBuilder); addDenseCableSizedCube(facing, cubeBuilder);
// Reset back to normal rendering for the rest // Reset back to normal rendering for the rest
cubeBuilder.setRenderFullBright(false); cubeBuilder.setEmissiveMaterial(false);
cubeBuilder.setTexture(texture); cubeBuilder.setTexture(texture);
} }
@@ -529,7 +538,7 @@ class CableBuilder {
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels); TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
// Render the channel indicators brightly lit at night // Render the channel indicators brightly lit at night
cubeBuilder.setRenderFullBright(true); cubeBuilder.setEmissiveMaterial(true);
cubeBuilder.setTexture(oddChannel); cubeBuilder.setTexture(oddChannel);
cubeBuilder.setColorRGB(cableColor.blackVariant); cubeBuilder.setColorRGB(cableColor.blackVariant);
@@ -538,6 +547,9 @@ class CableBuilder {
cubeBuilder.setTexture(evenChannel); cubeBuilder.setTexture(evenChannel);
cubeBuilder.setColorRGB(cableColor.whiteVariant); cubeBuilder.setColorRGB(cableColor.whiteVariant);
addStraightDenseCableSizedCube(facing, cubeBuilder); addStraightDenseCableSizedCube(facing, cubeBuilder);
// Reset back to default
cubeBuilder.setEmissiveMaterial(false);
} }
private static void addDenseCableSizedCube(Direction facing, CubeBuilder cubeBuilder) { private static void addDenseCableSizedCube(Direction facing, CubeBuilder cubeBuilder) {
@@ -331,7 +331,7 @@ public class CableBusBakedModel implements IBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false;// TODO return false;// TODO
} }
@@ -52,7 +52,7 @@ public class CubeBuilder {
private boolean useStandardUV = false; private boolean useStandardUV = false;
private boolean renderFullBright; private boolean emissiveMaterial;
public CubeBuilder(List<BakedQuad> output) { public CubeBuilder(List<BakedQuad> output) {
this.output = output; this.output = output;
@@ -379,7 +379,7 @@ public class CubeBuilder {
if (e.getIndex() == 0) { if (e.getIndex() == 0) {
builder.put(i, u, v); builder.put(i, u, v);
break; break;
} else if (e.getIndex() == 2 && renderFullBright) { } else if (e.getIndex() == 2 && emissiveMaterial) {
// Force Brightness to 15, this is for full bright mode // Force Brightness to 15, this is for full bright mode
// this vertex element will only be present in that case // this vertex element will only be present in that case
final float lightMapU = (float) (15 * 0x20) / 0xFFFF; final float lightMapU = (float) (15 * 0x20) / 0xFFFF;
@@ -434,8 +434,8 @@ public class CubeBuilder {
this.setColorRGB((int) (r * 255) << 16 | (int) (g * 255) << 8 | (int) (b * 255)); this.setColorRGB((int) (r * 255) << 16 | (int) (g * 255) << 8 | (int) (b * 255));
} }
public void setRenderFullBright(boolean renderFullBright) { public void setEmissiveMaterial(boolean renderFullBright) {
this.renderFullBright = renderFullBright; this.emissiveMaterial = renderFullBright;
} }
public void setCustomUv(Direction facing, float u1, float v1, float u2, float v2) { public void setCustomUv(Direction facing, float u1, float v1, float u2, float v2) {
@@ -49,7 +49,7 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
cb.setTexture(this.texture); cb.setTexture(this.texture);
cb.useStandardUV(); cb.useStandardUV();
cb.setRenderFullBright(active); cb.setEmissiveMaterial(active);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
final int[] offs = QUAD_OFFSETS[i]; final int[] offs = QUAD_OFFSETS[i];
@@ -70,6 +70,10 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
} }
} }
// Reset back to default
cb.setEmissiveMaterial(false);
return cb.getOutput(); return cb.getOutput();
} }
@@ -96,7 +100,7 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false;// TODO return false;// TODO
} }
@@ -276,7 +276,7 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -86,8 +86,8 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
// This determines diffuse lighting in the UI, and since we want to render // This determines diffuse lighting in the UI, and since we want to render
// the outputModel in the UI, we need to use it's setting here // the outputModel in the UI, we need to use it's setting here
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return outputModel.func_230044_c_(); return outputModel.isSideLit();
} }
} }
@@ -112,7 +112,7 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
@Nullable @Nullable
@Override @Override
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world, public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
@Nullable LivingEntity entity) { @Nullable LivingEntity entity) {
boolean shiftHeld = Screen.hasShiftDown(); boolean shiftHeld = Screen.hasShiftDown();
if (shiftHeld) { if (shiftHeld) {
@@ -122,12 +122,12 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
IBakedModel realModel = Minecraft.getInstance().getItemRenderer().getItemModelMesher() IBakedModel realModel = Minecraft.getInstance().getItemRenderer().getItemModelMesher()
.getItemModel(output); .getItemModel(output);
// Give the item model a chance to handle the overrides as well // Give the item model a chance to handle the overrides as well
realModel = realModel.getOverrides().func_239290_a_(realModel, output, world, entity); realModel = realModel.getOverrides().getOverrideModel(realModel, output, world, entity);
return new ShiftHoldingModelWrapper(getBaseModel(), realModel); return new ShiftHoldingModelWrapper(getBaseModel(), realModel);
} }
} }
return getBaseModel().getOverrides().func_239290_a_(originalModel, stack, world, entity); return getBaseModel().getOverrides().getOverrideModel(originalModel, stack, world, entity);
} }
} }
@@ -51,8 +51,10 @@ class LightBakedModel extends CraftingCubeBakedModel {
builder.addCube(x1, y1, z1, x2, y2, z2); builder.addCube(x1, y1, z1, x2, y2, z2);
boolean powered = state.get(AbstractCraftingUnitBlock.POWERED); boolean powered = state.get(AbstractCraftingUnitBlock.POWERED);
builder.setRenderFullBright(powered); builder.setEmissiveMaterial(powered);
builder.setTexture(this.lightTexture); builder.setTexture(this.lightTexture);
builder.addCube(x1, y1, z1, x2, y2, z2); builder.addCube(x1, y1, z1, x2, y2, z2);
// Reset back to default
builder.setEmissiveMaterial(false);
} }
} }
@@ -78,7 +78,7 @@ public class MonitorBakedModel extends CraftingCubeBakedModel {
AEColor color = getColor(modelData); AEColor color = getColor(modelData);
boolean powered = state.get(CraftingMonitorBlock.POWERED); boolean powered = state.get(CraftingMonitorBlock.POWERED);
builder.setRenderFullBright(powered); builder.setEmissiveMaterial(powered);
builder.setColorRGB(color.whiteVariant); builder.setColorRGB(color.whiteVariant);
builder.setTexture(this.lightBrightTexture); builder.setTexture(this.lightBrightTexture);
@@ -92,6 +92,8 @@ public class MonitorBakedModel extends CraftingCubeBakedModel {
builder.setTexture(this.lightDarkTexture); builder.setTexture(this.lightDarkTexture);
builder.addCube(x1, y1, z1, x2, y2, z2); builder.addCube(x1, y1, z1, x2, y2, z2);
// Reset back to default
builder.setEmissiveMaterial(false);
} }
private static AEColor getColor(IModelData modelData) { private static AEColor getColor(IModelData modelData) {
@@ -107,7 +107,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
// when piping it // when piping it
// to the AO lighter, thus fixing our problem. // to the AO lighter, thus fixing our problem.
BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getTintIndex(), BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getTintIndex(),
unpackedQuad.getFace(), quad.func_187508_a(), quad.func_239287_f_()); unpackedQuad.getFace(), quad.getSprite(), quad.applyDiffuseLighting());
rotated.add(packedQuad); rotated.add(packedQuad);
} }
return rotated; return rotated;
@@ -120,7 +120,7 @@ class BiometricCardBakedModel implements IBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false;// TODO return false;// TODO
} }
@@ -143,7 +143,7 @@ class BiometricCardBakedModel implements IBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
String username = ""; String username = "";
if (stack.getItem() instanceof IBiometricCard) { if (stack.getItem() instanceof IBiometricCard) {
@@ -50,19 +50,19 @@ class ColorApplicatorBakedModel implements IBakedModel {
for (BakedQuad quad : quads) { for (BakedQuad quad : quads) {
int tint; int tint;
if (quad.func_187508_a() == texDark) { if (quad.getSprite() == texDark) {
tint = 1; tint = 1;
} else if (quad.func_187508_a() == texMedium) { } else if (quad.getSprite() == texMedium) {
tint = 2; tint = 2;
} else if (quad.func_187508_a() == texBright) { } else if (quad.getSprite() == texBright) {
tint = 3; tint = 3;
} else { } else {
result.add(quad); result.add(quad);
continue; continue;
} }
BakedQuad newQuad = new BakedQuad(quad.getVertexData(), tint, quad.getFace(), quad.func_187508_a(), BakedQuad newQuad = new BakedQuad(quad.getVertexData(), tint, quad.getFace(), quad.getSprite(),
quad.func_239287_f_()); quad.applyDiffuseLighting());
result.add(newQuad); result.add(newQuad);
} }
@@ -88,7 +88,7 @@ class ColorApplicatorBakedModel implements IBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false;// TODO return false;// TODO
} }
@@ -157,7 +157,7 @@ class GlassBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
// TODO: Forge: Auto-generated method stub // TODO: Forge: Auto-generated method stub
return false; return false;
} }
@@ -105,7 +105,7 @@ class MemoryCardBakedModel implements IBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false;// TODO return false;// TODO
} }
@@ -128,7 +128,7 @@ class MemoryCardBakedModel implements IBakedModel {
public ItemOverrideList getOverrides() { public ItemOverrideList getOverrides() {
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world, public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
LivingEntity entity) { LivingEntity entity) {
try { try {
if (stack.getItem() instanceof IMemoryCard) { if (stack.getItem() instanceof IMemoryCard) {
@@ -122,7 +122,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -149,7 +149,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
*/ */
return new ItemOverrideList() { return new ItemOverrideList() {
@Override @Override
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world, public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
@Nullable LivingEntity entity) { @Nullable LivingEntity entity) {
// FIXME: This check prevents compasses being held by OTHERS from getting the // FIXME: This check prevents compasses being held by OTHERS from getting the
// rotation, BUT do we actually still need this??? // rotation, BUT do we actually still need this???
@@ -117,7 +117,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
if ((flags if ((flags
& SpatialPylonTileEntity.DISPLAY_POWERED_ENABLED) == SpatialPylonTileEntity.DISPLAY_POWERED_ENABLED) { & SpatialPylonTileEntity.DISPLAY_POWERED_ENABLED) == SpatialPylonTileEntity.DISPLAY_POWERED_ENABLED) {
builder.setRenderFullBright(true); builder.setEmissiveMaterial(true);
} }
builder.setTextures(this.textures.get(getTextureTypeFromSideInside(flags, ori, Direction.UP)), builder.setTextures(this.textures.get(getTextureTypeFromSideInside(flags, ori, Direction.UP)),
@@ -135,6 +135,9 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
builder.addCube(0, 0, 0, 16, 16, 16); builder.addCube(0, 0, 0, 16, 16, 16);
} }
// Reset back to default
builder.setEmissiveMaterial(false);
return builder.getOutput(); return builder.getOutput();
} }
@@ -178,7 +181,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false; return false;
} }
@@ -149,7 +149,7 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
for (int i = 0; i < quads.size(); i++) { for (int i = 0; i < quads.size(); i++) {
BakedQuad quad = quads.get(i); BakedQuad quad = quads.get(i);
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()), quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()),
quad.func_187508_a(), quad.func_239287_f_())); quad.getSprite(), quad.applyDiffuseLighting()));
} }
return quads; return quads;
@@ -69,7 +69,7 @@ public final class ContainerLocator {
private final AEPartLocation side; private final AEPartLocation side;
private ContainerLocator(Type type, int itemIndex, World world, BlockPos blockPos, AEPartLocation side) { private ContainerLocator(Type type, int itemIndex, World world, BlockPos blockPos, AEPartLocation side) {
this(type, itemIndex, world.func_234923_W_().func_240901_a_(), blockPos, side); this(type, itemIndex, world.getDimensionKey().getLocation(), blockPos, side);
} }
private ContainerLocator(Type type, int itemIndex, ResourceLocation worldId, BlockPos blockPos, private ContainerLocator(Type type, int itemIndex, ResourceLocation worldId, BlockPos blockPos,
@@ -133,7 +133,7 @@ public final class ContainerLocator {
public static ContainerLocator forPart(AEBasePart part) { public static ContainerLocator forPart(AEBasePart part) {
IPartHost host = part.getHost(); IPartHost host = part.getHost();
DimensionalCoord pos = host.getLocation(); DimensionalCoord pos = host.getLocation();
return new ContainerLocator(Type.PART, -1, pos.getWorld().getWorld(), pos.getBlockPos(), part.getSide()); return new ContainerLocator(Type.PART, -1, pos.getWorld(), pos.getBlockPos(), part.getSide());
} }
public boolean hasItemIndex() { public boolean hasItemIndex() {
@@ -129,7 +129,7 @@ public class SyncData {
String json = (String) val; String json = (String) val;
ITextComponent text = null; ITextComponent text = null;
if (!json.isEmpty()) { if (!json.isEmpty()) {
text = ITextComponent.Serializer.func_240643_a_((String) val); text = ITextComponent.Serializer.getComponentFromJson((String) val);
} }
this.updateTextComponent(text); this.updateTextComponent(text);
} else { } else {
@@ -46,6 +46,8 @@ import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.networking.IGrid; import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost; import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode; import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.energy.IEnergyGrid; import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource; import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.IActionHost; import appeng.api.networking.security.IActionHost;
@@ -100,6 +102,13 @@ public class MEMonitorableContainer extends AEBaseContainer
public boolean canAccessViewCells = false; public boolean canAccessViewCells = false;
@GuiSync(98) @GuiSync(98)
public boolean hasPower = false; public boolean hasPower = false;
/**
* The number of active crafting jobs in the network. -1 means unknown and will
* hide the label on the screen.
*/
@GuiSync(100)
public int activeCraftingJobs = -1;
private IConfigManagerHost gui; private IConfigManagerHost gui;
private IConfigManager serverCM; private IConfigManager serverCM;
private IGridNode networkNode; private IGridNode networkNode;
@@ -188,6 +197,8 @@ public class MEMonitorableContainer extends AEBaseContainer
this.setValidContainer(false); this.setValidContainer(false);
} }
this.updateActiveCraftingJobs();
for (final Settings set : this.serverCM.getSettings()) { for (final Settings set : this.serverCM.getSettings()) {
final Enum<?> sideLocal = this.serverCM.getSetting(set); final Enum<?> sideLocal = this.serverCM.getSetting(set);
final Enum<?> sideRemote = this.clientCM.getSetting(set); final Enum<?> sideRemote = this.clientCM.getSetting(set);
@@ -285,6 +296,36 @@ public class MEMonitorableContainer extends AEBaseContainer
this.queueInventory(c); this.queueInventory(c);
} }
private void updateActiveCraftingJobs() {
IGridNode hostNode = networkNode;
if (hostNode == null) {
// Wireless terminals do not directly expose the target grid (even though they
// have one)
if (host instanceof IActionHost) {
hostNode = ((IActionHost) host).getActionableNode();
}
}
IGrid grid = null;
if (hostNode != null) {
grid = hostNode.getGrid();
}
if (grid == null) {
// No grid to query crafting jobs from
this.activeCraftingJobs = -1;
return;
}
int activeJobs = 0;
ICraftingGrid craftingGrid = grid.getCache(ICraftingGrid.class);
for (ICraftingCPU cpus : craftingGrid.getCpus()) {
if (cpus.isBusy()) {
activeJobs++;
}
}
this.activeCraftingJobs = activeJobs;
}
private void queueInventory(final IContainerListener c) { private void queueInventory(final IContainerListener c) {
if (isServer() && c instanceof PlayerEntity && this.monitor != null) { if (isServer() && c instanceof PlayerEntity && this.monitor != null) {
try { try {
+1 -1
View File
@@ -595,7 +595,7 @@ public final class AEConfig {
this.spawnChargedChance = builder.defineInRange("spawnChargedChance", 0.08, 0.0, 1.0); this.spawnChargedChance = builder.defineInRange("spawnChargedChance", 0.08, 0.0, 1.0);
this.meteoriteMaximumSpawnHeight = builder.define("meteoriteMaximumSpawnHeight", 180); this.meteoriteMaximumSpawnHeight = builder.define("meteoriteMaximumSpawnHeight", 180);
List<String> defaultDimensionWhitelist = new ArrayList<>(); List<String> defaultDimensionWhitelist = new ArrayList<>();
defaultDimensionWhitelist.add(World.field_234918_g_.getRegistryName().toString()); defaultDimensionWhitelist.add(World.OVERWORLD.getRegistryName().toString());
this.meteoriteDimensionWhitelist = builder.defineList("meteoriteDimensionWhitelist", this.meteoriteDimensionWhitelist = builder.defineList("meteoriteDimensionWhitelist",
defaultDimensionWhitelist, obj -> true); defaultDimensionWhitelist, obj -> true);
+11 -6
View File
@@ -34,13 +34,12 @@ import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.particles.ParticleType; import net.minecraft.particles.ParticleType;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.biome.Biome;
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.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DeferredWorkQueue;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.client.registry.RenderingRegistry; import net.minecraftforge.fml.client.registry.RenderingRegistry;
@@ -101,6 +100,7 @@ public final class AppEng {
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
registration = new Registration(); registration = new Registration();
modEventBus.addListener(this::bootstrap);
modEventBus.addGenericListener(Block.class, registration::registerBlocks); modEventBus.addGenericListener(Block.class, registration::registerBlocks);
modEventBus.addGenericListener(Item.class, registration::registerItems); modEventBus.addGenericListener(Item.class, registration::registerItems);
modEventBus.addGenericListener(EntityType.class, registration::registerEntities); modEventBus.addGenericListener(EntityType.class, registration::registerEntities);
@@ -108,9 +108,6 @@ public final class AppEng {
modEventBus.addGenericListener(TileEntityType.class, registration::registerTileEntities); modEventBus.addGenericListener(TileEntityType.class, registration::registerTileEntities);
modEventBus.addGenericListener(ContainerType.class, registration::registerContainerTypes); modEventBus.addGenericListener(ContainerType.class, registration::registerContainerTypes);
modEventBus.addGenericListener(IRecipeSerializer.class, registration::registerRecipeSerializers); modEventBus.addGenericListener(IRecipeSerializer.class, registration::registerRecipeSerializers);
modEventBus.addGenericListener(Feature.class, registration::registerFeatures);
modEventBus.addGenericListener(Structure.class, registration::registerStructures);
modEventBus.addGenericListener(Biome.class, registration::registerBiomes);
modEventBus.addListener(Integrations::enqueueIMC); modEventBus.addListener(Integrations::enqueueIMC);
modEventBus.addListener(this::commonSetup); modEventBus.addListener(this::commonSetup);
@@ -129,7 +126,15 @@ public final class AppEng {
MinecraftForge.EVENT_BUS.register(new PartPlacement()); MinecraftForge.EVENT_BUS.register(new PartPlacement());
} }
private void bootstrap(RegistryEvent.NewRegistry e) {
// This has to be here so it's not run in parallel with other registrations
AppEngBootstrap.initialize();
}
private void commonSetup(FMLCommonSetupEvent event) { private void commonSetup(FMLCommonSetupEvent event) {
// This must run here because the config is not available earlier
DeferredWorkQueue.runLater(AppEngBootstrap::enhanceBiomes);
ApiDefinitions definitions = Api.INSTANCE.definitions(); ApiDefinitions definitions = Api.INSTANCE.definitions();
definitions.getRegistry().getBootstrapComponents(IInitComponent.class) definitions.getRegistry().getBootstrapComponents(IInitComponent.class)
.forEachRemaining(IInitComponent::initialize); .forEachRemaining(IInitComponent::initialize);
@@ -0,0 +1,135 @@
package appeng.core;
import net.minecraft.block.BlockState;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.OreFeatureConfig;
import net.minecraft.world.gen.placement.NoPlacementConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraft.world.gen.placement.TopSolidRangeConfig;
import appeng.api.features.AEFeature;
import appeng.mixins.feature.ConfiguredFeaturesAccessor;
import appeng.mixins.structure.ConfiguredStructureFeaturesAccessor;
import appeng.mixins.structure.StructureFeatureAccessor;
import appeng.spatial.SpatialStorageChunkGenerator;
import appeng.spatial.SpatialStorageDimensionIds;
import appeng.worldgen.BiomeModifier;
import appeng.worldgen.ChargedQuartzOreConfig;
import appeng.worldgen.ChargedQuartzOreFeature;
import appeng.worldgen.meteorite.MeteoriteStructure;
import appeng.worldgen.meteorite.MeteoriteStructurePiece;
/**
* Hooks into the very early bootstrapping phase to register things before the
* first dynamic registry manager is created.
*/
public final class AppEngBootstrap {
private static boolean initialized;
private static ConfiguredFeature<?, ?> quartzOreFeature;
private static ConfiguredFeature<?, ?> chargedQuartzOreFeature;
private AppEngBootstrap() {
}
public synchronized static void initialize() {
if (initialized) {
return;
}
initialized = true;
registerStructures();
quartzOreFeature = registerQuartzOreFeature();
chargedQuartzOreFeature = registerChargedQuartzOreFeature();
registerDimension();
}
public synchronized static void enhanceBiomes() {
// add to all standard biomes
// TODO: This means we'll not add these things to newly created biomes
WorldGenRegistries.BIOME.forEach(b -> {
addMeteoriteWorldGen(b);
addQuartzWorldGen(b, quartzOreFeature, chargedQuartzOreFeature);
});
}
private static void registerStructures() {
MeteoriteStructurePiece.register();
// Registering into the registry alone is INSUFFICIENT!
// There's a bidirectional map in the Structure class itself primarily for the
// purposes of NBT serialization
StructureFeatureAccessor.register(MeteoriteStructure.ID.toString(), MeteoriteStructure.INSTANCE,
GenerationStage.Decoration.TOP_LAYER_MODIFICATION);
ConfiguredStructureFeaturesAccessor.register(MeteoriteStructure.ID.toString(),
MeteoriteStructure.CONFIGURED_INSTANCE);
}
private static void addMeteoriteWorldGen(Biome b) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.METEORITE_WORLD_GEN)) {
return;
}
if (b.getCategory() == Biome.Category.THEEND || b.getCategory() == Biome.Category.NETHER) {
return;
}
BiomeModifier modifier = new BiomeModifier(b);
modifier.addStructureFeature(MeteoriteStructure.CONFIGURED_INSTANCE);
}
private static void addQuartzWorldGen(Biome b, ConfiguredFeature<?, ?> quartzOre,
ConfiguredFeature<?, ?> chargedQuartz) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.CERTUS_QUARTZ_WORLD_GEN)) {
return;
}
BiomeModifier modifier = new BiomeModifier(b);
modifier.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, quartzOre);
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHARGED_CERTUS_ORE)) {
modifier.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, chargedQuartz);
}
}
private static ConfiguredFeature<?, ?> registerQuartzOreFeature() {
// Tell Minecraft about our configured quartz ore feature
BlockState quartzOreState = Api.instance().definitions().blocks().quartzOre().block().getDefaultState();
return ConfiguredFeaturesAccessor.register(AppEng.makeId("quartz_ore").toString(), Feature.ORE
.withConfiguration(new OreFeatureConfig(OreFeatureConfig.FillerBlockType.field_241882_a, quartzOreState,
AEConfig.instance().getQuartzOresPerCluster()))
.withPlacement(Placement.field_242907_l/* RANGE */.configure(new TopSolidRangeConfig(12, 12, 72)))
.func_242728_a/* spreadHorizontally */()
.func_242731_b/* repeat */(AEConfig.instance().getQuartzOresClusterAmount()));
}
private static ConfiguredFeature<?, ?> registerChargedQuartzOreFeature() {
// Tell Minecraft about our configured charged quartz ore feature
Registry.register(Registry.FEATURE, AppEng.makeId("charged_quartz_ore"), ChargedQuartzOreFeature.INSTANCE);
BlockState quartzOreState = Api.instance().definitions().blocks().quartzOre().block().getDefaultState();
BlockState chargedQuartzOreState = Api.instance().definitions().blocks().quartzOreCharged().block()
.getDefaultState();
return ConfiguredFeaturesAccessor.register(AppEng.makeId("charged_quartz_ore").toString(),
ChargedQuartzOreFeature.INSTANCE
.withConfiguration(new ChargedQuartzOreConfig(quartzOreState, chargedQuartzOreState,
AEConfig.instance().getSpawnChargedChance()))
.withPlacement(Placement.NOPE.configure(NoPlacementConfig.field_236556_b_)));
}
private static void registerDimension() {
Registry.register(Registry.CHUNK_GENERATOR_CODEC, SpatialStorageDimensionIds.CHUNK_GENERATOR_ID,
SpatialStorageChunkGenerator.CODEC);
}
}
+1 -89
View File
@@ -22,7 +22,6 @@ import java.util.function.Supplier;
import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScreenManager; import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.particle.ParticleManager; import net.minecraft.client.particle.ParticleManager;
@@ -33,17 +32,7 @@ import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.particles.ParticleType; import net.minecraft.particles.ParticleType;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.OreFeatureConfig;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.placement.CountRangeConfig;
import net.minecraft.world.gen.placement.IPlacementConfig;
import net.minecraft.world.gen.placement.Placement;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.ColorHandlerEvent;
@@ -62,14 +51,12 @@ import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLEnvironment; import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.network.IContainerFactory; import net.minecraftforge.fml.network.IContainerFactory;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistry;
import appeng.api.config.Upgrades; import appeng.api.config.Upgrades;
import appeng.api.definitions.IBlocks; import appeng.api.definitions.IBlocks;
import appeng.api.definitions.IItems; import appeng.api.definitions.IItems;
import appeng.api.definitions.IParts; import appeng.api.definitions.IParts;
import appeng.api.features.AEFeature;
import appeng.api.features.IRegistryContainer; import appeng.api.features.IRegistryContainer;
import appeng.api.features.IWirelessTermHandler; import appeng.api.features.IWirelessTermHandler;
import appeng.api.features.IWorldGen; import appeng.api.features.IWorldGen;
@@ -213,22 +200,14 @@ import appeng.me.cache.PathGridCache;
import appeng.me.cache.SecurityCache; import appeng.me.cache.SecurityCache;
import appeng.me.cache.SpatialPylonCache; import appeng.me.cache.SpatialPylonCache;
import appeng.me.cache.TickManagerCache; import appeng.me.cache.TickManagerCache;
import appeng.mixins.StructureAccessor;
import appeng.parts.automation.PlaneModelLoader; import appeng.parts.automation.PlaneModelLoader;
import appeng.recipes.game.DisassembleRecipe; import appeng.recipes.game.DisassembleRecipe;
import appeng.recipes.game.FacadeRecipe; import appeng.recipes.game.FacadeRecipe;
import appeng.recipes.handlers.GrinderRecipeSerializer; import appeng.recipes.handlers.GrinderRecipeSerializer;
import appeng.recipes.handlers.InscriberRecipeSerializer; import appeng.recipes.handlers.InscriberRecipeSerializer;
import appeng.server.AECommand; import appeng.server.AECommand;
import appeng.spatial.SpatialStorageBiome;
import appeng.spatial.SpatialStorageChunkGenerator;
import appeng.spatial.SpatialStorageDimensionIds;
import appeng.tile.AEBaseTileEntity; import appeng.tile.AEBaseTileEntity;
import appeng.tile.crafting.MolecularAssemblerRenderer; 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 { final class Registration {
@@ -673,7 +652,7 @@ final class Registration {
* world gen * world gen
*/ */
for (final IWorldGen.WorldGenType type : IWorldGen.WorldGenType.values()) { for (final IWorldGen.WorldGenType type : IWorldGen.WorldGenType.values()) {
registries.worldgen().disableWorldGenForDimension(type, World.field_234919_h_.getRegistryName()); registries.worldgen().disableWorldGenForDimension(type, World.THE_NETHER.getRegistryName());
} }
// whitelist from config // whitelist from config
@@ -682,73 +661,6 @@ final class Registration {
new ResourceLocation(dimension)); new ResourceLocation(dimension));
} }
MeteoriteStructurePiece.register();
ForgeRegistries.BIOMES.forEach(b -> {
addMeteoriteWorldGen(b);
addQuartzWorldGen(b);
});
}
private static void addMeteoriteWorldGen(Biome b) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.METEORITE_WORLD_GEN)) {
return;
}
if (b.getCategory() == Biome.Category.THEEND || b.getCategory() == Biome.Category.NETHER) {
return;
}
b.func_235063_a_(MeteoriteStructure.INSTANCE.func_236391_a_(IFeatureConfig.NO_FEATURE_CONFIG));
}
private static void addQuartzWorldGen(Biome b) {
if (!AEConfig.instance().isFeatureEnabled(AEFeature.CERTUS_QUARTZ_WORLD_GEN)) {
return;
}
BlockState quartzOre = Api.instance().definitions().blocks().quartzOre().block().getDefaultState();
b.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES,
Feature.ORE
.withConfiguration(new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE,
quartzOre, AEConfig.instance().getQuartzOresPerCluster()))
.withPlacement(Placement.COUNT_RANGE.configure(
new CountRangeConfig(AEConfig.instance().getQuartzOresClusterAmount(), 12, 12, 72))));
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHARGED_CERTUS_ORE)) {
BlockState chargedQuartzOre = Api.instance().definitions().blocks().quartzOreCharged().block()
.getDefaultState();
b.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION,
ChargedQuartzOreFeature.INSTANCE
.withConfiguration(new ChargedQuartzOreConfig(quartzOre, chargedQuartzOre,
AEConfig.instance().getSpawnChargedChance()))
.withPlacement(Placement.NOPE.configure(IPlacementConfig.NO_PLACEMENT_CONFIG)));
}
}
public void registerFeatures(RegistryEvent.Register<Feature<?>> evt) {
IForgeRegistry<Feature<?>> r = evt.getRegistry();
r.register(ChargedQuartzOreFeature.INSTANCE.setRegistryName(AppEng.makeId("charged_quartz_ore")));
}
public void registerStructures(RegistryEvent.Register<Structure<?>> evt) {
// Registering into the Forge registry is INSUFFICIENT!
// There's a bidirectional map in the Structure class itself primarily for the
// purposes of NBT serialization
StructureAccessor.register(MeteoriteStructure.ID.toString(),
MeteoriteStructure.INSTANCE.setRegistryName(MeteoriteStructure.ID),
GenerationStage.Decoration.TOP_LAYER_MODIFICATION);
Registry.register(Registry.CHUNK_GENERATOR_CODEC, SpatialStorageDimensionIds.CHUNK_GENERATOR_ID,
SpatialStorageChunkGenerator.CODEC);
}
public void registerBiomes(RegistryEvent.Register<Biome> evt) {
evt.getRegistry().register(SpatialStorageBiome.INSTANCE.setRegistryName(SpatialStorageDimensionIds.BIOME_ID));
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@@ -221,7 +221,7 @@ public final class ApiItems implements IItems {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void setup() { public void setup() {
ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item; ColorApplicatorItem colorApplicatorItem = (ColorApplicatorItem) item;
ItemModelsProperties.func_239418_a_(item, new ResourceLocation(AppEng.MOD_ID, "colored"), ItemModelsProperties.registerProperty(item, new ResourceLocation(AppEng.MOD_ID, "colored"),
(itemStack, world, entity) -> { (itemStack, world, entity) -> {
// If the stack has no color, don't use the colored model since the impact of // 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 // calling getColor for every quad is extremely high, if the stack tries to
@@ -312,7 +312,7 @@ public final class ApiItems implements IItems {
GrowingCrystalEntity.TYPE = registry GrowingCrystalEntity.TYPE = registry
.<GrowingCrystalEntity>entity("growing_crystal", GrowingCrystalEntity::new, EntityClassification.MISC) .<GrowingCrystalEntity>entity("growing_crystal", GrowingCrystalEntity::new, EntityClassification.MISC)
.customize(builder -> builder.size(0.25F, 0.25F)).build(); .customize(builder -> builder.size(0.25F, 0.4F)).build();
// rv1 // rv1
this.encodedPattern = registry.item("encoded_pattern", EncodedPatternItem::new) this.encodedPattern = registry.item("encoded_pattern", EncodedPatternItem::new)
@@ -51,12 +51,12 @@ public class MovableTileRegistry implements IMovableRegistry {
private final List<IMovableHandler> handlers = new ArrayList<>(); private final List<IMovableHandler> handlers = new ArrayList<>();
private final DefaultSpatialHandler dsh = new DefaultSpatialHandler(); private final DefaultSpatialHandler dsh = new DefaultSpatialHandler();
private final IMovableHandler nullHandler = new DefaultSpatialHandler(); private final IMovableHandler nullHandler = new DefaultSpatialHandler();
private final ITag<Block> blockTagWhiteList; private final ITag.INamedTag<Block> blockTagWhiteList;
private final ITag<Block> blockTagBlackList; private final ITag.INamedTag<Block> blockTagBlackList;
public MovableTileRegistry() { public MovableTileRegistry() {
this.blockTagWhiteList = BlockTags.getCollection().getOrCreate(TAG_WHITELIST); this.blockTagWhiteList = BlockTags.makeWrapperTag(TAG_WHITELIST.toString());
this.blockTagBlackList = BlockTags.getCollection().getOrCreate(TAG_BLACKLIST); this.blockTagBlackList = BlockTags.makeWrapperTag(TAG_BLACKLIST.toString());
} }
@Override @Override
@@ -67,7 +67,7 @@ public final class WorldGenRegistry implements IWorldGen {
throw new IllegalArgumentException("Bad Provider Passed"); throw new IllegalArgumentException("Bad Provider Passed");
} }
ResourceLocation id = w.func_234923_W_().func_240901_a_(); ResourceLocation id = w.getDimensionKey().getLocation();
final boolean isBadDimension = this.types[type.ordinal()].badDimensions.contains(id); final boolean isBadDimension = this.types[type.ordinal()].badDimensions.contains(id);
final boolean isGoodDimension = this.types[type.ordinal()].enabledDimensions.contains(id); final boolean isGoodDimension = this.types[type.ordinal()].enabledDimensions.contains(id);
@@ -119,7 +119,7 @@ public class NetworkHandler {
public void sendToAllAround(final BasePacket message, final TargetPoint point) { public void sendToAllAround(final BasePacket message, final TargetPoint point) {
IPacket<?> pkt = message.toPacket(NetworkDirection.PLAY_TO_CLIENT); IPacket<?> pkt = message.toPacket(NetworkDirection.PLAY_TO_CLIENT);
getServer().getPlayerList().sendToAllNearExcept(point.excluded, point.x, point.y, point.z, point.r2, getServer().getPlayerList().sendToAllNearExcept(point.excluded, point.x, point.y, point.z, point.r2,
point.world.func_234923_W_(), pkt); point.world.getDimensionKey(), pkt);
} }
public void sendToServer(final BasePacket message) { public void sendToServer(final BasePacket message) {
@@ -71,7 +71,7 @@ public class BlockTransitionEffectPacket extends BasePacket {
data.writeInt(this.getPacketID()); data.writeInt(this.getPacketID());
data.writeBlockPos(pos); data.writeBlockPos(pos);
int blockStateId = GameData.getBlockStateIDMap().get(blockState); int blockStateId = GameData.getBlockStateIDMap().getId(blockState);
if (blockStateId == -1) { if (blockStateId == -1) {
AELog.warn("Failed to find numeric id for block state %s", blockState); AELog.warn("Failed to find numeric id for block state %s", blockState);
} }
@@ -18,15 +18,28 @@
package appeng.core.sync.packets; package appeng.core.sync.packets;
import java.util.Arrays;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.google.common.base.Preconditions;
import com.mojang.datafixers.util.Pair;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.ListNBT; import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.item.crafting.ShapedRecipe;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.common.crafting.IShapedRecipe;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import appeng.api.config.Actionable; import appeng.api.config.Actionable;
@@ -40,8 +53,10 @@ import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEMonitor; import appeng.api.storage.IMEMonitor;
import appeng.api.storage.channels.IItemStorageChannel; import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack; import appeng.api.storage.data.IAEItemStack;
import appeng.container.implementations.PatternTermContainer;
import appeng.core.Api; import appeng.core.Api;
import appeng.core.sync.BasePacket; import appeng.core.sync.BasePacket;
import appeng.core.sync.BasePacketHandler;
import appeng.core.sync.network.INetworkInfo; import appeng.core.sync.network.INetworkInfo;
import appeng.helpers.IContainerCraftingPacket; import appeng.helpers.IContainerCraftingPacket;
import appeng.items.storage.ViewCellItem; import appeng.items.storage.ViewCellItem;
@@ -54,152 +69,298 @@ import appeng.util.prioritylist.IPartitionList;
public class JEIRecipePacket extends BasePacket { public class JEIRecipePacket extends BasePacket {
private ItemStack[][] recipe; /**
* Transmit only a recipe ID.
*/
private static final int INLINE_RECIPE_NONE = 1;
/**
* Transmit the information about the recipe we actually need. This is
* explicitly limited since this is untrusted client->server info.
*/
private static final int INLINE_RECIPE_SHAPED = 2;
private ResourceLocation recipeId;
/**
* This is optional, in case the client already knows it could not resolve the
* recipe id.
*/
@Nullable
private IRecipe<?> recipe;
private boolean crafting;
public JEIRecipePacket(final PacketBuffer stream) { public JEIRecipePacket(final PacketBuffer stream) {
final CompoundNBT comp = stream.readCompoundTag(); this.crafting = stream.readBoolean();
if (comp != null) { final String id = stream.readString(Short.MAX_VALUE);
this.recipe = new ItemStack[9][]; this.recipeId = new ResourceLocation(id);
for (int x = 0; x < this.recipe.length; x++) {
final ListNBT list = comp.getList("#" + x, 10);
if (list.size() > 0) {
this.recipe[x] = new ItemStack[list.size()];
for (int y = 0; y < list.size(); y++) {
this.recipe[x][y] = ItemStack.read(list.getCompound(y));
}
}
}
}
}
// api int inlineRecipeType = stream.readVarInt();
public JEIRecipePacket(final CompoundNBT recipe) { switch (inlineRecipeType) {
final PacketBuffer data = new PacketBuffer(Unpooled.buffer()); case INLINE_RECIPE_NONE:
break;
data.writeInt(this.getPacketID()); case INLINE_RECIPE_SHAPED:
recipe = IRecipeSerializer.CRAFTING_SHAPED.read(this.recipeId, stream);
data.writeCompoundTag(recipe); break;
default:
this.configureWrite(data); throw new IllegalArgumentException("Invalid inline recipe type.");
}
@Override
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
final ServerPlayerEntity pmp = (ServerPlayerEntity) player;
final Container con = pmp.openContainer;
if (!(con instanceof IContainerCraftingPacket)) {
return;
}
final IContainerCraftingPacket cct = (IContainerCraftingPacket) con;
final IGridNode node = cct.getNetworkNode();
if (node == null) {
return;
}
final IGrid grid = node.getGrid();
if (grid == null) {
return;
}
final IStorageGrid inv = grid.getCache(IStorageGrid.class);
final IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
final ISecurityGrid security = grid.getCache(ISecurityGrid.class);
final ICraftingGrid crafting = grid.getCache(ICraftingGrid.class);
final IItemHandler craftMatrix = cct.getInventoryByName("crafting");
final IItemHandler playerInventory = cct.getInventoryByName("player");
if (inv != null && this.recipe != null && security != null) {
final IMEMonitor<IAEItemStack> storage = inv
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class));
final IPartitionList<IAEItemStack> filter = ViewCellItem.createFilter(cct.getViewCells());
for (int x = 0; x < craftMatrix.getSlots(); x++) {
ItemStack currentItem = craftMatrix.getStackInSlot(x);
// prepare slots
if (!currentItem.isEmpty()) {
// already the correct item?
ItemStack newItem = this.canUseInSlot(x, currentItem);
// put away old item
if (newItem != currentItem && security.hasPermission(player, SecurityPermissions.INJECT)) {
final IAEItemStack in = AEItemStack.fromItemStack(currentItem);
final IAEItemStack out = cct.useRealItems()
? Platform.poweredInsert(energy, storage, in, cct.getActionSource())
: null;
if (out != null) {
currentItem = out.createItemStack();
} else {
currentItem = ItemStack.EMPTY;
}
}
}
if (currentItem.isEmpty() && this.recipe[x] != null) {
// for each variant
for (int y = 0; y < this.recipe[x].length && currentItem.isEmpty(); y++) {
final IAEItemStack request = AEItemStack.fromItemStack(this.recipe[x][y]);
if (request != null) {
// try ae
if ((filter == null || filter.isListed(request))
&& security.hasPermission(player, SecurityPermissions.EXTRACT)) {
request.setStackSize(1);
IAEItemStack out;
if (cct.useRealItems()) {
out = Platform.poweredExtraction(energy, storage, request, cct.getActionSource());
} else {
// Query the crafting grid if there is a pattern providing the item
if (!crafting.getCraftingFor(request, null, 0, null).isEmpty()) {
out = request;
} else {
// Fall back using an existing item
out = storage.extractItems(request, Actionable.SIMULATE, cct.getActionSource());
}
}
if (out != null) {
currentItem = out.createItemStack();
}
}
// try inventory
if (currentItem.isEmpty()) {
AdaptorItemHandler ad = new AdaptorItemHandler(playerInventory);
if (cct.useRealItems()) {
currentItem = ad.removeItems(1, this.recipe[x][y], null);
} else {
currentItem = ad.simulateRemove(1, this.recipe[x][y], null);
}
}
}
}
}
ItemHandlerUtil.setStackInSlot(craftMatrix, x, currentItem);
}
con.onCraftMatrixChanged(new WrapperInvItemHandler(craftMatrix));
} }
} }
/** /**
* * Sends a recipe identified by the given recipe ID to the server for either
* @param slot * filling a crafting grid or a pattern.
* @param is itemstack
* @return is if it can be used, else EMPTY
*/ */
private ItemStack canUseInSlot(int slot, ItemStack is) { public JEIRecipePacket(final ResourceLocation recipeId, final boolean crafting) {
if (this.recipe[slot] != null) { PacketBuffer data = createCommonHeader(recipeId, crafting, INLINE_RECIPE_NONE);
for (ItemStack option : this.recipe[slot]) { this.configureWrite(data);
if (is.isItemEqual(option)) { }
return is;
/**
* Sends a recipe to the server for either filling a crafting grid or a pattern.
* <p>
* Prefer the id-based constructor above whereever possible.
*/
public JEIRecipePacket(final ShapedRecipe recipe, final boolean crafting) {
PacketBuffer data = createCommonHeader(recipe.getId(), crafting, INLINE_RECIPE_SHAPED);
IRecipeSerializer.CRAFTING_SHAPED.write(data, recipe);
this.configureWrite(data);
}
private PacketBuffer createCommonHeader(ResourceLocation recipeId, boolean crafting, int inlineRecipeType) {
final PacketBuffer data = new PacketBuffer(Unpooled.buffer());
data.writeInt(this.getPacketID());
data.writeBoolean(crafting);
data.writeResourceLocation(recipeId);
data.writeVarInt(inlineRecipeType);
return data;
}
/**
* Servside handler for this packet.
* <p>
* Makes use of {@link Preconditions#checkArgument(boolean)} as the
* {@link BasePacketHandler} is catching them and in general these cases should
* never happen except in an error case and should be logged then.
*/
@Override
public void serverPacketData(final INetworkInfo manager, final PlayerEntity player) {
// Setup and verification
final ServerPlayerEntity pmp = (ServerPlayerEntity) player;
final Container con = pmp.openContainer;
Preconditions.checkArgument(con instanceof IContainerCraftingPacket);
IRecipe<?> recipe = player.getEntityWorld().getRecipeManager().getRecipe(this.recipeId).orElse(null);
if (recipe == null && this.recipe != null) {
// Certain recipes (i.e. AE2 facades) are represented in JEI as ShapedRecipe's,
// while in reality they
// are special recipes. Those recipes are sent across the wire...
recipe = this.recipe;
}
Preconditions.checkArgument(recipe != null);
final IContainerCraftingPacket cct = (IContainerCraftingPacket) con;
final IGridNode node = cct.getNetworkNode();
Preconditions.checkArgument(node != null);
final IGrid grid = node.getGrid();
Preconditions.checkArgument(grid != null);
final IStorageGrid inv = grid.getCache(IStorageGrid.class);
Preconditions.checkArgument(inv != null);
final ISecurityGrid security = grid.getCache(ISecurityGrid.class);
Preconditions.checkArgument(security != null);
final IEnergyGrid energy = grid.getCache(IEnergyGrid.class);
final ICraftingGrid crafting = grid.getCache(ICraftingGrid.class);
final IItemHandler craftMatrix = cct.getInventoryByName("crafting");
final IItemHandler playerInventory = cct.getInventoryByName("player");
final IMEMonitor<IAEItemStack> storage = inv
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class));
final IPartitionList<IAEItemStack> filter = ViewCellItem.createFilter(cct.getViewCells());
final NonNullList<Ingredient> ingredients = this.ensure3by3CraftingMatrix(recipe);
// Handle each slot
for (int x = 0; x < craftMatrix.getSlots(); x++) {
ItemStack currentItem = craftMatrix.getStackInSlot(x);
Ingredient ingredient = ingredients.get(x);
// prepare slots
if (!currentItem.isEmpty()) {
// already the correct item? True, skip everything else
ItemStack newItem = this.canUseInSlot(ingredient, currentItem);
// put away old item, if not correct
if (newItem != currentItem && security.hasPermission(player, SecurityPermissions.INJECT)) {
final IAEItemStack in = AEItemStack.fromItemStack(currentItem);
final IAEItemStack out = cct.useRealItems()
? Platform.poweredInsert(energy, storage, in, cct.getActionSource())
: null;
if (out != null) {
currentItem = out.createItemStack();
} else {
currentItem = ItemStack.EMPTY;
}
}
}
// Find item or pattern from the network
if (currentItem.isEmpty() && security.hasPermission(player, SecurityPermissions.EXTRACT)) {
IAEItemStack out;
if (cct.useRealItems()) {
IAEItemStack request = findBestMatchingItemStack(ingredient, filter, storage, cct);
out = request != null
? Platform.poweredExtraction(energy, storage, request.setStackSize(1),
cct.getActionSource())
: null;
} else {
out = findBestMatchingPattern(ingredient, filter, crafting, storage, cct);
if (out == null) {
out = findBestMatchingItemStack(ingredient, filter, storage, cct);
}
if (out == null && ingredient.getMatchingStacks().length > 0) {
out = AEItemStack.fromItemStack(ingredient.getMatchingStacks()[0]);
}
}
if (out != null) {
currentItem = out.createItemStack();
}
}
// If still nothing, search the player inventory.
if (currentItem.isEmpty()) {
ItemStack[] matchingStacks = ingredient.getMatchingStacks();
for (ItemStack matchingStack : matchingStacks) {
if (currentItem.isEmpty()) {
AdaptorItemHandler ad = new AdaptorItemHandler(playerInventory);
if (cct.useRealItems()) {
currentItem = ad.removeItems(1, matchingStack, null);
} else {
currentItem = ad.simulateRemove(1, matchingStack, null);
}
}
}
}
ItemHandlerUtil.setStackInSlot(craftMatrix, x, currentItem);
}
if (!this.crafting) {
this.handleProcessing(con, cct, recipe);
}
con.onCraftMatrixChanged(new WrapperInvItemHandler(craftMatrix));
}
/**
* Expand any recipe to a 3x3 matrix.
* <p>
* Will throw an {@link IllegalArgumentException} in case it has more than 9 or
* a shaped recipe is either wider or higher than 3. ingredients.
*/
private NonNullList<Ingredient> ensure3by3CraftingMatrix(IRecipe<?> recipe) {
NonNullList<Ingredient> ingredients = recipe.getIngredients();
NonNullList<Ingredient> expandedIngredients = NonNullList.withSize(9, Ingredient.EMPTY);
Preconditions.checkArgument(ingredients.size() <= 9);
// shaped recipes can be smaller than 3x3, expand to 3x3 to match the crafting
// matrix
if (recipe instanceof IShapedRecipe) {
IShapedRecipe<?> shapedRecipe = (IShapedRecipe<?>) recipe;
int width = shapedRecipe.getRecipeWidth();
int height = shapedRecipe.getRecipeHeight();
Preconditions.checkArgument(width <= 3 && height <= 3);
for (int h = 0; h < height; h++) {
for (int w = 0; w < width; w++) {
int source = w + h * width;
int target = w + h * 3;
Ingredient i = ingredients.get(source);
expandedIngredients.set(target, i);
} }
} }
} }
return ItemStack.EMPTY; // Anything else should be a flat list
else {
for (int i = 0; i < ingredients.size(); i++) {
expandedIngredients.set(i, ingredients.get(i));
}
}
return expandedIngredients;
}
/**
* @param is itemstack
* @return is if it can be used, else EMPTY
*/
private ItemStack canUseInSlot(Ingredient ingredient, ItemStack is) {
return Arrays.stream(ingredient.getMatchingStacks()).filter(p -> p.isItemEqual(is)).findFirst()
.orElse(ItemStack.EMPTY);
}
/**
* Finds the first matching itemstack with the highest stored amount.
*/
private IAEItemStack findBestMatchingItemStack(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
Stream<AEItemStack> stacks = Arrays.stream(ingredients.getMatchingStacks())//
.map(AEItemStack::fromItemStack) //
.filter(r -> r != null && (filter == null || filter.isListed(r)));
return getMostStored(stacks, storage, cct);
}
/**
* This tries to find the first pattern matching the list of ingredients.
* <p>
* As additional condition, it sorts by the stored amount to return the one with
* the highest stored amount.
*/
private IAEItemStack findBestMatchingPattern(Ingredient ingredients, IPartitionList<IAEItemStack> filter,
ICraftingGrid crafting, IMEMonitor<IAEItemStack> storage, IContainerCraftingPacket cct) {
Stream<IAEItemStack> stacks = Arrays.stream(ingredients.getMatchingStacks())//
.map(AEItemStack::fromItemStack)//
.filter(r -> r != null && (filter == null || filter.isListed(r)))//
.map(s -> s.setCraftable(!crafting.getCraftingFor(s, null, 0, null).isEmpty()))//
.filter(IAEItemStack::isCraftable);
return getMostStored(stacks, storage, cct);
}
/**
* From a stream of AE item stacks, pick the one with the highest available
* amount in the network. Returns null if the stream is empty.
*/
private static IAEItemStack getMostStored(Stream<? extends IAEItemStack> stacks, IMEMonitor<IAEItemStack> storage,
IContainerCraftingPacket cct) {
return stacks//
.map(s -> {
// Determine the stored count
IAEItemStack stored = storage.extractItems(s.copy().setStackSize(Long.MAX_VALUE),
Actionable.SIMULATE, cct.getActionSource());
return Pair.of(s, stored != null ? stored.getStackSize() : 0);
})//
.min((left, right) -> Long.compare(right.getSecond(), left.getSecond()))//
.map(Pair::getFirst)//
.orElse(null);
}
private void handleProcessing(Container con, IContainerCraftingPacket cct, IRecipe<?> recipe) {
if (con instanceof PatternTermContainer) {
PatternTermContainer patternTerm = (PatternTermContainer) con;
if (!patternTerm.craftingMode) {
final IItemHandler output = cct.getInventoryByName("output");
ItemHandlerUtil.setStackInSlot(output, 0, recipe.getRecipeOutput());
ItemHandlerUtil.setStackInSlot(output, 1, ItemStack.EMPTY);
ItemHandlerUtil.setStackInSlot(output, 2, ItemStack.EMPTY);
}
}
} }
} }
@@ -19,11 +19,9 @@
package appeng.core.sync.packets; package appeng.core.sync.packets;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.nio.BufferOverflowException; import java.nio.BufferOverflowException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -61,7 +61,7 @@ public final class WorldData implements IWorldData {
Preconditions.checkNotNull(overworld); Preconditions.checkNotNull(overworld);
// Attach shared data to the server's overworld dimension // Attach shared data to the server's overworld dimension
if (overworld.func_234923_W_() != ServerWorld.field_234918_g_) { if (overworld.getDimensionKey() != ServerWorld.OVERWORLD) {
throw new IllegalStateException("The server doesn't have an overworld we could store our data on!"); throw new IllegalStateException("The server doesn't have an overworld we could store our data on!");
} }
@@ -94,7 +94,7 @@ public final class WorldData implements IWorldData {
throw new IllegalStateException("No server set."); throw new IllegalStateException("No server set.");
} }
ServerWorld overworld = server.getWorld(ServerWorld.field_234918_g_); ServerWorld overworld = server.getWorld(ServerWorld.OVERWORLD);
instance = new WorldData(overworld); instance = new WorldData(overworld);
} }
return instance; return instance;
@@ -28,6 +28,7 @@ import net.minecraft.loot.RandomValueRange;
import net.minecraft.loot.conditions.SurvivesExplosion; import net.minecraft.loot.conditions.SurvivesExplosion;
import net.minecraft.loot.functions.ApplyBonus; import net.minecraft.loot.functions.ApplyBonus;
import net.minecraft.loot.functions.SetCount; import net.minecraft.loot.functions.SetCount;
import net.minecraft.util.RegistryKey;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent; import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
@@ -62,12 +63,12 @@ public class BlockDropProvider extends BlockLootTables implements IAE2DataProvid
@Override @Override
public void act(@Nonnull DirectoryCache cache) throws IOException { public void act(@Nonnull DirectoryCache cache) throws IOException {
for (Map.Entry<ResourceLocation, Block> entry : ForgeRegistries.BLOCKS.getEntries()) { for (Map.Entry<RegistryKey<Block>, Block> entry : ForgeRegistries.BLOCKS.getEntries()) {
LootTable.Builder builder; LootTable.Builder builder;
if (entry.getKey().getNamespace().equals(AppEng.MOD_ID)) { if (entry.getKey().getLocation().getNamespace().equals(AppEng.MOD_ID)) {
builder = overrides.getOrDefault(entry.getValue(), this::defaultBuilder).apply(entry.getValue()); builder = overrides.getOrDefault(entry.getValue(), this::defaultBuilder).apply(entry.getValue());
IDataProvider.save(GSON, cache, toJson(builder), getPath(outputFolder, entry.getKey())); IDataProvider.save(GSON, cache, toJson(builder), getPath(outputFolder, entry.getKey().getLocation()));
} }
} }
} }
@@ -64,7 +64,7 @@ public class ChunkLoaderTileEntity extends AEBaseTileEntity implements ITickable
ServerWorld serverWorld = (ServerWorld) world; ServerWorld serverWorld = (ServerWorld) world;
if (!serverWorld.getForcedChunks().contains(chunkPos.asLong())) { if (!serverWorld.getForcedChunks().contains(chunkPos.asLong())) {
AELog.debug("Force-loading chunk @ %d,%d in %s", chunkPos.x, chunkPos.z, serverWorld.func_234923_W_()); AELog.debug("Force-loading chunk @ %d,%d in %s", chunkPos.x, chunkPos.z, serverWorld.getDimensionKey());
serverWorld.forceChunk(chunkPos.x, chunkPos.z, false); serverWorld.forceChunk(chunkPos.x, chunkPos.z, false);
} }
} }
@@ -129,7 +129,7 @@ public class MeteoritePlacerItem extends AEBaseItem {
// is a debug tool, we'll not care about being terribly efficient here // is a debug tool, we'll not care about being terribly efficient here
ChunkPos.getAllInBox(new ChunkPos(spawned.getPos()), 1).forEach(cp -> { ChunkPos.getAllInBox(new ChunkPos(spawned.getPos()), 1).forEach(cp -> {
Chunk c = world.getChunk(cp.x, cp.z); Chunk c = world.getChunk(cp.x, cp.z);
player.connection.sendPacket(new SChunkDataPacket(c, 65535, false)); // 65535 == full chunk player.connection.sendPacket(new SChunkDataPacket(c, 65535)); // 65535 == full chunk
}); });
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
@@ -101,7 +101,7 @@ public class ReplicatorCardItem extends AEBaseItem {
tag.putInt("y", y); tag.putInt("y", y);
tag.putInt("z", z); tag.putInt("z", z);
tag.putInt("side", side.ordinal()); tag.putInt("side", side.ordinal());
tag.putString("w", world.func_234923_W_().func_240901_a_().toString()); tag.putString("w", world.getDimensionKey().getLocation().toString());
tag.putInt("r", 0); tag.putInt("r", 0);
this.outputMsg(player, "Set replicator source"); this.outputMsg(player, "Set replicator source");
@@ -117,7 +117,7 @@ public class ReplicatorCardItem extends AEBaseItem {
final int src_side = ish.getInt("side"); final int src_side = ish.getInt("side");
final String worldId = ish.getString("w"); final String worldId = ish.getString("w");
final World src_w = world.getServer() final World src_w = world.getServer()
.getWorld(RegistryKey.func_240903_a_(Registry.WORLD_KEY, new ResourceLocation(worldId))); .getWorld(RegistryKey.getOrCreateKey(Registry.WORLD_KEY, new ResourceLocation(worldId)));
final int replications = ish.getInt("r") + 1; final int replications = ish.getInt("r") + 1;
final TileEntity te = src_w.getTileEntity(new BlockPos(src_x, src_y, src_z)); final TileEntity te = src_w.getTileEntity(new BlockPos(src_x, src_y, src_z));
@@ -176,7 +176,7 @@ public final class GrowingCrystalEntity extends AEBaseItemEntity {
BlockPos.Mutable testPos = new BlockPos.Mutable(); BlockPos.Mutable testPos = new BlockPos.Mutable();
for (Direction direction : Direction.values()) { for (Direction direction : Direction.values()) {
if (this.isPoweredAccelerator(testPos.func_239622_a_(pos, direction))) { if (this.isPoweredAccelerator(testPos.setAndMove(pos, direction))) {
count++; count++;
} }
} }
@@ -40,7 +40,6 @@ import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Explosion; import net.minecraft.world.Explosion;
import net.minecraft.world.Explosion.Mode;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkHooks;
@@ -158,7 +158,7 @@ public class FluidTerminalScreen extends AEBaseMEScreen<FluidTerminalContainer>
} }
@Override @Override
protected void func_230459_a_(MatrixStack matrixStack, int mouseX, int mouseY) { protected void renderHoveredTooltip(MatrixStack matrixStack, int mouseX, int mouseY) {
final Slot slot = this.getSlot(mouseX, mouseY); final Slot slot = this.getSlot(mouseX, mouseY);
if (slot instanceof IMEFluidSlot && slot.isEnabled()) { if (slot instanceof IMEFluidSlot && slot.isEnabled()) {
@@ -176,12 +176,12 @@ public class FluidTerminalScreen extends AEBaseMEScreen<FluidTerminalContainer>
list.add(new StringTextComponent(formattedAmount)); list.add(new StringTextComponent(formattedAmount));
list.add(new StringTextComponent(modName)); list.add(new StringTextComponent(modName));
this.renderTooltip(matrixStack, list, mouseX, mouseY); this.func_243308_b(matrixStack, list, mouseX, mouseY);
return; return;
} }
} }
super.func_230459_a_(matrixStack, mouseX, mouseY); super.renderHoveredTooltip(matrixStack, mouseX, mouseY);
} }
private <S extends Enum<S>> void toggleServerSetting(SettingToggleButton<S> btn, boolean backwards) { private <S extends Enum<S>> void toggleServerSetting(SettingToggleButton<S> btn, boolean backwards) {
@@ -1,6 +1,7 @@
package appeng.fluids.client.gui.widgets; package appeng.fluids.client.gui.widgets;
import java.util.Collections; import java.util.Collections;
import java.util.Optional;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
@@ -14,7 +15,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.FluidUtil;
@@ -73,7 +73,7 @@ public class FluidSlotWidget extends CustomSlotWidget {
if (clickStack.isEmpty() || mouseButton == 1) { if (clickStack.isEmpty() || mouseButton == 1) {
this.setFluidStack(null); this.setFluidStack(null);
} else if (mouseButton == 0) { } else if (mouseButton == 0) {
final LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(clickStack); final Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(clickStack);
fluidOpt.ifPresent(fluid -> { fluidOpt.ifPresent(fluid -> {
this.setFluidStack(AEFluidStack.fromFluidStack(fluid)); this.setFluidStack(AEFluidStack.fromFluidStack(fluid));
}); });
@@ -3,12 +3,12 @@ package appeng.fluids.container;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.IContainerListener; import net.minecraft.inventory.container.IContainerListener;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.FluidUtil;
@@ -39,7 +39,7 @@ public abstract class FluidConfigurableContainer extends UpgradeableContainer im
@Override @Override
protected ItemStack transferStackToContainer(ItemStack input) { protected ItemStack transferStackToContainer(ItemStack input) {
LazyOptional<FluidStack> fsOpt = FluidUtil.getFluidContained(input); Optional<FluidStack> fsOpt = FluidUtil.getFluidContained(input);
if (fsOpt.isPresent()) { if (fsOpt.isPresent()) {
final IAEFluidTank t = this.getFluidConfigInventory(); final IAEFluidTank t = this.getFluidConfigInventory();
final IAEFluidStack stack = AEFluidStack.fromFluidStack(fsOpt.orElse(null)); final IAEFluidStack stack = AEFluidStack.fromFluidStack(fsOpt.orElse(null));
@@ -18,10 +18,11 @@
package appeng.fluids.helper; package appeng.fluids.helper;
import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.FluidUtil;
@@ -46,7 +47,7 @@ public class FluidCellConfig extends CellConfig {
if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) { if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) {
super.insertItem(slot, stack, simulate); super.insertItem(slot, stack, simulate);
} }
LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack); Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) { if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) {
return stack; return stack;
} }
@@ -64,7 +65,7 @@ public class FluidCellConfig extends CellConfig {
if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) { if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) {
super.setStackInSlot(slot, stack); super.setStackInSlot(slot, stack);
} }
LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack); Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) { if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) {
return; return;
} }
@@ -82,7 +83,7 @@ public class FluidCellConfig extends CellConfig {
if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) { if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) {
super.isItemValid(slot, stack); super.isItemValid(slot, stack);
} }
LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack); Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) { if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) {
return false; return false;
} }
@@ -14,7 +14,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tags.FluidTags; import net.minecraft.tags.FluidTags;
import net.minecraft.tags.ITag; import net.minecraft.tags.ITag;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
@@ -57,8 +56,8 @@ import appeng.util.Platform;
public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridTickable { public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridTickable {
public static final ResourceLocation TAG_BLACKLIST = new ResourceLocation(AppEng.MOD_ID, public static final ITag.INamedTag<Fluid> TAG_BLACKLIST = FluidTags
"blacklisted/fluid_annihilation_plane"); .makeWrapperTag(AppEng.makeId("blacklisted/fluid_annihilation_plane").toString());
private static final PlaneModels MODELS = new PlaneModels("part/fluid_annihilation_plane", private static final PlaneModels MODELS = new PlaneModels("part/fluid_annihilation_plane",
"part/fluid_annihilation_plane_on"); "part/fluid_annihilation_plane_on");
@@ -214,8 +213,7 @@ public class FluidAnnihilationPlanePart extends BasicStatePart implements IGridT
} }
private boolean isFluidBlacklisted(Fluid fluid) { private boolean isFluidBlacklisted(Fluid fluid) {
ITag<Fluid> tag = FluidTags.getCollection().getOrCreate(TAG_BLACKLIST); return TAG_BLACKLIST.contains(fluid);
return fluid.isIn(tag);
} }
} }
@@ -18,6 +18,8 @@
package appeng.integration.abstraction; package appeng.integration.abstraction;
import mezz.jei.api.runtime.IJeiRuntime;
import appeng.integration.IIntegrationModule; import appeng.integration.IIntegrationModule;
/** /**
@@ -25,6 +27,10 @@ import appeng.integration.IIntegrationModule;
*/ */
public interface IJEI extends IIntegrationModule { public interface IJEI extends IIntegrationModule {
default IJeiRuntime getRuntime() {
return null;
}
default String getSearchText() { default String getSearchText() {
return ""; return "";
} }
@@ -0,0 +1,47 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2020 Team Appliedenergistics, 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.integration.modules.jei;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.crafting.IRecipe;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;
import appeng.container.implementations.CraftingTermContainer;
public class CraftingRecipeTransferHandler extends RecipeTransferHandler<CraftingTermContainer> {
CraftingRecipeTransferHandler(Class<CraftingTermContainer> containerClass, IRecipeTransferHandlerHelper helper) {
super(containerClass, helper);
}
@Override
protected IRecipeTransferError doTransferRecipe(CraftingTermContainer container, IRecipe<?> recipe,
IRecipeLayout recipeLayout, PlayerEntity player, boolean maxTransfer) {
return null;
}
@Override
protected boolean isCrafting() {
return true;
}
}
@@ -111,6 +111,8 @@ class FacadeRegistryPlugin implements IRecipeManagerPlugin {
ingredients.set(7, Ingredient.fromStacks(cableAnchor)); ingredients.set(7, Ingredient.fromStacks(cableAnchor));
ingredients.set(4, Ingredient.fromStacks(textureItem)); ingredients.set(4, Ingredient.fromStacks(textureItem));
result.setCount(4);
return new ShapedRecipe(id, "", 3, 3, ingredients, result); return new ShapedRecipe(id, "", 3, 3, ingredients, result);
} }
@@ -82,11 +82,15 @@ public class JEIPlugin implements IModPlugin {
@Override @Override
public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) { public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) {
// Allow recipe transfer from JEI to crafting and pattern terminal
registration.addRecipeTransferHandler(new RecipeTransferHandler<>(CraftingTermContainer.class), // Allow vanilla crafting recipe transfer from JEI to crafting terminal
VanillaRecipeCategoryUid.CRAFTING); registration.addRecipeTransferHandler(
registration.addRecipeTransferHandler(new RecipeTransferHandler<>(PatternTermContainer.class), new CraftingRecipeTransferHandler(CraftingTermContainer.class, registration.getTransferHelper()),
VanillaRecipeCategoryUid.CRAFTING); VanillaRecipeCategoryUid.CRAFTING);
// Universal handler for processing to try and handle all IRecipe
registration.addUniversalRecipeTransferHandler(
new PatternRecipeTransferHandler(PatternTermContainer.class, registration.getTransferHelper()));
} }
@Override @Override
@@ -37,6 +37,10 @@ class JeiRuntimeAdapter implements IJEI {
return true; return true;
} }
public IJeiRuntime getRuntime() {
return runtime;
}
@Override @Override
public String getSearchText() { public String getSearchText() {
return Strings.nullToEmpty(this.runtime.getIngredientFilter().getFilterText()); return Strings.nullToEmpty(this.runtime.getIngredientFilter().getFilterText());
@@ -0,0 +1,58 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2020 Team Appliedenergistics, 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.integration.modules.jei;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.crafting.IRecipe;
import mezz.jei.api.constants.VanillaRecipeCategoryUid;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;
import appeng.container.implementations.PatternTermContainer;
public class PatternRecipeTransferHandler extends RecipeTransferHandler<PatternTermContainer> {
PatternRecipeTransferHandler(Class<PatternTermContainer> containerClass, IRecipeTransferHandlerHelper helper) {
super(containerClass, helper);
}
protected IRecipeTransferError doTransferRecipe(PatternTermContainer container, IRecipe<?> recipe,
IRecipeLayout recipeLayout, PlayerEntity player, boolean maxTransfer) {
if (container.isCraftingMode()
&& recipeLayout.getRecipeCategory().getUid() != VanillaRecipeCategoryUid.CRAFTING) {
return this.helper
.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.requires_processing_mode"));
}
if (recipe.getRecipeOutput().isEmpty()) {
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.no_output"));
}
return null;
}
@Override
protected boolean isCrafting() {
return false;
}
}
@@ -18,101 +18,128 @@
package appeng.integration.modules.jei; package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable; import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.ListNBT; import net.minecraft.item.crafting.Ingredient;
import net.minecraft.item.crafting.ShapedRecipe;
import net.minecraft.item.crafting.ShapelessRecipe;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiIngredient; import mezz.jei.api.gui.ingredient.IGuiIngredient;
import mezz.jei.api.recipe.transfer.IRecipeTransferError; import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler; import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandlerHelper;
import appeng.container.slot.CraftingMatrixSlot;
import appeng.container.slot.FakeCraftingMatrixSlot;
import appeng.core.sync.network.NetworkHandler; import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.JEIRecipePacket; import appeng.core.sync.packets.JEIRecipePacket;
import appeng.util.Platform; import appeng.helpers.IContainerCraftingPacket;
class RecipeTransferHandler<T extends Container> implements IRecipeTransferHandler<T> { abstract class RecipeTransferHandler<T extends Container & IContainerCraftingPacket>
implements IRecipeTransferHandler<T> {
private final Class<T> containerClass; private final Class<T> containerClass;
protected final IRecipeTransferHandlerHelper helper;
RecipeTransferHandler(Class<T> containerClass) { RecipeTransferHandler(Class<T> containerClass, IRecipeTransferHandlerHelper helper) {
this.containerClass = containerClass; this.containerClass = containerClass;
this.helper = helper;
} }
@Override @Override
public Class<T> getContainerClass() { public final Class<T> getContainerClass() {
return this.containerClass; return this.containerClass;
} }
@Nullable
@Override @Override
public IRecipeTransferError transferRecipe(T container, IRecipeLayout recipeLayout, PlayerEntity player, public final IRecipeTransferError transferRecipe(T container, Object recipe, IRecipeLayout recipeLayout,
boolean maxTransfer, boolean doTransfer) { PlayerEntity player, boolean maxTransfer, boolean doTransfer) {
if (!doTransfer) { if (!(recipe instanceof IRecipe)) {
return null; return this.helper.createInternalError();
}
final IRecipe<?> irecipe = (IRecipe<?>) recipe;
final ResourceLocation recipeId = irecipe.getId();
if (recipeId == null) {
return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.missing_id"));
} }
Map<Integer, ? extends IGuiIngredient<ItemStack>> ingredients = recipeLayout.getItemStacks() // Check that the recipe can actually be looked up via the manager, i.e. our
.getGuiIngredients(); // facade recipes
// have an ID, but are never registered with the recipe manager.
final CompoundNBT recipe = new CompoundNBT(); boolean canSendReference = true;
if (!player.getEntityWorld().getRecipeManager().getRecipe(recipeId).isPresent()) {
int slotIndex = 0; // Validate that the recipe is a shapeless or shapedrecipe, since we can
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> ingredientEntry : ingredients.entrySet()) { // serialize those
IGuiIngredient<ItemStack> ingredient = ingredientEntry.getValue(); if (!(recipe instanceof ShapedRecipe) && !(recipe instanceof ShapelessRecipe)) {
if (!ingredient.isInput()) { return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.missing_id"));
continue;
} }
canSendReference = false;
}
for (final Slot slot : container.inventorySlots) { if (!irecipe.canFit(3, 3)) {
if (slot instanceof CraftingMatrixSlot || slot instanceof FakeCraftingMatrixSlot) { return this.helper.createUserErrorWithTooltip(I18n.format("jei.appliedenergistics2.recipe_too_large"));
if (slot.getSlotIndex() == slotIndex) { }
final ListNBT tags = new ListNBT();
final List<ItemStack> list = new ArrayList<>();
final ItemStack displayed = ingredient.getDisplayedIngredient();
// prefer currently displayed item final IRecipeTransferError error = doTransferRecipe(container, irecipe, recipeLayout, player, maxTransfer);
if (displayed != null && !displayed.isEmpty()) {
list.add(displayed); if (error != null) {
return error;
}
if (doTransfer) {
if (canSendReference) {
NetworkHandler.instance().sendToServer(new JEIRecipePacket(recipeId, isCrafting()));
} else {
// To avoid earlier problems of too large packets being sent that crashed the
// client,
// as a fallback when the recipe ID could not be resolved, we'll just send the
// displayed
// items.
NonNullList<Ingredient> flatIngredients = NonNullList.withSize(9, Ingredient.EMPTY);
ItemStack output = ItemStack.EMPTY;
// Determine the first JEI slot that has an actual input, we'll use this to
// offset the
// crafting grid target slot
int firstInputSlot = recipeLayout.getItemStacks().getGuiIngredients().entrySet().stream()
.filter(e -> e.getValue().isInput()).mapToInt(Map.Entry::getKey).min().orElse(0);
// Now map the actual ingredients into the output/input
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> entry : recipeLayout.getItemStacks()
.getGuiIngredients().entrySet()) {
IGuiIngredient<ItemStack> item = entry.getValue();
if (item.getDisplayedIngredient() == null) {
continue;
}
int inputIndex = entry.getKey() - firstInputSlot;
if (item.isInput() && inputIndex < flatIngredients.size()) {
ItemStack displayedIngredient = item.getDisplayedIngredient();
if (displayedIngredient != null) {
flatIngredients.set(inputIndex, Ingredient.fromStacks(displayedIngredient));
} }
} else if (!item.isInput() && output.isEmpty()) {
// prefer pure crystals. output = item.getDisplayedIngredient();
for (ItemStack stack : ingredient.getAllIngredients()) {
if (Platform.isRecipePrioritized(stack)) {
list.add(0, stack);
} else {
list.add(stack);
}
}
for (final ItemStack is : list) {
final CompoundNBT tag = new CompoundNBT();
is.write(tag);
tags.add(tag);
}
recipe.put("#" + slot.getSlotIndex(), tags);
break;
} }
} }
ShapedRecipe fallbackRecipe = new ShapedRecipe(recipeId, "", 3, 3, flatIngredients, output);
NetworkHandler.instance().sendToServer(new JEIRecipePacket(fallbackRecipe, isCrafting()));
} }
slotIndex++;
} }
NetworkHandler.instance().sendToServer(new JEIRecipePacket(recipe));
return null; return null;
} }
protected abstract IRecipeTransferError doTransferRecipe(T container, IRecipe<?> recipe, IRecipeLayout recipeLayout,
PlayerEntity player, boolean maxTransfer);
protected abstract boolean isCrafting();
} }
@@ -111,7 +111,7 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
} }
// Check for the normal supported fluid // Check for the normal supported fluid
if (world != null && world.func_234923_W_() == World.field_234919_h_) { if (world != null && world.getDimensionKey() == World.THE_NETHER) {
// In the nether, use Lava as the "normal" fluid // In the nether, use Lava as the "normal" fluid
return state.getFluidState().isTagged(FluidTags.LAVA) ? 1 : 0; return state.getFluidState().isTagged(FluidTags.LAVA) ? 1 : 0;
} else { } else {
@@ -23,7 +23,7 @@ public class CrystalSeedRendering implements IClientSetupComponent {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void setup() { public void setup() {
// Expose the growth of the seed to the model system // Expose the growth of the seed to the model system
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:growth"), ItemModelsProperties.registerProperty(item, new ResourceLocation("appliedenergistics2:growth"),
(is, w, p) -> CrystalSeedItem.getGrowthTicks(is) / (float) CrystalSeedItem.GROWTH_TICKS_REQUIRED); (is, w, p) -> CrystalSeedItem.getGrowthTicks(is) / (float) CrystalSeedItem.GROWTH_TICKS_REQUIRED);
} }
} }
@@ -58,7 +58,8 @@ public class FacadeItem extends AEBaseItem implements IFacadeItem, IAlphaPassIte
/** /**
* Block tag used to explicitly whitelist blocks for use in facades. * Block tag used to explicitly whitelist blocks for use in facades.
*/ */
private static final ResourceLocation TAG_WHITELISTED = new ResourceLocation(AppEng.MOD_ID, "whitelisted/facades"); private static final ITag.INamedTag<Block> BLOCK_WHITELIST = BlockTags
.makeWrapperTag(AppEng.makeId("whitelisted/facades").toString());
private static final String NBT_ITEM_ID = "item"; private static final String NBT_ITEM_ID = "item";
@@ -105,8 +106,7 @@ public class FacadeItem extends AEBaseItem implements IFacadeItem, IAlphaPassIte
BlockState blockState = block.getDefaultState(); BlockState blockState = block.getDefaultState();
final boolean areTileEntitiesEnabled = AEConfig.instance().isFeatureEnabled(AEFeature.TILE_ENTITY_FACADES); final boolean areTileEntitiesEnabled = AEConfig.instance().isFeatureEnabled(AEFeature.TILE_ENTITY_FACADES);
ITag<Block> whitelistTag = BlockTags.getCollection().getOrCreate(TAG_WHITELISTED); final boolean isWhiteListed = BLOCK_WHITELIST.contains(block);
final boolean isWhiteListed = block.isIn(whitelistTag);
final boolean isModel = blockState.getRenderType() == BlockRenderType.MODEL; final boolean isModel = blockState.getRenderType() == BlockRenderType.MODEL;
final BlockState defaultState = block.getDefaultState(); final BlockState defaultState = block.getDefaultState();
@@ -143,7 +143,7 @@ public class SpatialStorageCellItem extends AEBaseItem implements ISpatialStorag
} }
// Store some information about this transition in the plot // Store some information about this transition in the plot
TransitionInfo info = new TransitionInfo(w.func_234923_W_().func_240901_a_(), min.getBlockPos(), TransitionInfo info = new TransitionInfo(w.getDimensionKey().getLocation(), min.getBlockPos(),
max.getBlockPos(), Instant.now()); max.getBlockPos(), Instant.now());
manager.setLastTransition(plot.getId(), info); manager.setLastTransition(plot.getId(), info);
+5 -1
View File
@@ -96,7 +96,11 @@ public class CraftingGridCache
nextDetail) -> nextDetail.getPriority() - firstDetail.getPriority(); nextDetail) -> nextDetail.getPriority() - firstDetail.getPriority();
static { static {
final ThreadFactory factory = ar -> new Thread(ar, "AE Crafting Calculator"); final ThreadFactory factory = ar -> {
final Thread crafting = new Thread(ar, "AE Crafting Calculator");
crafting.setDaemon(true);
return crafting;
};
CRAFTING_POOL = Executors.newCachedThreadPool(factory); CRAFTING_POOL = Executors.newCachedThreadPool(factory);
} }
@@ -162,7 +162,7 @@ public class QuantumCluster implements ILocatable, IAECluster {
// until the center // until the center
// tile begins ticking normally. // tile begins ticking normally.
if (theWorld.isBlockLoaded(qc.center.getPos())) { if (theWorld.isBlockLoaded(qc.center.getPos())) {
final World cur = theWorld.getServer().getWorld(theWorld.func_234923_W_()); final World cur = theWorld.getServer().getWorld(theWorld.getDimensionKey());
final TileEntity te = theWorld.getTileEntity(qc.center.getPos()); final TileEntity te = theWorld.getTileEntity(qc.center.getPos());
return te != qc.center || theWorld != cur; return te != qc.center || theWorld != cur;
@@ -1,15 +0,0 @@
package appeng.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.world.chunk.listener.IChunkStatusListener;
import net.minecraft.world.server.ChunkManager;
@Mixin(ChunkManager.class)
public interface ThreadedAnvilChunkStorageAccessor {
@Accessor("field_219266_t")
IChunkStatusListener getWorldGenerationProgressListener();
}
@@ -0,0 +1,19 @@
package appeng.mixins.feature;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.Features;
import net.minecraft.world.gen.feature.IFeatureConfig;
@Mixin(Features.class)
public interface ConfiguredFeaturesAccessor {
@Invoker("register")
static <FC extends IFeatureConfig> ConfiguredFeature<FC, ?> register(String id,
ConfiguredFeature<FC, ?> configuredFeature) {
throw new AssertionError();
}
}
@@ -0,0 +1,27 @@
package appeng.mixins.spatial;
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.CallbackInfo;
import net.minecraft.util.registry.WorldGenRegistries;
import net.minecraft.world.biome.BiomeRegistry;
import appeng.spatial.SpatialStorageBiome;
import appeng.spatial.SpatialStorageDimensionIds;
/**
* This only needs to be here because the server-side will create a dynamic
* registry manager long before our mod is initialized.
*/
@Mixin(BiomeRegistry.class)
public class BiomesMixin {
@Inject(method = "<clinit>", at = @At("TAIL"))
private static void registerBiomes(CallbackInfo ci) {
WorldGenRegistries.register(WorldGenRegistries.BIOME, SpatialStorageDimensionIds.BIOME_KEY.getLocation(),
SpatialStorageBiome.INSTANCE);
}
}
@@ -35,4 +35,4 @@ public class DimensionOptionMixin {
return dimensions; return dimensions;
} }
} }
@@ -2,15 +2,25 @@ package appeng.mixins.spatial;
import java.util.OptionalLong; import java.util.OptionalLong;
import com.mojang.serialization.Lifecycle;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.server.IDynamicRegistries;
import net.minecraft.tags.BlockTags; import net.minecraft.tags.BlockTags;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.SimpleRegistry;
import net.minecraft.world.Dimension;
import net.minecraft.world.DimensionType; import net.minecraft.world.DimensionType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.DimensionSettings;
import appeng.spatial.SpatialStorageChunkGenerator;
import appeng.spatial.SpatialStorageDimensionIds; import appeng.spatial.SpatialStorageDimensionIds;
/** /**
@@ -21,12 +31,37 @@ import appeng.spatial.SpatialStorageDimensionIds;
@Mixin(value = DimensionType.class) @Mixin(value = DimensionType.class)
public class DimensionTypeMixin { public class DimensionTypeMixin {
@Inject(method = "func_236027_a_", at = @At("TAIL")) @Invoker("<init>")
private static void addRegistryDefaults(IDynamicRegistries.Impl registryTracker, CallbackInfoReturnable<?> cir) { static DimensionType create(OptionalLong fixedTime, boolean hasSkylight, boolean hasCeiling, boolean ultrawarm,
boolean natural, double coordinateScale, boolean piglinSafe, boolean bedWorks, boolean respawnAnchorWorks,
boolean hasRaids, int logicalHeight, ResourceLocation infiniburn, ResourceLocation skyProperties,
float ambientLight) {
throw new AssertionError();
}
registryTracker.func_239774_a_(SpatialStorageDimensionIds.DIMENSION_TYPE_ID, @Inject(method = "registerTypes", at = @At("TAIL"))
new DimensionType(OptionalLong.of(12000), false, false, false, false, false, false, true, false, false, private static void addRegistryDefaults(DynamicRegistries.Impl registryTracker, CallbackInfoReturnable<?> cir) {
256, BlockTags.INFINIBURN_OVERWORLD.getName(), 1.0f)); DimensionType dimensionType = create(OptionalLong.of(12000), false, false, false, false, 1.0, false, false,
false, false, 256, BlockTags.INFINIBURN_OVERWORLD.getName(),
SpatialStorageDimensionIds.SKY_PROPERTIES_ID, 1.0f);
Registry.register(registryTracker.func_230520_a_(), SpatialStorageDimensionIds.DIMENSION_TYPE_ID.getLocation(),
dimensionType);
}
/**
* Insert our custom dimension into the initial registry. <em>This is what will
* ultimately lead to the creation of a new World.</em>
*/
@Inject(method = "getDefaultSimpleRegistry", at = @At("RETURN"))
private static void buildDimensionRegistry(Registry<DimensionType> dimensionTypes, Registry<Biome> biomes,
Registry<DimensionSettings> dimensionSettings, long seed,
CallbackInfoReturnable<SimpleRegistry<Dimension>> cir) {
SimpleRegistry<Dimension> simpleregistry = cir.getReturnValue();
simpleregistry.register(SpatialStorageDimensionIds.DIMENSION_ID, new Dimension(() -> {
return dimensionTypes.getOrThrow(SpatialStorageDimensionIds.DIMENSION_TYPE_ID);
}, new SpatialStorageChunkGenerator(biomes)), Lifecycle.stable());
} }
@@ -0,0 +1,33 @@
package appeng.mixins.spatial;
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.block.PortalInfo;
import net.minecraft.entity.Entity;
import net.minecraft.world.server.ServerWorld;
import appeng.spatial.SpatialStorageDimensionIds;
import appeng.spatial.SpatialStorageHelper;
/**
* This mixin sets the teleport destination, because otherwise Vanilla will not
* move the player.
*/
@Mixin(Entity.class)
public class EntityMixin {
@Inject(method = "func_241829_a", at = @At("HEAD"), cancellable = true, allow = 1)
public void getTeleportTarget(ServerWorld destination, CallbackInfoReturnable<PortalInfo> cri) {
// Check if a destination has been set for the entity currently being teleported
if (destination.getDimensionKey() == SpatialStorageDimensionIds.WORLD_ID) {
PortalInfo target = SpatialStorageHelper.getInstance().getTeleportTarget();
if (target != null) {
cri.setReturnValue(target);
}
}
}
}
@@ -1,15 +1,15 @@
package appeng.mixins.spatial; package appeng.mixins.spatial;
import java.util.Optional;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.world.DimensionRenderInfo; import net.minecraft.client.world.DimensionRenderInfo;
import net.minecraft.util.RegistryKey; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.DimensionType;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import appeng.spatial.SpatialStorageDimensionIds; import appeng.spatial.SpatialStorageDimensionIds;
import appeng.spatial.SpatialStorageSkyProperties; import appeng.spatial.SpatialStorageSkyProperties;
@@ -17,12 +17,12 @@ import appeng.spatial.SpatialStorageSkyProperties;
@Mixin(DimensionRenderInfo.class) @Mixin(DimensionRenderInfo.class)
public class SkyPropertiesMixin { public class SkyPropertiesMixin {
@Inject(method = "func_239215_a_", at = @At("HEAD"), cancellable = true) @Shadow
private static void byDimensionType(Optional<RegistryKey<DimensionType>> optional, private static Object2ObjectMap<ResourceLocation, DimensionRenderInfo> field_239208_a_/* BY_IDENTIFIER */;
CallbackInfoReturnable<DimensionRenderInfo> ci) {
if (optional.orElse(null) == SpatialStorageDimensionIds.DIMENSION_TYPE_ID) { @Inject(method = "<clinit>", at = @At("TAIL"))
ci.setReturnValue(SpatialStorageSkyProperties.INSTANCE); private static void init(CallbackInfo ci) {
} field_239208_a_.put(SpatialStorageDimensionIds.SKY_PROPERTIES_ID, SpatialStorageSkyProperties.INSTANCE);
} }
} }
@@ -23,7 +23,7 @@ public class SkyRenderMixin {
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
@Inject(method = "renderSky(Lcom/mojang/blaze3d/matrix/MatrixStack;F)V", at = @At("HEAD"), cancellable = true) @Inject(method = "renderSky(Lcom/mojang/blaze3d/matrix/MatrixStack;F)V", at = @At("HEAD"), cancellable = true)
public void renderSky(MatrixStack matrices, float tickDelta, CallbackInfo ci) { public void renderSky(MatrixStack matrices, float tickDelta, CallbackInfo ci) {
if (mc.world.func_234922_V_() == SpatialStorageDimensionIds.DIMENSION_TYPE_ID) { if (mc.world.getDimensionKey() == SpatialStorageDimensionIds.WORLD_ID) {
SpatialSkyRender.getInstance().render(matrices); SpatialSkyRender.getInstance().render(matrices);
ci.cancel(); ci.cancel();
} }
@@ -0,0 +1,25 @@
package appeng.mixins.structure;
import java.util.List;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.feature.structure.Structure;
/**
* Allows access to the copy of _all_ structures that is maintained within each
* instance of {@link Biome}, in order to add our new structure to it. Note that
* this does not mean the structure will start _generating_ in this biome, it
* will only continue to generate if an adjacent biome has started the structure
* and it extends into this one.
*/
@Mixin(Biome.class)
public interface BiomeAccessor {
@Accessor
Map<Integer, List<Structure<?>>> getBiomeStructures();
}
@@ -0,0 +1,20 @@
package appeng.mixins.structure;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.gen.feature.structure.Structure;
import net.minecraft.world.gen.feature.structure.StructureFeatures;
@Mixin(StructureFeatures.class)
public interface ConfiguredStructureFeaturesAccessor {
@Invoker("func_244162_a")
static <FC extends IFeatureConfig, F extends Structure<FC>> StructureFeature<FC, F> register(String id,
StructureFeature<FC, F> configuredStructureFeature) {
throw new AssertionError();
}
}
@@ -1,4 +1,4 @@
package appeng.mixins; package appeng.mixins.structure;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@@ -0,0 +1,31 @@
package appeng.mixins.structure;
import java.util.List;
import java.util.function.Supplier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.world.biome.BiomeGenerationSettings;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.StructureFeature;
/**
* Allows the settings in a Biome's generation settings to be modified.
*/
@Mixin(BiomeGenerationSettings.class)
public interface GenerationSettingsAccessor {
@Accessor("features")
List<List<Supplier<ConfiguredFeature<?, ?>>>> getFeatures();
@Accessor("features")
void setFeatures(List<List<Supplier<ConfiguredFeature<?, ?>>>> features);
@Accessor("structures")
List<Supplier<StructureFeature<?, ?>>> getStructureFeatures();
@Accessor("structures")
void setStructureFeatures(List<Supplier<StructureFeature<?, ?>>> structureFeatures);
}
@@ -1,4 +1,4 @@
package appeng.mixins; package appeng.mixins.structure;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.gen.Invoker;
@@ -7,10 +7,10 @@ import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.structure.Structure; import net.minecraft.world.gen.feature.structure.Structure;
@Mixin(Structure.class) @Mixin(Structure.class)
public interface StructureAccessor { public interface StructureFeatureAccessor {
@Invoker("func_236394_a_") @Invoker("func_236394_a_")
static <F extends Structure<?>> F register(String id, F feature, GenerationStage.Decoration defaultStage) { static <F extends Structure<?>> F register(String id, F structureFeature, GenerationStage.Decoration step) {
throw new AssertionError(); throw new AssertionError();
} }
@@ -82,6 +82,10 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
public static final ResourceLocation TAG_BLACKLIST = new ResourceLocation(AppEng.MOD_ID, public static final ResourceLocation TAG_BLACKLIST = new ResourceLocation(AppEng.MOD_ID,
"blacklisted/annihilation_plane"); "blacklisted/annihilation_plane");
private static final ITag.INamedTag<Block> BLOCK_BLACKLIST = BlockTags.makeWrapperTag(TAG_BLACKLIST.toString());
private static final ITag.INamedTag<Item> ITEM_BLACKLIST = ItemTags.makeWrapperTag(TAG_BLACKLIST.toString());
private static final PlaneModels MODELS = new PlaneModels("part/annihilation_plane", "part/annihilation_plane_on"); private static final PlaneModels MODELS = new PlaneModels("part/annihilation_plane", "part/annihilation_plane_on");
@PartModels @PartModels
@@ -527,13 +531,11 @@ public class AnnihilationPlanePart extends BasicStatePart implements IGridTickab
} }
public static boolean isBlockBlacklisted(Block b) { public static boolean isBlockBlacklisted(Block b) {
ITag<Block> tag = BlockTags.getCollection().getOrCreate(TAG_BLACKLIST); return BLOCK_BLACKLIST.contains(b);
return b.isIn(tag);
} }
public static boolean isItemBlacklisted(Item i) { public static boolean isItemBlacklisted(Item i) {
ITag<Item> tag = ItemTags.getCollection().getOrCreate(TAG_BLACKLIST); return ITEM_BLACKLIST.contains(i);
return i.isIn(tag);
} }
} }
@@ -26,7 +26,6 @@ import java.util.Random;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.ContainerType; import net.minecraft.inventory.container.ContainerType;
@@ -277,51 +276,62 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
} }
private static boolean spawnItemEntity(World w, TileEntity te, AEPartLocation side, ItemStack is) { private static boolean spawnItemEntity(World w, TileEntity te, AEPartLocation side, ItemStack is) {
// the item offset based on the entity height plus some offset
final double itemOffset = .55 + EntityType.ITEM.getHeight();
// The center of the block the plane is located in // The center of the block the plane is located in
final double centerX = te.getPos().getX() + .5; final double centerX = te.getPos().getX() + .5;
final double centerY = te.getPos().getY() + .5; final double centerY = te.getPos().getY();
final double centerZ = te.getPos().getZ() + .5; final double centerZ = te.getPos().getZ() + .5;
// When spawning downwards, we have to take the item height of 0.25 into account // Create an ItemEntity already at the position of the plane.
// Otherwise it will get stuck and be spit out in a random direction as // We don't know the final position, but need it for its size.
// minecraft spawns it at its feet position and not center Entity entity = new ItemEntity(w, centerX, centerY, centerZ, is.copy());
final double additionalYOffset = side.yOffset == -1 ? -.3 : 0;
// Replace it if there is a custom entity
if (is.getItem().hasCustomEntity(is)) {
Entity result = is.getItem().createEntity(w, entity, is);
// Destroy the old one, in case it's spawned somehow and replace with the new
// one.
if (result != null) {
entity.remove();
entity = result;
}
}
// When spawning downwards, we have to take into account that it spawns it at
// their "feet" and not center like x or z. So we move it up to be flush with
// the plane
final double additionalYOffset = side.yOffset == -1 ? 1 - entity.getHeight() : 0;
// Calculate the maximum spawn area so an entity hitbox will always be inside
// the block.
final double spawnAreaHeight = Math.max(0, 1 - entity.getHeight());
final double spawnAreaWidth = Math.max(0, 1 - entity.getWidth());
// Calculate the offsets to spawn it into the adjacent block, taking the sign // Calculate the offsets to spawn it into the adjacent block, taking the sign
// into account. // into account.
// Spawn it 0.8 blocks away from the center pos when facing in this direction // Spawn it 0.8 blocks away from the center pos when facing in this direction
// Every other direction will select a position in a .5 block area around the // Every other direction will select a position in a .5 block area around the
// block center. // block center.
final double offsetX = (side.xOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25) final double offsetX = (side.xOffset == 0) //
: (side.xOffset * itemOffset); ? ((RANDOM_OFFSET.nextFloat() * spawnAreaWidth) - spawnAreaWidth / 2)
final double offsetY = (side.yOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25) : (side.xOffset * (.525 + entity.getWidth() / 2));
: ((side.yOffset * itemOffset) + additionalYOffset); final double offsetY = (side.yOffset == 0) //
final double offsetZ = (side.zOffset == 0) ? ((RANDOM_OFFSET.nextFloat() / 2) - .25) ? (RANDOM_OFFSET.nextFloat() * spawnAreaHeight)
: (side.zOffset * itemOffset); : ((side.yOffset) + additionalYOffset);
final double offsetZ = (side.zOffset == 0) //
? ((RANDOM_OFFSET.nextFloat() * spawnAreaWidth) - spawnAreaWidth / 2)
: (side.zOffset * (.525 + entity.getWidth() / 2));
final double absoluteX = centerX + offsetX; final double absoluteX = centerX + offsetX;
final double absoluteY = centerY + offsetY; final double absoluteY = centerY + offsetY;
final double absoluteZ = centerZ + offsetZ; final double absoluteZ = centerZ + offsetZ;
final ItemEntity ei = new ItemEntity(w, absoluteX, absoluteY, absoluteZ, is.copy()); // Set to correct position and slow the motion down a bit
Entity result = ei; entity.setPosition(absoluteX, absoluteY, absoluteZ);
entity.setMotion(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1);
ei.setMotion(side.xOffset * .1, side.yOffset * 0.1, side.zOffset * 0.1); // Try to spawn it and destroy it in case it's not possible
if (!w.addEntity(entity)) {
if (is.getItem().hasCustomEntity(is)) { entity.remove();
result = is.getItem().createEntity(w, ei, is);
if (result != null) {
ei.remove();
} else {
result = ei;
}
}
if (!w.addEntity(result)) {
result.remove();
return false; return false;
} }
return true; return true;
@@ -379,12 +389,12 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
@Override @Override
public BlockPos getPos() { public BlockPos getPos() {
return this.rayTraceResult.getPos(); return this.func_242401_i().getPos();
} }
@Override @Override
public boolean canPlace() { public boolean canPlace() {
return this.world.getBlockState(this.rayTraceResult.getPos()).isReplaceable(this); return getWorld().getBlockState(this.getPos()).isReplaceable(this);
} }
@Override @Override
@@ -423,7 +433,7 @@ public class FormationPlanePart extends AbstractFormationPlanePart<IAEItemStack>
} }
@Override @Override
public boolean func_225518_g_() { public boolean hasSecondaryUseForPlayer() {
return false; return false;
} }
@@ -101,7 +101,7 @@ public class PlaneBakedModel implements IDynamicBakedModel {
} }
@Override @Override
public boolean func_230044_c_() { public boolean isSideLit() {
return false;// TODO return false;// TODO
} }
@@ -90,7 +90,7 @@ public class SpatialStorageCommand implements ISubCommand {
*/ */
private void teleportBack(CommandSource source) { private void teleportBack(CommandSource source) {
if (source.getWorld().func_234923_W_() != SpatialStorageDimensionIds.WORLD_ID) { if (source.getWorld().getDimensionKey() != SpatialStorageDimensionIds.WORLD_ID) {
throw new CommandException(new StringTextComponent("Must be within the spatial storage world.")); throw new CommandException(new StringTextComponent("Must be within the spatial storage world."));
} }
@@ -110,7 +110,7 @@ public class SpatialStorageCommand implements ISubCommand {
} }
} }
throw new CommandException(ITextComponent.func_241827_a_("Couldn't find a plot for the current position.")); throw new CommandException(new StringTextComponent("Couldn't find a plot for the current position."));
} }
@@ -120,8 +120,7 @@ public class SpatialStorageCommand implements ISubCommand {
private void teleportBack(CommandSource source, SpatialStoragePlot plot) { private void teleportBack(CommandSource source, SpatialStoragePlot plot) {
TransitionInfo lastTransition = plot.getLastTransition(); TransitionInfo lastTransition = plot.getLastTransition();
if (lastTransition == null) { if (lastTransition == null) {
throw new CommandException( throw new CommandException(new StringTextComponent("This plot doesn't have a last known transition."));
ITextComponent.func_241827_a_("This plot doesn't have a last known transition."));
} }
String command = getTeleportCommand(lastTransition.getWorldId(), lastTransition.getMin().add(0, 1, 0)); String command = getTeleportCommand(lastTransition.getWorldId(), lastTransition.getMin().add(0, 1, 0));
@@ -157,7 +156,7 @@ public class SpatialStorageCommand implements ISubCommand {
sendKeyValuePair(source, "Size", formatBlockPos(plot.getSize(), "x")); sendKeyValuePair(source, "Size", formatBlockPos(plot.getSize(), "x"));
// Show the plot's origin and make it clickable to teleport directly to it // Show the plot's origin and make it clickable to teleport directly to it
String teleportToPlotCommand = getTeleportCommand(SpatialStorageDimensionIds.WORLD_ID.func_240901_a_(), String teleportToPlotCommand = getTeleportCommand(SpatialStorageDimensionIds.WORLD_ID.getLocation(),
plot.getOrigin()); plot.getOrigin());
sendKeyValuePair(source, "Origin", new StringTextComponent(formatBlockPos(plot.getOrigin(), ",")) sendKeyValuePair(source, "Origin", new StringTextComponent(formatBlockPos(plot.getOrigin(), ","))
.modifyStyle(makeCommandLink(teleportToPlotCommand, "Teleport into plot"))); .modifyStyle(makeCommandLink(teleportToPlotCommand, "Teleport into plot")));
@@ -189,7 +188,7 @@ public class SpatialStorageCommand implements ISubCommand {
private static void teleportToPlot(CommandSource source, int plotId) { private static void teleportToPlot(CommandSource source, int plotId) {
SpatialStoragePlot plot = getPlot(plotId); SpatialStoragePlot plot = getPlot(plotId);
String teleportCommand = getTeleportCommand(SpatialStorageDimensionIds.WORLD_ID.func_240901_a_(), String teleportCommand = getTeleportCommand(SpatialStorageDimensionIds.WORLD_ID.getLocation(),
plot.getOrigin()); plot.getOrigin());
runCommandFor(source, teleportCommand); runCommandFor(source, teleportCommand);
@@ -212,7 +211,7 @@ public class SpatialStorageCommand implements ISubCommand {
if (!(cell.getItem() instanceof SpatialStorageCellItem)) { if (!(cell.getItem() instanceof SpatialStorageCellItem)) {
throw new CommandException( throw new CommandException(
ITextComponent.func_241827_a_("Storage cell items don't implement the storage cell interface!")); new StringTextComponent("Storage cell items don't implement the storage cell interface!"));
} }
SpatialStorageCellItem spatialCellItem = (SpatialStorageCellItem) cell.getItem(); SpatialStorageCellItem spatialCellItem = (SpatialStorageCellItem) cell.getItem();
@@ -303,7 +302,7 @@ public class SpatialStorageCommand implements ISubCommand {
* Gets the spatial storage plot that the command source is currently in. * Gets the spatial storage plot that the command source is currently in.
*/ */
private static SpatialStoragePlot getCurrentPlot(CommandSource source) { private static SpatialStoragePlot getCurrentPlot(CommandSource source) {
if (source.getWorld().func_234923_W_() != SpatialStorageDimensionIds.WORLD_ID) { if (source.getWorld().getDimensionKey() != SpatialStorageDimensionIds.WORLD_ID) {
throw new CommandException(new StringTextComponent("Must be within the spatial storage world.")); throw new CommandException(new StringTextComponent("Must be within the spatial storage world."));
} }
@@ -321,7 +320,7 @@ public class SpatialStorageCommand implements ISubCommand {
} }
} }
throw new CommandException(ITextComponent.func_241827_a_("Couldn't find a plot for the current position.")); throw new CommandException(new StringTextComponent("Couldn't find a plot for the current position."));
} }
} }
@@ -87,8 +87,8 @@ public class TestMeteoritesCommand implements ISubCommand {
world = player.getServerWorld(); world = player.getServerWorld();
centerBlock = new BlockPos(player.getPosX(), 0, player.getPosZ()); centerBlock = new BlockPos(player.getPosX(), 0, player.getPosZ());
} else { } else {
world = srv.getWorld(World.field_234918_g_); world = srv.getWorld(World.OVERWORLD);
centerBlock = world.func_241135_u_(); centerBlock = world.getSpawnPoint();
} }
ChunkPos center = new ChunkPos(centerBlock); ChunkPos center = new ChunkPos(centerBlock);
@@ -172,8 +172,9 @@ public class TestMeteoritesCommand implements ISubCommand {
msg.append(getClickablePosition(world, settings, pos)).append(restOfLine); msg.append(getClickablePosition(world, settings, pos)).append(restOfLine);
// Add a tooltip // Add a tooltip
String biomeId = world.func_242406_i(pos).map(bk -> bk.getLocation().toString()).orElse("unknown");
ITextComponent tooltip = new StringTextComponent(settings.toString() + "\nBiome: ").deepCopy() ITextComponent tooltip = new StringTextComponent(settings.toString() + "\nBiome: ").deepCopy()
.append(world.getBiome(pos).getDisplayName()); .appendString(biomeId);
msg.modifyStyle(style -> style.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, tooltip))); msg.modifyStyle(style -> style.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, tooltip)));
sender.sendFeedback(msg, true); sender.sendFeedback(msg, true);
@@ -68,8 +68,8 @@ public class TestOreGenCommand implements ISubCommand {
world = player.getServerWorld(); world = player.getServerWorld();
center = new BlockPos(player.getPosX(), 0, player.getPosZ()); center = new BlockPos(player.getPosX(), 0, player.getPosZ());
} catch (CommandSyntaxException e) { } catch (CommandSyntaxException e) {
world = srv.getWorld(World.field_234918_g_); world = srv.getWorld(World.OVERWORLD);
center = world.func_241135_u_(); center = world.getSpawnPoint();
} }
ChunkPos tl = new ChunkPos(center.add(-radius, 0, -radius)); ChunkPos tl = new ChunkPos(center.add(-radius, 0, -radius));
@@ -31,8 +31,7 @@ import net.minecraft.block.Block;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IServerWorld;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunk; import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
@@ -92,18 +91,14 @@ public final class CompassService {
} }
} }
public void tryUpdateArea(final IWorld w, ChunkPos chunkPos) { public void tryUpdateArea(final IServerWorld w, ChunkPos chunkPos) {
// If this seems weird: during worldgen, WorldAccess is a specific region, but // If this seems weird: during worldgen, WorldAccess is a specific region, but
// getWorld is // getWorld is
// still the server world. We do need to use the world access to get the chunk // still the server world. We do need to use the world access to get the chunk
// in question // in question
// though, since during worldgen, it's not comitted to the actual world yet. // though, since during worldgen, it's not comitted to the actual world yet.
World world = w.getWorld();
if (!(world instanceof ServerWorld)) {
return;
}
IChunk chunk = w.getChunk(chunkPos.x, chunkPos.z); IChunk chunk = w.getChunk(chunkPos.x, chunkPos.z);
updateArea((ServerWorld) world, chunk); updateArea(w.getWorld(), chunk);
} }
public void updateArea(final ServerWorld w, IChunk chunk) { public void updateArea(final ServerWorld w, IChunk chunk) {
@@ -33,7 +33,9 @@ public final class CompassThreadFactory implements ThreadFactory {
@Override @Override
public Thread newThread(@Nonnull final Runnable job) { public Thread newThread(@Nonnull final Runnable job) {
Preconditions.checkNotNull(job); Preconditions.checkNotNull(job);
final Thread compass = new Thread(job, "AE Compass Service");
compass.setDaemon(true);
return new Thread(job, "AE Compass Service"); return compass;
} }
} }
@@ -323,7 +323,7 @@ public class CachedPlane {
WorldData.instance().compassData().service().updateArea(this.getWorld(), c); WorldData.instance().compassData().service().updateArea(this.getWorld(), c);
SChunkDataPacket cdp = new SChunkDataPacket(c, verticalBits, false); SChunkDataPacket cdp = new SChunkDataPacket(c, verticalBits);
world.getChunkProvider().chunkManager.getTrackingPlayers(c.getPos(), false) world.getChunkProvider().chunkManager.getTrackingPlayers(c.getPos(), false)
.forEach(spe -> spe.connection.sendPacket(cdp)); .forEach(spe -> spe.connection.sendPacket(cdp));
} }
@@ -20,33 +20,25 @@ package appeng.spatial;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeAmbience; import net.minecraft.world.biome.BiomeAmbience;
import net.minecraft.world.biome.BiomeGenerationSettings;
import net.minecraft.world.biome.MobSpawnInfo;
import net.minecraft.world.gen.surfacebuilders.ConfiguredSurfaceBuilder; import net.minecraft.world.gen.surfacebuilders.ConfiguredSurfaceBuilder;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder; import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
/** /**
* The single biome used within the spatial storage world. * The single biome used within the spatial storage world.
*/ */
public class SpatialStorageBiome extends Biome { public class SpatialStorageBiome {
public static final SpatialStorageBiome INSTANCE = new SpatialStorageBiome(); public static final Biome INSTANCE = new Biome.Builder()
.withGenerationSettings(new BiomeGenerationSettings.Builder().withSurfaceBuilder(
public SpatialStorageBiome() { new ConfiguredSurfaceBuilder<>(SurfaceBuilder.NOPE, SurfaceBuilder.STONE_STONE_GRAVEL_CONFIG))
super(new Biome.Builder() .build())
.surfaceBuilder( .precipitation(Biome.RainType.NONE).category(Biome.Category.NONE).depth(0).scale(1)
new ConfiguredSurfaceBuilder<>(SurfaceBuilder.NOPE, SurfaceBuilder.STONE_STONE_GRAVEL_CONFIG)) // Copied from the vanilla void biome
.precipitation(RainType.NONE).category(Category.NONE).depth(0).scale(1) .temperature(0.5F).downfall(0.5F)
// Copied from the vanilla void biome .setEffects(new BiomeAmbience.Builder().setWaterColor(4159204).setWaterFogColor(329011).setFogColor(0)
.temperature(0.5F).downfall(0.5F).func_235097_a_(new BiomeAmbience.Builder().setWaterColor(4159204) .withSkyColor(0x111111).build())
.setWaterFogColor(329011).setFogColor(0).build()) .withMobSpawnSettings(new MobSpawnInfo.Builder().withCreatureSpawnProbability(0).copy()).build();
.parent(null));
}
@Override
@OnlyIn(Dist.CLIENT)
public int getSkyColor() {
return 0x111111;
}
} }
@@ -23,15 +23,16 @@ import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryLookupCodec;
import net.minecraft.world.Blockreader; import net.minecraft.world.Blockreader;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeManager; import net.minecraft.world.biome.BiomeManager;
import net.minecraft.world.biome.provider.BiomeProvider;
import net.minecraft.world.biome.provider.SingleBiomeProvider; import net.minecraft.world.biome.provider.SingleBiomeProvider;
import net.minecraft.world.chunk.IChunk; import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.ChunkGenerator; import net.minecraft.world.gen.ChunkGenerator;
@@ -48,18 +49,28 @@ import appeng.core.Api;
*/ */
public class SpatialStorageChunkGenerator extends ChunkGenerator { public class SpatialStorageChunkGenerator extends ChunkGenerator {
/**
* This codec is necessary to restore the actual instance of the Biome we use,
* since it is sources from the dynamic registries and <em>must be the same
* object as in the registry!</em>.
* <p>
* If it was not the same object, then the Object->ID lookup would fail since it
* uses an identity hashmap internally.
*/
public static final Codec<SpatialStorageChunkGenerator> CODEC = RegistryLookupCodec
.getLookUpCodec(Registry.BIOME_KEY)
.xmap(SpatialStorageChunkGenerator::new, SpatialStorageChunkGenerator::getBiomeRegistry).stable().codec();
private final Registry<Biome> biomeRegistry;
private final Blockreader columnSample; private final Blockreader columnSample;
public static final SpatialStorageChunkGenerator INSTANCE = new SpatialStorageChunkGenerator();
public static final Codec<SpatialStorageChunkGenerator> CODEC = RecordCodecBuilder
.create((instance) -> instance.stable(INSTANCE));
private final BlockState defaultBlockState; private final BlockState defaultBlockState;
private SpatialStorageChunkGenerator() { public SpatialStorageChunkGenerator(Registry<Biome> biomeRegistry) {
super(createBiomeProvider(), createSettings()); super(createBiomeSource(biomeRegistry), createSettings());
this.defaultBlockState = Api.instance().definitions().blocks().matrixFrame().block().getDefaultState(); this.defaultBlockState = Api.instance().definitions().blocks().matrixFrame().block().getDefaultState();
this.biomeRegistry = biomeRegistry;
// Vertical sample is mostly used for Feature generation, for those purposes // Vertical sample is mostly used for Feature generation, for those purposes
// we're all filled with matrix blocks // we're all filled with matrix blocks
@@ -73,8 +84,12 @@ public class SpatialStorageChunkGenerator extends ChunkGenerator {
return CODEC; return CODEC;
} }
private static BiomeProvider createBiomeProvider() { private static SingleBiomeProvider createBiomeSource(Registry<Biome> biomeRegistry) {
return new SingleBiomeProvider(SpatialStorageBiome.INSTANCE); return new SingleBiomeProvider(biomeRegistry.getOrThrow(SpatialStorageDimensionIds.BIOME_KEY));
}
public Registry<Biome> getBiomeRegistry() {
return biomeRegistry;
} }
private static DimensionStructuresSettings createSettings() { private static DimensionStructuresSettings createSettings() {
@@ -6,6 +6,7 @@ import net.minecraft.util.registry.Registry;
import net.minecraft.world.Dimension; import net.minecraft.world.Dimension;
import net.minecraft.world.DimensionType; import net.minecraft.world.DimensionType;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import appeng.core.AppEng; import appeng.core.AppEng;
import appeng.mixins.spatial.DimensionTypeMixin; import appeng.mixins.spatial.DimensionTypeMixin;
@@ -21,7 +22,7 @@ public final class SpatialStorageDimensionIds {
* This is defined in {@link DimensionTypeMixin}. * This is defined in {@link DimensionTypeMixin}.
*/ */
public static final RegistryKey<DimensionType> DIMENSION_TYPE_ID = RegistryKey public static final RegistryKey<DimensionType> DIMENSION_TYPE_ID = RegistryKey
.func_240903_a_(Registry.DIMENSION_TYPE_KEY, AppEng.makeId("spatial_storage")); .getOrCreateKey(Registry.DIMENSION_TYPE_KEY, AppEng.makeId("spatial_storage"));
/** /**
* ID of the {@link net.minecraft.world.gen.ChunkGenerator} used for the spatial * ID of the {@link net.minecraft.world.gen.ChunkGenerator} used for the spatial
@@ -33,24 +34,30 @@ public final class SpatialStorageDimensionIds {
* ID of the {@link net.minecraft.world.biome.Biome} used for the spatial * ID of the {@link net.minecraft.world.biome.Biome} used for the spatial
* storage world. * storage world.
*/ */
public static final ResourceLocation BIOME_ID = AppEng.makeId("spatial_storage"); public static final RegistryKey<Biome> BIOME_KEY = RegistryKey.getOrCreateKey(Registry.BIOME_KEY,
AppEng.makeId("spatial_storage"));
/** /**
* ID of the {@link Dimension} used for the spatial storage dimension. * ID of the {@link Dimension} used for the spatial storage dimension.
* <p> * <p>
* This is defined in * This is defined in {@link appeng.mixins.spatial.DimensionTypeMixin}.
* <code>data/minecraft/dimension/appliedenergistics2/spatial_storage.json</code>
*/ */
public static final RegistryKey<Dimension> DIMENSION_ID = RegistryKey.func_240903_a_(Registry.DIMENSION_KEY, public static final RegistryKey<Dimension> DIMENSION_ID = RegistryKey.getOrCreateKey(Registry.DIMENSION_KEY,
AppEng.makeId("spatial_storage")); AppEng.makeId("spatial_storage"));
/** /**
* ID of the {@link World} that is instantiated from the dimension/dimension * ID of the {@link World} that is instantiated from the dimension/dimension
* type. * type.
*/ */
public static final RegistryKey<World> WORLD_ID = RegistryKey.func_240903_a_(Registry.WORLD_KEY, public static final RegistryKey<World> WORLD_ID = RegistryKey.getOrCreateKey(Registry.WORLD_KEY,
AppEng.makeId("spatial_storage")); AppEng.makeId("spatial_storage"));
/**
* ID of the {@link net.minecraft.client.world.DimensionRenderInfo} used for the
* spatial storage world.
*/
public static ResourceLocation SKY_PROPERTIES_ID = AppEng.makeId("spatial_storage");
private SpatialStorageDimensionIds() { private SpatialStorageDimensionIds() {
} }

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