Compare commits

...

53 Commits

Author SHA1 Message Date
Sebastian Hartte b1a55f3a79 Bumped dependencies. 2020-08-27 00:49:41 +02:00
Sebastian Hartte 226e9596ee Fix the fluid export bus not actually extracting fluids from storage when exporting. 2020-08-27 00:21:14 +02:00
Sebastian Hartte 5cab9c8799 Fix rendering of fluid filter slots in UIs. 2020-08-27 00:20:53 +02:00
Sebastian Hartte 1d2ac29742 Document Maven Repositories. 2020-08-26 23:22:17 +02:00
Sebastian Hartte cbe6012b98 Merge remote-tracking branch 'origin/master' into fabric/master 2020-08-26 23:20:50 +02:00
Sebastian Hartte 8a0dd192e5 Added Modmaven repository to README.md 2020-08-26 23:19:42 +02:00
Sebastian Hartte 1842febf86 Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts:
#	build.gradle
2020-08-26 11:41:13 +02:00
Sebastian Hartte a97b35f3d0 Merge branch '8.0.x-1.16.1' 2020-08-26 11:39:20 +02:00
Sebastian Hartte 00d4c20d9f Strip pom.xml dependencies. 2020-08-26 11:39:03 +02:00
Sebastian Hartte d2b69671f5 Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts:
#	src/main/java/appeng/tile/grid/AENetworkInvBlockEntity.java
2020-08-24 23:55:41 +02:00
Sebastian Hartte 1394ab0863 Merge branch '8.0.x-1.16.1' 2020-08-24 23:54:57 +02:00
Sebastian Hartte 5efc085693 Fix tiles that have a "powered" block state from not being able to be broken when
they are connected to a powered grid.
2020-08-24 23:54:37 +02:00
Sebastian Hartte 359e3f7e63 Fix crystal despawning. 2020-08-24 23:13:58 +02:00
Sebastian Hartte fa3e41e687 Fix remaining filtered item handler uses. 2020-08-24 22:48:07 +02:00
Sebastian Hartte 4e86c92720 Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts:
#	src/main/java/appeng/client/gui/implementations/InterfaceTerminalScreen.java
2020-08-24 22:34:26 +02:00
Sebastian Hartte 159f4c7f14 Merge branch '8.0.x-1.16.1' 2020-08-24 22:33:38 +02:00
Sebastian Hartte aff94cec8c Fix search box interactions in the interface terminal. 2020-08-24 22:33:04 +02:00
Sebastian Hartte 07dfa3db2e Fix filtered inventory for IO port. 2020-08-24 21:24:51 +02:00
Sebastian Hartte e0e139900f Fix Spatial IO Port filtered inventory. 2020-08-24 21:19:27 +02:00
Sebastian Hartte 9942f2d32c Fix filtered inventory for Grinder 2020-08-24 21:11:52 +02:00
Sebastian Hartte 858826d1fa Fix use of Fuel Registry (it is null not, 0 for unregistered items).
Fix Vibration Chamber inventory filter.
Fix Molecular Assembler inventory filter.
2020-08-24 20:58:49 +02:00
Sebastian Hartte 90ad345672 Slight wrench cleanup. 2020-08-24 20:34:57 +02:00
Sebastian Hartte 9a81ebfa50 Check the REI search field for being null before using it. 2020-08-24 20:25:03 +02:00
Sebastian Hartte da9fa3d697 Merge remote-tracking branch 'origin/master' into fabric/master 2020-08-24 01:07:08 +02:00
Sebastian Hartte ee7fe9f40d Merge branch '8.0.x-1.16.1' 2020-08-24 01:06:50 +02:00
Sebastian Hartte 2184d03d0b Actually save the rotation when a tile is rotated. 2020-08-24 01:06:26 +02:00
Sebastian Hartte cae1621613 Fix inscriber inventory filtering, and accidental overwriting of the output slot. 2020-08-24 01:01:16 +02:00
Sebastian Hartte e8574d03ea Use a different heuristic for determining how to render items in the middle of the inscriber. 2020-08-24 01:00:33 +02:00
Sebastian Hartte d28f33d198 Split into internal and external inventories.
Fixes Charger not being able to load inventories that violated the filter.
2020-08-24 00:01:18 +02:00
Sebastian Hartte 7df5bf4076 Fix crank not attaching sideways. 2020-08-23 23:49:50 +02:00
Sebastian Hartte 66760865a3 Split resource generation and build because there's a hidden dependency. 2020-08-23 23:12:47 +02:00
Sebastian Hartte e4a08ba99d Log where resources are being generated. 2020-08-23 23:07:12 +02:00
Sebastian Hartte f11e9e2a4c Actually generate data for branch-builds too. 2020-08-23 22:54:52 +02:00
Sebastian Hartte 7a469c1a1d Fix server-side HYWLA problems. 2020-08-23 22:30:08 +02:00
Sebastian Hartte e256a4f664 Post-Merge fixes. 2020-08-23 21:20:51 +02:00
Sebastian Hartte 73cc3f8998 Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts:
#	gradle.properties
#	src/main/java/appeng/core/api/definitions/ApiItems.java
2020-08-23 21:08:47 +02:00
Sebastian Hartte 9c9a49f9e7 Merge branch '8.0.x-1.16.1' 2020-08-23 20:48:19 +02:00
Sebastian Hartte 44c0931c02 Fixes #4635: Actually remove requesters when removing requesters. 2020-08-23 20:47:05 +02:00
Sebastian Hartte 874f46ed4d Fixes #4633: Storage buses cannot see attached inventories. 2020-08-23 11:23:35 +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
yueh 423ab81813 Added step to publish to modmaven (#4607)
(cherry picked from commit 7e1bfdb5ac)
2020-08-21 20:40:03 +02:00
Sebastian Hartte d82c713112 Delay registration of various client settings until the client is fully initialized. 2020-08-21 00:00:03 +02:00
Sebastian Hartte 45cbc40177 Fix wrench interaction with part hosts. 2020-08-20 22:58:49 +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 4e42b17e81 Fixes #4590: Crystal seeds (other than certus) don't display their growth stages. (#4618) 2020-08-19 16:43:45 +02:00
Sebastian Hartte 0e7e9313ee Fixes wrenches not working on tile entities.
This is a temporary hack for now.
2020-08-19 01:53:51 +02:00
Sebastian Hartte 2bba843313 Remove unused code in Condenser. 2020-08-19 01:34:15 +02:00
Sebastian Hartte a0949297d5 Added AE tools to fabric tool tags to fix breaking speed. 2020-08-19 01:34:08 +02:00
Sebastian Hartte 420fb272b4 Bump LBA version to fix filter bugs. 2020-08-19 01:33:34 +02:00
shartte fc0f8eab56 Fixes #4611: Use of client-side only method for Tiny TNT explosion. (#4612) 2020-08-18 01:33:47 +02:00
shartte 41b7900706 Fixes #4598: Incorrectly rotated face for determining block lightlevel in ME Chest renderer. (#4599) (#4609)
(cherry picked from commit 954ce1442e)
2020-08-17 21:58:51 +02:00
shartte 7656157b0d Fixes #4602: Prevent encoding invalid patterns and handle corrupted patterns a little more gracefully. (#4608) 2020-08-17 21:49:37 +02:00
48 changed files with 489 additions and 463 deletions
+3 -1
View File
@@ -21,7 +21,9 @@ jobs:
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
- name: Build with Gradle
- name: Generate Resources
run: ./gradlew generateData
- name: Build
run: ./gradlew build
- uses: actions/upload-artifact@v2
with:
+5 -1
View File
@@ -23,10 +23,14 @@ jobs:
run: chmod +x gradlew
- name: Validate no assets
run: test ! -d ./src/generated
- name: Generate resources
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew generateData
- name: Build with Gradle
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew generateData build
run: ./gradlew build
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
+26 -4
View File
@@ -72,19 +72,41 @@ The API for Applied Energistics 2. It is open source to discuss changes, improve
### 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 {
maven {
name "AE2"
url "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
name "Modmaven"
url "https://modmaven.k-4u.nl/"
// For Gradle 5.1 and above, limit it to just AE2
content {
includeGroup 'appeng'
}
}
// Required for libblockattributes
maven {
name = "BuildCraft"
url = "https://mod-buildcraft.com/maven"
content {
includeGroup "alexiil.mc.lib"
}
}
}
When compiling against the AE2 API you can use gradle dependencies, just add
dependencies {
compileOnly "appeng:appliedenergistics2:VERSION:api"
modCompileOnly "appeng:appliedenergistics2-fabric:VERSION:api"
// Include only if you want AE2 at runtime
modRuntimeOnly "appeng:appliedenergistics2-fabric:VERSION"
}
or add the `compileOnly` line to your existing dependencies task to your build.gradle.
+2 -2
View File
@@ -11,7 +11,7 @@ org.gradle.jvmargs=-Xmx2G
minecraft_version=1.16.2
yarn_mappings=1.16.2+build.6
loader_version=0.9.1+build.205
loader_version=0.9.2+build.206
#Fabric api
fabric_version=0.17.2+build.396-1.16
@@ -23,7 +23,7 @@ kotlin_version=1.3.61
fabric_kotlin_version=1.3.61+build.1
# Dependencies
libblockattributes_version=0.8.0-pre.18
libblockattributes_version=0.8.0
tr_energy_version=0.1.0
#########################################################
+2 -2
View File
@@ -33,8 +33,8 @@ dependencies {
compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api"
// Runtime, Mods
// FIXME 1.16.2 runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
// FIXME 1.16.2 runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_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("team.chisel.ctm:CTM:${ctm_version}")
// unit test dependencies
@@ -4,6 +4,9 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
import net.minecraft.Bootstrap;
import net.minecraft.data.DataGenerator;
@@ -11,16 +14,22 @@ import net.minecraft.data.DataGenerator;
import appeng.data.providers.loot.BlockDropProvider;
import appeng.data.providers.recipes.SlabStairRecipes;
import appeng.data.providers.tags.ConventionTagProvider;
import appeng.data.providers.tags.ToolTagProviders;
public class Entrypoint implements PreLaunchEntrypoint {
private static final Logger LOGGER = LogManager.getLogger();
public static void dump() throws Exception {
Path output = Paths.get("../src/generated/resources");
LOGGER.info("Writing generated resources to {}", output.toAbsolutePath());
DataGenerator generator = new DataGenerator(output, Collections.emptyList());
generator.install(new BlockDropProvider(output));
generator.install(new SlabStairRecipes(output));
generator.install(new ConventionTagProvider(output));
generator.install(new ToolTagProviders(output));
generator.run();
}
@@ -11,7 +11,7 @@ import appeng.core.AppEng;
public class ConventionTagProvider extends TagProvider {
public ConventionTagProvider(Path outputPath) {
super(outputPath);
super("c", outputPath);
}
@Override
@@ -24,15 +24,17 @@ import appeng.data.providers.IAE2DataProvider;
public abstract class TagProvider implements IAE2DataProvider {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
protected static final String CONVENTION_NAMESPACE = "c";
protected static final String TYPE_ITEMS = "items";
protected static final String TYPE_BLOCKS = "blocks";
private final String defaultNamespace;
private final Path outputPath;
private DataCache cache;
protected TagProvider(Path outputPath) {
protected TagProvider(String defaultNamespace, Path outputPath) {
this.defaultNamespace = defaultNamespace;
this.outputPath = outputPath;
}
@@ -49,15 +51,19 @@ public abstract class TagProvider implements IAE2DataProvider {
protected abstract void generate() throws IOException;
protected void addItemTag(String name, ItemConvertible... items) throws IOException {
Identifier id = parseId(name);
List<String> itemIds = Arrays.stream(items).map(ItemConvertible::asItem).map(Registry.ITEM::getId)
.map(Identifier::toString).collect(Collectors.toList());
writeTagFile(CONVENTION_NAMESPACE, TYPE_ITEMS, name, itemIds);
writeTagFile(id.getNamespace(), TYPE_ITEMS, id.getPath(), itemIds);
}
protected void addBlockTag(String name, Block... blocks) throws IOException {
Identifier id = parseId(name);
List<String> itemIds = Arrays.stream(blocks).map(Registry.BLOCK::getId).map(Identifier::toString)
.collect(Collectors.toList());
writeTagFile(CONVENTION_NAMESPACE, TYPE_BLOCKS, name, itemIds);
writeTagFile(id.getNamespace(), TYPE_BLOCKS, id.getPath(), itemIds);
}
protected void writeTagFile(String namespace, String tagType, String tagName, List<String> entries)
@@ -75,7 +81,15 @@ public abstract class TagProvider implements IAE2DataProvider {
@Override
public String getName() {
return AppEng.MOD_NAME + " Convention Tags";
return AppEng.MOD_NAME + " Tags (" + defaultNamespace + ")";
}
private Identifier parseId(String name) {
if (name.contains(":")) {
return new Identifier(name);
} else {
return new Identifier(defaultNamespace, name);
}
}
}
@@ -0,0 +1,28 @@
package appeng.data.providers.tags;
import java.io.IOException;
import java.nio.file.Path;
import appeng.core.AppEng;
public class ToolTagProviders extends TagProvider {
public ToolTagProviders(Path outputPath) {
super("fabric", outputPath);
}
@Override
protected void generate() throws IOException {
addItemTag("axes", ITEMS.netherQuartzAxe(), ITEMS.certusQuartzAxe());
addItemTag("hoes", ITEMS.netherQuartzHoe(), ITEMS.certusQuartzHoe());
addItemTag("pickaxes", ITEMS.netherQuartzPick(), ITEMS.certusQuartzPick());
addItemTag("shovels", ITEMS.netherQuartzShovel(), ITEMS.certusQuartzShovel());
addItemTag("swords", ITEMS.netherQuartzSword(), ITEMS.certusQuartzSword());
}
@Override
public String getName() {
return AppEng.MOD_NAME + " Tool Tags";
}
}
@@ -48,7 +48,7 @@ public final class MEAttributes {
return null;
}
return attribute.getFirstOrNull(world, be.getPos().offset(side), SearchOptions.inDirection(side.getOpposite()));
return attribute.getFirstOrNull(world, be.getPos(), SearchOptions.inDirection(side.getOpposite()));
}
// Convenience function to get an attribute of the block that is in front of a
@@ -232,7 +232,7 @@ public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBas
Platform.spawnDrops(world, pos, itemsToDrop);
}
return ActionResult.FAIL;
return ActionResult.SUCCESS;
}
if (heldItem.getItem() instanceof IMemoryCard && !(this instanceof CableBusBlock)) {
@@ -161,4 +161,9 @@ public class CrankBlock extends AEBaseTileBlock<CrankBlockEntity> {
}
}
@Override
protected boolean hasCustomRotation() {
return true;
}
}
@@ -11,7 +11,6 @@ import com.google.common.base.Preconditions;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.Identifier;
@@ -19,6 +18,7 @@ import net.minecraft.util.registry.Registry;
import appeng.api.features.AEFeature;
import appeng.block.AEBaseTileBlock;
import appeng.bootstrap.components.BlockEntityRendererComponent;
import appeng.bootstrap.components.ITileEntityRegistrationComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.core.AppEng;
@@ -115,7 +115,8 @@ public class BlockEntityBuilder<T extends AEBaseBlockEntity> {
@Environment(EnvType.CLIENT)
private void buildClient() {
if (tileEntityRendering.tileEntityRenderer != null) {
BlockEntityRendererRegistry.INSTANCE.register(type, tileEntityRendering.tileEntityRenderer);
factory.addBootstrapComponent(
new BlockEntityRendererComponent<>(type, tileEntityRendering.tileEntityRenderer));
}
}
@@ -0,0 +1,33 @@
package appeng.bootstrap.components;
import java.util.function.Function;
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
/**
* Registers a block entity renderer for a given block entity type. This must
* occur late in the client's initialization, since the constructors of our
* block entity renderers rely on the client being fully initialized.
*/
public class BlockEntityRendererComponent<T extends BlockEntity> implements IClientSetupComponent {
private final BlockEntityType<T> type;
private final Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> renderer;
public BlockEntityRendererComponent(BlockEntityType<T> type,
Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> renderer) {
this.type = type;
this.renderer = renderer;
}
@Override
public void setup() {
BlockEntityRendererRegistry.INSTANCE.register(type, renderer);
}
}
@@ -13,6 +13,7 @@ import javax.annotation.Nonnull;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
@@ -184,7 +185,9 @@ public final class AppEngClient extends AppEngBase {
ModelsReloadCallback.EVENT.register(this::onModelsReloaded);
callDeferredBootstrapComponents(IClientSetupComponent.class, IClientSetupComponent::setup);
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
callDeferredBootstrapComponents(IClientSetupComponent.class, IClientSetupComponent::setup);
});
registerModelProviders();
registerParticleRenderers();
registerEntityRenderers();
@@ -89,7 +89,9 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
this.searchField.setMaxLength(25);
this.searchField.setEditableColor(0xFFFFFF);
this.searchField.setVisible(true);
this.searchField.setFocused(true);
this.searchField.setChangedListener(str -> this.refreshList());
this.addChild(this.searchField);
this.changeFocus(true);
}
@Override
@@ -128,11 +130,8 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
@Override
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
this.refreshList();
}
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
this.searchField.setText("");
return true;
}
@@ -170,11 +169,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
if (character == ' ' && this.searchField.getText().isEmpty()) {
return true;
}
if (this.searchField.charTyped(character, key)) {
this.refreshList();
return true;
}
return false;
return super.charTyped(character, key);
}
@Override
@@ -1,5 +1,7 @@
package appeng.client.render.tesr;
import java.util.Random;
import com.google.common.collect.ImmutableList;
import net.minecraft.client.MinecraftClient;
@@ -9,12 +11,12 @@ import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction;
@@ -197,9 +199,12 @@ public final class InscriberTESR extends BlockEntityRenderer<InscriberBlockEntit
ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
// heuristic to scale items down much further than blocks
boolean renderAsCube = (stack.getItem() instanceof BlockItem);
if (!renderAsCube) {
// heuristic to scale items down much further than blocks,
// the assumption here is that the generated item models will return their faces
// for direction=null, while a block-model will have their faces for
// cull-faces, but not direction=null
BakedModel model = itemRenderer.getModels().getModel(stack);
if (!model.getQuads(null, null, new Random()).isEmpty()) {
ms.scale(0.5f, 0.5f, 0.5f);
}
@@ -33,6 +33,8 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import alexiil.mc.lib.attributes.item.SingleItemSlot;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
@@ -57,8 +59,6 @@ import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.AdaptorFixedInv;
import appeng.util.inv.WrapperCursorItemHandler;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.IAEItemFilter;
public final class InterfaceTerminalContainer extends AEBaseContainer {
@@ -196,35 +196,37 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
final InventoryAdaptor playerHand = new AdaptorFixedInv(new WrapperCursorItemHandler(player.inventory));
final FixedItemInv theSlot = new WrapperFilteredItemHandler(inv.server.getSubInv(slot, slot + 1),
new PatternSlotFilter());
final InventoryAdaptor interfaceSlot = new AdaptorFixedInv(theSlot);
// Create a wrapper around the targetted slot that will only allow insertions of
// patterns
LimitedFixedItemInv limitedSlotInv = inv.server.createLimitedFixedInv();
limitedSlotInv.getAllRule().filterInserts(this::isValidPattern);
SingleItemSlot theSlot = limitedSlotInv.getSlot(slot);
switch (action) {
case PICKUP_OR_SET_DOWN:
if (hasItemInHand) {
ItemStack inSlot = theSlot.getInvStack(0);
ItemStack inSlot = theSlot.get();
if (inSlot.isEmpty()) {
player.inventory.setCursorStack(interfaceSlot.addItems(player.inventory.getCursorStack()));
player.inventory.setCursorStack(theSlot.insert(player.inventory.getCursorStack()));
} else {
inSlot = inSlot.copy();
final ItemStack inHand = player.inventory.getCursorStack().copy();
ItemHandlerUtil.setStackInSlot(theSlot, 0, ItemStack.EMPTY);
theSlot.set(ItemStack.EMPTY);
player.inventory.setCursorStack(ItemStack.EMPTY);
player.inventory.setCursorStack(interfaceSlot.addItems(inHand.copy()));
player.inventory.setCursorStack(theSlot.insert(inHand.copy()));
if (player.inventory.getCursorStack().isEmpty()) {
player.inventory.setCursorStack(inSlot);
} else {
player.inventory.setCursorStack(inHand);
ItemHandlerUtil.setStackInSlot(theSlot, 0, inSlot);
theSlot.set(inSlot);
}
}
} else {
ItemHandlerUtil.setStackInSlot(theSlot, 0, playerHand.addItems(theSlot.getInvStack(0)));
theSlot.set(playerHand.addItems(theSlot.get()));
}
break;
@@ -233,18 +235,18 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
if (hasItemInHand) {
ItemStack extra = playerHand.removeItems(1, ItemStack.EMPTY, null);
if (!extra.isEmpty()) {
extra = interfaceSlot.addItems(extra);
extra = theSlot.insert(extra);
}
if (!extra.isEmpty()) {
playerHand.addItems(extra);
}
} else if (!is.isEmpty()) {
ItemStack extra = interfaceSlot.removeItems((is.getCount() + 1) / 2, ItemStack.EMPTY, null);
ItemStack extra = theSlot.extract((is.getCount() + 1) / 2);
if (!extra.isEmpty()) {
extra = playerHand.addItems(extra);
}
if (!extra.isEmpty()) {
interfaceSlot.addItems(extra);
theSlot.insert(extra);
}
}
@@ -252,8 +254,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
case SHIFT_CLICK:
final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor(player);
ItemHandlerUtil.setStackInSlot(theSlot, 0, playerInv.addItems(theSlot.getInvStack(0)));
theSlot.set(playerInv.addItems(theSlot.get()));
break;
case MOVE_REGION:
@@ -279,6 +280,10 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
}
}
private boolean isValidPattern(ItemStack stack) {
return !stack.isEmpty() && stack.getItem() instanceof EncodedPatternItem;
}
private void regenList(final CompoundTag data) {
this.byId.clear();
this.diList.clear();
@@ -369,15 +374,4 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
}
}
private static class PatternSlotFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return true;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return !stack.isEmpty() && stack.getItem() instanceof EncodedPatternItem;
}
}
}
@@ -165,7 +165,7 @@ public class RestrictedInputSlot extends AppEngSlot {
case ORE:
return GrinderRecipes.isValidIngredient(p.player.world, stack);
case FUEL:
return FuelRegistry.INSTANCE.get(stack.getItem()) > 0;
return FuelRegistry.INSTANCE.get(stack.getItem()) != null;
case POWERED_TOOL:
return Platform.isChargeable(stack);
case QE_SINGULARITY:
@@ -55,6 +55,7 @@ import appeng.hooks.BlockToolDispenseItemBehavior;
import appeng.hooks.MatterCannonDispenseItemBehavior;
import appeng.items.materials.MaterialType;
import appeng.items.misc.CrystalSeedItem;
import appeng.items.misc.CrystalSeedRendering;
import appeng.items.misc.EncodedPatternItem;
import appeng.items.misc.PaintBallItem;
import appeng.items.misc.PaintBallItemRendering;
@@ -140,12 +141,12 @@ public final class ApiItems implements IItems {
private final AEColoredItemDefinition coloredLumenPaintBall;
// unsupported dev tools
private IItemDefinition toolEraser;
private IItemDefinition toolMeteoritePlacer;
private IItemDefinition toolDebugCard;
private IItemDefinition toolReplicatorCard;
private final IItemDefinition toolEraser;
private final IItemDefinition toolMeteoritePlacer;
private final IItemDefinition toolDebugCard;
private final IItemDefinition toolReplicatorCard;
private IItemDefinition dummyFluidItem;
private final IItemDefinition dummyFluidItem;
public ApiItems(FeatureFactory registry, ApiMaterials materials) {
FeatureFactory certusTools = registry.features(AEFeature.CERTUS_QUARTZ_TOOLS);
@@ -305,24 +306,15 @@ public final class ApiItems implements IItems {
this.certusCrystalSeed = registry
.item("certus_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedCertusQuartzCrystal().item()))
.bootstrap(item -> new IClientSetupComponent() {
@Override
@Environment(EnvType.CLIENT)
public void setup() {
// Expose the growth of the seed to the model system
FabricModelPredicateProviderRegistry.register(item, AppEng.makeId("growth"),
(is, w, p) -> CrystalSeedItem.getGrowthTicks(is)
/ (float) CrystalSeedItem.GROWTH_TICKS_REQUIRED);
}
}).features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
this.fluixCrystalSeed = registry
.item("fluix_crystal_seed",
props -> new CrystalSeedItem(props, materials.purifiedFluixCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
this.netherQuartzSeed = registry
.item("nether_quartz_seed",
props -> new CrystalSeedItem(props, materials.purifiedNetherQuartzCrystal().item()))
.features(AEFeature.CRYSTAL_SEEDS).build();
.bootstrap(CrystalSeedRendering::new).features(AEFeature.CRYSTAL_SEEDS).build();
GrowingCrystalEntity.TYPE = registry
.<GrowingCrystalEntity>entity("growing_crystal", GrowingCrystalEntity::new, SpawnGroup.MISC)
@@ -44,8 +44,6 @@ public abstract class AEBaseItemEntity extends ItemEntity implements ICustomEnti
this.yaw = this.random.nextFloat() * 360.0F;
this.setVelocity(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D);
this.setStack(stack);
// FIXME FABRIC Needs replacement hook this.lifespan =
// stack.getEntityLifespan(world);
}
protected List<Entity> getCheckedEntitiesWithinAABBExcludingEntity(final Box region) {
@@ -35,9 +35,10 @@ import appeng.client.EffectType;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.items.misc.CrystalSeedItem;
import appeng.mixins.ItemEntityAccessor;
import appeng.util.Platform;
public final class GrowingCrystalEntity extends AEBaseItemEntity {
public class GrowingCrystalEntity extends AEBaseItemEntity {
public static EntityType<GrowingCrystalEntity> TYPE;
@@ -49,13 +50,16 @@ public final class GrowingCrystalEntity extends AEBaseItemEntity {
public GrowingCrystalEntity(final World w, final double x, final double y, final double z, final ItemStack is) {
super(TYPE, w, x, y, z, is);
this.setCovetedItem();
// FIXME FABRIC This does not actually fix despawning, we need to Mixin,
// probably.
}
@Override
public void tick() {
// Prevent the entity from despawning
ItemEntityAccessor accessor = (ItemEntityAccessor) this;
if (!this.world.isClient && accessor.getAge() >= 1000) {
accessor.setAge(0);
}
super.tick();
if (!AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_PURIFICATION)) {
@@ -39,8 +39,8 @@ public class FluidSlotWidget extends CustomSlotWidget {
// The tooltip area coincides with the area of the slot
int x = getTooltipAreaX();
int y = getTooltipAreaY();
int width = getTooltipAreaX();
int height = getTooltipAreaY();
int width = getTooltipAreaWidth();
int height = getTooltipAreaHeight();
fs.getFluidStack().renderGuiRect(x, y, x + width, y + height);
}
}
@@ -126,7 +126,7 @@ public class FluidExportBusPart extends SharedFluidBusPart {
// we'll deduct 1/1000th from storage.
long remainderMillibuckets = remainder.getAmount_F().asInt(1000, RoundingMode.DOWN);
toExtract.setStackSize(remainderMillibuckets);
toExtract.decStackSize(remainderMillibuckets);
inv.extractItems(toExtract, Actionable.MODULATE, this.source);
return TickRateModulation.FASTER;
@@ -18,9 +18,11 @@
package appeng.integration.modules.jei;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import me.shedaniel.rei.api.REIHelper;
import me.shedaniel.rei.gui.widget.TextFieldWidget;
import appeng.integration.abstraction.IRei;
@@ -29,7 +31,7 @@ class ReiRuntimeAdapter implements IRei {
private final REIHelper runtime;
ReiRuntimeAdapter() {
this.runtime = REIHelper.getInstance();
this.runtime = Preconditions.checkNotNull(REIHelper.getInstance(), "REI helper was null");
}
@Override
@@ -39,11 +41,18 @@ class ReiRuntimeAdapter implements IRei {
@Override
public String getSearchText() {
return Strings.nullToEmpty(this.runtime.getSearchTextField().getText());
TextFieldWidget searchField = this.runtime.getSearchTextField();
if (searchField == null) {
return "";
}
return Strings.nullToEmpty(searchField.getText());
}
@Override
public void setSearchText(String searchText) {
this.runtime.getSearchTextField().setText(Strings.nullToEmpty(searchText));
TextFieldWidget searchField = this.runtime.getSearchTextField();
if (searchField != null) {
searchField.setText(Strings.nullToEmpty(searchText));
}
}
}
@@ -20,6 +20,8 @@ package appeng.integration.modules.waila.tile;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.TooltipContext;
@@ -45,6 +47,7 @@ import appeng.tile.misc.ChargerBlockEntity;
public final class ChargerWailaDataProvider extends BaseWailaDataProvider {
@Override
@Environment(EnvType.CLIENT)
public void appendBody(List<Text> tooltip, IDataAccessor accessor, IPluginConfig config) {
final BlockEntity te = accessor.getBlockEntity();
@@ -0,0 +1,29 @@
package appeng.items.misc;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry;
import net.minecraft.item.Item;
import appeng.bootstrap.components.IClientSetupComponent;
import appeng.core.AppEng;
/**
* Exposes a predicate "growth", which is used in the item model to
* differentiate the growth stages.
*/
public class CrystalSeedRendering implements IClientSetupComponent {
private final Item item;
public CrystalSeedRendering(Item item) {
this.item = item;
}
@Override
@Environment(EnvType.CLIENT)
public void setup() {
// Expose the growth of the seed to the model system
FabricModelPredicateProviderRegistry.register(item, AppEng.makeId("growth"),
(is, w, p) -> CrystalSeedItem.getGrowthTicks(is) / (float) CrystalSeedItem.GROWTH_TICKS_REQUIRED);
}
}
@@ -32,6 +32,7 @@ import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import appeng.api.implementations.guiobjects.IGuiItem;
@@ -53,6 +54,7 @@ import appeng.core.sync.packets.ClickPacket;
import appeng.hooks.AEToolItem;
import appeng.items.AEBaseItem;
import appeng.items.contents.NetworkToolViewer;
import appeng.util.PartHostWrenching;
import appeng.util.Platform;
public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench, AEToolItem {
@@ -91,13 +93,17 @@ public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench,
final BlockEntity te = context.getWorld().getBlockEntity(context.getBlockPos());
if (te instanceof IPartHost) {
final SelectedPart part = ((IPartHost) te).selectPart(mop.getPos());
Vec3d relativePosition = mop.getPos().subtract(mop.getBlockPos().getX(), mop.getBlockPos().getY(),
mop.getBlockPos().getZ());
IPartHost host = (IPartHost) te;
final SelectedPart part = host.selectPart(relativePosition);
if (part.part != null || part.facade != null) {
if (part.part instanceof INetworkToolAgent && !((INetworkToolAgent) part.part).showNetworkInfo(mop)) {
return ActionResult.FAIL;
} else if (context.getPlayer().isInSneakingPose()) {
return ActionResult.PASS;
PartHostWrenching.wrenchPart(context.getWorld(), context.getBlockPos(), host, part);
return ActionResult.SUCCESS;
}
}
} else if (te instanceof INetworkToolAgent && !((INetworkToolAgent) te).showNetworkInfo(mop)) {
@@ -111,13 +117,6 @@ public class NetworkToolItem extends AEBaseItem implements IGuiItem, IAEWrench,
return ActionResult.SUCCESS;
}
// FIXME FABRIC: No direct equivalent
// FIXME FABRIC: Might already be handled by onItemUseFirst though
// FIXME FABRIC @Override
// FIXME FABRIC public boolean doesSneakBypassUse(ItemStack stack, WorldView world, BlockPos pos, PlayerEntity player) {
// FIXME FABRIC return true;
// FIXME FABRIC }
public boolean serverSideToolLogic(ItemUsageContext useContext) {
BlockPos pos = useContext.getBlockPos();
PlayerEntity p = useContext.getPlayer();
@@ -19,18 +19,27 @@
package appeng.items.tools.quartz;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import appeng.api.implementations.items.IAEWrench;
import appeng.api.parts.IPartHost;
import appeng.api.parts.SelectedPart;
import appeng.api.util.DimensionalCoord;
import appeng.block.AEBaseBlock;
import appeng.hooks.AEToolItem;
import appeng.items.AEBaseItem;
import appeng.parts.PartPlacement;
import appeng.util.PartHostWrenching;
import appeng.util.Platform;
public class QuartzWrenchItem extends AEBaseItem implements IAEWrench, AEToolItem {
@@ -41,23 +50,55 @@ public class QuartzWrenchItem extends AEBaseItem implements IAEWrench, AEToolIte
@Override
public ActionResult onItemUseFirst(ItemStack stack, ItemUsageContext context) {
if (!context.getPlayer().isInSneakingPose() && Platform
.hasPermissions(new DimensionalCoord(context.getWorld(), context.getBlockPos()), context.getPlayer())) {
PlayerEntity player = context.getPlayer();
if (player == null) {
return ActionResult.PASS;
}
Block block = context.getWorld().getBlockState(context.getBlockPos()).getBlock();
if (block instanceof AEBaseBlock) {
if (Platform.isClient()) {
// TODO 1.10-R - if we return FAIL on client, action will not be sent to server.
// Fix that in all Block#onItemUseFirst overrides.
return !context.getWorld().isClient ? ActionResult.SUCCESS : ActionResult.PASS;
boolean isHoldingShift = player.isInSneakingPose();
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
if (!Platform.hasPermissions(new DimensionalCoord(world, pos), player)) {
return ActionResult.FAIL;
}
BlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock();
if (isHoldingShift) {
// Wrenching parts of cable buses or other part hosts
BlockEntity tile = world.getBlockEntity(pos);
IPartHost host = null;
if (tile instanceof IPartHost) {
host = (IPartHost) tile;
}
if (host != null) {
if (!world.isClient) {
// Build the relative position within the part
Vec3d relPos = context.getHitPos().subtract(pos.getX(), pos.getY(), pos.getZ());
final SelectedPart sp = PartPlacement.selectPart(player, host, relPos);
PartHostWrenching.wrenchPart(world, pos, host, sp);
}
return ActionResult.SUCCESS;
}
// Pass the use onto the block...
return block.onUse(blockState, world, pos, player, context.getHand(),
new BlockHitResult(context.getHitPos(), context.getSide(), pos, context.hitsInsideBlock()));
}
if (block instanceof AEBaseBlock) {
if (!world.isClient) {
AEBaseBlock aeBlock = (AEBaseBlock) block;
if (aeBlock.rotateAroundFaceAxis(context.getWorld(), context.getBlockPos(), context.getSide())) {
context.getPlayer().swingHand(context.getHand());
return !context.getWorld().isClient ? ActionResult.SUCCESS : ActionResult.FAIL;
if (aeBlock.rotateAroundFaceAxis(world, pos, context.getSide())) {
player.swingHand(context.getHand());
}
}
return ActionResult.SUCCESS;
}
return ActionResult.PASS;
}
-1
View File
@@ -176,7 +176,6 @@ public class Grid implements IGrid {
}
gridNode.getGridProxy().gridChanged();
// postEventTo( gridNode, networkChanged );
}
@Override
+1 -1
View File
@@ -502,7 +502,7 @@ public class EnergyGridCache implements IEnergyGrid {
private void removeRequester(IAEPowerStorage requester) {
Preconditions.checkState(!ongoingInjectOperation,
"Cannot modify energy requesters while energy is being injected.");
this.requesters.add(requester);
this.requesters.remove(requester);
}
private void addProvider(IAEPowerStorage provider) {
@@ -0,0 +1,17 @@
package appeng.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.entity.ItemEntity;
@Mixin(ItemEntity.class)
public interface ItemEntityAccessor {
@Accessor
int getAge();
@Accessor
void setAge(int age);
}
+2 -57
View File
@@ -18,9 +18,6 @@
package appeng.parts;
import java.util.ArrayList;
import java.util.List;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -48,7 +45,6 @@ import appeng.api.definitions.IBlockDefinition;
import appeng.api.parts.IFacadePart;
import appeng.api.parts.IPartHost;
import appeng.api.parts.IPartItem;
import appeng.api.parts.PartItemStack;
import appeng.api.parts.SelectedPart;
import appeng.api.util.AEPartLocation;
import appeng.api.util.DimensionalCoord;
@@ -85,56 +81,6 @@ public class PartPlacement {
final BlockHitResult mop = world.rayTrace(rtc);
ItemPlacementContext useContext = new ItemPlacementContext(new ItemUsageContext(player, hand, mop));
if (!held.isEmpty() && Platform.isWrench(player, held, pos) && player.isInSneakingPose()) {
if (!Platform.hasPermissions(new DimensionalCoord(world, pos), player)) {
return ActionResult.FAIL;
}
final BlockEntity tile = world.getBlockEntity(pos);
IPartHost host = null;
if (tile instanceof IPartHost) {
host = (IPartHost) tile;
}
if (host != null) {
if (!world.isClient) {
if (mop.getType() == HitResult.Type.BLOCK) {
final List<ItemStack> is = new ArrayList<>();
final SelectedPart sp = selectPart(player, host,
mop.getPos().add(-mop.getPos().getX(), -mop.getPos().getY(), -mop.getPos().getZ()));
if (sp.part != null) {
is.add(sp.part.getItemStack(PartItemStack.WRENCH));
sp.part.getDrops(is, true);
host.removePart(sp.side, false);
}
if (sp.facade != null) {
is.add(sp.facade.getItemStack());
host.getFacadeContainer().removeFacade(host, sp.side);
Platform.notifyBlocksOfNeighbors(world, pos);
}
if (host.isEmpty()) {
host.cleanup();
}
if (!is.isEmpty()) {
Platform.spawnDrops(world, pos, is);
}
}
} else {
player.swingHand(hand);
NetworkHandler.instance()
.sendToServer(new PartPlacementPacket(pos, side, getEyeOffset(player), hand));
}
return ActionResult.SUCCESS;
}
return ActionResult.FAIL;
}
BlockEntity tile = world.getBlockEntity(pos);
IPartHost host = null;
@@ -178,6 +124,7 @@ public class PartPlacement {
if (held.isEmpty()) {
if (host != null && player.isInSneakingPose() && world.isAir(pos)) {
if (mop.getType() == HitResult.Type.BLOCK) {
// FIXME FABRIC: This looks wrong
Vec3d hitVec = mop.getPos().add(-mop.getPos().getX(), -mop.getPos().getY(), -mop.getPos().getZ());
final SelectedPart sPart = selectPart(player, host, hitVec);
if (sPart != null && sPart.part != null) {
@@ -323,7 +270,7 @@ public class PartPlacement {
return getEyeHeight();
}
private static SelectedPart selectPart(final PlayerEntity player, final IPartHost host, final Vec3d pos) {
public static SelectedPart selectPart(final PlayerEntity player, final IPartHost host, final Vec3d pos) {
AppEng.instance().setPartInteractionPlayer(player);
try {
return host.selectPart(pos);
@@ -401,8 +348,6 @@ public class PartPlacement {
// FIXME FABRIC NetworkHandler.instance().sendToServer(new ClickPacket(event.getHand()));
// FIXME FABRIC }
// FIXME FABRIC }
// FIXME FABRIC } else if (event instanceof PlayerInteractEvent.RightClickBlock && !event.getPlayer().world.isClient) {
// FIXME FABRIC
// FIXME FABRIC }
// FIXME FABRIC }
@@ -298,6 +298,7 @@ public class AEBaseBlockEntity extends BlockEntity implements IOrientable, IComm
this.up = inUp;
this.markForUpdate();
Platform.notifyBlocksOfNeighbors(this.world, this.pos);
this.saveChanges();
}
public void onPlacement(ItemPlacementContext context) {
@@ -59,6 +59,13 @@ public abstract class AEBaseInvBlockEntity extends AEBaseBlockEntity implements
public abstract @Nonnull FixedItemInv getInternalInventory();
/**
* Inventory offered to other mods accessing this block externally.
*/
public @Nonnull FixedItemInv getExternalInventory() {
return getInternalInventory();
}
@Override
public CompoundTag toTag(final CompoundTag data) {
super.toTag(data);
@@ -95,7 +102,7 @@ public abstract class AEBaseInvBlockEntity extends AEBaseBlockEntity implements
ItemStack added);
protected @Nonnull FixedItemInv getItemHandlerForSide(@Nonnull Direction side) {
return this.getInternalInventory();
return this.getExternalInventory();
}
@Override
@@ -107,7 +114,7 @@ public abstract class AEBaseInvBlockEntity extends AEBaseBlockEntity implements
private void offerItemInventory(AttributeList<?> to) {
Direction searchDirection = to.getSearchDirection();
if (searchDirection == null) {
to.offer(getInternalInventory());
to.offer(getExternalInventory());
} else {
Direction side = searchDirection.getOpposite();
to.offer(getItemHandlerForSide(side));
@@ -23,6 +23,8 @@ import java.util.List;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
@@ -38,6 +40,7 @@ import net.minecraft.world.World;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
@@ -78,8 +81,6 @@ import appeng.util.Platform;
import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperChainedItemHandler;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.IAEItemFilter;
import appeng.util.item.AEItemStack;
public class MolecularAssemblerBlockEntity extends AENetworkInvBlockEntity
@@ -90,8 +91,8 @@ public class MolecularAssemblerBlockEntity extends AENetworkInvBlockEntity
private final CraftingInventory craftingInv;
private final AppEngInternalInventory gridInv = new AppEngInternalInventory(this, 9 + 1, 1);
private final AppEngInternalInventory patternInv = new AppEngInternalInventory(this, 1, 1);
private final FixedItemInv gridInvExt = new WrapperFilteredItemHandler(this.gridInv, new CraftingGridFilter());
private final FixedItemInv internalInv = new WrapperChainedItemHandler(this.gridInv, this.patternInv);
private final LimitedFixedItemInv gridInvExt;
private final IConfigManager settings;
private final UpgradeInventory upgrades;
private boolean isPowered = false;
@@ -116,6 +117,20 @@ public class MolecularAssemblerBlockEntity extends AENetworkInvBlockEntity
this.upgrades = new DefinitionUpgradeInventory(assembler, this, this.getUpgradeSlots());
this.craftingInv = new CraftingInventory(new ContainerNull(), 3, 3);
gridInvExt = gridInv.createLimitedFixedInv();
// Limit the input slots to 1 of the respective crafting ingredient
for (int i = 0; i < 9; i++) {
int slot = i;
gridInvExt.getRule(slot).disallowExtraction().limitInsertionCount(1)
.filterInserts(stack -> isValidIngredientForSlot(slot, stack));
}
// Output slot
gridInvExt.getRule(9).disallowInsertion();
}
private boolean isValidIngredientForSlot(int slot, ItemStack stack) {
return this.myPlan != null && !ItemHandlerUtil.isEmpty(this.patternInv)
&& this.myPlan.isValidItemForSlot(slot, stack, MolecularAssemblerBlockEntity.this.getWorld());
}
private int getUpgradeSlots() {
@@ -310,8 +325,9 @@ public class MolecularAssemblerBlockEntity extends AENetworkInvBlockEntity
return this.internalInv;
}
@NotNull
@Override
protected FixedItemInv getItemHandlerForSide(Direction side) {
public FixedItemInv getExternalInventory() {
return this.gridInvExt;
}
@@ -554,28 +570,4 @@ public class MolecularAssemblerBlockEntity extends AENetworkInvBlockEntity
return this.animationStatus;
}
private class CraftingGridFilter implements IAEItemFilter {
private boolean hasPattern() {
return MolecularAssemblerBlockEntity.this.myPlan != null
&& !ItemHandlerUtil.isEmpty(MolecularAssemblerBlockEntity.this.patternInv);
}
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return slot == 9;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
if (slot >= 9) {
return false;
}
if (this.hasPattern()) {
return MolecularAssemblerBlockEntity.this.myPlan.isValidItemForSlot(slot, stack,
MolecularAssemblerBlockEntity.this.getWorld());
}
return false;
}
}
}
@@ -80,6 +80,10 @@ public abstract class AENetworkInvBlockEntity extends AEBaseInvBlockEntity imple
@Override
public void markRemoved() {
super.markRemoved();
// if the cached block state is not current, the following method may call
// markForUpdate
// and cause the block state to be changed back to non-air
resetBlock();
this.getProxy().remove();
}
@@ -28,6 +28,7 @@ import net.minecraft.util.math.Direction;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import appeng.api.implementations.tiles.ICrankable;
import appeng.recipes.handlers.GrinderOptionalResult;
@@ -39,18 +40,21 @@ import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorFixedInv;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.IAEItemFilter;
public class GrinderBlockEntity extends AEBaseInvBlockEntity implements ICrankable {
private static final int SLOT_PROCESSING = 6;
private final AppEngInternalInventory inv = new AppEngInternalInventory(this, 7);
private final FixedItemInv invExt = new WrapperFilteredItemHandler(this.inv, new GrinderFilter());
private final LimitedFixedItemInv invExt;
private int points;
public GrinderBlockEntity(BlockEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
invExt = inv.createLimitedFixedInv();
invExt.getAllRule().disallowExtraction().disallowInsertion();
invExt.getSubRule(3, 6).allowExtraction();
invExt.getSubRule(0, 3).filterInserts(stack -> GrinderRecipes.isValidIngredient(world, stack)).allowInsertion();
}
@Override
@@ -161,20 +165,4 @@ public class GrinderBlockEntity extends AEBaseInvBlockEntity implements ICrankab
return this.getUp() == directionToCrank;
}
private class GrinderFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slotIndex, int amount) {
return slotIndex >= 3 && slotIndex <= 5;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slotIndex, ItemStack stack) {
if (!GrinderRecipes.isValidIngredient(world, stack)) {
return false;
}
return slotIndex >= 0 && slotIndex <= 2;
}
}
}
@@ -23,6 +23,8 @@ import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
@@ -137,6 +139,12 @@ public class ChargerBlockEntity extends AENetworkPowerBlockEntity implements ICr
@Override
public FixedItemInv getInternalInventory() {
return inv;
}
@NotNull
@Override
public FixedItemInv getExternalInventory() {
return externalInv;
}
@@ -255,7 +263,7 @@ public class ChargerBlockEntity extends AENetworkPowerBlockEntity implements ICr
return true;
}
private class ChargerInvFilter implements IAEItemFilter {
private static class ChargerInvFilter implements IAEItemFilter {
@Override
public boolean allowInsert(FixedItemInv inv, final int i, final ItemStack itemstack) {
final IItemDefinition cert = Api.instance().definitions().materials().certusQuartzCrystal();
@@ -73,7 +73,6 @@ public class CondenserBlockEntity extends AEBaseInvBlockEntity implements IConfi
private final AppEngInternalInventory storageSlot = new AppEngInternalInventory(this, 1);
// This is a FixedItemInv implementation to satisfy the UI, which is slot based
private final CondenseItemHandler internalInputSlot = new CondenseItemHandler();
private final CondenseItemInsertable externalItemInput = new CondenseItemInsertable();
private final FluidInsertable externalFluidInput = new FluidHandler();
private final MEHandler meHandler = new MEHandler();
@@ -139,7 +138,7 @@ public class CondenserBlockEntity extends AEBaseInvBlockEntity implements IConfi
}
private boolean canAddOutput(final ItemStack output) {
return this.outputSlot.getInsertable().attemptInsertion(output, Simulation.SIMULATE).isEmpty();
return this.outputSlot.getInsertable().wouldAccept(output);
}
/**
@@ -148,7 +147,7 @@ public class CondenserBlockEntity extends AEBaseInvBlockEntity implements IConfi
* @param output to be added output
*/
private void addOutput(final ItemStack output) {
this.outputSlot.getInsertable().attemptInsertion(output, Simulation.ACTION);
this.outputSlot.getInsertable().insert(output);
}
FixedItemInv getOutputSlot() {
@@ -215,16 +214,6 @@ public class CondenserBlockEntity extends AEBaseInvBlockEntity implements IConfi
to.offer(meHandler);
}
private class CondenseItemInsertable implements ItemInsertable {
@Override
public ItemStack attemptInsertion(ItemStack itemStack, Simulation simulation) {
if (simulation == Simulation.ACTION && !itemStack.isEmpty()) {
CondenserBlockEntity.this.addPower(itemStack.getCount());
}
return ItemStack.EMPTY;
}
}
private class CondenseItemHandler implements FixedItemInv {
@Override
public int getSlotCount() {
@@ -243,7 +232,7 @@ public class CondenserBlockEntity extends AEBaseInvBlockEntity implements IConfi
@Override
public boolean setInvStack(int i, ItemStack itemStack, Simulation simulation) {
if (simulation == Simulation.ACTION) {
if (simulation == Simulation.ACTION && !itemStack.isEmpty()) {
CondenserBlockEntity.this.addPower(itemStack.getCount());
}
return true;
@@ -25,6 +25,8 @@ import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.ItemStack;
@@ -36,6 +38,7 @@ import net.minecraft.world.World;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
@@ -65,8 +68,6 @@ import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperChainedItemHandler;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.IAEItemFilter;
import appeng.util.item.AEItemStack;
/**
@@ -91,15 +92,17 @@ public class InscriberBlockEntity extends AENetworkPowerBlockEntity
private final AppEngInternalInventory bottomItemHandler = new AppEngInternalInventory(this, 1, 1);
private final AppEngInternalInventory sideItemHandler = new AppEngInternalInventory(this, 2, 1);
private final FixedItemInv topItemHandlerExtern;
private final FixedItemInv bottomItemHandlerExtern;
private final FixedItemInv sideItemHandlerExtern;
private final LimitedFixedItemInv topItemHandlerExtern;
private final LimitedFixedItemInv bottomItemHandlerExtern;
private final LimitedFixedItemInv sideItemHandlerExtern;
private InscriberRecipe cachedTask = null;
private final FixedItemInv inv = new WrapperChainedItemHandler(this.topItemHandler, this.bottomItemHandler,
this.sideItemHandler);
private final FixedItemInv externalInv;
public InscriberBlockEntity(BlockEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
@@ -113,10 +116,30 @@ public class InscriberBlockEntity extends AENetworkPowerBlockEntity
this.sideItemHandler.setMaxStackSize(1, 64);
final IAEItemFilter filter = new ItemHandlerFilter();
this.topItemHandlerExtern = new WrapperFilteredItemHandler(this.topItemHandler, filter);
this.bottomItemHandlerExtern = new WrapperFilteredItemHandler(this.bottomItemHandler, filter);
this.sideItemHandlerExtern = new WrapperFilteredItemHandler(this.sideItemHandler, filter);
this.topItemHandlerExtern = this.topItemHandler.createLimitedFixedInv();
this.topItemHandlerExtern.getAllRule().filterInserts(this::canInsertIntoTopOrBottom)
.filterExtracts(stack -> !isSmash());
this.bottomItemHandlerExtern = this.bottomItemHandler.createLimitedFixedInv();
this.bottomItemHandlerExtern.getAllRule().filterInserts(this::canInsertIntoTopOrBottom)
.filterExtracts(stack -> !isSmash());
this.sideItemHandlerExtern = this.sideItemHandler.createLimitedFixedInv();
this.sideItemHandlerExtern.getRule(0).disallowExtraction().filterInserts(stack -> !isSmash());
this.sideItemHandlerExtern.getRule(1).filterExtracts(stack -> !isSmash()).disallowInsertion();
this.externalInv = new WrapperChainedItemHandler(this.topItemHandlerExtern, this.bottomItemHandlerExtern,
this.sideItemHandlerExtern);
}
private boolean canInsertIntoTopOrBottom(ItemStack stack) {
if (isSmash()) {
return false;
}
if (Api.instance().definitions().materials().namePress().isSameAs(stack)) {
return true;
}
return InscriberRecipes.isValidOptionalIngredient(getWorld(), stack);
}
private int getUpgradeSlots() {
@@ -212,6 +235,12 @@ public class InscriberBlockEntity extends AENetworkPowerBlockEntity
return this.inv;
}
@NotNull
@Override
public FixedItemInv getExternalInventory() {
return this.externalInv;
}
@Override
public void onChangeInventory(final FixedItemInv inv, final int slot, final InvOperation mc,
final ItemStack removed, final ItemStack added) {
@@ -276,7 +305,7 @@ public class InscriberBlockEntity extends AENetworkPowerBlockEntity
if (out != null) {
final ItemStack outputCopy = out.getOutput().copy();
if (this.sideItemHandler.setInvStack(1, outputCopy, Simulation.ACTION)) {
if (this.sideItemHandler.getSlot(1).insert(outputCopy).isEmpty()) {
this.setProcessingTime(0);
if (out.getProcessType() == InscriberProcessType.PRESS) {
this.topItemHandler.setInvStack(0, ItemStack.EMPTY, Simulation.ACTION);
@@ -325,7 +354,7 @@ public class InscriberBlockEntity extends AENetworkPowerBlockEntity
final InscriberRecipe out = this.getTask();
if (out != null) {
final ItemStack outputCopy = out.getOutput().copy();
if (this.sideItemHandler.setInvStack(1, outputCopy, Simulation.SIMULATE)) {
if (this.sideItemHandler.getSlot(1).wouldAccept(outputCopy)) {
this.setSmash(true);
this.finalStep = 0;
this.markForUpdate();
@@ -403,42 +432,4 @@ public class InscriberBlockEntity extends AENetworkPowerBlockEntity
this.processingTime = processingTime;
}
/**
* This is an item handler that exposes the inscribers inventory while providing
* simulation capabilities that do not reset the progress if there's already an
* item in a slot. Previously, the progress of the inscriber was reset when
* another mod attempted insertion of items when there were already items in the
* slot.
*/
private class ItemHandlerFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
if (InscriberBlockEntity.this.isSmash()) {
return false;
}
return inv == InscriberBlockEntity.this.topItemHandler || inv == InscriberBlockEntity.this.bottomItemHandler
|| slot == 1;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
// output slot
if (slot == 1) {
return false;
}
if (InscriberBlockEntity.this.isSmash()) {
return false;
}
if (inv == InscriberBlockEntity.this.topItemHandler || inv == InscriberBlockEntity.this.bottomItemHandler) {
if (Api.instance().definitions().materials().namePress().isSameAs(stack)) {
return true;
}
return InscriberRecipes.isValidOptionalIngredient(getWorld(), stack);
}
return true;
}
}
}
@@ -33,6 +33,7 @@ import net.minecraft.util.math.Direction;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import appeng.api.config.Actionable;
import appeng.api.networking.IGridNode;
@@ -49,8 +50,6 @@ import appeng.tile.grid.AENetworkInvBlockEntity;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.IAEItemFilter;
public class VibrationChamberBlockEntity extends AENetworkInvBlockEntity implements IGridTickable {
public static final double POWER_PER_TICK = 5;
@@ -58,7 +57,7 @@ public class VibrationChamberBlockEntity extends AENetworkInvBlockEntity impleme
public static final int MAX_BURN_SPEED = 200;
public static final double DILATION_SCALING = 25.0; // x4 ~ 40 AE/t at max
private final AppEngInternalInventory inv = new AppEngInternalInventory(this, 1);
private final FixedItemInv invExt = new WrapperFilteredItemHandler(this.inv, new FuelSlotFilter());
private final LimitedFixedItemInv invExt;
private int burnSpeed = 100;
private double burnTime = 0;
@@ -71,6 +70,10 @@ public class VibrationChamberBlockEntity extends AENetworkInvBlockEntity impleme
super(tileEntityTypeIn);
this.getProxy().setIdlePowerUsage(0);
this.getProxy().setFlags();
invExt = inv.createLimitedFixedInv();
invExt.getAllRule().filterInserts(stack -> FuelRegistry.INSTANCE.get(stack.getItem()) != null)
.filterExtracts(stack -> FuelRegistry.INSTANCE.get(stack.getItem()) == null);
}
@Override
@@ -138,8 +141,8 @@ public class VibrationChamberBlockEntity extends AENetworkInvBlockEntity impleme
private boolean canEatFuel() {
final ItemStack is = this.inv.getInvStack(0);
if (!is.isEmpty()) {
final int newBurnTime = FuelRegistry.INSTANCE.get(is.getItem());
if (newBurnTime > 0 && is.getCount() > 0) {
final Integer newBurnTime = FuelRegistry.INSTANCE.get(is.getItem());
if (newBurnTime != null && is.getCount() > 0) {
return true;
}
}
@@ -210,8 +213,8 @@ public class VibrationChamberBlockEntity extends AENetworkInvBlockEntity impleme
private void eatFuel() {
final ItemStack is = this.inv.getInvStack(0);
if (!is.isEmpty()) {
final int newBurnTime = FuelRegistry.INSTANCE.get(is.getItem());
if (newBurnTime > 0 && is.getCount() > 0) {
final Integer newBurnTime = FuelRegistry.INSTANCE.get(is.getItem());
if (newBurnTime != null && is.getCount() > 0) {
this.setBurnTime(this.getBurnTime() + newBurnTime);
this.setMaxBurnTime(this.getBurnTime());
@@ -270,15 +273,4 @@ public class VibrationChamberBlockEntity extends AENetworkInvBlockEntity impleme
this.burnTime = burnTime;
}
private static class FuelSlotFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return FuelRegistry.INSTANCE.get(inv.getInvStack(slot).getItem()) == 0;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return FuelRegistry.INSTANCE.get(stack.getItem()) != 0;
}
}
}
@@ -30,6 +30,7 @@ import net.minecraft.world.World;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
@@ -51,18 +52,20 @@ import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.IWorldCallable;
import appeng.util.Platform;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.IAEItemFilter;
public class SpatialIOPortBlockEntity extends AENetworkInvBlockEntity implements IWorldCallable<Void> {
private final AppEngInternalInventory inv = new AppEngInternalInventory(this, 2);
private final FixedItemInv invExt = new WrapperFilteredItemHandler(this.inv, new SpatialIOFilter());
private final LimitedFixedItemInv invExt;
private YesNo lastRedstoneState = YesNo.UNDECIDED;
public SpatialIOPortBlockEntity(BlockEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
this.getProxy().setFlags(GridFlags.REQUIRE_CHANNEL);
invExt = inv.createLimitedFixedInv();
invExt.getRule(0).disallowExtraction().allowInsertion().filterInserts(this::isSpatialCell);
invExt.getRule(1).disallowInsertion().allowExtraction();
}
@Override
@@ -186,16 +189,4 @@ public class SpatialIOPortBlockEntity extends AENetworkInvBlockEntity implements
}
private class SpatialIOFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return slot == 1;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return (slot == 0 && SpatialIOPortBlockEntity.this.isSpatialCell(stack));
}
}
}
@@ -33,6 +33,7 @@ import net.minecraft.world.World;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
import appeng.api.config.Actionable;
import appeng.api.config.FullnessMode;
@@ -74,8 +75,6 @@ import appeng.util.helpers.ItemHandlerUtil;
import appeng.util.inv.AdaptorFixedInv;
import appeng.util.inv.InvOperation;
import appeng.util.inv.WrapperChainedItemHandler;
import appeng.util.inv.WrapperFilteredItemHandler;
import appeng.util.inv.filter.AEItemFilters;
public class IOPortBlockEntity extends AENetworkInvBlockEntity
implements IUpgradeableHost, IConfigManagerHost, IGridTickable {
@@ -88,10 +87,8 @@ public class IOPortBlockEntity extends AENetworkInvBlockEntity
private final AppEngInternalInventory outputCells = new AppEngInternalInventory(this, NUMBER_OF_CELL_SLOTS);
private final FixedItemInv combinedInventory = new WrapperChainedItemHandler(this.inputCells, this.outputCells);
private final FixedItemInv inputCellsExt = new WrapperFilteredItemHandler(this.inputCells,
AEItemFilters.INSERT_ONLY);
private final FixedItemInv outputCellsExt = new WrapperFilteredItemHandler(this.outputCells,
AEItemFilters.EXTRACT_ONLY);
private final LimitedFixedItemInv inputCellsExt;
private final LimitedFixedItemInv outputCellsExt;
private final UpgradeInventory upgrades;
private final IActionSource mySrc;
@@ -111,6 +108,12 @@ public class IOPortBlockEntity extends AENetworkInvBlockEntity
final Block ioPortBlock = Api.instance().definitions().blocks().iOPort().maybeBlock().get();
this.upgrades = new BlockUpgradeInventory(ioPortBlock, this, NUMBER_OF_UPGRADE_SLOTS);
inputCellsExt = inputCells.createLimitedFixedInv();
inputCellsExt.getAllRule().disallowExtraction();
outputCellsExt = outputCells.createLimitedFixedInv();
outputCellsExt.getAllRule().disallowInsertion();
}
@Override
@@ -0,0 +1,46 @@
package appeng.util;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import appeng.api.parts.IPartHost;
import appeng.api.parts.PartItemStack;
import appeng.api.parts.SelectedPart;
/**
* Support functionality for using a wrench on parts attached to a part host.
*/
public final class PartHostWrenching {
private PartHostWrenching() {
}
public static void wrenchPart(World world, BlockPos pos, IPartHost host, SelectedPart sp) {
final List<ItemStack> is = new ArrayList<>();
if (sp.part != null) {
is.add(sp.part.getItemStack(PartItemStack.WRENCH));
sp.part.getDrops(is, true);
host.removePart(sp.side, false);
}
if (sp.facade != null) {
is.add(sp.facade.getItemStack());
host.getFacadeContainer().removeFacade(host, sp.side);
Platform.notifyBlocksOfNeighbors(world, pos);
}
if (host.isEmpty()) {
host.cleanup();
}
if (!is.isEmpty()) {
Platform.spawnDrops(world, pos, is);
}
}
}
@@ -1,83 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util.inv;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
import alexiil.mc.lib.attributes.Simulation;
import alexiil.mc.lib.attributes.item.FixedItemInv;
import alexiil.mc.lib.attributes.item.ItemStackUtil;
import alexiil.mc.lib.attributes.item.filter.ItemFilter;
import alexiil.mc.lib.attributes.item.impl.DelegatingFixedItemInv;
import appeng.util.inv.filter.IAEItemFilter;
// FIXME: Needs to be double checked, LBA has better ways of doing this
public class WrapperFilteredItemHandler extends DelegatingFixedItemInv {
private final IAEItemFilter filter;
public WrapperFilteredItemHandler(@Nonnull FixedItemInv handler, @Nonnull IAEItemFilter filter) {
super(handler);
this.filter = filter;
}
@Override
public boolean setInvStack(int slot, ItemStack to, Simulation simulation) {
ItemStack current = this.getInvStack(slot);
boolean same = ItemStackUtil.areEqualIgnoreAmounts(current, to);
boolean isExtracting = !current.isEmpty() && (!same || to.getCount() < current.getCount());
boolean isInserting = !to.isEmpty() && (!same || to.getCount() > current.getCount());
if (isExtracting) {
// We may be extracting by "exchanging" the current item for something else,
// or we might be setting it to air
int extractAmount = current.getCount();
if (same && !to.isEmpty()) {
extractAmount -= to.getCount();
}
if (!filter.allowExtract(delegate, slot, extractAmount)) {
return false;
}
}
if (isInserting) {
if (!filter.allowInsert(delegate, slot, to)) {
return false;
}
}
return super.setInvStack(slot, to, simulation);
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
return (stack.isEmpty() || this.getFilterForSlot(slot).matches(stack)) && super.isItemValidForSlot(slot, stack);
}
@Override
public ItemFilter getFilterForSlot(int slot) {
ItemFilter parentFilter = super.getFilterForSlot(slot);
ItemFilter thisFilter = stack -> filter.allowInsert(delegate, slot, stack);
return thisFilter.and(parentFilter);
}
}
@@ -1,55 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2017, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.util.inv.filter;
import net.minecraft.item.ItemStack;
import alexiil.mc.lib.attributes.item.FixedItemInv;
public class AEItemFilters {
public static final IAEItemFilter INSERT_ONLY = new InsertOnlyFilter();
public static final IAEItemFilter EXTRACT_ONLY = new ExtractOnlyFilter();
private AEItemFilters() {
}
private static class InsertOnlyFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return false;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return true;
}
}
private static class ExtractOnlyFilter implements IAEItemFilter {
@Override
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
return true;
}
@Override
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
return false;
}
}
}
@@ -24,7 +24,8 @@
"SlotMixin",
"TntAccessor",
"ServerWorldCustomItemEntityMixin",
"BootstrapMixin"
"BootstrapMixin",
"ItemEntityAccessor"
],
"client": [
"spatial.SkyRenderMixin",