Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e41d543f5 | |||
| 81cc0b804d | |||
| e1fc9908b3 | |||
| 9ed1535477 | |||
| 1ef345d4a4 | |||
| ff7d1b9719 | |||
| 88c9370e4f | |||
| f2aae3ef0f | |||
| 12739f1e66 | |||
| 81d2170ada | |||
| 0f469e9df6 | |||
| 0f34f09b32 | |||
| 8e54a8fed9 | |||
| d9bb81a00f | |||
| 39e038d916 | |||
| 12ca8d109a | |||
| f0d0595c8f | |||
| b756d68be1 | |||
| 60b07e5ca5 | |||
| 7c99fca789 | |||
| ab393b0ed1 | |||
| 957bc4c5cc | |||
| 133ed1f09d | |||
| e90dd2f9c6 | |||
| 9719c7ffc3 | |||
| 319d92a371 | |||
| db9ec2b070 | |||
| 3a0552c56e | |||
| 8a0dd192e5 | |||
| a97b35f3d0 | |||
| 00d4c20d9f | |||
| 1394ab0863 | |||
| 5efc085693 | |||
| 159f4c7f14 | |||
| aff94cec8c | |||
| ee7fe9f40d | |||
| 2184d03d0b |
@@ -72,12 +72,20 @@ 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'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -190,6 +190,13 @@ publishing {
|
||||
groupId = project.group
|
||||
artifactId = project.archivesBaseName
|
||||
version = project.version
|
||||
|
||||
// ForgeGradle will generate wild dependency definitions, see https://github.com/MinecraftForge/ForgeGradle/issues/584
|
||||
// Since we don't actually depend on anything, just remove the entire node.
|
||||
pom.withXml {
|
||||
asNode().remove(asNode().dependencies)
|
||||
}
|
||||
|
||||
from components.java
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ artifact_basename=appliedenergistics2
|
||||
minecraft_release=1.16
|
||||
minecraft_version=1.16.2
|
||||
mcp_mappings=20200723-1.16.1
|
||||
forge_version=33.0.5
|
||||
forge_version=33.0.42
|
||||
|
||||
#########################################################
|
||||
# Provided APIs #
|
||||
|
||||
@@ -23,13 +23,23 @@
|
||||
|
||||
package appeng.api.implementations.items;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IGrowableCrystal {
|
||||
|
||||
ItemStack triggerGrowth(ItemStack is);
|
||||
|
||||
float getMultiplier(Block blk, Material mat);
|
||||
/**
|
||||
* Gets the crystal growth multiplier based on the material it is submerged in.
|
||||
*
|
||||
* @param state The blockstate of the block the crystal is currently in.
|
||||
* @return The multiplier for the growth tick progress. Zero if the crystal
|
||||
* cannot grow in the current material.
|
||||
*/
|
||||
float getMultiplier(BlockState state, @Nullable World world, @Nullable BlockPos pos);
|
||||
}
|
||||
|
||||
@@ -8,19 +8,18 @@ import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* rendering.
|
||||
*/
|
||||
class Size1Slot extends SlotItemHandler {
|
||||
class Size1Slot extends Slot {
|
||||
|
||||
private final SlotItemHandler delegate;
|
||||
private final Slot delegate;
|
||||
|
||||
public Size1Slot(SlotItemHandler delegate) {
|
||||
super(delegate.getItemHandler(), delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
|
||||
public Size1Slot(Slot delegate) {
|
||||
super(delegate.inventory, delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,9 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
this.searchField.setMaxStringLength(25);
|
||||
this.searchField.setTextColor(0xFFFFFF);
|
||||
this.searchField.setVisible(true);
|
||||
this.searchField.setFocused2(true);
|
||||
this.searchField.setResponder(str -> this.refreshList());
|
||||
this.addListener(this.searchField);
|
||||
this.changeFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,11 +133,8 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
|
||||
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
|
||||
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
|
||||
this.searchField.setText("");
|
||||
this.refreshList();
|
||||
}
|
||||
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
|
||||
this.searchField.setText("");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -173,11 +172,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
if (character == ' ' && this.searchField.getText().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (this.searchField.charTyped(character, key)) {
|
||||
this.refreshList();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return super.charTyped(character, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,7 +240,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
/**
|
||||
* Rebuilds the list of interfaces.
|
||||
*
|
||||
* <p>
|
||||
* Respects a search term if present (ignores case) and adding only matching
|
||||
* patterns.
|
||||
*/
|
||||
@@ -338,12 +333,11 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
/**
|
||||
* Tries to retrieve a cache for a with search term as keyword.
|
||||
*
|
||||
* <p>
|
||||
* If this cache should be empty, it will populate it with an earlier cache if
|
||||
* available or at least the cache for the empty string.
|
||||
*
|
||||
* @param searchTerm the corresponding search
|
||||
*
|
||||
* @return a Set matching a superset of the search term
|
||||
*/
|
||||
private Set<Object> getCacheForSearchTerm(final String searchTerm) {
|
||||
|
||||
@@ -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.IInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
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 SlotItemHandler implements IMEFluidSlot {
|
||||
public class SlotFluidME extends Slot implements IMEFluidSlot {
|
||||
|
||||
private InternalFluidSlotME slot;
|
||||
private static final IInventory EMPTY_INVENTORY = new Inventory(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;
|
||||
}
|
||||
|
||||
@@ -50,7 +49,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(final ItemStack par1ItemStack) {
|
||||
public boolean isItemValid(final ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -69,7 +68,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStack(final ItemStack par1ItemStack) {
|
||||
public void putStack(final ItemStack stack) {
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
|
||||
public boolean canTakeStack(final PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,23 +19,27 @@
|
||||
package appeng.client.me;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
|
||||
public class SlotME extends SlotItemHandler {
|
||||
public class SlotME extends Slot {
|
||||
|
||||
private final InternalSlotME mySlot;
|
||||
private static final IInventory EMPTY_INVENTORY = new Inventory(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 SlotItemHandler {
|
||||
|
||||
@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 getHasStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
if (this.slot.hasPower()) {
|
||||
return !this.getStack().isEmpty();
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -21,7 +21,6 @@ package appeng.client.render.cablebus;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -30,6 +29,11 @@ import java.util.Random;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.cache.Weigher;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
@@ -50,7 +54,10 @@ import appeng.api.util.AEColor;
|
||||
|
||||
public class CableBusBakedModel implements IBakedModel {
|
||||
|
||||
private static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
|
||||
// The number of quads overall that will be cached
|
||||
private static final int CACHE_QUAD_COUNT = 5000;
|
||||
|
||||
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
|
||||
|
||||
private final CableBuilder cableBuilder;
|
||||
|
||||
@@ -66,6 +73,17 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
this.facadeBuilder = facadeBuilder;
|
||||
this.partModels = partModels;
|
||||
this.particleTexture = particleTexture;
|
||||
this.cableModelCache = CacheBuilder.newBuilder()//
|
||||
.maximumWeight(CACHE_QUAD_COUNT)//
|
||||
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (key, value) -> value.size())//
|
||||
.build(new CacheLoader<CableBusRenderState, List<BakedQuad>>() {
|
||||
@Override
|
||||
public List<BakedQuad> load(CableBusRenderState renderState) {
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
addCableQuads(renderState, model);
|
||||
return model;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,11 +110,7 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
if (layer == RenderType.getCutout()) {
|
||||
|
||||
// First, handle the cable at the center of the cable bus
|
||||
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, k -> {
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
this.addCableQuads(renderState, model);
|
||||
return model;
|
||||
});
|
||||
final List<BakedQuad> cableModel = cableModelCache.getUnchecked(renderState);
|
||||
quads.addAll(cableModel);
|
||||
|
||||
// Then handle attachments
|
||||
@@ -341,8 +355,4 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
CABLE_MODEL_CACHE.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ public class CableBusModelLoader implements IModelLoader<CableBusModel> {
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager) {
|
||||
CableBusBakedModel.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,7 +42,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;
|
||||
@@ -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
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.Set;
|
||||
import java.util.function.DoubleSupplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -393,6 +395,15 @@ public final class AEConfig {
|
||||
return this.meteoriteDimensionWhitelist;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getImprovedFluidTag() {
|
||||
return Strings.emptyToNull(COMMON.improvedFluidTag.get());
|
||||
}
|
||||
|
||||
public float getImprovedFluidMultiplier() {
|
||||
return COMMON.improvedFluidMultiplier.get().floatValue();
|
||||
}
|
||||
|
||||
// Setters keep visibility as low as possible.
|
||||
|
||||
private static class ClientConfig {
|
||||
@@ -507,6 +518,11 @@ public final class AEConfig {
|
||||
public final ConfigValue<Integer> condenserMatterBallsPower;
|
||||
public final ConfigValue<Integer> condenserSingularityPower;
|
||||
|
||||
// In-World Purification
|
||||
// Settings for improved speed depending on fluid the crystal is in
|
||||
public final ConfigValue<String> improvedFluidTag;
|
||||
public final ConfigValue<Double> improvedFluidMultiplier;
|
||||
|
||||
public final Map<TickRates, ConfigValue<Integer>> tickRateMin = new HashMap<>();
|
||||
public final Map<TickRates, ConfigValue<Integer>> tickRateMax = new HashMap<>();
|
||||
|
||||
@@ -617,6 +633,17 @@ public final class AEConfig {
|
||||
tickRateMax.put(tickRate, builder.define(tickRate.name() + "Max", tickRate.getDefaultMax()));
|
||||
}
|
||||
builder.pop();
|
||||
|
||||
builder.comment("Settings for in-world purification of crystals.").push("inWorldPurification");
|
||||
|
||||
improvedFluidTag = builder.comment(
|
||||
"A fluid tag that identifies fluids that improve crystal purification speed. Does not affect purification with water/lava.")
|
||||
.define("improvedFluidTag", "");
|
||||
improvedFluidMultiplier = builder
|
||||
.comment("The speed multiplier to use when the crystals are submerged in the improved fluid.")
|
||||
.defineInRange("improvedFluidMultiplier", 2.0, 1.0, 10.0);
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,9 @@ package appeng.core.api.definitions;
|
||||
|
||||
import static appeng.block.AEBaseBlock.defaultProps;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.DispenserBlock;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.block.SoundType;
|
||||
@@ -28,6 +30,7 @@ import net.minecraft.block.StairsBlock;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
@@ -262,18 +265,20 @@ public final class ApiBlocks implements IBlocks {
|
||||
this.chiseledQuartzBlock = deco.block("chiseled_quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES))
|
||||
.build();
|
||||
|
||||
this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS)
|
||||
.block("quartz_glass", () -> new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid()))
|
||||
.rendering(new BlockRenderingCustomizer() {
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderType.getCutout());
|
||||
}
|
||||
}).build();
|
||||
AbstractBlock.IExtendedPositionPredicate<EntityType<?>> neverAllowSpawn = (p1, p2, p3, p4) -> false;
|
||||
this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS).block("quartz_glass", () -> {
|
||||
return new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid().setAllowsSpawn(neverAllowSpawn));
|
||||
}).rendering(new BlockRenderingCustomizer() {
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderType.getCutout());
|
||||
}
|
||||
}).build();
|
||||
this.quartzVibrantGlass = deco
|
||||
.block("quartz_vibrant_glass",
|
||||
() -> new QuartzLampBlock(defaultProps(Material.GLASS).setLightLevel(b -> 15).notSolid()))
|
||||
() -> new QuartzLampBlock(defaultProps(Material.GLASS).setLightLevel(b -> 15).notSolid()
|
||||
.setAllowsSpawn(neverAllowSpawn)))
|
||||
.addFeatures(AEFeature.DECORATIVE_LIGHTS, AEFeature.QUARTZ_GLASS)
|
||||
.rendering(new BlockRenderingCustomizer() {
|
||||
@Override
|
||||
|
||||
@@ -22,12 +22,12 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
import appeng.api.events.LocatableEventAnnounce;
|
||||
import appeng.api.events.LocatableEventAnnounce.LocatableEvent;
|
||||
import appeng.api.features.ILocatable;
|
||||
import appeng.api.features.ILocatableRegistry;
|
||||
import appeng.core.AELog;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public final class LocatableRegistry implements ILocatableRegistry {
|
||||
@@ -35,18 +35,19 @@ public final class LocatableRegistry implements ILocatableRegistry {
|
||||
|
||||
public LocatableRegistry() {
|
||||
this.set = new HashMap<>();
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::updateLocatable);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void updateLocatable(final LocatableEventAnnounce e) {
|
||||
private void updateLocatable(final LocatableEventAnnounce e) {
|
||||
if (Platform.isClient()) {
|
||||
return; // IGNORE!
|
||||
}
|
||||
|
||||
if (e.change == LocatableEvent.REGISTER) {
|
||||
AELog.debug("Registering locatable %s: %s", e.target.getLocatableSerial(), e.target);
|
||||
this.set.put(e.target.getLocatableSerial(), e.target);
|
||||
} else if (e.change == LocatableEvent.UNREGISTER) {
|
||||
AELog.debug("Unregistering locatable %s: %s", e.target.getLocatableSerial(), e.target);
|
||||
this.set.remove(e.target.getLocatableSerial());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.MockExplosionPacket;
|
||||
@@ -101,7 +101,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.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.network.NetworkDirection;
|
||||
|
||||
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 PacketBuffer data;
|
||||
@Nullable
|
||||
private final GZIPOutputStream compressFrame;
|
||||
|
||||
private int writtenBytes = 0;
|
||||
private boolean empty = true;
|
||||
|
||||
public MEFluidInventoryUpdatePacket(final PacketBuffer 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 PacketBuffer uncompressed = new PacketBuffer(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 PacketBuffer(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 IPacket<?> toPacket(NetworkDirection 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 PacketBuffer tmp = new PacketBuffer(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;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-44
@@ -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;
|
||||
|
||||
@@ -32,7 +26,6 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
@@ -41,55 +34,24 @@ 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 CompoundNBT in;
|
||||
// output...
|
||||
private final PacketBuffer data;
|
||||
private final GZIPOutputStream compressFrame;
|
||||
|
||||
public CompressedNBTPacket(final PacketBuffer stream) {
|
||||
public MEInterfaceUpdatePacket(final PacketBuffer 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 = CompressedStreamTools.read(inStream);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to decompress packet.", e);
|
||||
}
|
||||
this.in = stream.readCompoundTag();
|
||||
}
|
||||
|
||||
// api
|
||||
public CompressedNBTPacket(final CompoundNBT din) throws IOException {
|
||||
|
||||
public MEInterfaceUpdatePacket(final CompoundNBT din) throws IOException {
|
||||
this.in = null;
|
||||
this.data = new PacketBuffer(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);
|
||||
}
|
||||
});
|
||||
|
||||
CompressedStreamTools.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 PacketBuffer data;
|
||||
@Nullable
|
||||
private final GZIPOutputStream compressFrame;
|
||||
|
||||
private int writtenBytes = 0;
|
||||
private boolean empty = true;
|
||||
|
||||
public MEInventoryUpdatePacket(final PacketBuffer 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 PacketBuffer uncompressed = new PacketBuffer(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 PacketBuffer(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 IPacket<?> toPacket(NetworkDirection 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 PacketBuffer tmp = new PacketBuffer(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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.loot.RandomValueRange;
|
||||
import net.minecraft.loot.conditions.SurvivesExplosion;
|
||||
import net.minecraft.loot.functions.ApplyBonus;
|
||||
import net.minecraft.loot.functions.SetCount;
|
||||
import net.minecraft.util.RegistryKey;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
@@ -62,12 +63,13 @@ public class BlockDropProvider extends BlockLootTables implements IAE2DataProvid
|
||||
|
||||
@Override
|
||||
public void act(@Nonnull DirectoryCache cache) throws IOException {
|
||||
for (Map.Entry<ResourceLocation, Block> entry : ForgeRegistries.BLOCKS.getEntries()) {
|
||||
for (Map.Entry<RegistryKey<Block>, Block> entry : ForgeRegistries.BLOCKS.getEntries()) {
|
||||
LootTable.Builder builder;
|
||||
if (entry.getKey().getNamespace().equals(AppEng.MOD_ID)) {
|
||||
if (entry.getKey().func_240901_a_().getNamespace().equals(AppEng.MOD_ID)) {
|
||||
builder = overrides.getOrDefault(entry.getValue(), this::defaultBuilder).apply(entry.getValue());
|
||||
|
||||
IDataProvider.save(GSON, cache, toJson(builder), getPath(outputFolder, entry.getKey()));
|
||||
IDataProvider.save(GSON, cache, toJson(builder),
|
||||
getPath(outputFolder, entry.getKey().func_240901_a_()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,8 @@ package appeng.decorative.solid;
|
||||
|
||||
import net.minecraft.block.AbstractGlassBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
import appeng.helpers.AEMaterials;
|
||||
|
||||
public class QuartzGlassBlock extends AbstractGlassBlock {
|
||||
|
||||
public QuartzGlassBlock(Properties props) {
|
||||
@@ -33,8 +30,7 @@ public class QuartzGlassBlock extends AbstractGlassBlock {
|
||||
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) {
|
||||
final Material mat = adjacentBlockState.getMaterial();
|
||||
if (mat == Material.GLASS || mat == AEMaterials.GLASS) {
|
||||
if (adjacentBlockState.getBlock() instanceof QuartzGlassBlock) {
|
||||
if (adjacentBlockState.getRenderType() == state.getRenderType()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
|
||||
import appeng.block.AEBaseBlock;
|
||||
import appeng.core.worlddata.WorldData;
|
||||
@@ -43,11 +42,10 @@ public class SkyStoneBlock extends AEBaseBlock {
|
||||
super(props);
|
||||
this.type = type;
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::breakFaster);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void breakFaster(final PlayerEvent.BreakSpeed event) {
|
||||
private void breakFaster(final PlayerEvent.BreakSpeed event) {
|
||||
if (event.getState().getBlock() == this && event.getPlayer() != null) {
|
||||
final ItemStack is = event.getPlayer().getItemStackFromSlot(EquipmentSlotType.MAINHAND);
|
||||
int level = -1;
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
package appeng.entity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
@@ -35,12 +36,27 @@ import appeng.client.EffectType;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.items.misc.CrystalSeedItem;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public final class GrowingCrystalEntity extends AEBaseItemEntity {
|
||||
|
||||
public static EntityType<GrowingCrystalEntity> TYPE;
|
||||
|
||||
// Growth tick progress per tick by number of adjacent accelerators
|
||||
// Expressed as 1/1000th of a growth tick, applied to progress_1000
|
||||
// each time this entity ticks.
|
||||
private static final int[] GROWTH_TICK_PROGRESS = { 1, // no accelerators
|
||||
40, // 1 accelerator
|
||||
92, // 2 accelerators
|
||||
159, // 3 accelerators
|
||||
247, // 4 accelerators
|
||||
361, // 5 accelerators
|
||||
509 // 6 accelerators
|
||||
};
|
||||
|
||||
/**
|
||||
* The accumulated progress towards a single growth tick of the crystal in
|
||||
* 1/1000th of a growth tick.
|
||||
*/
|
||||
private int progress_1000 = 0;
|
||||
|
||||
public GrowingCrystalEntity(EntityType<? extends GrowingCrystalEntity> type, World world) {
|
||||
@@ -56,126 +72,140 @@ public final class GrowingCrystalEntity extends AEBaseItemEntity {
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
final ItemStack is = this.getItem();
|
||||
final Item gc = is.getItem();
|
||||
|
||||
if (!(gc instanceof IGrowableCrystal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
applyGrowthTick((IGrowableCrystal) gc, is);
|
||||
}
|
||||
|
||||
private void applyGrowthTick(IGrowableCrystal cry, ItemStack is) {
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.IN_WORLD_PURIFICATION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ItemStack is = this.getItem();
|
||||
final Item gc = is.getItem();
|
||||
final int x = MathHelper.floor(this.getPosX());
|
||||
final int y = MathHelper.floor((this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D);
|
||||
final int z = MathHelper.floor(this.getPosZ());
|
||||
|
||||
if (gc instanceof IGrowableCrystal) // if it changes this just stops being an issue...
|
||||
{
|
||||
final int j = MathHelper.floor(this.getPosX());
|
||||
final int i = MathHelper.floor((this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0D);
|
||||
final int k = MathHelper.floor(this.getPosZ());
|
||||
BlockPos pos = new BlockPos(x, y, z);
|
||||
final BlockState state = this.world.getBlockState(pos);
|
||||
|
||||
final BlockState state = this.world.getBlockState(new BlockPos(j, i, k));
|
||||
final Material mat = state.getMaterial();
|
||||
final IGrowableCrystal cry = (IGrowableCrystal) is.getItem();
|
||||
final float multiplier = cry.getMultiplier(state, world, pos);
|
||||
|
||||
final float multiplier = cry.getMultiplier(state.getBlock(), mat);
|
||||
final int speed = (int) Math.max(1, this.getSpeed(j, i, k) * multiplier);
|
||||
if (multiplier <= 0) {
|
||||
// Crystal is in unsuitable material, reset progress and quit
|
||||
this.progress_1000 = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean isClient = Platform.isClient();
|
||||
final int progressPerTick = (int) Math.max(1, this.getSpeed(pos) * multiplier);
|
||||
|
||||
if (mat.isLiquid()) {
|
||||
if (isClient) {
|
||||
this.progress_1000++;
|
||||
} else {
|
||||
this.progress_1000 += speed;
|
||||
}
|
||||
} else {
|
||||
if (world.isRemote()) {
|
||||
// On the client, we reuse the growth-tick-progress
|
||||
// as a tick-counter for particle effects
|
||||
int len = getTicksBetweenParticleEffects(progressPerTick);
|
||||
if (++this.progress_1000 >= len) {
|
||||
this.progress_1000 = 0;
|
||||
AppEng.proxy.spawnEffect(EffectType.Vibrant, this.world, this.getPosX(), this.getPosY() + 0.2,
|
||||
this.getPosZ(), null);
|
||||
}
|
||||
} else {
|
||||
this.progress_1000 += progressPerTick;
|
||||
|
||||
if (isClient) {
|
||||
int len = 40;
|
||||
if (this.progress_1000 >= 1000) {
|
||||
// We need to copy the stack or the change detection will not work and not sync
|
||||
// this new stack to the client
|
||||
ItemStack newItem = is.copy();
|
||||
|
||||
if (speed > 2) {
|
||||
len = 20;
|
||||
}
|
||||
|
||||
if (speed > 90) {
|
||||
len = 15;
|
||||
}
|
||||
|
||||
if (speed > 150) {
|
||||
len = 10;
|
||||
}
|
||||
|
||||
if (speed > 240) {
|
||||
len = 7;
|
||||
}
|
||||
|
||||
if (speed > 360) {
|
||||
len = 3;
|
||||
}
|
||||
|
||||
if (speed > 500) {
|
||||
len = 1;
|
||||
}
|
||||
|
||||
if (this.progress_1000 >= len) {
|
||||
this.progress_1000 = 0;
|
||||
AppEng.proxy.spawnEffect(EffectType.Vibrant, this.world, this.getPosX(), this.getPosY() + 0.2,
|
||||
this.getPosZ(), null);
|
||||
}
|
||||
} else {
|
||||
if (this.progress_1000 > 1000) {
|
||||
// If we did not use a while loop here, the fastest growth for a crystal
|
||||
// would be limited to a minimum of 30 seconds (based on 600 required growth
|
||||
// ticks).
|
||||
// Should a crystal decide to use a high multiplier for a certain material,
|
||||
// it should be possible to go faster.
|
||||
do {
|
||||
newItem = cry.triggerGrowth(newItem);
|
||||
this.progress_1000 -= 1000;
|
||||
// We need to copy the stack or the change detection will not work and not sync
|
||||
// this new stack to the client
|
||||
ItemStack newItem = cry.triggerGrowth(is.copy());
|
||||
this.setItem(newItem);
|
||||
}
|
||||
// We assume that if the item changes, the process is complete and we can break
|
||||
} while (this.progress_1000 >= 1000 && newItem.getItem() == is.getItem());
|
||||
|
||||
this.setItem(newItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getSpeed(final int x, final int y, final int z) {
|
||||
final int per = 80;
|
||||
final float mul = 0.3f;
|
||||
|
||||
int qty = 0;
|
||||
|
||||
if (this.isAccelerated(x + 1, y, z)) {
|
||||
qty += per + qty * mul;
|
||||
private static int getTicksBetweenParticleEffects(int progressPerTick) {
|
||||
if (progressPerTick > 500) {
|
||||
return 1; // 20 times per second
|
||||
} else if (progressPerTick > 360) {
|
||||
return 3;
|
||||
} else if (progressPerTick > 240) {
|
||||
return 7;
|
||||
} else if (progressPerTick > 150) {
|
||||
return 10;
|
||||
} else if (progressPerTick > 90) {
|
||||
return 15;
|
||||
} else if (progressPerTick > 2) {
|
||||
return 20;
|
||||
} else {
|
||||
return 40; // Every 2 seconds
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y + 1, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y, z + 1)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x - 1, y, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y - 1, z)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
if (this.isAccelerated(x, y, z - 1)) {
|
||||
qty += per + qty * mul;
|
||||
}
|
||||
|
||||
return qty;
|
||||
}
|
||||
|
||||
private boolean isAccelerated(final int x, final int y, final int z) {
|
||||
final TileEntity te = this.world.getTileEntity(new BlockPos(x, y, z));
|
||||
/**
|
||||
* Gets the extra progress per tick in 1/1000th of a growth tick based on the
|
||||
* surrounding accelerators.
|
||||
*/
|
||||
private int getSpeed(BlockPos pos) {
|
||||
int acceleratorCount = getAcceleratorCount(pos);
|
||||
|
||||
if (acceleratorCount < 0) {
|
||||
return GROWTH_TICK_PROGRESS[0];
|
||||
} else if (acceleratorCount >= GROWTH_TICK_PROGRESS.length) {
|
||||
return GROWTH_TICK_PROGRESS[GROWTH_TICK_PROGRESS.length - 1];
|
||||
} else {
|
||||
return GROWTH_TICK_PROGRESS[acceleratorCount];
|
||||
}
|
||||
}
|
||||
|
||||
private int getAcceleratorCount(BlockPos pos) {
|
||||
int count = 0;
|
||||
|
||||
BlockPos.Mutable testPos = new BlockPos.Mutable();
|
||||
for (Direction direction : Direction.values()) {
|
||||
if (this.isPoweredAccelerator(testPos.func_239622_a_(pos, direction))) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
private boolean isPoweredAccelerator(BlockPos pos) {
|
||||
final TileEntity te = this.world.getTileEntity(pos);
|
||||
|
||||
return te instanceof ICrystalGrowthAccelerator && ((ICrystalGrowthAccelerator) te).isPowered();
|
||||
}
|
||||
|
||||
// Don't let seeds "float" on water surface
|
||||
@Override
|
||||
protected void applyFloatMotion() {
|
||||
ItemStack item = getItem();
|
||||
|
||||
// Make ungrown seeds sink, and fully grown seeds bouyant allowing for
|
||||
// automation based around dropping seeds between 5 CGAs, then catchiung
|
||||
// them on their way up.
|
||||
if (item.getItem() instanceof CrystalSeedItem) {
|
||||
Vector3d v = this.getMotion();
|
||||
|
||||
// Apply a much smaller acceleration to make them slowly sink
|
||||
double yAccel = this.hasNoGravity() ? 0 : -0.002;
|
||||
|
||||
// Apply the x/z slow-down, and the y acceleration
|
||||
this.setMotion(v.x * 0.99, v.y + yAccel, v.z * 0.99);
|
||||
|
||||
return;
|
||||
}
|
||||
super.applyFloatMotion();
|
||||
|
||||
@@ -37,15 +37,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;
|
||||
@@ -56,6 +59,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();
|
||||
}
|
||||
@@ -84,6 +88,7 @@ public class FacadeContainer implements IFacadeContainer {
|
||||
for (int x = 0; x < this.facades; x++) {
|
||||
this.storage.setFacade(x, newFacades[x]);
|
||||
}
|
||||
this.notifyChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,4 +180,9 @@ public class FacadeContainer implements IFacadeContainer {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void notifyChange() {
|
||||
this.changeCallback.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package appeng.fluids.client.gui.widgets;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
@@ -73,7 +74,7 @@ public class FluidSlotWidget extends CustomSlotWidget {
|
||||
if (clickStack.isEmpty() || mouseButton == 1) {
|
||||
this.setFluidStack(null);
|
||||
} else if (mouseButton == 0) {
|
||||
final LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(clickStack);
|
||||
final Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(clickStack);
|
||||
fluidOpt.ifPresent(fluid -> {
|
||||
this.setFluidStack(AEFluidStack.fromFluidStack(fluid));
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ package appeng.fluids.container;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
@@ -39,7 +40,7 @@ public abstract class FluidConfigurableContainer extends UpgradeableContainer im
|
||||
|
||||
@Override
|
||||
protected ItemStack transferStackToContainer(ItemStack input) {
|
||||
LazyOptional<FluidStack> fsOpt = FluidUtil.getFluidContained(input);
|
||||
Optional<FluidStack> fsOpt = FluidUtil.getFluidContained(input);
|
||||
if (fsOpt.isPresent()) {
|
||||
final IAEFluidTank t = this.getFluidConfigInventory();
|
||||
final IAEFluidStack stack = AEFluidStack.fromFluidStack(fsOpt.orElse(null));
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
|
||||
package appeng.fluids.helper;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fluids.FluidAttributes;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.FluidUtil;
|
||||
@@ -46,7 +47,7 @@ public class FluidCellConfig extends CellConfig {
|
||||
if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) {
|
||||
super.insertItem(slot, stack, simulate);
|
||||
}
|
||||
LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
|
||||
Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
|
||||
if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) {
|
||||
return stack;
|
||||
}
|
||||
@@ -64,7 +65,7 @@ public class FluidCellConfig extends CellConfig {
|
||||
if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) {
|
||||
super.setStackInSlot(slot, stack);
|
||||
}
|
||||
LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
|
||||
Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
|
||||
if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) {
|
||||
return;
|
||||
}
|
||||
@@ -82,7 +83,7 @@ public class FluidCellConfig extends CellConfig {
|
||||
if (stack.isEmpty() || stack.getItem() instanceof FluidDummyItem) {
|
||||
super.isItemValid(slot, stack);
|
||||
}
|
||||
LazyOptional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
|
||||
Optional<FluidStack> fluidOpt = FluidUtil.getFluidContained(stack);
|
||||
if (!fluidOpt.isPresent() || !Api.instance().definitions().items().dummyFluidItem().maybeStack(1).isPresent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -96,16 +96,15 @@ public class FluidImportBusPart extends SharedFluidBusPart {
|
||||
}
|
||||
|
||||
final TileEntity te = this.getConnectedTE();
|
||||
LazyOptional<IFluidHandler> fhOpt = LazyOptional.empty();
|
||||
if (te != null) {
|
||||
te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, this.getSide().getFacing().getOpposite());
|
||||
}
|
||||
if (fhOpt.isPresent()) {
|
||||
try {
|
||||
final IFluidHandler fh = fhOpt.orElse(null);
|
||||
final IMEMonitor<IAEFluidStack> inv = this.getProxy().getStorage().getInventory(this.getChannel());
|
||||
LazyOptional<IFluidHandler> fhOpt = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY,
|
||||
this.getSide().getFacing().getOpposite());
|
||||
|
||||
if (fhOpt.isPresent()) {
|
||||
try {
|
||||
final IFluidHandler fh = fhOpt.orElseThrow(() -> new IllegalStateException());
|
||||
final IMEMonitor<IAEFluidStack> inv = this.getProxy().getStorage().getInventory(this.getChannel());
|
||||
|
||||
if (fh != null) {
|
||||
final FluidStack fluidStack = fh.drain(this.calculateAmountToSend(), FluidAction.SIMULATE);
|
||||
|
||||
if (this.filterEnabled() && !this.isInFilter(fluidStack)) {
|
||||
@@ -128,12 +127,11 @@ public class FluidImportBusPart extends SharedFluidBusPart {
|
||||
}
|
||||
|
||||
return TickRateModulation.IDLE;
|
||||
} catch (GridAccessException e) {
|
||||
// skip
|
||||
}
|
||||
} catch (GridAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return TickRateModulation.SLEEP;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,15 +24,19 @@ import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.tags.ITag;
|
||||
import net.minecraft.util.IItemProvider;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
@@ -41,6 +45,7 @@ import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import appeng.api.implementations.items.IGrowableCrystal;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.ButtonToolTips;
|
||||
import appeng.entity.GrowingCrystalEntity;
|
||||
import appeng.items.AEBaseItem;
|
||||
@@ -94,8 +99,24 @@ public class CrystalSeedItem extends AEBaseItem implements IGrowableCrystal {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMultiplier(final Block blk, final Material mat) {
|
||||
return 0.5f;
|
||||
public float getMultiplier(BlockState state, @Nullable World world, @Nullable BlockPos pos) {
|
||||
|
||||
// Check for the improved fluid tag and return the improved multiplier
|
||||
String improvedFluidTagName = AEConfig.instance().getImprovedFluidTag();
|
||||
if (improvedFluidTagName != null) {
|
||||
ITag<Fluid> tag = FluidTags.getCollection().get(new ResourceLocation(improvedFluidTagName));
|
||||
if (tag != null && state.getFluidState().isTagged(tag)) {
|
||||
return AEConfig.instance().getImprovedFluidMultiplier();
|
||||
}
|
||||
}
|
||||
|
||||
// Check for the normal supported fluid
|
||||
if (world != null && world.func_234923_W_() == World.field_234919_h_) {
|
||||
// In the nether, use Lava as the "normal" fluid
|
||||
return state.getFluidState().isTagged(FluidTags.LAVA) ? 1 : 0;
|
||||
} else {
|
||||
return state.getFluidState().isTagged(FluidTags.WATER) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -324,21 +324,21 @@ public class ColorApplicatorItem extends AEBasePoweredItem
|
||||
return w.setBlockState(pos, newState);
|
||||
}
|
||||
|
||||
if (blk instanceof CableBusBlock && p != null) {
|
||||
return ((CableBusBlock) blk).recolorBlock(w, pos, side, newColor.dye, p);
|
||||
}
|
||||
|
||||
TileEntity be = w.getTileEntity(pos);
|
||||
if (be instanceof IColorableTile) {
|
||||
IColorableTile ct = (IColorableTile) be;
|
||||
AEColor c = ct.getColor();
|
||||
if (c != newColor) {
|
||||
ct.recolourBlock(side, newColor, null);
|
||||
ct.recolourBlock(side, newColor, p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blk instanceof CableBusBlock && p != null) {
|
||||
return ((CableBusBlock) blk).recolorBlock(w, pos, side, newColor.dye, p);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.Iterator;
|
||||
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
@@ -159,12 +158,16 @@ public class QuantumCluster implements ILocatable, IAECluster {
|
||||
if (qc != null) {
|
||||
final World theWorld = qc.center.getWorld();
|
||||
if (!qc.isDestroyed) {
|
||||
ChunkPos cPos = new ChunkPos(qc.center.getPos());
|
||||
if (theWorld.getChunkProvider().isChunkLoaded(cPos)) {
|
||||
// In future versions, we might actually want to delay the entire registration
|
||||
// until the center
|
||||
// tile begins ticking normally.
|
||||
if (theWorld.isBlockLoaded(qc.center.getPos())) {
|
||||
final World cur = theWorld.getServer().getWorld(theWorld.func_234923_W_());
|
||||
|
||||
final TileEntity te = theWorld.getTileEntity(qc.center.getPos());
|
||||
return te != qc.center || theWorld != cur;
|
||||
} else {
|
||||
AELog.warn("Found a registered QNB with serial %s whose chunk seems to be unloaded: %s", qe, qc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,4 +278,17 @@ public class QuantumCluster implements ILocatable, IAECluster {
|
||||
private void setRing(final QuantumBridgeTileEntity[] ring) {
|
||||
this.Ring = ring;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (center == null) {
|
||||
return "QuantumCluster{no-center}";
|
||||
}
|
||||
|
||||
World world = center.getWorld();
|
||||
BlockPos pos = center.getPos();
|
||||
|
||||
return "QuantumCluster{" + world + "," + pos + "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
@@ -82,7 +81,6 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
private final EnumSet<LayerFlags> myLayerFlags = EnumSet.noneOf(LayerFlags.class);
|
||||
private YesNo hasRedstone = YesNo.UNDECIDED;
|
||||
private IPartHost tcb;
|
||||
// TODO 1.10.2-R - does somebody seriously want to make parts TESR??? Hope not.
|
||||
private boolean requiresDynamicRender = false;
|
||||
private boolean inWorld = false;
|
||||
// Cached collision shape for living entities
|
||||
@@ -125,7 +123,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
|
||||
@Override
|
||||
public IFacadeContainer getFacadeContainer() {
|
||||
return new FacadeContainer(this);
|
||||
return new FacadeContainer(this, this::invalidateShapes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1096,11 +1094,7 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||
}
|
||||
}
|
||||
|
||||
VoxelShape shape = VoxelShapes.empty();
|
||||
for (final AxisAlignedBB bx : boxes) {
|
||||
shape = VoxelShapes.or(shape, VoxelShapes.create(bx));
|
||||
}
|
||||
return shape;
|
||||
return VoxelShapeCache.get(boxes);
|
||||
}
|
||||
|
||||
private void invalidateShapes() {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, 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.parts;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
||||
/**
|
||||
* While creation of a {@link VoxelShape} with
|
||||
* {@link VoxelShapes#create(AxisAlignedBB)} is fast enough, combining voxel
|
||||
* shapes with {@link VoxelShapes#or(VoxelShape, VoxelShape)} or any other
|
||||
* combination method, as well as {@link VoxelShape#simplify()} are <b>extremely
|
||||
* slow</b>. For example: Creating a VoxelShape for a list of 5 bounding boxes
|
||||
* 10,000 times takes about 1.7 seconds.
|
||||
*
|
||||
* <p>
|
||||
* To reduce the impact of this on cables, we introduce a global voxel shape
|
||||
* cache so that cables can share their combined voxel shapes better.
|
||||
*/
|
||||
final class VoxelShapeCache {
|
||||
|
||||
// Why using a List here should not make much of a difference vs. using a Set:
|
||||
// The part's bounding box depends on the side it is attached to, and the sides
|
||||
// are iterated over in a fixed order, meaning the order of bounding boxes
|
||||
// should
|
||||
// be the same for a same set of parts.
|
||||
private static final LoadingCache<List<AxisAlignedBB>, VoxelShape> CACHE = CacheBuilder.newBuilder()//
|
||||
.maximumSize(10000L)//
|
||||
.build(new CacheLoader<List<AxisAlignedBB>, VoxelShape>() {
|
||||
@Override
|
||||
public VoxelShape load(List<AxisAlignedBB> key) {
|
||||
return create(key);
|
||||
}
|
||||
});
|
||||
|
||||
private VoxelShapeCache() {
|
||||
}
|
||||
|
||||
public static VoxelShape get(List<AxisAlignedBB> boxes) {
|
||||
return CACHE.getUnchecked(boxes);
|
||||
}
|
||||
|
||||
private static VoxelShape create(List<AxisAlignedBB> boxes) {
|
||||
if (boxes.isEmpty()) {
|
||||
return VoxelShapes.empty();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
VoxelShape shape = VoxelShapes.create(boxes.get(i));
|
||||
for (; i < boxes.size(); i++) {
|
||||
AxisAlignedBB box = boxes.get(i);
|
||||
shape = VoxelShapes.combine(shape, VoxelShapes.create(box), IBooleanFunction.OR);
|
||||
}
|
||||
return shape.simplify();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -253,9 +253,11 @@ public class AEBaseTileEntity extends TileEntity implements IOrientable, ICommon
|
||||
if (this.renderFragment > 0) {
|
||||
this.renderFragment |= 1;
|
||||
} else {
|
||||
// Clearing the cached model-data is always harmless regardless of status
|
||||
this.requestModelDataUpdate();
|
||||
|
||||
// TODO: Optimize Network Load
|
||||
if (this.world != null) {
|
||||
this.requestModelDataUpdate();
|
||||
if (this.world != null && !this.isRemoved() && !notLoaded()) {
|
||||
|
||||
boolean alreadyUpdated = false;
|
||||
// Let the block update it's own state with our internal state changes
|
||||
@@ -304,6 +306,7 @@ public class AEBaseTileEntity extends TileEntity implements IOrientable, ICommon
|
||||
this.up = inUp;
|
||||
this.markForUpdate();
|
||||
Platform.notifyBlocksOfNeighbors(this.world, this.pos);
|
||||
this.saveChanges();
|
||||
}
|
||||
|
||||
public void onPlacement(BlockItemUseContext context) {
|
||||
@@ -367,7 +370,6 @@ public class AEBaseTileEntity extends TileEntity implements IOrientable, ICommon
|
||||
* null means nothing to store...
|
||||
*
|
||||
* @param from source of settings
|
||||
*
|
||||
* @return compound of source
|
||||
*/
|
||||
public CompoundNBT downloadSettings(final SettingsFrom from) {
|
||||
|
||||
@@ -80,6 +80,10 @@ public abstract class AENetworkInvTileEntity extends AEBaseInvTileEntity impleme
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
// 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
|
||||
updateContainingBlockInfo();
|
||||
this.getProxy().remove();
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ public final class AEItemStack extends AEStack<IAEItemStack> implements IAEItemS
|
||||
buffer.writeBoolean(this.isCraftable());
|
||||
buffer.writeVarLong(this.getStackSize());
|
||||
buffer.writeVarLong(this.getCountRequestable());
|
||||
buffer.writeItemStack(getDefinition());
|
||||
buffer.writeItemStack(getDefinition(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,7 @@ import net.minecraft.nbt.CompoundNBT;
|
||||
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> {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ description="A Mod about Matter, Energy and using them to conquer the world.."
|
||||
[[dependencies.appliedenergistics2]]
|
||||
modId="forge"
|
||||
mandatory=true
|
||||
versionRange="[33.0.5,34.0.0)"
|
||||
versionRange="[33.0.22,34.0.0)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
|
||||
|
||||
@@ -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": "陨石罗盘",
|
||||
@@ -408,28 +408,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接口",
|
||||
@@ -459,13 +459,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.复制卡",
|
||||
@@ -478,7 +478,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流体存储组件",
|
||||
@@ -489,43 +489,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接口终端",
|
||||
@@ -533,44 +533,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": "名称压印模板",
|
||||
@@ -584,43 +584,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": "硅压印模板",
|
||||
@@ -643,24 +643,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",
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
{
|
||||
"parent": "appliedenergistics2:block/cable_bus"
|
||||
}
|
||||
{}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "appliedenergistics2:facade"
|
||||
"item": "appliedenergistics2:facade",
|
||||
"nbt": "{item:\"minecraft:stone\"}"
|
||||
},
|
||||
"title": {
|
||||
"translate": "achievement.ae2.Facade"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user