Compare commits

...

75 Commits

Author SHA1 Message Date
Sebastian Hartte 575a625f75 Also update the layer-map, even though the spatial biome should never show up in any vanilla layering. 2020-09-02 19:44:37 +02:00
Sebastian Hartte 89ea923c43 Merge fixes 2020-09-02 19:41:44 +02:00
Sebastian Hartte 5d818eb03e Merge remote-tracking branch 'origin/master' into fabric/master 2020-09-02 02:55:39 +02:00
Sebastian Hartte 12ca8d109a Merge remote-tracking branch 'origin/8.0.x-1.16.1' 2020-09-02 02:55:12 +02:00
Sebastian Hartte e34126458b Merge remote-tracking branch 'origin/master' into fabric/master
# Conflicts:
#	gradle.properties
#	src/main/java/appeng/client/gui/Size1Slot.java
#	src/main/java/appeng/client/me/SlotFluidME.java
#	src/main/java/appeng/client/me/SlotME.java
#	src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java
#	src/main/java/appeng/client/render/cablebus/CableBusModelLoader.java
#	src/main/java/appeng/core/sync/packets/MEFluidInventoryUpdatePacket.java
#	src/main/java/appeng/core/sync/packets/MEInterfaceUpdatePacket.java
#	src/main/java/appeng/core/sync/packets/MEInventoryUpdatePacket.java
#	src/main/java/appeng/datagen/providers/loot/BlockDropProvider.java
#	src/main/java/appeng/fluids/client/gui/widgets/FluidSlotWidget.java
#	src/main/java/appeng/fluids/container/FluidConfigurableContainer.java
#	src/main/java/appeng/fluids/helper/FluidCellConfig.java
#	src/main/resources/META-INF/mods.toml
2020-09-02 02:45:31 +02:00
Sebastian Hartte 0ac918c363 Fixed exclusion zones for many screens. 2020-09-02 02:37:47 +02:00
Sebastian Hartte b6160e40bc Fixes #4671: Use other Ingredient method which is not client-only. 2020-09-02 01:49:24 +02:00
Sebastian Hartte cf103b06c1 Fixes #4677: Stackoverflow when crafting with the quartz knife. 2020-09-02 00:12:20 +02:00
yueh f0d0595c8f Fixes #4669: Take NBT into account for comparing. (#4675)
This only covers combining different items together.
Fuzzy filtering is still a bit too fuzzy for corner cases.
2020-09-01 21:59:08 +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 7c99fca789 Fixes removal of facades not invalidating the cached server-side collision boxes. (#4663)
(cherry picked from commit 957bc4c5cc)
2020-09-01 01:07:30 +02:00
yueh ab393b0ed1 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.

(cherry picked from commit e90dd2f9c6)
2020-09-01 01:07:28 +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 133ed1f09d Remove GZipStreams from packets. (#4664)
This should now be handled by the normal network manager (hopefully).
Also renamed the `CompressedNBTPacket` to `MEInterfaceUpdatePacket` as that is the only use case.
2020-08-31 23:09:28 +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
shartte db9ec2b070 Remove the use of SlotItemHandler since we are only faking an inventory-backed slot, (#4654)
we might as well use what we had used pre-2017, which is simply extending a normal Slot.
This should also fix #4652.
2020-08-29 22:03:35 +02:00
Sebastian Hartte 5d33005aaf Added back dynamic cable bus lighting. 2020-08-29 01:02:32 +02:00
Sebastian Hartte 87cf070b33 Fixes #4657: Remove usage of an implementation class and just copy the needed values into arrays. 2020-08-29 00:45:01 +02:00
Masakitenchi 3a0552c56e Update zh_cn.json (#4653) 2020-08-28 10:49:11 +02:00
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
73 changed files with 815 additions and 839 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
@@ -144,13 +144,13 @@ dependencies {
modApi "teamreborn:energy:${tr_energy_version}"
include "teamreborn:energy:${tr_energy_version}"
modCompileOnly("me.shedaniel:RoughlyEnoughItems:5.0.2-unstable") {
modCompileOnly("me.shedaniel:RoughlyEnoughItems:${rei_version}") {
exclude group: "net.fabricmc.fabric-api"
}
modCompileOnly("mcp.mobius.waila:Hwyla:1.16.1-1.9.22-75") {
exclude group: "net.fabricmc.fabric-api"
}
modRuntime("me.shedaniel:RoughlyEnoughItems:5.0.2-unstable") {
modRuntime("me.shedaniel:RoughlyEnoughItems:${rei_version}") {
exclude group: "net.fabricmc.fabric-api"
}
modRuntime("TechReborn:TechReborn-1.16:3.5.1+build.101") {
+3 -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,8 +23,9 @@ 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
rei_version=5.2.10
#########################################################
# Deployment #
+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;
}
}
@@ -41,6 +41,8 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.IntProperty;
import net.minecraft.util.ActionResult;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Hand;
@@ -80,8 +82,12 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
private static final IntProperty LIGHT_LEVEL = IntProperty.of("light_level", 0, 15);
public CableBusBlock() {
super(defaultProps(AEMaterials.GLASS).nonOpaque().dropsNothing().dynamicBounds());
super(defaultProps(AEMaterials.GLASS).nonOpaque().dropsNothing().dynamicBounds()
.lightLevel(state -> state.get(LIGHT_LEVEL)));
setDefaultState(getDefaultState().with(LIGHT_LEVEL, 0));
}
static {
@@ -134,16 +140,13 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
// OPPOSITE!?
}
// FIXME Dynamic light seems unsupported (?) Must maybe use blockstates... :|
// FIXME FABRIC @Override
// FIXME FABRIC public int getLightValue(final BlockState state, final BlockView world, final BlockPos pos) {
// FIXME FABRIC if (state.getBlock() != this) {
// FIXME FABRIC return state.getLuminance();
// FIXME FABRIC }
// FIXME FABRIC return this.cb(world, pos).getLightValue();
// FIXME FABRIC }
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(LIGHT_LEVEL);
}
// FIXME: Must hook isClimbing ourselves
// FIXME: Must hook isClimbing ourselves
// FIXME FABRIC @Override
// FIXME FABRIC public boolean isLadder(BlockState state, WorldView world, BlockPos pos, LivingEntity entity) {
// FIXME FABRIC return this.cb(world, pos).isLadder(entity);
@@ -399,4 +402,13 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
}
}
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, CableBusBlockEntity te) {
if (currentState.getBlock() != this) {
return currentState;
}
int lightLevel = te.getCableBus().getLightValue();
return super.updateBlockStateFromTileEntity(currentState, te).with(LIGHT_LEVEL, lightLevel);
}
}
@@ -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();
@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
import com.google.common.base.Preconditions;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.mojang.blaze3d.systems.RenderSystem;
import org.lwjgl.glfw.GLFW;
@@ -58,6 +59,7 @@ import net.minecraft.util.Identifier;
import alexiil.mc.lib.attributes.fluid.render.FluidRenderFace;
import alexiil.mc.lib.attributes.fluid.render.FluidVolumeRenderer;
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
import me.shedaniel.math.Rectangle;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
@@ -803,4 +805,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
}
}
public List<Rectangle> getExclusionZones() {
return Lists.newArrayList(new Rectangle(x, y, backgroundWidth, backgroundHeight));
}
}
@@ -12,8 +12,6 @@ import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
import net.minecraft.util.Identifier;
import appeng.client.me.SlotME;
/**
* A proxy for a slot that will always return an itemstack with size 1, if there
* is an item in the slot. Used to prevent the default item count from
@@ -21,9 +19,9 @@ import appeng.client.me.SlotME;
*/
class Size1Slot extends Slot {
private final SlotME delegate;
private final Slot delegate;
public Size1Slot(SlotME delegate) {
public Size1Slot(Slot delegate) {
super(delegate.inventory, -1, delegate.x, delegate.y);
this.delegate = delegate;
}
@@ -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
@@ -28,6 +28,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
import net.minecraft.text.Text;
import me.shedaniel.math.Rectangle;
import appeng.api.config.SearchBoxMode;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
@@ -519,4 +521,14 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
this.init();
}
@Override
public List<Rectangle> getExclusionZones() {
List<Rectangle> zones = super.getExclusionZones();
// Button toolbar on the left
zones.add(new Rectangle(x - 18, y + 8, 18, 160));
// View-cells on the right
zones.add(new Rectangle(x + 197, y, 46, 128));
return zones;
}
}
@@ -18,10 +18,14 @@
package appeng.client.gui.implementations;
import java.util.List;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import me.shedaniel.math.Rectangle;
import appeng.api.config.FuzzyMode;
import appeng.api.config.RedstoneMode;
import appeng.api.config.SchedulingMode;
@@ -146,4 +150,11 @@ public class UpgradeableScreen<T extends UpgradeableContainer> extends AEBaseScr
return this.bc instanceof ImportBusPart ? GuiText.ImportBus : GuiText.ExportBus;
}
@Override
public List<Rectangle> getExclusionZones() {
List<Rectangle> zones = super.getExclusionZones();
zones.add(new Rectangle(x - 18, y + 8, 18, 60));
return zones;
}
}
@@ -41,11 +41,6 @@ import appeng.fluids.util.FluidSorters;
import appeng.util.Platform;
import appeng.util.prioritylist.IPartitionList;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class FluidRepo {
private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)
.createList();
@@ -21,23 +21,22 @@ package appeng.client.me;
import javax.annotation.Nonnull;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
import appeng.api.storage.data.IAEFluidStack;
import appeng.fluids.container.slots.IMEFluidSlot;
/**
* @author BrockWS
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class SlotFluidME extends Slot implements IMEFluidSlot {
private static final Inventory EMPTY_INVENTORY = new SimpleInventory(0);
private final InternalFluidSlotME slot;
public SlotFluidME(InternalFluidSlotME slot) {
super(null, 0, slot.getxPosition(), slot.getyPosition());
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
this.slot = slot;
}
@@ -69,7 +68,7 @@ public class SlotFluidME extends Slot implements IMEFluidSlot {
}
@Override
public void setStack(final ItemStack par1ItemStack) {
public void setStack(final ItemStack stack) {
}
@@ -85,7 +84,7 @@ public class SlotFluidME extends Slot implements IMEFluidSlot {
}
@Override
public boolean canTakeItems(final PlayerEntity par1PlayerEntity) {
public boolean canTakeItems(final PlayerEntity player) {
return false;
}
}
+13 -9
View File
@@ -19,6 +19,8 @@
package appeng.client.me;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
@@ -26,16 +28,18 @@ import appeng.api.storage.data.IAEItemStack;
public class SlotME extends Slot {
private final InternalSlotME mySlot;
private static final Inventory EMPTY_INVENTORY = new SimpleInventory(0);
public SlotME(final InternalSlotME me) {
super(null, 0, me.getxPosition(), me.getyPosition());
this.mySlot = me;
private final InternalSlotME slot;
public SlotME(final InternalSlotME slot) {
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
this.slot = slot;
}
public IAEItemStack getAEStack() {
if (this.mySlot.hasPower()) {
return this.mySlot.getAEStack();
if (this.slot.hasPower()) {
return this.slot.getAEStack();
}
return null;
}
@@ -47,15 +51,15 @@ public class SlotME extends Slot {
@Override
public ItemStack getStack() {
if (this.mySlot.hasPower()) {
return this.mySlot.getStack();
if (this.slot.hasPower()) {
return this.slot.getStack();
}
return ItemStack.EMPTY;
}
@Override
public boolean hasStack() {
if (this.mySlot.hasPower()) {
if (this.slot.hasPower()) {
return !this.getStack().isEmpty();
}
return false;
@@ -20,7 +20,6 @@ package appeng.client.render.cablebus;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -30,6 +29,10 @@ import java.util.function.Supplier;
import javax.annotation.Nullable;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
@@ -61,10 +64,15 @@ import appeng.api.util.AEColor;
@Environment(EnvType.CLIENT)
public class CableBusBakedModel implements BakedModel, FabricBakedModel {
private static final Mesh EMPTY_MESH = consumer -> {
};
private static final Renderer RENDERER = RendererAccess.INSTANCE.getRenderer();
// FIXME: This entire cache seems dumb as shit
private static final Map<CableBusRenderState, Mesh> CABLE_MODEL_CACHE = new HashMap<>();
// The number of meshes overall that will be cached
private static final int CACHE_MESH_COUNT = 100;
private final LoadingCache<CableBusRenderState, Mesh> cableModelCache;
private final CableBuilder cableBuilder;
@@ -80,6 +88,15 @@ public class CableBusBakedModel implements BakedModel, FabricBakedModel {
this.facadeBuilder = facadeBuilder;
this.partModels = partModels;
this.particleTexture = particleTexture;
this.cableModelCache = CacheBuilder.newBuilder()//
.maximumSize(CACHE_MESH_COUNT)//
.build(new CacheLoader<CableBusRenderState, Mesh>() {
@Override
public Mesh load(CableBusRenderState renderState) {
Mesh mesh = buildCableModel(renderState);
return mesh != null ? mesh : EMPTY_MESH;
}
});
}
@Override
@@ -109,8 +126,8 @@ public class CableBusBakedModel implements BakedModel, FabricBakedModel {
}
// First, handle the cable at the center of the cable bus
final Mesh cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, this::buildCableModel);
if (cableModel != null) {
final Mesh cableModel = cableModelCache.getUnchecked(renderState);
if (cableModel != EMPTY_MESH) {
context.meshConsumer().accept(cableModel);
}
@@ -359,10 +376,6 @@ public class CableBusBakedModel implements BakedModel, FabricBakedModel {
return ModelOverrideList.EMPTY;
}
public static void clearCache() {
CABLE_MODEL_CACHE.clear();
}
@Override
public boolean isVanillaAdapter() {
return false;
@@ -23,7 +23,6 @@ public class CableBusModelLoader implements ModelResourceProvider {
public UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context)
throws ModelProviderException {
if (CABLE_BUS_MODEL.equals(resourceId)) {
CableBusBakedModel.clearCache();
return new CableBusModel(partModels);
} else {
return null;
@@ -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;
@@ -43,7 +45,7 @@ import appeng.api.networking.security.IActionHost;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerLocator;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.CompressedNBTPacket;
import appeng.core.sync.packets.MEInterfaceUpdatePacket;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.InventoryAction;
@@ -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 {
@@ -177,7 +177,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
if (!this.data.isEmpty()) {
try {
NetworkHandler.instance().sendTo(new CompressedNBTPacket(this.data),
NetworkHandler.instance().sendTo(new MEInterfaceUpdatePacket(this.data),
(ServerPlayerEntity) this.getPlayerInv().player);
} catch (final IOException e) {
// :P
@@ -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;
}
}
}
@@ -143,9 +143,11 @@ public class QuartzKnifeContainer extends AEBaseContainer {
private void makePlate() {
if (Platform.isServer()) {
if (!this.takeStack(1).isEmpty()) {
if (!inSlot.getSlot(0).extract(1).isEmpty()) {
final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack();
final ItemStack before = item.copy();
// FIXME FABRIC: Quartz Knife currently is not damageable due to recipe
// remainder concerns
item.damage(1, QuartzKnifeContainer.this.getPlayerInv().player, p -> {
QuartzKnifeContainer.this.getPlayerInv()
.setStack(QuartzKnifeContainer.this.getPlayerInv().selectedSlot, ItemStack.EMPTY);
@@ -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)
@@ -29,7 +29,6 @@ import appeng.core.sync.packets.BlockTransitionEffectPacket;
import appeng.core.sync.packets.ClickPacket;
import appeng.core.sync.packets.CompassRequestPacket;
import appeng.core.sync.packets.CompassResponsePacket;
import appeng.core.sync.packets.CompressedNBTPacket;
import appeng.core.sync.packets.ConfigButtonPacket;
import appeng.core.sync.packets.ConfigValuePacket;
import appeng.core.sync.packets.CraftRequestPacket;
@@ -39,6 +38,7 @@ import appeng.core.sync.packets.ItemTransitionEffectPacket;
import appeng.core.sync.packets.JEIRecipePacket;
import appeng.core.sync.packets.LightningPacket;
import appeng.core.sync.packets.MEFluidInventoryUpdatePacket;
import appeng.core.sync.packets.MEInterfaceUpdatePacket;
import appeng.core.sync.packets.MEInventoryUpdatePacket;
import appeng.core.sync.packets.MatterCannonPacket;
import appeng.core.sync.packets.PaintedEntityPacket;
@@ -99,7 +99,7 @@ public class BasePacketHandler {
PACKET_ASSEMBLER_ANIMATION(AssemblerAnimationPacket.class, AssemblerAnimationPacket::new),
PACKET_COMPRESSED_NBT(CompressedNBTPacket.class, CompressedNBTPacket::new),
PACKET_ME_INTERFACE_UPDATE(MEInterfaceUpdatePacket.class, MEInterfaceUpdatePacket::new),
PACKET_PAINTED_ENTITY(PaintedEntityPacket.class, PaintedEntityPacket::new),
@@ -19,13 +19,9 @@
package appeng.core.sync.packets;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nullable;
@@ -41,7 +37,6 @@ import net.minecraft.network.Packet;
import net.minecraft.network.PacketByteBuf;
import appeng.api.storage.data.IAEFluidStack;
import appeng.core.AELog;
import appeng.core.sync.BasePacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.fluids.client.gui.FluidTerminalScreen;
@@ -55,8 +50,6 @@ import appeng.fluids.util.AEFluidStack;
public class MEFluidInventoryUpdatePacket extends BasePacket {
private static final int UNCOMPRESSED_PACKET_BYTE_LIMIT = 16 * 1024 * 1024;
private static final int OPERATION_BYTE_LIMIT = 2 * 1024;
private static final int TEMP_BUFFER_SIZE = 1024;
private static final int STREAM_MASK = 0xff;
// input.
@Nullable
@@ -66,47 +59,18 @@ public class MEFluidInventoryUpdatePacket extends BasePacket {
@Nullable
private final PacketByteBuf data;
@Nullable
private final GZIPOutputStream compressFrame;
private int writtenBytes = 0;
private boolean empty = true;
public MEFluidInventoryUpdatePacket(final PacketByteBuf stream) {
this.data = null;
this.compressFrame = null;
this.list = new LinkedList<>();
this.ref = stream.readByte();
try (final GZIPInputStream gzReader = new GZIPInputStream(new InputStream() {
@Override
public int read() {
if (stream.readableBytes() <= 0) {
return -1;
}
return stream.readByte() & STREAM_MASK;
}
})) {
final PacketByteBuf uncompressed = new PacketByteBuf(Unpooled.buffer(stream.readableBytes()));
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while (gzReader.available() != 0) {
final int bytes = gzReader.read(tmp);
if (bytes > 0) {
uncompressed.writeBytes(tmp, 0, bytes);
}
}
while (uncompressed.readableBytes() > 0) {
this.list.add(AEFluidStack.fromPacket(uncompressed));
}
} catch (IOException e) {
throw new RuntimeException("Failed to decompress packet.", e);
while (stream.readableBytes() > 0) {
this.list.add(AEFluidStack.fromPacket(stream));
}
this.empty = this.list.isEmpty();
}
@@ -121,14 +85,6 @@ public class MEFluidInventoryUpdatePacket extends BasePacket {
this.data = new PacketByteBuf(Unpooled.buffer(OPERATION_BYTE_LIMIT));
this.data.writeInt(this.getPacketID());
this.data.writeByte(this.ref);
this.compressFrame = new GZIPOutputStream(new OutputStream() {
@Override
public void write(final int value) {
MEFluidInventoryUpdatePacket.this.data.writeByte(value);
}
});
this.list = null;
}
@@ -145,28 +101,19 @@ public class MEFluidInventoryUpdatePacket extends BasePacket {
@Nullable
@Override
public Packet<?> toPacket(NetworkSide direction) {
try {
this.compressFrame.close();
this.configureWrite(this.data);
return super.toPacket(direction);
} catch (final IOException e) {
AELog.debug(e);
}
return null;
this.configureWrite(this.data);
return super.toPacket(direction);
}
public void appendFluid(final IAEFluidStack fs) throws IOException, BufferOverflowException {
final PacketByteBuf tmp = new PacketByteBuf(Unpooled.buffer(OPERATION_BYTE_LIMIT));
fs.writeToPacket(tmp);
this.compressFrame.flush();
if (this.writtenBytes + tmp.readableBytes() > UNCOMPRESSED_PACKET_BYTE_LIMIT) {
throw new BufferOverflowException();
} else {
this.writtenBytes += tmp.readableBytes();
this.compressFrame.write(tmp.array(), 0, tmp.readableBytes());
this.data.writeBytes(tmp.array(), 0, tmp.readableBytes());
this.empty = false;
}
}
@@ -18,13 +18,7 @@
package appeng.core.sync.packets;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import io.netty.buffer.Unpooled;
@@ -34,62 +28,30 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.network.PacketByteBuf;
import appeng.client.gui.implementations.InterfaceTerminalScreen;
import appeng.core.sync.BasePacket;
import appeng.core.sync.network.INetworkInfo;
//TODO, this is pointless, NBT is already compressed when written to a PacketBuffer.
public class CompressedNBTPacket extends BasePacket {
public class MEInterfaceUpdatePacket extends BasePacket {
// input.
private final CompoundTag in;
// output...
private final PacketByteBuf data;
private final GZIPOutputStream compressFrame;
public CompressedNBTPacket(final PacketByteBuf stream) {
public MEInterfaceUpdatePacket(final PacketByteBuf stream) {
this.data = null;
this.compressFrame = null;
try (DataInputStream inStream = new DataInputStream(new GZIPInputStream(new InputStream() {
@Override
public int read() {
if (stream.readableBytes() <= 0) {
return -1;
}
return stream.readByte() & 0xff;
}
}))) {
this.in = NbtIo.read(inStream);
} catch (IOException e) {
throw new RuntimeException("Failed to decompress packet.", e);
}
this.in = stream.readCompoundTag();
}
// api
public CompressedNBTPacket(final CompoundTag din) throws IOException {
public MEInterfaceUpdatePacket(final CompoundTag din) throws IOException {
this.in = null;
this.data = new PacketByteBuf(Unpooled.buffer(2048));
this.data.writeInt(this.getPacketID());
this.in = din;
this.compressFrame = new GZIPOutputStream(new OutputStream() {
@Override
public void write(final int value) {
CompressedNBTPacket.this.data.writeByte(value);
}
});
NbtIo.write(din, new DataOutputStream(this.compressFrame));
this.compressFrame.close();
this.data.writeCompoundTag(din);
this.configureWrite(this.data);
}
@@ -19,12 +19,10 @@
package appeng.core.sync.packets;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.BufferOverflowException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.annotation.Nullable;
@@ -45,7 +43,6 @@ import appeng.client.gui.implementations.CraftConfirmScreen;
import appeng.client.gui.implementations.CraftingCPUScreen;
import appeng.client.gui.implementations.MEMonitorableScreen;
import appeng.client.gui.implementations.NetworkStatusScreen;
import appeng.core.AELog;
import appeng.core.sync.BasePacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.util.item.AEItemStack;
@@ -53,8 +50,6 @@ import appeng.util.item.AEItemStack;
public class MEInventoryUpdatePacket extends BasePacket {
private static final int UNCOMPRESSED_PACKET_BYTE_LIMIT = 16 * 1024 * 1024;
private static final int OPERATION_BYTE_LIMIT = 2 * 1024;
private static final int TEMP_BUFFER_SIZE = 1024;
private static final int STREAM_MASK = 0xff;
// input.
@Nullable
@@ -64,48 +59,18 @@ public class MEInventoryUpdatePacket extends BasePacket {
@Nullable
private final PacketByteBuf data;
@Nullable
private final GZIPOutputStream compressFrame;
private int writtenBytes = 0;
private boolean empty = true;
public MEInventoryUpdatePacket(final PacketByteBuf stream) {
this.data = null;
this.compressFrame = null;
this.list = new ArrayList<>();
this.ref = stream.readByte();
// int originalBytes = stream.readableBytes();
try (GZIPInputStream gzReader = new GZIPInputStream(new InputStream() {
@Override
public int read() {
if (stream.readableBytes() <= 0) {
return -1;
}
return stream.readByte() & STREAM_MASK;
}
})) {
final PacketByteBuf uncompressed = new PacketByteBuf(Unpooled.buffer(stream.readableBytes()));
final byte[] tmp = new byte[TEMP_BUFFER_SIZE];
while (gzReader.available() != 0) {
final int bytes = gzReader.read(tmp);
if (bytes > 0) {
uncompressed.writeBytes(tmp, 0, bytes);
}
}
while (uncompressed.readableBytes() > 0) {
this.list.add(AEItemStack.fromPacket(uncompressed));
}
} catch (IOException e) {
throw new RuntimeException("Failed to decompress packet.", e);
while (stream.readableBytes() > 0) {
this.list.add(AEItemStack.fromPacket(stream));
}
this.empty = this.list.isEmpty();
}
@@ -120,14 +85,6 @@ public class MEInventoryUpdatePacket extends BasePacket {
this.data = new PacketByteBuf(Unpooled.buffer(OPERATION_BYTE_LIMIT));
this.data.writeInt(this.getPacketID());
this.data.writeByte(this.ref);
this.compressFrame = new GZIPOutputStream(new OutputStream() {
@Override
public void write(final int value) {
MEInventoryUpdatePacket.this.data.writeByte(value);
}
});
this.list = null;
}
@@ -156,28 +113,19 @@ public class MEInventoryUpdatePacket extends BasePacket {
@Nullable
@Override
public Packet<?> toPacket(NetworkSide direction) {
try {
this.compressFrame.close();
this.configureWrite(this.data);
return super.toPacket(direction);
} catch (final IOException e) {
AELog.debug(e);
}
return null;
this.configureWrite(this.data);
return super.toPacket(direction);
}
public void appendItem(final IAEItemStack is) throws IOException, BufferOverflowException {
final PacketByteBuf tmp = new PacketByteBuf(Unpooled.buffer(OPERATION_BYTE_LIMIT));
is.writeToPacket(tmp);
this.compressFrame.flush();
if (this.writtenBytes + tmp.readableBytes() > UNCOMPRESSED_PACKET_BYTE_LIMIT) {
throw new BufferOverflowException();
} else {
this.writtenBytes += tmp.readableBytes();
this.compressFrame.write(tmp.array(), 0, tmp.readableBytes());
this.data.writeBytes(tmp.array(), 0, tmp.readableBytes());
this.empty = false;
}
}
@@ -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)) {
@@ -38,15 +38,18 @@ public class FacadeContainer implements IFacadeContainer {
private final int facades = 6;
private final CableBusStorage storage;
private final Runnable changeCallback;
public FacadeContainer(final CableBusStorage cbs) {
public FacadeContainer(final CableBusStorage cbs, Runnable changeCallback) {
this.storage = cbs;
this.changeCallback = changeCallback;
}
@Override
public boolean addFacade(final IFacadePart a) {
if (this.getFacade(a.getSide()) == null) {
this.storage.setFacade(a.getSide().ordinal(), a);
this.notifyChange();
return true;
}
return false;
@@ -57,6 +60,7 @@ public class FacadeContainer implements IFacadeContainer {
if (side != null && side != AEPartLocation.INTERNAL) {
if (this.storage.getFacade(side.ordinal()) != null) {
this.storage.setFacade(side.ordinal(), null);
this.notifyChange();
if (host != null) {
host.markForUpdate();
}
@@ -85,6 +89,7 @@ public class FacadeContainer implements IFacadeContainer {
for (int x = 0; x < this.facades; x++) {
this.storage.setFacade(x, newFacades[x]);
}
this.notifyChange();
}
@Override
@@ -176,4 +181,9 @@ public class FacadeContainer implements IFacadeContainer {
}
return true;
}
private void notifyChange() {
this.changeCallback.run();
}
}
@@ -33,6 +33,8 @@ import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import me.shedaniel.math.Rectangle;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
@@ -331,4 +333,11 @@ public class FluidTerminalScreen extends AEBaseMEScreen<FluidTerminalContainer>
return "guis/terminal.png";
}
@Override
public List<Rectangle> getExclusionZones() {
List<Rectangle> zones = super.getExclusionZones();
zones.add(new Rectangle(x - 18, y, 18, 40));
return zones;
}
}
@@ -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;
@@ -20,6 +20,7 @@ package appeng.integration.modules.jei;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -158,7 +159,7 @@ public class ReiPlugin implements REIPluginV0 {
baseBoundsHandler.registerExclusionZones(AEBaseScreen.class, () -> {
AEBaseScreen<?> screen = (AEBaseScreen<?>) MinecraftClient.getInstance().currentScreen;
return ImmutableList.of(new Rectangle(screen.getX(), screen.getY(), screen.width, screen.height));
return screen != null ? screen.getExclusionZones() : Collections.emptyList();
});
}
@@ -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);
}
@@ -1,13 +1,21 @@
package appeng.mixins.spatial;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
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.BuiltinRegistries;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import appeng.spatial.SpatialStorageBiome;
import appeng.spatial.SpatialStorageDimensionIds;
@@ -18,10 +26,21 @@ import appeng.spatial.SpatialStorageDimensionIds;
@Mixin(Biomes.class)
public class BiomesMixin {
@Unique
private static final Logger LOGGER = LogManager.getLogger();
@Shadow
private static Int2ObjectMap<RegistryKey<Biome>> BIOMES;
@Inject(method = "<clinit>", at = @At("TAIL"))
private static void registerBiomes(CallbackInfo ci) {
BuiltinRegistries.add(BuiltinRegistries.BIOME, SpatialStorageDimensionIds.BIOME_KEY.getValue(),
SpatialStorageBiome.INSTANCE);
int rawId = BuiltinRegistries.BIOME.getRawId(SpatialStorageBiome.INSTANCE);
RegistryKey<Biome> prev = BIOMES.put(rawId, SpatialStorageDimensionIds.BIOME_KEY);
if (prev != null) {
LOGGER.warn("Biome with raw-id {} was already registered: {}", rawId, prev);
}
}
}
@@ -125,7 +125,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
@Override
public IFacadeContainer getFacadeContainer() {
return new FacadeContainer(this);
return new FacadeContainer(this, this::invalidateShapes);
}
@Override
+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 }
@@ -19,11 +19,8 @@
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView;
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.EncodingFormat;
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
import appeng.thirdparty.codechicken.lib.math.InterpHelper;
@@ -39,16 +36,11 @@ public class QuadReInterpolator implements RenderContext.QuadTransform {
private final InterpHelper interpHelper = new InterpHelper();
private final MutableQuadViewImpl bufferQuad = new MutableQuadViewImpl() {
{
data = new int[EncodingFormat.TOTAL_STRIDE];
}
private final int[] originalSpriteColor = new int[4];
@Override
public QuadEmitter emit() {
throw new UnsupportedOperationException();
}
};
private final float[] originalSpriteU = new float[4];
private final float[] originalSpriteV = new float[4];
public QuadReInterpolator() {
super();
@@ -63,7 +55,13 @@ public class QuadReInterpolator implements RenderContext.QuadTransform {
quad.posByIndex(1, xIdx), quad.posByIndex(1, yIdx), //
quad.posByIndex(2, xIdx), quad.posByIndex(2, yIdx), //
quad.posByIndex(3, xIdx), quad.posByIndex(3, yIdx));
quad.copyTo(bufferQuad);
// Save the original properties of the quad's vertices
for (int i = 0; i < 4; i++) {
originalSpriteColor[i] = quad.spriteColor(i, 0);
originalSpriteU[i] = quad.spriteU(i, 0);
originalSpriteV[i] = quad.spriteV(i, 0);
}
}
@Override
@@ -89,10 +87,10 @@ public class QuadReInterpolator implements RenderContext.QuadTransform {
* reference.
*/
public void interpColorFrom(MutableQuadView quad, int vertexIndex) {
int p1 = bufferQuad.spriteColor(0, 0);
int p2 = bufferQuad.spriteColor(1, 0);
int p3 = bufferQuad.spriteColor(2, 0);
int p4 = bufferQuad.spriteColor(3, 0);
int p1 = this.originalSpriteColor[0];
int p2 = this.originalSpriteColor[1];
int p3 = this.originalSpriteColor[2];
int p4 = this.originalSpriteColor[3];
if (p1 == p2 && p2 == p3 && p3 == p4) {
return; // Don't bother for uniformly colored quads
}
@@ -118,16 +116,16 @@ public class QuadReInterpolator implements RenderContext.QuadTransform {
* reference.
*/
public void interpUVFrom(MutableQuadView quad, int vertexIndex) {
float p1 = bufferQuad.spriteU(0, 0);
float p2 = bufferQuad.spriteU(1, 0);
float p3 = bufferQuad.spriteU(2, 0);
float p4 = bufferQuad.spriteU(3, 0);
float p1 = originalSpriteU[0];
float p2 = originalSpriteU[1];
float p3 = originalSpriteU[2];
float p4 = originalSpriteU[3];
float u = interpHelper.interpolate(p1, p2, p3, p4);
p1 = bufferQuad.spriteV(0, 0);
p2 = bufferQuad.spriteV(1, 0);
p3 = bufferQuad.spriteV(2, 0);
p4 = bufferQuad.spriteV(3, 0);
p1 = originalSpriteV[0];
p2 = originalSpriteV[1];
p3 = originalSpriteV[2];
p4 = originalSpriteV[3];
float v = interpHelper.interpolate(p1, p2, p3, p4);
quad.sprite(vertexIndex, 0, u, v);
}
@@ -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;
}
}
}
@@ -1,5 +1,7 @@
package appeng.tile.misc;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
@@ -78,7 +80,7 @@ public final class InscriberRecipes {
name += " " + tag.getString(MaterialItem.TAG_INSCRIBE_NAME);
}
final Ingredient startingItem = Ingredient.ofStacks(input.copy());
final Ingredient startingItem = Ingredient.method_26964(Stream.of(input.copy()));
final ItemStack renamedItem = input.copy();
if (!name.isEmpty()) {
@@ -90,8 +92,8 @@ public final class InscriberRecipes {
final InscriberProcessType type = InscriberProcessType.INSCRIBE;
return new InscriberRecipe(NAMEPLATE_RECIPE_ID, "", startingItem, renamedItem,
plateA.isEmpty() ? Ingredient.EMPTY : Ingredient.ofStacks(plateA),
plateB.isEmpty() ? Ingredient.EMPTY : Ingredient.ofStacks(plateB), type);
plateA.isEmpty() ? Ingredient.EMPTY : Ingredient.method_26964(Stream.of(plateA)),
plateB.isEmpty() ? Ingredient.EMPTY : Ingredient.method_26964(Stream.of(plateB)), type);
}
/**
@@ -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;
}
}
}
@@ -29,6 +29,7 @@ import net.minecraft.nbt.CompoundTag;
import appeng.api.config.FuzzyMode;
final class AESharedItemStack implements Comparable<AESharedItemStack> {
private final ItemStack itemStack;
private final int itemId;
private final int itemDamage;
@@ -97,7 +98,8 @@ final class AESharedItemStack implements Comparable<AESharedItemStack> {
return damageValue;
}
return 0;
return System.identityHashCode(this.getDefinition().getTag())
- System.identityHashCode(b.getDefinition().getTag());
}
private int makeHashCode() {
@@ -183,4 +185,5 @@ final class AESharedItemStack implements Comparable<AESharedItemStack> {
}
}
}
@@ -24,7 +24,8 @@
"SlotMixin",
"TntAccessor",
"ServerWorldCustomItemEntityMixin",
"BootstrapMixin"
"BootstrapMixin",
"ItemEntityAccessor"
],
"client": [
"spatial.SkyRenderMixin",
@@ -58,7 +58,7 @@
"block.appliedenergistics2.chest": "ME箱子",
"block.appliedenergistics2.chiseled_quartz_block": "錾制赛特斯石英块",
"block.appliedenergistics2.chiseled_quartz_slab": "錾制赛特斯石英台阶",
"block.appliedenergistics2.chiseled_quartz_stairs": "竖纹赛特斯石英楼梯",
"block.appliedenergistics2.chiseled_quartz_stairs": "錾制赛特斯石英楼梯",
"block.appliedenergistics2.condenser": "物质聚合器",
"block.appliedenergistics2.controller": "ME控制器",
"block.appliedenergistics2.crafting_accelerator": "并行处理单元",
@@ -77,7 +77,7 @@
"block.appliedenergistics2.fluid_interface": "ME流体接口",
"block.appliedenergistics2.fluix_block": "福鲁伊克斯块",
"block.appliedenergistics2.fluix_slab": "福鲁伊克斯台阶",
"block.appliedenergistics2.fluix_stairs": "錾制赛特斯石英楼梯",
"block.appliedenergistics2.fluix_stairs": "福鲁伊克斯楼梯",
"block.appliedenergistics2.grindstone": "石英磨具",
"block.appliedenergistics2.inscriber": "压印器",
"block.appliedenergistics2.interface": "ME接口",
@@ -92,11 +92,11 @@
"block.appliedenergistics2.quartz_glass": "石英玻璃",
"block.appliedenergistics2.quartz_growth_accelerator": "晶体催生器",
"block.appliedenergistics2.quartz_ore": "赛特斯石英矿石",
"block.appliedenergistics2.quartz_pillar": "赛特斯竖纹石英块",
"block.appliedenergistics2.quartz_pillar": "竖纹赛特斯石英块",
"block.appliedenergistics2.quartz_pillar_slab": "竖纹赛特斯石英台阶",
"block.appliedenergistics2.quartz_pillar_stairs": "赛特斯石英楼梯",
"block.appliedenergistics2.quartz_pillar_stairs": "竖纹赛特斯石英楼梯",
"block.appliedenergistics2.quartz_slab": "赛特斯石英台阶",
"block.appliedenergistics2.quartz_stairs": "福鲁伊克斯楼梯",
"block.appliedenergistics2.quartz_stairs": "赛特斯石英楼梯",
"block.appliedenergistics2.quartz_vibrant_glass": "聚能石英玻璃",
"block.appliedenergistics2.security_station": "ME安全终端",
"block.appliedenergistics2.sky_compass": "陨石罗盘",
@@ -407,28 +407,28 @@
"item.appliedenergistics2.annihilation_plane": "ME破坏面板",
"item.appliedenergistics2.basic_card": "基础卡",
"item.appliedenergistics2.biometric_card": "身份卡",
"item.appliedenergistics2.black_covered_cable": "黑色 ME包层线缆",
"item.appliedenergistics2.black_covered_dense_cable": "黑色 ME致密包层线缆",
"item.appliedenergistics2.black_glass_cable": "黑色 ME玻璃线缆",
"item.appliedenergistics2.black_lumen_paint_ball": "黑色 光通 染色球",
"item.appliedenergistics2.black_paint_ball": "黑色 染色球",
"item.appliedenergistics2.black_smart_cable": "黑色 ME智能线缆",
"item.appliedenergistics2.black_smart_dense_cable": "黑色 ME致密线缆",
"item.appliedenergistics2.black_covered_cable": "ME包层线缆(黑色)",
"item.appliedenergistics2.black_covered_dense_cable": "ME致密包层线缆(黑色)",
"item.appliedenergistics2.black_glass_cable": "ME玻璃线缆(黑色)",
"item.appliedenergistics2.black_lumen_paint_ball": "光通染色球(黑色)",
"item.appliedenergistics2.black_paint_ball": "染色球(黑色)",
"item.appliedenergistics2.black_smart_cable": "ME智能线缆(黑色)",
"item.appliedenergistics2.black_smart_dense_cable": "ME致密线缆(黑色)",
"item.appliedenergistics2.blank_pattern": "空白样板",
"item.appliedenergistics2.blue_covered_cable": "蓝色 ME包层线缆",
"item.appliedenergistics2.blue_covered_dense_cable": "蓝色 ME致密包层线缆",
"item.appliedenergistics2.blue_glass_cable": "蓝色 ME玻璃线缆",
"item.appliedenergistics2.blue_lumen_paint_ball": "蓝色 光通 染色球",
"item.appliedenergistics2.blue_paint_ball": "蓝色 染色球",
"item.appliedenergistics2.blue_smart_cable": "蓝色 ME智能线缆",
"item.appliedenergistics2.blue_smart_dense_cable": "蓝色 ME致密线缆",
"item.appliedenergistics2.brown_covered_cable": "棕色 ME包层线缆",
"item.appliedenergistics2.brown_covered_dense_cable": "棕色 ME致密包层线缆",
"item.appliedenergistics2.brown_glass_cable": "棕色 ME玻璃线缆",
"item.appliedenergistics2.brown_lumen_paint_ball": "棕色 光通 染色球",
"item.appliedenergistics2.brown_paint_ball": "棕色 染色球",
"item.appliedenergistics2.brown_smart_cable": "棕色 ME智能线缆",
"item.appliedenergistics2.brown_smart_dense_cable": "棕色 ME致密线缆",
"item.appliedenergistics2.blue_covered_cable": "ME包层线缆(蓝色)",
"item.appliedenergistics2.blue_covered_dense_cable": "ME致密包层线缆(蓝色)",
"item.appliedenergistics2.blue_glass_cable": "ME玻璃线缆(蓝色)",
"item.appliedenergistics2.blue_lumen_paint_ball": "光通染色球(蓝色)",
"item.appliedenergistics2.blue_paint_ball": "染色球(蓝色)",
"item.appliedenergistics2.blue_smart_cable": "ME智能线缆(蓝色)",
"item.appliedenergistics2.blue_smart_dense_cable": "ME致密线缆(蓝色)",
"item.appliedenergistics2.brown_covered_cable": "ME包层线缆(棕色)",
"item.appliedenergistics2.brown_covered_dense_cable": "棕色 ME致密包层线缆(棕色)",
"item.appliedenergistics2.brown_glass_cable": "ME玻璃线缆(棕色)",
"item.appliedenergistics2.brown_lumen_paint_ball": "光通染色球(棕色)",
"item.appliedenergistics2.brown_paint_ball": "染色球(棕色)",
"item.appliedenergistics2.brown_smart_cable": "ME智能线缆(棕色)",
"item.appliedenergistics2.brown_smart_dense_cable": "ME致密线缆(棕色)",
"item.appliedenergistics2.cable_anchor": "线缆锚",
"item.appliedenergistics2.cable_fluid_interface": "ME流体接口",
"item.appliedenergistics2.cable_interface": "ME接口",
@@ -458,13 +458,13 @@
"item.appliedenergistics2.crafting_monitor": "ME合成监控器",
"item.appliedenergistics2.crafting_terminal": "ME合成终端",
"item.appliedenergistics2.creative_storage_cell": "创造型ME存储元件",
"item.appliedenergistics2.cyan_covered_cable": "青色 ME包层线缆",
"item.appliedenergistics2.cyan_covered_dense_cable": "青色 ME致密包层线缆",
"item.appliedenergistics2.cyan_glass_cable": "青色 ME玻璃线缆",
"item.appliedenergistics2.cyan_lumen_paint_ball": "青色 光通 染色球",
"item.appliedenergistics2.cyan_paint_ball": "青色 染色球",
"item.appliedenergistics2.cyan_smart_cable": "青色 ME智能线缆",
"item.appliedenergistics2.cyan_smart_dense_cable": "青色 ME致密线缆",
"item.appliedenergistics2.cyan_covered_cable": "ME包层线缆(青色)",
"item.appliedenergistics2.cyan_covered_dense_cable": "ME致密包层线缆(青色)",
"item.appliedenergistics2.cyan_glass_cable": "ME玻璃线缆(青色)",
"item.appliedenergistics2.cyan_lumen_paint_ball": "光通染色球(青色)",
"item.appliedenergistics2.cyan_paint_ball": "染色球(青色)",
"item.appliedenergistics2.cyan_smart_cable": "ME智能线缆(青色)",
"item.appliedenergistics2.cyan_smart_dense_cable": "ME致密线缆(青色)",
"item.appliedenergistics2.dark_monitor": "暗色照明面板",
"item.appliedenergistics2.debug_card": "Dev.调试卡",
"item.appliedenergistics2.debug_replicator_card": "Dev.复制卡",
@@ -477,7 +477,7 @@
"item.appliedenergistics2.entropy_manipulator": "熵变机械臂",
"item.appliedenergistics2.export_bus": "ME输出总线",
"item.appliedenergistics2.facade": "线缆伪装板",
"item.appliedenergistics2.fe_p2p_tunnel": "FE P2P通道",
"item.appliedenergistics2.fe_p2p_tunnel": "P2P通道-FE",
"item.appliedenergistics2.flour": "面粉",
"item.appliedenergistics2.fluid_annihilation_plane": "ME流体破坏面板",
"item.appliedenergistics2.16k_fluid_cell_component": "16k-ME流体存储组件",
@@ -488,43 +488,43 @@
"item.appliedenergistics2.fluid_formation_plane": "ME流体成型面板",
"item.appliedenergistics2.fluid_import_bus": "ME流体输入总线",
"item.appliedenergistics2.fluid_level_emitter": "ME流体标准发信器",
"item.appliedenergistics2.fluid_p2p_tunnel": "流体 P2P通道",
"item.appliedenergistics2.fluid_storage_bus": "ME流体存总线",
"item.appliedenergistics2.fluid_p2p_tunnel": "P2P通道-流体",
"item.appliedenergistics2.fluid_storage_bus": "ME流体存总线",
"item.appliedenergistics2.16k_fluid_storage_cell": "16k-ME流体储存元件",
"item.appliedenergistics2.1k_fluid_storage_cell": "1k-ME流体储存元件",
"item.appliedenergistics2.4k_fluid_storage_cell": "4k-ME流体储存元件",
"item.appliedenergistics2.64k_fluid_storage_cell": "64k-ME流体储存元件",
"item.appliedenergistics2.fluid_terminal": "ME流体终端",
"item.appliedenergistics2.fluix_covered_cable": "Fluix默认色 ME包层线缆",
"item.appliedenergistics2.fluix_covered_dense_cable": "Fluix默认色 ME致密包层线缆",
"item.appliedenergistics2.fluix_covered_cable": "ME包层线缆(Fluix默认色)",
"item.appliedenergistics2.fluix_covered_dense_cable": "ME致密包层线缆(Fluix默认色)",
"item.appliedenergistics2.fluix_crystal": "福鲁伊克斯水晶",
"item.appliedenergistics2.fluix_crystal_seed": "福鲁伊克斯种子",
"item.appliedenergistics2.fluix_dust": "福鲁伊克斯粉",
"item.appliedenergistics2.fluix_glass_cable": "Fluix默认色 ME玻璃线缆",
"item.appliedenergistics2.fluix_lumen_paint_ball": "Fluix默认色 光通 染色球",
"item.appliedenergistics2.fluix_paint_ball": "Fluix默认色 染色球",
"item.appliedenergistics2.fluix_glass_cable": "ME玻璃线缆(Fluix默认色)",
"item.appliedenergistics2.fluix_lumen_paint_ball": "光通染色球(Fluix默认色)",
"item.appliedenergistics2.fluix_paint_ball": "色球(Fluix默认色)",
"item.appliedenergistics2.fluix_pearl": "福鲁伊克斯珍珠",
"item.appliedenergistics2.fluix_smart_cable": "Fluix默认色 ME智能线缆",
"item.appliedenergistics2.fluix_smart_dense_cable": "Fluix默认色 ME致密线缆",
"item.appliedenergistics2.fluix_smart_cable": "ME智能线缆(Fluix默认色)",
"item.appliedenergistics2.fluix_smart_dense_cable": "ME致密线缆(Fluix默认色)",
"item.appliedenergistics2.formation_core": "成型核心",
"item.appliedenergistics2.formation_plane": "ME成型面板",
"item.appliedenergistics2.fuzzy_card": "模糊卡",
"item.appliedenergistics2.gold_dust": "金粉",
"item.appliedenergistics2.gray_covered_cable": "灰色 ME包层线缆",
"item.appliedenergistics2.gray_covered_dense_cable": "灰色 ME致密包层线缆",
"item.appliedenergistics2.gray_glass_cable": "灰色 ME玻璃线缆",
"item.appliedenergistics2.gray_lumen_paint_ball": "灰色 光通 染色球",
"item.appliedenergistics2.gray_paint_ball": "灰色 染色球",
"item.appliedenergistics2.gray_smart_cable": "灰色 ME智能线缆",
"item.appliedenergistics2.gray_smart_dense_cable": "灰色 ME致密线缆",
"item.appliedenergistics2.green_covered_cable": "绿色 ME包层线缆",
"item.appliedenergistics2.green_covered_dense_cable": "绿色 ME致密包层线缆",
"item.appliedenergistics2.green_glass_cable": "绿色 ME玻璃线缆",
"item.appliedenergistics2.green_lumen_paint_ball": "绿色 光通 染色球",
"item.appliedenergistics2.green_paint_ball": "绿色 染色球",
"item.appliedenergistics2.green_smart_cable": "绿色 ME智能线缆",
"item.appliedenergistics2.green_smart_dense_cable": "绿色 ME致密线缆",
"item.appliedenergistics2.ic2_p2p_tunnel": "EU P2P通道",
"item.appliedenergistics2.gray_covered_cable": "ME包层线缆(灰色)",
"item.appliedenergistics2.gray_covered_dense_cable": "ME致密包层线缆(灰色)",
"item.appliedenergistics2.gray_glass_cable": "ME玻璃线缆(灰色)",
"item.appliedenergistics2.gray_lumen_paint_ball": "光通染色球(灰色)",
"item.appliedenergistics2.gray_paint_ball": "染色球(灰色)",
"item.appliedenergistics2.gray_smart_cable": "ME智能线缆(灰色)",
"item.appliedenergistics2.gray_smart_dense_cable": "ME致密线缆(灰色)",
"item.appliedenergistics2.green_covered_cable": "ME包层线缆(绿色)",
"item.appliedenergistics2.green_covered_dense_cable": "ME致密包层线缆(绿色)",
"item.appliedenergistics2.green_glass_cable": "ME玻璃线缆(绿色)",
"item.appliedenergistics2.green_lumen_paint_ball": "光通染色球(绿色)",
"item.appliedenergistics2.green_paint_ball": "染色球(绿色)",
"item.appliedenergistics2.green_smart_cable": "ME智能线缆(绿色)",
"item.appliedenergistics2.green_smart_dense_cable": "ME致密线缆(绿色)",
"item.appliedenergistics2.ic2_p2p_tunnel": "P2P通道-EU",
"item.appliedenergistics2.identity_annihilation_plane": "ME精准破坏面板",
"item.appliedenergistics2.import_bus": "ME输入总线",
"item.appliedenergistics2.interface_terminal": "ME接口终端",
@@ -532,44 +532,44 @@
"item.appliedenergistics2.inverted_toggle_bus": "ME反相触发总线",
"item.appliedenergistics2.inverter_card": "反相卡",
"item.appliedenergistics2.iron_dust": "铁粉",
"item.appliedenergistics2.item_p2p_tunnel": "物品 P2P通道",
"item.appliedenergistics2.item_p2p_tunnel": "P2P通道-物品",
"item.appliedenergistics2.level_emitter": "ME标准发信器",
"item.appliedenergistics2.light_blue_covered_cable": "浅蓝色 ME包层线缆",
"item.appliedenergistics2.light_blue_covered_dense_cable": "浅蓝色 ME致密包层线缆",
"item.appliedenergistics2.light_blue_glass_cable": "浅蓝色 ME玻璃线缆",
"item.appliedenergistics2.light_blue_lumen_paint_ball": "浅蓝色 光通 染色球",
"item.appliedenergistics2.light_blue_paint_ball": "浅蓝色 染色球",
"item.appliedenergistics2.light_blue_smart_cable": "浅蓝色 ME智能线缆",
"item.appliedenergistics2.light_blue_smart_dense_cable": "浅蓝色 ME致密线缆",
"item.appliedenergistics2.light_gray_covered_cable": "浅灰色 ME包层线缆",
"item.appliedenergistics2.light_gray_covered_dense_cable": "浅灰色 ME致密包层线缆",
"item.appliedenergistics2.light_gray_glass_cable": "浅灰色 ME玻璃线缆",
"item.appliedenergistics2.light_gray_lumen_paint_ball": "浅灰色 光通 染色球",
"item.appliedenergistics2.light_gray_paint_ball": "浅灰色 染色球",
"item.appliedenergistics2.light_gray_smart_cable": "浅灰色 ME智能线缆",
"item.appliedenergistics2.light_gray_smart_dense_cable": "浅灰色 ME致密线缆",
"item.appliedenergistics2.light_p2p_tunnel": "P2P通道",
"item.appliedenergistics2.lime_covered_cable": "柠檬色 ME包层线缆",
"item.appliedenergistics2.lime_covered_dense_cable": "柠檬色 ME致密包层线缆",
"item.appliedenergistics2.lime_glass_cable": "柠檬色 ME玻璃线缆",
"item.appliedenergistics2.lime_lumen_paint_ball": "柠檬色 光通 染色球",
"item.appliedenergistics2.lime_paint_ball": "柠檬色 染色球",
"item.appliedenergistics2.lime_smart_cable": "柠檬色 ME智能线缆",
"item.appliedenergistics2.lime_smart_dense_cable": "柠檬色 ME致密线缆",
"item.appliedenergistics2.light_blue_covered_cable": "ME包层线缆(浅蓝色)",
"item.appliedenergistics2.light_blue_covered_dense_cable": "ME致密包层线缆(浅蓝色)",
"item.appliedenergistics2.light_blue_glass_cable": "ME玻璃线缆(浅蓝色)",
"item.appliedenergistics2.light_blue_lumen_paint_ball": "光通染色球(浅蓝色)",
"item.appliedenergistics2.light_blue_paint_ball": "染色球(浅蓝色)",
"item.appliedenergistics2.light_blue_smart_cable": "ME智能线缆(浅蓝色)",
"item.appliedenergistics2.light_blue_smart_dense_cable": "ME致密线缆(浅蓝色)",
"item.appliedenergistics2.light_gray_covered_cable": "ME包层线缆(浅灰色)",
"item.appliedenergistics2.light_gray_covered_dense_cable": "ME致密包层线缆(浅灰色)",
"item.appliedenergistics2.light_gray_glass_cable": "ME玻璃线缆(浅灰色)",
"item.appliedenergistics2.light_gray_lumen_paint_ball": "光通染色球(浅灰色)",
"item.appliedenergistics2.light_gray_paint_ball": "染色球(浅灰色)",
"item.appliedenergistics2.light_gray_smart_cable": "ME智能线缆(浅灰色)",
"item.appliedenergistics2.light_gray_smart_dense_cable": "ME致密线缆(浅灰色)",
"item.appliedenergistics2.light_p2p_tunnel": "P2P通道-光",
"item.appliedenergistics2.lime_covered_cable": "ME包层线缆(柠檬色)",
"item.appliedenergistics2.lime_covered_dense_cable": "ME致密包层线缆(柠檬色)",
"item.appliedenergistics2.lime_glass_cable": "ME玻璃线缆(柠檬色)",
"item.appliedenergistics2.lime_lumen_paint_ball": "光通染色球(柠檬色)",
"item.appliedenergistics2.lime_paint_ball": "染色球(柠檬色)",
"item.appliedenergistics2.lime_smart_cable": "ME智能线缆(柠檬色)",
"item.appliedenergistics2.lime_smart_dense_cable": "ME致密线缆(柠檬色)",
"item.appliedenergistics2.logic_processor": "逻辑处理器",
"item.appliedenergistics2.logic_processor_asm": "半成品-逻辑处理器",
"item.appliedenergistics2.logic_processor_press": "逻辑压印模板",
"item.appliedenergistics2.printed_logic_processor": "逻辑电路板",
"item.appliedenergistics2.magenta_covered_cable": "品红色 ME包层线缆",
"item.appliedenergistics2.magenta_covered_dense_cable": "品红色 ME致密包层线缆",
"item.appliedenergistics2.magenta_glass_cable": "品红色 ME玻璃线缆",
"item.appliedenergistics2.magenta_lumen_paint_ball": "品红色 光通 染色球",
"item.appliedenergistics2.magenta_paint_ball": "品红色 染色球",
"item.appliedenergistics2.magenta_smart_cable": "品红色 ME智能线缆",
"item.appliedenergistics2.magenta_smart_dense_cable": "品红色 ME致密线缆",
"item.appliedenergistics2.magenta_covered_cable": "ME包层线缆(品红色)",
"item.appliedenergistics2.magenta_covered_dense_cable": "ME致密包层线缆(品红色)",
"item.appliedenergistics2.magenta_glass_cable": "ME玻璃线缆(品红色)",
"item.appliedenergistics2.magenta_lumen_paint_ball": "光通染色球(品红色)",
"item.appliedenergistics2.magenta_paint_ball": "染色球(品红色)",
"item.appliedenergistics2.magenta_smart_cable": "ME智能线缆(品红色)",
"item.appliedenergistics2.magenta_smart_dense_cable": "ME致密线缆(品红色)",
"item.appliedenergistics2.matter_ball": "物质球",
"item.appliedenergistics2.matter_cannon": "物质炮",
"item.appliedenergistics2.me_p2p_tunnel": "ME P2P通道",
"item.appliedenergistics2.me_p2p_tunnel": "P2P通道-ME",
"item.appliedenergistics2.memory_card": "内存卡",
"item.appliedenergistics2.monitor": "亮色照明面板",
"item.appliedenergistics2.name_press": "名称压印模板",
@@ -583,43 +583,43 @@
"item.appliedenergistics2.nether_quartz_sword": "下界石英剑",
"item.appliedenergistics2.nether_quartz_wrench": "下界石英扳手",
"item.appliedenergistics2.network_tool": "网络工具",
"item.appliedenergistics2.orange_covered_cable": "橙色 ME包层线缆",
"item.appliedenergistics2.orange_covered_dense_cable": "橙色 ME致密包层线缆",
"item.appliedenergistics2.orange_glass_cable": "橙色 ME玻璃线缆",
"item.appliedenergistics2.orange_lumen_paint_ball": "橙色 光通 染色球",
"item.appliedenergistics2.orange_paint_ball": "橙色 染色球",
"item.appliedenergistics2.orange_smart_cable": "橙色 ME智能线缆",
"item.appliedenergistics2.orange_smart_dense_cable": "橙色 ME致密线缆",
"item.appliedenergistics2.orange_covered_cable": "ME包层线缆(橙色)",
"item.appliedenergistics2.orange_covered_dense_cable": "ME致密包层线缆(橙色)",
"item.appliedenergistics2.orange_glass_cable": "ME玻璃线缆(橙色)",
"item.appliedenergistics2.orange_lumen_paint_ball": "光通染色球(橙色)",
"item.appliedenergistics2.orange_paint_ball": "染色球(橙色)",
"item.appliedenergistics2.orange_smart_cable": "ME智能线缆(橙色)",
"item.appliedenergistics2.orange_smart_dense_cable": "ME致密线缆(橙色)",
"item.appliedenergistics2.pattern_terminal": "ME样板终端",
"item.appliedenergistics2.pink_covered_cable": "粉色 ME包层线缆",
"item.appliedenergistics2.pink_covered_dense_cable": "粉色 ME致密包层线缆",
"item.appliedenergistics2.pink_glass_cable": "粉色 ME玻璃线缆",
"item.appliedenergistics2.pink_lumen_paint_ball": "粉色 光通 染色球",
"item.appliedenergistics2.pink_paint_ball": "粉色 染色球",
"item.appliedenergistics2.pink_smart_cable": "粉色 ME智能线缆",
"item.appliedenergistics2.pink_smart_dense_cable": "粉色 ME致密线缆",
"item.appliedenergistics2.pink_covered_cable": "ME包层线缆(粉色)",
"item.appliedenergistics2.pink_covered_dense_cable": "ME致密包层线缆(粉色)",
"item.appliedenergistics2.pink_glass_cable": "ME玻璃线缆(粉色)",
"item.appliedenergistics2.pink_lumen_paint_ball": "光通染色球(粉色)",
"item.appliedenergistics2.pink_paint_ball": "染色球(粉色)",
"item.appliedenergistics2.pink_smart_cable": "ME智能线缆(粉色)",
"item.appliedenergistics2.pink_smart_dense_cable": "ME致密线缆(粉色)",
"item.appliedenergistics2.portable_cell": "便携元件",
"item.appliedenergistics2.purified_certus_quartz_crystal": "高纯赛特斯石英水晶",
"item.appliedenergistics2.purified_fluix_crystal": "高纯福鲁伊克斯水晶",
"item.appliedenergistics2.purified_nether_quartz_crystal": "高纯下界石英水晶",
"item.appliedenergistics2.purple_covered_cable": "紫色 ME包层线缆",
"item.appliedenergistics2.purple_covered_dense_cable": "紫色 ME致密包层线缆",
"item.appliedenergistics2.purple_glass_cable": "紫色 ME玻璃线缆",
"item.appliedenergistics2.purple_lumen_paint_ball": "紫色 光通 染色球",
"item.appliedenergistics2.purple_paint_ball": "紫色 染色球",
"item.appliedenergistics2.purple_smart_cable": "紫色 ME智能线缆",
"item.appliedenergistics2.purple_smart_dense_cable": "紫色 ME致密线缆",
"item.appliedenergistics2.purple_covered_cable": "ME包层线缆(紫色)",
"item.appliedenergistics2.purple_covered_dense_cable": "ME致密包层线缆(紫色)",
"item.appliedenergistics2.purple_glass_cable": "ME玻璃线缆(紫色)",
"item.appliedenergistics2.purple_lumen_paint_ball": "光通染色球(紫色)",
"item.appliedenergistics2.purple_paint_ball": "染色球(紫色)",
"item.appliedenergistics2.purple_smart_cable": "ME智能线缆(紫色)",
"item.appliedenergistics2.purple_smart_dense_cable": "ME致密线缆(紫色)",
"item.appliedenergistics2.quantum_entangled_singularity": "量子缠绕态奇点",
"item.appliedenergistics2.quartz_fiber": "石英纤维",
"item.appliedenergistics2.red_covered_cable": "红色 ME包层线缆",
"item.appliedenergistics2.red_covered_dense_cable": "红色 ME致密包层线缆",
"item.appliedenergistics2.red_glass_cable": "红色 ME玻璃线缆",
"item.appliedenergistics2.red_lumen_paint_ball": "红色 光通 染色球",
"item.appliedenergistics2.red_paint_ball": "红色 染色球",
"item.appliedenergistics2.red_smart_cable": "红色 ME智能线缆",
"item.appliedenergistics2.red_smart_dense_cable": "红色 ME致密线缆",
"item.appliedenergistics2.red_covered_cable": "ME包层线缆(红色)",
"item.appliedenergistics2.red_covered_dense_cable": "ME致密包层线缆(红色)",
"item.appliedenergistics2.red_glass_cable": "ME玻璃线缆(红色)",
"item.appliedenergistics2.red_lumen_paint_ball": "光通染色球(红色)",
"item.appliedenergistics2.red_paint_ball": "染色球(红色)",
"item.appliedenergistics2.red_smart_cable": "ME智能线缆(红色)",
"item.appliedenergistics2.red_smart_dense_cable": "ME致密线缆(红色)",
"item.appliedenergistics2.redstone_card": "红石卡",
"item.appliedenergistics2.redstone_p2p_tunnel": "红石 P2P通道",
"item.appliedenergistics2.redstone_p2p_tunnel": "P2P通道-红石",
"item.appliedenergistics2.semi_dark_monitor": "照明面板",
"item.appliedenergistics2.silicon": "硅",
"item.appliedenergistics2.silicon_press": "硅压印模板",
@@ -642,24 +642,24 @@
"item.appliedenergistics2.terminal": "ME终端",
"item.appliedenergistics2.toggle_bus": "ME触发总线",
"item.appliedenergistics2.view_cell": "显示元件",
"item.appliedenergistics2.white_covered_cable": "白色 ME包层线缆",
"item.appliedenergistics2.white_covered_dense_cable": "白色 ME致密包层线缆",
"item.appliedenergistics2.white_glass_cable": "白色 ME玻璃线缆",
"item.appliedenergistics2.white_lumen_paint_ball": "白色 光通 染色球",
"item.appliedenergistics2.white_paint_ball": "白色 染色球",
"item.appliedenergistics2.white_smart_cable": "白色 ME智能线缆",
"item.appliedenergistics2.white_smart_dense_cable": "白色 ME致密线缆",
"item.appliedenergistics2.white_covered_cable": "ME包层线缆(白色)",
"item.appliedenergistics2.white_covered_dense_cable": "ME致密包层线缆(白色)",
"item.appliedenergistics2.white_glass_cable": "ME玻璃线缆(白色)",
"item.appliedenergistics2.white_lumen_paint_ball": "光通染色球(白色)",
"item.appliedenergistics2.white_paint_ball": "染色球(白色)",
"item.appliedenergistics2.white_smart_cable": "ME智能线缆(白色)",
"item.appliedenergistics2.white_smart_dense_cable": "ME致密线缆(白色)",
"item.appliedenergistics2.wireless_booster": "无线信号增幅器",
"item.appliedenergistics2.wireless_receiver": "无线接收器",
"item.appliedenergistics2.wireless_terminal": "无线终端",
"item.appliedenergistics2.wooden_gear": "木齿轮",
"item.appliedenergistics2.yellow_covered_cable": "黄色 ME包层线缆",
"item.appliedenergistics2.yellow_covered_dense_cable": "黄色 ME致密包层线缆",
"item.appliedenergistics2.yellow_glass_cable": "黄色 ME玻璃线缆",
"item.appliedenergistics2.yellow_lumen_paint_ball": "黄色 光通 染色球",
"item.appliedenergistics2.yellow_paint_ball": "黄色 染色球",
"item.appliedenergistics2.yellow_smart_cable": "黄色 ME智能线缆",
"item.appliedenergistics2.yellow_smart_dense_cable": "黄色 ME致密线缆",
"item.appliedenergistics2.yellow_covered_cable": "ME包层线缆(黄色)",
"item.appliedenergistics2.yellow_covered_dense_cable": "ME致密包层线缆(黄色)",
"item.appliedenergistics2.yellow_glass_cable": "ME玻璃线缆(黄色)",
"item.appliedenergistics2.yellow_lumen_paint_ball": "光通染色球(黄色)",
"item.appliedenergistics2.yellow_paint_ball": "染色球(黄色)",
"item.appliedenergistics2.yellow_smart_cable": "ME智能线缆(黄色)",
"item.appliedenergistics2.yellow_smart_dense_cable": "ME致密线缆(黄色)",
"itemGroup.appliedenergistics2": "应用能源2",
"itemGroup.appliedenergistics2.facades": "应用能源2-伪装板",
"key.appliedenergistics2.category": "Applied Energistics 2",